Example #1
0
 def test_store_multiple(self):
     data = ['key1', 'value1', 'key2', 'value2']
     ans = self.sim.tx(self.ALICE, self.contract, 0, data)
     assert ans == [1]
     storage = self.sim.get_storage_dict(self.contract)
     assert storage.get(utils.zpad('key1', 32)) == 'value1'
     assert storage.get(utils.zpad('key2', 32)) == 'value2'
Example #2
0
    def test_reveal_returns_entropy(self):
        assert self.c.commit(1, self.COW_HASH, value=self.DEPOSIT_COST) == [1]
        assert self.c.request_entropy(sender=tester.k1,
                                      value=self.ENTROPY_COST) == [0, 4]
        assert self.c.get_block(self.s.block.number + 1) == [0, 1, 0, 1]

        self.s.mine(2)

        COW_SEED = utils.big_endian_to_int(
            utils.sha3(
                utils.sha3(utils.zpad('cow', 32)) + utils.zpad('cow', 32)))
        COW_HASH_1 = utils.big_endian_to_int(
            utils.sha3(utils.int_to_big_endian(COW_SEED)))

        balance = self.s.block.get_balance(tester.a0)
        assert self.c.reveal(1, self.COW_INT) == [1]
        assert self.s.block.get_balance(
            tester.a0
        ) - balance == self.DEPOSIT_COST + self.ENTROPY_COST  # deposit return + payout of committer share

        assert self.c.get_block(1) == [COW_SEED, 1, 1, 1]

        # signed vs unsigned as introduced by tester.send
        assert self.c.get_entropy_ticket(0) == [
            int(tester.a1, 16), 1, 1, COW_HASH_1 - 2**256
        ]
        assert self.c.get_entropy(
            0, sender=tester.k1) == [1, COW_HASH_1 - 2**256]  # ready
Example #3
0
    def test_reservation(self):
        data = ['ethereum.bit', '54.200.236.204']
        ans = self.sim.tx(self.ALICE, self.contract, 0, data)

        assert ans == [1]
        assert self.sim.get_storage_dict(self.contract) == {
            utils.zpad('ethereum.bit', 32): '54.200.236.204'
        }
Example #4
0
def hash_list(l):
    def g(x):
        if type(x) in [int, long]: x=utils.int_to_big_endian(x)
        return x
    y=map(g, l)
    y=[utils.zpad(x, 32) for x in y]
    y=''.join(y)
    #save for pretty print z="".join("{:02x}".format(ord(c)) for c in y)
    return b.sha256(y)
Example #5
0
    def test_double_reservation(self):
        data = ['ethereum.bit', '127.0.0.1']
        ans = self.sim.tx(self.ALICE, self.contract, 0, data)
        assert ans == [1]

        data = ['ethereum.bit', '127.0.0.2']
        ans = self.sim.tx(self.ALICE, self.contract, 0, data)
        assert ans == [0]
        assert self.sim.get_storage_dict(self.contract) == {utils.zpad('ethereum.bit', 32): '127.0.0.1'}
def hash_list(l):
    def g(x):
        if type(x) in [int, long]: x = utils.int_to_big_endian(x)
        return x

    y = map(g, l)
    y = [utils.zpad(x, 32) for x in y]
    y = ''.join(y)
    #save for pretty print z="".join("{:02x}".format(ord(c)) for c in y)
    return b.sha256(y)
Example #7
0
    def test_double_reservation(self):
        data = ['ethereum.bit', '127.0.0.1']
        ans = self.sim.tx(self.ALICE, self.contract, 0, data)
        assert ans == [1]

        data = ['ethereum.bit', '127.0.0.2']
        ans = self.sim.tx(self.ALICE, self.contract, 0, data)
        assert ans == [0]
        assert self.sim.get_storage_dict(self.contract) == {
            utils.zpad('ethereum.bit', 32): '127.0.0.1'
        }
Example #8
0
 def get_proposal_id(self, proposal):
     return big_endian_to_int(sha3(zpad(proposal, 32)))
Example #9
0
def spvstorage(addr, index):
    prf1 = chain_manager.head.state.produce_spv_proof(addr.decode('hex'))
    storetree = chain_manager.head.get_storage(addr)
    prf2 = storetree.produce_spv_proof(utils.zpad(utils.encode_int(index), 32))
    return rlp.encode(prf1 + prf2).encode('hex')
Example #10
0
def encode_hex_from_int(x):
    return utils.zpad(utils.int_to_big_endian(x), 64).encode('hex')
Example #11
0
def hash_value(value):
    return utils.big_endian_to_int(utils.sha3(utils.zpad(value, 32)))
Example #12
0
def run_test_vm(params):
    pre = params['pre']
    exek = params['exec']
    callcreates = params.get('callcreates', [])
    env = params['env']
    post = params.get('post', {})

    check_testdata(env.keys(), [
        'currentGasLimit', 'currentTimestamp', 'previousHash',
        'currentCoinbase', 'currentDifficulty', 'currentNumber'
    ])
    # setup env
    db = new_db()
    blk = blocks.Block(db,
                       prevhash=env['previousHash'].decode('hex'),
                       number=int(env['currentNumber']),
                       coinbase=env['currentCoinbase'],
                       difficulty=int(env['currentDifficulty']),
                       gas_limit=int(env['currentGasLimit']),
                       timestamp=int(env['currentTimestamp']))

    # code FIXME WHAT TO DO WITH THIS CODE???
    # if isinstance(env['code'], str):
    #     continue
    # else:
    # addr = 0 # FIXME
    #     blk.set_code(addr, ''.join(map(chr, env['code'])))

    # setup state
    for address, h in pre.items():
        check_testdata(h.keys(), ['code', 'nonce', 'balance', 'storage'])
        blk.set_nonce(address, int(h['nonce']))
        blk.set_balance(address, int(h['balance']))
        blk.set_code(address, h['code'][2:].decode('hex'))
        for k, v in h['storage']:
            blk.set_storage_data(address, u.big_endian_to_int(k.decode('hex')),
                                 u.big_endian_to_int(v.decode('hex')))

    # execute transactions
    sender = exek['caller']  # a party that originates a call
    recvaddr = exek['address']
    tx = transactions.Transaction(nonce=blk._get_acct_item(
        exek['caller'], 'nonce'),
                                  gasprice=int(exek['gasPrice']),
                                  startgas=int(exek['gas']),
                                  to=recvaddr,
                                  value=int(exek['value']),
                                  data=exek['data'][2:].decode('hex'))
    tx.sender = sender

    # capture apply_message calls
    apply_message_calls = []
    orig_apply_msg = pb.apply_msg

    def apply_msg_wrapper(_ext, msg, code, toplevel=False):
        hexdata = msg.data.extract_all().encode('hex')
        apply_message_calls.append(
            dict(gasLimit=msg.gas,
                 value=msg.value,
                 destination=msg.to,
                 data=hexdata))
        if not toplevel:
            pb.apply_msg = orig_apply_msg
        result, gas_rem, data = orig_apply_msg(_ext, msg, code)
        if not toplevel:
            pb.apply_msg = apply_msg_wrapper
        return result, gas_rem, data

    pb.apply_msg = apply_msg_wrapper

    ext = pb.VMExt(blk, tx)
    msg = vm.Message(tx.sender, tx.to, tx.value, tx.startgas,
                     vm.CallData([ord(x) for x in tx.data]))
    success, gas_remained, output = \
        vm.vm_execute(ext, msg, exek['code'][2:].decode('hex'))
    pb.apply_msg = orig_apply_msg
    blk.commit_state()
    """
     generally expected that the test implementer will read env, exec and pre
     then check their results against gas, logs, out, post and callcreates.
     If an exception is expected, then latter sections are absent in the test.
     Since the reverting of the state is not part of the VM tests.
     """

    if not success:
        return

    for k in ['gas', 'logs', 'out', 'post', 'callcreates']:
        assert k in params
    assert len(callcreates) == len(apply_message_calls)

    # check against callcreates
    for i, callcreate in enumerate(callcreates):
        amc = apply_message_calls[i]
        assert callcreate['data'] == '0x' + amc['data']
        assert callcreate['gasLimit'] == str(amc['gasLimit'])
        assert callcreate['value'] == str(amc['value'])
        assert callcreate['destination'] == amc['destination']

    if 'out' in params:
        assert '0x' + ''.join(map(chr, output)).encode('hex') == params['out']
    if 'gas' in params:
        assert str(gas_remained) == params['gas']
    if 'logs' in params:
        """
        The logs sections is a mapping between the blooms and their corresponding logentries.
        Each logentry has the format:
        address: The address of the logentry.
        data: The data of the logentry.
        topics: The topics of the logentry, given as an array of values.
        """
        test_logs = params['logs']
        vm_logs = []
        for log in tx.logs:
            vm_logs.append({
                "bloom":
                bloom.b64(bloom.bloom_from_list(
                    log.bloomables())).encode('hex'),
                "address":
                log.address,
                "data":
                '0x' + log.data.encode('hex'),
                "topics": [
                    u.zpad(u.int_to_big_endian(t), 32).encode('hex')
                    for t in log.topics
                ]
            })

        assert len(vm_logs) == len(test_logs)
        assert vm_logs == test_logs

    # check state
    for address, data in post.items():
        state = blk.account_to_dict(address, for_vmtest=True)
        state.pop('storage_root',
                  None)  # attribute not present in vmtest fixtures
        assert data == state

    db.delete_db()
Example #13
0
 def get_proposal_id(self, proposal):
     return big_endian_to_int(sha3(zpad(proposal, 32)))
Example #14
0
def encode_hex_from_int(x):
    return utils.zpad(utils.int_to_big_endian(x), 64).encode('hex')
Example #15
0
def generate_op_tests():
    outs = {}
    for opcode, (name, inargs, outargs, _) in opcodes.opcodes.items():
     _subid = 0
     for push_depths in push_params:
      for jump_num, code_size in codesize_params:
        if name in ['CALL', 'CREATE', 'CALLCODE', 'LOG', 'POP', 'RETURN', 'STOP', 'INVALID', 'JUMP', 'JUMPI', 'CALLDATALOAD', 'CALLDATACOPY', 'CODECOPY', 'EXTCODECOPY', 'SHA3', 'MLOAD', 'MSTORE', 'MSTORE8', 'SUICIDE']:
            continue
        if name[:3] in ['DUP', 'SWA', 'LOG']:
            continue
        if name == 'SSTORE':
            jump_num /= 10
        c = '\x5b'
        if name[:4] == 'PUSH':
            if push_depths != push_params[0]:
                continue
            for i in range(code_size):
                v = int(name[4:])
                w = random.randrange(256**v)
                c += chr(0x5f + v) + utils.zpad(utils.encode_int(w), v)
        else:
            for i in range(code_size):
                for _ in range(inargs):
                    v = push_depths[i * len(push_depths) // code_size]
                    w = random.randrange(256**v)
                    c += chr(0x5f + v) + utils.zpad(utils.encode_int(w), v)
                c += chr(opcode)
                for _ in range(outargs):
                    c += chr(0x50)
        # PUSH1 0 MLOAD . DUP1 . PUSH1 1 ADD PUSH1 0 MSTORE . PUSH2 <jumps> GT PUSH1 0 JUMPI
        c += '\x60\x00\x51' + '\x80' + '\x60\x01\x01\x60\x00\x52' + \
            '\x61'+chr(jump_num // 256) + chr(jump_num % 256) + '\x11\x60\x00\x57'
        o = {
            "callcreates": [],
            "env": {
                "currentCoinbase": "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
                "currentDifficulty": "256",
                "currentGasLimit": "1000000000",
                "currentNumber": "257",
                "currentTimestamp": "1",
                "previousHash": "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
            },
            "exec": {
                "address": "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
                "caller": "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
                "code": "0x"+c.encode('hex'),
                "data": "0x",
                "gas": "1000000",
                "gasPrice": "100000000000000",
                "origin": "cd1722f3947def4cf144679da39c4c32bdc35681",
                "value": "1000000000000000000"
            },
            "pre": {
                "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6": {
                    "balance": "1000000000000000000",
                    "code": "0x",
                    "nonce": "0",
                    "storage": {
                    }
                }
            },
            "gas": "1000000",
            "logs": [],
            "out": "0x"
        }
        env = o['env']
        pre = o['pre']
        exek = o['exec']
        blk = blocks.Block(db,
                           prevhash=env['previousHash'].decode('hex'),
                           number=int(env['currentNumber']),
                           coinbase=env['currentCoinbase'],
                           difficulty=int(env['currentDifficulty']),
                           gas_limit=int(env['currentGasLimit']),
                           timestamp=int(env['currentTimestamp']))

        # setup state
        for address, h in pre.items():
            blk.set_nonce(address, int(h['nonce']))
            blk.set_balance(address, int(h['balance']))
            blk.set_code(address, h['code'][2:].decode('hex'))
            for k, v in h['storage'].iteritems():
                blk.set_storage_data(address,
                                     u.big_endian_to_int(k[2:].decode('hex')),
                                     u.big_endian_to_int(v[2:].decode('hex')))

        # execute transactions
        sender = exek['caller']  # a party that originates a call
        recvaddr = exek['address']
        tx = transactions.Transaction(
            nonce=blk._get_acct_item(exek['caller'], 'nonce'),
            gasprice=int(exek['gasPrice']),
            startgas=int(exek['gas']),
            to=recvaddr,
            value=int(exek['value']),
            data=exek['data'][2:].decode('hex'))
        tx.sender = sender

        ext = pb.VMExt(blk, tx)

        def blkhash(n):
            if n >= ext.block_number or n < ext.block_number - 256:
                return ''
            else:
                return u.sha3(str(n))

        ext.block_hash = blkhash

        msg = vm.Message(tx.sender, tx.to, tx.value, tx.startgas,
                         vm.CallData([ord(x) for x in tx.data]))
        success, gas_remained, output = \
            vm.vm_execute(ext, msg, exek['code'][2:].decode('hex'))

        o['post'] = blk.to_dict(True)['state']
        outs[name+str(_subid)] = o
        _subid += 1
    return outs
Example #16
0
 def test_store_single(self):
     data = ['key', 'value']
     ans = self.sim.tx(self.ALICE, self.contract, 0, data)
     assert ans == []
     storage = self.sim.get_storage_dict(self.contract)
     assert storage.get(utils.zpad('key', 32)) == 'value'
Example #17
0
def generate_op_tests():
    outs = {}
    for opcode, (name, inargs, outargs, _) in opcodes.opcodes.items():
        _subid = 0
        for push_depths in push_params:
            for jump_num, code_size in codesize_params:
                if name in [
                        'CALL', 'CREATE', 'CALLCODE', 'LOG', 'POP', 'RETURN',
                        'STOP', 'INVALID', 'JUMP', 'JUMPI', 'CALLDATALOAD',
                        'CALLDATACOPY', 'CODECOPY', 'EXTCODECOPY', 'SHA3',
                        'MLOAD', 'MSTORE', 'MSTORE8', 'SUICIDE'
                ]:
                    continue
                if name[:3] in ['DUP', 'SWA', 'LOG']:
                    continue
                if name == 'SSTORE':
                    jump_num /= 10
                c = '\x5b'
                if name[:4] == 'PUSH':
                    if push_depths != push_params[0]:
                        continue
                    for i in range(code_size):
                        v = int(name[4:])
                        w = random.randrange(256**v)
                        c += chr(0x5f + v) + utils.zpad(utils.encode_int(w), v)
                else:
                    for i in range(code_size):
                        for _ in range(inargs):
                            v = push_depths[i * len(push_depths) // code_size]
                            w = random.randrange(256**v)
                            c += chr(0x5f + v) + utils.zpad(
                                utils.encode_int(w), v)
                        c += chr(opcode)
                        for _ in range(outargs):
                            c += chr(0x50)
                # PUSH1 0 MLOAD . DUP1 . PUSH1 1 ADD PUSH1 0 MSTORE . PUSH2 <jumps> GT PUSH1 0 JUMPI
                c += '\x60\x00\x51' + '\x80' + '\x60\x01\x01\x60\x00\x52' + \
                    '\x61'+chr(jump_num // 256) + chr(jump_num % 256) + '\x11\x60\x00\x57'
                o = {
                    "callcreates": [],
                    "env": {
                        "currentCoinbase":
                        "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
                        "currentDifficulty":
                        "256",
                        "currentGasLimit":
                        "1000000000",
                        "currentNumber":
                        "257",
                        "currentTimestamp":
                        "1",
                        "previousHash":
                        "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
                    },
                    "exec": {
                        "address": "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
                        "caller": "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
                        "code": "0x" + c.encode('hex'),
                        "data": "0x",
                        "gas": "1000000",
                        "gasPrice": "100000000000000",
                        "origin": "cd1722f3947def4cf144679da39c4c32bdc35681",
                        "value": "1000000000000000000"
                    },
                    "pre": {
                        "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6": {
                            "balance": "1000000000000000000",
                            "code": "0x",
                            "nonce": "0",
                            "storage": {}
                        }
                    },
                    "gas": "1000000",
                    "logs": [],
                    "out": "0x"
                }
                env = o['env']
                pre = o['pre']
                exek = o['exec']
                blk = blocks.Block(db,
                                   prevhash=env['previousHash'].decode('hex'),
                                   number=int(env['currentNumber']),
                                   coinbase=env['currentCoinbase'],
                                   difficulty=int(env['currentDifficulty']),
                                   gas_limit=int(env['currentGasLimit']),
                                   timestamp=int(env['currentTimestamp']))

                # setup state
                for address, h in pre.items():
                    blk.set_nonce(address, int(h['nonce']))
                    blk.set_balance(address, int(h['balance']))
                    blk.set_code(address, h['code'][2:].decode('hex'))
                    for k, v in h['storage'].iteritems():
                        blk.set_storage_data(
                            address, u.big_endian_to_int(k[2:].decode('hex')),
                            u.big_endian_to_int(v[2:].decode('hex')))

                # execute transactions
                sender = exek['caller']  # a party that originates a call
                recvaddr = exek['address']
                tx = transactions.Transaction(
                    nonce=blk._get_acct_item(exek['caller'], 'nonce'),
                    gasprice=int(exek['gasPrice']),
                    startgas=int(exek['gas']),
                    to=recvaddr,
                    value=int(exek['value']),
                    data=exek['data'][2:].decode('hex'))
                tx.sender = sender

                ext = pb.VMExt(blk, tx)

                def blkhash(n):
                    if n >= ext.block_number or n < ext.block_number - 256:
                        return ''
                    else:
                        return u.sha3(str(n))

                ext.block_hash = blkhash

                msg = vm.Message(tx.sender, tx.to, tx.value, tx.startgas,
                                 vm.CallData([ord(x) for x in tx.data]))
                success, gas_remained, output = \
                    vm.vm_execute(ext, msg, exek['code'][2:].decode('hex'))

                o['post'] = blk.to_dict(True)['state']
                outs[name + str(_subid)] = o
                _subid += 1
    return outs
def generate_op_tests():
    out = {}
    for opcode, (name, inargs, outargs, _) in opcodes.items():
        _subid = 0
        for push_depths in push_params:
            for jump_num, code_size in codesize_params:
                if name in [
                        'DELEGATECALL', 'LOG0', 'LOG1', 'LOG2', 'LOG3', 'LOG4',
                        'CALL', 'CREATE', 'CALLCODE', 'RETURNDATACOPY',
                        'RETURNDATASIZE', 'CALLBLACKBOX', 'STATICCALL',
                        'REVERT', 'RETURN', 'STOP', 'INVALID', 'JUMP', 'JUMPI',
                        'SUICIDE'
                ]:
                    continue
                if name == 'SSTORE':
                    jump_num /= 10
                c = ''
                if name[:4] == 'PUSH':
                    if push_depths != push_params[0]:
                        continue
                    for i in range(code_size):
                        v = int(name[4:])
                        w = random.randrange(256**v)
                        c += chr(0x5f + v) + utils.zpad(utils.encode_int(w), v)
                elif name[:3] == 'DUP':
                    if push_depths != push_params[0]:
                        continue
                    for _ in range(inargs):
                        v = push_depths[_ * len(push_depths) // code_size]
                        w = random.randrange(256**v)
                        c += chr(0x5f + v) + utils.zpad(utils.encode_int(w), v)
                    for i in range(code_size):
                        c += chr(opcode)
                    for i in range(outargs):
                        c += chr(0x50)
                elif name[:4] == "SWAP":
                    if push_depths != push_params[0]:
                        continue
                    for _ in range(inargs):
                        v = push_depths[_ * len(push_depths) // code_size]
                        w = random.randrange(256**v)
                        c += chr(0x5f + v) + utils.zpad(utils.encode_int(w), v)
                    for i in range(code_size):
                        c += chr(opcode)
                    for i in range(outargs):
                        c += chr(0x50)
                elif name == "POP":
                    if push_depths != push_params[0]:
                        continue
                    for _ in range(code_size):
                        v = push_depths[_ * len(push_depths) // code_size]
                        w = random.randrange(256**v)
                        c += chr(0x5f + v) + utils.zpad(utils.encode_int(w), v)
                        c += '\x50'
                    # for i in range(code_size):
                    #     c += chr(opcode)
                elif name == 'SHA3':
                    if push_depths != push_params[0]:
                        continue
                    v = 32
                    w = random.randrange(256**v)
                    c += chr(0x5f + v) + utils.zpad(utils.encode_int(w), v)
                    _w = 0
                    c += chr(0x5f + 1) + utils.zpad(utils.encode_int(_w), 1)
                    c += '\x52'
                    c += chr(0x5f + v) + utils.zpad(utils.encode_int(w), v)
                    _w += 32
                    c += chr(0x5f + 1) + utils.zpad(utils.encode_int(_w), 1)
                    c += '\x52'
                    c += chr(0x5f + v) + utils.zpad(utils.encode_int(w), v)
                    _w += 64
                    c += chr(0x5f + 1) + utils.zpad(utils.encode_int(_w), 1)
                    c += '\x52'
                    c += chr(0x5f + v) + utils.zpad(utils.encode_int(w), v)
                    _w += 128
                    c += chr(0x5f + 1) + utils.zpad(utils.encode_int(_w), 1)
                    c += '\x52'
                    # c += chr(0x5f + v) + utils.zpad(utils.encode_int(w), v)
                    for i in range(code_size):
                        c += chr(0x59)
                        c += '\x60\x00'
                        c += chr(opcode)
                        c += '\x50'
                    c += '\x60\x48' + '\x60\x00' + '\x53' + '\x60\x45' + '\x60\x01' + '\x53' + '\x60\x4c' + '\x60\x02' + '\x53' + '\x60\x4c' + '\x60\x03' + '\x53' + '\x60\x4f' + '\x60\x04' + '\x53' + '\x60\x48' + '\x60\x05' + '\x53' + '\x60\x45' + '\x60\x06' + '\x53' + '\x60\x4c' + '\x60\x07' + '\x53' + '\x60\x4c' + '\x60\x08' + '\x53' + '\x60\x4f' + '\x60\x09' + '\x53' + '\x60\x48' + '\x60\x0a' + '\x53' + '\x60\x45' + '\x60\x0b' + '\x53' + '\x60\x4c' + '\x60\x0c' + '\x53' + '\x60\x4c' + '\x60\x0d' + '\x53' + '\x60\x4f' + '\x60\x0e' + '\x53' + '\x60\x48' + '\x60\x0f' + '\x53' + '\x60\x45' + '\x60\x10' + '\x53' + '\x60\x4c' + '\x60\x11' + '\x53' + '\x60\x4c' + '\x60\x12' + '\x53' + '\x60\x4f' + '\x60\x13' + '\x53' + '\x60\x48' + '\x60\x14' + '\x53' + '\x60\x45' + '\x60\x15' + '\x53' + '\x60\x4c' + '\x60\x16' + '\x53' + '\x60\x4c' + '\x60\x17' + '\x53' + '\x60\x4f' + '\x60\x18' + '\x53' + '\x60\x48' + '\x60\x19' + '\x53' + '\x60\x45' + '\x60\x1a' + '\x53' + '\x60\x4c' + '\x60\x1b' + '\x53' + '\x60\x4c' + '\x60\x1c' + '\x53' + '\x60\x4f' + '\x60\x1d' + '\x53' + '\x60\x48' + '\x60\x1e' + '\x53' + '\x60\x45' + '\x60\x1f' + '\x53' + '\x60\x1f' + '\x60\x00'
                    for i in range(code_size):
                        c += chr(opcode)
                        c += '\x50'
                elif name == 'MLOAD':
                    if push_depths != push_params[0]:
                        continue
                    w = random.randrange(256**32)
                    c += chr(0x7f) + utils.zpad(utils.encode_int(w), 32)
                    c += '\x60\x00' + '\x52' + '\x60\x00'
                    for i in range(code_size):
                        c += chr(opcode)
                        c += '\x50' + '\x60\x00'
                elif name == 'MSTORE':
                    if push_depths != push_params[0]:
                        continue
                    for i in range(code_size):
                        v = 32
                        w = random.randrange(256**v)
                        c += chr(0x5f + v) + utils.zpad(utils.encode_int(w), v)
                        _w = random.randrange(256**1)
                        c += chr(0x5f + 1) + utils.zpad(
                            utils.encode_int(_w), 1)
                        c += chr(opcode)
                elif name == 'MSTORE8':
                    if push_depths != push_params[0]:
                        continue
                    for i in range(code_size):
                        w = random.randrange(256)
                        c += chr(0x5f + 1) + utils.zpad(utils.encode_int(w), 1)
                        _w = random.randrange(32)
                        c += chr(0x5f + 1) + utils.zpad(
                            utils.encode_int(_w), 1)
                        c += chr(opcode)
                elif name == 'CALLDATALOAD':
                    if push_depths != push_params[0]:
                        continue
                    for i in range(code_size):
                        c += '\x60\x00'
                        c += chr(opcode)
                        c += '\x50'
                elif name == 'CALLDATACOPY':
                    if push_depths != push_params[0]:
                        continue
                    v = 32
                    w = random.randrange(256**v)
                    c += chr(0x5f + v) + utils.zpad(utils.encode_int(w), v)
                    _w = 0
                    c += chr(0x5f + 1) + utils.zpad(utils.encode_int(_w), 1)
                    c += '\x52'
                    for i in range(code_size):
                        c += '\x36\x60\x00'
                        _w = 256
                        c += chr(0x5f + 2) + utils.zpad(
                            utils.encode_int(_w), 1)
                        c += chr(opcode)
                elif name == 'EXTCODECOPY':
                    if push_depths != push_params[0]:
                        continue
                    for i in range(code_size):
                        c += '\x73\xee\xefSt\xfc\xe5\xed\xbc\x8e*\x86\x97\xc1S1g~n\xbf\x0b' + '\x3b' + '\x60\x00\x60\x00' '\x73\xee\xefSt\xfc\xe5\xed\xbc\x8e*\x86\x97\xc1S1g~n\xbf\x0b'
                        c += chr(opcode)
                elif name == 'EXTCODESIZE':
                    if push_depths != push_params[0]:
                        continue
                    for i in range(code_size):
                        c += '\x73\x0fW.R\x95\xc5\x7f\x15\x88o\x9b&>/m-l{^\xc6'
                        c += chr(opcode)
                elif name == 'CODECOPY':
                    if push_depths != push_params[0]:
                        continue
                    # coded = '`r`\xb5\x01P`\xb9`\xb4\x01P`\x8a`S\x01P`\xa4`z\x01P`\x92`\xc3\x01P`J'
                    # c += coded
                    for i in range(code_size):
                        c += '\x73\x0fW.R\x95\xc5\x7f\x15\x88o\x9b&>/m-l{^\xc6'
                        c += '\x38\x60\x00\x60\x00' + chr(opcode)
                elif name == "BALANCE":
                    if push_depths != push_params[0]:
                        continue
                    for i in range(code_size):
                        c += '\x73\x0fW.R\x95\xc5\x7f\x15\x88o\x9b&>/m-l{^\xc6'
                        c += chr(opcode)
                elif name == 'SSTORE':
                    if push_depths != push_params[0]:
                        continue
                    for i in range(code_size):
                        v = 32
                        w = random.randrange(256**v)
                        c += chr(0x5f + v) + utils.zpad(utils.encode_int(w), v)
                        _w = 86
                        c += chr(0x5f + 1) + utils.zpad(
                            utils.encode_int(_w), 1)
                        c += chr(opcode)
                elif name == 'SLOAD':
                    if push_depths != push_params[0]:
                        continue
                    for i in range(code_size):
                        v = 1
                        w = 86
                        c += chr(0x5f + v) + utils.zpad(utils.encode_int(w), v)
                        c += chr(opcode)
                elif name == "BLOCKHASH":
                    for i in range(code_size):
                        for i in range(inargs):
                            v = 1
                            w = random.randrange(256**v)
                            c += chr(0x5f + v) + utils.zpad(
                                utils.encode_int(w), 1)
                        c += chr(opcode)
                        # for _ in range(outargs):
                        #     c += chr(0x50)
                elif name == "EXP":
                    if push_depths != push_params[0]:
                        continue
                    for i in range(code_size):
                        for _ in range(inargs):
                            v = 32
                            w = random.randrange(256**v)
                            c += chr(0x5f + v) + utils.zpad(
                                utils.encode_int(w), 1)
                        c += chr(opcode)
                        for _ in range(outargs):
                            c += chr(0x50)
                # elif name == "RETURNDATACOPY":
                #     if push_depths != push_params[0]:
                #         continue
                #     for i in range(code_size):
                #         c += '\x60\x00\x60\x00\x60\x00'
                #         c += chr(opcode)
                # elif name == "RETURNDATASIZE":
                #     if push_depths != push_params[0]:
                #         continue
                #     for i in range(code_size):
                #         c += chr(opcode)
                else:
                    for i in range(code_size):
                        for _ in range(inargs):
                            v = push_depths[i * len(push_depths) // code_size]
                            w = random.randrange(256**v)
                            c += chr(0x5f + v) + utils.zpad(
                                utils.encode_int(w), v)
                        c += chr(opcode)
                        for _ in range(outargs):
                            c += chr(0x50)
                # PUSH1 0 MLOAD . DUP1 . PUSH1 1 ADD PUSH1 0 MSTORE . PUSH2 <jumps> GT PUSH1 0 JUMPI
                # c += '\x60\x00\x51' + '\x80' + '\x60\x01\x01\x60\x00\x52' + \
                #     '\x61'+chr(jump_num // 256) + chr(jump_num % 256) + '\x11\x60\x00\x57'

                o = o = {
                    "callcreates": [],
                    "env": {
                        "currentCoinbase":
                        "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
                        "currentDifficulty":
                        "256",
                        "currentGasLimit":
                        "1000000000",
                        "currentNumber":
                        "257",
                        "currentTimestamp":
                        "1",
                        "previousHash":
                        "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
                    },
                    "exec": {
                        "address": "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
                        "caller": "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
                        "code": "0x" + c.encode('hex'),
                        "data":
                        "0xc4ede3d3c49e38e7351405f35621bafce3a2ef3cef0af0a119fe3772ffcc2a8a0aa48ac7dc2bdc26dfad6de18cd9ea15a119bd676f5b3e492f2c2a5cc3ed6f6182041cda117a1fdc958df9e53b3f957d676f15003da9d6792800b612d8f9ec6d85ea7ca5f70789cf04137db582e89c73fcd3fafeb24db17c91ef9950eca6d3c194be97be7ecae7c2892fb915619d4845dcbd9510544a9cb88a54a7baa313d85c196387eeaeaddf8c03d2d0a222bf3b94c87c9ad20180f821db4f85347247e650200bc5b1b045f0da19aee3e94c585bb08bc47586962ec3269f66318ab2356e6a786dc5b0b51af3dc0d7751f22a63301baa9383c2c5e4d953e558b09af532e075",
                        "gas": "100000000",
                        "gasPrice": "100000000000000",
                        "origin": "cd1722f3947def4cf144679da39c4c32bdc35681",
                        "value": "1000000000000000000"
                    },
                    "pre": {
                        "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6": {
                            "balance": "1000000000000000000",
                            "code":
                            "0x36303732363062353031353036306239363062343031353036303861363035",
                            "nonce": "0",
                            "storage": {
                                "0x56":
                                "0x0f5b2ebf118c64ede45e3d5f4436fd219110d1f20442c6f153a22c39a70bf7df"
                            }
                        }
                    },
                    "gas": "1000000000",
                    "logs": [],
                    "out": "0x"
                }
                out[name + str(_subid)] = o
                _subid += 1
    return out
Example #19
0
def run_test_vm(params):
    print params
    pre = params['pre']
    exek = params['exec']
    callcreates = params.get('callcreates', [])
    env = params['env']
    post = params.get('post', {})

    check_testdata(env.keys(), ['currentGasLimit', 'currentTimestamp',
                                'previousHash', 'currentCoinbase',
                                'currentDifficulty', 'currentNumber'])
    # setup env
    blk = blocks.Block(db,
                       prevhash=env['previousHash'].decode('hex'),
                       number=int(env['currentNumber']),
                       coinbase=env['currentCoinbase'],
                       difficulty=int(env['currentDifficulty']),
                       gas_limit=int(env['currentGasLimit']),
                       timestamp=int(env['currentTimestamp']))

    # code FIXME WHAT TO DO WITH THIS CODE???
    # if isinstance(env['code'], str):
    #     continue
    # else:
    # addr = 0 # FIXME
    #     blk.set_code(addr, ''.join(map(chr, env['code'])))

    # setup state
    for address, h in pre.items():
        check_testdata(h.keys(), ['code', 'nonce', 'balance', 'storage'])
        blk.set_nonce(address, int(h['nonce']))
        blk.set_balance(address, int(h['balance']))
        blk.set_code(address, h['code'][2:].decode('hex'))
        for k, v in h['storage'].iteritems():
            blk.set_storage_data(address,
                                 u.big_endian_to_int(k[2:].decode('hex')),
                                 u.big_endian_to_int(v[2:].decode('hex')))

    # execute transactions
    sender = exek['caller']  # a party that originates a call
    recvaddr = exek['address']
    tx = transactions.Transaction(
        nonce=blk._get_acct_item(exek['caller'], 'nonce'),
        gasprice=int(exek['gasPrice']),
        startgas=int(exek['gas']),
        to=recvaddr,
        value=int(exek['value']),
        data=exek['data'][2:].decode('hex'))
    tx.sender = sender

    # capture apply_message calls
    apply_message_calls = []
    orig_apply_msg = pb.apply_msg

    ext = pb.VMExt(blk, tx)

    def call_wrapper(msg):
        ext.set_balance(msg.sender, ext.get_balance(msg.sender) - msg.value)
        hexdata = msg.data.extract_all().encode('hex')
        apply_message_calls.append(dict(gasLimit=msg.gas, value=msg.value,
                                        destination=msg.to, data=hexdata))
        return 1, msg.gas, ''

    def sendmsg_wrapper(msg, code):
        ext.set_balance(msg.sender, ext.get_balance(msg.sender) - msg.value)
        hexdata = msg.data.extract_all().encode('hex')
        apply_message_calls.append(dict(gasLimit=msg.gas, value=msg.value,
                                        destination=msg.to, data=hexdata))
        return 1, msg.gas, ''

    def create_wrapper(msg):
        ext.set_balance(msg.sender, ext.get_balance(msg.sender) - msg.value)
        sender = msg.sender.decode('hex') if len(msg.sender) == 40 else msg.sender
        nonce = u.encode_int(ext._block.get_nonce(msg.sender))
        addr = u.sha3(rlp.encode([sender, nonce]))[12:].encode('hex')
        hexdata = msg.data.extract_all().encode('hex')
        apply_message_calls.append(dict(gasLimit=msg.gas, value=msg.value,
                                        destination='', data=hexdata))
        return 1, msg.gas, addr

    ext.sendmsg = sendmsg_wrapper
    ext.call = call_wrapper
    ext.create = create_wrapper

    def blkhash(n):
        if n >= ext.block_number or n < ext.block_number - 256:
            return ''
        else:
            return u.sha3(str(n))

    ext.block_hash = blkhash

    msg = vm.Message(tx.sender, tx.to, tx.value, tx.startgas,
                     vm.CallData([ord(x) for x in tx.data]))
    success, gas_remained, output = \
        vm.vm_execute(ext, msg, exek['code'][2:].decode('hex'))
    pb.apply_msg = orig_apply_msg
    blk.commit_state()

    """
     generally expected that the test implementer will read env, exec and pre
     then check their results against gas, logs, out, post and callcreates.
     If an exception is expected, then latter sections are absent in the test.
     Since the reverting of the state is not part of the VM tests.
     """

    if not success:
        assert 'gas' not in params
        assert 'post' not in params
        return

    for k in ['gas', 'logs', 'out', 'post', 'callcreates']:
        assert k in params
    assert len(callcreates) == len(apply_message_calls)

    # check against callcreates
    for i, callcreate in enumerate(callcreates):
        amc = apply_message_calls[i]
        assert callcreate['data'] == '0x' + amc['data']
        assert callcreate['gasLimit'] == str(amc['gasLimit'])
        assert callcreate['value'] == str(amc['value'])
        assert callcreate['destination'] == amc['destination']

    if 'out' in params:
        assert '0x' + ''.join(map(chr, output)).encode('hex') == params['out']
    if 'gas' in params:
        assert str(gas_remained) == params['gas']
    if 'logs' in params:
        """
        The logs sections is a mapping between the blooms and their corresponding logentries.
        Each logentry has the format:
        address: The address of the logentry.
        data: The data of the logentry.
        topics: The topics of the logentry, given as an array of values.
        """
        test_logs = params['logs']
        vm_logs = []
        for log in tx.logs:
            vm_logs.append({
                "bloom": bloom.b64(bloom.bloom_from_list(log.bloomables())).encode('hex'),
                "address": log.address,
                "data": '0x' + log.data.encode('hex'),
                "topics": [u.zpad(u.int_to_big_endian(t), 32).encode('hex') for t in log.topics]
            })

        assert len(vm_logs) == len(test_logs)
        assert vm_logs == test_logs

    # check state
    for address, data in post.items():
        state = blk.account_to_dict(address, for_vmtest=True)
        state.pop('storage_root', None)  # attribute not present in vmtest fixtures
        assert data == state
Example #20
0
    def test_reservation(self):
        data = ['ethereum.bit', '54.200.236.204']
        ans = self.sim.tx(self.ALICE, self.contract, 0, data)

        assert ans == [1]
        assert self.sim.get_storage_dict(self.contract) == {utils.zpad('ethereum.bit', 32): '54.200.236.204'}