Skip to content

Commit

Permalink
Add Badger hardfork: version.Badger, fork epoch/version (#72)
Browse files Browse the repository at this point in the history
* Remove aliased types like ExecutionPayloadDeneb

* Clean unused versioner struct

* Refactor UpgradeState

* Refactor TestCanUpgradeTo*

* Refactor state_trie.go

* Simplify fork related code: avoid switch because as new fork version is introduced, a developer has to add its fork

* Run gazelle

* Add version.Badger & BadgerForkEpoch/Version:
Before defining BeaconStateBadger and BeaconBlockBadger

* Add missing fork version/epoch

* Skipping the failing assertion: will be fixed in the next PR
  • Loading branch information
syjn99 authored Feb 4, 2025
1 parent 29b20c8 commit ec7d47c
Show file tree
Hide file tree
Showing 59 changed files with 489 additions and 495 deletions.
28 changes: 12 additions & 16 deletions api/server/structs/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ type BeaconBlockBodyElectra struct {
Attestations []*AttestationElectra `json:"attestations"`
Deposits []*Deposit `json:"deposits"`
VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits"`
ExecutionPayload *ExecutionPayloadElectra `json:"execution_payload"`
ExecutionPayload *ExecutionPayloadDeneb `json:"execution_payload"`
BlobKzgCommitments []string `json:"blob_kzg_commitments"`
ExecutionRequests *ExecutionRequests `json:"execution_requests"`
}
Expand Down Expand Up @@ -379,17 +379,17 @@ func (s *SignedBlindedBeaconBlockElectra) SigString() string {
}

type BlindedBeaconBlockBodyElectra struct {
RandaoReveal string `json:"randao_reveal"`
Eth1Data *Eth1Data `json:"eth1_data"`
Graffiti string `json:"graffiti"`
ProposerSlashings []*ProposerSlashing `json:"proposer_slashings"`
AttesterSlashings []*AttesterSlashingElectra `json:"attester_slashings"`
Attestations []*AttestationElectra `json:"attestations"`
Deposits []*Deposit `json:"deposits"`
VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits"`
ExecutionPayloadHeader *ExecutionPayloadHeaderElectra `json:"execution_payload_header"`
BlobKzgCommitments []string `json:"blob_kzg_commitments"`
ExecutionRequests *ExecutionRequests `json:"execution_requests"`
RandaoReveal string `json:"randao_reveal"`
Eth1Data *Eth1Data `json:"eth1_data"`
Graffiti string `json:"graffiti"`
ProposerSlashings []*ProposerSlashing `json:"proposer_slashings"`
AttesterSlashings []*AttesterSlashingElectra `json:"attester_slashings"`
Attestations []*AttestationElectra `json:"attestations"`
Deposits []*Deposit `json:"deposits"`
VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits"`
ExecutionPayloadHeader *ExecutionPayloadHeaderDeneb `json:"execution_payload_header"`
BlobKzgCommitments []string `json:"blob_kzg_commitments"`
ExecutionRequests *ExecutionRequests `json:"execution_requests"`
}

type SignedBeaconBlockHeaderContainer struct {
Expand Down Expand Up @@ -501,8 +501,6 @@ type ExecutionPayloadDeneb struct {
ExcessBlobGas string `json:"excess_blob_gas"`
}

type ExecutionPayloadElectra = ExecutionPayloadDeneb

type ExecutionPayloadHeaderDeneb struct {
ParentHash string `json:"parent_hash"`
FeeRecipient string `json:"fee_recipient"`
Expand All @@ -523,8 +521,6 @@ type ExecutionPayloadHeaderDeneb struct {
ExcessBlobGas string `json:"excess_blob_gas"`
}

type ExecutionPayloadHeaderElectra = ExecutionPayloadHeaderDeneb

type ExecutionRequests struct {
Deposits []*DepositRequest `json:"deposits"`
Withdrawals []*WithdrawalRequest `json:"withdrawals"`
Expand Down
4 changes: 2 additions & 2 deletions api/server/structs/conversions_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -2010,7 +2010,7 @@ func (b *BeaconBlockElectra) ToConsensus() (*eth.BeaconBlockElectra, error) {
Attestations: atts,
Deposits: deposits,
VoluntaryExits: exits,
ExecutionPayload: &enginev1.ExecutionPayloadElectra{
ExecutionPayload: &enginev1.ExecutionPayloadDeneb{
ParentHash: payloadParentHash,
FeeRecipient: payloadFeeRecipient,
StateRoot: payloadStateRoot,
Expand Down Expand Up @@ -2282,7 +2282,7 @@ func (b *BlindedBeaconBlockElectra) ToConsensus() (*eth.BlindedBeaconBlockElectr
Attestations: atts,
Deposits: deposits,
VoluntaryExits: exits,
ExecutionPayloadHeader: &enginev1.ExecutionPayloadHeaderElectra{
ExecutionPayloadHeader: &enginev1.ExecutionPayloadHeaderDeneb{
ParentHash: payloadParentHash,
FeeRecipient: payloadFeeRecipient,
StateRoot: payloadStateRoot,
Expand Down
64 changes: 32 additions & 32 deletions api/server/structs/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,36 +134,36 @@ type BeaconStateDeneb struct {
}

type BeaconStateElectra struct {
GenesisTime string `json:"genesis_time"`
GenesisValidatorsRoot string `json:"genesis_validators_root"`
Slot string `json:"slot"`
Fork *Fork `json:"fork"`
LatestBlockHeader *BeaconBlockHeader `json:"latest_block_header"`
BlockRoots []string `json:"block_roots"`
StateRoots []string `json:"state_roots"`
RewardAdjustmentFactor uint64 `json:"reward_adjustment_factor"`
Eth1Data *Eth1Data `json:"eth1_data"`
Eth1DataVotes []*Eth1Data `json:"eth1_data_votes"`
Eth1DepositIndex string `json:"eth1_deposit_index"`
Validators []*Validator `json:"validators"`
Balances []string `json:"balances"`
Reserves uint64 `json:"reserves"`
RandaoMixes []string `json:"randao_mixes"`
PreviousEpochParticipation []string `json:"previous_epoch_participation"`
CurrentEpochParticipation []string `json:"current_epoch_participation"`
JustificationBits string `json:"justification_bits"`
PreviousJustifiedCheckpoint *Checkpoint `json:"previous_justified_checkpoint"`
CurrentJustifiedCheckpoint *Checkpoint `json:"current_justified_checkpoint"`
FinalizedCheckpoint *Checkpoint `json:"finalized_checkpoint"`
InactivityScores []string `json:"inactivity_scores"`
LatestExecutionPayloadHeader *ExecutionPayloadHeaderElectra `json:"latest_execution_payload_header"`
NextWithdrawalIndex string `json:"next_withdrawal_index"`
NextWithdrawalValidatorIndex string `json:"next_withdrawal_validator_index"`
HistoricalSummaries []*HistoricalSummary `json:"historical_summaries"`
DepositRequestsStartIndex string `json:"deposit_requests_start_index"`
DepositBalanceToConsume string `json:"deposit_balance_to_consume"`
ExitBalanceToConsume string `json:"exit_balance_to_consume"`
EarliestExitEpoch string `json:"earliest_exit_epoch"`
PendingDeposits []*PendingDeposit `json:"pending_deposits"`
PendingPartialWithdrawals []*PendingPartialWithdrawal `json:"pending_partial_withdrawals"`
GenesisTime string `json:"genesis_time"`
GenesisValidatorsRoot string `json:"genesis_validators_root"`
Slot string `json:"slot"`
Fork *Fork `json:"fork"`
LatestBlockHeader *BeaconBlockHeader `json:"latest_block_header"`
BlockRoots []string `json:"block_roots"`
StateRoots []string `json:"state_roots"`
RewardAdjustmentFactor uint64 `json:"reward_adjustment_factor"`
Eth1Data *Eth1Data `json:"eth1_data"`
Eth1DataVotes []*Eth1Data `json:"eth1_data_votes"`
Eth1DepositIndex string `json:"eth1_deposit_index"`
Validators []*Validator `json:"validators"`
Balances []string `json:"balances"`
Reserves uint64 `json:"reserves"`
RandaoMixes []string `json:"randao_mixes"`
PreviousEpochParticipation []string `json:"previous_epoch_participation"`
CurrentEpochParticipation []string `json:"current_epoch_participation"`
JustificationBits string `json:"justification_bits"`
PreviousJustifiedCheckpoint *Checkpoint `json:"previous_justified_checkpoint"`
CurrentJustifiedCheckpoint *Checkpoint `json:"current_justified_checkpoint"`
FinalizedCheckpoint *Checkpoint `json:"finalized_checkpoint"`
InactivityScores []string `json:"inactivity_scores"`
LatestExecutionPayloadHeader *ExecutionPayloadHeaderDeneb `json:"latest_execution_payload_header"`
NextWithdrawalIndex string `json:"next_withdrawal_index"`
NextWithdrawalValidatorIndex string `json:"next_withdrawal_validator_index"`
HistoricalSummaries []*HistoricalSummary `json:"historical_summaries"`
DepositRequestsStartIndex string `json:"deposit_requests_start_index"`
DepositBalanceToConsume string `json:"deposit_balance_to_consume"`
ExitBalanceToConsume string `json:"exit_balance_to_consume"`
EarliestExitEpoch string `json:"earliest_exit_epoch"`
PendingDeposits []*PendingDeposit `json:"pending_deposits"`
PendingPartialWithdrawals []*PendingPartialWithdrawal `json:"pending_partial_withdrawals"`
}
34 changes: 22 additions & 12 deletions beacon-chain/blockchain/execution_engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,15 +362,16 @@ func (s *Service) getPayloadAttribute(ctx context.Context, st state.BeaconState,
return emptyAttri
}

var attr payloadattribute.Attributer
switch st.Version() {
case version.Deneb, version.Alpaca:
v := st.Version()

if v >= version.Deneb {
withdrawals, _, _, err := st.ExpectedWithdrawals()
if err != nil {
log.WithError(err).Error("Could not get expected withdrawals to get payload attribute")
return emptyAttri
}
attr, err = payloadattribute.New(&enginev1.PayloadAttributesV3{

attr, err := payloadattribute.New(&enginev1.PayloadAttributesV3{
Timestamp: uint64(t.Unix()),
PrevRandao: prevRando,
SuggestedFeeRecipient: val.FeeRecipient[:],
Expand All @@ -381,13 +382,18 @@ func (s *Service) getPayloadAttribute(ctx context.Context, st state.BeaconState,
log.WithError(err).Error("Could not get payload attribute")
return emptyAttri
}
case version.Capella:

return attr
}

if v >= version.Capella {
withdrawals, _, _, err := st.ExpectedWithdrawals()
if err != nil {
log.WithError(err).Error("Could not get expected withdrawals to get payload attribute")
return emptyAttri
}
attr, err = payloadattribute.New(&enginev1.PayloadAttributesV2{

attr, err := payloadattribute.New(&enginev1.PayloadAttributesV2{
Timestamp: uint64(t.Unix()),
PrevRandao: prevRando,
SuggestedFeeRecipient: val.FeeRecipient[:],
Expand All @@ -397,8 +403,12 @@ func (s *Service) getPayloadAttribute(ctx context.Context, st state.BeaconState,
log.WithError(err).Error("Could not get payload attribute")
return emptyAttri
}
case version.Bellatrix:
attr, err = payloadattribute.New(&enginev1.PayloadAttributes{

return attr
}

if v >= version.Bellatrix {
attr, err := payloadattribute.New(&enginev1.PayloadAttributes{
Timestamp: uint64(t.Unix()),
PrevRandao: prevRando,
SuggestedFeeRecipient: val.FeeRecipient[:],
Expand All @@ -407,12 +417,12 @@ func (s *Service) getPayloadAttribute(ctx context.Context, st state.BeaconState,
log.WithError(err).Error("Could not get payload attribute")
return emptyAttri
}
default:
log.WithField("version", st.Version()).Error("Could not get payload attribute due to unknown state version")
return emptyAttri

return attr
}

return attr
log.WithField("version", version.String(st.Version())).Error("Could not get payload attribute due to unknown state version")
return emptyAttri
}

// removeInvalidBlockAndState removes the invalid block, blob and its corresponding state from the cache and DB.
Expand Down
2 changes: 1 addition & 1 deletion beacon-chain/core/blocks/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ func NewGenesisBlockForState(ctx context.Context, st state.BeaconState) (interfa
BlockHash: make([]byte, 32),
},
Graffiti: make([]byte, 32),
ExecutionPayload: &enginev1.ExecutionPayloadElectra{
ExecutionPayload: &enginev1.ExecutionPayloadDeneb{
ParentHash: make([]byte, 32),
FeeRecipient: make([]byte, 20),
StateRoot: make([]byte, 32),
Expand Down
2 changes: 1 addition & 1 deletion beacon-chain/core/blocks/withdrawals_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -903,7 +903,7 @@ func TestProcessWithdrawals(t *testing.T) {
}
st, err = state_native.InitializeFromProtoUnsafeElectra(spb)
require.NoError(t, err)
p, err = consensusblocks.WrappedExecutionPayloadElectra(&enginev1.ExecutionPayloadElectra{Withdrawals: test.Args.Withdrawals})
p, err = consensusblocks.WrappedExecutionPayloadDeneb(&enginev1.ExecutionPayloadDeneb{Withdrawals: test.Args.Withdrawals})
require.NoError(t, err)
default:
t.Fatalf("Add a beacon state setup for version %s", version.String(fork))
Expand Down
2 changes: 1 addition & 1 deletion beacon-chain/core/electra/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ func UpgradeToElectra(beaconState state.BeaconState) (state.BeaconState, error)
CurrentJustifiedCheckpoint: beaconState.CurrentJustifiedCheckpoint(),
FinalizedCheckpoint: beaconState.FinalizedCheckpoint(),
InactivityScores: inactivityScores,
LatestExecutionPayloadHeader: &enginev1.ExecutionPayloadHeaderElectra{
LatestExecutionPayloadHeader: &enginev1.ExecutionPayloadHeaderDeneb{
ParentHash: payloadHeader.ParentHash(),
FeeRecipient: payloadHeader.FeeRecipient(),
StateRoot: payloadHeader.StateRoot(),
Expand Down
4 changes: 2 additions & 2 deletions beacon-chain/core/electra/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func TestUpgradeToElectra(t *testing.T) {

header, err := mSt.LatestExecutionPayloadHeader()
require.NoError(t, err)
protoHeader, ok := header.Proto().(*enginev1.ExecutionPayloadHeaderElectra)
protoHeader, ok := header.Proto().(*enginev1.ExecutionPayloadHeaderDeneb)
require.Equal(t, true, ok)
prevHeader, err := preForkState.LatestExecutionPayloadHeader()
require.NoError(t, err)
Expand All @@ -88,7 +88,7 @@ func TestUpgradeToElectra(t *testing.T) {

wdRoot, err := prevHeader.WithdrawalsRoot()
require.NoError(t, err)
wanted := &enginev1.ExecutionPayloadHeaderElectra{
wanted := &enginev1.ExecutionPayloadHeaderDeneb{
ParentHash: prevHeader.ParentHash(),
FeeRecipient: prevHeader.FeeRecipient(),
StateRoot: prevHeader.StateRoot(),
Expand Down
9 changes: 9 additions & 0 deletions beacon-chain/core/time/slot_epoch.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@ func CanUpgradeToElectra(slot primitives.Slot) bool {
return epochStart && electraEpoch
}

// CanUpgradeToBadger returns true if the input `slot` can upgrade to Badger.
// Spec code:
// If state.slot % SLOTS_PER_EPOCH == 0 and compute_epoch_at_slot(state.slot) == BADGER_FORK_EPOCH
func CanUpgradeToBadger(slot primitives.Slot) bool {
epochStart := slots.IsEpochStart(slot)
badgerEpoch := slots.ToEpoch(slot) == params.BeaconConfig().BadgerForkEpoch
return epochStart && badgerEpoch
}

// CanProcessEpoch checks the eligibility to process epoch.
// The epoch can be processed at the end of the last slot of every epoch.
//
Expand Down
Loading

0 comments on commit ec7d47c

Please sign in to comment.