upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/compactblock.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/compactblock.cpp')
-rw-r--r--src/compactblock.cpp22
1 files changed, 21 insertions, 1 deletions
diff --git a/src/compactblock.cpp b/src/compactblock.cpp
index 3999ab7..1ca6118 100644
--- a/src/compactblock.cpp
+++ b/src/compactblock.cpp
@@ -48,8 +48,16 @@ bool BuildCompactBlock(const CBlock& block, CCmpctBlock& out)
48 out.nBits = block.nBits; 48 out.nBits = block.nBits;
49 out.nNonce = block.nNonce; 49 out.nNonce = block.nNonce;
50 50
51 // Upstream ignored the RAND_bytes return value here. On failure nonceBytes
52 // is left uninitialised and an indeterminate shortIdNonce goes out on the
53 // wire -- which is precisely the value this file relies on being
54 // unpredictable to stop short IDs being precomputed or ground against.
55 // Fail closed instead, matching every other RAND_bytes call site in this
56 // tree (bip32.cpp, db.cpp): the caller falls back to full-block relay,
57 // which is always correct.
51 unsigned char nonceBytes[sizeof(uint64)]; 58 unsigned char nonceBytes[sizeof(uint64)];
52 RAND_bytes(nonceBytes, sizeof(nonceBytes)); 59 if (RAND_bytes(nonceBytes, sizeof(nonceBytes)) != 1)
60 return false;
53 memcpy(&out.shortIdNonce, nonceBytes, sizeof(uint64)); 61 memcpy(&out.shortIdNonce, nonceBytes, sizeof(uint64));
54 62
55 out.vPrefilledIndex.clear(); 63 out.vPrefilledIndex.clear();
@@ -75,6 +83,18 @@ bool TryReconstructBlock(const CCmpctBlock& cmpct, CBlock& outBlock, std::vector
75 if (cmpct.vPrefilledIndex.size() != cmpct.vPrefilledTx.size() || nTotal == 0) 83 if (cmpct.vPrefilledIndex.size() != cmpct.vPrefilledTx.size() || nTotal == 0)
76 return false; // malformed 84 return false; // malformed
77 85
86 // nTotal comes straight off the wire once this is wired into the P2P
87 // layer, and serialize.h only bounds a vector length by MAX_SIZE
88 // (0x02000000), so an unbounded assign() below would let one 60-odd-byte
89 // message ask this node for ~33M default-constructed CTransactions. The
90 // smallest a transaction can serialise to is 10 bytes (nVersion, empty
91 // vin, empty vout, nLockTime), so no block within MAX_BLOCK_SIZE can hold
92 // more than MAX_BLOCK_SIZE/10 of them; anything above that is not a block
93 // we could ever accept. Rejecting here just falls back to full-block
94 // relay, which is always correct.
95 if (nTotal > MAX_BLOCK_SIZE / 10)
96 return false; // implausible tx count -- refuse to size a vector from it
97
78 outBlock.SetNull(); 98 outBlock.SetNull();
79 outBlock.nVersion = cmpct.nVersion; 99 outBlock.nVersion = cmpct.nVersion;
80 outBlock.hashPrevBlock = cmpct.hashPrevBlock; 100 outBlock.hashPrevBlock = cmpct.hashPrevBlock;