def test_rejects_invalid_signature(chain,
                                   web3,
                                   token_v2,
                                   token_v1_owner,
                                   token_id,
                                   get_mint_data,
                                   eth_sign):
    assert token_v2.call().balanceOf(token_v1_owner) == 1
    assert token_v2.call().upgradeCount() == 0
    assert token_v2.call().isTokenUpgraded(token_id) is False

    new_owner = web3.eth.accounts[3]

    signature_data = b''.join((
        decode_hex(token_v2.address),
        decode_hex(token_v1_owner),
        decode_hex(new_owner),
    ))
    signature = eth_sign(web3.eth.coinbase, signature_data)

    upgrade_txn_hash = token_v2.transact({
        'from': web3.eth.coinbase,
    }).proxyUpgrade(token_v1_owner, new_owner, signature)
    chain.wait.for_receipt(upgrade_txn_hash)

    with pytest.raises(AssertionError):
        get_mint_data(upgrade_txn_hash)

    assert token_v2.call().upgradeCount() == 0
    assert token_v2.call().isTokenUpgraded(token_id) is False
def test_rejects_already_upgraded_token(chain,
                                        web3,
                                        token_v2,
                                        token_v1_owner,
                                        upgraded_token,
                                        get_mint_data,
                                        eth_sign):
    new_owner = web3.eth.accounts[3]

    assert token_v2.call().balanceOf(token_v1_owner) == 1
    assert token_v2.call().isTokenUpgraded(upgraded_token) is True
    assert token_v2.call().isTokenOwner(new_owner) is False

    signature_data = b''.join((
        decode_hex(token_v2.address),
        decode_hex(token_v1_owner),
        decode_hex(new_owner),
    ))
    signature = eth_sign(token_v1_owner, signature_data)

    upgrade_txn_hash = token_v2.transact({
        'from': web3.eth.coinbase,
    }).proxyUpgrade(token_v1_owner, new_owner, signature)
    chain.wait.for_receipt(upgrade_txn_hash)

    with pytest.raises(AssertionError):
        get_mint_data(upgrade_txn_hash)

    assert token_v2.call().isTokenOwner(new_owner) is False
def test_proxy_upgrade_same_owner(chain,
                                  web3,
                                  token_v2,
                                  token_v1_owner,
                                  token_id,
                                  get_mint_data,
                                  eth_sign):
    assert token_v2.call().balanceOf(token_v1_owner) == 1
    assert token_v2.call().upgradeCount() == 0
    assert token_v2.call().isTokenUpgraded(token_id) is False

    signature_data = b''.join((
        decode_hex(token_v2.address),
        decode_hex(token_v1_owner),
        decode_hex(token_v1_owner),
    ))
    signature = eth_sign(token_v1_owner, signature_data)

    upgrade_txn_hash = token_v2.transact({
        'from': web3.eth.coinbase,
    }).proxyUpgrade(token_v1_owner, token_v1_owner, signature)
    chain.wait.for_receipt(upgrade_txn_hash)

    mint_data = get_mint_data(upgrade_txn_hash)

    assert token_v2.call().upgradeCount() == 1
    assert token_v2.call().isTokenUpgraded(token_id) is True
    assert mint_data['args']['_owner'] == token_v1_owner
    assert mint_data['args']['_tokenID'] == token_id
    assert mint_data['address'] == token_v2.address
def test_rejects_if_new_owner_is_null_address(chain,
                                              web3,
                                              token_v2,
                                              token_v1_owner,
                                              token_id,
                                              other_token_v1_owner,
                                              get_mint_data,
                                              NULL_ADDRESS,
                                              eth_sign):
    assert token_v2.call().isTokenUpgraded(token_id) is False

    signature_data = b''.join((
        decode_hex(token_v2.address),
        decode_hex(token_v1_owner),
        decode_hex(NULL_ADDRESS),
    ))
    signature = eth_sign(token_v1_owner, signature_data)

    upgrade_txn_hash = token_v2.transact({
        'from': web3.eth.coinbase,
    }).proxyUpgrade(token_v1_owner, other_token_v1_owner, signature)
    chain.wait.for_receipt(upgrade_txn_hash)

    with pytest.raises(AssertionError):
        get_mint_data(upgrade_txn_hash)

    assert token_v2.call().isTokenUpgraded(token_id) is False
Exemplo n.º 5
0
def test_miner_setExtra(web3_empty, wait_for_block):
    web3 = web3_empty

    initial_extra = decode_hex(
        web3.eth.getBlock(web3.eth.blockNumber)['extraData'])

    new_extra_data = b'-this-is-32-bytes-of-extra-data-'

    # sanity
    assert initial_extra != new_extra_data

    web3.miner.setExtra(new_extra_data)

    with gevent.Timeout(60):
        while True:
            extra_data = decode_hex(
                web3.eth.getBlock(web3.eth.blockNumber)['extraData'])
            if extra_data == new_extra_data:
                break
            gevent.sleep(random.random())

    after_extra = decode_hex(
        web3.eth.getBlock(web3.eth.blockNumber)['extraData'])

    assert after_extra == new_extra_data
def test_txn_request_for_txn_that_throw_exception(chain, web3,
                                                  get_execute_data,
                                                  RequestData,
                                                  error_generator):
    txn_request = RequestData(createdBy=error_generator.address,
                              donation=12345,
                              toAddress=error_generator.address,
                              callData=decode_hex(
                                  error_generator._encode_transaction_data(
                                      'doThrow'))).direct_deploy()

    request_data = RequestData.from_contract(txn_request)
    chain.wait.for_block(request_data.schedule.windowStart)

    execute_txn_hash = txn_request.transact({
        'from': web3.eth.accounts[1],
        'gas': 3000000,
    }).execute()
    execute_txn_receipt = chain.wait.for_receipt(execute_txn_hash)

    execute_data = get_execute_data(execute_txn_hash)
    request_data = RequestData.from_contract(txn_request)

    assert request_data.meta.wasCalled is True
    assert request_data.meta.wasSuccessful is False

    gas_used = execute_txn_receipt['gasUsed']
    measured_gas_consumption = execute_data['args']['measuredGasConsumption']

    assert measured_gas_consumption > gas_used
    assert measured_gas_consumption - gas_used < 120000
Exemplo n.º 7
0
    def request_blocking(self, method, params):
        if method == 'eth_sendTransaction':
            base_transaction = params[0]
            # create a fully signed transaction and send through the
            # `eth_sendRawTransaction` endpoint instead.
            full_transaction = self.construct_full_transaction(base_transaction)
            raw_transaction_bytes = self.sign_and_serialize_transaction(
                full_transaction,
            )
            raw_transaction_bytes_as_hex = encode_hex(raw_transaction_bytes)
            return self.request_blocking(
                'eth_sendRawTransaction', [raw_transaction_bytes_as_hex],
            )

        result = super(BaseSendRawTransactionMixin, self).request_blocking(
            method, params,
        )
        if method in self.TXN_SENDING_METHODS:
            if method == 'eth_sendRawTransaction':
                txn = rlp.decode(decode_hex(params[0]), Transaction)
                self._known_transactions[to_address(txn.sender)].add(result)
                self._known_nonces[to_address(txn.sender)].add(txn.nonce)
            else:
                txn = params[0]
                self._known_transactions[to_address(txn['from'])].add(result)
                if 'nonce' in txn:
                    self._known_nonces[to_address(txn['from'])].add(
                        to_decimal(txn['nonce'])
                    )
        return result
Exemplo n.º 8
0
    def request_blocking(self, method, params):
        if method == 'eth_sendTransaction':
            base_transaction = params[0]
            # create a fully signed transaction and send through the
            # `eth_sendRawTransaction` endpoint instead.
            full_transaction = self.construct_full_transaction(base_transaction)
            raw_transaction_bytes = self.sign_and_serialize_transaction(
                full_transaction,
            )
            raw_transaction_bytes_as_hex = encode_hex(raw_transaction_bytes)
            return self.request_blocking(
                'eth_sendRawTransaction', [raw_transaction_bytes_as_hex],
            )
 
        result = super(BaseSendRawTransactionMixin, self).request_blocking(
            method, params,
        )
        if method in self.TXN_SENDING_METHODS:
            if method == 'eth_sendRawTransaction':
                txn = rlp.decode(decode_hex(params[0]), Transaction)
                self._known_transactions[to_address(txn.sender)].add(result)
                self._known_nonces[to_address(txn.sender)].add(txn.nonce)
            else:
                txn = params[0]
                self._known_transactions[to_address(txn['from'])].add(result)
                if 'nonce' in txn:
                    self._known_nonces[to_address(txn['from'])].add(
                        to_decimal(txn['nonce'])
                    )
        return result
def test_proxy_execution_accepted_at_minimum_gas(chain, RequestData, proxy,
                                                 txn_recorder, request_lib,
                                                 execution_lib,
                                                 get_execute_data,
                                                 get_abort_data, AbortReasons):
    txn_request = RequestData(
        toAddress=txn_recorder.address,
        callGas=100000,
    ).direct_deploy()
    request_data = RequestData.from_contract(txn_request)

    assert txn_recorder.call().wasCalled() is False

    chain.wait.for_block(request_data.schedule.windowStart)

    minimum_call_gas = (request_data.txnData.callGas +
                        request_lib.call().EXECUTION_GAS_OVERHEAD() +
                        execution_lib.call().GAS_PER_DEPTH() *
                        request_data.txnData.requiredStackDepth)

    call_data_hex = txn_request._encode_transaction_data('execute')
    execute_txn_hash = proxy.transact({
        'gas': 3000000
    }).__proxy(
        to=txn_request.address,
        callData=decode_hex(call_data_hex),
        callGas=minimum_call_gas,
    )
    chain.wait.for_receipt(execute_txn_hash)

    request_data.refresh()

    assert get_execute_data(execute_txn_hash)
    assert txn_recorder.call().wasCalled() is True
    assert request_data.meta.wasCalled is True
Exemplo n.º 10
0
def test_dynamic_length_argument_extraction(web3, emitter,
                                            wait_for_transaction,
                                            emitter_log_topics,
                                            emitter_event_ids):
    string_0 = "this-is-the-first-string-which-exceeds-32-bytes-in-length"
    string_1 = "this-is-the-second-string-which-exceeds-32-bytes-in-length"
    txn_hash = emitter.transact().logDynamicArgs(string_0, string_1)
    txn_receipt = wait_for_transaction(web3, txn_hash)

    assert len(txn_receipt['logs']) == 1
    log_entry = txn_receipt['logs'][0]

    event_abi = emitter._find_matching_event_abi('LogDynamicArgs')

    event_topic = emitter_log_topics.LogDynamicArgs
    assert event_topic in log_entry['topics']

    string_0_topic = web3.sha3(string_0, encoding='utf8')
    assert string_0_topic in log_entry['topics']

    event_data = get_event_data(event_abi, log_entry)

    expected_args = {
        "arg0": force_text(decode_hex(string_0_topic)),
        "arg1": string_1,
    }

    assert event_data['args'] == expected_args
    assert event_data['blockHash'] == txn_receipt['blockHash']
    assert event_data['blockNumber'] == txn_receipt['blockNumber']
    assert event_data['transactionIndex'] == txn_receipt['transactionIndex']
    assert event_data['address'] == emitter.address
    assert event_data['event'] == 'LogDynamicArgs'
Exemplo n.º 11
0
def test_adding_signature_to_transaction(wait_for_first_block, web3,
                                         skip_if_testrpc):
    skip_if_testrpc(web3)

    transaction = {
        'nonce': hex(0),
        'to': '0xd3cda913deb6f67967b99d67acdfa1712c293601',
        'value': hex(12345),
        'gas': hex(1200300),
        'gasPrice': hex(54321),
        'data': '0x1234567890abcdef',
    }

    serialized_txn = serialize_transaction(transaction)
    signature_hex = web3.eth.sign(web3.eth.coinbase, serialized_txn)

    signed_transaction = add_signature_to_transaction(
        serialized_txn,
        decode_hex(signature_hex),
    )

    assert to_address(signed_transaction.to) == transaction['to']
    assert signed_transaction.startgas == int(transaction['gas'], 16)
    assert signed_transaction.gasprice == int(transaction['gasPrice'], 16)
    assert signed_transaction.nonce == int(transaction['nonce'], 16)
    assert signed_transaction.value == int(transaction['value'], 16)
    assert encode_hex(signed_transaction.data) == transaction['data']
    assert signed_transaction.sender == web3.eth.coinbase
def test_adding_signature_to_transaction(wait_for_first_block,
                                         web3,
                                         skip_if_testrpc):
    skip_if_testrpc(web3)

    transaction = {
        'nonce': hex(0),
        'to': '0xd3cda913deb6f67967b99d67acdfa1712c293601',
        'value': hex(12345),
        'gas': hex(1200300),
        'gasPrice': hex(54321),
        'data': '0x1234567890abcdef',
    }

    serialized_txn = serialize_transaction(transaction)
    signature_hex = web3.eth.sign(web3.eth.coinbase, serialized_txn)

    signed_transaction = add_signature_to_transaction(
        serialized_txn,
        decode_hex(signature_hex),
    )

    assert to_address(signed_transaction.to) == transaction['to']
    assert signed_transaction.startgas == int(transaction['gas'], 16)
    assert signed_transaction.gasprice == int(transaction['gasPrice'], 16)
    assert signed_transaction.nonce == int(transaction['nonce'], 16)
    assert signed_transaction.value == int(transaction['value'], 16)
    assert encode_hex(signed_transaction.data) == transaction['data']
    assert signed_transaction.sender == web3.eth.coinbase
def test_txn_request_for_txn_that_throw_exception(chain,
                                                  web3,
                                                  get_execute_data,
                                                  RequestData,
                                                  error_generator):
    txn_request = RequestData(
        createdBy=error_generator.address,
        donation=12345,
        toAddress=error_generator.address,
        callData=decode_hex(error_generator._encode_transaction_data('doThrow'))
    ).direct_deploy()

    request_data = RequestData.from_contract(txn_request)
    chain.wait.for_block(request_data.schedule.windowStart)

    execute_txn_hash = txn_request.transact({
        'from': web3.eth.accounts[1],
        'gas': 3000000,
    }).execute()
    execute_txn_receipt = chain.wait.for_receipt(execute_txn_hash)

    execute_data = get_execute_data(execute_txn_hash)
    request_data = RequestData.from_contract(txn_request)

    assert request_data.meta.wasCalled is True
    assert request_data.meta.wasSuccessful is False

    gas_used = execute_txn_receipt['gasUsed']
    measured_gas_consumption = execute_data['args']['measuredGasConsumption']

    assert measured_gas_consumption > gas_used
    assert measured_gas_consumption - gas_used < 120000
Exemplo n.º 14
0
def test_private_key_signing_manager(web3_pk_signer, account_private_key,
                                     account_public_key, wait_for_transaction):
    web3 = web3_pk_signer
    assert account_public_key not in web3_pk_signer.eth.accounts

    with pytest.raises(ValueError):
        web3.eth.sendTransaction({
            'from': account_public_key,
            'to': web3.eth.coinbase,
            'value': 1,
        })

    from ethereum import tester
    tester.keys.append(account_private_key)
    tester.accounts.append(decode_hex(account_public_key))

    txn_hash = web3.eth.sendTransaction({
        'from': account_public_key,
        'to': web3.eth.coinbase,
        'value': 1,
    })
    txn_receipt = wait_for_transaction(web3, txn_hash)
    txn = web3.eth.getTransaction(txn_hash)

    assert txn['from'] == account_public_key
def extract_ecdsa_signer(msg_hash, signature):
    msg_hash_bytes = decode_hex(msg_hash) if msg_hash.startswith(b'0x') else msg_hash
    signature_bytes = decode_hex(signature) if signature.startswith(b'0x') else signature

    pk = PublicKey(flags=ALL_FLAGS)
    rec_id = signature_bytes[64]
    if is_string(rec_id):
        rec_id = ord(rec_id)
    pk.public_key = pk.ecdsa_recover(
        msg_hash_bytes,
        pk.ecdsa_recoverable_deserialize(
            signature_bytes[:64], rec_id,
        ),
        raw=True,
    )
    pk_serialized = pk.serialize(compressed=False)
    address = add_0x_prefix(sha3(encode_pubkey(pk_serialized, 'bin')[1:])[-40:])
    return address
Exemplo n.º 16
0
def extract_ecdsa_signer(msg_hash, signature):
    msg_hash_bytes = decode_hex(msg_hash) if msg_hash.startswith(b'0x') else msg_hash
    signature_bytes = decode_hex(signature) if signature.startswith(b'0x') else signature

    pk = PublicKey(flags=ALL_FLAGS)
    rec_id = signature_bytes[64]
    if is_string(rec_id):
        rec_id = ord(rec_id)
    pk.public_key = pk.ecdsa_recover(
        msg_hash_bytes,
        pk.ecdsa_recoverable_deserialize(
            signature_bytes[:64], rec_id,
        ),
        raw=True,
    )
    pk_serialized = pk.serialize(compressed=False)
    address = add_0x_prefix(sha3(encode_pubkey(pk_serialized, 'bin')[1:])[-40:])
    return address
Exemplo n.º 17
0
def unknown_token_id(token_v1, web3):
    token = token_v1
    unknown_token_id = decode_hex(web3.sha3(encode_hex('Hudson James')))

    assert unknown_token_id == sha3_256(b'Hudson James').digest()
    assert token.call().identityOf(unknown_token_id) == ''
    assert token.call().ownerOf(
        unknown_token_id) == '0x0000000000000000000000000000000000000000'

    return unknown_token_id
Exemplo n.º 18
0
def test_miner_setExtra(web3_empty, wait_for_block):
    web3 = web3_empty

    initial_extra = decode_hex(web3.eth.getBlock(web3.eth.blockNumber)['extraData'])

    new_extra_data = b'-this-is-32-bytes-of-extra-data-'

    # sanity
    assert initial_extra != new_extra_data

    web3.miner.setExtra(new_extra_data)

    with gevent.Timeout(60):
        while True:
            extra_data = decode_hex(web3.eth.getBlock(web3.eth.blockNumber)['extraData'])
            if extra_data == new_extra_data:
                break
            gevent.sleep(random.random())

    after_extra = decode_hex(web3.eth.getBlock(web3.eth.blockNumber)['extraData'])

    assert after_extra == new_extra_data
Exemplo n.º 19
0
def set_can_call(chain, authority, caller_address, code_address, can_call,
                 function_signature):
    sig_as_hex = function_signature_to_4byte_selector(function_signature)
    sig_as_bytes = decode_hex(sig_as_hex)

    can_already_call = authority.call().canCall(
        callerAddress=caller_address,
        codeAddress=code_address,
        sig=sig_as_bytes,
    )
    if can_already_call:
        click.echo(
            "Permissions already set for: {0}".format(function_signature))
        return

    click.echo("Setting up permissions for:\n"
               "- function: {0}\n"
               "- sig: {1}\n"
               "- caller_address: {2}\n"
               "- code_address: {3}\n"
               "- can_call: {4}".format(
                   function_signature,
                   sig_as_hex,
                   caller_address,
                   code_address,
                   ("Yes" if can_call else "No"),
               ))
    click.echo("Sending authorization transaction... ", nl=False)
    authorize_txn_hash = authority.transact().setCanCall(
        callerAddress=caller_address,
        codeAddress=code_address,
        sig=sig_as_bytes,
        can=can_call,
    )
    click.echo("SENT")
    click.echo("Authorize Transaction Hash: {0}".format(authorize_txn_hash))
    click.echo("Waiting for transaction to be mined... ", nl=False)
    chain.wait.for_receipt(authorize_txn_hash, timeout=600)
    click.echo("MINED")

    check_can_call = authority.call().canCall(
        callerAddress=caller_address,
        codeAddress=code_address,
        sig=sig_as_bytes,
    )
    if check_can_call is not can_call:
        click.echo("Something went wrong.  Authorization did not go though")
        import pdb
        pdb.set_trace()
        raise ValueError("Failed to set authorization")
    return
def test_txn_request_when_everything_throws(chain,
                                            web3,
                                            get_execute_data,
                                            RequestData,
                                            error_generator):
    txn_request = RequestData(
        createdBy=error_generator.address,
        owner=error_generator.address,
        donationBenefactor=error_generator.address,
        toAddress=error_generator.address,
        callData=decode_hex(error_generator._encode_transaction_data('doThrow'))
    ).direct_deploy()

    request_data = RequestData.from_contract(txn_request)
    chain.wait.for_block(request_data.schedule.windowStart)

    proxy_call_data = decode_hex(txn_request._encode_transaction_data('execute'))

    execute_txn_hash = error_generator.transact({
        'from': web3.eth.accounts[1],
        'gas': 3000000,
    }).__proxy(
        to=txn_request.address,
        callData=proxy_call_data,
    )
    execute_txn_receipt = chain.wait.for_receipt(execute_txn_hash)

    execute_data = get_execute_data(execute_txn_hash)
    request_data = RequestData.from_contract(txn_request)

    assert request_data.meta.wasCalled is True
    assert request_data.meta.wasSuccessful is False

    gas_used = execute_txn_receipt['gasUsed']
    measured_gas_consumption = execute_data['args']['measuredGasConsumption']

    assert measured_gas_consumption > gas_used
    assert measured_gas_consumption - gas_used < 50000
Exemplo n.º 21
0
 def get_transaction_signature(self, transaction):
     serialized_txn = serialize_transaction(transaction)
     hash_to_sign = self.signing_manager.request_blocking(
         'web3_sha3', [encode_hex(serialized_txn)],
     )
     signature_hex = self.signing_manager.request_blocking(
         'eth_sign',
         [
             transaction['from'],
             hash_to_sign,
         ],
     )
     signature = decode_hex(signature_hex)
     return signature
    def _set_timestamp(timestamp):
        evm.block.finalize()
        evm.block.commit_state()
        evm.db.put(evm.block.hash, rlp.encode(evm.block))

        block = blocks.Block.init_from_parent(
            evm.block,
            decode_hex(web3.eth.coinbase),
            timestamp=timestamp,
        )

        evm.block = block
        evm.blocks.append(evm.block)
        return timestamp
Exemplo n.º 23
0
    def _set_timestamp(timestamp):
        evm.block.finalize()
        evm.block.commit_state()
        evm.db.put(evm.block.hash, rlp.encode(evm.block))

        block = blocks.Block.init_from_parent(
            evm.block,
            decode_hex(web3.eth.coinbase),
            timestamp=timestamp,
        )

        evm.block = block
        evm.blocks.append(evm.block)
        return timestamp
Exemplo n.º 24
0
 def get_transaction_signature(self, transaction):
     serialized_txn = serialize_transaction(transaction)
     hash_to_sign = self.signing_manager.request_blocking(
         'web3_sha3', [encode_hex(serialized_txn)],
     )
     signature_hex = self.signing_manager.request_blocking(
         'eth_sign',
         [
             transaction['from'],
             hash_to_sign,
         ],
     )
     signature = decode_hex(signature_hex)
     return signature
def test_txn_request_when_everything_throws(chain, web3, get_execute_data,
                                            RequestData, error_generator):
    txn_request = RequestData(createdBy=error_generator.address,
                              owner=error_generator.address,
                              donationBenefactor=error_generator.address,
                              toAddress=error_generator.address,
                              callData=decode_hex(
                                  error_generator._encode_transaction_data(
                                      'doThrow'))).direct_deploy()

    request_data = RequestData.from_contract(txn_request)
    chain.wait.for_block(request_data.schedule.windowStart)

    proxy_call_data = decode_hex(
        txn_request._encode_transaction_data('execute'))

    execute_txn_hash = error_generator.transact({
        'from': web3.eth.accounts[1],
        'gas': 3000000,
    }).__proxy(
        to=txn_request.address,
        callData=proxy_call_data,
    )
    execute_txn_receipt = chain.wait.for_receipt(execute_txn_hash)

    execute_data = get_execute_data(execute_txn_hash)
    request_data = RequestData.from_contract(txn_request)

    assert request_data.meta.wasCalled is True
    assert request_data.meta.wasSuccessful is False

    gas_used = execute_txn_receipt['gasUsed']
    measured_gas_consumption = execute_data['args']['measuredGasConsumption']

    assert measured_gas_consumption > gas_used
    assert measured_gas_consumption - gas_used < 50000
    def _inner_sign(account, data_to_sign):
        signature_hash_hex = web3.sha3(encode_hex(data_to_sign))
        signature_hash_bytes = decode_hex(signature_hash_hex)

        private_key = tester.keys[tester.accounts.index(decode_hex(account))]
        priv_key = PrivateKey(flags=ALL_FLAGS)
        priv_key.set_raw_privkey(private_key)

        signature_raw = priv_key.ecdsa_sign_recoverable(
            signature_hash_bytes,
            raw=True,
            digest=sha3_256,
        )
        signature_bytes, rec_id = priv_key.ecdsa_recoverable_serialize(signature_raw)
        signature = signature_bytes + force_bytes(chr(rec_id))

        # Sanity check that the signature is valid.
        signer_address = force_text(extract_ecdsa_signer(
            signature_hash_bytes,
            signature,
        ))

        assert signer_address == account
        return signature
Exemplo n.º 27
0
 def sign_and_serialize_transaction(self, transaction):
     txn_from = to_address(transaction['from'])
     if txn_from not in self.keys:
         raise KeyError("No signing key registered for from address: {0}".format(txn_from))
     transaction = Transaction(
         nonce=to_decimal(transaction['nonce']),
         gasprice=to_decimal(transaction['gasPrice']),
         startgas=to_decimal(transaction['gas']),
         to=transaction['to'],
         value=to_decimal(transaction['value']),
         data=decode_hex(transaction['data']),
     )
     transaction.sign(self.keys[txn_from])
     assert to_address(transaction.sender) == txn_from
     return rlp.encode(transaction, Transaction)
Exemplo n.º 28
0
 def sign_and_serialize_transaction(self, transaction):
     txn_from = to_address(transaction['from'])
     if txn_from not in self.keys:
         raise KeyError("No signing key registered for from address: {0}".format(txn_from))
     transaction = Transaction(
         nonce=to_decimal(transaction['nonce']),
         gasprice=to_decimal(transaction['gasPrice']),
         startgas=to_decimal(transaction['gas']),
         to=transaction['to'],
         value=to_decimal(transaction['value']),
         data=decode_hex(transaction['data']),
     )
     transaction.sign(self.keys[txn_from])
     assert to_address(transaction.sender) == txn_from
     return rlp.encode(transaction, Transaction)
Exemplo n.º 29
0
 def _whitelist_call(code_address, function_signature, can_call):
     sig = decode_hex(
         function_signature_to_4byte_selector(function_signature))
     chain.wait.for_receipt(
         authority.transact({
             'from': authority.call().owner(),
         }).setAnyoneCanCall(
             codeAddress=code_address,
             sig=sig,
             can=can_call,
         ))
     assert authority.call().canCall(
         '0x0000000000000000000000000000000000000000',
         codeAddress=code_address,
         sig=sig,
     ) is can_call
Exemplo n.º 30
0
def outputPostFormatter(post):
    """
    Formats the output of a received post message
    """

    post["expiry"] = to_decimal(post["expiry"])
    post["sent"] = to_decimal(post["sent"])
    post["ttl"] = to_decimal(post["ttl"])
    post["workProved"] = to_decimal(post["workProved"])

    if not post.get("topics"):
        post["topics"] = []

    post["topics"] = [decode_hex(topic) for topic in post["topics"]]

    return post
Exemplo n.º 31
0
def outputPostFormatter(post):
    """
    Formats the output of a received post message
    """

    post["expiry"] = to_decimal(post["expiry"])
    post["sent"] = to_decimal(post["sent"])
    post["ttl"] = to_decimal(post["ttl"])
    post["workProved"] = to_decimal(post["workProved"])

    if not post.get("topics"):
        post["topics"] = []

    post["topics"] = [decode_hex(topic) for topic in post["topics"]]

    return post
Exemplo n.º 32
0
 def _authorize_call(caller_address, code_address, function_signature,
                     can_call):
     sig = decode_hex(
         function_signature_to_4byte_selector(function_signature))
     chain.wait.for_receipt(
         authority.transact({
             'from': authority.call().authority(),
         }).setCanCall(
             callerAddress=caller_address,
             codeAddress=code_address,
             sig=sig,
             can=can_call,
         ))
     assert authority.call().canCall(
         callerAddress=caller_address,
         codeAddress=code_address,
         sig=sig,
     ) is can_call
def test_proxy_execution_rejected_for_insufficient_gas(chain,
                                                       RequestData,
                                                       proxy,
                                                       txn_recorder,
                                                       request_lib,
                                                       execution_lib,
                                                       get_execute_data,
                                                       get_abort_data,
                                                       AbortReasons):
    txn_request = RequestData(
        toAddress=txn_recorder.address,
        callGas=100000,
    ).direct_deploy()
    request_data = RequestData.from_contract(txn_request)

    assert txn_recorder.call().wasCalled() is False

    chain.wait.for_block(request_data.schedule.windowStart)

    minimum_call_gas = (
        request_data.txnData.callGas +
        request_lib.call().EXECUTION_GAS_OVERHEAD() +
        execution_lib.call().GAS_PER_DEPTH() * request_data.txnData.requiredStackDepth
    )
    too_low_call_gas = minimum_call_gas - request_lib.call().PRE_EXECUTION_GAS()

    call_data_hex = txn_request._encode_transaction_data('execute')
    execute_txn_hash = proxy.transact({'gas': 3000000}).__proxy(
        to=txn_request.address,
        callData=decode_hex(call_data_hex),
        callGas=too_low_call_gas,
    )
    chain.wait.for_receipt(execute_txn_hash)

    assert txn_recorder.call().wasCalled() is False
    assert request_data.meta.wasCalled is False

    with pytest.raises(AssertionError):
        get_execute_data(execute_txn_hash)

    abort_data = get_abort_data(execute_txn_hash)
    reasons = {entry['args']['reason'] for entry in abort_data}
    assert AbortReasons.InsufficientGas in reasons
Exemplo n.º 34
0
def generate_registrar_value_setters(receipt, prefix=None):
    if prefix is None:
        prefix = []

    if is_string(prefix):
        prefix = [prefix]

    if isinstance(receipt, RegistrarValue):
        raise ValueError("Receipt should not be instantiated at this point")
    elif is_hex_address(receipt):
        # Special case for addresses
        return [
            Address.defer(key='/'.join(prefix), value=receipt)
        ]
    elif is_hex_transaction_hash(receipt):
        # Special case for transaction hashes and addresses.
        return [
            Bytes32.defer(key='/'.join(prefix), value=decode_hex(receipt))
        ]
    elif isinstance(receipt, type) and issubclass(receipt, RegistrarValue):
        return [
            receipt.defer(
                key=receipt.key or '/'.join(prefix),
                value_type=receipt.value_type,
                value=receipt.value,
            )
        ]
    elif isinstance(receipt, dict):
        return list(itertools.chain.from_iterable([
            generate_registrar_value_setters(value, prefix + [key])
            for key, value in receipt.items()
        ]))
    elif isinstance(receipt, (list, tuple)):
        return list(itertools.chain.from_iterable([
            generate_registrar_value_setters(value, prefix + [str(index)])
            for index, value in enumerate(receipt)
        ]))
    else:
        raise ValueError(
            "Invalid type.  Must be one of transaction hash, address, "
            "ReceiptValue, dict, or list"
        )
def test_execution_rejected_if_stack_too_deep(chain,
                                              web3,
                                              RequestData,
                                              txn_recorder,
                                              digger_proxy,
                                              get_execute_data,
                                              get_abort_data,
                                              AbortReasons):
    txn_request = RequestData(
        toAddress=txn_recorder.address,
        requiredStackDepth=1000,
    ).direct_deploy()
    request_data = RequestData.from_contract(txn_request)

    assert txn_recorder.call().wasCalled() is False
    assert request_data.meta.wasCalled is False
    assert request_data.txnData.requiredStackDepth == 1000

    chain.wait.for_block(request_data.schedule.windowStart)

    execute_call_data = decode_hex(txn_request._encode_transaction_data('execute'))

    execute_txn_hash = digger_proxy.transact({'gas': 3000000}).__dig_then_proxy(
        24,
        txn_request.address,
        execute_call_data,
    )
    chain.wait.for_receipt(execute_txn_hash)

    request_data.refresh()

    assert digger_proxy.call().result() is True
    assert txn_recorder.call().wasCalled() is False
    assert request_data.meta.wasCalled is False

    with pytest.raises(AssertionError):
        get_execute_data(execute_txn_hash)

    abort_data = get_abort_data(execute_txn_hash)
    reasons = {entry['args']['reason'] for entry in abort_data}
    assert AbortReasons.StackTooDeep in reasons
def test_proxy_execution_rejected_for_insufficient_gas(
        chain, RequestData, proxy, txn_recorder, request_lib, execution_lib,
        get_execute_data, get_abort_data, AbortReasons):
    txn_request = RequestData(
        toAddress=txn_recorder.address,
        callGas=100000,
    ).direct_deploy()
    request_data = RequestData.from_contract(txn_request)

    assert txn_recorder.call().wasCalled() is False

    chain.wait.for_block(request_data.schedule.windowStart)

    minimum_call_gas = (request_data.txnData.callGas +
                        request_lib.call().EXECUTION_GAS_OVERHEAD() +
                        execution_lib.call().GAS_PER_DEPTH() *
                        request_data.txnData.requiredStackDepth)
    too_low_call_gas = minimum_call_gas - request_lib.call().PRE_EXECUTION_GAS(
    )

    call_data_hex = txn_request._encode_transaction_data('execute')
    execute_txn_hash = proxy.transact({
        'gas': 3000000
    }).__proxy(
        to=txn_request.address,
        callData=decode_hex(call_data_hex),
        callGas=too_low_call_gas,
    )
    chain.wait.for_receipt(execute_txn_hash)

    assert txn_recorder.call().wasCalled() is False
    assert request_data.meta.wasCalled is False

    with pytest.raises(AssertionError):
        get_execute_data(execute_txn_hash)

    abort_data = get_abort_data(execute_txn_hash)
    reasons = {entry['args']['reason'] for entry in abort_data}
    assert AbortReasons.InsufficientGas in reasons
def test_proxy_execution_accepted_at_minimum_gas(chain,
                                                 RequestData,
                                                 proxy,
                                                 txn_recorder,
                                                 request_lib,
                                                 execution_lib,
                                                 get_execute_data,
                                                 get_abort_data,
                                                 AbortReasons):
    txn_request = RequestData(
        toAddress=txn_recorder.address,
        callGas=100000,
    ).direct_deploy()
    request_data = RequestData.from_contract(txn_request)

    assert txn_recorder.call().wasCalled() is False

    chain.wait.for_block(request_data.schedule.windowStart)

    minimum_call_gas = (
        request_data.txnData.callGas +
        request_lib.call().EXECUTION_GAS_OVERHEAD() +
        execution_lib.call().GAS_PER_DEPTH() * request_data.txnData.requiredStackDepth
    )

    call_data_hex = txn_request._encode_transaction_data('execute')
    execute_txn_hash = proxy.transact({'gas': 3000000}).__proxy(
        to=txn_request.address,
        callData=decode_hex(call_data_hex),
        callGas=minimum_call_gas,
    )
    chain.wait.for_receipt(execute_txn_hash)

    request_data.refresh()

    assert get_execute_data(execute_txn_hash)
    assert txn_recorder.call().wasCalled() is True
    assert request_data.meta.wasCalled is True
def test_claim_deposit_returned_even_if_returning_it_throws(
        chain, web3, RequestData, get_claim_data, error_generator):
    txn_request = RequestData(windowStart=web3.eth.blockNumber + 255 + 10 +
                              5).direct_deploy()
    request_data = RequestData.from_contract(txn_request)

    try_claim_at = request_data.schedule.windowStart - request_data.schedule.freezePeriod - request_data.schedule.claimWindowSize - 3

    # sanity
    assert try_claim_at > web3.eth.blockNumber

    chain.wait.for_block(try_claim_at)

    deposit_amount = 2 * request_data.paymentData.payment

    before_contract_balance = web3.eth.getBalance(txn_request.address)
    before_account_balance = web3.eth.getBalance(error_generator.address)

    assert before_account_balance == 0

    claim_call_data = decode_hex(txn_request._encode_transaction_data('claim'))

    claim_txn_hash = error_generator.transact({
        'value': deposit_amount,
    }).__proxy(
        txn_request.address,
        claim_call_data,
    )
    chain.wait.for_receipt(claim_txn_hash)

    after_contract_balance = web3.eth.getBalance(txn_request.address)
    after_account_balance = web3.eth.getBalance(error_generator.address)

    assert after_contract_balance == before_contract_balance
    assert after_account_balance == deposit_amount

    request_data.refresh()
    assert request_data.claimData.claimedBy == '0x0000000000000000000000000000000000000000'
def test_claim_deposit_returned_even_if_returning_it_throws(chain,
                                                            web3,
                                                            RequestData,
                                                            get_claim_data,
                                                            error_generator):
    txn_request = RequestData(windowStart=web3.eth.blockNumber + 255 + 10 + 5).direct_deploy()
    request_data = RequestData.from_contract(txn_request)

    try_claim_at = request_data.schedule.windowStart - request_data.schedule.freezePeriod - request_data.schedule.claimWindowSize - 3

    # sanity
    assert try_claim_at > web3.eth.blockNumber

    chain.wait.for_block(try_claim_at)

    deposit_amount = 2 * request_data.paymentData.payment

    before_contract_balance = web3.eth.getBalance(txn_request.address)
    before_account_balance = web3.eth.getBalance(error_generator.address)

    assert before_account_balance == 0

    claim_call_data = decode_hex(txn_request._encode_transaction_data('claim'))

    claim_txn_hash = error_generator.transact({
        'value': deposit_amount,
    }).__proxy(txn_request.address, claim_call_data, )
    chain.wait.for_receipt(claim_txn_hash)

    after_contract_balance = web3.eth.getBalance(txn_request.address)
    after_account_balance = web3.eth.getBalance(error_generator.address)

    assert after_contract_balance == before_contract_balance
    assert after_account_balance == deposit_amount

    request_data.refresh()
    assert request_data.claimData.claimedBy == '0x0000000000000000000000000000000000000000'
def test_execution_accepted_when_stack_extendable(chain,
                                                  web3,
                                                  RequestData,
                                                  txn_recorder,
                                                  digger_proxy,
                                                  get_execute_data,
                                                  get_abort_data,
                                                  AbortReasons):
    txn_request = RequestData(
        toAddress=txn_recorder.address,
        requiredStackDepth=1000,
    ).direct_deploy()
    request_data = RequestData.from_contract(txn_request)

    assert txn_recorder.call().wasCalled() is False
    assert request_data.meta.wasCalled is False
    assert request_data.txnData.requiredStackDepth == 1000

    chain.wait.for_block(request_data.schedule.windowStart)

    execute_call_data = decode_hex(txn_request._encode_transaction_data('execute'))

    execute_txn_hash = digger_proxy.transact({'gas': 3000000}).__dig_then_proxy(
        21,
        txn_request.address,
        execute_call_data,
    )
    chain.wait.for_receipt(execute_txn_hash)

    request_data.refresh()

    assert digger_proxy.call().result() is True
    assert txn_recorder.call().wasCalled() is True
    assert request_data.meta.wasCalled is True

    assert get_execute_data(execute_txn_hash)
Exemplo n.º 41
0
def test_eth_sign(web3_empty, skip_if_testrpc):
    web3 = web3_empty

    skip_if_testrpc(web3)

    private_key_hex = '0x5e95384d8050109aab08c1922d3c230739bc16976553c317e5d0b87b59371f2a'
    private_key = decode_hex(private_key_hex)

    # This imports the private key into the running geth instance and unlocks
    # the account so that it can sign things.
    # `0xa5df35f30ba0ce878b1061ae086289adff3ba1e0`
    address = web3.personal.importRawKey(private_key, "password")
    web3.personal.unlockAccount(address, "password")

    assert add_0x_prefix(encode_hex(
        privtoaddr(private_key))) == add_0x_prefix(address)
    assert address == '0xa5df35f30ba0ce878b1061ae086289adff3ba1e0'

    # the data to be signed
    data = b'1234567890abcdefghijklmnopqrstuvwxyz'
    # the hash of the data `0x089c33d56ed10bd8b571a0f493cedb28db1ae0f40c6cd266243001528c06eab3`
    data_hash = web3.sha3(data, encoding=None)
    data_hash_bytes = decode_hex(data_hash)

    assert force_bytes(data_hash) == sha3(data)

    priv_key = PrivateKey(flags=ALL_FLAGS)
    priv_key.set_raw_privkey(private_key)

    # sanit check the extract_ecdsa_signer function works as expected.
    vector_sig = priv_key.ecdsa_sign_recoverable(data_hash_bytes,
                                                 raw=True,
                                                 digest=sha3_256)
    vector_sig_bytes, rec_id = priv_key.ecdsa_recoverable_serialize(vector_sig)
    vector_sig_bytes_full = vector_sig_bytes + force_bytes(chr(rec_id))
    vector_address = force_text(
        extract_ecdsa_signer(data_hash_bytes, vector_sig_bytes_full))

    assert vector_address == address

    # Now have geth sign some data.
    signature_hex = web3.eth.sign(address, data)
    signature_bytes = decode_hex(signature_hex)

    actual_signer = extract_ecdsa_signer(data_hash_bytes, signature_bytes)

    assert actual_signer == address

    # Verify the signature against the public key derived from the
    # original private key.  It fails.
    rec_id = signature_bytes[64]
    if is_string(rec_id):
        rec_id = ord(rec_id)
    recoverable_signature = priv_key.ecdsa_recoverable_deserialize(
        signature_bytes[:64],
        rec_id,
    )
    signature = priv_key.ecdsa_recoverable_convert(recoverable_signature)
    is_valid = priv_key.pubkey.ecdsa_verify(
        msg=data,
        raw_sig=signature,
        digest=sha3_256,
    )

    assert is_valid
def test_accounting_when_everything_throws(chain,
                                           web3,
                                           get_execute_data,
                                           RequestData,
                                           error_generator):
    txn_request = RequestData(
        createdBy=error_generator.address,
        owner=error_generator.address,
        donationBenefactor=error_generator.address,
        toAddress=error_generator.address,
        callData=decode_hex(error_generator._encode_transaction_data('doThrow')),
        windowStart=web3.eth.blockNumber + 10 + 255 + 5,
    ).direct_deploy()
    request_data = RequestData.from_contract(txn_request)

    claim_at = request_data.schedule.windowStart - 10 - 5
    deposit_amount = request_data.paymentData.payment * 2

    assert claim_at > web3.eth.blockNumber

    chain.wait.for_block(claim_at)

    claim_call_data = decode_hex(txn_request._encode_transaction_data('claim'))
    claim_txn_hash = error_generator.transact({
        'value': deposit_amount,
    }).__proxy(txn_request.address, claim_call_data, )
    chain.wait.for_receipt(claim_txn_hash)

    chain.wait.for_block(request_data.schedule.windowStart)

    execute_call_data = decode_hex(txn_request._encode_transaction_data('execute'))

    execute_txn_hash = error_generator.transact({
        'from': web3.eth.accounts[1],
        'gas': 3000000,
    }).__proxy(
        to=txn_request.address,
        callData=execute_call_data,
    )
    execute_txn_receipt = chain.wait.for_receipt(execute_txn_hash)

    chain.wait.for_block(request_data.schedule.windowStart + request_data.schedule.windowSize)

    execute_data = get_execute_data(execute_txn_hash)
    request_data.refresh()

    assert request_data.meta.wasCalled is True
    assert request_data.meta.wasSuccessful is False

    gas_used = execute_txn_receipt['gasUsed']
    measured_gas_consumption = execute_data['args']['measuredGasConsumption']

    assert measured_gas_consumption > gas_used
    assert measured_gas_consumption - gas_used < 50000

    payment_owed = request_data.paymentData.paymentOwed
    donation_owed = request_data.paymentData.donationOwed

    assert payment_owed > 0
    assert payment_owed == execute_data['args']['payment']
    assert donation_owed > 0
    assert donation_owed == execute_data['args']['donation']

    # make the contract stop throwing now.
    chain.wait.for_receipt(error_generator.transact().toggle())
    assert error_generator.call().shouldThrow() is False

    before_payments_contract_balance = web3.eth.getBalance(txn_request.address)

    before_owner_refund_balance = web3.eth.getBalance(error_generator.address)

    issue_owner_refund_txn_hash = txn_request.transact().sendOwnerEther()
    chain.wait.for_receipt(issue_owner_refund_txn_hash)

    after_owner_refund_balance = web3.eth.getBalance(error_generator.address)
    owner_refund = after_owner_refund_balance - before_owner_refund_balance
    assert owner_refund > 0

    before_payment_balance = web3.eth.getBalance(error_generator.address)

    issue_payment_txn_hash = txn_request.transact().sendPayment()
    chain.wait.for_receipt(issue_payment_txn_hash)
    request_data.refresh()

    after_payment_balance = web3.eth.getBalance(error_generator.address)
    assert after_payment_balance - before_payment_balance == payment_owed

    before_donation_balance = web3.eth.getBalance(error_generator.address)

    issue_donation_txn_hash = txn_request.transact().sendDonation()
    chain.wait.for_receipt(issue_donation_txn_hash)
    request_data.refresh()

    after_donation_balance = web3.eth.getBalance(error_generator.address)
    assert after_donation_balance - before_donation_balance == donation_owed

    assert owner_refund + payment_owed + donation_owed == before_payments_contract_balance
Exemplo n.º 43
0
def test_hex_encode_decode_round_trip(value):
    intermediate_value = encode_hex(value)
    result_value = decode_hex(intermediate_value)
    assert result_value == value, "Expected: {0!r}, Result: {1!r}, Intermediate: {2!r}".format(
        value, result_value, intermediate_value)
Exemplo n.º 44
0
def test_eth_sign(web3_empty, skip_if_testrpc):
    web3 = web3_empty

    skip_if_testrpc(web3)

    private_key_hex = '0x5e95384d8050109aab08c1922d3c230739bc16976553c317e5d0b87b59371f2a'
    private_key = decode_hex(private_key_hex)

    # This imports the private key into the running geth instance and unlocks
    # the account so that it can sign things.
    # `0xa5df35f30ba0ce878b1061ae086289adff3ba1e0`
    address = web3.personal.importRawKey(private_key, "password")
    web3.personal.unlockAccount(address, "password")

    assert add_0x_prefix(encode_hex(privtoaddr(private_key))) == add_0x_prefix(address)
    assert address == '0xa5df35f30ba0ce878b1061ae086289adff3ba1e0'

    # the data to be signed
    data = b'1234567890abcdefghijklmnopqrstuvwxyz'
    # the hash of the data `0x089c33d56ed10bd8b571a0f493cedb28db1ae0f40c6cd266243001528c06eab3`
    data_hash = web3.sha3(data, encoding=None)
    data_hash_bytes = decode_hex(data_hash)

    assert force_bytes(data_hash) == sha3(data)

    priv_key = PrivateKey(flags=ALL_FLAGS)
    priv_key.set_raw_privkey(private_key)

    # sanit check the extract_ecdsa_signer function works as expected.
    vector_sig = priv_key.ecdsa_sign_recoverable(data_hash_bytes, raw=True, digest=sha3_256)
    vector_sig_bytes, rec_id = priv_key.ecdsa_recoverable_serialize(vector_sig)
    vector_sig_bytes_full = vector_sig_bytes + force_bytes(chr(rec_id))
    vector_address = force_text(extract_ecdsa_signer(data_hash_bytes, vector_sig_bytes_full))

    assert vector_address == address

    # Now have geth sign some data.
    signature_hex = web3.eth.sign(address, data)
    signature_bytes = decode_hex(signature_hex)

    actual_signer = extract_ecdsa_signer(data_hash_bytes, signature_bytes)

    assert actual_signer == address

    # Verify the signature against the public key derived from the
    # original private key.  It fails.
    rec_id = signature_bytes[64]
    if is_string(rec_id):
        rec_id = ord(rec_id)
    recoverable_signature = priv_key.ecdsa_recoverable_deserialize(
        signature_bytes[:64],
        rec_id,
    )
    signature = priv_key.ecdsa_recoverable_convert(recoverable_signature)
    is_valid = priv_key.pubkey.ecdsa_verify(
        msg=data,
        raw_sig=signature,
        digest=sha3_256,
    )

    assert is_valid
Exemplo n.º 45
0
def test_hex_encode_decode_round_trip(value):
    intermediate_value = encode_hex(value)
    result_value = decode_hex(intermediate_value)
    assert result_value == value, "Expected: {0!r}, Result: {1!r}, Intermediate: {2!r}".format(value, result_value, intermediate_value)
def test_accounting_when_everything_throws(chain, web3, get_execute_data,
                                           RequestData, error_generator):
    txn_request = RequestData(
        createdBy=error_generator.address,
        owner=error_generator.address,
        donationBenefactor=error_generator.address,
        toAddress=error_generator.address,
        callData=decode_hex(
            error_generator._encode_transaction_data('doThrow')),
        windowStart=web3.eth.blockNumber + 10 + 255 + 5,
    ).direct_deploy()
    request_data = RequestData.from_contract(txn_request)

    claim_at = request_data.schedule.windowStart - 10 - 5
    deposit_amount = request_data.paymentData.payment * 2

    assert claim_at > web3.eth.blockNumber

    chain.wait.for_block(claim_at)

    claim_call_data = decode_hex(txn_request._encode_transaction_data('claim'))
    claim_txn_hash = error_generator.transact({
        'value': deposit_amount,
    }).__proxy(
        txn_request.address,
        claim_call_data,
    )
    chain.wait.for_receipt(claim_txn_hash)

    chain.wait.for_block(request_data.schedule.windowStart)

    execute_call_data = decode_hex(
        txn_request._encode_transaction_data('execute'))

    execute_txn_hash = error_generator.transact({
        'from': web3.eth.accounts[1],
        'gas': 3000000,
    }).__proxy(
        to=txn_request.address,
        callData=execute_call_data,
    )
    execute_txn_receipt = chain.wait.for_receipt(execute_txn_hash)

    chain.wait.for_block(request_data.schedule.windowStart +
                         request_data.schedule.windowSize)

    execute_data = get_execute_data(execute_txn_hash)
    request_data.refresh()

    assert request_data.meta.wasCalled is True
    assert request_data.meta.wasSuccessful is False

    gas_used = execute_txn_receipt['gasUsed']
    measured_gas_consumption = execute_data['args']['measuredGasConsumption']

    assert measured_gas_consumption > gas_used
    assert measured_gas_consumption - gas_used < 50000

    payment_owed = request_data.paymentData.paymentOwed
    donation_owed = request_data.paymentData.donationOwed

    assert payment_owed > 0
    assert payment_owed == execute_data['args']['payment']
    assert donation_owed > 0
    assert donation_owed == execute_data['args']['donation']

    # make the contract stop throwing now.
    chain.wait.for_receipt(error_generator.transact().toggle())
    assert error_generator.call().shouldThrow() is False

    before_payments_contract_balance = web3.eth.getBalance(txn_request.address)

    before_owner_refund_balance = web3.eth.getBalance(error_generator.address)

    issue_owner_refund_txn_hash = txn_request.transact().sendOwnerEther()
    chain.wait.for_receipt(issue_owner_refund_txn_hash)

    after_owner_refund_balance = web3.eth.getBalance(error_generator.address)
    owner_refund = after_owner_refund_balance - before_owner_refund_balance
    assert owner_refund > 0

    before_payment_balance = web3.eth.getBalance(error_generator.address)

    issue_payment_txn_hash = txn_request.transact().sendPayment()
    chain.wait.for_receipt(issue_payment_txn_hash)
    request_data.refresh()

    after_payment_balance = web3.eth.getBalance(error_generator.address)
    assert after_payment_balance - before_payment_balance == payment_owed

    before_donation_balance = web3.eth.getBalance(error_generator.address)

    issue_donation_txn_hash = txn_request.transact().sendDonation()
    chain.wait.for_receipt(issue_donation_txn_hash)
    request_data.refresh()

    after_donation_balance = web3.eth.getBalance(error_generator.address)
    assert after_donation_balance - before_donation_balance == donation_owed

    assert owner_refund + payment_owed + donation_owed == before_payments_contract_balance