Skip to content

Commit

Permalink
simulators/eth2: support 12 second slots, add test for large withdraw…
Browse files Browse the repository at this point in the history
…al amounts, more fixes (ethereum#694)
  • Loading branch information
marioevz authored and Rjected committed Feb 7, 2023
1 parent 89b5676 commit 5b3d8ca
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 22 deletions.
36 changes: 24 additions & 12 deletions simulators/eth2/common/clients/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,21 +85,27 @@ func (nodes NodeDefinitions) Shares() []uint64 {
return shares
}

func (all NodeDefinitions) FilterByCL(filter []string) NodeDefinitions {
func (all NodeDefinitions) FilterByCL(filters []string) NodeDefinitions {
ret := make(NodeDefinitions, 0)
for _, n := range all {
if slices.Contains(filter, n.ConsensusClient) {
ret = append(ret, n)
for _, filter := range filters {
if strings.Contains(n.ConsensusClient, filter) {
ret = append(ret, n)
break
}
}
}
return ret
}

func (all NodeDefinitions) FilterByEL(filter []string) NodeDefinitions {
func (all NodeDefinitions) FilterByEL(filters []string) NodeDefinitions {
ret := make(NodeDefinitions, 0)
for _, n := range all {
if slices.Contains(filter, n.ExecutionClient) {
ret = append(ret, n)
for _, filter := range filters {
if strings.Contains(n.ExecutionClient, filter) {
ret = append(ret, n)
break
}
}
}
return ret
Expand Down Expand Up @@ -333,21 +339,27 @@ func (all Nodes) Running() Nodes {
return res
}

func (all Nodes) FilterByCL(filter []string) Nodes {
func (all Nodes) FilterByCL(filters []string) Nodes {
ret := make(Nodes, 0)
for _, n := range all {
if slices.Contains(filter, n.BeaconClient.ClientName()) {
ret = append(ret, n)
for _, filter := range filters {
if strings.Contains(n.BeaconClient.ClientName(), filter) {
ret = append(ret, n)
break
}
}
}
return ret
}

func (all Nodes) FilterByEL(filter []string) Nodes {
func (all Nodes) FilterByEL(filters []string) Nodes {
ret := make(Nodes, 0)
for _, n := range all {
if slices.Contains(filter, n.ExecutionClient.ClientType) {
ret = append(ret, n)
for _, filter := range filters {
if strings.Contains(n.ExecutionClient.ClientType, filter) {
ret = append(ret, n)
break
}
}
}
return ret
Expand Down
7 changes: 6 additions & 1 deletion simulators/eth2/common/config/consensus/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,12 @@ func BuildBeaconState(

var state common.BeaconState
var forkVersion common.Version
var previousForkVersion common.Version
var emptyBodyRoot common.Root
if spec.CAPELLA_FORK_EPOCH == 0 {
stateView := capella.NewBeaconStateView(spec)
forkVersion = spec.CAPELLA_FORK_VERSION
previousForkVersion = spec.BELLATRIX_FORK_VERSION
emptyBodyRoot = capella.BeaconBlockBodyType(configs.Mainnet).
New().
HashTreeRoot(hFn)
Expand All @@ -114,19 +116,22 @@ func BuildBeaconState(
} else if spec.BELLATRIX_FORK_EPOCH == 0 {
stateView := bellatrix.NewBeaconStateView(spec)
forkVersion = spec.BELLATRIX_FORK_VERSION
previousForkVersion = spec.ALTAIR_FORK_VERSION
emptyBodyRoot = bellatrix.BeaconBlockBodyType(configs.Mainnet).
New().
HashTreeRoot(hFn)
state = stateView
} else if spec.ALTAIR_FORK_EPOCH == 0 {
state = bellatrix.NewBeaconStateView(spec)
forkVersion = spec.ALTAIR_FORK_VERSION
previousForkVersion = spec.GENESIS_FORK_VERSION
emptyBodyRoot = altair.BeaconBlockBodyType(configs.Mainnet).
New().
HashTreeRoot(hFn)
} else {
state = phase0.NewBeaconStateView(spec)
forkVersion = spec.GENESIS_FORK_VERSION
previousForkVersion = spec.GENESIS_FORK_VERSION
emptyBodyRoot = phase0.BeaconBlockBodyType(configs.Mainnet).
New().
HashTreeRoot(hFn)
Expand All @@ -137,7 +142,7 @@ func BuildBeaconState(
}

if err := state.SetFork(common.Fork{
PreviousVersion: forkVersion, // duplicate, since there is nothing before genesis.
PreviousVersion: previousForkVersion,
CurrentVersion: forkVersion,
Epoch: common.GENESIS_EPOCH,
}); err != nil {
Expand Down
6 changes: 6 additions & 0 deletions simulators/eth2/common/testnet/prepared_testnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ func prepareTestnet(
// Validators can withdraw immediately
spec.Config.MIN_VALIDATOR_WITHDRAWABILITY_DELAY = 0

spec.Config.PROPOSER_SCORE_BOOST = 40

// Generate keys opts for validators
shares := config.NodeDefinitions.Shares()
// ExtraShares defines an extra set of keys that none of the nodes will have.
Expand Down Expand Up @@ -249,6 +251,10 @@ func prepareTestnet(
clients.PortMetrics,
),
"HIVE_ETH2_CONFIG_DEPOSIT_CONTRACT_ADDRESS": depositAddress.String(),
"HIVE_ETH2_DEPOSIT_DEPLOY_BLOCK_HASH": fmt.Sprintf(
"%s",
eth1Genesis.Genesis.ToBlock().Hash(),
),
}
beaconOpts := hivesim.Bundle(
commonOpts,
Expand Down
13 changes: 12 additions & 1 deletion simulators/eth2/withdrawals/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,18 @@ var tests = []TestSpec{
},

BaseWithdrawalsTestSpec{
Name: "test-bls-to-execution-changes-on-capella",
Name: "test-large-withdrawal-amounts",
Description: `
Test withdrawing large amounts, such that:
- The amount multiplied by 1e9 overflows uint64 (on conversion from gwei to wei)
`,
CapellaGenesis: true,
GenesisExecutionWithdrawalCredentialsShares: 1,
ExtraGwei: 68719476736, // ((2 ** 35) * (1e9)) > (2 ** 64)
},

BaseWithdrawalsTestSpec{
Name: "test-bls-to-execution-changes-on-capella-bellatrix-genesis",
Description: `
Send BLS-To-Execution-Changes after capella fork has happened.
Half of the validators still on BLS withdrawal credentials, and the
Expand Down
26 changes: 23 additions & 3 deletions simulators/eth2/withdrawals/scenarios.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/hive/hivesim"
"github.com/ethereum/hive/simulators/eth2/common/clients"
"github.com/ethereum/hive/simulators/eth2/common/testnet"
tn "github.com/ethereum/hive/simulators/eth2/common/testnet"
"github.com/protolambda/eth2api"
beacon "github.com/protolambda/zrnt/eth2/beacon/common"
)

var ConsensusClientsSupportingBLSChangesBeforeCapella = []string{
"prysm",
"lodestar",
}

// Generic withdrawals test routine, capable of running most of the test
// scenarios.
func (ts BaseWithdrawalsTestSpec) Execute(
t *hivesim.T,
env *testnet.Environment,
env *tn.Environment,
n []clients.NodeDefinition,
) {
config := ts.GetTestnetConfig(n)
Expand Down Expand Up @@ -80,6 +80,8 @@ func (ts BaseWithdrawalsTestSpec) Execute(
"FAIL: Unable to submit bls-to-execution changes: %v",
err,
)
} else {
t.Logf("INFO: Sent validator %d BLS-To-Exec-Change on Bellatrix (%s)", v.Index, b.ClientName())
}
}

Expand Down Expand Up @@ -117,6 +119,8 @@ func (ts BaseWithdrawalsTestSpec) Execute(
"FAIL: Unable to submit bls-to-execution changes: %v",
err,
)
} else {
t.Logf("INFO: Sent validator %d BLS-To-Exec-Change on Capella (%s)", v.Index, b.ClientName())
}
}

Expand Down Expand Up @@ -222,5 +226,21 @@ loop:
// Lastly check all clients are on the same head
testnet.VerifyELHeads(ctx)

// TODO: Should we wait for finalization every time?
// Check for optimistic sync
for i, n := range testnet.Nodes.Running() {
bc := n.BeaconClient
if op, err := bc.BlockIsOptimistic(ctx, eth2api.BlockHead); op {
t.Fatalf(
"FAIL: client %d (%s) is optimistic, it should be synced.",
i,
n.ClientNames(),
)
} else if err != nil {
t.Fatalf("FAIL: error querying optimistic state on client %d (%s): %v", i, n.ClientNames(), err)
}
}

if ts.WaitForFinality {
testnet.WaitForFinality(ctx)
}
}
35 changes: 30 additions & 5 deletions simulators/eth2/withdrawals/specs.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,39 @@ type BaseWithdrawalsTestSpec struct {

// Other Testing Configuration
SubmitBLSChangesOnBellatrix bool

// Verifications
WaitForFinality bool

// Extra Gwei
ExtraGwei beacon.Gwei
}

var (
DEFAULT_VALIDATOR_COUNT uint64 = 128
DEFAULT_SLOT_TIME uint64 = 6
MAINNET_SLOT_TIME int64 = 12
MINIMAL_SLOT_TIME int64 = 6

EPOCHS_TO_FINALITY beacon.Epoch = 4

// Default config used for all tests unless a client specific config exists
DEFAULT_CONFIG = &testnet.Config{
ValidatorCount: big.NewInt(int64(DEFAULT_VALIDATOR_COUNT)),
SlotTime: big.NewInt(int64(DEFAULT_SLOT_TIME)),
SlotTime: big.NewInt(MAINNET_SLOT_TIME),
TerminalTotalDifficulty: common.Big0,
AltairForkEpoch: common.Big0,
BellatrixForkEpoch: common.Big0,
CapellaForkEpoch: common.Big1,
Eth1Consensus: &el.ExecutionCliqueConsensus{},
}

MINIMAL_SLOT_TIME_CLIENTS = []string{
"lighthouse",
"teku",
"prysm",
"lodestar",
}

// Clients that do not support starting on epoch 0 with all forks enabled.
// Tests take longer for these clients.
/*
Expand All @@ -65,19 +79,30 @@ var (
"prysm": true,
}
*/

)

func (ts BaseWithdrawalsTestSpec) GetTestnetConfig(
allNodeDefinitions []clients.NodeDefinition,
allNodeDefinitions clients.NodeDefinitions,
) *testnet.Config {
config := DEFAULT_CONFIG
config := *DEFAULT_CONFIG

/*
if INCREMENTAL_FORKS_CLIENTS[n.ConsensusClient] {
config = config.Join(INCREMENTAL_FORKS_CONFIG)
}
*/

if len(
allNodeDefinitions.FilterByCL(MINIMAL_SLOT_TIME_CLIENTS),
) == len(
allNodeDefinitions,
) {
// If all clients support using minimal 6 second slot time, use it
config.SlotTime = big.NewInt(MINIMAL_SLOT_TIME)
}
fmt.Printf("INFO: using %d second slot time\n", config.SlotTime)

if ts.CapellaGenesis {
config.CapellaForkEpoch = common.Big0
}
Expand Down Expand Up @@ -146,7 +171,7 @@ func (ts BaseWithdrawalsTestSpec) GetValidatorKeys(

for index, key := range keys {
// All validators have idiosyncratic balance amounts to identify them
key.ExtraInitialBalance = beacon.Gwei(index + 1)
key.ExtraInitialBalance = beacon.Gwei(index+1) + ts.ExtraGwei

if ts.GenesisExecutionWithdrawalCredentialsShares > 0 &&
(index%ts.GenesisExecutionWithdrawalCredentialsShares) == 0 {
Expand Down

0 comments on commit 5b3d8ca

Please sign in to comment.