Beispiel #1
0
    def test_if_enough_time_passed_since_last_play_then_grant_earnings_to_last_player(
            self):

        # Player 1 presses the button
        result = self.contract.process(MIN_AMOUNT_REQUIRED,
                                       value=140,
                                       sender=t.k0)
        self.assertEquals(result, 1)

        self.state.mine(1)

        winningBalanceBefore = State().get_balance(u.int_to_addr(t.k1))
        losingBalanceBefore = State().get_balance(u.int_to_addr(t.k0))

        # Player 2 presses the button
        result = self.contract.process(MIN_AMOUNT_REQUIRED,
                                       value=140,
                                       sender=t.k1)
        self.assertEquals(result, 1)

        self.state.mine(3)

        # Player 2 presses the button again
        result = self.contract.process(MIN_AMOUNT_REQUIRED,
                                       value=140,
                                       sender=t.k1)
        self.assertEquals(result, 2)

        winningBalanceAfter = State().get_balance(u.int_to_addr(t.k1))
        losingBalanceAfter = State().get_balance(u.int_to_addr(t.k0))

        self.assertEquals(losingBalanceAfter, losingBalanceBefore)
        self.assertTrue(winningBalanceAfter > losingBalanceBefore)
Beispiel #2
0
def test_send_transaction_with_contract(test_app):
    serpent_code = '''
def main(a,b):
    return(a ^ b)
'''
    tx_to = b''
    evm_code = serpent.compile(serpent_code)
    chain = test_app.services.chain.chain
    chainservice = test_app.services.chain
    hc_state = State(chainservice.head_candidate.state_root, chain.env)
    sender = test_app.services.accounts.unlocked_accounts[0].address
    assert hc_state.get_balance(sender) > 0

    eth = test_app.services.console.console_locals['eth']
    tx = eth.transact(to='', data=evm_code, startgas=500000, sender=sender)

    hc_state_dict = State(chainservice.head_candidate.state_root,
                          chain.env).to_dict()
    code = hc_state_dict[encode_hex(tx.creates)]['code']
    assert len(code) > 2
    assert code != '0x'

    test_app.mine_next_block()

    creates = chain.head.transactions[0].creates
    code = chain.state.to_dict()[encode_hex(creates)]['code']
    assert len(code) > 2
    assert code != '0x'
Beispiel #3
0
def test_send_transaction_with_contract(test_app):
    serpent_code = '''
def main(a,b):
    return(a ^ b)
'''
    tx_to = b''
    evm_code = serpent.compile(serpent_code)
    chainservice = test_app.services.chain
    chain = test_app.services.chain.chain
    state = State(chainservice.head_candidate.state_root, chain.env)
    sender = test_app.services.accounts.unlocked_accounts[0].address
    assert state.get_balance(sender) > 0
    tx = {
        'from': address_encoder(sender),
        'to': address_encoder(tx_to),
        'data': encode_hex(evm_code)
    }
    data_decoder(test_app.client.call('eth_sendTransaction', tx))
    assert len(chainservice.head_candidate.transactions) == 1
    creates = chainservice.head_candidate.transactions[0].creates

    candidate_state_dict = State(chainservice.head_candidate.state_root,
                                 chain.env).to_dict()
    code = candidate_state_dict[encode_hex(creates)]['code']
    assert len(code) > 2
    assert code != '0x'

    test_app.mine_next_block()

    assert len(chain.head.transactions) == 1
    creates = chain.head.transactions[0].creates
    state_dict = State(chain.head.state_root, chain.env).to_dict()
    code = state_dict[encode_hex(creates)]['code']
    assert len(code) > 2
    assert code != '0x'
Beispiel #4
0
def test_genesis_config():
    "test setting genesis alloc using the config"
    alloc = {
        '1' * 40: {
            'wei': 1
        },  # wei
        '2' * 40: {
            'balance': 2
        },  # balance
        '3' * 20: {
            'balance': 3
        },  # 20 bytes
    }
    config = dict(eth=dict(genesis=dict(alloc=alloc)))
    konfig.update_config_with_defaults(config,
                                       {'eth': {
                                           'block': default_config
                                       }})

    # Load genesis config
    update_config_from_genesis_json(config, config['eth']['genesis'])

    bc = config['eth']['block']
    pprint(bc)
    env = Env(DB(), bc)

    genesis = mk_genesis_block(env)
    state = State(genesis.state_root, env)
    for address, value_dict in list(alloc.items()):
        value = list(value_dict.values())[0]
        assert state.get_balance(address) == value
Beispiel #5
0
    def post(self):
        try:
            App = _eth_worker.App
            parser = reqparse.RequestParser()
            parser.add_argument('account', type=str)
            args = parser.parse_args()

            # do something this values
            _accounts = App.services.accounts.accounts
            account_index = ENUMS[args['account']]
            account_info = _accounts[account_index]

            block_head = App.services.chain.chain.head
            state = State(block_head.state_root, App.services.chain.chain.env)
            log.info(state.get_balance(account_info.address))
            balance_amount = int(
                state.get_balance(account_info.address) / 10**22)

            # TODO: account info parsing
            return {
                'status': 200,
                'pubkey': account_info.pubkey[0],
                'balance_amount': balance_amount
            }

        except Exception as e:
            return {'error': str(e)}
Beispiel #6
0
def get_contract_code(init_code):
    s = State(env=Env(config=casper_config))
    s.gas_limit = 10**9
    apply_transaction(s, Transaction(0, 0, 10**8, '', 0, init_code))
    addr = utils.mk_metropolis_contract_address(
        casper_config['METROPOLIS_ENTRY_POINT'], init_code)
    o = s.get_code(addr)
    assert o
    return o
Beispiel #7
0
def test_console_name_reg_contract(test_app, solidity_code):
    """
    exercise the console service with the NameReg contract found in The_Console wiki
    https://github.com/ethereum/pyethapp/wiki/The_Console#creating-contracts
    """

    import ethereum.tools._solidity

    solidity = ethereum.tools._solidity.get_solidity()
    if solidity is None:
        pytest.xfail("solidity not installed, not tested")
    else:
        # create the NameReg contract
        tx_to = b''
        evm_code = solidity.compile(solidity_code)
        chainservice = test_app.services.chain
        chain = test_app.services.chain.chain
        hc_state = State(chainservice.head_candidate.state_root, chain.env)
        sender = test_app.services.accounts.unlocked_accounts[0].address
        assert hc_state.get_balance(sender) > 0

        eth = test_app.services.console.console_locals['eth']
        tx = eth.transact(to='', data=evm_code, startgas=500000, sender=sender)

        hc_state_dict = State(chainservice.head_candidate.state_root,
                              chain.env).to_dict()
        code = hc_state_dict[encode_hex(tx.creates)]['code']
        assert len(code) > 2
        assert code != '0x'

        test_app.mine_next_block()

        creates = chain.head.transactions[0].creates
        state_dict = chain.state.to_dict()
        code = state_dict[encode_hex(creates)]['code']
        assert len(code) > 2
        assert code != '0x'

        # interact with the NameReg contract
        abi = solidity.mk_full_signature(solidity_code)
        namereg = eth.new_contract(abi, creates, sender=sender)

        register_tx = namereg.register('alice',
                                       startgas=90000,
                                       gasprice=50 * 10**9)

        test_app.mine_next_block()

        result = namereg.resolve(sender)
        assert result == b'alice' + ('\x00' * 27).encode()
Beispiel #8
0
def make_head_candidate(chain,
                        txqueue=None,
                        parent=None,
                        timestamp=None,
                        coinbase='\x35' * 20,
                        extra_data='moo ha ha says the laughing cow.',
                        min_gasprice=0):
    log.info('Creating head candidate')
    if parent is None:
        temp_state = State.from_snapshot(
            chain.state.to_snapshot(root_only=True), chain.env)
    else:
        temp_state = chain.mk_poststate_of_blockhash(parent.hash)

    cs = get_consensus_strategy(chain.env.config)
    # Initialize a block with the given parent and variables
    blk = mk_block_from_prevstate(chain, temp_state, timestamp, coinbase,
                                  extra_data)
    # Find and set the uncles
    blk.uncles = cs.get_uncles(chain, temp_state)
    blk.header.uncles_hash = sha3(rlp.encode(blk.uncles))
    # Call the initialize state transition function
    cs.initialize(temp_state, blk)
    # Add transactions
    add_transactions(temp_state, blk, txqueue, min_gasprice)
    # Call the finalize state transition function
    cs.finalize(temp_state, blk)
    # Set state root, receipt root, etc
    set_execution_results(temp_state, blk)
    log.info('Created head candidate successfully')
    return blk, temp_state
def test_update_collation_env_variables():
    """Test update_collation_env_variables(state, collation)
    """
    collation = Collation(CollationHeader(coinbase=tester.a2))
    state = State()
    state_transition.update_collation_env_variables(state, collation)
    assert state.block_coinbase == tester.a2
Beispiel #10
0
 def transact(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)
     state = State(this.head_candidate.state_root, this.chain.env)
     nonce = state.get_nonce(sender)
     tx = Transaction(nonce, gasprice, startgas, to, value, data)
     this.app.services.accounts.sign_tx(sender, tx)
     assert tx.sender == sender
     this.chainservice.add_transaction(tx)
     return tx
Beispiel #11
0
def trace(code, calldata=""):
    log_handlers = [
        "eth.vm.op",
        "eth.vm.op.stack",
        "eth.vm.op.memory",
        "eth.vm.op.storage",
    ]
    output = StringIO()
    stream_handler = StreamHandler(output)

    for handler in log_handlers:
        log_vm_op = get_logger(handler)
        log_vm_op.setLevel("TRACE")
        log_vm_op.addHandler(stream_handler)

    addr = bytes.fromhex("0123456789ABCDEF0123456789ABCDEF01234567")
    state = State()

    ext = messages.VMExt(state,
                         transactions.Transaction(0, 0, 21000, addr, 0, addr))
    message = vm.Message(addr, addr, 0, 21000, calldata)
    vm.vm_execute(ext, message, util.safe_decode(code))
    stream_handler.flush()
    ret = output.getvalue()
    lines = ret.split("\n")

    state_trace = []
    for line in lines:
        m = re.search(r"pc=b\'(\d+)\'.*op=([A-Z0-9]+)", line)
        if m:
            pc = m.group(1)
            op = m.group(2)
            m = re.match(r".*stack=(\[.*?\])", line)

            if m:
                stackitems = re.findall(r"b\'(\d+)\'", m.group(1))
                stack = "["

                if len(stackitems):
                    for i in range(0, len(stackitems) - 1):
                        stack += hex(int(stackitems[i])) + ", "
                    stack += hex(int(stackitems[-1]))

                stack += "]"
            else:
                stack = "[]"

            if re.match(r"^PUSH.*", op):
                val = re.search(r"pushvalue=(\d+)", line).group(1)
                pushvalue = hex(int(val))
                state_trace.append({
                    "pc": pc,
                    "op": op,
                    "stack": stack,
                    "pushvalue": pushvalue
                })
            else:
                state_trace.append({"pc": pc, "op": op, "stack": stack})

    return state_trace
Beispiel #12
0
def trace(code, address = "", calldata = ""):

	logHandlers = ['eth.vm.op', 'eth.vm.op.stack', 'eth.vm.op.memory', 'eth.vm.op.storage']

	output = StringIO()
	streamHandler = StreamHandler(output)

	for handler in logHandlers:
		log_vm_op = get_logger(handler)
		log_vm_op.setLevel("TRACE")
		log_vm_op.addHandler(streamHandler)

	addr_from = codecs.decode('0123456789ABCDEF0123456789ABCDEF01234567', 'hex_codec')
	addr_to = safe_decode(address)

	state = State()

	ext = messages.VMExt(state, transactions.Transaction(0, 0, 21000, addr_from, 0, addr_to))

	message = vm.Message(addr_from, addr_to, 0, 21000, calldata, code_address=addr_to)

	res, gas, dat = vm.vm_execute(ext, message, code)

	streamHandler.flush()

	# print(output.getvalue())

	ret = output.getvalue()

	return ret
def send_transaction(app, sender_id, receiver_id,value):
    chain = app.services.chain.chain
    chainservice = app.services.chain

    hc_state = State(chainservice.head_candidate.state_root, chain.env)
    sender = app.services.accounts.unlocked_accounts[sender_id].address
    receiver = app.services.accounts.unlocked_accounts[receiver_id].address
    print sender
    print type(sender)

    assert hc_state.get_balance(sender) > 0

    eth = app.services.console.console_locals['eth']
    tx = eth.transact(to=receiver, value=value, startgas=500000, sender=sender)

    return tx
Beispiel #14
0
def create_state_snapshot(chain, block):
    env = chain.env
    state = State(block.state_root, env)
    alloc = dict()
    count = 0
    for addr, account_rlp in state.trie.iter_branch():
        alloc[encode_hex(addr)] = create_account_snapshot(env, account_rlp)
        count += 1
        print("[%d] created account snapshot %s" % (count, encode_hex(addr)))
    return alloc
def test_set_execution_results():
    """Test set_execution_results(state, collation)
    """
    collation = Collation(CollationHeader(coinbase=tester.a2))
    state = State()
    state_transition.set_execution_results(state, collation)
    assert collation.header.receipts_root == mk_receipt_sha(state.receipts)
    assert collation.header.tx_list_root == mk_transaction_sha(
        collation.transactions)
    assert collation.header.post_state_root == state.trie.root_hash
Beispiel #16
0
def test_send_transaction_with_contract(test_app, serpent_code, sender_id,
                                        receiver_id):
    evm_code = serpent.compile(serpent_code)
    chain = test_app.services.chain.chain
    chainservice = test_app.services.chain
    hc_state = State(chainservice.head_candidate.state_root, chain.env)
    sender = test_app.services.accounts.unlocked_accounts[sender_id].address
    receiver = test_app.services.accounts.unlocked_accounts[
        receiver_id].address
    print sender
    print type(sender)

    assert hc_state.get_balance(sender) > 0

    eth = test_app.services.console.console_locals['eth']
    tx = eth.transact(to=receiver,
                      value=1,
                      data=evm_code,
                      startgas=500000,
                      sender=sender)

    test_app.mine_next_block()
    return tx
Beispiel #17
0
def test_send_transaction(test_app):
    chainservice = test_app.services.chain
    chain = chainservice.chain
    hc = chainservice.head_candidate
    state = State(hc.state_root, chain.env)
    assert state.get_balance(b'\xff' * 20) == 0
    sender = test_app.services.accounts.unlocked_accounts[0].address
    assert state.get_balance(sender) > 0
    tx = {
        'from': address_encoder(sender),
        'to': address_encoder(b'\xff' * 20),
        'value': quantity_encoder(1)
    }
    tx_hash = data_decoder(test_app.client.call('eth_sendTransaction', tx))
    test_app.mine_next_block()
    assert len(chain.head.transactions) == 1
    assert tx_hash == chain.head.transactions[0].hash
    assert chain.state.get_balance(b'\xff' * 20) == 1

    # send transactions from account which can't pay gas
    tx['from'] = address_encoder(
        test_app.services.accounts.unlocked_accounts[1].address)
    tx_hash = data_decoder(test_app.client.call('eth_sendTransaction', tx))
    assert chainservice.head_candidate.transactions == []
Beispiel #18
0
    def mk_poststate_of_blockhash(self, blockhash, convert=False):
        if blockhash not in self.db:
            raise Exception("Block hash %s not found" % encode_hex(blockhash))

        block_rlp = self.db.get(blockhash)
        if block_rlp == b'GENESIS':
            return State.from_snapshot(
                json.loads(self.db.get(b'GENESIS_STATE')), self.env)
        block = rlp.decode(block_rlp, Block)

        state = State(env=self.env)
        state.trie.root_hash = block.header.state_root if convert else self.db.get(
            b'state:' + blockhash)
        update_block_env_variables(state, block)
        state.gas_used = block.header.gas_used
        state.txindex = len(block.transactions)
        state.recent_uncles = {}
        state.prev_headers = []
        b = block
        header_depth = state.config['PREV_HEADER_DEPTH']
        for i in range(header_depth + 1):
            state.prev_headers.append(b.header)
            if i < 6:
                state.recent_uncles[state.block_number - i] = []
                for u in b.uncles:
                    state.recent_uncles[state.block_number - i].append(u.hash)
            try:
                b = rlp.decode(state.db.get(b.header.prevhash), Block)
            except:
                break
        if i < header_depth:
            if state.db.get(b.header.prevhash) == b'GENESIS':
                jsondata = json.loads(state.db.get(b'GENESIS_STATE'))
                for h in jsondata["prev_headers"][:header_depth - i]:
                    state.prev_headers.append(dict_to_prev_header(h))
                for blknum, uncles in jsondata["recent_uncles"].items():
                    if int(blknum) >= state.block_number - int(
                            state.config['MAX_UNCLE_DEPTH']):
                        state.recent_uncles[blknum] = [
                            parse_as_bin(u) for u in uncles
                        ]
            else:
                raise Exception("Dangling prevhash")
        assert len(state.journal) == 0, state.journal
        return state
Beispiel #19
0
    def mk_poststate_of_collation_hash(self, collation_hash):
        """Return the post-state of the collation
        """
        if collation_hash not in self.db:
            raise Exception("Collation hash %s not found" %
                            encode_hex(collation_hash))

        collation_rlp = self.db.get(collation_hash)
        if collation_rlp == 'GENESIS':
            return State.from_snapshot(
                json.loads(self.db.get('GENESIS_STATE')), self.env)
        collation = rlp.decode(collation_rlp, Collation)

        state = State(env=self.env)
        state.trie.root_hash = collation.header.post_state_root

        update_collation_env_variables(state, collation)
        state.gas_used = 0
        state.txindex = len(collation.transactions)
        state.recent_uncles = {}
        state.prev_headers = []

        assert len(state.journal) == 0, state.journal
        return state
Beispiel #20
0
def test_send_raw_transaction_with_contract(test_app):
    serpent_code = '''
def main(a,b):
    return(a ^ b)
'''
    tx_to = b''
    evm_code = serpent.compile(serpent_code)
    chainservice = test_app.services.chain
    chain = test_app.services.chain.chain
    state = State(chainservice.head_candidate.state_root, chain.env)
    sender = test_app.services.accounts.unlocked_accounts[0].address
    assert state.get_balance(sender) > 0
    nonce = state.get_nonce(sender)
    tx = ethereum.transactions.Transaction(nonce, default_gasprice,
                                           default_startgas, tx_to, 0,
                                           evm_code, 0, 0, 0)
    test_app.services.accounts.sign_tx(sender, tx)
    raw_transaction = data_encoder(
        rlp.codec.encode(tx, ethereum.transactions.Transaction))
    data_decoder(
        test_app.client.call('eth_sendRawTransaction', raw_transaction))
    assert len(chainservice.head_candidate.transactions) == 1
    creates = chainservice.head_candidate.transactions[0].creates

    candidate_state_dict = State(chainservice.head_candidate.state_root,
                                 chain.env).to_dict()
    code = candidate_state_dict[encode_hex(creates)]['code']
    assert len(code) > 2
    assert code != '0x'

    test_app.mine_next_block()

    assert len(chain.head.transactions) == 1
    creates = chain.head.transactions[0].creates
    state_dict = State(chain.head.state_root, chain.env).to_dict()
    code = state_dict[encode_hex(creates)]['code']
    assert len(code) > 2
    assert code != '0x'
Beispiel #21
0
def state_from_genesis_declaration(genesis_data,
                                   env,
                                   block=None,
                                   allow_empties=False,
                                   executing_on_head=False):
    if block:
        assert isinstance(block, Block)
    else:
        block = block_from_genesis_declaration(genesis_data, env)

    state = State(env=env)
    for addr, data in genesis_data["alloc"].items():
        addr = normalize_address(addr)
        assert len(addr) == 20
        if 'wei' in data:
            state.set_balance(addr, parse_as_int(data['wei']))
        if 'balance' in data:
            state.set_balance(addr, parse_as_int(data['balance']))
        if 'code' in data:
            state.set_code(addr, parse_as_bin(data['code']))
        if 'nonce' in data:
            state.set_nonce(addr, parse_as_int(data['nonce']))
        if 'storage' in data:
            for k, v in data['storage'].items():
                state.set_storage_data(addr,
                                       big_endian_to_int(parse_as_bin(k)),
                                       big_endian_to_int(parse_as_bin(v)))
    get_consensus_strategy(state.config).initialize(state, block)
    if executing_on_head:
        state.executing_on_head = True
    state.commit(allow_empties=allow_empties)
    print('deleting %d' % len(state.deletes))
    rdb = RefcountDB(state.db)
    for delete in state.deletes:
        rdb.delete(delete)
    block.header.state_root = state.trie.root_hash
    state.changed = {}
    state.prev_headers = [block.header]
    return state
Beispiel #22
0
def mk_basic_state(alloc, header=None, env=None, executing_on_head=False):
    env = env or Env()
    state = State(env=env, executing_on_head=executing_on_head)
    if not header:
        header = {
            "number": 0,
            "gas_limit": env.config['BLOCK_GAS_LIMIT'],
            "gas_used": 0,
            "timestamp": 1467446877,
            "difficulty": 1,
            "uncles_hash": '0x' + encode_hex(BLANK_UNCLES_HASH)
        }
    h = BlockHeader(number=parse_as_int(header['number']),
                    timestamp=parse_as_int(header['timestamp']),
                    difficulty=parse_as_int(header['difficulty']),
                    gas_limit=parse_as_int(header['gas_limit']),
                    uncles_hash=parse_as_bin(header['uncles_hash']))
    state.prev_headers = [h]

    for addr, data in alloc.items():
        addr = normalize_address(addr)
        assert len(addr) == 20
        if 'wei' in data:
            state.set_balance(addr, parse_as_int(data['wei']))
        if 'balance' in data:
            state.set_balance(addr, parse_as_int(data['balance']))
        if 'code' in data:
            state.set_code(addr, parse_as_bin(data['code']))
        if 'nonce' in data:
            state.set_nonce(addr, parse_as_int(data['nonce']))
        if 'storage' in data:
            for k, v in data['storage'].items():
                state.set_storage_data(addr, parse_as_bin(k), parse_as_bin(v))

    state.block_number = header["number"]
    state.gas_limit = header["gas_limit"]
    state.timestamp = header["timestamp"]
    state.block_difficulty = header["difficulty"]
    state.commit()
    return state
Beispiel #23
0
    def __init__(self,
                 genesis=None,
                 env=None,
                 new_head_cb=None,
                 reset_genesis=False,
                 localtime=None,
                 max_history=1000,
                 **kwargs):
        self.env = env or Env()
        # Initialize the state
        if b'head_hash' in self.db:  # new head tag
            self.state = self.mk_poststate_of_blockhash(
                self.db.get('head_hash'))
            self.state.executing_on_head = True
            print('Initializing chain from saved head, #%d (%s)' %
                  (self.state.prev_headers[0].number,
                   encode_hex(self.state.prev_headers[0].hash)))
        elif genesis is None:
            raise Exception("Need genesis decl!")
        elif isinstance(genesis, State):
            assert env is None
            self.state = genesis
            self.env = self.state.env
            print('Initializing chain from provided state')
            reset_genesis = True
        elif "extraData" in genesis:
            self.state = state_from_genesis_declaration(genesis,
                                                        self.env,
                                                        executing_on_head=True)
            reset_genesis = True
            print('Initializing chain from provided genesis declaration')
        elif "prev_headers" in genesis:
            self.state = State.from_snapshot(genesis,
                                             self.env,
                                             executing_on_head=True)
            reset_genesis = True
            print('Initializing chain from provided state snapshot, %d (%s)' %
                  (self.state.block_number,
                   encode_hex(self.state.prev_headers[0].hash[:8])))
        elif isinstance(genesis, dict):
            print('Initializing chain from new state based on alloc')
            self.state = mk_basic_state(
                genesis, {
                    "number":
                    kwargs.get('number', 0),
                    "gas_limit":
                    kwargs.get('gas_limit',
                               self.env.config['BLOCK_GAS_LIMIT']),
                    "gas_used":
                    kwargs.get('gas_used', 0),
                    "timestamp":
                    kwargs.get('timestamp', 1467446877),
                    "difficulty":
                    kwargs.get('difficulty', 2**25),
                    "hash":
                    kwargs.get('prevhash', '00' * 32),
                    "uncles_hash":
                    kwargs.get('uncles_hash',
                               '0x' + encode_hex(BLANK_UNCLES_HASH))
                }, self.env)
            reset_genesis = True

        assert self.env.db == self.state.db

        initialize(self.state)
        self.new_head_cb = new_head_cb

        if self.state.block_number == 0:
            assert self.state.block_number == self.state.prev_headers[0].number
        else:
            assert self.state.block_number - 1 == self.state.prev_headers[
                0].number

        if reset_genesis:
            if isinstance(self.state.prev_headers[0], FakeHeader):
                header = self.state.prev_headers[0].to_block_header()
            else:
                header = self.state.prev_headers[0]
            self.genesis = Block(header)
            self.state.prev_headers[0] = header
            initialize_genesis_keys(self.state, self.genesis)
        else:
            self.genesis = self.get_block_by_number(0)

        self.head_hash = self.state.prev_headers[0].hash
        self.time_queue = []
        self.parent_queue = {}
        self.localtime = time.time() if localtime is None else localtime
        self.max_history = max_history
Beispiel #24
0
    def __init__(self,
                 genesis=None,
                 env=None,
                 coinbase=b'\x00' * 20,
                 new_head_cb=None,
                 reset_genesis=False,
                 localtime=None,
                 **kwargs):
        self.env = env or Env()
        # Initialize the state
        if b'head_hash' in self.db:  # new head tag
            self.state = self.mk_poststate_of_blockhash(
                self.db.get(b'head_hash'))
            print('Initializing chain from saved head, #%d (%s)' %
                  (self.state.prev_headers[0].number,
                   encode_hex(self.state.prev_headers[0].hash)))
        elif genesis is None:
            raise Exception("Need genesis decl!")
        elif isinstance(genesis, State):
            assert env is None
            self.state = genesis
            self.env = self.state.env
            print('Initializing chain from provided state')
        elif "extraData" in genesis:
            self.state = state_from_genesis_declaration(genesis, self.env)
            reset_genesis = True
            print('Initializing chain from provided genesis declaration')
        elif "prev_headers" in genesis:
            self.state = State.from_snapshot(genesis, self.env)
            reset_genesis = True
            print('Initializing chain from provided state snapshot, %d (%s)' %
                  (self.state.block_number,
                   encode_hex(self.state.prev_headers[0].hash[:8])))
        else:
            print('Initializing chain from new state based on alloc')
            self.state = mk_basic_state(
                genesis, {
                    "number":
                    kwargs.get('number', 0),
                    "gas_limit":
                    kwargs.get('gas_limit', 4712388),
                    "gas_used":
                    kwargs.get('gas_used', 0),
                    "timestamp":
                    kwargs.get('timestamp', 1467446877),
                    "difficulty":
                    kwargs.get('difficulty', 2**25),
                    "hash":
                    kwargs.get('prevhash', '00' * 32),
                    "uncles_hash":
                    kwargs.get('uncles_hash',
                               '0x' + encode_hex(BLANK_UNCLES_HASH))
                }, self.env)
            reset_genesis = True

        assert self.env.db == self.state.db

        initialize(self.state)
        self.new_head_cb = new_head_cb

        self.head_hash = self.state.prev_headers[0].hash
        self.checkpoint_head_hash = b'\x00' * 32
        self.db.put(b'cp_subtree_score' + b'\x00' * 32, 2 / 3.)
        self.commit_logs = []
        self.casper_address = self.config['CASPER_ADDRESS']
        self.db.put(b'GENESIS_NUMBER', to_string(self.state.block_number))
        assert self.state.block_number == self.state.prev_headers[0].number
        if reset_genesis:
            self.genesis = Block(self.state.prev_headers[0], [], [])
            initialize_genesis_keys(self.state, self.genesis)
        else:
            self.genesis = self.get_block_by_number(0)
        self.db.put(b'cp_subtree_score' + self.genesis.hash, 2 / 3.)
        self.min_gasprice = kwargs.get('min_gasprice', 5 * 10**9)
        self.coinbase = coinbase
        self.extra_data = 'moo ha ha says the laughing cow.'
        self.time_queue = []
        self.parent_queue = {}
        self.localtime = time.time() if localtime is None else localtime
Beispiel #25
0
def trace(code, calldata=""):

    logHandlers = [
        'eth.vm.op', 'eth.vm.op.stack', 'eth.vm.op.memory', 'eth.vm.op.storage'
    ]

    output = StringIO()
    streamHandler = StreamHandler(output)

    for handler in logHandlers:
        log_vm_op = get_logger(handler)
        log_vm_op.setLevel("TRACE")
        log_vm_op.addHandler(streamHandler)

    addr = bytes.fromhex('0123456789ABCDEF0123456789ABCDEF01234567')

    state = State()

    ext = messages.VMExt(state,
                         transactions.Transaction(0, 0, 21000, addr, 0, addr))

    message = vm.Message(addr, addr, 0, 21000, calldata)

    res, gas, dat = vm.vm_execute(ext, message, util.safe_decode(code))

    streamHandler.flush()

    ret = output.getvalue()

    lines = ret.split("\n")

    trace = []

    for line in lines:

        m = re.search(r'pc=b\'(\d+)\'.*op=([A-Z0-9]+)', line)

        if m:
            pc = m.group(1)
            op = m.group(2)

            m = re.match(r'.*stack=(\[.*?\])', line)

            if (m):

                stackitems = re.findall(r'b\'(\d+)\'', m.group(1))

                stack = "["

                if (len(stackitems)):

                    for i in range(0, len(stackitems) - 1):
                        stack += hex(int(stackitems[i])) + ", "

                    stack += hex(int(stackitems[-1]))

                stack += "]"

            else:
                stack = "[]"

            if (re.match(r'^PUSH.*', op)):
                val = re.search(r'pushvalue=(\d+)', line).group(1)
                pushvalue = hex(int(val))
                trace.append({
                    'pc': pc,
                    'op': op,
                    'stack': stack,
                    'pushvalue': pushvalue
                })
            else:
                trace.append({'pc': pc, 'op': op, 'stack': stack})

    return trace
Beispiel #26
0
class ShardChain(object):
    def __init__(self,
                 shard_id,
                 env=None,
                 new_head_cb=None,
                 reset_genesis=False,
                 localtime=None,
                 max_history=1000,
                 initial_state=None,
                 main_chain=None,
                 **kwargs):
        self.env = env or Env()
        self.shard_id = shard_id

        self.collation_blockhash_lists = defaultdict(
            list)  # M1: collation_header_hash -> list[blockhash]
        self.head_collation_of_block = {}  # M2: blockhash -> head_collation
        self.main_chain = main_chain

        # Initialize the state
        head_hash_key = 'shard_' + str(shard_id) + '_head_hash'
        if head_hash_key in self.db:  # new head tag
            self.state = self.mk_poststate_of_collation_hash(
                self.db.get(head_hash_key))
            log.info('Initializing shard chain from saved head, #%d (%s)' %
                     (self.state.prev_headers[0].number,
                      encode_hex(self.state.prev_headers[0].hash)))
            self.head_hash = self.state.prev_headers[0].hash
        else:
            # no head_hash in db -> empty shard chain
            if initial_state is not None and isinstance(initial_state, State):
                # Normally, initial_state is for testing
                assert env is None
                self.state = initial_state
                self.env = self.state.env
                log.info('Initializing chain from provided state')
            else:
                self.state = State(env=self.env)
                self.last_state = self.state.to_snapshot()

            self.head_hash = self.env.config['GENESIS_PREVHASH']
            self.db.put(self.head_hash, 'GENESIS')
            self.db.put(head_hash_key, self.head_hash)

            # initial score
            key = b'score:' + self.head_hash
            self.db.put(key, str(0))
            self.db.commit()
            reset_genesis = True

        assert self.env.db == self.state.db

        initialize(self.state)
        self.new_head_cb = new_head_cb

        if reset_genesis:
            initialize_genesis_keys(self.state, Collation(CollationHeader()))

        self.time_queue = []
        self.parent_queue = {}
        self.localtime = time.time() if localtime is None else localtime
        self.max_history = max_history

    @property
    def db(self):
        return self.env.db

    # TODO: use head_collation_of_block to update head collation
    @property
    def head(self):
        """head collation
        """
        try:
            collation_rlp = self.db.get(self.head_hash)
            # [TODO] no genesis collation
            if collation_rlp == 'GENESIS':
                return Collation(CollationHeader())
                # return self.genesis
            else:
                return rlp.decode(collation_rlp, Collation)
            return rlp.decode(collation_rlp, Collation)
        except Exception as e:
            log.info(str(e))
            return None

    def add_collation(self, collation, period_start_prevblock,
                      handle_ignored_collation):
        """Add collation to db and update score
        """
        if collation.header.parent_collation_hash in self.env.db:
            log.info('Receiving collation(%s) which its parent is in db: %s' %
                     (encode_hex(collation.header.hash),
                      encode_hex(collation.header.parent_collation_hash)))
            if self.is_first_collation(collation):
                log.debug('It is the first collation of shard {}'.format(
                    self.shard_id))
            temp_state = self.mk_poststate_of_collation_hash(
                collation.header.parent_collation_hash)
            try:
                apply_collation(
                    temp_state, collation, period_start_prevblock,
                    None if self.main_chain is None else self.main_chain.state,
                    self.shard_id)
            except (AssertionError, KeyError, ValueError, InvalidTransaction,
                    VerificationFailed) as e:
                log.info('Collation %s with parent %s invalid, reason: %s' %
                         (encode_hex(collation.header.hash),
                          encode_hex(
                              collation.header.parent_collation_hash), str(e)))
                return False
            deletes = temp_state.deletes
            changed = temp_state.changed
            collation_score = self.get_score(collation)
            log.info('collation_score of {} is {}'.format(
                encode_hex(collation.header.hash), collation_score))
        # Collation has no parent yet
        else:
            changed = []
            deletes = []
            log.info(
                'Receiving collation(%s) which its parent is NOT in db: %s' %
                (encode_hex(collation.header.hash),
                 encode_hex(collation.header.parent_collation_hash)))
            if collation.header.parent_collation_hash not in self.parent_queue:
                self.parent_queue[collation.header.parent_collation_hash] = []
            self.parent_queue[collation.header.parent_collation_hash].append(
                collation)
            log.info('No parent found. Delaying for now')
            return False
        self.db.put(collation.header.hash, rlp.encode(collation))

        self.db.put(b'changed:' + collation.hash,
                    b''.join(list(changed.keys())))
        # log.debug('Saved %d address change logs' % len(changed.keys()))
        self.db.put(b'deletes:' + collation.hash, b''.join(deletes))
        # log.debug('Saved %d trie node deletes for collation (%s)' % (len(deletes), encode_hex(collation.hash)))

        # TODO: Delete old junk data
        # deletes, changed

        self.db.commit()
        log.info('Added collation (%s) with %d txs' % (encode_hex(
            collation.header.hash)[:8], len(collation.transactions)))

        # Call optional callback
        if self.new_head_cb and self.is_first_collation(collation):
            self.new_head_cb(collation)

        # TODO: It seems weird to use callback function to access member of MainChain
        try:
            handle_ignored_collation(collation)
        except Exception as e:
            log.info('handle_ignored_collation exception: {}'.format(str(e)))
            return False

        return True

    def mk_poststate_of_collation_hash(self, collation_hash):
        """Return the post-state of the collation
        """
        if collation_hash not in self.db:
            raise Exception("Collation hash %s not found" %
                            encode_hex(collation_hash))

        collation_rlp = self.db.get(collation_hash)
        if collation_rlp == 'GENESIS':
            return State.from_snapshot(
                json.loads(self.db.get('GENESIS_STATE')), self.env)
        collation = rlp.decode(collation_rlp, Collation)

        state = State(env=self.env)
        state.trie.root_hash = collation.header.post_state_root

        update_collation_env_variables(state, collation)
        state.gas_used = 0
        state.txindex = len(collation.transactions)
        state.recent_uncles = {}
        state.prev_headers = []

        assert len(state.journal) == 0, state.journal
        return state

    def get_parent(self, collation):
        """Get the parent collation of a given collation
        """
        if self.is_first_collation(collation):
            return None
        return self.get_collation(collation.header.parent_collation_hash)

    def get_collation(self, collation_hash):
        """Get the collation with a given collation hash
        """
        try:
            collation_rlp = self.db.get(collation_hash)
            if collation_rlp == 'GENESIS':
                return Collation(CollationHeader())
                # if not hasattr(self, 'genesis'):
                #     self.genesis = rlp.decode(self.db.get('GENESIS_RLP'), sedes=Block)
                # return self.genesis
            else:
                return rlp.decode(collation_rlp, Collation)
        except Exception as e:
            log.debug("Failed to get collation",
                      hash=encode_hex(collation_hash),
                      error=str(e))
            return None

    def get_score(self, collation):
        """Get the score of a given collation
        """
        score = 0

        if not collation:
            return 0
        key = b'score:' + collation.header.hash

        fills = []

        while key not in self.db and collation is not None:
            fills.insert(0, collation.header.hash)
            key = b'score:' + collation.header.parent_collation_hash
            collation = self.get_parent(collation)

        score = int(self.db.get(key))
        log.debug('int(self.db.get(key)):{}'.format(int(self.db.get(key))))

        for h in fills:
            key = b'score:' + h
            score += 1
            self.db.put(key, str(score))

        return score

    def get_head_coll_score(self, blockhash):
        if blockhash in self.head_collation_of_block:
            prev_head_coll_hash = self.head_collation_of_block[blockhash]
            prev_head_coll = self.get_collation(prev_head_coll_hash)
            prev_head_coll_score = self.get_score(prev_head_coll)
        else:
            prev_head_coll_score = 0
        return prev_head_coll_score

    def is_first_collation(self, collation):
        """Check if the given collation is the first collation of this shard
        """
        return collation.header.parent_collation_hash == self.env.config[
            'GENESIS_PREVHASH']
Beispiel #27
0
    def __init__(self,
                 shard_id,
                 env=None,
                 new_head_cb=None,
                 reset_genesis=False,
                 localtime=None,
                 max_history=1000,
                 initial_state=None,
                 main_chain=None,
                 **kwargs):
        self.env = env or Env()
        self.shard_id = shard_id

        self.collation_blockhash_lists = defaultdict(
            list)  # M1: collation_header_hash -> list[blockhash]
        self.head_collation_of_block = {}  # M2: blockhash -> head_collation
        self.main_chain = main_chain

        # Initialize the state
        head_hash_key = 'shard_' + str(shard_id) + '_head_hash'
        if head_hash_key in self.db:  # new head tag
            self.state = self.mk_poststate_of_collation_hash(
                self.db.get(head_hash_key))
            log.info('Initializing shard chain from saved head, #%d (%s)' %
                     (self.state.prev_headers[0].number,
                      encode_hex(self.state.prev_headers[0].hash)))
            self.head_hash = self.state.prev_headers[0].hash
        else:
            # no head_hash in db -> empty shard chain
            if initial_state is not None and isinstance(initial_state, State):
                # Normally, initial_state is for testing
                assert env is None
                self.state = initial_state
                self.env = self.state.env
                log.info('Initializing chain from provided state')
            else:
                self.state = State(env=self.env)
                self.last_state = self.state.to_snapshot()

            self.head_hash = self.env.config['GENESIS_PREVHASH']
            self.db.put(self.head_hash, 'GENESIS')
            self.db.put(head_hash_key, self.head_hash)

            # initial score
            key = b'score:' + self.head_hash
            self.db.put(key, str(0))
            self.db.commit()
            reset_genesis = True

        assert self.env.db == self.state.db

        initialize(self.state)
        self.new_head_cb = new_head_cb

        if reset_genesis:
            initialize_genesis_keys(self.state, Collation(CollationHeader()))

        self.time_queue = []
        self.parent_queue = {}
        self.localtime = time.time() if localtime is None else localtime
        self.max_history = max_history
Beispiel #28
0
def test_console_name_reg_contract(test_app):

    solidity_code = """
    contract NameReg  {
       event AddressRegistered(bytes32 indexed name, address indexed account);
       mapping (address => bytes32) toName;

       function register(bytes32 name) {
               toName[msg.sender] = name;
               AddressRegistered(name, msg.sender);
       }

       function resolve(address addr) constant returns (bytes32 name) {
               return toName[addr];
       }
    }
    """

    import ethereum.tools._solidity
    solidity = ethereum.tools._solidity.get_solidity()
    if solidity is None:
        pytest.xfail("solidity not installed, not tested")
    else:
        # create the NameReg contract
        tx_to = b''
        evm_code = solidity.compile(solidity_code)
        chainservice = test_app.services.chain
        chain = test_app.services.chain.chain
        hc_state = State(chainservice.head_candidate.state_root, chain.env)
        sender = test_app.services.accounts.unlocked_accounts[0].address
        assert hc_state.get_balance(sender) > 0

        eth = test_app.services.console.console_locals['eth']
        tx = eth.transact(to='', data=evm_code, startgas=500000, sender=sender)

        hc_state_dict = State(chainservice.head_candidate.state_root,
                              chain.env).to_dict()
        code = hc_state_dict[encode_hex(tx.creates)]['code']
        assert len(code) > 2
        assert code != '0x'

        test_app.mine_next_block()

        creates = chain.head.transactions[0].creates
        state_dict = chain.state.to_dict()
        code = state_dict[encode_hex(creates)]['code']
        assert len(code) > 2
        assert code != '0x'

        # interact with the NameReg contract
        abi = solidity.mk_full_signature(solidity_code)
        namereg = eth.new_contract(abi, creates, sender=sender)

        register_tx = namereg.register('alice',
                                       startgas=90000,
                                       gasprice=50 * 10**9)

        test_app.mine_next_block()

        result = namereg.resolve(sender)
        assert result == b'alice' + ('\x00' * 27).encode()
Beispiel #29
0
    # Check latest block
    block_head = test.services.chain.chain.head
    log.info(block_head.header)
    value = test.config['node']['id'].encode('hex')
    # read_blocks = read_blocks_thread(test)
    # time.sleep(2)

    # test_receive_newblock(test)

    #     # Make contract code
    serpent_code = '''
def main(a,b):
    return(a ^ b)
    '''
    state = State(block_head.state_root, test.services.chain.chain.env)
    log.info('Andy accounts\' coin amount: ' +
             str(state.get_balance(accounts_list[Andy].address)))
    # Make transaction with contract, sender of transaction is 'Andy', receiver is 'Choi'
    tx = test_send_transaction_with_contract(test,
                                             serpent_code,
                                             sender_id=Andy,
                                             receiver_id=Choi)
    log.info(tx.__dict__)
    log.info(tx.sender.encode('hex'))

    # Check latest block, Not mining yet
    block_head = test.services.chain.chain.head
    state = State(block_head.state_root, test.services.chain.chain.env)
    log.info('Andy accounts\' coin amount: ' +
             str(state.get_balance(accounts_list[Andy].address)))
Beispiel #30
0
def init_state(env, pre):
    # Setup env
    state = State(
        env=Env(config=konfig),
        block_prevhash=decode_hex(remove_0x_head(env['previousHash'])),
        prev_headers=[mk_fake_header(i) for i in range(parse_int_or_hex(env['currentNumber']) - 1,
                                                       max(-1, parse_int_or_hex(env['currentNumber']) - 257), -1)],
        block_number=parse_int_or_hex(env['currentNumber']),
        block_coinbase=decode_hex(remove_0x_head(env['currentCoinbase'])),
        block_difficulty=parse_int_or_hex(env['currentDifficulty']),
        gas_limit=parse_int_or_hex(env['currentGasLimit']),
        timestamp=parse_int_or_hex(env['currentTimestamp']))

    # Fill up pre
    for address, h in list(pre.items()):
        assert len(address) in (40, 42)
        address = decode_hex(remove_0x_head(address))
        assert set(h.keys()) == set(['code', 'nonce', 'balance', 'storage'])
        state.set_nonce(address, parse_int_or_hex(h['nonce']))
        state.set_balance(address, parse_int_or_hex(h['balance']))
        state.set_code(address, decode_hex(remove_0x_head(h['code'])))
        for k, v in h['storage'].items():
            state.set_storage_data(address,
                                   big_endian_to_int(decode_hex(k[2:])),
                                   big_endian_to_int(decode_hex(v[2:])))

    state.commit(allow_empties=True)
    # state.commit()
    return state