示例#1
0
def compute_state_test_unit(state, txdata, indices, konfig):
    state.env.config = konfig
    s = state.snapshot()
    try:
        # Create the transaction
        tx = transactions.Transaction(
            nonce=parse_int_or_hex(txdata['nonce'] or b"0"),
            gasprice=parse_int_or_hex(txdata['gasPrice'] or b"0"),
            startgas=parse_int_or_hex(txdata['gasLimit'][indices["gas"]]
                                      or b"0"),
            to=decode_hex(remove_0x_head(txdata['to'])),
            value=parse_int_or_hex(txdata['value'][indices["value"]] or b"0"),
            data=decode_hex(remove_0x_head(txdata['data'][indices["data"]])))
        if 'secretKey' in txdata:
            tx.sign(decode_hex(remove_0x_head(txdata['secretKey'])))
        else:
            tx.v = parse_int_or_hex(txdata['v'])
        # Run it
        prev = state.to_dict()
        success, output = apply_transaction(state, tx)
        print("Applied tx")
    except InvalidTransaction as e:
        print("Exception: %r" % e)
        success, output = False, b''
    # state.set_code('0x3e180b1862f9d158abb5e519a6d8605540c23682', b'')
    state.commit()
    post = state.to_dict()
    # print('pozt', post)
    output_decl = {
        "hash": '0x' + encode_hex(state.trie.root_hash),
        "indexes": indices,
        "diff": mk_state_diff(prev, post)
    }
    state.revert(s)
    return output_decl
def init_state(env, pre, is_qkc_state, qkc_env=None):
    # Setup env
    db = InMemoryDb()
    state_env = Env(config=konfig)
    state_env.db = db
    state = State(
        env=state_env,
        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"]),
        qkc_config=qkc_env.quark_chain_config,
        # If testing QuarkChain states, should not use mock account
        use_mock_evm_account=not is_qkc_state,
    )

    seen_token_ids = set()
    # Fill up pre
    for address, h in list(pre.items()):
        assert len(address) in (40, 42)
        address = decode_hex(remove_0x_head(address))
        state.set_nonce(address, parse_int_or_hex(h["nonce"]))
        if is_qkc_state and "balances" in h:
            # In QuarkChain state tests, can either specify balance map or single balance
            for token_id, balance in h["balances"].items():
                parsed_token_id = parse_int_or_hex(token_id)
                state.set_token_balance(
                    address, parsed_token_id, parse_int_or_hex(balance)
                )
                seen_token_ids.add(parsed_token_id)
        else:
            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:])),
            )

    # Update allowed token IDs
    if seen_token_ids:
        state.qkc_config._allowed_token_ids = seen_token_ids

    state.commit(allow_empties=True)
    return state
def verify_state_test(test):
    print("Verifying state test")
    if "env" not in test:
        raise EnvNotFoundException("Env not found")
    _state = init_state(test["env"], test["pre"], test["qkcstate"], qkc_env=test["qkc"])
    for config_name, results in test["post"].items():
        # Old protocol versions may not be supported
        if config_name not in network_to_test:
            continue
        print("Testing for %s" % config_name)
        for result in results:
            data = test["transaction"]["data"][result["indexes"]["data"]]
            if len(data) > 2000:
                data = "data<%d>" % (len(data) // 2 - 1)
            print(
                "Checking for values: g %d v %d d %s (indexes g %d v %d d %d)"
                % (
                    parse_int_or_hex(
                        test["transaction"]["gasLimit"][result["indexes"]["gas"]]
                    ),
                    parse_int_or_hex(
                        test["transaction"]["value"][result["indexes"]["value"]]
                    ),
                    data,
                    result["indexes"]["gas"],
                    result["indexes"]["value"],
                    result["indexes"]["data"],
                )
            )
            computed = compute_state_test_unit(
                _state,
                test["transaction"],
                result["indexes"],
                evm_config,
                test["qkcstate"],
                qkc_env=test["qkc"],
            )
            if computed["hash"][-64:] != result["hash"][-64:]:
                for k in computed["diff"]:
                    print(k, computed["diff"][k], file=sys.stderr)
                print(test["filename"], test["testname"], file=sys.stderr)
                raise Exception(
                    "Hash mismatch, computed: %s, supplied: %s"
                    % (computed["hash"], result["hash"])
                )
            else:
                for k in computed["diff"]:
                    print(k, computed["diff"][k])
                print("Hash matched!: %s" % computed["hash"])
    return True
def compute_state_test_unit(state,
                            txdata,
                            indices,
                            konfig,
                            is_qkc_state,
                            qkc_env=None):
    state.env.config = konfig
    s = state.snapshot()
    if "transferTokenId" in txdata:
        transfer_token_id = parse_int_or_hex(
            txdata["transferTokenId"][indices["transferTokenId"]])
    else:
        transfer_token_id = token_id_encode("QKC")
    try:
        # Create the transaction
        tx = transactions.Transaction(
            nonce=parse_int_or_hex(txdata["nonce"] or b"0"),
            gasprice=parse_int_or_hex(txdata["gasPrice"] or b"0"),
            startgas=parse_int_or_hex(txdata["gasLimit"][indices["gas"]]
                                      or b"0"),
            to=decode_hex(remove_0x_head(txdata["to"])),
            value=parse_int_or_hex(txdata["value"][indices["value"]] or b"0"),
            data=decode_hex(remove_0x_head(txdata["data"][indices["data"]])),
            gas_token_id=token_id_encode("QKC"),
            transfer_token_id=transfer_token_id,
            # Should not set testing flag if testing QuarkChain state
            is_testing=not is_qkc_state,
        )
        tx.set_quark_chain_config(qkc_env.quark_chain_config)
        if "secretKey" in txdata:
            tx.sign(decode_hex(remove_0x_head(txdata["secretKey"])))
        else:
            tx._in_mutable_context = True
            tx.v = parse_int_or_hex(txdata["v"])
            tx._in_mutable_context = False
        # Run it
        prev = state.to_dict()
        success, output = apply_transaction(state,
                                            tx,
                                            tx_wrapper_hash=bytes(32))
    except InvalidTransaction as e:
        print("Exception: %r" % e)
        success, output = False, b""
    # touch coinbase, make behavior consistent with go-ethereum
    state.delta_token_balance(state.block_coinbase, token_id_encode("QKC"), 0)
    state.commit()
    post = state.to_dict()
    output_decl = {
        "hash": "0x" + encode_hex(state.trie.root_hash),
        "indexes": indices,
        "diff": mk_state_diff(prev, post),
    }
    state.revert(s)
    return output_decl
def init_state(env, pre):
    # Setup env
    db = InMemoryDb()
    stateEnv = Env(config=konfig)
    stateEnv.db = db
    state = State(
        env=stateEnv,
        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