コード例 #1
0
    def test_set_affected_address(self, m_logger):
        result = set()
        params = self.default_params()
        tx = TransferTokenTransaction.create(**params)
        tx.set_affected_address(result)
        self.assertEqual(2, len(result))

        params = self.default_params()
        params["addrs_to"] = [self.bob.address, get_slave_xmss().address]
        params["amounts"] = [100, 200]
        tx = TransferTokenTransaction.create(**params)
        tx.set_affected_address(result)
        self.assertEqual(3, len(result))
コード例 #2
0
 def test_create(self, m_logger):
     tx = TransferTokenTransaction.create(token_txhash=b'000000000000000',
                                          addrs_to=[self.bob.address],
                                          amounts=[200000],
                                          fee=1,
                                          xmss_pk=self.alice.pk)
     self.assertTrue(tx)
コード例 #3
0
    def test_remove_transfer_token_metadata(self):
        alice_xmss = get_alice_xmss()
        bob_xmss = get_bob_xmss()

        token_transaction = get_token_transaction(alice_xmss, bob_xmss)
        TokenMetadata.create_token_metadata(self.state, token_transaction,
                                            None)

        transfer_token = TransferTokenTransaction.create(
            token_txhash=token_transaction.txhash,
            addrs_to=[alice_xmss.address],
            amounts=[100000000],
            fee=1,
            xmss_pk=bob_xmss.pk)
        transfer_token.sign(alice_xmss)

        TokenMetadata.update_token_metadata(self.state, transfer_token, None)
        token_metadata = TokenMetadata.get_token_metadata(
            self.state, transfer_token.token_txhash)
        self.assertIn(transfer_token.txhash,
                      token_metadata.transfer_token_tx_hashes)

        TokenMetadata.remove_transfer_token_metadata(self.state,
                                                     transfer_token, None)
        token_metadata = TokenMetadata.get_token_metadata(
            self.state, transfer_token.token_txhash)
        self.assertNotIn(transfer_token.txhash,
                         token_metadata.transfer_token_tx_hashes)
コード例 #4
0
    def test_to_json(self, m_logger):
        tx = TransferTokenTransaction.create(token_txhash=b'000000000000000',
                                             addrs_to=[self.bob.address],
                                             amounts=[200000],
                                             fee=1,
                                             xmss_pk=self.alice.pk)
        txjson = tx.to_json()

        self.assertEqual(json.loads(test_json_TransferToken),
                         json.loads(txjson))
コード例 #5
0
ファイル: test_p2pfactory.py プロジェクト: jack3343/xrd-core
 def test_broadcast_tx(self, m_reactor, m_logger):
     # broadcast_tx() should handle all Transaction Types
     self.factory.broadcast_tx(MessageTransaction())
     self.factory.broadcast_tx(TransferTransaction())
     self.factory.broadcast_tx(TokenTransaction())
     self.factory.broadcast_tx(TransferTokenTransaction())
     self.factory.broadcast_tx(SlaveTransaction())
     with self.assertRaises(ValueError):
         m_tx = Mock(autospec=TransferTransaction, txhash=bhstr2bin('deadbeef'))
         self.factory.broadcast_tx(m_tx)
コード例 #6
0
    def test_revert_transfer_token_txn_multi_send(self):
        """
        Alice has 1100 tokens and 100 xrd, Bob and Slave have none. Alice sends some tokens to Bob and Slave.
        Undo this.
        """
        slave = get_slave_xmss()
        self.params["addrs_to"] = [self.bob.address, slave.address]
        self.params["amounts"] = [100, 100]

        tx = TransferTokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = dict(self.addresses_state)
        addresses_state[self.alice.address].pbdata.balance = 100
        addresses_state[self.bob.address].pbdata.balance = 0
        addresses_state[slave.address] = OptimizedAddressState.get_default(
            slave.address)
        tokens = Indexer(b'token', None)
        tokens.data[(self.alice.address,
                     tx.token_txhash)] = TokenBalance(balance=1100)

        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=tokens,
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=1,
                                         total_coin_supply=1000,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)
        state_container.paginated_bitfield.set_ots_key(addresses_state,
                                                       self.alice.address, 0)

        self.assertTrue(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, 0))
        tx.apply(self.state, state_container)
        tx.revert(self.state, state_container)
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, 0))

        self.assertEqual(addresses_state[self.alice.address].balance, 100)
        self.assertEqual(addresses_state[self.bob.address].balance, 0)
        self.assertEqual(addresses_state[slave.address].balance, 0)

        self.assertEqual(
            tokens.data[(self.alice.address, tx.token_txhash)].balance, 1100)
        self.assertEqual(
            tokens.data[(self.bob.address, tx.token_txhash)].balance, 0)
        self.assertEqual(tokens.data[(slave.address, tx.token_txhash)].balance,
                         0)
コード例 #7
0
    def test_validate_tx(self, m_logger):
        tx = TransferTokenTransaction.create(token_txhash=b'000000000000000',
                                             addrs_to=[self.bob.address],
                                             amounts=[200000],
                                             fee=1,
                                             xmss_pk=self.alice.pk)

        # We must sign the tx before validation will work.
        tx.sign(self.alice)

        # We have not touched the tx: validation should pass.
        self.assertTrue(tx.validate_or_raise())
コード例 #8
0
    def test_validate_tx2(self, m_logger):
        params = self.default_params()
        tx = TransferTokenTransaction.create(**params)
        tx.sign(self.alice)

        self.assertTrue(tx.validate_or_raise())

        tx._data.transaction_hash = b'abc'

        # Should fail, as we have modified with invalid transaction_hash
        with self.assertRaises(ValueError):
            tx.validate_or_raise()
コード例 #9
0
ファイル: xrdnode.py プロジェクト: jack3343/xrd-core
 def create_transfer_token_txn(addrs_to: list,
                               token_txhash: bytes,
                               amounts: list,
                               fee: int,
                               xmss_pk: bytes,
                               master_addr: bytes):
     return TransferTokenTransaction.create(token_txhash,
                                            addrs_to,
                                            amounts,
                                            fee,
                                            xmss_pk,
                                            master_addr)
コード例 #10
0
def tx_transfertoken(ctx, src, master, token_txhash, dsts, amounts, decimals, fee, ots_key_index):
    """
    Create Transfer Token Transaction, which moves tokens from src to dst.
    """

    if decimals > 19:
        click.echo("The number of decimal cannot exceed 19 under any configuration")
        quit(1)

    try:
        addresses_dst, shor_amounts = _parse_dsts_amounts(dsts, amounts, token_decimals=decimals)
        bin_token_txhash = parse_hexblob(token_txhash)
        master_addr = None
        if master:
            master_addr = parse_qaddress(master)
        # FIXME: This could be problematic. Check
        fee_shor = _quanta_to_shor(fee)

        _, src_xmss = _select_wallet(ctx, src)
        if not src_xmss:
            click.echo("A local wallet is required to sign the transaction")
            quit(1)

        address_src_pk = src_xmss.pk

        ots_key_index = validate_ots_index(ots_key_index, src_xmss)
        src_xmss.set_ots_index(ots_key_index)

    except KeyboardInterrupt:
        click.echo("Terminated by user")
        quit(1)
    except Exception as e:
        click.echo("Error validating arguments: {}".format(e))
        quit(1)

    try:
        stub = ctx.obj.get_stub_public_api()
        tx = TransferTokenTransaction.create(token_txhash=bin_token_txhash,
                                             addrs_to=addresses_dst,
                                             amounts=shor_amounts,
                                             fee=fee_shor,
                                             xmss_pk=address_src_pk,
                                             master_addr=master_addr)
        tx.sign(src_xmss)

        push_transaction_req = xrd_pb2.PushTransactionReq(transaction_signed=tx.pbdata)
        push_transaction_resp = stub.PushTransaction(push_transaction_req, timeout=CONNECTION_TIMEOUT)

        print(push_transaction_resp.error_code)
    except Exception as e:
        print("Error {}".format(str(e)))
コード例 #11
0
    def test_state_validate_tx_custom(self, m_logger):
        """
        TransferTokenTransaction._validate_custom() checks for:
        1. 0 amounts
        2. fee < 0
        3. multi-send: too many recipients
        4. multi-send: recipient addresses and amounts not the same length
        5. invalid addr_from
        6. invalid addr_to
        """
        slave = get_slave_xmss()
        params = self.default_params()
        tx = TransferTokenTransaction.create(**params)
        tx.sign(self.alice)

        result = tx.validate_or_raise()
        self.assertTrue(result)

        params = self.default_params()
        params["addrs_to"] = [self.bob.address, slave.address]
        params["amounts"] = [1, 0]
        with self.assertRaises(ValueError):
            tx = TransferTokenTransaction.create(**params)

        # Protobuf validation doesn't allow negative fees already
        params = self.default_params()
        tx = TransferTokenTransaction.create(**params)
        tx.sign(self.alice)
        with patch('xrd.core.txs.Transaction.Transaction.fee',
                   new_callable=PropertyMock) as m_fee:
            m_fee.return_value = -1
            with self.assertRaises(ValueError):
                tx.validate_or_raise()

        # TX signing already fails if addrs_to and amounts are unequal length
        params = self.default_params()
        tx = TransferTokenTransaction.create(**params)
        tx.sign(self.alice)
        with patch(
                'xrd.core.txs.TransferTokenTransaction.TransferTokenTransaction.addrs_to',
                new_callable=PropertyMock) as m_addrs_to:
            m_addrs_to.return_value = [self.bob.address, slave.address]
            with self.assertRaises(ValueError):
                tx.validate_or_raise()

        params = self.default_params()
        params["master_addr"] = b'Bad xrd Address'
        with self.assertRaises(ValueError):
            tx = TransferTokenTransaction.create(**params)

        params = self.default_params()
        params["addrs_to"] = [self.bob.address, b'Bad xrd address']
        params["amounts"] = [100, 200]
        with self.assertRaises(ValueError):
            tx = TransferTokenTransaction.create(**params)
コード例 #12
0
    def relay_transfer_token_txn(self, qaddresses_to: list, amounts: list,
                                 token_txhash: str, fee: int, master_qaddress,
                                 signer_address: str, ots_index: int):
        self.authenticate()
        index, xmss = self._get_wallet_index_xmss(signer_address, ots_index)
        self.verify_ots(signer_address, xmss, user_ots_index=ots_index)

        tx = TransferTokenTransaction.create(
            token_txhash=bytes(hstr2bin(token_txhash)),
            addrs_to=self.qaddresses_to_address(qaddresses_to),
            amounts=amounts,
            fee=fee,
            xmss_pk=xmss.pk,
            master_addr=self.qaddress_to_address(master_qaddress))

        self.sign_and_push_transaction(tx, xmss, index)

        return self.to_plain_transaction(tx.pbdata)
コード例 #13
0
    def test_revert_transfer_token_txn_send_tokens_to_self(self):
        """
        Alice has 1000 tokens and 100 xrd. She sends some tokens to herself.
        Can we undo this?
        """
        self.params["addrs_to"] = [self.alice.address]
        tx = TransferTokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = dict(self.addresses_state)
        addresses_state[self.alice.address].pbdata.balance = 100
        tokens = Indexer(b'token', None)
        tokens.data[(self.alice.address,
                     tx.token_txhash)] = TokenBalance(balance=100)
        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=tokens,
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=1,
                                         total_coin_supply=1000,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)
        state_container.paginated_bitfield.set_ots_key(addresses_state,
                                                       self.alice.address, 0)

        self.assertTrue(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, 0))
        tx.apply(self.state, state_container)
        tx.revert(self.state, state_container)
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, 0))

        self.assertEqual(addresses_state[self.alice.address].balance, 100)
        # Unfortunately importing mock.call results in some sort of ValueError so I can't check the arguments.
        self.assertEqual(
            tokens.data[(self.alice.address, tx.token_txhash)].balance, 100)
コード例 #14
0
    def relay_transfer_token_txn_by_slave(self, qaddresses_to: list,
                                          amounts: list, token_txhash: str,
                                          fee: int, master_qaddress):
        self.authenticate()
        index, group_index, slave_index, slave_xmss = self.get_slave_xmss(
            master_qaddress)
        if slave_index == -1:
            raise Exception("No Slave Found")

        tx = TransferTokenTransaction.create(
            token_txhash=bytes(hstr2bin(token_txhash)),
            addrs_to=self.qaddresses_to_address(qaddresses_to),
            amounts=amounts,
            fee=fee,
            xmss_pk=slave_xmss.pk,
            master_addr=self.qaddress_to_address(master_qaddress))

        self.sign_and_push_transaction(tx, slave_xmss, index, group_index,
                                       slave_index)

        return self.to_plain_transaction(tx.pbdata)
コード例 #15
0
    def test_apply_transfer_token_txn(self):
        """
        Alice has 1000 tokens and 100 xrd, Bob has none. Alice sends some tokens to Bob.
        """
        tx = TransferTokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = dict(self.addresses_state)
        tokens = Indexer(b'token', None)
        tokens.data[(self.alice.address,
                     tx.token_txhash)] = TokenBalance(balance=150)
        tokens.data[(self.bob.address,
                     tx.token_txhash)] = TokenBalance(balance=0)
        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=tokens,
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=1,
                                         total_coin_supply=1000,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, 0))
        tx.apply(self.state, state_container)
        self.assertTrue(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, 0))

        self.assertEqual(addresses_state[self.alice.address].balance, 99)
        self.assertEqual(addresses_state[self.bob.address].balance, 0)

        self.assertEqual(
            tokens.data[(self.alice.address, tx.token_txhash)].balance, 50)
        self.assertEqual(
            tokens.data[(self.bob.address, tx.token_txhash)].balance, 100)
コード例 #16
0
    def test_revert_transfer_token_txn_empty_addresses_state(self):
        """
        If we didn't have any AddressStates for the addresses involved in this test, do nothing
        """
        tx = TransferTokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = dict(self.addresses_state)
        tokens = Indexer(b'token', None)
        tokens.data[(self.alice.address,
                     tx.token_txhash)] = TokenBalance(balance=100)
        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=tokens,
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=1,
                                         total_coin_supply=1000,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)
        state_container.paginated_bitfield.set_ots_key(addresses_state,
                                                       self.alice.address, 0)

        self.assertTrue(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, 0))
        tx.apply(self.state, state_container)
        tx.revert(self.state, state_container)
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, 0))

        self.assertEqual(
            100, tokens.data[(self.alice.address, tx.token_txhash)].balance)
        self.assertEqual(
            0, tokens.data[(self.bob.address, tx.token_txhash)].balance)
コード例 #17
0
    def test_validate_extended(self, m_validate_slave, m_logger):
        """
        TransferTokenTransaction._validate_extended checks for:
        1. valid master/slave
        2. negative fee, negative total token amounts transferred
        3. addr_from has enough funds for the fee
        4. if addr_from owns any tokens to begin with
        5. if addr_from has enough tokens
        6. addr_from ots_key reuse
        """
        alice_address_state = OptimizedAddressState.get_default(
            self.alice.address)
        alice_address_state.pbdata.balance = 100

        params = self.default_params()
        tx = TransferTokenTransaction.create(**params)
        tx.sign(self.alice)

        addresses_state = {alice_address_state.address: alice_address_state}
        tokens = Indexer(b'token', None)
        tokens.data[(self.alice.address,
                     tx.token_txhash)] = xrd_pb2.TokenBalance(balance=1000,
                                                              decimals=0,
                                                              delete=False)

        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=tokens,
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=1,
                                         total_coin_supply=1000,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)
        result = tx._validate_extended(state_container)
        self.assertTrue(result)

        # Invalid master XMSS/slave XMSS relationship
        m_validate_slave.return_value = False
        state_container.tokens = Indexer(b'token', None)
        state_container.tokens.data[(self.alice.address,
                                     tx.token_txhash)] = xrd_pb2.TokenBalance(
                                         balance=1000,
                                         decimals=0,
                                         delete=False)
        result = tx.validate_all(state_container)
        self.assertFalse(result)
        m_validate_slave.return_value = True

        # fee = -1
        with patch(
                'xrd.core.txs.TransferTokenTransaction.TransferTokenTransaction.fee',
                new_callable=PropertyMock) as m_fee:
            m_fee.return_value = -1
            tokens = Indexer(b'token', None)
            tokens.data[(self.alice.address,
                         tx.token_txhash)] = xrd_pb2.TokenBalance(balance=1000,
                                                                  decimals=0,
                                                                  delete=False)
            state_container.tokens = tokens
            result = tx._validate_extended(state_container)
            self.assertFalse(result)

        # total_amount = -1
        with patch(
                'xrd.core.txs.TransferTokenTransaction.TransferTokenTransaction.total_amount',
                new_callable=PropertyMock) as m_total_amount:
            m_total_amount.return_value = -100
            tokens = Indexer(b'token', None)
            tokens.data[(self.alice.address,
                         tx.token_txhash)] = xrd_pb2.TokenBalance(balance=1000,
                                                                  decimals=0,
                                                                  delete=False)
            state_container.tokens = tokens
            result = tx._validate_extended(state_container)
            self.assertFalse(result)

        # balance = 0, cannot pay the Transaction fee
        alice_address_state.pbdata.balance = 0
        tokens = Indexer(b'token', None)
        tokens.data[(self.alice.address,
                     tx.token_txhash)] = xrd_pb2.TokenBalance(balance=1000,
                                                              decimals=0,
                                                              delete=False)
        state_container.tokens = tokens
        result = tx._validate_extended(state_container)
        self.assertFalse(result)
        alice_address_state.pbdata.balance = 100

        # addr_from doesn't have these tokens
        state_container.tokens = Indexer(b'token', None)
        result = tx._validate_extended(state_container)
        self.assertFalse(result)

        # addr_from doesn't have enough tokens
        tokens = Indexer(b'token', None)
        tokens.data[(self.alice.address,
                     tx.token_txhash)] = xrd_pb2.TokenBalance(balance=99,
                                                              decimals=0,
                                                              delete=False)
        state_container.tokens = tokens
        result = tx._validate_extended(state_container)
        self.assertFalse(result)

        # addr_from_pk has used this OTS key before
        addresses_state = {self.alice.address: alice_address_state}
        state_container.addresses_state = addresses_state
        # addr_from_pk has used this OTS key before
        state_container.paginated_bitfield.set_ots_key(
            addresses_state, alice_address_state.address, tx.ots_key)
        result = tx.validate_all(state_container)
        self.assertFalse(result)

        slave = get_slave_xmss()
        params = self.default_params()
        params["addrs_to"] = [
            self.bob.address, slave.address, self.alice.address
        ]
        params["amounts"] = [2, 3, 5]
        tx = TransferTokenTransaction.create(**params)
        tx.sign(self.alice)
        with patch('xrd.core.config', autospec=True) as m_config:
            m_config.dev = config.dev.create(config.dev.prev_state_key,
                                             config.dev.current_state_key, b'',
                                             10, True, True)
            m_config.dev.pbdata.transaction.multi_output_limit = 1
            state_container.current_dev_config = m_config.dev
            self.assertFalse(
                tx._validate_extended(state_container=state_container))