Add MSG_WTX support to inv messages
The change to AlreadyHave() means that nodes will also now send getdata requests for v5 transactions.
This commit is contained in:
parent
9476f5d7ef
commit
d503691778
|
@ -10,6 +10,7 @@ from test_framework.mininode import (
|
|||
NodeConn,
|
||||
mininode_lock,
|
||||
msg_getdata,
|
||||
msg_mempool,
|
||||
uint256_from_str,
|
||||
)
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
|
@ -49,6 +50,31 @@ class Zip239Test(BitcoinTestFramework):
|
|||
else:
|
||||
return CInv(1, txid)
|
||||
|
||||
def verify_inv(self, testnode, txs):
|
||||
# Make sure we are synced before sending the mempool message
|
||||
testnode.sync_with_ping()
|
||||
|
||||
# Send p2p message "mempool" to receive contents from zcashd node in "inv" message
|
||||
with mininode_lock:
|
||||
testnode.last_inv = None
|
||||
testnode.send_message(msg_mempool())
|
||||
|
||||
# Sync up with node after p2p messages delivered
|
||||
testnode.sync_with_ping(waiting_for=lambda x: x.last_inv)
|
||||
|
||||
with mininode_lock:
|
||||
msg = testnode.last_inv
|
||||
assert_equal(len(msg.inv), len(txs))
|
||||
|
||||
expected_invs = sorted(txs, key=lambda inv: (inv.type, inv.hash, inv.hash_aux))
|
||||
actual_invs = sorted(msg.inv, key=lambda inv: (inv.type, inv.hash, inv.hash_aux))
|
||||
|
||||
for (expected, actual) in zip(expected_invs, actual_invs):
|
||||
fail_msg = "%r != %r" % (actual, expected)
|
||||
assert_equal(actual.type, expected.type, fail_msg)
|
||||
assert_equal(actual.hash, expected.hash, fail_msg)
|
||||
assert_equal(actual.hash_aux, expected.hash_aux, fail_msg)
|
||||
|
||||
def send_data_message(self, testnode, txid, authDigest=None):
|
||||
# Send p2p message "getdata" to verify tx gets sent in "tx" message
|
||||
getdatamsg = msg_getdata()
|
||||
|
@ -125,13 +151,11 @@ class Zip239Test(BitcoinTestFramework):
|
|||
)[::-1])
|
||||
|
||||
# Add v5 transaction to the mempool.
|
||||
""" TODO: Enable this once self.sync_all() works with v5 txs in the mempool.
|
||||
v5_txid = self.nodes[0].sendtoaddress(node1_taddr, 1, "", "", True)
|
||||
v5_tx = self.nodes[0].getrawtransaction(v5_txid, 1)
|
||||
assert_equal(v5_tx['version'], 5)
|
||||
v5_txid = uint256_from_str(hex_str_to_bytes(v5_txid)[::-1])
|
||||
v5_auth_digest = uint256_from_str(hex_str_to_bytes(v5_tx['authdigest'])[::-1])
|
||||
"""
|
||||
|
||||
# Wait for the mempools to sync.
|
||||
self.sync_all()
|
||||
|
@ -154,6 +178,19 @@ class Zip239Test(BitcoinTestFramework):
|
|||
NetworkThread().start() # Start up network handling in another thread
|
||||
[x.wait_for_verack() for x in test_nodes]
|
||||
|
||||
#
|
||||
# inv
|
||||
#
|
||||
|
||||
# On a mempool request, nodes should return an inv message containing:
|
||||
# - the v4 tx, with type MSG_TX.
|
||||
# - the v5 tx, with type MSG_WTX.
|
||||
for testnode in test_nodes:
|
||||
self.verify_inv(testnode, [
|
||||
self.cinv_for(v4_txid),
|
||||
self.cinv_for(v5_txid, v5_auth_digest),
|
||||
])
|
||||
|
||||
#
|
||||
# getdata
|
||||
#
|
||||
|
@ -162,7 +199,6 @@ class Zip239Test(BitcoinTestFramework):
|
|||
self.send_data_message(test_nodes[0], v4_txid)
|
||||
self.verify_last_tx(test_nodes[0], v4_txid)
|
||||
|
||||
""" TODO: Enable once we have a v5 tx in the mempool.
|
||||
# We can request a v5 transaction with MSG_WTX.
|
||||
self.send_data_message(test_nodes[1], v5_txid, v5_auth_digest)
|
||||
self.verify_last_tx(test_nodes[1], v5_txid, v5_auth_digest)
|
||||
|
@ -170,17 +206,14 @@ class Zip239Test(BitcoinTestFramework):
|
|||
# Requesting with a different authDigest results in a notfound.
|
||||
self.send_data_message(test_nodes[1], v5_txid, 1)
|
||||
self.verify_last_notfound(test_nodes[1], v5_txid, 1)
|
||||
"""
|
||||
|
||||
# Requesting a v4 transaction with MSG_WTX causes a disconnect.
|
||||
self.send_data_message(test_nodes[2], v4_txid, (1 << 256) - 1)
|
||||
self.verify_disconnected(test_nodes[2])
|
||||
|
||||
""" TODO: Enable once we have a v5 tx in the mempool.
|
||||
# Requesting a v5 transaction with MSG_TX causes a disconnect.
|
||||
self.send_data_message(test_nodes[3], v5_txid)
|
||||
self.verify_disconnected(test_nodes[3])
|
||||
"""
|
||||
|
||||
[c.disconnect_node() for c in connections]
|
||||
|
||||
|
|
20
src/main.cpp
20
src/main.cpp
|
@ -6006,11 +6006,22 @@ void static CheckBlockIndex(const Consensus::Params& consensusParams)
|
|||
//
|
||||
|
||||
|
||||
CInv static InvForTransaction(const std::shared_ptr<const CTransaction> tx)
|
||||
{
|
||||
if (tx->nVersion >= 5) {
|
||||
auto& wtxid = tx->GetWTxId();
|
||||
return CInv(MSG_WTX, wtxid.hash, wtxid.authDigest);
|
||||
} else {
|
||||
return CInv(MSG_TX, tx->GetHash());
|
||||
}
|
||||
}
|
||||
|
||||
bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||
{
|
||||
switch (inv.type)
|
||||
{
|
||||
case MSG_TX:
|
||||
case MSG_WTX:
|
||||
{
|
||||
assert(recentRejects);
|
||||
if (chainActive.Tip()->GetBlockHash() != hashRecentRejectsChainTip)
|
||||
|
@ -6541,7 +6552,7 @@ bool static ProcessMessage(const CChainParams& chainparams, CNode* pfrom, string
|
|||
}
|
||||
else
|
||||
{
|
||||
pfrom->AddInventoryKnown(inv);
|
||||
pfrom->AddKnownTx(inv.hash);
|
||||
if (fBlocksOnly)
|
||||
LogPrint("net", "transaction (%s) inv sent in violation of protocol peer=%d\n", inv.hash.ToString(), pfrom->id);
|
||||
else if (!fAlreadyHave && !IsInitialBlockDownload(chainparams.GetConsensus()))
|
||||
|
@ -6686,7 +6697,7 @@ bool static ProcessMessage(const CChainParams& chainparams, CNode* pfrom, string
|
|||
vRecv >> tx;
|
||||
|
||||
CInv inv(MSG_TX, tx.GetHash());
|
||||
pfrom->AddInventoryKnown(inv);
|
||||
pfrom->AddKnownTx(inv.hash);
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
|
@ -7484,7 +7495,7 @@ bool SendMessages(const Consensus::Params& params, CNode* pto)
|
|||
|
||||
for (const auto& txinfo : vtxinfo) {
|
||||
const uint256& hash = txinfo.tx->GetHash();
|
||||
CInv inv(MSG_TX, hash);
|
||||
CInv inv = InvForTransaction(txinfo.tx);
|
||||
pto->setInventoryTxToSend.erase(hash);
|
||||
if (IsExpiringSoonTx(*txinfo.tx, currentHeight + 1)) continue;
|
||||
if (pto->pfilter) {
|
||||
|
@ -7533,10 +7544,11 @@ bool SendMessages(const Consensus::Params& params, CNode* pto)
|
|||
if (!txinfo.tx) {
|
||||
continue;
|
||||
}
|
||||
CInv inv = InvForTransaction(txinfo.tx);
|
||||
if (IsExpiringSoonTx(*txinfo.tx, currentHeight + 1)) continue;
|
||||
if (pto->pfilter && !pto->pfilter->IsRelevantAndUpdate(*txinfo.tx)) continue;
|
||||
// Send
|
||||
vInv.push_back(CInv(MSG_TX, hash));
|
||||
vInv.push_back(inv);
|
||||
nRelayedTransactions++;
|
||||
{
|
||||
// Expire old relay messages
|
||||
|
|
Loading…
Reference in New Issue