def test_validate_tx3(self, m_logger): tx = TransferTransaction.create(addrs_to=[self.bob.address], amounts=[100], message_data=None, fee=1, xmss_pk=self.alice.pk) tx.sign(self.alice) tx._data.signature = tx.signature * 4183 + tx.signature[0:104] tx._data.transaction_hash = tx.generate_txhash() with self.assertRaises(ValueError): tx.validate_or_raise()
def create_send_tx(self, addrs_to: list, amounts: list, fee: int, xmss_pk: bytes, master_addr: bytes) -> TransferTransaction: addr_from = self.get_addr_from(xmss_pk, master_addr) balance = self._chain_manager.get_address_balance(addr_from) if sum(amounts) + fee > balance: raise ValueError("Not enough funds in the source address") return TransferTransaction.create(addrs_to=addrs_to, amounts=amounts, fee=fee, xmss_pk=xmss_pk, master_addr=master_addr)
def setUp(self): with set_qrl_dir('no_data'): self.state = State() self.chain_manager = ChainManager(self.state) self.alice = get_alice_xmss() self.bob = get_bob_xmss() self.slave = get_slave_xmss() self.tx1 = TransferTransaction.create(addrs_to=[self.bob.address], amounts=[10], message_data=None, fee=1, xmss_pk=self.alice.pk) self.tx2 = TransferTransaction.create(addrs_to=[self.bob.address], amounts=[10], message_data=None, fee=1, xmss_pk=self.slave.pk, master_addr=self.alice.address) self.tx1._data.nonce = 3 self.tx2._data.nonce = 6 self.tx1.sign(self.alice) self.tx2.sign(self.slave) self.block_attrs = { "dev_config": config.dev, "block_number": 5, "prev_headerhash": bytes(sha2_256(b'test')), "prev_timestamp": 10, "transactions": [self.tx1, self.tx2], "miner_address": self.alice.address, "seed_height": 0, "seed_hash": None, } self.coinbase_addrstate_attrs = OptimizedAddressState.get_default(config.dev.coinbase_address) self.coinbase_addrstate_attrs.update_balance(None, int(config.dev.coin_remaining_at_genesis * config.dev.shor_per_quanta)) self.bob_addrstate_attrs = OptimizedAddressState.get_default(self.bob.address) self.bob_addrstate_attrs.update_balance(None, 20) self.alice_addrstate_attrs = OptimizedAddressState.get_default(self.alice.address) self.alice_addrstate_attrs.update_balance(None, 100) self.alice_addrstate_attrs.pbdata.nonce = 2 self.slave_addrstate_attrs = OptimizedAddressState.get_default(self.slave.address) self.slave_addrstate_attrs.pbdata.nonce = 5
def setUp(self): self.alice = get_alice_xmss() self.bob = get_bob_xmss() self.slave = get_slave_xmss() self.tx1 = TransferTransaction.create(addrs_to=[self.bob.address], amounts=[10], fee=1, xmss_pk=self.alice.pk) self.tx2 = TransferTransaction.create(addrs_to=[self.bob.address], amounts=[10], fee=1, xmss_pk=self.slave.pk, master_addr=self.alice.address) # self.tx1 = Mock(autospec=TransferTransaction, addrs_to=[self.bob.address], amounts=[10], fee=1, # xmss_pk=self.alice.pk) # self.tx2 = Mock(autospec=TransferTransaction, addrs_to=[self.bob.address], amounts=[10], fee=1, # xmss_pk=self.slave.pk, master_addr=self.alice.address) self.tx1._data.nonce = 3 self.tx2._data.nonce = 6 self.tx1.sign(self.alice) self.tx2.sign(self.slave) self.block_attrs = { "block_number": 5, "prev_headerhash": bytes(sha2_256(b'test')), "prev_timestamp": 10, "transactions": [self.tx1, self.tx2], "miner_address": self.alice.address } self.alice_addrstate_attrs = { 'nonce': 2, 'ots_key_reuse.return_value': False } self.slave_addrstate_attrs = { 'nonce': 5, 'ots_key_reuse.return_value': False }
def test_validate_tx2(self, m_logger): tx = TransferTransaction.create(addrs_to=[self.bob.address], amounts=[100], fee=1, xmss_pk=self.alice.pk) 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()
def test_update_tx_metadata(self): with set_qrl_dir('no_data'): with State() as state: alice_xmss = get_alice_xmss() tx = TransferTransaction.create(addrs_to=[get_some_address(1), get_some_address(2)], amounts=[1, 2], fee=0, xmss_pk=alice_xmss.pk) block_number = 5 state.put_tx_metadata(tx, block_number, 10000, None) tx_metadata = state.get_tx_metadata(tx.txhash) self.assertEqual(tx_metadata[0].to_json(), tx.to_json()) self.assertEqual(tx_metadata[1], block_number)
def test_revert_state_changes_for_PK_master_slave_XMSS(self, m_logger): addresses_state = { self.alice.address: OptimizedAddressState.get_default(self.alice.address), self.slave.address: OptimizedAddressState.get_default(self.slave.address) } addresses_state[self.alice.address].pbdata.balance = 101 addresses_state[self.slave.address].pbdata.nonce = 1 tx = TransferTransaction.create(addrs_to=[self.bob.address], amounts=[100], message_data=None, fee=1, xmss_pk=self.slave.pk, master_addr=self.alice.address) tx.sign(self.slave) ots_key = self.slave.ots_index - 1 state_container = StateContainer(addresses_state=addresses_state, tokens=Indexer(b'token', None), 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=100, 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.slave.address, ots_key) state_container.paginated_bitfield.put_addresses_bitfield(None) self.assertTrue( state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse( self.slave.address, ots_key)) self.assertFalse( state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse( self.alice.address, self.alice.ots_index)) tx._apply_state_changes_for_PK(state_container) tx._revert_state_changes_for_PK(state_container) self.assertFalse( state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse( self.slave.address, ots_key)) self.assertFalse( state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse( self.alice.address, self.alice.ots_index))
def test_getTransaction(self): db_state = Mock(spec=State) db_state.get_tx_metadata = MagicMock(return_value=None) db_state.get_block = MagicMock(return_value=None) p2p_factory = Mock(spec=P2PFactory) p2p_factory.pow = Mock(spec=POW) chain_manager = ChainManager(db_state) qrlnode = QRLNode(mining_address=b'') qrlnode.set_chain_manager(chain_manager) qrlnode._p2pfactory = p2p_factory qrlnode._pow = p2p_factory.pow qrlnode._peer_addresses = ['127.0.0.1', '192.168.1.1'] service = PublicAPIService(qrlnode) # Find an address bob_xmss = get_bob_xmss() # Find a transaction alice_xmss = get_alice_xmss() db_state.address_used = MagicMock(return_value=False) tx1 = TransferTransaction.create( addrs_to=[bob_xmss.address], amounts=[125], message_data=None, fee=19, xmss_pk=bob_xmss.pk, master_addr=alice_xmss.address) chain_manager.tx_pool.transaction_pool = [(0, TransactionInfo(tx1, 0))] context = Mock(spec=ServicerContext) request = qrl_pb2.GetTransactionReq() request.tx_hash = tx1.txhash response = service.GetTransaction(request=request, context=context) context.set_code.assert_not_called() self.assertIsNotNone(response.tx) self.assertEqual('transfer', response.tx.WhichOneof('transactionType')) self.assertEqual(alice_xmss.address, response.tx.master_addr) self.assertEqual(bob_xmss.pk, response.tx.public_key) self.assertEqual(tx1.txhash, response.tx.transaction_hash) self.assertEqual(b'', response.tx.signature) self.assertEqual(bob_xmss.address, response.tx.transfer.addrs_to[0]) self.assertEqual(125, response.tx.transfer.amounts[0]) self.assertEqual(19, response.tx.fee)
def test_apply_state_changes_for_PK_master_slave_XMSS(self, m_logger): """ If the TX was signed by a slave XMSS, the slave XMSS's AddressState should be updated (not the master's). :return: """ tx = TransferTransaction.create(addrs_to=[self.bob.address], amounts=[100], message_data=None, fee=1, xmss_pk=self.slave.pk, master_addr=self.alice.address) addresses_state = { self.alice.address: OptimizedAddressState.get_default(self.alice.address), self.slave.address: OptimizedAddressState.get_default(self.slave.address) } tx.sign(self.slave) ots_key = self.slave.ots_index - 1 state_container = StateContainer(addresses_state=addresses_state, tokens=Indexer(b'token', None), 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=100, 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.slave.address, ots_key)) self.assertFalse( state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse( self.alice.address, self.alice.ots_index)) tx._apply_state_changes_for_PK(state_container) self.assertTrue( state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse( self.slave.address, ots_key)) self.assertFalse( state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse( self.alice.address, self.alice.ots_index)) self.assertEqual(1, addresses_state[self.slave.address].nonce) self.assertEqual(0, addresses_state[self.alice.address].nonce)
def test_multi_output_transaction_add_block(self, time_mock): # Test that adding block with a multi-output Transaction updates everybody's balances correctly. self.chain_manager.load(self.genesis_block) extended_seed = "010300cebc4e25553afa0aab899f7838e59e18a48852fa9dfd5" \ "ae78278c371902aa9e6e9c1fa8a196d2dba0cbfd2f2d212d16c" random_xmss = XMSS.from_extended_seed(hstr2bin(extended_seed)) transfer_transaction = TransferTransaction.create( addrs_to=[alice.address, random_xmss.address], amounts=[ 40 * int(config.dev.shor_per_quanta), 59 * int(config.dev.shor_per_quanta) ], fee=1 * config.dev.shor_per_quanta, xmss_pk=bob.pk) transfer_transaction._data.nonce = 1 transfer_transaction.sign(bob) time_mock.return_value = 1615270948 # Very high to get an easy difficulty block_1 = Block.create(block_number=1, prev_headerhash=self.genesis_block.headerhash, prev_timestamp=self.genesis_block.timestamp, transactions=[transfer_transaction], miner_address=alice.address) block_1.set_nonces(129, 0) # Uncomment only to determine the correct mining_nonce of above blocks # from qrl.core.PoWValidator import PoWValidator # while not PoWValidator().validate_mining_nonce(self.state, block_1.blockheader, False): # block_1.set_nonces(block_1.mining_nonce + 1) # print(block_1.mining_nonce) self.assertTrue(block_1.validate(self.chain_manager, {})) result = self.chain_manager.add_block(block_1) self.assertTrue(result) self.assertEqual(self.chain_manager.last_block, block_1) bob_addr_state = self.state.get_address_state(bob.address) alice_addr_state = self.state.get_address_state(alice.address) random_addr_state = self.state.get_address_state(random_xmss.address) self.assertEqual(bob_addr_state.balance, 0) self.assertEqual( alice_addr_state.balance, 140 * int(config.dev.shor_per_quanta) + block_1.block_reward + block_1.fee_reward) self.assertEqual(random_addr_state.balance, 159 * int(config.dev.shor_per_quanta))
def test_affected_address(self, m_logger): # The default transaction params involve only two addresses. affected_addresses = set() self.tx.set_affected_address(affected_addresses) self.assertEqual(2, len(affected_addresses)) # This transaction should involve 3 addresses. affected_addresses = set() tx = TransferTransaction.create( addrs_to=[self.bob.address, self.slave.address], amounts=[100, 100], fee=1, xmss_pk=self.alice.pk) tx.set_affected_address(affected_addresses) self.assertEqual(3, len(affected_addresses))
def test_revert_transfer_txn_tx_sends_to_self(self, m_logger): """ Alice sent coins to herself, but she still lost the Transaction fee. Undo this. """ addresses_state = { self.alice.address: OptimizedAddressState.get_default(self.alice.address), self.bob.address: OptimizedAddressState.get_default(self.bob.address) } addresses_state[self.alice.address].pbdata.balance = 200 tx = TransferTransaction.create(addrs_to=[self.alice.address], amounts=[100], message_data=None, fee=1, xmss_pk=self.alice.pk) tx.sign(self.alice) ots_key = self.alice.ots_index - 1 state_container = StateContainer(addresses_state=addresses_state, tokens=Indexer(b'token', None), 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=100, 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, ots_key) state_container.paginated_bitfield.put_addresses_bitfield(None) self.assertTrue( state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse( self.alice.address, ots_key)) 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, ots_key)) self.assertEqual(200, addresses_state[self.alice.address].balance) self.assertEqual(0, addresses_state[self.bob.address].balance)
def test_revert_state_changes_for_PK(self, m_logger): """ This is just an undo function. :return: """ tx = TransferTransaction.create(addrs_to=[self.bob.address], amounts=[100], fee=1, xmss_pk=self.alice.pk) addr_state = {self.alice.address: Mock(autospec=AddressState)} tx.sign(self.alice) tx._revert_state_changes_for_PK(addr_state, Mock(name='unused State Mock')) addr_state[self.alice.address].decrease_nonce.assert_called_once() addr_state[self.alice.address].unset_ots_key.assert_called_once()
def test_put_tx_metadata(self): self.assertIsNone(self.state.get_tx_metadata(b'test1')) alice_xmss = get_alice_xmss() tx = TransferTransaction.create( addrs_to=[get_some_address(1), get_some_address(2)], amounts=[1, 2], fee=0, xmss_pk=alice_xmss.pk) block_number = 5 self.state.put_tx_metadata(tx, block_number, 10000, None) tx_metadata = self.state.get_tx_metadata(tx.txhash) self.assertEqual(tx_metadata[0].to_json(), tx.to_json()) self.assertEqual(tx_metadata[1], block_number)
def test_apply_transfer_txn_tx_sends_to_self(self, m_logger): """ If you send coins to yourself, you should only lose the fee for the Transaction. """ addresses_state = { self.alice.address: OptimizedAddressState.get_default(self.alice.address), self.bob.address: OptimizedAddressState.get_default(self.bob.address), self.slave.address: OptimizedAddressState.get_default(self.slave.address) } addresses_state[self.alice.address].pbdata.balance = 200 tx = TransferTransaction.create(addrs_to=[self.alice.address], amounts=[100], message_data=None, fee=1, xmss_pk=self.alice.pk) tx.sign(self.alice) ots_key = self.alice.ots_index - 1 state_container = StateContainer(addresses_state=addresses_state, tokens=Indexer(b'token', None), 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=100, 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, ots_key)) tx.apply(self.state, state_container) self.assertTrue( state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse( self.alice.address, ots_key)) self.assertEqual(199, addresses_state[self.alice.address].balance) storage_key = state_container.paginated_tx_hash.generate_key( self.alice.address, 1) self.assertIn(tx.txhash, state_container.paginated_tx_hash.key_value[storage_key])
def relay_transfer_txn(self, qaddresses_to: list, amounts: list, fee: int, master_qaddress, signer_address: str, ots_index: int): self.authenticate() index, xmss = self._get_wallet_index_xmss(signer_address, ots_index) tx = TransferTransaction.create( 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._push_transaction(tx, xmss) self._wallet.set_ots_index(index, xmss.ots_index) return self.to_plain_transaction(tx.pbdata)
def test_update_tx_metadata(self): alice_xmss = get_alice_xmss() tx = TransferTransaction.create( addrs_to=[get_some_address(1), get_some_address(2)], amounts=[1, 2], message_data=None, fee=0, xmss_pk=alice_xmss.pk) block_number = 5 TransactionMetadata.put_tx_metadata(self.state, tx, block_number, 10000, None) tx_metadata = TransactionMetadata.get_tx_metadata( self.state, tx.txhash) self.assertEqual(tx_metadata[0].to_json(), tx.to_json()) self.assertEqual(tx_metadata[1], block_number)
def test_apply_transfer_txn_multi_send(self, m_logger): """ Test that apply_state_changes() also works with multiple recipients. """ addresses_state = { self.alice.address: OptimizedAddressState.get_default(self.alice.address), self.bob.address: OptimizedAddressState.get_default(self.bob.address), self.slave.address: OptimizedAddressState.get_default(self.slave.address) } addresses_state[self.alice.address].pbdata.balance = 200 tx_multisend = TransferTransaction.create( addrs_to=[self.bob.address, self.slave.address], amounts=[20, 20], message_data=None, fee=1, xmss_pk=self.alice.pk) tx_multisend.sign(self.alice) ots_key = self.alice.ots_index - 1 state_container = StateContainer(addresses_state=addresses_state, tokens=Indexer(b'token', None), 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=100, 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, ots_key)) tx_multisend.apply(self.state, state_container) self.assertTrue( state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse( self.alice.address, ots_key)) self.assertEqual(159, addresses_state[self.alice.address].balance) self.assertEqual(20, addresses_state[self.bob.address].balance) self.assertEqual(20, addresses_state[self.slave.address].balance)
def test_revert_state_changes_multi_send(self, m_logger): """ Alice has sent 20 coins to Bob and Slave each, using 1 as Transaction fee. Now we need to undo this. """ addresses_state = { self.alice.address: Mock(autospec=AddressState, name='alice AddressState', transaction_hashes=[self.tx.txhash], balance=159), self.bob.address: Mock(autospec=AddressState, name='bob AddressState', transaction_hashes=[self.tx.txhash], balance=20), self.slave.address: Mock(autospec=AddressState, name='slave AddressState', transaction_hashes=[self.tx.txhash], balance=20) } unused_chain_manager_mock = Mock(autospec=ChainManager, name='unused ChainManager') tx_multisend = TransferTransaction.create( addrs_to=[self.bob.address, self.slave.address], amounts=[20, 20], fee=1, xmss_pk=self.alice.pk) tx_multisend._revert_state_changes_for_PK = Mock( autospec=TransferTransaction._revert_state_changes_for_PK) tx_multisend.revert_state_changes(addresses_state, unused_chain_manager_mock) self.assertEqual(200, addresses_state[self.alice.address].balance) self.assertEqual(0, addresses_state[self.bob.address].balance) self.assertEqual(0, addresses_state[self.slave.address].balance) self.assertEqual( [], addresses_state[self.alice.address].transaction_hashes) self.assertEqual([], addresses_state[self.bob.address].transaction_hashes) self.assertEqual( [], addresses_state[self.slave.address].transaction_hashes) tx_multisend._revert_state_changes_for_PK.assert_called_once()
def test_get_last_txs(self): with set_qrl_dir('no_data'): with State() as state: self.assertEqual(state.get_last_txs(), []) alice_xmss = get_alice_xmss() block = Block() tx1 = TransferTransaction.create(addrs_to=[get_some_address(0), get_some_address(1)], amounts=[1, 2], fee=0, xmss_pk=alice_xmss.pk) block._data.transactions.extend([tx1.pbdata]) state._update_last_tx(block, None) last_txns = state.get_last_txs() # Test Case: When there is only 1 last txns self.assertEqual(len(last_txns), 1) self.assertEqual(last_txns[0].to_json(), tx1.to_json())
def test_revert_state_changes_for_PK_master_slave_XMSS(self, m_logger): tx = TransferTransaction.create( addrs_to=[self.bob.address], amounts=[100], fee=1, xmss_pk=self.slave.pk, master_addr=self.alice.address ) addr_state = { self.alice.address: Mock(autospec=AddressState, name='alice AddressState'), self.slave.address: Mock(autospec=AddressState, name='slave AddressState') } tx.sign(self.slave) tx._revert_state_changes_for_PK(addr_state, Mock(name='unused State Mock')) addr_state[self.slave.address].decrease_nonce.assert_called_once() addr_state[self.slave.address].unset_ots_key.assert_called_once() addr_state[self.slave.address].transaction_hashes.remove.assert_called_once()
def test_get_last_txs(self): self.assertEqual(LastTransactions.get_last_txs(self.state), []) alice_xmss = get_alice_xmss() block = Block() tx1 = TransferTransaction.create( addrs_to=[get_some_address(0), get_some_address(1)], amounts=[1, 2], message_data=None, fee=0, xmss_pk=alice_xmss.pk) block._data.transactions.extend([tx1.pbdata]) LastTransactions._update_last_tx(self.state, block, None) last_txns = LastTransactions.get_last_txs(self.state) # Test Case: When there is only 1 last txns self.assertEqual(len(last_txns), 1) self.assertEqual(last_txns[0].to_json(), tx1.to_json())
def test_validate_transaction_pool(self, m_logger): """ Two TransferTransactions. Although they're the same, they are signed with different OTS indexes. Therefore they should not conflict when they are both in the TransactionPool. :return: """ tx = self.tx tx2 = TransferTransaction.create(addrs_to=[self.bob.address], amounts=[100], fee=1, xmss_pk=self.alice.pk) tx.sign(self.alice) tx2.sign(self.alice) tx_info = Mock(autospec=TransactionInfo, transaction=tx) tx2_info = Mock(autospec=TransactionInfo, transaction=tx2) transaction_pool = [(replacement_getTime(), tx_info), (replacement_getTime(), tx2_info)] result = tx.validate_transaction_pool(transaction_pool) self.assertTrue(result)
def test_revert_state_changes_tx_sends_to_self(self, m_logger): """ Alice sent coins to herself, but she still lost the Transaction fee. Undo this. """ addresses_state = { self.alice.address: Mock(autospec=AddressState, name='alice AddressState', transaction_hashes=[self.tx.txhash], balance=199), self.bob.address: Mock(autospec=AddressState, name='bob AddressState', transaction_hashes=[], balance=0), self.slave.address: Mock(autospec=AddressState, name='slave AddressState', transaction_hashes=[], balance=0) } unused_chain_manager_mock = Mock(autospec=ChainManager, name='unused ChainManager') tx = TransferTransaction.create(addrs_to=[self.alice.address], amounts=[100], fee=1, xmss_pk=self.alice.pk) tx._revert_state_changes_for_PK = Mock( autospec=TransferTransaction._revert_state_changes_for_PK) tx.revert_state_changes(addresses_state, unused_chain_manager_mock) self.assertEqual(200, addresses_state[self.alice.address].balance) self.assertEqual(0, addresses_state[self.bob.address].balance) self.assertEqual( [], addresses_state[self.alice.address].transaction_hashes) self.assertEqual([], addresses_state[self.bob.address].transaction_hashes) tx._revert_state_changes_for_PK.assert_called_once()
def relay_transfer_txn_by_slave(self, qaddresses_to: list, amounts: list, 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 = TransferTransaction.create( 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)
def test_push_transaction(self): with set_qrl_dir("wallet_ver1"): walletd = WalletD() alice_xmss = get_alice_xmss() bob_xmss = get_bob_xmss() tx = TransferTransaction.create(addrs_to=[bob_xmss.address], amounts=[1], fee=1, xmss_pk=alice_xmss.pk) walletd._public_stub.PushTransaction = Mock( return_value=qrl_pb2.PushTransactionResp( error_code=qrl_pb2.PushTransactionResp.SUBMITTED)) walletd._push_transaction(tx, alice_xmss) walletd._public_stub.PushTransaction = Mock( return_value=qrl_pb2.PushTransactionResp( error_code=qrl_pb2.PushTransactionResp.UNKNOWN)) with self.assertRaises(Exception): walletd._push_transaction(tx, alice_xmss)
def test_apply_state_changes_tx_sends_to_self(self, m_logger): """ If you send coins to yourself, you should only lose the fee for the Transaction. """ addresses_state = { self.alice.address: Mock(autospec=AddressState, name='alice AddressState', transaction_hashes=[], balance=200), self.bob.address: Mock(autospec=AddressState, name='bob AddressState', transaction_hashes=[], balance=0), self.slave.address: Mock(autospec=AddressState, name='slave AddressState', transaction_hashes=[], balance=0) } tx = TransferTransaction.create( addrs_to=[self.alice.address], amounts=[100], fee=1, xmss_pk=self.alice.pk ) tx._apply_state_changes_for_PK = Mock(autospec=TransferTransaction._revert_state_changes_for_PK) tx.apply_state_changes(addresses_state) self.assertEqual(199, addresses_state[self.alice.address].balance) self.assertIn(tx.txhash, addresses_state[self.alice.address].transaction_hashes)
def test_remove_last_tx(self): # Test Case: When there is no last txns self.assertEqual(self.state.get_last_txs(), []) alice_xmss = get_alice_xmss() block = Block() tx1 = TransferTransaction.create( addrs_to=[get_some_address(1), get_some_address(2)], amounts=[1, 2], fee=0, xmss_pk=alice_xmss.pk) block._data.transactions.extend([tx1.pbdata]) self.state._update_last_tx(block, None) last_txns = self.state.get_last_txs() self.assertEqual(last_txns[0].to_json(), tx1.to_json()) self.state._remove_last_tx(block, None) last_txns = self.state.get_last_txs() self.assertEqual(last_txns, [])
def test_rollback_tx_metadata(self): alice_xmss = get_alice_xmss() tx1 = TransferTransaction.create( addrs_to=[get_some_address(1), get_some_address(2)], amounts=[1, 2], fee=0, xmss_pk=alice_xmss.pk) block = Block.create(block_number=5, prev_headerhash=b'', prev_timestamp=10, transactions=[tx1], miner_address=b'') self.state.update_tx_metadata(block=block, batch=None) tx_metadata = self.state.get_tx_metadata(tx1.txhash) self.assertEqual(tx_metadata[0].to_json(), tx1.to_json()) self.state.rollback_tx_metadata(block, None) self.assertIsNone(self.state.get_tx_metadata(tx1.txhash))
def test_notification(self): source = Mock() source.factory = Mock() source.factory.master_mr = Mock() source.factory.master_mr.isRequested = Mock() source.factory.add_unprocessed_txn = Mock() channel = Observable(source) self.tx_manager = P2PTxManagement() self.tx_manager.new_channel(channel) tx = TransferTransaction.create(addrs_to=[get_some_address()], amounts=[1], fee=10, xmss_pk=bytes(67)) event = qrllegacy_pb2.LegacyMessage( func_name=qrllegacy_pb2.LegacyMessage.TX, txData=tx.pbdata) channel.notify(event, force_delivery=True) source.factory.master_mr.isRequested.assert_called() source.factory.add_unprocessed_txn.assert_called()