Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(node-api) : Beacon headers and genesis API #2002

Draft
wants to merge 34 commits into
base: e2e-node-api
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
a23d23e
tests for genesis
nidhi-singh02 Sep 9, 2024
bdfb06a
block header json tags
nidhi-singh02 Sep 9, 2024
f700276
headers test
nidhi-singh02 Sep 11, 2024
7a5a95a
does not belong to header
nidhi-singh02 Sep 12, 2024
f49c6f3
Merge branch 'e2e-node-api' into beacon-endpoints
nidhi-singh02 Sep 12, 2024
f1f30d2
Merge branch 'e2e-node-api' into beacon-endpoints
nidhi-singh02 Sep 13, 2024
2d88a90
Revert "does not belong to header"
nidhi-singh02 Sep 13, 2024
6de3ce7
marshal JSON for header for data type as per beaconAPI
nidhi-singh02 Sep 13, 2024
b9b4e3f
linter
nidhi-singh02 Sep 13, 2024
33918ce
Merge branch 'e2e-node-api' into beacon-endpoints
nidhi-singh02 Sep 17, 2024
237effb
Merge branch 'e2e-node-api' into beacon-endpoints
nidhi-singh02 Sep 17, 2024
d703b64
Merge branch 'e2e-node-api' into beacon-endpoints
nidhi-singh02 Sep 17, 2024
d002de1
headerResponse use generics
nidhi-singh02 Sep 17, 2024
3eda29b
header error fix
nidhi-singh02 Sep 17, 2024
0345d5c
no input pass in headers- handle default case
nidhi-singh02 Sep 17, 2024
d0cd381
optimized way of getting lastest slot
nidhi-singh02 Sep 17, 2024
5bdcdc4
generateee
nidhi-singh02 Sep 17, 2024
19ffaec
linting
nidhi-singh02 Sep 17, 2024
6f5c98b
Merge branch 'e2e-node-api' into beacon-endpoints
nidhi-singh02 Sep 17, 2024
5dcefb9
Merge branch 'e2e-node-api' into beacon-endpoints
nidhi-singh02 Sep 18, 2024
6ee4886
using state for getting slot - do not change kvstore
nidhi-singh02 Sep 18, 2024
0ab10a2
generate
nidhi-singh02 Sep 18, 2024
7266db7
header response JSON - same pattern
nidhi-singh02 Sep 18, 2024
ae3b6b9
add more tests for beaconheader by ID
nidhi-singh02 Sep 18, 2024
9942f76
tests correct assert
nidhi-singh02 Sep 18, 2024
101d10b
fix error for root - use correct root
nidhi-singh02 Sep 19, 2024
957620d
implemented fork version at genesis
nidhi-singh02 Sep 19, 2024
72f7f35
mock for fork interface
nidhi-singh02 Sep 19, 2024
7369817
omg linter why you do that?
nidhi-singh02 Sep 19, 2024
bca471f
return correct root and query no key passed handle
nidhi-singh02 Sep 20, 2024
c562a53
query headers by parent block root
nidhi-singh02 Sep 20, 2024
28d38c2
split func
nidhi-singh02 Sep 20, 2024
322a794
linterr
nidhi-singh02 Sep 20, 2024
7436bd6
generatee
nidhi-singh02 Sep 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .mockery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,8 @@ packages:
recursive: False
with-expecter: true
all: True
github.com/berachain/beacon-kit/mod/storage/pkg/block:
config:
recursive: False
with-expecter: true
all: True
10 changes: 5 additions & 5 deletions mod/consensus-types/pkg/types/header.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@ var (
// BeaconBlockHeader represents the base of a beacon block header.
type BeaconBlockHeader struct {
// Slot represents the position of the block in the chain.
Slot math.Slot
Slot math.Slot `json:"slot"`
// ProposerIndex is the index of the validator who proposed the block.
ProposerIndex math.ValidatorIndex
ProposerIndex math.ValidatorIndex `json:"proposer_index"`
// ParentBlockRoot is the hash of the parent block
ParentBlockRoot common.Root
ParentBlockRoot common.Root `json:"parent_root"`
// StateRoot is the hash of the state at the block.
StateRoot common.Root
StateRoot common.Root `json:"state_root"`
// BodyRoot is the root of the block body.
BodyRoot common.Root
BodyRoot common.Root `json:"body_root"`
}

/* -------------------------------------------------------------------------- */
Expand Down
28 changes: 24 additions & 4 deletions mod/node-api/backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ type Backend[
DepositT any,
DepositStoreT DepositStore[DepositT],
Eth1DataT,
ExecutionPayloadHeaderT,
ForkT any,
ExecutionPayloadHeaderT any,
ForkT Fork[ForkT],
NodeT Node[ContextT],
StateStoreT any,
StorageBackendT StorageBackend[
Expand Down Expand Up @@ -86,8 +86,8 @@ func New[
DepositT any,
DepositStoreT DepositStore[DepositT],
Eth1DataT,
ExecutionPayloadHeaderT,
ForkT any,
ExecutionPayloadHeaderT any,
ForkT Fork[ForkT],
NodeT Node[ContextT],
StateStoreT any,
StorageBackendT StorageBackend[
Expand Down Expand Up @@ -206,3 +206,23 @@ func (b *Backend[
}
return st, slot, err
}

// GetHeadSlot returns the head slot from the backend.
func (b *Backend[
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
]) GetHeadSlot() (math.Slot, error) {
//#nosec:G701 // not an issue in practice.
queryCtx, err := b.node.CreateQueryContext(0, false)
if err != nil {
return 0, err
}
st := b.sb.StateFromContext(queryCtx)
return st.GetSlot()
}

// GetSlotByParentRoot returns the slot by a parent root from the block store.
func (b *Backend[
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
]) GetSlotByParentRoot(root common.Root) (math.Slot, error) {
return b.sb.BlockStore().GetSlotByParentRoot(root)
}
5 changes: 3 additions & 2 deletions mod/node-api/backend/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
"github.com/berachain/beacon-kit/mod/primitives/pkg/math"
)

// BlockHeader returns the block header at the given slot.
// BlockHeaderAtSlot returns the block header at the given slot.
func (b Backend[
_, _, _, BeaconBlockHeaderT, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
_,
Expand All @@ -42,7 +42,7 @@ func (b Backend[
return blockHeader, err
}

// GetBlockRoot returns the root of the block at the given stateID.
// BlockRootAtSlot returns the root of the block at the given stateID.
func (b Backend[
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
]) BlockRootAtSlot(slot math.Slot) (common.Root, error) {
Expand All @@ -56,6 +56,7 @@ func (b Backend[
return st.GetBlockRootAtIndex(slot.Unwrap() % b.cs.SlotsPerHistoricalRoot())
}

// BlockRewardsAtSlot returns the block rewards at the given slot.
// TODO: Implement this.
func (b Backend[
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
Expand Down
15 changes: 15 additions & 0 deletions mod/node-api/backend/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,18 @@ func (b Backend[
}
return st.GetGenesisValidatorsRoot()
}

// GetGenesisForkVersion returns the genesis fork version of the beacon chain.
func (b Backend[
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
]) GetGenesisForkVersion(genesisSlot math.Slot) (common.Version, error) {
st, _, err := b.stateFromSlot(genesisSlot)
if err != nil {
return common.Version{}, err
}
fork, err := st.GetFork()
if err != nil {
return common.Version{}, err
}
return fork.GetPreviousVersion(), nil
}
56 changes: 56 additions & 0 deletions mod/node-api/backend/mocks/block_store.mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

82 changes: 82 additions & 0 deletions mod/node-api/backend/mocks/fork.mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions mod/node-api/backend/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ type BlockStore[BeaconBlockT any] interface {
GetSlotByStateRoot(root common.Root) (math.Slot, error)
// GetSlotByExecutionNumber retrieves the slot by a given execution number.
GetSlotByExecutionNumber(executionNumber math.U64) (math.Slot, error)
// GetSlotByParentRoot retrieves the slot by a given parent root.
GetSlotByParentRoot(root common.Root) (math.Slot, error)
}

// DepositStore defines the interface for deposit storage.
Expand Down Expand Up @@ -140,3 +142,7 @@ type Withdrawal[T any] interface {
amount math.Gwei,
) T
}

type Fork[ForkT any] interface {
GetPreviousVersion() common.Version
}
13 changes: 10 additions & 3 deletions mod/node-api/engines/echo/vaildator.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ func ConstructValidator() *validator.Validate {
"epoch": ValidateUint64,
"slot": ValidateUint64,
"validator_status": ValidateValidatorStatus,
"parent_root": ValidateRoot,
}
validate := validator.New()
for tag, fn := range validators {
Expand Down Expand Up @@ -144,9 +145,9 @@ func ValidateValidatorID(fl validator.FieldLevel) bool {
return false
}

// ValidateRoot checks if the provided field is a valid root.
// validateRoot checks if the provided field is a valid root.
// It validates against a 32 byte hex-encoded root with "0x" prefix.
func ValidateRoot(value string) bool {
func validateRoot(value string) bool {
valid, err := validateRegex(value, `^0x[0-9a-fA-F]{64}$`)
if err != nil {
return false
Expand Down Expand Up @@ -201,8 +202,14 @@ func validateStateBlockIDs(value string, allowedValues map[string]bool) bool {
return true
}
// Check if value is a hex-encoded 32 byte root with "0x" prefix
if ValidateRoot(value) {
if validateRoot(value) {
return true
}
return false
}

// ValidateRoot checks if the provided field is a valid root.
// It validates against a 32 byte hex-encoded root with "0x" prefix.
func ValidateRoot(fl validator.FieldLevel) bool {
return validateRoot(fl.Field().String())
}
5 changes: 5 additions & 0 deletions mod/node-api/handlers/beacon/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,15 @@ type Backend[
GetSlotByBlockRoot(root common.Root) (math.Slot, error)
// GetSlotByStateRoot retrieves the slot by a given root from the store.
GetSlotByStateRoot(root common.Root) (math.Slot, error)
// GetSlotByParentRoot retrieves the slot by a given root from the store.
GetSlotByParentRoot(root common.Root) (math.Slot, error)
// GetHeadSlot retrieves the head slot from the store.
GetHeadSlot() (math.Slot, error)
}

type GenesisBackend interface {
GenesisValidatorsRoot(slot math.Slot) (common.Root, error)
GetGenesisForkVersion(genesisSlot math.Slot) (common.Version, error)
}

type HistoricalBackend[ForkT any] interface {
Expand Down
10 changes: 9 additions & 1 deletion mod/node-api/handlers/beacon/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
package beacon

import (
"encoding/hex"

beacontypes "github.com/berachain/beacon-kit/mod/node-api/handlers/beacon/types"
"github.com/berachain/beacon-kit/mod/node-api/handlers/types"
"github.com/berachain/beacon-kit/mod/node-api/handlers/utils"
Expand All @@ -34,9 +36,15 @@ func (h *Handler[_, ContextT, _, _]) GetGenesis(_ ContextT) (any, error) {
if len(genesisRoot) == 0 {
return nil, types.ErrNotFound
}

genesisVersion, err := h.backend.GetGenesisForkVersion(utils.Genesis)
if err != nil {
return nil, err
}
genesisForkVersionHex := "0x" + hex.EncodeToString(genesisVersion[:])
return types.Wrap(beacontypes.GenesisData{
GenesisTime: "1590832934", // stub
GenesisValidatorsRoot: genesisRoot,
GenesisForkVersion: "0x00000000", // stub
GenesisForkVersion: genesisForkVersionHex,
}), nil
}
Loading
Loading