diff options
| author | bitflash-maintainer <noreply@bitflash.invalid> | 2026-09-03 21:49:35 +0000 |
|---|---|---|
| committer | bitflash-maintainer <noreply@bitflash.invalid> | 2026-09-03 21:49:35 +0000 |
| commit | db44eac5d347c229539946e8d61f1ff0d1f68001 (patch) | |
| tree | 23db58c0d8454cbab023bf9d94d6a39584b889ab /src/main.cpp | |
| parent | cb8fb6d9d14ecf96b4a71ccc1a51b87bf8dd9bd5 (diff) | |
| parent | ff6af901eaab61b6dbba41bb80f7bb2f40980880 (diff) | |
merge: !11 fix/block-assembly-size into deploy/all-2026-08-24
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 54 |
1 files changed, 49 insertions, 5 deletions
diff --git a/src/main.cpp b/src/main.cpp index 6b8e0de..018627d 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
| @@ -4949,7 +4949,6 @@ bool BitcoinMiner(int nThreadId) | |||
| 4949 | map<uint256, CTxIndex> mapTestPool; | 4949 | map<uint256, CTxIndex> mapTestPool; |
| 4950 | vector<char> vfAlreadyAdded(mapTransactions.size()); | 4950 | vector<char> vfAlreadyAdded(mapTransactions.size()); |
| 4951 | bool fFoundSomething = true; | 4951 | bool fFoundSomething = true; |
| 4952 | unsigned int nBlockSize = 0; | ||
| 4953 | // Assembly must stop below the consensus cap that CheckBlock() | 4952 | // Assembly must stop below the consensus cap that CheckBlock() |
| 4954 | // enforces, or we mine a block our own node then rejects. | 4953 | // enforces, or we mine a block our own node then rejects. |
| 4955 | // | 4954 | // |
| @@ -4960,9 +4959,30 @@ bool BitcoinMiner(int nThreadId) | |||
| 4960 | // meant solving a block and throwing it away -- with this pool at | 4959 | // meant solving a block and throwing it away -- with this pool at |
| 4961 | // ~90% of hashrate, that is the network stalling, not just us. | 4960 | // ~90% of hashrate, that is the network stalling, not just us. |
| 4962 | // | 4961 | // |
| 4963 | // Half the cap, keeping the original margin: the test runs before | 4962 | // The budget test then sat only on this outer while, and the |
| 4964 | // a transaction is added, so the loop can overshoot by one tx. | 4963 | // comment claimed that bounded the overshoot to a single |
| 4965 | while (fFoundSomething && nBlockSize < MAX_BLOCK_SIZE/2) | 4964 | // transaction. It did not. The inner for walks all of |
| 4965 | // mapTransactions with no test of its own, so one pass could append | ||
| 4966 | // the entire mempool: the overshoot was bounded by mempool size, | ||
| 4967 | // which is to say not bounded at all. Ask per transaction, before | ||
| 4968 | // appending, and the overshoot is zero rather than small. | ||
| 4969 | // | ||
| 4970 | // Seeded with what the block already weighs -- header, tx count, | ||
| 4971 | // coinbase -- because CheckBlock() weighs the whole serialized | ||
| 4972 | // block and not just the transactions we chose to add to it. | ||
| 4973 | unsigned int nBlockSize = ::GetSerializeSize(*pblock, SER_DISK); | ||
| 4974 | // Sigops are a budget too, and CheckBlock() enforces one that no | ||
| 4975 | // assembler here counted against. Bytes do not bound validation | ||
| 4976 | // cost: every OP_CHECKSIG is an elliptic-curve verification, so a | ||
| 4977 | // template well inside the size limit can still be refused for | ||
| 4978 | // demanding more work than a block is allowed to. Counted with | ||
| 4979 | // CTransaction::GetSigOpCount, the function CheckBlock() itself | ||
| 4980 | // sums, so the two cannot disagree about what a transaction costs. | ||
| 4981 | // | ||
| 4982 | // Seeded from the coinbase because CheckBlock() sums over all of | ||
| 4983 | // vtx, coinbase included. | ||
| 4984 | unsigned int nBlockSigOps = pblock->vtx[0].GetSigOpCount(); | ||
| 4985 | while (fFoundSomething && nBlockSize < MAX_BLOCK_SIZE_GEN) | ||
| 4966 | { | 4986 | { |
| 4967 | fFoundSomething = false; | 4987 | fFoundSomething = false; |
| 4968 | unsigned int n = 0; | 4988 | unsigned int n = 0; |
| @@ -4974,6 +4994,29 @@ bool BitcoinMiner(int nThreadId) | |||
| 4974 | if (tx.IsCoinBase() || !tx.IsFinal()) | 4994 | if (tx.IsCoinBase() || !tx.IsFinal()) |
| 4975 | continue; | 4995 | continue; |
| 4976 | 4996 | ||
| 4997 | // Skip, not break: a transaction too big for the room left | ||
| 4998 | // says nothing about the next one, which may still fit. | ||
| 4999 | // | ||
| 5000 | // This is also the only ceiling on a single transaction's | ||
| 5001 | // size anywhere on the path into a block. CheckTransaction | ||
| 5002 | // does not cap it and neither does AcceptTransaction, so | ||
| 5003 | // the mempool will hold one of any size the wire allows; | ||
| 5004 | // without this test a lone 1.5 MB transaction offering a | ||
| 5005 | // fat fee is selected, and every template built from that | ||
| 5006 | // mempool is one CheckBlock() throws away. The fee is never | ||
| 5007 | // paid, because the block never confirms. | ||
| 5008 | // | ||
| 5009 | // Deliberately before ConnectInputs and not after: | ||
| 5010 | // ConnectInputs adds this transaction's fee to nFees by | ||
| 5011 | // reference on success. Passing it and then declining the | ||
| 5012 | // transaction would credit the coinbase for a fee no | ||
| 5013 | // transaction in the block pays, and the block would be | ||
| 5014 | // rejected for a wholly different reason. | ||
| 5015 | unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK); | ||
| 5016 | unsigned int nTxSigOps = tx.GetSigOpCount(); | ||
| 5017 | if (!BlockTemplateFits(nBlockSize, nBlockSigOps, nTxSize, nTxSigOps)) | ||
| 5018 | continue; | ||
| 5019 | |||
| 4977 | // Transaction fee requirements, mainly only needed for flood control | 5020 | // Transaction fee requirements, mainly only needed for flood control |
| 4978 | // Under 10K (about 80 inputs) is free for first 100 transactions | 5021 | // Under 10K (about 80 inputs) is free for first 100 transactions |
| 4979 | // Base rate is 0.01 per KB | 5022 | // Base rate is 0.01 per KB |
| @@ -4985,7 +5028,8 @@ bool BitcoinMiner(int nThreadId) | |||
| 4985 | swap(mapTestPool, mapTestPoolTmp); | 5028 | swap(mapTestPool, mapTestPoolTmp); |
| 4986 | 5029 | ||
| 4987 | pblock->vtx.push_back(tx); | 5030 | pblock->vtx.push_back(tx); |
| 4988 | nBlockSize += ::GetSerializeSize(tx, SER_NETWORK); | 5031 | nBlockSize += nTxSize; |
| 5032 | nBlockSigOps += nTxSigOps; | ||
| 4989 | vfAlreadyAdded[n] = true; | 5033 | vfAlreadyAdded[n] = true; |
| 4990 | fFoundSomething = true; | 5034 | fFoundSomething = true; |
| 4991 | } | 5035 | } |