X-Git-Url: https://git.novaco.in/?p=novacoin.git;a=blobdiff_plain;f=src%2Fmain.cpp;h=090dd4be1f1eef8e8dc6ffa26cfa9c46f540784a;hp=e14b73ebc694ae4e3680341faae1d021c61b81c8;hb=8d43f1482a14263a76c039c227c4383580dcc1db;hpb=78ed73a4539806af22ed9f6e6be988b95751f985 diff --git a/src/main.cpp b/src/main.cpp index e14b73e..090dd4b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -996,7 +996,7 @@ CBigNum inline GetProofOfStakeLimit(int nHeight, unsigned int nTime) } // miner's coin base reward based on nBits -int64 GetProofOfWorkReward(unsigned int nBits) +int64 GetProofOfWorkReward(unsigned int nBits, int64 nFees) { CBigNum bnSubsidyLimit = MAX_MINT_PROOF_OF_WORK; @@ -1031,7 +1031,7 @@ int64 GetProofOfWorkReward(unsigned int nBits) if (fDebug && GetBoolArg("-printcreation")) printf("GetProofOfWorkReward() : create=%s nBits=0x%08x nSubsidy=%"PRI64d"\n", FormatMoney(nSubsidy).c_str(), nBits, nSubsidy); - return min(nSubsidy, MAX_MINT_PROOF_OF_WORK); + return min(nSubsidy, MAX_MINT_PROOF_OF_WORK) + nFees; } // miner's coin stake reward based on nBits and coin age spent (coin-days) @@ -1638,6 +1638,8 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) if (!CheckBlock(!fJustCheck, !fJustCheck, false)) return false; + bool fProtocol048 = fTestNet || VALIDATION_SWITCH_TIME < nTime; + // Do not allow blocks that contain transactions which 'overwrite' older transactions, // unless those are already completely spent. // If such overwrites are allowed, coinbases and transactions depending upon those @@ -1721,15 +1723,26 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) mapQueuedChanges[hashTx] = CTxIndex(posThisTx, tx.vout.size()); } - // ppcoin: track money supply and mint amount info + if (IsProofOfWork()) + { + int64 nBlockReward = GetProofOfWorkReward(nBits, fProtocol048 ? nFees : 0); + + // Check coinbase reward + if (vtx[0].GetValueOut() > nBlockReward) + return error("CheckBlock() : coinbase reward exceeded (actual=%"PRI64d" vs calculated=%"PRI64d")", + vtx[0].GetValueOut(), + nBlockReward); + } + + // track money supply and mint amount info pindex->nMint = nValueOut - nValueIn + nFees; pindex->nMoneySupply = (pindex->pprev? pindex->pprev->nMoneySupply : 0) + nValueOut - nValueIn; if (!txdb.WriteBlockIndex(CDiskBlockIndex(pindex))) return error("Connect() : WriteBlockIndex for pindex failed"); - // ppcoin: fees are not collected by miners as in bitcoin - // ppcoin: fees are destroyed to compensate the entire network - if (fDebug && GetBoolArg("-printcreation")) + // fees are not collected by proof-of-stake miners + // fees are destroyed to compensate the entire network + if (fProtocol048 && fDebug && IsProofOfStake() && GetBoolArg("-printcreation")) printf("ConnectBlock() : destroy=%s nFees=%"PRI64d"\n", FormatMoney(nFees).c_str(), nFees); if (fJustCheck) @@ -2155,6 +2168,8 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, bool fCheckSig) c if (vtx.empty() || vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) return DoS(100, error("CheckBlock() : size limits failed")); + bool fProtocol048 = fTestNet || VALIDATION_SWITCH_TIME < nTime; + // Check proof of work matches claimed amount if (fCheckPOW && IsProofOfWork() && !CheckProofOfWork(GetHash(), nBits)) return DoS(50, error("CheckBlock() : proof of work failed")); @@ -2166,16 +2181,38 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, bool fCheckSig) c // First transaction must be coinbase, the rest must not be if (vtx.empty() || !vtx[0].IsCoinBase()) return DoS(100, error("CheckBlock() : first tx is not coinbase")); + + if (!fProtocol048) + { + // Check coinbase timestamp + if (GetBlockTime() < (int64)vtx[0].nTime) + return DoS(100, error("CheckBlock() : coinbase timestamp violation")); + } + else + { + // Check coinbase timestamp + if (GetBlockTime() < PastDrift((int64)vtx[0].nTime)) + return DoS(50, error("CheckBlock() : coinbase timestamp is too late")); + } + for (unsigned int i = 1; i < vtx.size(); i++) + { if (vtx[i].IsCoinBase()) return DoS(100, error("CheckBlock() : more than one coinbase")); - // Check coinbase timestamp - if (GetBlockTime() > FutureDrift((int64)vtx[0].nTime)) - return DoS(50, error("CheckBlock() : coinbase timestamp is too early")); + // Check transaction timestamp + if (GetBlockTime() < (int64)vtx[i].nTime) + return DoS(50, error("CheckBlock() : block timestamp earlier than transaction timestamp")); + } if (IsProofOfStake()) { + if (fProtocol048) + { + if (nNonce != 0) + return DoS(100, error("CheckBlock() : non-zero nonce in proof-of-stake block")); + } + // Coinbase output should be empty if proof-of-stake block if (vtx[0].vout.size() != 1 || !vtx[0].vout[0].IsEmpty()) return DoS(100, error("CheckBlock() : coinbase output not empty for proof-of-stake block")); @@ -2188,7 +2225,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, bool fCheckSig) c return DoS(100, error("CheckBlock() : more than one coinstake")); // Check coinstake timestamp - if (!CheckCoinStakeTimestamp(GetBlockTime(), (int64)vtx[1].nTime)) + if (GetBlockTime() != (int64)vtx[1].nTime) return DoS(50, error("CheckBlock() : coinstake timestamp violation nTimeBlock=%"PRI64d" nTimeTx=%u", GetBlockTime(), vtx[1].nTime)); // NovaCoin: check proof-of-stake block signature @@ -2197,13 +2234,6 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, bool fCheckSig) c } else { - int64 nReward = GetProofOfWorkReward(nBits); - // Check coinbase reward - if (vtx[0].GetValueOut() > nReward) - return DoS(50, error("CheckBlock() : coinbase reward exceeded (actual=%"PRI64d" vs calculated=%"PRI64d")", - vtx[0].GetValueOut(), - nReward)); - // Should we check proof-of-work block signature or not? // // * Always skip on TestNet @@ -2225,10 +2255,6 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, bool fCheckSig) c { if (!tx.CheckTransaction()) return DoS(tx.nDoS, error("CheckBlock() : CheckTransaction failed")); - - // ppcoin: check transaction timestamp - if (GetBlockTime() < (int64)tx.nTime) - return DoS(50, error("CheckBlock() : block timestamp earlier than transaction timestamp")); } // Check for duplicate txids. This is caught by ConnectInputs(),