diff options
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 30 |
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 | ||
| 732 | int64 CBlock::GetBlockValue(int64 nFees) const | 732 | int64 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 | ||