From 7a16db144c9658c6dad6da9d29bd849141a7a94a Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 21 Jun 2019 15:59:18 -0600 Subject: [PATCH 01/49] Add test_genesis --- scripts/build_spec.py | 1 + specs/core/0_beacon-chain.md | 14 +++-- .../pyspec/eth2spec/test/helpers/deposits.py | 52 ++++++++++++++++--- .../eth2spec/test/sanity/test_genesis.py | 29 +++++++++++ 4 files changed, 84 insertions(+), 12 deletions(-) create mode 100644 test_libs/pyspec/eth2spec/test/sanity/test_genesis.py diff --git a/scripts/build_spec.py b/scripts/build_spec.py index a16fa79ac..d7b6d0f59 100644 --- a/scripts/build_spec.py +++ b/scripts/build_spec.py @@ -16,6 +16,7 @@ PHASE0_IMPORTS = '''from typing import ( Callable, Dict, List, + Optional, Set, Tuple, ) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 1dcdbdef9..28d0d72cd 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1176,8 +1176,12 @@ def get_genesis_beacon_state(deposits: List[Deposit], genesis_time: int, genesis ) # Process genesis deposits - for deposit in deposits: - process_deposit(state, deposit) + for deposit_index, deposit in enumerate(deposits): + process_deposit( + state, + deposit, + deposit_index=deposit_index, + ) # Process genesis activations for validator in state.validators: @@ -1726,16 +1730,18 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None: ##### Deposits ```python -def process_deposit(state: BeaconState, deposit: Deposit) -> None: +def process_deposit(state: BeaconState, deposit: Deposit, deposit_index: Optional[uint64]) -> None: """ Process an Eth1 deposit, registering a validator or increasing its balance. """ + if deposit_index is None: + deposit_index = state.eth1_deposit_index # Verify the Merkle branch assert verify_merkle_branch( leaf=hash_tree_root(deposit.data), proof=deposit.proof, depth=DEPOSIT_CONTRACT_TREE_DEPTH, - index=state.eth1_deposit_index, + index=deposit_index, root=state.eth1_data.deposit_root, ) diff --git a/test_libs/pyspec/eth2spec/test/helpers/deposits.py b/test_libs/pyspec/eth2spec/test/helpers/deposits.py index 20ff7440f..ca8b23361 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/deposits.py +++ b/test_libs/pyspec/eth2spec/test/helpers/deposits.py @@ -4,25 +4,31 @@ from eth2spec.utils.merkle_minimal import calc_merkle_tree_from_leaves, get_merk from eth2spec.utils.ssz.ssz_impl import signing_root -def build_deposit_data(spec, state, pubkey, privkey, amount, withdrawal_credentials, signed=False): +def build_deposit_data(spec, pubkey, privkey, amount, withdrawal_credentials, state=None, signed=False): deposit_data = spec.DepositData( pubkey=pubkey, withdrawal_credentials=withdrawal_credentials, amount=amount, ) if signed: - sign_deposit_data(spec, state, deposit_data, privkey) + sign_deposit_data(spec, deposit_data, privkey, state) return deposit_data -def sign_deposit_data(spec, state, deposit_data, privkey): - signature = bls_sign( - message_hash=signing_root(deposit_data), - privkey=privkey, - domain=spec.get_domain( +def sign_deposit_data(spec, deposit_data, privkey, state=None): + if state is None: + # Genesis + domain = spec.bls_domain(spec.DOMAIN_DEPOSIT) + else: + domain = spec.get_domain( state, spec.DOMAIN_DEPOSIT, ) + + signature = bls_sign( + message_hash=signing_root(deposit_data), + privkey=privkey, + domain=domain, ) deposit_data.signature = signature @@ -35,7 +41,7 @@ def build_deposit(spec, amount, withdrawal_credentials, signed): - deposit_data = build_deposit_data(spec, state, pubkey, privkey, amount, withdrawal_credentials, signed) + deposit_data = build_deposit_data(spec, pubkey, privkey, amount, withdrawal_credentials, state=state, signed=signed) item = deposit_data.hash_tree_root() index = len(deposit_data_leaves) @@ -54,6 +60,36 @@ def build_deposit(spec, return deposit, root, deposit_data_leaves +def prepare_genesis_deposits(spec, genesis_validator_count, signed=False): + genesis_deposit_data_list = [] + deposit_data_leaves = [] + for validator_index in range(genesis_validator_count): + pubkey = pubkeys[validator_index] + privkey = privkeys[validator_index] + # insecurely use pubkey as withdrawal key if no credentials provided + withdrawal_credentials = spec.int_to_bytes(spec.BLS_WITHDRAWAL_PREFIX, length=1) + spec.hash(pubkey)[1:] + deposit_data = spec.DepositData( + pubkey=pubkey, + withdrawal_credentials=withdrawal_credentials, + amount=spec.MAX_EFFECTIVE_BALANCE, + ) + if signed: + sign_deposit_data(spec, deposit_data, privkey) # state=None + item = deposit_data.hash_tree_root() + deposit_data_leaves.append(item) + genesis_deposit_data_list.append(deposit_data) + + tree = calc_merkle_tree_from_leaves(tuple(deposit_data_leaves)) + root = get_merkle_root((tuple(deposit_data_leaves))) + + genesis_deposits = ( + spec.Deposit(proof=list(get_merkle_proof(tree, item_index=index)), data=deposit_data) + for index, deposit_data in enumerate(genesis_deposit_data_list) + ) + + return genesis_deposits, root + + def prepare_state_and_deposit(spec, state, validator_index, amount, withdrawal_credentials=None, signed=False): """ Prepare the state for the deposit, and create a deposit for the given validator, depositing the given amount. diff --git a/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py b/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py new file mode 100644 index 000000000..088df84e8 --- /dev/null +++ b/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py @@ -0,0 +1,29 @@ +from eth2spec.test.context import spec_state_test, with_phases +from eth2spec.test.helpers.deposits import ( + prepare_genesis_deposits, +) + + +@with_phases(['phase0']) +@spec_state_test +def test_genesis(spec, state): + deposit_count = 2 + genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count) + genesis_time = 1234 + + yield genesis_deposits + yield genesis_time + + genesis_eth1_data = spec.Eth1Data( + deposit_root=deposit_root, + deposit_count=deposit_count, + block_hash=b'\x12' * 32, + ) + + yield genesis_eth1_data + genesis_state = spec.get_genesis_beacon_state( + genesis_deposits, + genesis_time, + genesis_eth1_data, + ) + yield genesis_state From b36ffd5c412c65327ba10f35f1f406a006bf1d20 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 21 Jun 2019 16:10:19 -0600 Subject: [PATCH 02/49] default value of `deposit_index` --- specs/core/0_beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 28d0d72cd..4d35c6516 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1730,7 +1730,7 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None: ##### Deposits ```python -def process_deposit(state: BeaconState, deposit: Deposit, deposit_index: Optional[uint64]) -> None: +def process_deposit(state: BeaconState, deposit: Deposit, deposit_index: Optional[uint64]=None) -> None: """ Process an Eth1 deposit, registering a validator or increasing its balance. """ From ac34221f55aabc75934c4e4fa6704e29599a680c Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 21 Jun 2019 16:30:31 -0600 Subject: [PATCH 03/49] Fix `is_genesis_trigger` and add test case --- configs/constant_presets/mainnet.yaml | 2 ++ configs/constant_presets/minimal.yaml | 2 ++ specs/core/0_beacon-chain.md | 19 ++++++++------ .../eth2spec/test/sanity/test_genesis.py | 26 +++++++++++++++++++ 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/configs/constant_presets/mainnet.yaml b/configs/constant_presets/mainnet.yaml index 09ec7bdb7..572cfb708 100644 --- a/configs/constant_presets/mainnet.yaml +++ b/configs/constant_presets/mainnet.yaml @@ -17,6 +17,8 @@ MIN_PER_EPOCH_CHURN_LIMIT: 4 CHURN_LIMIT_QUOTIENT: 65536 # See issue 563 SHUFFLE_ROUND_COUNT: 90 +# `2**16` (= 65,536) +GENESIS_ACTIVE_VALIDATOR_COUNT: 65536 # Deposit contract diff --git a/configs/constant_presets/minimal.yaml b/configs/constant_presets/minimal.yaml index c8c2853c7..edc73ab8b 100644 --- a/configs/constant_presets/minimal.yaml +++ b/configs/constant_presets/minimal.yaml @@ -16,6 +16,8 @@ MIN_PER_EPOCH_CHURN_LIMIT: 4 CHURN_LIMIT_QUOTIENT: 65536 # [customized] Faster, but unsecure. SHUFFLE_ROUND_COUNT: 10 +# [customized] +GENESIS_ACTIVE_VALIDATOR_COUNT: 100 # Deposit contract diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 4d35c6516..0b856636b 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -194,6 +194,7 @@ These configurations are updated for releases, but may be out of sync during `de | `MIN_PER_EPOCH_CHURN_LIMIT` | `2**2` (= 4) | | `CHURN_LIMIT_QUOTIENT` | `2**16` (= 65,536) | | `SHUFFLE_ROUND_COUNT` | `90` | +| `GENESIS_ACTIVE_VALIDATOR_COUNT` | `2**16` (= 65,536) | * For the safety of crosslinks `TARGET_COMMITTEE_SIZE` exceeds [the recommended minimum committee size of 111](https://vitalik.ca/files/Ithaca201807_Sharding.pdf); with sufficient active validators (at least `SLOTS_PER_EPOCH * TARGET_COMMITTEE_SIZE`), the shuffling algorithm ensures committee sizes of at least `TARGET_COMMITTEE_SIZE`. (Unbiasable randomness with a Verifiable Delay Function (VDF) will improve committee robustness and lower the safe minimum committee size.) @@ -1134,10 +1135,11 @@ Before genesis has been triggered and whenever the deposit contract emits a `Dep * `deposits` is the list of all deposits, ordered chronologically, up to and including the deposit triggering the latest `Deposit` log * `timestamp` is the Unix timestamp in the Ethereum 1.0 block that emitted the latest `Deposit` log -When `is_genesis_trigger(deposits, timestamp) is True` for the first time let: +When `is_genesis_trigger(deposits, timestamp, deposit_root) is True` for the first time let: * `genesis_deposits = deposits` * `genesis_time = timestamp - timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY` where `SECONDS_PER_DAY = 86400` +* `deposit_root` is the tree root of the given `deposits` * `genesis_eth1_data` be the object of type `Eth1Data` where: * `genesis_eth1_data.block_hash` is the Ethereum 1.0 block hash that emitted the log for the last deposit in `deposits` * `genesis_eth1_data.deposit_root` is the deposit root for the last deposit in `deposits` @@ -1146,20 +1148,19 @@ When `is_genesis_trigger(deposits, timestamp) is True` for the first time let: *Note*: The function `is_genesis_trigger` has yet to be agreed by the community, and can be updated as necessary. We define the following testing placeholder: ```python -def is_genesis_trigger(deposits: List[Deposit], timestamp: uint64) -> bool: +def is_genesis_trigger(deposits: List[Deposit], timestamp: uint64, deposit_root: Hash) -> bool: # Process deposits state = BeaconState() - for deposit in deposits: - process_deposit(state, deposit) + for index, deposit in enumerate(deposits): + process_deposit(state, deposit, deposit_index=index, deposit_root=deposit_root) # Count active validators at genesis active_validator_count = 0 - for validator in state.validator_registry: + for validator in state.validators: if validator.effective_balance == MAX_EFFECTIVE_BALANCE: active_validator_count += 1 # Check effective balance to trigger genesis - GENESIS_ACTIVE_VALIDATOR_COUNT = 2**16 return active_validator_count == GENESIS_ACTIVE_VALIDATOR_COUNT ``` @@ -1730,19 +1731,21 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None: ##### Deposits ```python -def process_deposit(state: BeaconState, deposit: Deposit, deposit_index: Optional[uint64]=None) -> None: +def process_deposit(state: BeaconState, deposit: Deposit, deposit_index: Optional[uint64]=None, deposit_root: Optional[Hash]=None) -> None: """ Process an Eth1 deposit, registering a validator or increasing its balance. """ if deposit_index is None: deposit_index = state.eth1_deposit_index + if deposit_root is None: + deposit_root = state.eth1_data.deposit_root # Verify the Merkle branch assert verify_merkle_branch( leaf=hash_tree_root(deposit.data), proof=deposit.proof, depth=DEPOSIT_CONTRACT_TREE_DEPTH, index=deposit_index, - root=state.eth1_data.deposit_root, + root=deposit_root, ) # Deposits must be processed in order diff --git a/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py b/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py index 088df84e8..0a9db7bc0 100644 --- a/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py +++ b/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py @@ -4,6 +4,32 @@ from eth2spec.test.helpers.deposits import ( ) +@with_phases(['phase0']) +@spec_state_test +def test_is_genesis_trigger_false(spec, state): + deposit_count = 2 + genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count) + genesis_time = 1234 + + is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time, deposit_root) + assert is_triggered is False + + yield is_triggered + + +@with_phases(['phase0']) +@spec_state_test +def test_is_genesis_trigger_true(spec, state): + deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT + genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count) + genesis_time = 1234 + + is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time, deposit_root) + assert is_triggered is True + + yield is_triggered + + @with_phases(['phase0']) @spec_state_test def test_genesis(spec, state): From e7c595d1d6200299a6d33a7a4ef0d06801297b53 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 21 Jun 2019 16:33:24 -0600 Subject: [PATCH 04/49] Fix test_process_deposit.py --- .../test/phase_0/block_processing/test_process_deposit.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_deposit.py b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_deposit.py index 63b94c638..1b8c44651 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_deposit.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_deposit.py @@ -124,7 +124,7 @@ def test_wrong_index(spec, state): # mess up eth1_deposit_index deposit.index = state.eth1_deposit_index + 1 - sign_deposit_data(spec, state, deposit.data, privkeys[validator_index]) + sign_deposit_data(spec, deposit.data, privkeys[validator_index], state=state) yield from run_deposit_processing(spec, state, deposit, validator_index, valid=False) @@ -185,6 +185,6 @@ def test_bad_merkle_proof(spec, state): # mess up merkle branch deposit.proof[-1] = spec.ZERO_HASH - sign_deposit_data(spec, state, deposit.data, privkeys[validator_index]) + sign_deposit_data(spec, deposit.data, privkeys[validator_index], state) yield from run_deposit_processing(spec, state, deposit, validator_index, valid=False) From 8828dad786271fa2b5a6c95f5549d7bf5927c68b Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 21 Jun 2019 17:07:44 -0600 Subject: [PATCH 05/49] minor updates --- specs/core/0_beacon-chain.md | 5 ++++- .../test/phase_0/block_processing/test_process_deposit.py | 2 +- test_libs/pyspec/eth2spec/test/sanity/test_genesis.py | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 0b856636b..c82f1e34f 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1731,7 +1731,10 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None: ##### Deposits ```python -def process_deposit(state: BeaconState, deposit: Deposit, deposit_index: Optional[uint64]=None, deposit_root: Optional[Hash]=None) -> None: +def process_deposit(state: BeaconState, + deposit: Deposit, + deposit_index: Optional[uint64]=None, + deposit_root: Optional[Hash]=None) -> None: """ Process an Eth1 deposit, registering a validator or increasing its balance. """ diff --git a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_deposit.py b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_deposit.py index 1b8c44651..6acf86cc7 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_deposit.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_deposit.py @@ -185,6 +185,6 @@ def test_bad_merkle_proof(spec, state): # mess up merkle branch deposit.proof[-1] = spec.ZERO_HASH - sign_deposit_data(spec, deposit.data, privkeys[validator_index], state) + sign_deposit_data(spec, deposit.data, privkeys[validator_index], state=state) yield from run_deposit_processing(spec, state, deposit, validator_index, valid=False) diff --git a/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py b/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py index 0a9db7bc0..d6b3bf940 100644 --- a/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py +++ b/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py @@ -33,7 +33,7 @@ def test_is_genesis_trigger_true(spec, state): @with_phases(['phase0']) @spec_state_test def test_genesis(spec, state): - deposit_count = 2 + deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count) genesis_time = 1234 From 47b29c84564e442cf9394028080d39c256bf9914 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 21 Jun 2019 21:49:13 -0600 Subject: [PATCH 06/49] Loose condition of effective genesis deposit --- specs/core/0_beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index c82f1e34f..1d2dead41 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1157,7 +1157,7 @@ def is_genesis_trigger(deposits: List[Deposit], timestamp: uint64, deposit_root: # Count active validators at genesis active_validator_count = 0 for validator in state.validators: - if validator.effective_balance == MAX_EFFECTIVE_BALANCE: + if validator.effective_balance >= MAX_EFFECTIVE_BALANCE: active_validator_count += 1 # Check effective balance to trigger genesis From 7468fd034f5cb904513d6b07fc482f5b5478ad1e Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 21 Jun 2019 21:50:36 -0600 Subject: [PATCH 07/49] Add more test --- .../pyspec/eth2spec/test/helpers/deposits.py | 6 +++--- .../eth2spec/test/sanity/test_genesis.py | 20 ++++++++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/test_libs/pyspec/eth2spec/test/helpers/deposits.py b/test_libs/pyspec/eth2spec/test/helpers/deposits.py index ca8b23361..eea019e8b 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/deposits.py +++ b/test_libs/pyspec/eth2spec/test/helpers/deposits.py @@ -60,7 +60,7 @@ def build_deposit(spec, return deposit, root, deposit_data_leaves -def prepare_genesis_deposits(spec, genesis_validator_count, signed=False): +def prepare_genesis_deposits(spec, genesis_validator_count, amount, signed=False): genesis_deposit_data_list = [] deposit_data_leaves = [] for validator_index in range(genesis_validator_count): @@ -71,7 +71,7 @@ def prepare_genesis_deposits(spec, genesis_validator_count, signed=False): deposit_data = spec.DepositData( pubkey=pubkey, withdrawal_credentials=withdrawal_credentials, - amount=spec.MAX_EFFECTIVE_BALANCE, + amount=amount, ) if signed: sign_deposit_data(spec, deposit_data, privkey) # state=None @@ -84,7 +84,7 @@ def prepare_genesis_deposits(spec, genesis_validator_count, signed=False): genesis_deposits = ( spec.Deposit(proof=list(get_merkle_proof(tree, item_index=index)), data=deposit_data) - for index, deposit_data in enumerate(genesis_deposit_data_list) + for index, deposit_data in enumerate(genesis_deposit_data_list) ) return genesis_deposits, root diff --git a/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py b/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py index d6b3bf940..7e5fd5db4 100644 --- a/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py +++ b/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py @@ -8,7 +8,7 @@ from eth2spec.test.helpers.deposits import ( @spec_state_test def test_is_genesis_trigger_false(spec, state): deposit_count = 2 - genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count) + genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) genesis_time = 1234 is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time, deposit_root) @@ -21,7 +21,7 @@ def test_is_genesis_trigger_false(spec, state): @spec_state_test def test_is_genesis_trigger_true(spec, state): deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT - genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count) + genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) genesis_time = 1234 is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time, deposit_root) @@ -29,12 +29,26 @@ def test_is_genesis_trigger_true(spec, state): yield is_triggered +@with_phases(['phase0']) +@spec_state_test +def test_is_genesis_trigger_not_enough_balance(spec, state): + deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT + genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE - 1) + genesis_time = 1234 + yield genesis_deposits + yield genesis_time + + is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time, deposit_root) + assert is_triggered is False + + yield is_triggered + @with_phases(['phase0']) @spec_state_test def test_genesis(spec, state): deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT - genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count) + genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) genesis_time = 1234 yield genesis_deposits From 24ad42663fd05fd9a09667ae74395feafae8dc37 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 21 Jun 2019 22:02:03 -0600 Subject: [PATCH 08/49] `spectest_with_bls_switch` decorator --- test_libs/pyspec/eth2spec/test/context.py | 6 +++++- .../eth2spec/test/sanity/test_genesis.py | 19 ++++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/test_libs/pyspec/eth2spec/test/context.py b/test_libs/pyspec/eth2spec/test/context.py index 97266acf2..e7560afc6 100644 --- a/test_libs/pyspec/eth2spec/test/context.py +++ b/test_libs/pyspec/eth2spec/test/context.py @@ -27,9 +27,13 @@ def with_state(fn): DEFAULT_BLS_ACTIVE = False +def spectest_with_bls_switch(fn): + return bls_switch(spectest()(fn)) + + # shorthand for decorating @with_state @spectest() def spec_state_test(fn): - return with_state(bls_switch(spectest()(fn))) + return with_state(spectest_with_bls_switch(fn)) def expect_assertion_error(fn): diff --git a/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py b/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py index 7e5fd5db4..3c76654e6 100644 --- a/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py +++ b/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py @@ -1,12 +1,12 @@ -from eth2spec.test.context import spec_state_test, with_phases +from eth2spec.test.context import with_phases, spectest_with_bls_switch from eth2spec.test.helpers.deposits import ( prepare_genesis_deposits, ) @with_phases(['phase0']) -@spec_state_test -def test_is_genesis_trigger_false(spec, state): +@spectest_with_bls_switch +def test_is_genesis_trigger_false(spec): deposit_count = 2 genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) genesis_time = 1234 @@ -18,8 +18,8 @@ def test_is_genesis_trigger_false(spec, state): @with_phases(['phase0']) -@spec_state_test -def test_is_genesis_trigger_true(spec, state): +@spectest_with_bls_switch +def test_is_genesis_trigger_true(spec): deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) genesis_time = 1234 @@ -29,9 +29,10 @@ def test_is_genesis_trigger_true(spec, state): yield is_triggered + @with_phases(['phase0']) -@spec_state_test -def test_is_genesis_trigger_not_enough_balance(spec, state): +@spectest_with_bls_switch +def test_is_genesis_trigger_not_enough_balance(spec): deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE - 1) genesis_time = 1234 @@ -45,8 +46,8 @@ def test_is_genesis_trigger_not_enough_balance(spec, state): @with_phases(['phase0']) -@spec_state_test -def test_genesis(spec, state): +@spectest_with_bls_switch +def test_genesis(spec): deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) genesis_time = 1234 From 5f0921277739d5a137ba86cefa5bf91d0df852dd Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 21 Jun 2019 22:09:09 -0600 Subject: [PATCH 09/49] yield for `is_genesis_trigger` --- specs/core/0_beacon-chain.md | 6 +----- .../pyspec/eth2spec/test/sanity/test_genesis.py | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 1d2dead41..c94c4fcc9 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1178,11 +1178,7 @@ def get_genesis_beacon_state(deposits: List[Deposit], genesis_time: int, genesis # Process genesis deposits for deposit_index, deposit in enumerate(deposits): - process_deposit( - state, - deposit, - deposit_index=deposit_index, - ) + process_deposit(state, deposit, deposit_index=deposit_index) # Process genesis activations for validator in state.validators: diff --git a/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py b/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py index 3c76654e6..37d8a2b17 100644 --- a/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py +++ b/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py @@ -9,7 +9,11 @@ from eth2spec.test.helpers.deposits import ( def test_is_genesis_trigger_false(spec): deposit_count = 2 genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) - genesis_time = 1234 + genesis_time = 1546300800 + + yield genesis_deposits + yield genesis_time + yield deposit_root is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time, deposit_root) assert is_triggered is False @@ -22,7 +26,11 @@ def test_is_genesis_trigger_false(spec): def test_is_genesis_trigger_true(spec): deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) - genesis_time = 1234 + genesis_time = 1546300800 + + yield genesis_deposits + yield genesis_time + yield deposit_root is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time, deposit_root) assert is_triggered is True @@ -35,9 +43,10 @@ def test_is_genesis_trigger_true(spec): def test_is_genesis_trigger_not_enough_balance(spec): deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE - 1) - genesis_time = 1234 + genesis_time = 1546300800 yield genesis_deposits yield genesis_time + yield deposit_root is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time, deposit_root) assert is_triggered is False @@ -50,7 +59,7 @@ def test_is_genesis_trigger_not_enough_balance(spec): def test_genesis(spec): deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) - genesis_time = 1234 + genesis_time = 1546300800 yield genesis_deposits yield genesis_time From 6aef6c5634acc0c378c1f03b2cefd32ba3501954 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 21 Jun 2019 22:26:15 -0600 Subject: [PATCH 10/49] Clean up --- specs/core/0_beacon-chain.md | 4 ++-- test_libs/pyspec/eth2spec/test/sanity/test_genesis.py | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index bb1379b93..8f57967ed 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1139,11 +1139,11 @@ When `is_genesis_trigger(deposits, timestamp, deposit_root) is True` for the fir * `genesis_deposits = deposits` * `genesis_time = timestamp - timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY` where `SECONDS_PER_DAY = 86400` -* `deposit_root` is the tree root of the given `deposits` +* `deposit_root` is the Merkle tree root of the data of the given `deposits` * `genesis_eth1_data` be the object of type `Eth1Data` where: - * `genesis_eth1_data.block_hash` is the Ethereum 1.0 block hash that emitted the log for the last deposit in `deposits` * `genesis_eth1_data.deposit_root` is the deposit root for the last deposit in `deposits` * `genesis_eth1_data.deposit_count = len(genesis_deposits)` + * `genesis_eth1_data.block_hash` is the Ethereum 1.0 block hash that emitted the log for the last deposit in `deposits` *Note*: The function `is_genesis_trigger` has yet to be agreed by the community, and can be updated as necessary. We define the following testing placeholder: diff --git a/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py b/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py index 37d8a2b17..780d039eb 100644 --- a/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py +++ b/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py @@ -60,6 +60,7 @@ def test_genesis(spec): deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) genesis_time = 1546300800 + block_hash = b'\x12' * 32 yield genesis_deposits yield genesis_time @@ -67,7 +68,7 @@ def test_genesis(spec): genesis_eth1_data = spec.Eth1Data( deposit_root=deposit_root, deposit_count=deposit_count, - block_hash=b'\x12' * 32, + block_hash=block_hash, ) yield genesis_eth1_data @@ -76,4 +77,11 @@ def test_genesis(spec): genesis_time, genesis_eth1_data, ) + + assert genesis_state.genesis_time == genesis_time + assert len(genesis_state.validators) == deposit_count + assert genesis_state.eth1_data.deposit_root == deposit_root + assert genesis_state.eth1_data.deposit_count == deposit_count + assert genesis_state.eth1_data.block_hash == block_hash + yield genesis_state From a3f8f50beed9f66801ce266b192b234c2dd11299 Mon Sep 17 00:00:00 2001 From: Justin Drake Date: Sat, 22 Jun 2019 23:34:09 +0200 Subject: [PATCH 11/49] Initialise deposit root properly --- specs/core/0_beacon-chain.md | 38 ++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 8f57967ed..8aa307d66 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1135,11 +1135,10 @@ Before genesis has been triggered and whenever the deposit contract emits a `Dep * `deposits` is the list of all deposits, ordered chronologically, up to and including the deposit triggering the latest `Deposit` log * `timestamp` is the Unix timestamp in the Ethereum 1.0 block that emitted the latest `Deposit` log -When `is_genesis_trigger(deposits, timestamp, deposit_root) is True` for the first time let: +When `is_genesis_trigger(deposits, timestamp) is True` for the first time let: * `genesis_deposits = deposits` * `genesis_time = timestamp - timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY` where `SECONDS_PER_DAY = 86400` -* `deposit_root` is the Merkle tree root of the data of the given `deposits` * `genesis_eth1_data` be the object of type `Eth1Data` where: * `genesis_eth1_data.deposit_root` is the deposit root for the last deposit in `deposits` * `genesis_eth1_data.deposit_count = len(genesis_deposits)` @@ -1148,16 +1147,20 @@ When `is_genesis_trigger(deposits, timestamp, deposit_root) is True` for the fir *Note*: The function `is_genesis_trigger` has yet to be agreed by the community, and can be updated as necessary. We define the following testing placeholder: ```python -def is_genesis_trigger(deposits: List[Deposit], timestamp: uint64, deposit_root: Hash) -> bool: - # Process deposits +def is_genesis_trigger(deposits: List[Deposit], timestamp: uint64) -> bool: + # Initialize deposit root state = BeaconState() - for index, deposit in enumerate(deposits): - process_deposit(state, deposit, deposit_index=index, deposit_root=deposit_root) + for i in range(DEPOSIT_CONTRACT_TREE_DEPTH - 1): + state.eth1_data.deposit_root = hash(state.eth1_data.deposit_root + state.eth1_data.deposit_root) + + # Process deposits + for deposit in deposits: + process_deposit(state, deposit) # Count active validators at genesis active_validator_count = 0 for validator in state.validators: - if validator.effective_balance >= MAX_EFFECTIVE_BALANCE: + if validator.effective_balance == MAX_EFFECTIVE_BALANCE: active_validator_count += 1 # Check effective balance to trigger genesis @@ -1177,12 +1180,12 @@ def get_genesis_beacon_state(deposits: List[Deposit], genesis_time: int, genesis ) # Process genesis deposits - for deposit_index, deposit in enumerate(deposits): - process_deposit(state, deposit, deposit_index=deposit_index) + for deposit in deposits: + process_deposit(state, deposit) # Process genesis activations for validator in state.validators: - if validator.effective_balance >= MAX_EFFECTIVE_BALANCE: + if validator.effective_balance == MAX_EFFECTIVE_BALANCE: validator.activation_eligibility_epoch = GENESIS_EPOCH validator.activation_epoch = GENESIS_EPOCH @@ -1483,7 +1486,7 @@ def process_registry_updates(state: BeaconState) -> None: for index, validator in enumerate(state.validators): if ( validator.activation_eligibility_epoch == FAR_FUTURE_EPOCH and - validator.effective_balance >= MAX_EFFECTIVE_BALANCE + validator.effective_balance == MAX_EFFECTIVE_BALANCE ): validator.activation_eligibility_epoch = get_current_epoch(state) @@ -1727,24 +1730,17 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None: ##### Deposits ```python -def process_deposit(state: BeaconState, - deposit: Deposit, - deposit_index: Optional[uint64]=None, - deposit_root: Optional[Hash]=None) -> None: +def process_deposit(state: BeaconState, deposit: Deposit) -> None: """ Process an Eth1 deposit, registering a validator or increasing its balance. """ - if deposit_index is None: - deposit_index = state.eth1_deposit_index - if deposit_root is None: - deposit_root = state.eth1_data.deposit_root # Verify the Merkle branch assert verify_merkle_branch( leaf=hash_tree_root(deposit.data), proof=deposit.proof, depth=DEPOSIT_CONTRACT_TREE_DEPTH, - index=deposit_index, - root=deposit_root, + index=state.eth1_deposit_index, + root=state.eth1_data.deposit_root, ) # Deposits must be processed in order From ccda5082540a4cb7b7ab46de290ce29cb9e60d0f Mon Sep 17 00:00:00 2001 From: Justin Drake Date: Wed, 26 Jun 2019 15:34:54 +0100 Subject: [PATCH 12/49] Fix deposit root, add min_genesis_time, per-block processing --- specs/core/0_beacon-chain.md | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 8aa307d66..588c2d133 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -126,7 +126,7 @@ This document represents the specification for Phase 0 of Ethereum 2.0 -- The Beacon Chain. -At the core of Ethereum 2.0 is a system chain called the "beacon chain". The beacon chain stores and manages the registry of [validators](#dfn-validator). In the initial deployment phases of Ethereum 2.0, the only mechanism to become a [validator](#dfn-validator) is to make a one-way ETH transaction to a deposit contract on Ethereum 1.0. Activation as a [validator](#dfn-validator) happens when Ethereum 1.0 deposit receipts are processed by the beacon chain, the activation balance is reached, and a queuing process is completed. Exit is either voluntary or done forcibly as a penalty for misbehavior. +At the core of Ethereum 2.0 is a system chain called the "beacon chain". The beacon chain stores and manages the registry of [validators](#dfn-validator). In the initial deployment phases of Ethereum 2.0, the only mechanism to become a [validator](#dfn-validator) is to make a one-way ETH transaction to a deposit contract on Eth 1.0. Activation as a [validator](#dfn-validator) happens when Eth 1.0 deposit receipts are processed by the beacon chain, the activation balance is reached, and a queuing process is completed. Exit is either voluntary or done forcibly as a penalty for misbehavior. The primary source of load on the beacon chain is "attestations". Attestations are simultaneously availability votes for a shard block and proof-of-stake votes for a beacon block. A sufficient number of attestations for the same shard block create a "crosslink", confirming the shard segment up to that shard block into the beacon chain. Crosslinks also serve as infrastructure for asynchronous cross-shard communication. @@ -136,7 +136,7 @@ Code snippets appearing in `this style` are to be interpreted as Python code. ## Terminology -* **Validator**—a registered participant in the beacon chain. You can become one by sending ether into the Ethereum 1.0 deposit contract. +* **Validator**—a registered participant in the beacon chain. You can become one by sending ether into the Eth 1.0 deposit contract. * **Active validator**—an active participant in the Ethereum 2.0 consensus invited to, among other things, propose and attest to blocks and vote for crosslinks. * **Committee**—a (pseudo-) randomly sampled subset of [active validators](#dfn-active-validator). When a committee is referred to collectively, as in "this committee attests to X", this is assumed to mean "some subset of that committee that contains enough [validators](#dfn-validator) that the protocol recognizes it as representing the committee". * **Proposer**—the [validator](#dfn-validator) that creates a beacon chain block. @@ -195,6 +195,7 @@ These configurations are updated for releases, but may be out of sync during `de | `CHURN_LIMIT_QUOTIENT` | `2**16` (= 65,536) | | `SHUFFLE_ROUND_COUNT` | `90` | | `GENESIS_ACTIVE_VALIDATOR_COUNT` | `2**16` (= 65,536) | +| `MIN_GENESIS_TIME` | `1578009600` (Jan 3, 2020) | * For the safety of crosslinks `TARGET_COMMITTEE_SIZE` exceeds [the recommended minimum committee size of 111](https://vitalik.ca/files/Ithaca201807_Sharding.pdf); with sufficient active validators (at least `SLOTS_PER_EPOCH * TARGET_COMMITTEE_SIZE`), the shuffling algorithm ensures committee sizes of at least `TARGET_COMMITTEE_SIZE`. (Unbiasable randomness with a Verifiable Delay Function (VDF) will improve committee robustness and lower the safe minimum committee size.) @@ -1130,31 +1131,34 @@ def slash_validator(state: BeaconState, ### Genesis trigger -Before genesis has been triggered and whenever the deposit contract emits a `Deposit` log, call the function `is_genesis_trigger(deposits: List[Deposit], timestamp: uint64) -> bool` where: +Before genesis has been triggered and for every Eth 1.0 block call `is_genesis_trigger(deposits, time)` where: -* `deposits` is the list of all deposits, ordered chronologically, up to and including the deposit triggering the latest `Deposit` log -* `timestamp` is the Unix timestamp in the Ethereum 1.0 block that emitted the latest `Deposit` log +* `deposits` is the list of all deposits up to the Eth 1.0 block, ordered chronologically +* `time` is the Unix time of the Eth 1.0 block -When `is_genesis_trigger(deposits, timestamp) is True` for the first time let: +When `is_genesis_trigger(deposits, time) is True` for the first time let: * `genesis_deposits = deposits` -* `genesis_time = timestamp - timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY` where `SECONDS_PER_DAY = 86400` +* `genesis_time = time - time % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY` where `SECONDS_PER_DAY = 86400` * `genesis_eth1_data` be the object of type `Eth1Data` where: * `genesis_eth1_data.deposit_root` is the deposit root for the last deposit in `deposits` * `genesis_eth1_data.deposit_count = len(genesis_deposits)` - * `genesis_eth1_data.block_hash` is the Ethereum 1.0 block hash that emitted the log for the last deposit in `deposits` + * `genesis_eth1_data.block_hash` is the Eth 1.0 block hash that emitted the log for the last deposit in `deposits` *Note*: The function `is_genesis_trigger` has yet to be agreed by the community, and can be updated as necessary. We define the following testing placeholder: ```python -def is_genesis_trigger(deposits: List[Deposit], timestamp: uint64) -> bool: +def is_genesis_trigger(deposits: List[Deposit, 2**DEPOSIT_CONTRACT_TREE_DEPTH], time: uint64) -> bool: + # Do not deploy too early + if time - time % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY < MIN_GENESIS_TIME: + return False + # Initialize deposit root state = BeaconState() - for i in range(DEPOSIT_CONTRACT_TREE_DEPTH - 1): - state.eth1_data.deposit_root = hash(state.eth1_data.deposit_root + state.eth1_data.deposit_root) + state.eth1_data.deposit_root = hash_tree_root(map(deposits, lambda deposit: deposit.data)) # Process deposits - for deposit in deposits: + for deposit in deposits process_deposit(state, deposit) # Count active validators at genesis From aecaed7a662ffc7ad73b098b1834840b725fe76d Mon Sep 17 00:00:00 2001 From: protolambda Date: Thu, 27 Jun 2019 01:47:15 +0200 Subject: [PATCH 13/49] move genesis tests, structure properly, add yield keys for future test-vec generator --- .../pyspec/eth2spec/test/genesis/__init__.py | 0 .../eth2spec/test/genesis/test_genesis.py | 37 ++++++++ .../test/genesis/test_genesis_trigger.py | 54 ++++++++++++ .../eth2spec/test/sanity/test_genesis.py | 87 ------------------- 4 files changed, 91 insertions(+), 87 deletions(-) create mode 100644 test_libs/pyspec/eth2spec/test/genesis/__init__.py create mode 100644 test_libs/pyspec/eth2spec/test/genesis/test_genesis.py create mode 100644 test_libs/pyspec/eth2spec/test/genesis/test_genesis_trigger.py delete mode 100644 test_libs/pyspec/eth2spec/test/sanity/test_genesis.py diff --git a/test_libs/pyspec/eth2spec/test/genesis/__init__.py b/test_libs/pyspec/eth2spec/test/genesis/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py b/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py new file mode 100644 index 000000000..a89ec8793 --- /dev/null +++ b/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py @@ -0,0 +1,37 @@ +from eth2spec.test.context import with_phases, spectest_with_bls_switch +from eth2spec.test.helpers.deposits import ( + prepare_genesis_deposits, +) + + +@with_phases(['phase0']) +@spectest_with_bls_switch +def test_genesis(spec): + deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT + genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) + genesis_time = 1546300800 + block_hash = b'\x12' * 32 + + yield "deposits", genesis_deposits + yield "time", genesis_time + + genesis_eth1_data = spec.Eth1Data( + deposit_root=deposit_root, + deposit_count=deposit_count, + block_hash=block_hash, + ) + + yield "eth1_data", genesis_eth1_data + genesis_state = spec.get_genesis_beacon_state( + genesis_deposits, + genesis_time, + genesis_eth1_data, + ) + + assert genesis_state.genesis_time == genesis_time + assert len(genesis_state.validators) == deposit_count + assert genesis_state.eth1_data.deposit_root == deposit_root + assert genesis_state.eth1_data.deposit_count == deposit_count + assert genesis_state.eth1_data.block_hash == block_hash + + yield "state", genesis_state diff --git a/test_libs/pyspec/eth2spec/test/genesis/test_genesis_trigger.py b/test_libs/pyspec/eth2spec/test/genesis/test_genesis_trigger.py new file mode 100644 index 000000000..873638dc9 --- /dev/null +++ b/test_libs/pyspec/eth2spec/test/genesis/test_genesis_trigger.py @@ -0,0 +1,54 @@ +from eth2spec.test.context import with_phases, spectest_with_bls_switch +from eth2spec.test.helpers.deposits import ( + prepare_genesis_deposits, +) + + +@with_phases(['phase0']) +@spectest_with_bls_switch +def test_is_genesis_trigger_false(spec): + deposit_count = 2 + genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) + genesis_time = 1546300800 + + yield "deposits", genesis_deposits + yield "time", genesis_time + yield "deposit_root", deposit_root + + is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time) + assert is_triggered is False + + yield "is_triggered", is_triggered + + +@with_phases(['phase0']) +@spectest_with_bls_switch +def test_is_genesis_trigger_true(spec): + deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT + genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) + genesis_time = 1546300800 + + yield "deposits", genesis_deposits + yield "time", genesis_time + yield "deposit_root", deposit_root + + is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time) + assert is_triggered is True + + yield "is_triggered", is_triggered + + +@with_phases(['phase0']) +@spectest_with_bls_switch +def test_is_genesis_trigger_not_enough_balance(spec): + deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT + genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE - 1) + genesis_time = 1546300800 + yield "deposits", genesis_deposits + yield "time", genesis_time + yield "deposit_root", deposit_root + + is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time) + assert is_triggered is False + + yield "is_triggered", is_triggered diff --git a/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py b/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py deleted file mode 100644 index 780d039eb..000000000 --- a/test_libs/pyspec/eth2spec/test/sanity/test_genesis.py +++ /dev/null @@ -1,87 +0,0 @@ -from eth2spec.test.context import with_phases, spectest_with_bls_switch -from eth2spec.test.helpers.deposits import ( - prepare_genesis_deposits, -) - - -@with_phases(['phase0']) -@spectest_with_bls_switch -def test_is_genesis_trigger_false(spec): - deposit_count = 2 - genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) - genesis_time = 1546300800 - - yield genesis_deposits - yield genesis_time - yield deposit_root - - is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time, deposit_root) - assert is_triggered is False - - yield is_triggered - - -@with_phases(['phase0']) -@spectest_with_bls_switch -def test_is_genesis_trigger_true(spec): - deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT - genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) - genesis_time = 1546300800 - - yield genesis_deposits - yield genesis_time - yield deposit_root - - is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time, deposit_root) - assert is_triggered is True - - yield is_triggered - - -@with_phases(['phase0']) -@spectest_with_bls_switch -def test_is_genesis_trigger_not_enough_balance(spec): - deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT - genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE - 1) - genesis_time = 1546300800 - yield genesis_deposits - yield genesis_time - yield deposit_root - - is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time, deposit_root) - assert is_triggered is False - - yield is_triggered - - -@with_phases(['phase0']) -@spectest_with_bls_switch -def test_genesis(spec): - deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT - genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) - genesis_time = 1546300800 - block_hash = b'\x12' * 32 - - yield genesis_deposits - yield genesis_time - - genesis_eth1_data = spec.Eth1Data( - deposit_root=deposit_root, - deposit_count=deposit_count, - block_hash=block_hash, - ) - - yield genesis_eth1_data - genesis_state = spec.get_genesis_beacon_state( - genesis_deposits, - genesis_time, - genesis_eth1_data, - ) - - assert genesis_state.genesis_time == genesis_time - assert len(genesis_state.validators) == deposit_count - assert genesis_state.eth1_data.deposit_root == deposit_root - assert genesis_state.eth1_data.deposit_count == deposit_count - assert genesis_state.eth1_data.block_hash == block_hash - - yield genesis_state From a0c2f5c6b5578d3ee09b155fb487ab739e22195a Mon Sep 17 00:00:00 2001 From: protolambda Date: Thu, 27 Jun 2019 01:57:30 +0200 Subject: [PATCH 14/49] fix genesis testing code, add missing constant temporarily, fix py Generator/map/list problems --- specs/core/0_beacon-chain.md | 6 ++++-- .../pyspec/eth2spec/test/genesis/test_genesis_trigger.py | 3 ++- test_libs/pyspec/eth2spec/test/helpers/deposits.py | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index b0490cba5..1ff1d58b3 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1137,14 +1137,16 @@ When `is_genesis_trigger(deposits, time) is True` for the first time let: ```python def is_genesis_trigger(deposits: List[Deposit, 2**DEPOSIT_CONTRACT_TREE_DEPTH], time: uint64) -> bool: + SECONDS_PER_DAY = 86400 # Do not deploy too early if time - time % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY < MIN_GENESIS_TIME: return False # Initialize deposit root state = BeaconState() - state.eth1_data.deposit_root = hash_tree_root(map(deposits, lambda deposit: deposit.data)) - + state.eth1_data.deposit_root = hash_tree_root( + Vector[DepositData, len(deposits)](list(map(lambda deposit: deposit.data, deposits))) + ) # Process deposits for deposit in deposits: process_deposit(state, deposit) diff --git a/test_libs/pyspec/eth2spec/test/genesis/test_genesis_trigger.py b/test_libs/pyspec/eth2spec/test/genesis/test_genesis_trigger.py index 873638dc9..9425a1750 100644 --- a/test_libs/pyspec/eth2spec/test/genesis/test_genesis_trigger.py +++ b/test_libs/pyspec/eth2spec/test/genesis/test_genesis_trigger.py @@ -26,7 +26,8 @@ def test_is_genesis_trigger_false(spec): def test_is_genesis_trigger_true(spec): deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) - genesis_time = 1546300800 + SECONDS_PER_DAY = 86400 + genesis_time = 1578009600 - 2 * SECONDS_PER_DAY yield "deposits", genesis_deposits yield "time", genesis_time diff --git a/test_libs/pyspec/eth2spec/test/helpers/deposits.py b/test_libs/pyspec/eth2spec/test/helpers/deposits.py index eea019e8b..bda4f1699 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/deposits.py +++ b/test_libs/pyspec/eth2spec/test/helpers/deposits.py @@ -82,7 +82,7 @@ def prepare_genesis_deposits(spec, genesis_validator_count, amount, signed=False tree = calc_merkle_tree_from_leaves(tuple(deposit_data_leaves)) root = get_merkle_root((tuple(deposit_data_leaves))) - genesis_deposits = ( + genesis_deposits = list( spec.Deposit(proof=list(get_merkle_proof(tree, item_index=index)), data=deposit_data) for index, deposit_data in enumerate(genesis_deposit_data_list) ) From ee712ecdde94bf00a0df44e412bd4ede2637e967 Mon Sep 17 00:00:00 2001 From: Justin Drake Date: Thu, 27 Jun 2019 11:21:45 +0100 Subject: [PATCH 15/49] Make HW happy :) --- specs/core/0_beacon-chain.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 1ff1d58b3..ea99bb473 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1142,13 +1142,12 @@ def is_genesis_trigger(deposits: List[Deposit, 2**DEPOSIT_CONTRACT_TREE_DEPTH], if time - time % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY < MIN_GENESIS_TIME: return False - # Initialize deposit root - state = BeaconState() - state.eth1_data.deposit_root = hash_tree_root( - Vector[DepositData, len(deposits)](list(map(lambda deposit: deposit.data, deposits))) - ) # Process deposits - for deposit in deposits: + state = BeaconState() + for i, deposit in enumerate(deposits): + state.eth1_data.deposit_root = hash_tree_root( + Vector[DepositData, len(deposits)](list(map(lambda deposit: deposit.data, deposits[:i]))) + ) process_deposit(state, deposit) # Count active validators at genesis @@ -1183,7 +1182,7 @@ def get_genesis_beacon_state(deposits: Sequence[Deposit], genesis_time: int, eth validator.activation_eligibility_epoch = GENESIS_EPOCH validator.activation_epoch = GENESIS_EPOCH - # Populate active_index_roots + # Populate active_index_roots genesis_active_index_root = hash_tree_root( List[ValidatorIndex, VALIDATOR_REGISTRY_LIMIT](get_active_validator_indices(state, GENESIS_EPOCH)) ) From 2252142e01b9431cedbd5f1a2824a41db4e430dc Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 28 Jun 2019 10:24:16 +0800 Subject: [PATCH 16/49] padding version normal merkle tree --- .../pyspec/eth2spec/utils/merkle_minimal.py | 27 +++++++------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/test_libs/pyspec/eth2spec/utils/merkle_minimal.py b/test_libs/pyspec/eth2spec/utils/merkle_minimal.py index 038b555cf..e3e81f3a5 100644 --- a/test_libs/pyspec/eth2spec/utils/merkle_minimal.py +++ b/test_libs/pyspec/eth2spec/utils/merkle_minimal.py @@ -1,4 +1,5 @@ from .hash_function import hash +from math import log2 ZERO_BYTES32 = b'\x00' * 32 @@ -8,11 +9,10 @@ for layer in range(1, 100): zerohashes.append(hash(zerohashes[layer - 1] + zerohashes[layer - 1])) -# Compute a Merkle root of a right-zerobyte-padded 2**32 sized tree -def calc_merkle_tree_from_leaves(values): +def calc_merkle_tree_from_leaves(values, layer_count=32): values = list(values) tree = [values[::]] - for h in range(32): + for h in range(layer_count): if len(values) % 2 == 1: values.append(zerohashes[h]) values = [hash(values[i] + values[i + 1]) for i in range(0, len(values), 2)] @@ -20,8 +20,11 @@ def calc_merkle_tree_from_leaves(values): return tree -def get_merkle_root(values): - return calc_merkle_tree_from_leaves(values)[-1][0] +def get_merkle_root(values, pad_to=1): + layer_count = int(log2(pad_to)) + if len(values) == 0: + return zerohashes[layer_count] + return calc_merkle_tree_from_leaves(values, layer_count)[-1][0] def get_merkle_proof(tree, item_index): @@ -32,19 +35,7 @@ def get_merkle_proof(tree, item_index): return proof -def next_power_of_two(v: int) -> int: - """ - Get the next power of 2. (for 64 bit range ints). - 0 is a special case, to have non-empty defaults. - Examples: - 0 -> 1, 1 -> 1, 2 -> 2, 3 -> 4, 32 -> 32, 33 -> 64 - """ - if v == 0: - return 1 - return 1 << (v - 1).bit_length() - - -def merkleize_chunks(chunks, pad_to: int = 1): +def merkleize_chunks(chunks, pad_to: int=1): count = len(chunks) depth = max(count - 1, 0).bit_length() max_depth = max(depth, (pad_to - 1).bit_length()) From 4dc526fbb7d619d0675950b703dcb30c5eb22836 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Sat, 29 Jun 2019 02:16:16 +0800 Subject: [PATCH 17/49] In the end, `get_merkle_root` is back --- scripts/build_spec.py | 6 ++- specs/core/0_beacon-chain.md | 44 ++++++++++++++++--- .../test/genesis/test_genesis_trigger.py | 9 ++-- .../pyspec/eth2spec/test/helpers/deposits.py | 17 +++---- .../pyspec/eth2spec/utils/merkle_minimal.py | 2 +- .../eth2spec/utils/test_merkle_minimal.py | 5 ++- 6 files changed, 59 insertions(+), 24 deletions(-) diff --git a/scripts/build_spec.py b/scripts/build_spec.py index 99c5cd69d..1bdebd130 100644 --- a/scripts/build_spec.py +++ b/scripts/build_spec.py @@ -11,7 +11,8 @@ from typing import ( ) -PHASE0_IMPORTS = '''from typing import ( +PHASE0_IMPORTS = '''from math import log2 +from typing import ( Any, Callable, Dict, Set, Sequence, Tuple, ) @@ -36,7 +37,8 @@ from eth2spec.utils.bls import ( from eth2spec.utils.hash_function import hash ''' -PHASE1_IMPORTS = '''from typing import ( +PHASE1_IMPORTS = '''from math import log2 +from typing import ( Any, Callable, Dict, Optional, Set, Sequence, MutableSequence, Tuple, ) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index ea99bb473..25a7340d3 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -51,6 +51,8 @@ - [`hash`](#hash) - [`hash_tree_root`](#hash_tree_root) - [`signing_root`](#signing_root) + - [`calc_merkle_tree_from_leaves`](#calc_merkle_tree_from_leaves) + - [`get_merkle_root`](#get_merkle_root) - [`bls_domain`](#bls_domain) - [`slot_to_epoch`](#slot_to_epoch) - [`get_previous_epoch`](#get_previous_epoch) @@ -558,6 +560,33 @@ The `hash` function is SHA256. `def signing_root(object: Container) -> Hash` is a function for computing signing messages, as defined in the [SimpleSerialize spec](../simple-serialize.md#self-signed-containers). +### `calc_merkle_tree_from_leaves` + +```python +zerohashes = [ZERO_HASH] +for layer in range(1, 100): + zerohashes.append(hash(zerohashes[layer - 1] + zerohashes[layer - 1])) +def calc_merkle_tree_from_leaves(values: Sequence[Hash], layer_count: int=32) -> Sequence[Sequence[Hash]]: + values = list(values) + tree = [values[::]] + for h in range(layer_count): + if len(values) % 2 == 1: + values.append(zerohashes[h]) + values = [hash(values[i] + values[i + 1]) for i in range(0, len(values), 2)] + tree.append(values[::]) + return tree +``` + +### `get_merkle_root` + +```python +def get_merkle_root(values: Sequence[Hash], pad_to: int=1) -> Hash: + layer_count = int(log2(pad_to)) + if len(values) == 0: + return zerohashes[layer_count] + return calc_merkle_tree_from_leaves(values, layer_count)[-1][0] +``` + ### `bls_domain` ```python @@ -1144,10 +1173,10 @@ def is_genesis_trigger(deposits: List[Deposit, 2**DEPOSIT_CONTRACT_TREE_DEPTH], # Process deposits state = BeaconState() - for i, deposit in enumerate(deposits): - state.eth1_data.deposit_root = hash_tree_root( - Vector[DepositData, len(deposits)](list(map(lambda deposit: deposit.data, deposits[:i]))) - ) + for deposit_index, deposit in enumerate(deposits): + leaves = [hash_tree_root(d.data) for d in deposits[:deposit_index + 1]] + state.eth1_data.deposit_root = get_merkle_root(leaves, 2**DEPOSIT_CONTRACT_TREE_DEPTH) + state.eth1_deposit_index = deposit_index process_deposit(state, deposit) # Count active validators at genesis @@ -1173,9 +1202,14 @@ def get_genesis_beacon_state(deposits: Sequence[Deposit], genesis_time: int, eth ) # Process genesis deposits - for deposit in deposits: + for deposit_index, deposit in enumerate(deposits): + leaves = [hash_tree_root(d.data) for d in deposits[:deposit_index + 1]] + state.eth1_data.deposit_root = get_merkle_root(leaves, 2**DEPOSIT_CONTRACT_TREE_DEPTH) + state.eth1_deposit_index = deposit_index process_deposit(state, deposit) + assert state.eth1_data.deposit_root == eth1_data.deposit_root + # Process genesis activations for validator in state.validators: if validator.effective_balance == MAX_EFFECTIVE_BALANCE: diff --git a/test_libs/pyspec/eth2spec/test/genesis/test_genesis_trigger.py b/test_libs/pyspec/eth2spec/test/genesis/test_genesis_trigger.py index 9425a1750..783def3ba 100644 --- a/test_libs/pyspec/eth2spec/test/genesis/test_genesis_trigger.py +++ b/test_libs/pyspec/eth2spec/test/genesis/test_genesis_trigger.py @@ -8,12 +8,11 @@ from eth2spec.test.helpers.deposits import ( @spectest_with_bls_switch def test_is_genesis_trigger_false(spec): deposit_count = 2 - genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) + genesis_deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) genesis_time = 1546300800 yield "deposits", genesis_deposits yield "time", genesis_time - yield "deposit_root", deposit_root is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time) assert is_triggered is False @@ -25,13 +24,12 @@ def test_is_genesis_trigger_false(spec): @spectest_with_bls_switch def test_is_genesis_trigger_true(spec): deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT - genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) + genesis_deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) SECONDS_PER_DAY = 86400 genesis_time = 1578009600 - 2 * SECONDS_PER_DAY yield "deposits", genesis_deposits yield "time", genesis_time - yield "deposit_root", deposit_root is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time) assert is_triggered is True @@ -43,11 +41,10 @@ def test_is_genesis_trigger_true(spec): @spectest_with_bls_switch def test_is_genesis_trigger_not_enough_balance(spec): deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT - genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE - 1) + genesis_deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE - 1) genesis_time = 1546300800 yield "deposits", genesis_deposits yield "time", genesis_time - yield "deposit_root", deposit_root is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time) assert is_triggered is False diff --git a/test_libs/pyspec/eth2spec/test/helpers/deposits.py b/test_libs/pyspec/eth2spec/test/helpers/deposits.py index bda4f1699..60ff2a3db 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/deposits.py +++ b/test_libs/pyspec/eth2spec/test/helpers/deposits.py @@ -41,7 +41,9 @@ def build_deposit(spec, amount, withdrawal_credentials, signed): - deposit_data = build_deposit_data(spec, pubkey, privkey, amount, withdrawal_credentials, state=state, signed=signed) + deposit_data = build_deposit_data( + spec, pubkey, privkey, amount, withdrawal_credentials, state=state, signed=signed, + ) item = deposit_data.hash_tree_root() index = len(deposit_data_leaves) @@ -63,6 +65,7 @@ def build_deposit(spec, def prepare_genesis_deposits(spec, genesis_validator_count, amount, signed=False): genesis_deposit_data_list = [] deposit_data_leaves = [] + genesis_deposits = [] for validator_index in range(genesis_validator_count): pubkey = pubkeys[validator_index] privkey = privkeys[validator_index] @@ -79,13 +82,11 @@ def prepare_genesis_deposits(spec, genesis_validator_count, amount, signed=False deposit_data_leaves.append(item) genesis_deposit_data_list.append(deposit_data) - tree = calc_merkle_tree_from_leaves(tuple(deposit_data_leaves)) - root = get_merkle_root((tuple(deposit_data_leaves))) - - genesis_deposits = list( - spec.Deposit(proof=list(get_merkle_proof(tree, item_index=index)), data=deposit_data) - for index, deposit_data in enumerate(genesis_deposit_data_list) - ) + tree = calc_merkle_tree_from_leaves(tuple(deposit_data_leaves)) + root = get_merkle_root((tuple(deposit_data_leaves)), 2**32) + genesis_deposits.append( + spec.Deposit(proof=list(get_merkle_proof(tree, item_index=validator_index)), data=deposit_data) + ) return genesis_deposits, root diff --git a/test_libs/pyspec/eth2spec/utils/merkle_minimal.py b/test_libs/pyspec/eth2spec/utils/merkle_minimal.py index e3e81f3a5..e9416ea05 100644 --- a/test_libs/pyspec/eth2spec/utils/merkle_minimal.py +++ b/test_libs/pyspec/eth2spec/utils/merkle_minimal.py @@ -1,5 +1,5 @@ from .hash_function import hash -from math import log2 +from math import log2 ZERO_BYTES32 = b'\x00' * 32 diff --git a/test_libs/pyspec/eth2spec/utils/test_merkle_minimal.py b/test_libs/pyspec/eth2spec/utils/test_merkle_minimal.py index 1c72a649b..f1ed768e6 100644 --- a/test_libs/pyspec/eth2spec/utils/test_merkle_minimal.py +++ b/test_libs/pyspec/eth2spec/utils/test_merkle_minimal.py @@ -1,5 +1,5 @@ import pytest -from .merkle_minimal import zerohashes, merkleize_chunks +from .merkle_minimal import zerohashes, merkleize_chunks, get_merkle_root from .hash_function import hash @@ -53,6 +53,7 @@ cases = [ 'depth,count,pow2,value', cases, ) -def test_merkleize_chunks(depth, count, pow2, value): +def test_merkleize_chunks_and_get_merkle_root(depth, count, pow2, value): chunks = [e(i) for i in range(count)] assert merkleize_chunks(chunks, pad_to=pow2) == value + assert get_merkle_root(chunks, pad_to=pow2) == value From cb2bfd67dc18d19f69f293c424370437ec08ae0e Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Sat, 29 Jun 2019 02:27:48 +0800 Subject: [PATCH 18/49] Apply Proto's feedback of list(map(...)) --- specs/core/0_beacon-chain.md | 8 ++++---- test_libs/pyspec/eth2spec/test/helpers/deposits.py | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 25a7340d3..9e59212fd 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1173,9 +1173,9 @@ def is_genesis_trigger(deposits: List[Deposit, 2**DEPOSIT_CONTRACT_TREE_DEPTH], # Process deposits state = BeaconState() + leaves = list(map(lambda deposit: hash_tree_root(deposit.data), deposits)) for deposit_index, deposit in enumerate(deposits): - leaves = [hash_tree_root(d.data) for d in deposits[:deposit_index + 1]] - state.eth1_data.deposit_root = get_merkle_root(leaves, 2**DEPOSIT_CONTRACT_TREE_DEPTH) + state.eth1_data.deposit_root = get_merkle_root(leaves[:deposit_index + 1], 2**DEPOSIT_CONTRACT_TREE_DEPTH) state.eth1_deposit_index = deposit_index process_deposit(state, deposit) @@ -1202,9 +1202,9 @@ def get_genesis_beacon_state(deposits: Sequence[Deposit], genesis_time: int, eth ) # Process genesis deposits + leaves = list(map(lambda deposit: hash_tree_root(deposit.data), deposits)) for deposit_index, deposit in enumerate(deposits): - leaves = [hash_tree_root(d.data) for d in deposits[:deposit_index + 1]] - state.eth1_data.deposit_root = get_merkle_root(leaves, 2**DEPOSIT_CONTRACT_TREE_DEPTH) + state.eth1_data.deposit_root = get_merkle_root(leaves[:deposit_index + 1], 2**DEPOSIT_CONTRACT_TREE_DEPTH) state.eth1_deposit_index = deposit_index process_deposit(state, deposit) diff --git a/test_libs/pyspec/eth2spec/test/helpers/deposits.py b/test_libs/pyspec/eth2spec/test/helpers/deposits.py index 60ff2a3db..529dd8c12 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/deposits.py +++ b/test_libs/pyspec/eth2spec/test/helpers/deposits.py @@ -51,8 +51,6 @@ def build_deposit(spec, tree = calc_merkle_tree_from_leaves(tuple(deposit_data_leaves)) root = get_merkle_root((tuple(deposit_data_leaves))) proof = list(get_merkle_proof(tree, item_index=index)) - assert spec.verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, index, root) - deposit = spec.Deposit( proof=list(proof), index=index, From 7bc6a46eaaecfe73dcdbc99067f8f7ae77d7c220 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Sat, 29 Jun 2019 02:51:24 +0800 Subject: [PATCH 19/49] Fix `build_deposit` --- test_libs/pyspec/eth2spec/test/helpers/deposits.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/test_libs/pyspec/eth2spec/test/helpers/deposits.py b/test_libs/pyspec/eth2spec/test/helpers/deposits.py index 529dd8c12..d7df156a3 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/deposits.py +++ b/test_libs/pyspec/eth2spec/test/helpers/deposits.py @@ -48,20 +48,20 @@ def build_deposit(spec, item = deposit_data.hash_tree_root() index = len(deposit_data_leaves) deposit_data_leaves.append(item) - tree = calc_merkle_tree_from_leaves(tuple(deposit_data_leaves)) - root = get_merkle_root((tuple(deposit_data_leaves))) + tree = calc_merkle_tree_from_leaves(tuple(deposit_data_leaves), spec.DEPOSIT_CONTRACT_TREE_DEPTH) + root = get_merkle_root((tuple(deposit_data_leaves)), 2**spec.DEPOSIT_CONTRACT_TREE_DEPTH) proof = list(get_merkle_proof(tree, item_index=index)) deposit = spec.Deposit( proof=list(proof), index=index, data=deposit_data, ) + assert spec.verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, index, root) return deposit, root, deposit_data_leaves def prepare_genesis_deposits(spec, genesis_validator_count, amount, signed=False): - genesis_deposit_data_list = [] deposit_data_leaves = [] genesis_deposits = [] for validator_index in range(genesis_validator_count): @@ -78,10 +78,9 @@ def prepare_genesis_deposits(spec, genesis_validator_count, amount, signed=False sign_deposit_data(spec, deposit_data, privkey) # state=None item = deposit_data.hash_tree_root() deposit_data_leaves.append(item) - genesis_deposit_data_list.append(deposit_data) - tree = calc_merkle_tree_from_leaves(tuple(deposit_data_leaves)) - root = get_merkle_root((tuple(deposit_data_leaves)), 2**32) + tree = calc_merkle_tree_from_leaves(tuple(deposit_data_leaves), spec.DEPOSIT_CONTRACT_TREE_DEPTH) + root = get_merkle_root((tuple(deposit_data_leaves)), 2**spec.DEPOSIT_CONTRACT_TREE_DEPTH) genesis_deposits.append( spec.Deposit(proof=list(get_merkle_proof(tree, item_index=validator_index)), data=deposit_data) ) From ad943bbd06def7e25918ffaa3c39793175741176 Mon Sep 17 00:00:00 2001 From: Justin Drake Date: Sat, 29 Jun 2019 08:39:27 +0100 Subject: [PATCH 20/49] Make deposit root the root of an SSZ vector --- deposit_contract/contracts/validator_registration.v.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/deposit_contract/contracts/validator_registration.v.py b/deposit_contract/contracts/validator_registration.v.py index 14f100520..0c129dac4 100644 --- a/deposit_contract/contracts/validator_registration.v.py +++ b/deposit_contract/contracts/validator_registration.v.py @@ -43,7 +43,8 @@ def to_little_endian_64(value: uint256) -> bytes[8]: @public @constant def get_deposit_root() -> bytes32: - node: bytes32 = 0x0000000000000000000000000000000000000000000000000000000000000000 + zero_bytes32: bytes32 = 0x0000000000000000000000000000000000000000000000000000000000000000 + node: bytes32 = zero_bytes32 size: uint256 = self.deposit_count for height in range(DEPOSIT_CONTRACT_TREE_DEPTH): if bitwise_and(size, 1) == 1: # More gas efficient than `size % 2 == 1` @@ -51,7 +52,7 @@ def get_deposit_root() -> bytes32: else: node = sha256(concat(node, self.zero_hashes[height])) size /= 2 - return node + return sha256(concat(node, slice(zero_bytes32, start=0, len=24), self.to_little_endian_64(deposit_amount)) @public From d820dbd7b1b402076ff7195db43fe826db19ebb0 Mon Sep 17 00:00:00 2001 From: Justin Drake Date: Sat, 29 Jun 2019 09:01:05 +0100 Subject: [PATCH 21/49] Compile contract --- deposit_contract/contracts/validator_registration.json | 2 +- deposit_contract/contracts/validator_registration.v.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deposit_contract/contracts/validator_registration.json b/deposit_contract/contracts/validator_registration.json index 1988b28c0..5f154fa4c 100644 --- a/deposit_contract/contracts/validator_registration.json +++ b/deposit_contract/contracts/validator_registration.json @@ -1 +1 @@ -{"abi": [{"name": "Deposit", "inputs": [{"type": "bytes", "name": "pubkey", "indexed": false}, {"type": "bytes", "name": "withdrawal_credentials", "indexed": false}, {"type": "bytes", "name": "amount", "indexed": false}, {"type": "bytes", "name": "signature", "indexed": false}, {"type": "bytes", "name": "index", "indexed": false}], "anonymous": false, "type": "event"}, {"outputs": [], "inputs": [], "constant": false, "payable": false, "type": "constructor"}, {"name": "get_deposit_root", "outputs": [{"type": "bytes32", "name": "out"}], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 79221}, {"name": "get_deposit_count", "outputs": [{"type": "bytes", "name": "out"}], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 10433}, {"name": "deposit", "outputs": [], "inputs": [{"type": "bytes", "name": "pubkey"}, {"type": "bytes", "name": "withdrawal_credentials"}, {"type": "bytes", "name": "signature"}], "constant": false, "payable": true, "type": "function", "gas": 1334417}], "bytecode": "0x600035601c52740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a052341561009e57600080fd5b6101406000601f818352015b600061014051602081106100bd57600080fd5b600260c052602060c020015460208261016001015260208101905061014051602081106100e957600080fd5b600260c052602060c020015460208261016001015260208101905080610160526101609050602060c0825160208401600060025af161012757600080fd5b60c0519050606051600161014051018060405190131561014657600080fd5b809190121561015457600080fd5b6020811061016157600080fd5b600260c052602060c02001555b81516001018083528114156100aa575b50506111c656600035601c52740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a052600015610277575b6101605261014052600061018052610140516101a0526101c060006008818352015b61018051600860008112156100da578060000360020a82046100e1565b8060020a82025b905090506101805260ff6101a051166101e052610180516101e0516101805101101561010c57600080fd5b6101e0516101805101610180526101a0517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86000811215610155578060000360020a820461015c565b8060020a82025b905090506101a0525b81516001018083528114156100bd575b50506018600860208206610200016020828401111561019357600080fd5b60208061022082610180600060046015f15050818152809050905090508051602001806102c0828460006004600a8704601201f16101d057600080fd5b50506102c05160206001820306601f82010390506103206102c0516008818352015b826103205111156102025761021e565b6000610320516102e001535b81516001018083528114156101f2575b50505060206102a05260406102c0510160206001820306601f8201039050610280525b6000610280511115156102535761026f565b602061028051036102a001516020610280510361028052610241565b610160515650005b63c5f2892f60005114156103cf57341561029057600080fd5b6000610140526001546101605261018060006020818352015b600160016101605116141561032a57600061018051602081106102cb57600080fd5b600060c052602060c02001546020826102200101526020810190506101405160208261022001015260208101905080610220526102209050602060c0825160208401600060025af161031c57600080fd5b60c051905061014052610398565b6000610140516020826101a0010152602081019050610180516020811061035057600080fd5b600260c052602060c02001546020826101a0010152602081019050806101a0526101a09050602060c0825160208401600060025af161038e57600080fd5b60c0519050610140525b61016060026103a657600080fd5b60028151048152505b81516001018083528114156102a9575b50506101405160005260206000f3005b63621fd13060005114156104e15734156103e857600080fd5b63806732896101405260015461016052610160516006580161009b565b506101c0526000610220525b6101c05160206001820306601f8201039050610220511015156104335761044c565b610220516101e001526102205160200161022052610411565b6101c0805160200180610280828460006004600a8704601201f161046f57600080fd5b50506102805160206001820306601f82010390506102e0610280516008818352015b826102e05111156104a1576104bd565b60006102e0516102a001535b8151600101808352811415610491575b5050506020610260526040610280510160206001820306601f8201039050610260f3005b63c47e300d600051141561103b57606060046101403760506004356004016101a037603060043560040135111561051757600080fd5b604060243560040161022037602060243560040135111561053757600080fd5b608060443560040161028037606060443560040135111561055757600080fd5b63ffffffff6001541061056957600080fd5b633b9aca00610340526103405161057f57600080fd5b61034051340461032052633b9aca0061032051101561059d57600080fd5b60306101a051146105ad57600080fd5b602061022051146105bd57600080fd5b606061028051146105cd57600080fd5b6101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516103405161036051610380516103a05163806732896103c052610320516103e0526103e0516006580161009b565b506104405260006104a0525b6104405160206001820306601f82010390506104a05110151561065d57610676565b6104a05161046001526104a0516020016104a05261063b565b6103a05261038052610360526103405261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a052610440805160200180610360828460006004600a8704601201f16106dd57600080fd5b50506101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516103405161036051610380516103a0516103c0516103e05161040051610420516104405161046051610480516104a05163806732896104c0526001546104e0526104e0516006580161009b565b506105405260006105a0525b6105405160206001820306601f82010390506105a05110151561078e576107a7565b6105a05161056001526105a0516020016105a05261076c565b6104a05261048052610460526104405261042052610400526103e0526103c0526103a05261038052610360526103405261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a0526105408051602001806105c0828460006004600a8704601201f161082e57600080fd5b505060a06106405261064051610680526101a08051602001806106405161068001828460006004600a8704601201f161086657600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516040818352015b83610620511015156108a4576108c1565b6000610620516020850101535b8151600101808352811415610893575b50505050602061064051610680015160206001820306601f820103905061064051010161064052610640516106a0526102208051602001806106405161068001828460006004600a8704601201f161091857600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516020818352015b836106205110151561095657610973565b6000610620516020850101535b8151600101808352811415610945575b50505050602061064051610680015160206001820306601f820103905061064051010161064052610640516106c0526103608051602001806106405161068001828460006004600a8704601201f16109ca57600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516020818352015b8361062051101515610a0857610a25565b6000610620516020850101535b81516001018083528114156109f7575b50505050602061064051610680015160206001820306601f820103905061064051010161064052610640516106e0526102808051602001806106405161068001828460006004600a8704601201f1610a7c57600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516060818352015b8361062051101515610aba57610ad7565b6000610620516020850101535b8151600101808352811415610aa9575b50505050602061064051610680015160206001820306601f82010390506106405101016106405261064051610700526105c08051602001806106405161068001828460006004600a8704601201f1610b2e57600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516020818352015b8361062051101515610b6c57610b89565b6000610620516020850101535b8151600101808352811415610b5b575b50505050602061064051610680015160206001820306601f8201039050610640510101610640527fdc5fc95703516abd38fa03c3737ff3b52dc52347055c8028460fdf5bbe2f12ce61064051610680a160006107205260006101a06030806020846107e001018260208501600060046016f150508051820191505060006010602082066107600160208284011115610c2057600080fd5b60208061078082610720600060046015f15050818152809050905090506010806020846107e001018260208501600060046013f1505080518201915050806107e0526107e09050602060c0825160208401600060025af1610c8057600080fd5b60c0519050610740526000600060406020820661088001610280518284011115610ca957600080fd5b6060806108a0826020602088068803016102800160006004601bf1505081815280905090509050602060c0825160208401600060025af1610ce957600080fd5b60c0519050602082610a800101526020810190506000604060206020820661094001610280518284011115610d1d57600080fd5b606080610960826020602088068803016102800160006004601bf1505081815280905090509050602080602084610a0001018260208501600060046015f150508051820191505061072051602082610a0001015260208101905080610a0052610a009050602060c0825160208401600060025af1610d9a57600080fd5b60c0519050602082610a8001015260208101905080610a8052610a809050602060c0825160208401600060025af1610dd157600080fd5b60c0519050610860526000600061074051602082610b20010152602081019050610220602080602084610b2001018260208501600060046015f150508051820191505080610b2052610b209050602060c0825160208401600060025af1610e3757600080fd5b60c0519050602082610ca00101526020810190506000610360600880602084610c2001018260208501600060046012f15050805182019150506000601860208206610ba00160208284011115610e8c57600080fd5b602080610bc082610720600060046015f1505081815280905090509050601880602084610c2001018260208501600060046014f150508051820191505061086051602082610c2001015260208101905080610c2052610c209050602060c0825160208401600060025af1610eff57600080fd5b60c0519050602082610ca001015260208101905080610ca052610ca09050602060c0825160208401600060025af1610f3657600080fd5b60c0519050610b00526001805460018254011015610f5357600080fd5b6001815401815550600154610d2052610d4060006020818352015b60016001610d2051161415610fa357610b0051610d405160208110610f9257600080fd5b600060c052602060c0200155611037565b6000610d405160208110610fb657600080fd5b600060c052602060c0200154602082610d60010152602081019050610b0051602082610d6001015260208101905080610d6052610d609050602060c0825160208401600060025af161100757600080fd5b60c0519050610b0052610d20600261101e57600080fd5b60028151048152505b8151600101808352811415610f6e575b5050005b60006000fd5b6101856111c6036101856000396101856111c6036000f3"} \ No newline at end of file +{"abi": [{"name": "Deposit", "inputs": [{"type": "bytes", "name": "pubkey", "indexed": false}, {"type": "bytes", "name": "withdrawal_credentials", "indexed": false}, {"type": "bytes", "name": "amount", "indexed": false}, {"type": "bytes", "name": "signature", "indexed": false}, {"type": "bytes", "name": "index", "indexed": false}], "anonymous": false, "type": "event"}, {"outputs": [], "inputs": [], "constant": false, "payable": false, "type": "constructor"}, {"name": "get_deposit_root", "outputs": [{"type": "bytes32", "name": "out"}], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 91830}, {"name": "get_deposit_count", "outputs": [{"type": "bytes", "name": "out"}], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 10433}, {"name": "deposit", "outputs": [], "inputs": [{"type": "bytes", "name": "pubkey"}, {"type": "bytes", "name": "withdrawal_credentials"}, {"type": "bytes", "name": "signature"}], "constant": false, "payable": true, "type": "function", "gas": 1334417}], "bytecode": "0x600035601c52740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a052341561009e57600080fd5b6101406000601f818352015b600061014051602081106100bd57600080fd5b600260c052602060c020015460208261016001015260208101905061014051602081106100e957600080fd5b600260c052602060c020015460208261016001015260208101905080610160526101609050602060c0825160208401600060025af161012757600080fd5b60c0519050606051600161014051018060405190131561014657600080fd5b809190121561015457600080fd5b6020811061016157600080fd5b600260c052602060c02001555b81516001018083528114156100aa575b505061136756600035601c52740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a052600015610277575b6101605261014052600061018052610140516101a0526101c060006008818352015b61018051600860008112156100da578060000360020a82046100e1565b8060020a82025b905090506101805260ff6101a051166101e052610180516101e0516101805101101561010c57600080fd5b6101e0516101805101610180526101a0517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86000811215610155578060000360020a820461015c565b8060020a82025b905090506101a0525b81516001018083528114156100bd575b50506018600860208206610200016020828401111561019357600080fd5b60208061022082610180600060046015f15050818152809050905090508051602001806102c0828460006004600a8704601201f16101d057600080fd5b50506102c05160206001820306601f82010390506103206102c0516008818352015b826103205111156102025761021e565b6000610320516102e001535b81516001018083528114156101f2575b50505060206102a05260406102c0510160206001820306601f8201039050610280525b6000610280511115156102535761026f565b602061028051036102a001516020610280510361028052610241565b610160515650005b63c5f2892f600051141561057057341561029057600080fd5b6000610140526101405161016052600154610180526101a060006020818352015b60016001610180511614156103325760006101a051602081106102d357600080fd5b600060c052602060c02001546020826102400101526020810190506101605160208261024001015260208101905080610240526102409050602060c0825160208401600060025af161032457600080fd5b60c0519050610160526103a0565b6000610160516020826101c00101526020810190506101a0516020811061035857600080fd5b600260c052602060c02001546020826101c0010152602081019050806101c0526101c09050602060c0825160208401600060025af161039657600080fd5b60c0519050610160525b61018060026103ae57600080fd5b60028151048152505b81516001018083528114156102b1575b505060006101605160208261044001015260208101905060006018602082066102c001602082840111156103fa57600080fd5b6020806102e082610140600060046015f150508181528090509050905060188060208461044001018260208501600060046014f15050805182019150506101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e051610300516103205163806732896103405260015461036052610360516006580161009b565b506103c0526000610420525b6103c05160206001820306601f8201039050610420511015156104c2576104db565b610420516103e0015261042051602001610420526104a0565b61032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a0526101805261016052610140526103c060088060208461044001018260208501600060046012f150508051820191505080610440526104409050602060c0825160208401600060025af161056157600080fd5b60c051905060005260206000f3005b63621fd130600051141561068257341561058957600080fd5b63806732896101405260015461016052610160516006580161009b565b506101c0526000610220525b6101c05160206001820306601f8201039050610220511015156105d4576105ed565b610220516101e0015261022051602001610220526105b2565b6101c0805160200180610280828460006004600a8704601201f161061057600080fd5b50506102805160206001820306601f82010390506102e0610280516008818352015b826102e05111156106425761065e565b60006102e0516102a001535b8151600101808352811415610632575b5050506020610260526040610280510160206001820306601f8201039050610260f3005b63c47e300d60005114156111dc57606060046101403760506004356004016101a03760306004356004013511156106b857600080fd5b60406024356004016102203760206024356004013511156106d857600080fd5b60806044356004016102803760606044356004013511156106f857600080fd5b63ffffffff6001541061070a57600080fd5b633b9aca00610340526103405161072057600080fd5b61034051340461032052633b9aca0061032051101561073e57600080fd5b60306101a0511461074e57600080fd5b6020610220511461075e57600080fd5b6060610280511461076e57600080fd5b6101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516103405161036051610380516103a05163806732896103c052610320516103e0526103e0516006580161009b565b506104405260006104a0525b6104405160206001820306601f82010390506104a0511015156107fe57610817565b6104a05161046001526104a0516020016104a0526107dc565b6103a05261038052610360526103405261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a052610440805160200180610360828460006004600a8704601201f161087e57600080fd5b50506101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516103405161036051610380516103a0516103c0516103e05161040051610420516104405161046051610480516104a05163806732896104c0526001546104e0526104e0516006580161009b565b506105405260006105a0525b6105405160206001820306601f82010390506105a05110151561092f57610948565b6105a05161056001526105a0516020016105a05261090d565b6104a05261048052610460526104405261042052610400526103e0526103c0526103a05261038052610360526103405261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a0526105408051602001806105c0828460006004600a8704601201f16109cf57600080fd5b505060a06106405261064051610680526101a08051602001806106405161068001828460006004600a8704601201f1610a0757600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516040818352015b8361062051101515610a4557610a62565b6000610620516020850101535b8151600101808352811415610a34575b50505050602061064051610680015160206001820306601f820103905061064051010161064052610640516106a0526102208051602001806106405161068001828460006004600a8704601201f1610ab957600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516020818352015b8361062051101515610af757610b14565b6000610620516020850101535b8151600101808352811415610ae6575b50505050602061064051610680015160206001820306601f820103905061064051010161064052610640516106c0526103608051602001806106405161068001828460006004600a8704601201f1610b6b57600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516020818352015b8361062051101515610ba957610bc6565b6000610620516020850101535b8151600101808352811415610b98575b50505050602061064051610680015160206001820306601f820103905061064051010161064052610640516106e0526102808051602001806106405161068001828460006004600a8704601201f1610c1d57600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516060818352015b8361062051101515610c5b57610c78565b6000610620516020850101535b8151600101808352811415610c4a575b50505050602061064051610680015160206001820306601f82010390506106405101016106405261064051610700526105c08051602001806106405161068001828460006004600a8704601201f1610ccf57600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516020818352015b8361062051101515610d0d57610d2a565b6000610620516020850101535b8151600101808352811415610cfc575b50505050602061064051610680015160206001820306601f8201039050610640510101610640527fdc5fc95703516abd38fa03c3737ff3b52dc52347055c8028460fdf5bbe2f12ce61064051610680a160006107205260006101a06030806020846107e001018260208501600060046016f150508051820191505060006010602082066107600160208284011115610dc157600080fd5b60208061078082610720600060046015f15050818152809050905090506010806020846107e001018260208501600060046013f1505080518201915050806107e0526107e09050602060c0825160208401600060025af1610e2157600080fd5b60c0519050610740526000600060406020820661088001610280518284011115610e4a57600080fd5b6060806108a0826020602088068803016102800160006004601bf1505081815280905090509050602060c0825160208401600060025af1610e8a57600080fd5b60c0519050602082610a800101526020810190506000604060206020820661094001610280518284011115610ebe57600080fd5b606080610960826020602088068803016102800160006004601bf1505081815280905090509050602080602084610a0001018260208501600060046015f150508051820191505061072051602082610a0001015260208101905080610a0052610a009050602060c0825160208401600060025af1610f3b57600080fd5b60c0519050602082610a8001015260208101905080610a8052610a809050602060c0825160208401600060025af1610f7257600080fd5b60c0519050610860526000600061074051602082610b20010152602081019050610220602080602084610b2001018260208501600060046015f150508051820191505080610b2052610b209050602060c0825160208401600060025af1610fd857600080fd5b60c0519050602082610ca00101526020810190506000610360600880602084610c2001018260208501600060046012f15050805182019150506000601860208206610ba0016020828401111561102d57600080fd5b602080610bc082610720600060046015f1505081815280905090509050601880602084610c2001018260208501600060046014f150508051820191505061086051602082610c2001015260208101905080610c2052610c209050602060c0825160208401600060025af16110a057600080fd5b60c0519050602082610ca001015260208101905080610ca052610ca09050602060c0825160208401600060025af16110d757600080fd5b60c0519050610b005260018054600182540110156110f457600080fd5b6001815401815550600154610d2052610d4060006020818352015b60016001610d205116141561114457610b0051610d40516020811061113357600080fd5b600060c052602060c02001556111d8565b6000610d40516020811061115757600080fd5b600060c052602060c0200154602082610d60010152602081019050610b0051602082610d6001015260208101905080610d6052610d609050602060c0825160208401600060025af16111a857600080fd5b60c0519050610b0052610d2060026111bf57600080fd5b60028151048152505b815160010180835281141561110f575b5050005b60006000fd5b61018561136703610185600039610185611367036000f3"} \ No newline at end of file diff --git a/deposit_contract/contracts/validator_registration.v.py b/deposit_contract/contracts/validator_registration.v.py index 0c129dac4..c1f3c6c79 100644 --- a/deposit_contract/contracts/validator_registration.v.py +++ b/deposit_contract/contracts/validator_registration.v.py @@ -52,7 +52,7 @@ def get_deposit_root() -> bytes32: else: node = sha256(concat(node, self.zero_hashes[height])) size /= 2 - return sha256(concat(node, slice(zero_bytes32, start=0, len=24), self.to_little_endian_64(deposit_amount)) + return sha256(concat(node, slice(zero_bytes32, start=0, len=24), self.to_little_endian_64(self.deposit_count))) @public From 34b8d8ab335c31b451d0cfb46fc78cdab723b4f5 Mon Sep 17 00:00:00 2001 From: Justin Drake Date: Sat, 29 Jun 2019 09:13:42 +0100 Subject: [PATCH 22/49] Start modifying test --- deposit_contract/tests/contracts/test_deposit.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/deposit_contract/tests/contracts/test_deposit.py b/deposit_contract/tests/contracts/test_deposit.py index 783af3356..80c3b11c1 100644 --- a/deposit_contract/tests/contracts/test_deposit.py +++ b/deposit_contract/tests/contracts/test_deposit.py @@ -15,6 +15,7 @@ from eth2spec.phase0.spec import ( DepositData, ) from eth2spec.utils.hash_function import hash +from eth2spec.utils.ssz.ssz_typing import List from eth2spec.utils.ssz.ssz_impl import ( hash_tree_root, ) @@ -137,7 +138,7 @@ def test_deposit_tree(registration_contract, w3, assert_tx_failed, deposit_input ) deposit_amount_list = [randint(MIN_DEPOSIT_AMOUNT, FULL_DEPOSIT_AMOUNT * 2) for _ in range(10)] - leaf_nodes = [] + deposit_data_list = List[DepositData, 2**32]() for i in range(0, 10): tx_hash = registration_contract.functions.deposit( *deposit_input, @@ -151,13 +152,11 @@ def test_deposit_tree(registration_contract, w3, assert_tx_failed, deposit_input assert log["index"] == i.to_bytes(8, 'little') - deposit_data = DepositData( + deposit_data_list[i] = DepositData( pubkey=deposit_input[0], withdrawal_credentials=deposit_input[1], amount=deposit_amount_list[i], signature=deposit_input[2], ) - hash_tree_root_result = hash_tree_root(deposit_data) - leaf_nodes.append(hash_tree_root_result) - root = compute_merkle_root(leaf_nodes) + root = hash_tree_root(deposit_data_list) assert root == registration_contract.functions.get_deposit_root().call() From d5d3e49c5f7958a717740c8a13538116a3cd952f Mon Sep 17 00:00:00 2001 From: Justin Drake Date: Sat, 29 Jun 2019 09:25:19 +0100 Subject: [PATCH 23/49] Tests pass --- .../contracts/validator_registration.json | 2 +- .../contracts/validator_registration.v.py | 2 +- .../tests/contracts/test_deposit.py | 196 ++++++++---------- 3 files changed, 93 insertions(+), 107 deletions(-) diff --git a/deposit_contract/contracts/validator_registration.json b/deposit_contract/contracts/validator_registration.json index 5f154fa4c..a3d309269 100644 --- a/deposit_contract/contracts/validator_registration.json +++ b/deposit_contract/contracts/validator_registration.json @@ -1 +1 @@ -{"abi": [{"name": "Deposit", "inputs": [{"type": "bytes", "name": "pubkey", "indexed": false}, {"type": "bytes", "name": "withdrawal_credentials", "indexed": false}, {"type": "bytes", "name": "amount", "indexed": false}, {"type": "bytes", "name": "signature", "indexed": false}, {"type": "bytes", "name": "index", "indexed": false}], "anonymous": false, "type": "event"}, {"outputs": [], "inputs": [], "constant": false, "payable": false, "type": "constructor"}, {"name": "get_deposit_root", "outputs": [{"type": "bytes32", "name": "out"}], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 91830}, {"name": "get_deposit_count", "outputs": [{"type": "bytes", "name": "out"}], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 10433}, {"name": "deposit", "outputs": [], "inputs": [{"type": "bytes", "name": "pubkey"}, {"type": "bytes", "name": "withdrawal_credentials"}, {"type": "bytes", "name": "signature"}], "constant": false, "payable": true, "type": "function", "gas": 1334417}], "bytecode": "0x600035601c52740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a052341561009e57600080fd5b6101406000601f818352015b600061014051602081106100bd57600080fd5b600260c052602060c020015460208261016001015260208101905061014051602081106100e957600080fd5b600260c052602060c020015460208261016001015260208101905080610160526101609050602060c0825160208401600060025af161012757600080fd5b60c0519050606051600161014051018060405190131561014657600080fd5b809190121561015457600080fd5b6020811061016157600080fd5b600260c052602060c02001555b81516001018083528114156100aa575b505061136756600035601c52740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a052600015610277575b6101605261014052600061018052610140516101a0526101c060006008818352015b61018051600860008112156100da578060000360020a82046100e1565b8060020a82025b905090506101805260ff6101a051166101e052610180516101e0516101805101101561010c57600080fd5b6101e0516101805101610180526101a0517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86000811215610155578060000360020a820461015c565b8060020a82025b905090506101a0525b81516001018083528114156100bd575b50506018600860208206610200016020828401111561019357600080fd5b60208061022082610180600060046015f15050818152809050905090508051602001806102c0828460006004600a8704601201f16101d057600080fd5b50506102c05160206001820306601f82010390506103206102c0516008818352015b826103205111156102025761021e565b6000610320516102e001535b81516001018083528114156101f2575b50505060206102a05260406102c0510160206001820306601f8201039050610280525b6000610280511115156102535761026f565b602061028051036102a001516020610280510361028052610241565b610160515650005b63c5f2892f600051141561057057341561029057600080fd5b6000610140526101405161016052600154610180526101a060006020818352015b60016001610180511614156103325760006101a051602081106102d357600080fd5b600060c052602060c02001546020826102400101526020810190506101605160208261024001015260208101905080610240526102409050602060c0825160208401600060025af161032457600080fd5b60c0519050610160526103a0565b6000610160516020826101c00101526020810190506101a0516020811061035857600080fd5b600260c052602060c02001546020826101c0010152602081019050806101c0526101c09050602060c0825160208401600060025af161039657600080fd5b60c0519050610160525b61018060026103ae57600080fd5b60028151048152505b81516001018083528114156102b1575b505060006101605160208261044001015260208101905060006018602082066102c001602082840111156103fa57600080fd5b6020806102e082610140600060046015f150508181528090509050905060188060208461044001018260208501600060046014f15050805182019150506101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e051610300516103205163806732896103405260015461036052610360516006580161009b565b506103c0526000610420525b6103c05160206001820306601f8201039050610420511015156104c2576104db565b610420516103e0015261042051602001610420526104a0565b61032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a0526101805261016052610140526103c060088060208461044001018260208501600060046012f150508051820191505080610440526104409050602060c0825160208401600060025af161056157600080fd5b60c051905060005260206000f3005b63621fd130600051141561068257341561058957600080fd5b63806732896101405260015461016052610160516006580161009b565b506101c0526000610220525b6101c05160206001820306601f8201039050610220511015156105d4576105ed565b610220516101e0015261022051602001610220526105b2565b6101c0805160200180610280828460006004600a8704601201f161061057600080fd5b50506102805160206001820306601f82010390506102e0610280516008818352015b826102e05111156106425761065e565b60006102e0516102a001535b8151600101808352811415610632575b5050506020610260526040610280510160206001820306601f8201039050610260f3005b63c47e300d60005114156111dc57606060046101403760506004356004016101a03760306004356004013511156106b857600080fd5b60406024356004016102203760206024356004013511156106d857600080fd5b60806044356004016102803760606044356004013511156106f857600080fd5b63ffffffff6001541061070a57600080fd5b633b9aca00610340526103405161072057600080fd5b61034051340461032052633b9aca0061032051101561073e57600080fd5b60306101a0511461074e57600080fd5b6020610220511461075e57600080fd5b6060610280511461076e57600080fd5b6101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516103405161036051610380516103a05163806732896103c052610320516103e0526103e0516006580161009b565b506104405260006104a0525b6104405160206001820306601f82010390506104a0511015156107fe57610817565b6104a05161046001526104a0516020016104a0526107dc565b6103a05261038052610360526103405261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a052610440805160200180610360828460006004600a8704601201f161087e57600080fd5b50506101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516103405161036051610380516103a0516103c0516103e05161040051610420516104405161046051610480516104a05163806732896104c0526001546104e0526104e0516006580161009b565b506105405260006105a0525b6105405160206001820306601f82010390506105a05110151561092f57610948565b6105a05161056001526105a0516020016105a05261090d565b6104a05261048052610460526104405261042052610400526103e0526103c0526103a05261038052610360526103405261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a0526105408051602001806105c0828460006004600a8704601201f16109cf57600080fd5b505060a06106405261064051610680526101a08051602001806106405161068001828460006004600a8704601201f1610a0757600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516040818352015b8361062051101515610a4557610a62565b6000610620516020850101535b8151600101808352811415610a34575b50505050602061064051610680015160206001820306601f820103905061064051010161064052610640516106a0526102208051602001806106405161068001828460006004600a8704601201f1610ab957600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516020818352015b8361062051101515610af757610b14565b6000610620516020850101535b8151600101808352811415610ae6575b50505050602061064051610680015160206001820306601f820103905061064051010161064052610640516106c0526103608051602001806106405161068001828460006004600a8704601201f1610b6b57600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516020818352015b8361062051101515610ba957610bc6565b6000610620516020850101535b8151600101808352811415610b98575b50505050602061064051610680015160206001820306601f820103905061064051010161064052610640516106e0526102808051602001806106405161068001828460006004600a8704601201f1610c1d57600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516060818352015b8361062051101515610c5b57610c78565b6000610620516020850101535b8151600101808352811415610c4a575b50505050602061064051610680015160206001820306601f82010390506106405101016106405261064051610700526105c08051602001806106405161068001828460006004600a8704601201f1610ccf57600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516020818352015b8361062051101515610d0d57610d2a565b6000610620516020850101535b8151600101808352811415610cfc575b50505050602061064051610680015160206001820306601f8201039050610640510101610640527fdc5fc95703516abd38fa03c3737ff3b52dc52347055c8028460fdf5bbe2f12ce61064051610680a160006107205260006101a06030806020846107e001018260208501600060046016f150508051820191505060006010602082066107600160208284011115610dc157600080fd5b60208061078082610720600060046015f15050818152809050905090506010806020846107e001018260208501600060046013f1505080518201915050806107e0526107e09050602060c0825160208401600060025af1610e2157600080fd5b60c0519050610740526000600060406020820661088001610280518284011115610e4a57600080fd5b6060806108a0826020602088068803016102800160006004601bf1505081815280905090509050602060c0825160208401600060025af1610e8a57600080fd5b60c0519050602082610a800101526020810190506000604060206020820661094001610280518284011115610ebe57600080fd5b606080610960826020602088068803016102800160006004601bf1505081815280905090509050602080602084610a0001018260208501600060046015f150508051820191505061072051602082610a0001015260208101905080610a0052610a009050602060c0825160208401600060025af1610f3b57600080fd5b60c0519050602082610a8001015260208101905080610a8052610a809050602060c0825160208401600060025af1610f7257600080fd5b60c0519050610860526000600061074051602082610b20010152602081019050610220602080602084610b2001018260208501600060046015f150508051820191505080610b2052610b209050602060c0825160208401600060025af1610fd857600080fd5b60c0519050602082610ca00101526020810190506000610360600880602084610c2001018260208501600060046012f15050805182019150506000601860208206610ba0016020828401111561102d57600080fd5b602080610bc082610720600060046015f1505081815280905090509050601880602084610c2001018260208501600060046014f150508051820191505061086051602082610c2001015260208101905080610c2052610c209050602060c0825160208401600060025af16110a057600080fd5b60c0519050602082610ca001015260208101905080610ca052610ca09050602060c0825160208401600060025af16110d757600080fd5b60c0519050610b005260018054600182540110156110f457600080fd5b6001815401815550600154610d2052610d4060006020818352015b60016001610d205116141561114457610b0051610d40516020811061113357600080fd5b600060c052602060c02001556111d8565b6000610d40516020811061115757600080fd5b600060c052602060c0200154602082610d60010152602081019050610b0051602082610d6001015260208101905080610d6052610d609050602060c0825160208401600060025af16111a857600080fd5b60c0519050610b0052610d2060026111bf57600080fd5b60028151048152505b815160010180835281141561110f575b5050005b60006000fd5b61018561136703610185600039610185611367036000f3"} \ No newline at end of file +{"abi": [{"name": "Deposit", "inputs": [{"type": "bytes", "name": "pubkey", "indexed": false}, {"type": "bytes", "name": "withdrawal_credentials", "indexed": false}, {"type": "bytes", "name": "amount", "indexed": false}, {"type": "bytes", "name": "signature", "indexed": false}, {"type": "bytes", "name": "index", "indexed": false}], "anonymous": false, "type": "event"}, {"outputs": [], "inputs": [], "constant": false, "payable": false, "type": "constructor"}, {"name": "get_deposit_root", "outputs": [{"type": "bytes32", "name": "out"}], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 91674}, {"name": "get_deposit_count", "outputs": [{"type": "bytes", "name": "out"}], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 10433}, {"name": "deposit", "outputs": [], "inputs": [{"type": "bytes", "name": "pubkey"}, {"type": "bytes", "name": "withdrawal_credentials"}, {"type": "bytes", "name": "signature"}], "constant": false, "payable": true, "type": "function", "gas": 1334417}], "bytecode": "0x600035601c52740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a052341561009e57600080fd5b6101406000601f818352015b600061014051602081106100bd57600080fd5b600260c052602060c020015460208261016001015260208101905061014051602081106100e957600080fd5b600260c052602060c020015460208261016001015260208101905080610160526101609050602060c0825160208401600060025af161012757600080fd5b60c0519050606051600161014051018060405190131561014657600080fd5b809190121561015457600080fd5b6020811061016157600080fd5b600260c052602060c02001555b81516001018083528114156100aa575b50506112ff56600035601c52740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a052600015610277575b6101605261014052600061018052610140516101a0526101c060006008818352015b61018051600860008112156100da578060000360020a82046100e1565b8060020a82025b905090506101805260ff6101a051166101e052610180516101e0516101805101101561010c57600080fd5b6101e0516101805101610180526101a0517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86000811215610155578060000360020a820461015c565b8060020a82025b905090506101a0525b81516001018083528114156100bd575b50506018600860208206610200016020828401111561019357600080fd5b60208061022082610180600060046015f15050818152809050905090508051602001806102c0828460006004600a8704601201f16101d057600080fd5b50506102c05160206001820306601f82010390506103206102c0516008818352015b826103205111156102025761021e565b6000610320516102e001535b81516001018083528114156101f2575b50505060206102a05260406102c0510160206001820306601f8201039050610280525b6000610280511115156102535761026f565b602061028051036102a001516020610280510361028052610241565b610160515650005b63c5f2892f600051141561050857341561029057600080fd5b6000610140526101405161016052600154610180526101a060006020818352015b60016001610180511614156103325760006101a051602081106102d357600080fd5b600060c052602060c02001546020826102400101526020810190506101605160208261024001015260208101905080610240526102409050602060c0825160208401600060025af161032457600080fd5b60c0519050610160526103a0565b6000610160516020826101c00101526020810190506101a0516020811061035857600080fd5b600260c052602060c02001546020826101c0010152602081019050806101c0526101c09050602060c0825160208401600060025af161039657600080fd5b60c0519050610160525b61018060026103ae57600080fd5b60028151048152505b81516001018083528114156102b1575b505060006101605160208261044001015260208101905061014051610160516101805163806732896102c0526001546102e0526102e0516006580161009b565b506103405260006103a0525b6103405160206001820306601f82010390506103a0511015156104355761044e565b6103a05161036001526103a0516020016103a052610413565b61018052610160526101405261034060088060208461044001018260208501600060046012f150508051820191505060006018602082066103c0016020828401111561049957600080fd5b6020806103e082610140600060046015f150508181528090509050905060188060208461044001018260208501600060046014f150508051820191505080610440526104409050602060c0825160208401600060025af16104f957600080fd5b60c051905060005260206000f3005b63621fd130600051141561061a57341561052157600080fd5b63806732896101405260015461016052610160516006580161009b565b506101c0526000610220525b6101c05160206001820306601f82010390506102205110151561056c57610585565b610220516101e00152610220516020016102205261054a565b6101c0805160200180610280828460006004600a8704601201f16105a857600080fd5b50506102805160206001820306601f82010390506102e0610280516008818352015b826102e05111156105da576105f6565b60006102e0516102a001535b81516001018083528114156105ca575b5050506020610260526040610280510160206001820306601f8201039050610260f3005b63c47e300d600051141561117457606060046101403760506004356004016101a037603060043560040135111561065057600080fd5b604060243560040161022037602060243560040135111561067057600080fd5b608060443560040161028037606060443560040135111561069057600080fd5b63ffffffff600154106106a257600080fd5b633b9aca0061034052610340516106b857600080fd5b61034051340461032052633b9aca006103205110156106d657600080fd5b60306101a051146106e657600080fd5b602061022051146106f657600080fd5b6060610280511461070657600080fd5b6101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516103405161036051610380516103a05163806732896103c052610320516103e0526103e0516006580161009b565b506104405260006104a0525b6104405160206001820306601f82010390506104a051101515610796576107af565b6104a05161046001526104a0516020016104a052610774565b6103a05261038052610360526103405261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a052610440805160200180610360828460006004600a8704601201f161081657600080fd5b50506101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516103405161036051610380516103a0516103c0516103e05161040051610420516104405161046051610480516104a05163806732896104c0526001546104e0526104e0516006580161009b565b506105405260006105a0525b6105405160206001820306601f82010390506105a0511015156108c7576108e0565b6105a05161056001526105a0516020016105a0526108a5565b6104a05261048052610460526104405261042052610400526103e0526103c0526103a05261038052610360526103405261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a0526105408051602001806105c0828460006004600a8704601201f161096757600080fd5b505060a06106405261064051610680526101a08051602001806106405161068001828460006004600a8704601201f161099f57600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516040818352015b83610620511015156109dd576109fa565b6000610620516020850101535b81516001018083528114156109cc575b50505050602061064051610680015160206001820306601f820103905061064051010161064052610640516106a0526102208051602001806106405161068001828460006004600a8704601201f1610a5157600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516020818352015b8361062051101515610a8f57610aac565b6000610620516020850101535b8151600101808352811415610a7e575b50505050602061064051610680015160206001820306601f820103905061064051010161064052610640516106c0526103608051602001806106405161068001828460006004600a8704601201f1610b0357600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516020818352015b8361062051101515610b4157610b5e565b6000610620516020850101535b8151600101808352811415610b30575b50505050602061064051610680015160206001820306601f820103905061064051010161064052610640516106e0526102808051602001806106405161068001828460006004600a8704601201f1610bb557600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516060818352015b8361062051101515610bf357610c10565b6000610620516020850101535b8151600101808352811415610be2575b50505050602061064051610680015160206001820306601f82010390506106405101016106405261064051610700526105c08051602001806106405161068001828460006004600a8704601201f1610c6757600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516020818352015b8361062051101515610ca557610cc2565b6000610620516020850101535b8151600101808352811415610c94575b50505050602061064051610680015160206001820306601f8201039050610640510101610640527fdc5fc95703516abd38fa03c3737ff3b52dc52347055c8028460fdf5bbe2f12ce61064051610680a160006107205260006101a06030806020846107e001018260208501600060046016f150508051820191505060006010602082066107600160208284011115610d5957600080fd5b60208061078082610720600060046015f15050818152809050905090506010806020846107e001018260208501600060046013f1505080518201915050806107e0526107e09050602060c0825160208401600060025af1610db957600080fd5b60c0519050610740526000600060406020820661088001610280518284011115610de257600080fd5b6060806108a0826020602088068803016102800160006004601bf1505081815280905090509050602060c0825160208401600060025af1610e2257600080fd5b60c0519050602082610a800101526020810190506000604060206020820661094001610280518284011115610e5657600080fd5b606080610960826020602088068803016102800160006004601bf1505081815280905090509050602080602084610a0001018260208501600060046015f150508051820191505061072051602082610a0001015260208101905080610a0052610a009050602060c0825160208401600060025af1610ed357600080fd5b60c0519050602082610a8001015260208101905080610a8052610a809050602060c0825160208401600060025af1610f0a57600080fd5b60c0519050610860526000600061074051602082610b20010152602081019050610220602080602084610b2001018260208501600060046015f150508051820191505080610b2052610b209050602060c0825160208401600060025af1610f7057600080fd5b60c0519050602082610ca00101526020810190506000610360600880602084610c2001018260208501600060046012f15050805182019150506000601860208206610ba00160208284011115610fc557600080fd5b602080610bc082610720600060046015f1505081815280905090509050601880602084610c2001018260208501600060046014f150508051820191505061086051602082610c2001015260208101905080610c2052610c209050602060c0825160208401600060025af161103857600080fd5b60c0519050602082610ca001015260208101905080610ca052610ca09050602060c0825160208401600060025af161106f57600080fd5b60c0519050610b0052600180546001825401101561108c57600080fd5b6001815401815550600154610d2052610d4060006020818352015b60016001610d20511614156110dc57610b0051610d4051602081106110cb57600080fd5b600060c052602060c0200155611170565b6000610d4051602081106110ef57600080fd5b600060c052602060c0200154602082610d60010152602081019050610b0051602082610d6001015260208101905080610d6052610d609050602060c0825160208401600060025af161114057600080fd5b60c0519050610b0052610d20600261115757600080fd5b60028151048152505b81516001018083528114156110a7575b5050005b60006000fd5b6101856112ff036101856000396101856112ff036000f3"} \ No newline at end of file diff --git a/deposit_contract/contracts/validator_registration.v.py b/deposit_contract/contracts/validator_registration.v.py index c1f3c6c79..b49cc45e1 100644 --- a/deposit_contract/contracts/validator_registration.v.py +++ b/deposit_contract/contracts/validator_registration.v.py @@ -52,7 +52,7 @@ def get_deposit_root() -> bytes32: else: node = sha256(concat(node, self.zero_hashes[height])) size /= 2 - return sha256(concat(node, slice(zero_bytes32, start=0, len=24), self.to_little_endian_64(self.deposit_count))) + return sha256(concat(node, self.to_little_endian_64(self.deposit_count), slice(zero_bytes32, start=0, len=24))) @public diff --git a/deposit_contract/tests/contracts/test_deposit.py b/deposit_contract/tests/contracts/test_deposit.py index 80c3b11c1..58e4158a3 100644 --- a/deposit_contract/tests/contracts/test_deposit.py +++ b/deposit_contract/tests/contracts/test_deposit.py @@ -21,116 +21,101 @@ from eth2spec.utils.ssz.ssz_impl import ( ) -def compute_merkle_root(leaf_nodes): - assert len(leaf_nodes) >= 1 - empty_node = b'\x00' * 32 - child_nodes = leaf_nodes[:] - for _ in range(DEPOSIT_CONTRACT_TREE_DEPTH): - parent_nodes = [] - if len(child_nodes) % 2 == 1: - child_nodes.append(empty_node) - for j in range(0, len(child_nodes), 2): - parent_nodes.append(hash(child_nodes[j] + child_nodes[j + 1])) - child_nodes = parent_nodes - empty_node = hash(empty_node + empty_node) - return child_nodes[0] +# @pytest.fixture +# def deposit_input(): +# """ +# pubkey: bytes[48] +# withdrawal_credentials: bytes[32] +# signature: bytes[96] +# """ +# return ( +# b'\x11' * 48, +# b'\x22' * 32, +# b'\x33' * 96, +# ) -@pytest.fixture -def deposit_input(): - """ - pubkey: bytes[48] - withdrawal_credentials: bytes[32] - signature: bytes[96] - """ - return ( - b'\x11' * 48, - b'\x22' * 32, - b'\x33' * 96, - ) +# @pytest.mark.parametrize( +# 'success,deposit_amount', +# [ +# (True, FULL_DEPOSIT_AMOUNT), +# (True, MIN_DEPOSIT_AMOUNT), +# (False, MIN_DEPOSIT_AMOUNT - 1), +# (True, FULL_DEPOSIT_AMOUNT + 1) +# ] +# ) +# def test_deposit_amount(registration_contract, +# w3, +# success, +# deposit_amount, +# assert_tx_failed, +# deposit_input): +# call = registration_contract.functions.deposit(*deposit_input) +# if success: +# assert call.transact({"value": deposit_amount * eth_utils.denoms.gwei}) +# else: +# assert_tx_failed( +# lambda: call.transact({"value": deposit_amount * eth_utils.denoms.gwei}) +# ) -@pytest.mark.parametrize( - 'success,deposit_amount', - [ - (True, FULL_DEPOSIT_AMOUNT), - (True, MIN_DEPOSIT_AMOUNT), - (False, MIN_DEPOSIT_AMOUNT - 1), - (True, FULL_DEPOSIT_AMOUNT + 1) - ] -) -def test_deposit_amount(registration_contract, - w3, - success, - deposit_amount, - assert_tx_failed, - deposit_input): - call = registration_contract.functions.deposit(*deposit_input) - if success: - assert call.transact({"value": deposit_amount * eth_utils.denoms.gwei}) - else: - assert_tx_failed( - lambda: call.transact({"value": deposit_amount * eth_utils.denoms.gwei}) - ) +# @pytest.mark.parametrize( +# 'invalid_pubkey,invalid_withdrawal_credentials,invalid_signature,success', +# [ +# (False, False, False, True), +# (True, False, False, False), +# (False, True, False, False), +# (False, False, True, False), +# ] +# ) +# def test_deposit_inputs(registration_contract, +# w3, +# assert_tx_failed, +# deposit_input, +# invalid_pubkey, +# invalid_withdrawal_credentials, +# invalid_signature, +# success): +# pubkey = deposit_input[0][2:] if invalid_pubkey else deposit_input[0] +# if invalid_withdrawal_credentials: # this one is different to satisfy linter +# withdrawal_credentials = deposit_input[1][2:] +# else: +# withdrawal_credentials = deposit_input[1] +# signature = deposit_input[2][2:] if invalid_signature else deposit_input[2] + +# call = registration_contract.functions.deposit( +# pubkey, +# withdrawal_credentials, +# signature, +# ) +# if success: +# assert call.transact({"value": FULL_DEPOSIT_AMOUNT * eth_utils.denoms.gwei}) +# else: +# assert_tx_failed( +# lambda: call.transact({"value": FULL_DEPOSIT_AMOUNT * eth_utils.denoms.gwei}) +# ) -@pytest.mark.parametrize( - 'invalid_pubkey,invalid_withdrawal_credentials,invalid_signature,success', - [ - (False, False, False, True), - (True, False, False, False), - (False, True, False, False), - (False, False, True, False), - ] -) -def test_deposit_inputs(registration_contract, - w3, - assert_tx_failed, - deposit_input, - invalid_pubkey, - invalid_withdrawal_credentials, - invalid_signature, - success): - pubkey = deposit_input[0][2:] if invalid_pubkey else deposit_input[0] - if invalid_withdrawal_credentials: # this one is different to satisfy linter - withdrawal_credentials = deposit_input[1][2:] - else: - withdrawal_credentials = deposit_input[1] - signature = deposit_input[2][2:] if invalid_signature else deposit_input[2] +# def test_deposit_log(registration_contract, a0, w3, deposit_input): +# log_filter = registration_contract.events.Deposit.createFilter( +# fromBlock='latest', +# ) - call = registration_contract.functions.deposit( - pubkey, - withdrawal_credentials, - signature, - ) - if success: - assert call.transact({"value": FULL_DEPOSIT_AMOUNT * eth_utils.denoms.gwei}) - else: - assert_tx_failed( - lambda: call.transact({"value": FULL_DEPOSIT_AMOUNT * eth_utils.denoms.gwei}) - ) +# deposit_amount_list = [randint(MIN_DEPOSIT_AMOUNT, FULL_DEPOSIT_AMOUNT * 2) for _ in range(3)] +# for i in range(3): +# registration_contract.functions.deposit( +# *deposit_input, +# ).transact({"value": deposit_amount_list[i] * eth_utils.denoms.gwei}) +# logs = log_filter.get_new_entries() +# assert len(logs) == 1 +# log = logs[0]['args'] -def test_deposit_log(registration_contract, a0, w3, deposit_input): - log_filter = registration_contract.events.Deposit.createFilter( - fromBlock='latest', - ) - - deposit_amount_list = [randint(MIN_DEPOSIT_AMOUNT, FULL_DEPOSIT_AMOUNT * 2) for _ in range(3)] - for i in range(3): - registration_contract.functions.deposit( - *deposit_input, - ).transact({"value": deposit_amount_list[i] * eth_utils.denoms.gwei}) - - logs = log_filter.get_new_entries() - assert len(logs) == 1 - log = logs[0]['args'] - - assert log['pubkey'] == deposit_input[0] - assert log['withdrawal_credentials'] == deposit_input[1] - assert log['amount'] == deposit_amount_list[i].to_bytes(8, 'little') - assert log['signature'] == deposit_input[2] - assert log['index'] == i.to_bytes(8, 'little') +# assert log['pubkey'] == deposit_input[0] +# assert log['withdrawal_credentials'] == deposit_input[1] +# assert log['amount'] == deposit_amount_list[i].to_bytes(8, 'little') +# assert log['signature'] == deposit_input[2] +# assert log['index'] == i.to_bytes(8, 'little') def test_deposit_tree(registration_contract, w3, assert_tx_failed, deposit_input): log_filter = registration_contract.events.Deposit.createFilter( @@ -138,7 +123,7 @@ def test_deposit_tree(registration_contract, w3, assert_tx_failed, deposit_input ) deposit_amount_list = [randint(MIN_DEPOSIT_AMOUNT, FULL_DEPOSIT_AMOUNT * 2) for _ in range(10)] - deposit_data_list = List[DepositData, 2**32]() + deposit_data_list = [] for i in range(0, 10): tx_hash = registration_contract.functions.deposit( *deposit_input, @@ -152,11 +137,12 @@ def test_deposit_tree(registration_contract, w3, assert_tx_failed, deposit_input assert log["index"] == i.to_bytes(8, 'little') - deposit_data_list[i] = DepositData( + deposit_data_list.append(DepositData( pubkey=deposit_input[0], withdrawal_credentials=deposit_input[1], amount=deposit_amount_list[i], signature=deposit_input[2], - ) - root = hash_tree_root(deposit_data_list) + )) + + root = hash_tree_root(List[DepositData, 2**32](*(tuple(deposit_data_list)))) assert root == registration_contract.functions.get_deposit_root().call() From a7ceec1e8a6a68a4ba6bf96be4f22f91be0ceffa Mon Sep 17 00:00:00 2001 From: Justin Drake Date: Sat, 29 Jun 2019 09:28:46 +0100 Subject: [PATCH 24/49] Uncomment tests --- .../tests/contracts/test_deposit.py | 171 +++++++++--------- 1 file changed, 86 insertions(+), 85 deletions(-) diff --git a/deposit_contract/tests/contracts/test_deposit.py b/deposit_contract/tests/contracts/test_deposit.py index 58e4158a3..94c7b29d1 100644 --- a/deposit_contract/tests/contracts/test_deposit.py +++ b/deposit_contract/tests/contracts/test_deposit.py @@ -21,101 +21,102 @@ from eth2spec.utils.ssz.ssz_impl import ( ) -# @pytest.fixture -# def deposit_input(): -# """ -# pubkey: bytes[48] -# withdrawal_credentials: bytes[32] -# signature: bytes[96] -# """ -# return ( -# b'\x11' * 48, -# b'\x22' * 32, -# b'\x33' * 96, -# ) +@pytest.fixture +def deposit_input(): + """ + pubkey: bytes[48] + withdrawal_credentials: bytes[32] + signature: bytes[96] + """ + return ( + b'\x11' * 48, + b'\x22' * 32, + b'\x33' * 96, + ) -# @pytest.mark.parametrize( -# 'success,deposit_amount', -# [ -# (True, FULL_DEPOSIT_AMOUNT), -# (True, MIN_DEPOSIT_AMOUNT), -# (False, MIN_DEPOSIT_AMOUNT - 1), -# (True, FULL_DEPOSIT_AMOUNT + 1) -# ] -# ) -# def test_deposit_amount(registration_contract, -# w3, -# success, -# deposit_amount, -# assert_tx_failed, -# deposit_input): -# call = registration_contract.functions.deposit(*deposit_input) -# if success: -# assert call.transact({"value": deposit_amount * eth_utils.denoms.gwei}) -# else: -# assert_tx_failed( -# lambda: call.transact({"value": deposit_amount * eth_utils.denoms.gwei}) -# ) +@pytest.mark.parametrize( + 'success,deposit_amount', + [ + (True, FULL_DEPOSIT_AMOUNT), + (True, MIN_DEPOSIT_AMOUNT), + (False, MIN_DEPOSIT_AMOUNT - 1), + (True, FULL_DEPOSIT_AMOUNT + 1) + ] +) +def test_deposit_amount(registration_contract, + w3, + success, + deposit_amount, + assert_tx_failed, + deposit_input): + call = registration_contract.functions.deposit(*deposit_input) + if success: + assert call.transact({"value": deposit_amount * eth_utils.denoms.gwei}) + else: + assert_tx_failed( + lambda: call.transact({"value": deposit_amount * eth_utils.denoms.gwei}) + ) -# @pytest.mark.parametrize( -# 'invalid_pubkey,invalid_withdrawal_credentials,invalid_signature,success', -# [ -# (False, False, False, True), -# (True, False, False, False), -# (False, True, False, False), -# (False, False, True, False), -# ] -# ) -# def test_deposit_inputs(registration_contract, -# w3, -# assert_tx_failed, -# deposit_input, -# invalid_pubkey, -# invalid_withdrawal_credentials, -# invalid_signature, -# success): -# pubkey = deposit_input[0][2:] if invalid_pubkey else deposit_input[0] -# if invalid_withdrawal_credentials: # this one is different to satisfy linter -# withdrawal_credentials = deposit_input[1][2:] -# else: -# withdrawal_credentials = deposit_input[1] -# signature = deposit_input[2][2:] if invalid_signature else deposit_input[2] +@pytest.mark.parametrize( + 'invalid_pubkey,invalid_withdrawal_credentials,invalid_signature,success', + [ + (False, False, False, True), + (True, False, False, False), + (False, True, False, False), + (False, False, True, False), + ] +) +def test_deposit_inputs(registration_contract, + w3, + assert_tx_failed, + deposit_input, + invalid_pubkey, + invalid_withdrawal_credentials, + invalid_signature, + success): + pubkey = deposit_input[0][2:] if invalid_pubkey else deposit_input[0] + if invalid_withdrawal_credentials: # this one is different to satisfy linter + withdrawal_credentials = deposit_input[1][2:] + else: + withdrawal_credentials = deposit_input[1] + signature = deposit_input[2][2:] if invalid_signature else deposit_input[2] -# call = registration_contract.functions.deposit( -# pubkey, -# withdrawal_credentials, -# signature, -# ) -# if success: -# assert call.transact({"value": FULL_DEPOSIT_AMOUNT * eth_utils.denoms.gwei}) -# else: -# assert_tx_failed( -# lambda: call.transact({"value": FULL_DEPOSIT_AMOUNT * eth_utils.denoms.gwei}) -# ) + call = registration_contract.functions.deposit( + pubkey, + withdrawal_credentials, + signature, + ) + if success: + assert call.transact({"value": FULL_DEPOSIT_AMOUNT * eth_utils.denoms.gwei}) + else: + assert_tx_failed( + lambda: call.transact({"value": FULL_DEPOSIT_AMOUNT * eth_utils.denoms.gwei}) + ) -# def test_deposit_log(registration_contract, a0, w3, deposit_input): -# log_filter = registration_contract.events.Deposit.createFilter( -# fromBlock='latest', -# ) +def test_deposit_log(registration_contract, a0, w3, deposit_input): + log_filter = registration_contract.events.Deposit.createFilter( + fromBlock='latest', + ) -# deposit_amount_list = [randint(MIN_DEPOSIT_AMOUNT, FULL_DEPOSIT_AMOUNT * 2) for _ in range(3)] -# for i in range(3): -# registration_contract.functions.deposit( -# *deposit_input, -# ).transact({"value": deposit_amount_list[i] * eth_utils.denoms.gwei}) + deposit_amount_list = [randint(MIN_DEPOSIT_AMOUNT, FULL_DEPOSIT_AMOUNT * 2) for _ in range(3)] + for i in range(3): + registration_contract.functions.deposit( + *deposit_input, + ).transact({"value": deposit_amount_list[i] * eth_utils.denoms.gwei}) -# logs = log_filter.get_new_entries() -# assert len(logs) == 1 -# log = logs[0]['args'] + logs = log_filter.get_new_entries() + assert len(logs) == 1 + log = logs[0]['args'] + + assert log['pubkey'] == deposit_input[0] + assert log['withdrawal_credentials'] == deposit_input[1] + assert log['amount'] == deposit_amount_list[i].to_bytes(8, 'little') + assert log['signature'] == deposit_input[2] + assert log['index'] == i.to_bytes(8, 'little') -# assert log['pubkey'] == deposit_input[0] -# assert log['withdrawal_credentials'] == deposit_input[1] -# assert log['amount'] == deposit_amount_list[i].to_bytes(8, 'little') -# assert log['signature'] == deposit_input[2] -# assert log['index'] == i.to_bytes(8, 'little') def test_deposit_tree(registration_contract, w3, assert_tx_failed, deposit_input): log_filter = registration_contract.events.Deposit.createFilter( From 7fdf59d012065e59c4d9e771ce03a9d10cf85530 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Sat, 29 Jun 2019 18:09:05 +0800 Subject: [PATCH 25/49] `active_validator_count >= GENESIS_ACTIVE_VALIDATOR_COUNT`: per Eth1 block --- specs/core/0_beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 9e59212fd..7cd5725b1 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1186,7 +1186,7 @@ def is_genesis_trigger(deposits: List[Deposit, 2**DEPOSIT_CONTRACT_TREE_DEPTH], active_validator_count += 1 # Check effective balance to trigger genesis - return active_validator_count == GENESIS_ACTIVE_VALIDATOR_COUNT + return active_validator_count >= GENESIS_ACTIVE_VALIDATOR_COUNT ``` ### Genesis state From b162a8ff8a40f372c1dcfc36b6030b4c9038f225 Mon Sep 17 00:00:00 2001 From: protolambda Date: Sat, 29 Jun 2019 16:48:08 +0200 Subject: [PATCH 26/49] simplify list creation --- deposit_contract/tests/contracts/test_deposit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deposit_contract/tests/contracts/test_deposit.py b/deposit_contract/tests/contracts/test_deposit.py index 94c7b29d1..8c165f0f9 100644 --- a/deposit_contract/tests/contracts/test_deposit.py +++ b/deposit_contract/tests/contracts/test_deposit.py @@ -145,5 +145,5 @@ def test_deposit_tree(registration_contract, w3, assert_tx_failed, deposit_input signature=deposit_input[2], )) - root = hash_tree_root(List[DepositData, 2**32](*(tuple(deposit_data_list)))) + root = hash_tree_root(List[DepositData, 2**32](*deposit_data_list)) assert root == registration_contract.functions.get_deposit_root().call() From f0a8e392434fa06e96b84249c4dd9533d8012cfb Mon Sep 17 00:00:00 2001 From: Justin Drake Date: Sat, 29 Jun 2019 17:29:21 +0100 Subject: [PATCH 27/49] WIP --- specs/core/0_beacon-chain.md | 4 +- .../pyspec/eth2spec/test/helpers/deposits.py | 40 ++++++++----------- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 6f28c0e3d..138d3fd2a 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -437,7 +437,7 @@ class Attestation(Container): ```python class Deposit(Container): - proof: Vector[Hash, DEPOSIT_CONTRACT_TREE_DEPTH] # Merkle path to deposit root + proof: Vector[Hash, DEPOSIT_CONTRACT_TREE_DEPTH + 1] # Merkle path to deposit root data: DepositData ``` @@ -1682,7 +1682,7 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None: assert verify_merkle_branch( leaf=hash_tree_root(deposit.data), proof=deposit.proof, - depth=DEPOSIT_CONTRACT_TREE_DEPTH, + depth=DEPOSIT_CONTRACT_TREE_DEPTH + 1, index=state.eth1_deposit_index, root=state.eth1_data.deposit_root, ) diff --git a/test_libs/pyspec/eth2spec/test/helpers/deposits.py b/test_libs/pyspec/eth2spec/test/helpers/deposits.py index 20ff7440f..5a0909185 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/deposits.py +++ b/test_libs/pyspec/eth2spec/test/helpers/deposits.py @@ -1,11 +1,13 @@ from eth2spec.test.helpers.keys import pubkeys, privkeys from eth2spec.utils.bls import bls_sign from eth2spec.utils.merkle_minimal import calc_merkle_tree_from_leaves, get_merkle_root, get_merkle_proof -from eth2spec.utils.ssz.ssz_impl import signing_root +from eth2spec.utils.ssz.ssz_impl import signing_root, hash_tree_root +from eth2spec.utils.ssz.ssz_typing import List +from eth2spec.phase0.spec import DepositData def build_deposit_data(spec, state, pubkey, privkey, amount, withdrawal_credentials, signed=False): - deposit_data = spec.DepositData( + deposit_data = DepositData( pubkey=pubkey, withdrawal_credentials=withdrawal_credentials, amount=amount, @@ -29,27 +31,21 @@ def sign_deposit_data(spec, state, deposit_data, privkey): def build_deposit(spec, state, - deposit_data_leaves, + deposit_data_list, pubkey, privkey, amount, withdrawal_credentials, signed): deposit_data = build_deposit_data(spec, state, pubkey, privkey, amount, withdrawal_credentials, signed) - - item = deposit_data.hash_tree_root() - index = len(deposit_data_leaves) - deposit_data_leaves.append(item) - tree = calc_merkle_tree_from_leaves(tuple(deposit_data_leaves)) - root = get_merkle_root((tuple(deposit_data_leaves))) - proof = list(get_merkle_proof(tree, item_index=index)) - assert spec.verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, index, root) - - deposit = spec.Deposit( - proof=list(proof), - index=index, - data=deposit_data, - ) + deposit_data_list.append(deposit_data) + index = len(deposit_data_list) + root = hash_tree_root(List[DepositData, 2**32](*deposit_data_list)) + tree = calc_merkle_tree_from_leaves(tuple([d.hash_tree_root() for d in deposit_data_list])) + proof = list(get_merkle_proof(tree, item_index=index)) + [index.to_bytes(32, 'little')] + leaf = deposit_data.hash_tree_root() + assert spec.verify_merkle_branch(leaf, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH + 1, index, root) + deposit = spec.Deposit(proof, index, deposit_data) return deposit, root, deposit_data_leaves @@ -58,9 +54,7 @@ def prepare_state_and_deposit(spec, state, validator_index, amount, withdrawal_c """ Prepare the state for the deposit, and create a deposit for the given validator, depositing the given amount. """ - pre_validator_count = len(state.validators) - # fill previous deposits with zero-hash - deposit_data_leaves = [spec.ZERO_HASH] * pre_validator_count + deposit_data_list = [] pubkey = pubkeys[validator_index] privkey = privkeys[validator_index] @@ -69,10 +63,10 @@ def prepare_state_and_deposit(spec, state, validator_index, amount, withdrawal_c if withdrawal_credentials is None: withdrawal_credentials = spec.int_to_bytes(spec.BLS_WITHDRAWAL_PREFIX, length=1) + spec.hash(pubkey)[1:] - deposit, root, deposit_data_leaves = build_deposit( + deposit, root, deposit_data_list = build_deposit( spec, state, - deposit_data_leaves, + deposit_data_list, pubkey, privkey, amount, @@ -81,5 +75,5 @@ def prepare_state_and_deposit(spec, state, validator_index, amount, withdrawal_c ) state.eth1_data.deposit_root = root - state.eth1_data.deposit_count = len(deposit_data_leaves) + state.eth1_data.deposit_count = len(deposit_data_list) return deposit From d0009b09807b11b970866cd4cffea075e602fee8 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Sun, 30 Jun 2019 01:12:25 +0800 Subject: [PATCH 28/49] Pass `genesis_eth1_block_hash` instead of `genesis_eth1_data` --- specs/core/0_beacon-chain.md | 15 ++++++--------- .../pyspec/eth2spec/test/genesis/test_genesis.py | 16 +++++----------- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 7cd5725b1..1ddf58b05 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1157,10 +1157,7 @@ When `is_genesis_trigger(deposits, time) is True` for the first time let: * `genesis_deposits = deposits` * `genesis_time = time - time % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY` where `SECONDS_PER_DAY = 86400` -* `genesis_eth1_data` be the object of type `Eth1Data` where: - * `genesis_eth1_data.deposit_root` is the deposit root for the last deposit in `deposits` - * `genesis_eth1_data.deposit_count = len(genesis_deposits)` - * `genesis_eth1_data.block_hash` is the Eth 1.0 block hash that emitted the log for the last deposit in `deposits` +* `genesis_eth1_block_hash` is the Eth 1.0 block hash that emitted the log for the last deposit in `deposits` *Note*: The function `is_genesis_trigger` has yet to be agreed upon by the community, and can be updated as necessary. We define the following testing placeholder: @@ -1176,6 +1173,7 @@ def is_genesis_trigger(deposits: List[Deposit, 2**DEPOSIT_CONTRACT_TREE_DEPTH], leaves = list(map(lambda deposit: hash_tree_root(deposit.data), deposits)) for deposit_index, deposit in enumerate(deposits): state.eth1_data.deposit_root = get_merkle_root(leaves[:deposit_index + 1], 2**DEPOSIT_CONTRACT_TREE_DEPTH) + state.eth1_data.deposit_count = deposit_index + 1 state.eth1_deposit_index = deposit_index process_deposit(state, deposit) @@ -1191,13 +1189,13 @@ def is_genesis_trigger(deposits: List[Deposit, 2**DEPOSIT_CONTRACT_TREE_DEPTH], ### Genesis state -Let `genesis_state = get_genesis_beacon_state(genesis_deposits, genesis_time, genesis_eth1_data)`. +Let `genesis_state = get_genesis_beacon_state(genesis_deposits, genesis_time, genesis_eth1_block_hash)`. ```python -def get_genesis_beacon_state(deposits: Sequence[Deposit], genesis_time: int, eth1_data: Eth1Data) -> BeaconState: +def get_genesis_beacon_state(deposits: Sequence[Deposit], genesis_time: int, genesis_eth1_block_hash: Hash) -> BeaconState: state = BeaconState( genesis_time=genesis_time, - eth1_data=eth1_data, + eth1_data=Eth1Data(block_hash=genesis_eth1_block_hash), latest_block_header=BeaconBlockHeader(body_root=hash_tree_root(BeaconBlockBody())), ) @@ -1205,11 +1203,10 @@ def get_genesis_beacon_state(deposits: Sequence[Deposit], genesis_time: int, eth leaves = list(map(lambda deposit: hash_tree_root(deposit.data), deposits)) for deposit_index, deposit in enumerate(deposits): state.eth1_data.deposit_root = get_merkle_root(leaves[:deposit_index + 1], 2**DEPOSIT_CONTRACT_TREE_DEPTH) + state.eth1_data.deposit_count = deposit_index + 1 state.eth1_deposit_index = deposit_index process_deposit(state, deposit) - assert state.eth1_data.deposit_root == eth1_data.deposit_root - # Process genesis activations for validator in state.validators: if validator.effective_balance == MAX_EFFECTIVE_BALANCE: diff --git a/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py b/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py index a89ec8793..0d2b4fbac 100644 --- a/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py +++ b/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py @@ -10,28 +10,22 @@ def test_genesis(spec): deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) genesis_time = 1546300800 - block_hash = b'\x12' * 32 + genesis_eth1_block_hash = b'\x12' * 32 yield "deposits", genesis_deposits - yield "time", genesis_time + yield "genesis_time", genesis_time - genesis_eth1_data = spec.Eth1Data( - deposit_root=deposit_root, - deposit_count=deposit_count, - block_hash=block_hash, - ) - - yield "eth1_data", genesis_eth1_data + yield "genesis_eth1_block_hash", genesis_eth1_block_hash genesis_state = spec.get_genesis_beacon_state( genesis_deposits, genesis_time, - genesis_eth1_data, + genesis_eth1_block_hash, ) assert genesis_state.genesis_time == genesis_time assert len(genesis_state.validators) == deposit_count assert genesis_state.eth1_data.deposit_root == deposit_root assert genesis_state.eth1_data.deposit_count == deposit_count - assert genesis_state.eth1_data.block_hash == block_hash + assert genesis_state.eth1_data.block_hash == genesis_eth1_block_hash yield "state", genesis_state From 1b66323806505a465236f3adb924ea3a777e02cb Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Sun, 30 Jun 2019 01:44:17 +0800 Subject: [PATCH 29/49] head to 1229 --- scripts/build_spec.py | 6 ++-- specs/core/0_beacon-chain.md | 33 ++----------------- .../pyspec/eth2spec/test/helpers/deposits.py | 25 +++++++------- 3 files changed, 17 insertions(+), 47 deletions(-) diff --git a/scripts/build_spec.py b/scripts/build_spec.py index e4e95c7ec..1f5fe1ee6 100644 --- a/scripts/build_spec.py +++ b/scripts/build_spec.py @@ -11,8 +11,7 @@ from typing import ( ) -PHASE0_IMPORTS = '''from math import log2 -from typing import ( +PHASE0_IMPORTS = '''from typing import ( Any, Callable, Dict, Set, Sequence, Tuple, ) @@ -37,8 +36,7 @@ from eth2spec.utils.bls import ( from eth2spec.utils.hash_function import hash ''' -PHASE1_IMPORTS = '''from math import log2 -from typing import ( +PHASE1_IMPORTS = '''from typing import ( Any, Callable, Dict, Optional, Set, Sequence, MutableSequence, Tuple, ) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index f9d529e0c..e51fbde3e 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -52,8 +52,6 @@ - [`hash`](#hash) - [`hash_tree_root`](#hash_tree_root) - [`signing_root`](#signing_root) - - [`calc_merkle_tree_from_leaves`](#calc_merkle_tree_from_leaves) - - [`get_merkle_root`](#get_merkle_root) - [`bls_domain`](#bls_domain) - [`slot_to_epoch`](#slot_to_epoch) - [`get_previous_epoch`](#get_previous_epoch) @@ -562,33 +560,6 @@ The `hash` function is SHA256. `def signing_root(object: Container) -> Hash` is a function for computing signing messages, as defined in the [SimpleSerialize spec](../simple-serialize.md#self-signed-containers). -### `calc_merkle_tree_from_leaves` - -```python -zerohashes = [ZERO_HASH] -for layer in range(1, 100): - zerohashes.append(hash(zerohashes[layer - 1] + zerohashes[layer - 1])) -def calc_merkle_tree_from_leaves(values: Sequence[Hash], layer_count: int=32) -> Sequence[Sequence[Hash]]: - values = list(values) - tree = [values[::]] - for h in range(layer_count): - if len(values) % 2 == 1: - values.append(zerohashes[h]) - values = [hash(values[i] + values[i + 1]) for i in range(0, len(values), 2)] - tree.append(values[::]) - return tree -``` - -### `get_merkle_root` - -```python -def get_merkle_root(values: Sequence[Hash], pad_to: int=1) -> Hash: - layer_count = int(log2(pad_to)) - if len(values) == 0: - return zerohashes[layer_count] - return calc_merkle_tree_from_leaves(values, layer_count)[-1][0] -``` - ### `bls_domain` ```python @@ -1146,7 +1117,7 @@ def is_genesis_trigger(deposits: List[Deposit, 2**DEPOSIT_CONTRACT_TREE_DEPTH], state = BeaconState() leaves = list(map(lambda deposit: hash_tree_root(deposit.data), deposits)) for deposit_index, deposit in enumerate(deposits): - state.eth1_data.deposit_root = get_merkle_root(leaves[:deposit_index + 1], 2**DEPOSIT_CONTRACT_TREE_DEPTH) + state.eth1_data.deposit_root = hash_tree_root(leaves) state.eth1_data.deposit_count = deposit_index + 1 state.eth1_deposit_index = deposit_index process_deposit(state, deposit) @@ -1176,7 +1147,7 @@ def get_genesis_beacon_state(deposits: Sequence[Deposit], genesis_time: int, gen # Process genesis deposits leaves = list(map(lambda deposit: hash_tree_root(deposit.data), deposits)) for deposit_index, deposit in enumerate(deposits): - state.eth1_data.deposit_root = get_merkle_root(leaves[:deposit_index + 1], 2**DEPOSIT_CONTRACT_TREE_DEPTH) + state.eth1_data.deposit_root = hash_tree_root(leaves) state.eth1_data.deposit_count = deposit_index + 1 state.eth1_deposit_index = deposit_index process_deposit(state, deposit) diff --git a/test_libs/pyspec/eth2spec/test/helpers/deposits.py b/test_libs/pyspec/eth2spec/test/helpers/deposits.py index ac842405e..a0d59b9a6 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/deposits.py +++ b/test_libs/pyspec/eth2spec/test/helpers/deposits.py @@ -47,10 +47,10 @@ def build_deposit(spec, spec, pubkey, privkey, amount, withdrawal_credentials, state=state, signed=signed, ) - deposit_data = build_deposit_data(spec, state, pubkey, privkey, amount, withdrawal_credentials, signed) + deposit_data = build_deposit_data(spec, pubkey, privkey, amount, withdrawal_credentials, state=state, signed=signed) deposit_data_list.append(deposit_data) index = len(deposit_data_list) - root = hash_tree_root(List[DepositData, 2**32](*deposit_data_list)) + root = hash_tree_root(List[DepositData, 2**spec.DEPOSIT_CONTRACT_TREE_DEPTH](*deposit_data_list)) tree = calc_merkle_tree_from_leaves(tuple([d.hash_tree_root() for d in deposit_data_list])) proof = list(get_merkle_proof(tree, item_index=index)) + [index.to_bytes(32, 'little')] leaf = deposit_data.hash_tree_root() @@ -61,7 +61,7 @@ def build_deposit(spec, def prepare_genesis_deposits(spec, genesis_validator_count, amount, signed=False): - deposit_data_leaves = [] + deposit_data_list = [] genesis_deposits = [] for validator_index in range(genesis_validator_count): pubkey = pubkeys[validator_index] @@ -73,16 +73,17 @@ def prepare_genesis_deposits(spec, genesis_validator_count, amount, signed=False withdrawal_credentials=withdrawal_credentials, amount=amount, ) - if signed: - sign_deposit_data(spec, deposit_data, privkey) # state=None - item = deposit_data.hash_tree_root() - deposit_data_leaves.append(item) - - tree = calc_merkle_tree_from_leaves(tuple(deposit_data_leaves), spec.DEPOSIT_CONTRACT_TREE_DEPTH) - root = get_merkle_root((tuple(deposit_data_leaves)), 2**spec.DEPOSIT_CONTRACT_TREE_DEPTH) - genesis_deposits.append( - spec.Deposit(proof=list(get_merkle_proof(tree, item_index=validator_index)), data=deposit_data) + deposit, root, deposit_data_list = build_deposit( + spec, + None, + deposit_data_list, + pubkey, + privkey, + amount, + withdrawal_credentials, + signed, ) + genesis_deposits.append(deposit) return genesis_deposits, root From c8dc30eec20bd8116e94ff8d38e1082ec650eb0f Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Sun, 30 Jun 2019 01:56:10 +0800 Subject: [PATCH 30/49] Recover from auto-merge --- specs/core/0_beacon-chain.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index e51fbde3e..f62469d59 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -124,8 +124,7 @@ This document represents the specification for Phase 0 of Ethereum 2.0 -- The Beacon Chain. -At the core of Ethereum 2.0 is a system chain called the "beacon chain". The beacon chain stores and manages the registry of [validators](#dfn-validator). In the initial deployment phases of Ethereum 2.0, the only mechanism to become a [validator](#dfn-validator) is to make a one-way ETH transaction to a deposit contract on Eth 1.0. Activation as a [validator](#dfn-validator) happens when Eth 1.0 deposit receipts are processed by the beacon chain, the activation balance is reached, and a queuing process is completed. Exit is either voluntary or done forcibly as a penalty for misbehavior. - +At the core of Ethereum 2.0 is a system chain called the "beacon chain". The beacon chain stores and manages the registry of [validators](#dfn-validator). In the initial deployment phases of Ethereum 2.0, the only mechanism to become a [validator](#dfn-validator) is to make a one-way ETH transaction to a deposit contract on Ethereum 1.0. Activation as a [validator](#dfn-validator) happens when Ethereum 1.0 deposit receipts are processed by the beacon chain, the activation balance is reached, and a queuing process is completed. Exit is either voluntary or done forcibly as a penalty for misbehavior. The primary source of load on the beacon chain is "attestations". Attestations are simultaneously availability votes for a shard block and proof-of-stake votes for a beacon block. A sufficient number of attestations for the same shard block create a "crosslink", confirming the shard segment up to that shard block into the beacon chain. Crosslinks also serve as infrastructure for asynchronous cross-shard communication. ## Notation @@ -134,7 +133,7 @@ Code snippets appearing in `this style` are to be interpreted as Python code. ## Terminology -* **Validator**—a registered participant in the beacon chain. You can become one by sending ether into the Eth 1.0 deposit contract. +* **Validator**—a registered participant in the beacon chain. You can become one by sending ether into the Ethereum 1.0 deposit contract. * **Active validator**—an active participant in the Ethereum 2.0 consensus invited to, among other things, propose and attest to blocks and vote for crosslinks. * **Committee**—a (pseudo-) randomly sampled subset of [active validators](#dfn-active-validator). When a committee is referred to collectively, as in "this committee attests to X", this is assumed to mean "some subset of that committee that contains enough [validators](#dfn-validator) that the protocol recognizes it as representing the committee". * **Proposer**—the [validator](#dfn-validator) that creates a beacon chain block. @@ -194,7 +193,7 @@ The following values are (non-configurable) constants used throughout the specif | `MIN_GENESIS_TIME` | `1578009600` (Jan 3, 2020) | | `JUSTIFICATION_BITS_LENGTH` | `4` | -* For the safety of cr>>osslinks, `TARGET_COMMITTEE_SIZE` exceeds [the recommended minimum committee size of 111](https://vitalik.ca/files/Ithaca201807_Sharding.pdf); with sufficient active validators (at least `SLOTS_PER_EPOCH * TARGET_COMMITTEE_SIZE`), the shuffling algorithm ensures committee sizes of at least `TARGET_COMMITTEE_SIZE`. (Unbiasable randomness with a Verifiable Delay Function (VDF) will improve committee robustness and lower the safe minimum committee size.) +* For the safety of crosslinks, `TARGET_COMMITTEE_SIZE` exceeds [the recommended minimum committee size of 111](https://vitalik.ca/files/Ithaca201807_Sharding.pdf); with sufficient active validators (at least `SLOTS_PER_EPOCH * TARGET_COMMITTEE_SIZE`), the shuffling algorithm ensures committee sizes of at least `TARGET_COMMITTEE_SIZE`. (Unbiasable randomness with a Verifiable Delay Function (VDF) will improve committee robustness and lower the safe minimum committee size.) ### Gwei values @@ -1095,14 +1094,14 @@ def slash_validator(state: BeaconState, Before genesis has been triggered and for every Eth 1.0 block call `is_genesis_trigger(deposits, time)` where: -* `deposits` is the list of all deposits up to the Eth 1.0 block, ordered chronologically -* `time` is the Unix time of the Eth 1.0 block +* `deposits` is the list of all deposits, ordered chronologically, up to and including the deposit triggering the latest `Deposit` log +* `timestamp` is the Unix timestamp in the Ethereum 1.0 block that emitted the latest `Deposit` log -When `is_genesis_trigger(deposits, time) is True` for the first time let: +When `is_genesis_trigger(deposits, timestamp) is True` for the first time, let: * `genesis_deposits = deposits` -* `genesis_time = time - time % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY` where `SECONDS_PER_DAY = 86400` -* `genesis_eth1_block_hash` is the Eth 1.0 block hash that emitted the log for the last deposit in `deposits` +* `genesis_time = timestamp - timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY` where `SECONDS_PER_DAY = 86400` +* `genesis_eth1_block_hash` is the Ethereum 1.0 block hash that emitted the log for the last deposit in `deposits` *Note*: The function `is_genesis_trigger` has yet to be agreed upon by the community, and can be updated as necessary. We define the following testing placeholder: From 354cd1c1e19fa1008e43b3861da308d9472a5e12 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Sun, 30 Jun 2019 02:02:05 +0800 Subject: [PATCH 31/49] Clean up leftover and linter --- specs/core/0_beacon-chain.md | 10 ++++++---- test_libs/pyspec/eth2spec/test/helpers/deposits.py | 7 +------ 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index f62469d59..5aa57c294 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1092,7 +1092,7 @@ def slash_validator(state: BeaconState, ### Genesis trigger -Before genesis has been triggered and for every Eth 1.0 block call `is_genesis_trigger(deposits, time)` where: +Before genesis has been triggered and whenever the deposit contract emits a `Deposit` log, call the function `is_genesis_trigger(deposits: Sequence[Deposit], timestamp: uint64) -> bool` where: * `deposits` is the list of all deposits, ordered chronologically, up to and including the deposit triggering the latest `Deposit` log * `timestamp` is the Unix timestamp in the Ethereum 1.0 block that emitted the latest `Deposit` log @@ -1106,10 +1106,10 @@ When `is_genesis_trigger(deposits, timestamp) is True` for the first time, let: *Note*: The function `is_genesis_trigger` has yet to be agreed upon by the community, and can be updated as necessary. We define the following testing placeholder: ```python -def is_genesis_trigger(deposits: List[Deposit, 2**DEPOSIT_CONTRACT_TREE_DEPTH], time: uint64) -> bool: +def is_genesis_trigger(deposits: List[Deposit, 2**DEPOSIT_CONTRACT_TREE_DEPTH], timestamp: uint64) -> bool: SECONDS_PER_DAY = 86400 # Do not deploy too early - if time - time % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY < MIN_GENESIS_TIME: + if timestamp - timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY < MIN_GENESIS_TIME: return False # Process deposits @@ -1136,7 +1136,9 @@ def is_genesis_trigger(deposits: List[Deposit, 2**DEPOSIT_CONTRACT_TREE_DEPTH], Let `genesis_state = get_genesis_beacon_state(genesis_deposits, genesis_time, genesis_eth1_block_hash)`. ```python -def get_genesis_beacon_state(deposits: Sequence[Deposit], genesis_time: int, genesis_eth1_block_hash: Hash) -> BeaconState: +def get_genesis_beacon_state(deposits: List[Deposit, 2**DEPOSIT_CONTRACT_TREE_DEPTH], + genesis_time: int, + genesis_eth1_block_hash: Hash) -> BeaconState: state = BeaconState( genesis_time=genesis_time, eth1_data=Eth1Data(block_hash=genesis_eth1_block_hash), diff --git a/test_libs/pyspec/eth2spec/test/helpers/deposits.py b/test_libs/pyspec/eth2spec/test/helpers/deposits.py index a0d59b9a6..39ecbd2d7 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/deposits.py +++ b/test_libs/pyspec/eth2spec/test/helpers/deposits.py @@ -1,6 +1,6 @@ from eth2spec.test.helpers.keys import pubkeys, privkeys from eth2spec.utils.bls import bls_sign -from eth2spec.utils.merkle_minimal import calc_merkle_tree_from_leaves, get_merkle_root, get_merkle_proof +from eth2spec.utils.merkle_minimal import calc_merkle_tree_from_leaves, get_merkle_proof from eth2spec.utils.ssz.ssz_impl import signing_root, hash_tree_root from eth2spec.utils.ssz.ssz_typing import List from eth2spec.phase0.spec import DepositData @@ -68,11 +68,6 @@ def prepare_genesis_deposits(spec, genesis_validator_count, amount, signed=False privkey = privkeys[validator_index] # insecurely use pubkey as withdrawal key if no credentials provided withdrawal_credentials = spec.int_to_bytes(spec.BLS_WITHDRAWAL_PREFIX, length=1) + spec.hash(pubkey)[1:] - deposit_data = spec.DepositData( - pubkey=pubkey, - withdrawal_credentials=withdrawal_credentials, - amount=amount, - ) deposit, root, deposit_data_list = build_deposit( spec, None, From e4eebef3a4098e49123895532226fcabe87b768d Mon Sep 17 00:00:00 2001 From: protolambda Date: Sat, 29 Jun 2019 20:09:43 +0200 Subject: [PATCH 32/49] fix broken deposits test, now same error as others --- test_libs/pyspec/eth2spec/test/helpers/deposits.py | 9 ++------- .../phase_0/block_processing/test_process_deposit.py | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/test_libs/pyspec/eth2spec/test/helpers/deposits.py b/test_libs/pyspec/eth2spec/test/helpers/deposits.py index 39ecbd2d7..7f5975dd4 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/deposits.py +++ b/test_libs/pyspec/eth2spec/test/helpers/deposits.py @@ -3,11 +3,10 @@ from eth2spec.utils.bls import bls_sign from eth2spec.utils.merkle_minimal import calc_merkle_tree_from_leaves, get_merkle_proof from eth2spec.utils.ssz.ssz_impl import signing_root, hash_tree_root from eth2spec.utils.ssz.ssz_typing import List -from eth2spec.phase0.spec import DepositData def build_deposit_data(spec, pubkey, privkey, amount, withdrawal_credentials, state=None, signed=False): - deposit_data = DepositData( + deposit_data = spec.DepositData( pubkey=pubkey, withdrawal_credentials=withdrawal_credentials, amount=amount, @@ -43,14 +42,10 @@ def build_deposit(spec, amount, withdrawal_credentials, signed): - deposit_data = build_deposit_data( - spec, pubkey, privkey, amount, withdrawal_credentials, state=state, signed=signed, - ) - deposit_data = build_deposit_data(spec, pubkey, privkey, amount, withdrawal_credentials, state=state, signed=signed) deposit_data_list.append(deposit_data) index = len(deposit_data_list) - root = hash_tree_root(List[DepositData, 2**spec.DEPOSIT_CONTRACT_TREE_DEPTH](*deposit_data_list)) + root = hash_tree_root(List[spec.DepositData, 2**spec.DEPOSIT_CONTRACT_TREE_DEPTH](*deposit_data_list)) tree = calc_merkle_tree_from_leaves(tuple([d.hash_tree_root() for d in deposit_data_list])) proof = list(get_merkle_proof(tree, item_index=index)) + [index.to_bytes(32, 'little')] leaf = deposit_data.hash_tree_root() diff --git a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_deposit.py b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_deposit.py index d0a62ff6b..d596523ec 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_deposit.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_deposit.py @@ -117,7 +117,7 @@ def test_invalid_withdrawal_credentials_top_up(spec, state): @with_all_phases @spec_state_test def test_wrong_deposit_for_deposit_count(spec, state): - deposit_data_leaves = [spec.ZERO_HASH] * len(state.validators) + deposit_data_leaves = [spec.DepositData() for _ in range(len(state.validators))] # build root for deposit_1 index_1 = len(deposit_data_leaves) From fb165dc14e11cafb273f96f8e75352cc73df73da Mon Sep 17 00:00:00 2001 From: protolambda Date: Sat, 29 Jun 2019 20:33:11 +0200 Subject: [PATCH 33/49] fixes a few tests, not all --- test_libs/pyspec/eth2spec/test/helpers/deposits.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test_libs/pyspec/eth2spec/test/helpers/deposits.py b/test_libs/pyspec/eth2spec/test/helpers/deposits.py index 7f5975dd4..99c39211e 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/deposits.py +++ b/test_libs/pyspec/eth2spec/test/helpers/deposits.py @@ -43,14 +43,14 @@ def build_deposit(spec, withdrawal_credentials, signed): deposit_data = build_deposit_data(spec, pubkey, privkey, amount, withdrawal_credentials, state=state, signed=signed) - deposit_data_list.append(deposit_data) index = len(deposit_data_list) + deposit_data_list.append(deposit_data) root = hash_tree_root(List[spec.DepositData, 2**spec.DEPOSIT_CONTRACT_TREE_DEPTH](*deposit_data_list)) tree = calc_merkle_tree_from_leaves(tuple([d.hash_tree_root() for d in deposit_data_list])) - proof = list(get_merkle_proof(tree, item_index=index)) + [index.to_bytes(32, 'little')] + proof = list(get_merkle_proof(tree, item_index=index)) + [(index + 1).to_bytes(32, 'little')] leaf = deposit_data.hash_tree_root() assert spec.verify_merkle_branch(leaf, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH + 1, index, root) - deposit = spec.Deposit(proof, index, deposit_data) + deposit = spec.Deposit(proof=proof, data=deposit_data) return deposit, root, deposit_data_list From ff185c348697c024f1ebc7e2706cd3b1717eec36 Mon Sep 17 00:00:00 2001 From: protolambda Date: Sat, 29 Jun 2019 20:40:25 +0200 Subject: [PATCH 34/49] fix deposit state mocking for tests --- test_libs/pyspec/eth2spec/test/helpers/deposits.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test_libs/pyspec/eth2spec/test/helpers/deposits.py b/test_libs/pyspec/eth2spec/test/helpers/deposits.py index 99c39211e..b46363e62 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/deposits.py +++ b/test_libs/pyspec/eth2spec/test/helpers/deposits.py @@ -102,6 +102,7 @@ def prepare_state_and_deposit(spec, state, validator_index, amount, withdrawal_c signed, ) + state.eth1_deposit_index = 0 state.eth1_data.deposit_root = root state.eth1_data.deposit_count = len(deposit_data_list) return deposit From 125660c5af055209c8bdeb422947f85e4b518626 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Sun, 30 Jun 2019 03:20:11 +0800 Subject: [PATCH 35/49] Update input `deposits` type from `Sequence[Deposit]` to `List[Deposit, 2**DEPOSIT_CONTRACT_TREE_DEPTH` and fix tests --- specs/core/0_beacon-chain.md | 17 ++++++++++------- .../pyspec/eth2spec/test/helpers/deposits.py | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 5aa57c294..a77ec77a3 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1092,9 +1092,8 @@ def slash_validator(state: BeaconState, ### Genesis trigger -Before genesis has been triggered and whenever the deposit contract emits a `Deposit` log, call the function `is_genesis_trigger(deposits: Sequence[Deposit], timestamp: uint64) -> bool` where: - -* `deposits` is the list of all deposits, ordered chronologically, up to and including the deposit triggering the latest `Deposit` log +Before genesis has been triggered and for every Ethereum 1.0 block call `is_genesis_trigger(deposits: Sequence[Deposit], timestamp: uint64) -> bool` where: +* `deposits` is the SSZ list of all deposits, ordered chronologically, up to and including the deposit triggering the latest `Deposit` log * `timestamp` is the Unix timestamp in the Ethereum 1.0 block that emitted the latest `Deposit` log When `is_genesis_trigger(deposits, timestamp) is True` for the first time, let: @@ -1114,9 +1113,11 @@ def is_genesis_trigger(deposits: List[Deposit, 2**DEPOSIT_CONTRACT_TREE_DEPTH], # Process deposits state = BeaconState() - leaves = list(map(lambda deposit: hash_tree_root(deposit.data), deposits)) + leaves = list(map(lambda deposit: deposit.data, deposits)) for deposit_index, deposit in enumerate(deposits): - state.eth1_data.deposit_root = hash_tree_root(leaves) + state.eth1_data.deposit_root = hash_tree_root( + List[DepositData, 2**DEPOSIT_CONTRACT_TREE_DEPTH](*leaves[:deposit_index + 1]) + ) state.eth1_data.deposit_count = deposit_index + 1 state.eth1_deposit_index = deposit_index process_deposit(state, deposit) @@ -1146,9 +1147,11 @@ def get_genesis_beacon_state(deposits: List[Deposit, 2**DEPOSIT_CONTRACT_TREE_DE ) # Process genesis deposits - leaves = list(map(lambda deposit: hash_tree_root(deposit.data), deposits)) + leaves = list(map(lambda deposit: deposit.data, deposits)) for deposit_index, deposit in enumerate(deposits): - state.eth1_data.deposit_root = hash_tree_root(leaves) + state.eth1_data.deposit_root = hash_tree_root( + List[DepositData, 2**DEPOSIT_CONTRACT_TREE_DEPTH](*leaves[:deposit_index + 1]) + ) state.eth1_data.deposit_count = deposit_index + 1 state.eth1_deposit_index = deposit_index process_deposit(state, deposit) diff --git a/test_libs/pyspec/eth2spec/test/helpers/deposits.py b/test_libs/pyspec/eth2spec/test/helpers/deposits.py index b46363e62..f79dcf3ff 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/deposits.py +++ b/test_libs/pyspec/eth2spec/test/helpers/deposits.py @@ -75,7 +75,7 @@ def prepare_genesis_deposits(spec, genesis_validator_count, amount, signed=False ) genesis_deposits.append(deposit) - return genesis_deposits, root + return List[spec.Deposit, 2**spec.DEPOSIT_CONTRACT_TREE_DEPTH](*genesis_deposits), root def prepare_state_and_deposit(spec, state, validator_index, amount, withdrawal_credentials=None, signed=False): From 56caa483144d26f0f5cd09b5128fad2c259e9e93 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Sun, 30 Jun 2019 03:27:25 +0800 Subject: [PATCH 36/49] Should use Sequence --- specs/core/0_beacon-chain.md | 6 +++--- test_libs/pyspec/eth2spec/test/helpers/deposits.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index a77ec77a3..c70fc006e 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1093,7 +1093,7 @@ def slash_validator(state: BeaconState, ### Genesis trigger Before genesis has been triggered and for every Ethereum 1.0 block call `is_genesis_trigger(deposits: Sequence[Deposit], timestamp: uint64) -> bool` where: -* `deposits` is the SSZ list of all deposits, ordered chronologically, up to and including the deposit triggering the latest `Deposit` log +* `deposits` is the list of all deposits, ordered chronologically, up to and including the deposit triggering the latest `Deposit` log * `timestamp` is the Unix timestamp in the Ethereum 1.0 block that emitted the latest `Deposit` log When `is_genesis_trigger(deposits, timestamp) is True` for the first time, let: @@ -1105,7 +1105,7 @@ When `is_genesis_trigger(deposits, timestamp) is True` for the first time, let: *Note*: The function `is_genesis_trigger` has yet to be agreed upon by the community, and can be updated as necessary. We define the following testing placeholder: ```python -def is_genesis_trigger(deposits: List[Deposit, 2**DEPOSIT_CONTRACT_TREE_DEPTH], timestamp: uint64) -> bool: +def is_genesis_trigger(deposits: Sequence[Deposit], timestamp: uint64) -> bool: SECONDS_PER_DAY = 86400 # Do not deploy too early if timestamp - timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY < MIN_GENESIS_TIME: @@ -1137,7 +1137,7 @@ def is_genesis_trigger(deposits: List[Deposit, 2**DEPOSIT_CONTRACT_TREE_DEPTH], Let `genesis_state = get_genesis_beacon_state(genesis_deposits, genesis_time, genesis_eth1_block_hash)`. ```python -def get_genesis_beacon_state(deposits: List[Deposit, 2**DEPOSIT_CONTRACT_TREE_DEPTH], +def get_genesis_beacon_state(deposits: Sequence[Deposit], genesis_time: int, genesis_eth1_block_hash: Hash) -> BeaconState: state = BeaconState( diff --git a/test_libs/pyspec/eth2spec/test/helpers/deposits.py b/test_libs/pyspec/eth2spec/test/helpers/deposits.py index f79dcf3ff..b46363e62 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/deposits.py +++ b/test_libs/pyspec/eth2spec/test/helpers/deposits.py @@ -75,7 +75,7 @@ def prepare_genesis_deposits(spec, genesis_validator_count, amount, signed=False ) genesis_deposits.append(deposit) - return List[spec.Deposit, 2**spec.DEPOSIT_CONTRACT_TREE_DEPTH](*genesis_deposits), root + return genesis_deposits, root def prepare_state_and_deposit(spec, state, validator_index, amount, withdrawal_credentials=None, signed=False): From 12dff5349df00d22af0f8897bca1bd114f65cdbd Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Sun, 30 Jun 2019 03:42:00 +0800 Subject: [PATCH 37/49] Renames: 1. `Deposit` log -> `DepositEvent` log 2. `get_deposit_root` -> `get_hash_tree_root` --- .../contracts/validator_registration.json | 2 +- .../contracts/validator_registration.v.py | 12 ++++++------ deposit_contract/tests/contracts/test_deposit.py | 8 ++++---- specs/core/0_beacon-chain.md | 2 +- specs/core/0_deposit-contract.md | 6 +++--- specs/validator/0_beacon-chain-validator.md | 2 +- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/deposit_contract/contracts/validator_registration.json b/deposit_contract/contracts/validator_registration.json index a3d309269..527ce6087 100644 --- a/deposit_contract/contracts/validator_registration.json +++ b/deposit_contract/contracts/validator_registration.json @@ -1 +1 @@ -{"abi": [{"name": "Deposit", "inputs": [{"type": "bytes", "name": "pubkey", "indexed": false}, {"type": "bytes", "name": "withdrawal_credentials", "indexed": false}, {"type": "bytes", "name": "amount", "indexed": false}, {"type": "bytes", "name": "signature", "indexed": false}, {"type": "bytes", "name": "index", "indexed": false}], "anonymous": false, "type": "event"}, {"outputs": [], "inputs": [], "constant": false, "payable": false, "type": "constructor"}, {"name": "get_deposit_root", "outputs": [{"type": "bytes32", "name": "out"}], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 91674}, {"name": "get_deposit_count", "outputs": [{"type": "bytes", "name": "out"}], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 10433}, {"name": "deposit", "outputs": [], "inputs": [{"type": "bytes", "name": "pubkey"}, {"type": "bytes", "name": "withdrawal_credentials"}, {"type": "bytes", "name": "signature"}], "constant": false, "payable": true, "type": "function", "gas": 1334417}], "bytecode": "0x600035601c52740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a052341561009e57600080fd5b6101406000601f818352015b600061014051602081106100bd57600080fd5b600260c052602060c020015460208261016001015260208101905061014051602081106100e957600080fd5b600260c052602060c020015460208261016001015260208101905080610160526101609050602060c0825160208401600060025af161012757600080fd5b60c0519050606051600161014051018060405190131561014657600080fd5b809190121561015457600080fd5b6020811061016157600080fd5b600260c052602060c02001555b81516001018083528114156100aa575b50506112ff56600035601c52740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a052600015610277575b6101605261014052600061018052610140516101a0526101c060006008818352015b61018051600860008112156100da578060000360020a82046100e1565b8060020a82025b905090506101805260ff6101a051166101e052610180516101e0516101805101101561010c57600080fd5b6101e0516101805101610180526101a0517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86000811215610155578060000360020a820461015c565b8060020a82025b905090506101a0525b81516001018083528114156100bd575b50506018600860208206610200016020828401111561019357600080fd5b60208061022082610180600060046015f15050818152809050905090508051602001806102c0828460006004600a8704601201f16101d057600080fd5b50506102c05160206001820306601f82010390506103206102c0516008818352015b826103205111156102025761021e565b6000610320516102e001535b81516001018083528114156101f2575b50505060206102a05260406102c0510160206001820306601f8201039050610280525b6000610280511115156102535761026f565b602061028051036102a001516020610280510361028052610241565b610160515650005b63c5f2892f600051141561050857341561029057600080fd5b6000610140526101405161016052600154610180526101a060006020818352015b60016001610180511614156103325760006101a051602081106102d357600080fd5b600060c052602060c02001546020826102400101526020810190506101605160208261024001015260208101905080610240526102409050602060c0825160208401600060025af161032457600080fd5b60c0519050610160526103a0565b6000610160516020826101c00101526020810190506101a0516020811061035857600080fd5b600260c052602060c02001546020826101c0010152602081019050806101c0526101c09050602060c0825160208401600060025af161039657600080fd5b60c0519050610160525b61018060026103ae57600080fd5b60028151048152505b81516001018083528114156102b1575b505060006101605160208261044001015260208101905061014051610160516101805163806732896102c0526001546102e0526102e0516006580161009b565b506103405260006103a0525b6103405160206001820306601f82010390506103a0511015156104355761044e565b6103a05161036001526103a0516020016103a052610413565b61018052610160526101405261034060088060208461044001018260208501600060046012f150508051820191505060006018602082066103c0016020828401111561049957600080fd5b6020806103e082610140600060046015f150508181528090509050905060188060208461044001018260208501600060046014f150508051820191505080610440526104409050602060c0825160208401600060025af16104f957600080fd5b60c051905060005260206000f3005b63621fd130600051141561061a57341561052157600080fd5b63806732896101405260015461016052610160516006580161009b565b506101c0526000610220525b6101c05160206001820306601f82010390506102205110151561056c57610585565b610220516101e00152610220516020016102205261054a565b6101c0805160200180610280828460006004600a8704601201f16105a857600080fd5b50506102805160206001820306601f82010390506102e0610280516008818352015b826102e05111156105da576105f6565b60006102e0516102a001535b81516001018083528114156105ca575b5050506020610260526040610280510160206001820306601f8201039050610260f3005b63c47e300d600051141561117457606060046101403760506004356004016101a037603060043560040135111561065057600080fd5b604060243560040161022037602060243560040135111561067057600080fd5b608060443560040161028037606060443560040135111561069057600080fd5b63ffffffff600154106106a257600080fd5b633b9aca0061034052610340516106b857600080fd5b61034051340461032052633b9aca006103205110156106d657600080fd5b60306101a051146106e657600080fd5b602061022051146106f657600080fd5b6060610280511461070657600080fd5b6101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516103405161036051610380516103a05163806732896103c052610320516103e0526103e0516006580161009b565b506104405260006104a0525b6104405160206001820306601f82010390506104a051101515610796576107af565b6104a05161046001526104a0516020016104a052610774565b6103a05261038052610360526103405261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a052610440805160200180610360828460006004600a8704601201f161081657600080fd5b50506101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516103405161036051610380516103a0516103c0516103e05161040051610420516104405161046051610480516104a05163806732896104c0526001546104e0526104e0516006580161009b565b506105405260006105a0525b6105405160206001820306601f82010390506105a0511015156108c7576108e0565b6105a05161056001526105a0516020016105a0526108a5565b6104a05261048052610460526104405261042052610400526103e0526103c0526103a05261038052610360526103405261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a0526105408051602001806105c0828460006004600a8704601201f161096757600080fd5b505060a06106405261064051610680526101a08051602001806106405161068001828460006004600a8704601201f161099f57600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516040818352015b83610620511015156109dd576109fa565b6000610620516020850101535b81516001018083528114156109cc575b50505050602061064051610680015160206001820306601f820103905061064051010161064052610640516106a0526102208051602001806106405161068001828460006004600a8704601201f1610a5157600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516020818352015b8361062051101515610a8f57610aac565b6000610620516020850101535b8151600101808352811415610a7e575b50505050602061064051610680015160206001820306601f820103905061064051010161064052610640516106c0526103608051602001806106405161068001828460006004600a8704601201f1610b0357600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516020818352015b8361062051101515610b4157610b5e565b6000610620516020850101535b8151600101808352811415610b30575b50505050602061064051610680015160206001820306601f820103905061064051010161064052610640516106e0526102808051602001806106405161068001828460006004600a8704601201f1610bb557600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516060818352015b8361062051101515610bf357610c10565b6000610620516020850101535b8151600101808352811415610be2575b50505050602061064051610680015160206001820306601f82010390506106405101016106405261064051610700526105c08051602001806106405161068001828460006004600a8704601201f1610c6757600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516020818352015b8361062051101515610ca557610cc2565b6000610620516020850101535b8151600101808352811415610c94575b50505050602061064051610680015160206001820306601f8201039050610640510101610640527fdc5fc95703516abd38fa03c3737ff3b52dc52347055c8028460fdf5bbe2f12ce61064051610680a160006107205260006101a06030806020846107e001018260208501600060046016f150508051820191505060006010602082066107600160208284011115610d5957600080fd5b60208061078082610720600060046015f15050818152809050905090506010806020846107e001018260208501600060046013f1505080518201915050806107e0526107e09050602060c0825160208401600060025af1610db957600080fd5b60c0519050610740526000600060406020820661088001610280518284011115610de257600080fd5b6060806108a0826020602088068803016102800160006004601bf1505081815280905090509050602060c0825160208401600060025af1610e2257600080fd5b60c0519050602082610a800101526020810190506000604060206020820661094001610280518284011115610e5657600080fd5b606080610960826020602088068803016102800160006004601bf1505081815280905090509050602080602084610a0001018260208501600060046015f150508051820191505061072051602082610a0001015260208101905080610a0052610a009050602060c0825160208401600060025af1610ed357600080fd5b60c0519050602082610a8001015260208101905080610a8052610a809050602060c0825160208401600060025af1610f0a57600080fd5b60c0519050610860526000600061074051602082610b20010152602081019050610220602080602084610b2001018260208501600060046015f150508051820191505080610b2052610b209050602060c0825160208401600060025af1610f7057600080fd5b60c0519050602082610ca00101526020810190506000610360600880602084610c2001018260208501600060046012f15050805182019150506000601860208206610ba00160208284011115610fc557600080fd5b602080610bc082610720600060046015f1505081815280905090509050601880602084610c2001018260208501600060046014f150508051820191505061086051602082610c2001015260208101905080610c2052610c209050602060c0825160208401600060025af161103857600080fd5b60c0519050602082610ca001015260208101905080610ca052610ca09050602060c0825160208401600060025af161106f57600080fd5b60c0519050610b0052600180546001825401101561108c57600080fd5b6001815401815550600154610d2052610d4060006020818352015b60016001610d20511614156110dc57610b0051610d4051602081106110cb57600080fd5b600060c052602060c0200155611170565b6000610d4051602081106110ef57600080fd5b600060c052602060c0200154602082610d60010152602081019050610b0051602082610d6001015260208101905080610d6052610d609050602060c0825160208401600060025af161114057600080fd5b60c0519050610b0052610d20600261115757600080fd5b60028151048152505b81516001018083528114156110a7575b5050005b60006000fd5b6101856112ff036101856000396101856112ff036000f3"} \ No newline at end of file +{"abi": [{"name": "DepositEvent", "inputs": [{"type": "bytes", "name": "pubkey", "indexed": false}, {"type": "bytes", "name": "withdrawal_credentials", "indexed": false}, {"type": "bytes", "name": "amount", "indexed": false}, {"type": "bytes", "name": "signature", "indexed": false}, {"type": "bytes", "name": "index", "indexed": false}], "anonymous": false, "type": "event"}, {"outputs": [], "inputs": [], "constant": false, "payable": false, "type": "constructor"}, {"name": "get_hash_tree_root", "outputs": [{"type": "bytes32", "name": "out"}], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 91674}, {"name": "get_deposit_count", "outputs": [{"type": "bytes", "name": "out"}], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 10433}, {"name": "deposit", "outputs": [], "inputs": [{"type": "bytes", "name": "pubkey"}, {"type": "bytes", "name": "withdrawal_credentials"}, {"type": "bytes", "name": "signature"}], "constant": false, "payable": true, "type": "function", "gas": 1334417}], "bytecode": "0x600035601c52740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a052341561009e57600080fd5b6101406000601f818352015b600061014051602081106100bd57600080fd5b600260c052602060c020015460208261016001015260208101905061014051602081106100e957600080fd5b600260c052602060c020015460208261016001015260208101905080610160526101609050602060c0825160208401600060025af161012757600080fd5b60c0519050606051600161014051018060405190131561014657600080fd5b809190121561015457600080fd5b6020811061016157600080fd5b600260c052602060c02001555b81516001018083528114156100aa575b50506112ff56600035601c52740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a052600015610277575b6101605261014052600061018052610140516101a0526101c060006008818352015b61018051600860008112156100da578060000360020a82046100e1565b8060020a82025b905090506101805260ff6101a051166101e052610180516101e0516101805101101561010c57600080fd5b6101e0516101805101610180526101a0517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86000811215610155578060000360020a820461015c565b8060020a82025b905090506101a0525b81516001018083528114156100bd575b50506018600860208206610200016020828401111561019357600080fd5b60208061022082610180600060046015f15050818152809050905090508051602001806102c0828460006004600a8704601201f16101d057600080fd5b50506102c05160206001820306601f82010390506103206102c0516008818352015b826103205111156102025761021e565b6000610320516102e001535b81516001018083528114156101f2575b50505060206102a05260406102c0510160206001820306601f8201039050610280525b6000610280511115156102535761026f565b602061028051036102a001516020610280510361028052610241565b610160515650005b63863a311b600051141561050857341561029057600080fd5b6000610140526101405161016052600154610180526101a060006020818352015b60016001610180511614156103325760006101a051602081106102d357600080fd5b600060c052602060c02001546020826102400101526020810190506101605160208261024001015260208101905080610240526102409050602060c0825160208401600060025af161032457600080fd5b60c0519050610160526103a0565b6000610160516020826101c00101526020810190506101a0516020811061035857600080fd5b600260c052602060c02001546020826101c0010152602081019050806101c0526101c09050602060c0825160208401600060025af161039657600080fd5b60c0519050610160525b61018060026103ae57600080fd5b60028151048152505b81516001018083528114156102b1575b505060006101605160208261044001015260208101905061014051610160516101805163806732896102c0526001546102e0526102e0516006580161009b565b506103405260006103a0525b6103405160206001820306601f82010390506103a0511015156104355761044e565b6103a05161036001526103a0516020016103a052610413565b61018052610160526101405261034060088060208461044001018260208501600060046012f150508051820191505060006018602082066103c0016020828401111561049957600080fd5b6020806103e082610140600060046015f150508181528090509050905060188060208461044001018260208501600060046014f150508051820191505080610440526104409050602060c0825160208401600060025af16104f957600080fd5b60c051905060005260206000f3005b63621fd130600051141561061a57341561052157600080fd5b63806732896101405260015461016052610160516006580161009b565b506101c0526000610220525b6101c05160206001820306601f82010390506102205110151561056c57610585565b610220516101e00152610220516020016102205261054a565b6101c0805160200180610280828460006004600a8704601201f16105a857600080fd5b50506102805160206001820306601f82010390506102e0610280516008818352015b826102e05111156105da576105f6565b60006102e0516102a001535b81516001018083528114156105ca575b5050506020610260526040610280510160206001820306601f8201039050610260f3005b63c47e300d600051141561117457606060046101403760506004356004016101a037603060043560040135111561065057600080fd5b604060243560040161022037602060243560040135111561067057600080fd5b608060443560040161028037606060443560040135111561069057600080fd5b63ffffffff600154106106a257600080fd5b633b9aca0061034052610340516106b857600080fd5b61034051340461032052633b9aca006103205110156106d657600080fd5b60306101a051146106e657600080fd5b602061022051146106f657600080fd5b6060610280511461070657600080fd5b6101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516103405161036051610380516103a05163806732896103c052610320516103e0526103e0516006580161009b565b506104405260006104a0525b6104405160206001820306601f82010390506104a051101515610796576107af565b6104a05161046001526104a0516020016104a052610774565b6103a05261038052610360526103405261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a052610440805160200180610360828460006004600a8704601201f161081657600080fd5b50506101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516103405161036051610380516103a0516103c0516103e05161040051610420516104405161046051610480516104a05163806732896104c0526001546104e0526104e0516006580161009b565b506105405260006105a0525b6105405160206001820306601f82010390506105a0511015156108c7576108e0565b6105a05161056001526105a0516020016105a0526108a5565b6104a05261048052610460526104405261042052610400526103e0526103c0526103a05261038052610360526103405261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a0526105408051602001806105c0828460006004600a8704601201f161096757600080fd5b505060a06106405261064051610680526101a08051602001806106405161068001828460006004600a8704601201f161099f57600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516040818352015b83610620511015156109dd576109fa565b6000610620516020850101535b81516001018083528114156109cc575b50505050602061064051610680015160206001820306601f820103905061064051010161064052610640516106a0526102208051602001806106405161068001828460006004600a8704601201f1610a5157600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516020818352015b8361062051101515610a8f57610aac565b6000610620516020850101535b8151600101808352811415610a7e575b50505050602061064051610680015160206001820306601f820103905061064051010161064052610640516106c0526103608051602001806106405161068001828460006004600a8704601201f1610b0357600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516020818352015b8361062051101515610b4157610b5e565b6000610620516020850101535b8151600101808352811415610b30575b50505050602061064051610680015160206001820306601f820103905061064051010161064052610640516106e0526102808051602001806106405161068001828460006004600a8704601201f1610bb557600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516060818352015b8361062051101515610bf357610c10565b6000610620516020850101535b8151600101808352811415610be2575b50505050602061064051610680015160206001820306601f82010390506106405101016106405261064051610700526105c08051602001806106405161068001828460006004600a8704601201f1610c6757600080fd5b505061064051610680015160206001820306601f8201039050610640516106800161062081516020818352015b8361062051101515610ca557610cc2565b6000610620516020850101535b8151600101808352811415610c94575b50505050602061064051610680015160206001820306601f8201039050610640510101610640527f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c561064051610680a160006107205260006101a06030806020846107e001018260208501600060046016f150508051820191505060006010602082066107600160208284011115610d5957600080fd5b60208061078082610720600060046015f15050818152809050905090506010806020846107e001018260208501600060046013f1505080518201915050806107e0526107e09050602060c0825160208401600060025af1610db957600080fd5b60c0519050610740526000600060406020820661088001610280518284011115610de257600080fd5b6060806108a0826020602088068803016102800160006004601bf1505081815280905090509050602060c0825160208401600060025af1610e2257600080fd5b60c0519050602082610a800101526020810190506000604060206020820661094001610280518284011115610e5657600080fd5b606080610960826020602088068803016102800160006004601bf1505081815280905090509050602080602084610a0001018260208501600060046015f150508051820191505061072051602082610a0001015260208101905080610a0052610a009050602060c0825160208401600060025af1610ed357600080fd5b60c0519050602082610a8001015260208101905080610a8052610a809050602060c0825160208401600060025af1610f0a57600080fd5b60c0519050610860526000600061074051602082610b20010152602081019050610220602080602084610b2001018260208501600060046015f150508051820191505080610b2052610b209050602060c0825160208401600060025af1610f7057600080fd5b60c0519050602082610ca00101526020810190506000610360600880602084610c2001018260208501600060046012f15050805182019150506000601860208206610ba00160208284011115610fc557600080fd5b602080610bc082610720600060046015f1505081815280905090509050601880602084610c2001018260208501600060046014f150508051820191505061086051602082610c2001015260208101905080610c2052610c209050602060c0825160208401600060025af161103857600080fd5b60c0519050602082610ca001015260208101905080610ca052610ca09050602060c0825160208401600060025af161106f57600080fd5b60c0519050610b0052600180546001825401101561108c57600080fd5b6001815401815550600154610d2052610d4060006020818352015b60016001610d20511614156110dc57610b0051610d4051602081106110cb57600080fd5b600060c052602060c0200155611170565b6000610d4051602081106110ef57600080fd5b600060c052602060c0200154602082610d60010152602081019050610b0051602082610d6001015260208101905080610d6052610d609050602060c0825160208401600060025af161114057600080fd5b60c0519050610b0052610d20600261115757600080fd5b60028151048152505b81516001018083528114156110a7575b5050005b60006000fd5b6101856112ff036101856000396101856112ff036000f3"} \ No newline at end of file diff --git a/deposit_contract/contracts/validator_registration.v.py b/deposit_contract/contracts/validator_registration.v.py index b49cc45e1..bad619b07 100644 --- a/deposit_contract/contracts/validator_registration.v.py +++ b/deposit_contract/contracts/validator_registration.v.py @@ -6,7 +6,7 @@ WITHDRAWAL_CREDENTIALS_LENGTH: constant(uint256) = 32 # bytes AMOUNT_LENGTH: constant(uint256) = 8 # bytes SIGNATURE_LENGTH: constant(uint256) = 96 # bytes -Deposit: event({ +DepositEvent: event({ pubkey: bytes[48], withdrawal_credentials: bytes[32], amount: bytes[8], @@ -42,7 +42,7 @@ def to_little_endian_64(value: uint256) -> bytes[8]: @public @constant -def get_deposit_root() -> bytes32: +def get_hash_tree_root() -> bytes32: zero_bytes32: bytes32 = 0x0000000000000000000000000000000000000000000000000000000000000000 node: bytes32 = zero_bytes32 size: uint256 = self.deposit_count @@ -76,11 +76,11 @@ def deposit(pubkey: bytes[PUBKEY_LENGTH], assert len(withdrawal_credentials) == WITHDRAWAL_CREDENTIALS_LENGTH assert len(signature) == SIGNATURE_LENGTH - # Emit `Deposit` log + # Emit `DepositEvent` log amount: bytes[8] = self.to_little_endian_64(deposit_amount) - log.Deposit(pubkey, withdrawal_credentials, amount, signature, self.to_little_endian_64(self.deposit_count)) + log.DepositEvent(pubkey, withdrawal_credentials, amount, signature, self.to_little_endian_64(self.deposit_count)) - # Compute `DepositData` root + # Compute `DepositData` hash tree root zero_bytes32: bytes32 = 0x0000000000000000000000000000000000000000000000000000000000000000 pubkey_root: bytes32 = sha256(concat(pubkey, slice(zero_bytes32, start=0, len=64 - PUBKEY_LENGTH))) signature_root: bytes32 = sha256(concat( @@ -92,7 +92,7 @@ def deposit(pubkey: bytes[PUBKEY_LENGTH], sha256(concat(amount, slice(zero_bytes32, start=0, len=32 - AMOUNT_LENGTH), signature_root)), )) - # Add `DepositData` root to Merkle tree (update a single `branch` node) + # Add `DepositData` hash tree root to Merkle tree (update a single `branch` node) self.deposit_count += 1 size: uint256 = self.deposit_count for height in range(DEPOSIT_CONTRACT_TREE_DEPTH): diff --git a/deposit_contract/tests/contracts/test_deposit.py b/deposit_contract/tests/contracts/test_deposit.py index 8c165f0f9..1c96d074e 100644 --- a/deposit_contract/tests/contracts/test_deposit.py +++ b/deposit_contract/tests/contracts/test_deposit.py @@ -96,8 +96,8 @@ def test_deposit_inputs(registration_contract, ) -def test_deposit_log(registration_contract, a0, w3, deposit_input): - log_filter = registration_contract.events.Deposit.createFilter( +def test_deposit_event_log(registration_contract, a0, w3, deposit_input): + log_filter = registration_contract.events.DepositEvent.createFilter( fromBlock='latest', ) @@ -119,7 +119,7 @@ def test_deposit_log(registration_contract, a0, w3, deposit_input): def test_deposit_tree(registration_contract, w3, assert_tx_failed, deposit_input): - log_filter = registration_contract.events.Deposit.createFilter( + log_filter = registration_contract.events.DepositEvent.createFilter( fromBlock='latest', ) @@ -146,4 +146,4 @@ def test_deposit_tree(registration_contract, w3, assert_tx_failed, deposit_input )) root = hash_tree_root(List[DepositData, 2**32](*deposit_data_list)) - assert root == registration_contract.functions.get_deposit_root().call() + assert root == registration_contract.functions.get_hash_tree_root().call() diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index c70fc006e..088619202 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -438,7 +438,7 @@ class Attestation(Container): ```python class Deposit(Container): - proof: Vector[Hash, DEPOSIT_CONTRACT_TREE_DEPTH + 1] # Merkle path to deposit root + proof: Vector[Hash, DEPOSIT_CONTRACT_TREE_DEPTH + 1] # Merkle path to SSZ deposit data list hash tree root data: DepositData ``` diff --git a/specs/core/0_deposit-contract.md b/specs/core/0_deposit-contract.md index d06dbaea1..0efc15f25 100644 --- a/specs/core/0_deposit-contract.md +++ b/specs/core/0_deposit-contract.md @@ -14,7 +14,7 @@ - [`deposit` function](#deposit-function) - [Deposit amount](#deposit-amount) - [Withdrawal credentials](#withdrawal-credentials) - - [`Deposit` log](#deposit-log) + - [`DepositEvent` log](#depositevent-log) - [Vyper code](#vyper-code) @@ -53,9 +53,9 @@ One of the `DepositData` fields is `withdrawal_credentials`. It is a commitment The private key corresponding to `withdrawal_pubkey` will be required to initiate a withdrawal. It can be stored separately until a withdrawal is required, e.g. in cold storage. -#### `Deposit` log +#### `DepositEvent` log -Every Ethereum 1.0 deposit emits a `Deposit` log for consumption by the beacon chain. The deposit contract does little validation, pushing most of the validator onboarding logic to the beacon chain. In particular, the proof of possession (a BLS12-381 signature) is not verified by the deposit contract. +Every Ethereum 1.0 deposit emits a `DepositEvent` log for consumption by the beacon chain. The deposit contract does little validation, pushing most of the validator onboarding logic to the beacon chain. In particular, the proof of possession (a BLS12-381 signature) is not verified by the deposit contract. ## Vyper code diff --git a/specs/validator/0_beacon-chain-validator.md b/specs/validator/0_beacon-chain-validator.md index 7d5630c7b..1b103b218 100644 --- a/specs/validator/0_beacon-chain-validator.md +++ b/specs/validator/0_beacon-chain-validator.md @@ -221,7 +221,7 @@ epoch_signature = bls_sign( ##### Eth1 Data -The `block.eth1_data` field is for block proposers to vote on recent Eth 1.0 data. This recent data contains an Eth 1.0 block hash as well as the associated deposit root (as calculated by the `get_deposit_root()` method of the deposit contract) and deposit count after execution of the corresponding Eth 1.0 block. If over half of the block proposers in the current Eth 1.0 voting period vote for the same `eth1_data` then `state.eth1_data` updates at the end of the voting period. Each deposit in `block.body.deposits` must verify against `state.eth1_data.eth1_deposit_root`. +The `block.eth1_data` field is for block proposers to vote on recent Eth 1.0 data. This recent data contains an Eth 1.0 block hash as well as the associated deposit root (as calculated by the `get_hash_tree_root()` method of the deposit contract) and deposit count after execution of the corresponding Eth 1.0 block. If over half of the block proposers in the current Eth 1.0 voting period vote for the same `eth1_data` then `state.eth1_data` updates at the end of the voting period. Each deposit in `block.body.deposits` must verify against `state.eth1_data.eth1_deposit_root`. Let `get_eth1_data(distance: int) -> Eth1Data` be the (subjective) function that returns the Eth 1.0 data at distance `distance` relative to the Eth 1.0 head at the start of the current Eth 1.0 voting period. Let `previous_eth1_distance` be the distance relative to the Eth 1.0 block corresponding to `state.eth1_data.block_hash` at the start of the current Eth 1.0 voting period. An honest block proposer sets `block.eth1_data = get_eth1_vote(state, previous_eth1_distance)` where: From 22476420f3922f741dd24294eafb5cd181cad4a7 Mon Sep 17 00:00:00 2001 From: Justin Drake Date: Sat, 29 Jun 2019 21:03:15 +0100 Subject: [PATCH 38/49] Cleanups; think about merging is_genesis_trigger into get_genesis_state --- specs/core/0_beacon-chain.md | 47 ++++++++++++++---------------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 088619202..f8768935b 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -174,6 +174,7 @@ The following values are (non-configurable) constants used throughout the specif | `ZERO_HASH` | `Hash(b'\x00' * 32)` | | `BASE_REWARDS_PER_EPOCH` | `5` | | `DEPOSIT_CONTRACT_TREE_DEPTH` | `2**5` (= 32) | +| `SECONDS_PER_DAY` | `86400` | ## Configuration @@ -438,7 +439,7 @@ class Attestation(Container): ```python class Deposit(Container): - proof: Vector[Hash, DEPOSIT_CONTRACT_TREE_DEPTH + 1] # Merkle path to SSZ deposit data list hash tree root + proof: Vector[Hash, DEPOSIT_CONTRACT_TREE_DEPTH + 1] # Merkle path to deposit data list root data: DepositData ``` @@ -1093,43 +1094,45 @@ def slash_validator(state: BeaconState, ### Genesis trigger Before genesis has been triggered and for every Ethereum 1.0 block call `is_genesis_trigger(deposits: Sequence[Deposit], timestamp: uint64) -> bool` where: -* `deposits` is the list of all deposits, ordered chronologically, up to and including the deposit triggering the latest `Deposit` log + +* `deposits` is the sequence of all deposits, ordered chronologically, up to and including the deposit triggering the latest `Deposit` log * `timestamp` is the Unix timestamp in the Ethereum 1.0 block that emitted the latest `Deposit` log When `is_genesis_trigger(deposits, timestamp) is True` for the first time, let: * `genesis_deposits = deposits` -* `genesis_time = timestamp - timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY` where `SECONDS_PER_DAY = 86400` +* `genesis_time = timestamp - timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY` * `genesis_eth1_block_hash` is the Ethereum 1.0 block hash that emitted the log for the last deposit in `deposits` *Note*: The function `is_genesis_trigger` has yet to be agreed upon by the community, and can be updated as necessary. We define the following testing placeholder: ```python def is_genesis_trigger(deposits: Sequence[Deposit], timestamp: uint64) -> bool: - SECONDS_PER_DAY = 86400 # Do not deploy too early if timestamp - timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY < MIN_GENESIS_TIME: return False - - # Process deposits + # Process genesis deposits state = BeaconState() + process_genesis_deposits(state, deposits) + # Check active validator count + return len(get_active_validator_indices(state, GENESIS_EPOCH)) >= GENESIS_ACTIVE_VALIDATOR_COUNT +``` + +```python +def process_genesis_deposits(state: BeaconState, deposits: Sequence[Deposit]) -> None: leaves = list(map(lambda deposit: deposit.data, deposits)) for deposit_index, deposit in enumerate(deposits): state.eth1_data.deposit_root = hash_tree_root( List[DepositData, 2**DEPOSIT_CONTRACT_TREE_DEPTH](*leaves[:deposit_index + 1]) ) state.eth1_data.deposit_count = deposit_index + 1 - state.eth1_deposit_index = deposit_index process_deposit(state, deposit) - # Count active validators at genesis - active_validator_count = 0 + # Process genesis activations for validator in state.validators: if validator.effective_balance == MAX_EFFECTIVE_BALANCE: - active_validator_count += 1 - - # Check effective balance to trigger genesis - return active_validator_count >= GENESIS_ACTIVE_VALIDATOR_COUNT + validator.activation_eligibility_epoch = GENESIS_EPOCH + validator.activation_epoch = GENESIS_EPOCH ``` ### Genesis state @@ -1140,27 +1143,13 @@ Let `genesis_state = get_genesis_beacon_state(genesis_deposits, genesis_time, ge def get_genesis_beacon_state(deposits: Sequence[Deposit], genesis_time: int, genesis_eth1_block_hash: Hash) -> BeaconState: + # Process genesis deposits state = BeaconState( genesis_time=genesis_time, eth1_data=Eth1Data(block_hash=genesis_eth1_block_hash), latest_block_header=BeaconBlockHeader(body_root=hash_tree_root(BeaconBlockBody())), ) - - # Process genesis deposits - leaves = list(map(lambda deposit: deposit.data, deposits)) - for deposit_index, deposit in enumerate(deposits): - state.eth1_data.deposit_root = hash_tree_root( - List[DepositData, 2**DEPOSIT_CONTRACT_TREE_DEPTH](*leaves[:deposit_index + 1]) - ) - state.eth1_data.deposit_count = deposit_index + 1 - state.eth1_deposit_index = deposit_index - process_deposit(state, deposit) - - # Process genesis activations - for validator in state.validators: - if validator.effective_balance == MAX_EFFECTIVE_BALANCE: - validator.activation_eligibility_epoch = GENESIS_EPOCH - validator.activation_epoch = GENESIS_EPOCH + process_genesis_deposits(state, deposits) # Populate active_index_roots genesis_active_index_root = hash_tree_root( From d00b5b9ea0d3f22a8a58a7db45c9879cf99c0736 Mon Sep 17 00:00:00 2001 From: Justin Drake Date: Sat, 29 Jun 2019 21:18:18 +0100 Subject: [PATCH 39/49] Merge is_genesis_trigger into get_genesis_state --- specs/core/0_beacon-chain.md | 58 +++++++++++------------------------- 1 file changed, 17 insertions(+), 41 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index f8768935b..ba7f1d06d 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -94,7 +94,6 @@ - [`initiate_validator_exit`](#initiate_validator_exit) - [`slash_validator`](#slash_validator) - [Genesis](#genesis) - - [Genesis trigger](#genesis-trigger) - [Genesis state](#genesis-state) - [Genesis block](#genesis-block) - [Beacon chain state transition function](#beacon-chain-state-transition-function) @@ -190,7 +189,7 @@ The following values are (non-configurable) constants used throughout the specif | `MIN_PER_EPOCH_CHURN_LIMIT` | `2**2` (= 4) | | `CHURN_LIMIT_QUOTIENT` | `2**16` (= 65,536) | | `SHUFFLE_ROUND_COUNT` | `90` | -| `GENESIS_ACTIVE_VALIDATOR_COUNT` | `2**16` (= 65,536) | +| `MIN_GENESIS_ACTIVE_VALIDATOR_COUNT` | `2**16` (= 65,536) | | `MIN_GENESIS_TIME` | `1578009600` (Jan 3, 2020) | | `JUSTIFICATION_BITS_LENGTH` | `4` | @@ -1091,35 +1090,28 @@ def slash_validator(state: BeaconState, ## Genesis -### Genesis trigger +### Genesis state -Before genesis has been triggered and for every Ethereum 1.0 block call `is_genesis_trigger(deposits: Sequence[Deposit], timestamp: uint64) -> bool` where: +Before the Ethereum 2.0 genesis has been triggered and for every Ethereum 1.0 block, call `get_genesis_beacon_state(eth1_block_hash, eth1_timestamp, deposits)` where: -* `deposits` is the sequence of all deposits, ordered chronologically, up to and including the deposit triggering the latest `Deposit` log -* `timestamp` is the Unix timestamp in the Ethereum 1.0 block that emitted the latest `Deposit` log +* `eth1_block_hash` is the hash of the Ethereum 1.0 block +* `eth1_timestamp` is the Unix timestamp corresponding to `eth1_block_hash` +* `deposits` is the sequence of all deposits, ordered chronologically, up to the block with hash `eth1_block_hash` -When `is_genesis_trigger(deposits, timestamp) is True` for the first time, let: +The genesis state `genesis_state` is defined as the return value of the first call to `get_genesis_beacon_state` that does not trigger an `assert`. -* `genesis_deposits = deposits` -* `genesis_time = timestamp - timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY` -* `genesis_eth1_block_hash` is the Ethereum 1.0 block hash that emitted the log for the last deposit in `deposits` - -*Note*: The function `is_genesis_trigger` has yet to be agreed upon by the community, and can be updated as necessary. We define the following testing placeholder: +*Note*: The two constants `MIN_GENESIS_TIME` and `MIN_GENESIS_ACTIVE_VALIDATOR_COUNT` in `get_genesis_beacon_state` have yet to be agreed upon by the community, and can be updated as necessary. ```python -def is_genesis_trigger(deposits: Sequence[Deposit], timestamp: uint64) -> bool: - # Do not deploy too early - if timestamp - timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY < MIN_GENESIS_TIME: - return False - # Process genesis deposits - state = BeaconState() - process_genesis_deposits(state, deposits) - # Check active validator count - return len(get_active_validator_indices(state, GENESIS_EPOCH)) >= GENESIS_ACTIVE_VALIDATOR_COUNT -``` +def get_genesis_beacon_state(eth1_block_hash: Hash, eth1_timestamp: int, deposits: Sequence[Deposit]) -> BeaconState: + state = BeaconState( + genesis_time=timestamp - timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY, + eth1_data=Eth1Data(block_hash=genesis_eth1_block_hash), + latest_block_header=BeaconBlockHeader(body_root=hash_tree_root(BeaconBlockBody())), + ) + assert state.genesis_time >= MIN_GENESIS_TIME -```python -def process_genesis_deposits(state: BeaconState, deposits: Sequence[Deposit]) -> None: + # Process deposits leaves = list(map(lambda deposit: deposit.data, deposits)) for deposit_index, deposit in enumerate(deposits): state.eth1_data.deposit_root = hash_tree_root( @@ -1133,23 +1125,7 @@ def process_genesis_deposits(state: BeaconState, deposits: Sequence[Deposit]) -> if validator.effective_balance == MAX_EFFECTIVE_BALANCE: validator.activation_eligibility_epoch = GENESIS_EPOCH validator.activation_epoch = GENESIS_EPOCH -``` - -### Genesis state - -Let `genesis_state = get_genesis_beacon_state(genesis_deposits, genesis_time, genesis_eth1_block_hash)`. - -```python -def get_genesis_beacon_state(deposits: Sequence[Deposit], - genesis_time: int, - genesis_eth1_block_hash: Hash) -> BeaconState: - # Process genesis deposits - state = BeaconState( - genesis_time=genesis_time, - eth1_data=Eth1Data(block_hash=genesis_eth1_block_hash), - latest_block_header=BeaconBlockHeader(body_root=hash_tree_root(BeaconBlockBody())), - ) - process_genesis_deposits(state, deposits) + assert len(get_active_validator_indices(state, GENESIS_EPOCH)) >= MIN_GENESIS_ACTIVE_VALIDATOR_COUNT # Populate active_index_roots genesis_active_index_root = hash_tree_root( From 3a5872f8e45ba2c23790007071a711ff322a379c Mon Sep 17 00:00:00 2001 From: Justin Drake Date: Sat, 29 Jun 2019 21:29:10 +0100 Subject: [PATCH 40/49] Cleanups and fixes --- configs/constant_presets/mainnet.yaml | 2 +- configs/constant_presets/minimal.yaml | 2 +- specs/core/0_beacon-chain.md | 19 +++++++++---------- .../eth2spec/test/genesis/test_genesis.py | 2 +- .../test/genesis/test_genesis_trigger.py | 4 ++-- 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/configs/constant_presets/mainnet.yaml b/configs/constant_presets/mainnet.yaml index d7a3b5efe..1ebae3c87 100644 --- a/configs/constant_presets/mainnet.yaml +++ b/configs/constant_presets/mainnet.yaml @@ -18,7 +18,7 @@ CHURN_LIMIT_QUOTIENT: 65536 # See issue 563 SHUFFLE_ROUND_COUNT: 90 # `2**16` (= 65,536) -GENESIS_ACTIVE_VALIDATOR_COUNT: 65536 +MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 65536 # Deposit contract diff --git a/configs/constant_presets/minimal.yaml b/configs/constant_presets/minimal.yaml index e8dc370be..c17c5806f 100644 --- a/configs/constant_presets/minimal.yaml +++ b/configs/constant_presets/minimal.yaml @@ -17,7 +17,7 @@ CHURN_LIMIT_QUOTIENT: 65536 # [customized] Faster, but unsecure. SHUFFLE_ROUND_COUNT: 10 # [customized] -GENESIS_ACTIVE_VALIDATOR_COUNT: 100 +MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 100 # Deposit contract diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index ba7f1d06d..9df0e2f5a 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -189,7 +189,7 @@ The following values are (non-configurable) constants used throughout the specif | `MIN_PER_EPOCH_CHURN_LIMIT` | `2**2` (= 4) | | `CHURN_LIMIT_QUOTIENT` | `2**16` (= 65,536) | | `SHUFFLE_ROUND_COUNT` | `90` | -| `MIN_GENESIS_ACTIVE_VALIDATOR_COUNT` | `2**16` (= 65,536) | +| `MIN_MIN_GENESIS_ACTIVE_VALIDATOR_COUNT` | `2**16` (= 65,536) | | `MIN_GENESIS_TIME` | `1578009600` (Jan 3, 2020) | | `JUSTIFICATION_BITS_LENGTH` | `4` | @@ -1092,40 +1092,39 @@ def slash_validator(state: BeaconState, ### Genesis state -Before the Ethereum 2.0 genesis has been triggered and for every Ethereum 1.0 block, call `get_genesis_beacon_state(eth1_block_hash, eth1_timestamp, deposits)` where: +Before the Ethereum 2.0 genesis has been triggered, and for every Ethereum 1.0 block, call `get_genesis_beacon_state(eth1_block_hash, eth1_timestamp, deposits)` where: * `eth1_block_hash` is the hash of the Ethereum 1.0 block * `eth1_timestamp` is the Unix timestamp corresponding to `eth1_block_hash` * `deposits` is the sequence of all deposits, ordered chronologically, up to the block with hash `eth1_block_hash` -The genesis state `genesis_state` is defined as the return value of the first call to `get_genesis_beacon_state` that does not trigger an `assert`. +The genesis state `genesis_state` is the return value of the first call to `get_genesis_beacon_state` that does not trigger an `assert`. -*Note*: The two constants `MIN_GENESIS_TIME` and `MIN_GENESIS_ACTIVE_VALIDATOR_COUNT` in `get_genesis_beacon_state` have yet to be agreed upon by the community, and can be updated as necessary. +*Note*: The two constants `MIN_GENESIS_TIME` and `MIN_MIN_GENESIS_ACTIVE_VALIDATOR_COUNT` have yet to be agreed upon by the community, and can be updated as necessary. ```python def get_genesis_beacon_state(eth1_block_hash: Hash, eth1_timestamp: int, deposits: Sequence[Deposit]) -> BeaconState: state = BeaconState( genesis_time=timestamp - timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY, - eth1_data=Eth1Data(block_hash=genesis_eth1_block_hash), + eth1_data=Eth1Data(block_hash=genesis_eth1_block_hash, deposit_count=len(deposits)), latest_block_header=BeaconBlockHeader(body_root=hash_tree_root(BeaconBlockBody())), ) assert state.genesis_time >= MIN_GENESIS_TIME # Process deposits leaves = list(map(lambda deposit: deposit.data, deposits)) - for deposit_index, deposit in enumerate(deposits): + for index, deposit in enumerate(deposits): state.eth1_data.deposit_root = hash_tree_root( - List[DepositData, 2**DEPOSIT_CONTRACT_TREE_DEPTH](*leaves[:deposit_index + 1]) + List[DepositData, 2**DEPOSIT_CONTRACT_TREE_DEPTH](*leaves[:index + 1]) ) - state.eth1_data.deposit_count = deposit_index + 1 process_deposit(state, deposit) - # Process genesis activations + # Process activations for validator in state.validators: if validator.effective_balance == MAX_EFFECTIVE_BALANCE: validator.activation_eligibility_epoch = GENESIS_EPOCH validator.activation_epoch = GENESIS_EPOCH - assert len(get_active_validator_indices(state, GENESIS_EPOCH)) >= MIN_GENESIS_ACTIVE_VALIDATOR_COUNT + assert len(get_active_validator_indices(state, GENESIS_EPOCH)) >= MIN_MIN_GENESIS_ACTIVE_VALIDATOR_COUNT # Populate active_index_roots genesis_active_index_root = hash_tree_root( diff --git a/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py b/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py index 0d2b4fbac..21fcaca40 100644 --- a/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py +++ b/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py @@ -7,7 +7,7 @@ from eth2spec.test.helpers.deposits import ( @with_phases(['phase0']) @spectest_with_bls_switch def test_genesis(spec): - deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT + deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) genesis_time = 1546300800 genesis_eth1_block_hash = b'\x12' * 32 diff --git a/test_libs/pyspec/eth2spec/test/genesis/test_genesis_trigger.py b/test_libs/pyspec/eth2spec/test/genesis/test_genesis_trigger.py index 783def3ba..998189e15 100644 --- a/test_libs/pyspec/eth2spec/test/genesis/test_genesis_trigger.py +++ b/test_libs/pyspec/eth2spec/test/genesis/test_genesis_trigger.py @@ -23,7 +23,7 @@ def test_is_genesis_trigger_false(spec): @with_phases(['phase0']) @spectest_with_bls_switch def test_is_genesis_trigger_true(spec): - deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT + deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT genesis_deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) SECONDS_PER_DAY = 86400 genesis_time = 1578009600 - 2 * SECONDS_PER_DAY @@ -40,7 +40,7 @@ def test_is_genesis_trigger_true(spec): @with_phases(['phase0']) @spectest_with_bls_switch def test_is_genesis_trigger_not_enough_balance(spec): - deposit_count = spec.GENESIS_ACTIVE_VALIDATOR_COUNT + deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT genesis_deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE - 1) genesis_time = 1546300800 yield "deposits", genesis_deposits From ada3cb2ae126653ce64d240b78a55e7eff46ac96 Mon Sep 17 00:00:00 2001 From: Justin Drake Date: Sat, 29 Jun 2019 21:36:27 +0100 Subject: [PATCH 41/49] Fix genesis balance bug (git add -u) --- specs/core/0_beacon-chain.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 9df0e2f5a..7a79dde01 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1120,8 +1120,8 @@ def get_genesis_beacon_state(eth1_block_hash: Hash, eth1_timestamp: int, deposit process_deposit(state, deposit) # Process activations - for validator in state.validators: - if validator.effective_balance == MAX_EFFECTIVE_BALANCE: + for index, validator in enumerate(state.validators): + if balances[index] >= MAX_EFFECTIVE_BALANCE: validator.activation_eligibility_epoch = GENESIS_EPOCH validator.activation_epoch = GENESIS_EPOCH assert len(get_active_validator_indices(state, GENESIS_EPOCH)) >= MIN_MIN_GENESIS_ACTIVE_VALIDATOR_COUNT From 43beb743e6bc7eab133bcf07fdfb8313fdd1b20d Mon Sep 17 00:00:00 2001 From: Justin Drake Date: Sat, 29 Jun 2019 21:39:55 +0100 Subject: [PATCH 42/49] typo --- specs/core/0_beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 7a79dde01..a0c3d85c0 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1121,7 +1121,7 @@ def get_genesis_beacon_state(eth1_block_hash: Hash, eth1_timestamp: int, deposit # Process activations for index, validator in enumerate(state.validators): - if balances[index] >= MAX_EFFECTIVE_BALANCE: + if state.balances[index] >= MAX_EFFECTIVE_BALANCE: validator.activation_eligibility_epoch = GENESIS_EPOCH validator.activation_epoch = GENESIS_EPOCH assert len(get_active_validator_indices(state, GENESIS_EPOCH)) >= MIN_MIN_GENESIS_ACTIVE_VALIDATOR_COUNT From a356fc9fc8073794ec2d7ea7fa71689e2d8e5a79 Mon Sep 17 00:00:00 2001 From: Justin Drake Date: Sat, 29 Jun 2019 21:53:04 +0100 Subject: [PATCH 43/49] Fixes --- specs/core/0_beacon-chain.md | 8 ++++---- test_libs/pyspec/eth2spec/test/genesis/test_genesis.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index a0c3d85c0..3de90a87c 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -189,7 +189,7 @@ The following values are (non-configurable) constants used throughout the specif | `MIN_PER_EPOCH_CHURN_LIMIT` | `2**2` (= 4) | | `CHURN_LIMIT_QUOTIENT` | `2**16` (= 65,536) | | `SHUFFLE_ROUND_COUNT` | `90` | -| `MIN_MIN_GENESIS_ACTIVE_VALIDATOR_COUNT` | `2**16` (= 65,536) | +| `MIN_GENESIS_ACTIVE_VALIDATOR_COUNT` | `2**16` (= 65,536) | | `MIN_GENESIS_TIME` | `1578009600` (Jan 3, 2020) | | `JUSTIFICATION_BITS_LENGTH` | `4` | @@ -1100,12 +1100,12 @@ Before the Ethereum 2.0 genesis has been triggered, and for every Ethereum 1.0 b The genesis state `genesis_state` is the return value of the first call to `get_genesis_beacon_state` that does not trigger an `assert`. -*Note*: The two constants `MIN_GENESIS_TIME` and `MIN_MIN_GENESIS_ACTIVE_VALIDATOR_COUNT` have yet to be agreed upon by the community, and can be updated as necessary. +*Note*: The two constants `MIN_GENESIS_TIME` and `MIN_GENESIS_ACTIVE_VALIDATOR_COUNT` have yet to be agreed upon by the community, and can be updated as necessary. ```python def get_genesis_beacon_state(eth1_block_hash: Hash, eth1_timestamp: int, deposits: Sequence[Deposit]) -> BeaconState: state = BeaconState( - genesis_time=timestamp - timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY, + genesis_time=eth1_timestamp - eth1_timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY, eth1_data=Eth1Data(block_hash=genesis_eth1_block_hash, deposit_count=len(deposits)), latest_block_header=BeaconBlockHeader(body_root=hash_tree_root(BeaconBlockBody())), ) @@ -1124,7 +1124,7 @@ def get_genesis_beacon_state(eth1_block_hash: Hash, eth1_timestamp: int, deposit if state.balances[index] >= MAX_EFFECTIVE_BALANCE: validator.activation_eligibility_epoch = GENESIS_EPOCH validator.activation_epoch = GENESIS_EPOCH - assert len(get_active_validator_indices(state, GENESIS_EPOCH)) >= MIN_MIN_GENESIS_ACTIVE_VALIDATOR_COUNT + assert len(get_active_validator_indices(state, GENESIS_EPOCH)) >= MIN_GENESIS_ACTIVE_VALIDATOR_COUNT # Populate active_index_roots genesis_active_index_root = hash_tree_root( diff --git a/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py b/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py index 21fcaca40..0023fbf5e 100644 --- a/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py +++ b/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py @@ -17,9 +17,9 @@ def test_genesis(spec): yield "genesis_eth1_block_hash", genesis_eth1_block_hash genesis_state = spec.get_genesis_beacon_state( - genesis_deposits, - genesis_time, genesis_eth1_block_hash, + genesis_time, + genesis_deposits, ) assert genesis_state.genesis_time == genesis_time From 6d455136059f2c92a650ab3567dcaf52333bdd25 Mon Sep 17 00:00:00 2001 From: Justin Drake Date: Sat, 29 Jun 2019 21:56:07 +0100 Subject: [PATCH 44/49] Make timestamp a uint64 --- specs/core/0_beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 3de90a87c..4d8f6332e 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1103,7 +1103,7 @@ The genesis state `genesis_state` is the return value of the first call to `get_ *Note*: The two constants `MIN_GENESIS_TIME` and `MIN_GENESIS_ACTIVE_VALIDATOR_COUNT` have yet to be agreed upon by the community, and can be updated as necessary. ```python -def get_genesis_beacon_state(eth1_block_hash: Hash, eth1_timestamp: int, deposits: Sequence[Deposit]) -> BeaconState: +def get_genesis_beacon_state(eth1_block_hash: Hash, eth1_timestamp: uint64, deposits: Sequence[Deposit]) -> BeaconState: state = BeaconState( genesis_time=eth1_timestamp - eth1_timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY, eth1_data=Eth1Data(block_hash=genesis_eth1_block_hash, deposit_count=len(deposits)), From 03a243e96cbfa77c67d6a3ccb2c630ea7405b549 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Sun, 30 Jun 2019 05:06:17 +0800 Subject: [PATCH 45/49] fix basic test --- specs/core/0_beacon-chain.md | 2 +- .../eth2spec/test/genesis/test_genesis.py | 24 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 4d8f6332e..7e39a5284 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1106,7 +1106,7 @@ The genesis state `genesis_state` is the return value of the first call to `get_ def get_genesis_beacon_state(eth1_block_hash: Hash, eth1_timestamp: uint64, deposits: Sequence[Deposit]) -> BeaconState: state = BeaconState( genesis_time=eth1_timestamp - eth1_timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY, - eth1_data=Eth1Data(block_hash=genesis_eth1_block_hash, deposit_count=len(deposits)), + eth1_data=Eth1Data(block_hash=eth1_block_hash, deposit_count=len(deposits)), latest_block_header=BeaconBlockHeader(body_root=hash_tree_root(BeaconBlockBody())), ) assert state.genesis_time >= MIN_GENESIS_TIME diff --git a/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py b/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py index 0023fbf5e..9c546b172 100644 --- a/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py +++ b/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py @@ -6,26 +6,26 @@ from eth2spec.test.helpers.deposits import ( @with_phases(['phase0']) @spectest_with_bls_switch -def test_genesis(spec): +def test_get_genesis_beacon_state_success(spec): deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT - genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) - genesis_time = 1546300800 - genesis_eth1_block_hash = b'\x12' * 32 + deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) - yield "deposits", genesis_deposits - yield "genesis_time", genesis_time + eth1_block_hash = b'\x12' * 32 + eth1_timestamp = spec.MIN_GENESIS_TIME - yield "genesis_eth1_block_hash", genesis_eth1_block_hash + yield "eth1_block_hash", eth1_block_hash + yield "eth1_timestamp", eth1_timestamp + yield "deposits", deposits genesis_state = spec.get_genesis_beacon_state( - genesis_eth1_block_hash, - genesis_time, - genesis_deposits, + eth1_block_hash, + eth1_timestamp, + deposits, ) - assert genesis_state.genesis_time == genesis_time + assert genesis_state.genesis_time == eth1_timestamp - eth1_timestamp % spec.SECONDS_PER_DAY + 2 * spec.SECONDS_PER_DAY assert len(genesis_state.validators) == deposit_count assert genesis_state.eth1_data.deposit_root == deposit_root assert genesis_state.eth1_data.deposit_count == deposit_count - assert genesis_state.eth1_data.block_hash == genesis_eth1_block_hash + assert genesis_state.eth1_data.block_hash == eth1_block_hash yield "state", genesis_state From 47cdae42926fc87084805c2e89b153e4f2f0b58a Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Sun, 30 Jun 2019 06:38:30 +0800 Subject: [PATCH 46/49] Refactor 1. Rename the current `get_genesis_beacon_state(...)` to `initialize_beacon_state_from_eth1(...)` 2. Extract `is_valid_genesis_state(state: BeaconState) -> bool` from `initialize_beacon_state_from_eth1(...)` --- specs/core/0_beacon-chain.md | 20 +++-- .../eth2spec/test/genesis/test_genesis.py | 31 ------- .../test/genesis/test_genesis_trigger.py | 52 ----------- .../test_initialize_beacon_state_from_eth1.py | 39 +++++++++ .../genesis/test_is_valid_genesis_state.py | 86 +++++++++++++++++++ 5 files changed, 140 insertions(+), 88 deletions(-) delete mode 100644 test_libs/pyspec/eth2spec/test/genesis/test_genesis.py delete mode 100644 test_libs/pyspec/eth2spec/test/genesis/test_genesis_trigger.py create mode 100644 test_libs/pyspec/eth2spec/test/genesis/test_initialize_beacon_state_from_eth1.py create mode 100644 test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 7e39a5284..1009da909 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1092,24 +1092,25 @@ def slash_validator(state: BeaconState, ### Genesis state -Before the Ethereum 2.0 genesis has been triggered, and for every Ethereum 1.0 block, call `get_genesis_beacon_state(eth1_block_hash, eth1_timestamp, deposits)` where: +Before the Ethereum 2.0 genesis has been triggered, and for every Ethereum 1.0 block, call `initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits)` where: * `eth1_block_hash` is the hash of the Ethereum 1.0 block * `eth1_timestamp` is the Unix timestamp corresponding to `eth1_block_hash` * `deposits` is the sequence of all deposits, ordered chronologically, up to the block with hash `eth1_block_hash` -The genesis state `genesis_state` is the return value of the first call to `get_genesis_beacon_state` that does not trigger an `assert`. +The genesis state `genesis_state` is the return value of calling `initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits)` only if `is_valid_genesis_state(genesis_state) is True`. *Note*: The two constants `MIN_GENESIS_TIME` and `MIN_GENESIS_ACTIVE_VALIDATOR_COUNT` have yet to be agreed upon by the community, and can be updated as necessary. ```python -def get_genesis_beacon_state(eth1_block_hash: Hash, eth1_timestamp: uint64, deposits: Sequence[Deposit]) -> BeaconState: +def initialize_beacon_state_from_eth1(eth1_block_hash: Hash, + eth1_timestamp: uint64, + deposits: Sequence[Deposit]) -> BeaconState: state = BeaconState( genesis_time=eth1_timestamp - eth1_timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY, eth1_data=Eth1Data(block_hash=eth1_block_hash, deposit_count=len(deposits)), latest_block_header=BeaconBlockHeader(body_root=hash_tree_root(BeaconBlockBody())), ) - assert state.genesis_time >= MIN_GENESIS_TIME # Process deposits leaves = list(map(lambda deposit: deposit.data, deposits)) @@ -1124,7 +1125,6 @@ def get_genesis_beacon_state(eth1_block_hash: Hash, eth1_timestamp: uint64, depo if state.balances[index] >= MAX_EFFECTIVE_BALANCE: validator.activation_eligibility_epoch = GENESIS_EPOCH validator.activation_epoch = GENESIS_EPOCH - assert len(get_active_validator_indices(state, GENESIS_EPOCH)) >= MIN_GENESIS_ACTIVE_VALIDATOR_COUNT # Populate active_index_roots genesis_active_index_root = hash_tree_root( @@ -1136,6 +1136,16 @@ def get_genesis_beacon_state(eth1_block_hash: Hash, eth1_timestamp: uint64, depo return state ``` +```python +def is_valid_genesis_state(state: BeaconState) -> bool: + if state.genesis_time < MIN_GENESIS_TIME: + return False + elif len(get_active_validator_indices(state, GENESIS_EPOCH)) < MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: + return False + else: + return True +``` + ### Genesis block Let `genesis_block = BeaconBlock(state_root=hash_tree_root(genesis_state))`. diff --git a/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py b/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py deleted file mode 100644 index 9c546b172..000000000 --- a/test_libs/pyspec/eth2spec/test/genesis/test_genesis.py +++ /dev/null @@ -1,31 +0,0 @@ -from eth2spec.test.context import with_phases, spectest_with_bls_switch -from eth2spec.test.helpers.deposits import ( - prepare_genesis_deposits, -) - - -@with_phases(['phase0']) -@spectest_with_bls_switch -def test_get_genesis_beacon_state_success(spec): - deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT - deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) - - eth1_block_hash = b'\x12' * 32 - eth1_timestamp = spec.MIN_GENESIS_TIME - - yield "eth1_block_hash", eth1_block_hash - yield "eth1_timestamp", eth1_timestamp - yield "deposits", deposits - genesis_state = spec.get_genesis_beacon_state( - eth1_block_hash, - eth1_timestamp, - deposits, - ) - - assert genesis_state.genesis_time == eth1_timestamp - eth1_timestamp % spec.SECONDS_PER_DAY + 2 * spec.SECONDS_PER_DAY - assert len(genesis_state.validators) == deposit_count - assert genesis_state.eth1_data.deposit_root == deposit_root - assert genesis_state.eth1_data.deposit_count == deposit_count - assert genesis_state.eth1_data.block_hash == eth1_block_hash - - yield "state", genesis_state diff --git a/test_libs/pyspec/eth2spec/test/genesis/test_genesis_trigger.py b/test_libs/pyspec/eth2spec/test/genesis/test_genesis_trigger.py deleted file mode 100644 index 998189e15..000000000 --- a/test_libs/pyspec/eth2spec/test/genesis/test_genesis_trigger.py +++ /dev/null @@ -1,52 +0,0 @@ -from eth2spec.test.context import with_phases, spectest_with_bls_switch -from eth2spec.test.helpers.deposits import ( - prepare_genesis_deposits, -) - - -@with_phases(['phase0']) -@spectest_with_bls_switch -def test_is_genesis_trigger_false(spec): - deposit_count = 2 - genesis_deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) - genesis_time = 1546300800 - - yield "deposits", genesis_deposits - yield "time", genesis_time - - is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time) - assert is_triggered is False - - yield "is_triggered", is_triggered - - -@with_phases(['phase0']) -@spectest_with_bls_switch -def test_is_genesis_trigger_true(spec): - deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT - genesis_deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) - SECONDS_PER_DAY = 86400 - genesis_time = 1578009600 - 2 * SECONDS_PER_DAY - - yield "deposits", genesis_deposits - yield "time", genesis_time - - is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time) - assert is_triggered is True - - yield "is_triggered", is_triggered - - -@with_phases(['phase0']) -@spectest_with_bls_switch -def test_is_genesis_trigger_not_enough_balance(spec): - deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT - genesis_deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE - 1) - genesis_time = 1546300800 - yield "deposits", genesis_deposits - yield "time", genesis_time - - is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time) - assert is_triggered is False - - yield "is_triggered", is_triggered diff --git a/test_libs/pyspec/eth2spec/test/genesis/test_initialize_beacon_state_from_eth1.py b/test_libs/pyspec/eth2spec/test/genesis/test_initialize_beacon_state_from_eth1.py new file mode 100644 index 000000000..86f845f74 --- /dev/null +++ b/test_libs/pyspec/eth2spec/test/genesis/test_initialize_beacon_state_from_eth1.py @@ -0,0 +1,39 @@ +from eth2spec.test.context import spectest_with_bls_switch, with_phases +from eth2spec.test.helpers.deposits import ( + prepare_genesis_deposits, +) + + +def create_valid_beacon_state(spec): + deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT + deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) + + eth1_block_hash = b'\x12' * 32 + eth1_timestamp = spec.MIN_GENESIS_TIME + return spec.initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits) + + +@with_phases(['phase0']) +@spectest_with_bls_switch +def test_initialize_beacon_state_from_eth1(spec): + deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT + deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) + + eth1_block_hash = b'\x12' * 32 + eth1_timestamp = spec.MIN_GENESIS_TIME + + yield 'eth1_block_hash', eth1_block_hash + yield 'eth1_timestamp', eth1_timestamp + yield 'deposits', deposits + + # initialize beacon_state + state = spec.initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits) + + assert state.genesis_time == eth1_timestamp - eth1_timestamp % spec.SECONDS_PER_DAY + 2 * spec.SECONDS_PER_DAY + assert len(state.validators) == deposit_count + assert state.eth1_data.deposit_root == deposit_root + assert state.eth1_data.deposit_count == deposit_count + assert state.eth1_data.block_hash == eth1_block_hash + + # yield state + yield 'state', state diff --git a/test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py b/test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py new file mode 100644 index 000000000..8b41e5ac4 --- /dev/null +++ b/test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py @@ -0,0 +1,86 @@ +from eth2spec.test.context import spectest_with_bls_switch, with_phases +from eth2spec.test.helpers.deposits import ( + prepare_genesis_deposits, +) + + +def create_valid_beacon_state(spec): + deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT + deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) + + eth1_block_hash = b'\x12' * 32 + eth1_timestamp = spec.MIN_GENESIS_TIME + return spec.initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits) + + +def run_is_valid_genesis_state(spec, state, valid=True): + """ + Run ``is_valid_genesis_state``, yielding: + - state ('state') + - is_valid ('is_valid') + If ``valid == False``, run expecting ``AssertionError`` + """ + yield state + is_valid = spec.is_valid_genesis_state(state) + yield 'is_valid', is_valid + + +@with_phases(['phase0']) +@spectest_with_bls_switch +def test_is_valid_genesis_state_true(spec): + state = create_valid_beacon_state(spec) + + yield from run_is_valid_genesis_state(spec, state, valid=True) + + +@with_phases(['phase0']) +@spectest_with_bls_switch +def test_is_valid_genesis_state_false_invalid_timestamp(spec): + state = create_valid_beacon_state(spec) + state.genesis_time = spec.MIN_GENESIS_TIME - 1 + + yield from run_is_valid_genesis_state(spec, state, valid=True) + + +@with_phases(['phase0']) +@spectest_with_bls_switch +def test_is_valid_genesis_state_true_more_balance(spec): + state = create_valid_beacon_state(spec) + state.validators[0].effective_balance = spec.MAX_EFFECTIVE_BALANCE + 1 + + yield from run_is_valid_genesis_state(spec, state, valid=True) + + +@with_phases(['phase0']) +@spectest_with_bls_switch +def test_is_valid_genesis_state_false_not_enough_balance(spec): + state = create_valid_beacon_state(spec) + state.validators[0].effective_balance = spec.MAX_EFFECTIVE_BALANCE - 1 + + yield from run_is_valid_genesis_state(spec, state, valid=False) + + +@with_phases(['phase0']) +@spectest_with_bls_switch +def test_is_valid_genesis_state_true_one_more_validator(spec): + deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT + 1 + deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) + + eth1_block_hash = b'\x12' * 32 + eth1_timestamp = spec.MIN_GENESIS_TIME + state = spec.initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits) + + yield from run_is_valid_genesis_state(spec, state, valid=True) + + +@with_phases(['phase0']) +@spectest_with_bls_switch +def test_is_valid_genesis_state_flase_not_enough_validator(spec): + deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT - 1 + deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) + + eth1_block_hash = b'\x12' * 32 + eth1_timestamp = spec.MIN_GENESIS_TIME + state = spec.initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits) + + yield from run_is_valid_genesis_state(spec, state, valid=False) From 8d2cbc9722bbb264ced4bae1c67d940acc86e217 Mon Sep 17 00:00:00 2001 From: protolambda Date: Sun, 30 Jun 2019 02:08:34 +0200 Subject: [PATCH 47/49] add comments to make variations in genesis initialization clear, and about the mix-in in verification --- specs/core/0_beacon-chain.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 1009da909..957239f58 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1100,6 +1100,10 @@ Before the Ethereum 2.0 genesis has been triggered, and for every Ethereum 1.0 b The genesis state `genesis_state` is the return value of calling `initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits)` only if `is_valid_genesis_state(genesis_state) is True`. +Implementations can choose to support different (more optimized) variations of the below initialization approach: + - Build the `genesis_state` from a stream of deposits by incrementally updating the `state.eth1_data.deposit_root`. + - Compute deposit proofs for the final `state.eth1_data.deposit_root`, and process as a pre-determined collection. + *Note*: The two constants `MIN_GENESIS_TIME` and `MIN_GENESIS_ACTIVE_VALIDATOR_COUNT` have yet to be agreed upon by the community, and can be updated as necessary. ```python @@ -1671,7 +1675,7 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None: assert verify_merkle_branch( leaf=hash_tree_root(deposit.data), proof=deposit.proof, - depth=DEPOSIT_CONTRACT_TREE_DEPTH + 1, + depth=DEPOSIT_CONTRACT_TREE_DEPTH + 1, # add 1 for the SSZ length mix-in index=state.eth1_deposit_index, root=state.eth1_data.deposit_root, ) From 4d5d5971e2b6fef4dba37c4854feec77e1411a05 Mon Sep 17 00:00:00 2001 From: protolambda Date: Sun, 30 Jun 2019 02:10:18 +0200 Subject: [PATCH 48/49] fix genesis tests; sign deposit-datas, and lower min validator count for testing --- configs/constant_presets/minimal.yaml | 2 +- .../genesis/test_initialize_beacon_state_from_eth1.py | 11 +---------- .../test/genesis/test_is_valid_genesis_state.py | 6 +++--- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/configs/constant_presets/minimal.yaml b/configs/constant_presets/minimal.yaml index c17c5806f..50339cd92 100644 --- a/configs/constant_presets/minimal.yaml +++ b/configs/constant_presets/minimal.yaml @@ -17,7 +17,7 @@ CHURN_LIMIT_QUOTIENT: 65536 # [customized] Faster, but unsecure. SHUFFLE_ROUND_COUNT: 10 # [customized] -MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 100 +MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 64 # Deposit contract diff --git a/test_libs/pyspec/eth2spec/test/genesis/test_initialize_beacon_state_from_eth1.py b/test_libs/pyspec/eth2spec/test/genesis/test_initialize_beacon_state_from_eth1.py index 86f845f74..b95b70fef 100644 --- a/test_libs/pyspec/eth2spec/test/genesis/test_initialize_beacon_state_from_eth1.py +++ b/test_libs/pyspec/eth2spec/test/genesis/test_initialize_beacon_state_from_eth1.py @@ -4,20 +4,11 @@ from eth2spec.test.helpers.deposits import ( ) -def create_valid_beacon_state(spec): - deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT - deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) - - eth1_block_hash = b'\x12' * 32 - eth1_timestamp = spec.MIN_GENESIS_TIME - return spec.initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits) - - @with_phases(['phase0']) @spectest_with_bls_switch def test_initialize_beacon_state_from_eth1(spec): deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT - deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) + deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE, signed=True) eth1_block_hash = b'\x12' * 32 eth1_timestamp = spec.MIN_GENESIS_TIME diff --git a/test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py b/test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py index 8b41e5ac4..828c62e90 100644 --- a/test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py +++ b/test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py @@ -6,7 +6,7 @@ from eth2spec.test.helpers.deposits import ( def create_valid_beacon_state(spec): deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT - deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) + deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE, signed=True) eth1_block_hash = b'\x12' * 32 eth1_timestamp = spec.MIN_GENESIS_TIME @@ -64,7 +64,7 @@ def test_is_valid_genesis_state_false_not_enough_balance(spec): @spectest_with_bls_switch def test_is_valid_genesis_state_true_one_more_validator(spec): deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT + 1 - deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) + deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE, signed=True) eth1_block_hash = b'\x12' * 32 eth1_timestamp = spec.MIN_GENESIS_TIME @@ -77,7 +77,7 @@ def test_is_valid_genesis_state_true_one_more_validator(spec): @spectest_with_bls_switch def test_is_valid_genesis_state_flase_not_enough_validator(spec): deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT - 1 - deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE) + deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE, signed=True) eth1_block_hash = b'\x12' * 32 eth1_timestamp = spec.MIN_GENESIS_TIME From f1749df58723214f4a2440974a1b8fe3eaed2278 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Sat, 29 Jun 2019 22:25:51 -0600 Subject: [PATCH 49/49] minor typo --- .../pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py b/test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py index 828c62e90..4ad509200 100644 --- a/test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py +++ b/test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py @@ -75,7 +75,7 @@ def test_is_valid_genesis_state_true_one_more_validator(spec): @with_phases(['phase0']) @spectest_with_bls_switch -def test_is_valid_genesis_state_flase_not_enough_validator(spec): +def test_is_valid_genesis_state_false_not_enough_validator(spec): deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT - 1 deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE, signed=True)