Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
2cfc948
replaced genesis special methods with getter to state
abi87 Sep 10, 2025
22cbe62
moved blob getter from backend to handler
abi87 Sep 10, 2025
e215fb0
cleaned up node-api backend mocks
abi87 Sep 10, 2025
c124adf
improved slot retrieval for blob apis
abi87 Sep 10, 2025
ae5c36e
wip: genesis state copy in node-api backend
abi87 Sep 11, 2025
7cf09ca
wip: mapping stateID requests to int64 instead of uint64
abi87 Sep 11, 2025
af5575a
improved mapping naming
abi87 Sep 11, 2025
5c3d91d
introduced backend.ReadOnlyBeaconState instead of nake state.StateDB
abi87 Sep 11, 2025
0cf76e9
copy genesis state for safety
abi87 Sep 11, 2025
de12505
wip: moved mapping to mapping package
abi87 Sep 11, 2025
5a81c83
conslidated error handling for chain-not-ready and heigth-too-high
abi87 Sep 11, 2025
7b8bdc0
Merge branch 'main' into node-api-complete-backend-simplification
abi87 Sep 12, 2025
efa20c7
Merge branch 'main' into node-api-complete-backend-simplification
abi87 Sep 12, 2025
c1109bd
Merge branch 'node-api-complete-backend-simplification' into node-api…
abi87 Sep 12, 2025
f1a95d7
added LoadData UT
abi87 Sep 12, 2025
e1b73a9
some more checks in UTs
abi87 Sep 12, 2025
3d4a7b4
nit
abi87 Sep 15, 2025
ca4cb72
added simple UT
abi87 Sep 15, 2025
b6ac1da
Merge branch 'node-api-complete-backend-simplification' into node-api…
abi87 Sep 15, 2025
19efe81
Merge branch 'node-api-fix-genesis-state' into node-api-fix-http-errors
abi87 Sep 15, 2025
d0a4b56
Merge branch 'main' into node-api-fix-http-errors
abi87 Sep 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion node-api/backend/getters.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ import (
"cosmossdk.io/log"
cometbft "github.com/berachain/beacon-kit/consensus/cometbft/service"
datypes "github.com/berachain/beacon-kit/da/types"
"github.com/berachain/beacon-kit/node-api/middleware"
"github.com/berachain/beacon-kit/primitives/common"
"github.com/berachain/beacon-kit/primitives/math"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/version"
)

Expand All @@ -52,7 +54,8 @@ func (b *Backend) StateAndSlotFromHeight(height int64) (ReadOnlyBeaconState, mat
return nil, 0, fmt.Errorf("failed loading genesis state: %w", err)
}
case errors.Is(err, cometbft.ErrAppNotReady):
return nil, 0, cometbft.ErrAppNotReady
// chain not ready, like when genesis time is set in the future
return nil, 0, middleware.ErrNotFound
default:
return nil, 0, fmt.Errorf("unable to check whether app is ready: %w", err)
}
Expand All @@ -71,6 +74,14 @@ func (b *Backend) StateAndSlotFromHeight(height int64) (ReadOnlyBeaconState, mat
height = max(0, height) // CreateQueryContext uses 0 to pick latest height.
queryCtx, err := b.node.CreateQueryContext(height, false)
if err != nil {
if errors.Is(err, cometbft.ErrAppNotReady) {
// chain not ready, like when genesis time is set in the future
return nil, 0, middleware.ErrNotFound
}
if errors.Is(err, sdkerrors.ErrInvalidHeight) {
// height requested too high
return nil, 0, middleware.ErrNotFound
}
return nil, 0, fmt.Errorf("CreateQueryContext failed: %w", err)
}
st := b.sb.StateFromContext(queryCtx)
Expand Down
4 changes: 2 additions & 2 deletions node-api/handlers/beacon/blob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ import (
"github.com/berachain/beacon-kit/node-api/handlers/beacon"
"github.com/berachain/beacon-kit/node-api/handlers/beacon/mocks"
beacontypes "github.com/berachain/beacon-kit/node-api/handlers/beacon/types"
"github.com/berachain/beacon-kit/node-api/handlers/mapping"
handlertypes "github.com/berachain/beacon-kit/node-api/handlers/types"
"github.com/berachain/beacon-kit/node-api/handlers/utils"
"github.com/berachain/beacon-kit/node-api/middleware"
"github.com/berachain/beacon-kit/primitives/common"
"github.com/berachain/beacon-kit/primitives/math"
Expand Down Expand Up @@ -77,7 +77,7 @@ func TestGetBlobSidecars(t *testing.T) {
inputs: func() beacontypes.GetBlobSidecarsRequest {
return beacontypes.GetBlobSidecarsRequest{
BlockIDRequest: handlertypes.BlockIDRequest{
BlockID: utils.StateIDHead,
BlockID: mapping.StateIDHead,
},
Indices: nil,
}
Expand Down
5 changes: 3 additions & 2 deletions node-api/handlers/beacon/blobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (

"github.com/berachain/beacon-kit/node-api/handlers"
"github.com/berachain/beacon-kit/node-api/handlers/beacon/types"
"github.com/berachain/beacon-kit/node-api/handlers/mapping"
"github.com/berachain/beacon-kit/node-api/handlers/utils"
"github.com/berachain/beacon-kit/primitives/math"
)
Expand All @@ -43,13 +44,13 @@ func (h *Handler) GetBlobSidecars(c handlers.Context) (any, error) {
}

// Map requested blockID to slot
slotID, err := utils.BlockIDToHeight(req.BlockID, h.backend)
slotID, err := mapping.BlockIDToHeight(req.BlockID, h.backend)
if err != nil {
return nil, err
}

var slot math.Slot
if slotID == utils.Head {
if slotID == mapping.Head {
latestHeight, _ := h.backend.GetSyncData()
if latestHeight < 0 {
return nil, errors.New("invalid negative block height")
Expand Down
11 changes: 2 additions & 9 deletions node-api/handlers/beacon/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,16 @@
package beacon

import (
"errors"
"fmt"

cometbft "github.com/berachain/beacon-kit/consensus/cometbft/service"
"github.com/berachain/beacon-kit/node-api/handlers"
beacontypes "github.com/berachain/beacon-kit/node-api/handlers/beacon/types"
handlertypes "github.com/berachain/beacon-kit/node-api/handlers/types"
"github.com/berachain/beacon-kit/node-api/handlers/utils"
"github.com/berachain/beacon-kit/node-api/handlers/mapping"
)

func (h *Handler) GetGenesis(handlers.Context) (any, error) {
st, _, err := h.backend.StateAndSlotFromHeight(utils.Genesis)
st, _, err := h.backend.StateAndSlotFromHeight(mapping.Genesis)
if err != nil {
if errors.Is(err, cometbft.ErrAppNotReady) {
// chain not ready, like when genesis time is set in the future
return nil, handlertypes.ErrNotFound
}
return nil, fmt.Errorf("failed to get state from genesis: %w", err)
}

Expand Down
6 changes: 2 additions & 4 deletions node-api/handlers/beacon/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,11 @@ import (
"github.com/berachain/beacon-kit/chain"
"github.com/berachain/beacon-kit/config/spec"
ctypes "github.com/berachain/beacon-kit/consensus-types/types"
cometbft "github.com/berachain/beacon-kit/consensus/cometbft/service"
beaconlog "github.com/berachain/beacon-kit/log"
"github.com/berachain/beacon-kit/log/noop"
"github.com/berachain/beacon-kit/node-api/handlers/beacon"
"github.com/berachain/beacon-kit/node-api/handlers/beacon/mocks"
beacontypes "github.com/berachain/beacon-kit/node-api/handlers/beacon/types"
"github.com/berachain/beacon-kit/node-api/handlers/types"
"github.com/berachain/beacon-kit/node-api/middleware"
"github.com/berachain/beacon-kit/node-core/components/metrics"
"github.com/berachain/beacon-kit/primitives/common"
Expand Down Expand Up @@ -104,12 +102,12 @@ func TestGetGenesis(t *testing.T) {
{
name: "genesis not ready",
setMockExpectations: func(b *mocks.Backend) {
b.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(nil, 0, cometbft.ErrAppNotReady)
b.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(nil, 0, middleware.ErrNotFound)
},
check: func(t *testing.T, res any, err error) {
t.Helper()

require.ErrorIs(t, err, types.ErrNotFound)
require.ErrorIs(t, err, middleware.ErrNotFound)
require.Nil(t, res)
},
},
Expand Down
23 changes: 12 additions & 11 deletions node-api/handlers/beacon/header.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ import (

"github.com/berachain/beacon-kit/node-api/handlers"
beacontypes "github.com/berachain/beacon-kit/node-api/handlers/beacon/types"
handlertypes "github.com/berachain/beacon-kit/node-api/handlers/types"
"github.com/berachain/beacon-kit/node-api/handlers/mapping"
"github.com/berachain/beacon-kit/node-api/handlers/utils"
"github.com/berachain/beacon-kit/node-api/middleware"
"github.com/berachain/beacon-kit/primitives/math"
)

Expand All @@ -44,7 +45,7 @@ func (h *Handler) GetBlockHeaders(c handlers.Context) (any, error) {
case len(req.Slot) == 0 && len(req.ParentRoot) == 0:
// no parameter specified, pick chain HEAD
// by requesting special height -1.
height := utils.Head
height := mapping.Head
return h.makeBlockHeaderResponse(height, true /*resultsInList*/)

case len(req.Slot) != 0 && len(req.ParentRoot) == 0:
Expand All @@ -54,32 +55,32 @@ func (h *Handler) GetBlockHeaders(c handlers.Context) (any, error) {
return nil, fmt.Errorf("failed retrieving slot from input parameters: %w", errSlot)
}
if slot > stdmath.MaxInt64 { // appease linters
return 0, fmt.Errorf("%w: slot %d", utils.ErrFailedMappingHeightTooHigh, slot)
return 0, fmt.Errorf("%w: slot %d", mapping.ErrFailedMappingHeightTooHigh, slot)
}
return h.makeBlockHeaderResponse(int64(slot), true /*resultsInList*/) //#nosec: G115 // safe

case len(req.Slot) == 0 && len(req.ParentRoot) != 0:
parentHeight, errParent := utils.BlockIDToHeight(req.ParentRoot, h.backend)
parentHeight, errParent := mapping.BlockIDToHeight(req.ParentRoot, h.backend)
if errParent != nil {
return nil, fmt.Errorf("%w, failed retrieving parent root with error: %w", handlertypes.ErrNotFound, errParent)
return nil, fmt.Errorf("%w, failed retrieving parent root with error: %w", middleware.ErrNotFound, errParent)
}
if parentHeight == utils.Head {
return nil, fmt.Errorf("%w, requested header of tip's child", handlertypes.ErrNotFound)
if parentHeight == mapping.Head {
return nil, fmt.Errorf("%w, requested header of tip's child", middleware.ErrNotFound)
}
height := parentHeight + 1
return h.makeBlockHeaderResponse(height, true /*resultsInList*/)

default:
var (
slot, errSlot = math.U64FromString(req.Slot)
parentSlot, errParent = utils.BlockIDToHeight(req.ParentRoot, h.backend)
parentSlot, errParent = mapping.BlockIDToHeight(req.ParentRoot, h.backend)
)
if err := errors.Join(errSlot, errParent); err != nil {
return nil, err
}

if slot > stdmath.MaxInt64 { // appease linters
return 0, fmt.Errorf("%w: slot %d", utils.ErrFailedMappingHeightTooHigh, slot)
return 0, fmt.Errorf("%w: slot %d", mapping.ErrFailedMappingHeightTooHigh, slot)
}
height := int64(slot) //#nosec: G115 // safe
if height != parentSlot+1 {
Expand All @@ -94,7 +95,7 @@ func (h *Handler) GetBlockHeaderByID(c handlers.Context) (any, error) {
if err != nil {
return nil, err
}
slot, err := utils.BlockIDToHeight(req.BlockID, h.backend)
slot, err := mapping.BlockIDToHeight(req.BlockID, h.backend)
if err != nil {
return nil, fmt.Errorf("failed retrieving slot from block ID %s: %w", req.BlockID, err)
}
Expand All @@ -104,7 +105,7 @@ func (h *Handler) GetBlockHeaderByID(c handlers.Context) (any, error) {
func (h *Handler) makeBlockHeaderResponse(height int64, resultsInList bool) (any, error) {
st, _, err := h.backend.StateAndSlotFromHeight(height)
if err != nil {
return nil, fmt.Errorf("%w: failed to get state from height %d, %s", handlertypes.ErrNotFound, height, err.Error())
return nil, fmt.Errorf("failed to get state from height %d, %w", height, err)
}
// Return after updating the state root in the block header.
header, err := st.GetLatestBlockHeader()
Expand Down
18 changes: 9 additions & 9 deletions node-api/handlers/beacon/header_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func TestGetBlockHeaders(t *testing.T) {
},
check: func(t *testing.T, _ common.Root, _ any, err error) {
t.Helper()
require.ErrorIs(t, err, handlertypes.ErrInvalidRequest)
require.ErrorIs(t, err, middleware.ErrInvalidRequest)
},
},
{
Expand All @@ -187,14 +187,14 @@ func TestGetBlockHeaders(t *testing.T) {
},
setMockExpectations: func(t *testing.T, b *mocks.Backend) common.Root {
t.Helper()
b.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(nil, math.Slot(0), errTestHeaderNotFound)
b.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(nil, math.Slot(0), middleware.ErrNotFound)
return common.Root{}
},
check: func(t *testing.T, _ common.Root, _ any, err error) {
t.Helper()
// Implicitly ensuring that 404 error code is returned
// (see responseFromError implementation)
require.ErrorIs(t, err, handlertypes.ErrNotFound)
require.ErrorIs(t, err, middleware.ErrNotFound)
},
},
{
Expand Down Expand Up @@ -250,7 +250,7 @@ func TestGetBlockHeaders(t *testing.T) {
},
check: func(t *testing.T, _ common.Root, _ any, err error) {
t.Helper()
require.ErrorIs(t, err, handlertypes.ErrInvalidRequest)
require.ErrorIs(t, err, middleware.ErrInvalidRequest)
},
},
{
Expand All @@ -270,7 +270,7 @@ func TestGetBlockHeaders(t *testing.T) {
t.Helper()
// Implicitly ensuring that 404 error code is returned
// (see responseFromError implementation)
require.ErrorIs(t, err, handlertypes.ErrNotFound)
require.ErrorIs(t, err, middleware.ErrNotFound)
},
},
{
Expand Down Expand Up @@ -444,7 +444,7 @@ func TestGetBlockHeaderByID(t *testing.T) {
},
check: func(t *testing.T, _ common.Root, _ any, err error) {
t.Helper()
require.ErrorIs(t, err, handlertypes.ErrInvalidRequest)
require.ErrorIs(t, err, middleware.ErrInvalidRequest)
},
},
{
Expand All @@ -458,15 +458,15 @@ func TestGetBlockHeaderByID(t *testing.T) {
},
setMockExpectations: func(t *testing.T, b *mocks.Backend) common.Root {
t.Helper()
b.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(nil, math.Slot(0), errTestHeaderNotFound)
b.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(nil, math.Slot(0), middleware.ErrNotFound)
return common.Root{}
},
check: func(t *testing.T, _ common.Root, _ any, err error) {
t.Helper()

// Implicitly ensuring that 404 error code is returned
// (see responseFromError implementation)
require.ErrorIs(t, err, handlertypes.ErrNotFound)
require.ErrorIs(t, err, middleware.ErrNotFound)
},
},
{
Expand Down Expand Up @@ -523,7 +523,7 @@ func TestGetBlockHeaderByID(t *testing.T) {
},
check: func(t *testing.T, _ common.Root, _ any, err error) {
t.Helper()
require.ErrorIs(t, err, handlertypes.ErrInvalidRequest)
require.ErrorIs(t, err, middleware.ErrInvalidRequest)
},
},
{
Expand Down
5 changes: 3 additions & 2 deletions node-api/handlers/beacon/historical.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ package beacon
import (
"github.com/berachain/beacon-kit/node-api/handlers"
beacontypes "github.com/berachain/beacon-kit/node-api/handlers/beacon/types"
"github.com/berachain/beacon-kit/node-api/handlers/mapping"
"github.com/berachain/beacon-kit/node-api/handlers/utils"
)

Expand All @@ -33,7 +34,7 @@ func (h *Handler) GetStateRoot(c handlers.Context) (any, error) {
if err != nil {
return nil, err
}
slot, err := utils.StateIDToHeight(req.StateID, h.backend)
slot, err := mapping.StateIDToHeight(req.StateID, h.backend)
if err != nil {
return nil, err
}
Expand All @@ -51,7 +52,7 @@ func (h *Handler) GetStateFork(c handlers.Context) (any, error) {
if err != nil {
return nil, err
}
slot, err := utils.StateIDToHeight(req.StateID, h.backend)
slot, err := mapping.StateIDToHeight(req.StateID, h.backend)
if err != nil {
return nil, err
}
Expand Down
3 changes: 2 additions & 1 deletion node-api/handlers/beacon/randao.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/berachain/beacon-kit/errors"
"github.com/berachain/beacon-kit/node-api/handlers"
beacontypes "github.com/berachain/beacon-kit/node-api/handlers/beacon/types"
"github.com/berachain/beacon-kit/node-api/handlers/mapping"
"github.com/berachain/beacon-kit/node-api/handlers/utils"
"github.com/berachain/beacon-kit/primitives/math"
)
Expand All @@ -38,7 +39,7 @@ func (h *Handler) GetRandao(c handlers.Context) (any, error) {
}

// Get slot and associated state
height, err := utils.StateIDToHeight(req.StateID, h.backend)
height, err := mapping.StateIDToHeight(req.StateID, h.backend)
if err != nil {
return nil, err
}
Expand Down
6 changes: 3 additions & 3 deletions node-api/handlers/beacon/randao_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ import (
"github.com/berachain/beacon-kit/node-api/handlers/beacon"
"github.com/berachain/beacon-kit/node-api/handlers/beacon/mocks"
beacontypes "github.com/berachain/beacon-kit/node-api/handlers/beacon/types"
"github.com/berachain/beacon-kit/node-api/handlers/mapping"
handlertypes "github.com/berachain/beacon-kit/node-api/handlers/types"
"github.com/berachain/beacon-kit/node-api/handlers/utils"
"github.com/berachain/beacon-kit/node-api/middleware"
"github.com/berachain/beacon-kit/primitives/common"
"github.com/berachain/beacon-kit/primitives/math"
Expand Down Expand Up @@ -66,7 +66,7 @@ func TestGetRandao(t *testing.T) {
{
name: "randao request - specified epoch",
inputs: func() beacontypes.GetRandaoRequest {
stateID := utils.StateIDHead
stateID := mapping.StateIDHead
epoch := strconv.Itoa(int(testEpoch.Unwrap()))
return beacontypes.GetRandaoRequest{
StateIDRequest: handlertypes.StateIDRequest{
Expand Down Expand Up @@ -98,7 +98,7 @@ func TestGetRandao(t *testing.T) {
{
name: "randao request - unspecified epoch",
inputs: func() beacontypes.GetRandaoRequest {
stateID := utils.StateIDHead
stateID := mapping.StateIDHead
return beacontypes.GetRandaoRequest{
StateIDRequest: handlertypes.StateIDRequest{
StateID: stateID,
Expand Down
Loading
Loading