upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp10
-rw-r--r--src/main.h15
-rw-r--r--src/script.h23
3 files changed, 48 insertions, 0 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 17e446e..a75bf54 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1261,6 +1261,16 @@ bool CBlock::CheckBlock() const
1261 if (!tx.CheckTransaction()) 1261 if (!tx.CheckTransaction())
1262 return error("CheckBlock() : CheckTransaction failed"); 1262 return error("CheckBlock() : CheckTransaction failed");
1263 1263
1264 // Cap the work a block can demand. MAX_SIZE bounds the bytes, not the cost:
1265 // every signature operation is an elliptic-curve verification, and at this
1266 // chain's difficulty a block packed with them is affordable to mine and
1267 // expensive for everyone else to reject.
1268 unsigned int nSigOps = 0;
1269 foreach(const CTransaction& tx, vtx)
1270 nSigOps += tx.GetSigOpCount();
1271 if (nSigOps > MAX_BLOCK_SIGOPS)
1272 return error("CheckBlock() : out-of-bounds signature operation count");
1273
1264 // Reject blocks carrying the same transaction twice (CVE-2012-2459). 1274 // Reject blocks carrying the same transaction twice (CVE-2012-2459).
1265 // 1275 //
1266 // BuildMerkleTree duplicates the last hash when a level has an odd width, 1276 // BuildMerkleTree duplicates the last hash when a level has an odd width,
diff --git a/src/main.h b/src/main.h
index 40f8d45..fde3a4e 100644
--- a/src/main.h
+++ b/src/main.h
@@ -18,6 +18,11 @@ static const unsigned int MAX_SIZE = 0x02000000;
18// Ceiling on transactions held waiting for a parent that has not arrived. 18// Ceiling on transactions held waiting for a parent that has not arrived.
19// They cost a peer nothing to send and are never validated, only stored. 19// They cost a peer nothing to send and are never validated, only stored.
20static const unsigned int MAX_ORPHAN_TRANSACTIONS = 100; 20static const unsigned int MAX_ORPHAN_TRANSACTIONS = 100;
21// Signature operations allowed in one block. Size alone does not bound what a
22// block costs to validate: every OP_CHECKSIG is an elliptic-curve verification,
23// so a block within the size limit could still hold millions of them and take
24// the network minutes of CPU to reject. Same value Bitcoin settled on.
25static const unsigned int MAX_BLOCK_SIGOPS = 20000;
21static const int64 COIN = 100000000; 26static const int64 COIN = 100000000;
22// Total Bitflash emission: identical to Bitcoin (21 million). 27// Total Bitflash emission: identical to Bitcoin (21 million).
23// MAX_MONEY guards against the value overflow bug (CVE-2010-5139), which in 28// MAX_MONEY guards against the value overflow bug (CVE-2010-5139), which in
@@ -503,6 +508,16 @@ public:
503 return (vin.size() == 1 && vin[0].prevout.IsNull()); 508 return (vin.size() == 1 && vin[0].prevout.IsNull());
504 } 509 }
505 510
511 unsigned int GetSigOpCount() const
512 {
513 unsigned int n = 0;
514 foreach(const CTxIn& txin, vin)
515 n += txin.scriptSig.GetSigOpCount();
516 foreach(const CTxOut& txout, vout)
517 n += txout.scriptPubKey.GetSigOpCount();
518 return n;
519 }
520
506 bool CheckTransaction() const 521 bool CheckTransaction() const
507 { 522 {
508 // Basic checks that don't depend on any context 523 // Basic checks that don't depend on any context
diff --git a/src/script.h b/src/script.h
index 27c1b13..26bb65a 100644
--- a/src/script.h
+++ b/src/script.h
@@ -536,6 +536,29 @@ public:
536 } 536 }
537 537
538 538
539 // Signature operations in this script. Each one costs every validating
540 // node an elliptic-curve verification, so blocks are capped on this count
541 // and not only on their size -- a byte of OP_CHECKSIG is far more
542 // expensive to check than a byte of anything else.
543 unsigned int GetSigOpCount() const
544 {
545 unsigned int n = 0;
546 const_iterator pc = begin();
547 opcodetype opcode;
548 vector<unsigned char> vchPushValue;
549 while (pc < end())
550 {
551 if (!GetOp(pc, opcode, vchPushValue))
552 break;
553 if (opcode == OP_CHECKSIG || opcode == OP_CHECKSIGVERIFY)
554 n++;
555 else if (opcode == OP_CHECKMULTISIG || opcode == OP_CHECKMULTISIGVERIFY)
556 n += 20;
557 }
558 return n;
559 }
560
561
539 void FindAndDelete(const CScript& b) 562 void FindAndDelete(const CScript& b)
540 { 563 {
541 iterator pc = begin(); 564 iterator pc = begin();