Esempio n. 1
0
def apply_block(state, block):
    # Pre-processing and verification
    snapshot = state.snapshot()
    cs = get_consensus_strategy(state.config)
    try:
        # Start a new block context
        cs.initialize(state, block)
        # Basic validation
        assert validate_header(state, block.header)
        assert cs.check_seal(state, block.header)
        assert cs.validate_uncles(state, block)
        assert validate_transaction_tree(state, block)
        # Process transactions
        for tx in block.transactions:
            apply_transaction(state, tx)
        # Finalize (incl paying block rewards)
        cs.finalize(state, block)
        # Verify state root, tx list root, receipt root
        assert verify_execution_results(state, block)
        # Post-finalize (ie. add the block header to the state for now)
        post_finalize(state, block)
    except (ValueError, AssertionError) as e:
        state.revert(snapshot)
        raise e
    return state
Esempio n. 2
0
def test_transaction(db):
    k, v, k2, v2 = accounts()
    chain = Chain({v: {"balance": utils.denoms.ether * 1}}, difficulty=1)
    blk = mine_next_block(chain)
    tx = get_transaction()
    assert tx not in blk.transactions
    messages.apply_transaction(chain.state, tx)
    assert chain.state.get_balance(v) == utils.denoms.finney * 990
    assert chain.state.get_balance(v2) == utils.denoms.finney * 10
Esempio n. 3
0
 def get_receipts(self, block):
     # Receipts are no longer stored in the database, so need to generate
     # them on the fly here.
     temp_state = self.chain.mk_poststate_of_blockhash(
         block.header.prevhash)
     initialize(temp_state, block)
     for tx in block.transactions:
         apply_transaction(temp_state, tx)
     return temp_state.receipts
def inject_tx(txhex):
    tx = rlp.decode(ethereum_utils.decode_hex(txhex[2:]), transactions.Transaction)
    chain.head_state.set_balance(tx.sender, tx.startgas * tx.gasprice)
    chain.chain.state.set_balance(tx.sender, tx.startgas * tx.gasprice)
    messages.apply_transaction(chain.head_state, tx)
    chain.block.transactions.append(tx)
    contract_address = ethereum_utils.sha3(rlp.encode([tx.sender, 0]))[12:]
    assert chain.head_state.get_code(contract_address)
    chain.mine(1)
    return contract_address
Esempio n. 5
0
 def direct_tx(self, transaction):
     self.last_tx, self.last_sender = transaction, None
     success, output = apply_transaction(self.head_state, transaction)
     self.block.transactions.append(transaction)
     if not success:
         raise TransactionFailed()
     return output
Esempio n. 6
0
def compute_state_test_unit(state, txdata, konfig):
    state.env.config = konfig
    s = state.snapshot()
    try:
        # Create the transaction
        tx = transactions.Transaction(
            nonce=parse_int_or_hex(txdata['nonce'] or b"0"),
            gasprice=parse_int_or_hex(txdata['gasPrice'] or b"0"),
            startgas=parse_int_or_hex(txdata['gasLimit'] or b"0"),
            to=decode_hex(remove_0x_head(txdata['to'])),
            value=parse_int_or_hex(txdata['value'] or b"0"),
            data=decode_hex(remove_0x_head(txdata['data'])))
        if 'secretKey' in txdata:
            tx.sign(decode_hex(remove_0x_head(txdata['secretKey'])))
        else:
            tx.v = parse_int_or_hex(txdata['v'])
        # Run it
        prev = state.to_dict()
        print("calling apply_transaction")
        success, output = apply_transaction(state, tx)
        print("Applied tx")
    except InvalidTransaction as e:
        print("Exception: %r" % e)
        success, output = False, b''
    state.commit()
    post = state.to_dict()
    output_decl = {
        "hash": '0x' + encode_hex(state.trie.root_hash),
        #"indexes": indices,
        #"diff": mk_state_diff(prev, post)
    }
    state.revert(s)
    return output_decl
Esempio n. 7
0
def make_casper_genesis(alloc, epoch_length, withdrawal_delay,
                        base_interest_factor, base_penalty_factor):
    # The Casper-specific config declaration
    casper_config = copy.deepcopy(config.default_config)
    casper_config['HOMESTEAD_FORK_BLKNUM'] = 0
    casper_config['ANTI_DOS_FORK_BLKNUM'] = 0
    casper_config['CLEARING_FORK_BLKNUM'] = 0
    casper_config['CONSENSUS_STRATEGY'] = 'hybrid_casper'
    casper_config['NULL_SENDER'] = utils.sha3('NULL_SENDER')
    casper_config['EPOCH_LENGTH'] = epoch_length
    casper_config['WITHDRAWAL_DELAY'] = withdrawal_delay
    casper_config['OWNER'] = a0
    casper_config['BASE_INTEREST_FACTOR'] = base_interest_factor
    casper_config['BASE_PENALTY_FACTOR'] = base_penalty_factor
    # Get initialization txs
    init_txs, casper_address = mk_initializers(casper_config,
                                               casper_config['NULL_SENDER'])
    casper_config['CASPER_ADDRESS'] = casper_address
    # Create state and apply required state_transitions for initializing Casper
    state = genesis_helpers.mk_basic_state(
        alloc, None, env=config.Env(config=casper_config))
    state.gas_limit = 10**8
    for tx in init_txs:
        state.set_balance(utils.privtoaddr(casper_config['NULL_SENDER']),
                          15**18)
        success, output = apply_transaction(state, tx)
        assert success
        state.gas_used = 0
        state.set_balance(utils.privtoaddr(casper_config['NULL_SENDER']), 0)
    consensus.initialize(state)
    state.commit()
    return state
Esempio n. 8
0
def compute_state_test_unit(state, txdata, indices, konfig):
    state.env.config = konfig
    s = state.snapshot()
    try:
        # Create the transaction
        tx = transactions.Transaction(
            nonce=parse_int_or_hex(txdata['nonce'] or b"0"),
            gasprice=parse_int_or_hex(txdata['gasPrice'] or b"0"),
            startgas=parse_int_or_hex(
                txdata['gasLimit'][indices["gas"]] or b"0"),
            to=decode_hex(remove_0x_head(txdata['to'])),
            value=parse_int_or_hex(txdata['value'][indices["value"]] or b"0"),
            data=decode_hex(remove_0x_head(txdata['data'][indices["data"]])))
        if 'secretKey' in txdata:
            tx.sign(decode_hex(remove_0x_head(txdata['secretKey'])))
        else:
            tx.v = parse_int_or_hex(txdata['v'])
        # Run it
        prev = state.to_dict()
        success, output = apply_transaction(state, tx)
        print("Applied tx")
    except InvalidTransaction as e:
        print("Exception: %r" % e)
        success, output = False, b''
    # state.set_code('0x3e180b1862f9d158abb5e519a6d8605540c23682', b'')
    state.commit()
    post = state.to_dict()
    # print('pozt', post)
    output_decl = {
        "hash": '0x' + encode_hex(state.trie.root_hash),
        "indexes": indices,
        "diff": mk_state_diff(prev, post)
    }
    state.revert(s)
    return output_decl
Esempio n. 9
0
 def tx(self, sender=k0, to=b'\x00' * 20, value=0,
        data=b'', startgas=STARTGAS, gasprice=GASPRICE):
     sender_addr = privtoaddr(sender)
     transaction = Transaction(self.state.get_nonce(sender_addr), gasprice, startgas,
                               to, value, data).sign(sender)
     success, output = apply_transaction(self.state, transaction)
     if not success:
         raise TransactionFailed()
     return output
Esempio n. 10
0
def add_transactions(state, block, txqueue, min_gasprice=0):
    if not txqueue:
        return
    pre_txs = len(block.transactions)
    log.info('Adding transactions, %d in txqueue, %d dunkles' %
             (len(txqueue.txs), pre_txs))
    while True:
        tx = txqueue.pop_transaction(max_gas=state.gas_limit - state.gas_used,
                                     min_gasprice=min_gasprice)
        if tx is None:
            break
        try:
            apply_transaction(state, tx)
            block.transactions.append(tx)
        except (InsufficientBalance, BlockGasLimitReached,
                InsufficientStartGas, InvalidNonce, UnsignedTransaction) as e:
            pass
    log.info('Added %d transactions' % (len(block.transactions) - pre_txs))
Esempio n. 11
0
 def direct_tx(self, transaction):
     self.last_tx = transaction
     if self.last_sender is not None and privtoaddr(
             self.last_sender) != transaction.sender:
         self.last_sender = None
     success, output = apply_transaction(self.head_state, transaction)
     self.block.transactions.append(transaction)
     if not success:
         raise TransactionFailed()
     return output
Esempio n. 12
0
            def call(this,
                     to,
                     value=0,
                     data='',
                     sender=None,
                     startgas=25000,
                     gasprice=60 * denoms.shannon):
                sender = normalize_address(sender or this.coinbase)
                to = normalize_address(to, allow_blank=True)
                block = this.head_candidate
                state_root_before = block.state_root
                assert block.prevhash == this.chain.head_hash
                # rebuild block state before finalization
                test_state = this.chain.mk_poststate_of_blockhash(
                    block.prevhash)
                initialize(test_state, block)
                for tx in block.transactions:
                    success, _ = apply_transaction(test_state, tx)
                    assert success

                # Need this because otherwise the Transaction.network_id
                # @property returns 0, which causes the tx to fail validation.
                class MockedTx(Transaction):
                    network_id = None

                # apply transaction
                nonce = test_state.get_nonce(sender)
                tx = MockedTx(nonce, gasprice, startgas, to, value, data)
                tx.sender = sender

                try:
                    success, output = apply_transaction(test_state, tx)
                except InvalidTransaction as e:
                    log.debug("error applying tx in Eth.call", exc=e)
                    success = False

                assert block.state_root == state_root_before

                if success:
                    return output
                else:
                    return False
Esempio n. 13
0
def apply_shard_transaction(mainchain_state, shard_state, shard_id, tx):
    """Apply shard transactions, including both receipt-consuming and normal
    transactions.
    """
    if ((mainchain_state is not None)
            and (shard_id is not None) and is_valid_receipt_consuming_tx(
                mainchain_state, shard_state, shard_id, tx)):
        success, output = send_msg_transfer_value(mainchain_state, shard_state,
                                                  shard_id, tx)
    else:
        success, output = apply_transaction(shard_state, tx)
    return success, output
Esempio n. 14
0
 def broadcast_deposit(self):
     if not self.valcode_tx or not self.deposit_tx:
         # Generate transactions
         valcode_tx = self.mk_validation_code_tx()
         valcode_addr = utils.mk_contract_address(self.coinbase,
                                                  self.nonce - 1)
         deposit_tx = self.mk_deposit_tx(3 * 10**18, valcode_addr)
         # Verify the transactions pass
         temp_state = self.chain.state.ephemeral_clone()
         valcode_success, o1 = apply_transaction(temp_state, valcode_tx)
         deposit_success, o2 = apply_transaction(temp_state, deposit_tx)
         if not (valcode_success and deposit_success):
             self.nonce = self.chain.state.get_nonce(self.coinbase)
             raise Exception('Valcode tx or deposit tx failed')
         self.valcode_tx = valcode_tx
         log.info('Valcode Tx generated: {}'.format(str(valcode_tx)))
         self.valcode_addr = valcode_addr
         self.deposit_tx = deposit_tx
         log.info('Deposit Tx generated: {}'.format(str(deposit_tx)))
     self.broadcast_transaction(self.valcode_tx)
     self.broadcast_transaction(self.deposit_tx)
Esempio n. 15
0
 def broadcast_logout(self, login_logout_flag):
     epoch = self.chain.state.block_number // self.epoch_length
     # Generage the message
     logout_msg = casper_utils.mk_logout(
         self.get_validator_index(self.chain.state), epoch, self.key)
     # Generate transactions
     logout_tx = self.mk_logout(logout_msg)
     # Verify the transactions pass
     temp_state = self.chain.state.ephemeral_clone()
     logout_success, o1 = apply_transaction(temp_state, logout_tx)
     if not logout_success:
         self.nonce = self.chain.state.get_nonce(self.coinbase)
         raise Exception('Valcode tx or deposit tx failed')
     log.info('Login/logout Tx generated: {}'.format(str(logout_tx)))
     self.broadcast_transaction(logout_tx)
Esempio n. 16
0
    def direct_tx(self, transaction, shard_id=None):
        if shard_id is None:
            self.last_tx, self.last_sender = transaction, None
            success, output = apply_transaction(self.head_state, transaction)
            self.block.transactions.append(transaction)
        else:
            self.shard_last_tx[shard_id], self.shard_last_sender[
                shard_id] = transaction, None
            assert self.chain.has_shard(shard_id)
            success, output = apply_shard_transaction(
                self.head_state, self.shard_head_state[shard_id], shard_id,
                transaction)
            self.collation[shard_id].transactions.append(transaction)

        if not success:
            raise TransactionFailed()
        return output
Esempio n. 17
0
def initialize(state, block=None):
    config = state.config

    state.txindex = 0
    state.gas_used = 0
    state.bloom = 0
    state.receipts = []

    if block is not None:
        update_block_env_variables(state, block)

    # Initalize the next epoch in the Casper contract
    if state.block_number % state.config[
            'EPOCH_LENGTH'] == 0 and state.block_number != 0:
        key, account = state.config['NULL_SENDER'], privtoaddr(
            state.config['NULL_SENDER'])
        data = casper_utils.casper_translator.encode(
            'initialize_epoch',
            [state.block_number // state.config['EPOCH_LENGTH']])
        transaction = transactions.Transaction(state.get_nonce(account), 0,
                                               3141592,
                                               state.config['CASPER_ADDRESS'],
                                               0, data).sign(key)
        success, output = apply_transaction(state, transaction)
        assert success

    if state.is_DAO(at_fork_height=True):
        for acct in state.config['CHILD_DAO_LIST']:
            state.transfer_value(acct, state.config['DAO_WITHDRAWER'],
                                 state.get_balance(acct))

    if state.is_METROPOLIS(at_fork_height=True):
        state.set_code(
            utils.normalize_address(config["METROPOLIS_STATEROOT_STORE"]),
            config["METROPOLIS_GETTER_CODE"])
        state.set_code(
            utils.normalize_address(config["METROPOLIS_BLOCKHASH_STORE"]),
            config["METROPOLIS_GETTER_CODE"])
Esempio n. 18
0
def conBench(state, exek, curr_row, _nonce, index):
    ################################### Start contracts' benchmarking ###################################

    Ugas = 0
    exTime = []
    gasUsed = []
    minTime = 0
    maxTime = 0
    avgTime = 0
    medTime = 0
    stdevTime = 0
    CITime = 0
    type = "Execution"

    #### prepare creation & execution bytecodes for benchmarking ####
    if worksheet.cell_value(curr_row, 5) != "":
        creation_bytecode = worksheet.cell_value(
            curr_row, 4) + worksheet.cell_value(curr_row, 5)
    else:
        creation_bytecode = worksheet.cell_value(curr_row, 4)
    if worksheet.cell_value(curr_row, 7) != "":
        execution_bytecode = worksheet.cell_value(
            curr_row, 6) + worksheet.cell_value(curr_row, 7)
    else:
        execution_bytecode = worksheet.cell_value(curr_row, 6)

    ##### if transaction is to invoke a contract, we first need to deploy the contract #####
    if creation_bytecode != "Contract Creation":
        try:
            tx1 = transactions.Transaction(nonce=_nonce,
                                           gasprice=int(exek['gasPrice']),
                                           startgas=int(exek['gas']),
                                           to="",
                                           value=0,
                                           data=codecs.decode(
                                               creation_bytecode[2:], 'hex'),
                                           r=1,
                                           s=2,
                                           v=27)
            tx1._sender = exek['origin']
            _nonce = _nonce + 1
            success, address, t, g = pb.apply_transaction(state, tx1)
            if g > blockLimit:
                success = 0
                address = ""
        except Exception:
            success = 0
            address = ""
            pass

    elif creation_bytecode == "Contract Creation":  # if transaction is to create a contract, make address empty and pass for next test
        type = "Creation"
        address = ""
        success = 1

    #################### test transaction execution ########################
    ################ test if execution works or not, before conducting the benchmark #######################
    if success == 1:  # if contract was crteated successfully
        try:
            tx2 = transactions.Transaction(nonce=_nonce,
                                           gasprice=int(exek['gasPrice']),
                                           startgas=int(exek['gas']),
                                           to=address,
                                           value=0,
                                           data=codecs.decode(
                                               execution_bytecode[2:], 'hex'),
                                           r=1,
                                           s=2,
                                           v=27)
            tx2._sender = exek['origin']
            success1, output1, t, g = pb.apply_transaction(state, tx2)
            if g > blockLimit: success1 = 0
        except Exception:
            success1 = 0
            pass
        _nonce = _nonce + 1

        #################### transactions' benchmarking ########################
        if success1 == 1:  # if contract was created successfully  or if transaction is to create a new contract
            if type == "creation": address = ""
            attempts = 0
            while attempts < 10:  # attempt the benchmark up to 10 times if confidence interval is more than 2% of the average value
                exTime = []
                gasUsed = []
                for i in range(num_runs):
                    try:
                        txInvoke = transactions.Transaction(
                            nonce=_nonce,
                            gasprice=int(exek['gasPrice']),
                            startgas=int(exek['gas']),
                            to=address,
                            value=0,
                            data=codecs.decode(execution_bytecode[2:], 'hex'),
                            r=1,
                            s=2,
                            v=27)
                        txInvoke._sender = exek['origin']
                        success2, output2, time, gas = pb.apply_transaction(
                            state, txInvoke)
                        if gas > blockLimit:
                            gas = 0
                            time = 0
                    except Exception:
                        time = 0
                        gas = 0
                        pass

                    _nonce = _nonce + 1
                    exTime.append(time)
                    gasUsed.append(gas)

                minTime = round(min(exTime), 0)
                maxTime = round(max(exTime), 0)
                avgTime = round(np.mean(exTime), 0)
                medTime = round(statistics.median(exTime), 0)
                stdevTime = round(statistics.stdev(exTime), 0)
                if min(gasUsed) == max(gasUsed):
                    Ugas = max(gasUsed)
                else:
                    Ugas = 0
                CITime = mean_confidence_interval(exTime)

                if Ugas != 0 and (CITime / avgTime * 100) > 2.0:
                    attempts += 1
                else:
                    break

    result[index][0] = worksheet.cell_value(curr_row, 1)
    result[index][1] = type
    result[index][2] = Ugas
    result[index][3] = minTime
    result[index][4] = maxTime
    result[index][5] = avgTime
    result[index][6] = medTime
    result[index][7] = stdevTime
    result[index][8] = CITime