From 747f99fb5d37ef7faa66dd0bd40a56faca41094a Mon Sep 17 00:00:00 2001 From: Scott Nadal Date: Sun, 15 Apr 2012 06:11:55 +0100 Subject: [PATCH] PPCoin: a preliminary version of coinstake creation --- src/main.cpp | 5 +++-- src/wallet.cpp | 40 +++++++++++++++++++++++++++++----------- src/wallet.h | 2 +- 3 files changed, 33 insertions(+), 14 deletions(-) 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); -- 1.7.1