Example #1
0
def state_from_genesis_declaration(genesis_data, env, block=None, allow_empties=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)
    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.prev_headers=[block.header]
    return state
Example #2
0
def dict_to_prev_header(h):
    return FakeHeader(hash=parse_as_bin(h['hash']),
                      number=parse_as_int(h['number']),
                      timestamp=parse_as_int(h['timestamp']),
                      difficulty=parse_as_int(h['difficulty']),
                      gas_used=parse_as_int(h.get('gas_used', '0')),
                      gas_limit=parse_as_int(h['gas_limit']),
                      uncles_hash=parse_as_bin(h.get('uncles_hash', '0x' + encode_hex(BLANK_UNCLES_HASH))))
Example #3
0
def block_from_genesis_declaration(genesis_data, env):
    h = BlockHeader(nonce=parse_as_bin(genesis_data["nonce"]),
                    difficulty=parse_as_int(genesis_data["difficulty"]),
                    mixhash=parse_as_bin(genesis_data.get("mixhash", genesis_data.get("mixHash", "0"*64))),
                    coinbase=parse_as_bin(genesis_data["coinbase"]),
                    bloom=parse_as_int(genesis_data.get("bloom", "0")),
                    timestamp=parse_as_int(genesis_data["timestamp"]),
                    prevhash=parse_as_bin(genesis_data["parentHash"]),
                    extra_data=parse_as_bin(genesis_data["extraData"]),
                    gas_used=parse_as_int(genesis_data.get("gasUsed", "0")),
                    gas_limit=parse_as_int(genesis_data["gasLimit"]))
    return Block(h, [], [])
Example #4
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
Example #5
0
 def from_snapshot(cls, snapshot_data, env, executing_on_head=False):
     state = State(env=env)
     if "alloc" in snapshot_data:
         for addr, data in snapshot_data["alloc"].items():
             if len(addr) == 40:
                 addr = decode_hex(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)))
     elif "state_root" in snapshot_data:
         state.trie.root_hash = parse_as_bin(snapshot_data["state_root"])
     else:
         raise Exception(
             "Must specify either alloc or state root parameter")
     for k, default in STATE_DEFAULTS.items():
         default = copy.copy(default)
         v = snapshot_data[k] if k in snapshot_data else None
         if is_numeric(default):
             setattr(state, k, parse_as_int(v)
                     if k in snapshot_data else default)
         elif is_string(default):
             setattr(state, k, parse_as_bin(v)
                     if k in snapshot_data else default)
         elif k == 'prev_headers':
             if k in snapshot_data:
                 headers = [dict_to_prev_header(h) for h in v]
             else:
                 headers = default
             setattr(state, k, headers)
         elif k == 'recent_uncles':
             if k in snapshot_data:
                 uncles = {}
                 for height, _uncles in v.items():
                     uncles[int(height)] = []
                     for uncle in _uncles:
                         uncles[int(height)].append(parse_as_bin(uncle))
             else:
                 uncles = default
             setattr(state, k, uncles)
     if executing_on_head:
         state.executing_on_head = True
     state.commit()
     state.changed = {}
     return state
Example #6
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
Example #7
0
def normalize_hash(hash):
    if len(hash) != 32:
        hash = parse_as_bin(hash)
    assert len(hash) == 32
    return hash
Example #8
0
STARTGAS = 3141592  # TODO: use config
GASPRICE = 1  # TODO: use config
DEPOSIT_SIZE = sharding_config['DEPOSIT_SIZE']
WITHDRAW_HASH = utils.sha3("withdraw")
ADD_HEADER_TOPIC = utils.sha3("add_header()")

_valmgr_ct = None
_valmgr_code = None
_valmgr_bytecode = None
_valmgr_addr = None
_valmgr_sender_addr = None
_valmgr_tx = None

viper_rlp_decoder_tx = rlp.decode(
    utils.parse_as_bin(
        "0xf90237808506fc23ac00830330888080b902246102128061000e60003961022056600060007f010000000000000000000000000000000000000000000000000000000000000060003504600060c082121515585760f882121561004d5760bf820336141558576001905061006e565b600181013560f783036020035260005160f6830301361415585760f6820390505b5b368112156101c2577f010000000000000000000000000000000000000000000000000000000000000081350483602086026040015260018501945060808112156100d55760018461044001526001828561046001376001820191506021840193506101bc565b60b881121561014357608081038461044001526080810360018301856104600137608181141561012e5760807f010000000000000000000000000000000000000000000000000000000000000060018401350412151558575b607f81038201915060608103840193506101bb565b60c08112156101b857600182013560b782036020035260005160388112157f010000000000000000000000000000000000000000000000000000000000000060018501350402155857808561044001528060b6838501038661046001378060b6830301830192506020810185019450506101ba565bfe5b5b5b5061006f565b601f841315155857602060208502016020810391505b6000821215156101fc578082604001510182826104400301526020820391506101d8565b808401610420528381018161044003f350505050505b6000f31b2d4f"
    ), Transaction)
viper_rlp_decoder_addr = viper_rlp_decoder_tx.creates

sighasher_tx = rlp.decode(
    utils.parse_as_bin(
        "0xf9016d808506fc23ac0083026a508080b9015a6101488061000e6000396101565660007f01000000000000000000000000000000000000000000000000000000000000006000350460f8811215610038576001915061003f565b60f6810391505b508060005b368312156100c8577f01000000000000000000000000000000000000000000000000000000000000008335048391506080811215610087576001840193506100c2565b60b881121561009d57607f8103840193506100c1565b60c08112156100c05760b68103600185013560b783036020035260005101840193505b5b5b50610044565b81810360388112156100f4578060c00160005380836001378060010160002060e052602060e0f3610143565b61010081121561010557600161011b565b6201000081121561011757600261011a565b60035b5b8160005280601f038160f701815382856020378282600101018120610140526020610140f350505b505050505b6000f31b2d4f"
    ), Transaction)
sighasher_addr = sighasher_tx.creates


class MessageFailed(Exception):
    pass


def mk_validation_code(address):
Example #9
0
def send_msg_transfer_value(mainchain_state, shard_state, shard_id, tx):
    urs_addr = get_urs_contract(shard_id)['addr']
    log_rctx.debug("Begin: urs.balance={}, tx.to.balance={}".format(
        shard_state.get_balance(urs_addr), shard_state.get_balance(tx.to)))

    receipt_id = tx.r
    # we should deduct the startgas of this message in advance, because
    # the message may be possibly a contract, not only a normal value transfer.
    value = tx.value - tx.gasprice * tx.startgas
    log_rctx.debug(
        "value={}, tx.value={}, tx.gasprice={}, tx.startgas={}".format(
            value, tx.value, tx.gasprice, tx.startgas))
    if value <= 0:
        return False, None

    # start transactioning
    if not send_msg_add_used_receipt(shard_state, shard_id, receipt_id):
        return False, None

    receipt_sender_hex = call_valmgr(mainchain_state, 'get_receipts__sender',
                                     [receipt_id])
    receipt_data = call_valmgr(mainchain_state, 'get_receipts__data',
                               [receipt_id])
    msg_data = (b'00' *
                12) + utils.parse_as_bin(receipt_sender_hex) + receipt_data
    msg = vm.Message(urs_addr, tx.to, value,
                     tx.startgas - tx.intrinsic_gas_used, msg_data)
    env_tx = Transaction(0, tx.gasprice, tx.startgas, b'', 0, b'')
    env_tx._sender = urs_addr
    ext = VMExt(shard_state, env_tx)
    log_rctx.debug(
        "before apply_msg: urs_addr.balance={}, tx.to.balance={}".format(
            shard_state.get_balance(urs_addr), shard_state.get_balance(tx.to)))
    # even if `transfer_value` in `apply_msg` fails, no error occurs.
    # it seems no raise in apply_msg
    result, gas_remained, data = apply_msg(ext, msg)
    log_rctx.debug(
        "after apply_msg:  urs_addr.balance={}, tx.to.balance={}".format(
            shard_state.get_balance(urs_addr), shard_state.get_balance(tx.to)))

    assert gas_remained >= 0

    gas_used = tx.startgas - gas_remained

    # Transaction failed
    if not result:
        log_rctx.debug('TX FAILED',
                       reason='out of gas',
                       startgas=tx.startgas,
                       gas_remained=gas_remained)
        shard_state.gas_used += tx.startgas
        shard_state.delta_balance(tx.to, tx.gasprice * gas_remained)
        shard_state.delta_balance(shard_state.block_coinbase,
                                  tx.gasprice * gas_used)
        output = b''
        success = 0
    # Transaction success
    else:
        log_rctx.debug('TX SUCCESS', data=data)
        shard_state.refunds += len(set(
            shard_state.suicides)) * opcodes.GSUICIDEREFUND
        if shard_state.refunds > 0:
            log_rctx.debug('Refunding',
                           gas_refunded=min(shard_state.refunds,
                                            gas_used // 2))
            gas_remained += min(shard_state.refunds, gas_used // 2)
            gas_used -= min(shard_state.refunds, gas_used // 2)
            shard_state.refunds = 0
        # sell remaining gas
        shard_state.delta_balance(tx.to, tx.gasprice * gas_remained)
        log_rctx.debug("gas_remained={}, gasprice={}".format(
            gas_remained, tx.gasprice))
        log_rctx.debug("End: urs.balance={}, tx.to.balance={}".format(
            shard_state.get_balance(urs_addr), shard_state.get_balance(tx.to)))
        shard_state.delta_balance(shard_state.block_coinbase,
                                  tx.gasprice * gas_used)
        shard_state.gas_used += gas_used
        if tx.to:
            output = utils.bytearray_to_bytestr(data)
        else:
            output = data
        success = 1

    # Clear suicides
    suicides = shard_state.suicides
    shard_state.suicides = []
    for s in suicides:
        shard_state.set_balance(s, 0)
        shard_state.del_account(s)

    # Pre-Metropolis: commit state after every tx
    if not shard_state.is_METROPOLIS() and not SKIP_MEDSTATES:
        shard_state.commit()

    # Construct a receipt
    r = mk_receipt(shard_state, success, shard_state.logs)
    _logs = list(shard_state.logs)
    shard_state.logs = []
    shard_state.add_receipt(r)
    shard_state.set_param('bloom', shard_state.bloom | r.bloom)
    shard_state.set_param('txindex', shard_state.txindex + 1)

    return success, output