2019-05-15 16:36:32 +00:00
|
|
|
from eth2spec.test.helpers.keys import pubkeys, privkeys
|
|
|
|
from eth2spec.utils.bls import bls_sign
|
2019-06-29 18:02:05 +00:00
|
|
|
from eth2spec.utils.merkle_minimal import calc_merkle_tree_from_leaves, get_merkle_proof
|
2019-06-29 16:29:21 +00:00
|
|
|
from eth2spec.utils.ssz.ssz_impl import signing_root, hash_tree_root
|
|
|
|
from eth2spec.utils.ssz.ssz_typing import List
|
2019-05-15 16:36:32 +00:00
|
|
|
|
|
|
|
|
2019-06-21 21:59:18 +00:00
|
|
|
def build_deposit_data(spec, pubkey, privkey, amount, withdrawal_credentials, state=None, signed=False):
|
2019-06-29 18:09:43 +00:00
|
|
|
deposit_data = spec.DepositData(
|
2019-05-15 16:36:32 +00:00
|
|
|
pubkey=pubkey,
|
2019-05-30 02:38:55 +00:00
|
|
|
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-06-21 21:59:18 +00:00
|
|
|
sign_deposit_data(spec, deposit_data, privkey, state)
|
2019-05-15 17:31:02 +00:00
|
|
|
return deposit_data
|
|
|
|
|
|
|
|
|
2019-06-21 21:59:18 +00:00
|
|
|
def sign_deposit_data(spec, deposit_data, privkey, state=None):
|
|
|
|
if state is None:
|
|
|
|
# Genesis
|
2019-06-30 23:35:09 +00:00
|
|
|
domain = spec.compute_domain(spec.DOMAIN_DEPOSIT)
|
2019-06-21 21:59:18 +00:00
|
|
|
else:
|
|
|
|
domain = spec.get_domain(
|
2019-05-15 16:36:32 +00:00
|
|
|
state,
|
|
|
|
spec.DOMAIN_DEPOSIT,
|
|
|
|
)
|
2019-06-21 21:59:18 +00:00
|
|
|
|
|
|
|
signature = bls_sign(
|
|
|
|
message_hash=signing_root(deposit_data),
|
|
|
|
privkey=privkey,
|
|
|
|
domain=domain,
|
2019-05-15 16:36:32 +00:00
|
|
|
)
|
|
|
|
deposit_data.signature = signature
|
|
|
|
|
|
|
|
|
2019-05-30 20:57:18 +00:00
|
|
|
def build_deposit(spec,
|
|
|
|
state,
|
2019-06-29 16:29:21 +00:00
|
|
|
deposit_data_list,
|
2019-05-15 16:36:32 +00:00
|
|
|
pubkey,
|
|
|
|
privkey,
|
2019-05-15 17:31:02 +00:00
|
|
|
amount,
|
2019-05-30 02:38:55 +00:00
|
|
|
withdrawal_credentials,
|
2019-05-15 17:31:02 +00:00
|
|
|
signed):
|
2019-06-29 17:44:17 +00:00
|
|
|
deposit_data = build_deposit_data(spec, pubkey, privkey, amount, withdrawal_credentials, state=state, signed=signed)
|
2019-06-29 16:29:21 +00:00
|
|
|
index = len(deposit_data_list)
|
2019-06-29 18:33:11 +00:00
|
|
|
deposit_data_list.append(deposit_data)
|
2019-06-29 18:09:43 +00:00
|
|
|
root = hash_tree_root(List[spec.DepositData, 2**spec.DEPOSIT_CONTRACT_TREE_DEPTH](*deposit_data_list))
|
2019-06-29 16:29:21 +00:00
|
|
|
tree = calc_merkle_tree_from_leaves(tuple([d.hash_tree_root() for d in deposit_data_list]))
|
2019-06-29 18:33:11 +00:00
|
|
|
proof = list(get_merkle_proof(tree, item_index=index)) + [(index + 1).to_bytes(32, 'little')]
|
2019-06-29 16:29:21 +00:00
|
|
|
leaf = deposit_data.hash_tree_root()
|
2019-06-30 09:11:23 +00:00
|
|
|
assert spec.is_valid_merkle_branch(leaf, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH + 1, index, root)
|
2019-06-29 18:33:11 +00:00
|
|
|
deposit = spec.Deposit(proof=proof, data=deposit_data)
|
2019-05-15 16:36:32 +00:00
|
|
|
|
2019-06-29 17:33:29 +00:00
|
|
|
return deposit, root, deposit_data_list
|
2019-05-15 16:36:32 +00:00
|
|
|
|
|
|
|
|
2019-06-22 03:50:36 +00:00
|
|
|
def prepare_genesis_deposits(spec, genesis_validator_count, amount, signed=False):
|
2019-06-29 17:44:17 +00:00
|
|
|
deposit_data_list = []
|
2019-06-28 18:16:16 +00:00
|
|
|
genesis_deposits = []
|
2019-06-21 21:59:18 +00:00
|
|
|
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
|
2019-06-30 22:36:24 +00:00
|
|
|
withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.hash(pubkey)[1:]
|
2019-06-29 17:44:17 +00:00
|
|
|
deposit, root, deposit_data_list = build_deposit(
|
|
|
|
spec,
|
|
|
|
None,
|
|
|
|
deposit_data_list,
|
|
|
|
pubkey,
|
|
|
|
privkey,
|
|
|
|
amount,
|
|
|
|
withdrawal_credentials,
|
|
|
|
signed,
|
2019-06-28 18:16:16 +00:00
|
|
|
)
|
2019-06-29 17:44:17 +00:00
|
|
|
genesis_deposits.append(deposit)
|
2019-06-21 21:59:18 +00:00
|
|
|
|
2019-06-29 19:27:25 +00:00
|
|
|
return genesis_deposits, root
|
2019-06-21 21:59:18 +00:00
|
|
|
|
|
|
|
|
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.
|
|
|
|
"""
|
2019-06-29 16:29:21 +00:00
|
|
|
deposit_data_list = []
|
2019-05-15 16:36:32 +00:00
|
|
|
|
|
|
|
pubkey = pubkeys[validator_index]
|
|
|
|
privkey = privkeys[validator_index]
|
2019-05-30 02:38:55 +00:00
|
|
|
|
|
|
|
# insecurely use pubkey as withdrawal key if no credentials provided
|
|
|
|
if withdrawal_credentials is None:
|
2019-06-30 22:36:24 +00:00
|
|
|
withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.hash(pubkey)[1:]
|
2019-05-30 02:38:55 +00:00
|
|
|
|
2019-06-29 16:29:21 +00:00
|
|
|
deposit, root, deposit_data_list = build_deposit(
|
2019-05-31 11:20:10 +00:00
|
|
|
spec,
|
2019-05-15 16:36:32 +00:00
|
|
|
state,
|
2019-06-29 16:29:21 +00:00
|
|
|
deposit_data_list,
|
2019-05-15 16:36:32 +00:00
|
|
|
pubkey,
|
|
|
|
privkey,
|
|
|
|
amount,
|
2019-05-30 02:38:55 +00:00
|
|
|
withdrawal_credentials,
|
2019-05-31 19:54:58 +00:00
|
|
|
signed,
|
2019-05-15 16:36:32 +00:00
|
|
|
)
|
|
|
|
|
2019-06-29 18:40:25 +00:00
|
|
|
state.eth1_deposit_index = 0
|
2019-06-09 19:41:21 +00:00
|
|
|
state.eth1_data.deposit_root = root
|
2019-06-29 16:29:21 +00:00
|
|
|
state.eth1_data.deposit_count = len(deposit_data_list)
|
2019-05-15 16:36:32 +00:00
|
|
|
return deposit
|