Merge remote-tracking branch 'origin/unstable' into tree-states

This commit is contained in:
Michael Sproul
2022-02-02 16:02:33 +11:00
108 changed files with 4838 additions and 928 deletions

View File

@@ -596,6 +596,161 @@ impl ChainSpec {
..ChainSpec::mainnet()
}
}
/// Returns a `ChainSpec` compatible with the Gnosis Beacon Chain specification.
pub fn gnosis() -> Self {
Self {
/*
* Constants
*/
genesis_slot: Slot::new(0),
far_future_epoch: Epoch::new(u64::MAX),
base_rewards_per_epoch: 4,
deposit_contract_tree_depth: 32,
/*
* Misc
*/
max_committees_per_slot: 64,
target_committee_size: 128,
min_per_epoch_churn_limit: 4,
churn_limit_quotient: 4_096,
shuffle_round_count: 90,
min_genesis_active_validator_count: 4_096,
min_genesis_time: 1638968400, // Dec 8, 2020
hysteresis_quotient: 4,
hysteresis_downward_multiplier: 1,
hysteresis_upward_multiplier: 5,
/*
* Gwei values
*/
min_deposit_amount: option_wrapper(|| {
u64::checked_pow(2, 0)?.checked_mul(u64::checked_pow(10, 9)?)
})
.expect("calculation does not overflow"),
max_effective_balance: option_wrapper(|| {
u64::checked_pow(2, 5)?.checked_mul(u64::checked_pow(10, 9)?)
})
.expect("calculation does not overflow"),
ejection_balance: option_wrapper(|| {
u64::checked_pow(2, 4)?.checked_mul(u64::checked_pow(10, 9)?)
})
.expect("calculation does not overflow"),
effective_balance_increment: option_wrapper(|| {
u64::checked_pow(2, 0)?.checked_mul(u64::checked_pow(10, 9)?)
})
.expect("calculation does not overflow"),
/*
* Initial Values
*/
genesis_fork_version: [0x00, 0x00, 0x00, 0x64],
bls_withdrawal_prefix_byte: 0,
/*
* Time parameters
*/
genesis_delay: 6000, // 100 minutes
seconds_per_slot: 5,
min_attestation_inclusion_delay: 1,
min_seed_lookahead: Epoch::new(1),
max_seed_lookahead: Epoch::new(4),
min_epochs_to_inactivity_penalty: 4,
min_validator_withdrawability_delay: Epoch::new(256),
shard_committee_period: 256,
/*
* Reward and penalty quotients
*/
base_reward_factor: 25,
whistleblower_reward_quotient: 512,
proposer_reward_quotient: 8,
inactivity_penalty_quotient: u64::checked_pow(2, 26).expect("pow does not overflow"),
min_slashing_penalty_quotient: 128,
proportional_slashing_multiplier: 1,
/*
* Signature domains
*/
domain_beacon_proposer: 0,
domain_beacon_attester: 1,
domain_randao: 2,
domain_deposit: 3,
domain_voluntary_exit: 4,
domain_selection_proof: 5,
domain_aggregate_and_proof: 6,
/*
* Fork choice
*/
safe_slots_to_update_justified: 8,
proposer_score_boost: None,
/*
* Eth1
*/
eth1_follow_distance: 1024,
seconds_per_eth1_block: 6,
deposit_chain_id: 100,
deposit_network_id: 100,
deposit_contract_address: "0B98057eA310F4d31F2a452B414647007d1645d9"
.parse()
.expect("chain spec deposit contract address"),
/*
* Altair hard fork params
*/
inactivity_penalty_quotient_altair: option_wrapper(|| {
u64::checked_pow(2, 24)?.checked_mul(3)
})
.expect("calculation does not overflow"),
min_slashing_penalty_quotient_altair: u64::checked_pow(2, 6)
.expect("pow does not overflow"),
proportional_slashing_multiplier_altair: 2,
inactivity_score_bias: 4,
inactivity_score_recovery_rate: 16,
min_sync_committee_participants: 1,
epochs_per_sync_committee_period: Epoch::new(512),
domain_sync_committee: 7,
domain_sync_committee_selection_proof: 8,
domain_contribution_and_proof: 9,
altair_fork_version: [0x01, 0x00, 0x00, 0x64],
altair_fork_epoch: Some(Epoch::new(256)),
/*
* Merge hard fork params
*/
inactivity_penalty_quotient_bellatrix: u64::checked_pow(2, 24)
.expect("pow does not overflow"),
min_slashing_penalty_quotient_bellatrix: u64::checked_pow(2, 5)
.expect("pow does not overflow"),
proportional_slashing_multiplier_bellatrix: 3,
bellatrix_fork_version: [0x02, 0x00, 0x00, 0x64],
bellatrix_fork_epoch: None,
terminal_total_difficulty: Uint256::MAX
.checked_sub(Uint256::from(2u64.pow(10)))
.expect("subtraction does not overflow")
// Add 1 since the spec declares `2**256 - 2**10` and we use
// `Uint256::MAX` which is `2*256- 1`.
.checked_add(Uint256::one())
.expect("addition does not overflow"),
terminal_block_hash: Hash256::zero(),
terminal_block_hash_activation_epoch: Epoch::new(u64::MAX),
/*
* Network specific
*/
boot_nodes: vec![],
network_id: 100, // Gnosis Chain network id
attestation_propagation_slot_range: 32,
attestation_subnet_count: 64,
random_subnets_per_validator: 1,
maximum_gossip_clock_disparity_millis: 500,
target_aggregators_per_committee: 16,
epochs_per_random_subnet_subscription: 256,
}
}
}
impl Default for ChainSpec {
@@ -688,10 +843,16 @@ fn default_bellatrix_fork_epoch() -> Option<MaybeQuoted<Epoch>> {
None
}
fn default_terminal_total_difficulty() -> Uint256 {
"115792089237316195423570985008687907853269984665640564039457584007913129638912"
.parse()
.unwrap()
/// Placeholder value: 2^256-2^10 (115792089237316195423570985008687907853269984665640564039457584007913129638912).
///
/// Taken from https://github.com/ethereum/consensus-specs/blob/d5e4828aecafaf1c57ef67a5f23c4ae7b08c5137/configs/mainnet.yaml#L15-L16
const fn default_terminal_total_difficulty() -> Uint256 {
ethereum_types::U256([
18446744073709550592,
18446744073709551615,
18446744073709551615,
18446744073709551615,
])
}
fn default_terminal_block_hash() -> Hash256 {
@@ -746,6 +907,7 @@ impl Config {
match self.preset_base.as_str() {
"minimal" => Some(EthSpecId::Minimal),
"mainnet" => Some(EthSpecId::Mainnet),
"gnosis" => Some(EthSpecId::Gnosis),
_ => None,
}
}
@@ -1038,4 +1200,73 @@ mod yaml_tests {
.expect("should have applied spec");
assert_eq!(new_spec, ChainSpec::minimal());
}
#[test]
fn test_defaults() {
// Spec yaml string. Fields that serialize/deserialize with a default value are commented out.
let spec = r#"
PRESET_BASE: 'mainnet'
#TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129638911
#TERMINAL_BLOCK_HASH: 0x0000000000000000000000000000000000000000000000000000000000000001
#TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: 18446744073709551614
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 16384
MIN_GENESIS_TIME: 1606824000
GENESIS_FORK_VERSION: 0x00000000
GENESIS_DELAY: 604800
ALTAIR_FORK_VERSION: 0x01000000
ALTAIR_FORK_EPOCH: 74240
#BELLATRIX_FORK_VERSION: 0x02000000
#BELLATRIX_FORK_EPOCH: 18446744073709551614
SHARDING_FORK_VERSION: 0x03000000
SHARDING_FORK_EPOCH: 18446744073709551615
SECONDS_PER_SLOT: 12
SECONDS_PER_ETH1_BLOCK: 14
MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256
SHARD_COMMITTEE_PERIOD: 256
ETH1_FOLLOW_DISTANCE: 2048
INACTIVITY_SCORE_BIAS: 4
INACTIVITY_SCORE_RECOVERY_RATE: 16
EJECTION_BALANCE: 16000000000
MIN_PER_EPOCH_CHURN_LIMIT: 4
CHURN_LIMIT_QUOTIENT: 65536
PROPOSER_SCORE_BOOST: 70
DEPOSIT_CHAIN_ID: 1
DEPOSIT_NETWORK_ID: 1
DEPOSIT_CONTRACT_ADDRESS: 0x00000000219ab540356cBB839Cbe05303d7705Fa
"#;
let chain_spec: Config = serde_yaml::from_str(spec).unwrap();
assert_eq!(
chain_spec.terminal_total_difficulty,
default_terminal_total_difficulty()
);
assert_eq!(
chain_spec.terminal_block_hash,
default_terminal_block_hash()
);
assert_eq!(
chain_spec.terminal_block_hash_activation_epoch,
default_terminal_block_hash_activation_epoch()
);
assert_eq!(
chain_spec.bellatrix_fork_epoch,
default_bellatrix_fork_epoch()
);
assert_eq!(
chain_spec.bellatrix_fork_version,
default_bellatrix_fork_version()
);
}
#[test]
fn test_total_terminal_difficulty() {
assert_eq!(
Ok(default_terminal_total_difficulty()),
Uint256::from_dec_str(
"115792089237316195423570985008687907853269984665640564039457584007913129638912"
)
);
}
}

View File

@@ -3,17 +3,17 @@ use crate::*;
use safe_arith::SafeArith;
use serde_derive::{Deserialize, Serialize};
use ssz_types::typenum::{
Unsigned, U0, U1024, U1073741824, U1099511627776, U128, U16, U16777216, U2, U2048, U32, U4,
U4096, U512, U64, U65536, U8, U8192,
bit::B0, UInt, Unsigned, U0, U1024, U1048576, U1073741824, U1099511627776, U128, U16,
U16777216, U2, U2048, U256, U32, U4, U4096, U512, U625, U64, U65536, U8, U8192,
};
use std::fmt::{self, Debug};
use std::str::FromStr;
use ssz_types::typenum::{bit::B0, UInt, U1048576, U256, U625};
pub type U5000 = UInt<UInt<UInt<U625, B0>, B0>, B0>; // 625 * 8 = 5000
const MAINNET: &str = "mainnet";
const MINIMAL: &str = "minimal";
pub const GNOSIS: &str = "gnosis";
/// Used to identify one of the `EthSpec` instances defined here.
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
@@ -21,6 +21,7 @@ const MINIMAL: &str = "minimal";
pub enum EthSpecId {
Mainnet,
Minimal,
Gnosis,
}
impl FromStr for EthSpecId {
@@ -30,6 +31,7 @@ impl FromStr for EthSpecId {
match s {
MAINNET => Ok(EthSpecId::Mainnet),
MINIMAL => Ok(EthSpecId::Minimal),
GNOSIS => Ok(EthSpecId::Gnosis),
_ => Err(format!("Unknown eth spec: {}", s)),
}
}
@@ -40,6 +42,7 @@ impl fmt::Display for EthSpecId {
let s = match self {
EthSpecId::Mainnet => MAINNET,
EthSpecId::Minimal => MINIMAL,
EthSpecId::Gnosis => GNOSIS,
};
write!(f, "{}", s)
}
@@ -317,3 +320,46 @@ impl EthSpec for MinimalEthSpec {
EthSpecId::Minimal
}
}
/// Gnosis Beacon Chain specifications.
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize, Deserialize)]
pub struct GnosisEthSpec;
impl EthSpec for GnosisEthSpec {
type JustificationBitsLength = U4;
type SubnetBitfieldLength = U64;
type MaxValidatorsPerCommittee = U2048;
type GenesisEpoch = U0;
type SlotsPerEpoch = U16;
type EpochsPerEth1VotingPeriod = U64;
type SlotsPerHistoricalRoot = U8192;
type EpochsPerHistoricalVector = U65536;
type EpochsPerSlashingsVector = U8192;
type HistoricalRootsLimit = U16777216;
type ValidatorRegistryLimit = U1099511627776;
type MaxProposerSlashings = U16;
type MaxAttesterSlashings = U2;
type MaxAttestations = U128;
type MaxDeposits = U16;
type MaxVoluntaryExits = U16;
type SyncCommitteeSize = U512;
type SyncCommitteeSubnetCount = U4;
type MaxBytesPerTransaction = U1073741824; // 1,073,741,824
type MaxTransactionsPerPayload = U1048576; // 1,048,576
type BytesPerLogsBloom = U256;
type GasLimitDenominator = U1024;
type MinGasLimit = U5000;
type MaxExtraDataBytes = U32;
type SyncSubcommitteeSize = U128; // 512 committee size / 4 sync committee subnet count
type MaxPendingAttestations = U2048; // 128 max attestations * 16 slots per epoch
type SlotsPerEth1VotingPeriod = U1024; // 64 epochs * 16 slots per epoch
fn default_spec() -> ChainSpec {
ChainSpec::gnosis()
}
fn spec_name() -> EthSpecId {
EthSpecId::Gnosis
}
}

View File

@@ -187,7 +187,7 @@ impl BellatrixPreset {
#[cfg(test)]
mod test {
use super::*;
use crate::{MainnetEthSpec, MinimalEthSpec};
use crate::{GnosisEthSpec, MainnetEthSpec, MinimalEthSpec};
use serde::de::DeserializeOwned;
use std::env;
use std::fs::File;
@@ -226,6 +226,11 @@ mod test {
preset_test::<MainnetEthSpec>();
}
#[test]
fn gnosis_presets_consistent() {
preset_test::<GnosisEthSpec>();
}
#[test]
fn minimal_presets_consistent() {
preset_test::<MinimalEthSpec>();