From a23d23e159024f30b23a7d6e20c0f99b481d868f Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Mon, 9 Sep 2024 16:15:55 +0530 Subject: [PATCH 01/27] tests for genesis Signed-off-by: nidhi-singh02 --- testing/e2e/e2e_api_test.go | 48 +++++++++++++++++++++ testing/e2e/suite/types/consensus_client.go | 21 +++++++++ 2 files changed, 69 insertions(+) diff --git a/testing/e2e/e2e_api_test.go b/testing/e2e/e2e_api_test.go index 7aab153c0b..d9cf2d2caa 100644 --- a/testing/e2e/e2e_api_test.go +++ b/testing/e2e/e2e_api_test.go @@ -182,3 +182,51 @@ func (s *BeaconKitE2ESuite) TestBeaconRandao() { "Randao should not be all zeros", ) } + +func (s *BeaconKitE2ESuite) TestBeaconGenesis() { + client := s.initBeaconTest() + + genesisResp, err := client.Genesis(s.Ctx(), + &beaconapi.GenesisOpts{}) + s.Require().NoError(err) + s.Require().NotNil(genesisResp) + + s.Require().NotZero(genesisResp.Data.GenesisTime, "Genesis time should not be zero") + + s.Require().NotEmpty(genesisResp.Data.GenesisValidatorsRoot, "Genesis validators root should not be empty") + + s.Require().NotEmpty(genesisResp.Data.GenesisForkVersion, "Genesis fork version should not be empty") +} + +// func (s *BeaconKitE2ESuite) TestBeaconBlockHeaderByID() { +// client := s.initBeaconTest() + +// // Test getting the head block header +// headResp, err := client.BeaconBlockHeader(s.Ctx(), &beaconapi.BeaconBlockHeaderOpts{ +// Block: "head", +// }) +// s.Require().NoError(err) +// s.Require().NotNil(headResp) +// s.Require().NotNil(headResp.Data) +// s.Require().NotEmpty(headResp.Data.Root) +// s.Require().NotZero(headResp.Data.Header.Message.Slot) + +// // Test getting a block header by slot +// slot := headResp.Data.Header.Message.Slot - 1 +// slotResp, err := client.BeaconBlockHeader(s.Ctx(), &beaconapi.BeaconBlockHeaderOpts{ +// Block: strconv.FormatUint(uint64(slot), 10), +// }) +// s.Require().NoError(err) +// s.Require().NotNil(slotResp) +// s.Require().NotNil(slotResp.Data) +// s.Require().Equal(slot, slotResp.Data.Header.Message.Slot) + +// // Test getting a block header by root +// rootResp, err := client.BeaconBlockHeader(s.Ctx(), &beaconapi.BeaconBlockHeaderOpts{ +// Block: "0x" + hex.EncodeToString(headResp.Data.Root[:]), +// }) +// s.Require().NoError(err) +// s.Require().NotNil(rootResp) +// s.Require().NotNil(rootResp.Data) +// s.Require().Equal(headResp.Data.Root, rootResp.Data.Root) +// } diff --git a/testing/e2e/suite/types/consensus_client.go b/testing/e2e/suite/types/consensus_client.go index 84e4a2571a..9643b798ce 100644 --- a/testing/e2e/suite/types/consensus_client.go +++ b/testing/e2e/suite/types/consensus_client.go @@ -217,5 +217,26 @@ func (cc ConsensusClient) BeaconStateRandao( return cc.beaconClient.BeaconStateRandao(ctx, opts) } +// Genesis returns the genesis of the node. +func (cc ConsensusClient) Genesis( + ctx context.Context, + opts *beaconapi.GenesisOpts, +) (*beaconapi.Response[*apiv1.Genesis], error) { + if cc.beaconClient == nil { + return nil, errors.New("beacon client is not initialized") + } + return cc.beaconClient.Genesis(ctx, opts) +} + +func (cc ConsensusClient) BeaconBlockHeader( + ctx context.Context, + opts *beaconapi.BeaconBlockHeaderOpts, +) (*beaconapi.Response[*apiv1.BeaconBlockHeader], error) { + if cc.beaconClient == nil { + return nil, errors.New("beacon client is not initialized") + } + return cc.beaconClient.BeaconBlockHeader(ctx, opts) +} + // TODO: Add helpers for the beacon node-api client (converting from // go-eth2-client types to beacon-kit consensus types). From bdfb06af23e2fcd16c9191cfbe51fbd774f0b1a4 Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Mon, 9 Sep 2024 16:34:59 +0530 Subject: [PATCH 02/27] block header json tags Signed-off-by: nidhi-singh02 --- mod/consensus-types/pkg/types/header.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mod/consensus-types/pkg/types/header.go b/mod/consensus-types/pkg/types/header.go index f1a91e432c..05d585bb3c 100644 --- a/mod/consensus-types/pkg/types/header.go +++ b/mod/consensus-types/pkg/types/header.go @@ -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"` } /* -------------------------------------------------------------------------- */ From f70027623287ad21b2a3072a8ccab3bfb0a3b2ea Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Wed, 11 Sep 2024 17:22:53 +0530 Subject: [PATCH 03/27] headers test Signed-off-by: nidhi-singh02 --- testing/e2e/e2e_api_test.go | 66 ++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/testing/e2e/e2e_api_test.go b/testing/e2e/e2e_api_test.go index d9cf2d2caa..7b8b13cbbc 100644 --- a/testing/e2e/e2e_api_test.go +++ b/testing/e2e/e2e_api_test.go @@ -195,38 +195,38 @@ func (s *BeaconKitE2ESuite) TestBeaconGenesis() { s.Require().NotEmpty(genesisResp.Data.GenesisValidatorsRoot, "Genesis validators root should not be empty") - s.Require().NotEmpty(genesisResp.Data.GenesisForkVersion, "Genesis fork version should not be empty") + //s.Require().NotEmpty(genesisResp.Data.GenesisForkVersion, "Genesis fork version should be empty") } -// func (s *BeaconKitE2ESuite) TestBeaconBlockHeaderByID() { -// client := s.initBeaconTest() - -// // Test getting the head block header -// headResp, err := client.BeaconBlockHeader(s.Ctx(), &beaconapi.BeaconBlockHeaderOpts{ -// Block: "head", -// }) -// s.Require().NoError(err) -// s.Require().NotNil(headResp) -// s.Require().NotNil(headResp.Data) -// s.Require().NotEmpty(headResp.Data.Root) -// s.Require().NotZero(headResp.Data.Header.Message.Slot) - -// // Test getting a block header by slot -// slot := headResp.Data.Header.Message.Slot - 1 -// slotResp, err := client.BeaconBlockHeader(s.Ctx(), &beaconapi.BeaconBlockHeaderOpts{ -// Block: strconv.FormatUint(uint64(slot), 10), -// }) -// s.Require().NoError(err) -// s.Require().NotNil(slotResp) -// s.Require().NotNil(slotResp.Data) -// s.Require().Equal(slot, slotResp.Data.Header.Message.Slot) - -// // Test getting a block header by root -// rootResp, err := client.BeaconBlockHeader(s.Ctx(), &beaconapi.BeaconBlockHeaderOpts{ -// Block: "0x" + hex.EncodeToString(headResp.Data.Root[:]), -// }) -// s.Require().NoError(err) -// s.Require().NotNil(rootResp) -// s.Require().NotNil(rootResp.Data) -// s.Require().Equal(headResp.Data.Root, rootResp.Data.Root) -// } +func (s *BeaconKitE2ESuite) TestBeaconBlockHeaderByID() { + client := s.initBeaconTest() + + // Test getting the head block header + headResp, err := client.BeaconBlockHeader(s.Ctx(), &beaconapi.BeaconBlockHeaderOpts{ + Block: "head", + }) + s.Require().NoError(err) + s.Require().NotNil(headResp) + s.Require().NotNil(headResp.Data) + s.Require().NotEmpty(headResp.Data.Root) + s.Require().NotZero(headResp.Data.Header.Message.Slot) + + // // Test getting a block header by slot + //slot := headResp.Data.Header.Message.Slot - 1 + //slotResp, err := client.BeaconBlockHeader(s.Ctx(), &beaconapi.BeaconBlockHeaderOpts{ + // Block: strconv.FormatUint(uint64(slot), 10), + //}) + //s.Require().NoError(err) + //s.Require().NotNil(slotResp) + //s.Require().NotNil(slotResp.Data) + //s.Require().Equal(slot, slotResp.Data.Header.Message.Slot) + + // // Test getting a block header by root + // rootResp, err := client.BeaconBlockHeader(s.Ctx(), &beaconapi.BeaconBlockHeaderOpts{ + // Block: "0x" + hex.EncodeToString(headResp.Data.Root[:]), + // }) + // s.Require().NoError(err) + // s.Require().NotNil(rootResp) + // s.Require().NotNil(rootResp.Data) + // s.Require().Equal(headResp.Data.Root, rootResp.Data.Root) +} From 7a5a95a4222a4202f3b78e770d2a9eb33f614438 Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Thu, 12 Sep 2024 12:35:07 +0530 Subject: [PATCH 04/27] does not belong to header Signed-off-by: nidhi-singh02 --- examples/berad/pkg/consensus-types/state.go | 3 ++ mod/consensus-types/pkg/types/block.go | 4 ++- mod/consensus-types/pkg/types/header.go | 8 ++++- mod/consensus-types/pkg/types/state.go | 2 ++ mod/node-api/backend/block.go | 39 +++++++++++++++++++++ mod/node-api/backend/types.go | 3 +- mod/node-api/handlers/beacon/backend.go | 2 ++ mod/node-api/handlers/beacon/header.go | 8 ++++- mod/node-api/handlers/proof/backend.go | 2 ++ mod/node-core/pkg/components/interfaces.go | 2 ++ 10 files changed, 69 insertions(+), 4 deletions(-) diff --git a/examples/berad/pkg/consensus-types/state.go b/examples/berad/pkg/consensus-types/state.go index 455a64a258..ab7f677268 100644 --- a/examples/berad/pkg/consensus-types/state.go +++ b/examples/berad/pkg/consensus-types/state.go @@ -21,6 +21,7 @@ package consensustypes import ( + "github.com/berachain/beacon-kit/mod/primitives/pkg/bytes" "github.com/berachain/beacon-kit/mod/primitives/pkg/common" "github.com/berachain/beacon-kit/mod/primitives/pkg/constraints" "github.com/berachain/beacon-kit/mod/primitives/pkg/math" @@ -64,6 +65,8 @@ type BeaconState[ // Withdrawals NextWithdrawalIndex uint64 NextWithdrawalValidatorIndex math.ValidatorIndex + + Signatures bytes.B48 } /* -------------------------------------------------------------------------- */ diff --git a/mod/consensus-types/pkg/types/block.go b/mod/consensus-types/pkg/types/block.go index 5a6b10131e..0d390cb8c8 100644 --- a/mod/consensus-types/pkg/types/block.go +++ b/mod/consensus-types/pkg/types/block.go @@ -21,6 +21,7 @@ package types import ( + "github.com/berachain/beacon-kit/mod/primitives/pkg/bytes" "github.com/berachain/beacon-kit/mod/primitives/pkg/common" "github.com/berachain/beacon-kit/mod/primitives/pkg/math" "github.com/berachain/beacon-kit/mod/primitives/pkg/version" @@ -41,7 +42,8 @@ type BeaconBlock struct { StateRoot common.Root `json:"state_root"` // Body is the body of the BeaconBlock, containing the block's // operations. - Body *BeaconBlockBody `json:"body"` + Body *BeaconBlockBody `json:"body"` + Signature bytes.B48 `json:"signature"` } // Empty creates an empty beacon block. diff --git a/mod/consensus-types/pkg/types/header.go b/mod/consensus-types/pkg/types/header.go index 05d585bb3c..9e6bc46784 100644 --- a/mod/consensus-types/pkg/types/header.go +++ b/mod/consensus-types/pkg/types/header.go @@ -21,6 +21,7 @@ package types import ( + "github.com/berachain/beacon-kit/mod/primitives/pkg/bytes" "github.com/berachain/beacon-kit/mod/primitives/pkg/common" "github.com/berachain/beacon-kit/mod/primitives/pkg/constraints" "github.com/berachain/beacon-kit/mod/primitives/pkg/math" @@ -50,7 +51,8 @@ type BeaconBlockHeader struct { // StateRoot is the hash of the state at the block. StateRoot common.Root `json:"state_root"` // BodyRoot is the root of the block body. - BodyRoot common.Root `json:"body_root"` + BodyRoot common.Root `json:"body_root"` + Signature bytes.B48 `json:"signature"` } /* -------------------------------------------------------------------------- */ @@ -225,3 +227,7 @@ func (b *BeaconBlockHeader) GetBodyRoot() common.Root { func (b *BeaconBlockHeader) SetBodyRoot(bodyRoot common.Root) { b.BodyRoot = bodyRoot } + +func (b *BeaconBlockHeader) GetSignatures() bytes.B48 { + return b.Signature +} diff --git a/mod/consensus-types/pkg/types/state.go b/mod/consensus-types/pkg/types/state.go index d48f36a8cc..a549a1f22e 100644 --- a/mod/consensus-types/pkg/types/state.go +++ b/mod/consensus-types/pkg/types/state.go @@ -21,6 +21,7 @@ package types import ( + "github.com/berachain/beacon-kit/mod/primitives/pkg/bytes" "github.com/berachain/beacon-kit/mod/primitives/pkg/common" "github.com/berachain/beacon-kit/mod/primitives/pkg/constraints" "github.com/berachain/beacon-kit/mod/primitives/pkg/math" @@ -71,6 +72,7 @@ type BeaconState[ // Slashing Slashings []uint64 TotalSlashing math.Gwei + Signatures bytes.B48 } // New creates a new BeaconState. diff --git a/mod/node-api/backend/block.go b/mod/node-api/backend/block.go index c6087cc989..796e969571 100644 --- a/mod/node-api/backend/block.go +++ b/mod/node-api/backend/block.go @@ -21,7 +21,10 @@ package backend import ( + "fmt" + types "github.com/berachain/beacon-kit/mod/node-api/handlers/beacon/types" + "github.com/berachain/beacon-kit/mod/primitives/pkg/bytes" "github.com/berachain/beacon-kit/mod/primitives/pkg/common" "github.com/berachain/beacon-kit/mod/primitives/pkg/math" ) @@ -69,3 +72,39 @@ func (b Backend[ AttesterSlashings: 1, }, nil } + +func (b Backend[ + _, _, _, BeaconBlockHeaderT, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, +]) BlockSignatureAtSlot(slot math.Slot) (bytes.B48, error) { + // Get the block header + header, err := b.BlockHeaderAtSlot(slot) + if err != nil { + return bytes.B48{}, err + } + + // Extract the signature from the header + // This will depend on how your BeaconBlockHeaderT type stores the signature + signature, err := b.extractSignatureFromHeader(header) + if err != nil { + return bytes.B48{}, err + } + + return signature, nil +} + +func (b Backend[ + _, _, _, BeaconBlockHeaderT, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + _, +]) extractSignatureFromHeader(header BeaconBlockHeaderT) (bytes.B48, error) { + // Implementation depends on how signatures are stored in your header structure + // This is a placeholder implementation + rawSignature := header.GetSignatures() + if len(rawSignature) != 48 { + return bytes.B48{}, fmt.Errorf("invalid signature length: expected 48, got %d", len(rawSignature)) + } + + //var signature bytes.B48 + //copy(signature[:], rawSignature) + return rawSignature, nil +} diff --git a/mod/node-api/backend/types.go b/mod/node-api/backend/types.go index 0ae940772f..0c86e2c9d9 100644 --- a/mod/node-api/backend/types.go +++ b/mod/node-api/backend/types.go @@ -22,7 +22,7 @@ package backend import ( "context" - + "github.com/berachain/beacon-kit/mod/primitives/pkg/bytes" "github.com/berachain/beacon-kit/mod/primitives/pkg/common" "github.com/berachain/beacon-kit/mod/primitives/pkg/constraints" "github.com/berachain/beacon-kit/mod/primitives/pkg/math" @@ -60,6 +60,7 @@ type BeaconBlockHeader[BeaconBlockHeaderT any] interface { GetStateRoot() common.Root SetStateRoot(common.Root) GetBodyRoot() common.Root + GetSignatures() bytes.B48 } // BeaconState is the interface for the beacon state. diff --git a/mod/node-api/handlers/beacon/backend.go b/mod/node-api/handlers/beacon/backend.go index f16b956482..bb40e14251 100644 --- a/mod/node-api/handlers/beacon/backend.go +++ b/mod/node-api/handlers/beacon/backend.go @@ -22,6 +22,7 @@ package beacon import ( "github.com/berachain/beacon-kit/mod/node-api/handlers/beacon/types" + "github.com/berachain/beacon-kit/mod/primitives/pkg/bytes" "github.com/berachain/beacon-kit/mod/primitives/pkg/common" "github.com/berachain/beacon-kit/mod/primitives/pkg/math" ) @@ -57,6 +58,7 @@ type BlockBackend[BeaconBlockHeaderT any] interface { BlockRootAtSlot(slot math.Slot) (common.Root, error) BlockRewardsAtSlot(slot math.Slot) (*types.BlockRewardsData, error) BlockHeaderAtSlot(slot math.Slot) (BeaconBlockHeaderT, error) + BlockSignatureAtSlot(slot math.Slot) (bytes.B48, error) } type StateBackend[ForkT any] interface { diff --git a/mod/node-api/handlers/beacon/header.go b/mod/node-api/handlers/beacon/header.go index 9cba5a83b5..3eefa6feda 100644 --- a/mod/node-api/handlers/beacon/header.go +++ b/mod/node-api/handlers/beacon/header.go @@ -74,6 +74,12 @@ func (h *Handler[ if err != nil { return nil, err } + + signature, err := h.backend.BlockSignatureAtSlot(slot) + if err != nil { + return nil, err + } + return beacontypes.ValidatorResponse{ ExecutionOptimistic: false, // stubbed Finalized: false, // stubbed @@ -82,7 +88,7 @@ func (h *Handler[ Canonical: true, Header: &beacontypes.BlockHeader[BeaconBlockHeaderT]{ Message: header, - Signature: bytes.B48{}, // TODO: implement + Signature: signature, // TODO: implement }, }, }, nil diff --git a/mod/node-api/handlers/proof/backend.go b/mod/node-api/handlers/proof/backend.go index 376c039206..439f7f293d 100644 --- a/mod/node-api/handlers/proof/backend.go +++ b/mod/node-api/handlers/proof/backend.go @@ -21,6 +21,7 @@ package proof import ( + "github.com/berachain/beacon-kit/mod/primitives/pkg/bytes" "github.com/berachain/beacon-kit/mod/primitives/pkg/math" ) @@ -33,6 +34,7 @@ type Backend[BeaconBlockHeaderT, BeaconStateT, ValidatorT any] interface { type BlockBackend[BeaconBlockHeaderT any] interface { BlockHeaderAtSlot(slot math.Slot) (BeaconBlockHeaderT, error) + BlockSignatureAtSlot(slot math.Slot) (bytes.B48, error) } type StateBackend[BeaconStateT any] interface { diff --git a/mod/node-core/pkg/components/interfaces.go b/mod/node-core/pkg/components/interfaces.go index ab98993121..640a5c6c8b 100644 --- a/mod/node-core/pkg/components/interfaces.go +++ b/mod/node-core/pkg/components/interfaces.go @@ -176,6 +176,7 @@ type ( SetStateRoot(common.Root) GetBodyRoot() common.Root GetTree() (*fastssz.Node, error) + GetSignatures() bytes.B48 } // BeaconStateMarshallable represents an interface for a beacon state @@ -1142,6 +1143,7 @@ type ( BlockRootAtSlot(slot math.Slot) (common.Root, error) BlockRewardsAtSlot(slot math.Slot) (*types.BlockRewardsData, error) BlockHeaderAtSlot(slot math.Slot) (BeaconBlockHeaderT, error) + BlockSignatureAtSlot(slot math.Slot) (bytes.B48, error) } StateBackend[BeaconStateT, ForkT any] interface { From 2d88a9070dfaaeafb02343f25fceb3d6ae25de69 Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Fri, 13 Sep 2024 13:09:09 +0530 Subject: [PATCH 05/27] Revert "does not belong to header" This reverts commit 7a5a95a4222a4202f3b78e770d2a9eb33f614438. --- examples/berad/pkg/consensus-types/state.go | 3 -- mod/consensus-types/pkg/types/block.go | 4 +-- mod/consensus-types/pkg/types/header.go | 8 +---- mod/consensus-types/pkg/types/state.go | 2 -- mod/node-api/backend/block.go | 39 --------------------- mod/node-api/backend/types.go | 3 +- mod/node-api/handlers/beacon/backend.go | 2 -- mod/node-api/handlers/beacon/header.go | 8 +---- mod/node-api/handlers/proof/backend.go | 2 -- mod/node-core/pkg/components/interfaces.go | 2 -- 10 files changed, 4 insertions(+), 69 deletions(-) diff --git a/examples/berad/pkg/consensus-types/state.go b/examples/berad/pkg/consensus-types/state.go index ab7f677268..455a64a258 100644 --- a/examples/berad/pkg/consensus-types/state.go +++ b/examples/berad/pkg/consensus-types/state.go @@ -21,7 +21,6 @@ package consensustypes import ( - "github.com/berachain/beacon-kit/mod/primitives/pkg/bytes" "github.com/berachain/beacon-kit/mod/primitives/pkg/common" "github.com/berachain/beacon-kit/mod/primitives/pkg/constraints" "github.com/berachain/beacon-kit/mod/primitives/pkg/math" @@ -65,8 +64,6 @@ type BeaconState[ // Withdrawals NextWithdrawalIndex uint64 NextWithdrawalValidatorIndex math.ValidatorIndex - - Signatures bytes.B48 } /* -------------------------------------------------------------------------- */ diff --git a/mod/consensus-types/pkg/types/block.go b/mod/consensus-types/pkg/types/block.go index 0d390cb8c8..5a6b10131e 100644 --- a/mod/consensus-types/pkg/types/block.go +++ b/mod/consensus-types/pkg/types/block.go @@ -21,7 +21,6 @@ package types import ( - "github.com/berachain/beacon-kit/mod/primitives/pkg/bytes" "github.com/berachain/beacon-kit/mod/primitives/pkg/common" "github.com/berachain/beacon-kit/mod/primitives/pkg/math" "github.com/berachain/beacon-kit/mod/primitives/pkg/version" @@ -42,8 +41,7 @@ type BeaconBlock struct { StateRoot common.Root `json:"state_root"` // Body is the body of the BeaconBlock, containing the block's // operations. - Body *BeaconBlockBody `json:"body"` - Signature bytes.B48 `json:"signature"` + Body *BeaconBlockBody `json:"body"` } // Empty creates an empty beacon block. diff --git a/mod/consensus-types/pkg/types/header.go b/mod/consensus-types/pkg/types/header.go index 9e6bc46784..05d585bb3c 100644 --- a/mod/consensus-types/pkg/types/header.go +++ b/mod/consensus-types/pkg/types/header.go @@ -21,7 +21,6 @@ package types import ( - "github.com/berachain/beacon-kit/mod/primitives/pkg/bytes" "github.com/berachain/beacon-kit/mod/primitives/pkg/common" "github.com/berachain/beacon-kit/mod/primitives/pkg/constraints" "github.com/berachain/beacon-kit/mod/primitives/pkg/math" @@ -51,8 +50,7 @@ type BeaconBlockHeader struct { // StateRoot is the hash of the state at the block. StateRoot common.Root `json:"state_root"` // BodyRoot is the root of the block body. - BodyRoot common.Root `json:"body_root"` - Signature bytes.B48 `json:"signature"` + BodyRoot common.Root `json:"body_root"` } /* -------------------------------------------------------------------------- */ @@ -227,7 +225,3 @@ func (b *BeaconBlockHeader) GetBodyRoot() common.Root { func (b *BeaconBlockHeader) SetBodyRoot(bodyRoot common.Root) { b.BodyRoot = bodyRoot } - -func (b *BeaconBlockHeader) GetSignatures() bytes.B48 { - return b.Signature -} diff --git a/mod/consensus-types/pkg/types/state.go b/mod/consensus-types/pkg/types/state.go index a549a1f22e..d48f36a8cc 100644 --- a/mod/consensus-types/pkg/types/state.go +++ b/mod/consensus-types/pkg/types/state.go @@ -21,7 +21,6 @@ package types import ( - "github.com/berachain/beacon-kit/mod/primitives/pkg/bytes" "github.com/berachain/beacon-kit/mod/primitives/pkg/common" "github.com/berachain/beacon-kit/mod/primitives/pkg/constraints" "github.com/berachain/beacon-kit/mod/primitives/pkg/math" @@ -72,7 +71,6 @@ type BeaconState[ // Slashing Slashings []uint64 TotalSlashing math.Gwei - Signatures bytes.B48 } // New creates a new BeaconState. diff --git a/mod/node-api/backend/block.go b/mod/node-api/backend/block.go index 796e969571..c6087cc989 100644 --- a/mod/node-api/backend/block.go +++ b/mod/node-api/backend/block.go @@ -21,10 +21,7 @@ package backend import ( - "fmt" - types "github.com/berachain/beacon-kit/mod/node-api/handlers/beacon/types" - "github.com/berachain/beacon-kit/mod/primitives/pkg/bytes" "github.com/berachain/beacon-kit/mod/primitives/pkg/common" "github.com/berachain/beacon-kit/mod/primitives/pkg/math" ) @@ -72,39 +69,3 @@ func (b Backend[ AttesterSlashings: 1, }, nil } - -func (b Backend[ - _, _, _, BeaconBlockHeaderT, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, -]) BlockSignatureAtSlot(slot math.Slot) (bytes.B48, error) { - // Get the block header - header, err := b.BlockHeaderAtSlot(slot) - if err != nil { - return bytes.B48{}, err - } - - // Extract the signature from the header - // This will depend on how your BeaconBlockHeaderT type stores the signature - signature, err := b.extractSignatureFromHeader(header) - if err != nil { - return bytes.B48{}, err - } - - return signature, nil -} - -func (b Backend[ - _, _, _, BeaconBlockHeaderT, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, -]) extractSignatureFromHeader(header BeaconBlockHeaderT) (bytes.B48, error) { - // Implementation depends on how signatures are stored in your header structure - // This is a placeholder implementation - rawSignature := header.GetSignatures() - if len(rawSignature) != 48 { - return bytes.B48{}, fmt.Errorf("invalid signature length: expected 48, got %d", len(rawSignature)) - } - - //var signature bytes.B48 - //copy(signature[:], rawSignature) - return rawSignature, nil -} diff --git a/mod/node-api/backend/types.go b/mod/node-api/backend/types.go index 0c86e2c9d9..0ae940772f 100644 --- a/mod/node-api/backend/types.go +++ b/mod/node-api/backend/types.go @@ -22,7 +22,7 @@ package backend import ( "context" - "github.com/berachain/beacon-kit/mod/primitives/pkg/bytes" + "github.com/berachain/beacon-kit/mod/primitives/pkg/common" "github.com/berachain/beacon-kit/mod/primitives/pkg/constraints" "github.com/berachain/beacon-kit/mod/primitives/pkg/math" @@ -60,7 +60,6 @@ type BeaconBlockHeader[BeaconBlockHeaderT any] interface { GetStateRoot() common.Root SetStateRoot(common.Root) GetBodyRoot() common.Root - GetSignatures() bytes.B48 } // BeaconState is the interface for the beacon state. diff --git a/mod/node-api/handlers/beacon/backend.go b/mod/node-api/handlers/beacon/backend.go index bb40e14251..f16b956482 100644 --- a/mod/node-api/handlers/beacon/backend.go +++ b/mod/node-api/handlers/beacon/backend.go @@ -22,7 +22,6 @@ package beacon import ( "github.com/berachain/beacon-kit/mod/node-api/handlers/beacon/types" - "github.com/berachain/beacon-kit/mod/primitives/pkg/bytes" "github.com/berachain/beacon-kit/mod/primitives/pkg/common" "github.com/berachain/beacon-kit/mod/primitives/pkg/math" ) @@ -58,7 +57,6 @@ type BlockBackend[BeaconBlockHeaderT any] interface { BlockRootAtSlot(slot math.Slot) (common.Root, error) BlockRewardsAtSlot(slot math.Slot) (*types.BlockRewardsData, error) BlockHeaderAtSlot(slot math.Slot) (BeaconBlockHeaderT, error) - BlockSignatureAtSlot(slot math.Slot) (bytes.B48, error) } type StateBackend[ForkT any] interface { diff --git a/mod/node-api/handlers/beacon/header.go b/mod/node-api/handlers/beacon/header.go index 3eefa6feda..9cba5a83b5 100644 --- a/mod/node-api/handlers/beacon/header.go +++ b/mod/node-api/handlers/beacon/header.go @@ -74,12 +74,6 @@ func (h *Handler[ if err != nil { return nil, err } - - signature, err := h.backend.BlockSignatureAtSlot(slot) - if err != nil { - return nil, err - } - return beacontypes.ValidatorResponse{ ExecutionOptimistic: false, // stubbed Finalized: false, // stubbed @@ -88,7 +82,7 @@ func (h *Handler[ Canonical: true, Header: &beacontypes.BlockHeader[BeaconBlockHeaderT]{ Message: header, - Signature: signature, // TODO: implement + Signature: bytes.B48{}, // TODO: implement }, }, }, nil diff --git a/mod/node-api/handlers/proof/backend.go b/mod/node-api/handlers/proof/backend.go index 439f7f293d..376c039206 100644 --- a/mod/node-api/handlers/proof/backend.go +++ b/mod/node-api/handlers/proof/backend.go @@ -21,7 +21,6 @@ package proof import ( - "github.com/berachain/beacon-kit/mod/primitives/pkg/bytes" "github.com/berachain/beacon-kit/mod/primitives/pkg/math" ) @@ -34,7 +33,6 @@ type Backend[BeaconBlockHeaderT, BeaconStateT, ValidatorT any] interface { type BlockBackend[BeaconBlockHeaderT any] interface { BlockHeaderAtSlot(slot math.Slot) (BeaconBlockHeaderT, error) - BlockSignatureAtSlot(slot math.Slot) (bytes.B48, error) } type StateBackend[BeaconStateT any] interface { diff --git a/mod/node-core/pkg/components/interfaces.go b/mod/node-core/pkg/components/interfaces.go index 640a5c6c8b..ab98993121 100644 --- a/mod/node-core/pkg/components/interfaces.go +++ b/mod/node-core/pkg/components/interfaces.go @@ -176,7 +176,6 @@ type ( SetStateRoot(common.Root) GetBodyRoot() common.Root GetTree() (*fastssz.Node, error) - GetSignatures() bytes.B48 } // BeaconStateMarshallable represents an interface for a beacon state @@ -1143,7 +1142,6 @@ type ( BlockRootAtSlot(slot math.Slot) (common.Root, error) BlockRewardsAtSlot(slot math.Slot) (*types.BlockRewardsData, error) BlockHeaderAtSlot(slot math.Slot) (BeaconBlockHeaderT, error) - BlockSignatureAtSlot(slot math.Slot) (bytes.B48, error) } StateBackend[BeaconStateT, ForkT any] interface { From 6de3ce726bd550b625dc23f2d3b1c8f1f5debe1c Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Fri, 13 Sep 2024 13:48:59 +0530 Subject: [PATCH 06/27] marshal JSON for header for data type as per beaconAPI Signed-off-by: nidhi-singh02 --- mod/node-api/handlers/beacon/header.go | 4 +- .../handlers/beacon/types/response.go | 48 ++++++++++++++++--- mod/node-api/handlers/beacon/types/types.go | 4 ++ 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/mod/node-api/handlers/beacon/header.go b/mod/node-api/handlers/beacon/header.go index 9cba5a83b5..baebae7ae3 100644 --- a/mod/node-api/handlers/beacon/header.go +++ b/mod/node-api/handlers/beacon/header.go @@ -49,7 +49,7 @@ func (h *Handler[ Data: &beacontypes.BlockHeaderResponse[BeaconBlockHeaderT]{ Root: header.GetBodyRoot(), Canonical: true, - Header: &beacontypes.BlockHeader[BeaconBlockHeaderT]{ + Header: &beacontypes.BlockHeader{ Message: header, Signature: bytes.B48{}, // TODO: implement }, @@ -80,7 +80,7 @@ func (h *Handler[ Data: &beacontypes.BlockHeaderResponse[BeaconBlockHeaderT]{ Root: header.GetBodyRoot(), Canonical: true, - Header: &beacontypes.BlockHeader[BeaconBlockHeaderT]{ + Header: &beacontypes.BlockHeader{ Message: header, Signature: bytes.B48{}, // TODO: implement }, diff --git a/mod/node-api/handlers/beacon/types/response.go b/mod/node-api/handlers/beacon/types/response.go index 9bde230931..dec6e7126a 100644 --- a/mod/node-api/handlers/beacon/types/response.go +++ b/mod/node-api/handlers/beacon/types/response.go @@ -43,14 +43,50 @@ type BlockResponse struct { } type BlockHeaderResponse[BlockHeaderT any] struct { - Root common.Root `json:"root"` - Canonical bool `json:"canonical"` - Header *BlockHeader[BlockHeaderT] `json:"header"` + Root common.Root `json:"root"` + Canonical bool `json:"canonical"` + Header *BlockHeader `json:"header"` } -type BlockHeader[BlockHeaderT any] struct { - Message BlockHeaderT `json:"message"` - Signature bytes.B48 `json:"signature"` +type BlockHeaderHeadResponse struct { + BeaconBlockHeader +} + +// BlockHeader contains the block header details +type BlockHeader struct { + Message BeaconBlockHeader `json:"message"` + Signature bytes.B48 `json:"signature"` +} + +// MarshalJSON implements custom JSON marshaling for BlockHeader +func (bh *BlockHeader) MarshalJSON() ([]byte, error) { + type Alias struct { + Message struct { + Slot string `json:"slot"` + ProposerIndex string `json:"proposer_index"` + ParentRoot common.Root `json:"parent_root"` + StateRoot common.Root `json:"state_root"` + BodyRoot common.Root `json:"body_root"` + } `json:"message"` + Signature bytes.B48 `json:"signature"` + } + + return json.Marshal(&Alias{ + Message: struct { + Slot string `json:"slot"` + ProposerIndex string `json:"proposer_index"` + ParentRoot common.Root `json:"parent_root"` + StateRoot common.Root `json:"state_root"` + BodyRoot common.Root `json:"body_root"` + }{ + Slot: strconv.FormatUint(uint64(bh.Message.GetSlot()), 10), + ProposerIndex: strconv.FormatUint(uint64(bh.Message.GetProposerIndex()), 10), + ParentRoot: bh.Message.GetParentBlockRoot(), + StateRoot: bh.Message.GetStateRoot(), + BodyRoot: bh.Message.GetBodyRoot(), + }, + Signature: bh.Signature, + }) } type GenesisData struct { diff --git a/mod/node-api/handlers/beacon/types/types.go b/mod/node-api/handlers/beacon/types/types.go index 9a70989e29..6728d3cfb3 100644 --- a/mod/node-api/handlers/beacon/types/types.go +++ b/mod/node-api/handlers/beacon/types/types.go @@ -29,6 +29,10 @@ import ( // BeaconBlockHeader is the interface for the beacon block header. type BeaconBlockHeader interface { + GetProposerIndex() math.ValidatorIndex + GetSlot() math.Slot + GetStateRoot() common.Root + GetParentBlockRoot() common.Root GetBodyRoot() common.Root } From b9b4e3feb4bbbbc4731f27a123e7207d091b752b Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Fri, 13 Sep 2024 15:08:22 +0530 Subject: [PATCH 07/27] linter Signed-off-by: nidhi-singh02 --- mod/node-api/handlers/beacon/header.go | 6 +- .../handlers/beacon/types/response.go | 12 +-- testing/e2e/e2e_api_test.go | 75 ++++++++++++------- 3 files changed, 59 insertions(+), 34 deletions(-) diff --git a/mod/node-api/handlers/beacon/header.go b/mod/node-api/handlers/beacon/header.go index baebae7ae3..3857187456 100644 --- a/mod/node-api/handlers/beacon/header.go +++ b/mod/node-api/handlers/beacon/header.go @@ -23,7 +23,7 @@ package beacon import ( beacontypes "github.com/berachain/beacon-kit/mod/node-api/handlers/beacon/types" "github.com/berachain/beacon-kit/mod/node-api/handlers/utils" - "github.com/berachain/beacon-kit/mod/primitives/pkg/bytes" + "github.com/berachain/beacon-kit/mod/primitives/pkg/crypto" ) func (h *Handler[ @@ -51,7 +51,7 @@ func (h *Handler[ Canonical: true, Header: &beacontypes.BlockHeader{ Message: header, - Signature: bytes.B48{}, // TODO: implement + Signature: crypto.BLSSignature{}, // TODO: implement }, }, }, nil @@ -82,7 +82,7 @@ func (h *Handler[ Canonical: true, Header: &beacontypes.BlockHeader{ Message: header, - Signature: bytes.B48{}, // TODO: implement + Signature: crypto.BLSSignature{}, // TODO: implement }, }, }, nil diff --git a/mod/node-api/handlers/beacon/types/response.go b/mod/node-api/handlers/beacon/types/response.go index dec6e7126a..cd531ce07c 100644 --- a/mod/node-api/handlers/beacon/types/response.go +++ b/mod/node-api/handlers/beacon/types/response.go @@ -25,8 +25,8 @@ import ( "encoding/json" "strconv" - "github.com/berachain/beacon-kit/mod/primitives/pkg/bytes" "github.com/berachain/beacon-kit/mod/primitives/pkg/common" + "github.com/berachain/beacon-kit/mod/primitives/pkg/crypto" ) // TODO: change this to a arbitrary response type. types.Wrap(data) should @@ -52,13 +52,13 @@ type BlockHeaderHeadResponse struct { BeaconBlockHeader } -// BlockHeader contains the block header details +// BlockHeader contains the block header details. type BlockHeader struct { - Message BeaconBlockHeader `json:"message"` - Signature bytes.B48 `json:"signature"` + Message BeaconBlockHeader `json:"message"` + Signature crypto.BLSSignature `json:"signature"` } -// MarshalJSON implements custom JSON marshaling for BlockHeader +// MarshalJSON implements custom JSON marshaling for BlockHeader. func (bh *BlockHeader) MarshalJSON() ([]byte, error) { type Alias struct { Message struct { @@ -68,7 +68,7 @@ func (bh *BlockHeader) MarshalJSON() ([]byte, error) { StateRoot common.Root `json:"state_root"` BodyRoot common.Root `json:"body_root"` } `json:"message"` - Signature bytes.B48 `json:"signature"` + Signature crypto.BLSSignature `json:"signature"` } return json.Marshal(&Alias{ diff --git a/testing/e2e/e2e_api_test.go b/testing/e2e/e2e_api_test.go index 7b8b13cbbc..6accb23552 100644 --- a/testing/e2e/e2e_api_test.go +++ b/testing/e2e/e2e_api_test.go @@ -21,6 +21,9 @@ package e2e_test import ( + "encoding/json" + "strconv" + beaconapi "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/spec/phase0" "github.com/berachain/beacon-kit/mod/node-api/handlers/utils" @@ -191,42 +194,64 @@ func (s *BeaconKitE2ESuite) TestBeaconGenesis() { s.Require().NoError(err) s.Require().NotNil(genesisResp) - s.Require().NotZero(genesisResp.Data.GenesisTime, "Genesis time should not be zero") + s.Require().NotZero( + genesisResp.Data.GenesisTime, + "Genesis time should not be zero", + ) - s.Require().NotEmpty(genesisResp.Data.GenesisValidatorsRoot, "Genesis validators root should not be empty") + s.Require().NotEmpty( + genesisResp.Data.GenesisValidatorsRoot, + "Genesis validators root should not be empty", + ) - //s.Require().NotEmpty(genesisResp.Data.GenesisForkVersion, "Genesis fork version should be empty") + // s.Require().NotEmpty( + // genesisResp.Data.GenesisForkVersion, + // "Genesis fork version should be empty", + // ) } func (s *BeaconKitE2ESuite) TestBeaconBlockHeaderByID() { client := s.initBeaconTest() - // Test getting the head block header - headResp, err := client.BeaconBlockHeader(s.Ctx(), &beaconapi.BeaconBlockHeaderOpts{ - Block: "head", - }) + // Test getting the head block header. + headResp, err := client.BeaconBlockHeader( + s.Ctx(), + &beaconapi.BeaconBlockHeaderOpts{ + Block: "head", + }, + ) + + rawJSON, _ := json.MarshalIndent(headResp, "", " ") + s.Logger().Info("Raw JSON response:%s\n", string(rawJSON)) + s.Require().NoError(err) s.Require().NotNil(headResp) s.Require().NotNil(headResp.Data) s.Require().NotEmpty(headResp.Data.Root) s.Require().NotZero(headResp.Data.Header.Message.Slot) - // // Test getting a block header by slot - //slot := headResp.Data.Header.Message.Slot - 1 - //slotResp, err := client.BeaconBlockHeader(s.Ctx(), &beaconapi.BeaconBlockHeaderOpts{ - // Block: strconv.FormatUint(uint64(slot), 10), - //}) - //s.Require().NoError(err) - //s.Require().NotNil(slotResp) - //s.Require().NotNil(slotResp.Data) - //s.Require().Equal(slot, slotResp.Data.Header.Message.Slot) - - // // Test getting a block header by root - // rootResp, err := client.BeaconBlockHeader(s.Ctx(), &beaconapi.BeaconBlockHeaderOpts{ - // Block: "0x" + hex.EncodeToString(headResp.Data.Root[:]), - // }) - // s.Require().NoError(err) - // s.Require().NotNil(rootResp) - // s.Require().NotNil(rootResp.Data) - // s.Require().Equal(headResp.Data.Root, rootResp.Data.Root) + // Test getting a block header by slot. + slot := headResp.Data.Header.Message.Slot - 1 + slotResp, err := client.BeaconBlockHeader( + s.Ctx(), + &beaconapi.BeaconBlockHeaderOpts{ + Block: strconv.FormatUint(uint64(slot), 10), + }, + ) + s.Require().NoError(err) + s.Require().NotNil(slotResp) + s.Require().NotNil(slotResp.Data) + s.Require().Equal(slot, slotResp.Data.Header.Message.Slot) + + // Test getting a block header by root. + // rootResp, err := client.BeaconBlockHeader( + // s.Ctx(), + // &beaconapi.BeaconBlockHeaderOpts{ + // Block: "0x" + hex.EncodeToString(headResp.Data.Root[:]), + // }, + // ) + // s.Require().NoError(err) + // s.Require().NotNil(rootResp) + // s.Require().NotNil(rootResp.Data) + // s.Require().Equal(headResp.Data.Root, rootResp.Data.Root) } From d002de10ef2db51ce34f493c342753257e2bbdaf Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Tue, 17 Sep 2024 13:52:40 +0530 Subject: [PATCH 08/27] headerResponse use generics Signed-off-by: nidhi-singh02 --- mod/node-api/handlers/beacon/header.go | 4 +- .../handlers/beacon/types/response.go | 40 +++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/mod/node-api/handlers/beacon/header.go b/mod/node-api/handlers/beacon/header.go index 82ccba4bba..88f7055f6c 100644 --- a/mod/node-api/handlers/beacon/header.go +++ b/mod/node-api/handlers/beacon/header.go @@ -50,7 +50,7 @@ func (h *Handler[ Canonical: true, Header: &beacontypes.BlockHeader[BeaconBlockHeaderT]{ Message: header, - Signature: bytes.B48{}, // TODO: implement + Signature: crypto.BLSSignature{}, // TODO: implement }, }), nil } @@ -78,7 +78,7 @@ func (h *Handler[ Canonical: true, Header: &beacontypes.BlockHeader[BeaconBlockHeaderT]{ Message: header, - Signature: bytes.B48{}, // TODO: implement + Signature: crypto.BLSSignature{}, // TODO: implement }, }), nil } diff --git a/mod/node-api/handlers/beacon/types/response.go b/mod/node-api/handlers/beacon/types/response.go index f9c3317956..84c6217dec 100644 --- a/mod/node-api/handlers/beacon/types/response.go +++ b/mod/node-api/handlers/beacon/types/response.go @@ -29,25 +29,21 @@ import ( "github.com/berachain/beacon-kit/mod/primitives/pkg/crypto" ) -type BlockHeaderResponse[BlockHeaderT any] struct { - Root common.Root `json:"root"` - Canonical bool `json:"canonical"` - Header *BlockHeader `json:"header"` -} - -type BlockHeaderHeadResponse struct { - BeaconBlockHeader -} - // BlockHeader contains the block header details. -type BlockHeader struct { - Message BeaconBlockHeader `json:"message"` +type BlockHeader[BlockHeaderT BeaconBlockHeader] struct { + Message BlockHeaderT `json:"message"` Signature crypto.BLSSignature `json:"signature"` } +type BlockHeaderResponse[BlockHeaderT BeaconBlockHeader] struct { + Root common.Root `json:"root"` + Canonical bool `json:"canonical"` + Header *BlockHeader[BlockHeaderT] `json:"header"` +} + // MarshalJSON implements custom JSON marshaling for BlockHeader. -func (bh *BlockHeader) MarshalJSON() ([]byte, error) { - type Alias struct { +func (bh *BlockHeader[BlockHeaderT]) MarshalJSON() ([]byte, error) { + type Response struct { Message struct { Slot string `json:"slot"` ProposerIndex string `json:"proposer_index"` @@ -58,7 +54,7 @@ func (bh *BlockHeader) MarshalJSON() ([]byte, error) { Signature crypto.BLSSignature `json:"signature"` } - return json.Marshal(&Alias{ + return json.Marshal(&Response{ Message: struct { Slot string `json:"slot"` ProposerIndex string `json:"proposer_index"` @@ -66,11 +62,15 @@ func (bh *BlockHeader) MarshalJSON() ([]byte, error) { StateRoot common.Root `json:"state_root"` BodyRoot common.Root `json:"body_root"` }{ - Slot: strconv.FormatUint(uint64(bh.Message.GetSlot()), 10), - ProposerIndex: strconv.FormatUint(uint64(bh.Message.GetProposerIndex()), 10), - ParentRoot: bh.Message.GetParentBlockRoot(), - StateRoot: bh.Message.GetStateRoot(), - BodyRoot: bh.Message.GetBodyRoot(), + Slot: strconv.FormatUint( + bh.Message.GetSlot().Unwrap(), 10, + ), + ProposerIndex: strconv.FormatUint( + bh.Message.GetProposerIndex().Unwrap(), 10, + ), + ParentRoot: bh.Message.GetParentBlockRoot(), + StateRoot: bh.Message.GetStateRoot(), + BodyRoot: bh.Message.GetBodyRoot(), }, Signature: bh.Signature, }) From 3eda29b2b4c7413319d0736c58fb82af230ec15a Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Tue, 17 Sep 2024 15:24:51 +0530 Subject: [PATCH 09/27] header error fix Signed-off-by: nidhi-singh02 --- mod/node-api/engines/echo/vaildator.go | 13 ++++++++++--- mod/node-api/handlers/beacon/types/request.go | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/mod/node-api/engines/echo/vaildator.go b/mod/node-api/engines/echo/vaildator.go index 4749154bbc..a691c1d862 100644 --- a/mod/node-api/engines/echo/vaildator.go +++ b/mod/node-api/engines/echo/vaildator.go @@ -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 { @@ -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 @@ -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()) +} diff --git a/mod/node-api/handlers/beacon/types/request.go b/mod/node-api/handlers/beacon/types/request.go index fe64ef0a45..eba1fd6fe6 100644 --- a/mod/node-api/handlers/beacon/types/request.go +++ b/mod/node-api/handlers/beacon/types/request.go @@ -84,7 +84,7 @@ type GetRandaoRequest struct { type GetBlockHeadersRequest struct { SlotRequest - ParentRoot string `query:"parent_root" validate:"hex"` + ParentRoot string `query:"parent_root" validate:"parent_root"` } type GetBlockHeaderRequest struct { From 0345d5c3eae79978b3cda6fb081005448a505ed4 Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Tue, 17 Sep 2024 15:56:06 +0530 Subject: [PATCH 10/27] no input pass in headers- handle default case Signed-off-by: nidhi-singh02 --- mod/node-api/backend/backend.go | 7 ++++++ mod/node-api/backend/types.go | 2 ++ mod/node-api/handlers/beacon/backend.go | 2 ++ mod/node-api/handlers/beacon/header.go | 17 +++++++++++--- mod/node-core/pkg/components/interfaces.go | 5 +++++ mod/storage/pkg/block/store.go | 26 ++++++++++++++++++++++ 6 files changed, 56 insertions(+), 3 deletions(-) diff --git a/mod/node-api/backend/backend.go b/mod/node-api/backend/backend.go index a159003da8..bf5d9713d2 100644 --- a/mod/node-api/backend/backend.go +++ b/mod/node-api/backend/backend.go @@ -206,3 +206,10 @@ func (b *Backend[ } return st, slot, err } + +// GetHeadSlot returns the head slot from the backend. +func (b *Backend[ + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, +]) GetHeadSlot() (math.Slot, error) { + return b.sb.BlockStore().GetHeadSlot() +} diff --git a/mod/node-api/backend/types.go b/mod/node-api/backend/types.go index c6a49488cb..ee37d2a58c 100644 --- a/mod/node-api/backend/types.go +++ b/mod/node-api/backend/types.go @@ -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) + // GetHeadSlot retrieves the head slot by block root. + GetHeadSlot() (math.Slot, error) } // DepositStore defines the interface for deposit storage. diff --git a/mod/node-api/handlers/beacon/backend.go b/mod/node-api/handlers/beacon/backend.go index 7c12d0a0c4..eeec26127b 100644 --- a/mod/node-api/handlers/beacon/backend.go +++ b/mod/node-api/handlers/beacon/backend.go @@ -42,6 +42,8 @@ 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) + // GetHeadSlot retrieves the head slot from the store using block root. + GetHeadSlot() (math.Slot, error) } type GenesisBackend interface { diff --git a/mod/node-api/handlers/beacon/header.go b/mod/node-api/handlers/beacon/header.go index 88f7055f6c..9c40709edd 100644 --- a/mod/node-api/handlers/beacon/header.go +++ b/mod/node-api/handlers/beacon/header.go @@ -25,6 +25,7 @@ import ( "github.com/berachain/beacon-kit/mod/node-api/handlers/types" "github.com/berachain/beacon-kit/mod/node-api/handlers/utils" "github.com/berachain/beacon-kit/mod/primitives/pkg/crypto" + "github.com/berachain/beacon-kit/mod/primitives/pkg/math" ) func (h *Handler[ @@ -36,9 +37,19 @@ func (h *Handler[ if err != nil { return nil, err } - slot, err := utils.U64FromString(req.Slot) - if err != nil { - return nil, err + var slot math.Slot + // If slot is not being passed in the request, + // by default fetch current head slot blocks. + if req.Slot == "" { + slot, err = h.backend.GetHeadSlot() + if err != nil { + return nil, err + } + } else { + slot, err = utils.U64FromString(req.Slot) + if err != nil { + return nil, err + } } header, err := h.backend.BlockHeaderAtSlot(slot) if err != nil { diff --git a/mod/node-core/pkg/components/interfaces.go b/mod/node-core/pkg/components/interfaces.go index 58a5dd2a63..22268d55aa 100644 --- a/mod/node-core/pkg/components/interfaces.go +++ b/mod/node-core/pkg/components/interfaces.go @@ -297,6 +297,8 @@ type ( // number // from the store. GetSlotByExecutionNumber(executionNumber math.U64) (math.Slot, error) + // GetHeadSlot retrieves the head slot by the block root. + GetHeadSlot() (math.Slot, error) } ConsensusEngine interface { @@ -1091,6 +1093,7 @@ type ( GetSlotByBlockRoot(root common.Root) (math.Slot, error) GetSlotByStateRoot(root common.Root) (math.Slot, error) GetSlotByExecutionNumber(executionNumber math.U64) (math.Slot, error) + GetHeadSlot() (math.Slot, error) NodeAPIBeaconBackend[ BeaconStateT, BeaconBlockHeaderT, ForkT, ValidatorT, @@ -1115,6 +1118,8 @@ type ( 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) + // GetHeadSlot retrieves the head slot from the store. + GetHeadSlot() (math.Slot, error) } // NodeAPIProofBackend is the interface for backend of the proof API. diff --git a/mod/storage/pkg/block/store.go b/mod/storage/pkg/block/store.go index 3e1c069ec9..f43ebc1992 100644 --- a/mod/storage/pkg/block/store.go +++ b/mod/storage/pkg/block/store.go @@ -111,3 +111,29 @@ func (kv *KVStore[BeaconBlockT]) GetSlotByStateRoot( } return slot, nil } + +// GetHeadSlot retrieves the head slot. +// TODO: This is very hoody way to get the the current slot, optimize it. +func (kv *KVStore[BeaconBlockT]) GetHeadSlot() (math.Slot, error) { + keys := kv.blockRoots.Keys() + if len(keys) == 0 { + return 0, fmt.Errorf("no blocks in the store") + } + + var maxSlot math.Slot + for _, key := range keys { + slot, ok := kv.blockRoots.Peek(key) + if !ok { + continue + } + if slot > maxSlot { + maxSlot = slot + } + } + + if maxSlot == 0 { + return 0, fmt.Errorf("no valid slots found") + } + + return maxSlot, nil +} From d0cd3815126b524b92d710bf72ae05fce8c9a63c Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Tue, 17 Sep 2024 16:08:09 +0530 Subject: [PATCH 11/27] optimized way of getting lastest slot Signed-off-by: nidhi-singh02 --- mod/storage/pkg/block/store.go | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/mod/storage/pkg/block/store.go b/mod/storage/pkg/block/store.go index f43ebc1992..65452d8e64 100644 --- a/mod/storage/pkg/block/store.go +++ b/mod/storage/pkg/block/store.go @@ -35,8 +35,8 @@ type KVStore[BeaconBlockT BeaconBlock] struct { blockRoots *lru.Cache[common.Root, math.Slot] executionNumbers *lru.Cache[math.U64, math.Slot] stateRoots *lru.Cache[common.Root, math.Slot] - - logger log.Logger + headSlot math.Slot + logger log.Logger } // NewStore creates a new block store. @@ -65,13 +65,17 @@ func NewStore[BeaconBlockT BeaconBlock]( } // Set sets the block by a given index in the store, storing the block root, -// execution number, and state root. Only this function may potentially evict +// execution number, state root and head slot. Only this function may potentially evict // entries from the store if the availability window is reached. func (kv *KVStore[BeaconBlockT]) Set(blk BeaconBlockT) error { slot := blk.GetSlot() kv.blockRoots.Add(blk.HashTreeRoot(), slot) kv.executionNumbers.Add(blk.GetExecutionNumber(), slot) kv.stateRoots.Add(blk.GetStateRoot(), slot) + // Update head slot if this is a new head + if slot > kv.headSlot { + kv.headSlot = slot + } return nil } @@ -113,27 +117,9 @@ func (kv *KVStore[BeaconBlockT]) GetSlotByStateRoot( } // GetHeadSlot retrieves the head slot. -// TODO: This is very hoody way to get the the current slot, optimize it. func (kv *KVStore[BeaconBlockT]) GetHeadSlot() (math.Slot, error) { - keys := kv.blockRoots.Keys() - if len(keys) == 0 { + if kv.headSlot == 0 { return 0, fmt.Errorf("no blocks in the store") } - - var maxSlot math.Slot - for _, key := range keys { - slot, ok := kv.blockRoots.Peek(key) - if !ok { - continue - } - if slot > maxSlot { - maxSlot = slot - } - } - - if maxSlot == 0 { - return 0, fmt.Errorf("no valid slots found") - } - - return maxSlot, nil + return kv.headSlot, nil } From 5bdcdc458dd5671ad88f38cb89ff4e5d0d19a0b6 Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Tue, 17 Sep 2024 16:10:23 +0530 Subject: [PATCH 12/27] generateee Signed-off-by: nidhi-singh02 --- .../backend/mocks/block_store.mock.go | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/mod/node-api/backend/mocks/block_store.mock.go b/mod/node-api/backend/mocks/block_store.mock.go index 1a0bf79276..30929cbb1a 100644 --- a/mod/node-api/backend/mocks/block_store.mock.go +++ b/mod/node-api/backend/mocks/block_store.mock.go @@ -22,6 +22,61 @@ func (_m *BlockStore[BeaconBlockT]) EXPECT() *BlockStore_Expecter[BeaconBlockT] return &BlockStore_Expecter[BeaconBlockT]{mock: &_m.Mock} } +// GetHeadSlot provides a mock function with given fields: +func (_m *BlockStore[BeaconBlockT]) GetHeadSlot() (math.U64, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetHeadSlot") + } + + var r0 math.U64 + var r1 error + if rf, ok := ret.Get(0).(func() (math.U64, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() math.U64); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(math.U64) + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// BlockStore_GetHeadSlot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetHeadSlot' +type BlockStore_GetHeadSlot_Call[BeaconBlockT interface{}] struct { + *mock.Call +} + +// GetHeadSlot is a helper method to define mock.On call +func (_e *BlockStore_Expecter[BeaconBlockT]) GetHeadSlot() *BlockStore_GetHeadSlot_Call[BeaconBlockT] { + return &BlockStore_GetHeadSlot_Call[BeaconBlockT]{Call: _e.mock.On("GetHeadSlot")} +} + +func (_c *BlockStore_GetHeadSlot_Call[BeaconBlockT]) Run(run func()) *BlockStore_GetHeadSlot_Call[BeaconBlockT] { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *BlockStore_GetHeadSlot_Call[BeaconBlockT]) Return(_a0 math.U64, _a1 error) *BlockStore_GetHeadSlot_Call[BeaconBlockT] { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *BlockStore_GetHeadSlot_Call[BeaconBlockT]) RunAndReturn(run func() (math.U64, error)) *BlockStore_GetHeadSlot_Call[BeaconBlockT] { + _c.Call.Return(run) + return _c +} + // GetSlotByBlockRoot provides a mock function with given fields: root func (_m *BlockStore[BeaconBlockT]) GetSlotByBlockRoot(root common.Root) (math.U64, error) { ret := _m.Called(root) From 19ffaeceb89cfc432acc40c40fd83449098d8534 Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Tue, 17 Sep 2024 16:24:52 +0530 Subject: [PATCH 13/27] linting Signed-off-by: nidhi-singh02 --- mod/storage/pkg/block/store.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mod/storage/pkg/block/store.go b/mod/storage/pkg/block/store.go index 65452d8e64..158641b872 100644 --- a/mod/storage/pkg/block/store.go +++ b/mod/storage/pkg/block/store.go @@ -23,6 +23,7 @@ package block import ( "fmt" + "github.com/berachain/beacon-kit/mod/errors" "github.com/berachain/beacon-kit/mod/log" "github.com/berachain/beacon-kit/mod/primitives/pkg/common" "github.com/berachain/beacon-kit/mod/primitives/pkg/math" @@ -65,8 +66,9 @@ func NewStore[BeaconBlockT BeaconBlock]( } // Set sets the block by a given index in the store, storing the block root, -// execution number, state root and head slot. Only this function may potentially evict -// entries from the store if the availability window is reached. +// execution number, state root and head slot. Only this function may +// potentially evict entries from the store if +// the availability window is reached. func (kv *KVStore[BeaconBlockT]) Set(blk BeaconBlockT) error { slot := blk.GetSlot() kv.blockRoots.Add(blk.HashTreeRoot(), slot) @@ -79,7 +81,7 @@ func (kv *KVStore[BeaconBlockT]) Set(blk BeaconBlockT) error { return nil } -// GetSlotByRoot retrieves the slot by a given block root from the store. +// GetSlotByBlockRoot retrieves the slot by a given block root from the store. func (kv *KVStore[BeaconBlockT]) GetSlotByBlockRoot( blockRoot common.Root, ) (math.Slot, error) { @@ -119,7 +121,7 @@ func (kv *KVStore[BeaconBlockT]) GetSlotByStateRoot( // GetHeadSlot retrieves the head slot. func (kv *KVStore[BeaconBlockT]) GetHeadSlot() (math.Slot, error) { if kv.headSlot == 0 { - return 0, fmt.Errorf("no blocks in the store") + return 0, errors.New("head slot not found: store may be empty") } return kv.headSlot, nil } From 6ee4886f71a8be33bc46dc224f68696367026432 Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Wed, 18 Sep 2024 14:05:15 +0530 Subject: [PATCH 14/27] using state for getting slot - do not change kvstore Signed-off-by: nidhi-singh02 --- mod/node-api/backend/backend.go | 8 +++++++- mod/node-api/backend/types.go | 2 -- mod/node-core/pkg/components/interfaces.go | 4 +--- mod/storage/pkg/block/store.go | 15 +-------------- 4 files changed, 9 insertions(+), 20 deletions(-) diff --git a/mod/node-api/backend/backend.go b/mod/node-api/backend/backend.go index bf5d9713d2..469153c319 100644 --- a/mod/node-api/backend/backend.go +++ b/mod/node-api/backend/backend.go @@ -211,5 +211,11 @@ func (b *Backend[ func (b *Backend[ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, ]) GetHeadSlot() (math.Slot, error) { - return b.sb.BlockStore().GetHeadSlot() + //#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() } diff --git a/mod/node-api/backend/types.go b/mod/node-api/backend/types.go index ee37d2a58c..c6a49488cb 100644 --- a/mod/node-api/backend/types.go +++ b/mod/node-api/backend/types.go @@ -86,8 +86,6 @@ 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) - // GetHeadSlot retrieves the head slot by block root. - GetHeadSlot() (math.Slot, error) } // DepositStore defines the interface for deposit storage. diff --git a/mod/node-core/pkg/components/interfaces.go b/mod/node-core/pkg/components/interfaces.go index 22268d55aa..76693ec49c 100644 --- a/mod/node-core/pkg/components/interfaces.go +++ b/mod/node-core/pkg/components/interfaces.go @@ -297,8 +297,6 @@ type ( // number // from the store. GetSlotByExecutionNumber(executionNumber math.U64) (math.Slot, error) - // GetHeadSlot retrieves the head slot by the block root. - GetHeadSlot() (math.Slot, error) } ConsensusEngine interface { @@ -1103,7 +1101,7 @@ type ( ] } - // NodeAPIBackend is the interface for backend of the beacon API. + // NodeAPIBeaconBackend is the interface for backend of the beacon API. NodeAPIBeaconBackend[ BeaconStateT, BeaconBlockHeaderT, ForkT any, ValidatorT types.Validator, diff --git a/mod/storage/pkg/block/store.go b/mod/storage/pkg/block/store.go index 158641b872..5ba2e67c7c 100644 --- a/mod/storage/pkg/block/store.go +++ b/mod/storage/pkg/block/store.go @@ -23,7 +23,6 @@ package block import ( "fmt" - "github.com/berachain/beacon-kit/mod/errors" "github.com/berachain/beacon-kit/mod/log" "github.com/berachain/beacon-kit/mod/primitives/pkg/common" "github.com/berachain/beacon-kit/mod/primitives/pkg/math" @@ -36,7 +35,6 @@ type KVStore[BeaconBlockT BeaconBlock] struct { blockRoots *lru.Cache[common.Root, math.Slot] executionNumbers *lru.Cache[math.U64, math.Slot] stateRoots *lru.Cache[common.Root, math.Slot] - headSlot math.Slot logger log.Logger } @@ -74,10 +72,7 @@ func (kv *KVStore[BeaconBlockT]) Set(blk BeaconBlockT) error { kv.blockRoots.Add(blk.HashTreeRoot(), slot) kv.executionNumbers.Add(blk.GetExecutionNumber(), slot) kv.stateRoots.Add(blk.GetStateRoot(), slot) - // Update head slot if this is a new head - if slot > kv.headSlot { - kv.headSlot = slot - } + return nil } @@ -117,11 +112,3 @@ func (kv *KVStore[BeaconBlockT]) GetSlotByStateRoot( } return slot, nil } - -// GetHeadSlot retrieves the head slot. -func (kv *KVStore[BeaconBlockT]) GetHeadSlot() (math.Slot, error) { - if kv.headSlot == 0 { - return 0, errors.New("head slot not found: store may be empty") - } - return kv.headSlot, nil -} From 0ab10a24ef28cae310f05b20893c2e139b063533 Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Wed, 18 Sep 2024 14:12:58 +0530 Subject: [PATCH 15/27] generate Signed-off-by: nidhi-singh02 --- .../backend/mocks/block_store.mock.go | 55 ------------------- mod/node-api/handlers/beacon/backend.go | 2 +- mod/storage/pkg/block/store.go | 9 ++- 3 files changed, 5 insertions(+), 61 deletions(-) diff --git a/mod/node-api/backend/mocks/block_store.mock.go b/mod/node-api/backend/mocks/block_store.mock.go index 30929cbb1a..1a0bf79276 100644 --- a/mod/node-api/backend/mocks/block_store.mock.go +++ b/mod/node-api/backend/mocks/block_store.mock.go @@ -22,61 +22,6 @@ func (_m *BlockStore[BeaconBlockT]) EXPECT() *BlockStore_Expecter[BeaconBlockT] return &BlockStore_Expecter[BeaconBlockT]{mock: &_m.Mock} } -// GetHeadSlot provides a mock function with given fields: -func (_m *BlockStore[BeaconBlockT]) GetHeadSlot() (math.U64, error) { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for GetHeadSlot") - } - - var r0 math.U64 - var r1 error - if rf, ok := ret.Get(0).(func() (math.U64, error)); ok { - return rf() - } - if rf, ok := ret.Get(0).(func() math.U64); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(math.U64) - } - - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// BlockStore_GetHeadSlot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetHeadSlot' -type BlockStore_GetHeadSlot_Call[BeaconBlockT interface{}] struct { - *mock.Call -} - -// GetHeadSlot is a helper method to define mock.On call -func (_e *BlockStore_Expecter[BeaconBlockT]) GetHeadSlot() *BlockStore_GetHeadSlot_Call[BeaconBlockT] { - return &BlockStore_GetHeadSlot_Call[BeaconBlockT]{Call: _e.mock.On("GetHeadSlot")} -} - -func (_c *BlockStore_GetHeadSlot_Call[BeaconBlockT]) Run(run func()) *BlockStore_GetHeadSlot_Call[BeaconBlockT] { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *BlockStore_GetHeadSlot_Call[BeaconBlockT]) Return(_a0 math.U64, _a1 error) *BlockStore_GetHeadSlot_Call[BeaconBlockT] { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *BlockStore_GetHeadSlot_Call[BeaconBlockT]) RunAndReturn(run func() (math.U64, error)) *BlockStore_GetHeadSlot_Call[BeaconBlockT] { - _c.Call.Return(run) - return _c -} - // GetSlotByBlockRoot provides a mock function with given fields: root func (_m *BlockStore[BeaconBlockT]) GetSlotByBlockRoot(root common.Root) (math.U64, error) { ret := _m.Called(root) diff --git a/mod/node-api/handlers/beacon/backend.go b/mod/node-api/handlers/beacon/backend.go index eeec26127b..f4d7510718 100644 --- a/mod/node-api/handlers/beacon/backend.go +++ b/mod/node-api/handlers/beacon/backend.go @@ -42,7 +42,7 @@ 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) - // GetHeadSlot retrieves the head slot from the store using block root. + // GetHeadSlot retrieves the head slot from the store. GetHeadSlot() (math.Slot, error) } diff --git a/mod/storage/pkg/block/store.go b/mod/storage/pkg/block/store.go index 5ba2e67c7c..c266705d1b 100644 --- a/mod/storage/pkg/block/store.go +++ b/mod/storage/pkg/block/store.go @@ -35,7 +35,8 @@ type KVStore[BeaconBlockT BeaconBlock] struct { blockRoots *lru.Cache[common.Root, math.Slot] executionNumbers *lru.Cache[math.U64, math.Slot] stateRoots *lru.Cache[common.Root, math.Slot] - logger log.Logger + + logger log.Logger } // NewStore creates a new block store. @@ -64,15 +65,13 @@ func NewStore[BeaconBlockT BeaconBlock]( } // Set sets the block by a given index in the store, storing the block root, -// execution number, state root and head slot. Only this function may -// potentially evict entries from the store if -// the availability window is reached. +// execution number, and state root. Only this function may potentially evict +// entries from the store if the availability window is reached. func (kv *KVStore[BeaconBlockT]) Set(blk BeaconBlockT) error { slot := blk.GetSlot() kv.blockRoots.Add(blk.HashTreeRoot(), slot) kv.executionNumbers.Add(blk.GetExecutionNumber(), slot) kv.stateRoots.Add(blk.GetStateRoot(), slot) - return nil } From 7266db753a6d3210ad83867680e970a9ff3ce0ce Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Wed, 18 Sep 2024 14:38:34 +0530 Subject: [PATCH 16/27] header response JSON - same pattern Signed-off-by: nidhi-singh02 --- .../handlers/beacon/types/response.go | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/mod/node-api/handlers/beacon/types/response.go b/mod/node-api/handlers/beacon/types/response.go index 522f748f41..ec3038e9de 100644 --- a/mod/node-api/handlers/beacon/types/response.go +++ b/mod/node-api/handlers/beacon/types/response.go @@ -29,39 +29,37 @@ import ( "github.com/berachain/beacon-kit/mod/primitives/pkg/crypto" ) -// BlockHeader contains the block header details. +// BlockHeader contains the block header details +// that resides in BlockHeaderResponse. type BlockHeader[BlockHeaderT BeaconBlockHeader] struct { Message BlockHeaderT `json:"message"` Signature crypto.BLSSignature `json:"signature"` } +// BlockHeaderResponse contains the block header response for the Beacon API. type BlockHeaderResponse[BlockHeaderT BeaconBlockHeader] struct { Root common.Root `json:"root"` Canonical bool `json:"canonical"` Header *BlockHeader[BlockHeaderT] `json:"header"` } +type messageJSON struct { + Slot string `json:"slot"` + ProposerIndex string `json:"proposer_index"` + ParentRoot common.Root `json:"parent_root"` + StateRoot common.Root `json:"state_root"` + BodyRoot common.Root `json:"body_root"` +} + +type blockHeaderResponseJSON struct { + Message messageJSON `json:"message"` + Signature crypto.BLSSignature `json:"signature"` +} + // MarshalJSON implements custom JSON marshaling for BlockHeader. func (bh *BlockHeader[BlockHeaderT]) MarshalJSON() ([]byte, error) { - type Response struct { - Message struct { - Slot string `json:"slot"` - ProposerIndex string `json:"proposer_index"` - ParentRoot common.Root `json:"parent_root"` - StateRoot common.Root `json:"state_root"` - BodyRoot common.Root `json:"body_root"` - } `json:"message"` - Signature crypto.BLSSignature `json:"signature"` - } - - return json.Marshal(&Response{ - Message: struct { - Slot string `json:"slot"` - ProposerIndex string `json:"proposer_index"` - ParentRoot common.Root `json:"parent_root"` - StateRoot common.Root `json:"state_root"` - BodyRoot common.Root `json:"body_root"` - }{ + return json.Marshal(&blockHeaderResponseJSON{ + Message: messageJSON{ Slot: strconv.FormatUint( bh.Message.GetSlot().Unwrap(), 10, ), From ae3b6b9c980abf6e5cc68bbdd67c7aef2b82c575 Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Wed, 18 Sep 2024 15:49:19 +0530 Subject: [PATCH 17/27] add more tests for beaconheader by ID Signed-off-by: nidhi-singh02 --- testing/e2e/e2e_api_test.go | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/testing/e2e/e2e_api_test.go b/testing/e2e/e2e_api_test.go index 4e97887682..287378f0e4 100644 --- a/testing/e2e/e2e_api_test.go +++ b/testing/e2e/e2e_api_test.go @@ -21,7 +21,6 @@ package e2e_test import ( - "encoding/json" "strconv" beaconapi "github.com/attestantio/go-eth2-client/api" @@ -228,6 +227,22 @@ func (s *BeaconKitE2ESuite) TestBeaconGenesis() { func (s *BeaconKitE2ESuite) TestBeaconBlockHeaderByID() { client := s.initBeaconTest() + // Test getting the genesis block header. + genesisResp, err := client.BeaconBlockHeader( + s.Ctx(), + &beaconapi.BeaconBlockHeaderOpts{ + Block: "genesis", + }, + ) + + s.Require().NoError(err) + s.Require().NotNil(genesisResp) + s.Require().NotNil(genesisResp.Data) + s.Require().NotZero(genesisResp.Data.Root) + s.Require().NotZero(genesisResp.Data.Header.Message.Slot) + // Check slot to be equal than 1 + s.Require().Equal(genesisResp.Data.Header.Message.Slot, uint64(1)) + // Test getting the head block header. headResp, err := client.BeaconBlockHeader( s.Ctx(), @@ -236,14 +251,13 @@ func (s *BeaconKitE2ESuite) TestBeaconBlockHeaderByID() { }, ) - rawJSON, _ := json.MarshalIndent(headResp, "", " ") - s.Logger().Info("Raw JSON response:%s\n", string(rawJSON)) - s.Require().NoError(err) s.Require().NotNil(headResp) s.Require().NotNil(headResp.Data) - s.Require().NotEmpty(headResp.Data.Root) + s.Require().NotZero(headResp.Data.Root) s.Require().NotZero(headResp.Data.Header.Message.Slot) + // Check slot to be greater than 1 + s.Require().Greater(headResp.Data.Header.Message.Slot, uint64(1)) // Test getting a block header by slot. slot := headResp.Data.Header.Message.Slot - 1 @@ -256,6 +270,7 @@ func (s *BeaconKitE2ESuite) TestBeaconBlockHeaderByID() { s.Require().NoError(err) s.Require().NotNil(slotResp) s.Require().NotNil(slotResp.Data) + s.Require().NotZero(slotResp.Data.Root) s.Require().Equal(slot, slotResp.Data.Header.Message.Slot) // Test getting a block header by root. From 9942f764eb1751db161eae846097d95dc331a1dd Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Wed, 18 Sep 2024 18:11:51 +0530 Subject: [PATCH 18/27] tests correct assert Signed-off-by: nidhi-singh02 --- testing/e2e/e2e_api_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testing/e2e/e2e_api_test.go b/testing/e2e/e2e_api_test.go index 287378f0e4..daa678dcf6 100644 --- a/testing/e2e/e2e_api_test.go +++ b/testing/e2e/e2e_api_test.go @@ -241,7 +241,7 @@ func (s *BeaconKitE2ESuite) TestBeaconBlockHeaderByID() { s.Require().NotZero(genesisResp.Data.Root) s.Require().NotZero(genesisResp.Data.Header.Message.Slot) // Check slot to be equal than 1 - s.Require().Equal(genesisResp.Data.Header.Message.Slot, uint64(1)) + s.Require().Equal(uint64(1), uint64(genesisResp.Data.Header.Message.Slot)) // Test getting the head block header. headResp, err := client.BeaconBlockHeader( @@ -257,7 +257,7 @@ func (s *BeaconKitE2ESuite) TestBeaconBlockHeaderByID() { s.Require().NotZero(headResp.Data.Root) s.Require().NotZero(headResp.Data.Header.Message.Slot) // Check slot to be greater than 1 - s.Require().Greater(headResp.Data.Header.Message.Slot, uint64(1)) + s.Require().Greater(uint64(headResp.Data.Header.Message.Slot), uint64(1)) // Test getting a block header by slot. slot := headResp.Data.Header.Message.Slot - 1 @@ -271,7 +271,7 @@ func (s *BeaconKitE2ESuite) TestBeaconBlockHeaderByID() { s.Require().NotNil(slotResp) s.Require().NotNil(slotResp.Data) s.Require().NotZero(slotResp.Data.Root) - s.Require().Equal(slot, slotResp.Data.Header.Message.Slot) + s.Require().Equal(uint64(slot), uint64(slotResp.Data.Header.Message.Slot)) // Test getting a block header by root. // rootResp, err := client.BeaconBlockHeader( From 101d10ba1144db7ffbf3c5c326d941d77433b7d8 Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Thu, 19 Sep 2024 12:52:07 +0530 Subject: [PATCH 19/27] fix error for root - use correct root Signed-off-by: nidhi-singh02 --- mod/node-api/backend/block.go | 5 +++-- mod/node-api/handlers/beacon/header.go | 8 ++++++-- testing/e2e/e2e_api_test.go | 23 ++++++++++++----------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/mod/node-api/backend/block.go b/mod/node-api/backend/block.go index c6087cc989..59df7e56ee 100644 --- a/mod/node-api/backend/block.go +++ b/mod/node-api/backend/block.go @@ -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, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, @@ -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) { @@ -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[ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, diff --git a/mod/node-api/handlers/beacon/header.go b/mod/node-api/handlers/beacon/header.go index 9c40709edd..80626cd67f 100644 --- a/mod/node-api/handlers/beacon/header.go +++ b/mod/node-api/handlers/beacon/header.go @@ -39,7 +39,7 @@ func (h *Handler[ } var slot math.Slot // If slot is not being passed in the request, - // by default fetch current head slot blocks. + // by default fetch current head slot. Else use the slot from the request. if req.Slot == "" { slot, err = h.backend.GetHeadSlot() if err != nil { @@ -84,8 +84,12 @@ func (h *Handler[ return nil, err } + root, err := h.backend.BlockRootAtSlot(slot) + if err != nil { + return nil, err + } return types.Wrap(&beacontypes.BlockHeaderResponse[BeaconBlockHeaderT]{ - Root: header.GetBodyRoot(), + Root: root, // This is root hash of entire beacon block. Canonical: true, Header: &beacontypes.BlockHeader[BeaconBlockHeaderT]{ Message: header, diff --git a/testing/e2e/e2e_api_test.go b/testing/e2e/e2e_api_test.go index daa678dcf6..9950f2f02e 100644 --- a/testing/e2e/e2e_api_test.go +++ b/testing/e2e/e2e_api_test.go @@ -21,6 +21,7 @@ package e2e_test import ( + "encoding/hex" "strconv" beaconapi "github.com/attestantio/go-eth2-client/api" @@ -273,15 +274,15 @@ func (s *BeaconKitE2ESuite) TestBeaconBlockHeaderByID() { s.Require().NotZero(slotResp.Data.Root) s.Require().Equal(uint64(slot), uint64(slotResp.Data.Header.Message.Slot)) - // Test getting a block header by root. - // rootResp, err := client.BeaconBlockHeader( - // s.Ctx(), - // &beaconapi.BeaconBlockHeaderOpts{ - // Block: "0x" + hex.EncodeToString(headResp.Data.Root[:]), - // }, - // ) - // s.Require().NoError(err) - // s.Require().NotNil(rootResp) - // s.Require().NotNil(rootResp.Data) - // s.Require().Equal(headResp.Data.Root, rootResp.Data.Root) + // Test getting a block header by block root. + rootResp, err := client.BeaconBlockHeader( + s.Ctx(), + &beaconapi.BeaconBlockHeaderOpts{ + Block: "0x" + hex.EncodeToString(headResp.Data.Root[:]), + }, + ) + s.Require().NoError(err) + s.Require().NotNil(rootResp) + s.Require().NotNil(rootResp.Data) + s.Require().Equal(headResp.Data.Root, rootResp.Data.Root) } From 957620d2f45a22da0ee732efb424ade8e6a0ba10 Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Thu, 19 Sep 2024 14:08:46 +0530 Subject: [PATCH 20/27] implemented fork version at genesis Signed-off-by: nidhi-singh02 --- mod/node-api/backend/backend.go | 8 ++++---- mod/node-api/backend/genesis.go | 15 +++++++++++++++ mod/node-api/backend/types.go | 4 ++++ mod/node-api/handlers/beacon/backend.go | 1 + mod/node-api/handlers/beacon/genesis.go | 9 ++++++++- mod/node-core/pkg/components/interfaces.go | 1 + testing/e2e/e2e_api_test.go | 15 +++++++++++---- 7 files changed, 44 insertions(+), 9 deletions(-) diff --git a/mod/node-api/backend/backend.go b/mod/node-api/backend/backend.go index 469153c319..2b415ace36 100644 --- a/mod/node-api/backend/backend.go +++ b/mod/node-api/backend/backend.go @@ -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[ @@ -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[ diff --git a/mod/node-api/backend/genesis.go b/mod/node-api/backend/genesis.go index 66aeaf5247..5f42455dfa 100644 --- a/mod/node-api/backend/genesis.go +++ b/mod/node-api/backend/genesis.go @@ -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 +} diff --git a/mod/node-api/backend/types.go b/mod/node-api/backend/types.go index c6a49488cb..f62d9391c5 100644 --- a/mod/node-api/backend/types.go +++ b/mod/node-api/backend/types.go @@ -140,3 +140,7 @@ type Withdrawal[T any] interface { amount math.Gwei, ) T } + +type Fork[ForkT any] interface { + GetPreviousVersion() common.Version +} diff --git a/mod/node-api/handlers/beacon/backend.go b/mod/node-api/handlers/beacon/backend.go index f4d7510718..c1394b7de8 100644 --- a/mod/node-api/handlers/beacon/backend.go +++ b/mod/node-api/handlers/beacon/backend.go @@ -48,6 +48,7 @@ type Backend[ type GenesisBackend interface { GenesisValidatorsRoot(slot math.Slot) (common.Root, error) + GetGenesisForkVersion(genesisSlot math.Slot) (common.Version, error) } type HistoricalBackend[ForkT any] interface { diff --git a/mod/node-api/handlers/beacon/genesis.go b/mod/node-api/handlers/beacon/genesis.go index 1566eaaec9..057181d439 100644 --- a/mod/node-api/handlers/beacon/genesis.go +++ b/mod/node-api/handlers/beacon/genesis.go @@ -21,6 +21,7 @@ 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" @@ -34,9 +35,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 } diff --git a/mod/node-core/pkg/components/interfaces.go b/mod/node-core/pkg/components/interfaces.go index 76693ec49c..59c2322df2 100644 --- a/mod/node-core/pkg/components/interfaces.go +++ b/mod/node-core/pkg/components/interfaces.go @@ -1131,6 +1131,7 @@ type ( GenesisBackend interface { GenesisValidatorsRoot(slot math.Slot) (common.Root, error) + GetGenesisForkVersion(genesisSlot math.Slot) (common.Version, error) } HistoricalBackend[ForkT any] interface { diff --git a/testing/e2e/e2e_api_test.go b/testing/e2e/e2e_api_test.go index 9950f2f02e..ee8ed3740a 100644 --- a/testing/e2e/e2e_api_test.go +++ b/testing/e2e/e2e_api_test.go @@ -219,10 +219,17 @@ func (s *BeaconKitE2ESuite) TestBeaconGenesis() { "Genesis validators root should not be empty", ) - // s.Require().NotEmpty( - // genesisResp.Data.GenesisForkVersion, - // "Genesis fork version should be empty", - // ) + s.Require().NotEmpty( + genesisResp.Data.GenesisForkVersion, + "Genesis fork version should be empty", + ) + + expectedVersion := phase0.Version{0x04, 0x00, 0x00, 0x00} + s.Require().Equal( + expectedVersion, + genesisResp.Data.GenesisForkVersion, + "Genesis fork version does not match expected value", + ) } func (s *BeaconKitE2ESuite) TestBeaconBlockHeaderByID() { From 72f7f35901a0863e71235ad3fb79eeb055ab8cd0 Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Thu, 19 Sep 2024 14:37:08 +0530 Subject: [PATCH 21/27] mock for fork interface Signed-off-by: nidhi-singh02 --- mod/node-api/backend/mocks/fork.mock.go | 82 +++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 mod/node-api/backend/mocks/fork.mock.go diff --git a/mod/node-api/backend/mocks/fork.mock.go b/mod/node-api/backend/mocks/fork.mock.go new file mode 100644 index 0000000000..e5bb60c83d --- /dev/null +++ b/mod/node-api/backend/mocks/fork.mock.go @@ -0,0 +1,82 @@ +// Code generated by mockery v2.46.0. DO NOT EDIT. + +package mocks + +import ( + bytes "github.com/berachain/beacon-kit/mod/primitives/pkg/bytes" + mock "github.com/stretchr/testify/mock" +) + +// Fork is an autogenerated mock type for the Fork type +type Fork[ForkT interface{}] struct { + mock.Mock +} + +type Fork_Expecter[ForkT interface{}] struct { + mock *mock.Mock +} + +func (_m *Fork[ForkT]) EXPECT() *Fork_Expecter[ForkT] { + return &Fork_Expecter[ForkT]{mock: &_m.Mock} +} + +// GetPreviousVersion provides a mock function with given fields: +func (_m *Fork[ForkT]) GetPreviousVersion() bytes.B4 { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetPreviousVersion") + } + + var r0 bytes.B4 + if rf, ok := ret.Get(0).(func() bytes.B4); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(bytes.B4) + } + } + + return r0 +} + +// Fork_GetPreviousVersion_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPreviousVersion' +type Fork_GetPreviousVersion_Call[ForkT interface{}] struct { + *mock.Call +} + +// GetPreviousVersion is a helper method to define mock.On call +func (_e *Fork_Expecter[ForkT]) GetPreviousVersion() *Fork_GetPreviousVersion_Call[ForkT] { + return &Fork_GetPreviousVersion_Call[ForkT]{Call: _e.mock.On("GetPreviousVersion")} +} + +func (_c *Fork_GetPreviousVersion_Call[ForkT]) Run(run func()) *Fork_GetPreviousVersion_Call[ForkT] { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *Fork_GetPreviousVersion_Call[ForkT]) Return(_a0 bytes.B4) *Fork_GetPreviousVersion_Call[ForkT] { + _c.Call.Return(_a0) + return _c +} + +func (_c *Fork_GetPreviousVersion_Call[ForkT]) RunAndReturn(run func() bytes.B4) *Fork_GetPreviousVersion_Call[ForkT] { + _c.Call.Return(run) + return _c +} + +// NewFork creates a new instance of Fork. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewFork[ForkT interface{}](t interface { + mock.TestingT + Cleanup(func()) +}) *Fork[ForkT] { + mock := &Fork[ForkT]{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} From 7369817d0539a05d98759e9553cabfd6325f351e Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Thu, 19 Sep 2024 15:21:30 +0530 Subject: [PATCH 22/27] omg linter why you do that? Signed-off-by: nidhi-singh02 --- mod/node-api/handlers/beacon/genesis.go | 1 + 1 file changed, 1 insertion(+) diff --git a/mod/node-api/handlers/beacon/genesis.go b/mod/node-api/handlers/beacon/genesis.go index 057181d439..52d74895e9 100644 --- a/mod/node-api/handlers/beacon/genesis.go +++ b/mod/node-api/handlers/beacon/genesis.go @@ -22,6 +22,7 @@ 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" From bca471fa434a72ebba807e09d9447c7785247cbf Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Fri, 20 Sep 2024 12:08:11 +0530 Subject: [PATCH 23/27] return correct root and query no key passed handle Signed-off-by: nidhi-singh02 --- mod/node-api/handlers/beacon/header.go | 33 +++++++++++++++++++++----- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/mod/node-api/handlers/beacon/header.go b/mod/node-api/handlers/beacon/header.go index 80626cd67f..f3ba11b6d1 100644 --- a/mod/node-api/handlers/beacon/header.go +++ b/mod/node-api/handlers/beacon/header.go @@ -21,9 +21,11 @@ package beacon import ( + "github.com/berachain/beacon-kit/mod/errors" 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" + "github.com/berachain/beacon-kit/mod/primitives/pkg/common" "github.com/berachain/beacon-kit/mod/primitives/pkg/crypto" "github.com/berachain/beacon-kit/mod/primitives/pkg/math" ) @@ -38,15 +40,29 @@ func (h *Handler[ return nil, err } var slot math.Slot - // If slot is not being passed in the request, - // by default fetch current head slot. Else use the slot from the request. - if req.Slot == "" { - slot, err = h.backend.GetHeadSlot() + // If slot is being passed in the request, fetch block header at that slot. + if req.Slot != "" { + slot, err = utils.U64FromString(req.Slot) + if err != nil { + return nil, err + } + } else if req.ParentRoot != "" { + // TODO: If parent_root is being passed in the request, + // fetch block header at that parent_root. + // Convert the string to common.Root + var parentRoot common.Root + err = parentRoot.UnmarshalText([]byte(req.ParentRoot)) + if err != nil { + return nil, errors.Wrapf(err, "invalid parent root: %v", req.ParentRoot) + } + + slot, err = h.backend.GetSlotByStateRoot(parentRoot) if err != nil { return nil, err } } else { - slot, err = utils.U64FromString(req.Slot) + // If neither slot nor parent_root is provided, fetch current head slot. + slot, err = h.backend.GetHeadSlot() if err != nil { return nil, err } @@ -56,8 +72,13 @@ func (h *Handler[ return nil, err } + root, err := h.backend.BlockRootAtSlot(slot) + if err != nil { + return nil, err + } + return types.Wrap(&beacontypes.BlockHeaderResponse[BeaconBlockHeaderT]{ - Root: header.GetBodyRoot(), + Root: root, Canonical: true, Header: &beacontypes.BlockHeader[BeaconBlockHeaderT]{ Message: header, From c562a5310e7e59be65976bb9d21b3d07f831afda Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Fri, 20 Sep 2024 13:30:29 +0530 Subject: [PATCH 24/27] query headers by parent block root Signed-off-by: nidhi-singh02 --- mod/node-api/backend/backend.go | 7 ++++ mod/node-api/backend/types.go | 2 ++ mod/node-api/handlers/beacon/backend.go | 2 ++ mod/node-api/handlers/beacon/header.go | 42 ++++++++++++++++------ mod/node-core/pkg/components/interfaces.go | 4 +++ mod/storage/pkg/block/store.go | 19 ++++++++++ mod/storage/pkg/block/types.go | 3 +- 7 files changed, 68 insertions(+), 11 deletions(-) diff --git a/mod/node-api/backend/backend.go b/mod/node-api/backend/backend.go index 2b415ace36..6c9af4807d 100644 --- a/mod/node-api/backend/backend.go +++ b/mod/node-api/backend/backend.go @@ -219,3 +219,10 @@ func (b *Backend[ 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) +} diff --git a/mod/node-api/backend/types.go b/mod/node-api/backend/types.go index f62d9391c5..9bc1cc6566 100644 --- a/mod/node-api/backend/types.go +++ b/mod/node-api/backend/types.go @@ -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. diff --git a/mod/node-api/handlers/beacon/backend.go b/mod/node-api/handlers/beacon/backend.go index c1394b7de8..2c7439bbf0 100644 --- a/mod/node-api/handlers/beacon/backend.go +++ b/mod/node-api/handlers/beacon/backend.go @@ -42,6 +42,8 @@ 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) } diff --git a/mod/node-api/handlers/beacon/header.go b/mod/node-api/handlers/beacon/header.go index f3ba11b6d1..9791c4d16a 100644 --- a/mod/node-api/handlers/beacon/header.go +++ b/mod/node-api/handlers/beacon/header.go @@ -40,28 +40,50 @@ func (h *Handler[ return nil, err } var slot math.Slot - // If slot is being passed in the request, fetch block header at that slot. - if req.Slot != "" { + var parentRoot common.Root + + switch { + case req.Slot != "" && req.ParentRoot != "": + // Both slot and parent_root are provided slot, err = utils.U64FromString(req.Slot) + if err != nil { + return nil, errors.Wrapf(err, "invalid slot: %v", req.Slot) + } + err = parentRoot.UnmarshalText([]byte(req.ParentRoot)) + if err != nil { + return nil, errors.Wrapf(err, "invalid parent root: %v", req.ParentRoot) + } + // Verify that the provided slot and parent root match + verifiedSlot, err := h.backend.GetSlotByParentRoot(parentRoot) if err != nil { return nil, err } - } else if req.ParentRoot != "" { - // TODO: If parent_root is being passed in the request, - // fetch block header at that parent_root. + if verifiedSlot != slot { + return nil, errors.New("provided slot does not match the slot for the given parent root") + } + + case req.Slot != "": + // If only slot is provided + slot, err = utils.U64FromString(req.Slot) + if err != nil { + return nil, err + } + + case req.ParentRoot != "": + // If only parent_root is provided + // Convert the string to common.Root - var parentRoot common.Root err = parentRoot.UnmarshalText([]byte(req.ParentRoot)) if err != nil { return nil, errors.Wrapf(err, "invalid parent root: %v", req.ParentRoot) } - - slot, err = h.backend.GetSlotByStateRoot(parentRoot) + slot, err = h.backend.GetSlotByParentRoot(parentRoot) if err != nil { return nil, err } - } else { - // If neither slot nor parent_root is provided, fetch current head slot. + + default: + // If neither slot nor parent_root is provided, fetch current head slot slot, err = h.backend.GetHeadSlot() if err != nil { return nil, err diff --git a/mod/node-core/pkg/components/interfaces.go b/mod/node-core/pkg/components/interfaces.go index 59c2322df2..c58d178e31 100644 --- a/mod/node-core/pkg/components/interfaces.go +++ b/mod/node-core/pkg/components/interfaces.go @@ -297,6 +297,9 @@ type ( // number // from the store. GetSlotByExecutionNumber(executionNumber math.U64) (math.Slot, error) + // GetSlotByParentRoot retrieves the slot by a given parent root from the + // store. + GetSlotByParentRoot(root common.Root) (math.Slot, error) } ConsensusEngine interface { @@ -1092,6 +1095,7 @@ type ( GetSlotByStateRoot(root common.Root) (math.Slot, error) GetSlotByExecutionNumber(executionNumber math.U64) (math.Slot, error) GetHeadSlot() (math.Slot, error) + GetSlotByParentRoot(root common.Root) (math.Slot, error) NodeAPIBeaconBackend[ BeaconStateT, BeaconBlockHeaderT, ForkT, ValidatorT, diff --git a/mod/storage/pkg/block/store.go b/mod/storage/pkg/block/store.go index c266705d1b..0fa34f48cf 100644 --- a/mod/storage/pkg/block/store.go +++ b/mod/storage/pkg/block/store.go @@ -35,6 +35,7 @@ type KVStore[BeaconBlockT BeaconBlock] struct { blockRoots *lru.Cache[common.Root, math.Slot] executionNumbers *lru.Cache[math.U64, math.Slot] stateRoots *lru.Cache[common.Root, math.Slot] + parentRoots *lru.Cache[common.Root, math.Slot] logger log.Logger } @@ -56,11 +57,17 @@ func NewStore[BeaconBlockT BeaconBlock]( if err != nil { panic(err) } + + parentRoots, err := lru.New[common.Root, math.Slot](availabilityWindow) + if err != nil { + panic(err) + } return &KVStore[BeaconBlockT]{ blockRoots: blockRoots, executionNumbers: executionNumbers, stateRoots: stateRoots, logger: logger, + parentRoots: parentRoots, } } @@ -72,6 +79,7 @@ func (kv *KVStore[BeaconBlockT]) Set(blk BeaconBlockT) error { kv.blockRoots.Add(blk.HashTreeRoot(), slot) kv.executionNumbers.Add(blk.GetExecutionNumber(), slot) kv.stateRoots.Add(blk.GetStateRoot(), slot) + kv.parentRoots.Add(blk.GetParentBlockRoot(), slot) return nil } @@ -111,3 +119,14 @@ func (kv *KVStore[BeaconBlockT]) GetSlotByStateRoot( } return slot, nil } + +// GetSlotByParentRoot retrieves the slot by a given parent root from the store. +func (kv *KVStore[BeaconBlockT]) GetSlotByParentRoot( + parentRoot common.Root, +) (math.Slot, error) { + slot, ok := kv.parentRoots.Peek(parentRoot) + if !ok { + return 0, fmt.Errorf("slot not found at parent root: %s", parentRoot) + } + return slot, nil +} diff --git a/mod/storage/pkg/block/types.go b/mod/storage/pkg/block/types.go index 07afd76035..4021be9245 100644 --- a/mod/storage/pkg/block/types.go +++ b/mod/storage/pkg/block/types.go @@ -26,10 +26,11 @@ import ( ) // BeaconBlock is a block in the beacon chain that has a slot, block root (hash -// tree root), execution number, and state root. +// tree root), execution number, state root and parent block root. type BeaconBlock interface { GetSlot() math.U64 HashTreeRoot() common.Root GetExecutionNumber() math.U64 GetStateRoot() common.Root + GetParentBlockRoot() common.Root } From 28d38c2babf63497aff695deb2a52f03a45c2518 Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Fri, 20 Sep 2024 14:38:04 +0530 Subject: [PATCH 25/27] split func Signed-off-by: nidhi-singh02 --- .mockery.yaml | 5 + .../backend/mocks/block_store.mock.go | 56 ++++ mod/node-api/handlers/beacon/header.go | 79 +++--- .../pkg/block/mocks/beacon_block.mock.go | 268 ++++++++++++++++++ 4 files changed, 375 insertions(+), 33 deletions(-) create mode 100644 mod/storage/pkg/block/mocks/beacon_block.mock.go diff --git a/.mockery.yaml b/.mockery.yaml index 6062236306..417b8b93d0 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -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 diff --git a/mod/node-api/backend/mocks/block_store.mock.go b/mod/node-api/backend/mocks/block_store.mock.go index 1a0bf79276..21d8dd2c54 100644 --- a/mod/node-api/backend/mocks/block_store.mock.go +++ b/mod/node-api/backend/mocks/block_store.mock.go @@ -134,6 +134,62 @@ func (_c *BlockStore_GetSlotByExecutionNumber_Call[BeaconBlockT]) RunAndReturn(r return _c } +// GetSlotByParentRoot provides a mock function with given fields: root +func (_m *BlockStore[BeaconBlockT]) GetSlotByParentRoot(root common.Root) (math.U64, error) { + ret := _m.Called(root) + + if len(ret) == 0 { + panic("no return value specified for GetSlotByParentRoot") + } + + var r0 math.U64 + var r1 error + if rf, ok := ret.Get(0).(func(common.Root) (math.U64, error)); ok { + return rf(root) + } + if rf, ok := ret.Get(0).(func(common.Root) math.U64); ok { + r0 = rf(root) + } else { + r0 = ret.Get(0).(math.U64) + } + + if rf, ok := ret.Get(1).(func(common.Root) error); ok { + r1 = rf(root) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// BlockStore_GetSlotByParentRoot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSlotByParentRoot' +type BlockStore_GetSlotByParentRoot_Call[BeaconBlockT interface{}] struct { + *mock.Call +} + +// GetSlotByParentRoot is a helper method to define mock.On call +// - root common.Root +func (_e *BlockStore_Expecter[BeaconBlockT]) GetSlotByParentRoot(root interface{}) *BlockStore_GetSlotByParentRoot_Call[BeaconBlockT] { + return &BlockStore_GetSlotByParentRoot_Call[BeaconBlockT]{Call: _e.mock.On("GetSlotByParentRoot", root)} +} + +func (_c *BlockStore_GetSlotByParentRoot_Call[BeaconBlockT]) Run(run func(root common.Root)) *BlockStore_GetSlotByParentRoot_Call[BeaconBlockT] { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(common.Root)) + }) + return _c +} + +func (_c *BlockStore_GetSlotByParentRoot_Call[BeaconBlockT]) Return(_a0 math.U64, _a1 error) *BlockStore_GetSlotByParentRoot_Call[BeaconBlockT] { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *BlockStore_GetSlotByParentRoot_Call[BeaconBlockT]) RunAndReturn(run func(common.Root) (math.U64, error)) *BlockStore_GetSlotByParentRoot_Call[BeaconBlockT] { + _c.Call.Return(run) + return _c +} + // GetSlotByStateRoot provides a mock function with given fields: root func (_m *BlockStore[BeaconBlockT]) GetSlotByStateRoot(root common.Root) (math.U64, error) { ret := _m.Called(root) diff --git a/mod/node-api/handlers/beacon/header.go b/mod/node-api/handlers/beacon/header.go index 9791c4d16a..998859ddf5 100644 --- a/mod/node-api/handlers/beacon/header.go +++ b/mod/node-api/handlers/beacon/header.go @@ -39,74 +39,87 @@ func (h *Handler[ if err != nil { return nil, err } + + slot, err := h.determineSlot(&req) + if err != nil { + return nil, err + } + header, err := h.backend.BlockHeaderAtSlot(slot) + if err != nil { + return nil, err + } + + root, err := h.backend.BlockRootAtSlot(slot) + if err != nil { + return nil, err + } + + return types.Wrap(&beacontypes.BlockHeaderResponse[BeaconBlockHeaderT]{ + Root: root, + Canonical: true, + Header: &beacontypes.BlockHeader[BeaconBlockHeaderT]{ + Message: header, + Signature: crypto.BLSSignature{}, // TODO: implement + }, + }), nil +} + +func (h *Handler[ + BeaconBlockHeaderT, ContextT, _, _, +]) determineSlot(req *beacontypes.GetBlockHeadersRequest) (math.Slot, error) { var slot math.Slot var parentRoot common.Root - switch { case req.Slot != "" && req.ParentRoot != "": // Both slot and parent_root are provided - slot, err = utils.U64FromString(req.Slot) + slot, err := utils.U64FromString(req.Slot) if err != nil { - return nil, errors.Wrapf(err, "invalid slot: %v", req.Slot) + return 0, errors.Wrapf(err, "invalid slot: %v", req.Slot) } err = parentRoot.UnmarshalText([]byte(req.ParentRoot)) if err != nil { - return nil, errors.Wrapf(err, "invalid parent root: %v", req.ParentRoot) + return 0, errors.Wrapf(err, "invalid parent root: %v", req.ParentRoot) } // Verify that the provided slot and parent root match - verifiedSlot, err := h.backend.GetSlotByParentRoot(parentRoot) - if err != nil { - return nil, err + verifiedSlot, errVerify := h.backend.GetSlotByParentRoot(parentRoot) + if errVerify != nil { + return 0, errVerify } if verifiedSlot != slot { - return nil, errors.New("provided slot does not match the slot for the given parent root") + return 0, errors.New("provided slot does not match the slot for the given parent root") } + return slot, nil case req.Slot != "": // If only slot is provided - slot, err = utils.U64FromString(req.Slot) + slot, err := utils.U64FromString(req.Slot) if err != nil { - return nil, err + return 0, err } + return slot, nil case req.ParentRoot != "": // If only parent_root is provided // Convert the string to common.Root - err = parentRoot.UnmarshalText([]byte(req.ParentRoot)) + err := parentRoot.UnmarshalText([]byte(req.ParentRoot)) if err != nil { - return nil, errors.Wrapf(err, "invalid parent root: %v", req.ParentRoot) + return 0, errors.Wrapf(err, "invalid parent root: %v", req.ParentRoot) } slot, err = h.backend.GetSlotByParentRoot(parentRoot) if err != nil { - return nil, err + return 0, err } + return slot, nil default: // If neither slot nor parent_root is provided, fetch current head slot - slot, err = h.backend.GetHeadSlot() + slot, err := h.backend.GetHeadSlot() if err != nil { - return nil, err + return 0, err } + return slot, nil } - header, err := h.backend.BlockHeaderAtSlot(slot) - if err != nil { - return nil, err - } - - root, err := h.backend.BlockRootAtSlot(slot) - if err != nil { - return nil, err - } - - return types.Wrap(&beacontypes.BlockHeaderResponse[BeaconBlockHeaderT]{ - Root: root, - Canonical: true, - Header: &beacontypes.BlockHeader[BeaconBlockHeaderT]{ - Message: header, - Signature: crypto.BLSSignature{}, // TODO: implement - }, - }), nil } func (h *Handler[ diff --git a/mod/storage/pkg/block/mocks/beacon_block.mock.go b/mod/storage/pkg/block/mocks/beacon_block.mock.go new file mode 100644 index 0000000000..fd3745d49e --- /dev/null +++ b/mod/storage/pkg/block/mocks/beacon_block.mock.go @@ -0,0 +1,268 @@ +// Code generated by mockery v2.46.0. DO NOT EDIT. + +package mocks + +import ( + common "github.com/berachain/beacon-kit/mod/primitives/pkg/common" + math "github.com/berachain/beacon-kit/mod/primitives/pkg/math" + + mock "github.com/stretchr/testify/mock" +) + +// BeaconBlock is an autogenerated mock type for the BeaconBlock type +type BeaconBlock struct { + mock.Mock +} + +type BeaconBlock_Expecter struct { + mock *mock.Mock +} + +func (_m *BeaconBlock) EXPECT() *BeaconBlock_Expecter { + return &BeaconBlock_Expecter{mock: &_m.Mock} +} + +// GetExecutionNumber provides a mock function with given fields: +func (_m *BeaconBlock) GetExecutionNumber() math.U64 { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetExecutionNumber") + } + + var r0 math.U64 + if rf, ok := ret.Get(0).(func() math.U64); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(math.U64) + } + + return r0 +} + +// BeaconBlock_GetExecutionNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetExecutionNumber' +type BeaconBlock_GetExecutionNumber_Call struct { + *mock.Call +} + +// GetExecutionNumber is a helper method to define mock.On call +func (_e *BeaconBlock_Expecter) GetExecutionNumber() *BeaconBlock_GetExecutionNumber_Call { + return &BeaconBlock_GetExecutionNumber_Call{Call: _e.mock.On("GetExecutionNumber")} +} + +func (_c *BeaconBlock_GetExecutionNumber_Call) Run(run func()) *BeaconBlock_GetExecutionNumber_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *BeaconBlock_GetExecutionNumber_Call) Return(_a0 math.U64) *BeaconBlock_GetExecutionNumber_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *BeaconBlock_GetExecutionNumber_Call) RunAndReturn(run func() math.U64) *BeaconBlock_GetExecutionNumber_Call { + _c.Call.Return(run) + return _c +} + +// GetParentBlockRoot provides a mock function with given fields: +func (_m *BeaconBlock) GetParentBlockRoot() common.Root { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetParentBlockRoot") + } + + var r0 common.Root + if rf, ok := ret.Get(0).(func() common.Root); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Root) + } + } + + return r0 +} + +// BeaconBlock_GetParentBlockRoot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetParentBlockRoot' +type BeaconBlock_GetParentBlockRoot_Call struct { + *mock.Call +} + +// GetParentBlockRoot is a helper method to define mock.On call +func (_e *BeaconBlock_Expecter) GetParentBlockRoot() *BeaconBlock_GetParentBlockRoot_Call { + return &BeaconBlock_GetParentBlockRoot_Call{Call: _e.mock.On("GetParentBlockRoot")} +} + +func (_c *BeaconBlock_GetParentBlockRoot_Call) Run(run func()) *BeaconBlock_GetParentBlockRoot_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *BeaconBlock_GetParentBlockRoot_Call) Return(_a0 common.Root) *BeaconBlock_GetParentBlockRoot_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *BeaconBlock_GetParentBlockRoot_Call) RunAndReturn(run func() common.Root) *BeaconBlock_GetParentBlockRoot_Call { + _c.Call.Return(run) + return _c +} + +// GetSlot provides a mock function with given fields: +func (_m *BeaconBlock) GetSlot() math.U64 { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetSlot") + } + + var r0 math.U64 + if rf, ok := ret.Get(0).(func() math.U64); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(math.U64) + } + + return r0 +} + +// BeaconBlock_GetSlot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSlot' +type BeaconBlock_GetSlot_Call struct { + *mock.Call +} + +// GetSlot is a helper method to define mock.On call +func (_e *BeaconBlock_Expecter) GetSlot() *BeaconBlock_GetSlot_Call { + return &BeaconBlock_GetSlot_Call{Call: _e.mock.On("GetSlot")} +} + +func (_c *BeaconBlock_GetSlot_Call) Run(run func()) *BeaconBlock_GetSlot_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *BeaconBlock_GetSlot_Call) Return(_a0 math.U64) *BeaconBlock_GetSlot_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *BeaconBlock_GetSlot_Call) RunAndReturn(run func() math.U64) *BeaconBlock_GetSlot_Call { + _c.Call.Return(run) + return _c +} + +// GetStateRoot provides a mock function with given fields: +func (_m *BeaconBlock) GetStateRoot() common.Root { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetStateRoot") + } + + var r0 common.Root + if rf, ok := ret.Get(0).(func() common.Root); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Root) + } + } + + return r0 +} + +// BeaconBlock_GetStateRoot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetStateRoot' +type BeaconBlock_GetStateRoot_Call struct { + *mock.Call +} + +// GetStateRoot is a helper method to define mock.On call +func (_e *BeaconBlock_Expecter) GetStateRoot() *BeaconBlock_GetStateRoot_Call { + return &BeaconBlock_GetStateRoot_Call{Call: _e.mock.On("GetStateRoot")} +} + +func (_c *BeaconBlock_GetStateRoot_Call) Run(run func()) *BeaconBlock_GetStateRoot_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *BeaconBlock_GetStateRoot_Call) Return(_a0 common.Root) *BeaconBlock_GetStateRoot_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *BeaconBlock_GetStateRoot_Call) RunAndReturn(run func() common.Root) *BeaconBlock_GetStateRoot_Call { + _c.Call.Return(run) + return _c +} + +// HashTreeRoot provides a mock function with given fields: +func (_m *BeaconBlock) HashTreeRoot() common.Root { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for HashTreeRoot") + } + + var r0 common.Root + if rf, ok := ret.Get(0).(func() common.Root); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Root) + } + } + + return r0 +} + +// BeaconBlock_HashTreeRoot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'HashTreeRoot' +type BeaconBlock_HashTreeRoot_Call struct { + *mock.Call +} + +// HashTreeRoot is a helper method to define mock.On call +func (_e *BeaconBlock_Expecter) HashTreeRoot() *BeaconBlock_HashTreeRoot_Call { + return &BeaconBlock_HashTreeRoot_Call{Call: _e.mock.On("HashTreeRoot")} +} + +func (_c *BeaconBlock_HashTreeRoot_Call) Run(run func()) *BeaconBlock_HashTreeRoot_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *BeaconBlock_HashTreeRoot_Call) Return(_a0 common.Root) *BeaconBlock_HashTreeRoot_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *BeaconBlock_HashTreeRoot_Call) RunAndReturn(run func() common.Root) *BeaconBlock_HashTreeRoot_Call { + _c.Call.Return(run) + return _c +} + +// NewBeaconBlock creates a new instance of BeaconBlock. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewBeaconBlock(t interface { + mock.TestingT + Cleanup(func()) +}) *BeaconBlock { + mock := &BeaconBlock{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} From 322a7940fd5dd36634c79295260625aff69f883e Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Fri, 20 Sep 2024 14:44:41 +0530 Subject: [PATCH 26/27] linterr Signed-off-by: nidhi-singh02 --- mod/node-api/handlers/beacon/header.go | 7 ++++--- mod/storage/pkg/block/mocks/beacon_block.mock.go | 2 +- mod/storage/pkg/block/store_test.go | 4 ++++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/mod/node-api/handlers/beacon/header.go b/mod/node-api/handlers/beacon/header.go index 998859ddf5..83f0af6297 100644 --- a/mod/node-api/handlers/beacon/header.go +++ b/mod/node-api/handlers/beacon/header.go @@ -67,7 +67,6 @@ func (h *Handler[ func (h *Handler[ BeaconBlockHeaderT, ContextT, _, _, ]) determineSlot(req *beacontypes.GetBlockHeadersRequest) (math.Slot, error) { - var slot math.Slot var parentRoot common.Root switch { case req.Slot != "" && req.ParentRoot != "": @@ -86,7 +85,9 @@ func (h *Handler[ return 0, errVerify } if verifiedSlot != slot { - return 0, errors.New("provided slot does not match the slot for the given parent root") + return 0, errors.New( + "provided slot does not match the slot for the given parent root", + ) } return slot, nil @@ -106,7 +107,7 @@ func (h *Handler[ if err != nil { return 0, errors.Wrapf(err, "invalid parent root: %v", req.ParentRoot) } - slot, err = h.backend.GetSlotByParentRoot(parentRoot) + slot, err := h.backend.GetSlotByParentRoot(parentRoot) if err != nil { return 0, err } diff --git a/mod/storage/pkg/block/mocks/beacon_block.mock.go b/mod/storage/pkg/block/mocks/beacon_block.mock.go index fd3745d49e..1d264a937a 100644 --- a/mod/storage/pkg/block/mocks/beacon_block.mock.go +++ b/mod/storage/pkg/block/mocks/beacon_block.mock.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.46.0. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/mod/storage/pkg/block/store_test.go b/mod/storage/pkg/block/store_test.go index e41553b7b4..b9827bc89d 100644 --- a/mod/storage/pkg/block/store_test.go +++ b/mod/storage/pkg/block/store_test.go @@ -50,6 +50,10 @@ func (m MockBeaconBlock) GetStateRoot() common.Root { return [32]byte{byte(m.slot)} } +func (m MockBeaconBlock) GetParentBlockRoot() common.Root { + return [32]byte{byte(m.slot - 1)} +} + func TestBlockStore(t *testing.T) { blockStore := block.NewStore[*MockBeaconBlock](noop.NewLogger[any](), 5) From 7436bd69d6ff67c65b7fa057dfb562e1da13532d Mon Sep 17 00:00:00 2001 From: nidhi-singh02 Date: Fri, 20 Sep 2024 15:14:45 +0530 Subject: [PATCH 27/27] generatee Signed-off-by: nidhi-singh02 --- mod/storage/pkg/block/mocks/beacon_block.mock.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/storage/pkg/block/mocks/beacon_block.mock.go b/mod/storage/pkg/block/mocks/beacon_block.mock.go index 1d264a937a..fd3745d49e 100644 --- a/mod/storage/pkg/block/mocks/beacon_block.mock.go +++ b/mod/storage/pkg/block/mocks/beacon_block.mock.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.2. DO NOT EDIT. +// Code generated by mockery v2.46.0. DO NOT EDIT. package mocks