Example #1
0
    def import_empty_blocks(self, chain: Chain, number_blocks: int) -> int:

        total_gas_used = 0
        for _ in range(1, number_blocks + 1):
            block = chain.import_block(chain.get_vm().block, False)
            total_gas_used = total_gas_used + block.header.gas_used
            logging.debug(format_block(block))

        return total_gas_used
Example #2
0
    def apply_transaction(self, chain: Chain) -> None:

        # Instantiate the contract
        SimpleToken = self.w3.eth.contract(
            abi=self.contract_interface['abi'],
            bytecode=self.contract_interface['bin'])

        # Build transaction to deploy the contract
        w3_tx1 = SimpleToken.constructor().buildTransaction(W3_TX_DEFAULTS)

        tx = new_transaction(
            vm=chain.get_vm(),
            private_key=FUNDED_ADDRESS_PRIVATE_KEY,
            from_=FUNDED_ADDRESS,
            to=CREATE_CONTRACT_ADDRESS,
            amount=0,
            gas=FIRST_TX_GAS_LIMIT,
            data=decode_hex(w3_tx1['data']),
        )

        logging.debug('Applying Transaction {}'.format(tx))

        block, receipt, computation = chain.apply_transaction(tx)
        deployed_contract_address = computation.msg.storage_address

        assert computation.is_success

        # Interact with the deployed contract by calling the totalSupply() API
        simple_token = self.w3.eth.contract(
            address=Web3.toChecksumAddress(
                encode_hex(deployed_contract_address)),
            abi=self.contract_interface['abi'],
        )
        w3_tx2 = simple_token.functions.totalSupply().buildTransaction(
            W3_TX_DEFAULTS)

        tx2 = new_transaction(
            vm=chain.get_vm(),
            private_key=FUNDED_ADDRESS_PRIVATE_KEY,
            from_=FUNDED_ADDRESS,
            to=deployed_contract_address,
            amount=0,
            gas=SECOND_TX_GAS_LIMIT,
            data=decode_hex(w3_tx2['data']),
        )

        block, receipt, computation = chain.apply_transaction(tx2)

        assert computation.is_success
        assert to_int(computation.output) == EXPECTED_TOTAL_SUPPLY
Example #3
0
    def mine_block(self, chain: Chain, block_number: int,
                   num_tx: int) -> BaseBlock:

        for i in range(1, num_tx + 1):
            self.apply_transaction(chain)

        return chain.mine_block()
    def mine_blocks(self, chain: Chain, num_blocks: int) -> Tuple[int, int]:
        total_gas_used = 0
        total_num_tx = 0

        for i in range(1, num_blocks + 1):
            num_tx = chain.get_block(
            ).header.gas_limit // SIMPLE_VALUE_TRANSFER_GAS_COST
            block = self.mine_block(chain, i, num_tx)
            total_num_tx = total_num_tx + len(block.transactions)
            total_gas_used = total_gas_used + block.header.gas_used

        return total_gas_used, total_num_tx
    def apply_transaction(self, chain: Chain) -> None:

        if self.config.to_address is None:
            to_address = generate_random_address()
        else:
            to_address = self.config.to_address

        tx = new_transaction(vm=chain.get_vm(),
                             private_key=FUNDED_ADDRESS_PRIVATE_KEY,
                             from_=FUNDED_ADDRESS,
                             to=to_address,
                             amount=100,
                             data=b'')

        logging.debug('Applying Transaction {}'.format(tx))

        block, receipt, computation = chain.apply_transaction(tx)

        logging.debug('Block {}'.format(block))
        logging.debug('Receipt {}'.format(receipt))
        logging.debug('Computation {}'.format(computation))
Example #6
0
    SpuriousDragonVM,
    TangerineWhistleVM,
)

ROPSTEN_VM_CONFIGURATION = (
    # Note: Frontier and Homestead are excluded since this chain starts at Tangerine Whistle.
    (TANGERINE_WHISTLE_ROPSTEN_BLOCK, TangerineWhistleVM),
    (SPURIOUS_DRAGON_ROPSTEN_BLOCK, SpuriousDragonVM),
    (BYZANTIUM_ROPSTEN_BLOCK, ByzantiumVM),
)

ROPSTEN_NETWORK_ID = 3

RopstenChain = Chain.configure(
    'RopstenChain',
    vm_configuration=ROPSTEN_VM_CONFIGURATION,
    network_id=ROPSTEN_NETWORK_ID,
)

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,
Example #7
0
    ByzantiumVM,
)

MAINNET_VM_CONFIGURATION = (
    (0, FrontierVM),
    (HOMESTEAD_MAINNET_BLOCK, HomesteadVM),
    (TANGERINE_WHISTLE_MAINNET_BLOCK, TangerineWhistleVM),
    (SPURIOUS_DRAGON_MAINNET_BLOCK, SpuriousDragonVM),
    (BYZANTIUM_MAINNET_BLOCK, ByzantiumVM),
)

MAINNET_NETWORK_ID = 1

MainnetChain = Chain.configure(
    'MainnetChain',
    vm_configuration=MAINNET_VM_CONFIGURATION,
    network_id=MAINNET_NETWORK_ID,
)

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,
Example #8
0
def test_vm_not_found_if_no_matching_block_number(genesis_header):
    chain_class = Chain.configure('ChainStartsAtBlock10', vm_configuration=(
        (10, VM_A),
    ))
    with pytest.raises(VMNotFound):
        chain_class.get_vm_class_for_block_number(9)
Example #9
0
def chain_with_block_validation(base_db, funded_address,
                                funded_address_initial_balance):
    """
    Return a Chain object containing just the genesis block.

    The Chain's state includes one funded account, which can be found in the
    funded_address in the chain itself.

    This Chain will perform all validations when importing new blocks, so only
    valid and finalized blocks can be used with it. If you want to test
    importing arbitrarily constructe, not finalized blocks, use the
    chain_without_block_validation fixture instead.
    """
    genesis_params = {
        "bloom":
        0,
        "coinbase":
        to_canonical_address("8888f1f195afa192cfee860698584c030f4c9db1"),
        "difficulty":
        131072,
        "extra_data":
        b"B",
        "gas_limit":
        3141592,
        "gas_used":
        0,
        "mix_hash":
        decode_hex(
            "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
        ),  # noqa: E501
        "nonce":
        decode_hex("0102030405060708"),
        "block_number":
        0,
        "parent_hash":
        decode_hex(
            "0000000000000000000000000000000000000000000000000000000000000000"
        ),  # noqa: E501
        "receipt_root":
        decode_hex(
            "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
        ),  # noqa: E501
        "timestamp":
        1422494849,
        "transaction_root":
        decode_hex(
            "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
        ),  # noqa: E501
        "uncles_hash":
        decode_hex(
            "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
        )  # noqa: E501
    }
    genesis_state = {
        funded_address: {
            "balance": funded_address_initial_balance,
            "nonce": 0,
            "code": b"",
            "storage": {}
        }
    }
    klass = Chain.configure(
        __name__='TestChain',
        vm_configuration=((constants.GENESIS_BLOCK_NUMBER,
                           SpuriousDragonVM), ),
        network_id=1337,
    )
    chain = klass.from_genesis(base_db, genesis_params, genesis_state)
    return chain
Example #10
0
                yield (start_block, vm_class.configure(support_dao_fork=False))
            elif dao_start_block is None:
                yield (start_block,
                       vm_class.configure(dao_fork_block_number=start_block))
            elif isinstance(dao_start_block, int):
                validate_gte(dao_start_block, start_block)
                yield (start_block,
                       vm_class.configure(
                           dao_fork_block_number=dao_start_block))
            else:
                raise Exception("Invariant: unreachable code path")
        else:
            yield (start_block, vm_class)


BaseMainnetTesterChain = Chain.configure(
    'MainnetTesterChain', vm_configuration=_generate_vm_configuration())


class MainnetTesterChain(BaseMainnetTesterChain):  # type: ignore
    """
    This class is intended to be used for in-memory test chains.  It
    explicitely bypasses the proof of work validation to allow for instant
    block mining.

    It exposes one additional API `configure_forks` to allow for in-flight
    configuration of fork rules.
    """
    def validate_seal(self, block):
        """
        We don't validate the proof of work seal on the tester chain.
        """
Example #11
0
    def mine_empty_blocks(self, chain: Chain, number_blocks: int) -> None:

        for _ in range(1, number_blocks + 1):
            block = chain.mine_block()
            logging.debug(format_block(block))