X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fmain.cpp;h=c830a8ffadafe694ea104edc00180c5473a4b355;hb=2c8f88fc67af7916670ce0086e6a9078df8182f0;hp=68190ad82c701793a802307947557ecac20caf79;hpb=f6123ec5244fa565ebeba660de94a47b28ef0105;p=novacoin.git diff --git a/src/main.cpp b/src/main.cpp index 68190ad..c830a8f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -77,7 +77,8 @@ const string strMessageMagic = "NovaCoin Signed Message:\n"; // Settings int64 nTransactionFee = MIN_TX_FEE; -bool fStakeUsePooledKeys = false; +int64 nMinimumInputValue = MIN_TX_FEE; + extern enum Checkpoints::CPMode CheckpointsMode; ////////////////////////////////////////////////////////////////////////////// @@ -475,8 +476,8 @@ bool CTransaction::CheckTransaction() const if (txout.IsEmpty() && !IsCoinBase() && !IsCoinStake()) return DoS(100, error("CTransaction::CheckTransaction() : txout empty for user transaction")); - // NovaCoin: enforce minimum output amount for user transactions - if (!IsCoinBase() && !txout.IsEmpty() && txout.nValue < MIN_TXOUT_AMOUNT) + // NovaCoin: enforce minimum output amount for user transactions until 1 May 2014 04:00:00 GMT + if (!fTestNet && !IsCoinBase() && !txout.IsEmpty() && nTime < OUTPUT_SWITCH_TIME && txout.nValue < MIN_TXOUT_AMOUNT) return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue below minimum")); if (txout.nValue > MAX_MONEY) @@ -511,12 +512,11 @@ bool CTransaction::CheckTransaction() const } int64 CTransaction::GetMinFee(unsigned int nBlockSize, bool fAllowFree, - enum GetMinFee_mode mode) const + enum GetMinFee_mode mode, unsigned int nBytes) const { // Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE int64 nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_TX_FEE; - unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION); unsigned int nNewBlockSize = nBlockSize + nBytes; int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee; @@ -632,7 +632,7 @@ bool CTxMemPool::accept(CTxDB& txdb, CTransaction &tx, bool fCheckInputs, unsigned int nSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); // Don't accept it if it can't get into a block - int64 txMinFee = tx.GetMinFee(1000, false, GMF_RELAY); + int64 txMinFee = tx.GetMinFee(1000, false, GMF_RELAY, nSize); if (nFees < txMinFee) return error("CTxMemPool::accept() : not enough fees %s, %"PRI64d" < %"PRI64d, hash.ToString().c_str(), @@ -1399,9 +1399,8 @@ unsigned int CTransaction::GetP2SHSigOpCount(const MapPrevTx& inputs) const return nSigOps; } -bool CTransaction::ConnectInputs(CTxDB& txdb, MapPrevTx inputs, - map& mapTestPool, const CDiskTxPos& posThisTx, - const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, bool fStrictPayToScriptHash) +bool CTransaction::ConnectInputs(CTxDB& txdb, MapPrevTx inputs, map& mapTestPool, const CDiskTxPos& posThisTx, + const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, bool fStrictPayToScriptHash) { // Take over previous transactions' spent pointers // fBlock is true when this is called from AcceptBlock when a new best-block is added to the blockchain @@ -1502,8 +1501,9 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, MapPrevTx inputs, int64 nTxFee = nValueIn - GetValueOut(); if (nTxFee < 0) return DoS(100, error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,10).c_str())); - // ppcoin: enforce transaction fees for every block - if (nTxFee < GetMinFee()) + + // enforce transaction fees for every block until 1 May 2014 04:00:00 GMT + if (!fTestNet && nTxFee < GetMinFee() && nTime < OUTPUT_SWITCH_TIME) return fBlock? DoS(100, error("ConnectInputs() : %s not paying required fee=%s, paid=%s", GetHash().ToString().substr(0,10).c_str(), FormatMoney(GetMinFee()).c_str(), FormatMoney(nTxFee).c_str())) : false; nFees += nTxFee; @@ -2117,7 +2117,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, bool fCheckSig) c return DoS(50, error("CheckBlock() : proof of work failed")); // Check timestamp - if (GetBlockTime() > GetAdjustedTime() + nMaxClockDrift) + if (GetBlockTime() > FutureDrift(GetAdjustedTime())) return error("CheckBlock() : block timestamp too far in the future"); // First transaction must be coinbase, the rest must not be @@ -2128,7 +2128,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, bool fCheckSig) c return DoS(100, error("CheckBlock() : more than one coinbase")); // Check coinbase timestamp - if (GetBlockTime() > (int64)vtx[0].nTime + nMaxClockDrift) + if (GetBlockTime() > FutureDrift((int64)vtx[0].nTime)) return DoS(50, error("CheckBlock() : coinbase timestamp is too early")); if (IsProofOfStake()) @@ -2233,7 +2233,7 @@ bool CBlock::AcceptBlock() return DoS(100, error("AcceptBlock() : incorrect %s", IsProofOfWork() ? "proof-of-work" : "proof-of-stake")); // Check timestamp against prev - if (GetBlockTime() <= pindexPrev->GetMedianTimePast() || GetBlockTime() + nMaxClockDrift < pindexPrev->GetBlockTime()) + if (GetBlockTime() <= pindexPrev->GetMedianTimePast() || FutureDrift(GetBlockTime()) < pindexPrev->GetBlockTime()) return error("AcceptBlock() : block's timestamp is too early"); // Check that all transactions are finalized @@ -2503,61 +2503,53 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) return true; } -// ppcoin: sign block -bool CBlock::SignBlock(const CKeyStore& keystore) +// novacoin: attempt to generate suitable proof-of-stake +bool CBlock::SignBlock(CWallet& wallet) { - vector vSolutions; - txnouttype whichType; - - if(!IsProofOfStake()) - { - for(unsigned int i = 0; i < vtx[0].vout.size(); i++) - { - const CTxOut& txout = vtx[0].vout[i]; + // if we are trying to sign + // something except proof-of-stake block template + if (!vtx[0].vout[0].IsEmpty()) + return false; - if (!Solver(txout.scriptPubKey, whichType, vSolutions)) - continue; + // if we are trying to sign + // a complete proof-of-stake block + if (IsProofOfStake()) + return true; - if (whichType == TX_PUBKEY) - { - // Sign - valtype& vchPubKey = vSolutions[0]; - CKey key; + static int64 nLastCoinStakeSearchTime = GetAdjustedTime(); // startup timestamp - if (!keystore.GetKey(Hash160(vchPubKey), key)) - continue; - if (key.GetPubKey() != vchPubKey) - continue; - if(!key.Sign(GetHash(), vchBlockSig)) - continue; + CKey key; + CTransaction txCoinStake; + int64 nSearchTime = txCoinStake.nTime; // search to current time - return true; - } - } - } - else + if (nSearchTime > nLastCoinStakeSearchTime) { - const CTxOut& txout = vtx[1].vout[1]; - - if (!Solver(txout.scriptPubKey, whichType, vSolutions)) - return false; - - if (whichType == TX_PUBKEY) + if (wallet.CreateCoinStake(wallet, nBits, nSearchTime-nLastCoinStakeSearchTime, txCoinStake, key)) { - // Sign - valtype& vchPubKey = vSolutions[0]; - CKey key; - - if (!keystore.GetKey(Hash160(vchPubKey), key)) - return false; - if (key.GetPubKey() != vchPubKey) - return false; - - return key.Sign(GetHash(), vchBlockSig); + if (txCoinStake.nTime >= max(pindexBest->GetMedianTimePast()+1, PastDrift(pindexBest->GetBlockTime()))) + { + // make sure coinstake would meet timestamp protocol + // as it would be the same as the block timestamp + vtx[0].nTime = nTime = txCoinStake.nTime; + nTime = max(pindexBest->GetMedianTimePast()+1, GetMaxTransactionTime()); + nTime = max(GetBlockTime(), PastDrift(pindexBest->GetBlockTime())); + + // we have to make sure that we have no future timestamps in + // our transactions set + for (vector::iterator it = vtx.begin(); it != vtx.end();) + if (it->nTime > nTime) { it = vtx.erase(it); } else { ++it; } + + vtx.insert(vtx.begin() + 1, txCoinStake); + hashMerkleRoot = BuildMerkleTree(); + + // append a signature to our block + return key.Sign(GetHash(), vchBlockSig); + } } + nLastCoinStakeSearchInterval = nSearchTime - nLastCoinStakeSearchTime; + nLastCoinStakeSearchTime = nSearchTime; } - printf("Sign failed\n"); return false; }