mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-20 15:19:07 +01:00
BIP144: Serialization, hashes, relay (sender side)
Contains refactorings by Eric Lombrozo. Contains fixup by Nicolas Dorier. Contains cleanup of CInv::GetCommand by Alex Morcos
This commit is contained in:
28
src/main.cpp
28
src/main.cpp
@@ -1029,8 +1029,8 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
|
||||
return state.DoS(10, false, REJECT_INVALID, "bad-txns-vin-empty");
|
||||
if (tx.vout.empty())
|
||||
return state.DoS(10, false, REJECT_INVALID, "bad-txns-vout-empty");
|
||||
// Size limits
|
||||
if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
|
||||
// Size limits (this doesn't take the witness into account, as that hasn't been checked for malleability)
|
||||
if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) > MAX_BLOCK_SIZE)
|
||||
return state.DoS(100, false, REJECT_INVALID, "bad-txns-oversize");
|
||||
|
||||
// Check for negative or overflow output values
|
||||
@@ -3396,7 +3396,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P
|
||||
// because we receive the wrong transactions for it.
|
||||
|
||||
// Size limits
|
||||
if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
|
||||
if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) > MAX_BLOCK_SIZE)
|
||||
return state.DoS(100, false, REJECT_INVALID, "bad-blk-length", false, "size limits failed");
|
||||
|
||||
// First transaction must be coinbase, the rest must not be
|
||||
@@ -4508,6 +4508,7 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||
switch (inv.type)
|
||||
{
|
||||
case MSG_TX:
|
||||
case MSG_WITNESS_TX:
|
||||
{
|
||||
assert(recentRejects);
|
||||
if (chainActive.Tip()->GetBlockHash() != hashRecentRejectsChainTip)
|
||||
@@ -4528,6 +4529,7 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||
pcoinsTip->HaveCoinsInCache(inv.hash);
|
||||
}
|
||||
case MSG_BLOCK:
|
||||
case MSG_WITNESS_BLOCK:
|
||||
return mapBlockIndex.count(inv.hash);
|
||||
}
|
||||
// Don't know what it is, just say we already got one
|
||||
@@ -4552,7 +4554,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
||||
boost::this_thread::interruption_point();
|
||||
it++;
|
||||
|
||||
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK)
|
||||
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK || inv.type == MSG_WITNESS_BLOCK)
|
||||
{
|
||||
bool send = false;
|
||||
BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
|
||||
@@ -4593,6 +4595,8 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
||||
if (!ReadBlockFromDisk(block, (*mi).second, consensusParams))
|
||||
assert(!"cannot load block from disk");
|
||||
if (inv.type == MSG_BLOCK)
|
||||
pfrom->PushMessageWithFlag(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCK, block);
|
||||
else if (inv.type == MSG_WITNESS_BLOCK)
|
||||
pfrom->PushMessage(NetMsgType::BLOCK, block);
|
||||
else if (inv.type == MSG_FILTERED_BLOCK)
|
||||
{
|
||||
@@ -4609,7 +4613,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
||||
// however we MUST always provide at least what the remote peer needs
|
||||
typedef std::pair<unsigned int, uint256> PairType;
|
||||
BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn)
|
||||
pfrom->PushMessage(NetMsgType::TX, block.vtx[pair.first]);
|
||||
pfrom->PushMessageWithFlag(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::TX, block.vtx[pair.first]);
|
||||
}
|
||||
// else
|
||||
// no response
|
||||
@@ -4622,9 +4626,9 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
||||
// instead we respond with the full, non-compact block.
|
||||
if (mi->second->nHeight >= chainActive.Height() - 10) {
|
||||
CBlockHeaderAndShortTxIDs cmpctblock(block);
|
||||
pfrom->PushMessage(NetMsgType::CMPCTBLOCK, cmpctblock);
|
||||
pfrom->PushMessageWithFlag(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::CMPCTBLOCK, cmpctblock);
|
||||
} else
|
||||
pfrom->PushMessage(NetMsgType::BLOCK, block);
|
||||
pfrom->PushMessageWithFlag(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCK, block);
|
||||
}
|
||||
|
||||
// Trigger the peer node to send a getblocks request for the next batch of inventory
|
||||
@@ -4640,20 +4644,20 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (inv.type == MSG_TX)
|
||||
else if (inv.type == MSG_TX || inv.type == MSG_WITNESS_TX)
|
||||
{
|
||||
// Send stream from relay memory
|
||||
bool push = false;
|
||||
auto mi = mapRelay.find(inv.hash);
|
||||
if (mi != mapRelay.end()) {
|
||||
pfrom->PushMessage(NetMsgType::TX, *mi->second);
|
||||
pfrom->PushMessageWithFlag(inv.type == MSG_TX ? SERIALIZE_TRANSACTION_NO_WITNESS : 0, NetMsgType::TX, *mi->second);
|
||||
push = true;
|
||||
} else if (pfrom->timeLastMempoolReq) {
|
||||
auto txinfo = mempool.info(inv.hash);
|
||||
// To protect privacy, do not answer getdata using the mempool when
|
||||
// that TX couldn't have been INVed in reply to a MEMPOOL request.
|
||||
if (txinfo.tx && txinfo.nTime <= pfrom->timeLastMempoolReq) {
|
||||
pfrom->PushMessage(NetMsgType::TX, *txinfo.tx);
|
||||
pfrom->PushMessageWithFlag(inv.type == MSG_TX ? SERIALIZE_TRANSACTION_NO_WITNESS : 0, NetMsgType::TX, *txinfo.tx);
|
||||
push = true;
|
||||
}
|
||||
}
|
||||
@@ -4665,7 +4669,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
||||
// Track requests for our stuff.
|
||||
GetMainSignals().Inventory(inv.hash);
|
||||
|
||||
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK)
|
||||
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK || inv.type == MSG_WITNESS_BLOCK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -5146,7 +5150,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||
}
|
||||
resp.txn[i] = block.vtx[req.indexes[i]];
|
||||
}
|
||||
pfrom->PushMessage(NetMsgType::BLOCKTXN, resp);
|
||||
pfrom->PushMessageWithFlag(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCKTXN, resp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user