key pool for safer wallet backup
git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@163 1a98c847-1fd6-4fd8-948a-caf3550aa51b
This commit is contained in:
61
main.cpp
61
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<CWalletTx*>& 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<unsigned char> 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();
|
||||
|
||||
Reference in New Issue
Block a user