From 103849419a9c014a69c76b6f96e48b66cbc838ca Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sat, 9 Oct 2010 19:33:35 +0000 Subject: key pool for safer wallet backup git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@163 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- main.cpp | 61 +++++++++++++++++++++++++++---------------------------------- 1 file changed, 27 insertions(+), 34 deletions(-) (limited to 'main.cpp') diff --git a/main.cpp b/main.cpp index c03172ef12..7b04a1f634 100644 --- a/main.cpp +++ b/main.cpp @@ -158,7 +158,8 @@ bool AddToWallet(const CWalletTx& wtxIn) if (txout.scriptPubKey == scriptDefaultKey) { CWalletDB walletdb; - walletdb.WriteDefaultKey(GenerateNewKey()); + vchDefaultKey = walletdb.GetKeyFromKeyPool(); + walletdb.WriteDefaultKey(vchDefaultKey); walletdb.WriteName(PubKeyToAddress(vchDefaultKey), ""); } } @@ -1493,15 +1494,6 @@ bool CBlock::AcceptBlock() (nHeight == 74000 && hash != uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))) return error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight); - // Scanback checkpoint lockin - for (CBlockIndex* pindex = pindexPrev; pindex->nHeight >= 74000; pindex = pindex->pprev) - { - if (pindex->nHeight == 74000 && pindex->GetBlockHash() != uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")) - return error("AcceptBlock() : rejected by scanback lockin at %d", pindex->nHeight); - if (pindex->nHeight == 74638 && pindex->GetBlockHash() == uint256("0x0000000000790ab3f22ec756ad43b6ab569abf0bddeb97c67a6f7b1470a7ec1c")) - return error("AcceptBlock() : rejected by scanback lockin at %d", pindex->nHeight); - } - // Write block to history file if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK))) return error("AcceptBlock() : out of disk space"); @@ -1961,7 +1953,7 @@ bool AlreadyHave(CTxDB& txdb, const CInv& inv) { switch (inv.type) { - case MSG_TX: return mapTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash); + case MSG_TX: return mapTransactions.count(inv.hash) || mapOrphanTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash); case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash); } // Don't know what it is, just say we already got one @@ -2472,7 +2464,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // Keep giving the same key to the same ip until they use it if (!mapReuseKey.count(pfrom->addr.ip)) - mapReuseKey[pfrom->addr.ip] = GenerateNewKey(); + mapReuseKey[pfrom->addr.ip] = CWalletDB().GetKeyFromKeyPool(); // Send back approval of order and pubkey to use CScript scriptPubKey; @@ -2933,8 +2925,7 @@ void BitcoinMiner() if (mapArgs.count("-4way")) f4WaySSE2 = (mapArgs["-4way"] != "0"); - CKey key; - key.MakeNewKey(); + CReserveKey reservekey; CBigNum bnExtraNonce = 0; while (fGenerateBitcoins) { @@ -2961,9 +2952,9 @@ void BitcoinMiner() CTransaction txNew; txNew.vin.resize(1); txNew.vin[0].prevout.SetNull(); - txNew.vin[0].scriptSig << nBits << ++bnExtraNonce; + txNew.vin[0].scriptSig << ++bnExtraNonce; txNew.vout.resize(1); - txNew.vout[0].scriptPubKey << key.GetPubKey() << OP_CHECKSIG; + txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG; // @@ -3113,10 +3104,8 @@ void BitcoinMiner() { if (pindexPrev == pindexBest) { - // Save key - if (!AddKey(key)) - return; - key.MakeNewKey(); + // Remove key from key pool + reservekey.KeepKey(); // Track how many getdata requests this block gets CRITICAL_BLOCK(cs_mapRequestCount) @@ -3183,7 +3172,10 @@ void BitcoinMiner() break; // Update nTime every few seconds - pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); + int64 nNewTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); + if (nNewTime != pblock->nTime && bnExtraNonce > 10) + bnExtraNonce = 0; + pblock->nTime = nNewTime; tmp.block.nTime = ByteReverse(pblock->nTime); } } @@ -3342,7 +3334,7 @@ bool SelectCoins(int64 nTargetValue, set& setCoinsRet) -bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet) +bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRequiredRet) { nFeeRequiredRet = 0; CRITICAL_BLOCK(cs_main) @@ -3386,18 +3378,20 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK // rediscover unknown transactions that were written with keys of ours to recover // post-backup change. - // New private key - if (keyRet.IsNull()) - keyRet.MakeNewKey(); + // Reserve a new key pair from key pool + vector vchPubKey = reservekey.GetReservedKey(); + assert(mapKeys.count(vchPubKey)); // Fill a vout to ourself, using same address type as the payment CScript scriptChange; if (scriptPubKey.GetBitcoinAddressHash160() != 0) - scriptChange.SetBitcoinAddress(keyRet.GetPubKey()); + scriptChange.SetBitcoinAddress(vchPubKey); else - scriptChange << keyRet.GetPubKey() << OP_CHECKSIG; + scriptChange << vchPubKey << OP_CHECKSIG; wtxNew.vout.push_back(CTxOut(nChange, scriptChange)); } + else + reservekey.ReturnKey(); // Fill a vout to the payee if (fChangeFirst) @@ -3440,7 +3434,7 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK } // Call after CreateTransaction unless you want to abort -bool CommitTransaction(CWalletTx& wtxNew, const CKey& key) +bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) { CRITICAL_BLOCK(cs_main) { @@ -3452,9 +3446,8 @@ bool CommitTransaction(CWalletTx& wtxNew, const CKey& key) // maybe makes sense; please don't do it anywhere else. CWalletDB walletdb("r"); - // Add the change's private key to wallet - if (!key.IsNull() && !AddKey(key)) - throw runtime_error("CommitTransaction() : AddKey failed"); + // Take key pair from key pool so it won't be used again + reservekey.KeepKey(); // Add tx to wallet, because if it has change it's also ours, // otherwise just for transaction history. @@ -3496,9 +3489,9 @@ string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAs { CRITICAL_BLOCK(cs_main) { - CKey key; + CReserveKey reservekey; int64 nFeeRequired; - if (!CreateTransaction(scriptPubKey, nValue, wtxNew, key, nFeeRequired)) + if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired)) { string strError; if (nValue + nFeeRequired > GetBalance()) @@ -3512,7 +3505,7 @@ string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAs if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."), NULL)) return "ABORTED"; - if (!CommitTransaction(wtxNew, key)) + if (!CommitTransaction(wtxNew, reservekey)) return _("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); } MainFrameRepaint(); -- cgit v1.2.3