From 05a85b2b38d516a8701f684fcd2ab99f3e5b462d Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 31 Jul 2012 17:42:35 -0400 Subject: [PATCH] Add 'mempool' P2P command, and extend 'getdata' behavior to permit downloading of mempool transactions from the remote peer. --- src/main.cpp | 35 ++++++++++++++++++++++++++++++++--- src/main.h | 1 + src/version.h | 5 ++++- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 0c636cde..293e7bca 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2562,7 +2562,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { vector vInv; vRecv >> vInv; - if (vInv.size() > 50000) + if (vInv.size() > MAX_INV_SZ) { pfrom->Misbehaving(20); return error("message inv size() = %d", vInv.size()); @@ -2613,7 +2613,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { vector vInv; vRecv >> vInv; - if (vInv.size() > 50000) + if (vInv.size() > MAX_INV_SZ) { pfrom->Misbehaving(20); return error("message getdata size() = %d", vInv.size()); @@ -2655,11 +2655,24 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) else if (inv.IsKnownType()) { // Send stream from relay memory + bool pushed = false; { LOCK(cs_mapRelay); map::iterator mi = mapRelay.find(inv); - if (mi != mapRelay.end()) + if (mi != mapRelay.end()) { pfrom->PushMessage(inv.GetCommand(), (*mi).second); + pushed = true; + } + } + if (!pushed && inv.type == MSG_TX) { + LOCK(mempool.cs); + if (mempool.exists(inv.hash)) { + CTransaction tx = mempool.lookup(inv.hash); + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss.reserve(1000); + ss << tx; + pfrom->PushMessage("tx", ss); + } } } @@ -2834,6 +2847,22 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) } + else if (strCommand == "mempool") + { + std::vector vtxid; + mempool.queryHashes(vtxid); + vector vInv; + for (unsigned int i = 0; i < vtxid.size(); i++) { + CInv inv(MSG_TX, vtxid[i]); + vInv.push_back(inv); + if (i == (MAX_INV_SZ - 1)) + break; + } + if (vInv.size() > 0) + pfrom->PushMessage("inv", vInv); + } + + else if (strCommand == "checkorder") { uint256 hashReply; diff --git a/src/main.h b/src/main.h index 301badcc..62187e42 100644 --- a/src/main.h +++ b/src/main.h @@ -27,6 +27,7 @@ static const unsigned int MAX_BLOCK_SIZE = 1000000; static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2; static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; static const unsigned int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100; +static const unsigned int MAX_INV_SZ = 50000; static const int64 MIN_TX_FEE = 50000; static const int64 MIN_RELAY_TX_FEE = 10000; static const int64 MAX_MONEY = 21000000 * COIN; diff --git a/src/version.h b/src/version.h index c0d53e8b..9d2fa6bb 100644 --- a/src/version.h +++ b/src/version.h @@ -30,7 +30,7 @@ extern const std::string CLIENT_DATE; // network protocol versioning // -static const int PROTOCOL_VERSION = 60001; +static const int PROTOCOL_VERSION = 60002; // earlier versions not supported as of Feb 2012, and are disconnected static const int MIN_PROTO_VERSION = 209; @@ -46,4 +46,7 @@ static const int NOBLKS_VERSION_END = 32400; // BIP 0031, pong message, is enabled for all versions AFTER this one static const int BIP0031_VERSION = 60000; +// "mempool" command, enhanced "getdata" behavior starts with this version: +static const int MEMPOOL_GD_VERSION = 60002; + #endif