예제 #1
0
def create_mock_genesis_validator_deposits(num_validators, deposit_data_leaves=None):
    if not deposit_data_leaves:
        deposit_data_leaves = []
    signature = b'\x33' * 96

    deposit_data_list = []
    for i in range(num_validators):
        pubkey = pubkeys[i]
        deposit_data = DepositData(
            pubkey=pubkey,
            # insecurely use pubkey as withdrawal key as well
            withdrawal_credentials=spec.BLS_WITHDRAWAL_PREFIX_BYTE + hash(pubkey)[1:],
            amount=spec.MAX_EFFECTIVE_BALANCE,
            signature=signature,
        )
        item = deposit_data.hash_tree_root()
        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,
            data=deposit_data_list[i]
        ))
    return genesis_validator_deposits, root
def test_deposit_event_log(registration_contract, a0, w3):
    log_filter = registration_contract.events.DepositEvent.createFilter(
        fromBlock='latest', )
    deposit_amount_list = [
        randint(MIN_DEPOSIT_AMOUNT, FULL_DEPOSIT_AMOUNT * 2) for _ in range(3)
    ]

    for i in range(3):
        deposit_input = (
            SAMPLE_PUBKEY, SAMPLE_WITHDRAWAL_CREDENTIALS,
            SAMPLE_VALID_SIGNATURE,
            hash_tree_root(
                DepositData(
                    pubkey=SAMPLE_PUBKEY,
                    withdrawal_credentials=SAMPLE_WITHDRAWAL_CREDENTIALS,
                    amount=deposit_amount_list[i],
                    signature=SAMPLE_VALID_SIGNATURE,
                ), ))
        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')
예제 #3
0
 def to_deposit_data(self) -> DepositData:
     return DepositData(
         pubkey=self.pubkey,
         withdrawal_credentials=self.withdrawal_credentials,
         amount=self.amount,
         signature=self.signature,
     )
예제 #4
0
def test_deposit_tree(registration_contract, w3, assert_tx_failed, deposit_input):
    log_filter = registration_contract.events.DepositEvent.createFilter(
        fromBlock='latest',
    )

    deposit_amount_list = [randint(MIN_DEPOSIT_AMOUNT, FULL_DEPOSIT_AMOUNT * 2) for _ in range(10)]
    deposit_data_list = []
    for i in range(0, 10):
        tx_hash = registration_contract.functions.deposit(
            *deposit_input,
        ).transact({"value": deposit_amount_list[i] * eth_utils.denoms.gwei})
        receipt = w3.eth.getTransactionReceipt(tx_hash)
        print("deposit transaction consumes %d gas" % receipt['gasUsed'])

        logs = log_filter.get_new_entries()
        assert len(logs) == 1
        log = logs[0]['args']

        assert log["index"] == i.to_bytes(8, 'little')

        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(List[DepositData, 2**32](*deposit_data_list))
        assert root == registration_contract.functions.get_hash_tree_root().call()
def test_deposit_inputs(registration_contract, w3, assert_tx_failed, amount,
                        invalid_pubkey, invalid_withdrawal_credentials,
                        invalid_signature, success):
    pubkey = SAMPLE_PUBKEY[2:] if invalid_pubkey else SAMPLE_PUBKEY
    withdrawal_credentials = (SAMPLE_WITHDRAWAL_CREDENTIALS[2:]
                              if invalid_withdrawal_credentials else
                              SAMPLE_WITHDRAWAL_CREDENTIALS)
    signature = SAMPLE_VALID_SIGNATURE[
        2:] if invalid_signature else SAMPLE_VALID_SIGNATURE

    call = registration_contract.functions.deposit(
        pubkey, withdrawal_credentials, signature,
        hash_tree_root(
            DepositData(
                pubkey=SAMPLE_PUBKEY if invalid_pubkey else pubkey,
                withdrawal_credentials=(SAMPLE_WITHDRAWAL_CREDENTIALS
                                        if invalid_withdrawal_credentials else
                                        withdrawal_credentials),
                amount=amount,
                signature=SAMPLE_VALID_SIGNATURE
                if invalid_signature else signature,
            ), ))
    if success:
        assert call.transact({"value": amount * eth_utils.denoms.gwei})
    else:
        assert_tx_failed(
            lambda: call.transact({"value": amount * eth_utils.denoms.gwei}))
예제 #6
0
def build_deposit_data(state, pubkey, privkey, amount):
    deposit_data = DepositData(
        pubkey=pubkey,
        # insecurely use pubkey as withdrawal key as well
        withdrawal_credentials=spec.BLS_WITHDRAWAL_PREFIX_BYTE +
        hash(pubkey)[1:],
        amount=amount,
    )
    signature = bls.sign(message_hash=signing_root(deposit_data),
                         privkey=privkey,
                         domain=get_domain(
                             state,
                             spec.DOMAIN_DEPOSIT,
                         ))
    deposit_data.signature = signature
    return deposit_data
예제 #7
0
def deposit_data_root(deposit_message, signature):
    deposit_data = DepositData(
        pubkey=deposit_message.pubkey,
        withdrawal_credentials=deposit_message.withdrawal_credentials,
        amount=deposit_message.amount,
        signature=signature,
    )
    root = hash_tree_root(deposit_data)
    return root
예제 #8
0
def build_deposit_data(state, pubkey, privkey, amount, signed=False):
    deposit_data = DepositData(
        pubkey=pubkey,
        # insecurely use pubkey as withdrawal key as well
        withdrawal_credentials=spec.BLS_WITHDRAWAL_PREFIX_BYTE + spec.hash(pubkey)[1:],
        amount=amount,
    )
    if signed:
        sign_deposit_data(state, deposit_data, privkey)
    return deposit_data
def deposit_input(amount):
    """
    pubkey: bytes[48]
    withdrawal_credentials: bytes[32]
    signature: bytes[96]
    deposit_data_root: bytes[32]
    """
    return (SAMPLE_PUBKEY, SAMPLE_WITHDRAWAL_CREDENTIALS,
            SAMPLE_VALID_SIGNATURE,
            hash_tree_root(
                DepositData(
                    pubkey=SAMPLE_PUBKEY,
                    withdrawal_credentials=SAMPLE_WITHDRAWAL_CREDENTIALS,
                    amount=amount,
                    signature=SAMPLE_VALID_SIGNATURE,
                ), ))
def test_deposit_tree(registration_contract, w3, assert_tx_failed):
    log_filter = registration_contract.events.DepositEvent.createFilter(
        fromBlock='latest', )

    deposit_amount_list = [
        randint(MIN_DEPOSIT_AMOUNT, FULL_DEPOSIT_AMOUNT * 2) for _ in range(10)
    ]
    deposit_data_list = []
    for i in range(0, 10):
        deposit_data = DepositData(
            pubkey=SAMPLE_PUBKEY,
            withdrawal_credentials=SAMPLE_WITHDRAWAL_CREDENTIALS,
            amount=deposit_amount_list[i],
            signature=SAMPLE_VALID_SIGNATURE,
        )
        deposit_input = (
            SAMPLE_PUBKEY,
            SAMPLE_WITHDRAWAL_CREDENTIALS,
            SAMPLE_VALID_SIGNATURE,
            hash_tree_root(deposit_data),
        )
        deposit_data_list.append(deposit_data)

        tx_hash = registration_contract.functions.deposit(
            *deposit_input, ).transact(
                {"value": deposit_amount_list[i] * eth_utils.denoms.gwei})
        receipt = w3.eth.getTransactionReceipt(tx_hash)
        print("deposit transaction consumes %d gas" % receipt['gasUsed'])

        logs = log_filter.get_new_entries()
        assert len(logs) == 1
        log = logs[0]['args']

        assert log["index"] == i.to_bytes(8, 'little')

        # Check deposit count and root
        count = len(deposit_data_list).to_bytes(8, 'little')
        assert count == registration_contract.functions.get_deposit_count(
        ).call()
        root = hash_tree_root(List[DepositData, 2**32](*deposit_data_list))
        assert root == registration_contract.functions.get_deposit_root().call(
        )
예제 #11
0
    'b12af968a0f2b6f55b448dd395a3cc2a88b07f902cbddc1ec735dde573c6cad67c099241c50ce9e856a7a2c6ef3f8f08105d3ed5227bcee0356d3a471748bcd445c4f4471d540b3049fa324d519b0bd13e16dbcb340ebc90f165f005fa81ff7d'
)
deposit_root = Root(
    'ba066d557b3b27a55ae129f01c569dff5daa9ca8a3e45f13188dcb1ac01cb1c5')

fork_version = Version('0x00000001')

deposit_message = DepositMessage(
    pubkey=pubkey,
    withdrawal_credentials=withdrawal_creds,
    amount=amount,
)
domain = compute_domain(domain_type=DOMAIN_DEPOSIT, fork_version=fork_version)
signing_root = compute_signing_root(deposit_message, domain)

if bls.Verify(pubkey, signing_root, signature):
    print("GOOD signature")
else:
    print("BAD signature")

deposit_data = DepositData(
    pubkey=pubkey,
    withdrawal_credentials=withdrawal_creds,
    amount=amount,
    signature=signature,
)
if deposit_data.hash_tree_root() == deposit_root:
    print("GOOD deposit root")
else:
    print("BAD deposit root")