mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-22 03:30:35 +00:00
E2E from Phase0 or Bellatrix (#11802)
* e2e using dynamic configs; runtime bellatrix setup * starts from phase0 but fee recipient eval fails * lower TTD to cross before bellatrix epoch in e2e * fix debug printf * fix it * dynamic ttd and more robust fee_recipient eval * let multiplication set ttd=0 if bellatrix epoch=0 * refactoring fee recipient test after cognit errors * lint * appease deepsource * deep sourcin * gazelle * missed a usage of this when refactoring Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com> Co-authored-by: nisdas <nishdas93@gmail.com>
This commit is contained in:
parent
e43152102e
commit
d916827fb9
@ -43,6 +43,7 @@ go_library(
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//container/trie:go_default_library",
|
||||
"//crypto/bls:go_default_library",
|
||||
"//crypto/hash:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
state_native "github.com/prysmaticlabs/prysm/v3/beacon-chain/state/state-native"
|
||||
"github.com/prysmaticlabs/prysm/v3/beacon-chain/state/stateutil"
|
||||
"github.com/prysmaticlabs/prysm/v3/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v3/container/trie"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
@ -75,6 +76,43 @@ func GenesisBeaconState(ctx context.Context, deposits []*ethpb.Deposit, genesisT
|
||||
return OptimizedGenesisBeaconState(genesisTime, st, st.Eth1Data())
|
||||
}
|
||||
|
||||
// PreminedGenesisBeaconState works almost exactly like GenesisBeaconState, except that it assumes that genesis deposits
|
||||
// are not represented in the deposit contract and are only found in the genesis state validator registry. In order
|
||||
// to ensure the deposit root and count match the empty deposit contract deployed in a testnet genesis block, the root
|
||||
// of an empty deposit trie is computed and used as Eth1Data.deposit_root, and the deposit count is set to 0.
|
||||
func PreminedGenesisBeaconState(ctx context.Context, deposits []*ethpb.Deposit, genesisTime uint64, eth1Data *ethpb.Eth1Data) (state.BeaconState, error) {
|
||||
st, err := EmptyGenesisState()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Process initial deposits.
|
||||
st, err = helpers.UpdateGenesisEth1Data(st, deposits, eth1Data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
st, err = b.ProcessPreGenesisDeposits(ctx, st, deposits)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not process validator deposits")
|
||||
}
|
||||
|
||||
t, err := trie.NewTrie(params.BeaconConfig().DepositContractTreeDepth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dr, err := t.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := st.SetEth1Data(ðpb.Eth1Data{DepositRoot: dr[:], BlockHash: eth1Data.BlockHash}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := st.SetEth1DepositIndex(0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return OptimizedGenesisBeaconState(genesisTime, st, st.Eth1Data())
|
||||
}
|
||||
|
||||
// OptimizedGenesisBeaconState is used to create a state that has already processed deposits. This is to efficiently
|
||||
// create a mainnet state at chainstart.
|
||||
func OptimizedGenesisBeaconState(genesisTime uint64, preState state.BeaconState, eth1Data *ethpb.Eth1Data) (state.BeaconState, error) {
|
||||
|
@ -718,6 +718,9 @@ func (s *Service) determineEarliestVotingBlock(ctx context.Context, followBlock
|
||||
return 0, errors.Errorf("invalid genesis time provided. %d > %d", followBackDist, votingTime)
|
||||
}
|
||||
earliestValidTime := votingTime - followBackDist
|
||||
if earliestValidTime < genesisTime {
|
||||
return 0, nil
|
||||
}
|
||||
hdr, err := s.BlockByTimestamp(ctx, earliestValidTime)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
@ -1,6 +1,7 @@
|
||||
package testing
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
|
||||
@ -16,7 +17,7 @@ import (
|
||||
const defaultMinerAddress = "0x878705ba3f8bc32fcf7f4caa1a35e72af65cf766"
|
||||
const defaultTestChainId int64 = 1337
|
||||
const defaultCoinbase = "0x0000000000000000000000000000000000000000"
|
||||
const defaultDifficulty = "0x20000"
|
||||
const defaultDifficulty = "1"
|
||||
const defaultMixhash = "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
const defaultParenthash = "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
const defaultMinerBalance = "100000000000000000000000000000"
|
||||
@ -78,6 +79,10 @@ const DefaultCliqueSigner = "0x0000000000000000000000000000000000000000000000000
|
||||
// like in an e2e test. The parameters are minimal but the full value is returned unmarshaled so that it can be
|
||||
// customized as desired.
|
||||
func GethTestnetGenesis(genesisTime uint64, cfg *clparams.BeaconChainConfig) core.Genesis {
|
||||
ttd, ok := big.NewInt(0).SetString(clparams.BeaconConfig().TerminalTotalDifficulty, 10)
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("unable to parse TerminalTotalDifficulty as an integer = %s", clparams.BeaconConfig().TerminalTotalDifficulty))
|
||||
}
|
||||
cc := ¶ms.ChainConfig{
|
||||
ChainID: big.NewInt(defaultTestChainId),
|
||||
HomesteadBlock: bigz,
|
||||
@ -95,16 +100,24 @@ func GethTestnetGenesis(genesisTime uint64, cfg *clparams.BeaconChainConfig) cor
|
||||
ArrowGlacierBlock: bigz,
|
||||
GrayGlacierBlock: bigz,
|
||||
MergeNetsplitBlock: bigz,
|
||||
TerminalTotalDifficulty: bigz,
|
||||
TerminalTotalDifficulty: ttd,
|
||||
TerminalTotalDifficultyPassed: false,
|
||||
Clique: ¶ms.CliqueConfig{
|
||||
Period: cfg.SecondsPerETH1Block,
|
||||
Epoch: 20000,
|
||||
},
|
||||
}
|
||||
da := defaultDepositContractAllocation(cfg.DepositContractAddress)
|
||||
ma := minerAllocation()
|
||||
extra, err := hexutil.Decode(DefaultCliqueSigner)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("unable to decode DefaultCliqueSigner, with error %v", err.Error()))
|
||||
}
|
||||
return core.Genesis{
|
||||
Config: cc,
|
||||
Nonce: 0, // overridden for authorized signer votes in clique, so we should leave it empty?
|
||||
Timestamp: genesisTime,
|
||||
ExtraData: []byte(DefaultCliqueSigner),
|
||||
ExtraData: extra,
|
||||
GasLimit: math.MaxUint64 >> 1, // shift 1 back from the max, just in case
|
||||
Difficulty: common.HexToHash(defaultDifficulty).Big(),
|
||||
Mixhash: common.HexToHash(defaultMixhash),
|
||||
|
@ -10,7 +10,6 @@ import (
|
||||
type Flags struct {
|
||||
// Configuration related flags.
|
||||
MinimalConfig bool // MinimalConfig as defined in the spec.
|
||||
E2EConfig bool // E2EConfig made specifically for testing, do not use except in E2E.
|
||||
MaxRPCPageSize int // MaxRPCPageSize is used for a cap of page sizes in RPC requests.
|
||||
}
|
||||
|
||||
|
@ -25,11 +25,7 @@ func isMinimal(lines []string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func UnmarshalConfigFile(path string, conf *BeaconChainConfig) (*BeaconChainConfig, error) {
|
||||
yamlFile, err := os.ReadFile(path) // #nosec G304
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to read chain config file.")
|
||||
}
|
||||
func UnmarshalConfig(yamlFile []byte, conf *BeaconChainConfig) (*BeaconChainConfig, error) {
|
||||
// To track if config name is defined inside config file.
|
||||
hasConfigName := false
|
||||
// Convert 0x hex inputs to fixed bytes arrays
|
||||
@ -72,6 +68,14 @@ func UnmarshalConfigFile(path string, conf *BeaconChainConfig) (*BeaconChainConf
|
||||
return conf, nil
|
||||
}
|
||||
|
||||
func UnmarshalConfigFile(path string, conf *BeaconChainConfig) (*BeaconChainConfig, error) {
|
||||
yamlFile, err := os.ReadFile(path) // #nosec G304
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to read chain config file.")
|
||||
}
|
||||
return UnmarshalConfig(yamlFile, conf)
|
||||
}
|
||||
|
||||
// LoadChainConfigFile load, convert hex values into valid param yaml format,
|
||||
// unmarshal , and apply beacon chain config file.
|
||||
func LoadChainConfigFile(path string, conf *BeaconChainConfig) error {
|
||||
@ -201,6 +205,7 @@ func ConfigToYaml(cfg *BeaconChainConfig) []byte {
|
||||
fmt.Sprintf("TERMINAL_TOTAL_DIFFICULTY: %s", cfg.TerminalTotalDifficulty),
|
||||
fmt.Sprintf("TERMINAL_BLOCK_HASH: %#x", cfg.TerminalBlockHash),
|
||||
fmt.Sprintf("TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: %d", cfg.TerminalBlockHashActivationEpoch),
|
||||
fmt.Sprintf("DEPOSIT_CONTRACT_ADDRESS: %s", cfg.DepositContractAddress),
|
||||
}
|
||||
|
||||
yamlFile := []byte(strings.Join(lines, "\n"))
|
||||
|
@ -22,99 +22,115 @@ import (
|
||||
// These are variables that we don't use in Prysm. (i.e. future hardfork, light client... etc)
|
||||
var placeholderFields = []string{"UPDATE_TIMEOUT", "EIP4844_FORK_EPOCH", "EIP4844_FORK_VERSION"}
|
||||
|
||||
func assertEqualConfigs(t *testing.T, name string, fields []string, expected, actual *params.BeaconChainConfig) {
|
||||
// Misc params.
|
||||
assert.Equal(t, expected.MaxCommitteesPerSlot, actual.MaxCommitteesPerSlot, "%s: MaxCommitteesPerSlot", name)
|
||||
assert.Equal(t, expected.TargetCommitteeSize, actual.TargetCommitteeSize, "%s: TargetCommitteeSize", name)
|
||||
assert.Equal(t, expected.MaxValidatorsPerCommittee, actual.MaxValidatorsPerCommittee, "%s: MaxValidatorsPerCommittee", name)
|
||||
assert.Equal(t, expected.MinPerEpochChurnLimit, actual.MinPerEpochChurnLimit, "%s: MinPerEpochChurnLimit", name)
|
||||
assert.Equal(t, expected.ChurnLimitQuotient, actual.ChurnLimitQuotient, "%s: ChurnLimitQuotient", name)
|
||||
assert.Equal(t, expected.ShuffleRoundCount, actual.ShuffleRoundCount, "%s: ShuffleRoundCount", name)
|
||||
assert.Equal(t, expected.MinGenesisActiveValidatorCount, actual.MinGenesisActiveValidatorCount, "%s: MinGenesisActiveValidatorCount", name)
|
||||
assert.Equal(t, expected.MinGenesisTime, actual.MinGenesisTime, "%s: MinGenesisTime", name)
|
||||
assert.Equal(t, expected.HysteresisQuotient, actual.HysteresisQuotient, "%s: HysteresisQuotient", name)
|
||||
assert.Equal(t, expected.HysteresisDownwardMultiplier, actual.HysteresisDownwardMultiplier, "%s: HysteresisDownwardMultiplier", name)
|
||||
assert.Equal(t, expected.HysteresisUpwardMultiplier, actual.HysteresisUpwardMultiplier, "%s: HysteresisUpwardMultiplier", name)
|
||||
|
||||
// Fork Choice params.
|
||||
assert.Equal(t, expected.SafeSlotsToUpdateJustified, actual.SafeSlotsToUpdateJustified, "%s: SafeSlotsToUpdateJustified", name)
|
||||
|
||||
// Validator params.
|
||||
assert.Equal(t, expected.Eth1FollowDistance, actual.Eth1FollowDistance, "%s: Eth1FollowDistance", name)
|
||||
assert.Equal(t, expected.TargetAggregatorsPerCommittee, actual.TargetAggregatorsPerCommittee, "%s: TargetAggregatorsPerCommittee", name)
|
||||
assert.Equal(t, expected.RandomSubnetsPerValidator, actual.RandomSubnetsPerValidator, "%s: RandomSubnetsPerValidator", name)
|
||||
assert.Equal(t, expected.EpochsPerRandomSubnetSubscription, actual.EpochsPerRandomSubnetSubscription, "%s: EpochsPerRandomSubnetSubscription", name)
|
||||
assert.Equal(t, expected.SecondsPerETH1Block, actual.SecondsPerETH1Block, "%s: SecondsPerETH1Block", name)
|
||||
|
||||
// Deposit contract.
|
||||
assert.Equal(t, expected.DepositChainID, actual.DepositChainID, "%s: DepositChainID", name)
|
||||
assert.Equal(t, expected.DepositNetworkID, actual.DepositNetworkID, "%s: DepositNetworkID", name)
|
||||
assert.Equal(t, expected.DepositContractAddress, actual.DepositContractAddress, "%s: DepositContractAddress", name)
|
||||
|
||||
// Gwei values.
|
||||
assert.Equal(t, expected.MinDepositAmount, actual.MinDepositAmount, "%s: MinDepositAmount", name)
|
||||
assert.Equal(t, expected.MaxEffectiveBalance, actual.MaxEffectiveBalance, "%s: MaxEffectiveBalance", name)
|
||||
assert.Equal(t, expected.EjectionBalance, actual.EjectionBalance, "%s: EjectionBalance", name)
|
||||
assert.Equal(t, expected.EffectiveBalanceIncrement, actual.EffectiveBalanceIncrement, "%s: EffectiveBalanceIncrement", name)
|
||||
|
||||
// Initial values.
|
||||
assert.DeepEqual(t, expected.GenesisForkVersion, actual.GenesisForkVersion, "%s: GenesisForkVersion", name)
|
||||
assert.DeepEqual(t, expected.BLSWithdrawalPrefixByte, actual.BLSWithdrawalPrefixByte, "%s: BLSWithdrawalPrefixByte", name)
|
||||
assert.DeepEqual(t, expected.ETH1AddressWithdrawalPrefixByte, actual.ETH1AddressWithdrawalPrefixByte, "%s: ETH1AddressWithdrawalPrefixByte", name)
|
||||
|
||||
// Time parameters.
|
||||
assert.Equal(t, expected.GenesisDelay, actual.GenesisDelay, "%s: GenesisDelay", name)
|
||||
assert.Equal(t, expected.SecondsPerSlot, actual.SecondsPerSlot, "%s: SecondsPerSlot", name)
|
||||
assert.Equal(t, expected.MinAttestationInclusionDelay, actual.MinAttestationInclusionDelay, "%s: MinAttestationInclusionDelay", name)
|
||||
assert.Equal(t, expected.SlotsPerEpoch, actual.SlotsPerEpoch, "%s: SlotsPerEpoch", name)
|
||||
assert.Equal(t, expected.MinSeedLookahead, actual.MinSeedLookahead, "%s: MinSeedLookahead", name)
|
||||
assert.Equal(t, expected.MaxSeedLookahead, actual.MaxSeedLookahead, "%s: MaxSeedLookahead", name)
|
||||
assert.Equal(t, expected.EpochsPerEth1VotingPeriod, actual.EpochsPerEth1VotingPeriod, "%s: EpochsPerEth1VotingPeriod", name)
|
||||
assert.Equal(t, expected.SlotsPerHistoricalRoot, actual.SlotsPerHistoricalRoot, "%s: SlotsPerHistoricalRoot", name)
|
||||
assert.Equal(t, expected.MinValidatorWithdrawabilityDelay, actual.MinValidatorWithdrawabilityDelay, "%s: MinValidatorWithdrawabilityDelay", name)
|
||||
assert.Equal(t, expected.ShardCommitteePeriod, actual.ShardCommitteePeriod, "%s: ShardCommitteePeriod", name)
|
||||
assert.Equal(t, expected.MinEpochsToInactivityPenalty, actual.MinEpochsToInactivityPenalty, "%s: MinEpochsToInactivityPenalty", name)
|
||||
|
||||
// State vector lengths.
|
||||
assert.Equal(t, expected.EpochsPerHistoricalVector, actual.EpochsPerHistoricalVector, "%s: EpochsPerHistoricalVector", name)
|
||||
assert.Equal(t, expected.EpochsPerSlashingsVector, actual.EpochsPerSlashingsVector, "%s: EpochsPerSlashingsVector", name)
|
||||
assert.Equal(t, expected.HistoricalRootsLimit, actual.HistoricalRootsLimit, "%s: HistoricalRootsLimit", name)
|
||||
assert.Equal(t, expected.ValidatorRegistryLimit, actual.ValidatorRegistryLimit, "%s: ValidatorRegistryLimit", name)
|
||||
|
||||
// Reward and penalty quotients.
|
||||
assert.Equal(t, expected.BaseRewardFactor, actual.BaseRewardFactor, "%s: BaseRewardFactor", name)
|
||||
assert.Equal(t, expected.WhistleBlowerRewardQuotient, actual.WhistleBlowerRewardQuotient, "%s: WhistleBlowerRewardQuotient", name)
|
||||
assert.Equal(t, expected.ProposerRewardQuotient, actual.ProposerRewardQuotient, "%s: ProposerRewardQuotient", name)
|
||||
assert.Equal(t, expected.InactivityPenaltyQuotient, actual.InactivityPenaltyQuotient, "%s: InactivityPenaltyQuotient", name)
|
||||
assert.Equal(t, expected.InactivityPenaltyQuotientAltair, actual.InactivityPenaltyQuotientAltair, "%s: InactivityPenaltyQuotientAltair", name)
|
||||
assert.Equal(t, expected.MinSlashingPenaltyQuotient, actual.MinSlashingPenaltyQuotient, "%s: MinSlashingPenaltyQuotient", name)
|
||||
assert.Equal(t, expected.MinSlashingPenaltyQuotientAltair, actual.MinSlashingPenaltyQuotientAltair, "%s: MinSlashingPenaltyQuotientAltair", name)
|
||||
assert.Equal(t, expected.ProportionalSlashingMultiplier, actual.ProportionalSlashingMultiplier, "%s: ProportionalSlashingMultiplier", name)
|
||||
assert.Equal(t, expected.ProportionalSlashingMultiplierAltair, actual.ProportionalSlashingMultiplierAltair, "%s: ProportionalSlashingMultiplierAltair", name)
|
||||
|
||||
// Max operations per block.
|
||||
assert.Equal(t, expected.MaxProposerSlashings, actual.MaxProposerSlashings, "%s: MaxProposerSlashings", name)
|
||||
assert.Equal(t, expected.MaxAttesterSlashings, actual.MaxAttesterSlashings, "%s: MaxAttesterSlashings", name)
|
||||
assert.Equal(t, expected.MaxAttestations, actual.MaxAttestations, "%s: MaxAttestations", name)
|
||||
assert.Equal(t, expected.MaxDeposits, actual.MaxDeposits, "%s: MaxDeposits", name)
|
||||
assert.Equal(t, expected.MaxVoluntaryExits, actual.MaxVoluntaryExits, "%s: MaxVoluntaryExits", name)
|
||||
|
||||
// Signature domains.
|
||||
assert.Equal(t, expected.DomainBeaconProposer, actual.DomainBeaconProposer, "%s: DomainBeaconProposer", name)
|
||||
assert.Equal(t, expected.DomainBeaconAttester, actual.DomainBeaconAttester, "%s: DomainBeaconAttester", name)
|
||||
assert.Equal(t, expected.DomainRandao, actual.DomainRandao, "%s: DomainRandao", name)
|
||||
assert.Equal(t, expected.DomainDeposit, actual.DomainDeposit, "%s: DomainDeposit", name)
|
||||
assert.Equal(t, expected.DomainVoluntaryExit, actual.DomainVoluntaryExit, "%s: DomainVoluntaryExit", name)
|
||||
assert.Equal(t, expected.DomainSelectionProof, actual.DomainSelectionProof, "%s: DomainSelectionProof", name)
|
||||
assert.Equal(t, expected.DomainAggregateAndProof, actual.DomainAggregateAndProof, "%s: DomainAggregateAndProof", name)
|
||||
assert.Equal(t, expected.TerminalTotalDifficulty, actual.TerminalTotalDifficulty, "%s: DomainAggregateAndProof", name)
|
||||
assert.Equal(t, expected.AltairForkEpoch, actual.AltairForkEpoch, "%s: DomainAggregateAndProof", name)
|
||||
assert.Equal(t, expected.BellatrixForkEpoch, actual.BellatrixForkEpoch, "%s: DomainAggregateAndProof", name)
|
||||
assert.Equal(t, expected.SqrRootSlotsPerEpoch, actual.SqrRootSlotsPerEpoch, "%s: DomainAggregateAndProof", name)
|
||||
assert.DeepEqual(t, expected.GenesisForkVersion, actual.GenesisForkVersion, "%s: DomainAggregateAndProof", name)
|
||||
assert.DeepEqual(t, expected.AltairForkVersion, actual.AltairForkVersion, "%s: DomainAggregateAndProof", name)
|
||||
assert.DeepEqual(t, expected.BellatrixForkVersion, actual.BellatrixForkVersion, "%s: DomainAggregateAndProof", name)
|
||||
|
||||
assertYamlFieldsMatch(t, name, fields, expected, actual)
|
||||
}
|
||||
|
||||
func TestModifiedE2E(t *testing.T) {
|
||||
c := params.E2ETestConfig().Copy()
|
||||
c.DepositContractAddress = "0x4242424242424242424242424242424242424242"
|
||||
c.TerminalTotalDifficulty = "0"
|
||||
c.AltairForkEpoch = 0
|
||||
c.BellatrixForkEpoch = 0
|
||||
y := params.ConfigToYaml(c)
|
||||
cfg, err := params.UnmarshalConfig(y, nil)
|
||||
require.NoError(t, err)
|
||||
assertEqualConfigs(t, "modified-e2e", []string{}, c, cfg)
|
||||
}
|
||||
|
||||
func TestLoadConfigFile(t *testing.T) {
|
||||
// TODO(11750)
|
||||
t.Skip("needs https://github.com/prysmaticlabs/prysm/issues/11750")
|
||||
// See https://media.githubusercontent.com/media/ethereum/consensus-spec-tests/master/tests/minimal/config/phase0.yaml
|
||||
assertVals := func(name string, fields []string, expected, actual *params.BeaconChainConfig) {
|
||||
// Misc params.
|
||||
assert.Equal(t, expected.MaxCommitteesPerSlot, actual.MaxCommitteesPerSlot, "%s: MaxCommitteesPerSlot", name)
|
||||
assert.Equal(t, expected.TargetCommitteeSize, actual.TargetCommitteeSize, "%s: TargetCommitteeSize", name)
|
||||
assert.Equal(t, expected.MaxValidatorsPerCommittee, actual.MaxValidatorsPerCommittee, "%s: MaxValidatorsPerCommittee", name)
|
||||
assert.Equal(t, expected.MinPerEpochChurnLimit, actual.MinPerEpochChurnLimit, "%s: MinPerEpochChurnLimit", name)
|
||||
assert.Equal(t, expected.ChurnLimitQuotient, actual.ChurnLimitQuotient, "%s: ChurnLimitQuotient", name)
|
||||
assert.Equal(t, expected.ShuffleRoundCount, actual.ShuffleRoundCount, "%s: ShuffleRoundCount", name)
|
||||
assert.Equal(t, expected.MinGenesisActiveValidatorCount, actual.MinGenesisActiveValidatorCount, "%s: MinGenesisActiveValidatorCount", name)
|
||||
assert.Equal(t, expected.MinGenesisTime, actual.MinGenesisTime, "%s: MinGenesisTime", name)
|
||||
assert.Equal(t, expected.HysteresisQuotient, actual.HysteresisQuotient, "%s: HysteresisQuotient", name)
|
||||
assert.Equal(t, expected.HysteresisDownwardMultiplier, actual.HysteresisDownwardMultiplier, "%s: HysteresisDownwardMultiplier", name)
|
||||
assert.Equal(t, expected.HysteresisUpwardMultiplier, actual.HysteresisUpwardMultiplier, "%s: HysteresisUpwardMultiplier", name)
|
||||
|
||||
// Fork Choice params.
|
||||
assert.Equal(t, expected.SafeSlotsToUpdateJustified, actual.SafeSlotsToUpdateJustified, "%s: SafeSlotsToUpdateJustified", name)
|
||||
|
||||
// Validator params.
|
||||
assert.Equal(t, expected.Eth1FollowDistance, actual.Eth1FollowDistance, "%s: Eth1FollowDistance", name)
|
||||
assert.Equal(t, expected.TargetAggregatorsPerCommittee, actual.TargetAggregatorsPerCommittee, "%s: TargetAggregatorsPerCommittee", name)
|
||||
assert.Equal(t, expected.RandomSubnetsPerValidator, actual.RandomSubnetsPerValidator, "%s: RandomSubnetsPerValidator", name)
|
||||
assert.Equal(t, expected.EpochsPerRandomSubnetSubscription, actual.EpochsPerRandomSubnetSubscription, "%s: EpochsPerRandomSubnetSubscription", name)
|
||||
assert.Equal(t, expected.SecondsPerETH1Block, actual.SecondsPerETH1Block, "%s: SecondsPerETH1Block", name)
|
||||
|
||||
// Deposit contract.
|
||||
assert.Equal(t, expected.DepositChainID, actual.DepositChainID, "%s: DepositChainID", name)
|
||||
assert.Equal(t, expected.DepositNetworkID, actual.DepositNetworkID, "%s: DepositNetworkID", name)
|
||||
assert.Equal(t, expected.DepositContractAddress, actual.DepositContractAddress, "%s: DepositContractAddress", name)
|
||||
|
||||
// Gwei values.
|
||||
assert.Equal(t, expected.MinDepositAmount, actual.MinDepositAmount, "%s: MinDepositAmount", name)
|
||||
assert.Equal(t, expected.MaxEffectiveBalance, actual.MaxEffectiveBalance, "%s: MaxEffectiveBalance", name)
|
||||
assert.Equal(t, expected.EjectionBalance, actual.EjectionBalance, "%s: EjectionBalance", name)
|
||||
assert.Equal(t, expected.EffectiveBalanceIncrement, actual.EffectiveBalanceIncrement, "%s: EffectiveBalanceIncrement", name)
|
||||
|
||||
// Initial values.
|
||||
assert.DeepEqual(t, expected.GenesisForkVersion, actual.GenesisForkVersion, "%s: GenesisForkVersion", name)
|
||||
assert.DeepEqual(t, expected.BLSWithdrawalPrefixByte, actual.BLSWithdrawalPrefixByte, "%s: BLSWithdrawalPrefixByte", name)
|
||||
assert.DeepEqual(t, expected.ETH1AddressWithdrawalPrefixByte, actual.ETH1AddressWithdrawalPrefixByte, "%s: ETH1AddressWithdrawalPrefixByte", name)
|
||||
|
||||
// Time parameters.
|
||||
assert.Equal(t, expected.GenesisDelay, actual.GenesisDelay, "%s: GenesisDelay", name)
|
||||
assert.Equal(t, expected.SecondsPerSlot, actual.SecondsPerSlot, "%s: SecondsPerSlot", name)
|
||||
assert.Equal(t, expected.MinAttestationInclusionDelay, actual.MinAttestationInclusionDelay, "%s: MinAttestationInclusionDelay", name)
|
||||
assert.Equal(t, expected.SlotsPerEpoch, actual.SlotsPerEpoch, "%s: SlotsPerEpoch", name)
|
||||
assert.Equal(t, expected.MinSeedLookahead, actual.MinSeedLookahead, "%s: MinSeedLookahead", name)
|
||||
assert.Equal(t, expected.MaxSeedLookahead, actual.MaxSeedLookahead, "%s: MaxSeedLookahead", name)
|
||||
assert.Equal(t, expected.EpochsPerEth1VotingPeriod, actual.EpochsPerEth1VotingPeriod, "%s: EpochsPerEth1VotingPeriod", name)
|
||||
assert.Equal(t, expected.SlotsPerHistoricalRoot, actual.SlotsPerHistoricalRoot, "%s: SlotsPerHistoricalRoot", name)
|
||||
assert.Equal(t, expected.MinValidatorWithdrawabilityDelay, actual.MinValidatorWithdrawabilityDelay, "%s: MinValidatorWithdrawabilityDelay", name)
|
||||
assert.Equal(t, expected.ShardCommitteePeriod, actual.ShardCommitteePeriod, "%s: ShardCommitteePeriod", name)
|
||||
assert.Equal(t, expected.MinEpochsToInactivityPenalty, actual.MinEpochsToInactivityPenalty, "%s: MinEpochsToInactivityPenalty", name)
|
||||
|
||||
// State vector lengths.
|
||||
assert.Equal(t, expected.EpochsPerHistoricalVector, actual.EpochsPerHistoricalVector, "%s: EpochsPerHistoricalVector", name)
|
||||
assert.Equal(t, expected.EpochsPerSlashingsVector, actual.EpochsPerSlashingsVector, "%s: EpochsPerSlashingsVector", name)
|
||||
assert.Equal(t, expected.HistoricalRootsLimit, actual.HistoricalRootsLimit, "%s: HistoricalRootsLimit", name)
|
||||
assert.Equal(t, expected.ValidatorRegistryLimit, actual.ValidatorRegistryLimit, "%s: ValidatorRegistryLimit", name)
|
||||
|
||||
// Reward and penalty quotients.
|
||||
assert.Equal(t, expected.BaseRewardFactor, actual.BaseRewardFactor, "%s: BaseRewardFactor", name)
|
||||
assert.Equal(t, expected.WhistleBlowerRewardQuotient, actual.WhistleBlowerRewardQuotient, "%s: WhistleBlowerRewardQuotient", name)
|
||||
assert.Equal(t, expected.ProposerRewardQuotient, actual.ProposerRewardQuotient, "%s: ProposerRewardQuotient", name)
|
||||
assert.Equal(t, expected.InactivityPenaltyQuotient, actual.InactivityPenaltyQuotient, "%s: InactivityPenaltyQuotient", name)
|
||||
assert.Equal(t, expected.InactivityPenaltyQuotientAltair, actual.InactivityPenaltyQuotientAltair, "%s: InactivityPenaltyQuotientAltair", name)
|
||||
assert.Equal(t, expected.MinSlashingPenaltyQuotient, actual.MinSlashingPenaltyQuotient, "%s: MinSlashingPenaltyQuotient", name)
|
||||
assert.Equal(t, expected.MinSlashingPenaltyQuotientAltair, actual.MinSlashingPenaltyQuotientAltair, "%s: MinSlashingPenaltyQuotientAltair", name)
|
||||
assert.Equal(t, expected.ProportionalSlashingMultiplier, actual.ProportionalSlashingMultiplier, "%s: ProportionalSlashingMultiplier", name)
|
||||
assert.Equal(t, expected.ProportionalSlashingMultiplierAltair, actual.ProportionalSlashingMultiplierAltair, "%s: ProportionalSlashingMultiplierAltair", name)
|
||||
|
||||
// Max operations per block.
|
||||
assert.Equal(t, expected.MaxProposerSlashings, actual.MaxProposerSlashings, "%s: MaxProposerSlashings", name)
|
||||
assert.Equal(t, expected.MaxAttesterSlashings, actual.MaxAttesterSlashings, "%s: MaxAttesterSlashings", name)
|
||||
assert.Equal(t, expected.MaxAttestations, actual.MaxAttestations, "%s: MaxAttestations", name)
|
||||
assert.Equal(t, expected.MaxDeposits, actual.MaxDeposits, "%s: MaxDeposits", name)
|
||||
assert.Equal(t, expected.MaxVoluntaryExits, actual.MaxVoluntaryExits, "%s: MaxVoluntaryExits", name)
|
||||
|
||||
// Signature domains.
|
||||
assert.Equal(t, expected.DomainBeaconProposer, actual.DomainBeaconProposer, "%s: DomainBeaconProposer", name)
|
||||
assert.Equal(t, expected.DomainBeaconAttester, actual.DomainBeaconAttester, "%s: DomainBeaconAttester", name)
|
||||
assert.Equal(t, expected.DomainRandao, actual.DomainRandao, "%s: DomainRandao", name)
|
||||
assert.Equal(t, expected.DomainDeposit, actual.DomainDeposit, "%s: DomainDeposit", name)
|
||||
assert.Equal(t, expected.DomainVoluntaryExit, actual.DomainVoluntaryExit, "%s: DomainVoluntaryExit", name)
|
||||
assert.Equal(t, expected.DomainSelectionProof, actual.DomainSelectionProof, "%s: DomainSelectionProof", name)
|
||||
assert.Equal(t, expected.DomainAggregateAndProof, actual.DomainAggregateAndProof, "%s: DomainAggregateAndProof", name)
|
||||
|
||||
assertYamlFieldsMatch(t, name, fields, expected, actual)
|
||||
}
|
||||
|
||||
t.Run("mainnet", func(t *testing.T) {
|
||||
mn := params.MainnetConfig().Copy()
|
||||
mainnetPresetsFiles := presetsFilePath(t, "mainnet")
|
||||
@ -130,7 +146,7 @@ func TestLoadConfigFile(t *testing.T) {
|
||||
mnf, err := params.UnmarshalConfigFile(mainnetConfigFile, nil)
|
||||
require.NoError(t, err)
|
||||
fields := fieldsFromYamls(t, append(mainnetPresetsFiles, mainnetConfigFile))
|
||||
assertVals("mainnet", fields, mn, mnf)
|
||||
assertEqualConfigs(t, "mainnet", fields, mn, mnf)
|
||||
})
|
||||
|
||||
t.Run("minimal", func(t *testing.T) {
|
||||
@ -148,7 +164,7 @@ func TestLoadConfigFile(t *testing.T) {
|
||||
minf, err := params.UnmarshalConfigFile(minimalConfigFile, nil)
|
||||
require.NoError(t, err)
|
||||
fields := fieldsFromYamls(t, append(minimalPresetsFiles, minimalConfigFile))
|
||||
assertVals("minimal", fields, min, minf)
|
||||
assertEqualConfigs(t, "minimal", fields, min, minf)
|
||||
})
|
||||
|
||||
t.Run("e2e", func(t *testing.T) {
|
||||
@ -158,7 +174,7 @@ func TestLoadConfigFile(t *testing.T) {
|
||||
e2ef, err := params.UnmarshalConfigFile(configFile, nil)
|
||||
require.NoError(t, err)
|
||||
fields := fieldsFromYamls(t, []string{configFile})
|
||||
assertVals("e2e", fields, e2e, e2ef)
|
||||
assertEqualConfigs(t, "e2e", fields, e2e, e2ef)
|
||||
})
|
||||
}
|
||||
|
||||
|
6
config/params/testdata/e2e_config.yaml
vendored
6
config/params/testdata/e2e_config.yaml
vendored
@ -7,8 +7,8 @@ PRESET_BASE: 'minimal'
|
||||
|
||||
# Transition
|
||||
# ---------------------------------------------------------------
|
||||
# TBD, 2**256-2**10 is a placeholder, e2e is 616
|
||||
TERMINAL_TOTAL_DIFFICULTY: 616
|
||||
# TBD, 2**256-2**10 is a placeholder, e2e is 480
|
||||
TERMINAL_TOTAL_DIFFICULTY: 480
|
||||
# By default, don't use these params
|
||||
#TERMINAL_BLOCK_HASH: 0x0000000000000000000000000000000000000000000000000000000000000000
|
||||
#TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: 18446744073709551615
|
||||
@ -83,7 +83,7 @@ PROPOSER_SCORE_BOOST: 40
|
||||
DEPOSIT_CHAIN_ID: 1337 # Override for e2e tests
|
||||
DEPOSIT_NETWORK_ID: 1337 # Override for e2e tests
|
||||
# Configured on a per testnet basis
|
||||
DEPOSIT_CONTRACT_ADDRESS: 0x1234567890123456789012345678901234567890
|
||||
DEPOSIT_CONTRACT_ADDRESS: 0x4242424242424242424242424242424242424242
|
||||
|
||||
# Updated penalty values
|
||||
# ---------------------------------------------------------------
|
||||
|
@ -20,14 +20,12 @@ func testnetConfigFilePath(t *testing.T, network string) string {
|
||||
}
|
||||
|
||||
func TestE2EConfigParity(t *testing.T) {
|
||||
// TODO(11750)
|
||||
t.Skip("needs https://github.com/prysmaticlabs/prysm/issues/11750")
|
||||
params.SetupTestConfigCleanup(t)
|
||||
testDir := bazel.TestTmpDir()
|
||||
yamlDir := filepath.Join(testDir, "config.yaml")
|
||||
|
||||
testCfg := params.E2EMainnetTestConfig()
|
||||
yamlObj := params.E2EMainnetConfigYaml()
|
||||
yamlObj := params.ConfigToYaml(params.E2EMainnetTestConfig())
|
||||
assert.NoError(t, file.WriteFile(yamlDir, yamlObj))
|
||||
|
||||
require.NoError(t, params.LoadChainConfigFile(yamlDir, params.MainnetConfig().Copy()))
|
||||
|
@ -1,8 +1,8 @@
|
||||
package params
|
||||
|
||||
const (
|
||||
altairE2EForkEpoch = 0
|
||||
bellatrixE2EForkEpoch = 0
|
||||
altairE2EForkEpoch = 6
|
||||
bellatrixE2EForkEpoch = 8
|
||||
)
|
||||
|
||||
// E2ETestConfig retrieves the configurations made specifically for E2E testing.
|
||||
@ -36,7 +36,7 @@ func E2ETestConfig() *BeaconChainConfig {
|
||||
e2eConfig.BellatrixForkEpoch = bellatrixE2EForkEpoch
|
||||
|
||||
// Terminal Total Difficulty.
|
||||
e2eConfig.TerminalTotalDifficulty = "0"
|
||||
e2eConfig.TerminalTotalDifficulty = "480"
|
||||
|
||||
// Prysm constants.
|
||||
e2eConfig.ConfigName = EndToEndName
|
||||
@ -74,7 +74,7 @@ func E2EMainnetTestConfig() *BeaconChainConfig {
|
||||
e2eConfig.BellatrixForkEpoch = bellatrixE2EForkEpoch
|
||||
|
||||
// Terminal Total Difficulty.
|
||||
e2eConfig.TerminalTotalDifficulty = "0"
|
||||
e2eConfig.TerminalTotalDifficulty = "480"
|
||||
|
||||
// Prysm constants.
|
||||
e2eConfig.ConfigName = EndToEndMainnetName
|
||||
@ -86,13 +86,3 @@ func E2EMainnetTestConfig() *BeaconChainConfig {
|
||||
e2eConfig.InitializeForkSchedule()
|
||||
return e2eConfig
|
||||
}
|
||||
|
||||
// E2EMainnetConfigYaml returns the e2e config in yaml format.
|
||||
func E2EMainnetConfigYaml() []byte {
|
||||
return ConfigToYaml(E2EMainnetTestConfig())
|
||||
}
|
||||
|
||||
// E2ETestConfigYaml returns the e2e config in yaml format.
|
||||
func E2ETestConfigYaml() []byte {
|
||||
return ConfigToYaml(E2ETestConfig())
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ go_library(
|
||||
"generate_genesis_state.go",
|
||||
"generate_genesis_state_bellatrix.go",
|
||||
"generate_keys.go",
|
||||
"premined_genesis_state.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v3/runtime/interop",
|
||||
visibility = ["//visibility:public"],
|
||||
|
63
runtime/interop/premined_genesis_state.go
Normal file
63
runtime/interop/premined_genesis_state.go
Normal file
@ -0,0 +1,63 @@
|
||||
package interop
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
coreState "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/transition"
|
||||
statenative "github.com/prysmaticlabs/prysm/v3/beacon-chain/state/state-native"
|
||||
"github.com/prysmaticlabs/prysm/v3/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v3/container/trie"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
// GeneratePreminedGenesisState deterministically given a genesis time and number of validators.
|
||||
// If a genesis time of 0 is supplied it is set to the current time.
|
||||
func GeneratePreminedGenesisState(ctx context.Context, genesisTime, numValidators uint64, e1d *ethpb.Eth1Data) (*ethpb.BeaconState, []*ethpb.Deposit, error) {
|
||||
privKeys, pubKeys, err := DeterministicallyGenerateKeys(0 /*startIndex*/, numValidators)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrapf(err, "could not deterministically generate keys for %d validators", numValidators)
|
||||
}
|
||||
depositDataItems, depositDataRoots, err := DepositDataFromKeys(privKeys, pubKeys)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "could not generate deposit data from keys")
|
||||
}
|
||||
return GeneratePreminedGenesisStateFromDepositData(ctx, genesisTime, depositDataItems, depositDataRoots, e1d)
|
||||
}
|
||||
|
||||
// GeneratePreminedGenesisStateFromDepositData creates a genesis state given a list of
|
||||
// deposit data items and their corresponding roots.
|
||||
func GeneratePreminedGenesisStateFromDepositData(
|
||||
ctx context.Context, genesisTime uint64, depositData []*ethpb.Deposit_Data, depositDataRoots [][]byte, e1d *ethpb.Eth1Data,
|
||||
) (*ethpb.BeaconState, []*ethpb.Deposit, error) {
|
||||
t, err := trie.GenerateTrieFromItems(depositDataRoots, params.BeaconConfig().DepositContractTreeDepth)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "could not generate Merkle trie for deposit proofs")
|
||||
}
|
||||
deposits, err := GenerateDepositsFromData(depositData, t)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "could not generate deposits from the deposit data provided")
|
||||
}
|
||||
root, err := t.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "could not hash tree root of deposit trie")
|
||||
}
|
||||
if genesisTime == 0 {
|
||||
genesisTime = uint64(time.Now().Unix())
|
||||
}
|
||||
beaconState, err := coreState.PreminedGenesisBeaconState(ctx, deposits, genesisTime, ðpb.Eth1Data{
|
||||
DepositRoot: root[:],
|
||||
DepositCount: uint64(len(deposits)),
|
||||
BlockHash: e1d.BlockHash,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "could not generate genesis state")
|
||||
}
|
||||
|
||||
pbState, err := statenative.ProtobufBeaconStatePhase0(beaconState.ToProtoUnsafe())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return pbState, deposits, nil
|
||||
}
|
@ -37,10 +37,6 @@ var (
|
||||
|
||||
// VerifyTosAcceptedOrPrompt check if Tos was accepted before or asks to accept.
|
||||
func VerifyTosAcceptedOrPrompt(ctx *cli.Context) error {
|
||||
if ctx.Bool(cmd.E2EConfigFlag.Name) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if file.FileExists(filepath.Join(ctx.String(cmd.DataDirFlag.Name), acceptTosFilename)) {
|
||||
return nil
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ test_suite(
|
||||
)
|
||||
|
||||
common_deps = [
|
||||
"//runtime/version:go_default_library",
|
||||
"//api/client/beacon:go_default_library",
|
||||
"//beacon-chain/blockchain/testing:go_default_library",
|
||||
"//beacon-chain/core/transition:go_default_library",
|
||||
|
@ -20,7 +20,6 @@ go_library(
|
||||
importpath = "github.com/prysmaticlabs/prysm/v3/testing/endtoend/components",
|
||||
visibility = ["//testing/endtoend:__subpackages__"],
|
||||
deps = [
|
||||
"//beacon-chain/core/blocks:go_default_library",
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//beacon-chain/state/state-native:go_default_library",
|
||||
"//cmd:go_default_library",
|
||||
@ -38,12 +37,14 @@ go_library(
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//runtime/interop:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"//testing/endtoend/helpers:go_default_library",
|
||||
"//testing/endtoend/params:go_default_library",
|
||||
"//testing/endtoend/types:go_default_library",
|
||||
"//validator/keymanager:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
|
||||
"@com_github_google_uuid//:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
|
@ -13,8 +13,8 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v3/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v3/beacon-chain/state"
|
||||
state_native "github.com/prysmaticlabs/prysm/v3/beacon-chain/state/state-native"
|
||||
cmdshared "github.com/prysmaticlabs/prysm/v3/cmd"
|
||||
@ -29,6 +29,7 @@ import (
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v3/runtime/interop"
|
||||
"github.com/prysmaticlabs/prysm/v3/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/endtoend/helpers"
|
||||
e2e "github.com/prysmaticlabs/prysm/v3/testing/endtoend/params"
|
||||
e2etypes "github.com/prysmaticlabs/prysm/v3/testing/endtoend/types"
|
||||
@ -182,7 +183,6 @@ func (node *BeaconNode) generateGenesis(ctx context.Context) (state.BeaconState,
|
||||
return nil, errors.New("Cannot construct bellatrix block, e2e.TestParams.Eth1GenesisBlock == nil")
|
||||
}
|
||||
gb := e2e.TestParams.Eth1GenesisBlock
|
||||
|
||||
// so the DepositRoot in the BeaconState should be set to the HTR of an empty deposit trie.
|
||||
t, err := trie.NewTrie(params.BeaconConfig().DepositContractTreeDepth)
|
||||
if err != nil {
|
||||
@ -197,54 +197,15 @@ func (node *BeaconNode) generateGenesis(ctx context.Context) (state.BeaconState,
|
||||
DepositCount: 0,
|
||||
BlockHash: gb.Hash().Bytes(),
|
||||
}
|
||||
|
||||
payload := &enginev1.ExecutionPayload{
|
||||
ParentHash: gb.ParentHash().Bytes(),
|
||||
FeeRecipient: gb.Coinbase().Bytes(),
|
||||
StateRoot: gb.Root().Bytes(),
|
||||
ReceiptsRoot: gb.ReceiptHash().Bytes(),
|
||||
LogsBloom: gb.Bloom().Bytes(),
|
||||
PrevRandao: params.BeaconConfig().ZeroHash[:],
|
||||
BlockNumber: gb.NumberU64(),
|
||||
GasLimit: gb.GasLimit(),
|
||||
GasUsed: gb.GasUsed(),
|
||||
Timestamp: gb.Time(),
|
||||
ExtraData: gb.Extra()[:32],
|
||||
BaseFeePerGas: bytesutil.PadTo(bytesutil.ReverseByteOrder(gb.BaseFee().Bytes()), fieldparams.RootLength),
|
||||
BlockHash: gb.Hash().Bytes(),
|
||||
Transactions: make([][]byte, 0),
|
||||
v := e2etypes.GenesisFork()
|
||||
switch v {
|
||||
case version.Bellatrix:
|
||||
return generateGenesisBellatrix(ctx, gb, e1d)
|
||||
case version.Phase0:
|
||||
return generateGenesisPhase0(ctx, e1d)
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported genesis fork version %s", version.String(v))
|
||||
}
|
||||
genesis, _, err := interop.GenerateGenesisStateBellatrix(ctx, e2e.TestParams.CLGenesisTime, params.BeaconConfig().MinGenesisActiveValidatorCount, payload, e1d)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lbhr, err := genesis.LatestBlockHeader.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
si, err := state_native.InitializeFromProtoUnsafeBellatrix(genesis)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
genb, err := blocks.NewGenesisBlockForState(ctx, si)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gbr, err := genb.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.WithField("el_block_time", gb.Time()).
|
||||
WithField("cl_genesis_time", genesis.GenesisTime).
|
||||
WithField("state_root", fmt.Sprintf("%#x", genb.Block().StateRoot())).
|
||||
WithField("latest_block_header_root", fmt.Sprintf("%#x", lbhr)).
|
||||
WithField("latest_block_header_state_root", fmt.Sprintf("%#x", genesis.LatestBlockHeader.StateRoot)).
|
||||
WithField("latest_block_header_parent_root", fmt.Sprintf("%#x", genesis.LatestBlockHeader.ParentRoot)).
|
||||
WithField("latest_block_header_body_root", fmt.Sprintf("%#x", genesis.LatestBlockHeader.BodyRoot)).
|
||||
WithField("derived_block_root", fmt.Sprintf("%#x", gbr)).
|
||||
WithField("el_block_root", fmt.Sprintf("%#x", genesis.Eth1Data.BlockHash)).
|
||||
Info("genesis eth1 data")
|
||||
return si, nil
|
||||
}
|
||||
|
||||
func (node *BeaconNode) saveGenesis(ctx context.Context) (string, error) {
|
||||
@ -279,6 +240,17 @@ func (node *BeaconNode) saveGenesis(ctx context.Context) (string, error) {
|
||||
return genesisPath, file.WriteFile(genesisPath, genesisBytes)
|
||||
}
|
||||
|
||||
func (node *BeaconNode) saveConfig() (string, error) {
|
||||
cfg := params.BeaconConfig().Copy()
|
||||
cfgBytes := params.ConfigToYaml(cfg)
|
||||
cfgDir := path.Join(e2e.TestParams.TestPath, fmt.Sprintf("config/%d", node.index))
|
||||
if err := file.MkdirAll(cfgDir); err != nil {
|
||||
return "", err
|
||||
}
|
||||
cfgPath := path.Join(cfgDir, "beacon-config.yaml")
|
||||
return cfgPath, file.WriteFile(cfgPath, cfgBytes)
|
||||
}
|
||||
|
||||
// Start starts a fresh beacon node, connecting to all passed in beacon nodes.
|
||||
func (node *BeaconNode) Start(ctx context.Context) error {
|
||||
binaryPath, found := bazel.FindBinary("cmd/beacon-chain", "beacon-chain")
|
||||
@ -309,6 +281,10 @@ func (node *BeaconNode) Start(ctx context.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfgPath, err := node.saveConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
args := []string{
|
||||
fmt.Sprintf("--%s=%s", genesis.StatePath.Name, genesisPath),
|
||||
fmt.Sprintf("--%s=%s/eth2-beacon-node-%d", cmdshared.DataDirFlag.Name, e2e.TestParams.TestPath, index),
|
||||
@ -329,8 +305,8 @@ func (node *BeaconNode) Start(ctx context.Context) error {
|
||||
fmt.Sprintf("--%s=%s", cmdshared.BootstrapNode.Name, enr),
|
||||
fmt.Sprintf("--%s=%s", cmdshared.VerbosityFlag.Name, "debug"),
|
||||
fmt.Sprintf("--%s=%d", flags.BlockBatchLimitBurstFactor.Name, 8),
|
||||
fmt.Sprintf("--%s=%s", cmdshared.ChainConfigFileFlag.Name, cfgPath),
|
||||
"--" + cmdshared.ForceClearDB.Name,
|
||||
"--" + cmdshared.E2EConfigFlag.Name,
|
||||
"--" + cmdshared.AcceptTosFlag.Name,
|
||||
"--" + flags.EnableDebugRPCEndpoints.Name,
|
||||
}
|
||||
@ -413,3 +389,35 @@ func (node *BeaconNode) Stop() error {
|
||||
func (node *BeaconNode) UnderlyingProcess() *os.Process {
|
||||
return node.cmd.Process
|
||||
}
|
||||
|
||||
func generateGenesisPhase0(ctx context.Context, e1d *ethpb.Eth1Data) (state.BeaconState, error) {
|
||||
g, _, err := interop.GeneratePreminedGenesisState(ctx, e2e.TestParams.CLGenesisTime, params.BeaconConfig().MinGenesisActiveValidatorCount, e1d)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return state_native.InitializeFromProtoUnsafePhase0(g)
|
||||
}
|
||||
|
||||
func generateGenesisBellatrix(ctx context.Context, gb *types.Block, e1d *ethpb.Eth1Data) (state.BeaconState, error) {
|
||||
payload := &enginev1.ExecutionPayload{
|
||||
ParentHash: gb.ParentHash().Bytes(),
|
||||
FeeRecipient: gb.Coinbase().Bytes(),
|
||||
StateRoot: gb.Root().Bytes(),
|
||||
ReceiptsRoot: gb.ReceiptHash().Bytes(),
|
||||
LogsBloom: gb.Bloom().Bytes(),
|
||||
PrevRandao: params.BeaconConfig().ZeroHash[:],
|
||||
BlockNumber: gb.NumberU64(),
|
||||
GasLimit: gb.GasLimit(),
|
||||
GasUsed: gb.GasUsed(),
|
||||
Timestamp: gb.Time(),
|
||||
ExtraData: gb.Extra()[:32],
|
||||
BaseFeePerGas: bytesutil.PadTo(bytesutil.ReverseByteOrder(gb.BaseFee().Bytes()), fieldparams.RootLength),
|
||||
BlockHash: gb.Hash().Bytes(),
|
||||
Transactions: make([][]byte, 0),
|
||||
}
|
||||
g, _, err := interop.GenerateGenesisStateBellatrix(ctx, e2e.TestParams.CLGenesisTime, params.BeaconConfig().MinGenesisActiveValidatorCount, payload, e1d)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return state_native.InitializeFromProtoUnsafeBellatrix(g)
|
||||
}
|
||||
|
@ -260,7 +260,7 @@ func (node *LighthouseBeaconNode) Stop() error {
|
||||
func (node *LighthouseBeaconNode) createTestnetDir(index int) (string, error) {
|
||||
testNetDir := e2e.TestParams.TestPath + fmt.Sprintf("/lighthouse-testnet-%d", index)
|
||||
configPath := filepath.Join(testNetDir, "config.yaml")
|
||||
rawYaml := params.E2EMainnetConfigYaml()
|
||||
rawYaml := params.ConfigToYaml(params.BeaconConfig())
|
||||
// Add in deposit contract in yaml
|
||||
depContractStr := fmt.Sprintf("\nDEPOSIT_CONTRACT_ADDRESS: %s", params.BeaconConfig().DepositContractAddress)
|
||||
rawYaml = append(rawYaml, []byte(depContractStr)...)
|
||||
|
@ -164,6 +164,17 @@ func NewValidatorNode(config *e2etypes.E2EConfig, validatorNum, index, offset in
|
||||
}
|
||||
}
|
||||
|
||||
func (node *ValidatorNode) saveConfig() (string, error) {
|
||||
cfg := params.BeaconConfig().Copy()
|
||||
cfgBytes := params.ConfigToYaml(cfg)
|
||||
cfgDir := path.Join(e2e.TestParams.TestPath, fmt.Sprintf("config/%d", node.index))
|
||||
if err := file.MkdirAll(cfgDir); err != nil {
|
||||
return "", err
|
||||
}
|
||||
cfgPath := path.Join(cfgDir, "validator-config.yaml")
|
||||
return cfgPath, file.WriteFile(cfgPath, cfgBytes)
|
||||
}
|
||||
|
||||
// Start starts a validator client.
|
||||
func (v *ValidatorNode) Start(ctx context.Context) error {
|
||||
validatorHexPubKeys := make([]string, 0)
|
||||
@ -206,6 +217,10 @@ func (v *ValidatorNode) Start(ctx context.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfgPath, err := v.saveConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
args := []string{
|
||||
fmt.Sprintf("--%s=%s/eth2-val-%d", cmdshared.DataDirFlag.Name, e2e.TestParams.TestPath, index),
|
||||
fmt.Sprintf("--%s=%s", cmdshared.LogFileName.Name, file.Name()),
|
||||
@ -217,8 +232,8 @@ func (v *ValidatorNode) Start(ctx context.Context) error {
|
||||
fmt.Sprintf("--%s=%s", flags.GrpcHeadersFlag.Name, "dummy=value,foo=bar"), // Sending random headers shouldn't break anything.
|
||||
fmt.Sprintf("--%s=%s", cmdshared.VerbosityFlag.Name, "debug"),
|
||||
fmt.Sprintf("--%s=%s", flags.ProposerSettingsFlag.Name, proposerSettingsPathPath),
|
||||
fmt.Sprintf("--%s=%s", cmdshared.ChainConfigFileFlag.Name, cfgPath),
|
||||
"--" + cmdshared.ForceClearDB.Name,
|
||||
"--" + cmdshared.E2EConfigFlag.Name,
|
||||
"--" + cmdshared.AcceptTosFlag.Name,
|
||||
}
|
||||
|
||||
@ -314,40 +329,26 @@ func (v *ValidatorNode) UnderlyingProcess() *os.Process {
|
||||
return v.cmd.Process
|
||||
}
|
||||
|
||||
func createProposerSettingsPath(pubkeys []string, validatorIndex int) (string, error) {
|
||||
testNetDir := e2e.TestParams.TestPath + fmt.Sprintf("/proposer-settings/validator_%d", validatorIndex)
|
||||
func createProposerSettingsPath(pubkeys []string, nodeIdx int) (string, error) {
|
||||
testNetDir := e2e.TestParams.TestPath + fmt.Sprintf("/proposer-settings/validator_%d", nodeIdx)
|
||||
configPath := filepath.Join(testNetDir, "config.json")
|
||||
if len(pubkeys) == 0 {
|
||||
return "", errors.New("number of validators must be greater than 0")
|
||||
}
|
||||
var proposerSettingsPayload validator_service_config.ProposerSettingsPayload
|
||||
if len(pubkeys) == 1 {
|
||||
proposerSettingsPayload = validator_service_config.ProposerSettingsPayload{
|
||||
DefaultConfig: &validator_service_config.ProposerOptionPayload{
|
||||
FeeRecipient: DefaultFeeRecipientAddress,
|
||||
},
|
||||
}
|
||||
} else {
|
||||
config := make(map[string]*validator_service_config.ProposerOptionPayload)
|
||||
config := make(map[string]*validator_service_config.ProposerOptionPayload)
|
||||
|
||||
for i, pubkey := range pubkeys {
|
||||
// Create an account
|
||||
byteval, err := hexutil.Decode(pubkey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
deterministicFeeRecipient := common.HexToAddress(hexutil.Encode(byteval[:fieldparams.FeeRecipientLength])).Hex()
|
||||
config[pubkeys[i]] = &validator_service_config.ProposerOptionPayload{
|
||||
FeeRecipient: deterministicFeeRecipient,
|
||||
}
|
||||
}
|
||||
proposerSettingsPayload = validator_service_config.ProposerSettingsPayload{
|
||||
ProposerConfig: config,
|
||||
DefaultConfig: &validator_service_config.ProposerOptionPayload{
|
||||
FeeRecipient: DefaultFeeRecipientAddress,
|
||||
},
|
||||
for i, pubkey := range pubkeys {
|
||||
config[pubkeys[i]] = &validator_service_config.ProposerOptionPayload{
|
||||
FeeRecipient: FeeRecipientFromPubkey(pubkey),
|
||||
}
|
||||
}
|
||||
proposerSettingsPayload = validator_service_config.ProposerSettingsPayload{
|
||||
ProposerConfig: config,
|
||||
DefaultConfig: &validator_service_config.ProposerOptionPayload{
|
||||
FeeRecipient: DefaultFeeRecipientAddress,
|
||||
},
|
||||
}
|
||||
jsonBytes, err := json.Marshal(proposerSettingsPayload)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -360,3 +361,10 @@ func createProposerSettingsPath(pubkeys []string, validatorIndex int) (string, e
|
||||
}
|
||||
return configPath, nil
|
||||
}
|
||||
|
||||
// FeeRecipientFromPubkey slices, from the beginning of the hex-encoded pubkey string, the 2 character 0x preamble
|
||||
// plus enough hex chars to fill out the fee_recipient byte value.
|
||||
func FeeRecipientFromPubkey(key string) string {
|
||||
// pubkey[:(2+fieldparams.FeeRecipientLength*2)] slicing 2 (for the 0x preamble) + 2 hex chars for each byte
|
||||
return common.HexToAddress(key[:(2 + fieldparams.FeeRecipientLength*2)]).Hex()
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ func (w *Web3RemoteSigner) Start(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
testDir, err := w.createTestnetDir()
|
||||
testDir, err := createTestnetDir()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -256,10 +256,14 @@ func writeKeystoreKeys(ctx context.Context, keystorePath string, numKeys uint64)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *Web3RemoteSigner) createTestnetDir() (string, error) {
|
||||
func (w *Web3RemoteSigner) UnderlyingProcess() *os.Process {
|
||||
return w.cmd.Process
|
||||
}
|
||||
|
||||
func createTestnetDir() (string, error) {
|
||||
testNetDir := e2e.TestParams.TestPath + "/web3signer-testnet"
|
||||
configPath := filepath.Join(testNetDir, "config.yaml")
|
||||
rawYaml := params.E2ETestConfigYaml()
|
||||
rawYaml := params.ConfigToYaml(params.BeaconConfig())
|
||||
// Add in deposit contract in yaml
|
||||
depContractStr := fmt.Sprintf("\nDEPOSIT_CONTRACT_ADDRESS: %s", params.BeaconConfig().DepositContractAddress)
|
||||
rawYaml = append(rawYaml, []byte(depContractStr)...)
|
||||
@ -273,7 +277,3 @@ func (w *Web3RemoteSigner) createTestnetDir() (string, error) {
|
||||
|
||||
return configPath, nil
|
||||
}
|
||||
|
||||
func (w *Web3RemoteSigner) UnderlyingProcess() *os.Process {
|
||||
return w.cmd.Process
|
||||
}
|
||||
|
@ -14,9 +14,9 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/require"
|
||||
)
|
||||
|
||||
func e2eMinimal(t *testing.T, cfgo ...types.E2EConfigOpt) *testRunner {
|
||||
func e2eMinimal(t *testing.T, v int, cfgo ...types.E2EConfigOpt) *testRunner {
|
||||
params.SetupTestConfigCleanup(t)
|
||||
params.OverrideBeaconConfig(params.E2ETestConfig().Copy())
|
||||
require.NoError(t, params.SetActive(types.StartAt(v, params.E2ETestConfig())))
|
||||
require.NoError(t, e2eParams.Init(t, e2eParams.StandardBeaconCount))
|
||||
|
||||
// Run for 12 epochs if not in long-running to confirm long-running has no issues.
|
||||
@ -87,9 +87,9 @@ func e2eMinimal(t *testing.T, cfgo ...types.E2EConfigOpt) *testRunner {
|
||||
return newTestRunner(t, testConfig)
|
||||
}
|
||||
|
||||
func e2eMainnet(t *testing.T, usePrysmSh, useMultiClient bool, cfgo ...types.E2EConfigOpt) *testRunner {
|
||||
func e2eMainnet(t *testing.T, usePrysmSh, useMultiClient bool, cfg *params.BeaconChainConfig, cfgo ...types.E2EConfigOpt) *testRunner {
|
||||
params.SetupTestConfigCleanup(t)
|
||||
params.OverrideBeaconConfig(params.E2EMainnetTestConfig())
|
||||
require.NoError(t, params.SetActive(cfg))
|
||||
if useMultiClient {
|
||||
require.NoError(t, e2eParams.InitMultiClient(t, e2eParams.StandardBeaconCount, e2eParams.StandardLighthouseNodeCount))
|
||||
} else {
|
||||
@ -153,6 +153,7 @@ func e2eMainnet(t *testing.T, usePrysmSh, useMultiClient bool, cfgo ...types.E2E
|
||||
for _, o := range cfgo {
|
||||
o(testConfig)
|
||||
}
|
||||
|
||||
// In the event we use the cross-client e2e option, we add in an additional
|
||||
// evaluator for multiclient runs to verify the beacon api conformance.
|
||||
if testConfig.UseValidatorCrossClient {
|
||||
|
@ -31,7 +31,6 @@ go_library(
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//container/slice:go_default_library",
|
||||
"//crypto/bls:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//math:go_default_library",
|
||||
"//network/forks:go_default_library",
|
||||
|
@ -1,6 +1,7 @@
|
||||
package evaluators
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
@ -9,9 +10,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/pkg/errors"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v3/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v3/crypto/bls"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v3/runtime/interop"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/endtoend/components"
|
||||
@ -19,6 +18,7 @@ import (
|
||||
e2e "github.com/prysmaticlabs/prysm/v3/testing/endtoend/params"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/endtoend/policies"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/endtoend/types"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
@ -29,6 +29,39 @@ var FeeRecipientIsPresent = types.Evaluator{
|
||||
Evaluation: feeRecipientIsPresent,
|
||||
}
|
||||
|
||||
func lhKeyMap() (map[string]bool, error) {
|
||||
if e2e.TestParams.LighthouseBeaconNodeCount == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
pry, lh := e2e.TestParams.BeaconNodeCount, e2e.TestParams.LighthouseBeaconNodeCount
|
||||
valPerNode := int(params.BeaconConfig().MinGenesisActiveValidatorCount) / (pry + lh)
|
||||
lhOff := valPerNode * pry
|
||||
_, keys, err := interop.DeterministicallyGenerateKeys(uint64(lhOff), uint64(valPerNode*lh))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
km := make(map[string]bool)
|
||||
for _, k := range keys {
|
||||
km[hexutil.Encode(k.Marshal())] = true
|
||||
}
|
||||
return km, nil
|
||||
}
|
||||
|
||||
func valKeyMap() (map[string]bool, error) {
|
||||
nvals := params.BeaconConfig().MinGenesisActiveValidatorCount
|
||||
// matches validator start in validator component + validators used for deposits
|
||||
_, pubs, err := interop.DeterministicallyGenerateKeys(0, nvals+e2e.DepositCount)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
km := make(map[string]bool)
|
||||
for _, k := range pubs {
|
||||
km[hexutil.Encode(k.Marshal())] = true
|
||||
}
|
||||
return km, nil
|
||||
}
|
||||
|
||||
func feeRecipientIsPresent(_ types.EvaluationContext, conns ...*grpc.ClientConn) error {
|
||||
conn := conns[0]
|
||||
client := ethpb.NewBeaconChainClient(conn)
|
||||
@ -47,97 +80,98 @@ func feeRecipientIsPresent(_ types.EvaluationContext, conns ...*grpc.ClientConn)
|
||||
return err
|
||||
}
|
||||
defer rpcclient.Close()
|
||||
web3 := ethclient.NewClient(rpcclient)
|
||||
ctx := context.Background()
|
||||
|
||||
validatorNum := int(params.BeaconConfig().MinGenesisActiveValidatorCount)
|
||||
_, pubs, err := interop.DeterministicallyGenerateKeys(uint64(0), uint64(validatorNum+int(e2e.DepositCount))) // matches validator start in validator component + validators used for deposits
|
||||
valkeys, err := valKeyMap()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lighthouseKeys := []bls.PublicKey{}
|
||||
if e2e.TestParams.LighthouseBeaconNodeCount != 0 {
|
||||
totalNodecount := e2e.TestParams.BeaconNodeCount + e2e.TestParams.LighthouseBeaconNodeCount
|
||||
valPerNode := validatorNum / totalNodecount
|
||||
lighthouseOffset := valPerNode * e2e.TestParams.BeaconNodeCount
|
||||
|
||||
_, lighthouseKeys, err = interop.DeterministicallyGenerateKeys(uint64(lighthouseOffset), uint64(valPerNode*e2e.TestParams.LighthouseBeaconNodeCount))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lhkeys, err := lhKeyMap()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, ctr := range blks.BlockContainers {
|
||||
if fr := ctr.GetBellatrixBlock(); fr != nil {
|
||||
var account common.Address
|
||||
|
||||
fr := ctr.GetBellatrixBlock().Block.Body.ExecutionPayload.FeeRecipient
|
||||
if len(fr) != 0 && hexutil.Encode(fr) != params.BeaconConfig().EthBurnAddressHex {
|
||||
account = common.BytesToAddress(fr)
|
||||
} else {
|
||||
if ctr.GetBellatrixBlock() != nil {
|
||||
bb := ctr.GetBellatrixBlock().Block
|
||||
payload := bb.Body.ExecutionPayload
|
||||
// If the beacon chain has transitioned to Bellatrix, but the EL hasn't hit TTD, we could see a few slots
|
||||
// of blocks with empty payloads.
|
||||
if bytes.Equal(payload.BlockHash, make([]byte, 32)) {
|
||||
continue
|
||||
}
|
||||
if len(payload.FeeRecipient) == 0 || hexutil.Encode(payload.FeeRecipient) == params.BeaconConfig().EthBurnAddressHex {
|
||||
log.WithField("proposer_index", bb.ProposerIndex).WithField("slot", bb.Slot).Error("fee recipient eval bug")
|
||||
return errors.New("fee recipient is not set")
|
||||
}
|
||||
validatorRequest := ðpb.GetValidatorRequest{
|
||||
|
||||
fr := common.BytesToAddress(payload.FeeRecipient)
|
||||
gvr := ðpb.GetValidatorRequest{
|
||||
QueryFilter: ðpb.GetValidatorRequest_Index{
|
||||
Index: ctr.GetBellatrixBlock().Block.ProposerIndex,
|
||||
},
|
||||
}
|
||||
validator, err := client.GetValidator(context.Background(), validatorRequest)
|
||||
validator, err := client.GetValidator(context.Background(), gvr)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get validators")
|
||||
}
|
||||
publickey := validator.GetPublicKey()
|
||||
isDeterministicKey := false
|
||||
isLighthouseKey := false
|
||||
pk := hexutil.Encode(validator.GetPublicKey())
|
||||
|
||||
// If lighthouse keys are present, we skip the check.
|
||||
for _, pub := range lighthouseKeys {
|
||||
if hexutil.Encode(publickey) == hexutil.Encode(pub.Marshal()) {
|
||||
isLighthouseKey = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if isLighthouseKey {
|
||||
if _, ok := lhkeys[pk]; ok {
|
||||
// Don't check lighthouse keys.
|
||||
continue
|
||||
}
|
||||
for _, pub := range pubs {
|
||||
if hexutil.Encode(publickey) == hexutil.Encode(pub.Marshal()) {
|
||||
isDeterministicKey = true
|
||||
break
|
||||
}
|
||||
}
|
||||
// calculate deterministic fee recipient using first 20 bytes of public key
|
||||
deterministicFeeRecipient := common.HexToAddress(hexutil.Encode(publickey[:fieldparams.FeeRecipientLength])).Hex()
|
||||
if isDeterministicKey && deterministicFeeRecipient != account.Hex() {
|
||||
return fmt.Errorf("publickey %s, fee recipient %s does not match the proposer settings fee recipient %s",
|
||||
hexutil.Encode(publickey), account.Hex(), deterministicFeeRecipient)
|
||||
}
|
||||
if !isDeterministicKey && components.DefaultFeeRecipientAddress != account.Hex() {
|
||||
return fmt.Errorf("publickey %s, fee recipient %s does not match the default fee recipient %s",
|
||||
hexutil.Encode(publickey), account.Hex(), components.DefaultFeeRecipientAddress)
|
||||
}
|
||||
currentBlock, err := web3.BlockByHash(ctx, common.BytesToHash(ctr.GetBellatrixBlock().GetBlock().GetBody().GetExecutionPayload().BlockHash))
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
// In e2e we generate deterministic keys by validator index, and then use a slice of their public key bytes
|
||||
// as the fee recipient, so that this will also be deterministic, so this test can statelessly verify it.
|
||||
// These should be the only keys we see.
|
||||
// Otherwise something has changed in e2e and this test needs to be updated.
|
||||
_, knownKey := valkeys[pk]
|
||||
if !knownKey {
|
||||
log.WithField("pubkey", pk).
|
||||
WithField("slot", bb.Slot).
|
||||
WithField("proposer_index", bb.ProposerIndex).
|
||||
WithField("fee_recipient", fr.Hex()).
|
||||
Warn("unknown key observed, not a deterministically generated key")
|
||||
return errors.New("unknown key observed, not a deterministically generated key")
|
||||
}
|
||||
|
||||
accountBalance, err := web3.BalanceAt(ctx, account, currentBlock.Number())
|
||||
if err != nil {
|
||||
return err
|
||||
if components.FeeRecipientFromPubkey(pk) != fr.Hex() {
|
||||
return fmt.Errorf("publickey %s, fee recipient %s does not match the proposer settings fee recipient %s",
|
||||
pk, fr.Hex(), components.FeeRecipientFromPubkey(pk))
|
||||
}
|
||||
previousBlock, err := web3.BlockByHash(ctx, common.BytesToHash(ctr.GetBellatrixBlock().GetBlock().GetBody().GetExecutionPayload().ParentHash))
|
||||
if err != nil {
|
||||
|
||||
if err := checkRecipientBalance(rpcclient, common.BytesToHash(payload.BlockHash), common.BytesToHash(payload.ParentHash), fr); err != nil {
|
||||
return err
|
||||
}
|
||||
prevAccountBalance, err := web3.BalanceAt(ctx, account, previousBlock.Number())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if currentBlock.GasUsed() > 0 && accountBalance.Uint64() <= prevAccountBalance.Uint64() {
|
||||
return errors.Errorf("account balance didn't change after applying fee recipient for account: %s", account.Hex())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkRecipientBalance(c *rpc.Client, block, parent common.Hash, account common.Address) error {
|
||||
web3 := ethclient.NewClient(c)
|
||||
ctx := context.Background()
|
||||
b, err := web3.BlockByHash(ctx, block)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bal, err := web3.BalanceAt(ctx, account, b.Number())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pBlock, err := web3.BlockByHash(ctx, parent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pBal, err := web3.BalanceAt(ctx, account, pBlock.Number())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if b.GasUsed() > 0 && bal.Uint64() <= pBal.Uint64() {
|
||||
return errors.Errorf("account balance didn't change after applying fee recipient for account: %s", account.Hex())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -7,8 +7,6 @@ import (
|
||||
"math"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
corehelpers "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v3/beacon-chain/core/signing"
|
||||
@ -256,7 +254,6 @@ func getAllValidators(c ethpb.BeaconChainClient) ([]*ethpb.Validator, error) {
|
||||
vals = append(vals, v.Validator)
|
||||
}
|
||||
pageToken = validators.NextPageToken
|
||||
log.WithField("len", len(vals)).WithField("pageToken", pageToken).Info("getAllValidators")
|
||||
}
|
||||
return vals, nil
|
||||
}
|
||||
@ -425,6 +422,7 @@ func validatorsVoteWithTheMajority(_ e2etypes.EvaluationContext, conns ...*grpc.
|
||||
default:
|
||||
return errors.New("block neither phase0,altair or bellatrix")
|
||||
}
|
||||
seenVotes[slot] = vote
|
||||
|
||||
// We treat epoch 1 differently from other epoch for two reasons:
|
||||
// - this evaluator is not executed for epoch 0 so we have to calculate the first slot differently
|
||||
@ -445,6 +443,14 @@ func validatorsVoteWithTheMajority(_ e2etypes.EvaluationContext, conns ...*grpc.
|
||||
}
|
||||
|
||||
if !bytes.Equal(vote, expectedEth1DataVote) {
|
||||
for i := types.Slot(0); i < slot; i++ {
|
||||
v, ok := seenVotes[i]
|
||||
if ok {
|
||||
fmt.Printf("vote at slot=%d = %#x\n", i, v)
|
||||
} else {
|
||||
fmt.Printf("did not see slot=%d\n", i)
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("incorrect eth1data vote for slot %d; expected: %#x vs voted: %#x",
|
||||
slot, expectedEth1DataVote, vote)
|
||||
}
|
||||
@ -452,4 +458,5 @@ func validatorsVoteWithTheMajority(_ e2etypes.EvaluationContext, conns ...*grpc.
|
||||
return nil
|
||||
}
|
||||
|
||||
var seenVotes = make(map[types.Slot][]byte)
|
||||
var expectedEth1DataVote []byte
|
||||
|
1
testing/endtoend/fork.go
Normal file
1
testing/endtoend/fork.go
Normal file
@ -0,0 +1 @@
|
||||
package endtoend
|
@ -2,9 +2,14 @@ package endtoend
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v3/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v3/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/endtoend/types"
|
||||
)
|
||||
|
||||
// Run mainnet e2e config with the current release validator against latest beacon node.
|
||||
func TestEndToEnd_MainnetConfig_ValidatorAtCurrentRelease(t *testing.T) {
|
||||
e2eMainnet(t, true, false).run()
|
||||
r := e2eMainnet(t, true, false, types.StartAt(version.Phase0, params.E2EMainnetTestConfig()))
|
||||
r.run()
|
||||
}
|
||||
|
@ -3,15 +3,16 @@ package endtoend
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v3/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/endtoend/types"
|
||||
)
|
||||
|
||||
func TestEndToEnd_MainnetConfig_MultiClient(t *testing.T) {
|
||||
e2eMainnet(t, false /*usePrysmSh*/, true /*useMultiClient*/, types.WithValidatorCrossClient()).run()
|
||||
e2eMainnet(t, false, true, params.E2EMainnetTestConfig().Copy(), types.WithValidatorCrossClient()).run()
|
||||
}
|
||||
|
||||
func TestEndToEnd_MultiScenarioRun_Multiclient(t *testing.T) {
|
||||
runner := e2eMainnet(t, false /*usePrysmSh*/, true /*useMultiClient*/, types.WithEpochs(22))
|
||||
runner := e2eMainnet(t, false, true, params.E2EMainnetTestConfig().Copy(), types.WithEpochs(22))
|
||||
runner.config.Evaluators = scenarioEvalsMulti()
|
||||
runner.config.EvalInterceptor = runner.multiScenarioMulticlient
|
||||
runner.scenarioRunner()
|
||||
|
@ -3,9 +3,11 @@ package endtoend
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v3/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/endtoend/types"
|
||||
)
|
||||
|
||||
func TestEndToEnd_MinimalConfig(t *testing.T) {
|
||||
e2eMinimal(t, types.WithCheckpointSync()).run()
|
||||
r := e2eMinimal(t, version.Phase0, types.WithCheckpointSync())
|
||||
r.run()
|
||||
}
|
||||
|
@ -3,11 +3,12 @@ package endtoend
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v3/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/endtoend/types"
|
||||
)
|
||||
|
||||
func TestEndToEnd_MultiScenarioRun(t *testing.T) {
|
||||
runner := e2eMinimal(t, types.WithEpochs(22))
|
||||
runner := e2eMinimal(t, version.Phase0, types.WithEpochs(22))
|
||||
|
||||
runner.config.Evaluators = scenarioEvals()
|
||||
runner.config.EvalInterceptor = runner.multiScenario
|
||||
@ -15,16 +16,16 @@ func TestEndToEnd_MultiScenarioRun(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEndToEnd_MinimalConfig_Web3Signer(t *testing.T) {
|
||||
e2eMinimal(t, types.WithRemoteSigner()).run()
|
||||
e2eMinimal(t, version.Phase0, types.WithRemoteSigner()).run()
|
||||
}
|
||||
|
||||
func TestEndToEnd_MinimalConfig_ValidatorRESTApi(t *testing.T) {
|
||||
e2eMinimal(t, types.WithCheckpointSync(), types.WithValidatorRESTApi()).run()
|
||||
e2eMinimal(t, version.Phase0, types.WithCheckpointSync(), types.WithValidatorRESTApi()).run()
|
||||
}
|
||||
|
||||
func TestEndToEnd_ScenarioRun_EEOffline(t *testing.T) {
|
||||
t.Skip("TODO(#10242) Prysm is current unable to handle an offline e2e")
|
||||
runner := e2eMinimal(t)
|
||||
runner := e2eMinimal(t, version.Phase0)
|
||||
|
||||
runner.config.Evaluators = scenarioEvals()
|
||||
runner.config.EvalInterceptor = runner.eeOffline
|
||||
|
@ -5,12 +5,15 @@ go_library(
|
||||
testonly = True,
|
||||
srcs = [
|
||||
"empty.go",
|
||||
"fork.go",
|
||||
"types.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v3/testing/endtoend/types",
|
||||
visibility = ["//testing/endtoend:__subpackages__"],
|
||||
deps = [
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"@org_golang_google_grpc//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
26
testing/endtoend/types/fork.go
Normal file
26
testing/endtoend/types/fork.go
Normal file
@ -0,0 +1,26 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v3/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v3/runtime/version"
|
||||
)
|
||||
|
||||
func StartAt(v int, c *params.BeaconChainConfig) *params.BeaconChainConfig {
|
||||
c = c.Copy()
|
||||
if v >= version.Altair {
|
||||
c.AltairForkEpoch = 0
|
||||
}
|
||||
if v >= version.Bellatrix {
|
||||
c.BellatrixForkEpoch = 0
|
||||
}
|
||||
if v >= version.Capella {
|
||||
c.CapellaForkEpoch = 0
|
||||
}
|
||||
// Time TTD to line up roughly with the bellatrix fork epoch.
|
||||
// E2E sets EL block production rate equal to SecondsPerETH1Block to keep the math simple.
|
||||
ttd := uint64(c.BellatrixForkEpoch) * uint64(c.SlotsPerEpoch) * c.SecondsPerSlot
|
||||
c.TerminalTotalDifficulty = fmt.Sprintf("%d", ttd)
|
||||
return c
|
||||
}
|
@ -6,7 +6,9 @@ import (
|
||||
"context"
|
||||
"os"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v3/config/params"
|
||||
types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v3/runtime/version"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
@ -65,6 +67,20 @@ type E2EConfig struct {
|
||||
ExtraEpochs uint64
|
||||
}
|
||||
|
||||
func GenesisFork() int {
|
||||
cfg := params.BeaconConfig()
|
||||
if cfg.CapellaForkEpoch == 0 {
|
||||
return version.Capella
|
||||
}
|
||||
if cfg.BellatrixForkEpoch == 0 {
|
||||
return version.Bellatrix
|
||||
}
|
||||
if cfg.AltairForkEpoch == 0 {
|
||||
return version.Altair
|
||||
}
|
||||
return version.Phase0
|
||||
}
|
||||
|
||||
// Evaluator defines the structure of the evaluators used to
|
||||
// conduct the current beacon state during the E2E.
|
||||
type Evaluator struct {
|
||||
|
Loading…
Reference in New Issue
Block a user