2019-03-18 16:18:57 +00:00
|
|
|
import pytest
|
2019-03-18 18:51:52 +00:00
|
|
|
|
|
|
|
from py_ecc import bls
|
|
|
|
|
2019-03-18 16:18:57 +00:00
|
|
|
from build.phase0 import spec
|
|
|
|
|
2019-03-18 18:51:52 +00:00
|
|
|
from build.utils.merkle_minimal import (
|
|
|
|
calc_merkle_tree_from_leaves,
|
|
|
|
get_merkle_proof,
|
|
|
|
get_merkle_root,
|
|
|
|
)
|
|
|
|
from build.phase0.spec import (
|
|
|
|
Deposit,
|
|
|
|
DepositData,
|
|
|
|
DepositInput,
|
|
|
|
Eth1Data,
|
|
|
|
get_genesis_beacon_state,
|
|
|
|
verify_merkle_branch,
|
|
|
|
hash,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
privkeys_list = [i+1 for i in range(1000)]
|
|
|
|
pubkeys_list = [bls.privtopub(privkey) for privkey in privkeys_list]
|
|
|
|
pubkey_to_privkey = {pubkey: privkey for privkey, pubkey in zip(privkeys_list, pubkeys_list)}
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def privkeys():
|
|
|
|
return privkeys_list
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def pubkeys():
|
|
|
|
return pubkeys_list
|
|
|
|
|
|
|
|
|
|
|
|
def overwrite_spec_config(config):
|
|
|
|
for field in config:
|
|
|
|
setattr(spec, field, config[field])
|
|
|
|
if field == "LATEST_RANDAO_MIXES_LENGTH":
|
|
|
|
spec.BeaconState.fields['latest_randao_mixes'][1] = config[field]
|
|
|
|
elif field == "SHARD_COUNT":
|
|
|
|
spec.BeaconState.fields['latest_crosslinks'][1] = config[field]
|
|
|
|
elif field == "SLOTS_PER_HISTORICAL_ROOT":
|
|
|
|
spec.BeaconState.fields['latest_block_roots'][1] = config[field]
|
|
|
|
spec.BeaconState.fields['latest_state_roots'][1] = config[field]
|
|
|
|
spec.HistoricalBatch.fields['block_roots'][1] = config[field]
|
|
|
|
spec.HistoricalBatch.fields['state_roots'][1] = config[field]
|
|
|
|
elif field == "LATEST_ACTIVE_INDEX_ROOTS_LENGTH":
|
|
|
|
spec.BeaconState.fields['latest_active_index_roots'][1] = config[field]
|
|
|
|
elif field == "LATEST_SLASHED_EXIT_LENGTH":
|
|
|
|
spec.BeaconState.fields['latest_slashed_balances'][1] = config[field]
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def config():
|
|
|
|
return {
|
|
|
|
"SHARD_COUNT": 8,
|
|
|
|
"MIN_ATTESTATION_INCLUSION_DELAY": 2,
|
|
|
|
"TARGET_COMMITTEE_SIZE": 4,
|
|
|
|
"SLOTS_PER_EPOCH": 8,
|
|
|
|
"GENESIS_EPOCH": spec.GENESIS_SLOT // 8,
|
|
|
|
"SLOTS_PER_HISTORICAL_ROOT": 64,
|
|
|
|
"LATEST_RANDAO_MIXES_LENGTH": 64,
|
|
|
|
"LATEST_ACTIVE_INDEX_ROOTS_LENGTH": 64,
|
|
|
|
"LATEST_SLASHED_EXIT_LENGTH": 64,
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
|
|
def overwrite_config(config):
|
|
|
|
overwrite_spec_config(config)
|
|
|
|
|
|
|
|
|
|
|
|
def create_mock_genesis_validator_deposits(num_validators, deposit_data_leaves):
|
|
|
|
deposit_timestamp = 0
|
|
|
|
proof_of_possession = b'\x33' * 96
|
|
|
|
|
|
|
|
deposit_data_list = []
|
|
|
|
for i in range(num_validators):
|
|
|
|
pubkey = pubkeys_list[i]
|
|
|
|
privkey = pubkey_to_privkey[pubkey]
|
|
|
|
deposit_data = DepositData(
|
|
|
|
amount=spec.MAX_DEPOSIT_AMOUNT,
|
|
|
|
timestamp=deposit_timestamp,
|
|
|
|
deposit_input=DepositInput(
|
|
|
|
pubkey=pubkey,
|
|
|
|
withdrawal_credentials=privkey.to_bytes(32, byteorder='big'),
|
|
|
|
proof_of_possession=proof_of_possession,
|
|
|
|
),
|
|
|
|
)
|
|
|
|
item = hash(deposit_data.serialize())
|
|
|
|
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=i))
|
|
|
|
assert verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, i, root)
|
|
|
|
deposit_data_list.append(deposit_data)
|
|
|
|
|
|
|
|
genesis_validator_deposits = []
|
|
|
|
for i in range(num_validators):
|
|
|
|
genesis_validator_deposits.append(Deposit(
|
|
|
|
proof=list(get_merkle_proof(tree, item_index=i)),
|
|
|
|
index=i,
|
|
|
|
deposit_data=deposit_data_list[i]
|
|
|
|
))
|
|
|
|
return genesis_validator_deposits, root
|
|
|
|
|
|
|
|
|
|
|
|
def create_genesis_state(num_validators, deposit_data_leaves):
|
|
|
|
initial_deposits, deposit_root = create_mock_genesis_validator_deposits(num_validators, deposit_data_leaves)
|
|
|
|
return get_genesis_beacon_state(
|
|
|
|
initial_deposits,
|
|
|
|
genesis_time=0,
|
|
|
|
genesis_eth1_data=Eth1Data(
|
|
|
|
deposit_root=deposit_root,
|
|
|
|
block_hash=spec.ZERO_HASH,
|
|
|
|
),
|
|
|
|
)
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def num_validators():
|
|
|
|
return 100
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def deposit_data_leaves():
|
|
|
|
return list()
|
|
|
|
|
2019-03-18 16:18:57 +00:00
|
|
|
|
2019-03-18 18:51:52 +00:00
|
|
|
@pytest.fixture
|
|
|
|
def state(num_validators, deposit_data_leaves):
|
|
|
|
return create_genesis_state(num_validators, deposit_data_leaves)
|