diff --git a/relayer/magefile.go b/relayer/magefile.go index ce607b0e9..4aa5c4f15 100644 --- a/relayer/magefile.go +++ b/relayer/magefile.go @@ -13,7 +13,7 @@ func Build() { } func BuildMain() error { - err := sh.Run("sszgen", "--path", "relays/beacon/state", "--objs", "BlockRootsContainerMainnet,TransactionsRootContainer,WithdrawalsRootContainerMainnet,BeaconStateDenebMainnet,BeaconBlockDenebMainnet,SignedBeaconBlockDeneb,SignedBeaconBlockElectra,BeaconStateElectra,BeaconBlockElectra") + err := sh.Run("sszgen", "--path", "relays/beacon/state", "--objs", "BlockRootsContainerMainnet,TransactionsRootContainer,WithdrawalsRootContainerMainnet,BeaconStateDenebMainnet,BeaconBlockDenebMainnet,SignedBeaconBlockDeneb,SignedBeaconBlockElectra,BeaconStateElectra,BeaconBlockElectra,BeaconStateFulu") if err != nil { return err } diff --git a/relayer/relays/beacon/config/config.go b/relayer/relays/beacon/config/config.go index 614bc63e5..bf42bf4af 100644 --- a/relayer/relays/beacon/config/config.go +++ b/relayer/relays/beacon/config/config.go @@ -20,6 +20,7 @@ type SpecSettings struct { type ForkVersions struct { Deneb uint64 `mapstructure:"deneb"` Electra uint64 `mapstructure:"electra"` + Fulu uint64 `mapstructure:"fulu"` } type SourceConfig struct { diff --git a/relayer/relays/beacon/header/header_test.go b/relayer/relays/beacon/header/header_test.go index c1ec91902..996d46dab 100644 --- a/relayer/relays/beacon/header/header_test.go +++ b/relayer/relays/beacon/header/header_test.go @@ -23,10 +23,7 @@ func TestSyncInterimFinalizedUpdate_WithDataFromAPI(t *testing.T) { settings := config.SpecSettings{ SlotsInEpoch: 32, EpochsPerSyncCommitteePeriod: 256, - ForkVersions: config.ForkVersions{ - Deneb: 0, - Electra: 800000, - }, + ForkVersions: forkVersions(), } p := protocol.New(settings, MaxRedundancy) client := mock.API{} @@ -84,10 +81,7 @@ func TestSyncInterimFinalizedUpdate_WithDataFromStore(t *testing.T) { settings := config.SpecSettings{ SlotsInEpoch: 32, EpochsPerSyncCommitteePeriod: 256, - ForkVersions: config.ForkVersions{ - Deneb: 0, - Electra: 800000, - }, + ForkVersions: forkVersions(), } p := protocol.New(settings, MaxRedundancy) client := mock.API{} @@ -153,10 +147,7 @@ func TestSyncInterimFinalizedUpdate_WithDataFromStoreWithDifferentBlocks(t *test settings := config.SpecSettings{ SlotsInEpoch: 32, EpochsPerSyncCommitteePeriod: 256, - ForkVersions: config.ForkVersions{ - Deneb: 0, - Electra: 800000, - }, + ForkVersions: forkVersions(), } p := protocol.New(settings, MaxRedundancy) client := mock.API{} @@ -222,10 +213,7 @@ func TestSyncInterimFinalizedUpdate_BeaconStateNotAvailableInAPIAndStore(t *test settings := config.SpecSettings{ SlotsInEpoch: 32, EpochsPerSyncCommitteePeriod: 256, - ForkVersions: config.ForkVersions{ - Deneb: 0, - Electra: 800000, - }, + ForkVersions: forkVersions(), } p := protocol.New(settings, MaxRedundancy) client := mock.API{} @@ -269,10 +257,7 @@ func TestSyncInterimFinalizedUpdate_NoValidBlocksFound(t *testing.T) { settings := config.SpecSettings{ SlotsInEpoch: 32, EpochsPerSyncCommitteePeriod: 256, - ForkVersions: config.ForkVersions{ - Deneb: 0, - Electra: 800000, - }, + ForkVersions: forkVersions(), } p := protocol.New(settings, MaxRedundancy) client := mock.API{} @@ -440,3 +425,11 @@ func TestFindLatestCheckPoint(t *testing.T) { assert.Equal(t, headerIndex4, header.BeaconBlockRoot) assert.Equal(t, uint64(46), header.BeaconSlot) } + +func forkVersions() config.ForkVersions { + return config.ForkVersions{ + Deneb: 0, + Electra: 800000, + Fulu: 1000000, + } +} diff --git a/relayer/relays/beacon/header/syncer/syncer.go b/relayer/relays/beacon/header/syncer/syncer.go index 194e31fbb..fc02f564a 100644 --- a/relayer/relays/beacon/header/syncer/syncer.go +++ b/relayer/relays/beacon/header/syncer/syncer.go @@ -316,7 +316,9 @@ func (s *Syncer) GetBlockRoots(slot uint64) (scale.BlockRootProof, error) { forkVersion := s.protocol.ForkVersion(slot) blockRootsContainer = &state.BlockRootsContainerMainnet{} - if forkVersion == protocol.Electra { + if forkVersion == protocol.Fulu { + beaconState = &state.BeaconStateFulu{} + } else if forkVersion == protocol.Electra { beaconState = &state.BeaconStateElectra{} } else { beaconState = &state.BeaconStateDenebMainnet{} @@ -557,7 +559,7 @@ func (s *Syncer) GetHeaderUpdate(blockRoot common.Hash, checkpoint *cache.Proof) var signedBlock state.SignedBeaconBlock forkVersion := s.protocol.ForkVersion(slot) - if forkVersion == protocol.Electra { + if forkVersion == protocol.Fulu || forkVersion == protocol.Electra { signedBlock = &state.SignedBeaconBlockElectra{} } else { signedBlock = &state.SignedBeaconBlockDeneb{} @@ -635,7 +637,9 @@ func (s *Syncer) getBeaconStateAtSlot(slot uint64) (state.BeaconState, error) { func (s *Syncer) UnmarshalBeaconState(slot uint64, data []byte) (state.BeaconState, error) { var beaconState state.BeaconState forkVersion := s.protocol.ForkVersion(slot) - if forkVersion == protocol.Electra { + if forkVersion == protocol.Fulu { + beaconState = &state.BeaconStateFulu{} + } else if forkVersion == protocol.Electra { beaconState = &state.BeaconStateElectra{} } else { beaconState = &state.BeaconStateDenebMainnet{} diff --git a/relayer/relays/beacon/protocol/protocol.go b/relayer/relays/beacon/protocol/protocol.go index 24a1b44a2..6dc785394 100644 --- a/relayer/relays/beacon/protocol/protocol.go +++ b/relayer/relays/beacon/protocol/protocol.go @@ -81,46 +81,58 @@ type ForkVersion string const ( Deneb ForkVersion = "Deneb" Electra ForkVersion = "Electra" + Fulu ForkVersion = "Fulu" ) func (p *Protocol) ForkVersion(slot uint64) ForkVersion { epoch := p.ComputeEpochAtSlot(slot) - if epoch >= p.Settings.ForkVersions.Electra { - return Electra + var fv ForkVersion + if epoch >= p.Settings.ForkVersions.Fulu { + fv = Fulu + } else if epoch >= p.Settings.ForkVersions.Electra { + fv = Electra + } else { + fv = Deneb } - return Deneb + log.WithField("ForkVersion", fv).Info("Found fork version") + return fv } func (p *Protocol) BlockRootGeneralizedIndex(slot uint64) int { - if p.ForkVersion(slot) == Electra { + forkVersion := p.ForkVersion(slot) + if forkVersion == Fulu || forkVersion == Electra { return ElectraBlockRootGeneralizedIndex } return AltairBlockRootGeneralizedIndex } func (p *Protocol) FinalizedCheckpointGeneralizedIndex(slot uint64) int { - if p.ForkVersion(slot) == Electra { + forkVersion := p.ForkVersion(slot) + if forkVersion == Fulu || forkVersion == Electra { return ElectraFinalizedCheckpointGeneralizedIndex } return AltairFinalizedCheckpointGeneralizedIndex } func (p *Protocol) CurrentSyncCommitteeGeneralizedIndex(slot uint64) int { - if p.ForkVersion(slot) == Electra { + forkVersion := p.ForkVersion(slot) + if forkVersion == Fulu || forkVersion == Electra { return ElectraCurrentSyncCommitteeGeneralizedIndex } return AltairCurrentSyncCommitteeGeneralizedIndex } func (p *Protocol) NextSyncCommitteeGeneralizedIndex(slot uint64) int { - if p.ForkVersion(slot) == Electra { + forkVersion := p.ForkVersion(slot) + if forkVersion == Fulu || forkVersion == Electra { return ElectraNextSyncCommitteeGeneralizedIndex } return AltairNextSyncCommitteeGeneralizedIndex } func (p *Protocol) ExecutionPayloadGeneralizedIndex(slot uint64) int { - if p.ForkVersion(slot) == Electra { + forkVersion := p.ForkVersion(slot) + if forkVersion == Fulu || forkVersion == Electra { return ElectraExecutionPayloadGeneralizedIndex } return AltairExecutionPayloadGeneralizedIndex diff --git a/relayer/relays/beacon/protocol/protocol_test.go b/relayer/relays/beacon/protocol/protocol_test.go index a8a2c5b8d..c78a4f7ac 100644 --- a/relayer/relays/beacon/protocol/protocol_test.go +++ b/relayer/relays/beacon/protocol/protocol_test.go @@ -4,6 +4,7 @@ import ( "errors" "testing" + "github.com/snowfork/snowbridge/relayer/relays/beacon/config" "github.com/stretchr/testify/assert" ) @@ -119,3 +120,140 @@ func TestSyncCommitteeBits(t *testing.T) { assert.Equal(t, tt.expected, result, "expected %t but found %t", tt.expected, result) } } + +func TestForkVersion(t *testing.T) { + values := []struct { + name string + slot uint64 + expected ForkVersion + }{ + { + name: "deneb fork - slot before electra epoch", + slot: 0, + expected: Deneb, + }, + { + name: "deneb fork - slot just before electra activation", + slot: 25599999, // epoch 799999 + expected: Deneb, + }, + { + name: "electra fork - first slot of electra epoch", + slot: 25600000, // epoch 800000 (32 slots per epoch) + expected: Electra, + }, + { + name: "electra fork - middle of electra era", + slot: 29000000, // epoch ~906250 + expected: Electra, + }, + { + name: "electra fork - just before fulu activation", + slot: 31999999, // epoch 999999 + expected: Electra, + }, + { + name: "fulu fork - first slot of fulu epoch", + slot: 32000000, // epoch 1000000 (32 slots per epoch) + expected: Fulu, + }, + { + name: "fulu fork - well into fulu era", + slot: 50000000, // epoch 1562500 + expected: Fulu, + }, + } + + p := Protocol{} + p.Settings.SlotsInEpoch = 32 + p.Settings.ForkVersions = config.ForkVersions{ + Deneb: 0, + Electra: 800000, + Fulu: 1000000, + } + + for _, tt := range values { + t.Run(tt.name, func(t *testing.T) { + result := p.ForkVersion(tt.slot) + assert.Equal(t, tt.expected, result, "expected %s but found %s for slot %d", tt.expected, result, tt.slot) + }) + } +} + +func TestForkVersionEdgeCases(t *testing.T) { + values := []struct { + name string + slot uint64 + expected ForkVersion + }{ + { + name: "slot 0 is deneb", + slot: 0, + expected: Deneb, + }, + { + name: "exact electra boundary", + slot: 800000 * 32, // First slot of epoch 800000 + expected: Electra, + }, + { + name: "exact fulu boundary", + slot: 1000000 * 32, // First slot of epoch 1000000 + expected: Fulu, + }, + } + + p := Protocol{} + p.Settings.SlotsInEpoch = 32 + p.Settings.ForkVersions = config.ForkVersions{ + Deneb: 0, + Electra: 800000, + Fulu: 1000000, + } + + for _, tt := range values { + t.Run(tt.name, func(t *testing.T) { + result := p.ForkVersion(tt.slot) + assert.Equal(t, tt.expected, result, "expected %s but found %s for slot %d", tt.expected, result, tt.slot) + }) + } +} + +func TestForkVersionWithDifferentSlotsPerEpoch(t *testing.T) { + values := []struct { + name string + slot uint64 + expected ForkVersion + }{ + { + name: "deneb with 8 slots per epoch", + slot: 0, + expected: Deneb, + }, + { + name: "electra boundary with 8 slots per epoch", + slot: 8 * 800000, // epoch 800000 with 8 slots per epoch + expected: Electra, + }, + { + name: "fulu boundary with 8 slots per epoch", + slot: 8 * 1000000, // epoch 1000000 with 8 slots per epoch + expected: Fulu, + }, + } + + p := Protocol{} + p.Settings.SlotsInEpoch = 8 // Different from default 32 + p.Settings.ForkVersions = config.ForkVersions{ + Deneb: 0, + Electra: 800000, + Fulu: 1000000, + } + + for _, tt := range values { + t.Run(tt.name, func(t *testing.T) { + result := p.ForkVersion(tt.slot) + assert.Equal(t, tt.expected, result, "expected %s but found %s for slot %d", tt.expected, result, tt.slot) + }) + } +} diff --git a/relayer/relays/beacon/state/beacon_deneb_encoding.go b/relayer/relays/beacon/state/beacon_deneb_encoding.go index 878eebe48..dd2dd8aad 100644 --- a/relayer/relays/beacon/state/beacon_deneb_encoding.go +++ b/relayer/relays/beacon/state/beacon_deneb_encoding.go @@ -1,5 +1,5 @@ // Code generated by fastssz. DO NOT EDIT. -// Hash: e80ede50b28a6c8990c5466d0a25a807e20ae9e7c1bd2bcfbe6d1f8df0150bc6 +// Hash: 760ee633391de0e6421cf7092fbee77c89a4e969fabb4a3d98b1662058d0f1a5 // Version: 0.1.3 package state diff --git a/relayer/relays/beacon/state/beacon_electra_encoding.go b/relayer/relays/beacon/state/beacon_electra_encoding.go index 1ee715002..8ed797566 100644 --- a/relayer/relays/beacon/state/beacon_electra_encoding.go +++ b/relayer/relays/beacon/state/beacon_electra_encoding.go @@ -1,5 +1,5 @@ // Code generated by fastssz. DO NOT EDIT. -// Hash: e80ede50b28a6c8990c5466d0a25a807e20ae9e7c1bd2bcfbe6d1f8df0150bc6 +// Hash: 760ee633391de0e6421cf7092fbee77c89a4e969fabb4a3d98b1662058d0f1a5 // Version: 0.1.3 package state diff --git a/relayer/relays/beacon/state/beacon_encoding.go b/relayer/relays/beacon/state/beacon_encoding.go index e4974ec55..83de495f5 100644 --- a/relayer/relays/beacon/state/beacon_encoding.go +++ b/relayer/relays/beacon/state/beacon_encoding.go @@ -1,5 +1,5 @@ // Code generated by fastssz. DO NOT EDIT. -// Hash: e80ede50b28a6c8990c5466d0a25a807e20ae9e7c1bd2bcfbe6d1f8df0150bc6 +// Hash: 760ee633391de0e6421cf7092fbee77c89a4e969fabb4a3d98b1662058d0f1a5 // Version: 0.1.3 package state diff --git a/relayer/relays/beacon/state/beacon_fulu.go b/relayer/relays/beacon/state/beacon_fulu.go new file mode 100644 index 000000000..bae8d52f7 --- /dev/null +++ b/relayer/relays/beacon/state/beacon_fulu.go @@ -0,0 +1,69 @@ +package state + +type BeaconStateFulu struct { + GenesisTime uint64 `json:"genesis_time"` + GenesisValidatorsRoot []byte `json:"genesis_validators_root" ssz-size:"32"` + Slot uint64 `json:"slot"` + Fork *Fork `json:"fork"` + LatestBlockHeader *BeaconBlockHeader `json:"latest_block_header"` + BlockRoots [][]byte `json:"block_roots" ssz-size:"8192,32"` + StateRoots [][]byte `json:"state_roots" ssz-size:"8192,32"` + HistoricalRoots [][]byte `json:"historical_roots" ssz-max:"16777216" ssz-size:"?,32"` + Eth1Data *Eth1Data `json:"eth1_data"` + Eth1DataVotes []*Eth1Data `json:"eth1_data_votes" ssz-max:"2048"` + Eth1DepositIndex uint64 `json:"eth1_deposit_index"` + Validators []*Validator `json:"validators" ssz-max:"1099511627776"` + Balances []uint64 `json:"balances" ssz-max:"1099511627776"` + RandaoMixes [][]byte `json:"randao_mixes" ssz-size:"65536,32"` + Slashings []uint64 `json:"slashings" ssz-size:"8192"` + PreviousEpochParticipation []byte `json:"previous_epoch_participation" ssz-max:"1099511627776"` + CurrentEpochParticipation []byte `json:"current_epoch_participation" ssz-max:"1099511627776"` + JustificationBits []byte `json:"justification_bits" cast-type:"github.com/prysmaticlabs/go-bitfield.Bitvector4" ssz-size:"1"` + PreviousJustifiedCheckpoint *Checkpoint `json:"previous_justified_checkpoint"` + CurrentJustifiedCheckpoint *Checkpoint `json:"current_justified_checkpoint"` + FinalizedCheckpoint *Checkpoint `json:"finalized_checkpoint"` + InactivityScores []uint64 `json:"inactivity_scores" ssz-max:"1099511627776"` + CurrentSyncCommittee *SyncCommittee `json:"current_sync_committee"` + NextSyncCommittee *SyncCommittee `json:"next_sync_committee"` + LatestExecutionPayloadHeader *ExecutionPayloadHeaderDeneb `json:"latest_execution_payload_header"` + NextWithdrawalIndex uint64 `json:"next_withdrawal_index,omitempty"` + NextWithdrawalValidatorIndex uint64 `json:"next_withdrawal_validator_index,omitempty"` + HistoricalSummaries []*HistoricalSummary `json:"historical_summaries,omitempty" ssz-max:"16777216"` + DepositRequestsStartIndex uint64 `json:"deposit_requests_start_index,omitempty"` + DepositBalanceToConsume uint64 `json:"deposit_balance_to_consume,omitempty"` + ExitBalanceToConsume uint64 `json:"exit_balance_to_consume,omitempty"` + EarliestExitEpoch uint64 `json:"earliest_exit_epoch,omitempty"` + ConsolidationBalanceToConsume uint64 `json:"consolidation_balance_to_consume,omitempty"` + EarliestConsolidationEpoch uint64 `json:"earliest_consolidation_epoch,omitempty"` + PendingDeposits []*PendingDeposit `json:"pending_deposits,omitempty" ssz-max:"134217728"` + PendingPartialWithdrawals []*PendingPartialWithdrawal `json:"pending_partial_withdrawals,omitempty" ssz-max:"134217728"` + PendingConsolidations []*PendingConsolidation `json:"pending_consolidations,omitempty" ssz-max:"262144"` + ProposerLookahead []uint64 `json:"proposer_lookahead,omitempty" ssz-size:"64"` // New in Fulu:EIP7917 +} + +func (b *BeaconStateFulu) GetSlot() uint64 { + return b.Slot +} + +func (b *BeaconStateFulu) GetLatestBlockHeader() *BeaconBlockHeader { + return b.LatestBlockHeader +} + +func (b *BeaconStateFulu) GetBlockRoots() [][]byte { + return b.BlockRoots +} + +func (b *BeaconStateFulu) SetBlockRoots(blockRoots [][]byte) { + b.BlockRoots = blockRoots +} + +func (b *BeaconStateFulu) GetFinalizedCheckpoint() *Checkpoint { + return b.FinalizedCheckpoint +} + +func (b *BeaconStateFulu) GetNextSyncCommittee() *SyncCommittee { + return b.NextSyncCommittee +} +func (b *BeaconStateFulu) GetCurrentSyncCommittee() *SyncCommittee { + return b.CurrentSyncCommittee +} diff --git a/relayer/relays/beacon/state/beacon_fulu_encoding.go b/relayer/relays/beacon/state/beacon_fulu_encoding.go new file mode 100644 index 000000000..dc63cc13d --- /dev/null +++ b/relayer/relays/beacon/state/beacon_fulu_encoding.go @@ -0,0 +1,1191 @@ +// Code generated by fastssz. DO NOT EDIT. +// Hash: 760ee633391de0e6421cf7092fbee77c89a4e969fabb4a3d98b1662058d0f1a5 +// Version: 0.1.3 +package state + +import ( + ssz "github.com/ferranbt/fastssz" +) + +// MarshalSSZ ssz marshals the BeaconStateFulu object +func (b *BeaconStateFulu) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(b) +} + +// MarshalSSZTo ssz marshals the BeaconStateFulu object to a target array +func (b *BeaconStateFulu) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + offset := int(2737225) + + // Field (0) 'GenesisTime' + dst = ssz.MarshalUint64(dst, b.GenesisTime) + + // Field (1) 'GenesisValidatorsRoot' + if size := len(b.GenesisValidatorsRoot); size != 32 { + err = ssz.ErrBytesLengthFn("BeaconStateFulu.GenesisValidatorsRoot", size, 32) + return + } + dst = append(dst, b.GenesisValidatorsRoot...) + + // Field (2) 'Slot' + dst = ssz.MarshalUint64(dst, b.Slot) + + // Field (3) 'Fork' + if b.Fork == nil { + b.Fork = new(Fork) + } + if dst, err = b.Fork.MarshalSSZTo(dst); err != nil { + return + } + + // Field (4) 'LatestBlockHeader' + if b.LatestBlockHeader == nil { + b.LatestBlockHeader = new(BeaconBlockHeader) + } + if dst, err = b.LatestBlockHeader.MarshalSSZTo(dst); err != nil { + return + } + + // Field (5) 'BlockRoots' + if size := len(b.BlockRoots); size != 8192 { + err = ssz.ErrVectorLengthFn("BeaconStateFulu.BlockRoots", size, 8192) + return + } + for ii := 0; ii < 8192; ii++ { + if size := len(b.BlockRoots[ii]); size != 32 { + err = ssz.ErrBytesLengthFn("BeaconStateFulu.BlockRoots[ii]", size, 32) + return + } + dst = append(dst, b.BlockRoots[ii]...) + } + + // Field (6) 'StateRoots' + if size := len(b.StateRoots); size != 8192 { + err = ssz.ErrVectorLengthFn("BeaconStateFulu.StateRoots", size, 8192) + return + } + for ii := 0; ii < 8192; ii++ { + if size := len(b.StateRoots[ii]); size != 32 { + err = ssz.ErrBytesLengthFn("BeaconStateFulu.StateRoots[ii]", size, 32) + return + } + dst = append(dst, b.StateRoots[ii]...) + } + + // Offset (7) 'HistoricalRoots' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.HistoricalRoots) * 32 + + // Field (8) 'Eth1Data' + if b.Eth1Data == nil { + b.Eth1Data = new(Eth1Data) + } + if dst, err = b.Eth1Data.MarshalSSZTo(dst); err != nil { + return + } + + // Offset (9) 'Eth1DataVotes' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.Eth1DataVotes) * 72 + + // Field (10) 'Eth1DepositIndex' + dst = ssz.MarshalUint64(dst, b.Eth1DepositIndex) + + // Offset (11) 'Validators' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.Validators) * 121 + + // Offset (12) 'Balances' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.Balances) * 8 + + // Field (13) 'RandaoMixes' + if size := len(b.RandaoMixes); size != 65536 { + err = ssz.ErrVectorLengthFn("BeaconStateFulu.RandaoMixes", size, 65536) + return + } + for ii := 0; ii < 65536; ii++ { + if size := len(b.RandaoMixes[ii]); size != 32 { + err = ssz.ErrBytesLengthFn("BeaconStateFulu.RandaoMixes[ii]", size, 32) + return + } + dst = append(dst, b.RandaoMixes[ii]...) + } + + // Field (14) 'Slashings' + if size := len(b.Slashings); size != 8192 { + err = ssz.ErrVectorLengthFn("BeaconStateFulu.Slashings", size, 8192) + return + } + for ii := 0; ii < 8192; ii++ { + dst = ssz.MarshalUint64(dst, b.Slashings[ii]) + } + + // Offset (15) 'PreviousEpochParticipation' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.PreviousEpochParticipation) + + // Offset (16) 'CurrentEpochParticipation' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.CurrentEpochParticipation) + + // Field (17) 'JustificationBits' + if size := len(b.JustificationBits); size != 1 { + err = ssz.ErrBytesLengthFn("BeaconStateFulu.JustificationBits", size, 1) + return + } + dst = append(dst, b.JustificationBits...) + + // Field (18) 'PreviousJustifiedCheckpoint' + if b.PreviousJustifiedCheckpoint == nil { + b.PreviousJustifiedCheckpoint = new(Checkpoint) + } + if dst, err = b.PreviousJustifiedCheckpoint.MarshalSSZTo(dst); err != nil { + return + } + + // Field (19) 'CurrentJustifiedCheckpoint' + if b.CurrentJustifiedCheckpoint == nil { + b.CurrentJustifiedCheckpoint = new(Checkpoint) + } + if dst, err = b.CurrentJustifiedCheckpoint.MarshalSSZTo(dst); err != nil { + return + } + + // Field (20) 'FinalizedCheckpoint' + if b.FinalizedCheckpoint == nil { + b.FinalizedCheckpoint = new(Checkpoint) + } + if dst, err = b.FinalizedCheckpoint.MarshalSSZTo(dst); err != nil { + return + } + + // Offset (21) 'InactivityScores' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.InactivityScores) * 8 + + // Field (22) 'CurrentSyncCommittee' + if b.CurrentSyncCommittee == nil { + b.CurrentSyncCommittee = new(SyncCommittee) + } + if dst, err = b.CurrentSyncCommittee.MarshalSSZTo(dst); err != nil { + return + } + + // Field (23) 'NextSyncCommittee' + if b.NextSyncCommittee == nil { + b.NextSyncCommittee = new(SyncCommittee) + } + if dst, err = b.NextSyncCommittee.MarshalSSZTo(dst); err != nil { + return + } + + // Offset (24) 'LatestExecutionPayloadHeader' + dst = ssz.WriteOffset(dst, offset) + if b.LatestExecutionPayloadHeader == nil { + b.LatestExecutionPayloadHeader = new(ExecutionPayloadHeaderDeneb) + } + offset += b.LatestExecutionPayloadHeader.SizeSSZ() + + // Field (25) 'NextWithdrawalIndex' + dst = ssz.MarshalUint64(dst, b.NextWithdrawalIndex) + + // Field (26) 'NextWithdrawalValidatorIndex' + dst = ssz.MarshalUint64(dst, b.NextWithdrawalValidatorIndex) + + // Offset (27) 'HistoricalSummaries' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.HistoricalSummaries) * 64 + + // Field (28) 'DepositRequestsStartIndex' + dst = ssz.MarshalUint64(dst, b.DepositRequestsStartIndex) + + // Field (29) 'DepositBalanceToConsume' + dst = ssz.MarshalUint64(dst, b.DepositBalanceToConsume) + + // Field (30) 'ExitBalanceToConsume' + dst = ssz.MarshalUint64(dst, b.ExitBalanceToConsume) + + // Field (31) 'EarliestExitEpoch' + dst = ssz.MarshalUint64(dst, b.EarliestExitEpoch) + + // Field (32) 'ConsolidationBalanceToConsume' + dst = ssz.MarshalUint64(dst, b.ConsolidationBalanceToConsume) + + // Field (33) 'EarliestConsolidationEpoch' + dst = ssz.MarshalUint64(dst, b.EarliestConsolidationEpoch) + + // Offset (34) 'PendingDeposits' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.PendingDeposits) * 192 + + // Offset (35) 'PendingPartialWithdrawals' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.PendingPartialWithdrawals) * 24 + + // Offset (36) 'PendingConsolidations' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.PendingConsolidations) * 16 + + // Field (37) 'ProposerLookahead' + if size := len(b.ProposerLookahead); size != 64 { + err = ssz.ErrVectorLengthFn("BeaconStateFulu.ProposerLookahead", size, 64) + return + } + for ii := 0; ii < 64; ii++ { + dst = ssz.MarshalUint64(dst, b.ProposerLookahead[ii]) + } + + // Field (7) 'HistoricalRoots' + if size := len(b.HistoricalRoots); size > 16777216 { + err = ssz.ErrListTooBigFn("BeaconStateFulu.HistoricalRoots", size, 16777216) + return + } + for ii := 0; ii < len(b.HistoricalRoots); ii++ { + if size := len(b.HistoricalRoots[ii]); size != 32 { + err = ssz.ErrBytesLengthFn("BeaconStateFulu.HistoricalRoots[ii]", size, 32) + return + } + dst = append(dst, b.HistoricalRoots[ii]...) + } + + // Field (9) 'Eth1DataVotes' + if size := len(b.Eth1DataVotes); size > 2048 { + err = ssz.ErrListTooBigFn("BeaconStateFulu.Eth1DataVotes", size, 2048) + return + } + for ii := 0; ii < len(b.Eth1DataVotes); ii++ { + if dst, err = b.Eth1DataVotes[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + // Field (11) 'Validators' + if size := len(b.Validators); size > 1099511627776 { + err = ssz.ErrListTooBigFn("BeaconStateFulu.Validators", size, 1099511627776) + return + } + for ii := 0; ii < len(b.Validators); ii++ { + if dst, err = b.Validators[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + // Field (12) 'Balances' + if size := len(b.Balances); size > 1099511627776 { + err = ssz.ErrListTooBigFn("BeaconStateFulu.Balances", size, 1099511627776) + return + } + for ii := 0; ii < len(b.Balances); ii++ { + dst = ssz.MarshalUint64(dst, b.Balances[ii]) + } + + // Field (15) 'PreviousEpochParticipation' + if size := len(b.PreviousEpochParticipation); size > 1099511627776 { + err = ssz.ErrBytesLengthFn("BeaconStateFulu.PreviousEpochParticipation", size, 1099511627776) + return + } + dst = append(dst, b.PreviousEpochParticipation...) + + // Field (16) 'CurrentEpochParticipation' + if size := len(b.CurrentEpochParticipation); size > 1099511627776 { + err = ssz.ErrBytesLengthFn("BeaconStateFulu.CurrentEpochParticipation", size, 1099511627776) + return + } + dst = append(dst, b.CurrentEpochParticipation...) + + // Field (21) 'InactivityScores' + if size := len(b.InactivityScores); size > 1099511627776 { + err = ssz.ErrListTooBigFn("BeaconStateFulu.InactivityScores", size, 1099511627776) + return + } + for ii := 0; ii < len(b.InactivityScores); ii++ { + dst = ssz.MarshalUint64(dst, b.InactivityScores[ii]) + } + + // Field (24) 'LatestExecutionPayloadHeader' + if dst, err = b.LatestExecutionPayloadHeader.MarshalSSZTo(dst); err != nil { + return + } + + // Field (27) 'HistoricalSummaries' + if size := len(b.HistoricalSummaries); size > 16777216 { + err = ssz.ErrListTooBigFn("BeaconStateFulu.HistoricalSummaries", size, 16777216) + return + } + for ii := 0; ii < len(b.HistoricalSummaries); ii++ { + if dst, err = b.HistoricalSummaries[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + // Field (34) 'PendingDeposits' + if size := len(b.PendingDeposits); size > 134217728 { + err = ssz.ErrListTooBigFn("BeaconStateFulu.PendingDeposits", size, 134217728) + return + } + for ii := 0; ii < len(b.PendingDeposits); ii++ { + if dst, err = b.PendingDeposits[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + // Field (35) 'PendingPartialWithdrawals' + if size := len(b.PendingPartialWithdrawals); size > 134217728 { + err = ssz.ErrListTooBigFn("BeaconStateFulu.PendingPartialWithdrawals", size, 134217728) + return + } + for ii := 0; ii < len(b.PendingPartialWithdrawals); ii++ { + if dst, err = b.PendingPartialWithdrawals[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + // Field (36) 'PendingConsolidations' + if size := len(b.PendingConsolidations); size > 262144 { + err = ssz.ErrListTooBigFn("BeaconStateFulu.PendingConsolidations", size, 262144) + return + } + for ii := 0; ii < len(b.PendingConsolidations); ii++ { + if dst, err = b.PendingConsolidations[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + return +} + +// UnmarshalSSZ ssz unmarshals the BeaconStateFulu object +func (b *BeaconStateFulu) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size < 2737225 { + return ssz.ErrSize + } + + tail := buf + var o7, o9, o11, o12, o15, o16, o21, o24, o27, o34, o35, o36 uint64 + + // Field (0) 'GenesisTime' + b.GenesisTime = ssz.UnmarshallUint64(buf[0:8]) + + // Field (1) 'GenesisValidatorsRoot' + if cap(b.GenesisValidatorsRoot) == 0 { + b.GenesisValidatorsRoot = make([]byte, 0, len(buf[8:40])) + } + b.GenesisValidatorsRoot = append(b.GenesisValidatorsRoot, buf[8:40]...) + + // Field (2) 'Slot' + b.Slot = ssz.UnmarshallUint64(buf[40:48]) + + // Field (3) 'Fork' + if b.Fork == nil { + b.Fork = new(Fork) + } + if err = b.Fork.UnmarshalSSZ(buf[48:64]); err != nil { + return err + } + + // Field (4) 'LatestBlockHeader' + if b.LatestBlockHeader == nil { + b.LatestBlockHeader = new(BeaconBlockHeader) + } + if err = b.LatestBlockHeader.UnmarshalSSZ(buf[64:176]); err != nil { + return err + } + + // Field (5) 'BlockRoots' + b.BlockRoots = make([][]byte, 8192) + for ii := 0; ii < 8192; ii++ { + if cap(b.BlockRoots[ii]) == 0 { + b.BlockRoots[ii] = make([]byte, 0, len(buf[176:262320][ii*32:(ii+1)*32])) + } + b.BlockRoots[ii] = append(b.BlockRoots[ii], buf[176:262320][ii*32:(ii+1)*32]...) + } + + // Field (6) 'StateRoots' + b.StateRoots = make([][]byte, 8192) + for ii := 0; ii < 8192; ii++ { + if cap(b.StateRoots[ii]) == 0 { + b.StateRoots[ii] = make([]byte, 0, len(buf[262320:524464][ii*32:(ii+1)*32])) + } + b.StateRoots[ii] = append(b.StateRoots[ii], buf[262320:524464][ii*32:(ii+1)*32]...) + } + + // Offset (7) 'HistoricalRoots' + if o7 = ssz.ReadOffset(buf[524464:524468]); o7 > size { + return ssz.ErrOffset + } + + if o7 < 2737225 { + return ssz.ErrInvalidVariableOffset + } + + // Field (8) 'Eth1Data' + if b.Eth1Data == nil { + b.Eth1Data = new(Eth1Data) + } + if err = b.Eth1Data.UnmarshalSSZ(buf[524468:524540]); err != nil { + return err + } + + // Offset (9) 'Eth1DataVotes' + if o9 = ssz.ReadOffset(buf[524540:524544]); o9 > size || o7 > o9 { + return ssz.ErrOffset + } + + // Field (10) 'Eth1DepositIndex' + b.Eth1DepositIndex = ssz.UnmarshallUint64(buf[524544:524552]) + + // Offset (11) 'Validators' + if o11 = ssz.ReadOffset(buf[524552:524556]); o11 > size || o9 > o11 { + return ssz.ErrOffset + } + + // Offset (12) 'Balances' + if o12 = ssz.ReadOffset(buf[524556:524560]); o12 > size || o11 > o12 { + return ssz.ErrOffset + } + + // Field (13) 'RandaoMixes' + b.RandaoMixes = make([][]byte, 65536) + for ii := 0; ii < 65536; ii++ { + if cap(b.RandaoMixes[ii]) == 0 { + b.RandaoMixes[ii] = make([]byte, 0, len(buf[524560:2621712][ii*32:(ii+1)*32])) + } + b.RandaoMixes[ii] = append(b.RandaoMixes[ii], buf[524560:2621712][ii*32:(ii+1)*32]...) + } + + // Field (14) 'Slashings' + b.Slashings = ssz.ExtendUint64(b.Slashings, 8192) + for ii := 0; ii < 8192; ii++ { + b.Slashings[ii] = ssz.UnmarshallUint64(buf[2621712:2687248][ii*8 : (ii+1)*8]) + } + + // Offset (15) 'PreviousEpochParticipation' + if o15 = ssz.ReadOffset(buf[2687248:2687252]); o15 > size || o12 > o15 { + return ssz.ErrOffset + } + + // Offset (16) 'CurrentEpochParticipation' + if o16 = ssz.ReadOffset(buf[2687252:2687256]); o16 > size || o15 > o16 { + return ssz.ErrOffset + } + + // Field (17) 'JustificationBits' + if cap(b.JustificationBits) == 0 { + b.JustificationBits = make([]byte, 0, len(buf[2687256:2687257])) + } + b.JustificationBits = append(b.JustificationBits, buf[2687256:2687257]...) + + // Field (18) 'PreviousJustifiedCheckpoint' + if b.PreviousJustifiedCheckpoint == nil { + b.PreviousJustifiedCheckpoint = new(Checkpoint) + } + if err = b.PreviousJustifiedCheckpoint.UnmarshalSSZ(buf[2687257:2687297]); err != nil { + return err + } + + // Field (19) 'CurrentJustifiedCheckpoint' + if b.CurrentJustifiedCheckpoint == nil { + b.CurrentJustifiedCheckpoint = new(Checkpoint) + } + if err = b.CurrentJustifiedCheckpoint.UnmarshalSSZ(buf[2687297:2687337]); err != nil { + return err + } + + // Field (20) 'FinalizedCheckpoint' + if b.FinalizedCheckpoint == nil { + b.FinalizedCheckpoint = new(Checkpoint) + } + if err = b.FinalizedCheckpoint.UnmarshalSSZ(buf[2687337:2687377]); err != nil { + return err + } + + // Offset (21) 'InactivityScores' + if o21 = ssz.ReadOffset(buf[2687377:2687381]); o21 > size || o16 > o21 { + return ssz.ErrOffset + } + + // Field (22) 'CurrentSyncCommittee' + if b.CurrentSyncCommittee == nil { + b.CurrentSyncCommittee = new(SyncCommittee) + } + if err = b.CurrentSyncCommittee.UnmarshalSSZ(buf[2687381:2712005]); err != nil { + return err + } + + // Field (23) 'NextSyncCommittee' + if b.NextSyncCommittee == nil { + b.NextSyncCommittee = new(SyncCommittee) + } + if err = b.NextSyncCommittee.UnmarshalSSZ(buf[2712005:2736629]); err != nil { + return err + } + + // Offset (24) 'LatestExecutionPayloadHeader' + if o24 = ssz.ReadOffset(buf[2736629:2736633]); o24 > size || o21 > o24 { + return ssz.ErrOffset + } + + // Field (25) 'NextWithdrawalIndex' + b.NextWithdrawalIndex = ssz.UnmarshallUint64(buf[2736633:2736641]) + + // Field (26) 'NextWithdrawalValidatorIndex' + b.NextWithdrawalValidatorIndex = ssz.UnmarshallUint64(buf[2736641:2736649]) + + // Offset (27) 'HistoricalSummaries' + if o27 = ssz.ReadOffset(buf[2736649:2736653]); o27 > size || o24 > o27 { + return ssz.ErrOffset + } + + // Field (28) 'DepositRequestsStartIndex' + b.DepositRequestsStartIndex = ssz.UnmarshallUint64(buf[2736653:2736661]) + + // Field (29) 'DepositBalanceToConsume' + b.DepositBalanceToConsume = ssz.UnmarshallUint64(buf[2736661:2736669]) + + // Field (30) 'ExitBalanceToConsume' + b.ExitBalanceToConsume = ssz.UnmarshallUint64(buf[2736669:2736677]) + + // Field (31) 'EarliestExitEpoch' + b.EarliestExitEpoch = ssz.UnmarshallUint64(buf[2736677:2736685]) + + // Field (32) 'ConsolidationBalanceToConsume' + b.ConsolidationBalanceToConsume = ssz.UnmarshallUint64(buf[2736685:2736693]) + + // Field (33) 'EarliestConsolidationEpoch' + b.EarliestConsolidationEpoch = ssz.UnmarshallUint64(buf[2736693:2736701]) + + // Offset (34) 'PendingDeposits' + if o34 = ssz.ReadOffset(buf[2736701:2736705]); o34 > size || o27 > o34 { + return ssz.ErrOffset + } + + // Offset (35) 'PendingPartialWithdrawals' + if o35 = ssz.ReadOffset(buf[2736705:2736709]); o35 > size || o34 > o35 { + return ssz.ErrOffset + } + + // Offset (36) 'PendingConsolidations' + if o36 = ssz.ReadOffset(buf[2736709:2736713]); o36 > size || o35 > o36 { + return ssz.ErrOffset + } + + // Field (37) 'ProposerLookahead' + b.ProposerLookahead = ssz.ExtendUint64(b.ProposerLookahead, 64) + for ii := 0; ii < 64; ii++ { + b.ProposerLookahead[ii] = ssz.UnmarshallUint64(buf[2736713:2737225][ii*8 : (ii+1)*8]) + } + + // Field (7) 'HistoricalRoots' + { + buf = tail[o7:o9] + num, err := ssz.DivideInt2(len(buf), 32, 16777216) + if err != nil { + return err + } + b.HistoricalRoots = make([][]byte, num) + for ii := 0; ii < num; ii++ { + if cap(b.HistoricalRoots[ii]) == 0 { + b.HistoricalRoots[ii] = make([]byte, 0, len(buf[ii*32:(ii+1)*32])) + } + b.HistoricalRoots[ii] = append(b.HistoricalRoots[ii], buf[ii*32:(ii+1)*32]...) + } + } + + // Field (9) 'Eth1DataVotes' + { + buf = tail[o9:o11] + num, err := ssz.DivideInt2(len(buf), 72, 2048) + if err != nil { + return err + } + b.Eth1DataVotes = make([]*Eth1Data, num) + for ii := 0; ii < num; ii++ { + if b.Eth1DataVotes[ii] == nil { + b.Eth1DataVotes[ii] = new(Eth1Data) + } + if err = b.Eth1DataVotes[ii].UnmarshalSSZ(buf[ii*72 : (ii+1)*72]); err != nil { + return err + } + } + } + + // Field (11) 'Validators' + { + buf = tail[o11:o12] + num, err := ssz.DivideInt2(len(buf), 121, 1099511627776) + if err != nil { + return err + } + b.Validators = make([]*Validator, num) + for ii := 0; ii < num; ii++ { + if b.Validators[ii] == nil { + b.Validators[ii] = new(Validator) + } + if err = b.Validators[ii].UnmarshalSSZ(buf[ii*121 : (ii+1)*121]); err != nil { + return err + } + } + } + + // Field (12) 'Balances' + { + buf = tail[o12:o15] + num, err := ssz.DivideInt2(len(buf), 8, 1099511627776) + if err != nil { + return err + } + b.Balances = ssz.ExtendUint64(b.Balances, num) + for ii := 0; ii < num; ii++ { + b.Balances[ii] = ssz.UnmarshallUint64(buf[ii*8 : (ii+1)*8]) + } + } + + // Field (15) 'PreviousEpochParticipation' + { + buf = tail[o15:o16] + if len(buf) > 1099511627776 { + return ssz.ErrBytesLength + } + if cap(b.PreviousEpochParticipation) == 0 { + b.PreviousEpochParticipation = make([]byte, 0, len(buf)) + } + b.PreviousEpochParticipation = append(b.PreviousEpochParticipation, buf...) + } + + // Field (16) 'CurrentEpochParticipation' + { + buf = tail[o16:o21] + if len(buf) > 1099511627776 { + return ssz.ErrBytesLength + } + if cap(b.CurrentEpochParticipation) == 0 { + b.CurrentEpochParticipation = make([]byte, 0, len(buf)) + } + b.CurrentEpochParticipation = append(b.CurrentEpochParticipation, buf...) + } + + // Field (21) 'InactivityScores' + { + buf = tail[o21:o24] + num, err := ssz.DivideInt2(len(buf), 8, 1099511627776) + if err != nil { + return err + } + b.InactivityScores = ssz.ExtendUint64(b.InactivityScores, num) + for ii := 0; ii < num; ii++ { + b.InactivityScores[ii] = ssz.UnmarshallUint64(buf[ii*8 : (ii+1)*8]) + } + } + + // Field (24) 'LatestExecutionPayloadHeader' + { + buf = tail[o24:o27] + if b.LatestExecutionPayloadHeader == nil { + b.LatestExecutionPayloadHeader = new(ExecutionPayloadHeaderDeneb) + } + if err = b.LatestExecutionPayloadHeader.UnmarshalSSZ(buf); err != nil { + return err + } + } + + // Field (27) 'HistoricalSummaries' + { + buf = tail[o27:o34] + num, err := ssz.DivideInt2(len(buf), 64, 16777216) + if err != nil { + return err + } + b.HistoricalSummaries = make([]*HistoricalSummary, num) + for ii := 0; ii < num; ii++ { + if b.HistoricalSummaries[ii] == nil { + b.HistoricalSummaries[ii] = new(HistoricalSummary) + } + if err = b.HistoricalSummaries[ii].UnmarshalSSZ(buf[ii*64 : (ii+1)*64]); err != nil { + return err + } + } + } + + // Field (34) 'PendingDeposits' + { + buf = tail[o34:o35] + num, err := ssz.DivideInt2(len(buf), 192, 134217728) + if err != nil { + return err + } + b.PendingDeposits = make([]*PendingDeposit, num) + for ii := 0; ii < num; ii++ { + if b.PendingDeposits[ii] == nil { + b.PendingDeposits[ii] = new(PendingDeposit) + } + if err = b.PendingDeposits[ii].UnmarshalSSZ(buf[ii*192 : (ii+1)*192]); err != nil { + return err + } + } + } + + // Field (35) 'PendingPartialWithdrawals' + { + buf = tail[o35:o36] + num, err := ssz.DivideInt2(len(buf), 24, 134217728) + if err != nil { + return err + } + b.PendingPartialWithdrawals = make([]*PendingPartialWithdrawal, num) + for ii := 0; ii < num; ii++ { + if b.PendingPartialWithdrawals[ii] == nil { + b.PendingPartialWithdrawals[ii] = new(PendingPartialWithdrawal) + } + if err = b.PendingPartialWithdrawals[ii].UnmarshalSSZ(buf[ii*24 : (ii+1)*24]); err != nil { + return err + } + } + } + + // Field (36) 'PendingConsolidations' + { + buf = tail[o36:] + num, err := ssz.DivideInt2(len(buf), 16, 262144) + if err != nil { + return err + } + b.PendingConsolidations = make([]*PendingConsolidation, num) + for ii := 0; ii < num; ii++ { + if b.PendingConsolidations[ii] == nil { + b.PendingConsolidations[ii] = new(PendingConsolidation) + } + if err = b.PendingConsolidations[ii].UnmarshalSSZ(buf[ii*16 : (ii+1)*16]); err != nil { + return err + } + } + } + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the BeaconStateFulu object +func (b *BeaconStateFulu) SizeSSZ() (size int) { + size = 2737225 + + // Field (7) 'HistoricalRoots' + size += len(b.HistoricalRoots) * 32 + + // Field (9) 'Eth1DataVotes' + size += len(b.Eth1DataVotes) * 72 + + // Field (11) 'Validators' + size += len(b.Validators) * 121 + + // Field (12) 'Balances' + size += len(b.Balances) * 8 + + // Field (15) 'PreviousEpochParticipation' + size += len(b.PreviousEpochParticipation) + + // Field (16) 'CurrentEpochParticipation' + size += len(b.CurrentEpochParticipation) + + // Field (21) 'InactivityScores' + size += len(b.InactivityScores) * 8 + + // Field (24) 'LatestExecutionPayloadHeader' + if b.LatestExecutionPayloadHeader == nil { + b.LatestExecutionPayloadHeader = new(ExecutionPayloadHeaderDeneb) + } + size += b.LatestExecutionPayloadHeader.SizeSSZ() + + // Field (27) 'HistoricalSummaries' + size += len(b.HistoricalSummaries) * 64 + + // Field (34) 'PendingDeposits' + size += len(b.PendingDeposits) * 192 + + // Field (35) 'PendingPartialWithdrawals' + size += len(b.PendingPartialWithdrawals) * 24 + + // Field (36) 'PendingConsolidations' + size += len(b.PendingConsolidations) * 16 + + return +} + +// HashTreeRoot ssz hashes the BeaconStateFulu object +func (b *BeaconStateFulu) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(b) +} + +// HashTreeRootWith ssz hashes the BeaconStateFulu object with a hasher +func (b *BeaconStateFulu) HashTreeRootWith(hh ssz.HashWalker) (err error) { + indx := hh.Index() + + // Field (0) 'GenesisTime' + hh.PutUint64(b.GenesisTime) + + // Field (1) 'GenesisValidatorsRoot' + if size := len(b.GenesisValidatorsRoot); size != 32 { + err = ssz.ErrBytesLengthFn("BeaconStateFulu.GenesisValidatorsRoot", size, 32) + return + } + hh.PutBytes(b.GenesisValidatorsRoot) + + // Field (2) 'Slot' + hh.PutUint64(b.Slot) + + // Field (3) 'Fork' + if b.Fork == nil { + b.Fork = new(Fork) + } + if err = b.Fork.HashTreeRootWith(hh); err != nil { + return + } + + // Field (4) 'LatestBlockHeader' + if b.LatestBlockHeader == nil { + b.LatestBlockHeader = new(BeaconBlockHeader) + } + if err = b.LatestBlockHeader.HashTreeRootWith(hh); err != nil { + return + } + + // Field (5) 'BlockRoots' + { + if size := len(b.BlockRoots); size != 8192 { + err = ssz.ErrVectorLengthFn("BeaconStateFulu.BlockRoots", size, 8192) + return + } + subIndx := hh.Index() + for _, i := range b.BlockRoots { + if len(i) != 32 { + err = ssz.ErrBytesLength + return + } + hh.Append(i) + } + hh.Merkleize(subIndx) + } + + // Field (6) 'StateRoots' + { + if size := len(b.StateRoots); size != 8192 { + err = ssz.ErrVectorLengthFn("BeaconStateFulu.StateRoots", size, 8192) + return + } + subIndx := hh.Index() + for _, i := range b.StateRoots { + if len(i) != 32 { + err = ssz.ErrBytesLength + return + } + hh.Append(i) + } + hh.Merkleize(subIndx) + } + + // Field (7) 'HistoricalRoots' + { + if size := len(b.HistoricalRoots); size > 16777216 { + err = ssz.ErrListTooBigFn("BeaconStateFulu.HistoricalRoots", size, 16777216) + return + } + subIndx := hh.Index() + for _, i := range b.HistoricalRoots { + if len(i) != 32 { + err = ssz.ErrBytesLength + return + } + hh.Append(i) + } + numItems := uint64(len(b.HistoricalRoots)) + hh.MerkleizeWithMixin(subIndx, numItems, 16777216) + } + + // Field (8) 'Eth1Data' + if b.Eth1Data == nil { + b.Eth1Data = new(Eth1Data) + } + if err = b.Eth1Data.HashTreeRootWith(hh); err != nil { + return + } + + // Field (9) 'Eth1DataVotes' + { + subIndx := hh.Index() + num := uint64(len(b.Eth1DataVotes)) + if num > 2048 { + err = ssz.ErrIncorrectListSize + return + } + for _, elem := range b.Eth1DataVotes { + if err = elem.HashTreeRootWith(hh); err != nil { + return + } + } + hh.MerkleizeWithMixin(subIndx, num, 2048) + } + + // Field (10) 'Eth1DepositIndex' + hh.PutUint64(b.Eth1DepositIndex) + + // Field (11) 'Validators' + { + subIndx := hh.Index() + num := uint64(len(b.Validators)) + if num > 1099511627776 { + err = ssz.ErrIncorrectListSize + return + } + for _, elem := range b.Validators { + if err = elem.HashTreeRootWith(hh); err != nil { + return + } + } + hh.MerkleizeWithMixin(subIndx, num, 1099511627776) + } + + // Field (12) 'Balances' + { + if size := len(b.Balances); size > 1099511627776 { + err = ssz.ErrListTooBigFn("BeaconStateFulu.Balances", size, 1099511627776) + return + } + subIndx := hh.Index() + for _, i := range b.Balances { + hh.AppendUint64(i) + } + hh.FillUpTo32() + numItems := uint64(len(b.Balances)) + hh.MerkleizeWithMixin(subIndx, numItems, ssz.CalculateLimit(1099511627776, numItems, 8)) + } + + // Field (13) 'RandaoMixes' + { + if size := len(b.RandaoMixes); size != 65536 { + err = ssz.ErrVectorLengthFn("BeaconStateFulu.RandaoMixes", size, 65536) + return + } + subIndx := hh.Index() + for _, i := range b.RandaoMixes { + if len(i) != 32 { + err = ssz.ErrBytesLength + return + } + hh.Append(i) + } + hh.Merkleize(subIndx) + } + + // Field (14) 'Slashings' + { + if size := len(b.Slashings); size != 8192 { + err = ssz.ErrVectorLengthFn("BeaconStateFulu.Slashings", size, 8192) + return + } + subIndx := hh.Index() + for _, i := range b.Slashings { + hh.AppendUint64(i) + } + hh.Merkleize(subIndx) + } + + // Field (15) 'PreviousEpochParticipation' + { + elemIndx := hh.Index() + byteLen := uint64(len(b.PreviousEpochParticipation)) + if byteLen > 1099511627776 { + err = ssz.ErrIncorrectListSize + return + } + hh.Append(b.PreviousEpochParticipation) + hh.MerkleizeWithMixin(elemIndx, byteLen, (1099511627776+31)/32) + } + + // Field (16) 'CurrentEpochParticipation' + { + elemIndx := hh.Index() + byteLen := uint64(len(b.CurrentEpochParticipation)) + if byteLen > 1099511627776 { + err = ssz.ErrIncorrectListSize + return + } + hh.Append(b.CurrentEpochParticipation) + hh.MerkleizeWithMixin(elemIndx, byteLen, (1099511627776+31)/32) + } + + // Field (17) 'JustificationBits' + if size := len(b.JustificationBits); size != 1 { + err = ssz.ErrBytesLengthFn("BeaconStateFulu.JustificationBits", size, 1) + return + } + hh.PutBytes(b.JustificationBits) + + // Field (18) 'PreviousJustifiedCheckpoint' + if b.PreviousJustifiedCheckpoint == nil { + b.PreviousJustifiedCheckpoint = new(Checkpoint) + } + if err = b.PreviousJustifiedCheckpoint.HashTreeRootWith(hh); err != nil { + return + } + + // Field (19) 'CurrentJustifiedCheckpoint' + if b.CurrentJustifiedCheckpoint == nil { + b.CurrentJustifiedCheckpoint = new(Checkpoint) + } + if err = b.CurrentJustifiedCheckpoint.HashTreeRootWith(hh); err != nil { + return + } + + // Field (20) 'FinalizedCheckpoint' + if b.FinalizedCheckpoint == nil { + b.FinalizedCheckpoint = new(Checkpoint) + } + if err = b.FinalizedCheckpoint.HashTreeRootWith(hh); err != nil { + return + } + + // Field (21) 'InactivityScores' + { + if size := len(b.InactivityScores); size > 1099511627776 { + err = ssz.ErrListTooBigFn("BeaconStateFulu.InactivityScores", size, 1099511627776) + return + } + subIndx := hh.Index() + for _, i := range b.InactivityScores { + hh.AppendUint64(i) + } + hh.FillUpTo32() + numItems := uint64(len(b.InactivityScores)) + hh.MerkleizeWithMixin(subIndx, numItems, ssz.CalculateLimit(1099511627776, numItems, 8)) + } + + // Field (22) 'CurrentSyncCommittee' + if b.CurrentSyncCommittee == nil { + b.CurrentSyncCommittee = new(SyncCommittee) + } + if err = b.CurrentSyncCommittee.HashTreeRootWith(hh); err != nil { + return + } + + // Field (23) 'NextSyncCommittee' + if b.NextSyncCommittee == nil { + b.NextSyncCommittee = new(SyncCommittee) + } + if err = b.NextSyncCommittee.HashTreeRootWith(hh); err != nil { + return + } + + // Field (24) 'LatestExecutionPayloadHeader' + if err = b.LatestExecutionPayloadHeader.HashTreeRootWith(hh); err != nil { + return + } + + // Field (25) 'NextWithdrawalIndex' + hh.PutUint64(b.NextWithdrawalIndex) + + // Field (26) 'NextWithdrawalValidatorIndex' + hh.PutUint64(b.NextWithdrawalValidatorIndex) + + // Field (27) 'HistoricalSummaries' + { + subIndx := hh.Index() + num := uint64(len(b.HistoricalSummaries)) + if num > 16777216 { + err = ssz.ErrIncorrectListSize + return + } + for _, elem := range b.HistoricalSummaries { + if err = elem.HashTreeRootWith(hh); err != nil { + return + } + } + hh.MerkleizeWithMixin(subIndx, num, 16777216) + } + + // Field (28) 'DepositRequestsStartIndex' + hh.PutUint64(b.DepositRequestsStartIndex) + + // Field (29) 'DepositBalanceToConsume' + hh.PutUint64(b.DepositBalanceToConsume) + + // Field (30) 'ExitBalanceToConsume' + hh.PutUint64(b.ExitBalanceToConsume) + + // Field (31) 'EarliestExitEpoch' + hh.PutUint64(b.EarliestExitEpoch) + + // Field (32) 'ConsolidationBalanceToConsume' + hh.PutUint64(b.ConsolidationBalanceToConsume) + + // Field (33) 'EarliestConsolidationEpoch' + hh.PutUint64(b.EarliestConsolidationEpoch) + + // Field (34) 'PendingDeposits' + { + subIndx := hh.Index() + num := uint64(len(b.PendingDeposits)) + if num > 134217728 { + err = ssz.ErrIncorrectListSize + return + } + for _, elem := range b.PendingDeposits { + if err = elem.HashTreeRootWith(hh); err != nil { + return + } + } + hh.MerkleizeWithMixin(subIndx, num, 134217728) + } + + // Field (35) 'PendingPartialWithdrawals' + { + subIndx := hh.Index() + num := uint64(len(b.PendingPartialWithdrawals)) + if num > 134217728 { + err = ssz.ErrIncorrectListSize + return + } + for _, elem := range b.PendingPartialWithdrawals { + if err = elem.HashTreeRootWith(hh); err != nil { + return + } + } + hh.MerkleizeWithMixin(subIndx, num, 134217728) + } + + // Field (36) 'PendingConsolidations' + { + subIndx := hh.Index() + num := uint64(len(b.PendingConsolidations)) + if num > 262144 { + err = ssz.ErrIncorrectListSize + return + } + for _, elem := range b.PendingConsolidations { + if err = elem.HashTreeRootWith(hh); err != nil { + return + } + } + hh.MerkleizeWithMixin(subIndx, num, 262144) + } + + // Field (37) 'ProposerLookahead' + { + if size := len(b.ProposerLookahead); size != 64 { + err = ssz.ErrVectorLengthFn("BeaconStateFulu.ProposerLookahead", size, 64) + return + } + subIndx := hh.Index() + for _, i := range b.ProposerLookahead { + hh.AppendUint64(i) + } + hh.Merkleize(subIndx) + } + + hh.Merkleize(indx) + return +} + +// GetTree ssz hashes the BeaconStateFulu object +func (b *BeaconStateFulu) GetTree() (*ssz.Node, error) { + return ssz.ProofTree(b) +} diff --git a/web/packages/test/config/beacon-relay.json b/web/packages/test/config/beacon-relay.json index e8b6d40c0..ddde1a917 100644 --- a/web/packages/test/config/beacon-relay.json +++ b/web/packages/test/config/beacon-relay.json @@ -9,7 +9,8 @@ "epochsPerSyncCommitteePeriod": 256, "forkVersions": { "deneb": 0, - "electra": 2000000 + "electra": 0, + "fulu": 50000000 } }, "datastore": { diff --git a/web/packages/test/config/execution-relay.json b/web/packages/test/config/execution-relay.json index 27737b4d7..eff010561 100644 --- a/web/packages/test/config/execution-relay.json +++ b/web/packages/test/config/execution-relay.json @@ -16,7 +16,8 @@ "epochsPerSyncCommitteePeriod": 256, "forkVersions": { "deneb": 0, - "electra": 2000000 + "electra": 0, + "fulu": 50000000 } }, "datastore": { diff --git a/web/packages/test/scripts/build-binary.sh b/web/packages/test/scripts/build-binary.sh index 4009b3716..ed5369dac 100755 --- a/web/packages/test/scripts/build-binary.sh +++ b/web/packages/test/scripts/build-binary.sh @@ -66,9 +66,9 @@ set_slot_time() { echo "Hack lodestar for faster slot time" local preset_mainnet_config_file="$root_dir/lodestar/packages/config/src/chainConfig/configs/mainnet.ts" if [[ "$(uname)" == "Darwin" && -z "${IN_NIX_SHELL:-}" ]]; then - gsed -i "s/SECONDS_PER_SLOT: .*/SECONDS_PER_SLOT: $new_value,/g" $preset_mainnet_config_file + gsed -i "s/SLOT_DURATION_MS: .*/SLOT_DURATION_MS: $new_value,/g" $preset_mainnet_config_file else - sed -i "s/SECONDS_PER_SLOT: .*/SECONDS_PER_SLOT: $new_value,/g" $preset_mainnet_config_file + sed -i "s/SLOT_DURATION_MS: .*/SLOT_DURATION_MS: $new_value,/g" $preset_mainnet_config_file fi } @@ -76,9 +76,9 @@ build_lodestar() { if [ "$rebuild_lodestar" == "true" ]; then pushd $root_dir/lodestar if [ "$eth_fast_mode" == "true" ]; then - set_slot_time 1 + set_slot_time 1000 else - set_slot_time 12 + set_slot_time 12000 fi yarn install && yarn run build popd diff --git a/web/packages/test/scripts/deploy-ethereum.sh b/web/packages/test/scripts/deploy-ethereum.sh index b96ad2121..993ad3982 100755 --- a/web/packages/test/scripts/deploy-ethereum.sh +++ b/web/packages/test/scripts/deploy-ethereum.sh @@ -53,7 +53,8 @@ start_lodestar() { export LODESTAR_PRESET="mainnet" - pushd $root_dir/lodestar + pushd $root_dir/../lodestar + ./lodestar --version ./lodestar dev \ --genesisValidators 8 \ --genesisTime $timestamp \ @@ -70,10 +71,12 @@ start_lodestar() { --params.BELLATRIX_FORK_EPOCH 0 \ --params.CAPELLA_FORK_EPOCH 0 \ --params.DENEB_FORK_EPOCH 0 \ - --eth1=true \ + --params.ELECTRA_FORK_EPOCH 0 \ + --params.FULU_FORK_EPOCH 50000000 \ --rest.namespace="*" \ --jwt-secret $config_dir/jwtsecret \ --chain.archiveStateEpochFrequency 1 \ + --serveHistoricalState true \ >"$output_dir/lodestar.log" 2>&1 & popd fi diff --git a/web/packages/test/scripts/set-env.sh b/web/packages/test/scripts/set-env.sh index 2e6ff5f8c..d3710eb63 100755 --- a/web/packages/test/scripts/set-env.sh +++ b/web/packages/test/scripts/set-env.sh @@ -10,7 +10,7 @@ export output_bin_dir="$output_dir/bin" ethereum_data_dir="$output_dir/ethereum" zombienet_data_dir="$output_dir/zombienet" export PATH="$output_bin_dir:$PATH" -export polkadot_sdk_dir="${POLKADOT_SDK_DIR:-../polkadot-sdk}" +polkadot_sdk_dir="${POLKADOT_SDK_DIR:-../polkadot-sdk}" eth_network="${ETH_NETWORK:-localhost}" eth_endpoint_http="${ETH_RPC_ENDPOINT:-http://127.0.0.1:8545}/${INFURA_PROJECT_ID:-}" diff --git a/web/packages/test/scripts/start-relayer.sh b/web/packages/test/scripts/start-relayer.sh index e6779bea6..5abe99549 100755 --- a/web/packages/test/scripts/start-relayer.sh +++ b/web/packages/test/scripts/start-relayer.sh @@ -4,10 +4,8 @@ set -eu source scripts/set-env.sh config_relayer() { - local electra_forked_epoch=2000000 - if [ "$is_electra" == "true" ]; then - electra_forked_epoch=0 - fi + local electra_forked_epoch=0 + local fulu_forked_epoch=50000000 # Configure beefy relay jq \ --arg k1 "$(address_for BeefyClient)" \ @@ -145,9 +143,11 @@ config_relayer() { jq \ --arg beacon_endpoint_http $beacon_endpoint_http \ --argjson electra_forked_epoch $electra_forked_epoch \ + --argjson fulu_forked_epoch $fulu_forked_epoch \ ' .source.beacon.endpoint = $beacon_endpoint_http | .source.beacon.spec.forkVersions.electra = $electra_forked_epoch + | .source.beacon.spec.forkVersions.fulu = $fulu_forked_epoch ' \ config/beacon-relay.json >$output_dir/beacon-relay.json @@ -157,12 +157,14 @@ config_relayer() { --arg k1 "$(address_for GatewayProxy)" \ --arg channelID $ASSET_HUB_CHANNEL_ID \ --argjson electra_forked_epoch $electra_forked_epoch \ + --argjson fulu_forked_epoch $fulu_forked_epoch \ ' .source.ethereum.endpoint = $eth_endpoint_ws | .source.contracts.Gateway = $k1 | .source."channel-id" = $channelID | .schedule.id = 0 | .source.beacon.spec.forkVersions.electra = $electra_forked_epoch + | .source.beacon.spec.forkVersions.fulu = $fulu_forked_epoch ' \ config/execution-relay.json >$output_dir/execution-relay-asset-hub-0.json @@ -172,12 +174,14 @@ config_relayer() { --arg k1 "$(address_for GatewayProxy)" \ --arg channelID $ASSET_HUB_CHANNEL_ID \ --argjson electra_forked_epoch $electra_forked_epoch \ + --argjson fulu_forked_epoch $fulu_forked_epoch \ ' .source.ethereum.endpoint = $eth_endpoint_ws | .source.contracts.Gateway = $k1 | .source."channel-id" = $channelID | .schedule.id = 1 | .source.beacon.spec.forkVersions.electra = $electra_forked_epoch + | .source.beacon.spec.forkVersions.fulu = $fulu_forked_epoch ' \ config/execution-relay.json >$output_dir/execution-relay-asset-hub-1.json @@ -187,12 +191,14 @@ config_relayer() { --arg k1 "$(address_for GatewayProxy)" \ --arg channelID $ASSET_HUB_CHANNEL_ID \ --argjson electra_forked_epoch $electra_forked_epoch \ + --argjson fulu_forked_epoch $fulu_forked_epoch \ ' .source.ethereum.endpoint = $eth_endpoint_ws | .source.contracts.Gateway = $k1 | .source."channel-id" = $channelID | .schedule.id = 2 | .source.beacon.spec.forkVersions.electra = $electra_forked_epoch + | .source.beacon.spec.forkVersions.fulu = $fulu_forked_epoch ' \ config/execution-relay.json >$output_dir/execution-relay-asset-hub-2.json @@ -202,11 +208,13 @@ config_relayer() { --arg k1 "$(address_for GatewayProxy)" \ --arg channelID $PENPAL_CHANNEL_ID \ --argjson electra_forked_epoch $electra_forked_epoch \ + --argjson fulu_forked_epoch $fulu_forked_epoch \ ' .source.ethereum.endpoint = $eth_endpoint_ws | .source.contracts.Gateway = $k1 | .source."channel-id" = $channelID | .source.beacon.spec.forkVersions.electra = $electra_forked_epoch + | .source.beacon.spec.forkVersions.fulu = $fulu_forked_epoch ' \ config/execution-relay.json >$output_dir/execution-relay-penpal.json }