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