Exemple #1
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
Exemple #2
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
Exemple #3
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()
Exemple #4
0
def encode_hex_from_int(x):
    return utils.zpad(utils.int_to_big_endian(x), 64).encode('hex')
Exemple #5
0
def encode_hex_from_int(x):
    return utils.zpad(utils.int_to_big_endian(x), 64).encode('hex')
 def g(x):
     if type(x) in [int, long]: x=utils.int_to_big_endian(x)
     return x
Exemple #7
0
def step_impl(context):
    total_payload_length = sum(len(rlp.encode(x)) for x in context.src)
    context.length_bin = int_to_big_endian(total_payload_length)
    assert context.dst[0] == chr(0xf7 + len(context.length_bin))
Exemple #8
0
def step_impl(context):
    context.length_bin = int_to_big_endian(len(context.src))
    assert context.dst[0] == chr(0xb7 + len(context.length_bin))
Exemple #9
0
def step_impl(context):
    total_payload_length = sum(len(rlp.encode(x)) for x in context.src)
    context.length_bin = int_to_big_endian(total_payload_length)
    assert context.dst[0] == chr(0xf7 + len(context.length_bin))
Exemple #10
0
def step_impl(context):
    context.length_bin = int_to_big_endian(len(context.src))
    assert context.dst[0] == chr(0xb7 + len(context.length_bin))
 def g(x):
     if type(x) in [int, long]: x = utils.int_to_big_endian(x)
     return x