mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
skip eth1data voting after electra (#14835)
* wip skip eth1data voting after electra * updating technique * adding fix for electra eth1 voting * fixing linting on test * seeing if reversing genesis state fixes problem * increasing safety of legacy check * review feedback * forgot to fix tests * nishant's feedback * nishant's feedback * rename function a little * Update beacon-chain/core/helpers/legacy.go Co-authored-by: Jun Song <87601811+syjn99@users.noreply.github.com> * fixing naming --------- Co-authored-by: Jun Song <87601811+syjn99@users.noreply.github.com>
This commit is contained in:
@@ -7,6 +7,7 @@ go_library(
|
||||
"beacon_committee.go",
|
||||
"block.go",
|
||||
"genesis.go",
|
||||
"legacy.go",
|
||||
"metrics.go",
|
||||
"randao.go",
|
||||
"rewards_penalties.go",
|
||||
@@ -52,6 +53,7 @@ go_test(
|
||||
"attestation_test.go",
|
||||
"beacon_committee_test.go",
|
||||
"block_test.go",
|
||||
"legacy_test.go",
|
||||
"private_access_fuzz_noop_test.go", # keep
|
||||
"private_access_test.go",
|
||||
"randao_test.go",
|
||||
@@ -86,5 +88,6 @@ go_test(
|
||||
"//time:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
||||
"@com_github_stretchr_testify//require:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
20
beacon-chain/core/helpers/legacy.go
Normal file
20
beacon-chain/core/helpers/legacy.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v5/runtime/version"
|
||||
)
|
||||
|
||||
// DepositRequestsStarted determines if the deposit requests have started.
|
||||
func DepositRequestsStarted(beaconState state.BeaconState) bool {
|
||||
if beaconState.Version() < version.Electra {
|
||||
return false
|
||||
}
|
||||
|
||||
requestsStartIndex, err := beaconState.DepositRequestsStartIndex()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return beaconState.Eth1DepositIndex() == requestsStartIndex
|
||||
}
|
||||
33
beacon-chain/core/helpers/legacy_test.go
Normal file
33
beacon-chain/core/helpers/legacy_test.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package helpers_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/util"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestDepositRequestHaveStarted contains several test cases for depositRequestHaveStarted.
|
||||
func TestDepositRequestHaveStarted(t *testing.T) {
|
||||
t.Run("Version below Electra returns false", func(t *testing.T) {
|
||||
st, _ := util.DeterministicGenesisStateBellatrix(t, 1)
|
||||
result := helpers.DepositRequestsStarted(st)
|
||||
require.False(t, result)
|
||||
})
|
||||
|
||||
t.Run("Version is Electra or higher, no error, but Eth1DepositIndex != requestsStartIndex returns false", func(t *testing.T) {
|
||||
st, _ := util.DeterministicGenesisStateElectra(t, 1)
|
||||
require.NoError(t, st.SetEth1DepositIndex(1))
|
||||
result := helpers.DepositRequestsStarted(st)
|
||||
require.False(t, result)
|
||||
})
|
||||
|
||||
t.Run("Version is Electra or higher, no error, and Eth1DepositIndex == requestsStartIndex returns true", func(t *testing.T) {
|
||||
st, _ := util.DeterministicGenesisStateElectra(t, 1)
|
||||
require.NoError(t, st.SetEth1DepositIndex(33))
|
||||
require.NoError(t, st.SetDepositRequestsStartIndex(33))
|
||||
result := helpers.DepositRequestsStarted(st)
|
||||
require.True(t, result)
|
||||
})
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/cache"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
@@ -71,6 +72,10 @@ func (vs *Server) packDepositsAndAttestations(
|
||||
// this eth1data has enough support to be considered for deposits inclusion. If current vote has
|
||||
// enough support, then use that vote for basis of determining deposits, otherwise use current state
|
||||
// eth1data.
|
||||
// In the post-electra phase, this function will usually return an empty list,
|
||||
// as the legacy deposit process is deprecated. (EIP-6110)
|
||||
// NOTE: During the transition period, the legacy deposit process
|
||||
// may still be active and managed. This function handles that scenario.
|
||||
func (vs *Server) deposits(
|
||||
ctx context.Context,
|
||||
beaconState state.BeaconState,
|
||||
@@ -87,6 +92,12 @@ func (vs *Server) deposits(
|
||||
log.Warn("not connected to eth1 node, skip pending deposit insertion")
|
||||
return []*ethpb.Deposit{}, nil
|
||||
}
|
||||
|
||||
// skip legacy deposits if eth1 deposit index is already at the index of deposit requests start
|
||||
if helpers.DepositRequestsStarted(beaconState) {
|
||||
return []*ethpb.Deposit{}, nil
|
||||
}
|
||||
|
||||
// Need to fetch if the deposits up to the state's latest eth1 data matches
|
||||
// the number of all deposits in this RPC call. If not, then we return nil.
|
||||
canonicalEth1Data, canonicalEth1DataHeight, err := vs.canonicalEth1Data(ctx, beaconState, currentVote)
|
||||
@@ -94,14 +105,6 @@ func (vs *Server) deposits(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// In the post-electra phase, this function will usually return an empty list,
|
||||
// as the legacy deposit process is deprecated. (EIP-6110)
|
||||
// NOTE: During the transition period, the legacy deposit process
|
||||
// may still be active and managed. This function handles that scenario.
|
||||
if !isLegacyDepositProcessPeriod(beaconState, canonicalEth1Data) {
|
||||
return []*ethpb.Deposit{}, nil
|
||||
}
|
||||
|
||||
_, genesisEth1Block := vs.Eth1InfoFetcher.GenesisExecutionChainInfo()
|
||||
if genesisEth1Block.Cmp(canonicalEth1DataHeight) == 0 {
|
||||
return []*ethpb.Deposit{}, nil
|
||||
@@ -285,21 +288,3 @@ func shouldRebuildTrie(totalDepCount, unFinalizedDeps uint64) bool {
|
||||
unFinalizedCompute := unFinalizedDeps * params.BeaconConfig().DepositContractTreeDepth
|
||||
return unFinalizedCompute > totalDepCount
|
||||
}
|
||||
|
||||
// isLegacyDepositProcessPeriod determines if the current state should use the legacy deposit process.
|
||||
func isLegacyDepositProcessPeriod(beaconState state.BeaconState, canonicalEth1Data *ethpb.Eth1Data) bool {
|
||||
// Before the Electra upgrade, always use the legacy deposit process.
|
||||
if beaconState.Version() < version.Electra {
|
||||
return true
|
||||
}
|
||||
|
||||
// Handle the transition period between the legacy and the new deposit process.
|
||||
requestsStartIndex, err := beaconState.DepositRequestsStartIndex()
|
||||
if err != nil {
|
||||
// If we can't get the deposit requests start index,
|
||||
// we should default to the legacy deposit process.
|
||||
return true
|
||||
}
|
||||
eth1DepositIndexLimit := math.Min(canonicalEth1Data.DepositCount, requestsStartIndex)
|
||||
return beaconState.Eth1DepositIndex() < eth1DepositIndexLimit
|
||||
}
|
||||
|
||||
@@ -2,14 +2,12 @@ package validator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
mock "github.com/prysmaticlabs/prysm/v5/beacon-chain/blockchain/testing"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/cache/depositsnapshot"
|
||||
mockExecution "github.com/prysmaticlabs/prysm/v5/beacon-chain/execution/testing"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/container/trie"
|
||||
@@ -214,85 +212,3 @@ func TestProposer_PendingDeposits_Electra(t *testing.T) {
|
||||
assert.Equal(t, 0, len(deposits), "Received unexpected number of pending deposits")
|
||||
|
||||
}
|
||||
|
||||
func TestIsLegacyDepositProcessPeriod(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
state state.BeaconState
|
||||
canonicalEth1Data *ethpb.Eth1Data
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "pre-electra",
|
||||
state: func() state.BeaconState {
|
||||
st, err := state_native.InitializeFromProtoDeneb(ðpb.BeaconStateDeneb{
|
||||
Eth1Data: ðpb.Eth1Data{
|
||||
BlockHash: []byte("0x0"),
|
||||
DepositRoot: make([]byte, 32),
|
||||
DepositCount: 5,
|
||||
},
|
||||
Eth1DepositIndex: 1,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
return st
|
||||
}(),
|
||||
canonicalEth1Data: ðpb.Eth1Data{
|
||||
BlockHash: []byte("0x0"),
|
||||
DepositRoot: make([]byte, 32),
|
||||
DepositCount: 5,
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "post-electra, pending deposits from pre-electra",
|
||||
state: func() state.BeaconState {
|
||||
st, err := state_native.InitializeFromProtoElectra(ðpb.BeaconStateElectra{
|
||||
Eth1Data: ðpb.Eth1Data{
|
||||
BlockHash: []byte("0x0"),
|
||||
DepositRoot: make([]byte, 32),
|
||||
DepositCount: 5,
|
||||
},
|
||||
DepositRequestsStartIndex: math.MaxUint64,
|
||||
Eth1DepositIndex: 1,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
return st
|
||||
}(),
|
||||
canonicalEth1Data: ðpb.Eth1Data{
|
||||
BlockHash: []byte("0x0"),
|
||||
DepositRoot: make([]byte, 32),
|
||||
DepositCount: 5,
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "post-electra, no pending deposits from pre-alpaca",
|
||||
state: func() state.BeaconState {
|
||||
st, err := state_native.InitializeFromProtoElectra(ðpb.BeaconStateElectra{
|
||||
Eth1Data: ðpb.Eth1Data{
|
||||
BlockHash: []byte("0x0"),
|
||||
DepositRoot: make([]byte, 32),
|
||||
DepositCount: 5,
|
||||
},
|
||||
DepositRequestsStartIndex: 1,
|
||||
Eth1DepositIndex: 5,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
return st
|
||||
}(),
|
||||
canonicalEth1Data: ðpb.Eth1Data{
|
||||
BlockHash: []byte("0x0"),
|
||||
DepositRoot: make([]byte, 32),
|
||||
DepositCount: 5,
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := isLegacyDepositProcessPeriod(tt.state, tt.canonicalEth1Data); got != tt.want {
|
||||
t.Errorf("isLegacyDepositProcessPeriod() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
fastssz "github.com/prysmaticlabs/fastssz"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/features"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
@@ -30,10 +31,17 @@ import (
|
||||
// - Otherwise:
|
||||
// - Determine the vote with the highest count. Prefer the vote with the highest eth1 block height in the event of a tie.
|
||||
// - This vote's block is the eth1 block to use for the block proposal.
|
||||
//
|
||||
// After Electra and eth1 deposit transition period voting will no longer be needed
|
||||
func (vs *Server) eth1DataMajorityVote(ctx context.Context, beaconState state.BeaconState) (*ethpb.Eth1Data, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, eth1dataTimeout)
|
||||
defer cancel()
|
||||
|
||||
// post eth1 deposits, the Eth 1 data will then be frozen
|
||||
if helpers.DepositRequestsStarted(beaconState) {
|
||||
return beaconState.Eth1Data(), nil
|
||||
}
|
||||
|
||||
slot := beaconState.Slot()
|
||||
votingPeriodStartTime := vs.slotStartTime(slot)
|
||||
|
||||
|
||||
@@ -2698,6 +2698,41 @@ func TestProposer_Eth1Data_MajorityVote(t *testing.T) {
|
||||
expectedHash := []byte("eth1data")
|
||||
assert.DeepEqual(t, expectedHash, hash)
|
||||
})
|
||||
|
||||
t.Run("post electra the head eth1data should be returned", func(t *testing.T) {
|
||||
p := mockExecution.New().
|
||||
InsertBlock(50, earliestValidTime, []byte("earliest")).
|
||||
InsertBlock(100, latestValidTime, []byte("latest"))
|
||||
p.Eth1Data = ðpb.Eth1Data{
|
||||
BlockHash: []byte("eth1data"),
|
||||
}
|
||||
|
||||
depositCache, err := depositsnapshot.New()
|
||||
require.NoError(t, err)
|
||||
|
||||
beaconState, err := state_native.InitializeFromProtoElectra(ðpb.BeaconStateElectra{
|
||||
Slot: slot,
|
||||
Eth1Data: ðpb.Eth1Data{BlockHash: []byte("legacy"), DepositCount: 1},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
ps := &Server{
|
||||
ChainStartFetcher: p,
|
||||
Eth1InfoFetcher: p,
|
||||
Eth1BlockFetcher: p,
|
||||
BlockFetcher: p,
|
||||
DepositFetcher: depositCache,
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
majorityVoteEth1Data, err := ps.eth1DataMajorityVote(ctx, beaconState)
|
||||
require.NoError(t, err)
|
||||
|
||||
hash := majorityVoteEth1Data.BlockHash
|
||||
|
||||
expectedHash := []byte("legacy")
|
||||
assert.DeepEqual(t, expectedHash, hash)
|
||||
})
|
||||
}
|
||||
|
||||
func TestProposer_FilterAttestation(t *testing.T) {
|
||||
|
||||
3
changelog/james-prysm_electra-eth1voting.md
Normal file
3
changelog/james-prysm_electra-eth1voting.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Added
|
||||
|
||||
- check to stop eth1 voting after electra and eth1 deposits stop
|
||||
@@ -71,14 +71,14 @@ func genesisBeaconStateElectra(ctx context.Context, deposits []*ethpb.Deposit, g
|
||||
return buildGenesisBeaconStateElectra(genesisTime, st, st.Eth1Data())
|
||||
}
|
||||
|
||||
// emptyGenesisStateDeneb returns an empty genesis state in Electra format.
|
||||
// emptyGenesisStateElectra returns an empty genesis state in Electra format.
|
||||
func emptyGenesisStateElectra() (state.BeaconState, error) {
|
||||
st := ðpb.BeaconStateElectra{
|
||||
// Misc fields.
|
||||
Slot: 0,
|
||||
Fork: ðpb.Fork{
|
||||
PreviousVersion: params.BeaconConfig().BellatrixForkVersion,
|
||||
CurrentVersion: params.BeaconConfig().DenebForkVersion,
|
||||
PreviousVersion: params.BeaconConfig().DenebForkVersion,
|
||||
CurrentVersion: params.BeaconConfig().ElectraForkVersion,
|
||||
Epoch: 0,
|
||||
},
|
||||
// Validator registry fields.
|
||||
|
||||
Reference in New Issue
Block a user