diff --git a/src/avalanche/processor.h b/src/avalanche/processor.h --- a/src/avalanche/processor.h +++ b/src/avalanche/processor.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -277,13 +278,16 @@ std::unordered_map stakingRewards GUARDED_BY(cs_stakingRewards); + const bool m_preConsensus{false}; + Processor(Config avaconfig, interfaces::Chain &chain, CConnman *connmanIn, ChainstateManager &chainman, CTxMemPool *mempoolIn, CScheduler &scheduler, std::unique_ptr peerDataIn, CKey sessionKeyIn, uint32_t minQuorumTotalScoreIn, double minQuorumConnectedScoreRatioIn, int64_t minAvaproofsNodeCountIn, uint32_t staleVoteThresholdIn, - uint32_t staleVoteFactorIn, Amount stakeUtxoDustThresholdIn); + uint32_t staleVoteFactorIn, Amount stakeUtxoDustThresholdIn, + bool preConsensus); public: ~Processor(); @@ -388,6 +392,8 @@ private: void updatedBlockTip() EXCLUSIVE_LOCKS_REQUIRED(!cs_peerManager, !cs_finalizedItems); + void transactionAddedToMempool(const CTransactionRef &tx) + EXCLUSIVE_LOCKS_REQUIRED(!cs_finalizedItems); void runEventLoop() EXCLUSIVE_LOCKS_REQUIRED(!cs_peerManager, !cs_stakingRewards, !cs_finalizedItems); diff --git a/src/avalanche/processor.cpp b/src/avalanche/processor.cpp --- a/src/avalanche/processor.cpp +++ b/src/avalanche/processor.cpp @@ -134,6 +134,11 @@ NotificationsHandler(Processor *p) : m_processor(p) {} void updatedBlockTip() override { m_processor->updatedBlockTip(); } + + void transactionAddedToMempool(const CTransactionRef &tx, + uint64_t mempool_sequence) override { + m_processor->transactionAddedToMempool(tx); + } }; Processor::Processor(Config avaconfigIn, interfaces::Chain &chain, @@ -144,7 +149,7 @@ double minQuorumConnectedScoreRatioIn, int64_t minAvaproofsNodeCountIn, uint32_t staleVoteThresholdIn, uint32_t staleVoteFactorIn, - Amount stakeUtxoDustThreshold) + Amount stakeUtxoDustThreshold, bool preConsensus) : avaconfig(std::move(avaconfigIn)), connman(connmanIn), chainman(chainmanIn), mempool(mempoolIn), voteRecords(RWCollection(VoteMap(VoteMapComparator(mempool)))), @@ -156,7 +161,7 @@ minQuorumConnectedScoreRatio(minQuorumConnectedScoreRatioIn), minAvaproofsNodeCount(minAvaproofsNodeCountIn), staleVoteThreshold(staleVoteThresholdIn), - staleVoteFactor(staleVoteFactorIn) { + staleVoteFactor(staleVoteFactorIn), m_preConsensus(preConsensus) { // Make sure we get notified of chain state changes. chainNotificationsHandler = chain.handleNotifications(std::make_shared(this)); @@ -392,7 +397,9 @@ std::move(peerData), std::move(sessionKey), Proof::amountToScore(minQuorumStake), minQuorumConnectedStakeRatio, minAvaproofsNodeCount, staleVoteThreshold, staleVoteFactor, - stakeUtxoDustThreshold)); + stakeUtxoDustThreshold, + argsman.GetBoolArg("-avalanchepreconsensus", + DEFAULT_AVALANCHE_PRECONSENSUS))); } static bool isNull(const AnyVoteItem &item) { @@ -996,6 +1003,12 @@ } } +void Processor::transactionAddedToMempool(const CTransactionRef &tx) { + if (m_preConsensus) { + addToReconcile(tx); + } +} + void Processor::runEventLoop() { // Don't poll if quorum hasn't been established yet if (!isQuorumEstablished()) { diff --git a/test/functional/abc_p2p_avalanche_transaction_voting.py b/test/functional/abc_p2p_avalanche_transaction_voting.py --- a/test/functional/abc_p2p_avalanche_transaction_voting.py +++ b/test/functional/abc_p2p_avalanche_transaction_voting.py @@ -5,7 +5,7 @@ """Test avalanche transaction voting.""" import random -from test_framework.avatools import get_ava_p2p_interface +from test_framework.avatools import can_find_inv_in_poll, get_ava_p2p_interface from test_framework.key import ECPubKey from test_framework.messages import ( MSG_TX, @@ -19,7 +19,7 @@ ) from test_framework.test_framework import BitcoinTestFramework from test_framework.txtools import pad_tx -from test_framework.util import assert_equal +from test_framework.util import assert_equal, uint256_hex from test_framework.wallet import MiniWallet QUORUM_NODE_COUNT = 16 @@ -91,7 +91,8 @@ get_ava_p2p_interface(self, node) for _ in range(0, QUORUM_NODE_COUNT) ] - _ = get_quorum() + quorum = get_quorum() + assert node.getavalancheinfo()["ready_to_poll"] poll_node.send_poll(tx_ids, MSG_TX) assert_response( @@ -152,6 +153,27 @@ poll_node.send_poll([orphan_txid], MSG_TX) assert_response([AvalancheVote(AvalancheTxVoteError.ORPHAN, orphan_txid)]) + self.log.info("Check the node polls for transactions added to the mempool") + + # Let's clean up the non transaction inventories from our avalanche polls + def has_finalized_proof(proofid): + can_find_inv_in_poll(quorum, proofid) + return node.getrawavalancheproof(uint256_hex(proofid))["finalized"] + + for q in quorum: + self.wait_until(lambda: has_finalized_proof(q.proof.proofid)) + + def has_finalized_block(block_hash): + can_find_inv_in_poll(quorum, int(block_hash, 16)) + return node.isfinalblock(block_hash) + + tip = node.getbestblockhash() + self.wait_until(lambda: has_finalized_block(tip)) + + txid = wallet.send_self_transfer(from_node=node)["txid"] + assert txid in node.getrawmempool() + self.wait_until(lambda: can_find_inv_in_poll(quorum, int(txid, 16))) + if __name__ == "__main__": AvalancheTransactionVotingTest().main()