Beispiel #1
0
    def _deploy_simple_token(self, chain: MiningChain) -> 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_tx = 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_tx['data']),
        )
        logging.debug(f'Applying Transaction {tx}')
        block, receipt, computation = chain.apply_transaction(tx)
        # Keep track of deployed contract address
        self.deployed_contract_address = computation.msg.storage_address

        assert computation.is_success
        # Keep track of simple_token object
        self.simple_token = self.w3.eth.contract(
            address=Web3.toChecksumAddress(
                encode_hex(self.deployed_contract_address)),
            abi=self.contract_interface['abi'],
        )
Beispiel #2
0
    def deploy_dos_contract(self, chain: MiningChain) -> None:
        # Instantiate the contract
        dos_contract = self.w3.eth.contract(
            abi=self.contract_interface['abi'],
            bytecode=self.contract_interface['bin']
        )

        # Build transaction to deploy the contract
        w3_tx1 = dos_contract.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(f'Applying Transaction {tx}')

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

        assert computation.is_success

        # Interact with the deployed contract by calling the totalSupply() API ?????
        self.dos_contract = self.w3.eth.contract(
            address=Web3.toChecksumAddress(encode_hex(self.deployed_contract_address)),
            abi=self.contract_interface['abi'],
        )
Beispiel #3
0
def mine_blocks(num_blocks: int, chain: MiningChain) -> MiningChain:
    """
    Variadic argument version of :func:`~eth.tools.builder.chain.mine_block`
    """
    if not isinstance(chain, MiningChain):
        raise ValidationError('`mine_block` may only be used on MiningChain instances')
    for _ in range(num_blocks):
        chain.mine_block()
    return chain
Beispiel #4
0
def mine_block(chain: MiningChain, **kwargs: Any) -> MiningChain:
    """
    Mine a new block on the chain.  Header parameters for the new block can be
    overridden using keyword arguments.

    """
    if not isinstance(chain, MiningChain):
        raise ValidationError('`mine_block` may only be used on MiningChain instances')
    chain.mine_block(**kwargs)
    return chain
Beispiel #5
0
def at_block_number(block_number: BlockNumber, chain: MiningChain) -> MiningChain:
    """
    Rewind the chain back to the given block number.  Calls to things like
    ``get_canonical_head`` will still return the canonical head of the chain,
    however, you can use ``mine_block`` to mine fork chains.
    """
    if not isinstance(chain, MiningChain):
        raise ValidationError("`at_block_number` may only be used with 'MiningChain")
    at_block = chain.get_canonical_block_by_number(block_number)

    db = chain.chaindb.db
    chain_at_block = type(chain)(db, chain.create_header_from_parent(at_block.header))
    return chain_at_block
Beispiel #6
0
    def sstore_uint64_revert(self, chain: MiningChain) -> None:
        w3_tx4 = self.dos_contract.functions.storageEntropyRevert().buildTransaction(W3_TX_DEFAULTS)

        tx4 = new_transaction(
            vm=chain.get_vm(),
            private_key=FUNDED_ADDRESS_PRIVATE_KEY,
            from_=FUNDED_ADDRESS,
            to=self.deployed_contract_address,
            amount=0,
            gas=FORTH_TX_GAS_LIMIT,
            data=decode_hex(w3_tx4['data']),
        )

        block, receipt, computation = chain.apply_transaction(tx4)
Beispiel #7
0
    def apply_transaction(self, chain: MiningChain) -> 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
Beispiel #8
0
    def create_empty_contract_revert(self, chain: MiningChain) -> None:
        w3_tx5 = self.dos_contract.functions.createEmptyContractRevert().buildTransaction(
            W3_TX_DEFAULTS)

        tx5 = new_transaction(
            vm=chain.get_vm(),
            private_key=FUNDED_ADDRESS_PRIVATE_KEY,
            from_=FUNDED_ADDRESS,
            to=self.deployed_contract_address,
            amount=0,
            gas=FIFTH_TX_GAS_LIMIT,
            data=decode_hex(w3_tx5['data']),
        )

        block, receipt, computation = chain.apply_transaction(tx5)
    def next_transaction(self, chain: MiningChain) -> 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'',
            nonce=self._next_nonce,
        )
        logging.debug(f'Built Transaction {tx}')

        self._next_nonce = tx.nonce + 1

        def callback(receipt, computation) -> None:
            logging.debug(f'Receipt {receipt}')
            logging.debug(f'Computation {computation}')

        return tx, callback
Beispiel #10
0
def get_eth1_shell_context(
        database_dir: Path,
        trinity_config: TrinityConfig) -> Iterator[Dict[str, Any]]:
    app_config = trinity_config.get_app_config(Eth1AppConfig)
    ipc_path = trinity_config.database_ipc_path
    trinity_already_running = ipc_path.exists()

    with _get_base_db(database_dir, ipc_path) as db:
        chaindb = ChainDB(db)
        head = chaindb.get_canonical_head()
        chain_config = app_config.get_chain_config()
        chain = chain_config.full_chain_class(db)

        mining_chain_class = MiningChain.configure(
            __name__=chain_config.full_chain_class.__name__,
            vm_configuration=chain.vm_configuration,
            consensus_context_class=chain.consensus_context_class,
            chain_id=chain.chain_id,
        )
        mining_chain = mining_chain_class(db)
        yield {
            'db': db,
            'chaindb': chaindb,
            'trinity_config': trinity_config,
            'chain_config': chain_config,
            'chain': chain,
            'mining_chain': mining_chain,
            'block_number': head.block_number,
            'hex_hash': head.hex_hash,
            'state_root_hex': encode_hex(head.state_root),
            'trinity_already_running': trinity_already_running,
        }
Beispiel #11
0
def chain_without_block_validation(
        base_db,
        genesis_state):
    """
    Return a Chain object containing just the genesis block.

    This Chain does not perform any validation when importing new blocks.

    The Chain's state includes one funded account and a private key for it,
    which can be found in the funded_address and private_keys variables in the
    chain itself.
    """
    klass = MiningChain.configure(
        __name__='TestChainWithoutBlockValidation',
        vm_configuration=ConsensusApplier(NoProofConsensus).amend_vm_configuration(
            (
                (eth_constants.GENESIS_BLOCK_NUMBER, SpuriousDragonVM),
            )
        ),
        chain_id=1337,
    )
    genesis_params = {
        'block_number': eth_constants.GENESIS_BLOCK_NUMBER,
        'difficulty': eth_constants.GENESIS_DIFFICULTY,
        'gas_limit': 3141592,
        'parent_hash': eth_constants.GENESIS_PARENT_HASH,
        'coinbase': eth_constants.GENESIS_COINBASE,
        'nonce': eth_constants.GENESIS_NONCE,
        'mix_hash': eth_constants.GENESIS_MIX_HASH,
        'extra_data': eth_constants.GENESIS_EXTRA_DATA,
        'timestamp': 1501851927,
    }
    chain = klass.from_genesis(base_db, genesis_params, genesis_state)
    return chain
Beispiel #12
0
 def _setup_benchmark(self, chain: MiningChain) -> None:
     self._next_nonce = None
     txn, callback = self._deploy_simple_token(chain)
     _, receipts, computations = chain.mine_all([txn])
     assert len(receipts) == 1
     assert len(computations) == 1
     callback(receipts[0], computations[0])
Beispiel #13
0
    def _deploy_simple_token(self,
                             chain: MiningChain,
                             nonce: int = None) -> 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_tx = 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_tx['data']),
            nonce=nonce,
        )

        def callback(receipt, computation) -> None:
            computation.raise_if_error()

            # Keep track of deployed contract address
            self.deployed_contract_address = computation.msg.storage_address

            # Keep track of simple_token object
            self.simple_token = self.w3.eth.contract(
                address=Web3.toChecksumAddress(
                    encode_hex(self.deployed_contract_address)),
                abi=self.contract_interface['abi'],
            )

        return tx, callback
Beispiel #14
0
    def _erc_transfer_from(self,
                           addr1: str,
                           addr2: str,
                           chain: MiningChain,
                           nonce: int = None) -> None:

        w3_tx = self.simple_token.functions.transferFrom(
            addr1, addr2, TRANSER_FROM_AMOUNT).buildTransaction(W3_TX_DEFAULTS)

        tx = new_transaction(
            vm=chain.get_vm(),
            private_key=SECOND_ADDRESS_PRIVATE_KEY,
            from_=SECOND_ADDRESS,
            to=self.deployed_contract_address,
            amount=0,
            gas=SECOND_TX_GAS_LIMIT,
            data=decode_hex(w3_tx['data']),
            nonce=nonce,
        )

        def callback(receipt, computation) -> None:
            computation.raise_if_error()
            assert computation.output == b'\0' * 31 + b'\x01', computation.output

        return tx, callback
Beispiel #15
0
    def mine_block(self, chain: MiningChain, block_number: int,
                   num_tx: int) -> BaseBlock:

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

        return chain.mine_block()
Beispiel #16
0
def get_eth1_shell_context(database_dir: Path, trinity_config: TrinityConfig) -> Dict[str, Any]:
    app_config = trinity_config.get_app_config(Eth1AppConfig)
    ipc_path = trinity_config.database_ipc_path

    db: DatabaseAPI

    trinity_already_running = ipc_path.exists()
    if trinity_already_running:
        db = DBClient.connect(ipc_path)
    else:
        db = LevelDB(database_dir)

    chaindb = ChainDB(db)
    head = chaindb.get_canonical_head()
    chain_config = app_config.get_chain_config()
    chain = chain_config.full_chain_class(db)

    mining_chain_class = MiningChain.configure(
        __name__=chain_config.full_chain_class.__name__,
        vm_configuration=chain.vm_configuration,
        chain_id=chain.chain_id,
    )
    mining_chain = mining_chain_class(db)
    return {
        'db': db,
        'chaindb': chaindb,
        'trinity_config': trinity_config,
        'chain_config': chain_config,
        'chain': chain,
        'mining_chain': mining_chain,
        'block_number': head.block_number,
        'hex_hash': head.hex_hash,
        'state_root_hex': encode_hex(head.state_root),
        'trinity_already_running': trinity_already_running,
    }
Beispiel #17
0
    def _setup_benchmark(self, chain: MiningChain) -> None:
        self._next_nonce = None
        txn, callback = self._deploy_simple_token(chain)
        _, receipts, computations = chain.mine_all([txn])
        assert len(receipts) == 1
        assert len(computations) == 1
        callback(receipts[0], computations[0])

        actions = [
            self._erc_transfer(self.addr1, chain, nonce=1),
            self._erc_approve(self.addr2, chain, nonce=2),
        ]
        transactions, callbacks = zip(*actions)
        _, receipts, computations = chain.mine_all(transactions)

        for callback, receipt, computation in zip(callbacks, receipts,
                                                  computations):
            callback(receipt, computation)
Beispiel #18
0
    def _erc_approve(self, addr2: str, chain: MiningChain) -> None:
        w3_tx = self.simple_token.functions.approve(
            addr2, TRANSFER_AMOUNT).buildTransaction(W3_TX_DEFAULTS)

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

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

        assert computation.is_success
        assert to_int(computation.output) == 1
Beispiel #19
0
def chain_without_pow(base_db: AtomicDB, vm: Type[BaseVM], genesis_params: Any,
                      genesis_state: Any) -> MiningChain:

    vm_without_pow = vm.configure(validate_seal=lambda block: None)

    klass = MiningChain.configure(
        __name__='TestChain',
        vm_configuration=((constants.GENESIS_BLOCK_NUMBER, vm_without_pow), ))
    chain = klass.from_genesis(base_db, genesis_params, genesis_state)
    return chain
Beispiel #20
0
    def mine_blocks(self, chain: MiningChain, 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
Beispiel #21
0
    def mine_block(self, chain: MiningChain, block_number: int,
                   num_tx: int) -> BaseBlock:
        transactions, callbacks = zip(*(self._next_transaction(chain)
                                        for _ in range(num_tx)))

        mining_result, receipts, computations = chain.mine_all(transactions)

        for callback, receipt, computation in zip(callbacks, receipts,
                                                  computations):
            callback(receipt, computation)

        return mining_result
    def apply_transaction(self, chain: MiningChain) -> 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))
    def _erc_transfer_from(self, addr1: str, addr2: str,
                           chain: MiningChain) -> None:

        w3_tx = self.simple_token.functions.transferFrom(
            addr1, addr2, TRANSER_FROM_AMOUNT).buildTransaction(W3_TX_DEFAULTS)

        tx = new_transaction(
            vm=chain.get_vm(),
            private_key=SECOND_ADDRESS_PRIVATE_KEY,
            from_=SECOND_ADDRESS,
            to=self.deployed_contract_address,
            amount=0,
            gas=SECOND_TX_GAS_LIMIT,
            data=decode_hex(w3_tx['data']),
        )

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

        computation.raise_if_error()

        assert to_int(computation.output) == 1
def goerli_chain(base_db):

    vms = ((
        0,
        PetersburgVM,
    ), )
    clique_vms = CliqueApplier().amend_vm_configuration(vms)

    chain = MiningChain.configure(
        vm_configuration=clique_vms,
        consensus_context_class=CliqueConsensusContext,
        chain_id=5,
    ).from_genesis_header(base_db, GOERLI_GENESIS_HEADER)
    return chain
Beispiel #25
0
def main():
    args = parse_args()
    # print('Called with args:')
    # print(args)

    # genesis address
    init_address = to_canonical_address(
        "8888f1f195afa192cfee860698584c030f4c9db1")
    base_state = base_genesis_state(init_address,
                                    funded_address_initial_balance())

    # just an address
    simple_contract_address = create_simple_contract_address()

    # create chain
    klass = MiningChain.configure(
        __name__='MyTestChain',
        vm_configuration=((constants.GENESIS_BLOCK_NUMBER,
                           SpuriousDragonVM), ),
        network_id=1337,
    )
    chain = klass.from_genesis(
        MemoryDB(), GENESIS_PARAMS,
        genesis_state(base_state, simple_contract_address, args.data))

    # TODO
    # signature = 'getMeaningOfLife()'  # function name
    # function_selector = function_signature_to_4byte_selector(signature)
    '''
		new_transaction(
		    vm,
		    from_,
		    to,
		    amount=0,
		    private_key=None,
		    gas_price=10,
		    gas=100000,
		    data=b''
		)
    '''
    call_txn = new_transaction(
        chain.get_vm(),
        SENDER,
        simple_contract_address,
        gas_price=0,
        # data=function_selector,
        data=decode_hex(args.signature),
    )
    result_bytes = chain.get_transaction_result(call_txn,
                                                chain.get_canonical_head())
Beispiel #26
0
def _configure_mining_chain(starting_vm, vm_under_test):
    return MiningChain.configure(
        __name__="AllVMs",
        vm_configuration=(
            (
                constants.GENESIS_BLOCK_NUMBER,
                starting_vm.configure(consensus_class=NoProofConsensus),
            ),
            (
                constants.GENESIS_BLOCK_NUMBER + 1,
                vm_under_test.configure(consensus_class=NoProofConsensus),
            ),
        ),
        chain_id=1337,
    )
Beispiel #27
0
 def make_chain(self):
     klass = MiningChain.configure(
         __name__='Shard{}Chain'.format(self.shard_id),
         vm_configuration=((constants.GENESIS_BLOCK_NUMBER, ByzantiumVM), ))
     self.chain = klass.from_genesis(AtomicDB(), self.genesis_params,
                                     self.genesis_state)
     self.vm = self.chain.get_vm()
     print("Shard " + str(self.shard_id) + " was initialized")
     print("Parent Shard ID:", self.parent_id)
     print("Child Shard IDs:", self.child_ids)
     print("\tAccounts on this shard are:")
     for address in self.accounts['addresses']:
         print("\t\t", encode_hex(address))
     print("\tMagic Account is:")
     print("\t\t", encode_hex(MAGIC_ADDRESS))
     return self.chain
Beispiel #28
0
def paragon_chain_with_clique(base_db):

    vms = ((
        0,
        PetersburgVM,
    ), )

    clique = CliqueConsensus(base_db)

    vms = clique.amend_vm_configuration(vms)

    chain = MiningChain.configure(
        vm_configuration=vms,
        chain_id=5,
    ).from_genesis(base_db, PARAGON_GENESIS_PARAMS, PARAGON_GENESIS_STATE)
    return chain, clique
def paragon_chain(base_db):

    vms = ((
        0,
        PetersburgVM,
    ), (
        2,
        IstanbulVM,
    ))
    clique_vms = CliqueApplier().amend_vm_configuration(vms)

    chain = MiningChain.configure(
        vm_configuration=clique_vms,
        consensus_context_class=CliqueConsensusContext,
        chain_id=5,
    ).from_genesis(base_db, PARAGON_GENESIS_PARAMS, PARAGON_GENESIS_STATE)
    return chain
Beispiel #30
0
def vm_crossover_chain(request, base_db, genesis_state):
    start_vm, end_vm = request.param
    klass = MiningChain.configure(
        __name__='CrossoverTestChain',
        vm_configuration=(
            (
                constants.GENESIS_BLOCK_NUMBER,
                start_vm.configure(consensus_class=NoProofConsensus),
            ),
            # Can mine one block of the first VM, then the next block with be the next VM
            (
                constants.GENESIS_BLOCK_NUMBER + 2,
                end_vm.configure(consensus_class=NoProofConsensus),
            ),
        ),
        chain_id=1337,
    )
    return klass.from_genesis(base_db, dict(difficulty=1), genesis_state)