diff options
Diffstat (limited to 'src/rpc.cpp')
| -rw-r--r-- | src/rpc.cpp | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/src/rpc.cpp b/src/rpc.cpp index 1d53fb2..3827cd5 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp | |||
| @@ -303,16 +303,29 @@ static bool RebuildJob() | |||
| 303 | map<uint256, CTxIndex> pool; | 303 | map<uint256, CTxIndex> pool; |
| 304 | vector<char> vfAlreadyAdded(mapTransactions.size()); | 304 | vector<char> vfAlreadyAdded(mapTransactions.size()); |
| 305 | bool fFoundSomething = true; | 305 | bool fFoundSomething = true; |
| 306 | unsigned int sz = 0; | 306 | // The cap is MAX_BLOCK_SIZE_GEN, not MAX_SIZE/2. MAX_SIZE is |
| 307 | // The cap is MAX_BLOCK_SIZE/2, not MAX_SIZE/2. MAX_SIZE is the | 307 | // the 32 MB serialisation ceiling, so half of it is 16 MB -- |
| 308 | // 32 MB serialisation ceiling, so half of it is 16 MB -- this | 308 | // this builder would happily assemble a template that its own |
| 309 | // builder would happily assemble a template that its own | ||
| 310 | // CheckBlock() rejects at the 1 MB consensus cap. This is the | 309 | // CheckBlock() rejects at the 1 MB consensus cap. This is the |
| 311 | // pool's job builder, so a block over the cap is not one | 310 | // pool's job builder, so a block over the cap is not one |
| 312 | // wasted solve, it is every miner on the pool working a | 311 | // wasted solve, it is every miner on the pool working a |
| 313 | // template the network will reject. The inner break bounds the | 312 | // template the network will reject. |
| 314 | // overshoot to a single transaction within a pass. | 313 | // |
| 315 | while (fFoundSomething && sz < MAX_BLOCK_SIZE / 2) | 314 | // The inner break used to bound the overshoot to one |
| 315 | // transaction per pass. One transaction is still too many: | ||
| 316 | // nothing caps how big a single transaction may be, so that | ||
| 317 | // bound was worth up to MAX_SIZE. Asking whether each one fits | ||
| 318 | // before appending it bounds the overshoot at zero instead. | ||
| 319 | // | ||
| 320 | // Seeded with the header, tx count and coinbase, because | ||
| 321 | // CheckBlock() weighs the whole serialized block. | ||
| 322 | unsigned int sz = ::GetSerializeSize(block, SER_DISK); | ||
| 323 | // And the sigop budget, which CheckBlock() enforces and this | ||
| 324 | // builder never counted against. Same counting function | ||
| 325 | // CheckBlock() sums, seeded from the coinbase because it sums | ||
| 326 | // over all of vtx. | ||
| 327 | unsigned int nSigOps = block.vtx[0].GetSigOpCount(); | ||
| 328 | while (fFoundSomething && sz < MAX_BLOCK_SIZE_GEN) | ||
| 316 | { | 329 | { |
| 317 | fFoundSomething = false; | 330 | fFoundSomething = false; |
| 318 | unsigned int n = 0; | 331 | unsigned int n = 0; |
| @@ -323,16 +336,26 @@ static bool RebuildJob() | |||
| 323 | continue; | 336 | continue; |
| 324 | CTransaction& tx = (*mi).second; | 337 | CTransaction& tx = (*mi).second; |
| 325 | if (tx.IsCoinBase() || !tx.IsFinal()) continue; | 338 | if (tx.IsCoinBase() || !tx.IsFinal()) continue; |
| 339 | // Skip rather than stop: one transaction too big for | ||
| 340 | // the room left does not mean the next is. Ordered | ||
| 341 | // before ConnectInputs because ConnectInputs credits | ||
| 342 | // nFees by reference on success, and a transaction we | ||
| 343 | // then decline would leave the coinbase claiming a fee | ||
| 344 | // this block does not collect. | ||
| 345 | unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK); | ||
| 346 | unsigned int nTxSigOps = tx.GetSigOpCount(); | ||
| 347 | if (!BlockTemplateFits(sz, nSigOps, nTxSize, nTxSigOps)) | ||
| 348 | continue; | ||
| 326 | map<uint256, CTxIndex> tmp(pool); | 349 | map<uint256, CTxIndex> tmp(pool); |
| 327 | if (!tx.ConnectInputs(txdb, tmp, CDiskTxPos(1,1,1), 0, nFees, | 350 | if (!tx.ConnectInputs(txdb, tmp, CDiskTxPos(1,1,1), 0, nFees, |
| 328 | false, true, tx.GetMinFee(block.vtx.size() < 100))) | 351 | false, true, tx.GetMinFee(block.vtx.size() < 100))) |
| 329 | continue; | 352 | continue; |
| 330 | swap(pool, tmp); | 353 | swap(pool, tmp); |
| 331 | block.vtx.push_back(tx); | 354 | block.vtx.push_back(tx); |
| 332 | sz += ::GetSerializeSize(tx, SER_NETWORK); | 355 | sz += nTxSize; |
| 356 | nSigOps += nTxSigOps; | ||
| 333 | vfAlreadyAdded[n] = true; | 357 | vfAlreadyAdded[n] = true; |
| 334 | fFoundSomething = true; | 358 | fFoundSomething = true; |
| 335 | if (sz > MAX_BLOCK_SIZE / 2) break; | ||
| 336 | } | 359 | } |
| 337 | } | 360 | } |
| 338 | } | 361 | } |