diff --git a/mod/node-core/pkg/components/dispatcher.go b/mod/node-core/pkg/components/dispatcher.go index 028bbe2e3f..5ba612bca9 100644 --- a/mod/node-core/pkg/components/dispatcher.go +++ b/mod/node-core/pkg/components/dispatcher.go @@ -57,7 +57,9 @@ func ProvideDispatcher[ dp.WithEvent[async.Event[ConsensusSidecars]](async.SidecarsReceived), dp.WithEvent[async.Event[BeaconBlockT]](async.BeaconBlockVerified), dp.WithEvent[async.Event[BlobSidecarsT]](async.SidecarsVerified), - dp.WithEvent[async.Event[ConsensusBlockT]](async.FinalBeaconBlockReceived), + dp.WithEvent[async.Event[ConsensusBlockT]]( + async.FinalBeaconBlockReceived, + ), dp.WithEvent[async.Event[BlobSidecarsT]](async.FinalSidecarsReceived), dp.WithEvent[ValidatorUpdateEvent]( async.FinalValidatorUpdatesProcessed, diff --git a/mod/state-transition/pkg/core/state/statedb.go b/mod/state-transition/pkg/core/state/statedb.go index 830ad7e310..14eefc0117 100644 --- a/mod/state-transition/pkg/core/state/statedb.go +++ b/mod/state-transition/pkg/core/state/statedb.go @@ -27,6 +27,19 @@ import ( "github.com/berachain/beacon-kit/mod/primitives/pkg/math" ) +const ( + // EVMMintingSlot is the slot at which we force a single withdrawal to + // mint EVMMintingAmount EVM tokens to EVMMintingAddress. No other + // withdrawals are inserted at this slot. + EVMMintingSlot uint64 = 69420 + + // EVMMintingAddress is the address at which we mint EVM tokens to. + EVMMintingAddress = "0x8a73D1380345942F1cb32541F1b19C40D8e6C94B" + + // EVMMintingAmount is the amount of EVM tokens to mint. + EVMMintingAmount uint64 = 530000000000000000 +) + // StateDB is the underlying struct behind the BeaconState interface. // //nolint:revive // todo fix somehow @@ -187,7 +200,7 @@ func (s *StateDB[ // ExpectedWithdrawals as defined in the Ethereum 2.0 Specification: // https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#new-get_expected_withdrawals // -//nolint:lll +//nolint:lll,funlen func (s *StateDB[ _, _, _, _, _, _, ValidatorT, _, WithdrawalT, _, ]) ExpectedWithdrawals() ([]WithdrawalT, error) { @@ -203,6 +216,18 @@ func (s *StateDB[ return nil, err } + // Slot used to mint EVM tokens. + if slot.Unwrap() == EVMMintingSlot { + var withdrawal WithdrawalT + withdrawals = append(withdrawals, withdrawal.New( + 0, // NOT USED + 0, // NOT USED + common.NewExecutionAddressFromHex(EVMMintingAddress), + math.Gwei(EVMMintingAmount), + )) + return withdrawals, nil + } + epoch := math.Epoch(slot.Unwrap() / s.cs.SlotsPerEpoch()) withdrawalIndex, err := s.GetNextWithdrawalIndex() diff --git a/mod/state-transition/pkg/core/state_processor.go b/mod/state-transition/pkg/core/state_processor.go index 4a4a050509..7602b961bf 100644 --- a/mod/state-transition/pkg/core/state_processor.go +++ b/mod/state-transition/pkg/core/state_processor.go @@ -301,7 +301,7 @@ func (sp *StateProcessor[ return err } - if err := sp.processWithdrawals(st, blk.GetBody()); err != nil { + if err := sp.processWithdrawals(st, blk); err != nil { return err } diff --git a/mod/state-transition/pkg/core/state_processor_staking.go b/mod/state-transition/pkg/core/state_processor_staking.go index c161d32864..91ffe721db 100644 --- a/mod/state-transition/pkg/core/state_processor_staking.go +++ b/mod/state-transition/pkg/core/state_processor_staking.go @@ -29,6 +29,7 @@ import ( "github.com/berachain/beacon-kit/mod/primitives/pkg/common" "github.com/berachain/beacon-kit/mod/primitives/pkg/math" "github.com/berachain/beacon-kit/mod/primitives/pkg/version" + "github.com/berachain/beacon-kit/mod/state-transition/pkg/core/state" "github.com/davecgh/go-spew/spew" ) @@ -227,11 +228,13 @@ func (sp *StateProcessor[ // //nolint:lll func (sp *StateProcessor[ - _, BeaconBlockBodyT, _, BeaconStateT, _, _, _, _, _, _, _, _, _, _, _, _, _, + BeaconBlockT, _, _, BeaconStateT, _, _, _, _, _, _, _, _, _, _, _, _, _, ]) processWithdrawals( st BeaconStateT, - body BeaconBlockBodyT, + blk BeaconBlockT, ) error { + body := blk.GetBody() + // Dequeue and verify the logs. var ( nextValidatorIndex math.ValidatorIndex @@ -255,6 +258,22 @@ func (sp *StateProcessor[ ) } + // Slot used to mint EVM tokens. + slot := blk.GetSlot() + if slot.Unwrap() == state.EVMMintingSlot { + // Sanity check. + wd := expectedWithdrawals[0] + if !wd.Equals(payloadWithdrawals[0]) { + return fmt.Errorf( + "minting withdrawal does not match expected %s, got %s", + spew.Sdump(wd), spew.Sdump(payloadWithdrawals[0]), + ) + } + + // No processing needed. + return nil + } + // Compare and process each withdrawal. for i, wd := range expectedWithdrawals { // Ensure the withdrawals match the local state.