示例#1
0
    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(),
                )
示例#2
0
    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],
                    )
示例#3
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
        )