eth2.0-specs/test_libs/pyspec/eth2spec/test/helpers/deposits.py

86 lines
2.8 KiB
Python
Raw Normal View History

2019-05-15 16:36:32 +00:00
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.minimal_ssz import signing_root
2019-05-30 20:57:18 +00:00
def build_deposit_data(spec, state, pubkey, privkey, amount, withdrawal_credentials, signed=False):
deposit_data = spec.DepositData(
2019-05-15 16:36:32 +00:00
pubkey=pubkey,
withdrawal_credentials=withdrawal_credentials,
2019-05-15 16:36:32 +00:00
amount=amount,
)
2019-05-15 17:31:02 +00:00
if signed:
2019-05-30 20:57:18 +00:00
sign_deposit_data(spec, state, deposit_data, privkey)
2019-05-15 17:31:02 +00:00
return deposit_data
2019-05-30 20:57:18 +00:00
def sign_deposit_data(spec, state, deposit_data, privkey):
2019-05-15 16:36:32 +00:00
signature = bls_sign(
message_hash=signing_root(deposit_data),
privkey=privkey,
2019-05-30 20:57:18 +00:00
domain=spec.get_domain(
2019-05-15 16:36:32 +00:00
state,
spec.DOMAIN_DEPOSIT,
)
)
deposit_data.signature = signature
2019-05-30 20:57:18 +00:00
def build_deposit(spec,
state,
2019-05-15 16:36:32 +00:00
deposit_data_leaves,
pubkey,
privkey,
2019-05-15 17:31:02 +00:00
amount,
withdrawal_credentials,
2019-05-15 17:31:02 +00:00
signed):
2019-05-30 20:57:18 +00:00
deposit_data = build_deposit_data(spec, state, pubkey, privkey, amount, withdrawal_credentials, signed)
2019-05-15 16:36:32 +00:00
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))
2019-05-30 20:57:18 +00:00
assert spec.verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, index, root)
2019-05-15 16:36:32 +00:00
2019-05-30 20:57:18 +00:00
deposit = spec.Deposit(
2019-05-15 16:36:32 +00:00
proof=list(proof),
index=index,
data=deposit_data,
)
return deposit, root, deposit_data_leaves
2019-05-30 20:57:18 +00:00
def prepare_state_and_deposit(spec, state, validator_index, amount, withdrawal_credentials=None, signed=False):
2019-05-15 16:36:32 +00:00
"""
Prepare the state for the deposit, and create a deposit for the given validator, depositing the given amount.
"""
pre_validator_count = len(state.validator_registry)
# fill previous deposits with zero-hash
2019-05-30 20:57:18 +00:00
deposit_data_leaves = [spec.ZERO_HASH] * pre_validator_count
2019-05-15 16:36:32 +00:00
pubkey = pubkeys[validator_index]
privkey = privkeys[validator_index]
# insecurely use pubkey as withdrawal key if no credentials provided
if withdrawal_credentials is None:
withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX_BYTE + spec.hash(pubkey)[1:]
2019-05-15 16:36:32 +00:00
deposit, root, deposit_data_leaves = build_deposit(
2019-05-30 20:57:18 +00:00
spec,
2019-05-15 16:36:32 +00:00
state,
deposit_data_leaves,
pubkey,
privkey,
amount,
withdrawal_credentials,
2019-05-15 17:31:02 +00:00
signed
2019-05-15 16:36:32 +00:00
)
state.latest_eth1_data.deposit_root = root
state.latest_eth1_data.deposit_count = len(deposit_data_leaves)
return deposit