diff --git a/beacon-chain/db/kv/BUILD.bazel b/beacon-chain/db/kv/BUILD.bazel index 9de4f5c7b5f2..732da2fb5b2a 100644 --- a/beacon-chain/db/kv/BUILD.bazel +++ b/beacon-chain/db/kv/BUILD.bazel @@ -116,6 +116,7 @@ go_test( "//encoding/bytesutil:go_default_library", "//proto/dbval:go_default_library", "//proto/engine/v1:go_default_library", + "//proto/eth/v1:go_default_library", "//proto/eth/v2:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "//proto/testing:go_default_library", diff --git a/beacon-chain/db/kv/lightclient_test.go b/beacon-chain/db/kv/lightclient_test.go index 528e55023d39..dd2df2acac8b 100644 --- a/beacon-chain/db/kv/lightclient_test.go +++ b/beacon-chain/db/kv/lightclient_test.go @@ -5,38 +5,179 @@ import ( "testing" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" + enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" + ethpbv1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1" ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" + "github.com/prysmaticlabs/prysm/v5/runtime/version" "github.com/prysmaticlabs/prysm/v5/testing/require" ) -func TestStore_LightclientUpdate_CanSaveRetrieve(t *testing.T) { +func TestStore_LightClientUpdate_CanSaveRetrieveAltair(t *testing.T) { db := setupDB(t) ctx := context.Background() update := ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ + HeaderAltair: ðpbv2.LightClientHeader{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + }, + }, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 7, + FinalizedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ + HeaderAltair: ðpbv2.LightClientHeader{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + }, + }, + }, + FinalityBranch: nil, + SyncAggregate: nil, + SignatureSlot: 7, } + period := uint64(1) + err := db.SaveLightClientUpdate(ctx, period, ðpbv2.LightClientUpdateWithVersion{ + Version: version.Altair, + Data: update, + }) + require.NoError(t, err) + + retrievedUpdate, err := db.LightClientUpdate(ctx, period) + require.NoError(t, err) + require.DeepEqual(t, update, retrievedUpdate.Data, "retrieved update does not match saved update") +} +func TestStore_LightClientUpdate_CanSaveRetrieveCapella(t *testing.T) { + db := setupDB(t) + ctx := context.Background() + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ + HeaderCapella: ðpbv2.LightClientHeaderCapella{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + Execution: &enginev1.ExecutionPayloadHeaderCapella{ + FeeRecipient: []byte{1, 2, 3}, + }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, + }, + }, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ + HeaderCapella: ðpbv2.LightClientHeaderCapella{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + Execution: nil, + ExecutionBranch: nil, + }, + }, + }, + FinalityBranch: nil, + SyncAggregate: nil, + SignatureSlot: 7, + } period := uint64(1) err := db.SaveLightClientUpdate(ctx, period, ðpbv2.LightClientUpdateWithVersion{ - Version: 1, + Version: version.Capella, Data: update, }) require.NoError(t, err) - // Retrieve the update retrievedUpdate, err := db.LightClientUpdate(ctx, period) require.NoError(t, err) - require.Equal(t, update.SignatureSlot, retrievedUpdate.Data.SignatureSlot, "retrieved update does not match saved update") + require.DeepEqual(t, update, retrievedUpdate.Data, "retrieved update does not match saved update") +} +func TestStore_LightClientUpdate_CanSaveRetrieveDeneb(t *testing.T) { + db := setupDB(t) + ctx := context.Background() + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ + HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + Execution: &enginev1.ExecutionPayloadHeaderDeneb{ + FeeRecipient: []byte{1, 2, 3}, + }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, + }, + }, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ + HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + Execution: nil, + ExecutionBranch: nil, + }, + }, + }, + FinalityBranch: nil, + SyncAggregate: nil, + SignatureSlot: 7, + } + period := uint64(1) + err := db.SaveLightClientUpdate(ctx, period, ðpbv2.LightClientUpdateWithVersion{ + Version: version.Deneb, + Data: update, + }) + require.NoError(t, err) + + retrievedUpdate, err := db.LightClientUpdate(ctx, period) + require.NoError(t, err) + require.DeepEqual(t, update, retrievedUpdate.Data, "retrieved update does not match saved update") } -func TestStore_LightclientUpdates_canRetrieveRange(t *testing.T) { +func TestStore_LightClientUpdates_canRetrieveRange(t *testing.T) { db := setupDB(t) ctx := context.Background() updates := []*ethpbv2.LightClientUpdateWithVersion{ diff --git a/proto/eth/v2/custom.go b/proto/eth/v2/custom.go index 9a9633db2df3..f61e764614fa 100644 --- a/proto/eth/v2/custom.go +++ b/proto/eth/v2/custom.go @@ -3,6 +3,7 @@ package eth import ( "bytes" "fmt" + enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" "math/bits" v1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1" @@ -65,3 +66,32 @@ func (x *LightClientHeaderContainer) GetBeacon() (*v1.BeaconBlockHeader, error) return nil, fmt.Errorf("unknown header type: %T", input) } } + +func (x *LightClientHeaderContainer) GetExecutionHeaderCapella() (*enginev1.ExecutionPayloadHeaderCapella, error) { + switch input := x.Header.(type) { + case *LightClientHeaderContainer_HeaderCapella: + return input.HeaderCapella.Execution, nil + default: + return nil, fmt.Errorf("header type %T not Capella", input) + } +} + +func (x *LightClientHeaderContainer) GetExecutionHeaderDeneb() (*enginev1.ExecutionPayloadHeaderDeneb, error) { + switch input := x.Header.(type) { + case *LightClientHeaderContainer_HeaderDeneb: + return input.HeaderDeneb.Execution, nil + default: + return nil, fmt.Errorf("header type %T not Deneb", input) + } +} + +func (x *LightClientHeaderContainer) GetExecutionBranch() ([][]byte, error) { + switch input := x.Header.(type) { + case *LightClientHeaderContainer_HeaderCapella: + return input.HeaderCapella.ExecutionBranch, nil + case *LightClientHeaderContainer_HeaderDeneb: + return input.HeaderDeneb.ExecutionBranch, nil + default: + return nil, fmt.Errorf("wrong header type %T", input) + } +}