mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 21:08:10 -05:00
2075 lines
84 KiB
Go
2075 lines
84 KiB
Go
package light_client_test
|
|
|
|
import (
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/OffchainLabs/prysm/v7/config/params"
|
|
light_client "github.com/OffchainLabs/prysm/v7/consensus-types/light-client"
|
|
"github.com/OffchainLabs/prysm/v7/runtime/version"
|
|
|
|
lightClient "github.com/OffchainLabs/prysm/v7/beacon-chain/light-client"
|
|
fieldparams "github.com/OffchainLabs/prysm/v7/config/fieldparams"
|
|
consensustypes "github.com/OffchainLabs/prysm/v7/consensus-types"
|
|
"github.com/OffchainLabs/prysm/v7/consensus-types/blocks"
|
|
"github.com/OffchainLabs/prysm/v7/encoding/ssz"
|
|
v11 "github.com/OffchainLabs/prysm/v7/proto/engine/v1"
|
|
pb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
|
|
"github.com/OffchainLabs/prysm/v7/testing/require"
|
|
"github.com/OffchainLabs/prysm/v7/testing/util"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
func TestLightClient_NewLightClientOptimisticUpdateFromBeaconState(t *testing.T) {
|
|
params.SetupTestConfigCleanup(t)
|
|
cfg := params.BeaconConfig()
|
|
cfg.AltairForkEpoch = 1
|
|
cfg.BellatrixForkEpoch = 2
|
|
cfg.CapellaForkEpoch = 3
|
|
cfg.DenebForkEpoch = 4
|
|
cfg.ElectraForkEpoch = 5
|
|
cfg.FuluForkEpoch = 6
|
|
params.OverrideBeaconConfig(cfg)
|
|
|
|
for _, testVersion := range version.All()[1:] {
|
|
if testVersion == version.Gloas {
|
|
// TODO(16027): Unskip light client tests for Gloas
|
|
continue
|
|
}
|
|
t.Run(version.String(testVersion), func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, testVersion)
|
|
|
|
update, err := lightClient.NewLightClientOptimisticUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, update, "update is nil")
|
|
require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal")
|
|
|
|
l.CheckSyncAggregate(update.SyncAggregate())
|
|
l.CheckAttestedHeader(update.AttestedHeader())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLightClient_NewLightClientFinalityUpdateFromBeaconState(t *testing.T) {
|
|
params.SetupTestConfigCleanup(t)
|
|
cfg := params.BeaconConfig()
|
|
cfg.AltairForkEpoch = 1
|
|
cfg.BellatrixForkEpoch = 2
|
|
cfg.CapellaForkEpoch = 3
|
|
cfg.DenebForkEpoch = 4
|
|
cfg.ElectraForkEpoch = 5
|
|
cfg.FuluForkEpoch = 6
|
|
params.OverrideBeaconConfig(cfg)
|
|
|
|
t.Run("Altair", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Altair)
|
|
|
|
t.Run("FinalizedBlock Not Nil", func(t *testing.T) {
|
|
update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, update, "update is nil")
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal")
|
|
|
|
l.CheckSyncAggregate(update.SyncAggregate())
|
|
l.CheckAttestedHeader(update.AttestedHeader())
|
|
|
|
finalizedBlockHeader, err := l.FinalizedBlock.Header()
|
|
require.NoError(t, err)
|
|
|
|
//zeroHash := params.BeaconConfig().ZeroHash[:]
|
|
require.NotNil(t, update.FinalizedHeader(), "Finalized header is nil")
|
|
require.Equal(t, reflect.TypeOf(update.FinalizedHeader().Proto()), reflect.TypeFor[*pb.LightClientHeaderAltair](), "Finalized header is not Altair")
|
|
updateFinalizedHeaderBeacon := update.FinalizedHeader().Beacon()
|
|
require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal")
|
|
require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal")
|
|
fb, err := update.FinalityBranch()
|
|
require.NoError(t, err)
|
|
proof, err := l.AttestedState.FinalizedRootProof(l.Ctx)
|
|
require.NoError(t, err)
|
|
for i, leaf := range fb {
|
|
require.DeepSSZEqual(t, proof[i], leaf[:], "Leaf is not equal")
|
|
}
|
|
})
|
|
})
|
|
|
|
t.Run("Capella", func(t *testing.T) {
|
|
|
|
t.Run("FinalizedBlock Not Nil", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Capella)
|
|
update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, update, "update is nil")
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal")
|
|
|
|
l.CheckSyncAggregate(update.SyncAggregate())
|
|
l.CheckAttestedHeader(update.AttestedHeader())
|
|
|
|
finalizedBlockHeader, err := l.FinalizedBlock.Header()
|
|
require.NoError(t, err)
|
|
require.NotNil(t, update.FinalizedHeader(), "Finalized header is nil")
|
|
require.Equal(t, reflect.TypeOf(update.FinalizedHeader().Proto()), reflect.TypeFor[*pb.LightClientHeaderCapella](), "Finalized header is not Capella")
|
|
updateFinalizedHeaderBeacon := update.FinalizedHeader().Beacon()
|
|
require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal")
|
|
require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal")
|
|
fb, err := update.FinalityBranch()
|
|
require.NoError(t, err)
|
|
proof, err := l.AttestedState.FinalizedRootProof(l.Ctx)
|
|
require.NoError(t, err)
|
|
for i, leaf := range fb {
|
|
require.DeepSSZEqual(t, proof[i], leaf[:], "Leaf is not equal")
|
|
}
|
|
|
|
// Check Execution BlockHash
|
|
payloadInterface, err := l.FinalizedBlock.Block().Body().Execution()
|
|
require.NoError(t, err)
|
|
transactionsRoot, err := payloadInterface.TransactionsRoot()
|
|
if errors.Is(err, consensustypes.ErrUnsupportedField) {
|
|
transactions, err := payloadInterface.Transactions()
|
|
require.NoError(t, err)
|
|
transactionsRootArray, err := ssz.TransactionsRoot(transactions)
|
|
require.NoError(t, err)
|
|
transactionsRoot = transactionsRootArray[:]
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
withdrawalsRoot, err := payloadInterface.WithdrawalsRoot()
|
|
if errors.Is(err, consensustypes.ErrUnsupportedField) {
|
|
withdrawals, err := payloadInterface.Withdrawals()
|
|
require.NoError(t, err)
|
|
withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload)
|
|
require.NoError(t, err)
|
|
withdrawalsRoot = withdrawalsRootArray[:]
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
execution := &v11.ExecutionPayloadHeaderCapella{
|
|
ParentHash: payloadInterface.ParentHash(),
|
|
FeeRecipient: payloadInterface.FeeRecipient(),
|
|
StateRoot: payloadInterface.StateRoot(),
|
|
ReceiptsRoot: payloadInterface.ReceiptsRoot(),
|
|
LogsBloom: payloadInterface.LogsBloom(),
|
|
PrevRandao: payloadInterface.PrevRandao(),
|
|
BlockNumber: payloadInterface.BlockNumber(),
|
|
GasLimit: payloadInterface.GasLimit(),
|
|
GasUsed: payloadInterface.GasUsed(),
|
|
Timestamp: payloadInterface.Timestamp(),
|
|
ExtraData: payloadInterface.ExtraData(),
|
|
BaseFeePerGas: payloadInterface.BaseFeePerGas(),
|
|
BlockHash: payloadInterface.BlockHash(),
|
|
TransactionsRoot: transactionsRoot,
|
|
WithdrawalsRoot: withdrawalsRoot,
|
|
}
|
|
updateExecution, err := update.FinalizedHeader().Execution()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, execution, updateExecution.Proto(), "Finalized Block Execution is not equal")
|
|
})
|
|
|
|
t.Run("FinalizedBlock In Previous Fork", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Capella, util.WithFinalizedCheckpointInPrevFork())
|
|
update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, update, "update is nil")
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal")
|
|
|
|
l.CheckSyncAggregate(update.SyncAggregate())
|
|
l.CheckAttestedHeader(update.AttestedHeader())
|
|
|
|
finalizedBlockHeader, err := l.FinalizedBlock.Header()
|
|
require.NoError(t, err)
|
|
require.NotNil(t, update.FinalizedHeader(), "Finalized header is nil")
|
|
require.Equal(t, reflect.TypeOf(update.FinalizedHeader().Proto()), reflect.TypeFor[*pb.LightClientHeaderCapella](), "Finalized header is not Capella")
|
|
updateFinalizedHeaderBeacon := update.FinalizedHeader().Beacon()
|
|
require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal")
|
|
require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal")
|
|
fb, err := update.FinalityBranch()
|
|
require.NoError(t, err)
|
|
proof, err := l.AttestedState.FinalizedRootProof(l.Ctx)
|
|
require.NoError(t, err)
|
|
for i, leaf := range fb {
|
|
require.DeepSSZEqual(t, proof[i], leaf[:], "Leaf is not equal")
|
|
}
|
|
})
|
|
})
|
|
|
|
t.Run("Deneb", func(t *testing.T) {
|
|
|
|
t.Run("FinalizedBlock Not Nil", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Deneb)
|
|
|
|
update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, update, "update is nil")
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal")
|
|
|
|
l.CheckSyncAggregate(update.SyncAggregate())
|
|
l.CheckAttestedHeader(update.AttestedHeader())
|
|
|
|
//zeroHash := params.BeaconConfig().ZeroHash[:]
|
|
finalizedBlockHeader, err := l.FinalizedBlock.Header()
|
|
require.NoError(t, err)
|
|
require.NotNil(t, update.FinalizedHeader(), "Finalized header is nil")
|
|
updateFinalizedHeaderBeacon := update.FinalizedHeader().Beacon()
|
|
require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal")
|
|
require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal")
|
|
fb, err := update.FinalityBranch()
|
|
require.NoError(t, err)
|
|
proof, err := l.AttestedState.FinalizedRootProof(l.Ctx)
|
|
require.NoError(t, err)
|
|
for i, leaf := range fb {
|
|
require.DeepSSZEqual(t, proof[i], leaf[:], "Leaf is not equal")
|
|
}
|
|
|
|
// Check Execution BlockHash
|
|
payloadInterface, err := l.FinalizedBlock.Block().Body().Execution()
|
|
require.NoError(t, err)
|
|
transactionsRoot, err := payloadInterface.TransactionsRoot()
|
|
if errors.Is(err, consensustypes.ErrUnsupportedField) {
|
|
transactions, err := payloadInterface.Transactions()
|
|
require.NoError(t, err)
|
|
transactionsRootArray, err := ssz.TransactionsRoot(transactions)
|
|
require.NoError(t, err)
|
|
transactionsRoot = transactionsRootArray[:]
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
withdrawalsRoot, err := payloadInterface.WithdrawalsRoot()
|
|
if errors.Is(err, consensustypes.ErrUnsupportedField) {
|
|
withdrawals, err := payloadInterface.Withdrawals()
|
|
require.NoError(t, err)
|
|
withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload)
|
|
require.NoError(t, err)
|
|
withdrawalsRoot = withdrawalsRootArray[:]
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
execution := &v11.ExecutionPayloadHeaderDeneb{
|
|
ParentHash: payloadInterface.ParentHash(),
|
|
FeeRecipient: payloadInterface.FeeRecipient(),
|
|
StateRoot: payloadInterface.StateRoot(),
|
|
ReceiptsRoot: payloadInterface.ReceiptsRoot(),
|
|
LogsBloom: payloadInterface.LogsBloom(),
|
|
PrevRandao: payloadInterface.PrevRandao(),
|
|
BlockNumber: payloadInterface.BlockNumber(),
|
|
GasLimit: payloadInterface.GasLimit(),
|
|
GasUsed: payloadInterface.GasUsed(),
|
|
Timestamp: payloadInterface.Timestamp(),
|
|
ExtraData: payloadInterface.ExtraData(),
|
|
BaseFeePerGas: payloadInterface.BaseFeePerGas(),
|
|
BlockHash: payloadInterface.BlockHash(),
|
|
TransactionsRoot: transactionsRoot,
|
|
WithdrawalsRoot: withdrawalsRoot,
|
|
}
|
|
updateExecution, err := update.FinalizedHeader().Execution()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, execution, updateExecution.Proto(), "Finalized Block Execution is not equal")
|
|
})
|
|
|
|
t.Run("FinalizedBlock In Previous Fork", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Deneb, util.WithFinalizedCheckpointInPrevFork())
|
|
|
|
update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, update, "update is nil")
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal")
|
|
|
|
l.CheckSyncAggregate(update.SyncAggregate())
|
|
l.CheckAttestedHeader(update.AttestedHeader())
|
|
|
|
finalizedBlockHeader, err := l.FinalizedBlock.Header()
|
|
require.NoError(t, err)
|
|
require.NotNil(t, update.FinalizedHeader(), "Finalized header is nil")
|
|
updateFinalizedHeaderBeacon := update.FinalizedHeader().Beacon()
|
|
require.Equal(t, reflect.TypeOf(update.FinalizedHeader().Proto()), reflect.TypeFor[*pb.LightClientHeaderDeneb](), "Finalized header is not Deneb")
|
|
require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal")
|
|
require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal")
|
|
fb, err := update.FinalityBranch()
|
|
require.NoError(t, err)
|
|
proof, err := l.AttestedState.FinalizedRootProof(l.Ctx)
|
|
require.NoError(t, err)
|
|
for i, leaf := range fb {
|
|
require.DeepSSZEqual(t, proof[i], leaf[:], "Leaf is not equal")
|
|
}
|
|
|
|
// Check Execution BlockHash
|
|
payloadInterface, err := l.FinalizedBlock.Block().Body().Execution()
|
|
require.NoError(t, err)
|
|
transactionsRoot, err := payloadInterface.TransactionsRoot()
|
|
if errors.Is(err, consensustypes.ErrUnsupportedField) {
|
|
transactions, err := payloadInterface.Transactions()
|
|
require.NoError(t, err)
|
|
transactionsRootArray, err := ssz.TransactionsRoot(transactions)
|
|
require.NoError(t, err)
|
|
transactionsRoot = transactionsRootArray[:]
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
withdrawalsRoot, err := payloadInterface.WithdrawalsRoot()
|
|
if errors.Is(err, consensustypes.ErrUnsupportedField) {
|
|
withdrawals, err := payloadInterface.Withdrawals()
|
|
require.NoError(t, err)
|
|
withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload)
|
|
require.NoError(t, err)
|
|
withdrawalsRoot = withdrawalsRootArray[:]
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
execution := &v11.ExecutionPayloadHeaderDeneb{
|
|
ParentHash: payloadInterface.ParentHash(),
|
|
FeeRecipient: payloadInterface.FeeRecipient(),
|
|
StateRoot: payloadInterface.StateRoot(),
|
|
ReceiptsRoot: payloadInterface.ReceiptsRoot(),
|
|
LogsBloom: payloadInterface.LogsBloom(),
|
|
PrevRandao: payloadInterface.PrevRandao(),
|
|
BlockNumber: payloadInterface.BlockNumber(),
|
|
GasLimit: payloadInterface.GasLimit(),
|
|
GasUsed: payloadInterface.GasUsed(),
|
|
Timestamp: payloadInterface.Timestamp(),
|
|
ExtraData: payloadInterface.ExtraData(),
|
|
BaseFeePerGas: payloadInterface.BaseFeePerGas(),
|
|
BlockHash: payloadInterface.BlockHash(),
|
|
TransactionsRoot: transactionsRoot,
|
|
WithdrawalsRoot: withdrawalsRoot,
|
|
}
|
|
updateExecution, err := update.FinalizedHeader().Execution()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, execution, updateExecution.Proto(), "Finalized Block Execution is not equal")
|
|
})
|
|
})
|
|
|
|
t.Run("Electra", func(t *testing.T) {
|
|
t.Run("FinalizedBlock Not Nil", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Electra)
|
|
|
|
update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, update, "update is nil")
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal")
|
|
|
|
l.CheckSyncAggregate(update.SyncAggregate())
|
|
l.CheckAttestedHeader(update.AttestedHeader())
|
|
|
|
//zeroHash := params.BeaconConfig().ZeroHash[:]
|
|
finalizedBlockHeader, err := l.FinalizedBlock.Header()
|
|
require.NoError(t, err)
|
|
require.NotNil(t, update.FinalizedHeader(), "Finalized header is nil")
|
|
updateFinalizedHeaderBeacon := update.FinalizedHeader().Beacon()
|
|
require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal")
|
|
require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal")
|
|
fb, err := update.FinalityBranchElectra()
|
|
require.NoError(t, err)
|
|
proof, err := l.AttestedState.FinalizedRootProof(l.Ctx)
|
|
require.NoError(t, err)
|
|
for i, leaf := range fb {
|
|
require.DeepSSZEqual(t, proof[i], leaf[:], "Leaf is not equal")
|
|
}
|
|
|
|
// Check Execution BlockHash
|
|
payloadInterface, err := l.FinalizedBlock.Block().Body().Execution()
|
|
require.NoError(t, err)
|
|
transactionsRoot, err := payloadInterface.TransactionsRoot()
|
|
if errors.Is(err, consensustypes.ErrUnsupportedField) {
|
|
transactions, err := payloadInterface.Transactions()
|
|
require.NoError(t, err)
|
|
transactionsRootArray, err := ssz.TransactionsRoot(transactions)
|
|
require.NoError(t, err)
|
|
transactionsRoot = transactionsRootArray[:]
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
withdrawalsRoot, err := payloadInterface.WithdrawalsRoot()
|
|
if errors.Is(err, consensustypes.ErrUnsupportedField) {
|
|
withdrawals, err := payloadInterface.Withdrawals()
|
|
require.NoError(t, err)
|
|
withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload)
|
|
require.NoError(t, err)
|
|
withdrawalsRoot = withdrawalsRootArray[:]
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
execution := &v11.ExecutionPayloadHeaderDeneb{
|
|
ParentHash: payloadInterface.ParentHash(),
|
|
FeeRecipient: payloadInterface.FeeRecipient(),
|
|
StateRoot: payloadInterface.StateRoot(),
|
|
ReceiptsRoot: payloadInterface.ReceiptsRoot(),
|
|
LogsBloom: payloadInterface.LogsBloom(),
|
|
PrevRandao: payloadInterface.PrevRandao(),
|
|
BlockNumber: payloadInterface.BlockNumber(),
|
|
GasLimit: payloadInterface.GasLimit(),
|
|
GasUsed: payloadInterface.GasUsed(),
|
|
Timestamp: payloadInterface.Timestamp(),
|
|
ExtraData: payloadInterface.ExtraData(),
|
|
BaseFeePerGas: payloadInterface.BaseFeePerGas(),
|
|
BlockHash: payloadInterface.BlockHash(),
|
|
TransactionsRoot: transactionsRoot,
|
|
WithdrawalsRoot: withdrawalsRoot,
|
|
}
|
|
updateExecution, err := update.FinalizedHeader().Execution()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, execution, updateExecution.Proto(), "Finalized Block Execution is not equal")
|
|
})
|
|
|
|
t.Run("FinalizedBlock In Previous Fork", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Electra, util.WithFinalizedCheckpointInPrevFork())
|
|
|
|
update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, update, "update is nil")
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal")
|
|
|
|
l.CheckSyncAggregate(update.SyncAggregate())
|
|
l.CheckAttestedHeader(update.AttestedHeader())
|
|
|
|
finalizedBlockHeader, err := l.FinalizedBlock.Header()
|
|
require.NoError(t, err)
|
|
require.NotNil(t, update.FinalizedHeader(), "Finalized header is nil")
|
|
updateFinalizedHeaderBeacon := update.FinalizedHeader().Beacon()
|
|
require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal")
|
|
require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal")
|
|
fb, err := update.FinalityBranchElectra()
|
|
require.NoError(t, err)
|
|
proof, err := l.AttestedState.FinalizedRootProof(l.Ctx)
|
|
require.NoError(t, err)
|
|
for i, leaf := range fb {
|
|
require.DeepSSZEqual(t, proof[i], leaf[:], "Leaf is not equal")
|
|
}
|
|
|
|
// Check Execution BlockHash
|
|
payloadInterface, err := l.FinalizedBlock.Block().Body().Execution()
|
|
require.NoError(t, err)
|
|
transactionsRoot, err := payloadInterface.TransactionsRoot()
|
|
if errors.Is(err, consensustypes.ErrUnsupportedField) {
|
|
transactions, err := payloadInterface.Transactions()
|
|
require.NoError(t, err)
|
|
transactionsRootArray, err := ssz.TransactionsRoot(transactions)
|
|
require.NoError(t, err)
|
|
transactionsRoot = transactionsRootArray[:]
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
withdrawalsRoot, err := payloadInterface.WithdrawalsRoot()
|
|
if errors.Is(err, consensustypes.ErrUnsupportedField) {
|
|
withdrawals, err := payloadInterface.Withdrawals()
|
|
require.NoError(t, err)
|
|
withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload)
|
|
require.NoError(t, err)
|
|
withdrawalsRoot = withdrawalsRootArray[:]
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
execution := &v11.ExecutionPayloadHeaderDeneb{
|
|
ParentHash: payloadInterface.ParentHash(),
|
|
FeeRecipient: payloadInterface.FeeRecipient(),
|
|
StateRoot: payloadInterface.StateRoot(),
|
|
ReceiptsRoot: payloadInterface.ReceiptsRoot(),
|
|
LogsBloom: payloadInterface.LogsBloom(),
|
|
PrevRandao: payloadInterface.PrevRandao(),
|
|
BlockNumber: payloadInterface.BlockNumber(),
|
|
GasLimit: payloadInterface.GasLimit(),
|
|
GasUsed: payloadInterface.GasUsed(),
|
|
Timestamp: payloadInterface.Timestamp(),
|
|
ExtraData: payloadInterface.ExtraData(),
|
|
BaseFeePerGas: payloadInterface.BaseFeePerGas(),
|
|
BlockHash: payloadInterface.BlockHash(),
|
|
TransactionsRoot: transactionsRoot,
|
|
WithdrawalsRoot: withdrawalsRoot,
|
|
}
|
|
updateExecution, err := update.FinalizedHeader().Execution()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, execution, updateExecution.Proto(), "Finalized Block Execution is not equal")
|
|
})
|
|
})
|
|
|
|
t.Run("Fulu", func(t *testing.T) {
|
|
t.Run("FinalizedBlock Not Nil", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Fulu)
|
|
|
|
update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, update, "update is nil")
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal")
|
|
|
|
l.CheckSyncAggregate(update.SyncAggregate())
|
|
l.CheckAttestedHeader(update.AttestedHeader())
|
|
|
|
//zeroHash := params.BeaconConfig().ZeroHash[:]
|
|
finalizedBlockHeader, err := l.FinalizedBlock.Header()
|
|
require.NoError(t, err)
|
|
require.NotNil(t, update.FinalizedHeader(), "Finalized header is nil")
|
|
updateFinalizedHeaderBeacon := update.FinalizedHeader().Beacon()
|
|
require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal")
|
|
require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal")
|
|
fb, err := update.FinalityBranchElectra()
|
|
require.NoError(t, err)
|
|
proof, err := l.AttestedState.FinalizedRootProof(l.Ctx)
|
|
require.NoError(t, err)
|
|
for i, leaf := range fb {
|
|
require.DeepSSZEqual(t, proof[i], leaf[:], "Leaf is not equal")
|
|
}
|
|
|
|
// Check Execution BlockHash
|
|
payloadInterface, err := l.FinalizedBlock.Block().Body().Execution()
|
|
require.NoError(t, err)
|
|
transactionsRoot, err := payloadInterface.TransactionsRoot()
|
|
if errors.Is(err, consensustypes.ErrUnsupportedField) {
|
|
transactions, err := payloadInterface.Transactions()
|
|
require.NoError(t, err)
|
|
transactionsRootArray, err := ssz.TransactionsRoot(transactions)
|
|
require.NoError(t, err)
|
|
transactionsRoot = transactionsRootArray[:]
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
withdrawalsRoot, err := payloadInterface.WithdrawalsRoot()
|
|
if errors.Is(err, consensustypes.ErrUnsupportedField) {
|
|
withdrawals, err := payloadInterface.Withdrawals()
|
|
require.NoError(t, err)
|
|
withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload)
|
|
require.NoError(t, err)
|
|
withdrawalsRoot = withdrawalsRootArray[:]
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
execution := &v11.ExecutionPayloadHeaderDeneb{
|
|
ParentHash: payloadInterface.ParentHash(),
|
|
FeeRecipient: payloadInterface.FeeRecipient(),
|
|
StateRoot: payloadInterface.StateRoot(),
|
|
ReceiptsRoot: payloadInterface.ReceiptsRoot(),
|
|
LogsBloom: payloadInterface.LogsBloom(),
|
|
PrevRandao: payloadInterface.PrevRandao(),
|
|
BlockNumber: payloadInterface.BlockNumber(),
|
|
GasLimit: payloadInterface.GasLimit(),
|
|
GasUsed: payloadInterface.GasUsed(),
|
|
Timestamp: payloadInterface.Timestamp(),
|
|
ExtraData: payloadInterface.ExtraData(),
|
|
BaseFeePerGas: payloadInterface.BaseFeePerGas(),
|
|
BlockHash: payloadInterface.BlockHash(),
|
|
TransactionsRoot: transactionsRoot,
|
|
WithdrawalsRoot: withdrawalsRoot,
|
|
}
|
|
updateExecution, err := update.FinalizedHeader().Execution()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, execution, updateExecution.Proto(), "Finalized Block Execution is not equal")
|
|
})
|
|
|
|
t.Run("FinalizedBlock In Previous Fork", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Fulu, util.WithFinalizedCheckpointInPrevFork())
|
|
|
|
update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, update, "update is nil")
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal")
|
|
|
|
l.CheckSyncAggregate(update.SyncAggregate())
|
|
l.CheckAttestedHeader(update.AttestedHeader())
|
|
|
|
finalizedBlockHeader, err := l.FinalizedBlock.Header()
|
|
require.NoError(t, err)
|
|
require.NotNil(t, update.FinalizedHeader(), "Finalized header is nil")
|
|
updateFinalizedHeaderBeacon := update.FinalizedHeader().Beacon()
|
|
require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal")
|
|
require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal")
|
|
require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal")
|
|
fb, err := update.FinalityBranchElectra()
|
|
require.NoError(t, err)
|
|
proof, err := l.AttestedState.FinalizedRootProof(l.Ctx)
|
|
require.NoError(t, err)
|
|
for i, leaf := range fb {
|
|
require.DeepSSZEqual(t, proof[i], leaf[:], "Leaf is not equal")
|
|
}
|
|
|
|
// Check Execution BlockHash
|
|
payloadInterface, err := l.FinalizedBlock.Block().Body().Execution()
|
|
require.NoError(t, err)
|
|
transactionsRoot, err := payloadInterface.TransactionsRoot()
|
|
if errors.Is(err, consensustypes.ErrUnsupportedField) {
|
|
transactions, err := payloadInterface.Transactions()
|
|
require.NoError(t, err)
|
|
transactionsRootArray, err := ssz.TransactionsRoot(transactions)
|
|
require.NoError(t, err)
|
|
transactionsRoot = transactionsRootArray[:]
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
withdrawalsRoot, err := payloadInterface.WithdrawalsRoot()
|
|
if errors.Is(err, consensustypes.ErrUnsupportedField) {
|
|
withdrawals, err := payloadInterface.Withdrawals()
|
|
require.NoError(t, err)
|
|
withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload)
|
|
require.NoError(t, err)
|
|
withdrawalsRoot = withdrawalsRootArray[:]
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
execution := &v11.ExecutionPayloadHeaderDeneb{
|
|
ParentHash: payloadInterface.ParentHash(),
|
|
FeeRecipient: payloadInterface.FeeRecipient(),
|
|
StateRoot: payloadInterface.StateRoot(),
|
|
ReceiptsRoot: payloadInterface.ReceiptsRoot(),
|
|
LogsBloom: payloadInterface.LogsBloom(),
|
|
PrevRandao: payloadInterface.PrevRandao(),
|
|
BlockNumber: payloadInterface.BlockNumber(),
|
|
GasLimit: payloadInterface.GasLimit(),
|
|
GasUsed: payloadInterface.GasUsed(),
|
|
Timestamp: payloadInterface.Timestamp(),
|
|
ExtraData: payloadInterface.ExtraData(),
|
|
BaseFeePerGas: payloadInterface.BaseFeePerGas(),
|
|
BlockHash: payloadInterface.BlockHash(),
|
|
TransactionsRoot: transactionsRoot,
|
|
WithdrawalsRoot: withdrawalsRoot,
|
|
}
|
|
updateExecution, err := update.FinalizedHeader().Execution()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, execution, updateExecution.Proto(), "Finalized Block Execution is not equal")
|
|
})
|
|
})
|
|
}
|
|
|
|
func TestLightClient_BlockToLightClientHeader(t *testing.T) {
|
|
t.Run("Altair", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Altair)
|
|
|
|
header, err := lightClient.BlockToLightClientHeader(
|
|
l.Ctx,
|
|
version.Altair,
|
|
l.Block,
|
|
)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, header, "header is nil")
|
|
|
|
parentRoot := l.Block.Block().ParentRoot()
|
|
stateRoot := l.Block.Block().StateRoot()
|
|
bodyRoot, err := l.Block.Block().Body().HashTreeRoot()
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal")
|
|
require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal")
|
|
require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal")
|
|
require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal")
|
|
require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal")
|
|
})
|
|
|
|
t.Run("Bellatrix", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Bellatrix)
|
|
|
|
header, err := lightClient.BlockToLightClientHeader(
|
|
l.Ctx,
|
|
version.Bellatrix,
|
|
l.Block,
|
|
)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, header, "header is nil")
|
|
|
|
parentRoot := l.Block.Block().ParentRoot()
|
|
stateRoot := l.Block.Block().StateRoot()
|
|
bodyRoot, err := l.Block.Block().Body().HashTreeRoot()
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal")
|
|
require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal")
|
|
require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal")
|
|
require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal")
|
|
require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal")
|
|
})
|
|
|
|
t.Run("Capella", func(t *testing.T) {
|
|
t.Run("Non-Blinded Beacon Block", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Capella)
|
|
|
|
header, err := lightClient.BlockToLightClientHeader(
|
|
l.Ctx,
|
|
version.Capella,
|
|
l.Block,
|
|
)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, header, "header is nil")
|
|
|
|
parentRoot := l.Block.Block().ParentRoot()
|
|
stateRoot := l.Block.Block().StateRoot()
|
|
bodyRoot, err := l.Block.Block().Body().HashTreeRoot()
|
|
require.NoError(t, err)
|
|
|
|
payload, err := l.Block.Block().Body().Execution()
|
|
require.NoError(t, err)
|
|
|
|
transactionsRoot, err := lightClient.ComputeTransactionsRoot(payload)
|
|
require.NoError(t, err)
|
|
|
|
withdrawalsRoot, err := lightClient.ComputeWithdrawalsRoot(payload)
|
|
require.NoError(t, err)
|
|
|
|
executionHeader := &v11.ExecutionPayloadHeaderCapella{
|
|
ParentHash: payload.ParentHash(),
|
|
FeeRecipient: payload.FeeRecipient(),
|
|
StateRoot: payload.StateRoot(),
|
|
ReceiptsRoot: payload.ReceiptsRoot(),
|
|
LogsBloom: payload.LogsBloom(),
|
|
PrevRandao: payload.PrevRandao(),
|
|
BlockNumber: payload.BlockNumber(),
|
|
GasLimit: payload.GasLimit(),
|
|
GasUsed: payload.GasUsed(),
|
|
Timestamp: payload.Timestamp(),
|
|
ExtraData: payload.ExtraData(),
|
|
BaseFeePerGas: payload.BaseFeePerGas(),
|
|
BlockHash: payload.BlockHash(),
|
|
TransactionsRoot: transactionsRoot,
|
|
WithdrawalsRoot: withdrawalsRoot,
|
|
}
|
|
|
|
executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block())
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal")
|
|
require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal")
|
|
require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal")
|
|
require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal")
|
|
require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal")
|
|
|
|
headerExecution, err := header.Execution()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, executionHeader, headerExecution.Proto(), "Execution headers are not equal")
|
|
|
|
headerExecutionBranch, err := header.ExecutionBranch()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, executionPayloadProof, convertArrayToSlice(headerExecutionBranch), "Execution payload proofs are not equal")
|
|
})
|
|
|
|
t.Run("Blinded Beacon Block", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Capella, util.WithBlinded())
|
|
|
|
header, err := lightClient.BlockToLightClientHeader(
|
|
l.Ctx,
|
|
version.Capella,
|
|
l.Block,
|
|
)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, header, "header is nil")
|
|
|
|
parentRoot := l.Block.Block().ParentRoot()
|
|
stateRoot := l.Block.Block().StateRoot()
|
|
bodyRoot, err := l.Block.Block().Body().HashTreeRoot()
|
|
require.NoError(t, err)
|
|
|
|
payload, err := l.Block.Block().Body().Execution()
|
|
require.NoError(t, err)
|
|
|
|
transactionsRoot, err := payload.TransactionsRoot()
|
|
require.NoError(t, err)
|
|
|
|
withdrawalsRoot, err := payload.WithdrawalsRoot()
|
|
require.NoError(t, err)
|
|
|
|
executionHeader := &v11.ExecutionPayloadHeaderCapella{
|
|
ParentHash: payload.ParentHash(),
|
|
FeeRecipient: payload.FeeRecipient(),
|
|
StateRoot: payload.StateRoot(),
|
|
ReceiptsRoot: payload.ReceiptsRoot(),
|
|
LogsBloom: payload.LogsBloom(),
|
|
PrevRandao: payload.PrevRandao(),
|
|
BlockNumber: payload.BlockNumber(),
|
|
GasLimit: payload.GasLimit(),
|
|
GasUsed: payload.GasUsed(),
|
|
Timestamp: payload.Timestamp(),
|
|
ExtraData: payload.ExtraData(),
|
|
BaseFeePerGas: payload.BaseFeePerGas(),
|
|
BlockHash: payload.BlockHash(),
|
|
TransactionsRoot: transactionsRoot,
|
|
WithdrawalsRoot: withdrawalsRoot,
|
|
}
|
|
|
|
executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block())
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal")
|
|
require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal")
|
|
require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal")
|
|
require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal")
|
|
require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal")
|
|
|
|
headerExecution, err := header.Execution()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, executionHeader, headerExecution.Proto(), "Execution headers are not equal")
|
|
|
|
headerExecutionBranch, err := header.ExecutionBranch()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, executionPayloadProof, convertArrayToSlice(headerExecutionBranch), "Execution payload proofs are not equal")
|
|
})
|
|
})
|
|
|
|
t.Run("Deneb", func(t *testing.T) {
|
|
t.Run("Non-Blinded Beacon Block", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Deneb)
|
|
|
|
header, err := lightClient.BlockToLightClientHeader(
|
|
l.Ctx,
|
|
version.Deneb,
|
|
l.Block,
|
|
)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, header, "header is nil")
|
|
|
|
parentRoot := l.Block.Block().ParentRoot()
|
|
stateRoot := l.Block.Block().StateRoot()
|
|
bodyRoot, err := l.Block.Block().Body().HashTreeRoot()
|
|
require.NoError(t, err)
|
|
|
|
payload, err := l.Block.Block().Body().Execution()
|
|
require.NoError(t, err)
|
|
|
|
transactionsRoot, err := lightClient.ComputeTransactionsRoot(payload)
|
|
require.NoError(t, err)
|
|
|
|
withdrawalsRoot, err := lightClient.ComputeWithdrawalsRoot(payload)
|
|
require.NoError(t, err)
|
|
|
|
blobGasUsed, err := payload.BlobGasUsed()
|
|
require.NoError(t, err)
|
|
|
|
excessBlobGas, err := payload.ExcessBlobGas()
|
|
require.NoError(t, err)
|
|
|
|
executionHeader := &v11.ExecutionPayloadHeaderDeneb{
|
|
ParentHash: payload.ParentHash(),
|
|
FeeRecipient: payload.FeeRecipient(),
|
|
StateRoot: payload.StateRoot(),
|
|
ReceiptsRoot: payload.ReceiptsRoot(),
|
|
LogsBloom: payload.LogsBloom(),
|
|
PrevRandao: payload.PrevRandao(),
|
|
BlockNumber: payload.BlockNumber(),
|
|
GasLimit: payload.GasLimit(),
|
|
GasUsed: payload.GasUsed(),
|
|
Timestamp: payload.Timestamp(),
|
|
ExtraData: payload.ExtraData(),
|
|
BaseFeePerGas: payload.BaseFeePerGas(),
|
|
BlockHash: payload.BlockHash(),
|
|
TransactionsRoot: transactionsRoot,
|
|
WithdrawalsRoot: withdrawalsRoot,
|
|
BlobGasUsed: blobGasUsed,
|
|
ExcessBlobGas: excessBlobGas,
|
|
}
|
|
|
|
executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block())
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal")
|
|
require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal")
|
|
require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal")
|
|
require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal")
|
|
require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal")
|
|
|
|
headerExecution, err := header.Execution()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, executionHeader, headerExecution.Proto(), "Execution headers are not equal")
|
|
|
|
headerExecutionBranch, err := header.ExecutionBranch()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, executionPayloadProof, convertArrayToSlice(headerExecutionBranch), "Execution payload proofs are not equal")
|
|
})
|
|
|
|
t.Run("Blinded Beacon Block", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Deneb, util.WithBlinded())
|
|
|
|
header, err := lightClient.BlockToLightClientHeader(
|
|
l.Ctx,
|
|
version.Deneb,
|
|
l.Block,
|
|
)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, header, "header is nil")
|
|
|
|
parentRoot := l.Block.Block().ParentRoot()
|
|
stateRoot := l.Block.Block().StateRoot()
|
|
bodyRoot, err := l.Block.Block().Body().HashTreeRoot()
|
|
require.NoError(t, err)
|
|
|
|
payload, err := l.Block.Block().Body().Execution()
|
|
require.NoError(t, err)
|
|
|
|
transactionsRoot, err := payload.TransactionsRoot()
|
|
require.NoError(t, err)
|
|
|
|
withdrawalsRoot, err := payload.WithdrawalsRoot()
|
|
require.NoError(t, err)
|
|
|
|
blobGasUsed, err := payload.BlobGasUsed()
|
|
require.NoError(t, err)
|
|
|
|
excessBlobGas, err := payload.ExcessBlobGas()
|
|
require.NoError(t, err)
|
|
|
|
executionHeader := &v11.ExecutionPayloadHeaderDeneb{
|
|
ParentHash: payload.ParentHash(),
|
|
FeeRecipient: payload.FeeRecipient(),
|
|
StateRoot: payload.StateRoot(),
|
|
ReceiptsRoot: payload.ReceiptsRoot(),
|
|
LogsBloom: payload.LogsBloom(),
|
|
PrevRandao: payload.PrevRandao(),
|
|
BlockNumber: payload.BlockNumber(),
|
|
GasLimit: payload.GasLimit(),
|
|
GasUsed: payload.GasUsed(),
|
|
Timestamp: payload.Timestamp(),
|
|
ExtraData: payload.ExtraData(),
|
|
BaseFeePerGas: payload.BaseFeePerGas(),
|
|
BlockHash: payload.BlockHash(),
|
|
TransactionsRoot: transactionsRoot,
|
|
WithdrawalsRoot: withdrawalsRoot,
|
|
BlobGasUsed: blobGasUsed,
|
|
ExcessBlobGas: excessBlobGas,
|
|
}
|
|
|
|
executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block())
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal")
|
|
require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal")
|
|
require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal")
|
|
require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal")
|
|
require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal")
|
|
|
|
headerExecution, err := header.Execution()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, executionHeader, headerExecution.Proto(), "Execution headers are not equal")
|
|
|
|
headerExecutionBranch, err := header.ExecutionBranch()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, executionPayloadProof, convertArrayToSlice(headerExecutionBranch), "Execution payload proofs are not equal")
|
|
})
|
|
})
|
|
|
|
t.Run("Electra", func(t *testing.T) {
|
|
t.Run("Non-Blinded Beacon Block", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Electra)
|
|
|
|
header, err := lightClient.BlockToLightClientHeader(l.Ctx, version.Electra, l.Block)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, header, "header is nil")
|
|
|
|
parentRoot := l.Block.Block().ParentRoot()
|
|
stateRoot := l.Block.Block().StateRoot()
|
|
bodyRoot, err := l.Block.Block().Body().HashTreeRoot()
|
|
require.NoError(t, err)
|
|
|
|
payload, err := l.Block.Block().Body().Execution()
|
|
require.NoError(t, err)
|
|
|
|
transactionsRoot, err := lightClient.ComputeTransactionsRoot(payload)
|
|
require.NoError(t, err)
|
|
|
|
withdrawalsRoot, err := lightClient.ComputeWithdrawalsRoot(payload)
|
|
require.NoError(t, err)
|
|
|
|
blobGasUsed, err := payload.BlobGasUsed()
|
|
require.NoError(t, err)
|
|
|
|
excessBlobGas, err := payload.ExcessBlobGas()
|
|
require.NoError(t, err)
|
|
|
|
executionHeader := &v11.ExecutionPayloadHeaderDeneb{
|
|
ParentHash: payload.ParentHash(),
|
|
FeeRecipient: payload.FeeRecipient(),
|
|
StateRoot: payload.StateRoot(),
|
|
ReceiptsRoot: payload.ReceiptsRoot(),
|
|
LogsBloom: payload.LogsBloom(),
|
|
PrevRandao: payload.PrevRandao(),
|
|
BlockNumber: payload.BlockNumber(),
|
|
GasLimit: payload.GasLimit(),
|
|
GasUsed: payload.GasUsed(),
|
|
Timestamp: payload.Timestamp(),
|
|
ExtraData: payload.ExtraData(),
|
|
BaseFeePerGas: payload.BaseFeePerGas(),
|
|
BlockHash: payload.BlockHash(),
|
|
TransactionsRoot: transactionsRoot,
|
|
WithdrawalsRoot: withdrawalsRoot,
|
|
BlobGasUsed: blobGasUsed,
|
|
ExcessBlobGas: excessBlobGas,
|
|
}
|
|
|
|
executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block())
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal")
|
|
require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal")
|
|
require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal")
|
|
require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal")
|
|
require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal")
|
|
|
|
headerExecution, err := header.Execution()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, executionHeader, headerExecution.Proto(), "Execution headers are not equal")
|
|
|
|
headerExecutionBranch, err := header.ExecutionBranch()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, executionPayloadProof, convertArrayToSlice(headerExecutionBranch), "Execution payload proofs are not equal")
|
|
})
|
|
|
|
t.Run("Blinded Beacon Block", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Electra, util.WithBlinded())
|
|
|
|
header, err := lightClient.BlockToLightClientHeader(l.Ctx, version.Electra, l.Block)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, header, "header is nil")
|
|
|
|
parentRoot := l.Block.Block().ParentRoot()
|
|
stateRoot := l.Block.Block().StateRoot()
|
|
bodyRoot, err := l.Block.Block().Body().HashTreeRoot()
|
|
require.NoError(t, err)
|
|
|
|
payload, err := l.Block.Block().Body().Execution()
|
|
require.NoError(t, err)
|
|
|
|
transactionsRoot, err := payload.TransactionsRoot()
|
|
require.NoError(t, err)
|
|
|
|
withdrawalsRoot, err := payload.WithdrawalsRoot()
|
|
require.NoError(t, err)
|
|
|
|
blobGasUsed, err := payload.BlobGasUsed()
|
|
require.NoError(t, err)
|
|
|
|
excessBlobGas, err := payload.ExcessBlobGas()
|
|
require.NoError(t, err)
|
|
|
|
executionHeader := &v11.ExecutionPayloadHeaderDeneb{
|
|
ParentHash: payload.ParentHash(),
|
|
FeeRecipient: payload.FeeRecipient(),
|
|
StateRoot: payload.StateRoot(),
|
|
ReceiptsRoot: payload.ReceiptsRoot(),
|
|
LogsBloom: payload.LogsBloom(),
|
|
PrevRandao: payload.PrevRandao(),
|
|
BlockNumber: payload.BlockNumber(),
|
|
GasLimit: payload.GasLimit(),
|
|
GasUsed: payload.GasUsed(),
|
|
Timestamp: payload.Timestamp(),
|
|
ExtraData: payload.ExtraData(),
|
|
BaseFeePerGas: payload.BaseFeePerGas(),
|
|
BlockHash: payload.BlockHash(),
|
|
TransactionsRoot: transactionsRoot,
|
|
WithdrawalsRoot: withdrawalsRoot,
|
|
BlobGasUsed: blobGasUsed,
|
|
ExcessBlobGas: excessBlobGas,
|
|
}
|
|
|
|
executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block())
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal")
|
|
require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal")
|
|
require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal")
|
|
require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal")
|
|
require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal")
|
|
|
|
headerExecution, err := header.Execution()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, executionHeader, headerExecution.Proto(), "Execution headers are not equal")
|
|
|
|
headerExecutionBranch, err := header.ExecutionBranch()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, executionPayloadProof, convertArrayToSlice(headerExecutionBranch), "Execution payload proofs are not equal")
|
|
})
|
|
})
|
|
|
|
t.Run("Fulu", func(t *testing.T) {
|
|
t.Run("Non-Blinded Beacon Block", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Fulu)
|
|
|
|
header, err := lightClient.BlockToLightClientHeader(l.Ctx, version.Fulu, l.Block)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, header, "header is nil")
|
|
|
|
parentRoot := l.Block.Block().ParentRoot()
|
|
stateRoot := l.Block.Block().StateRoot()
|
|
bodyRoot, err := l.Block.Block().Body().HashTreeRoot()
|
|
require.NoError(t, err)
|
|
|
|
payload, err := l.Block.Block().Body().Execution()
|
|
require.NoError(t, err)
|
|
|
|
transactionsRoot, err := lightClient.ComputeTransactionsRoot(payload)
|
|
require.NoError(t, err)
|
|
|
|
withdrawalsRoot, err := lightClient.ComputeWithdrawalsRoot(payload)
|
|
require.NoError(t, err)
|
|
|
|
blobGasUsed, err := payload.BlobGasUsed()
|
|
require.NoError(t, err)
|
|
|
|
excessBlobGas, err := payload.ExcessBlobGas()
|
|
require.NoError(t, err)
|
|
|
|
executionHeader := &v11.ExecutionPayloadHeaderDeneb{
|
|
ParentHash: payload.ParentHash(),
|
|
FeeRecipient: payload.FeeRecipient(),
|
|
StateRoot: payload.StateRoot(),
|
|
ReceiptsRoot: payload.ReceiptsRoot(),
|
|
LogsBloom: payload.LogsBloom(),
|
|
PrevRandao: payload.PrevRandao(),
|
|
BlockNumber: payload.BlockNumber(),
|
|
GasLimit: payload.GasLimit(),
|
|
GasUsed: payload.GasUsed(),
|
|
Timestamp: payload.Timestamp(),
|
|
ExtraData: payload.ExtraData(),
|
|
BaseFeePerGas: payload.BaseFeePerGas(),
|
|
BlockHash: payload.BlockHash(),
|
|
TransactionsRoot: transactionsRoot,
|
|
WithdrawalsRoot: withdrawalsRoot,
|
|
BlobGasUsed: blobGasUsed,
|
|
ExcessBlobGas: excessBlobGas,
|
|
}
|
|
|
|
executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block())
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal")
|
|
require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal")
|
|
require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal")
|
|
require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal")
|
|
require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal")
|
|
|
|
headerExecution, err := header.Execution()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, executionHeader, headerExecution.Proto(), "Execution headers are not equal")
|
|
|
|
headerExecutionBranch, err := header.ExecutionBranch()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, executionPayloadProof, convertArrayToSlice(headerExecutionBranch), "Execution payload proofs are not equal")
|
|
})
|
|
|
|
t.Run("Blinded Beacon Block", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Fulu, util.WithBlinded())
|
|
|
|
header, err := lightClient.BlockToLightClientHeader(l.Ctx, version.Fulu, l.Block)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, header, "header is nil")
|
|
|
|
parentRoot := l.Block.Block().ParentRoot()
|
|
stateRoot := l.Block.Block().StateRoot()
|
|
bodyRoot, err := l.Block.Block().Body().HashTreeRoot()
|
|
require.NoError(t, err)
|
|
|
|
payload, err := l.Block.Block().Body().Execution()
|
|
require.NoError(t, err)
|
|
|
|
transactionsRoot, err := payload.TransactionsRoot()
|
|
require.NoError(t, err)
|
|
|
|
withdrawalsRoot, err := payload.WithdrawalsRoot()
|
|
require.NoError(t, err)
|
|
|
|
blobGasUsed, err := payload.BlobGasUsed()
|
|
require.NoError(t, err)
|
|
|
|
excessBlobGas, err := payload.ExcessBlobGas()
|
|
require.NoError(t, err)
|
|
|
|
executionHeader := &v11.ExecutionPayloadHeaderDeneb{
|
|
ParentHash: payload.ParentHash(),
|
|
FeeRecipient: payload.FeeRecipient(),
|
|
StateRoot: payload.StateRoot(),
|
|
ReceiptsRoot: payload.ReceiptsRoot(),
|
|
LogsBloom: payload.LogsBloom(),
|
|
PrevRandao: payload.PrevRandao(),
|
|
BlockNumber: payload.BlockNumber(),
|
|
GasLimit: payload.GasLimit(),
|
|
GasUsed: payload.GasUsed(),
|
|
Timestamp: payload.Timestamp(),
|
|
ExtraData: payload.ExtraData(),
|
|
BaseFeePerGas: payload.BaseFeePerGas(),
|
|
BlockHash: payload.BlockHash(),
|
|
TransactionsRoot: transactionsRoot,
|
|
WithdrawalsRoot: withdrawalsRoot,
|
|
BlobGasUsed: blobGasUsed,
|
|
ExcessBlobGas: excessBlobGas,
|
|
}
|
|
|
|
executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block())
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal")
|
|
require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal")
|
|
require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal")
|
|
require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal")
|
|
require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal")
|
|
|
|
headerExecution, err := header.Execution()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, executionHeader, headerExecution.Proto(), "Execution headers are not equal")
|
|
|
|
headerExecutionBranch, err := header.ExecutionBranch()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, executionPayloadProof, convertArrayToSlice(headerExecutionBranch), "Execution payload proofs are not equal")
|
|
})
|
|
})
|
|
|
|
t.Run("Capella fork with Altair block", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Altair)
|
|
|
|
header, err := lightClient.BlockToLightClientHeader(
|
|
l.Ctx,
|
|
version.Capella,
|
|
l.Block)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, header, "header is nil")
|
|
|
|
parentRoot := l.Block.Block().ParentRoot()
|
|
stateRoot := l.Block.Block().StateRoot()
|
|
bodyRoot, err := l.Block.Block().Body().HashTreeRoot()
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal")
|
|
require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal")
|
|
require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal")
|
|
require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal")
|
|
require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal")
|
|
})
|
|
|
|
t.Run("Deneb fork with Altair block", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Altair)
|
|
|
|
header, err := lightClient.BlockToLightClientHeader(
|
|
l.Ctx,
|
|
version.Deneb,
|
|
l.Block)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, header, "header is nil")
|
|
|
|
parentRoot := l.Block.Block().ParentRoot()
|
|
stateRoot := l.Block.Block().StateRoot()
|
|
bodyRoot, err := l.Block.Block().Body().HashTreeRoot()
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal")
|
|
require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal")
|
|
require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal")
|
|
require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal")
|
|
require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal")
|
|
})
|
|
|
|
t.Run("Deneb fork with Capella block", func(t *testing.T) {
|
|
t.Run("Non-Blinded Beacon Block", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Capella)
|
|
|
|
header, err := lightClient.BlockToLightClientHeader(
|
|
l.Ctx,
|
|
version.Deneb,
|
|
l.Block)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, header, "header is nil")
|
|
|
|
parentRoot := l.Block.Block().ParentRoot()
|
|
stateRoot := l.Block.Block().StateRoot()
|
|
bodyRoot, err := l.Block.Block().Body().HashTreeRoot()
|
|
require.NoError(t, err)
|
|
|
|
payload, err := l.Block.Block().Body().Execution()
|
|
require.NoError(t, err)
|
|
|
|
transactionsRoot, err := lightClient.ComputeTransactionsRoot(payload)
|
|
require.NoError(t, err)
|
|
|
|
withdrawalsRoot, err := lightClient.ComputeWithdrawalsRoot(payload)
|
|
require.NoError(t, err)
|
|
|
|
executionHeader := &v11.ExecutionPayloadHeaderDeneb{
|
|
ParentHash: payload.ParentHash(),
|
|
FeeRecipient: payload.FeeRecipient(),
|
|
StateRoot: payload.StateRoot(),
|
|
ReceiptsRoot: payload.ReceiptsRoot(),
|
|
LogsBloom: payload.LogsBloom(),
|
|
PrevRandao: payload.PrevRandao(),
|
|
BlockNumber: payload.BlockNumber(),
|
|
GasLimit: payload.GasLimit(),
|
|
GasUsed: payload.GasUsed(),
|
|
Timestamp: payload.Timestamp(),
|
|
ExtraData: payload.ExtraData(),
|
|
BaseFeePerGas: payload.BaseFeePerGas(),
|
|
BlockHash: payload.BlockHash(),
|
|
TransactionsRoot: transactionsRoot,
|
|
WithdrawalsRoot: withdrawalsRoot,
|
|
}
|
|
|
|
executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block())
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal")
|
|
require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal")
|
|
require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal")
|
|
require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal")
|
|
require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal")
|
|
|
|
headerExecution, err := header.Execution()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, executionHeader, headerExecution.Proto(), "Execution headers are not equal")
|
|
|
|
headerExecutionBranch, err := header.ExecutionBranch()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, executionPayloadProof, convertArrayToSlice(headerExecutionBranch), "Execution payload proofs are not equal")
|
|
})
|
|
|
|
t.Run("Blinded Beacon Block", func(t *testing.T) {
|
|
l := util.NewTestLightClient(t, version.Capella, util.WithBlinded())
|
|
|
|
header, err := lightClient.BlockToLightClientHeader(
|
|
l.Ctx,
|
|
version.Deneb,
|
|
l.Block)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, header, "header is nil")
|
|
|
|
parentRoot := l.Block.Block().ParentRoot()
|
|
stateRoot := l.Block.Block().StateRoot()
|
|
bodyRoot, err := l.Block.Block().Body().HashTreeRoot()
|
|
require.NoError(t, err)
|
|
|
|
payload, err := l.Block.Block().Body().Execution()
|
|
require.NoError(t, err)
|
|
|
|
transactionsRoot, err := payload.TransactionsRoot()
|
|
require.NoError(t, err)
|
|
|
|
withdrawalsRoot, err := payload.WithdrawalsRoot()
|
|
require.NoError(t, err)
|
|
|
|
executionHeader := &v11.ExecutionPayloadHeaderDeneb{
|
|
ParentHash: payload.ParentHash(),
|
|
FeeRecipient: payload.FeeRecipient(),
|
|
StateRoot: payload.StateRoot(),
|
|
ReceiptsRoot: payload.ReceiptsRoot(),
|
|
LogsBloom: payload.LogsBloom(),
|
|
PrevRandao: payload.PrevRandao(),
|
|
BlockNumber: payload.BlockNumber(),
|
|
GasLimit: payload.GasLimit(),
|
|
GasUsed: payload.GasUsed(),
|
|
Timestamp: payload.Timestamp(),
|
|
ExtraData: payload.ExtraData(),
|
|
BaseFeePerGas: payload.BaseFeePerGas(),
|
|
BlockHash: payload.BlockHash(),
|
|
TransactionsRoot: transactionsRoot,
|
|
WithdrawalsRoot: withdrawalsRoot,
|
|
}
|
|
|
|
executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block())
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal")
|
|
require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal")
|
|
require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal")
|
|
require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal")
|
|
require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal")
|
|
|
|
headerExecution, err := header.Execution()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, executionHeader, headerExecution.Proto(), "Execution headers are not equal")
|
|
|
|
headerExecutionBranch, err := header.ExecutionBranch()
|
|
require.NoError(t, err)
|
|
require.DeepSSZEqual(t, executionPayloadProof, convertArrayToSlice(headerExecutionBranch), "Execution payload proofs are not equal")
|
|
})
|
|
})
|
|
}
|
|
|
|
func convertArrayToSlice(arr [4][32]uint8) [][]uint8 {
|
|
slice := make([][]uint8, len(arr))
|
|
for i := range arr {
|
|
slice[i] = arr[i][:]
|
|
}
|
|
return slice
|
|
}
|
|
|
|
// When the update has relevant sync committee
|
|
func createNonEmptySyncCommitteeBranch() [][]byte {
|
|
res := make([][]byte, fieldparams.SyncCommitteeBranchDepth)
|
|
res[0] = []byte(strings.Repeat("x", 32))
|
|
for i := 1; i < len(res); i++ {
|
|
res[i] = make([]byte, fieldparams.RootLength)
|
|
}
|
|
return res
|
|
}
|
|
|
|
// When the update has finality
|
|
func createNonEmptyFinalityBranch() [][]byte {
|
|
res := make([][]byte, fieldparams.FinalityBranchDepth)
|
|
res[0] = []byte(strings.Repeat("x", 32))
|
|
for i := 1; i < fieldparams.FinalityBranchDepth; i++ {
|
|
res[i] = make([]byte, 32)
|
|
}
|
|
return res
|
|
}
|
|
|
|
func TestIsBetterUpdate(t *testing.T) {
|
|
blk, err := blocks.NewSignedBeaconBlock(util.NewBeaconBlockAltair())
|
|
require.NoError(t, err)
|
|
|
|
t.Run("new has supermajority but old doesn't", func(t *testing.T) {
|
|
oldUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
newUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
|
|
oldUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,0,1,1,1,1,1,0]
|
|
})
|
|
newUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b11111100, 0b1}, // [0,0,1,1,1,1,1,1]
|
|
})
|
|
|
|
result, err := lightClient.IsBetterUpdate(newUpdate, oldUpdate)
|
|
require.NoError(t, err)
|
|
require.Equal(t, true, result)
|
|
})
|
|
|
|
t.Run("old has supermajority but new doesn't", func(t *testing.T) {
|
|
oldUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
newUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
|
|
oldUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b11111100, 0b1}, // [0,0,1,1,1,1,1,1]
|
|
})
|
|
newUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,0,1,1,1,1,1,0]
|
|
})
|
|
|
|
result, err := lightClient.IsBetterUpdate(newUpdate, oldUpdate)
|
|
require.NoError(t, err)
|
|
require.Equal(t, false, result)
|
|
})
|
|
|
|
t.Run("new doesn't have supermajority and newNumActiveParticipants is greater than oldNumActiveParticipants", func(t *testing.T) {
|
|
oldUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
newUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
|
|
oldUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
newUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,0,1,1,1,1,1,0]
|
|
})
|
|
|
|
result, err := lightClient.IsBetterUpdate(newUpdate, oldUpdate)
|
|
require.NoError(t, err)
|
|
require.Equal(t, true, result)
|
|
})
|
|
|
|
t.Run("new doesn't have supermajority and newNumActiveParticipants is lesser than oldNumActiveParticipants", func(t *testing.T) {
|
|
oldUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
newUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
|
|
oldUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,0,1,1,1,1,1,0]
|
|
})
|
|
newUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
|
|
result, err := lightClient.IsBetterUpdate(newUpdate, oldUpdate)
|
|
require.NoError(t, err)
|
|
require.Equal(t, false, result)
|
|
})
|
|
|
|
t.Run("new has relevant sync committee but old doesn't", func(t *testing.T) {
|
|
oldUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
newUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
|
|
oldUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
oldAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 1000000,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetAttestedHeader(oldAttestedHeader)
|
|
require.NoError(t, err)
|
|
oldUpdate.SetSignatureSlot(9999)
|
|
|
|
newUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
newAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 1000001,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetAttestedHeader(newAttestedHeader)
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch())
|
|
require.NoError(t, err)
|
|
newUpdate.SetSignatureSlot(1000000)
|
|
|
|
result, err := lightClient.IsBetterUpdate(newUpdate, oldUpdate)
|
|
require.NoError(t, err)
|
|
require.Equal(t, true, result)
|
|
})
|
|
|
|
t.Run("old has relevant sync committee but new doesn't", func(t *testing.T) {
|
|
oldUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
newUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
|
|
oldUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
oldAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 1000001,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetAttestedHeader(oldAttestedHeader)
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch())
|
|
require.NoError(t, err)
|
|
oldUpdate.SetSignatureSlot(1000000)
|
|
|
|
newUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
newAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 1000000,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetAttestedHeader(newAttestedHeader)
|
|
require.NoError(t, err)
|
|
newUpdate.SetSignatureSlot(9999)
|
|
|
|
result, err := lightClient.IsBetterUpdate(newUpdate, oldUpdate)
|
|
require.NoError(t, err)
|
|
require.Equal(t, false, result)
|
|
})
|
|
|
|
t.Run("new has finality but old doesn't", func(t *testing.T) {
|
|
oldUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
newUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
|
|
oldUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
oldAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 1000000,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetAttestedHeader(oldAttestedHeader)
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch())
|
|
require.NoError(t, err)
|
|
oldUpdate.SetSignatureSlot(9999)
|
|
|
|
newUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
newAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 1000000,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetAttestedHeader(newAttestedHeader)
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch())
|
|
require.NoError(t, err)
|
|
newUpdate.SetSignatureSlot(9999)
|
|
err = newUpdate.SetFinalityBranch(createNonEmptyFinalityBranch())
|
|
require.NoError(t, err)
|
|
|
|
result, err := lightClient.IsBetterUpdate(newUpdate, oldUpdate)
|
|
require.NoError(t, err)
|
|
require.Equal(t, true, result)
|
|
})
|
|
|
|
t.Run("old has finality but new doesn't", func(t *testing.T) {
|
|
oldUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
newUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
|
|
oldUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
oldAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 1000000,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetAttestedHeader(oldAttestedHeader)
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch())
|
|
require.NoError(t, err)
|
|
oldUpdate.SetSignatureSlot(9999)
|
|
err = oldUpdate.SetFinalityBranch(createNonEmptyFinalityBranch())
|
|
require.NoError(t, err)
|
|
|
|
newUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
newAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 1000000,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetAttestedHeader(newAttestedHeader)
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch())
|
|
require.NoError(t, err)
|
|
newUpdate.SetSignatureSlot(9999)
|
|
|
|
result, err := lightClient.IsBetterUpdate(newUpdate, oldUpdate)
|
|
require.NoError(t, err)
|
|
require.Equal(t, false, result)
|
|
})
|
|
|
|
t.Run("new has finality and sync committee finality both but old doesn't have sync committee finality", func(t *testing.T) {
|
|
oldUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
newUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
|
|
oldUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
oldAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 1000000,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetAttestedHeader(oldAttestedHeader)
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch())
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetFinalityBranch(createNonEmptyFinalityBranch())
|
|
require.NoError(t, err)
|
|
oldUpdate.SetSignatureSlot(9999)
|
|
oldFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 9999,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetFinalizedHeader(oldFinalizedHeader)
|
|
require.NoError(t, err)
|
|
|
|
newUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,0,1,1,1,1,1,0]
|
|
})
|
|
newAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 1000000,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetAttestedHeader(newAttestedHeader)
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch())
|
|
require.NoError(t, err)
|
|
newUpdate.SetSignatureSlot(999999)
|
|
err = newUpdate.SetFinalityBranch(createNonEmptyFinalityBranch())
|
|
require.NoError(t, err)
|
|
newFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 999999,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetFinalizedHeader(newFinalizedHeader)
|
|
require.NoError(t, err)
|
|
|
|
result, err := lightClient.IsBetterUpdate(newUpdate, oldUpdate)
|
|
require.NoError(t, err)
|
|
require.Equal(t, true, result)
|
|
})
|
|
|
|
t.Run("new has finality but doesn't have sync committee finality and old has sync committee finality", func(t *testing.T) {
|
|
oldUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
newUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
|
|
oldUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
oldAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 1000000,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetAttestedHeader(oldAttestedHeader)
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch())
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetFinalityBranch(createNonEmptyFinalityBranch())
|
|
require.NoError(t, err)
|
|
oldUpdate.SetSignatureSlot(999999)
|
|
oldFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 999999,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetFinalizedHeader(oldFinalizedHeader)
|
|
require.NoError(t, err)
|
|
|
|
newUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
newAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 1000000,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetAttestedHeader(newAttestedHeader)
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch())
|
|
require.NoError(t, err)
|
|
newUpdate.SetSignatureSlot(9999)
|
|
err = newUpdate.SetFinalityBranch(createNonEmptyFinalityBranch())
|
|
require.NoError(t, err)
|
|
newFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 9999,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetFinalizedHeader(newFinalizedHeader)
|
|
require.NoError(t, err)
|
|
|
|
result, err := lightClient.IsBetterUpdate(newUpdate, oldUpdate)
|
|
require.NoError(t, err)
|
|
require.Equal(t, false, result)
|
|
})
|
|
|
|
t.Run("new has more active participants than old", func(t *testing.T) {
|
|
oldUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
newUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
|
|
oldUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
newUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,1,1,1,1,1,0,0]
|
|
})
|
|
|
|
result, err := lightClient.IsBetterUpdate(newUpdate, oldUpdate)
|
|
require.NoError(t, err)
|
|
require.Equal(t, true, result)
|
|
})
|
|
|
|
t.Run("new has less active participants than old", func(t *testing.T) {
|
|
oldUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
newUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
|
|
oldUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,1,1,1,1,1,0,0]
|
|
})
|
|
newUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
|
|
result, err := lightClient.IsBetterUpdate(newUpdate, oldUpdate)
|
|
require.NoError(t, err)
|
|
require.Equal(t, false, result)
|
|
})
|
|
|
|
t.Run("new's attested header's slot is lesser than old's attested header's slot", func(t *testing.T) {
|
|
oldUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
newUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
|
|
oldUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
oldAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 1000000,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetAttestedHeader(oldAttestedHeader)
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch())
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetFinalityBranch(createNonEmptyFinalityBranch())
|
|
require.NoError(t, err)
|
|
oldUpdate.SetSignatureSlot(9999)
|
|
oldFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 9999,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetFinalizedHeader(oldFinalizedHeader)
|
|
require.NoError(t, err)
|
|
|
|
newUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
newAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 999999,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetAttestedHeader(newAttestedHeader)
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch())
|
|
require.NoError(t, err)
|
|
newUpdate.SetSignatureSlot(9999)
|
|
err = newUpdate.SetFinalityBranch(createNonEmptyFinalityBranch())
|
|
require.NoError(t, err)
|
|
newFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 9999,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetFinalizedHeader(newFinalizedHeader)
|
|
require.NoError(t, err)
|
|
|
|
result, err := lightClient.IsBetterUpdate(newUpdate, oldUpdate)
|
|
require.NoError(t, err)
|
|
require.Equal(t, true, result)
|
|
})
|
|
|
|
t.Run("new's attested header's slot is greater than old's attested header's slot", func(t *testing.T) {
|
|
oldUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
newUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
|
|
oldUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
oldAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 999999,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetAttestedHeader(oldAttestedHeader)
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch())
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetFinalityBranch(createNonEmptyFinalityBranch())
|
|
require.NoError(t, err)
|
|
oldUpdate.SetSignatureSlot(9999)
|
|
oldFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 9999,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetFinalizedHeader(oldFinalizedHeader)
|
|
require.NoError(t, err)
|
|
|
|
newUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
newAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 1000000,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetAttestedHeader(newAttestedHeader)
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch())
|
|
require.NoError(t, err)
|
|
newUpdate.SetSignatureSlot(9999)
|
|
err = newUpdate.SetFinalityBranch(createNonEmptyFinalityBranch())
|
|
require.NoError(t, err)
|
|
newFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 9999,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetFinalizedHeader(newFinalizedHeader)
|
|
require.NoError(t, err)
|
|
|
|
result, err := lightClient.IsBetterUpdate(newUpdate, oldUpdate)
|
|
require.NoError(t, err)
|
|
require.Equal(t, false, result)
|
|
})
|
|
|
|
t.Run("none of the above conditions are met and new signature's slot is less than old signature's slot", func(t *testing.T) {
|
|
oldUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
newUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
|
|
oldUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
oldAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 1000000,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetAttestedHeader(oldAttestedHeader)
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch())
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetFinalityBranch(createNonEmptyFinalityBranch())
|
|
require.NoError(t, err)
|
|
oldUpdate.SetSignatureSlot(9999)
|
|
oldFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 9999,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetFinalizedHeader(oldFinalizedHeader)
|
|
require.NoError(t, err)
|
|
|
|
newUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
newAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 1000000,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetAttestedHeader(newAttestedHeader)
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch())
|
|
require.NoError(t, err)
|
|
newUpdate.SetSignatureSlot(9998)
|
|
err = newUpdate.SetFinalityBranch(createNonEmptyFinalityBranch())
|
|
require.NoError(t, err)
|
|
newFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 9999,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetFinalizedHeader(newFinalizedHeader)
|
|
require.NoError(t, err)
|
|
|
|
result, err := lightClient.IsBetterUpdate(newUpdate, oldUpdate)
|
|
require.NoError(t, err)
|
|
require.Equal(t, true, result)
|
|
})
|
|
|
|
t.Run("none of the above conditions are met and new signature's slot is greater than old signature's slot", func(t *testing.T) {
|
|
oldUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
newUpdate, err := lightClient.CreateDefaultLightClientUpdate(blk)
|
|
require.NoError(t, err)
|
|
|
|
oldUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
oldAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 1000000,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetAttestedHeader(oldAttestedHeader)
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch())
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetFinalityBranch(createNonEmptyFinalityBranch())
|
|
require.NoError(t, err)
|
|
oldUpdate.SetSignatureSlot(9998)
|
|
oldFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 9999,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = oldUpdate.SetFinalizedHeader(oldFinalizedHeader)
|
|
require.NoError(t, err)
|
|
|
|
newUpdate.SetSyncAggregate(&pb.SyncAggregate{
|
|
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
|
})
|
|
newAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 1000000,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetAttestedHeader(newAttestedHeader)
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch())
|
|
require.NoError(t, err)
|
|
newUpdate.SetSignatureSlot(9999)
|
|
err = newUpdate.SetFinalityBranch(createNonEmptyFinalityBranch())
|
|
require.NoError(t, err)
|
|
newFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{
|
|
Beacon: &pb.BeaconBlockHeader{
|
|
Slot: 9999,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
err = newUpdate.SetFinalizedHeader(newFinalizedHeader)
|
|
require.NoError(t, err)
|
|
|
|
result, err := lightClient.IsBetterUpdate(newUpdate, oldUpdate)
|
|
require.NoError(t, err)
|
|
require.Equal(t, false, result)
|
|
})
|
|
}
|