def mk_header_chain(length):
    assert length >= 1
    genesis = BlockHeader(difficulty=100, block_number=0, gas_limit=3000000)
    yield genesis
    parent = genesis
    if length == 1:
        return

    for i in range(length - 1):
        header = BlockHeader(
            difficulty=100,
            block_number=parent.block_number + 1,
            parent_hash=parent.hash,
            gas_limit=3000000,
        )
        yield header
        parent = header
Beispiel #2
0
def mk_uncle(block_number):
    return BlockHeader(
        state_root=os.urandom(32),
        difficulty=1000000,
        block_number=block_number,
        gas_limit=3141592,
        timestamp=int(time.time()),
    )
Beispiel #3
0
def test_headerdb_persist_header_disallows_unknown_parent(headerdb):
    header = BlockHeader(
        difficulty=GENESIS_DIFFICULTY,
        block_number=GENESIS_BLOCK_NUMBER,
        gas_limit=GENESIS_GAS_LIMIT,
        parent_hash=b'\x0f' * 32,
    )
    with pytest.raises(ParentNotFound, match="unknown parent"):
        headerdb.persist_header(header)
def mk_header_and_receipts(block_number, num_receipts):
    receipts = mk_receipts(num_receipts)
    root_hash, trie_root_and_data = make_trie_root_and_nodes(receipts)
    header = BlockHeader(
        difficulty=1000000,
        block_number=block_number,
        gas_limit=3141592,
        timestamp=int(time.time()),
        receipt_root=root_hash,
    )
    return header, receipts, (root_hash, trie_root_and_data)
def create_helios_testnet_header_from_parent(parent_header, **header_params):
    if 'gas_limit' not in header_params:
        #        header_params['gas_limit'] = compute_gas_limit(
        #            parent_header,
        #            gas_limit_floor=GENESIS_GAS_LIMIT,
        #        )
        header_params['gas_limit'] = compute_gas_limit()

    header = BlockHeader.from_parent(parent=parent_header, **header_params)

    return header
Beispiel #6
0
def mk_header_chain(base_header, length):
    previous_header = base_header
    for _ in range(length):
        next_header = BlockHeader.from_parent(
            parent=previous_header,
            timestamp=previous_header.timestamp + 1,
            gas_limit=previous_header.gas_limit,
            difficulty=previous_header.difficulty,
            extra_data=keccak(random.randint(0, 1e18)),
        )
        yield next_header
        previous_header = next_header
def test_chaindb_get_score(chaindb):
    genesis = BlockHeader(difficulty=1, block_number=0, gas_limit=0)
    chaindb.persist_header(genesis)

    genesis_score_key = SchemaV1.make_block_hash_to_score_lookup_key(
        genesis.hash)
    genesis_score = rlp.decode(chaindb.db.get(genesis_score_key),
                               sedes=rlp.sedes.big_endian_int)
    assert genesis_score == 1
    assert chaindb.get_score(genesis.hash) == 1

    block1 = BlockHeader(difficulty=10,
                         block_number=1,
                         gas_limit=0,
                         parent_hash=genesis.hash)
    chaindb.persist_header(block1)

    block1_score_key = SchemaV1.make_block_hash_to_score_lookup_key(
        block1.hash)
    block1_score = rlp.decode(chaindb.db.get(block1_score_key),
                              sedes=rlp.sedes.big_endian_int)
    assert block1_score == 11
    assert chaindb.get_score(block1.hash) == 11
Beispiel #8
0
 def make_genesis_block(cls, chain_address: Address):
     genesis_header = BlockHeader(
         chain_address=chain_address,
         account_hash=constants.GENESIS_ACCOUNT_HASH,
         extra_data=constants.GENESIS_EXTRA_DATA,
         gas_limit=constants.GENESIS_GAS_LIMIT,
         gas_used=0,
         bloom=0,
         block_number=0,
         parent_hash=constants.GENESIS_PARENT_HASH,
         receipt_root=constants.BLANK_ROOT_HASH,
         timestamp=int(time.time()),
         transaction_root=constants.BLANK_ROOT_HASH,
         receive_transaction_root=constants.BLANK_ROOT_HASH,
     )
     return cls.from_header(genesis_header)
Beispiel #9
0
def test_blockchain_fixtures(fixture_data, fixture):
    try:
        chain = new_chain_from_fixture(fixture)
    except ValueError as e:
        raise AssertionError("could not load chain for %r" % fixture_data) from e

    genesis_params = genesis_params_from_fixture(fixture)
    expected_genesis_header = BlockHeader(**genesis_params)

    # TODO: find out if this is supposed to pass?
    # if 'genesisRLP' in fixture:
    #     assert rlp_templates.encode(genesis_header) == fixture['genesisRLP']

    genesis_block = chain.get_canonical_block_by_number(0)
    genesis_header = genesis_block.header

    assert_imported_genesis_header_unchanged(expected_genesis_header, genesis_header)

    # 1 - mine the genesis block
    # 2 - loop over blocks:
    #     - apply transactions
    #     - mine block
    # 4 - profit!!

    for block_fixture in fixture['blocks']:
        should_be_good_block = 'blockHeader' in block_fixture

        if 'rlp_error' in block_fixture:
            assert not should_be_good_block
            continue

        if should_be_good_block:
            (block, mined_block, block_rlp) = apply_fixture_block_to_chain(block_fixture, chain)
            assert_mined_block_unchanged(block, mined_block)
        else:
            try:
                apply_fixture_block_to_chain(block_fixture, chain)
            except (TypeError, rlp.DecodingError, rlp.DeserializationError, ValidationError) as err:
                # failure is expected on this bad block
                pass
            else:
                raise AssertionError("Block should have caused a validation error")

    latest_block_hash = chain.get_canonical_block_by_number(chain.get_block().number - 1).hash
    assert latest_block_hash == fixture['lastblockhash']

    verify_account_db(fixture['postState'], chain.get_vm().state.account_db)
Beispiel #10
0
def create_frontier_header_from_parent(parent_header, **header_params):
    if 'difficulty' not in header_params:
        # Use setdefault to ensure the new header has the same timestamp we use to calculate its
        # difficulty.
        header_params.setdefault('timestamp', parent_header.timestamp + 1)
        header_params['difficulty'] = compute_frontier_difficulty(
            parent_header,
            header_params['timestamp'],
        )
    if 'gas_limit' not in header_params:
        header_params['gas_limit'] = compute_gas_limit(
            parent_header,
            gas_limit_floor=GENESIS_GAS_LIMIT,
        )

    header = BlockHeader.from_parent(parent=parent_header, **header_params)

    return header
Beispiel #11
0
def mk_header_and_body(block_number, num_transactions, num_uncles):
    transactions = tuple(mk_transaction() for _ in range(num_transactions))
    uncles = tuple(mk_uncle(block_number - 1) for _ in range(num_uncles))

    transaction_root, trie_data = make_trie_root_and_nodes(transactions)
    uncles_hash = keccak(rlp.encode(uncles))

    body = BlockBody(transactions=transactions, uncles=uncles)

    header = BlockHeader(
        difficulty=1000000,
        block_number=block_number,
        gas_limit=3141592,
        timestamp=int(time.time()),
        transaction_root=transaction_root,
        uncles_hash=uncles_hash,
    )

    return header, body, transaction_root, trie_data, uncles_hash
Beispiel #12
0
    def apply_send_transaction(
            self,
            header: BlockHeader,
            transaction: BaseTransaction,
            caller_chain_address: Address,
            validate: bool = True
    ) -> Tuple[BlockHeader, Receipt, BaseComputation]:
        """
        Apply the transaction to the current block. This is a wrapper around
        :func:`~hvm.vm.state.State.apply_transaction` with some extra orchestration logic.

        :param header: header of the block before application
        :param transaction: to apply
        """
        #caller_chain_address = header.sender
        #this is a send transaction
        send_transaction = transaction
        receive_transaction = None
        if validate:
            self.validate_transaction_against_header(
                header, send_transaction=send_transaction)

        computation, _ = self.state.apply_transaction(
            send_transaction=send_transaction,
            caller_chain_address=caller_chain_address,
            receive_transaction=receive_transaction,
            validate=validate)
        if validate:
            receipt = self.make_receipt(header, computation, send_transaction)

            new_header = header.copy(
                bloom=int(BloomFilter(header.bloom) | receipt.bloom),
                gas_used=receipt.gas_used,
            )

            return new_header, receipt, computation
        else:
            return None, None, computation
def test_state_fixtures(fixture, fixture_vm_class):
    header = BlockHeader(
        coinbase=fixture['env']['currentCoinbase'],
        difficulty=fixture['env']['currentDifficulty'],
        block_number=fixture['env']['currentNumber'],
        gas_limit=fixture['env']['currentGasLimit'],
        timestamp=fixture['env']['currentTimestamp'],
        parent_hash=fixture['env']['previousHash'],
    )

    chaindb = ChainDB(get_db_backend())
    vm = fixture_vm_class(header=header, chaindb=chaindb)

    state = vm.state
    apply_state_dict(state.account_db, fixture['pre'])
    state.account_db.persist()

    # Update state_root manually
    vm.block = vm.block.copy(header=vm.block.header.copy(state_root=state.state_root))
    if 'secretKey' in fixture['transaction']:
        unsigned_transaction = vm.create_unsigned_transaction(
            nonce=fixture['transaction']['nonce'],
            gas_price=fixture['transaction']['gasPrice'],
            gas=fixture['transaction']['gasLimit'],
            to=fixture['transaction']['to'],
            value=fixture['transaction']['value'],
            data=fixture['transaction']['data'],
        )
        private_key = keys.PrivateKey(fixture['transaction']['secretKey'])
        transaction = unsigned_transaction.as_signed_transaction(private_key=private_key)
    elif 'vrs' in fixture['transaction']:
        v, r, s = (
            fixture['transaction']['v'],
            fixture['transaction']['r'],
            fixture['transaction']['s'],
        )
        transaction = vm.create_transaction(
            nonce=fixture['transaction']['nonce'],
            gas_price=fixture['transaction']['gasPrice'],
            gas=fixture['transaction']['gasLimit'],
            to=fixture['transaction']['to'],
            value=fixture['transaction']['value'],
            data=fixture['transaction']['data'],
            v=v,
            r=r,
            s=s,
        )

    try:
        header, receipt, computation = vm.apply_transaction(vm.block.header, transaction)
        transactions = vm.block.transactions + (transaction, )
        receipts = vm.block.get_receipts(chaindb) + (receipt, )
        block = vm.set_block_transactions(vm.block, header, transactions, receipts)
    except ValidationError as err:
        block = vm.block
        transaction_error = err
        logger.warning("Got transaction error", exc_info=True)
    else:
        transaction_error = False

    if not transaction_error:
        log_entries = computation.get_log_entries()
        actual_logs_hash = hash_log_entries(log_entries)
        if 'logs' in fixture['post']:
            expected_logs_hash = fixture['post']['logs']
            assert expected_logs_hash == actual_logs_hash
        elif log_entries:
            raise AssertionError("Got log {0} entries. hash:{1}".format(
                len(log_entries),
                actual_logs_hash,
            ))

        if 'out' in fixture:
            expected_output = fixture['out']
            if isinstance(expected_output, int):
                assert len(computation.output) == expected_output
            else:
                assert computation.output == expected_output

    assert block.header.state_root == fixture['post']['hash']
Beispiel #14
0
def genesis_header():
    return BlockHeader(
        difficulty=GENESIS_DIFFICULTY,
        block_number=GENESIS_BLOCK_NUMBER,
        gas_limit=GENESIS_GAS_LIMIT,
    )
Beispiel #15
0

# Ethereum mainnet headers, from two headers before to ten headers after the fork:
ETH_HEADERS_NEAR_FORK = [
    BlockHeader(
        difficulty=62352470509925,
        block_number=1919998,
        gas_limit=4712388,
        timestamp=1469020835,
        coinbase=
        b'\xbc\xdf\xc3[\x86\xbe\xdfr\xf0\xcd\xa0F\xa3\xc1h)\xa2\xefA\xd1',
        parent_hash=
        b'\xe7\xe3\xe8+\xf3C\xbe\xf9\xa2R\xb8\x7f\x06r\x9adZop\x9b.RK\x9e\xf4\xf9;\xb9\xf2]S\x8d',  # noqa: E501
        uncles_hash=
        b'\x1d\xccM\xe8\xde\xc7]z\xab\x85\xb5g\xb6\xcc\xd4\x1a\xd3\x12E\x1b\x94\x8at\x13\xf0\xa1B\xfd@\xd4\x93G',  # noqa: E501
        state_root=
        b'\x1f!\x88?4\xde&\x93\xb4\xadGD\xc26a\xdbd\xca\xcb=\xa2\x1dr \xceW\xb97d\xb3\xbb\xfe',  # noqa: E501
        transaction_root=
        b'\xf2n\xb9\x94\x0e\xbb\xe8\x0c\xc3\xab\xbc\x9ev\xe9\xb7\xb1\x0f\xbcG\xc0\xd2\x12\xf9\x81\xa6q/\xf7\xf4\x97\xd3\xb4',  # noqa: E501
        receipt_root=
        b'D\xda\xa2\x9c4?\xa0/\xe8\x8fH\xf8?z\xc2\x1e\xfa\xc8j\xb0w8\r\xed\x81[(n\xd2jx\x1f',  # noqa: E501
        bloom=0,
        gas_used=420000,
        extra_data=b'\xd7\x83\x01\x04\n\x84Geth\x87go1.6.2\x85linux',
        mix_hash=
        b'\x8d\x03\xe0$?1\xa6\xcd\x11\x04E\x1f\xfc\x10#[\x04\x16N\xbe[\xd4u-\xa6\xb54t\x8d\x87}\x9f',  # noqa: E501
        nonce=b'a\xd8\xc5\xdf\xfd\x0e\xb2v',
    ),
    BlockHeader(
        difficulty=62382916183238,
        block_number=1919999,
        gas_limit=4707788,
Beispiel #16
0
MAINNET_NETWORK_ID = 1


class BaseMainnetChain:
    vm_configuration = MAINNET_VM_CONFIGURATION  # type: Tuple[Tuple[int, Type[BaseVM]], ...]  # noqa: E501
    network_id = MAINNET_NETWORK_ID  # type: int


class MainnetChain(BaseMainnetChain, Chain):
    pass


MAINNET_GENESIS_HEADER = BlockHeader(
    difficulty=17179869184,
    extra_data=decode_hex(
        "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"),
    gas_limit=5000,
    gas_used=0,
    bloom=0,
    mix_hash=constants.ZERO_HASH32,
    nonce=constants.GENESIS_NONCE,
    block_number=0,
    parent_hash=constants.ZERO_HASH32,
    receipt_root=constants.BLANK_ROOT_HASH,
    uncles_hash=constants.EMPTY_UNCLE_HASH,
    state_root=decode_hex(
        "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"),
    timestamp=0,
    transaction_root=constants.BLANK_ROOT_HASH,
)
def test_vm_fixtures(fixture, vm_class, computation_getter):
    chaindb = ChainDB(get_db_backend())
    header = BlockHeader(
        coinbase=fixture['env']['currentCoinbase'],
        difficulty=fixture['env']['currentDifficulty'],
        block_number=fixture['env']['currentNumber'],
        gas_limit=fixture['env']['currentGasLimit'],
        timestamp=fixture['env']['currentTimestamp'],
    )
    vm = vm_class(header=header, chaindb=chaindb)
    state = vm.state
    setup_account_db(fixture['pre'], state.account_db)
    code = state.account_db.get_code(fixture['exec']['address'])
    # Update state_root manually
    vm.block = vm.block.copy(header=vm.block.header.copy(
        state_root=state.state_root))

    message = Message(
        to=fixture['exec']['address'],
        sender=fixture['exec']['caller'],
        value=fixture['exec']['value'],
        data=fixture['exec']['data'],
        code=code,
        gas=fixture['exec']['gas'],
    )
    transaction_context = BaseTransactionContext(
        origin=fixture['exec']['origin'],
        gas_price=fixture['exec']['gasPrice'],
    )
    computation = vm.state.get_computation(
        message, transaction_context).apply_computation(
            vm.state,
            message,
            transaction_context,
        )
    # Update state_root manually
    vm.block = vm.block.copy(
        header=vm.block.header.copy(state_root=computation.state.state_root), )

    if 'post' in fixture:
        #
        # Success checks
        #
        assert not computation.is_error

        log_entries = computation.get_log_entries()
        if 'logs' in fixture:
            actual_logs_hash = hash_log_entries(log_entries)
            expected_logs_hash = fixture['logs']
            assert expected_logs_hash == actual_logs_hash
        elif log_entries:
            raise AssertionError("Got log entries: {0}".format(log_entries))

        expected_output = fixture['out']
        assert computation.output == expected_output

        gas_meter = computation._gas_meter

        expected_gas_remaining = fixture['gas']
        actual_gas_remaining = gas_meter.gas_remaining
        gas_delta = actual_gas_remaining - expected_gas_remaining
        assert gas_delta == 0, "Gas difference: {0}".format(gas_delta)

        call_creates = fixture.get('callcreates', [])
        assert len(computation.children) == len(call_creates)

        call_creates = fixture.get('callcreates', [])
        for child_computation, created_call in zip(computation.children,
                                                   call_creates):
            to_address = created_call['destination']
            data = created_call['data']
            gas_limit = created_call['gasLimit']
            value = created_call['value']

            assert child_computation.msg.to == to_address
            assert data == child_computation.msg.data or child_computation.msg.code
            assert gas_limit == child_computation.msg.gas
            assert value == child_computation.msg.value
        expected_account_db = fixture['post']
    else:
        #
        # Error checks
        #
        assert computation.is_error
        assert isinstance(computation._error, VMError)
        expected_account_db = fixture['pre']

    verify_account_db(expected_account_db, vm.state.account_db)
Beispiel #18
0
    def apply_receive_transaction(
        self,
        header: BlockHeader,
        receive_transaction: BaseReceiveTransaction,
        caller_chain_address: Address,
        validate: bool = True
    ) -> Tuple[Optional[BlockHeader], Optional[Receipt], BaseComputation,
               Optional[BaseReceiveTransaction]]:
        """
        Apply the transaction to the current block. This is a wrapper around
        :func:`~hvm.vm.state.State.apply_transaction` with some extra orchestration logic.

        :param header: header of the block before application
        :param transaction: to apply
        """
        # Lets make sure we have this receivable transaction in the account
        receivable_tx_key = self.state.account_db.get_receivable_transaction(
            caller_chain_address, receive_transaction.send_transaction_hash)

        # Very first thing, check to see if this transaction has been received before:
        try:
            block_hash, index, is_receive = self.chaindb.get_transaction_index(
                receive_transaction.hash)
            if self.chaindb.is_in_canonical_chain(block_hash):
                raise ValidationError(
                    'Tried to import a receive transaction that has already been received in the canonical chain'
                )
        except TransactionNotFound:
            pass

        if receivable_tx_key is None:
            # There is no receivable transaction that matches this one.
            # now check to see if the block is in the canonical chain, but didnt have the transaction in it
            try:
                block_hash, index, is_receive = self.chaindb.get_transaction_index(
                    receive_transaction.send_transaction_hash)
                if block_hash == receive_transaction.sender_block_hash:
                    raise ValidationError(
                        'Receive transaction is invalid. We do have the send transaction and send block, but it has already been received.'
                    )
                else:
                    raise ValidationError(
                        'Receive transaction is invalid. We have already imported this transaction, but it was from another block.'
                    )
            except TransactionNotFound:
                if self.chaindb.is_in_canonical_chain(
                        receive_transaction.sender_block_hash):
                    raise ValidationError(
                        'Receive transaction is invalid. We have the sender block, but it didn\'t contain the send transaction'
                    )

            if self.chaindb.exists(receive_transaction.send_transaction_hash):
                self.logger.debug(
                    "The missing receivable transaction exists in the db but not canonical chain."
                )

            if self.chaindb.is_in_canonical_chain(
                    receive_transaction.sender_block_hash):
                self.logger.debug(
                    "The sender block of the missing receivable transaction is in the canonical chain. This must means the tx is in there, but wasnt saved to canonical transactions..."
                )

            raise ReceivableTransactionNotFound(
                "caller_chain_address = {}, send_transaction_hash = {}, sender_block_hash = {}"
                .format(
                    encode_hex(caller_chain_address),
                    encode_hex(receive_transaction.send_transaction_hash),
                    encode_hex(receive_transaction.sender_block_hash),
                ))

        else:
            #now lets get all of the relevant transactions in this chain
            try:

                if receive_transaction.is_refund:
                    #this is a refund transaction. We need to load the receive_transaction containing the refund and the send_transaction
                    refund_transaction = receive_transaction

                    block_hash, index, is_receive = self.chaindb.get_transaction_index(
                        refund_transaction.send_transaction_hash)

                    if block_hash != refund_transaction.sender_block_hash:
                        raise ValidationError(
                            "The sender_block_hash of this refund transaction doesn't match the block of the receive transaction"
                        )

                    if not is_receive:
                        raise ValidationError(
                            "This refund transaction references a send transaction. This is not allowed."
                        )

                    receive_transaction = self.chaindb.get_receive_transaction_by_index_and_block_hash(
                        block_hash,
                        index,
                        self.get_receive_transaction_class(),
                    )
                else:
                    refund_transaction = None

                block_hash, index, is_receive = self.chaindb.get_transaction_index(
                    receive_transaction.send_transaction_hash)

                if block_hash != receive_transaction.sender_block_hash:
                    raise ValidationError(
                        "The sender_block_hash of this receive transaction doesn't match the block of the send transaction"
                    )

                if is_receive:
                    raise ValidationError(
                        "This receive transaction references another receive transaction. This is not allowed."
                    )

                send_transaction = self.chaindb.get_transaction_by_index_and_block_hash(
                    block_hash,
                    index,
                    self.get_transaction_class(),
                )

            except TransactionNotFound:
                raise ReceivableTransactionNotFound()

            # we assume past this point that, if it is a receive transaction, the send transaction exists in account
            computation, processed_transaction = self.state.apply_transaction(
                send_transaction=send_transaction,
                caller_chain_address=caller_chain_address,
                receive_transaction=receive_transaction,
                refund_transaction=refund_transaction,
                validate=validate)

            if validate:
                receipt = self.make_receipt(header, computation,
                                            send_transaction,
                                            receive_transaction,
                                            refund_transaction)

                new_header = header.copy(
                    bloom=int(BloomFilter(header.bloom) | receipt.bloom),
                    gas_used=receipt.gas_used,
                )

                return new_header, receipt, computation, processed_transaction
            else:
                return None, None, computation, processed_transaction
def header(request):
    block_number = request.param
    difficulty = 1
    gas_limit = 1
    return BlockHeader(difficulty, block_number, gas_limit)
Beispiel #20
0
    def signBlock(self,
                  header_dict: dict,
                  private_key: str,
                  send_transaction_dicts: List[dict] = [],
                  receive_transaction_dicts: List[dict] = []) -> AttributeDict:
        '''

        transaction = {
                    # Note that the address must be in checksum format:
                    'to': '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55',
                    'value': 1000000000,
                    'gas': 2000000,
                    'gasPrice': 234567897654321,
                    'nonce': 0,
                    'chainId': 1
                }

         receive_transaction = {
                'senderBlockHash',
                'sendTransactionHash',
                'isRefund',
                'remainingRefund'
            }

        header = {
                'parentHash',
                'blockNumber',
                'extraData',
            }

        :param send_transaction_dicts:
        :param receive_transaction_dicts:
        :param reward_bundle:
        :param private_key:
        :return:
        '''

        timestamp = int(time.time())

        if not is_bytes(header_dict['parentHash']):
            header_dict['parentHash'] = to_bytes(
                hexstr=header_dict['parentHash'])

        if "extraData" in header_dict:
            if not is_bytes(header_dict['extraData']):
                extra_data = to_bytes(hexstr=header_dict['extraData'])
            else:
                extra_data = header_dict['extraData']
        else:
            extra_data = b''

        if "chainId" in header_dict:
            chain_id = header_dict['chainId']
        else:
            if len(send_transaction_dicts) > 0:
                if 'chainId' in send_transaction_dicts[0]:
                    chain_id = send_transaction_dicts[0]['chainId']
                else:
                    chain_id = 1
            else:
                chain_id = 1

        photon_timestamp = get_photon_timestamp(chain_id)
        if timestamp < photon_timestamp:
            fork_id = 0
        else:
            fork_id = 1

        account = self.privateKeyToAccount(private_key)

        send_transactions = []
        for transaction_dict in send_transaction_dicts:
            if 'data' in transaction_dict:
                if not is_bytes(transaction_dict['data']):
                    data = to_bytes(hexstr=transaction_dict['data'])
                else:
                    data = transaction_dict['data']
            else:
                data = b''

            if not is_bytes(transaction_dict['to']):
                to = to_bytes(hexstr=transaction_dict['to'])
            else:
                to = transaction_dict['to']

            if fork_id == 0:
                tx = BosonTransaction(nonce=transaction_dict['nonce'],
                                      gas_price=transaction_dict['gasPrice'],
                                      gas=transaction_dict['gas'],
                                      to=to,
                                      value=transaction_dict['value'],
                                      data=data,
                                      v=0,
                                      r=0,
                                      s=0)
                signed_tx = tx.get_signed(account._key_obj, chain_id)
            elif fork_id == 1:
                if 'codeAddress' in transaction_dict:
                    if not is_bytes(transaction_dict['codeAddress']):
                        code_address = to_bytes(
                            hexstr=transaction_dict['codeAddress'])
                    else:
                        code_address = transaction_dict['codeAddress']
                else:
                    code_address = b''

                if 'executeOnSend' in transaction_dict:
                    execute_on_send = bool(transaction_dict['executeOnSend'])
                else:
                    execute_on_send = False

                tx = PhotonTransaction(nonce=transaction_dict['nonce'],
                                       gas_price=transaction_dict['gasPrice'],
                                       gas=transaction_dict['gas'],
                                       to=to,
                                       value=transaction_dict['value'],
                                       data=data,
                                       code_address=code_address,
                                       execute_on_send=execute_on_send,
                                       v=0,
                                       r=0,
                                       s=0)
                signed_tx = tx.get_signed(account._key_obj, chain_id)
            else:
                raise Exception("Unknown fork id")

            send_transactions.append(signed_tx)

        receive_transactions = []
        for receive_transaction_dict in receive_transaction_dicts:

            if not is_bytes(receive_transaction_dict['senderBlockHash']):
                receive_transaction_dict['senderBlockHash'] = to_bytes(
                    hexstr=receive_transaction_dict['senderBlockHash'])

            if not is_bytes(receive_transaction_dict['sendTransactionHash']):
                receive_transaction_dict['sendTransactionHash'] = to_bytes(
                    hexstr=receive_transaction_dict['sendTransactionHash'])

            if not is_boolean(receive_transaction_dict['isRefund']):
                receive_transaction_dict['isRefund'] = False if to_int(
                    hexstr=receive_transaction_dict['isRefund']) == 0 else True

            # We renamed the fourth parameter in the new photon fork
            fourth_parameter = 0
            if 'remainingRefund' in receive_transaction_dict:
                if not is_integer(receive_transaction_dict['remainingRefund']):
                    fourth_parameter = to_int(
                        hexstr=receive_transaction_dict['remainingRefund'])
                else:
                    fourth_parameter = receive_transaction_dict[
                        'remainingRefund']
            elif 'refundAmount' in receive_transaction_dict:
                if not is_integer(receive_transaction_dict['refundAmount']):
                    fourth_parameter = to_int(
                        hexstr=receive_transaction_dict['refundAmount'])
                else:
                    fourth_parameter = receive_transaction_dict['refundAmount']

            if fork_id == 0:
                receive_transaction_class = BosonReceiveTransaction
            elif fork_id == 1:
                receive_transaction_class = PhotonReceiveTransaction
            else:
                raise Exception("Unknown fork id")

            tx = receive_transaction_class(
                receive_transaction_dict['senderBlockHash'],
                receive_transaction_dict['sendTransactionHash'],
                receive_transaction_dict['isRefund'], fourth_parameter)

            receive_transactions.append(tx)

        send_tx_root_hash, _ = make_trie_root_and_nodes(send_transactions)
        receive_tx_root_hash, _ = make_trie_root_and_nodes(
            receive_transactions)

        chain_address = account.address

        reward_bundle = StakeRewardBundle()

        header = BlockHeader(chain_address=decode_hex(chain_address),
                             parent_hash=header_dict['parentHash'],
                             transaction_root=send_tx_root_hash,
                             receive_transaction_root=receive_tx_root_hash,
                             block_number=header_dict['blockNumber'],
                             timestamp=timestamp,
                             extra_data=extra_data,
                             reward_hash=reward_bundle.hash)

        signed_header = header.get_signed(account._key_obj, chain_id)
        signed_micro_header = signed_header.to_micro_header()

        if fork_id == 0:
            micro_block = BosonMicroBlock(
                header=signed_micro_header,
                transactions=send_transactions,
                receive_transactions=receive_transactions,
                reward_bundle=reward_bundle)
            rlp_encoded_micro_block = rlp.encode(micro_block,
                                                 sedes=BosonMicroBlock)
        elif fork_id == 1:
            micro_block = PhotonMicroBlock(
                header=signed_micro_header,
                transactions=send_transactions,
                receive_transactions=receive_transactions,
                reward_bundle=reward_bundle)
            rlp_encoded_micro_block = rlp.encode(micro_block,
                                                 sedes=PhotonMicroBlock)
        else:
            raise Exception("Unknown fork id")

        return AttributeDict({
            'rawBlock':
            encode_hex(rlp_encoded_micro_block),
            'send_tx_hashes': [tx.hash for tx in send_transactions],
            'receive_tx_hashes': [tx.hash for tx in receive_transactions],
            'r':
            signed_header.r,
            's':
            signed_header.s,
            'v':
            signed_header.v,
        })
Beispiel #21
0

ROPSTEN_NETWORK_ID = 3


class BaseRopstenChain:
    vm_configuration = ROPSTEN_VM_CONFIGURATION  # type: Tuple[Tuple[int, Type[BaseVM]], ...]  # noqa: E501
    network_id = ROPSTEN_NETWORK_ID  # type: int


class RopstenChain(BaseRopstenChain, Chain):
    pass


ROPSTEN_GENESIS_HEADER = BlockHeader(
    difficulty=1048576,
    extra_data=decode_hex("0x3535353535353535353535353535353535353535353535353535353535353535"),
    gas_limit=16777216,
    gas_used=0,
    bloom=0,
    mix_hash=constants.ZERO_HASH32,
    nonce=constants.GENESIS_NONCE,
    block_number=0,
    parent_hash=constants.ZERO_HASH32,
    receipt_root=constants.BLANK_ROOT_HASH,
    uncles_hash=constants.EMPTY_UNCLE_HASH,
    state_root=decode_hex("0x217b0bbcfb72e2d57e28f33cb361b9983513177755dc3f33ce3e7022ed62b77b"),
    timestamp=0,
    transaction_root=constants.BLANK_ROOT_HASH,
)
Beispiel #22
0
from hvm.vm.message import (
    Message, )

NORMALIZED_ADDRESS_A = "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6"
NORMALIZED_ADDRESS_B = "0xcd1722f3947def4cf144679da39c4c32bdc35681"
ADDRESS_WITH_CODE = ("0xddd722f3947def4cf144679da39c4c32bdc35681",
                     b'pseudocode')
EMPTY_ADDRESS_IN_STATE = NORMALIZED_ADDRESS_A
ADDRESS_NOT_IN_STATE = NORMALIZED_ADDRESS_B
CANONICAL_ADDRESS_A = to_canonical_address(
    "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6")
CANONICAL_ADDRESS_B = to_canonical_address(
    "0xcd1722f3947def4cf144679da39c4c32bdc35681")
GENESIS_HEADER = BlockHeader(
    difficulty=constants.GENESIS_DIFFICULTY,
    block_number=constants.GENESIS_BLOCK_NUMBER,
    gas_limit=constants.GENESIS_GAS_LIMIT,
)


def prepare_computation(vm_class):

    message = Message(
        to=CANONICAL_ADDRESS_A,
        sender=CANONICAL_ADDRESS_B,
        value=100,
        data=b'',
        code=b'',
        gas=800,
    )