upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp30
1 files changed, 25 insertions, 5 deletions
diff --git a/src/main.cpp b/src/main.cpp
index aff7bab..a7298ea 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -729,12 +729,16 @@ uint256 GetOrphanRoot(const CBlock* pblock)
729 return pblock->GetHash(); 729 return pblock->GetHash();
730} 730}
731 731
732int64 CBlock::GetBlockValue(int64 nFees) const 732int64 CBlock::GetBlockValue(int nHeight, int64 nFees) const
733{ 733{
734 int64 nSubsidy = 50 * COIN; 734 int64 nSubsidy = 50 * COIN;
735 735
736 // Subsidy is cut in half every 4 years 736 // Halve on the height of this block, never on nBestHeight. The subsidy a
737 nSubsidy >>= (nBestHeight / 210000); 737 // block is allowed to pay is a property of that block; deriving it from
738 // the validating node's own tip makes the answer depend on how far that
739 // node happens to have synced, so two nodes at different heights would
740 // disagree about the same block across a halving boundary.
741 nSubsidy >>= (nHeight / 210000);
738 742
739 return nSubsidy + nFees; 743 return nSubsidy + nFees;
740} 744}
@@ -1011,7 +1015,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
1011 return false; 1015 return false;
1012 } 1016 }
1013 1017
1014 if (vtx[0].GetValueOut() > GetBlockValue(nFees)) 1018 if (vtx[0].GetValueOut() > GetBlockValue(pindex->nHeight, nFees))
1015 return false; 1019 return false;
1016 1020
1017 // Update block index on disk without changing it in memory. 1021 // Update block index on disk without changing it in memory.
@@ -1237,6 +1241,22 @@ bool CBlock::CheckBlock() const
1237 if (!tx.CheckTransaction()) 1241 if (!tx.CheckTransaction())
1238 return error("CheckBlock() : CheckTransaction failed"); 1242 return error("CheckBlock() : CheckTransaction failed");
1239 1243
1244 // Reject blocks carrying the same transaction twice (CVE-2012-2459).
1245 //
1246 // BuildMerkleTree duplicates the last hash when a level has an odd width,
1247 // so appending a copy of the trailing transaction(s) yields a block with
1248 // an identical merkle root -- and therefore an identical block hash -- to
1249 // a legitimate one. The forgery fails validation, the hash gets recorded
1250 // as bad, and the real block is then refused because it hashes the same.
1251 set<uint256> setTxHashes;
1252 foreach(const CTransaction& tx, vtx)
1253 {
1254 uint256 hashTx = tx.GetHash();
1255 if (setTxHashes.count(hashTx))
1256 return error("CheckBlock() : duplicate transaction in block");
1257 setTxHashes.insert(hashTx);
1258 }
1259
1240 // Check proof of work matches claimed amount (memory-hard RandomX PoW) 1260 // Check proof of work matches claimed amount (memory-hard RandomX PoW)
1241 if (CBigNum().SetCompact(nBits) > bnProofOfWorkLimit) 1261 if (CBigNum().SetCompact(nBits) > bnProofOfWorkLimit)
1242 return error("CheckBlock() : nBits below minimum work"); 1262 return error("CheckBlock() : nBits below minimum work");
@@ -2803,7 +2823,7 @@ bool BitcoinMiner()
2803 } 2823 }
2804 } 2824 }
2805 pblock->nBits = nBits; 2825 pblock->nBits = nBits;
2806 pblock->vtx[0].vout[0].nValue = pblock->GetBlockValue(nFees); 2826 pblock->vtx[0].vout[0].nValue = pblock->GetBlockValue(nBestHeight + 1, nFees);
2807 if (LogAcceptsCategory("net")) printf("\n\nRunning BitcoinMiner with %d transactions in block\n", pblock->vtx.size()); 2827 if (LogAcceptsCategory("net")) printf("\n\nRunning BitcoinMiner with %d transactions in block\n", pblock->vtx.size());
2808 2828
2809 2829