Beispiel #1
0
    def test_xshard_tx_sent(self):
        id1 = Identity.create_random_identity()
        acc1 = Address.create_from_identity(id1, full_shard_id=0)
        acc2 = Address.create_from_identity(id1, full_shard_id=1)
        acc3 = Address.create_random_account(full_shard_id=0)

        env = get_test_env(genesis_account=acc1,
                           genesis_minor_quarkash=10000000)
        state = create_default_shard_state(env=env, shard_id=0)
        env1 = get_test_env(genesis_account=acc1,
                            genesis_minor_quarkash=10000000)
        state1 = create_default_shard_state(env=env1, shard_id=1)

        # Add a root block to update block gas limit so that xshard tx can be included
        root_block = (
            state.root_tip.create_block_to_append().add_minor_block_header(
                state.header_tip).add_minor_block_header(
                    state1.header_tip).finalize())
        state.add_root_block(root_block)

        tx = create_transfer_transaction(
            shard_state=state,
            key=id1.get_key(),
            from_address=acc1,
            to_address=acc2,
            value=888888,
            gas=opcodes.GTXXSHARDCOST + opcodes.GTXCOST,
        )
        state.add_tx(tx)

        b1 = state.create_block_to_mine(address=acc3)
        self.assertEqual(len(b1.tx_list), 1)

        self.assertEqual(state.evm_state.gas_used, 0)
        # Should succeed
        state.finalize_and_add_block(b1)
        self.assertEqual(len(state.evm_state.xshard_list), 1)
        self.assertEqual(
            state.evm_state.xshard_list[0],
            CrossShardTransactionDeposit(
                tx_hash=tx.get_hash(),
                from_address=acc1,
                to_address=acc2,
                value=888888,
                gas_price=1,
            ),
        )
        self.assertEqual(
            state.get_balance(id1.recipient),
            10000000 - 888888 - opcodes.GTXCOST - opcodes.GTXXSHARDCOST,
        )
        # Make sure the xshard gas is not used by local block
        self.assertEqual(state.evm_state.gas_used,
                         opcodes.GTXCOST + opcodes.GTXXSHARDCOST)
        # GTXXSHARDCOST is consumed by remote shard
        self.assertEqual(state.get_balance(acc3.recipient),
                         opcodes.GTXCOST // 2)
Beispiel #2
0
    def test_serialization_and_deserialization(self):
        cstor_params = {
            "tx_hash": bytes(32),
            "from_address": Address.create_random_account(1),
            "to_address": Address.create_random_account(1),
            "value": 123,
            "gas_price": 456,
            "gas_token_id": 789,
            "transfer_token_id": 101,
        }
        deposit_deprecated = CrossShardTransactionDepositDeprecated(
            **cstor_params)
        deposit_v0 = CrossShardTransactionDepositV0(**cstor_params)
        deposit_v1 = CrossShardTransactionDeposit(**cstor_params)

        testcases = [
            (CrossShardTransactionDeprecatedList([deposit_deprecated]), None),
            (CrossShardTransactionListV0([deposit_v0]), None),
            (CrossShardTransactionList([deposit_v1]), 55),
        ]
        for ls, refund_rate_update in testcases:
            if refund_rate_update:
                ls.tx_list[0].refund_rate = refund_rate_update
            else:
                refund_rate_update = 100  # default refund rate, for comparison

            deserialized = CrossShardTransactionList.from_data(ls.serialize())
            self.assertIsInstance(deserialized, CrossShardTransactionList)
            self.assertEqual(len(deserialized.tx_list), 1)
            deposit = deserialized.tx_list[0]
            self.assertIsInstance(deposit, CrossShardTransactionDeposit)
            self.assertEqual(deposit.refund_rate, refund_rate_update)
            # serialize and deserialize again
            deposit_deserialized_again = CrossShardTransactionDeposit.deserialize(
                deposit.serialize())
            self.assertIsInstance(deposit_deserialized_again,
                                  CrossShardTransactionDeposit)
            self.assertEqual(deposit_deserialized_again.refund_rate,
                             refund_rate_update)
Beispiel #3
0
    def test_xshard_native_token_gas_received(self):
        qeth = token_id_encode("QETHXX")
        id1 = Identity.create_random_identity()
        acc1 = Address.create_from_identity(id1, full_shard_key=0)
        acc2 = Address.create_from_identity(id1, full_shard_key=16)
        acc3 = Address.create_random_account(full_shard_key=0)

        env0 = get_test_env(
            genesis_account=acc1,
            genesis_minor_token_balances={"QETHXX": 9999999},
            shard_size=64,
        )
        env1 = get_test_env(
            genesis_account=acc1,
            genesis_minor_token_balances={"QETHXX": 9999999},
            shard_size=64,
        )
        state0 = create_default_shard_state(env=env0, shard_id=0)
        state1 = create_default_shard_state(env=env1, shard_id=16)

        # Add a root block to allow later minor blocks referencing this root block to
        # be broadcasted
        root_block = (
            state0.root_tip.create_block_to_append()
            .add_minor_block_header(state0.header_tip)
            .add_minor_block_header(state1.header_tip)
            .finalize()
        )
        state0.add_root_block(root_block)
        state1.add_root_block(root_block)

        # Add one block in shard 0
        b0 = state0.create_block_to_mine()
        state0.finalize_and_add_block(b0)

        b1 = state1.get_tip().create_block_to_append()
        b1.header.hash_prev_root_block = root_block.header.get_hash()
        tx = create_transfer_transaction(
            shard_state=state1,
            key=id1.get_key(),
            from_address=acc2,
            to_address=acc1,
            value=8888888,
            gas=opcodes.GTXXSHARDCOST + opcodes.GTXCOST,
            gas_price=2,
            gas_token_id=qeth,
            transfer_token_id=qeth,
        )
        b1.add_tx(tx)

        # Add a x-shard tx from remote peer
        state0.add_cross_shard_tx_list_by_minor_block_hash(
            h=b1.header.get_hash(),
            tx_list=CrossShardTransactionList(
                tx_list=[
                    CrossShardTransactionDeposit(
                        tx_hash=tx.get_hash(),
                        from_address=acc2,
                        to_address=acc1,
                        value=8888888,
                        gas_price=2,
                        gas_token_id=self.genesis_token,
                        transfer_token_id=qeth,
                    )
                ]
            ),
        )

        # Create a root block containing the block with the x-shard tx
        root_block = (
            state0.root_tip.create_block_to_append()
            .add_minor_block_header(b0.header)
            .add_minor_block_header(b1.header)
            .finalize()
        )
        state0.add_root_block(root_block)

        # Add b0 and make sure all x-shard tx's are added
        b2 = state0.create_block_to_mine(address=acc3)
        state0.finalize_and_add_block(b2)

        self.assertEqual(
            state0.get_token_balance(acc1.recipient, qeth), 9999999 + 8888888
        )
        # Half coinbase collected by root + tx fee
        self.assertEqual(
            state0.get_token_balance(acc3.recipient, self.genesis_token),
            self.get_after_tax_reward(self.shard_coinbase + opcodes.GTXXSHARDCOST * 2),
        )

        # X-shard gas used
        self.assertEqual(
            state0.evm_state.xshard_receive_gas_used, opcodes.GTXXSHARDCOST
        )
Beispiel #4
0
    def test_xshard_native_token_gas_sent(self):
        """x-shard transfer QETH using QETH as gas
        """
        qeth = token_id_encode("QETHXX")
        id1 = Identity.create_random_identity()
        acc1 = Address.create_from_identity(id1, full_shard_key=0)
        acc2 = Address.create_from_identity(id1, full_shard_key=1)
        acc3 = Address.create_random_account(full_shard_key=0)

        env = get_test_env(
            genesis_account=acc1,
            genesis_minor_token_balances={"QETHXX": 9999999},
            charge_gas_reserve=True,
        )
        state = create_default_shard_state(env=env, shard_id=0)
        env1 = get_test_env(genesis_account=acc1, genesis_minor_token_balances={})
        state1 = create_default_shard_state(env=env1, shard_id=1)

        # Add a root block to update block gas limit so that xshard tx can be included
        root_block = (
            state.root_tip.create_block_to_append()
            .add_minor_block_header(state.header_tip)
            .add_minor_block_header(state1.header_tip)
            .finalize()
        )
        state.add_root_block(root_block)

        tx = create_transfer_transaction(
            shard_state=state,
            key=id1.get_key(),
            from_address=acc1,
            to_address=acc2,
            value=8888888,
            gas=opcodes.GTXXSHARDCOST + opcodes.GTXCOST,
            gas_token_id=qeth,
            transfer_token_id=qeth,
        )
        state.add_tx(tx)

        b1 = state.create_block_to_mine(address=acc3)
        self.assertEqual(len(b1.tx_list), 1)

        self.assertEqual(state.evm_state.gas_used, 0)
        # Should succeed
        state.finalize_and_add_block(b1)
        self.assertEqual(len(state.evm_state.xshard_list), 1)
        self.assertEqual(
            state.evm_state.xshard_list[0],
            CrossShardTransactionDeposit(
                tx_hash=tx.get_hash(),
                from_address=acc1,
                to_address=acc2,
                value=8888888,
                gas_price=1,
                gas_token_id=self.genesis_token,
                transfer_token_id=qeth,
            ),
        )
        self.assertEqual(
            state.get_token_balance(id1.recipient, qeth),
            9999999 - 8888888 - (opcodes.GTXCOST + opcodes.GTXXSHARDCOST),
        )

        # Make sure the xshard gas is not used by local block
        self.assertEqual(state.evm_state.gas_used, opcodes.GTXCOST)
        # block coinbase for mining is still in genesis_token + xshard fee
        self.assertEqual(
            state.get_token_balance(acc3.recipient, self.genesis_token),
            self.get_after_tax_reward(self.shard_coinbase + opcodes.GTXCOST),
        )
    def test_xshard_native_token_sent(self):
        """x-shard transfer QETH using genesis_token as gas
        """
        QETH = token_id_encode("QETHXX")
        id1 = Identity.create_random_identity()
        acc1 = Address.create_from_identity(id1, full_shard_key=0)
        acc2 = Address.create_from_identity(id1, full_shard_key=1)
        acc3 = Address.create_random_account(full_shard_key=0)

        env = get_test_env(
            genesis_account=acc1,
            genesis_minor_token_balances={
                self.GENESIS_TOKEN: 10000000,
                "QETHXX": 999999,
            },
        )
        state = create_default_shard_state(env=env, shard_id=0)
        env1 = get_test_env(genesis_account=acc1,
                            genesis_minor_quarkash=10000000)
        state1 = create_default_shard_state(env=env1, shard_id=1)

        # Add a root block to update block gas limit so that xshard tx can be included
        root_block = (
            state.root_tip.create_block_to_append().add_minor_block_header(
                state.header_tip).add_minor_block_header(
                    state1.header_tip).finalize())
        state.add_root_block(root_block)

        tx = create_transfer_transaction(
            shard_state=state,
            key=id1.get_key(),
            from_address=acc1,
            to_address=acc2,
            value=888888,
            gas=opcodes.GTXXSHARDCOST + opcodes.GTXCOST,
            gas_token_id=self.genesis_token,
            transfer_token_id=QETH,
        )
        state.add_tx(tx)

        b1 = state.create_block_to_mine(address=acc3)
        self.assertEqual(len(b1.tx_list), 1)

        self.assertEqual(state.evm_state.gas_used, 0)
        # Should succeed
        state.finalize_and_add_block(b1)
        self.assertEqual(len(state.evm_state.xshard_list), 1)
        self.assertEqual(
            state.evm_state.xshard_list[0],
            CrossShardTransactionDeposit(
                tx_hash=tx.get_hash(),
                from_address=acc1,
                to_address=acc2,
                value=888888,
                gas_price=1,
                gas_token_id=self.genesis_token,
                transfer_token_id=QETH,
            ),
        )
        self.assertEqual(
            state.get_token_balance(id1.recipient, self.genesis_token),
            10000000 - (opcodes.GTXCOST + opcodes.GTXXSHARDCOST),
        )
        self.assertEqual(state.get_token_balance(id1.recipient, QETH),
                         999999 - 888888)

        # Make sure the xshard gas is not used by local block
        self.assertEqual(state.evm_state.gas_used,
                         opcodes.GTXCOST + opcodes.GTXXSHARDCOST)
        # GTXXSHARDCOST is consumed by remote shard
        self.assertEqual(
            state.get_token_balance(acc3.recipient, self.genesis_token),
            self.getAfterTaxReward(opcodes.GTXCOST + self.shard_coinbase),
        )
Beispiel #6
0
    def test_xshard_for_two_root_blocks(self):
        id1 = Identity.create_random_identity()
        acc1 = Address.create_from_identity(id1, full_shard_id=0)
        acc2 = Address.create_from_identity(id1, full_shard_id=1)
        acc3 = Address.create_random_account(full_shard_id=0)

        env0 = get_test_env(genesis_account=acc1,
                            genesis_minor_quarkash=10000000)
        env1 = get_test_env(genesis_account=acc1,
                            genesis_minor_quarkash=10000000)
        state0 = create_default_shard_state(env=env0, shard_id=0)
        state1 = create_default_shard_state(env=env1, shard_id=1)

        # Add a root block to allow later minor blocks referencing this root block to
        # be broadcasted
        root_block = (
            state0.root_tip.create_block_to_append().add_minor_block_header(
                state0.header_tip).add_minor_block_header(
                    state1.header_tip).finalize())
        state0.add_root_block(root_block)
        state1.add_root_block(root_block)

        # Add one block in shard 0
        b0 = state0.create_block_to_mine()
        state0.finalize_and_add_block(b0)

        b1 = state1.get_tip().create_block_to_append()
        b1.header.hash_prev_root_block = root_block.header.get_hash()
        tx = create_transfer_transaction(
            shard_state=state1,
            key=id1.get_key(),
            from_address=acc2,
            to_address=acc1,
            value=888888,
            gas=opcodes.GTXXSHARDCOST + opcodes.GTXCOST,
        )
        b1.add_tx(tx)

        # Add a x-shard tx from state1
        state0.add_cross_shard_tx_list_by_minor_block_hash(
            h=b1.header.get_hash(),
            tx_list=CrossShardTransactionList(tx_list=[
                CrossShardTransactionDeposit(
                    tx_hash=tx.get_hash(),
                    from_address=acc2,
                    to_address=acc1,
                    value=888888,
                    gas_price=2,
                )
            ]),
        )

        # Create a root block containing the block with the x-shard tx
        root_block0 = (
            state0.root_tip.create_block_to_append().add_minor_block_header(
                b0.header).add_minor_block_header(b1.header).finalize())
        state0.add_root_block(root_block0)

        b2 = state0.get_tip().create_block_to_append()
        state0.finalize_and_add_block(b2)

        b3 = b1.create_block_to_append()
        b3.header.hash_prev_root_block = root_block.header.get_hash()

        # Add a x-shard tx from state1
        state0.add_cross_shard_tx_list_by_minor_block_hash(
            h=b3.header.get_hash(),
            tx_list=CrossShardTransactionList(tx_list=[
                CrossShardTransactionDeposit(
                    tx_hash=bytes(32),
                    from_address=acc2,
                    to_address=acc1,
                    value=385723,
                    gas_price=3,
                )
            ]),
        )

        root_block1 = (
            state0.root_tip.create_block_to_append().add_minor_block_header(
                b2.header).add_minor_block_header(b3.header).finalize())
        state0.add_root_block(root_block1)

        # Test x-shard gas limit when create_block_to_mine
        b5 = state0.create_block_to_mine(address=acc3, gas_limit=0)
        # Current algorithm allows at least one root block to be included
        self.assertEqual(b5.header.hash_prev_root_block,
                         root_block0.header.get_hash())
        b6 = state0.create_block_to_mine(address=acc3,
                                         gas_limit=opcodes.GTXXSHARDCOST)
        self.assertEqual(b6.header.hash_prev_root_block,
                         root_block0.header.get_hash())
        # There are two x-shard txs: one is root block coinbase with zero gas, and anonther is from shard 1
        b7 = state0.create_block_to_mine(address=acc3,
                                         gas_limit=2 * opcodes.GTXXSHARDCOST)
        self.assertEqual(b7.header.hash_prev_root_block,
                         root_block1.header.get_hash())
        b8 = state0.create_block_to_mine(address=acc3,
                                         gas_limit=3 * opcodes.GTXXSHARDCOST)
        self.assertEqual(b8.header.hash_prev_root_block,
                         root_block1.header.get_hash())

        # Add b0 and make sure all x-shard tx's are added
        b4 = state0.create_block_to_mine(address=acc3)
        self.assertEqual(b4.header.hash_prev_root_block,
                         root_block1.header.get_hash())
        state0.finalize_and_add_block(b4)

        self.assertEqual(state0.get_balance(acc1.recipient),
                         10000000 + 888888 + 385723)
        # Half collected by root
        self.assertEqual(state0.get_balance(acc3.recipient),
                         opcodes.GTXXSHARDCOST * (2 + 3) // 2)

        # Check gas used for receiving x-shard tx
        self.assertEqual(state0.evm_state.gas_used, 18000)
        self.assertEqual(state0.evm_state.xshard_receive_gas_used, 18000)
Beispiel #7
0
    def test_xshard_tx_received_exclude_non_neighbor(self):
        id1 = Identity.create_random_identity()
        acc1 = Address.create_from_identity(id1, full_shard_id=0)
        acc2 = Address.create_from_identity(id1, full_shard_id=3)
        acc3 = Address.create_random_account(full_shard_id=0)

        env0 = get_test_env(genesis_account=acc1,
                            genesis_minor_quarkash=10000000,
                            shard_size=64)
        env1 = get_test_env(genesis_account=acc1,
                            genesis_minor_quarkash=10000000,
                            shard_size=64)
        state0 = create_default_shard_state(env=env0, shard_id=0)
        state1 = create_default_shard_state(env=env1, shard_id=3)

        # Add one block in shard 0
        b0 = state0.create_block_to_mine()
        state0.finalize_and_add_block(b0)

        b1 = state1.get_tip().create_block_to_append()
        tx = create_transfer_transaction(
            shard_state=state1,
            key=id1.get_key(),
            from_address=acc2,
            to_address=acc1,
            value=888888,
            gas=opcodes.GTXXSHARDCOST + opcodes.GTXCOST,
            gas_price=2,
        )
        b1.add_tx(tx)

        # Add a x-shard tx from remote peer
        state0.add_cross_shard_tx_list_by_minor_block_hash(
            h=b1.header.get_hash(),
            tx_list=CrossShardTransactionList(tx_list=[
                CrossShardTransactionDeposit(
                    tx_hash=tx.get_hash(),
                    from_address=acc2,
                    to_address=acc1,
                    value=888888,
                    gas_price=2,
                )
            ]),
        )

        # Create a root block containing the block with the x-shard tx
        root_block = (
            state0.root_tip.create_block_to_append().add_minor_block_header(
                b0.header).add_minor_block_header(b1.header).finalize())
        state0.add_root_block(root_block)

        # Add b0 and make sure all x-shard tx's are added
        b2 = state0.create_block_to_mine(address=acc3)
        state0.finalize_and_add_block(b2)

        self.assertEqual(state0.get_balance(acc1.recipient), 10000000)
        # Half collected by root
        self.assertEqual(state0.get_balance(acc3.recipient), 0)

        # X-shard gas used
        evmState0 = state0.evm_state
        self.assertEqual(evmState0.xshard_receive_gas_used, 0)