def test_getTransactionReceipt_on_contract_creation(self): id1 = Identity.create_random_identity() acc1 = Address.create_from_identity(id1, full_shard_id=0) with ClusterContext( 1, acc1, small_coinbase=True) as clusters, jrpc_server_context( clusters[0].master): master = clusters[0].master slaves = clusters[0].slave_list branch = Branch.create(2, 0) to_full_shard_id = acc1.full_shard_id + 2 tx = create_contract_creation_transaction( shard_state=slaves[0].shards[branch].state, key=id1.get_key(), from_address=acc1, to_full_shard_id=to_full_shard_id, ) self.assertTrue(slaves[0].add_tx(tx)) _, block1 = call_async(master.get_next_block_to_mine(address=acc1)) self.assertTrue( call_async(clusters[0].get_shard(0).add_block(block1))) for endpoint in ("getTransactionReceipt", "eth_getTransactionReceipt"): resp = send_request( endpoint, "0x" + tx.get_hash().hex() + branch.serialize().hex()) self.assertEqual(resp["transactionHash"], "0x" + tx.get_hash().hex()) self.assertEqual(resp["status"], "0x1") self.assertEqual(resp["cumulativeGasUsed"], "0x213eb") contract_address = mk_contract_address(acc1.recipient, to_full_shard_id, 0) self.assertEqual( resp["contractAddress"], "0x" + contract_address.hex() + to_full_shard_id.to_bytes(4, "big").hex(), )
def test_getLogs(self): id1 = Identity.create_random_identity() acc1 = Address.create_from_identity(id1, full_shard_key=0) expected_log_parts = { "logIndex": "0x0", "transactionIndex": "0x0", "blockNumber": "0x1", "blockHeight": "0x1", "data": "0x", } with ClusterContext( 1, acc1, small_coinbase=True) as clusters, jrpc_server_context( clusters[0].master): master = clusters[0].master slaves = clusters[0].slave_list tx = create_contract_creation_with_event_transaction( shard_state=clusters[0].get_shard_state(2 | 0), key=id1.get_key(), from_address=acc1, to_full_shard_key=acc1.full_shard_key, ) self.assertTrue(slaves[0].add_tx(tx)) block = call_async( master.get_next_block_to_mine(address=acc1, branch_value=0b10)) self.assertTrue( call_async(clusters[0].get_shard(2 | 0).add_block(block))) for using_eth_endpoint in (True, False): shard_id = hex(acc1.full_shard_key) if using_eth_endpoint: req = lambda o: send_request("eth_getLogs", [o, shard_id]) else: # `None` needed to bypass some request modification req = lambda o: send_request("getLogs", [o, shard_id]) # no filter object as wild cards resp = req({}) self.assertEqual(1, len(resp)) self.assertDictContainsSubset(expected_log_parts, resp[0]) # filter by contract address contract_addr = mk_contract_address(acc1.recipient, 0, acc1.full_shard_key) filter_obj = { "address": "0x" + contract_addr.hex() + ("" if using_eth_endpoint else hex( acc1.full_shard_key)[2:].zfill(8)) } resp = req(filter_obj) self.assertEqual(1, len(resp)) # filter by topics filter_obj = { "topics": [ "0xa9378d5bd800fae4d5b8d4c6712b2b64e8ecc86fdc831cb51944000fc7c8ecfa" ] } filter_obj_nested = { "topics": [[ "0xa9378d5bd800fae4d5b8d4c6712b2b64e8ecc86fdc831cb51944000fc7c8ecfa" ]] } for f in (filter_obj, filter_obj_nested): resp = req(f) self.assertEqual(1, len(resp)) self.assertDictContainsSubset(expected_log_parts, resp[0]) self.assertEqual( "0xa9378d5bd800fae4d5b8d4c6712b2b64e8ecc86fdc831cb51944000fc7c8ecfa", resp[0]["topics"][0], )
def test_contract_suicide(self): """ Kill Call Data: 0x41c0e1b5 """ QETH = token_id_encode("QETH") id1 = Identity.create_random_identity() acc1 = Address.create_from_identity(id1, full_shard_key=0) id2 = Identity.create_random_identity() acc2 = Address.create_from_identity(id2, full_shard_key=0) acc3 = Address.create_random_account(full_shard_key=0) env = get_test_env( genesis_account=acc1, genesis_minor_token_balances={ self.GENESIS_TOKEN: 200 * 10 ** 18, "QETH": 99999, }, ) state = create_default_shard_state(env=env) # 1. create contract BYTECODE = "6080604052348015600f57600080fd5b5060948061001e6000396000f3fe6080604052600436106039576000357c01000000000000000000000000000000000000000000000000000000009004806341c0e1b514603b575b005b348015604657600080fd5b50604d604f565b005b3373ffffffffffffffffffffffffffffffffffffffff16fffea165627a7a7230582034cc4e996685dcadcc12db798751d2913034a3e963356819f2293c3baea4a18c0029" """ pragma solidity ^0.5.1; contract Sample { function () payable external{} function kill() external {selfdestruct(msg.sender);} } """ CREATION_GAS = 92417 tx = contract_creation_tx( shard_state=state, key=id1.get_key(), from_address=acc1, to_full_shard_key=acc1.full_shard_key, bytecode=BYTECODE, gas_token_id=self.genesis_token, transfer_token_id=self.genesis_token, ) self.assertTrue(state.add_tx(tx)) b1 = state.create_block_to_mine(address=acc3) self.assertEqual(len(b1.tx_list), 1) state.finalize_and_add_block(b1) self.assertEqual(state.header_tip, b1.header) self.assertEqual(len(state.evm_state.receipts), 1) self.assertEqual(state.evm_state.receipts[0].state_root, b"\x01") self.assertEqual(state.evm_state.receipts[0].gas_used, CREATION_GAS) contract_address = mk_contract_address(acc1.recipient, 0, acc1.full_shard_key) self.assertEqual(contract_address, state.evm_state.receipts[0].contract_address) self.assertEqual( acc1.full_shard_key, state.evm_state.receipts[0].contract_full_shard_key ) self.assertEqual( state.get_token_balance(id1.recipient, self.genesis_token), 200 * 10 ** 18 - CREATION_GAS, ) self.assertEqual( state.get_token_balance(acc3.recipient, self.genesis_token), self.get_after_tax_reward(CREATION_GAS + self.shard_coinbase), ) tx_list, _ = state.db.get_transactions_by_address(acc1) self.assertEqual(tx_list[0].value, 0) self.assertEqual(tx_list[0].gas_token_id, self.genesis_token) self.assertEqual(tx_list[0].transfer_token_id, self.genesis_token) # 2. send some default token tx_send = create_transfer_transaction( shard_state=state, key=id1.get_key(), from_address=acc1, to_address=Address(contract_address, acc1.full_shard_key), value=10 * 10 ** 18, gas=opcodes.GTXCOST + 40, gas_price=1, nonce=None, data=b"", gas_token_id=self.genesis_token, transfer_token_id=self.genesis_token, ) self.assertTrue(state.add_tx(tx_send)) b2 = state.create_block_to_mine(address=acc3) self.assertEqual(len(b2.tx_list), 1) state.finalize_and_add_block(b2) self.assertEqual(state.header_tip, b2.header) self.assertEqual(len(state.evm_state.receipts), 1) self.assertEqual(state.evm_state.receipts[0].state_root, b"\x01") self.assertEqual(state.evm_state.receipts[0].gas_used, opcodes.GTXCOST + 40) self.assertEqual( state.get_token_balance(id1.recipient, self.genesis_token), 200 * 10 ** 18 - CREATION_GAS - (opcodes.GTXCOST + 40) - 10 * 10 ** 18, ) self.assertEqual( state.get_token_balance(contract_address, self.genesis_token), 10 * 10 ** 18 ) # 3. suicide SUICIDE_GAS = 13199 tx_kill = create_transfer_transaction( shard_state=state, key=id2.get_key(), from_address=acc2, to_address=Address(contract_address, acc1.full_shard_key), value=0, gas=1000000, gas_price=0, # !!! acc2 has no token yet... nonce=None, data=bytes.fromhex("41c0e1b5"), gas_token_id=self.genesis_token, transfer_token_id=self.genesis_token, ) self.assertTrue(state.add_tx(tx_kill)) b3 = state.create_block_to_mine(address=acc3) self.assertEqual(len(b3.tx_list), 1) state.finalize_and_add_block(b3) self.assertEqual(state.header_tip, b3.header) self.assertEqual(len(state.evm_state.receipts), 1) self.assertEqual(state.evm_state.receipts[0].state_root, b"\x01") self.assertEqual(state.evm_state.receipts[0].gas_used, SUICIDE_GAS) self.assertEqual( state.get_token_balance(id2.recipient, self.genesis_token), 10 * 10 ** 18 ) self.assertEqual( state.get_token_balance(contract_address, self.genesis_token), 0 )