mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-03 00:31:50 +00:00
Use eth1_withdrawal_credentials in Test States (#3898)
* Use eth1_withdrawal_credential in Some Test States * Update beacon_node/genesis/src/interop.rs Co-authored-by: Michael Sproul <micsproul@gmail.com> * Update beacon_node/genesis/src/interop.rs Co-authored-by: Michael Sproul <micsproul@gmail.com> * Increase validator sizes * Pick next sync committee message Co-authored-by: Michael Sproul <micsproul@gmail.com> Co-authored-by: Paul Hauner <paul@paulhauner.com>
This commit is contained in:
@@ -10,6 +10,20 @@ use types::{
|
||||
|
||||
pub const DEFAULT_ETH1_BLOCK_HASH: &[u8] = &[0x42; 32];
|
||||
|
||||
fn bls_withdrawal_credentials(pubkey: &PublicKey, spec: &ChainSpec) -> Hash256 {
|
||||
let mut credentials = hash(&pubkey.as_ssz_bytes());
|
||||
credentials[0] = spec.bls_withdrawal_prefix_byte;
|
||||
Hash256::from_slice(&credentials)
|
||||
}
|
||||
|
||||
fn eth1_withdrawal_credentials(pubkey: &PublicKey, spec: &ChainSpec) -> Hash256 {
|
||||
let fake_execution_address = &hash(&pubkey.as_ssz_bytes())[0..20];
|
||||
let mut credentials = [0u8; 32];
|
||||
credentials[0] = spec.eth1_address_withdrawal_prefix_byte;
|
||||
credentials[12..].copy_from_slice(fake_execution_address);
|
||||
Hash256::from_slice(&credentials)
|
||||
}
|
||||
|
||||
/// Builds a genesis state as defined by the Eth2 interop procedure (see below).
|
||||
///
|
||||
/// Reference:
|
||||
@@ -24,17 +38,67 @@ pub fn interop_genesis_state<T: EthSpec>(
|
||||
let eth1_timestamp = 2_u64.pow(40);
|
||||
let amount = spec.max_effective_balance;
|
||||
|
||||
let withdrawal_credentials = |pubkey: &PublicKey| {
|
||||
let mut credentials = hash(&pubkey.as_ssz_bytes());
|
||||
credentials[0] = spec.bls_withdrawal_prefix_byte;
|
||||
Hash256::from_slice(&credentials)
|
||||
};
|
||||
|
||||
let datas = keypairs
|
||||
.into_par_iter()
|
||||
.map(|keypair| {
|
||||
let mut data = DepositData {
|
||||
withdrawal_credentials: withdrawal_credentials(&keypair.pk),
|
||||
withdrawal_credentials: bls_withdrawal_credentials(&keypair.pk, spec),
|
||||
pubkey: keypair.pk.clone().into(),
|
||||
amount,
|
||||
signature: Signature::empty().into(),
|
||||
};
|
||||
|
||||
data.signature = data.create_signature(&keypair.sk, spec);
|
||||
|
||||
data
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut state = initialize_beacon_state_from_eth1(
|
||||
eth1_block_hash,
|
||||
eth1_timestamp,
|
||||
genesis_deposits(datas, spec)?,
|
||||
execution_payload_header,
|
||||
spec,
|
||||
)
|
||||
.map_err(|e| format!("Unable to initialize genesis state: {:?}", e))?;
|
||||
|
||||
*state.genesis_time_mut() = genesis_time;
|
||||
|
||||
// Invalidate all the caches after all the manual state surgery.
|
||||
state
|
||||
.drop_all_caches()
|
||||
.map_err(|e| format!("Unable to drop caches: {:?}", e))?;
|
||||
|
||||
Ok(state)
|
||||
}
|
||||
|
||||
// returns an interop genesis state except every other
|
||||
// validator has eth1 withdrawal credentials
|
||||
pub fn interop_genesis_state_with_eth1<T: EthSpec>(
|
||||
keypairs: &[Keypair],
|
||||
genesis_time: u64,
|
||||
eth1_block_hash: Hash256,
|
||||
execution_payload_header: Option<ExecutionPayloadHeader<T>>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<BeaconState<T>, String> {
|
||||
let eth1_timestamp = 2_u64.pow(40);
|
||||
let amount = spec.max_effective_balance;
|
||||
|
||||
let withdrawal_credentials = |index: usize, pubkey: &PublicKey| {
|
||||
if index % 2 == 0 {
|
||||
bls_withdrawal_credentials(pubkey, spec)
|
||||
} else {
|
||||
eth1_withdrawal_credentials(pubkey, spec)
|
||||
}
|
||||
};
|
||||
|
||||
let datas = keypairs
|
||||
.into_par_iter()
|
||||
.enumerate()
|
||||
.map(|(index, keypair)| {
|
||||
let mut data = DepositData {
|
||||
withdrawal_credentials: withdrawal_credentials(index, &keypair.pk),
|
||||
pubkey: keypair.pk.clone().into(),
|
||||
amount,
|
||||
signature: Signature::empty().into(),
|
||||
@@ -133,4 +197,83 @@ mod test {
|
||||
"validator count should be correct"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interop_state_with_eth1() {
|
||||
let validator_count = 16;
|
||||
let genesis_time = 42;
|
||||
let spec = &TestEthSpec::default_spec();
|
||||
|
||||
let keypairs = generate_deterministic_keypairs(validator_count);
|
||||
|
||||
let state = interop_genesis_state_with_eth1::<TestEthSpec>(
|
||||
&keypairs,
|
||||
genesis_time,
|
||||
Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH),
|
||||
None,
|
||||
spec,
|
||||
)
|
||||
.expect("should build state");
|
||||
|
||||
assert_eq!(
|
||||
state.eth1_data().block_hash,
|
||||
Hash256::from_slice(&[0x42; 32]),
|
||||
"eth1 block hash should be co-ordinated junk"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
state.genesis_time(),
|
||||
genesis_time,
|
||||
"genesis time should be as specified"
|
||||
);
|
||||
|
||||
for b in state.balances() {
|
||||
assert_eq!(
|
||||
*b, spec.max_effective_balance,
|
||||
"validator balances should be max effective balance"
|
||||
);
|
||||
}
|
||||
|
||||
for (index, v) in state.validators().iter().enumerate() {
|
||||
let creds = v.withdrawal_credentials.as_bytes();
|
||||
if index % 2 == 0 {
|
||||
assert_eq!(
|
||||
creds[0], spec.bls_withdrawal_prefix_byte,
|
||||
"first byte of withdrawal creds should be bls prefix"
|
||||
);
|
||||
assert_eq!(
|
||||
&creds[1..],
|
||||
&hash(&v.pubkey.as_ssz_bytes())[1..],
|
||||
"rest of withdrawal creds should be pubkey hash"
|
||||
);
|
||||
} else {
|
||||
assert_eq!(
|
||||
creds[0], spec.eth1_address_withdrawal_prefix_byte,
|
||||
"first byte of withdrawal creds should be eth1 prefix"
|
||||
);
|
||||
assert_eq!(
|
||||
creds[1..12],
|
||||
[0u8; 11],
|
||||
"bytes [1:12] of withdrawal creds must be zero"
|
||||
);
|
||||
assert_eq!(
|
||||
&creds[12..],
|
||||
&hash(&v.pubkey.as_ssz_bytes())[0..20],
|
||||
"rest of withdrawal creds should be first 20 bytes of pubkey hash"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
state.balances().len(),
|
||||
validator_count,
|
||||
"validator balances len should be correct"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
state.validators().len(),
|
||||
validator_count,
|
||||
"validator count should be correct"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,5 +5,7 @@ mod interop;
|
||||
pub use eth1::Config as Eth1Config;
|
||||
pub use eth1::Eth1Endpoint;
|
||||
pub use eth1_genesis_service::{Eth1GenesisService, Statistics};
|
||||
pub use interop::{interop_genesis_state, DEFAULT_ETH1_BLOCK_HASH};
|
||||
pub use interop::{
|
||||
interop_genesis_state, interop_genesis_state_with_eth1, DEFAULT_ETH1_BLOCK_HASH,
|
||||
};
|
||||
pub use types::test_utils::generate_deterministic_keypairs;
|
||||
|
||||
Reference in New Issue
Block a user