From: Scott Nadal Date: Sun, 15 Apr 2012 05:11:55 +0000 (+0100) Subject: PPCoin: a preliminary version of coinstake creation X-Git-Tag: v0.4.0-unstable~193 X-Git-Url: https://git.novaco.in/?p=novacoin.git;a=commitdiff_plain;h=747f99fb5d37ef7faa66dd0bd40a56faca41094a PPCoin: a preliminary version of coinstake creation --- diff --git a/src/main.cpp b/src/main.cpp index fc7ae08..950b893 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2958,6 +2958,8 @@ CBlock* CreateNewBlock(CWallet* pwallet) if (!pblock.get()) return NULL; + pblock->nBits = GetNextWorkRequired(pindexPrev); + // Create coinbase tx CTransaction txNew; txNew.vin.resize(1); @@ -2970,7 +2972,7 @@ CBlock* CreateNewBlock(CWallet* pwallet) // ppcoin: if coinstake available add coinstake tx CTransaction txCoinStake; - if (pwallet->CreateCoinStake(txNew.vout[0].scriptPubKey, txCoinStake)) + if (pwallet->CreateCoinStake(txNew.vout[0].scriptPubKey, pblock->nBits, txCoinStake)) pblock->vtx.push_back(txCoinStake); // Collect memory pool transactions into the block @@ -3092,7 +3094,6 @@ CBlock* CreateNewBlock(CWallet* pwallet) } } } - pblock->nBits = GetNextWorkRequired(pindexPrev); pblock->vtx[0].vout[0].nValue = GetProofOfWorkReward(pblock->nBits); // Fill in header diff --git a/src/wallet.cpp b/src/wallet.cpp index fd8e9c2..58e1baf 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -7,6 +7,7 @@ #include "headers.h" #include "db.h" #include "crypter.h" +#include "checkpoints.h" using namespace std; @@ -1061,8 +1062,11 @@ bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& w } // ppcoin: create coin stake transaction -bool CWallet::CreateCoinStake(CScript scriptPubKey, CTransaction& txNew) +bool CWallet::CreateCoinStake(CScript scriptPubKey, unsigned int nBits, CTransaction& txNew) { + CBigNum bnTargetPerCoinDay; + bnTargetPerCoinDay.SetCompact(nBits); + CRITICAL_BLOCK(cs_main) CRITICAL_BLOCK(cs_wallet) { @@ -1085,19 +1089,33 @@ bool CWallet::CreateCoinStake(CScript scriptPubKey, CTransaction& txNew) int64 nCredit = 0; BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) { - nCredit += pcoin.first->vout[pcoin.second].nValue; - // Only spend one tx for now - break; + CTxDB txdb("r"); + CTxIndex txindex; + if (!txdb.ReadTxIndex(pcoin.first->GetHash(), txindex)) + continue; + + // Read block header + CBlock block; + if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false)) + continue; + if (block.GetBlockTime() + AUTO_CHECKPOINT_TRUST_SPAN > txNew.nTime) + continue; // only count coins from at least one week ago + + int64 nValueIn = pcoin.first->vout[pcoin.second].nValue; + CBigNum bnCoinDay = CBigNum(nValueIn) * (txNew.nTime-pcoin.first->nTime) / COIN / (24 * 60 * 60); + // Calculate hash + CDataStream ss(SER_GETHASH, VERSION); + ss << nBits << block.nTime << pcoin.first->nTime << txNew.nTime; + if (CBigNum(Hash(ss.begin(), ss.end())) <= bnCoinDay * bnTargetPerCoinDay) + { + txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second)); + nCredit += pcoin.first->vout[pcoin.second].nValue; + // Only spend one tx for now + break; + } } if (nCredit > nBalance - nBalanceReserve) return false; - // Fill vin - BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins) - { - txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second)); - // Only spend one tx for now - break; - } // Calculate coin age reward { uint64 nCoinAge; diff --git a/src/wallet.h b/src/wallet.h index 4beebb8..07b2b7c 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -89,7 +89,7 @@ public: int64 GetStake() const; bool CreateTransaction(const std::vector >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet); bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet); - bool CreateCoinStake(CScript scriptPubKey, CTransaction& txNew); + bool CreateCoinStake(CScript scriptPubKey, unsigned int nBits, CTransaction& txNew); bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); bool BroadcastTransaction(CWalletTx& wtxNew); std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);