upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/main.h
diff options
context:
space:
mode:
authorbitflash-maintainer <noreply@bitflash.invalid>2026-09-02 14:16:48 +0000
committerbitflash-maintainer <noreply@bitflash.invalid>2026-09-02 14:16:48 +0000
commit2ed8fae6088c99f1a5dfcfd760c1a24c2b2706db (patch)
treef23023e737fc73cdb384e4840c033cfc5ac08e10 /src/main.h
parent74c068829967bbff60da3506613844df4da1ae80 (diff)
mine: count sigops while selecting, not only when validating
CheckBlock() caps a block at MAX_BLOCK_SIGOPS and neither assembler counted against it. Bytes do not bound what a block costs to verify: every OP_CHECKSIG is an elliptic-curve verification, so a template comfortably inside the size budget can still be one the network refuses for demanding more work than a block is allowed to. Counted with CTransaction::GetSigOpCount -- the same function CheckBlock() sums, not a second implementation of it -- and seeded from the coinbase, because CheckBlock() sums over all of vtx. The comparison matches too: CheckBlock() fails on `> MAX_BLOCK_SIGOPS`, so a block exactly on the limit is valid and selection accepts it. Assembly and validation differing by one is the shape of the bug this series started with. Unlike the size budget this takes no margin. There is no use for headroom in a sigop count, so assembly holds itself to the consensus number exactly. Assembly only; MAX_BLOCK_SIGOPS and the CheckBlock() test are unchanged.
Diffstat (limited to 'src/main.h')
-rw-r--r--src/main.h15
1 files changed, 12 insertions, 3 deletions
diff --git a/src/main.h b/src/main.h
index 1f452b5..30e25ef 100644
--- a/src/main.h
+++ b/src/main.h
@@ -43,15 +43,24 @@ static const unsigned int MAX_BLOCK_SIZE = 1000000;
43static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE / 2; 43static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE / 2;
44 44
45// Room for one more transaction in a template that currently weighs 45// Room for one more transaction in a template that currently weighs
46// nBlockSize bytes? 46// nBlockSize bytes and spends nBlockSigOps signature operations?
47// 47//
48// Asked BEFORE the transaction is appended, never after. A template that has 48// Asked BEFORE the transaction is appended, never after. A template that has
49// already overshot is one CheckBlock() rejects, and asking afterwards only 49// already overshot is one CheckBlock() rejects, and asking afterwards only
50// measures the waste. Both assemblers call this, so neither can drift into a 50// measures the waste. Both assemblers call this, so neither can drift into a
51// different idea of what fits. 51// different idea of what fits.
52inline bool BlockTemplateFits(unsigned int nBlockSize, unsigned int nTxSize) 52//
53// Size gets a margin (half the cap); sigops do not. There is no cheap way to
54// spend the sigop budget usefully and no reason to reserve headroom in it, so
55// assembly holds itself to the same number CheckBlock() enforces -- and to the
56// same comparison. CheckBlock() fails on `> MAX_BLOCK_SIGOPS`, so a block
57// sitting exactly on the limit is valid and this has to accept it too.
58// Assembly and validation disagreeing by one is how the size bug started.
59inline bool BlockTemplateFits(unsigned int nBlockSize, unsigned int nBlockSigOps,
60 unsigned int nTxSize, unsigned int nTxSigOps)
53{ 61{
54 return (nBlockSize + nTxSize <= MAX_BLOCK_SIZE_GEN); 62 return (nBlockSize + nTxSize <= MAX_BLOCK_SIZE_GEN &&
63 nBlockSigOps + nTxSigOps <= MAX_BLOCK_SIGOPS);
55} 64}
56static const int64 COIN = 100000000; 65static const int64 COIN = 100000000;
57// Total Bitflash emission: identical to Bitcoin (21 million). 66// Total Bitflash emission: identical to Bitcoin (21 million).