upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp50
1 files changed, 45 insertions, 5 deletions
diff --git a/src/main.cpp b/src/main.cpp
index d9fe713..8926d57 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -3293,16 +3293,56 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
3293 CInv inv(MSG_BLOCK, pblock->GetHash()); 3293 CInv inv(MSG_BLOCK, pblock->GetHash());
3294 pfrom->AddInventoryKnown(inv); 3294 pfrom->AddInventoryKnown(inv);
3295 3295
3296 // The body is here, so the fetch is over whatever validation says 3296 // GetHash() covers the 80-byte header and nothing else, so the hash
3297 // next -- unlike the mapAlreadyAskedFor erase below, which stays 3297 // coming out right does not make this the block we asked for. Every
3298 // conditional on acceptance so a peer feeding us garbage does not 3298 // peer that saw X announced holds X's header, and can answer our
3299 // cancel the scheduled retries for the real thing. 3299 // getdata with that header bolted onto a transaction list of its own
3300 mapBlockFetch.erase(inv.hash); 3300 // invention -- the reply still hashes to X. hashMerkleRoot is the only
3301 // thing binding the header to the body, so check it here, before the
3302 // mapBlockFetch entry is touched and before CheckBlock spends a
3303 // RandomX hash on a body already known to be forged.
3304 //
3305 // There is no honest way to arrive here. Peer traffic rides the .btf
3306 // channel, which is XChaCha20-Poly1305, so a body that arrives at all
3307 // arrived intact: a mismatch is the peer's own construction, not line
3308 // noise. Drop the peer and leave the fetch outstanding so the failover
3309 // sweep asks somebody else for the real X, rather than recording X as
3310 // delivered on the strength of a header anyone could copy.
3311 if (pblock->hashMerkleRoot != pblock->BuildMerkleTree())
3312 {
3313 if (LogAcceptsCategory("net"))
3314 printf("peer %s served a forged body for %s\n",
3315 pfrom->addr.ToString().c_str(), inv.ToString().c_str());
3316 // One line per connection: ProcessMessages keeps draining the
3317 // receive buffer after fDisconnect is set, so a peer that packs
3318 // many forged bodies into one buffer must not get one log line
3319 // for each of them.
3320 if (!pfrom->fDisconnect)
3321 printf("block fetch: a peer answered the request for %s with a body that is not "
3322 "that block -- dropping it\n", inv.hash.ToString().substr(0,14).c_str());
3323 pfrom->fDisconnect = true;
3324 return error("ProcessMessage() : forged block body for %s",
3325 inv.hash.ToString().substr(0,14).c_str());
3326 }
3301 3327
3302 if (ProcessBlock(pfrom, pblock.release())) 3328 if (ProcessBlock(pfrom, pblock.release()))
3303 { 3329 {
3304 mapAlreadyAskedFor.erase(inv); 3330 mapAlreadyAskedFor.erase(inv);
3305 3331
3332 // The body arrived and validated, so the fetch really is over:
3333 // the block is now in mapBlockIndex, or parked in mapOrphanBlocks,
3334 // and either way AlreadyHave answers for it from here on.
3335 //
3336 // This has to stay inside the success branch, next to the erase
3337 // above. When validation rejects a body nothing is stored,
3338 // AlreadyHave stays false, and the mapAskFor entry was already
3339 // consumed when the getdata went out -- so erasing the tracking
3340 // here would leave the block requested from nobody at all until
3341 // some peer happened to re-announce it. That is exactly the stall
3342 // of #33, and erasing before ProcessBlock made it reachable on
3343 // demand.
3344 mapBlockFetch.erase(inv.hash);
3345
3306 // A peer that just handed us a block is demonstrably at least at 3346 // A peer that just handed us a block is demonstrably at least at
3307 // that block's height. Without this, nStartingHeight is a snapshot 3347 // that block's height. Without this, nStartingHeight is a snapshot
3308 // taken once during the version handshake and never touched again, 3348 // taken once during the version handshake and never touched again,