diff --git a/.github/workflows/relayer.yml b/.github/workflows/relayer.yml index 4a67172004..f932b8340d 100644 --- a/.github/workflows/relayer.yml +++ b/.github/workflows/relayer.yml @@ -22,7 +22,7 @@ jobs: - name: setup go uses: actions/checkout@v4 with: - go-version: '^1.20.1' + go-version: '^1.22.5' - name: check go version run: go version diff --git a/relayer/cmd/generate_beacon_data.go b/relayer/cmd/generate_beacon_data.go index 06202d84e5..d0767c3f50 100644 --- a/relayer/cmd/generate_beacon_data.go +++ b/relayer/cmd/generate_beacon_data.go @@ -105,9 +105,9 @@ type InboundFixture struct { const ( pathToBeaconTestFixtureFiles = "polkadot-sdk/bridges/snowbridge/pallets/ethereum-client/tests/fixtures" - pathToInboundQueueFixtureTemplate = "polkadot-sdk/bridges/snowbridge/templates/beacon-fixtures.mustache" + pathToInboundQueueFixtureTemplate = "relayer/templates/beacon-fixtures.mustache" pathToInboundQueueFixtureData = "polkadot-sdk/bridges/snowbridge/pallets/ethereum-client/fixtures/src/lib.rs" - pathToInboundQueueFixtureTestCaseTemplate = "polkadot-sdk/bridges/snowbridge/templates/inbound-fixtures.mustache" + pathToInboundQueueFixtureTestCaseTemplate = "relayer/templates/inbound-fixtures.mustache" pathToInboundQueueFixtureTestCaseData = "polkadot-sdk/bridges/snowbridge/pallets/inbound-queue/fixtures/src/%s.rs" ) @@ -206,7 +206,7 @@ func generateBeaconTestFixture(cmd *cobra.Command, _ []string) error { client := api.NewBeaconClient(conf.Source.Beacon.Endpoint, conf.Source.Beacon.StateEndpoint) s := syncer.New(client, &store, p) - viper.SetConfigFile("/tmp/snowbridge/execution-relay-asset-hub.json") + viper.SetConfigFile("/tmp/snowbridge/execution-relay-asset-hub-0.json") if err = viper.ReadInConfig(); err != nil { return err @@ -402,7 +402,8 @@ func generateBeaconTestFixture(cmd *cobra.Command, _ []string) error { for { nextFinalizedUpdateScale, err := s.GetFinalizedUpdate() if err != nil { - return fmt.Errorf("get next finalized header update: %w", err) + log.Error(err) + continue } nextFinalizedUpdate := nextFinalizedUpdateScale.Payload.ToJSON() nextFinalizedUpdatePeriod := p.ComputeSyncPeriodAtSlot(nextFinalizedUpdate.FinalizedHeader.Slot) @@ -416,7 +417,8 @@ func generateBeaconTestFixture(cmd *cobra.Command, _ []string) error { // generate nextSyncCommitteeUpdate nextSyncCommitteeUpdateScale, err := s.GetSyncCommitteePeriodUpdate(initialSyncPeriod+1, 0) if err != nil { - return fmt.Errorf("get sync committee update: %w", err) + log.Error(err) + continue } nextSyncCommitteeUpdate := nextSyncCommitteeUpdateScale.Payload.ToJSON() err = writeJSONToFile(nextSyncCommitteeUpdate, fmt.Sprintf("%s/%s", pathToBeaconTestFixtureFiles, "next-sync-committee-update.json")) diff --git a/relayer/cmd/import_beacon_state.go b/relayer/cmd/import_beacon_state.go index 0dac560832..66843d5344 100644 --- a/relayer/cmd/import_beacon_state.go +++ b/relayer/cmd/import_beacon_state.go @@ -92,7 +92,7 @@ func importBeaconState(cmd *cobra.Command, _ []string) error { return fmt.Errorf("read finalized state data from file: %w", err) } - afterDenebFork := (conf.Source.Beacon.Spec.DenebForkEpoch + 1) * 32 + afterDenebFork := (conf.Source.Beacon.Spec.ForkVersions.Deneb + 1) * 32 attestedState, err := syncer.UnmarshalBeaconState(afterDenebFork, attestedData) if err != nil { diff --git a/relayer/magefile.go b/relayer/magefile.go index 859e614e06..27fae365e0 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", "BeaconStateCapellaMainnet,BlockRootsContainerMainnet,TransactionsRootContainer,BeaconBlockCapellaMainnet,WithdrawalsRootContainerMainnet,BeaconStateDenebMainnet,BeaconBlockDenebMainnet") + err := sh.Run("sszgen", "--path", "relays/beacon/state", "--objs", "BeaconStateCapellaMainnet,BlockRootsContainerMainnet,TransactionsRootContainer,BeaconBlockCapellaMainnet,WithdrawalsRootContainerMainnet,BeaconStateDenebMainnet,BeaconBlockDenebMainnet,SignedBeaconBlockDeneb,SignedBeaconBlockElectra,BeaconStateElectra,BeaconBlockElectra") if err != nil { return err } diff --git a/relayer/relays/beacon/config/config.go b/relayer/relays/beacon/config/config.go index cd56105196..17f75aad57 100644 --- a/relayer/relays/beacon/config/config.go +++ b/relayer/relays/beacon/config/config.go @@ -11,10 +11,15 @@ type Config struct { } type SpecSettings struct { - SyncCommitteeSize uint64 `mapstructure:"syncCommitteeSize"` - SlotsInEpoch uint64 `mapstructure:"slotsInEpoch"` - EpochsPerSyncCommitteePeriod uint64 `mapstructure:"epochsPerSyncCommitteePeriod"` - DenebForkEpoch uint64 `mapstructure:"denebForkedEpoch"` + SyncCommitteeSize uint64 `mapstructure:"syncCommitteeSize"` + SlotsInEpoch uint64 `mapstructure:"slotsInEpoch"` + EpochsPerSyncCommitteePeriod uint64 `mapstructure:"epochsPerSyncCommitteePeriod"` + ForkVersions ForkVersions `mapstructure:"forkVersions"` +} + +type ForkVersions struct { + Deneb uint64 `mapstructure:"deneb"` + Electra uint64 `mapstructure:"electra"` } type SourceConfig struct { diff --git a/relayer/relays/beacon/header/header_test.go b/relayer/relays/beacon/header/header_test.go index 358cbe9d09..c1ec91902e 100644 --- a/relayer/relays/beacon/header/header_test.go +++ b/relayer/relays/beacon/header/header_test.go @@ -23,7 +23,10 @@ func TestSyncInterimFinalizedUpdate_WithDataFromAPI(t *testing.T) { settings := config.SpecSettings{ SlotsInEpoch: 32, EpochsPerSyncCommitteePeriod: 256, - DenebForkEpoch: 0, + ForkVersions: config.ForkVersions{ + Deneb: 0, + Electra: 800000, + }, } p := protocol.New(settings, MaxRedundancy) client := mock.API{} @@ -81,7 +84,10 @@ func TestSyncInterimFinalizedUpdate_WithDataFromStore(t *testing.T) { settings := config.SpecSettings{ SlotsInEpoch: 32, EpochsPerSyncCommitteePeriod: 256, - DenebForkEpoch: 0, + ForkVersions: config.ForkVersions{ + Deneb: 0, + Electra: 800000, + }, } p := protocol.New(settings, MaxRedundancy) client := mock.API{} @@ -147,7 +153,10 @@ func TestSyncInterimFinalizedUpdate_WithDataFromStoreWithDifferentBlocks(t *test settings := config.SpecSettings{ SlotsInEpoch: 32, EpochsPerSyncCommitteePeriod: 256, - DenebForkEpoch: 0, + ForkVersions: config.ForkVersions{ + Deneb: 0, + Electra: 800000, + }, } p := protocol.New(settings, MaxRedundancy) client := mock.API{} @@ -213,7 +222,10 @@ func TestSyncInterimFinalizedUpdate_BeaconStateNotAvailableInAPIAndStore(t *test settings := config.SpecSettings{ SlotsInEpoch: 32, EpochsPerSyncCommitteePeriod: 256, - DenebForkEpoch: 0, + ForkVersions: config.ForkVersions{ + Deneb: 0, + Electra: 800000, + }, } p := protocol.New(settings, MaxRedundancy) client := mock.API{} @@ -257,7 +269,10 @@ func TestSyncInterimFinalizedUpdate_NoValidBlocksFound(t *testing.T) { settings := config.SpecSettings{ SlotsInEpoch: 32, EpochsPerSyncCommitteePeriod: 256, - DenebForkEpoch: 0, + ForkVersions: config.ForkVersions{ + Deneb: 0, + Electra: 800000, + }, } p := protocol.New(settings, MaxRedundancy) client := mock.API{} @@ -332,7 +347,6 @@ func TestFindLatestCheckPoint(t *testing.T) { settings := config.SpecSettings{ SlotsInEpoch: 4, EpochsPerSyncCommitteePeriod: 2, - DenebForkEpoch: 0, } maxRedundancy := uint64(2) p := protocol.New(settings, maxRedundancy) diff --git a/relayer/relays/beacon/header/syncer/api/api.go b/relayer/relays/beacon/header/syncer/api/api.go index 9aaf558cb4..bf0fcc4947 100644 --- a/relayer/relays/beacon/header/syncer/api/api.go +++ b/relayer/relays/beacon/header/syncer/api/api.go @@ -36,6 +36,7 @@ type BeaconAPI interface { GetBeaconBlockBySlot(slot uint64) (BeaconBlockResponse, error) GetBeaconBlockRoot(slot uint64) (common.Hash, error) GetBeaconBlock(blockID common.Hash) (BeaconBlockResponse, error) + GetBeaconBlockBytes(blockID common.Hash) ([]byte, error) GetSyncCommitteePeriodUpdate(from uint64) (SyncCommitteePeriodUpdateResponse, error) GetLatestFinalizedUpdate() (LatestFinalisedUpdateResponse, error) GetBeaconState(stateIdOrSlot string) ([]byte, error) @@ -417,7 +418,7 @@ func (b *BeaconClient) GetBeaconState(stateIdOrSlot string) ([]byte, error) { res, err := b.httpClient.Do(req) endTime := time.Now() duration := endTime.Sub(startTime) - log.WithFields(log.Fields{"startTime": startTime.Format(time.UnixDate), "endTime": endTime.Format(time.UnixDate), "duration": duration.Seconds()}).Warn("beacon state download time") + log.WithFields(log.Fields{"startTime": startTime.Format(time.UnixDate), "endTime": endTime.Format(time.UnixDate), "duration": duration.Seconds()}).Info("beacon state download time") if err != nil { return data, err @@ -436,3 +437,31 @@ func (b *BeaconClient) GetBeaconState(stateIdOrSlot string) ([]byte, error) { data = buf.Bytes() return data, nil } + +func (b *BeaconClient) GetBeaconBlockBytes(blockID common.Hash) ([]byte, error) { + var data []byte + req, err := http.NewRequest("GET", fmt.Sprintf("%s/eth/v2/beacon/blocks/%s", b.stateEndpoint, blockID), nil) + if err != nil { + return data, err + } + + req.Header.Add("Accept", "application/octet-stream") + + res, err := b.httpClient.Do(req) + if err != nil { + return data, err + } + + if res.StatusCode != http.StatusOK { + if res.StatusCode == 404 { + return data, ErrNotFound + } + + return data, fmt.Errorf("%s: %d", DoHTTPRequestErrorMessage, res.StatusCode) + } + + buf := new(bytes.Buffer) + buf.ReadFrom(res.Body) + data = buf.Bytes() + return data, nil +} diff --git a/relayer/relays/beacon/header/syncer/api/api_deneb.go b/relayer/relays/beacon/header/syncer/api/api_deneb.go index 3ebe17f982..d57f1533b3 100644 --- a/relayer/relays/beacon/header/syncer/api/api_deneb.go +++ b/relayer/relays/beacon/header/syncer/api/api_deneb.go @@ -3,9 +3,7 @@ package api import ( "math/big" - "github.com/ethereum/go-ethereum/common" "github.com/snowfork/go-substrate-rpc-client/v4/types" - beaconjson "github.com/snowfork/snowbridge/relayer/relays/beacon/header/syncer/json" "github.com/snowfork/snowbridge/relayer/relays/beacon/header/syncer/scale" "github.com/snowfork/snowbridge/relayer/relays/beacon/state" "github.com/snowfork/snowbridge/relayer/relays/util" @@ -55,49 +53,3 @@ func DenebExecutionPayloadToScale(e *state.ExecutionPayloadDeneb) (scale.Executi }, nil } -func DenebJsonExecutionPayloadHeaderToScale(e *beaconjson.FullExecutionPayloadHeaderJson) (scale.ExecutionPayloadHeaderDeneb, error) { - var executionPayloadHeader scale.ExecutionPayloadHeaderDeneb - var baseFeePerGas big.Int - baseFeePerGasU64, err := util.ToUint64(e.BaseFeePerGas) - if err != nil { - return executionPayloadHeader, err - } - blockNumber, err := util.ToUint64(e.BlockNumber) - if err != nil { - return executionPayloadHeader, err - } - baseFeePerGas.SetUint64(baseFeePerGasU64) - gasLimit, err := util.ToUint64(e.GasLimit) - if err != nil { - return executionPayloadHeader, err - } - gasUsed, err := util.ToUint64(e.GasUsed) - if err != nil { - return executionPayloadHeader, err - } - timestamp, err := util.ToUint64(e.Timestamp) - if err != nil { - return executionPayloadHeader, err - } - blobGasUsed, _ := util.ToUint64(e.BlobGasUsed) - excessBlobGas, _ := util.ToUint64(e.ExcessBlobGas) - return scale.ExecutionPayloadHeaderDeneb{ - ParentHash: types.NewH256(common.HexToHash(e.ParentHash).Bytes()), - FeeRecipient: types.NewH160(common.HexToAddress(e.FeeRecipient).Bytes()), - StateRoot: types.NewH256(common.HexToHash(e.StateRoot).Bytes()), - ReceiptsRoot: types.NewH256(common.HexToHash(e.ReceiptsRoot).Bytes()), - LogsBloom: common.FromHex(e.LogsBloom), - PrevRandao: types.NewH256(common.HexToHash(e.PrevRandao).Bytes()), - BlockNumber: types.NewU64(blockNumber), - GasLimit: types.NewU64(gasLimit), - GasUsed: types.NewU64(gasUsed), - Timestamp: types.NewU64(timestamp), - ExtraData: common.FromHex(e.ExtraData), - BaseFeePerGas: types.NewU256(baseFeePerGas), - BlockHash: types.NewH256(common.HexToHash(e.BlockHash).Bytes()), - TransactionsRoot: types.NewH256(common.HexToHash(e.TransactionsRoot).Bytes()), - WithdrawalsRoot: types.NewH256(common.HexToHash(e.WithdrawalsRoot).Bytes()), - BlobGasUsed: types.NewU64(blobGasUsed), - ExcessBlobGas: types.NewU64(excessBlobGas), - }, nil -} diff --git a/relayer/relays/beacon/header/syncer/api/api_response.go b/relayer/relays/beacon/header/syncer/api/api_response.go index 1ba06034b7..58cf3e022d 100644 --- a/relayer/relays/beacon/header/syncer/api/api_response.go +++ b/relayer/relays/beacon/header/syncer/api/api_response.go @@ -150,6 +150,7 @@ type AttestationResponse struct { AggregationBits string `json:"aggregation_bits"` Data AttestationDataResponse `json:"data"` Signature string `json:"signature"` + CommitteeBits string `json:"committee_bits,omitempty"` } type SignedVoluntaryExitResponse struct { @@ -324,86 +325,6 @@ type SignedBLSToExecutionChangeResponse struct { Signature string `json:"signature,omitempty"` } -func (s *SignedBLSToExecutionChangeResponse) ToFastSSZ() (*state.SignedBLSToExecutionChange, error) { - validateIndex, err := util.ToUint64(s.Message.ValidatorIndex) - if err != nil { - return nil, err - } - pubKey, err := util.HexStringToPublicKey(s.Message.FromBlsPubkey) - if err != nil { - return nil, err - } - address, err := util.HexStringTo20Bytes(s.Message.ToExecutionAddress) - if err != nil { - return nil, err - } - signature, err := util.HexStringTo96Bytes(s.Signature) - if err != nil { - return nil, err - } - return &state.SignedBLSToExecutionChange{Message: &state.BLSToExecutionChange{ValidatorIndex: validateIndex, FromBlsPubkey: pubKey[:], ToExecutionAddress: address[:]}, Signature: signature[:]}, nil -} - -func (w *WithdrawalResponse) ToFastSSZ() (*state.Withdrawal, error) { - index, err := util.ToUint64(w.Index) - if err != nil { - return nil, err - } - validatorIndex, err := util.ToUint64(w.ValidatorIndex) - if err != nil { - return nil, err - } - address, err := util.HexStringTo20Bytes(w.Address) - if err != nil { - return nil, err - } - amount, err := util.ToUint64(w.Amount) - if err != nil { - return nil, err - } - return &state.Withdrawal{ - Index: index, - ValidatorIndex: validatorIndex, - Address: address, - Amount: amount, - }, nil -} - -func (h *HeaderResponse) ToFastSSZ() (*state.BeaconBlockHeader, error) { - slot, err := util.ToUint64(h.Slot) - if err != nil { - return nil, err - } - - proposerIndex, err := util.ToUint64(h.ProposerIndex) - if err != nil { - return nil, err - } - - parentRoot, err := util.HexStringToByteArray(h.ParentRoot) - if err != nil { - return nil, err - } - - stateRoot, err := util.HexStringToByteArray(h.StateRoot) - if err != nil { - return nil, err - } - - bodyRoot, err := util.HexStringToByteArray(h.BodyRoot) - if err != nil { - return nil, err - } - - return &state.BeaconBlockHeader{ - Slot: slot, - ProposerIndex: proposerIndex, - ParentRoot: parentRoot, - StateRoot: stateRoot, - BodyRoot: bodyRoot, - }, nil -} - func (h BeaconHeader) ToScale() (scale.BeaconHeader, error) { return scale.BeaconHeader{ Slot: types.NewU64(h.Slot), @@ -457,529 +378,6 @@ func (s SyncAggregateResponse) ToScale() (scale.SyncAggregate, error) { }, nil } -// ToFastSSZ can be removed once Lodestar supports returning block data as SSZ instead of JSON only. -// Because it only returns JSON, we need this interim step where we convert the block JSON to the data -// types that the FastSSZ lib expects. When Lodestar supports SSZ block response, we can remove all these -// and directly unmarshal SSZ bytes to state.BeaconBlock. -func (b BeaconBlockResponse) ToFastSSZ(isDeneb bool) (state.BeaconBlock, error) { - data := b.Data.Message - - slot, err := util.ToUint64(data.Slot) - if err != nil { - return nil, err - } - - proposerIndex, err := util.ToUint64(data.ProposerIndex) - if err != nil { - return nil, err - } - - parentRoot, err := util.HexStringToByteArray(data.ParentRoot) - if err != nil { - return nil, err - } - - stateRoot, err := util.HexStringToByteArray(data.StateRoot) - if err != nil { - return nil, err - } - - body := data.Body - - randaoReveal, err := util.HexStringToByteArray(body.RandaoReveal) - if err != nil { - return nil, err - } - - eth1DepositRoot, err := util.HexStringToByteArray(body.Eth1Data.DepositRoot) - if err != nil { - return nil, err - } - - eth1DepositCount, err := util.ToUint64(body.Eth1Data.DepositCount) - if err != nil { - return nil, err - } - - eth1BlockHash, err := util.HexStringToByteArray(body.Eth1Data.BlockHash) - if err != nil { - return nil, err - } - - graffiti, err := util.HexStringTo32Bytes(body.Graffiti) - if err != nil { - return nil, err - } - - proposerSlashings := []*state.ProposerSlashing{} - for _, proposerSlashing := range body.ProposerSlashings { - proposerSlashingSSZ, err := proposerSlashing.ToFastSSZ() - if err != nil { - return nil, err - } - - proposerSlashings = append(proposerSlashings, proposerSlashingSSZ) - } - - attesterSlashings := []*state.AttesterSlashing{} - for _, attesterSlashing := range body.AttesterSlashings { - attesterSlashingSSZ, err := attesterSlashing.ToFastSSZ() - if err != nil { - return nil, err - } - - attesterSlashings = append(attesterSlashings, attesterSlashingSSZ) - } - - attestations := []*state.Attestation{} - for _, attestation := range body.Attestations { - attestationSSZ, err := attestation.ToFastSSZ() - if err != nil { - return nil, err - } - - attestations = append(attestations, attestationSSZ) - } - - deposits := []*state.Deposit{} - for _, deposit := range body.Deposits { - depositScale, err := deposit.ToFastSSZ() - if err != nil { - return nil, err - } - - deposits = append(deposits, depositScale) - } - - voluntaryExits := []*state.SignedVoluntaryExit{} - for _, voluntaryExit := range body.VoluntaryExits { - voluntaryExitSSZ, err := voluntaryExit.ToFastSSZ() - if err != nil { - return nil, err - } - - voluntaryExits = append(voluntaryExits, voluntaryExitSSZ) - } - - executionPayload := body.ExecutionPayload - parentHash, err := util.HexStringTo32Bytes(executionPayload.ParentHash) - if err != nil { - return nil, err - } - - executionStateRoot, err := util.HexStringTo32Bytes(executionPayload.StateRoot) - if err != nil { - return nil, err - } - - receiptsRoot, err := util.HexStringTo32Bytes(executionPayload.ReceiptsRoot) - if err != nil { - return nil, err - } - - prevRando, err := util.HexStringTo32Bytes(executionPayload.PrevRandao) - if err != nil { - return nil, err - } - - n := new(big.Int) - n, ok := n.SetString(executionPayload.BaseFeePerGas, 10) - if !ok { - return nil, err - } - - // FastSSZ expects a little endian byte array - baseFeePerGas := util.ChangeByteOrder(n.Bytes()) - - var baseFeePerGasBytes [32]byte - copy(baseFeePerGasBytes[:], baseFeePerGas) - - blockHash, err := util.HexStringTo32Bytes(executionPayload.BlockHash) - if err != nil { - return nil, err - } - - feeRecipient, err := util.HexStringTo20Bytes(executionPayload.FeeRecipient) - if err != nil { - return nil, err - } - - logsBloom, err := util.HexStringTo256Bytes(executionPayload.LogsBloom) - if err != nil { - return nil, err - } - - extraData, err := util.HexStringToByteArray(executionPayload.ExtraData) - if err != nil { - return nil, err - } - - transactions := [][]byte{} - for _, transaction := range executionPayload.Transactions { - transactionSSZ, err := util.HexStringToByteArray(transaction) - if err != nil { - return nil, err - } - - transactions = append(transactions, transactionSSZ) - } - - withdrawals := []*state.Withdrawal{} - for _, withdrawalResponse := range executionPayload.Withdrawals { - withdrawalSSZ, err := withdrawalResponse.ToFastSSZ() - if err != nil { - return nil, err - } - withdrawals = append(withdrawals, withdrawalSSZ) - } - - blockNumber, err := util.ToUint64(executionPayload.BlockNumber) - if err != nil { - return nil, err - } - - gasLimit, err := util.ToUint64(executionPayload.GasLimit) - if err != nil { - return nil, err - } - - gasUsed, err := util.ToUint64(executionPayload.GasUsed) - if err != nil { - return nil, err - } - - timestamp, err := util.ToUint64(executionPayload.Timestamp) - if err != nil { - return nil, err - } - - blobGasUsed, err := util.ToUint64AllowEmpty(executionPayload.BlobGasUsed) - if err != nil { - return nil, err - } - - excessBlobGas, err := util.ToUint64AllowEmpty(executionPayload.ExcessBlobGas) - if err != nil { - return nil, err - } - - syncCommitteeBits, err := util.HexStringToByteArray(body.SyncAggregate.SyncCommitteeBits) - if err != nil { - return nil, err - } - - syncCommitteeSignature, err := util.HexStringTo96Bytes(body.SyncAggregate.SyncCommitteeSignature) - if err != nil { - return nil, err - } - - blsExecutionChanges := []*state.SignedBLSToExecutionChange{} - for _, changeResponse := range body.BlsToExecutionChanges { - changeSSZ, err := changeResponse.ToFastSSZ() - if err != nil { - return nil, err - } - blsExecutionChanges = append(blsExecutionChanges, changeSSZ) - } - - var kzgCommitments [][48]byte - for _, kzgCommitment := range body.BlobKzgCommitments { - kzgCommitmentSSZ, err := util.HexStringTo48Bytes(kzgCommitment) - if err != nil { - return nil, err - } - kzgCommitments = append(kzgCommitments, kzgCommitmentSSZ) - } - - if isDeneb { - return &state.BeaconBlockDenebMainnet{ - Slot: slot, - ProposerIndex: proposerIndex, - ParentRoot: parentRoot, - StateRoot: stateRoot, - Body: &state.BeaconBlockBodyDenebMainnet{ - RandaoReveal: randaoReveal, - Eth1Data: &state.Eth1Data{ - DepositRoot: eth1DepositRoot, - DepositCount: eth1DepositCount, - BlockHash: eth1BlockHash, - }, - Graffiti: graffiti, - ProposerSlashings: proposerSlashings, - AttesterSlashings: attesterSlashings, - Attestations: attestations, - Deposits: deposits, - VoluntaryExits: voluntaryExits, - SyncAggregate: &state.SyncAggregateMainnet{ - SyncCommitteeBits: syncCommitteeBits, - SyncCommitteeSignature: syncCommitteeSignature, - }, - ExecutionPayload: &state.ExecutionPayloadDeneb{ - ParentHash: parentHash, - FeeRecipient: feeRecipient, - StateRoot: executionStateRoot, - ReceiptsRoot: receiptsRoot, - LogsBloom: logsBloom, - PrevRandao: prevRando, - BlockNumber: blockNumber, - GasLimit: gasLimit, - GasUsed: gasUsed, - Timestamp: timestamp, - ExtraData: extraData, - BaseFeePerGas: baseFeePerGasBytes, - BlockHash: blockHash, - Transactions: transactions, - Withdrawals: withdrawals, - BlobGasUsed: blobGasUsed, // new for Deneb - ExcessBlobGas: excessBlobGas, // new for Deneb - }, - BlsToExecutionChanges: blsExecutionChanges, - BlobKzgCommitments: kzgCommitments, // new for Deneb - }, - }, nil - } - return &state.BeaconBlockCapellaMainnet{ - Slot: slot, - ProposerIndex: proposerIndex, - ParentRoot: parentRoot, - StateRoot: stateRoot, - Body: &state.BeaconBlockBodyCapellaMainnet{ - RandaoReveal: randaoReveal, - Eth1Data: &state.Eth1Data{ - DepositRoot: eth1DepositRoot, - DepositCount: eth1DepositCount, - BlockHash: eth1BlockHash, - }, - Graffiti: graffiti, - ProposerSlashings: proposerSlashings, - AttesterSlashings: attesterSlashings, - Attestations: attestations, - Deposits: deposits, - VoluntaryExits: voluntaryExits, - SyncAggregate: &state.SyncAggregateMainnet{ - SyncCommitteeBits: syncCommitteeBits, - SyncCommitteeSignature: syncCommitteeSignature, - }, - ExecutionPayload: &state.ExecutionPayloadCapella{ - ParentHash: parentHash, - FeeRecipient: feeRecipient, - StateRoot: executionStateRoot, - ReceiptsRoot: receiptsRoot, - LogsBloom: logsBloom, - PrevRandao: prevRando, - BlockNumber: blockNumber, - GasLimit: gasLimit, - GasUsed: gasUsed, - Timestamp: timestamp, - ExtraData: extraData, - BaseFeePerGas: baseFeePerGasBytes, - BlockHash: blockHash, - Transactions: transactions, - Withdrawals: withdrawals, // new for Capella - }, - BlsToExecutionChanges: blsExecutionChanges, // new for Capella - }, - }, nil -} - -func (p ProposerSlashingResponse) ToFastSSZ() (*state.ProposerSlashing, error) { - signedHeader1, err := p.SignedHeader1.ToFastSSZ() - if err != nil { - return nil, err - } - - signedHeader2, err := p.SignedHeader2.ToFastSSZ() - if err != nil { - return nil, err - } - - return &state.ProposerSlashing{ - Header1: signedHeader1, - Header2: signedHeader2, - }, nil -} - -func (a AttesterSlashingResponse) ToFastSSZ() (*state.AttesterSlashing, error) { - attestation1, err := a.Attestation1.ToFastSSZ() - if err != nil { - return nil, err - } - - attestation2, err := a.Attestation2.ToFastSSZ() - if err != nil { - return nil, err - } - - return &state.AttesterSlashing{ - Attestation1: attestation1, - Attestation2: attestation2, - }, nil -} - -func (a AttestationResponse) ToFastSSZ() (*state.Attestation, error) { - data, err := a.Data.ToFastSSZ() - if err != nil { - return nil, err - } - - aggregationBits, err := util.HexStringToByteArray(a.AggregationBits) - if err != nil { - return nil, err - } - - signature, err := util.HexStringTo96Bytes(a.Signature) - if err != nil { - return nil, err - } - - return &state.Attestation{ - AggregationBits: aggregationBits, - Data: data, - Signature: signature, - }, nil -} - -func (d SignedVoluntaryExitResponse) ToFastSSZ() (*state.SignedVoluntaryExit, error) { - epoch, err := util.ToUint64(d.Message.Epoch) - if err != nil { - return nil, err - } - - validaterIndex, err := util.ToUint64(d.Message.ValidatorIndex) - if err != nil { - return nil, err - } - - signature, err := util.HexStringTo96Bytes(d.Signature) - if err != nil { - return nil, err - } - - return &state.SignedVoluntaryExit{ - Exit: &state.VoluntaryExit{ - Epoch: epoch, - ValidatorIndex: validaterIndex, - }, - Signature: signature, - }, nil -} - -func (d DepositResponse) ToFastSSZ() (*state.Deposit, error) { - proofs := [][]byte{} - for _, proofData := range d.Proof { - proofs = append(proofs, common.HexToHash(proofData).Bytes()) - } - - amount, err := util.ToUint64(d.Data.Amount) - if err != nil { - return nil, err - } - - pubkey, err := util.HexStringToPublicKey(d.Data.Pubkey) - if err != nil { - return nil, err - } - - signature, err := util.HexStringToByteArray(d.Data.Signature) - if err != nil { - return nil, err - } - - withdrawalCredentials, err := util.HexStringTo32Bytes(d.Data.WithdrawalCredentials) - if err != nil { - return nil, err - } - - return &state.Deposit{ - Proof: proofs, - Data: &state.DepositData{ - Pubkey: pubkey, - WithdrawalCredentials: withdrawalCredentials, - Amount: amount, - Signature: signature, - }, - }, nil -} - -func (s SignedHeaderResponse) ToFastSSZ() (*state.SignedBeaconBlockHeader, error) { - message, err := s.Message.ToFastSSZ() - if err != nil { - return nil, err - } - signature, err := util.HexStringToByteArray(s.Signature) - if err != nil { - return nil, err - } - - return &state.SignedBeaconBlockHeader{ - Header: message, - Signature: signature, - }, nil -} - -func (i IndexedAttestationResponse) ToFastSSZ() (*state.IndexedAttestation, error) { - data, err := i.Data.ToFastSSZ() - if err != nil { - return nil, err - } - - attestationIndexes := []uint64{} - for _, index := range i.AttestingIndices { - indexInt, err := util.ToUint64(index) - if err != nil { - return nil, err - } - - attestationIndexes = append(attestationIndexes, indexInt) - } - - signature, err := util.HexStringToByteArray(i.Signature) - if err != nil { - return nil, err - } - - return &state.IndexedAttestation{ - AttestationIndices: attestationIndexes, - Data: data, - Signature: signature, - }, nil -} - -func (a AttestationDataResponse) ToFastSSZ() (*state.AttestationData, error) { - slot, err := util.ToUint64(a.Slot) - if err != nil { - return nil, err - } - - index, err := util.ToUint64(a.Index) - if err != nil { - return nil, err - } - - source, err := a.Source.ToFastSSZ() - if err != nil { - return nil, err - } - - target, err := a.Target.ToFastSSZ() - if err != nil { - return nil, err - } - - hash, err := util.HexStringTo32Bytes(a.BeaconBlockRoot) - if err != nil { - return nil, err - } - - return &state.AttestationData{ - Slot: state.Slot(slot), - Index: index, - BeaconBlockHash: hash, - Source: source, - Target: target, - }, nil -} - func (c CheckpointResponse) ToScale() (scale.Checkpoint, error) { epoch, err := util.ToUint64(c.Epoch) if err != nil { @@ -992,18 +390,6 @@ func (c CheckpointResponse) ToScale() (scale.Checkpoint, error) { }, nil } -func (c CheckpointResponse) ToFastSSZ() (*state.Checkpoint, error) { - epoch, err := util.ToUint64(c.Epoch) - if err != nil { - return nil, err - } - - return &state.Checkpoint{ - Epoch: epoch, - Root: common.HexToHash(c.Root).Bytes(), - }, nil -} - func CapellaExecutionPayloadToScale(e *state.ExecutionPayloadCapella) (scale.ExecutionPayloadHeaderCapella, error) { transactionsContainer := state.TransactionsRootContainer{} transactionsContainer.Transactions = e.Transactions @@ -1045,46 +431,3 @@ func CapellaExecutionPayloadToScale(e *state.ExecutionPayloadCapella) (scale.Exe WithdrawalsRoot: withdrawalRoot, }, nil } - -func CapellaJsonExecutionPayloadHeaderToScale(e *beaconjson.FullExecutionPayloadHeaderJson) (scale.ExecutionPayloadHeaderCapella, error) { - var executionPayloadHeader scale.ExecutionPayloadHeaderCapella - var baseFeePerGas big.Int - baseFeePerGasU64, err := util.ToUint64(e.BaseFeePerGas) - if err != nil { - return executionPayloadHeader, err - } - blockNumber, err := util.ToUint64(e.BlockNumber) - if err != nil { - return executionPayloadHeader, err - } - baseFeePerGas.SetUint64(baseFeePerGasU64) - gasLimit, err := util.ToUint64(e.GasLimit) - if err != nil { - return executionPayloadHeader, err - } - gasUsed, err := util.ToUint64(e.GasUsed) - if err != nil { - return executionPayloadHeader, err - } - timestamp, err := util.ToUint64(e.Timestamp) - if err != nil { - return executionPayloadHeader, err - } - return scale.ExecutionPayloadHeaderCapella{ - ParentHash: types.NewH256(common.HexToHash(e.ParentHash).Bytes()), - FeeRecipient: types.NewH160(common.HexToAddress(e.FeeRecipient).Bytes()), - StateRoot: types.NewH256(common.HexToHash(e.StateRoot).Bytes()), - ReceiptsRoot: types.NewH256(common.HexToHash(e.ReceiptsRoot).Bytes()), - LogsBloom: common.Hex2Bytes(e.LogsBloom), - PrevRandao: types.NewH256(common.HexToHash(e.PrevRandao).Bytes()), - BlockNumber: types.NewU64(blockNumber), - GasLimit: types.NewU64(gasLimit), - GasUsed: types.NewU64(gasUsed), - Timestamp: types.NewU64(timestamp), - ExtraData: common.Hex2Bytes(e.ExtraData), - BaseFeePerGas: types.NewU256(baseFeePerGas), - BlockHash: types.NewH256(common.HexToHash(e.ParentHash).Bytes()), - TransactionsRoot: types.NewH256(common.HexToHash(e.TransactionsRoot).Bytes()), - WithdrawalsRoot: types.NewH256(common.HexToHash(e.WithdrawalsRoot).Bytes()), - }, nil -} diff --git a/relayer/relays/beacon/header/syncer/json/beacon_json_deneb.go b/relayer/relays/beacon/header/syncer/json/beacon_json_deneb.go index 1c05aed0eb..c5d924da58 100644 --- a/relayer/relays/beacon/header/syncer/json/beacon_json_deneb.go +++ b/relayer/relays/beacon/header/syncer/json/beacon_json_deneb.go @@ -20,26 +20,6 @@ type ExecutionPayloadHeaderDeneb struct { ExcessBlobGas uint64 `json:"excess_blob_gas"` } -type FullExecutionPayloadHeaderJson struct { - ParentHash string `json:"parent_hash"` - FeeRecipient string `json:"fee_recipient"` - StateRoot string `json:"state_root"` - ReceiptsRoot string `json:"receipts_root"` - LogsBloom string `json:"logs_bloom"` - PrevRandao string `json:"prev_randao"` - BlockNumber string `json:"block_number"` - GasLimit string `json:"gas_limit"` - GasUsed string `json:"gas_used"` - Timestamp string `json:"timestamp"` - ExtraData string `json:"extra_data"` - BaseFeePerGas string `json:"base_fee_per_gas"` - BlockHash string `json:"block_hash"` - TransactionsRoot string `json:"transactions_root"` - WithdrawalsRoot string `json:"withdrawals_root"` - BlobGasUsed string `json:"blob_gas_used,omitempty"` - ExcessBlobGas string `json:"excess_blob_gas,omitempty"` -} - func (e *ExecutionPayloadHeaderDeneb) RemoveLeadingZeroHashes() { e.ParentHash = removeLeadingZeroHash(e.ParentHash) e.FeeRecipient = removeLeadingZeroHash(e.FeeRecipient) diff --git a/relayer/relays/beacon/header/syncer/syncer.go b/relayer/relays/beacon/header/syncer/syncer.go index 8016ed4ba1..423cdc4219 100644 --- a/relayer/relays/beacon/header/syncer/syncer.go +++ b/relayer/relays/beacon/header/syncer/syncer.go @@ -6,6 +6,7 @@ import ( "fmt" "os" "strconv" + "time" "github.com/snowfork/go-substrate-rpc-client/v4/types" "github.com/snowfork/snowbridge/relayer/relays/beacon/cache" @@ -22,14 +23,6 @@ import ( log "github.com/sirupsen/logrus" ) -const ( - BlockRootGeneralizedIndex = 37 - FinalizedCheckpointGeneralizedIndex = 105 - CurrentSyncCommitteeGeneralizedIndex = 54 - NextSyncCommitteeGeneralizedIndex = 55 - ExecutionPayloadGeneralizedIndex = 25 -) - var ( ErrCommitteeUpdateHeaderInDifferentSyncPeriod = errors.New("sync committee in different sync period") ErrBeaconStateUnavailable = errors.New("beacon state object not available yet") @@ -59,12 +52,20 @@ type finalizedUpdateContainer struct { } func (s *Syncer) GetCheckpoint() (scale.BeaconCheckpoint, error) { - checkpoint, err := s.Client.GetFinalizedCheckpoint() + retries := 5 + bootstrap, err := s.getCheckpoint() if err != nil { - return scale.BeaconCheckpoint{}, fmt.Errorf("get finalized checkpoint: %w", err) + for retries > 0 { + retries = retries - 1 + bootstrap, err = s.getCheckpoint() + if err != nil { + log.WithError(err).Info("retry bootstrap, sleeping") + time.Sleep(10 * time.Second) + continue + } + break + } } - - bootstrap, err := s.Client.GetBootstrap(checkpoint.FinalizedBlockRoot) if err != nil { return scale.BeaconCheckpoint{}, fmt.Errorf("get bootstrap: %w", err) } @@ -99,6 +100,20 @@ func (s *Syncer) GetCheckpoint() (scale.BeaconCheckpoint, error) { }, nil } +func (s *Syncer) getCheckpoint() (api.BootstrapResponse, error) { + checkpoint, err := s.Client.GetFinalizedCheckpoint() + if err != nil { + return api.BootstrapResponse{}, fmt.Errorf("get finalized checkpoint: %w", err) + } + + bootstrap, err := s.Client.GetBootstrap(checkpoint.FinalizedBlockRoot) + if err != nil { + return api.BootstrapResponse{}, fmt.Errorf("get bootstrap: %w", err) + } + + return bootstrap, err +} + func (s *Syncer) GetCheckpointFromFile(file string) (scale.BeaconCheckpoint, error) { type CheckPointResponse struct { Header api.BeaconHeader `json:"header"` @@ -170,7 +185,7 @@ func (s *Syncer) GetCheckpointAtSlot(slot uint64) (scale.BeaconCheckpoint, error _ = stateTree.Hash() // necessary to populate the proof tree values - proof, err := stateTree.Prove(CurrentSyncCommitteeGeneralizedIndex) + proof, err := stateTree.Prove(s.protocol.CurrentSyncCommitteeGeneralizedIndex(uint64(checkpoint.Payload.FinalizedHeader.Slot))) if err != nil { return scale.BeaconCheckpoint{}, fmt.Errorf("get block roof proof: %w", err) } @@ -295,10 +310,13 @@ func (s *Syncer) GetBlockRoots(slot uint64) (scale.BlockRootProof, error) { if err != nil { return blockRootProof, fmt.Errorf("fetch beacon state: %w", err) } - isDeneb := s.protocol.DenebForked(slot) + + forkVersion := s.protocol.ForkVersion(slot) blockRootsContainer = &state.BlockRootsContainerMainnet{} - if isDeneb { + if forkVersion == protocol.Electra { + beaconState = &state.BeaconStateElectra{} + } else if forkVersion == protocol.Deneb { beaconState = &state.BeaconStateDenebMainnet{} } else { beaconState = &state.BeaconStateCapellaMainnet{} @@ -316,7 +334,7 @@ func (s *Syncer) GetBlockRoots(slot uint64) (scale.BlockRootProof, error) { _ = stateTree.Hash() // necessary to populate the proof tree values - proof, err := stateTree.Prove(BlockRootGeneralizedIndex) + proof, err := stateTree.Prove(s.protocol.BlockRootGeneralizedIndex(slot)) if err != nil { return scale.BlockRootProof{}, fmt.Errorf("get block roof proof: %w", err) } @@ -353,7 +371,7 @@ func (s *Syncer) GetBlockRootsFromState(beaconState state.BeaconState) (scale.Bl _ = stateTree.Hash() // necessary to populate the proof tree values - proof, err := stateTree.Prove(BlockRootGeneralizedIndex) + proof, err := stateTree.Prove(s.protocol.BlockRootGeneralizedIndex(beaconState.GetSlot())) if err != nil { return scale.BlockRootProof{}, fmt.Errorf("get block roof proof: %w", err) } @@ -525,24 +543,29 @@ func (s *Syncer) GetHeaderUpdateBySlotWithCheckpoint(slot uint64, checkpoint *ca func (s *Syncer) GetHeaderUpdate(blockRoot common.Hash, checkpoint *cache.Proof) (scale.HeaderUpdatePayload, error) { var update scale.HeaderUpdatePayload - blockResponse, err := s.Client.GetBeaconBlock(blockRoot) + blockBytes, err := s.Client.GetBeaconBlockBytes(blockRoot) if err != nil { return update, fmt.Errorf("fetch block: %w", err) } - data := blockResponse.Data.Message - slot, err := util.ToUint64(data.Slot) + + header, err := s.Client.GetHeaderByBlockRoot(blockRoot) if err != nil { - return update, err + return scale.HeaderUpdatePayload{}, fmt.Errorf("fetch block: %w", err) } - sszBlock, err := blockResponse.ToFastSSZ(s.protocol.DenebForked(slot)) - if err != nil { - return update, err + slot := header.Slot + + var signedBlock state.SignedBeaconBlock + forkVersion := s.protocol.ForkVersion(slot) + if forkVersion == protocol.Electra { + signedBlock = &state.SignedBeaconBlockElectra{} + } else { + signedBlock = &state.SignedBeaconBlockDeneb{} } - header, err := s.Client.GetHeaderBySlot(sszBlock.GetBeaconSlot()) + err = signedBlock.UnmarshalSSZ(blockBytes) if err != nil { - return scale.HeaderUpdatePayload{}, fmt.Errorf("fetch block: %w", err) + return scale.HeaderUpdatePayload{}, fmt.Errorf("unmarshal block ssz: %w", err) } beaconHeader, err := header.ToScale() @@ -550,20 +573,22 @@ func (s *Syncer) GetHeaderUpdate(blockRoot common.Hash, checkpoint *cache.Proof) return scale.HeaderUpdatePayload{}, fmt.Errorf("beacon header to scale: %w", err) } - executionHeaderBranch, err := s.getExecutionHeaderBranch(sszBlock) + beaconBlock := signedBlock.GetBlock() + executionHeaderBranch, err := s.getExecutionHeaderBranch(beaconBlock) if err != nil { return scale.HeaderUpdatePayload{}, err } var versionedExecutionPayloadHeader scale.VersionedExecutionPayloadHeader - if s.protocol.DenebForked(slot) { - executionPayloadScale, err := api.DenebExecutionPayloadToScale(sszBlock.ExecutionPayloadDeneb()) + // The execution payload did not change in Electra, so we reuse Deneb's version. + if forkVersion == protocol.Electra || forkVersion == protocol.Deneb { + executionPayloadScale, err := api.DenebExecutionPayloadToScale(beaconBlock.ExecutionPayloadDeneb()) if err != nil { return scale.HeaderUpdatePayload{}, err } versionedExecutionPayloadHeader = scale.VersionedExecutionPayloadHeader{Deneb: &executionPayloadScale} } else { - executionPayloadScale, err := api.CapellaExecutionPayloadToScale(sszBlock.ExecutionPayloadCapella()) + executionPayloadScale, err := api.CapellaExecutionPayloadToScale(beaconBlock.ExecutionPayloadCapella()) if err != nil { return scale.HeaderUpdatePayload{}, err } @@ -571,7 +596,7 @@ func (s *Syncer) GetHeaderUpdate(blockRoot common.Hash, checkpoint *cache.Proof) } // If checkpoint not provided or slot == finalizedSlot there won't be an ancestry proof because the header state in question is also the finalized header - if checkpoint == nil || sszBlock.GetBeaconSlot() == checkpoint.Slot { + if checkpoint == nil || beaconBlock.GetBeaconSlot() == checkpoint.Slot { return scale.HeaderUpdatePayload{ Header: beaconHeader, AncestryProof: scale.OptionAncestryProof{ @@ -582,7 +607,7 @@ func (s *Syncer) GetHeaderUpdate(blockRoot common.Hash, checkpoint *cache.Proof) }, nil } - proofScale, err := s.getBlockHeaderAncestryProof(int(sszBlock.GetBeaconSlot()), blockRoot, checkpoint.BlockRootsTree) + proofScale, err := s.getBlockHeaderAncestryProof(int(beaconBlock.GetBeaconSlot()), blockRoot, checkpoint.BlockRootsTree) if err != nil { return scale.HeaderUpdatePayload{}, err } @@ -618,9 +643,10 @@ func (s *Syncer) getBeaconStateAtSlot(slot uint64) (state.BeaconState, error) { func (s *Syncer) UnmarshalBeaconState(slot uint64, data []byte) (state.BeaconState, error) { var beaconState state.BeaconState - isDeneb := s.protocol.DenebForked(slot) - - if isDeneb { + forkVersion := s.protocol.ForkVersion(slot) + if forkVersion == protocol.Electra { + beaconState = &state.BeaconStateElectra{} + } else if forkVersion == protocol.Deneb { beaconState = &state.BeaconStateDenebMainnet{} } else { beaconState = &state.BeaconStateCapellaMainnet{} @@ -779,14 +805,14 @@ func (s *Syncer) GetFinalizedUpdateAtAttestedSlot(minSlot, maxSlot uint64, fetch return update, fmt.Errorf("get state tree: %w", err) } _ = stateTree.Hash() // necessary to populate the proof tree values - finalizedHeaderProof, err := stateTree.Prove(FinalizedCheckpointGeneralizedIndex) + finalizedHeaderProof, err := stateTree.Prove(s.protocol.FinalizedCheckpointGeneralizedIndex(attestedSlot)) if err != nil { return update, fmt.Errorf("get finalized header proof: %w", err) } var nextSyncCommitteeScale scale.OptionNextSyncCommitteeUpdatePayload if fetchNextSyncCommittee { - nextSyncCommitteeProof, err := stateTree.Prove(NextSyncCommitteeGeneralizedIndex) + nextSyncCommitteeProof, err := stateTree.Prove(s.protocol.NextSyncCommitteeGeneralizedIndex(attestedSlot)) if err != nil { return update, fmt.Errorf("get finalized header proof: %w", err) } @@ -901,7 +927,7 @@ func (s *Syncer) getExecutionHeaderBranch(block state.BeaconBlock) ([]types.H256 tree.Hash() - proof, err := tree.Prove(ExecutionPayloadGeneralizedIndex) + proof, err := tree.Prove(s.protocol.ExecutionPayloadGeneralizedIndex(block.GetBeaconSlot())) return util.BytesBranchToScale(proof.Hashes), nil } diff --git a/relayer/relays/beacon/header/syncer/syncer_test.go b/relayer/relays/beacon/header/syncer/syncer_test.go index b74dfb15c2..a3b534a2cd 100644 --- a/relayer/relays/beacon/header/syncer/syncer_test.go +++ b/relayer/relays/beacon/header/syncer/syncer_test.go @@ -25,7 +25,6 @@ func newTestRunner() *Syncer { return New(api.NewBeaconClient(TestUrl, TestUrl), &mock.Store{}, protocol.New(config.SpecSettings{ SlotsInEpoch: 32, EpochsPerSyncCommitteePeriod: 256, - DenebForkEpoch: 0, }, MaxRedundancy)) } @@ -110,7 +109,6 @@ func TestGetFinalizedUpdateWithSyncCommitteeUpdateAtSlot(t *testing.T) { }, protocol.New(config.SpecSettings{ SlotsInEpoch: 32, EpochsPerSyncCommitteePeriod: 256, - DenebForkEpoch: 0, }, MaxRedundancy)) // Manually construct a finalized update @@ -165,7 +163,6 @@ func TestFindAttestedAndFinalizedHeadersAtBoundary(t *testing.T) { syncer := New(&mockAPI, &mock.Store{}, protocol.New(config.SpecSettings{ SlotsInEpoch: 32, EpochsPerSyncCommitteePeriod: 256, - DenebForkEpoch: 0, }, MaxRedundancy)) attested, err := syncer.FindValidAttestedHeader(8000, 8160) @@ -195,7 +192,6 @@ func TestFindAttestedAndFinalizedHeadersAtBoundary(t *testing.T) { syncer = New(&mockAPI, &mock.Store{}, protocol.New(config.SpecSettings{ SlotsInEpoch: 32, EpochsPerSyncCommitteePeriod: 256, - DenebForkEpoch: 0, }, MaxRedundancy)) attested, err = syncer.FindValidAttestedHeader(32576, 32704) @@ -225,7 +221,6 @@ func TestFindAttestedAndFinalizedHeadersAtBoundary(t *testing.T) { syncer = New(&mockAPI, &mock.Store{}, protocol.New(config.SpecSettings{ SlotsInEpoch: 32, EpochsPerSyncCommitteePeriod: 256, - DenebForkEpoch: 0, }, MaxRedundancy)) attested, err = syncer.FindValidAttestedHeader(25076, 32736) @@ -249,7 +244,6 @@ func TestFindAttestedAndFinalizedHeadersAtBoundary(t *testing.T) { syncer = New(&mockAPI, &mock.Store{}, protocol.New(config.SpecSettings{ SlotsInEpoch: 32, EpochsPerSyncCommitteePeriod: 256, - DenebForkEpoch: 0, }, MaxRedundancy)) attested, err = syncer.FindValidAttestedHeader(32540, 32768) diff --git a/relayer/relays/beacon/mock/mock_api.go b/relayer/relays/beacon/mock/mock_api.go index 5fbc9746dd..2cab184f36 100644 --- a/relayer/relays/beacon/mock/mock_api.go +++ b/relayer/relays/beacon/mock/mock_api.go @@ -53,6 +53,10 @@ func (m *API) GetBeaconBlockBySlot(slot uint64) (api.BeaconBlockResponse, error) return value, nil } +func (m *API) GetBeaconBlockBytes(blockRoot common.Hash) ([]byte, error) { + return nil, nil +} + func (m *API) GetBeaconBlockRoot(slot uint64) (common.Hash, error) { return common.Hash{}, nil } diff --git a/relayer/relays/beacon/protocol/protocol.go b/relayer/relays/beacon/protocol/protocol.go index a81a6b30e2..6c5af5d7a2 100644 --- a/relayer/relays/beacon/protocol/protocol.go +++ b/relayer/relays/beacon/protocol/protocol.go @@ -4,6 +4,7 @@ import ( "encoding/hex" "strings" + log "github.com/sirupsen/logrus" "github.com/snowfork/snowbridge/relayer/relays/beacon/config" ) @@ -14,6 +15,7 @@ type Protocol struct { } func New(setting config.SpecSettings, headerRedundancy uint64) *Protocol { + log.WithField("settings", setting).Info("protocol settings") return &Protocol{ Settings: setting, SlotsPerHistoricalRoot: setting.SlotsInEpoch * setting.EpochsPerSyncCommitteePeriod, @@ -44,10 +46,6 @@ func (p *Protocol) CalculateNextCheckpointSlot(slot uint64) uint64 { return (syncPeriod + 1) * p.Settings.SlotsInEpoch * p.Settings.EpochsPerSyncCommitteePeriod } -func (p *Protocol) DenebForked(slot uint64) bool { - return p.ComputeEpochAtSlot(slot) >= p.Settings.DenebForkEpoch -} - func (p *Protocol) SyncPeriodLength() uint64 { return p.Settings.SlotsInEpoch * p.Settings.EpochsPerSyncCommitteePeriod } @@ -76,3 +74,58 @@ func (p *Protocol) SyncCommitteeSuperMajority(syncCommitteeHex string) (bool, er } return true, nil } + +// ForkVersion is a custom type for Ethereum fork versions. +type ForkVersion string + +const ( + Deneb ForkVersion = "Deneb" + Capella ForkVersion = "Capella" + Electra ForkVersion = "Electra" +) + +func (p *Protocol) ForkVersion(slot uint64) ForkVersion { + epoch := p.ComputeEpochAtSlot(slot) + if epoch >= p.Settings.ForkVersions.Electra { + return Electra + } + if epoch >= p.Settings.ForkVersions.Deneb { + return Deneb + } + return Capella +} + +func (p *Protocol) BlockRootGeneralizedIndex(slot uint64) int { + if p.ForkVersion(slot) == Electra { + return ElectraBlockRootGeneralizedIndex + } + return AltairBlockRootGeneralizedIndex +} + +func (p *Protocol) FinalizedCheckpointGeneralizedIndex(slot uint64) int { + if p.ForkVersion(slot) == Electra { + return ElectraFinalizedCheckpointGeneralizedIndex + } + return AltairFinalizedCheckpointGeneralizedIndex +} + +func (p *Protocol) CurrentSyncCommitteeGeneralizedIndex(slot uint64) int { + if p.ForkVersion(slot) == Electra { + return ElectraCurrentSyncCommitteeGeneralizedIndex + } + return AltairCurrentSyncCommitteeGeneralizedIndex +} + +func (p *Protocol) NextSyncCommitteeGeneralizedIndex(slot uint64) int { + if p.ForkVersion(slot) == Electra { + return ElectraNextSyncCommitteeGeneralizedIndex + } + return AltairNextSyncCommitteeGeneralizedIndex +} + +func (p *Protocol) ExecutionPayloadGeneralizedIndex(slot uint64) int { + if p.ForkVersion(slot) == Electra { + return ElectraExecutionPayloadGeneralizedIndex + } + return AltairExecutionPayloadGeneralizedIndex +} diff --git a/relayer/relays/beacon/protocol/protocol_altair.go b/relayer/relays/beacon/protocol/protocol_altair.go new file mode 100644 index 0000000000..6467b932f0 --- /dev/null +++ b/relayer/relays/beacon/protocol/protocol_altair.go @@ -0,0 +1,9 @@ +package protocol + +const ( + AltairBlockRootGeneralizedIndex = 37 + AltairFinalizedCheckpointGeneralizedIndex = 105 + AltairCurrentSyncCommitteeGeneralizedIndex = 54 + AltairNextSyncCommitteeGeneralizedIndex = 55 + AltairExecutionPayloadGeneralizedIndex = 25 +) diff --git a/relayer/relays/beacon/protocol/protocol_electra.go b/relayer/relays/beacon/protocol/protocol_electra.go new file mode 100644 index 0000000000..5d96e5f736 --- /dev/null +++ b/relayer/relays/beacon/protocol/protocol_electra.go @@ -0,0 +1,9 @@ +package protocol + +const ( + ElectraBlockRootGeneralizedIndex = 69 + ElectraFinalizedCheckpointGeneralizedIndex = 169 + ElectraCurrentSyncCommitteeGeneralizedIndex = 86 + ElectraNextSyncCommitteeGeneralizedIndex = 87 + ElectraExecutionPayloadGeneralizedIndex = 25 +) diff --git a/relayer/relays/beacon/state/beacon.go b/relayer/relays/beacon/state/beacon.go index bd0f5e8907..0cde4c5dbe 100644 --- a/relayer/relays/beacon/state/beacon.go +++ b/relayer/relays/beacon/state/beacon.go @@ -191,6 +191,11 @@ type BeaconBlock interface { GetBlockBodyTree() (*ssz.Node, error) } +type SignedBeaconBlock interface { + UnmarshalSSZ(buf []byte) error + GetBlock() BeaconBlock +} + func (b *BlockRootsContainerMainnet) SetBlockRoots(blockRoots [][]byte) { b.BlockRoots = blockRoots } diff --git a/relayer/relays/beacon/state/beacon_deneb.go b/relayer/relays/beacon/state/beacon_deneb.go index f68f43ccfe..e48b6893b3 100644 --- a/relayer/relays/beacon/state/beacon_deneb.go +++ b/relayer/relays/beacon/state/beacon_deneb.go @@ -20,8 +20,8 @@ type ExecutionPayloadDeneb struct { BlockHash [32]byte `ssz-size:"32" json:"block_hash"` Transactions [][]byte `ssz-max:"1048576,1073741824" ssz-size:"?,?" json:"transactions"` Withdrawals []*Withdrawal `ssz-max:"16" json:"withdrawals"` - BlobGasUsed uint64 `json:"blob_gas_used,omitempty"` - ExcessBlobGas uint64 `json:"excess_blob_gas,omitempty"` + BlobGasUsed uint64 `json:"blob_gas_used,omitempty"` // New in Deneb + ExcessBlobGas uint64 `json:"excess_blob_gas,omitempty"` // New in Deneb } type ExecutionPayloadHeaderDeneb struct { @@ -40,8 +40,13 @@ type ExecutionPayloadHeaderDeneb struct { BlockHash []byte `json:"block_hash" ssz-size:"32"` TransactionsRoot []byte `json:"transactions_root" ssz-size:"32"` WithdrawalsRoot []byte `json:"withdrawals_root" ssz-size:"32"` - BlobGasUsed uint64 `json:"blob_gas_used,omitempty"` - ExcessBlobGas uint64 `json:"excess_blob_gas,omitempty"` + BlobGasUsed uint64 `json:"blob_gas_used,omitempty"` // New in Deneb + ExcessBlobGas uint64 `json:"excess_blob_gas,omitempty"` // New in Deneb +} + +type SignedBeaconBlockDeneb struct { + Message BeaconBlockDenebMainnet + Signature [96]byte `json:"signature,omitempty" ssz-size:"96"` } type BeaconBlockDenebMainnet struct { @@ -64,7 +69,7 @@ type BeaconBlockBodyDenebMainnet struct { SyncAggregate *SyncAggregateMainnet `json:"sync_aggregate"` ExecutionPayload *ExecutionPayloadDeneb `json:"execution_payload"` BlsToExecutionChanges []*SignedBLSToExecutionChange `json:"bls_to_execution_changes,omitempty" ssz-max:"16"` - BlobKzgCommitments [][48]byte `json:"blob_kzg_commitments,omitempty" ssz-max:"4096" ssz-size:"?,48"` + BlobKzgCommitments [][48]byte `json:"blob_kzg_commitments,omitempty" ssz-max:"4096" ssz-size:"?,48"` // New in Deneb } type BeaconStateDenebMainnet struct { @@ -140,3 +145,6 @@ func (b *BeaconStateDenebMainnet) GetNextSyncCommittee() *SyncCommittee { func (b *BeaconStateDenebMainnet) GetCurrentSyncCommittee() *SyncCommittee { return b.CurrentSyncCommittee } +func (b *SignedBeaconBlockDeneb) GetBlock() BeaconBlock { + return &b.Message +} diff --git a/relayer/relays/beacon/state/beacon_deneb_encoding.go b/relayer/relays/beacon/state/beacon_deneb_encoding.go index f041c55b0f..0e26881f24 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: 03b5096ab94e41e2c740924a4ae7ea8fdd515fe3dd4861032a569e28bcba8bb4 +// Hash: b1d302f8bf37c4a5c505fc9650d27803c352a01033937e6f1a567f1ff6998c2a // Version: 0.1.3 package state @@ -724,6 +724,100 @@ func (e *ExecutionPayloadHeaderDeneb) GetTree() (*ssz.Node, error) { return ssz.ProofTree(e) } +// MarshalSSZ ssz marshals the SignedBeaconBlockDeneb object +func (s *SignedBeaconBlockDeneb) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(s) +} + +// MarshalSSZTo ssz marshals the SignedBeaconBlockDeneb object to a target array +func (s *SignedBeaconBlockDeneb) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + offset := int(100) + + // Offset (0) 'Message' + dst = ssz.WriteOffset(dst, offset) + offset += s.Message.SizeSSZ() + + // Field (1) 'Signature' + dst = append(dst, s.Signature[:]...) + + // Field (0) 'Message' + if dst, err = s.Message.MarshalSSZTo(dst); err != nil { + return + } + + return +} + +// UnmarshalSSZ ssz unmarshals the SignedBeaconBlockDeneb object +func (s *SignedBeaconBlockDeneb) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size < 100 { + return ssz.ErrSize + } + + tail := buf + var o0 uint64 + + // Offset (0) 'Message' + if o0 = ssz.ReadOffset(buf[0:4]); o0 > size { + return ssz.ErrOffset + } + + if o0 < 100 { + return ssz.ErrInvalidVariableOffset + } + + // Field (1) 'Signature' + copy(s.Signature[:], buf[4:100]) + + // Field (0) 'Message' + { + buf = tail[o0:] + if err = s.Message.UnmarshalSSZ(buf); err != nil { + return err + } + } + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the SignedBeaconBlockDeneb object +func (s *SignedBeaconBlockDeneb) SizeSSZ() (size int) { + size = 100 + + // Field (0) 'Message' + size += s.Message.SizeSSZ() + + return +} + +// HashTreeRoot ssz hashes the SignedBeaconBlockDeneb object +func (s *SignedBeaconBlockDeneb) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(s) +} + +// HashTreeRootWith ssz hashes the SignedBeaconBlockDeneb object with a hasher +func (s *SignedBeaconBlockDeneb) HashTreeRootWith(hh ssz.HashWalker) (err error) { + indx := hh.Index() + + // Field (0) 'Message' + if err = s.Message.HashTreeRootWith(hh); err != nil { + return + } + + // Field (1) 'Signature' + hh.PutBytes(s.Signature[:]) + + hh.Merkleize(indx) + return +} + +// GetTree ssz hashes the SignedBeaconBlockDeneb object +func (s *SignedBeaconBlockDeneb) GetTree() (*ssz.Node, error) { + return ssz.ProofTree(s) +} + // MarshalSSZ ssz marshals the BeaconBlockDenebMainnet object func (b *BeaconBlockDenebMainnet) MarshalSSZ() ([]byte, error) { return ssz.MarshalSSZ(b) diff --git a/relayer/relays/beacon/state/beacon_electra.go b/relayer/relays/beacon/state/beacon_electra.go new file mode 100644 index 0000000000..9367c70f31 --- /dev/null +++ b/relayer/relays/beacon/state/beacon_electra.go @@ -0,0 +1,191 @@ +package state + +import ssz "github.com/ferranbt/fastssz" + +type DepositRequestsContainer struct { + DepositRequests []*DepositRequest `ssz-max:"8192" json:"deposit_requests"` +} + +type WithdrawalRequestsContainer struct { + WithdrawalRequests []*WithdrawalRequest `ssz-max:"16" json:"withdrawal_requests"` +} + +type ConsolidationRequestsContainer struct { + ConsolidationRequests []*ConsolidationRequest `ssz-max:"1" json:"consolidation_requests"` +} + +type DepositRequest struct { + Pubkey [48]byte `json:"pubkey" ssz-size:"48"` + WithdrawalCredentials [32]byte `ssz-size:"32" json:"withdrawal_credentials"` + Amount uint64 `json:"amount"` + Signature [96]byte `json:"signature,omitempty" ssz-size:"96"` + Index uint64 `json:"index,omitempty"` +} + +type WithdrawalRequest struct { + SourceAddress [20]byte `ssz-size:"20" json:"source_address" ` + ValidatorPubkey [48]byte `ssz-size:"48" json:"validator_pubkey"` + Amount uint64 `json:"amount"` +} + +type ConsolidationRequest struct { + SourceAddress [20]byte `ssz-size:"20" json:"source_address" ` + SourcePubkey [48]byte `ssz-size:"48" json:"source_pubkey"` + TargetPubkey [48]byte `ssz-size:"48" json:"target_pubkey"` +} + +type SignedBeaconBlockElectra struct { + Message BeaconBlockElectra + Signature [96]byte `json:"signature,omitempty" ssz-size:"96"` +} + +type BeaconBlockElectra struct { + Slot uint64 `json:"slot"` + ProposerIndex uint64 `json:"proposer_index"` + ParentRoot []byte `json:"parent_root" ssz-size:"32"` + StateRoot []byte `json:"state_root" ssz-size:"32"` + Body *BeaconBlockBodyElectra `json:"body"` +} + +type BeaconBlockBodyElectra struct { + RandaoReveal []byte `json:"randao_reveal" ssz-size:"96"` + Eth1Data *Eth1Data `json:"eth1_data"` + Graffiti [32]byte `json:"graffiti" ssz-size:"32"` + ProposerSlashings []*ProposerSlashing `json:"proposer_slashings" ssz-max:"16"` + AttesterSlashings []*AttesterSlashingElectra `json:"attester_slashings" ssz-max:"1"` // Modified in Electra + Attestations []*AttestationElectra `json:"attestations" ssz-max:"8"` // Modified in Electra + Deposits []*Deposit `json:"deposits" ssz-max:"16"` + VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits" ssz-max:"16"` + SyncAggregate *SyncAggregateMainnet `json:"sync_aggregate"` + ExecutionPayload *ExecutionPayloadDeneb `json:"execution_payload"` + BlsToExecutionChanges []*SignedBLSToExecutionChange `json:"bls_to_execution_changes,omitempty" ssz-max:"16"` + BlobKzgCommitments [][48]byte `json:"blob_kzg_commitments,omitempty" ssz-max:"4096" ssz-size:"?,48"` + ExecutionRequests *ExecutionRequests `json:"execution_requests"` // New in Electra +} + +type BeaconStateElectra 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"` // New in Electra + DepositBalanceToConsume uint64 `json:"deposit_balance_to_consume,omitempty"` // New in Electra + ExitBalanceToConsume uint64 `json:"exit_balance_to_consume,omitempty"` // New in Electra + EarliestExitEpoch uint64 `json:"earliest_exit_epoch,omitempty"` // New in Electra + ConsolidationBalanceToConsume uint64 `json:"consolidation_balance_to_consume,omitempty"` // New in Electra + EarliestConsolidationEpoch uint64 `json:"earliest_consolidation_epoch,omitempty"` // New in Electra + PendingBalanceDeposits []*PendingBalanceDeposit `json:"pending_balance_deposits,omitempty" ssz-max:"134217728"` // New in Electra + PendingPartialWithdrawals []*PendingPartialWithdrawal `json:"pending_partial_withdrawals,omitempty" ssz-max:"134217728"` // New in Electra + PendingConsolidations []*PendingConsolidation `json:"pending_consolidations,omitempty" ssz-max:"262144"` // New in Electra +} + +type AttestationElectra struct { + AggregationBits []byte `json:"aggregation_bits" ssz:"bitlist" ssz-max:"131072"` // Modified in Electra + Data *AttestationData `json:"data"` + Signature [96]byte `json:"signature" ssz-size:"96"` + CommitteeBits []byte `json:"committee_bits" cast-type:"github.com/prysmaticlabs/go-bitfield.Bitvector64" ssz-size:"8"` // New in Electra +} + +type AttesterSlashingElectra struct { + Attestation1 *IndexedAttestationElectra `json:"attestation_1"` + Attestation2 *IndexedAttestationElectra `json:"attestation_2"` +} + +type IndexedAttestationElectra struct { + AttestationIndices []uint64 `json:"attesting_indices" ssz-max:"131072"` // Modified in Electra + Data *AttestationData `json:"data"` + Signature [96]byte `json:"signature" ssz-size:"96"` +} + +type PendingBalanceDeposit struct { + Index uint64 `json:"index"` + Amount uint64 `json:"amount"` +} + +type PendingPartialWithdrawal struct { + Index uint64 `json:"index"` + Amount uint64 `json:"amount"` + WithdrawableEpoch uint64 `json:"withdrawable_epoch"` +} + +type PendingConsolidation struct { + SourceIndex uint64 `json:"source_index"` + TargetIndex uint64 `json:"target_index"` +} + +type ExecutionRequests struct { + Deposits []*DepositRequest `json:"deposit_requests,omitempty" ssz-max:"8192"` // New in Electra + Withdrawals []*WithdrawalRequest `json:"withdrawals_requests,omitempty" ssz-max:"16"` // New in Electra + Consolidations []*ConsolidationRequest `json:"consolidations_requests,omitempty" ssz-max:"2"` // New in Electra +} + +func (b *BeaconBlockElectra) GetBeaconSlot() uint64 { + return b.Slot +} + +func (b *BeaconBlockElectra) GetBlockBodyTree() (*ssz.Node, error) { + return b.Body.GetTree() +} + +func (b *BeaconBlockElectra) ExecutionPayloadCapella() *ExecutionPayloadCapella { + return nil +} + +func (b *BeaconBlockElectra) ExecutionPayloadDeneb() *ExecutionPayloadDeneb { + return b.Body.ExecutionPayload +} + +func (b *BeaconStateElectra) GetSlot() uint64 { + return b.Slot +} + +func (b *BeaconStateElectra) GetLatestBlockHeader() *BeaconBlockHeader { + return b.LatestBlockHeader +} + +func (b *BeaconStateElectra) GetBlockRoots() [][]byte { + return b.BlockRoots +} + +func (b *BeaconStateElectra) SetBlockRoots(blockRoots [][]byte) { + b.BlockRoots = blockRoots +} + +func (b *BeaconStateElectra) GetFinalizedCheckpoint() *Checkpoint { + return b.FinalizedCheckpoint +} + +func (b *BeaconStateElectra) GetNextSyncCommittee() *SyncCommittee { + return b.NextSyncCommittee +} +func (b *BeaconStateElectra) GetCurrentSyncCommittee() *SyncCommittee { + return b.CurrentSyncCommittee +} + +func (b *SignedBeaconBlockElectra) GetBlock() BeaconBlock { + return &b.Message +} diff --git a/relayer/relays/beacon/state/beacon_electra_encoding.go b/relayer/relays/beacon/state/beacon_electra_encoding.go new file mode 100644 index 0000000000..3009460d7e --- /dev/null +++ b/relayer/relays/beacon/state/beacon_electra_encoding.go @@ -0,0 +1,3465 @@ +// Code generated by fastssz. DO NOT EDIT. +// Hash: b1d302f8bf37c4a5c505fc9650d27803c352a01033937e6f1a567f1ff6998c2a +// Version: 0.1.3 +package state + +import ( + ssz "github.com/ferranbt/fastssz" +) + +// MarshalSSZ ssz marshals the DepositRequestsContainer object +func (d *DepositRequestsContainer) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(d) +} + +// MarshalSSZTo ssz marshals the DepositRequestsContainer object to a target array +func (d *DepositRequestsContainer) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + offset := int(4) + + // Offset (0) 'DepositRequests' + dst = ssz.WriteOffset(dst, offset) + offset += len(d.DepositRequests) * 192 + + // Field (0) 'DepositRequests' + if size := len(d.DepositRequests); size > 8192 { + err = ssz.ErrListTooBigFn("DepositRequestsContainer.DepositRequests", size, 8192) + return + } + for ii := 0; ii < len(d.DepositRequests); ii++ { + if dst, err = d.DepositRequests[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + return +} + +// UnmarshalSSZ ssz unmarshals the DepositRequestsContainer object +func (d *DepositRequestsContainer) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size < 4 { + return ssz.ErrSize + } + + tail := buf + var o0 uint64 + + // Offset (0) 'DepositRequests' + if o0 = ssz.ReadOffset(buf[0:4]); o0 > size { + return ssz.ErrOffset + } + + if o0 < 4 { + return ssz.ErrInvalidVariableOffset + } + + // Field (0) 'DepositRequests' + { + buf = tail[o0:] + num, err := ssz.DivideInt2(len(buf), 192, 8192) + if err != nil { + return err + } + d.DepositRequests = make([]*DepositRequest, num) + for ii := 0; ii < num; ii++ { + if d.DepositRequests[ii] == nil { + d.DepositRequests[ii] = new(DepositRequest) + } + if err = d.DepositRequests[ii].UnmarshalSSZ(buf[ii*192 : (ii+1)*192]); err != nil { + return err + } + } + } + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the DepositRequestsContainer object +func (d *DepositRequestsContainer) SizeSSZ() (size int) { + size = 4 + + // Field (0) 'DepositRequests' + size += len(d.DepositRequests) * 192 + + return +} + +// HashTreeRoot ssz hashes the DepositRequestsContainer object +func (d *DepositRequestsContainer) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(d) +} + +// HashTreeRootWith ssz hashes the DepositRequestsContainer object with a hasher +func (d *DepositRequestsContainer) HashTreeRootWith(hh ssz.HashWalker) (err error) { + indx := hh.Index() + + // Field (0) 'DepositRequests' + { + subIndx := hh.Index() + num := uint64(len(d.DepositRequests)) + if num > 8192 { + err = ssz.ErrIncorrectListSize + return + } + for _, elem := range d.DepositRequests { + if err = elem.HashTreeRootWith(hh); err != nil { + return + } + } + hh.MerkleizeWithMixin(subIndx, num, 8192) + } + + hh.Merkleize(indx) + return +} + +// GetTree ssz hashes the DepositRequestsContainer object +func (d *DepositRequestsContainer) GetTree() (*ssz.Node, error) { + return ssz.ProofTree(d) +} + +// MarshalSSZ ssz marshals the WithdrawalRequestsContainer object +func (w *WithdrawalRequestsContainer) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(w) +} + +// MarshalSSZTo ssz marshals the WithdrawalRequestsContainer object to a target array +func (w *WithdrawalRequestsContainer) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + offset := int(4) + + // Offset (0) 'WithdrawalRequests' + dst = ssz.WriteOffset(dst, offset) + offset += len(w.WithdrawalRequests) * 76 + + // Field (0) 'WithdrawalRequests' + if size := len(w.WithdrawalRequests); size > 16 { + err = ssz.ErrListTooBigFn("WithdrawalRequestsContainer.WithdrawalRequests", size, 16) + return + } + for ii := 0; ii < len(w.WithdrawalRequests); ii++ { + if dst, err = w.WithdrawalRequests[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + return +} + +// UnmarshalSSZ ssz unmarshals the WithdrawalRequestsContainer object +func (w *WithdrawalRequestsContainer) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size < 4 { + return ssz.ErrSize + } + + tail := buf + var o0 uint64 + + // Offset (0) 'WithdrawalRequests' + if o0 = ssz.ReadOffset(buf[0:4]); o0 > size { + return ssz.ErrOffset + } + + if o0 < 4 { + return ssz.ErrInvalidVariableOffset + } + + // Field (0) 'WithdrawalRequests' + { + buf = tail[o0:] + num, err := ssz.DivideInt2(len(buf), 76, 16) + if err != nil { + return err + } + w.WithdrawalRequests = make([]*WithdrawalRequest, num) + for ii := 0; ii < num; ii++ { + if w.WithdrawalRequests[ii] == nil { + w.WithdrawalRequests[ii] = new(WithdrawalRequest) + } + if err = w.WithdrawalRequests[ii].UnmarshalSSZ(buf[ii*76 : (ii+1)*76]); err != nil { + return err + } + } + } + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the WithdrawalRequestsContainer object +func (w *WithdrawalRequestsContainer) SizeSSZ() (size int) { + size = 4 + + // Field (0) 'WithdrawalRequests' + size += len(w.WithdrawalRequests) * 76 + + return +} + +// HashTreeRoot ssz hashes the WithdrawalRequestsContainer object +func (w *WithdrawalRequestsContainer) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(w) +} + +// HashTreeRootWith ssz hashes the WithdrawalRequestsContainer object with a hasher +func (w *WithdrawalRequestsContainer) HashTreeRootWith(hh ssz.HashWalker) (err error) { + indx := hh.Index() + + // Field (0) 'WithdrawalRequests' + { + subIndx := hh.Index() + num := uint64(len(w.WithdrawalRequests)) + if num > 16 { + err = ssz.ErrIncorrectListSize + return + } + for _, elem := range w.WithdrawalRequests { + if err = elem.HashTreeRootWith(hh); err != nil { + return + } + } + hh.MerkleizeWithMixin(subIndx, num, 16) + } + + hh.Merkleize(indx) + return +} + +// GetTree ssz hashes the WithdrawalRequestsContainer object +func (w *WithdrawalRequestsContainer) GetTree() (*ssz.Node, error) { + return ssz.ProofTree(w) +} + +// MarshalSSZ ssz marshals the ConsolidationRequestsContainer object +func (c *ConsolidationRequestsContainer) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(c) +} + +// MarshalSSZTo ssz marshals the ConsolidationRequestsContainer object to a target array +func (c *ConsolidationRequestsContainer) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + offset := int(4) + + // Offset (0) 'ConsolidationRequests' + dst = ssz.WriteOffset(dst, offset) + offset += len(c.ConsolidationRequests) * 116 + + // Field (0) 'ConsolidationRequests' + if size := len(c.ConsolidationRequests); size > 1 { + err = ssz.ErrListTooBigFn("ConsolidationRequestsContainer.ConsolidationRequests", size, 1) + return + } + for ii := 0; ii < len(c.ConsolidationRequests); ii++ { + if dst, err = c.ConsolidationRequests[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + return +} + +// UnmarshalSSZ ssz unmarshals the ConsolidationRequestsContainer object +func (c *ConsolidationRequestsContainer) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size < 4 { + return ssz.ErrSize + } + + tail := buf + var o0 uint64 + + // Offset (0) 'ConsolidationRequests' + if o0 = ssz.ReadOffset(buf[0:4]); o0 > size { + return ssz.ErrOffset + } + + if o0 < 4 { + return ssz.ErrInvalidVariableOffset + } + + // Field (0) 'ConsolidationRequests' + { + buf = tail[o0:] + num, err := ssz.DivideInt2(len(buf), 116, 1) + if err != nil { + return err + } + c.ConsolidationRequests = make([]*ConsolidationRequest, num) + for ii := 0; ii < num; ii++ { + if c.ConsolidationRequests[ii] == nil { + c.ConsolidationRequests[ii] = new(ConsolidationRequest) + } + if err = c.ConsolidationRequests[ii].UnmarshalSSZ(buf[ii*116 : (ii+1)*116]); err != nil { + return err + } + } + } + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the ConsolidationRequestsContainer object +func (c *ConsolidationRequestsContainer) SizeSSZ() (size int) { + size = 4 + + // Field (0) 'ConsolidationRequests' + size += len(c.ConsolidationRequests) * 116 + + return +} + +// HashTreeRoot ssz hashes the ConsolidationRequestsContainer object +func (c *ConsolidationRequestsContainer) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(c) +} + +// HashTreeRootWith ssz hashes the ConsolidationRequestsContainer object with a hasher +func (c *ConsolidationRequestsContainer) HashTreeRootWith(hh ssz.HashWalker) (err error) { + indx := hh.Index() + + // Field (0) 'ConsolidationRequests' + { + subIndx := hh.Index() + num := uint64(len(c.ConsolidationRequests)) + if num > 1 { + err = ssz.ErrIncorrectListSize + return + } + for _, elem := range c.ConsolidationRequests { + if err = elem.HashTreeRootWith(hh); err != nil { + return + } + } + hh.MerkleizeWithMixin(subIndx, num, 1) + } + + hh.Merkleize(indx) + return +} + +// GetTree ssz hashes the ConsolidationRequestsContainer object +func (c *ConsolidationRequestsContainer) GetTree() (*ssz.Node, error) { + return ssz.ProofTree(c) +} + +// MarshalSSZ ssz marshals the DepositRequest object +func (d *DepositRequest) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(d) +} + +// MarshalSSZTo ssz marshals the DepositRequest object to a target array +func (d *DepositRequest) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + + // Field (0) 'Pubkey' + dst = append(dst, d.Pubkey[:]...) + + // Field (1) 'WithdrawalCredentials' + dst = append(dst, d.WithdrawalCredentials[:]...) + + // Field (2) 'Amount' + dst = ssz.MarshalUint64(dst, d.Amount) + + // Field (3) 'Signature' + dst = append(dst, d.Signature[:]...) + + // Field (4) 'Index' + dst = ssz.MarshalUint64(dst, d.Index) + + return +} + +// UnmarshalSSZ ssz unmarshals the DepositRequest object +func (d *DepositRequest) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size != 192 { + return ssz.ErrSize + } + + // Field (0) 'Pubkey' + copy(d.Pubkey[:], buf[0:48]) + + // Field (1) 'WithdrawalCredentials' + copy(d.WithdrawalCredentials[:], buf[48:80]) + + // Field (2) 'Amount' + d.Amount = ssz.UnmarshallUint64(buf[80:88]) + + // Field (3) 'Signature' + copy(d.Signature[:], buf[88:184]) + + // Field (4) 'Index' + d.Index = ssz.UnmarshallUint64(buf[184:192]) + + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the DepositRequest object +func (d *DepositRequest) SizeSSZ() (size int) { + size = 192 + return +} + +// HashTreeRoot ssz hashes the DepositRequest object +func (d *DepositRequest) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(d) +} + +// HashTreeRootWith ssz hashes the DepositRequest object with a hasher +func (d *DepositRequest) HashTreeRootWith(hh ssz.HashWalker) (err error) { + indx := hh.Index() + + // Field (0) 'Pubkey' + hh.PutBytes(d.Pubkey[:]) + + // Field (1) 'WithdrawalCredentials' + hh.PutBytes(d.WithdrawalCredentials[:]) + + // Field (2) 'Amount' + hh.PutUint64(d.Amount) + + // Field (3) 'Signature' + hh.PutBytes(d.Signature[:]) + + // Field (4) 'Index' + hh.PutUint64(d.Index) + + hh.Merkleize(indx) + return +} + +// GetTree ssz hashes the DepositRequest object +func (d *DepositRequest) GetTree() (*ssz.Node, error) { + return ssz.ProofTree(d) +} + +// MarshalSSZ ssz marshals the WithdrawalRequest object +func (w *WithdrawalRequest) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(w) +} + +// MarshalSSZTo ssz marshals the WithdrawalRequest object to a target array +func (w *WithdrawalRequest) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + + // Field (0) 'SourceAddress' + dst = append(dst, w.SourceAddress[:]...) + + // Field (1) 'ValidatorPubkey' + dst = append(dst, w.ValidatorPubkey[:]...) + + // Field (2) 'Amount' + dst = ssz.MarshalUint64(dst, w.Amount) + + return +} + +// UnmarshalSSZ ssz unmarshals the WithdrawalRequest object +func (w *WithdrawalRequest) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size != 76 { + return ssz.ErrSize + } + + // Field (0) 'SourceAddress' + copy(w.SourceAddress[:], buf[0:20]) + + // Field (1) 'ValidatorPubkey' + copy(w.ValidatorPubkey[:], buf[20:68]) + + // Field (2) 'Amount' + w.Amount = ssz.UnmarshallUint64(buf[68:76]) + + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the WithdrawalRequest object +func (w *WithdrawalRequest) SizeSSZ() (size int) { + size = 76 + return +} + +// HashTreeRoot ssz hashes the WithdrawalRequest object +func (w *WithdrawalRequest) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(w) +} + +// HashTreeRootWith ssz hashes the WithdrawalRequest object with a hasher +func (w *WithdrawalRequest) HashTreeRootWith(hh ssz.HashWalker) (err error) { + indx := hh.Index() + + // Field (0) 'SourceAddress' + hh.PutBytes(w.SourceAddress[:]) + + // Field (1) 'ValidatorPubkey' + hh.PutBytes(w.ValidatorPubkey[:]) + + // Field (2) 'Amount' + hh.PutUint64(w.Amount) + + hh.Merkleize(indx) + return +} + +// GetTree ssz hashes the WithdrawalRequest object +func (w *WithdrawalRequest) GetTree() (*ssz.Node, error) { + return ssz.ProofTree(w) +} + +// MarshalSSZ ssz marshals the ConsolidationRequest object +func (c *ConsolidationRequest) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(c) +} + +// MarshalSSZTo ssz marshals the ConsolidationRequest object to a target array +func (c *ConsolidationRequest) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + + // Field (0) 'SourceAddress' + dst = append(dst, c.SourceAddress[:]...) + + // Field (1) 'SourcePubkey' + dst = append(dst, c.SourcePubkey[:]...) + + // Field (2) 'TargetPubkey' + dst = append(dst, c.TargetPubkey[:]...) + + return +} + +// UnmarshalSSZ ssz unmarshals the ConsolidationRequest object +func (c *ConsolidationRequest) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size != 116 { + return ssz.ErrSize + } + + // Field (0) 'SourceAddress' + copy(c.SourceAddress[:], buf[0:20]) + + // Field (1) 'SourcePubkey' + copy(c.SourcePubkey[:], buf[20:68]) + + // Field (2) 'TargetPubkey' + copy(c.TargetPubkey[:], buf[68:116]) + + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the ConsolidationRequest object +func (c *ConsolidationRequest) SizeSSZ() (size int) { + size = 116 + return +} + +// HashTreeRoot ssz hashes the ConsolidationRequest object +func (c *ConsolidationRequest) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(c) +} + +// HashTreeRootWith ssz hashes the ConsolidationRequest object with a hasher +func (c *ConsolidationRequest) HashTreeRootWith(hh ssz.HashWalker) (err error) { + indx := hh.Index() + + // Field (0) 'SourceAddress' + hh.PutBytes(c.SourceAddress[:]) + + // Field (1) 'SourcePubkey' + hh.PutBytes(c.SourcePubkey[:]) + + // Field (2) 'TargetPubkey' + hh.PutBytes(c.TargetPubkey[:]) + + hh.Merkleize(indx) + return +} + +// GetTree ssz hashes the ConsolidationRequest object +func (c *ConsolidationRequest) GetTree() (*ssz.Node, error) { + return ssz.ProofTree(c) +} + +// MarshalSSZ ssz marshals the SignedBeaconBlockElectra object +func (s *SignedBeaconBlockElectra) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(s) +} + +// MarshalSSZTo ssz marshals the SignedBeaconBlockElectra object to a target array +func (s *SignedBeaconBlockElectra) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + offset := int(100) + + // Offset (0) 'Message' + dst = ssz.WriteOffset(dst, offset) + offset += s.Message.SizeSSZ() + + // Field (1) 'Signature' + dst = append(dst, s.Signature[:]...) + + // Field (0) 'Message' + if dst, err = s.Message.MarshalSSZTo(dst); err != nil { + return + } + + return +} + +// UnmarshalSSZ ssz unmarshals the SignedBeaconBlockElectra object +func (s *SignedBeaconBlockElectra) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size < 100 { + return ssz.ErrSize + } + + tail := buf + var o0 uint64 + + // Offset (0) 'Message' + if o0 = ssz.ReadOffset(buf[0:4]); o0 > size { + return ssz.ErrOffset + } + + if o0 < 100 { + return ssz.ErrInvalidVariableOffset + } + + // Field (1) 'Signature' + copy(s.Signature[:], buf[4:100]) + + // Field (0) 'Message' + { + buf = tail[o0:] + if err = s.Message.UnmarshalSSZ(buf); err != nil { + return err + } + } + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the SignedBeaconBlockElectra object +func (s *SignedBeaconBlockElectra) SizeSSZ() (size int) { + size = 100 + + // Field (0) 'Message' + size += s.Message.SizeSSZ() + + return +} + +// HashTreeRoot ssz hashes the SignedBeaconBlockElectra object +func (s *SignedBeaconBlockElectra) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(s) +} + +// HashTreeRootWith ssz hashes the SignedBeaconBlockElectra object with a hasher +func (s *SignedBeaconBlockElectra) HashTreeRootWith(hh ssz.HashWalker) (err error) { + indx := hh.Index() + + // Field (0) 'Message' + if err = s.Message.HashTreeRootWith(hh); err != nil { + return + } + + // Field (1) 'Signature' + hh.PutBytes(s.Signature[:]) + + hh.Merkleize(indx) + return +} + +// GetTree ssz hashes the SignedBeaconBlockElectra object +func (s *SignedBeaconBlockElectra) GetTree() (*ssz.Node, error) { + return ssz.ProofTree(s) +} + +// MarshalSSZ ssz marshals the BeaconBlockElectra object +func (b *BeaconBlockElectra) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(b) +} + +// MarshalSSZTo ssz marshals the BeaconBlockElectra object to a target array +func (b *BeaconBlockElectra) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + offset := int(84) + + // Field (0) 'Slot' + dst = ssz.MarshalUint64(dst, b.Slot) + + // Field (1) 'ProposerIndex' + dst = ssz.MarshalUint64(dst, b.ProposerIndex) + + // Field (2) 'ParentRoot' + if size := len(b.ParentRoot); size != 32 { + err = ssz.ErrBytesLengthFn("BeaconBlockElectra.ParentRoot", size, 32) + return + } + dst = append(dst, b.ParentRoot...) + + // Field (3) 'StateRoot' + if size := len(b.StateRoot); size != 32 { + err = ssz.ErrBytesLengthFn("BeaconBlockElectra.StateRoot", size, 32) + return + } + dst = append(dst, b.StateRoot...) + + // Offset (4) 'Body' + dst = ssz.WriteOffset(dst, offset) + if b.Body == nil { + b.Body = new(BeaconBlockBodyElectra) + } + offset += b.Body.SizeSSZ() + + // Field (4) 'Body' + if dst, err = b.Body.MarshalSSZTo(dst); err != nil { + return + } + + return +} + +// UnmarshalSSZ ssz unmarshals the BeaconBlockElectra object +func (b *BeaconBlockElectra) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size < 84 { + return ssz.ErrSize + } + + tail := buf + var o4 uint64 + + // Field (0) 'Slot' + b.Slot = ssz.UnmarshallUint64(buf[0:8]) + + // Field (1) 'ProposerIndex' + b.ProposerIndex = ssz.UnmarshallUint64(buf[8:16]) + + // Field (2) 'ParentRoot' + if cap(b.ParentRoot) == 0 { + b.ParentRoot = make([]byte, 0, len(buf[16:48])) + } + b.ParentRoot = append(b.ParentRoot, buf[16:48]...) + + // Field (3) 'StateRoot' + if cap(b.StateRoot) == 0 { + b.StateRoot = make([]byte, 0, len(buf[48:80])) + } + b.StateRoot = append(b.StateRoot, buf[48:80]...) + + // Offset (4) 'Body' + if o4 = ssz.ReadOffset(buf[80:84]); o4 > size { + return ssz.ErrOffset + } + + if o4 < 84 { + return ssz.ErrInvalidVariableOffset + } + + // Field (4) 'Body' + { + buf = tail[o4:] + if b.Body == nil { + b.Body = new(BeaconBlockBodyElectra) + } + if err = b.Body.UnmarshalSSZ(buf); err != nil { + return err + } + } + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the BeaconBlockElectra object +func (b *BeaconBlockElectra) SizeSSZ() (size int) { + size = 84 + + // Field (4) 'Body' + if b.Body == nil { + b.Body = new(BeaconBlockBodyElectra) + } + size += b.Body.SizeSSZ() + + return +} + +// HashTreeRoot ssz hashes the BeaconBlockElectra object +func (b *BeaconBlockElectra) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(b) +} + +// HashTreeRootWith ssz hashes the BeaconBlockElectra object with a hasher +func (b *BeaconBlockElectra) HashTreeRootWith(hh ssz.HashWalker) (err error) { + indx := hh.Index() + + // Field (0) 'Slot' + hh.PutUint64(b.Slot) + + // Field (1) 'ProposerIndex' + hh.PutUint64(b.ProposerIndex) + + // Field (2) 'ParentRoot' + if size := len(b.ParentRoot); size != 32 { + err = ssz.ErrBytesLengthFn("BeaconBlockElectra.ParentRoot", size, 32) + return + } + hh.PutBytes(b.ParentRoot) + + // Field (3) 'StateRoot' + if size := len(b.StateRoot); size != 32 { + err = ssz.ErrBytesLengthFn("BeaconBlockElectra.StateRoot", size, 32) + return + } + hh.PutBytes(b.StateRoot) + + // Field (4) 'Body' + if err = b.Body.HashTreeRootWith(hh); err != nil { + return + } + + hh.Merkleize(indx) + return +} + +// GetTree ssz hashes the BeaconBlockElectra object +func (b *BeaconBlockElectra) GetTree() (*ssz.Node, error) { + return ssz.ProofTree(b) +} + +// MarshalSSZ ssz marshals the BeaconBlockBodyElectra object +func (b *BeaconBlockBodyElectra) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(b) +} + +// MarshalSSZTo ssz marshals the BeaconBlockBodyElectra object to a target array +func (b *BeaconBlockBodyElectra) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + offset := int(396) + + // Field (0) 'RandaoReveal' + if size := len(b.RandaoReveal); size != 96 { + err = ssz.ErrBytesLengthFn("BeaconBlockBodyElectra.RandaoReveal", size, 96) + return + } + dst = append(dst, b.RandaoReveal...) + + // Field (1) 'Eth1Data' + if b.Eth1Data == nil { + b.Eth1Data = new(Eth1Data) + } + if dst, err = b.Eth1Data.MarshalSSZTo(dst); err != nil { + return + } + + // Field (2) 'Graffiti' + dst = append(dst, b.Graffiti[:]...) + + // Offset (3) 'ProposerSlashings' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.ProposerSlashings) * 416 + + // Offset (4) 'AttesterSlashings' + dst = ssz.WriteOffset(dst, offset) + for ii := 0; ii < len(b.AttesterSlashings); ii++ { + offset += 4 + offset += b.AttesterSlashings[ii].SizeSSZ() + } + + // Offset (5) 'Attestations' + dst = ssz.WriteOffset(dst, offset) + for ii := 0; ii < len(b.Attestations); ii++ { + offset += 4 + offset += b.Attestations[ii].SizeSSZ() + } + + // Offset (6) 'Deposits' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.Deposits) * 1240 + + // Offset (7) 'VoluntaryExits' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.VoluntaryExits) * 112 + + // Field (8) 'SyncAggregate' + if b.SyncAggregate == nil { + b.SyncAggregate = new(SyncAggregateMainnet) + } + if dst, err = b.SyncAggregate.MarshalSSZTo(dst); err != nil { + return + } + + // Offset (9) 'ExecutionPayload' + dst = ssz.WriteOffset(dst, offset) + if b.ExecutionPayload == nil { + b.ExecutionPayload = new(ExecutionPayloadDeneb) + } + offset += b.ExecutionPayload.SizeSSZ() + + // Offset (10) 'BlsToExecutionChanges' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.BlsToExecutionChanges) * 172 + + // Offset (11) 'BlobKzgCommitments' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.BlobKzgCommitments) * 48 + + // Offset (12) 'ExecutionRequests' + dst = ssz.WriteOffset(dst, offset) + if b.ExecutionRequests == nil { + b.ExecutionRequests = new(ExecutionRequests) + } + offset += b.ExecutionRequests.SizeSSZ() + + // Field (3) 'ProposerSlashings' + if size := len(b.ProposerSlashings); size > 16 { + err = ssz.ErrListTooBigFn("BeaconBlockBodyElectra.ProposerSlashings", size, 16) + return + } + for ii := 0; ii < len(b.ProposerSlashings); ii++ { + if dst, err = b.ProposerSlashings[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + // Field (4) 'AttesterSlashings' + if size := len(b.AttesterSlashings); size > 1 { + err = ssz.ErrListTooBigFn("BeaconBlockBodyElectra.AttesterSlashings", size, 1) + return + } + { + offset = 4 * len(b.AttesterSlashings) + for ii := 0; ii < len(b.AttesterSlashings); ii++ { + dst = ssz.WriteOffset(dst, offset) + offset += b.AttesterSlashings[ii].SizeSSZ() + } + } + for ii := 0; ii < len(b.AttesterSlashings); ii++ { + if dst, err = b.AttesterSlashings[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + // Field (5) 'Attestations' + if size := len(b.Attestations); size > 8 { + err = ssz.ErrListTooBigFn("BeaconBlockBodyElectra.Attestations", size, 8) + return + } + { + offset = 4 * len(b.Attestations) + for ii := 0; ii < len(b.Attestations); ii++ { + dst = ssz.WriteOffset(dst, offset) + offset += b.Attestations[ii].SizeSSZ() + } + } + for ii := 0; ii < len(b.Attestations); ii++ { + if dst, err = b.Attestations[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + // Field (6) 'Deposits' + if size := len(b.Deposits); size > 16 { + err = ssz.ErrListTooBigFn("BeaconBlockBodyElectra.Deposits", size, 16) + return + } + for ii := 0; ii < len(b.Deposits); ii++ { + if dst, err = b.Deposits[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + // Field (7) 'VoluntaryExits' + if size := len(b.VoluntaryExits); size > 16 { + err = ssz.ErrListTooBigFn("BeaconBlockBodyElectra.VoluntaryExits", size, 16) + return + } + for ii := 0; ii < len(b.VoluntaryExits); ii++ { + if dst, err = b.VoluntaryExits[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + // Field (9) 'ExecutionPayload' + if dst, err = b.ExecutionPayload.MarshalSSZTo(dst); err != nil { + return + } + + // Field (10) 'BlsToExecutionChanges' + if size := len(b.BlsToExecutionChanges); size > 16 { + err = ssz.ErrListTooBigFn("BeaconBlockBodyElectra.BlsToExecutionChanges", size, 16) + return + } + for ii := 0; ii < len(b.BlsToExecutionChanges); ii++ { + if dst, err = b.BlsToExecutionChanges[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + // Field (11) 'BlobKzgCommitments' + if size := len(b.BlobKzgCommitments); size > 4096 { + err = ssz.ErrListTooBigFn("BeaconBlockBodyElectra.BlobKzgCommitments", size, 4096) + return + } + for ii := 0; ii < len(b.BlobKzgCommitments); ii++ { + dst = append(dst, b.BlobKzgCommitments[ii][:]...) + } + + // Field (12) 'ExecutionRequests' + if dst, err = b.ExecutionRequests.MarshalSSZTo(dst); err != nil { + return + } + + return +} + +// UnmarshalSSZ ssz unmarshals the BeaconBlockBodyElectra object +func (b *BeaconBlockBodyElectra) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size < 396 { + return ssz.ErrSize + } + + tail := buf + var o3, o4, o5, o6, o7, o9, o10, o11, o12 uint64 + + // Field (0) 'RandaoReveal' + if cap(b.RandaoReveal) == 0 { + b.RandaoReveal = make([]byte, 0, len(buf[0:96])) + } + b.RandaoReveal = append(b.RandaoReveal, buf[0:96]...) + + // Field (1) 'Eth1Data' + if b.Eth1Data == nil { + b.Eth1Data = new(Eth1Data) + } + if err = b.Eth1Data.UnmarshalSSZ(buf[96:168]); err != nil { + return err + } + + // Field (2) 'Graffiti' + copy(b.Graffiti[:], buf[168:200]) + + // Offset (3) 'ProposerSlashings' + if o3 = ssz.ReadOffset(buf[200:204]); o3 > size { + return ssz.ErrOffset + } + + if o3 < 396 { + return ssz.ErrInvalidVariableOffset + } + + // Offset (4) 'AttesterSlashings' + if o4 = ssz.ReadOffset(buf[204:208]); o4 > size || o3 > o4 { + return ssz.ErrOffset + } + + // Offset (5) 'Attestations' + if o5 = ssz.ReadOffset(buf[208:212]); o5 > size || o4 > o5 { + return ssz.ErrOffset + } + + // Offset (6) 'Deposits' + if o6 = ssz.ReadOffset(buf[212:216]); o6 > size || o5 > o6 { + return ssz.ErrOffset + } + + // Offset (7) 'VoluntaryExits' + if o7 = ssz.ReadOffset(buf[216:220]); o7 > size || o6 > o7 { + return ssz.ErrOffset + } + + // Field (8) 'SyncAggregate' + if b.SyncAggregate == nil { + b.SyncAggregate = new(SyncAggregateMainnet) + } + if err = b.SyncAggregate.UnmarshalSSZ(buf[220:380]); err != nil { + return err + } + + // Offset (9) 'ExecutionPayload' + if o9 = ssz.ReadOffset(buf[380:384]); o9 > size || o7 > o9 { + return ssz.ErrOffset + } + + // Offset (10) 'BlsToExecutionChanges' + if o10 = ssz.ReadOffset(buf[384:388]); o10 > size || o9 > o10 { + return ssz.ErrOffset + } + + // Offset (11) 'BlobKzgCommitments' + if o11 = ssz.ReadOffset(buf[388:392]); o11 > size || o10 > o11 { + return ssz.ErrOffset + } + + // Offset (12) 'ExecutionRequests' + if o12 = ssz.ReadOffset(buf[392:396]); o12 > size || o11 > o12 { + return ssz.ErrOffset + } + + // Field (3) 'ProposerSlashings' + { + buf = tail[o3:o4] + num, err := ssz.DivideInt2(len(buf), 416, 16) + if err != nil { + return err + } + b.ProposerSlashings = make([]*ProposerSlashing, num) + for ii := 0; ii < num; ii++ { + if b.ProposerSlashings[ii] == nil { + b.ProposerSlashings[ii] = new(ProposerSlashing) + } + if err = b.ProposerSlashings[ii].UnmarshalSSZ(buf[ii*416 : (ii+1)*416]); err != nil { + return err + } + } + } + + // Field (4) 'AttesterSlashings' + { + buf = tail[o4:o5] + num, err := ssz.DecodeDynamicLength(buf, 1) + if err != nil { + return err + } + b.AttesterSlashings = make([]*AttesterSlashingElectra, num) + err = ssz.UnmarshalDynamic(buf, num, func(indx int, buf []byte) (err error) { + if b.AttesterSlashings[indx] == nil { + b.AttesterSlashings[indx] = new(AttesterSlashingElectra) + } + if err = b.AttesterSlashings[indx].UnmarshalSSZ(buf); err != nil { + return err + } + return nil + }) + if err != nil { + return err + } + } + + // Field (5) 'Attestations' + { + buf = tail[o5:o6] + num, err := ssz.DecodeDynamicLength(buf, 8) + if err != nil { + return err + } + b.Attestations = make([]*AttestationElectra, num) + err = ssz.UnmarshalDynamic(buf, num, func(indx int, buf []byte) (err error) { + if b.Attestations[indx] == nil { + b.Attestations[indx] = new(AttestationElectra) + } + if err = b.Attestations[indx].UnmarshalSSZ(buf); err != nil { + return err + } + return nil + }) + if err != nil { + return err + } + } + + // Field (6) 'Deposits' + { + buf = tail[o6:o7] + num, err := ssz.DivideInt2(len(buf), 1240, 16) + if err != nil { + return err + } + b.Deposits = make([]*Deposit, num) + for ii := 0; ii < num; ii++ { + if b.Deposits[ii] == nil { + b.Deposits[ii] = new(Deposit) + } + if err = b.Deposits[ii].UnmarshalSSZ(buf[ii*1240 : (ii+1)*1240]); err != nil { + return err + } + } + } + + // Field (7) 'VoluntaryExits' + { + buf = tail[o7:o9] + num, err := ssz.DivideInt2(len(buf), 112, 16) + if err != nil { + return err + } + b.VoluntaryExits = make([]*SignedVoluntaryExit, num) + for ii := 0; ii < num; ii++ { + if b.VoluntaryExits[ii] == nil { + b.VoluntaryExits[ii] = new(SignedVoluntaryExit) + } + if err = b.VoluntaryExits[ii].UnmarshalSSZ(buf[ii*112 : (ii+1)*112]); err != nil { + return err + } + } + } + + // Field (9) 'ExecutionPayload' + { + buf = tail[o9:o10] + if b.ExecutionPayload == nil { + b.ExecutionPayload = new(ExecutionPayloadDeneb) + } + if err = b.ExecutionPayload.UnmarshalSSZ(buf); err != nil { + return err + } + } + + // Field (10) 'BlsToExecutionChanges' + { + buf = tail[o10:o11] + num, err := ssz.DivideInt2(len(buf), 172, 16) + if err != nil { + return err + } + b.BlsToExecutionChanges = make([]*SignedBLSToExecutionChange, num) + for ii := 0; ii < num; ii++ { + if b.BlsToExecutionChanges[ii] == nil { + b.BlsToExecutionChanges[ii] = new(SignedBLSToExecutionChange) + } + if err = b.BlsToExecutionChanges[ii].UnmarshalSSZ(buf[ii*172 : (ii+1)*172]); err != nil { + return err + } + } + } + + // Field (11) 'BlobKzgCommitments' + { + buf = tail[o11:o12] + num, err := ssz.DivideInt2(len(buf), 48, 4096) + if err != nil { + return err + } + b.BlobKzgCommitments = make([][48]byte, num) + for ii := 0; ii < num; ii++ { + copy(b.BlobKzgCommitments[ii][:], buf[ii*48:(ii+1)*48]) + } + } + + // Field (12) 'ExecutionRequests' + { + buf = tail[o12:] + if b.ExecutionRequests == nil { + b.ExecutionRequests = new(ExecutionRequests) + } + if err = b.ExecutionRequests.UnmarshalSSZ(buf); err != nil { + return err + } + } + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the BeaconBlockBodyElectra object +func (b *BeaconBlockBodyElectra) SizeSSZ() (size int) { + size = 396 + + // Field (3) 'ProposerSlashings' + size += len(b.ProposerSlashings) * 416 + + // Field (4) 'AttesterSlashings' + for ii := 0; ii < len(b.AttesterSlashings); ii++ { + size += 4 + size += b.AttesterSlashings[ii].SizeSSZ() + } + + // Field (5) 'Attestations' + for ii := 0; ii < len(b.Attestations); ii++ { + size += 4 + size += b.Attestations[ii].SizeSSZ() + } + + // Field (6) 'Deposits' + size += len(b.Deposits) * 1240 + + // Field (7) 'VoluntaryExits' + size += len(b.VoluntaryExits) * 112 + + // Field (9) 'ExecutionPayload' + if b.ExecutionPayload == nil { + b.ExecutionPayload = new(ExecutionPayloadDeneb) + } + size += b.ExecutionPayload.SizeSSZ() + + // Field (10) 'BlsToExecutionChanges' + size += len(b.BlsToExecutionChanges) * 172 + + // Field (11) 'BlobKzgCommitments' + size += len(b.BlobKzgCommitments) * 48 + + // Field (12) 'ExecutionRequests' + if b.ExecutionRequests == nil { + b.ExecutionRequests = new(ExecutionRequests) + } + size += b.ExecutionRequests.SizeSSZ() + + return +} + +// HashTreeRoot ssz hashes the BeaconBlockBodyElectra object +func (b *BeaconBlockBodyElectra) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(b) +} + +// HashTreeRootWith ssz hashes the BeaconBlockBodyElectra object with a hasher +func (b *BeaconBlockBodyElectra) HashTreeRootWith(hh ssz.HashWalker) (err error) { + indx := hh.Index() + + // Field (0) 'RandaoReveal' + if size := len(b.RandaoReveal); size != 96 { + err = ssz.ErrBytesLengthFn("BeaconBlockBodyElectra.RandaoReveal", size, 96) + return + } + hh.PutBytes(b.RandaoReveal) + + // Field (1) 'Eth1Data' + if b.Eth1Data == nil { + b.Eth1Data = new(Eth1Data) + } + if err = b.Eth1Data.HashTreeRootWith(hh); err != nil { + return + } + + // Field (2) 'Graffiti' + hh.PutBytes(b.Graffiti[:]) + + // Field (3) 'ProposerSlashings' + { + subIndx := hh.Index() + num := uint64(len(b.ProposerSlashings)) + if num > 16 { + err = ssz.ErrIncorrectListSize + return + } + for _, elem := range b.ProposerSlashings { + if err = elem.HashTreeRootWith(hh); err != nil { + return + } + } + hh.MerkleizeWithMixin(subIndx, num, 16) + } + + // Field (4) 'AttesterSlashings' + { + subIndx := hh.Index() + num := uint64(len(b.AttesterSlashings)) + if num > 1 { + err = ssz.ErrIncorrectListSize + return + } + for _, elem := range b.AttesterSlashings { + if err = elem.HashTreeRootWith(hh); err != nil { + return + } + } + hh.MerkleizeWithMixin(subIndx, num, 1) + } + + // Field (5) 'Attestations' + { + subIndx := hh.Index() + num := uint64(len(b.Attestations)) + if num > 8 { + err = ssz.ErrIncorrectListSize + return + } + for _, elem := range b.Attestations { + if err = elem.HashTreeRootWith(hh); err != nil { + return + } + } + hh.MerkleizeWithMixin(subIndx, num, 8) + } + + // Field (6) 'Deposits' + { + subIndx := hh.Index() + num := uint64(len(b.Deposits)) + if num > 16 { + err = ssz.ErrIncorrectListSize + return + } + for _, elem := range b.Deposits { + if err = elem.HashTreeRootWith(hh); err != nil { + return + } + } + hh.MerkleizeWithMixin(subIndx, num, 16) + } + + // Field (7) 'VoluntaryExits' + { + subIndx := hh.Index() + num := uint64(len(b.VoluntaryExits)) + if num > 16 { + err = ssz.ErrIncorrectListSize + return + } + for _, elem := range b.VoluntaryExits { + if err = elem.HashTreeRootWith(hh); err != nil { + return + } + } + hh.MerkleizeWithMixin(subIndx, num, 16) + } + + // Field (8) 'SyncAggregate' + if b.SyncAggregate == nil { + b.SyncAggregate = new(SyncAggregateMainnet) + } + if err = b.SyncAggregate.HashTreeRootWith(hh); err != nil { + return + } + + // Field (9) 'ExecutionPayload' + if err = b.ExecutionPayload.HashTreeRootWith(hh); err != nil { + return + } + + // Field (10) 'BlsToExecutionChanges' + { + subIndx := hh.Index() + num := uint64(len(b.BlsToExecutionChanges)) + if num > 16 { + err = ssz.ErrIncorrectListSize + return + } + for _, elem := range b.BlsToExecutionChanges { + if err = elem.HashTreeRootWith(hh); err != nil { + return + } + } + hh.MerkleizeWithMixin(subIndx, num, 16) + } + + // Field (11) 'BlobKzgCommitments' + { + if size := len(b.BlobKzgCommitments); size > 4096 { + err = ssz.ErrListTooBigFn("BeaconBlockBodyElectra.BlobKzgCommitments", size, 4096) + return + } + subIndx := hh.Index() + for _, i := range b.BlobKzgCommitments { + hh.PutBytes(i[:]) + } + numItems := uint64(len(b.BlobKzgCommitments)) + hh.MerkleizeWithMixin(subIndx, numItems, 4096) + } + + // Field (12) 'ExecutionRequests' + if err = b.ExecutionRequests.HashTreeRootWith(hh); err != nil { + return + } + + hh.Merkleize(indx) + return +} + +// GetTree ssz hashes the BeaconBlockBodyElectra object +func (b *BeaconBlockBodyElectra) GetTree() (*ssz.Node, error) { + return ssz.ProofTree(b) +} + +// MarshalSSZ ssz marshals the BeaconStateElectra object +func (b *BeaconStateElectra) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(b) +} + +// MarshalSSZTo ssz marshals the BeaconStateElectra object to a target array +func (b *BeaconStateElectra) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + offset := int(2736713) + + // Field (0) 'GenesisTime' + dst = ssz.MarshalUint64(dst, b.GenesisTime) + + // Field (1) 'GenesisValidatorsRoot' + if size := len(b.GenesisValidatorsRoot); size != 32 { + err = ssz.ErrBytesLengthFn("BeaconStateElectra.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("BeaconStateElectra.BlockRoots", size, 8192) + return + } + for ii := 0; ii < 8192; ii++ { + if size := len(b.BlockRoots[ii]); size != 32 { + err = ssz.ErrBytesLengthFn("BeaconStateElectra.BlockRoots[ii]", size, 32) + return + } + dst = append(dst, b.BlockRoots[ii]...) + } + + // Field (6) 'StateRoots' + if size := len(b.StateRoots); size != 8192 { + err = ssz.ErrVectorLengthFn("BeaconStateElectra.StateRoots", size, 8192) + return + } + for ii := 0; ii < 8192; ii++ { + if size := len(b.StateRoots[ii]); size != 32 { + err = ssz.ErrBytesLengthFn("BeaconStateElectra.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("BeaconStateElectra.RandaoMixes", size, 65536) + return + } + for ii := 0; ii < 65536; ii++ { + if size := len(b.RandaoMixes[ii]); size != 32 { + err = ssz.ErrBytesLengthFn("BeaconStateElectra.RandaoMixes[ii]", size, 32) + return + } + dst = append(dst, b.RandaoMixes[ii]...) + } + + // Field (14) 'Slashings' + if size := len(b.Slashings); size != 8192 { + err = ssz.ErrVectorLengthFn("BeaconStateElectra.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("BeaconStateElectra.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) 'PendingBalanceDeposits' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.PendingBalanceDeposits) * 16 + + // 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 (7) 'HistoricalRoots' + if size := len(b.HistoricalRoots); size > 16777216 { + err = ssz.ErrListTooBigFn("BeaconStateElectra.HistoricalRoots", size, 16777216) + return + } + for ii := 0; ii < len(b.HistoricalRoots); ii++ { + if size := len(b.HistoricalRoots[ii]); size != 32 { + err = ssz.ErrBytesLengthFn("BeaconStateElectra.HistoricalRoots[ii]", size, 32) + return + } + dst = append(dst, b.HistoricalRoots[ii]...) + } + + // Field (9) 'Eth1DataVotes' + if size := len(b.Eth1DataVotes); size > 2048 { + err = ssz.ErrListTooBigFn("BeaconStateElectra.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("BeaconStateElectra.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("BeaconStateElectra.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("BeaconStateElectra.PreviousEpochParticipation", size, 1099511627776) + return + } + dst = append(dst, b.PreviousEpochParticipation...) + + // Field (16) 'CurrentEpochParticipation' + if size := len(b.CurrentEpochParticipation); size > 1099511627776 { + err = ssz.ErrBytesLengthFn("BeaconStateElectra.CurrentEpochParticipation", size, 1099511627776) + return + } + dst = append(dst, b.CurrentEpochParticipation...) + + // Field (21) 'InactivityScores' + if size := len(b.InactivityScores); size > 1099511627776 { + err = ssz.ErrListTooBigFn("BeaconStateElectra.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("BeaconStateElectra.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) 'PendingBalanceDeposits' + if size := len(b.PendingBalanceDeposits); size > 134217728 { + err = ssz.ErrListTooBigFn("BeaconStateElectra.PendingBalanceDeposits", size, 134217728) + return + } + for ii := 0; ii < len(b.PendingBalanceDeposits); ii++ { + if dst, err = b.PendingBalanceDeposits[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + // Field (35) 'PendingPartialWithdrawals' + if size := len(b.PendingPartialWithdrawals); size > 134217728 { + err = ssz.ErrListTooBigFn("BeaconStateElectra.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("BeaconStateElectra.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 BeaconStateElectra object +func (b *BeaconStateElectra) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size < 2736713 { + 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 < 2736713 { + 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) 'PendingBalanceDeposits' + 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 (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) 'PendingBalanceDeposits' + { + buf = tail[o34:o35] + num, err := ssz.DivideInt2(len(buf), 16, 134217728) + if err != nil { + return err + } + b.PendingBalanceDeposits = make([]*PendingBalanceDeposit, num) + for ii := 0; ii < num; ii++ { + if b.PendingBalanceDeposits[ii] == nil { + b.PendingBalanceDeposits[ii] = new(PendingBalanceDeposit) + } + if err = b.PendingBalanceDeposits[ii].UnmarshalSSZ(buf[ii*16 : (ii+1)*16]); 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 BeaconStateElectra object +func (b *BeaconStateElectra) SizeSSZ() (size int) { + size = 2736713 + + // 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) 'PendingBalanceDeposits' + size += len(b.PendingBalanceDeposits) * 16 + + // Field (35) 'PendingPartialWithdrawals' + size += len(b.PendingPartialWithdrawals) * 24 + + // Field (36) 'PendingConsolidations' + size += len(b.PendingConsolidations) * 16 + + return +} + +// HashTreeRoot ssz hashes the BeaconStateElectra object +func (b *BeaconStateElectra) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(b) +} + +// HashTreeRootWith ssz hashes the BeaconStateElectra object with a hasher +func (b *BeaconStateElectra) 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("BeaconStateElectra.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("BeaconStateElectra.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("BeaconStateElectra.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("BeaconStateElectra.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("BeaconStateElectra.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("BeaconStateElectra.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("BeaconStateElectra.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("BeaconStateElectra.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("BeaconStateElectra.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) 'PendingBalanceDeposits' + { + subIndx := hh.Index() + num := uint64(len(b.PendingBalanceDeposits)) + if num > 134217728 { + err = ssz.ErrIncorrectListSize + return + } + for _, elem := range b.PendingBalanceDeposits { + 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) + } + + hh.Merkleize(indx) + return +} + +// GetTree ssz hashes the BeaconStateElectra object +func (b *BeaconStateElectra) GetTree() (*ssz.Node, error) { + return ssz.ProofTree(b) +} + +// MarshalSSZ ssz marshals the AttestationElectra object +func (a *AttestationElectra) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(a) +} + +// MarshalSSZTo ssz marshals the AttestationElectra object to a target array +func (a *AttestationElectra) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + offset := int(236) + + // Offset (0) 'AggregationBits' + dst = ssz.WriteOffset(dst, offset) + offset += len(a.AggregationBits) + + // Field (1) 'Data' + if a.Data == nil { + a.Data = new(AttestationData) + } + if dst, err = a.Data.MarshalSSZTo(dst); err != nil { + return + } + + // Field (2) 'Signature' + dst = append(dst, a.Signature[:]...) + + // Field (3) 'CommitteeBits' + if size := len(a.CommitteeBits); size != 8 { + err = ssz.ErrBytesLengthFn("AttestationElectra.CommitteeBits", size, 8) + return + } + dst = append(dst, a.CommitteeBits...) + + // Field (0) 'AggregationBits' + if size := len(a.AggregationBits); size > 131072 { + err = ssz.ErrBytesLengthFn("AttestationElectra.AggregationBits", size, 131072) + return + } + dst = append(dst, a.AggregationBits...) + + return +} + +// UnmarshalSSZ ssz unmarshals the AttestationElectra object +func (a *AttestationElectra) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size < 236 { + return ssz.ErrSize + } + + tail := buf + var o0 uint64 + + // Offset (0) 'AggregationBits' + if o0 = ssz.ReadOffset(buf[0:4]); o0 > size { + return ssz.ErrOffset + } + + if o0 < 236 { + return ssz.ErrInvalidVariableOffset + } + + // Field (1) 'Data' + if a.Data == nil { + a.Data = new(AttestationData) + } + if err = a.Data.UnmarshalSSZ(buf[4:132]); err != nil { + return err + } + + // Field (2) 'Signature' + copy(a.Signature[:], buf[132:228]) + + // Field (3) 'CommitteeBits' + if cap(a.CommitteeBits) == 0 { + a.CommitteeBits = make([]byte, 0, len(buf[228:236])) + } + a.CommitteeBits = append(a.CommitteeBits, buf[228:236]...) + + // Field (0) 'AggregationBits' + { + buf = tail[o0:] + if err = ssz.ValidateBitlist(buf, 131072); err != nil { + return err + } + if cap(a.AggregationBits) == 0 { + a.AggregationBits = make([]byte, 0, len(buf)) + } + a.AggregationBits = append(a.AggregationBits, buf...) + } + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the AttestationElectra object +func (a *AttestationElectra) SizeSSZ() (size int) { + size = 236 + + // Field (0) 'AggregationBits' + size += len(a.AggregationBits) + + return +} + +// HashTreeRoot ssz hashes the AttestationElectra object +func (a *AttestationElectra) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(a) +} + +// HashTreeRootWith ssz hashes the AttestationElectra object with a hasher +func (a *AttestationElectra) HashTreeRootWith(hh ssz.HashWalker) (err error) { + indx := hh.Index() + + // Field (0) 'AggregationBits' + if len(a.AggregationBits) == 0 { + err = ssz.ErrEmptyBitlist + return + } + hh.PutBitlist(a.AggregationBits, 131072) + + // Field (1) 'Data' + if a.Data == nil { + a.Data = new(AttestationData) + } + if err = a.Data.HashTreeRootWith(hh); err != nil { + return + } + + // Field (2) 'Signature' + hh.PutBytes(a.Signature[:]) + + // Field (3) 'CommitteeBits' + if size := len(a.CommitteeBits); size != 8 { + err = ssz.ErrBytesLengthFn("AttestationElectra.CommitteeBits", size, 8) + return + } + hh.PutBytes(a.CommitteeBits) + + hh.Merkleize(indx) + return +} + +// GetTree ssz hashes the AttestationElectra object +func (a *AttestationElectra) GetTree() (*ssz.Node, error) { + return ssz.ProofTree(a) +} + +// MarshalSSZ ssz marshals the AttesterSlashingElectra object +func (a *AttesterSlashingElectra) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(a) +} + +// MarshalSSZTo ssz marshals the AttesterSlashingElectra object to a target array +func (a *AttesterSlashingElectra) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + offset := int(8) + + // Offset (0) 'Attestation1' + dst = ssz.WriteOffset(dst, offset) + if a.Attestation1 == nil { + a.Attestation1 = new(IndexedAttestationElectra) + } + offset += a.Attestation1.SizeSSZ() + + // Offset (1) 'Attestation2' + dst = ssz.WriteOffset(dst, offset) + if a.Attestation2 == nil { + a.Attestation2 = new(IndexedAttestationElectra) + } + offset += a.Attestation2.SizeSSZ() + + // Field (0) 'Attestation1' + if dst, err = a.Attestation1.MarshalSSZTo(dst); err != nil { + return + } + + // Field (1) 'Attestation2' + if dst, err = a.Attestation2.MarshalSSZTo(dst); err != nil { + return + } + + return +} + +// UnmarshalSSZ ssz unmarshals the AttesterSlashingElectra object +func (a *AttesterSlashingElectra) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size < 8 { + return ssz.ErrSize + } + + tail := buf + var o0, o1 uint64 + + // Offset (0) 'Attestation1' + if o0 = ssz.ReadOffset(buf[0:4]); o0 > size { + return ssz.ErrOffset + } + + if o0 < 8 { + return ssz.ErrInvalidVariableOffset + } + + // Offset (1) 'Attestation2' + if o1 = ssz.ReadOffset(buf[4:8]); o1 > size || o0 > o1 { + return ssz.ErrOffset + } + + // Field (0) 'Attestation1' + { + buf = tail[o0:o1] + if a.Attestation1 == nil { + a.Attestation1 = new(IndexedAttestationElectra) + } + if err = a.Attestation1.UnmarshalSSZ(buf); err != nil { + return err + } + } + + // Field (1) 'Attestation2' + { + buf = tail[o1:] + if a.Attestation2 == nil { + a.Attestation2 = new(IndexedAttestationElectra) + } + if err = a.Attestation2.UnmarshalSSZ(buf); err != nil { + return err + } + } + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the AttesterSlashingElectra object +func (a *AttesterSlashingElectra) SizeSSZ() (size int) { + size = 8 + + // Field (0) 'Attestation1' + if a.Attestation1 == nil { + a.Attestation1 = new(IndexedAttestationElectra) + } + size += a.Attestation1.SizeSSZ() + + // Field (1) 'Attestation2' + if a.Attestation2 == nil { + a.Attestation2 = new(IndexedAttestationElectra) + } + size += a.Attestation2.SizeSSZ() + + return +} + +// HashTreeRoot ssz hashes the AttesterSlashingElectra object +func (a *AttesterSlashingElectra) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(a) +} + +// HashTreeRootWith ssz hashes the AttesterSlashingElectra object with a hasher +func (a *AttesterSlashingElectra) HashTreeRootWith(hh ssz.HashWalker) (err error) { + indx := hh.Index() + + // Field (0) 'Attestation1' + if err = a.Attestation1.HashTreeRootWith(hh); err != nil { + return + } + + // Field (1) 'Attestation2' + if err = a.Attestation2.HashTreeRootWith(hh); err != nil { + return + } + + hh.Merkleize(indx) + return +} + +// GetTree ssz hashes the AttesterSlashingElectra object +func (a *AttesterSlashingElectra) GetTree() (*ssz.Node, error) { + return ssz.ProofTree(a) +} + +// MarshalSSZ ssz marshals the IndexedAttestationElectra object +func (i *IndexedAttestationElectra) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(i) +} + +// MarshalSSZTo ssz marshals the IndexedAttestationElectra object to a target array +func (i *IndexedAttestationElectra) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + offset := int(228) + + // Offset (0) 'AttestationIndices' + dst = ssz.WriteOffset(dst, offset) + offset += len(i.AttestationIndices) * 8 + + // Field (1) 'Data' + if i.Data == nil { + i.Data = new(AttestationData) + } + if dst, err = i.Data.MarshalSSZTo(dst); err != nil { + return + } + + // Field (2) 'Signature' + dst = append(dst, i.Signature[:]...) + + // Field (0) 'AttestationIndices' + if size := len(i.AttestationIndices); size > 131072 { + err = ssz.ErrListTooBigFn("IndexedAttestationElectra.AttestationIndices", size, 131072) + return + } + for ii := 0; ii < len(i.AttestationIndices); ii++ { + dst = ssz.MarshalUint64(dst, i.AttestationIndices[ii]) + } + + return +} + +// UnmarshalSSZ ssz unmarshals the IndexedAttestationElectra object +func (i *IndexedAttestationElectra) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size < 228 { + return ssz.ErrSize + } + + tail := buf + var o0 uint64 + + // Offset (0) 'AttestationIndices' + if o0 = ssz.ReadOffset(buf[0:4]); o0 > size { + return ssz.ErrOffset + } + + if o0 < 228 { + return ssz.ErrInvalidVariableOffset + } + + // Field (1) 'Data' + if i.Data == nil { + i.Data = new(AttestationData) + } + if err = i.Data.UnmarshalSSZ(buf[4:132]); err != nil { + return err + } + + // Field (2) 'Signature' + copy(i.Signature[:], buf[132:228]) + + // Field (0) 'AttestationIndices' + { + buf = tail[o0:] + num, err := ssz.DivideInt2(len(buf), 8, 131072) + if err != nil { + return err + } + i.AttestationIndices = ssz.ExtendUint64(i.AttestationIndices, num) + for ii := 0; ii < num; ii++ { + i.AttestationIndices[ii] = ssz.UnmarshallUint64(buf[ii*8 : (ii+1)*8]) + } + } + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the IndexedAttestationElectra object +func (i *IndexedAttestationElectra) SizeSSZ() (size int) { + size = 228 + + // Field (0) 'AttestationIndices' + size += len(i.AttestationIndices) * 8 + + return +} + +// HashTreeRoot ssz hashes the IndexedAttestationElectra object +func (i *IndexedAttestationElectra) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(i) +} + +// HashTreeRootWith ssz hashes the IndexedAttestationElectra object with a hasher +func (i *IndexedAttestationElectra) HashTreeRootWith(hh ssz.HashWalker) (err error) { + indx := hh.Index() + + // Field (0) 'AttestationIndices' + { + if size := len(i.AttestationIndices); size > 131072 { + err = ssz.ErrListTooBigFn("IndexedAttestationElectra.AttestationIndices", size, 131072) + return + } + subIndx := hh.Index() + for _, i := range i.AttestationIndices { + hh.AppendUint64(i) + } + hh.FillUpTo32() + numItems := uint64(len(i.AttestationIndices)) + hh.MerkleizeWithMixin(subIndx, numItems, ssz.CalculateLimit(131072, numItems, 8)) + } + + // Field (1) 'Data' + if i.Data == nil { + i.Data = new(AttestationData) + } + if err = i.Data.HashTreeRootWith(hh); err != nil { + return + } + + // Field (2) 'Signature' + hh.PutBytes(i.Signature[:]) + + hh.Merkleize(indx) + return +} + +// GetTree ssz hashes the IndexedAttestationElectra object +func (i *IndexedAttestationElectra) GetTree() (*ssz.Node, error) { + return ssz.ProofTree(i) +} + +// MarshalSSZ ssz marshals the PendingBalanceDeposit object +func (p *PendingBalanceDeposit) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(p) +} + +// MarshalSSZTo ssz marshals the PendingBalanceDeposit object to a target array +func (p *PendingBalanceDeposit) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + + // Field (0) 'Index' + dst = ssz.MarshalUint64(dst, p.Index) + + // Field (1) 'Amount' + dst = ssz.MarshalUint64(dst, p.Amount) + + return +} + +// UnmarshalSSZ ssz unmarshals the PendingBalanceDeposit object +func (p *PendingBalanceDeposit) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size != 16 { + return ssz.ErrSize + } + + // Field (0) 'Index' + p.Index = ssz.UnmarshallUint64(buf[0:8]) + + // Field (1) 'Amount' + p.Amount = ssz.UnmarshallUint64(buf[8:16]) + + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the PendingBalanceDeposit object +func (p *PendingBalanceDeposit) SizeSSZ() (size int) { + size = 16 + return +} + +// HashTreeRoot ssz hashes the PendingBalanceDeposit object +func (p *PendingBalanceDeposit) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(p) +} + +// HashTreeRootWith ssz hashes the PendingBalanceDeposit object with a hasher +func (p *PendingBalanceDeposit) HashTreeRootWith(hh ssz.HashWalker) (err error) { + indx := hh.Index() + + // Field (0) 'Index' + hh.PutUint64(p.Index) + + // Field (1) 'Amount' + hh.PutUint64(p.Amount) + + hh.Merkleize(indx) + return +} + +// GetTree ssz hashes the PendingBalanceDeposit object +func (p *PendingBalanceDeposit) GetTree() (*ssz.Node, error) { + return ssz.ProofTree(p) +} + +// MarshalSSZ ssz marshals the PendingPartialWithdrawal object +func (p *PendingPartialWithdrawal) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(p) +} + +// MarshalSSZTo ssz marshals the PendingPartialWithdrawal object to a target array +func (p *PendingPartialWithdrawal) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + + // Field (0) 'Index' + dst = ssz.MarshalUint64(dst, p.Index) + + // Field (1) 'Amount' + dst = ssz.MarshalUint64(dst, p.Amount) + + // Field (2) 'WithdrawableEpoch' + dst = ssz.MarshalUint64(dst, p.WithdrawableEpoch) + + return +} + +// UnmarshalSSZ ssz unmarshals the PendingPartialWithdrawal object +func (p *PendingPartialWithdrawal) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size != 24 { + return ssz.ErrSize + } + + // Field (0) 'Index' + p.Index = ssz.UnmarshallUint64(buf[0:8]) + + // Field (1) 'Amount' + p.Amount = ssz.UnmarshallUint64(buf[8:16]) + + // Field (2) 'WithdrawableEpoch' + p.WithdrawableEpoch = ssz.UnmarshallUint64(buf[16:24]) + + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the PendingPartialWithdrawal object +func (p *PendingPartialWithdrawal) SizeSSZ() (size int) { + size = 24 + return +} + +// HashTreeRoot ssz hashes the PendingPartialWithdrawal object +func (p *PendingPartialWithdrawal) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(p) +} + +// HashTreeRootWith ssz hashes the PendingPartialWithdrawal object with a hasher +func (p *PendingPartialWithdrawal) HashTreeRootWith(hh ssz.HashWalker) (err error) { + indx := hh.Index() + + // Field (0) 'Index' + hh.PutUint64(p.Index) + + // Field (1) 'Amount' + hh.PutUint64(p.Amount) + + // Field (2) 'WithdrawableEpoch' + hh.PutUint64(p.WithdrawableEpoch) + + hh.Merkleize(indx) + return +} + +// GetTree ssz hashes the PendingPartialWithdrawal object +func (p *PendingPartialWithdrawal) GetTree() (*ssz.Node, error) { + return ssz.ProofTree(p) +} + +// MarshalSSZ ssz marshals the PendingConsolidation object +func (p *PendingConsolidation) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(p) +} + +// MarshalSSZTo ssz marshals the PendingConsolidation object to a target array +func (p *PendingConsolidation) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + + // Field (0) 'SourceIndex' + dst = ssz.MarshalUint64(dst, p.SourceIndex) + + // Field (1) 'TargetIndex' + dst = ssz.MarshalUint64(dst, p.TargetIndex) + + return +} + +// UnmarshalSSZ ssz unmarshals the PendingConsolidation object +func (p *PendingConsolidation) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size != 16 { + return ssz.ErrSize + } + + // Field (0) 'SourceIndex' + p.SourceIndex = ssz.UnmarshallUint64(buf[0:8]) + + // Field (1) 'TargetIndex' + p.TargetIndex = ssz.UnmarshallUint64(buf[8:16]) + + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the PendingConsolidation object +func (p *PendingConsolidation) SizeSSZ() (size int) { + size = 16 + return +} + +// HashTreeRoot ssz hashes the PendingConsolidation object +func (p *PendingConsolidation) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(p) +} + +// HashTreeRootWith ssz hashes the PendingConsolidation object with a hasher +func (p *PendingConsolidation) HashTreeRootWith(hh ssz.HashWalker) (err error) { + indx := hh.Index() + + // Field (0) 'SourceIndex' + hh.PutUint64(p.SourceIndex) + + // Field (1) 'TargetIndex' + hh.PutUint64(p.TargetIndex) + + hh.Merkleize(indx) + return +} + +// GetTree ssz hashes the PendingConsolidation object +func (p *PendingConsolidation) GetTree() (*ssz.Node, error) { + return ssz.ProofTree(p) +} + +// MarshalSSZ ssz marshals the ExecutionRequests object +func (e *ExecutionRequests) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(e) +} + +// MarshalSSZTo ssz marshals the ExecutionRequests object to a target array +func (e *ExecutionRequests) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + offset := int(12) + + // Offset (0) 'Deposits' + dst = ssz.WriteOffset(dst, offset) + offset += len(e.Deposits) * 192 + + // Offset (1) 'Withdrawals' + dst = ssz.WriteOffset(dst, offset) + offset += len(e.Withdrawals) * 76 + + // Offset (2) 'Consolidations' + dst = ssz.WriteOffset(dst, offset) + offset += len(e.Consolidations) * 116 + + // Field (0) 'Deposits' + if size := len(e.Deposits); size > 8192 { + err = ssz.ErrListTooBigFn("ExecutionRequests.Deposits", size, 8192) + return + } + for ii := 0; ii < len(e.Deposits); ii++ { + if dst, err = e.Deposits[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + // Field (1) 'Withdrawals' + if size := len(e.Withdrawals); size > 16 { + err = ssz.ErrListTooBigFn("ExecutionRequests.Withdrawals", size, 16) + return + } + for ii := 0; ii < len(e.Withdrawals); ii++ { + if dst, err = e.Withdrawals[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + // Field (2) 'Consolidations' + if size := len(e.Consolidations); size > 2 { + err = ssz.ErrListTooBigFn("ExecutionRequests.Consolidations", size, 2) + return + } + for ii := 0; ii < len(e.Consolidations); ii++ { + if dst, err = e.Consolidations[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + return +} + +// UnmarshalSSZ ssz unmarshals the ExecutionRequests object +func (e *ExecutionRequests) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size < 12 { + return ssz.ErrSize + } + + tail := buf + var o0, o1, o2 uint64 + + // Offset (0) 'Deposits' + if o0 = ssz.ReadOffset(buf[0:4]); o0 > size { + return ssz.ErrOffset + } + + if o0 < 12 { + return ssz.ErrInvalidVariableOffset + } + + // Offset (1) 'Withdrawals' + if o1 = ssz.ReadOffset(buf[4:8]); o1 > size || o0 > o1 { + return ssz.ErrOffset + } + + // Offset (2) 'Consolidations' + if o2 = ssz.ReadOffset(buf[8:12]); o2 > size || o1 > o2 { + return ssz.ErrOffset + } + + // Field (0) 'Deposits' + { + buf = tail[o0:o1] + num, err := ssz.DivideInt2(len(buf), 192, 8192) + if err != nil { + return err + } + e.Deposits = make([]*DepositRequest, num) + for ii := 0; ii < num; ii++ { + if e.Deposits[ii] == nil { + e.Deposits[ii] = new(DepositRequest) + } + if err = e.Deposits[ii].UnmarshalSSZ(buf[ii*192 : (ii+1)*192]); err != nil { + return err + } + } + } + + // Field (1) 'Withdrawals' + { + buf = tail[o1:o2] + num, err := ssz.DivideInt2(len(buf), 76, 16) + if err != nil { + return err + } + e.Withdrawals = make([]*WithdrawalRequest, num) + for ii := 0; ii < num; ii++ { + if e.Withdrawals[ii] == nil { + e.Withdrawals[ii] = new(WithdrawalRequest) + } + if err = e.Withdrawals[ii].UnmarshalSSZ(buf[ii*76 : (ii+1)*76]); err != nil { + return err + } + } + } + + // Field (2) 'Consolidations' + { + buf = tail[o2:] + num, err := ssz.DivideInt2(len(buf), 116, 2) + if err != nil { + return err + } + e.Consolidations = make([]*ConsolidationRequest, num) + for ii := 0; ii < num; ii++ { + if e.Consolidations[ii] == nil { + e.Consolidations[ii] = new(ConsolidationRequest) + } + if err = e.Consolidations[ii].UnmarshalSSZ(buf[ii*116 : (ii+1)*116]); err != nil { + return err + } + } + } + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the ExecutionRequests object +func (e *ExecutionRequests) SizeSSZ() (size int) { + size = 12 + + // Field (0) 'Deposits' + size += len(e.Deposits) * 192 + + // Field (1) 'Withdrawals' + size += len(e.Withdrawals) * 76 + + // Field (2) 'Consolidations' + size += len(e.Consolidations) * 116 + + return +} + +// HashTreeRoot ssz hashes the ExecutionRequests object +func (e *ExecutionRequests) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(e) +} + +// HashTreeRootWith ssz hashes the ExecutionRequests object with a hasher +func (e *ExecutionRequests) HashTreeRootWith(hh ssz.HashWalker) (err error) { + indx := hh.Index() + + // Field (0) 'Deposits' + { + subIndx := hh.Index() + num := uint64(len(e.Deposits)) + if num > 8192 { + err = ssz.ErrIncorrectListSize + return + } + for _, elem := range e.Deposits { + if err = elem.HashTreeRootWith(hh); err != nil { + return + } + } + hh.MerkleizeWithMixin(subIndx, num, 8192) + } + + // Field (1) 'Withdrawals' + { + subIndx := hh.Index() + num := uint64(len(e.Withdrawals)) + if num > 16 { + err = ssz.ErrIncorrectListSize + return + } + for _, elem := range e.Withdrawals { + if err = elem.HashTreeRootWith(hh); err != nil { + return + } + } + hh.MerkleizeWithMixin(subIndx, num, 16) + } + + // Field (2) 'Consolidations' + { + subIndx := hh.Index() + num := uint64(len(e.Consolidations)) + if num > 2 { + err = ssz.ErrIncorrectListSize + return + } + for _, elem := range e.Consolidations { + if err = elem.HashTreeRootWith(hh); err != nil { + return + } + } + hh.MerkleizeWithMixin(subIndx, num, 2) + } + + hh.Merkleize(indx) + return +} + +// GetTree ssz hashes the ExecutionRequests object +func (e *ExecutionRequests) GetTree() (*ssz.Node, error) { + return ssz.ProofTree(e) +} diff --git a/relayer/relays/beacon/state/beacon_encoding.go b/relayer/relays/beacon/state/beacon_encoding.go index ea9e3b1fb0..200859af0b 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: 03b5096ab94e41e2c740924a4ae7ea8fdd515fe3dd4861032a569e28bcba8bb4 +// Hash: b1d302f8bf37c4a5c505fc9650d27803c352a01033937e6f1a567f1ff6998c2a // Version: 0.1.3 package state diff --git a/relayer/relays/beacon/store/datastore_test.go b/relayer/relays/beacon/store/datastore_test.go index 75069c5883..adaca06afd 100644 --- a/relayer/relays/beacon/store/datastore_test.go +++ b/relayer/relays/beacon/store/datastore_test.go @@ -19,11 +19,16 @@ func TestGetBeaconState(t *testing.T) { _ = os.RemoveAll(TestDataStoreFile + BeaconStateDir) _ = os.Remove(TestDataStoreFile + BeaconStoreName) - store := New(TestDataStoreFile, 100, *protocol.New(config.SpecSettings{ + specSettings := config.SpecSettings{ SlotsInEpoch: 32, EpochsPerSyncCommitteePeriod: 256, - DenebForkEpoch: 0, - }, MaxRedundancy)) + ForkVersions: config.ForkVersions{ + Deneb: 0, + Electra: 800000, + }, + } + store := New(TestDataStoreFile, 100, *protocol.New(specSettings, MaxRedundancy)) + err := store.Connect() require.NoError(t, err) defer func() { @@ -66,7 +71,10 @@ func TestPruneOldStates(t *testing.T) { store := New(TestDataStoreFile, 2, *protocol.New(config.SpecSettings{ SlotsInEpoch: 32, EpochsPerSyncCommitteePeriod: 256, - DenebForkEpoch: 0, + ForkVersions: config.ForkVersions{ + Deneb: 0, + Electra: 800000, + }, }, MaxRedundancy)) err := store.Connect() require.NoError(t, err) @@ -137,7 +145,10 @@ func TestFindBeaconStateWithinRange(t *testing.T) { p := protocol.New(config.SpecSettings{ SlotsInEpoch: 32, EpochsPerSyncCommitteePeriod: 256, - DenebForkEpoch: 0, + ForkVersions: config.ForkVersions{ + Deneb: 0, + Electra: 800000, + }, }, MaxRedundancy) store := New(TestDataStoreFile, 2, *p) err := store.Connect() diff --git a/relayer/templates/beacon-fixtures.mustache b/relayer/templates/beacon-fixtures.mustache new file mode 100644 index 0000000000..5942be0563 --- /dev/null +++ b/relayer/templates/beacon-fixtures.mustache @@ -0,0 +1,270 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 Snowfork +// Generated, do not edit! +// See README.md for instructions to generate +#![cfg_attr(not(feature = "std"), no_std)] + +use hex_literal::hex; +use snowbridge_beacon_primitives::{ + types::deneb, AncestryProof, BeaconHeader, ExecutionProof, NextSyncCommitteeUpdate, + SyncAggregate, SyncCommittee, VersionedExecutionPayloadHeader, +}; +use snowbridge_core::inbound::{InboundQueueFixture, Log, Message, Proof}; +use sp_core::U256; +use sp_std::{boxed::Box, vec}; + +const SC_SIZE: usize = 512; +const SC_BITS_SIZE: usize = 64; +type CheckpointUpdate = snowbridge_beacon_primitives::CheckpointUpdate; +type Update = snowbridge_beacon_primitives::Update; + + +pub fn make_checkpoint() -> Box { + Box::new(CheckpointUpdate { + header: BeaconHeader { + slot: {{CheckpointUpdate.Header.Slot}}, + proposer_index: {{CheckpointUpdate.Header.ProposerIndex}}, + parent_root: hex!("{{CheckpointUpdate.Header.ParentRoot}}").into(), + state_root: hex!("{{CheckpointUpdate.Header.StateRoot}}").into(), + body_root: hex!("{{CheckpointUpdate.Header.BodyRoot}}").into(), + }, + current_sync_committee: SyncCommittee { + pubkeys: [ + {{#CheckpointUpdate.CurrentSyncCommittee.Pubkeys}} + hex!("{{.}}").into(), + {{/CheckpointUpdate.CurrentSyncCommittee.Pubkeys}} + ], + aggregate_pubkey: hex!("{{CheckpointUpdate.CurrentSyncCommittee.AggregatePubkey}}").into(), + }, + current_sync_committee_branch: vec![ + {{#CheckpointUpdate.CurrentSyncCommitteeBranch}} + hex!("{{.}}").into(), + {{/CheckpointUpdate.CurrentSyncCommitteeBranch}} + ], + validators_root: hex!("{{CheckpointUpdate.ValidatorsRoot}}").into(), + block_roots_root: hex!("{{CheckpointUpdate.BlockRootsRoot}}").into(), + block_roots_branch: vec![ + {{#CheckpointUpdate.BlockRootsBranch}} + hex!("{{.}}").into(), + {{/CheckpointUpdate.BlockRootsBranch}} + ], + }) +} + +pub fn make_sync_committee_update() -> Box { + Box::new(Update { + attested_header: BeaconHeader { + slot: {{SyncCommitteeUpdate.AttestedHeader.Slot}}, + proposer_index: {{SyncCommitteeUpdate.AttestedHeader.ProposerIndex}}, + parent_root: hex!("{{SyncCommitteeUpdate.AttestedHeader.ParentRoot}}").into(), + state_root: hex!("{{SyncCommitteeUpdate.AttestedHeader.StateRoot}}").into(), + body_root: hex!("{{SyncCommitteeUpdate.AttestedHeader.BodyRoot}}").into(), + }, + sync_aggregate: SyncAggregate{ + sync_committee_bits: hex!("{{SyncCommitteeUpdate.SyncAggregate.SyncCommitteeBits}}"), + sync_committee_signature: hex!("{{SyncCommitteeUpdate.SyncAggregate.SyncCommitteeSignature}}").into(), + }, + signature_slot: {{SyncCommitteeUpdate.SignatureSlot}}, + next_sync_committee_update: Some(NextSyncCommitteeUpdate { + next_sync_committee: SyncCommittee { + pubkeys: [ + {{#SyncCommitteeUpdate.NextSyncCommitteeUpdate.NextSyncCommittee.Pubkeys}} + hex!("{{.}}").into(), + {{/SyncCommitteeUpdate.NextSyncCommitteeUpdate.NextSyncCommittee.Pubkeys}} + ], + aggregate_pubkey: hex!("{{SyncCommitteeUpdate.NextSyncCommitteeUpdate.NextSyncCommittee.AggregatePubkey}}").into(), + }, + next_sync_committee_branch: vec![ + {{#SyncCommitteeUpdate.NextSyncCommitteeUpdate.NextSyncCommitteeBranch}} + hex!("{{.}}").into(), + {{/SyncCommitteeUpdate.NextSyncCommitteeUpdate.NextSyncCommitteeBranch}} + ], + }), + finalized_header: BeaconHeader{ + slot: {{SyncCommitteeUpdate.FinalizedHeader.Slot}}, + proposer_index: {{SyncCommitteeUpdate.FinalizedHeader.ProposerIndex}}, + parent_root: hex!("{{SyncCommitteeUpdate.FinalizedHeader.ParentRoot}}").into(), + state_root: hex!("{{SyncCommitteeUpdate.FinalizedHeader.StateRoot}}").into(), + body_root: hex!("{{SyncCommitteeUpdate.FinalizedHeader.BodyRoot}}").into(), + }, + finality_branch: vec![ + {{#SyncCommitteeUpdate.FinalityBranch}} + hex!("{{.}}").into(), + {{/SyncCommitteeUpdate.FinalityBranch}} + ], + block_roots_root: hex!("{{SyncCommitteeUpdate.BlockRootsRoot}}").into(), + block_roots_branch: vec![ + {{#SyncCommitteeUpdate.BlockRootsBranch}} + hex!("{{.}}").into(), + {{/SyncCommitteeUpdate.BlockRootsBranch}} + ], + }) +} + +pub fn make_finalized_header_update() -> Box { + Box::new(Update { + attested_header: BeaconHeader { + slot: {{FinalizedHeaderUpdate.AttestedHeader.Slot}}, + proposer_index: {{FinalizedHeaderUpdate.AttestedHeader.ProposerIndex}}, + parent_root: hex!("{{FinalizedHeaderUpdate.AttestedHeader.ParentRoot}}").into(), + state_root: hex!("{{FinalizedHeaderUpdate.AttestedHeader.StateRoot}}").into(), + body_root: hex!("{{FinalizedHeaderUpdate.AttestedHeader.BodyRoot}}").into(), + }, + sync_aggregate: SyncAggregate{ + sync_committee_bits: hex!("{{FinalizedHeaderUpdate.SyncAggregate.SyncCommitteeBits}}"), + sync_committee_signature: hex!("{{FinalizedHeaderUpdate.SyncAggregate.SyncCommitteeSignature}}").into(), + }, + signature_slot: {{FinalizedHeaderUpdate.SignatureSlot}}, + next_sync_committee_update: None, + finalized_header: BeaconHeader { + slot: {{FinalizedHeaderUpdate.FinalizedHeader.Slot}}, + proposer_index: {{FinalizedHeaderUpdate.FinalizedHeader.ProposerIndex}}, + parent_root: hex!("{{FinalizedHeaderUpdate.FinalizedHeader.ParentRoot}}").into(), + state_root: hex!("{{FinalizedHeaderUpdate.FinalizedHeader.StateRoot}}").into(), + body_root: hex!("{{FinalizedHeaderUpdate.FinalizedHeader.BodyRoot}}").into(), + }, + finality_branch: vec![ + {{#FinalizedHeaderUpdate.FinalityBranch}} + hex!("{{.}}").into(), + {{/FinalizedHeaderUpdate.FinalityBranch}} + ], + block_roots_root: hex!("{{FinalizedHeaderUpdate.BlockRootsRoot}}").into(), + block_roots_branch: vec![ + {{#FinalizedHeaderUpdate.BlockRootsBranch}} + hex!("{{.}}").into(), + {{/FinalizedHeaderUpdate.BlockRootsBranch}} + ] + }) +} + +pub fn make_execution_proof() -> Box { + Box::new(ExecutionProof { + header: BeaconHeader { + slot: {{HeaderUpdate.Header.Slot}}, + proposer_index: {{HeaderUpdate.Header.ProposerIndex}}, + parent_root: hex!("{{HeaderUpdate.Header.ParentRoot}}").into(), + state_root: hex!("{{HeaderUpdate.Header.StateRoot}}").into(), + body_root: hex!("{{HeaderUpdate.Header.BodyRoot}}").into(), + }, + {{#HeaderUpdate.AncestryProof}} + ancestry_proof: Some(AncestryProof { + header_branch: vec![ + {{#HeaderUpdate.AncestryProof.HeaderBranch}} + hex!("{{.}}").into(), + {{/HeaderUpdate.AncestryProof.HeaderBranch}} + ], + finalized_block_root: hex!("{{HeaderUpdate.AncestryProof.FinalizedBlockRoot}}").into(), + }), + {{/HeaderUpdate.AncestryProof}} + {{^HeaderUpdate.AncestryProof}} + ancestry_proof: None, + {{/HeaderUpdate.AncestryProof}} + execution_header: VersionedExecutionPayloadHeader::Deneb(deneb::ExecutionPayloadHeader { + parent_hash: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.ParentHash}}").into(), + fee_recipient: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.FeeRecipient}}").into(), + state_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.StateRoot}}").into(), + receipts_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.ReceiptsRoot}}").into(), + logs_bloom: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.LogsBloom}}").into(), + prev_randao: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.PrevRandao}}").into(), + block_number: {{HeaderUpdate.ExecutionHeader.Deneb.BlockNumber}}, + gas_limit: {{HeaderUpdate.ExecutionHeader.Deneb.GasLimit}}, + gas_used: {{HeaderUpdate.ExecutionHeader.Deneb.GasUsed}}, + timestamp: {{HeaderUpdate.ExecutionHeader.Deneb.Timestamp}}, + extra_data: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.ExtraData}}").into(), + base_fee_per_gas: U256::from({{HeaderUpdate.ExecutionHeader.Deneb.BaseFeePerGas}}u64), + block_hash: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.BlockHash}}").into(), + transactions_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.TransactionsRoot}}").into(), + withdrawals_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.WithdrawalsRoot}}").into(), + blob_gas_used: {{HeaderUpdate.ExecutionHeader.Deneb.BlobGasUsed}}, + excess_blob_gas: {{HeaderUpdate.ExecutionHeader.Deneb.ExcessBlobGas}}, + }), + execution_branch: vec![ + {{#HeaderUpdate.ExecutionBranch}} + hex!("{{.}}").into(), + {{/HeaderUpdate.ExecutionBranch}} + ], + }) +} + +pub fn make_inbound_fixture() -> InboundQueueFixture { + InboundQueueFixture { + message: Message { + event_log: Log { + address: hex!("{{InboundMessage.EventLog.Address}}").into(), + topics: vec![ + {{#InboundMessage.EventLog.Topics}} + hex!("{{.}}").into(), + {{/InboundMessage.EventLog.Topics}} + ], + data: hex!("{{InboundMessage.EventLog.Data}}").into(), + }, + proof: Proof { + block_hash: hex!("{{InboundMessage.Proof.BlockHash}}").into(), + tx_index: {{InboundMessage.Proof.TxIndex}}, + receipt_proof: (vec![ + {{#InboundMessage.Proof.ReceiptProof.Keys}} + hex!("{{.}}").to_vec(), + {{/InboundMessage.Proof.ReceiptProof.Keys}} + ], vec![ + {{#InboundMessage.Proof.ReceiptProof.Values}} + hex!("{{.}}").to_vec(), + {{/InboundMessage.Proof.ReceiptProof.Values}} + ]), + execution_proof: ExecutionProof { + header: BeaconHeader { + slot: {{HeaderUpdate.Header.Slot}}, + proposer_index: {{HeaderUpdate.Header.ProposerIndex}}, + parent_root: hex!("{{HeaderUpdate.Header.ParentRoot}}").into(), + state_root: hex!("{{HeaderUpdate.Header.StateRoot}}").into(), + body_root: hex!("{{HeaderUpdate.Header.BodyRoot}}").into(), + }, + {{#HeaderUpdate.AncestryProof}} + ancestry_proof: Some(AncestryProof { + header_branch: vec![ + {{#HeaderUpdate.AncestryProof.HeaderBranch}} + hex!("{{.}}").into(), + {{/HeaderUpdate.AncestryProof.HeaderBranch}} + ], + finalized_block_root: hex!("{{HeaderUpdate.AncestryProof.FinalizedBlockRoot}}").into(), + }), + {{/HeaderUpdate.AncestryProof}} + {{^HeaderUpdate.AncestryProof}} + ancestry_proof: None, + {{/HeaderUpdate.AncestryProof}} + execution_header: VersionedExecutionPayloadHeader::Deneb(deneb::ExecutionPayloadHeader { + parent_hash: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.ParentHash}}").into(), + fee_recipient: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.FeeRecipient}}").into(), + state_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.StateRoot}}").into(), + receipts_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.ReceiptsRoot}}").into(), + logs_bloom: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.LogsBloom}}").into(), + prev_randao: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.PrevRandao}}").into(), + block_number: {{HeaderUpdate.ExecutionHeader.Deneb.BlockNumber}}, + gas_limit: {{HeaderUpdate.ExecutionHeader.Deneb.GasLimit}}, + gas_used: {{HeaderUpdate.ExecutionHeader.Deneb.GasUsed}}, + timestamp: {{HeaderUpdate.ExecutionHeader.Deneb.Timestamp}}, + extra_data: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.ExtraData}}").into(), + base_fee_per_gas: U256::from({{HeaderUpdate.ExecutionHeader.Deneb.BaseFeePerGas}}u64), + block_hash: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.BlockHash}}").into(), + transactions_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.TransactionsRoot}}").into(), + withdrawals_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.WithdrawalsRoot}}").into(), + blob_gas_used: {{HeaderUpdate.ExecutionHeader.Deneb.BlobGasUsed}}, + excess_blob_gas: {{HeaderUpdate.ExecutionHeader.Deneb.ExcessBlobGas}}, + }), + execution_branch: vec![ + {{#HeaderUpdate.ExecutionBranch}} + hex!("{{.}}").into(), + {{/HeaderUpdate.ExecutionBranch}} + ], + } + }, + }, + finalized_header: BeaconHeader { + slot: {{FinalizedHeaderUpdate.FinalizedHeader.Slot}}, + proposer_index: {{FinalizedHeaderUpdate.FinalizedHeader.ProposerIndex}}, + parent_root: hex!("{{FinalizedHeaderUpdate.FinalizedHeader.ParentRoot}}").into(), + state_root: hex!("{{FinalizedHeaderUpdate.FinalizedHeader.StateRoot}}").into(), + body_root: hex!("{{FinalizedHeaderUpdate.FinalizedHeader.BodyRoot}}").into(), + }, + block_roots_root: hex!("{{FinalizedHeaderUpdate.BlockRootsRoot}}").into(), + } +} diff --git a/relayer/templates/inbound-fixtures.mustache b/relayer/templates/inbound-fixtures.mustache new file mode 100644 index 0000000000..b35a263fda --- /dev/null +++ b/relayer/templates/inbound-fixtures.mustache @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 Snowfork +// Generated, do not edit! +// See ethereum client README.md for instructions to generate + +use hex_literal::hex; +use snowbridge_beacon_primitives::{ +types::deneb, AncestryProof, BeaconHeader, ExecutionProof, VersionedExecutionPayloadHeader, +}; +use snowbridge_core::inbound::{InboundQueueFixture, Log, Message, Proof}; +use sp_core::U256; +use sp_std::vec; + +pub fn make_{{TestCase}}_message() -> InboundQueueFixture { + InboundQueueFixture { + message: Message { + event_log: Log { + address: hex!("{{InboundMessage.EventLog.Address}}").into(), + topics: vec![ + {{#InboundMessage.EventLog.Topics}} + hex!("{{.}}").into(), + {{/InboundMessage.EventLog.Topics}} + ], + data: hex!("{{InboundMessage.EventLog.Data}}").into(), + }, + proof: Proof { + block_hash: hex!("{{InboundMessage.Proof.BlockHash}}").into(), + tx_index: {{InboundMessage.Proof.TxIndex}}, + receipt_proof: (vec![ + {{#InboundMessage.Proof.ReceiptProof.Keys}} + hex!("{{.}}").to_vec(), + {{/InboundMessage.Proof.ReceiptProof.Keys}} + ], vec![ + {{#InboundMessage.Proof.ReceiptProof.Values}} + hex!("{{.}}").to_vec(), + {{/InboundMessage.Proof.ReceiptProof.Values}} + ]), + execution_proof: ExecutionProof { + header: BeaconHeader { + slot: {{HeaderUpdate.Header.Slot}}, + proposer_index: {{HeaderUpdate.Header.ProposerIndex}}, + parent_root: hex!("{{HeaderUpdate.Header.ParentRoot}}").into(), + state_root: hex!("{{HeaderUpdate.Header.StateRoot}}").into(), + body_root: hex!("{{HeaderUpdate.Header.BodyRoot}}").into(), + }, + {{#HeaderUpdate.AncestryProof}} + ancestry_proof: Some(AncestryProof { + header_branch: vec![ + {{#HeaderUpdate.AncestryProof.HeaderBranch}} + hex!("{{.}}").into(), + {{/HeaderUpdate.AncestryProof.HeaderBranch}} + ], + finalized_block_root: hex!("{{HeaderUpdate.AncestryProof.FinalizedBlockRoot}}").into(), + }), + {{/HeaderUpdate.AncestryProof}} + {{^HeaderUpdate.AncestryProof}} + ancestry_proof: None, + {{/HeaderUpdate.AncestryProof}} + execution_header: VersionedExecutionPayloadHeader::Deneb(deneb::ExecutionPayloadHeader { + parent_hash: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.ParentHash}}").into(), + fee_recipient: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.FeeRecipient}}").into(), + state_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.StateRoot}}").into(), + receipts_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.ReceiptsRoot}}").into(), + logs_bloom: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.LogsBloom}}").into(), + prev_randao: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.PrevRandao}}").into(), + block_number: {{HeaderUpdate.ExecutionHeader.Deneb.BlockNumber}}, + gas_limit: {{HeaderUpdate.ExecutionHeader.Deneb.GasLimit}}, + gas_used: {{HeaderUpdate.ExecutionHeader.Deneb.GasUsed}}, + timestamp: {{HeaderUpdate.ExecutionHeader.Deneb.Timestamp}}, + extra_data: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.ExtraData}}").into(), + base_fee_per_gas: U256::from({{HeaderUpdate.ExecutionHeader.Deneb.BaseFeePerGas}}u64), + block_hash: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.BlockHash}}").into(), + transactions_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.TransactionsRoot}}").into(), + withdrawals_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.WithdrawalsRoot}}").into(), + blob_gas_used: {{HeaderUpdate.ExecutionHeader.Deneb.BlobGasUsed}}, + excess_blob_gas: {{HeaderUpdate.ExecutionHeader.Deneb.ExcessBlobGas}}, + }), + execution_branch: vec![ + {{#HeaderUpdate.ExecutionBranch}} + hex!("{{.}}").into(), + {{/HeaderUpdate.ExecutionBranch}} + ], + } + }, + }, + finalized_header: BeaconHeader { + slot: {{FinalizedHeaderUpdate.FinalizedHeader.Slot}}, + proposer_index: {{FinalizedHeaderUpdate.FinalizedHeader.ProposerIndex}}, + parent_root: hex!("{{FinalizedHeaderUpdate.FinalizedHeader.ParentRoot}}").into(), + state_root: hex!("{{FinalizedHeaderUpdate.FinalizedHeader.StateRoot}}").into(), + body_root: hex!("{{FinalizedHeaderUpdate.FinalizedHeader.BodyRoot}}").into(), + }, + block_roots_root: hex!("{{FinalizedHeaderUpdate.BlockRootsRoot}}").into(), + } +} diff --git a/relayer/templates/module-weight-template.hbs b/relayer/templates/module-weight-template.hbs new file mode 100644 index 0000000000..5919a7cc7c --- /dev/null +++ b/relayer/templates/module-weight-template.hbs @@ -0,0 +1,74 @@ +{{header}} +//! Autogenerated weights for `{{pallet}}` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION {{version}} +//! DATE: {{date}}, STEPS: `{{cmd.steps}}`, REPEAT: `{{cmd.repeat}}`, LOW RANGE: `{{cmd.lowest_range_values}}`, HIGH RANGE: `{{cmd.highest_range_values}}` +//! WORST CASE MAP SIZE: `{{cmd.worst_case_map_values}}` +//! HOSTNAME: `{{hostname}}`, CPU: `{{cpuname}}` +//! WASM-EXECUTION: `{{cmd.wasm_execution}}`, CHAIN: `{{cmd.chain}}`, DB CACHE: `{{cmd.db_cache}}` + +// Executed Command: +{{#each args as |arg|}} +// {{arg}} +{{/each}} + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weight functions needed for `{{pallet}}`. +pub trait WeightInfo { + {{#each benchmarks as |benchmark|}} + fn {{benchmark.name~}} + ( + {{~#each benchmark.components as |c| ~}} + {{c.name}}: u32, {{/each~}} + ) -> Weight; + {{/each}} +} + +// For backwards compatibility and tests. +impl WeightInfo for () { + {{#each benchmarks as |benchmark|}} + {{#each benchmark.comments as |comment|}} + /// {{comment}} + {{/each}} + {{#each benchmark.component_ranges as |range|}} + /// The range of component `{{range.name}}` is `[{{range.min}}, {{range.max}}]`. + {{/each}} + fn {{benchmark.name~}} + ( + {{~#each benchmark.components as |c| ~}} + {{~#if (not c.is_used)}}_{{/if}}{{c.name}}: u32, {{/each~}} + ) -> Weight { + // Proof Size summary in bytes: + // Measured: `{{benchmark.base_recorded_proof_size}}{{#each benchmark.component_recorded_proof_size as |cp|}} + {{cp.name}} * ({{cp.slope}} ±{{underscore cp.error}}){{/each}}` + // Estimated: `{{benchmark.base_calculated_proof_size}}{{#each benchmark.component_calculated_proof_size as |cp|}} + {{cp.name}} * ({{cp.slope}} ±{{underscore cp.error}}){{/each}}` + // Minimum execution time: {{underscore benchmark.min_execution_time}}_000 picoseconds. + Weight::from_parts({{underscore benchmark.base_weight}}, {{benchmark.base_calculated_proof_size}}) + {{#each benchmark.component_weight as |cw|}} + // Standard Error: {{underscore cw.error}} + .saturating_add(Weight::from_parts({{underscore cw.slope}}, 0).saturating_mul({{cw.name}}.into())) + {{/each}} + {{#if (ne benchmark.base_reads "0")}} + .saturating_add(RocksDbWeight::get().reads({{benchmark.base_reads}}_u64)) + {{/if}} + {{#each benchmark.component_reads as |cr|}} + .saturating_add(RocksDbWeight::get().reads(({{cr.slope}}_u64).saturating_mul({{cr.name}}.into()))) + {{/each}} + {{#if (ne benchmark.base_writes "0")}} + .saturating_add(RocksDbWeight::get().writes({{benchmark.base_writes}}_u64)) + {{/if}} + {{#each benchmark.component_writes as |cw|}} + .saturating_add(RocksDbWeight::get().writes(({{cw.slope}}_u64).saturating_mul({{cw.name}}.into()))) + {{/each}} + {{#each benchmark.component_calculated_proof_size as |cp|}} + .saturating_add(Weight::from_parts(0, {{cp.slope}}).saturating_mul({{cp.name}}.into())) + {{/each}} + } + {{/each}} +} diff --git a/web/packages/test/config/beacon-relay.json b/web/packages/test/config/beacon-relay.json index 73534b66f6..e8b6d40c00 100644 --- a/web/packages/test/config/beacon-relay.json +++ b/web/packages/test/config/beacon-relay.json @@ -7,7 +7,10 @@ "syncCommitteeSize": 512, "slotsInEpoch": 32, "epochsPerSyncCommitteePeriod": 256, - "denebForkedEpoch": 0 + "forkVersions": { + "deneb": 0, + "electra": 2000000 + } }, "datastore": { "location": "/tmp/snowbridge/beaconstore", diff --git a/web/packages/test/config/execution-relay.json b/web/packages/test/config/execution-relay.json index ca40fdeaab..27737b4d7f 100644 --- a/web/packages/test/config/execution-relay.json +++ b/web/packages/test/config/execution-relay.json @@ -14,7 +14,10 @@ "syncCommitteeSize": 512, "slotsInEpoch": 32, "epochsPerSyncCommitteePeriod": 256, - "denebForkedEpoch": 0 + "forkVersions": { + "deneb": 0, + "electra": 2000000 + } }, "datastore": { "location": "/tmp/snowbridge/beaconstore", diff --git a/web/packages/test/config/genesis-electra.json b/web/packages/test/config/genesis-electra.json new file mode 100644 index 0000000000..a0fdd654b6 --- /dev/null +++ b/web/packages/test/config/genesis-electra.json @@ -0,0 +1,62 @@ +{ + "config": { + "chainId": 11155111, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "ethash": {}, + "terminalTotalDifficulty": 0, + "ShanghaiTime": 0, + "CancunTime": 0, + "PragueTime": 0, + "terminalTotalDifficultyPassed": true + }, + "difficulty": "0x9FFE0", + "gasLimit": "80000000", + "alloc": { + "90A987B944Cb1dCcE5564e5FDeCD7a54D3de27Fe": { + "balance": "10000000000000000000000" + }, + "Be68fC2d8249eb60bfCf0e71D5A0d2F2e292c4eD": { + "balance": "100000000000000000000" + }, + "89b4AB1eF20763630df9743ACF155865600daFF2": { + "balance": "100000000000000000000" + }, + "04E00e6D2e9Ea1E2AF553De02A5172120BFA5c3e": { + "balance": "100000000000000000000" + }, + "a255dC78C1510e2c1332fBAC2de848058f479CEE": { + "balance": "100000000000000000000" + }, + "ACbd24742b87c34dED607FB87b22401B2Ede167E": { + "balance": "100000000000000000000" + }, + "01F6749035e02205768f97e6f1d394Fb6769EC20": { + "balance": "100000000000000000000" + }, + "8b66D5499F52D6F1857084A61743dFCB9a712859": { + "balance": "100000000000000000000" + }, + "13e16C4e5787f878f98a610EB321170512b134D4": { + "balance": "100000000000000000000" + }, + "eEBFA6B9242A19f91a0463291A937a20e3355681": { + "balance": "100000000000000000000" + }, + "87D987206180B8f3807Dd90455606eEa85cdB87a": { + "balance": "100000000000000000000" + }, + "0xACbd24742b87c34dED607FB87b22401B2Ede167E": { + "balance": "100000000000000000000" + } + } +} diff --git a/web/packages/test/config/genesis.json b/web/packages/test/config/genesis.json index e90d106d2a..dd2e4fbfdb 100644 --- a/web/packages/test/config/genesis.json +++ b/web/packages/test/config/genesis.json @@ -15,7 +15,7 @@ "ethash": {}, "terminalTotalDifficulty": 0, "ShanghaiTime": 0, - "CancunTime": null, + "CancunTime": 0, "terminalTotalDifficultyPassed": true }, "difficulty": "0x9FFE0", diff --git a/web/packages/test/scripts/configure-substrate.sh b/web/packages/test/scripts/configure-substrate.sh index 582006fe8d..3af185abcb 100755 --- a/web/packages/test/scripts/configure-substrate.sh +++ b/web/packages/test/scripts/configure-substrate.sh @@ -5,8 +5,20 @@ source scripts/set-env.sh source scripts/xcm-helper.sh config_beacon_checkpoint() { + # Configure beacon relay + local electra_forked_epoch=2000000 + if [ "$is_electra" == "true" ]; then + electra_forked_epoch=0 + fi + jq \ + --argjson electra_forked_epoch $electra_forked_epoch \ + ' + .source.beacon.spec.forkVersions.electra = $electra_forked_epoch + ' \ + config/beacon-relay.json >$output_dir/beacon-relay.json + pushd $root_dir - local check_point_hex=$($relay_bin generate-beacon-checkpoint --config $config_dir/beacon-relay.json) + local check_point_hex=$($relay_bin generate-beacon-checkpoint --config $output_dir/beacon-relay.json) popd local transact_call="0x5200"$check_point_hex send_governance_transact_from_relaychain $BRIDGE_HUB_PARAID "$transact_call" 180000000000 900000 diff --git a/web/packages/test/scripts/electra-deploy-ethereum.sh b/web/packages/test/scripts/electra-deploy-ethereum.sh new file mode 100755 index 0000000000..c61e52b19b --- /dev/null +++ b/web/packages/test/scripts/electra-deploy-ethereum.sh @@ -0,0 +1,124 @@ +#!/usr/bin/env bash +set -eu + +source scripts/set-env.sh +export output_electra_dir="/tmp/electra" + +start_geth() { + rm -rf $output_electra_dir + mkdir -p $output_electra_dir + mkdir -p $output_electra_dir/ethereum + cp config/genesis-electra.json $output_electra_dir + cp config/jwtsecret $output_electra_dir + + echo "Starting geth local node" + docker run --rm \ + -v "${output_electra_dir}:/mnt" \ + docker.io/ethpandaops/geth:lightclient-prague-devnet-4 \ + --datadir /mnt/ethereum \ + --state.scheme=hash \ + init /mnt/genesis-electra.json + docker run --rm -m=12g --memory-reservation=8g --cpus 2 \ + -v "${output_electra_dir}:/mnt" \ + -p 8551:8551 \ + -p 8545:8545 \ + -p 8546:8546 \ + --env 'NODE_OPTIONS=--max-old-space-size=8192' \ + docker.io/ethpandaops/geth:lightclient-prague-devnet-4 \ + --networkid 11155111 \ + --vmdebug \ + --datadir /mnt/ethereum \ + --http \ + --http.api debug,personal,eth,net,web3,txpool,engine \ + --ws --ws.api debug,eth,net,web3 \ + --rpc.allow-unprotected-txs \ + --authrpc.addr 0.0.0.0 \ + --authrpc.vhosts "*" \ + --http \ + --http.api "debug,personal,eth,net,web3,txpool,engine,miner" \ + --http.addr 0.0.0.0 \ + --http.vhosts "*" \ + --http.corsdomain '*' \ + --ws \ + --ws.api "debug,eth,net,web3" \ + --ws.addr 0.0.0.0 \ + --ws.origins "*" \ + --allow-insecure-unlock \ + --authrpc.jwtsecret mnt/jwtsecret \ + --password /dev/null \ + --rpc.gascap 0 \ + --ws.origins "*" \ + --gcmode archive \ + --syncmode=full \ + --state.scheme=hash \ + > "$output_electra_dir/geth.log" 2>&1 & +} + +start_lodestar() { + echo "Starting lodestar local node" + local genesisHash=$(curl $eth_endpoint_http \ + -X POST \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc": "2.0", "id": "1", "method": "eth_getBlockByNumber","params": ["0x0", false]}' | jq -r '.result.hash') + echo "genesisHash is: $genesisHash" + # use gdate here for raw macos without nix + local timestamp="" + if [[ "$(uname)" == "Darwin" && -z "${IN_NIX_SHELL:-}" ]]; then + timestamp=$(gdate -d'+10second' +%s) + else + timestamp=$(date -d'+10second' +%s) + fi + + export LODESTAR_PRESET="mainnet" + + pushd $root_dir/lodestar + ./lodestar --version + ./lodestar dev \ + --genesisValidators 8 \ + --genesisTime $timestamp \ + --startValidators "0..7" \ + --enr.ip6 "127.0.0.1" \ + --rest.address "0.0.0.0" \ + --eth1.providerUrls "http://$HOST:8545" \ + --execution.urls "http://$HOST:8551" \ + --dataDir "$ethereum_data_dir" \ + --reset \ + --terminal-total-difficulty-override 0 \ + --genesisEth1Hash $genesisHash \ + --params.ALTAIR_FORK_EPOCH 0 \ + --params.BELLATRIX_FORK_EPOCH 0 \ + --params.CAPELLA_FORK_EPOCH 0 \ + --params.DENEB_FORK_EPOCH 0 \ + --params.ELECTRA_FORK_EPOCH 0 \ + --eth1=true \ + --rest.namespace="*" \ + --jwt-secret $config_dir/jwtsecret \ + --chain.archiveStateEpochFrequency 1 \ + >"$output_dir/lodestar.log" 2>&1 & + popd +} + +deploy_local() { + # 1. deploy execution client + echo "Starting execution node" + start_geth + + echo "Waiting for geth API to be ready" + sleep 10 + + # 2. deploy consensus client + echo "Starting beacon node" + start_lodestar +} + +deploy_ethereum() { + check_tool && rm -rf "$ethereum_data_dir" && deploy_local +} + +if [ -z "${from_start_services:-}" ]; then + echo "start ethereum only!" + trap kill_all SIGINT SIGTERM EXIT + deploy_ethereum + echo "ethereum local nodes started!" + wait +fi diff --git a/web/packages/test/scripts/electra-start-services.sh b/web/packages/test/scripts/electra-start-services.sh new file mode 100755 index 0000000000..794ee11fce --- /dev/null +++ b/web/packages/test/scripts/electra-start-services.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +set -eu + +start=$(date +%s) + +from_start_services=true + +is_electra=true + +source scripts/set-env.sh +source scripts/build-binary.sh + +trap kill_all SIGINT SIGTERM EXIT +cleanup + +# 0. check required tools +echo "Check building tools" +check_tool + +# 1. install binary if required +echo "Installing binaries if required" +install_binary + +# 2. start ethereum +echo "Starting ethereum nodes" +source scripts/electra-deploy-ethereum.sh +deploy_ethereum + +# 3. start polkadot +echo "Starting polkadot nodes" +source scripts/deploy-polkadot.sh +deploy_polkadot + +# 4. generate beefy checkpoint +echo "Generate beefy checkpoint" +source scripts/generate-beefy-checkpoint.sh +generate_beefy_checkpoint + +# 5. deploy contracts +echo "Deploying ethereum contracts" +source scripts/deploy-contracts.sh +deploy_contracts + +# 6. config substrate +echo "Config Substrate" +source scripts/configure-substrate.sh +configure_substrate + +if [ "$skip_relayer" == "false" ]; then + # 7. start relayer + echo "Starting relayers" + source scripts/start-relayer.sh + deploy_relayer +fi + +echo "Testnet has been initialized" + +end=$(date +%s) +runtime=$((end - start)) +minutes=$(((runtime % 3600) / 60)) +seconds=$(((runtime % 3600) % 60)) +echo "Took $minutes minutes $seconds seconds" + +wait diff --git a/web/packages/test/scripts/set-env.sh b/web/packages/test/scripts/set-env.sh index 1ab1d6c278..983e626eb1 100755 --- a/web/packages/test/scripts/set-env.sh +++ b/web/packages/test/scripts/set-env.sh @@ -12,10 +12,19 @@ zombienet_data_dir="$output_dir/zombienet" export PATH="$output_bin_dir:$PATH" export polkadot_sdk_dir="${POLKADOT_SDK_DIR:-../polkadot-sdk}" +if [ "$is_electra" == "true" ]; then + HOST=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1') + eth_endpoint_http="${ETH_RPC_ENDPOINT:-http://$HOST:8545}/${INFURA_PROJECT_ID:-}" + eth_endpoint_ws="${ETH_WS_ENDPOINT:-ws://$HOST:8546}/${INFURA_PROJECT_ID:-}" + eth_writer_endpoint="${ETH_WRITER_ENDPOINT:-http://$HOST:8545}/${INFURA_PROJECT_ID:-}" +else + eth_endpoint_http="${ETH_RPC_ENDPOINT:-http://127.0.0.1:8545}/${INFURA_PROJECT_ID:-}" + eth_endpoint_ws="${ETH_WS_ENDPOINT:-ws://127.0.0.1:8546}/${INFURA_PROJECT_ID:-}" + eth_writer_endpoint="${ETH_WRITER_ENDPOINT:-http://127.0.0.1:8545}/${INFURA_PROJECT_ID:-}" +fi + eth_network="${ETH_NETWORK:-localhost}" -eth_endpoint_http="${ETH_RPC_ENDPOINT:-http://127.0.0.1:8545}/${INFURA_PROJECT_ID:-}" -eth_endpoint_ws="${ETH_WS_ENDPOINT:-ws://127.0.0.1:8546}/${INFURA_PROJECT_ID:-}" -eth_writer_endpoint="${ETH_WRITER_ENDPOINT:-http://127.0.0.1:8545}/${INFURA_PROJECT_ID:-}" + eth_gas_limit="${ETH_GAS_LIMIT:-5000000}" eth_chain_id="${ETH_NETWORK_ID:-15}" eth_fast_mode="${ETH_FAST_MODE:-true}" diff --git a/web/packages/test/scripts/start-relayer.sh b/web/packages/test/scripts/start-relayer.sh index ce79007066..40accbdcf8 100755 --- a/web/packages/test/scripts/start-relayer.sh +++ b/web/packages/test/scripts/start-relayer.sh @@ -138,16 +138,16 @@ config_relayer() { config/parachain-relay.json >$output_dir/parachain-relay-penpal.json # Configure beacon relay - local deneb_forked_epoch=132608 - if [ "$eth_fast_mode" == "true" ]; then - deneb_forked_epoch=0 + local electra_forked_epoch=2000000 + if [ "$is_electra" == "true" ]; then + electra_forked_epoch=0 fi jq \ --arg beacon_endpoint_http $beacon_endpoint_http \ - --argjson deneb_forked_epoch $deneb_forked_epoch \ + --argjson electra_forked_epoch $electra_forked_epoch \ ' .source.beacon.endpoint = $beacon_endpoint_http - | .source.beacon.spec.denebForkedEpoch = $deneb_forked_epoch + | .source.beacon.spec.forkVersions.electra = $electra_forked_epoch ' \ config/beacon-relay.json >$output_dir/beacon-relay.json diff --git a/web/packages/test/scripts/start-services.sh b/web/packages/test/scripts/start-services.sh index fa0fff872e..b4663180cb 100755 --- a/web/packages/test/scripts/start-services.sh +++ b/web/packages/test/scripts/start-services.sh @@ -4,6 +4,7 @@ set -eu start=$(date +%s) from_start_services=true +is_electra=false source scripts/set-env.sh source scripts/build-binary.sh