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 get_tx_metadata(self, txhash: bytes): try: tx_metadata = TransactionMetadata.deserialize( self._db.get_raw(txhash)) data, block_number = tx_metadata.transaction, tx_metadata.block_number return Transaction.from_pbdata(data), block_number except Exception: return None
def put_tx_metadata(self, txn: Transaction, block_number: int, timestamp: int, batch): try: tm = TransactionMetadata.create(tx=txn, block_number=block_number, timestamp=timestamp) self._db.put_raw(txn.txhash, tm.serialize(), batch) except Exception: pass
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], message_data=None, fee=0, xmss_pk=alice_xmss.pk) block = Block.create(dev_config=config.dev, block_number=5, prev_headerhash=b'', prev_timestamp=10, transactions=[tx1], miner_address=b'', seed_height=0, seed_hash=None) TransactionMetadata.update_tx_metadata(self.state, block=block, batch=None) tx_metadata = TransactionMetadata.get_tx_metadata( self.state, tx1.txhash) self.assertEqual(tx_metadata[0].to_json(), tx1.to_json()) TransactionMetadata.rollback_tx_metadata(self.state, block, None) self.assertIsNone( TransactionMetadata.get_tx_metadata(self.state, tx1.txhash))
def test_getMiniTransactionsByAddress(self, mock_dev_config): mock_dev_config.data_per_page = 5 with set_qrl_dir('no_data'): db_state = State() 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 a transaction alice_xmss = get_alice_xmss(8) context = Mock(spec=ServicerContext) bob_xmss = get_bob_xmss(4) txs = [] for i in range(0, 100): tx = TransferTransaction.create(addrs_to=[bob_xmss.address], amounts=[10], message_data=None, fee=0, xmss_pk=alice_xmss.pk) tx.sign(alice_xmss) txs.append(tx) addresses_set = {bob_xmss.address, alice_xmss.address} block = Block.create(config.dev, 10, b'', 100000000, txs, alice_xmss.address, seed_height=0, seed_hash=None) state_container = chain_manager.new_state_container(addresses_set, 5, True, None) for tx in txs: chain_manager.update_state_container(tx, state_container) address_state = state_container.addresses_state[tx.addr_from] state_container.paginated_tx_hash.insert(address_state, tx.txhash) address_state = state_container.addresses_state[tx.addrs_to[0]] state_container.paginated_tx_hash.insert(address_state, tx.txhash) state_container.paginated_tx_hash.put_paginated_data(None) OptimizedAddressState.put_optimized_addresses_state(db_state, state_container.addresses_state) TransactionMetadata.update_tx_metadata(db_state, block, None) request = qrl_pb2.GetMiniTransactionsByAddressReq(address=alice_xmss.address, item_per_page=10, page_number=1) response = service.GetMiniTransactionsByAddress(request=request, context=context) context.set_code.assert_not_called() self.assertEqual(len(response.mini_transactions), 10) for i in range(0, 10): self.assertEqual(bin2hstr(txs[len(txs) - i - 1].txhash), response.mini_transactions[i].transaction_hash) self.assertEqual(response.balance, 0) TransactionMetadata.update_tx_metadata(db_state, block, None) request = qrl_pb2.GetMiniTransactionsByAddressReq(address=alice_xmss.address, item_per_page=8, page_number=3) response = service.GetMiniTransactionsByAddress(request=request, context=context) context.set_code.assert_not_called() self.assertEqual(len(response.mini_transactions), 8) for i in range(0, 8): self.assertEqual(bin2hstr(txs[len(txs) - i - 17].txhash), response.mini_transactions[i].transaction_hash) self.assertEqual(response.balance, 0)
def test_getLatestData(self): with set_qrl_dir('no_data'): db_state = State() chain_manager = ChainManager(db_state) blocks = [] txs = [] alice_xmss = get_alice_xmss() bob_xmss = get_bob_xmss() for i in range(0, 4): for j in range(1, 3): txs.append(TransferTransaction.create(addrs_to=[bob_xmss.address], amounts=[i * 100 + j], message_data=None, fee=j, xmss_pk=alice_xmss.pk)) blocks.append(Block.create(dev_config=config.dev, block_number=i, prev_headerhash=sha256(b'reveal'), prev_timestamp=10, transactions=txs, miner_address=alice_xmss.address, seed_height=10, seed_hash=None)) block = blocks[i] Block.put_block(db_state, block, None) Block.put_block_number_mapping(db_state, block.block_number, qrl_pb2.BlockNumberMapping(headerhash=block.headerhash), None) TransactionMetadata.update_tx_metadata(db_state, block, None) chain_manager._last_block = blocks[-1] txpool = [] txs = [] for j in range(10, 15): tx = TransferTransaction.create(addrs_to=[bob_xmss.address], amounts=[1000 + j], message_data=None, fee=j, xmss_pk=get_alice_xmss().pk) txpool.append((tx.fee, TransactionInfo(tx, 0))) txs.append(tx) p2p_factory = Mock(spec=P2PFactory) p2p_factory.pow = Mock(spec=POW) chain_manager.tx_pool = Mock() chain_manager.tx_pool.transactions = heapq.nlargest(len(txpool), txpool) chain_manager.tx_pool.transaction_pool = txpool qrlnode = QRLNode(mining_address=b'') qrlnode.set_chain_manager(chain_manager) qrlnode.get_block_from_index = MagicMock(return_value=None) qrlnode._p2pfactory = p2p_factory qrlnode._pow = p2p_factory.pow service = PublicAPIService(qrlnode) context = Mock(spec=ServicerContext) request = qrl_pb2.GetLatestDataReq(filter=qrl_pb2.GetLatestDataReq.ALL, offset=0, quantity=3) response = service.GetLatestData(request=request, context=context) context.set_code.assert_not_called() context.set_details.assert_not_called() # Verify blockheaders self.assertEqual(3, len(response.blockheaders)) self.assertEqual(1, response.blockheaders[0].header.block_number) self.assertEqual(2, response.blockheaders[1].header.block_number) self.assertEqual(3, response.blockheaders[2].header.block_number) # Verify transactions_unconfirmed self.assertEqual(3, len(response.transactions_unconfirmed)) # TODO: Verify expected order self.assertEqual(1014, response.transactions_unconfirmed[0].tx.transfer.amounts[0]) self.assertEqual(1013, response.transactions_unconfirmed[1].tx.transfer.amounts[0]) self.assertEqual(1012, response.transactions_unconfirmed[2].tx.transfer.amounts[0]) # Verify transactions self.assertEqual(3, len(response.transactions)) self.assertEqual(2, response.transactions[0].tx.fee) self.assertEqual(1, response.transactions[1].tx.fee) self.assertEqual(2, response.transactions[2].tx.fee) self.assertEqual(302, response.transactions[0].tx.transfer.amounts[0]) self.assertEqual(301, response.transactions[1].tx.transfer.amounts[0]) self.assertEqual(202, response.transactions[2].tx.transfer.amounts[0])
def get_multi_sig_address_by_shared_key(state: State, shared_key: bytes): tx, _ = TransactionMetadata.get_tx_metadata(state, shared_key) if tx is None: return None return tx.multi_sig_address