aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2011-09-02 17:35:30 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2011-09-02 17:35:30 +0200
commit7a15d4ff67c9a6e3b6b5a63f82f76ffe1937c3b8 (patch)
tree8ac8a0e7b9994ade96f635dd261c5ae46703f7df /src
parentf43f46c175d7e6d7426536f8efcad05d2eafba80 (diff)
parent86fd7c5af6cf3f907c50cf25ff844cd23e271c70 (diff)
Merge branch 'master' of https://github.com/bitcoin/bitcoin
Conflicts: src/main.cpp
Diffstat (limited to 'src')
-rw-r--r--src/bitcoinrpc.cpp642
-rw-r--r--src/db.cpp3
-rw-r--r--src/keystore.cpp21
-rw-r--r--src/keystore.h54
-rw-r--r--src/main.cpp24
-rw-r--r--src/main.h14
-rw-r--r--src/makefile.linux-mingw60
-rw-r--r--src/makefile.mingw67
-rw-r--r--src/makefile.osx39
-rw-r--r--src/makefile.unix39
-rw-r--r--src/makefile.vc50
-rw-r--r--src/net.cpp128
-rw-r--r--src/net.h405
-rw-r--r--src/protocol.cpp312
-rw-r--r--src/protocol.h150
-rw-r--r--src/script.cpp102
-rw-r--r--src/serialize.h11
-rw-r--r--src/ui.cpp381
-rw-r--r--src/util.cpp8
-rw-r--r--src/util.h8
-rw-r--r--src/wallet.cpp239
-rw-r--r--src/wallet.h17
22 files changed, 1433 insertions, 1341 deletions
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp
index d49f898828..5348e9a3fc 100644
--- a/src/bitcoinrpc.cpp
+++ b/src/bitcoinrpc.cpp
@@ -331,71 +331,59 @@ Value getnewaddress(const Array& params, bool fHelp)
"If [account] is specified (recommended), it is added to the address book "
"so payments received with the address will be credited to [account].");
- if (!pwalletMain->IsLocked())
- pwalletMain->TopUpKeyPool();
-
- if (pwalletMain->GetKeyPoolSize() < 1)
- throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
-
// Parse the account first so we don't generate a key if there's an error
string strAccount;
if (params.size() > 0)
strAccount = AccountFromValue(params[0]);
+ if (!pwalletMain->IsLocked())
+ pwalletMain->TopUpKeyPool();
+
// Generate a new key that is added to wallet
- CBitcoinAddress address(pwalletMain->GetOrReuseKeyFromPool());
+ std::vector<unsigned char> newKey;
+ if (!pwalletMain->GetKeyFromPool(newKey, false))
+ throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
+ CBitcoinAddress address(newKey);
- // This could be done in the same main CS as GetKeyFromKeyPool.
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
- pwalletMain->SetAddressBookName(address, strAccount);
+ pwalletMain->SetAddressBookName(address, strAccount);
return address.ToString();
}
-// requires cs_main, cs_mapWallet, cs_mapAddressBook locks
CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
{
CWalletDB walletdb(pwalletMain->strWalletFile);
CAccount account;
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
- {
- walletdb.ReadAccount(strAccount, account);
+ walletdb.ReadAccount(strAccount, account);
- bool bKeyUsed = false;
+ bool bKeyUsed = false;
- // Check if the current key has been used
- if (!account.vchPubKey.empty())
+ // Check if the current key has been used
+ if (!account.vchPubKey.empty())
+ {
+ CScript scriptPubKey;
+ scriptPubKey.SetBitcoinAddress(account.vchPubKey);
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
+ it != pwalletMain->mapWallet.end() && !account.vchPubKey.empty();
+ ++it)
{
- CScript scriptPubKey;
- scriptPubKey.SetBitcoinAddress(account.vchPubKey);
- for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
- it != pwalletMain->mapWallet.end() && !account.vchPubKey.empty();
- ++it)
- {
- const CWalletTx& wtx = (*it).second;
- BOOST_FOREACH(const CTxOut& txout, wtx.vout)
- if (txout.scriptPubKey == scriptPubKey)
- bKeyUsed = true;
- }
+ const CWalletTx& wtx = (*it).second;
+ BOOST_FOREACH(const CTxOut& txout, wtx.vout)
+ if (txout.scriptPubKey == scriptPubKey)
+ bKeyUsed = true;
}
+ }
- // Generate a new key
- if (account.vchPubKey.empty() || bForceNew || bKeyUsed)
- {
- if (pwalletMain->GetKeyPoolSize() < 1)
- {
- if (bKeyUsed || bForceNew)
- throw JSONRPCError(-12, "Error: Keypool ran out, please call topupkeypool first");
- }
- else
- {
- account.vchPubKey = pwalletMain->GetOrReuseKeyFromPool();
- pwalletMain->SetAddressBookName(CBitcoinAddress(account.vchPubKey), strAccount);
- walletdb.WriteAccount(strAccount, account);
- }
- }
+ // Generate a new key
+ if (account.vchPubKey.empty() || bForceNew || bKeyUsed)
+ {
+ if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false))
+ throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
+
+ pwalletMain->SetAddressBookName(CBitcoinAddress(account.vchPubKey), strAccount);
+ walletdb.WriteAccount(strAccount, account);
}
return CBitcoinAddress(account.vchPubKey);
@@ -413,12 +401,7 @@ Value getaccountaddress(const Array& params, bool fHelp)
Value ret;
- CRITICAL_BLOCK(cs_main)
- CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
- {
- ret = GetAccountAddress(strAccount).ToString();
- }
+ ret = GetAccountAddress(strAccount).ToString();
return ret;
}
@@ -442,20 +425,15 @@ Value setaccount(const Array& params, bool fHelp)
strAccount = AccountFromValue(params[1]);
// Detect when changing the account of an address that is the 'unused current key' of another account:
- CRITICAL_BLOCK(cs_main)
- CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+ if (pwalletMain->mapAddressBook.count(address))
{
- if (pwalletMain->mapAddressBook.count(address))
- {
- string strOldAccount = pwalletMain->mapAddressBook[address];
- if (address == GetAccountAddress(strOldAccount))
- GetAccountAddress(strOldAccount, true);
- }
-
- pwalletMain->SetAddressBookName(address, strAccount);
+ string strOldAccount = pwalletMain->mapAddressBook[address];
+ if (address == GetAccountAddress(strOldAccount))
+ GetAccountAddress(strOldAccount, true);
}
+ pwalletMain->SetAddressBookName(address, strAccount);
+
return Value::null;
}
@@ -472,12 +450,9 @@ Value getaccount(const Array& params, bool fHelp)
throw JSONRPCError(-5, "Invalid bitcoin address");
string strAccount;
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
- {
- map<CBitcoinAddress, string>::iterator mi = pwalletMain->mapAddressBook.find(address);
- if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty())
- strAccount = (*mi).second;
- }
+ map<CBitcoinAddress, string>::iterator mi = pwalletMain->mapAddressBook.find(address);
+ if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty())
+ strAccount = (*mi).second;
return strAccount;
}
@@ -493,15 +468,12 @@ Value getaddressesbyaccount(const Array& params, bool fHelp)
// Find all addresses that have the given account
Array ret;
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+ BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
{
- BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
- {
- const CBitcoinAddress& address = item.first;
- const string& strName = item.second;
- if (strName == strAccount)
- ret.push_back(address.ToString());
- }
+ const CBitcoinAddress& address = item.first;
+ const string& strName = item.second;
+ if (strName == strAccount)
+ ret.push_back(address.ToString());
}
return ret;
}
@@ -548,16 +520,12 @@ Value sendtoaddress(const Array& params, bool fHelp)
if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty())
wtx.mapValue["to"] = params[3].get_str();
- CRITICAL_BLOCK(cs_main)
- CRITICAL_BLOCK(pwalletMain->cs_vMasterKey)
- {
- if(pwalletMain->IsLocked())
- throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
+ if (pwalletMain->IsLocked())
+ throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
- string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx);
- if (strError != "")
- throw JSONRPCError(-4, strError);
- }
+ string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx);
+ if (strError != "")
+ throw JSONRPCError(-4, strError);
return wtx.GetHash().GetHex();
}
@@ -586,19 +554,16 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
// Tally
int64 nAmount = 0;
- CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
{
- for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
- {
- const CWalletTx& wtx = (*it).second;
- if (wtx.IsCoinBase() || !wtx.IsFinal())
- continue;
+ const CWalletTx& wtx = (*it).second;
+ if (wtx.IsCoinBase() || !wtx.IsFinal())
+ continue;
- BOOST_FOREACH(const CTxOut& txout, wtx.vout)
- if (txout.scriptPubKey == scriptPubKey)
- if (wtx.GetDepthInMainChain() >= nMinDepth)
- nAmount += txout.nValue;
- }
+ BOOST_FOREACH(const CTxOut& txout, wtx.vout)
+ if (txout.scriptPubKey == scriptPubKey)
+ if (wtx.GetDepthInMainChain() >= nMinDepth)
+ nAmount += txout.nValue;
}
return ValueFromAmount(nAmount);
@@ -607,15 +572,12 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
void GetAccountAddresses(string strAccount, set<CBitcoinAddress>& setAddress)
{
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+ BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
{
- BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
- {
- const CBitcoinAddress& address = item.first;
- const string& strName = item.second;
- if (strName == strAccount)
- setAddress.insert(address);
- }
+ const CBitcoinAddress& address = item.first;
+ const string& strName = item.second;
+ if (strName == strAccount)
+ setAddress.insert(address);
}
}
@@ -639,21 +601,18 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
// Tally
int64 nAmount = 0;
- CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
{
- for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
- {
- const CWalletTx& wtx = (*it).second;
- if (wtx.IsCoinBase() || !wtx.IsFinal())
- continue;
+ const CWalletTx& wtx = (*it).second;
+ if (wtx.IsCoinBase() || !wtx.IsFinal())
+ continue;
- BOOST_FOREACH(const CTxOut& txout, wtx.vout)
- {
- CBitcoinAddress address;
- if (ExtractAddress(txout.scriptPubKey, pwalletMain, address) && setAddress.count(address))
- if (wtx.GetDepthInMainChain() >= nMinDepth)
- nAmount += txout.nValue;
- }
+ BOOST_FOREACH(const CTxOut& txout, wtx.vout)
+ {
+ CBitcoinAddress address;
+ if (ExtractAddress(txout.scriptPubKey, pwalletMain, address) && setAddress.count(address))
+ if (wtx.GetDepthInMainChain() >= nMinDepth)
+ nAmount += txout.nValue;
}
}
@@ -664,27 +623,25 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth)
{
int64 nBalance = 0;
- CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
- {
- // Tally wallet transactions
- for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
- {
- const CWalletTx& wtx = (*it).second;
- if (!wtx.IsFinal())
- continue;
- int64 nGenerated, nReceived, nSent, nFee;
- wtx.GetAccountAmounts(strAccount, nGenerated, nReceived, nSent, nFee);
+ // Tally wallet transactions
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
+ {
+ const CWalletTx& wtx = (*it).second;
+ if (!wtx.IsFinal())
+ continue;
- if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth)
- nBalance += nReceived;
- nBalance += nGenerated - nSent - nFee;
- }
+ int64 nGenerated, nReceived, nSent, nFee;
+ wtx.GetAccountAmounts(strAccount, nGenerated, nReceived, nSent, nFee);
- // Tally internal accounting entries
- nBalance += walletdb.GetAccountCreditDebit(strAccount);
+ if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth)
+ nBalance += nReceived;
+ nBalance += nGenerated - nSent - nFee;
}
+ // Tally internal accounting entries
+ nBalance += walletdb.GetAccountCreditDebit(strAccount);
+
return nBalance;
}
@@ -763,33 +720,31 @@ Value movecmd(const Array& params, bool fHelp)
if (params.size() > 4)
strComment = params[4].get_str();
- CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
- {
- CWalletDB walletdb(pwalletMain->strWalletFile);
- walletdb.TxnBegin();
-
- int64 nNow = GetAdjustedTime();
-
- // Debit
- CAccountingEntry debit;
- debit.strAccount = strFrom;
- debit.nCreditDebit = -nAmount;
- debit.nTime = nNow;
- debit.strOtherAccount = strTo;
- debit.strComment = strComment;
- walletdb.WriteAccountingEntry(debit);
-
- // Credit
- CAccountingEntry credit;
- credit.strAccount = strTo;
- credit.nCreditDebit = nAmount;
- credit.nTime = nNow;
- credit.strOtherAccount = strFrom;
- credit.strComment = strComment;
- walletdb.WriteAccountingEntry(credit);
-
- walletdb.TxnCommit();
- }
+ CWalletDB walletdb(pwalletMain->strWalletFile);
+ walletdb.TxnBegin();
+
+ int64 nNow = GetAdjustedTime();
+
+ // Debit
+ CAccountingEntry debit;
+ debit.strAccount = strFrom;
+ debit.nCreditDebit = -nAmount;
+ debit.nTime = nNow;
+ debit.strOtherAccount = strTo;
+ debit.strComment = strComment;
+ walletdb.WriteAccountingEntry(debit);
+
+ // Credit
+ CAccountingEntry credit;
+ credit.strAccount = strTo;
+ credit.nCreditDebit = nAmount;
+ credit.nTime = nNow;
+ credit.strOtherAccount = strFrom;
+ credit.strComment = strComment;
+ walletdb.WriteAccountingEntry(credit);
+
+ walletdb.TxnCommit();
+
return true;
}
@@ -822,23 +777,18 @@ Value sendfrom(const Array& params, bool fHelp)
if (params.size() > 5 && params[5].type() != null_type && !params[5].get_str().empty())
wtx.mapValue["to"] = params[5].get_str();
- CRITICAL_BLOCK(cs_main)
- CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
- CRITICAL_BLOCK(pwalletMain->cs_vMasterKey)
- {
- if(pwalletMain->IsLocked())
- throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
+ if (pwalletMain->IsLocked())
+ throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
- // Check funds
- int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
- if (nAmount > nBalance)
- throw JSONRPCError(-6, "Account has insufficient funds");
+ // Check funds
+ int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
+ if (nAmount > nBalance)
+ throw JSONRPCError(-6, "Account has insufficient funds");
- // Send
- string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx);
- if (strError != "")
- throw JSONRPCError(-4, strError);
- }
+ // Send
+ string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx);
+ if (strError != "")
+ throw JSONRPCError(-4, strError);
return wtx.GetHash().GetHex();
}
@@ -889,31 +839,26 @@ Value sendmany(const Array& params, bool fHelp)
vecSend.push_back(make_pair(scriptPubKey, nAmount));
}
- CRITICAL_BLOCK(cs_main)
- CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
- CRITICAL_BLOCK(pwalletMain->cs_vMasterKey)
- {
- if(pwalletMain->IsLocked())
- throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
-
- // Check funds
- int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
- if (totalAmount > nBalance)
- throw JSONRPCError(-6, "Account has insufficient funds");
+ if (pwalletMain->IsLocked())
+ throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
- // Send
- CReserveKey keyChange(pwalletMain);
- int64 nFeeRequired = 0;
- bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired);
- if (!fCreated)
- {
- if (totalAmount + nFeeRequired > pwalletMain->GetBalance())
- throw JSONRPCError(-6, "Insufficient funds");
- throw JSONRPCError(-4, "Transaction creation failed");
- }
- if (!pwalletMain->CommitTransaction(wtx, keyChange))
- throw JSONRPCError(-4, "Transaction commit failed");
+ // Check funds
+ int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
+ if (totalAmount > nBalance)
+ throw JSONRPCError(-6, "Account has insufficient funds");
+
+ // Send
+ CReserveKey keyChange(pwalletMain);
+ int64 nFeeRequired = 0;
+ bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired);
+ if (!fCreated)
+ {
+ if (totalAmount + nFeeRequired > pwalletMain->GetBalance())
+ throw JSONRPCError(-6, "Insufficient funds");
+ throw JSONRPCError(-4, "Transaction creation failed");
}
+ if (!pwalletMain->CommitTransaction(wtx, keyChange))
+ throw JSONRPCError(-4, "Transaction commit failed");
return wtx.GetHash().GetHex();
}
@@ -944,68 +889,62 @@ Value ListReceived(const Array& params, bool fByAccounts)
// Tally
map<CBitcoinAddress, tallyitem> mapTally;
- CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
{
- for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
- {
- const CWalletTx& wtx = (*it).second;
- if (wtx.IsCoinBase() || !wtx.IsFinal())
- continue;
+ const CWalletTx& wtx = (*it).second;
+ if (wtx.IsCoinBase() || !wtx.IsFinal())
+ continue;
- int nDepth = wtx.GetDepthInMainChain();
- if (nDepth < nMinDepth)
- continue;
+ int nDepth = wtx.GetDepthInMainChain();
+ if (nDepth < nMinDepth)
+ continue;
- BOOST_FOREACH(const CTxOut& txout, wtx.vout)
- {
- CBitcoinAddress address;
- if (!ExtractAddress(txout.scriptPubKey, pwalletMain, address) || !address.IsValid())
- continue;
+ BOOST_FOREACH(const CTxOut& txout, wtx.vout)
+ {
+ CBitcoinAddress address;
+ if (!ExtractAddress(txout.scriptPubKey, pwalletMain, address) || !address.IsValid())
+ continue;
- tallyitem& item = mapTally[address];
- item.nAmount += txout.nValue;
- item.nConf = min(item.nConf, nDepth);
- }
+ tallyitem& item = mapTally[address];
+ item.nAmount += txout.nValue;
+ item.nConf = min(item.nConf, nDepth);
}
}
// Reply
Array ret;
map<string, tallyitem> mapAccountTally;
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+ BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
{
- BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
- {
- const CBitcoinAddress& address = item.first;
- const string& strAccount = item.second;
- map<CBitcoinAddress, tallyitem>::iterator it = mapTally.find(address);
- if (it == mapTally.end() && !fIncludeEmpty)
- continue;
+ const CBitcoinAddress& address = item.first;
+ const string& strAccount = item.second;
+ map<CBitcoinAddress, tallyitem>::iterator it = mapTally.find(address);
+ if (it == mapTally.end() && !fIncludeEmpty)
+ continue;
- int64 nAmount = 0;
- int nConf = INT_MAX;
- if (it != mapTally.end())
- {
- nAmount = (*it).second.nAmount;
- nConf = (*it).second.nConf;
- }
+ int64 nAmount = 0;
+ int nConf = INT_MAX;
+ if (it != mapTally.end())
+ {
+ nAmount = (*it).second.nAmount;
+ nConf = (*it).second.nConf;
+ }
- if (fByAccounts)
- {
- tallyitem& item = mapAccountTally[strAccount];
- item.nAmount += nAmount;
- item.nConf = min(item.nConf, nConf);
- }
- else
- {
- Object obj;
- obj.push_back(Pair("address", address.ToString()));
- obj.push_back(Pair("account", strAccount));
- obj.push_back(Pair("label", strAccount)); // deprecated
- obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
- obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf)));
- ret.push_back(obj);
- }
+ if (fByAccounts)
+ {
+ tallyitem& item = mapAccountTally[strAccount];
+ item.nAmount += nAmount;
+ item.nConf = min(item.nConf, nConf);
+ }
+ else
+ {
+ Object obj;
+ obj.push_back(Pair("address", address.ToString()));
+ obj.push_back(Pair("account", strAccount));
+ obj.push_back(Pair("label", strAccount)); // deprecated
+ obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
+ obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf)));
+ ret.push_back(obj);
}
}
@@ -1107,27 +1046,23 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
// Received
if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+ BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived)
{
- BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived)
+ string account;
+ if (pwalletMain->mapAddressBook.count(r.first))
+ account = pwalletMain->mapAddressBook[r.first];
+ if (fAllAccounts || (account == strAccount))
{
- string account;
- if (pwalletMain->mapAddressBook.count(r.first))
- account = pwalletMain->mapAddressBook[r.first];
- if (fAllAccounts || (account == strAccount))
- {
- Object entry;
- entry.push_back(Pair("account", account));
- entry.push_back(Pair("address", r.first.ToString()));
- entry.push_back(Pair("category", "receive"));
- entry.push_back(Pair("amount", ValueFromAmount(r.second)));
- if (fLong)
- WalletTxToJSON(wtx, entry);
- ret.push_back(entry);
- }
+ Object entry;
+ entry.push_back(Pair("account", account));
+ entry.push_back(Pair("address", r.first.ToString()));
+ entry.push_back(Pair("category", "receive"));
+ entry.push_back(Pair("amount", ValueFromAmount(r.second)));
+ if (fLong)
+ WalletTxToJSON(wtx, entry);
+ ret.push_back(entry);
}
}
-
}
void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Array& ret)
@@ -1167,41 +1102,38 @@ Value listtransactions(const Array& params, bool fHelp)
Array ret;
CWalletDB walletdb(pwalletMain->strWalletFile);
- CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
- {
- // Firs: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap:
- typedef pair<CWalletTx*, CAccountingEntry*> TxPair;
- typedef multimap<int64, TxPair > TxItems;
- TxItems txByTime;
+ // Firs: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap:
+ typedef pair<CWalletTx*, CAccountingEntry*> TxPair;
+ typedef multimap<int64, TxPair > TxItems;
+ TxItems txByTime;
- for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
- {
- CWalletTx* wtx = &((*it).second);
- txByTime.insert(make_pair(wtx->GetTxTime(), TxPair(wtx, (CAccountingEntry*)0)));
- }
- list<CAccountingEntry> acentries;
- walletdb.ListAccountCreditDebit(strAccount, acentries);
- BOOST_FOREACH(CAccountingEntry& entry, acentries)
- {
- txByTime.insert(make_pair(entry.nTime, TxPair((CWalletTx*)0, &entry)));
- }
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
+ {
+ CWalletTx* wtx = &((*it).second);
+ txByTime.insert(make_pair(wtx->GetTxTime(), TxPair(wtx, (CAccountingEntry*)0)));
+ }
+ list<CAccountingEntry> acentries;
+ walletdb.ListAccountCreditDebit(strAccount, acentries);
+ BOOST_FOREACH(CAccountingEntry& entry, acentries)
+ {
+ txByTime.insert(make_pair(entry.nTime, TxPair((CWalletTx*)0, &entry)));
+ }
- // Now: iterate backwards until we have nCount items to return:
- TxItems::reverse_iterator it = txByTime.rbegin();
- if (txByTime.size() > nFrom) std::advance(it, nFrom);
- for (; it != txByTime.rend(); ++it)
- {
- CWalletTx *const pwtx = (*it).second.first;
- if (pwtx != 0)
- ListTransactions(*pwtx, strAccount, 0, true, ret);
- CAccountingEntry *const pacentry = (*it).second.second;
- if (pacentry != 0)
- AcentryToJSON(*pacentry, strAccount, ret);
-
- if (ret.size() >= nCount) break;
- }
- // ret is now newest to oldest
+ // Now: iterate backwards until we have nCount items to return:
+ TxItems::reverse_iterator it = txByTime.rbegin();
+ if (txByTime.size() > nFrom) std::advance(it, nFrom);
+ for (; it != txByTime.rend(); ++it)
+ {
+ CWalletTx *const pwtx = (*it).second.first;
+ if (pwtx != 0)
+ ListTransactions(*pwtx, strAccount, 0, true, ret);
+ CAccountingEntry *const pacentry = (*it).second.second;
+ if (pacentry != 0)
+ AcentryToJSON(*pacentry, strAccount, ret);
+
+ if (ret.size() >= nCount) break;
}
+ // ret is now newest to oldest
// Make sure we return only last nCount items (sends-to-self might give us an extra):
if (ret.size() > nCount)
@@ -1227,34 +1159,30 @@ Value listaccounts(const Array& params, bool fHelp)
nMinDepth = params[0].get_int();
map<string, int64> mapAccountBalances;
- CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
- {
- BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& entry, pwalletMain->mapAddressBook) {
- if (pwalletMain->HaveKey(entry.first)) // This address belongs to me
- mapAccountBalances[entry.second] = 0;
- }
+ BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& entry, pwalletMain->mapAddressBook) {
+ if (pwalletMain->HaveKey(entry.first)) // This address belongs to me
+ mapAccountBalances[entry.second] = 0;
+ }
- for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
+ {
+ const CWalletTx& wtx = (*it).second;
+ int64 nGeneratedImmature, nGeneratedMature, nFee;
+ string strSentAccount;
+ list<pair<CBitcoinAddress, int64> > listReceived;
+ list<pair<CBitcoinAddress, int64> > listSent;
+ wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
+ mapAccountBalances[strSentAccount] -= nFee;
+ BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent)
+ mapAccountBalances[strSentAccount] -= s.second;
+ if (wtx.GetDepthInMainChain() >= nMinDepth)
{
- const CWalletTx& wtx = (*it).second;
- int64 nGeneratedImmature, nGeneratedMature, nFee;
- string strSentAccount;
- list<pair<CBitcoinAddress, int64> > listReceived;
- list<pair<CBitcoinAddress, int64> > listSent;
- wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
- mapAccountBalances[strSentAccount] -= nFee;
- BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent)
- mapAccountBalances[strSentAccount] -= s.second;
- if (wtx.GetDepthInMainChain() >= nMinDepth)
- {
- mapAccountBalances[""] += nGeneratedMature;
- BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived)
- if (pwalletMain->mapAddressBook.count(r.first))
- mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second;
- else
- mapAccountBalances[""] += r.second;
- }
+ mapAccountBalances[""] += nGeneratedMature;
+ BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived)
+ if (pwalletMain->mapAddressBook.count(r.first))
+ mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second;
+ else
+ mapAccountBalances[""] += r.second;
}
}
@@ -1281,27 +1209,25 @@ Value gettransaction(const Array& params, bool fHelp)
hash.SetHex(params[0].get_str());
Object entry;
- CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
- {
- if (!pwalletMain->mapWallet.count(hash))
- throw JSONRPCError(-5, "Invalid or non-wallet transaction id");
- const CWalletTx& wtx = pwalletMain->mapWallet[hash];
- int64 nCredit = wtx.GetCredit();
- int64 nDebit = wtx.GetDebit();
- int64 nNet = nCredit - nDebit;
- int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0);
+ if (!pwalletMain->mapWallet.count(hash))
+ throw JSONRPCError(-5, "Invalid or non-wallet transaction id");
+ const CWalletTx& wtx = pwalletMain->mapWallet[hash];
- entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
- if (wtx.IsFromMe())
- entry.push_back(Pair("fee", ValueFromAmount(nFee)));
+ int64 nCredit = wtx.GetCredit();
+ int64 nDebit = wtx.GetDebit();
+ int64 nNet = nCredit - nDebit;
+ int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0);
- WalletTxToJSON(pwalletMain->mapWallet[hash], entry);
+ entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
+ if (wtx.IsFromMe())
+ entry.push_back(Pair("fee", ValueFromAmount(nFee)));
- Array details;
- ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details);
- entry.push_back(Pair("details", details));
- }
+ WalletTxToJSON(pwalletMain->mapWallet[hash], entry);
+
+ Array details;
+ ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details);
+ entry.push_back(Pair("details", details));
return entry;
}
@@ -1332,13 +1258,10 @@ Value keypoolrefill(const Array& params, bool fHelp)
"keypoolrefill\n"
"Fills the keypool.");
- CRITICAL_BLOCK(pwalletMain->cs_vMasterKey)
- {
- if (pwalletMain->IsLocked())
- throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
+ if (pwalletMain->IsLocked())
+ throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
- pwalletMain->TopUpKeyPool();
- }
+ pwalletMain->TopUpKeyPool();
if (pwalletMain->GetKeyPoolSize() < GetArg("-keypool", 100))
throw JSONRPCError(-4, "Error refreshing keypool.");
@@ -1407,24 +1330,21 @@ Value walletpassphrase(const Array& params, bool fHelp)
mlock(&strWalletPass[0], strWalletPass.capacity());
strWalletPass = params[0].get_str();
- CRITICAL_BLOCK(pwalletMain->cs_vMasterKey)
+ if (strWalletPass.length() > 0)
{
- if (strWalletPass.length() > 0)
+ if (!pwalletMain->Unlock(strWalletPass))
{
- if (!pwalletMain->Unlock(strWalletPass))
- {
- fill(strWalletPass.begin(), strWalletPass.end(), '\0');
- munlock(&strWalletPass[0], strWalletPass.capacity());
- throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
- }
fill(strWalletPass.begin(), strWalletPass.end(), '\0');
munlock(&strWalletPass[0], strWalletPass.capacity());
+ throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
}
- else
- throw runtime_error(
- "walletpassphrase <passphrase> <timeout>\n"
- "Stores the wallet decryption key in memory for <timeout> seconds.");
+ fill(strWalletPass.begin(), strWalletPass.end(), '\0');
+ munlock(&strWalletPass[0], strWalletPass.capacity());
}
+ else
+ throw runtime_error(
+ "walletpassphrase <passphrase> <timeout>\n"
+ "Stores the wallet decryption key in memory for <timeout> seconds.");
CreateThread(ThreadTopUpKeyPool, NULL);
int* pnSleepTime = new int(params[1].get_int());
@@ -1553,11 +1473,8 @@ Value validateaddress(const Array& params, bool fHelp)
string currentAddress = address.ToString();
ret.push_back(Pair("address", currentAddress));
ret.push_back(Pair("ismine", (pwalletMain->HaveKey(address) > 0)));
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
- {
- if (pwalletMain->mapAddressBook.count(address))
- ret.push_back(Pair("account", pwalletMain->mapAddressBook[address]));
- }
+ if (pwalletMain->mapAddressBook.count(address))
+ ret.push_back(Pair("account", pwalletMain->mapAddressBook[address]));
}
return ret;
}
@@ -2233,7 +2150,10 @@ void ThreadRPCServer2(void* parg)
try
{
// Execute
- Value result = (*(*mi).second)(params, false);
+ Value result;
+ CRITICAL_BLOCK(cs_main)
+ CRITICAL_BLOCK(pwalletMain->cs_wallet)
+ result = (*(*mi).second)(params, false);
// Send reply
string strReply = JSONRPCReply(result, Value::null, id);
diff --git a/src/db.cpp b/src/db.cpp
index 72542705a6..a22b17e34c 100644
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -683,8 +683,7 @@ int CWalletDB::LoadWallet(CWallet* pwallet)
#endif
//// todo: shouldn't we catch exceptions and try to recover and continue?
- CRITICAL_BLOCK(pwallet->cs_mapWallet)
- CRITICAL_BLOCK(pwallet->cs_KeyStore)
+ CRITICAL_BLOCK(pwallet->cs_wallet)
{
// Get cursor
Dbc* pcursor = GetCursor();
diff --git a/src/keystore.cpp b/src/keystore.cpp
index 4c6848b47a..68f57e7e0e 100644
--- a/src/keystore.cpp
+++ b/src/keystore.cpp
@@ -33,6 +33,19 @@ bool CBasicKeyStore::AddKey(const CKey& key)
return true;
}
+bool CCryptoKeyStore::SetCrypted()
+{
+ CRITICAL_BLOCK(cs_KeyStore)
+ {
+ if (fUseCrypto)
+ return true;
+ if (!mapKeys.empty())
+ return false;
+ fUseCrypto = true;
+ }
+ return true;
+}
+
std::vector<unsigned char> CCryptoKeyStore::GenerateNewKey()
{
RandAddSeedPerfmon();
@@ -45,7 +58,7 @@ std::vector<unsigned char> CCryptoKeyStore::GenerateNewKey()
bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
{
- CRITICAL_BLOCK(cs_vMasterKey)
+ CRITICAL_BLOCK(cs_KeyStore)
{
if (!SetCrypted())
return false;
@@ -72,7 +85,6 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
bool CCryptoKeyStore::AddKey(const CKey& key)
{
CRITICAL_BLOCK(cs_KeyStore)
- CRITICAL_BLOCK(cs_vMasterKey)
{
if (!IsCrypted())
return CBasicKeyStore::AddKey(key);
@@ -106,7 +118,7 @@ bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey,
bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
{
- CRITICAL_BLOCK(cs_vMasterKey)
+ CRITICAL_BLOCK(cs_KeyStore)
{
if (!IsCrypted())
return CBasicKeyStore::GetKey(address, keyOut);
@@ -128,7 +140,7 @@ bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const
{
- CRITICAL_BLOCK(cs_vMasterKey)
+ CRITICAL_BLOCK(cs_KeyStore)
{
if (!IsCrypted())
return CKeyStore::GetPubKey(address, vchPubKeyOut);
@@ -146,7 +158,6 @@ bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsi
bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
{
CRITICAL_BLOCK(cs_KeyStore)
- CRITICAL_BLOCK(cs_vMasterKey)
{
if (!mapCryptedKeys.empty() || IsCrypted())
return false;
diff --git a/src/keystore.h b/src/keystore.h
index 0324cc6e1b..bbfac83d1f 100644
--- a/src/keystore.h
+++ b/src/keystore.h
@@ -9,9 +9,10 @@
class CKeyStore
{
-public:
+protected:
mutable CCriticalSection cs_KeyStore;
+public:
virtual bool AddKey(const CKey& key) =0;
virtual bool HaveKey(const CBitcoinAddress &address) const =0;
virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const =0;
@@ -30,15 +31,21 @@ public:
bool AddKey(const CKey& key);
bool HaveKey(const CBitcoinAddress &address) const
{
- return (mapKeys.count(address) > 0);
+ bool result;
+ CRITICAL_BLOCK(cs_KeyStore)
+ result = (mapKeys.count(address) > 0);
+ return result;
}
bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const
{
- KeyMap::const_iterator mi = mapKeys.find(address);
- if (mi != mapKeys.end())
+ CRITICAL_BLOCK(cs_KeyStore)
{
- keyOut.SetSecret((*mi).second);
- return true;
+ KeyMap::const_iterator mi = mapKeys.find(address);
+ if (mi != mapKeys.end())
+ {
+ keyOut.SetSecret((*mi).second);
+ return true;
+ }
}
return false;
}
@@ -58,15 +65,7 @@ private:
bool fUseCrypto;
protected:
- bool SetCrypted()
- {
- if (fUseCrypto)
- return true;
- if (!mapKeys.empty())
- return false;
- fUseCrypto = true;
- return true;
- }
+ bool SetCrypted();
// will encrypt previously unencrypted keys
bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
@@ -74,8 +73,6 @@ protected:
bool Unlock(const CKeyingMaterial& vMasterKeyIn);
public:
- mutable CCriticalSection cs_vMasterKey; //No guarantees master key wont get locked before you can use it, so lock this first
-
CCryptoKeyStore() : fUseCrypto(false)
{
}
@@ -89,18 +86,20 @@ public:
{
if (!IsCrypted())
return false;
- return vMasterKey.empty();
+ bool result;
+ CRITICAL_BLOCK(cs_KeyStore)
+ result = vMasterKey.empty();
+ return result;
}
bool Lock()
{
- CRITICAL_BLOCK(cs_vMasterKey)
- {
- if (!SetCrypted())
- return false;
+ if (!SetCrypted())
+ return false;
+ CRITICAL_BLOCK(cs_KeyStore)
vMasterKey.clear();
- }
+
return true;
}
@@ -109,9 +108,12 @@ public:
bool AddKey(const CKey& key);
bool HaveKey(const CBitcoinAddress &address) const
{
- if (!IsCrypted())
- return CBasicKeyStore::HaveKey(address);
- return mapCryptedKeys.count(address) > 0;
+ CRITICAL_BLOCK(cs_KeyStore)
+ {
+ if (!IsCrypted())
+ return CBasicKeyStore::HaveKey(address);
+ return mapCryptedKeys.count(address) > 0;
+ }
}
bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const;
bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
diff --git a/src/main.cpp b/src/main.cpp
index 4d668b6ffb..5d29492fcb 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -22,15 +22,15 @@ set<CWallet*> setpwalletRegistered;
CCriticalSection cs_main;
-map<uint256, CTransaction> mapTransactions;
+static map<uint256, CTransaction> mapTransactions;
CCriticalSection cs_mapTransactions;
unsigned int nTransactionsUpdated = 0;
map<COutPoint, CInPoint> mapNextTx;
map<uint256, CBlockIndex*> mapBlockIndex;
uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
-CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
-int nTotalBlocksEstimate = 134444; // Conservative estimate of total nr of blocks on main chain
+static CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
+const int nTotalBlocksEstimate = 140700; // Conservative estimate of total nr of blocks on main chain
const int nInitialBlockThreshold = 120; // Regard blocks up until N-threshold as "initial download"
CBlockIndex* pindexGenesisBlock = NULL;
int nBestHeight = -1;
@@ -295,9 +295,10 @@ int CMerkleTx::SetMerkleBranch(const CBlock* pblock)
bool CTransaction::CheckTransaction() const
{
// Basic checks that don't depend on any context
- if (vin.empty() || vout.empty())
- return error("CTransaction::CheckTransaction() : vin or vout empty");
-
+ if (vin.empty())
+ return error("CTransaction::CheckTransaction() : vin empty");
+ if (vout.empty())
+ return error("CTransaction::CheckTransaction() : vout empty");
// Size limits
if (::GetSerializeSize(*this, SER_NETWORK) > MAX_BLOCK_SIZE)
return error("CTransaction::CheckTransaction() : size limits failed");
@@ -1301,7 +1302,8 @@ bool CBlock::AcceptBlock()
(nHeight == 74000 && hash != uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")) ||
(nHeight == 105000 && hash != uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")) ||
(nHeight == 118000 && hash != uint256("0x000000000000774a7f8a7a12dc906ddb9e17e75d684f15e00f8767f9e8f36553")) ||
- (nHeight == 134444 && hash != uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")))
+ (nHeight == 134444 && hash != uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")) ||
+ (nHeight == 140700 && hash != uint256("0x000000000000033b512028abb90e1626d8b346fd0ed598ac0a3c371138dce2bd")))
return error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight);
// Write block to history file
@@ -1318,7 +1320,7 @@ bool CBlock::AcceptBlock()
if (hashBestChain == hash)
CRITICAL_BLOCK(cs_vNodes)
BOOST_FOREACH(CNode* pnode, vNodes)
- if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 134444))
+ if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 140700))
pnode->PushInventory(CInv(MSG_BLOCK, hash));
return true;
@@ -2185,7 +2187,7 @@ bool static 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] = pwalletMain->GetOrReuseKeyFromPool();
+ pwalletMain->GetKeyFromPool(mapReuseKey[pfrom->addr.ip], true);
// Send back approval of order and pubkey to use
CScript scriptPubKey;
@@ -2627,7 +2629,7 @@ unsigned int static ScanHash_CryptoPP(char* pmidstate, char* pdata, char* phash1
}
}
-
+// Some explaining would be appreciated
class COrphan
{
public:
@@ -2883,7 +2885,7 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
reservekey.KeepKey();
// Track how many getdata requests this block gets
- CRITICAL_BLOCK(wallet.cs_mapRequestCount)
+ CRITICAL_BLOCK(wallet.cs_wallet)
wallet.mapRequestCount[pblock->GetHash()] = 0;
// Process this block the same as if we had received it from another node
diff --git a/src/main.h b/src/main.h
index 97a40d3ec9..427067bc94 100644
--- a/src/main.h
+++ b/src/main.h
@@ -21,7 +21,6 @@ class CKeyItem;
class CReserveKey;
class CWalletDB;
-class CMessageHeader;
class CAddress;
class CInv;
class CRequestTracker;
@@ -54,7 +53,6 @@ static const int fHaveUPnP = false;
extern CCriticalSection cs_main;
extern std::map<uint256, CBlockIndex*> mapBlockIndex;
extern uint256 hashGenesisBlock;
-extern CBigNum bnProofOfWorkLimit;
extern CBlockIndex* pindexGenesisBlock;
extern int nBestHeight;
extern CBigNum bnBestChainWork;
@@ -1558,16 +1556,4 @@ public:
bool ProcessAlert();
};
-
-
-
-
-
-
-
-
-
-
-extern std::map<uint256, CTransaction> mapTransactions;
-
#endif
diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw
index e2ef4213aa..24cc127c2d 100644
--- a/src/makefile.linux-mingw
+++ b/src/makefile.linux-mingw
@@ -7,19 +7,19 @@ DEPSDIR:=/usr/i586-mingw32msvc
USE_UPNP:=0
INCLUDEPATHS= \
- -I"$(DEPSDIR)/boost_1_43_0" \
- -I"$(DEPSDIR)/db-4.7.25.NC/build_unix" \
+ -I"$(DEPSDIR)/boost_1_47_0" \
+ -I"$(DEPSDIR)/db-4.8.30.NC/build_unix" \
-I"$(DEPSDIR)/openssl-1.0.0d/include" \
- -I"$(DEPSDIR)/wxWidgets-2.9.1/lib/gcc_lib/mswud" \
- -I"$(DEPSDIR)/wxWidgets-2.9.1/include" \
- -I"$(DEPSDIR)/wxWidgets-2.9.1/lib/wx/include/i586-mingw32msvc-msw-unicode-static-2.9/" \
+ -I"$(DEPSDIR)/wxWidgets-2.9.2/lib/gcc_lib/mswud" \
+ -I"$(DEPSDIR)/wxWidgets-2.9.2/include" \
+ -I"$(DEPSDIR)/wxWidgets-2.9.2/lib/wx/include/i586-mingw32msvc-msw-unicode-static-2.9/" \
-I"$(DEPSDIR)"
LIBPATHS= \
- -L"$(DEPSDIR)/boost_1_43_0/stage/lib" \
- -L"$(DEPSDIR)/db-4.7.25.NC/build_unix" \
+ -L"$(DEPSDIR)/boost_1_47_0/stage/lib" \
+ -L"$(DEPSDIR)/db-4.8.30.NC/build_unix" \
-L"$(DEPSDIR)/openssl-1.0.0d" \
- -L"$(DEPSDIR)/wxWidgets-2.9.1/lib"
+ -L"$(DEPSDIR)/wxWidgets-2.9.2/lib"
WXLIBS= -l wx_mswu-2.9-i586-mingw32msvc
@@ -32,16 +32,35 @@ LIBS= \
-l ssl \
-l crypto
-DEFS=-D_MT -DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH -DUSE_SSL
+DEFS=-D_MT -DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH -DUSE_SSL -DBOOST_THREAD_USE_LIB
DEBUGFLAGS=-g -D__WXDEBUG__
CFLAGS=-O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
-HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
- script.h db.h net.h irc.h keystore.h main.h wallet.h rpc.h uibase.h ui.h noui.h \
- crypter.h init.h
+HEADERS = \
+ base58.h \
+ bignum.h \
+ crypter.h \
+ db.h \
+ headers.h \
+ init.h \
+ irc.h \
+ key.h \
+ keystore.h \
+ main.h \
+ net.h \
+ noui.h \
+ protocol.h \
+ rpc.h \
+ script.h \
+ serialize.h \
+ strlcpy.h \
+ ui.h \
+ uibase.h \
+ uint256.h \
+ util.h \
+ wallet.h
ifdef USE_UPNP
- INCLUDEPATHS += -I"$(DEPSDIR)/upnpc-exe-win32-20110215"
- LIBPATHS += -L"$(DEPSDIR)/upnpc-exe-win32-20110215"
+ LIBPATHS += -L"$(DEPSDIR)/miniupnpc"
LIBS += -l miniupnpc -l iphlpapi
DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP)
endif
@@ -49,17 +68,18 @@ endif
LIBS += -l mingwthrd -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi
OBJS= \
- obj/util.o \
- obj/script.o \
+ obj/crypter.o \
obj/db.o \
- obj/net.o \
+ obj/init.o \
obj/irc.o \
obj/keystore.o \
obj/main.o \
- obj/wallet.o \
+ obj/net.o \
+ obj/protocol.o \
obj/rpc.o \
- obj/init.o \
- obj/crypter.o \
+ obj/script.o \
+ obj/util.o \
+ obj/wallet.o \
cryptopp/obj/sha.o \
cryptopp/obj/cpu.o
diff --git a/src/makefile.mingw b/src/makefile.mingw
index d630fe235f..1ca1a7bbe2 100644
--- a/src/makefile.mingw
+++ b/src/makefile.mingw
@@ -5,40 +5,60 @@
USE_UPNP:=0
INCLUDEPATHS= \
- -I"C:\boost-1.43.0-mgw" \
- -I"C:\db-4.7.25.NC-mgw\build_unix" \
+ -I"C:\boost-1.47.0-mgw" \
+ -I"C:\db-4.8.30.NC-mgw\build_unix" \
-I"C:\openssl-1.0.0d-mgw\include" \
- -I"C:\wxWidgets-2.9.1-mgw\lib\gcc_lib\mswud" \
- -I"C:\wxWidgets-2.9.1-mgw\include"
+ -I"C:\wxWidgets-2.9.2-mgw\lib\gcc_lib\mswud" \
+ -I"C:\wxWidgets-2.9.2-mgw\include"
LIBPATHS= \
- -L"C:\boost-1.43.0-mgw\stage\lib" \
- -L"C:\db-4.7.25.NC-mgw\build_unix" \
+ -L"C:\boost-1.47.0-mgw\stage\lib" \
+ -L"C:\db-4.8.30.NC-mgw\build_unix" \
-L"C:\openssl-1.0.0d-mgw" \
- -L"C:\wxWidgets-2.9.1-mgw\lib\gcc_lib"
+ -L"C:\wxWidgets-2.9.2-mgw\lib\gcc_lib"
WXLIBS= \
-l wxmsw29ud_html -l wxmsw29ud_core -l wxmsw29ud_adv -l wxbase29ud -l wxtiffd -l wxjpegd -l wxpngd -l wxzlibd
LIBS= \
- -l boost_system-mgw45-mt-s-1_43 \
- -l boost_filesystem-mgw45-mt-s-1_43 \
- -l boost_program_options-mgw45-mt-s-1_43 \
- -l boost_thread-mgw45-mt-s-1_43 \
+ -l boost_system-mgw45-mt-s-1_47 \
+ -l boost_filesystem-mgw45-mt-s-1_47 \
+ -l boost_program_options-mgw45-mt-s-1_47 \
+ -l boost_thread-mgw45-mt-s-1_47 \
-l db_cxx \
-l ssl \
-l crypto
-DEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH -DUSE_SSL
+DEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH -DUSE_SSL -DBOOST_THREAD_USE_LIB
DEBUGFLAGS=-g -D__WXDEBUG__
CFLAGS=-mthreads -O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
-HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
- script.h db.h net.h irc.h keystore.h main.h wallet.h rpc.h uibase.h ui.h noui.h \
- init.h crypter.h
+HEADERS = \
+ base58.h \
+ bignum.h \
+ crypter.h \
+ db.h \
+ headers.h \
+ init.h \
+ irc.h \
+ key.h \
+ keystore.h \
+ main.h \
+ net.h \
+ noui.h \
+ protocol.h \
+ rpc.h \
+ script.h \
+ serialize.h \
+ strlcpy.h \
+ ui.h \
+ uibase.h \
+ uint256.h \
+ util.h \
+ wallet.h
ifdef USE_UPNP
- INCLUDEPATHS += -I"C:\upnpc-exe-win32-20110215"
- LIBPATHS += -L"C:\upnpc-exe-win32-20110215"
+ INCLUDEPATHS += -I"C:\miniupnpc-1.6-mgw"
+ LIBPATHS += -L"C:\miniupnpc-1.6-mgw"
LIBS += -l miniupnpc -l iphlpapi
DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP)
endif
@@ -46,17 +66,18 @@ endif
LIBS += -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi
OBJS= \
- obj/util.o \
- obj/script.o \
+ obj/crypter.o \
obj/db.o \
- obj/net.o \
+ obj/init.o \
obj/irc.o \
obj/keystore.o \
obj/main.o \
- obj/wallet.o \
+ obj/net.o \
+ obj/protocol.o \
obj/rpc.o \
- obj/init.o \
- obj/crypter.o \
+ obj/script.o \
+ obj/util.o \
+ obj/wallet.o \
cryptopp/obj/sha.o \
cryptopp/obj/cpu.o
diff --git a/src/makefile.osx b/src/makefile.osx
index 363a85fc7b..97264c7eb4 100644
--- a/src/makefile.osx
+++ b/src/makefile.osx
@@ -32,22 +32,43 @@ DEFS=$(shell $(DEPSDIR)/bin/wx-config --cxxflags) -D__WXMAC_OSX__ -DNOPCH -DMSG_
DEBUGFLAGS=-g -DwxDEBUG_LEVEL=0
# ppc doesn't work because we don't support big-endian
CFLAGS=-mmacosx-version-min=10.5 -arch i386 -arch x86_64 -O3 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
-HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
- script.h db.h net.h irc.h keystore.h main.h wallet.h rpc.h uibase.h ui.h noui.h \
- init.h crypter.h
+HEADERS = \
+ base58.h \
+ bignum.h \
+ crypter.h \
+ db.h \
+ headers.h \
+ init.h \
+ irc.h \
+ key.h \
+ keystore.h \
+ main.h \
+ net.h \
+ noui.h \
+ protocol.h \
+ rpc.h \
+ script.h \
+ serialize.h \
+ strlcpy.h \
+ ui.h \
+ uibase.h \
+ uint256.h \
+ util.h \
+ wallet.h
OBJS= \
- obj/util.o \
- obj/script.o \
+ obj/crypter.o \
obj/db.o \
- obj/net.o \
+ obj/init.o \
obj/irc.o \
obj/keystore.o \
obj/main.o \
- obj/wallet.o \
+ obj/net.o \
+ obj/protocol.o \
obj/rpc.o \
- obj/init.o \
- obj/crypter.o \
+ obj/script.o \
+ obj/util.o \
+ obj/wallet.o \
cryptopp/obj/sha.o \
cryptopp/obj/cpu.o
diff --git a/src/makefile.unix b/src/makefile.unix
index 597eea0dc8..298d856ecb 100644
--- a/src/makefile.unix
+++ b/src/makefile.unix
@@ -38,22 +38,43 @@ LIBS+= \
DEBUGFLAGS=-g -D__WXDEBUG__
CXXFLAGS=-O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS)
-HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
- script.h db.h net.h irc.h keystore.h main.h wallet.h rpc.h uibase.h ui.h noui.h \
- init.h crypter.h
+HEADERS = \
+ base58.h \
+ bignum.h \
+ crypter.h \
+ db.h \
+ headers.h \
+ init.h \
+ irc.h \
+ key.h \
+ keystore.h \
+ main.h \
+ net.h \
+ noui.h \
+ protocol.h \
+ rpc.h \
+ script.h \
+ serialize.h \
+ strlcpy.h \
+ ui.h \
+ uibase.h \
+ uint256.h \
+ util.h \
+ wallet.h
OBJS= \
- obj/util.o \
- obj/script.o \
+ obj/crypter.o \
obj/db.o \
- obj/net.o \
+ obj/init.o \
obj/irc.o \
obj/keystore.o \
obj/main.o \
- obj/wallet.o \
+ obj/net.o \
+ obj/protocol.o \
obj/rpc.o \
- obj/init.o \
- obj/crypter.o \
+ obj/script.o \
+ obj/util.o \
+ obj/wallet.o \
cryptopp/obj/sha.o \
cryptopp/obj/cpu.o
diff --git a/src/makefile.vc b/src/makefile.vc
index c050deb6ed..a5437bcf5c 100644
--- a/src/makefile.vc
+++ b/src/makefile.vc
@@ -45,21 +45,45 @@ LIBS=$(LIBS) \
DEBUGFLAGS=/Os
CFLAGS=/MD /c /nologo /EHsc /GR /Zm300 $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
-HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
- script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h noui.h init.h wallet.h keystore.h crypter.h
+HEADERS = \
+ base58.h \
+ bignum.h \
+ crypter.h \
+ db.h \
+ headers.h \
+ init.h \
+ irc.h \
+ key.h \
+ keystore.h \
+ main.h \
+ net.h \
+ noui.h \
+ protocol.h \
+ rpc.h \
+ script.h \
+ serialize.h \
+ strlcpy.h \
+ ui.h \
+ uibase.h \
+ uint256.h \
+ util.h \
+ wallet.h
OBJS= \
- obj\util.obj \
- obj\script.obj \
- obj\db.obj \
- obj\net.obj \
- obj\irc.obj \
- obj\keystore.obj \
- obj\main.obj \
- obj\wallet.obj \
- obj\rpc.obj \
- obj\init.obj \
- obj\crypter.obj
+ obj\crypter.o \
+ obj\db.o \
+ obj\init.o \
+ obj\irc.o \
+ obj\keystore.o \
+ obj\main.o \
+ obj\net.o \
+ obj\rpc.o \
+ obj\protocol.o \
+ obj\script.o \
+ obj\util.o \
+ obj\wallet.o \
+ cryptopp\obj\sha.o \
+ cryptopp\obj\cpu.o
CRYPTOPP_OBJS= \
cryptopp\obj\sha.obj \
diff --git a/src/net.cpp b/src/net.cpp
index 3953f021e9..952102ede2 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -12,11 +12,6 @@
#ifdef __WXMSW__
#include <string.h>
-// This file can be downloaded as a part of the Windows Platform SDK
-// and is required for Bitcoin binaries to work properly on versions
-// of Windows before XP. If you are doing builds of Bitcoin for
-// public release, you should uncomment this line.
-//#include <WSPiApi.h>
#endif
#ifdef USE_UPNP
@@ -50,10 +45,10 @@ bool fClient = false;
bool fAllowDNS = false;
uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices);
-CNode* pnodeLocalHost = NULL;
+static CNode* pnodeLocalHost = NULL;
uint64 nLocalHostNonce = 0;
array<int, 10> vnThreadsRunning;
-SOCKET hListenSocket = INVALID_SOCKET;
+static SOCKET hListenSocket = INVALID_SOCKET;
vector<CNode*> vNodes;
CCriticalSection cs_vNodes;
@@ -1079,10 +1074,11 @@ void ThreadMapPort2(void* parg)
const char * rootdescurl = 0;
const char * multicastif = 0;
const char * minissdpdpath = 0;
+ int error = 0;
struct UPNPDev * devlist = 0;
char lanaddr[64];
- devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
+ devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
struct UPNPUrls urls;
struct IGDdatas data;
@@ -1094,14 +1090,9 @@ void ThreadMapPort2(void* parg)
char intClient[16];
char intPort[6];
string strDesc = "Bitcoin " + FormatFullVersion();
-
-#ifndef __WXMSW__
- r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
- port, port, lanaddr, strDesc.c_str(), "TCP", 0);
-#else
r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
-#endif
+
if(r!=UPNPCOMMAND_SUCCESS)
printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
port, port, lanaddr, r, strupnperror(r));
@@ -1202,46 +1193,70 @@ void DNSAddressSeed()
unsigned int pnSeed[] =
{
- 0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
- 0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
- 0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
- 0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
- 0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
- 0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
- 0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
- 0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
- 0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
- 0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
- 0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
- 0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
- 0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
- 0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
- 0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
- 0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
- 0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
- 0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
- 0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
- 0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
- 0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
- 0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
- 0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
- 0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
- 0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
- 0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
- 0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
- 0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
- 0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
- 0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
- 0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
- 0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
- 0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
- 0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
- 0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
- 0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
- 0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
- 0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
- 0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
- 0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
+ 0x6884ac63, 0x3ffecead, 0x2919b953, 0x0942fe50, 0x7a1d922e, 0xcdd6734a, 0x953a5bb6, 0x2c46922e,
+ 0xe2a5f143, 0xaa39103a, 0xa06afa5c, 0x135ffd59, 0xe8e82863, 0xf61ef029, 0xf75f042e, 0x2b363532,
+ 0x29b2df42, 0x16b1f64e, 0xd46e281b, 0x5280bf58, 0x60372229, 0x1be58e4f, 0xa8496f45, 0x1fb1a057,
+ 0x756b3844, 0x3bb79445, 0x0b375518, 0xcccb0102, 0xb682bf2e, 0x46431c02, 0x3a81073a, 0xa3771f1f,
+ 0x213a121f, 0x85dc2c1b, 0x56b4323b, 0xb34e8945, 0x3c40b33d, 0xfa276418, 0x1f818d29, 0xebe1e344,
+ 0xf6160a18, 0xf4fa384a, 0x34b09558, 0xb882b543, 0xe3ce2253, 0x6abf56d8, 0xe91b1155, 0x688ee6ad,
+ 0x2efc6058, 0x4792cd47, 0x0c32f757, 0x4c813a46, 0x8c93644a, 0x37507444, 0x813ad218, 0xdac06d4a,
+ 0xe4c63e4b, 0x21a1ea3c, 0x8d88556f, 0x30e9173a, 0x041f681b, 0xdc77ba50, 0xc0072753, 0xceddd44f,
+ 0x052d1743, 0xe3c77a4a, 0x13981c3a, 0x5685d918, 0x3c0e4e70, 0x3e56fb54, 0xb676ae0c, 0xac93c859,
+ 0x22279f43, 0x975a4542, 0xe527f071, 0xea162f2e, 0x3c65a32e, 0x5be5713b, 0x961ec418, 0xb202922e,
+ 0x5ef7be50, 0xce49f53e, 0x05803b47, 0x8463b055, 0x78576153, 0x3ec2ae3a, 0x4bbd7118, 0xafcee043,
+ 0x56a3e8ba, 0x6174de4d, 0x8d01ba4b, 0xc9af564e, 0xdbc9c547, 0xa627474d, 0xdada9244, 0xd3b3083a,
+ 0x523e071f, 0xd6b96f18, 0xbd527c46, 0xdf2bbb4d, 0xd37b4a4b, 0x3a6a2158, 0xc064b055, 0x18a8e055,
+ 0xec4dae3b, 0x0540416c, 0x475b4fbe, 0x064803b2, 0x48e9f062, 0x2898524b, 0xd315ff43, 0xf786d247,
+ 0xc7ea2f3e, 0xc087f043, 0xc163354b, 0x8250284d, 0xed300029, 0xbf36e05c, 0x8eb3ae4c, 0xe7aa623e,
+ 0x7ced0274, 0xdd362c1b, 0x362b995a, 0xca26b629, 0x3fc41618, 0xb97b364e, 0xa05b8729, 0x0f5e3c43,
+ 0xdf942618, 0x6aeb9b5b, 0xbf04762e, 0xfaaeb118, 0x87579958, 0x76520044, 0xc2660c5b, 0x628b201b,
+ 0xf193932e, 0x1c0ad045, 0xff908346, 0x8da9d4da, 0xed201c1f, 0xa47a2b1b, 0x330007d4, 0x8ba1ed47,
+ 0xb2f02d44, 0x7db62c1b, 0x781c454b, 0xc0300029, 0xb7062a45, 0x88b52e3a, 0x78dd6b63, 0x1cb9b718,
+ 0x5d358e47, 0x59912c3b, 0x79607544, 0x5197f759, 0xc023be48, 0xd1013743, 0x0f354057, 0x8e3aac3b,
+ 0x4114693e, 0x22316318, 0xe27dda50, 0x878eac3b, 0x4948a21f, 0x5db7f24c, 0x8ccb6157, 0x26a5de18,
+ 0x0a11bd43, 0x27bb1e41, 0x60a7a951, 0x3e16b35e, 0x07888b53, 0x5648a853, 0x0149fe50, 0xd070a34f,
+ 0x6454c96d, 0xd6e54758, 0xa96dc152, 0x65447861, 0xf6bdf95e, 0x10400202, 0x2c29d483, 0x18174732,
+ 0x1d840618, 0x12e61818, 0x089d3f3c, 0x917e931f, 0xd1b0c90e, 0x25bd3c42, 0xeb05775b, 0x7d550c59,
+ 0x6cfacb01, 0xe4224444, 0xa41dd943, 0x0f5aa643, 0x5e33731b, 0x81036d50, 0x6f46a0d1, 0x7731be43,
+ 0x14840e18, 0xf1e8d059, 0x661d2b1f, 0x40a3201b, 0x9407b843, 0xedf0254d, 0x7bd1a5bc, 0x073dbe51,
+ 0xe864a97b, 0x2efd947b, 0xb9ca0e45, 0x4e2113ad, 0xcc305731, 0xd39ca63c, 0x733df918, 0xda172b1f,
+ 0xaa03b34d, 0x7230fd4d, 0xf1ce6e3a, 0x2e9fab43, 0xa4010750, 0xa928bd18, 0x6809be42, 0xb19de348,
+ 0xff956270, 0x0d795f51, 0xd2dec247, 0x6df5774b, 0xbac11f79, 0xdfb05c75, 0x887683d8, 0xa1e83632,
+ 0x2c0f7671, 0x28bcb65d, 0xac2a7545, 0x3eebfc60, 0x304ad7c4, 0xa215a462, 0xc86f0f58, 0xcfb92ebe,
+ 0x5e23ed82, 0xf506184b, 0xec0f19b7, 0x060c59ad, 0x86ee3174, 0x85380774, 0xa199a562, 0x02b507ae,
+ 0x33eb2163, 0xf2112b1f, 0xb702ba50, 0x131b9618, 0x90ccd04a, 0x08f3273b, 0xecb61718, 0x64b8b44d,
+ 0x182bf4dc, 0xc7b68286, 0x6e318d5f, 0xfdb03654, 0xb3272e54, 0xe014ad4b, 0x274e4a31, 0x7806375c,
+ 0xbc34a748, 0x1b5ad94a, 0x6b54d10e, 0x73e2ae6e, 0x5529d483, 0x8455a76d, 0x99c13f47, 0x1d811741,
+ 0xa9782a78, 0x0b00464d, 0x7266ea50, 0x532dab46, 0x33e1413e, 0x780d0c18, 0x0fb0854e, 0x03370155,
+ 0x2693042e, 0xfa3d824a, 0x2bb1681b, 0x37ea2a18, 0x7fb8414b, 0x32e0713b, 0xacf38d3f, 0xa282716f,
+ 0xb1a09d7b, 0xa04b764b, 0x83c94d18, 0x05ee4c6d, 0x0e795f51, 0x46984352, 0xf80fc247, 0x3fccb946,
+ 0xd7ae244b, 0x0a8e0a4c, 0x57b141bc, 0x3647bed1, 0x1431b052, 0x803a8bbb, 0xfc69056b, 0xf5991862,
+ 0x14963b2e, 0xd35d5dda, 0xc6c73574, 0xc8f1405b, 0x0ca4224d, 0xecd36071, 0xa9461754, 0xe7a0ed72,
+ 0x559e8346, 0x1c9beec1, 0xc786ea4a, 0x9561b44d, 0x9788074d, 0x1a69934f, 0x23c5614c, 0x07c79d4b,
+ 0xc7ee52db, 0xc72df351, 0xcb135e44, 0xa0988346, 0xc211fc4c, 0x87dec34b, 0x1381074d, 0x04a65cb7,
+ 0x4409083a, 0x4a407a4c, 0x92b8d37d, 0xacf50b4d, 0xa58aa5bc, 0x448f801f, 0x9c83762e, 0x6fd5734a,
+ 0xfe2d454b, 0x84144c55, 0x05190e4c, 0xb2151448, 0x63867a3e, 0x16099018, 0x9c010d3c, 0x962d8f3d,
+ 0xd51ee453, 0x9d86801f, 0x68e87b47, 0x6bf7bb73, 0x5fc7910e, 0x10d90118, 0x3db04442, 0x729d3e4b,
+ 0xc397d842, 0x57bb15ad, 0x72f31f4e, 0xc9380043, 0x2bb24e18, 0xd9b8ab50, 0xb786801f, 0xf4dc4847,
+ 0x85f4bb51, 0x4435995b, 0x5ba07e40, 0x2c57392e, 0x3628124b, 0x9839b64b, 0x6fe8b24d, 0xaddce847,
+ 0x75260e45, 0x0c572a43, 0xfea21902, 0xb9f9742e, 0x5a70d443, 0x8fc5910e, 0x868d4744, 0x56245e02,
+ 0xd7eb5f02, 0x35c12c1b, 0x4373034b, 0x8786554c, 0xa6facf18, 0x4b11a31f, 0x3570664e, 0x5a64bc42,
+ 0x0b03983f, 0x8f457e4c, 0x0fd874c3, 0xb6cf31b2, 0x2bbc2d4e, 0x146ca5b2, 0x9d00b150, 0x048a4153,
+ 0xca4dcd43, 0xc1607cca, 0x8234cf57, 0x9c7daead, 0x3dc07658, 0xea5c6e4c, 0xf1a0084e, 0x16d2ee53,
+ 0x1b849418, 0xfe913a47, 0x1e988f62, 0x208b644c, 0xc55ee980, 0xbdbce747, 0xf59a384e, 0x0f56091b,
+ 0x7417b745, 0x0c37344e, 0x2c62ab47, 0xf8533a4d, 0x8030084d, 0x76b93c4b, 0xda6ea0ad, 0x3c54f618,
+ 0x63b0de1f, 0x7370d858, 0x1a70bb4c, 0xdda63b2e, 0x60b2ba50, 0x1ba7d048, 0xbe1b2c1b, 0xabea5747,
+ 0x29ad2e4d, 0xe8cd7642, 0x66c80e18, 0x138bf34a, 0xc6145e44, 0x2586794c, 0x07bc5478, 0x0da0b14d,
+ 0x8f95354e, 0x9eb11c62, 0xa1545e46, 0x2e7a2602, 0x408c9c3d, 0x59065d55, 0xf51d1a4c, 0x3bbc6a4e,
+ 0xc71b2a2e, 0xcdaaa545, 0x17d659d0, 0x5202e7ad, 0xf1b68445, 0x93375961, 0xbd88a043, 0x066ad655,
+ 0x890f6318, 0x7b7dca47, 0x99bdd662, 0x3bb4fc53, 0x1231efdc, 0xc0a99444, 0x96bbea47, 0x61ed8748,
+ 0x27dfa73b, 0x8d4d1754, 0x3460042e, 0x551f0c4c, 0x8d0e0718, 0x162ddc53, 0x53231718, 0x1ecd65d0,
+ 0x944d28bc, 0x3b79d058, 0xaff97fbc, 0x4860006c, 0xc101c90e, 0xace41743, 0xa5975d4c, 0x5cc2703e,
+ 0xb55a4450, 0x02d18840, 0xee2765ae, 0xd6012fd5, 0x24c94d7d, 0x8c6eec47, 0x7520ba5d, 0x9e15e460,
+ 0x8510b04c, 0x75ec3847, 0x1dfa6661, 0xe172b3ad, 0x5744c90e, 0x52a0a152, 0x8d6fad18, 0x67b74b6d,
+ 0x93a089b2, 0x0f3ac5d5, 0xe5de1855, 0x43d25747, 0x4bad804a, 0x55b408d8, 0x60a36441, 0xf553e860,
+ 0xdb2fa2c8, 0x03152b32, 0xdd27a7d5, 0x3116a8b8, 0x0a1d708c, 0xeee2f13c, 0x6acf436f, 0xce6eb4ca,
+ 0x101cd3d9, 0x1c48a6b8, 0xe57d6f44, 0x93dcf562,
};
@@ -1342,9 +1357,12 @@ void ThreadOpenConnections2(void* parg)
{
// It'll only connect to one or two seed nodes because once it connects,
// it'll get a pile of addresses with newer timestamps.
+ // Seed nodes are given a random 'last seen time' of between one and two
+ // weeks ago.
+ const int64 nOneWeek = 7*24*60*60;
CAddress addr;
addr.ip = pnSeed[i];
- addr.nTime = 0;
+ addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
AddAddress(addr);
}
fSeedUsed = true;
diff --git a/src/net.h b/src/net.h
index 3b098e1a82..efac1f452a 100644
--- a/src/net.h
+++ b/src/net.h
@@ -14,10 +14,9 @@
#include <arpa/inet.h>
#endif
-class CMessageHeader;
-class CAddress;
+#include "protocol.h"
+
class CAddrDB;
-class CInv;
class CRequestTracker;
class CNode;
class CBlockIndex;
@@ -28,15 +27,7 @@ extern int nConnectTimeout;
inline unsigned int ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 10*1000); }
inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 10*1000); }
-inline unsigned short GetDefaultPort() { return fTestNet ? 18333 : 8333; }
static const unsigned int PUBLISH_HOPS = 5;
-enum
-{
- NODE_NETWORK = (1 << 0),
-};
-
-
-
bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout=nConnectTimeout);
bool Lookup(const char *pszName, std::vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
@@ -54,402 +45,12 @@ bool BindListenPort(std::string& strError=REF(std::string()));
void StartNode(void* parg);
bool StopNode();
-
-
-
-
-
-
-
-//
-// Message header
-// (4) message start
-// (12) command
-// (4) size
-// (4) checksum
-
-extern unsigned char pchMessageStart[4];
-
-class CMessageHeader
-{
-public:
- enum { COMMAND_SIZE=12 };
- char pchMessageStart[sizeof(::pchMessageStart)];
- char pchCommand[COMMAND_SIZE];
- unsigned int nMessageSize;
- unsigned int nChecksum;
-
- CMessageHeader()
- {
- memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));
- memset(pchCommand, 0, sizeof(pchCommand));
- pchCommand[1] = 1;
- nMessageSize = -1;
- nChecksum = 0;
- }
-
- CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn)
- {
- memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));
- strncpy(pchCommand, pszCommand, COMMAND_SIZE);
- nMessageSize = nMessageSizeIn;
- nChecksum = 0;
- }
-
- IMPLEMENT_SERIALIZE
- (
- READWRITE(FLATDATA(pchMessageStart));
- READWRITE(FLATDATA(pchCommand));
- READWRITE(nMessageSize);
- if (nVersion >= 209)
- READWRITE(nChecksum);
- )
-
- std::string GetCommand()
- {
- if (pchCommand[COMMAND_SIZE-1] == 0)
- return std::string(pchCommand, pchCommand + strlen(pchCommand));
- else
- return std::string(pchCommand, pchCommand + COMMAND_SIZE);
- }
-
- bool IsValid()
- {
- // Check start string
- if (memcmp(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)) != 0)
- return false;
-
- // Check the command string for errors
- for (char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++)
- {
- if (*p1 == 0)
- {
- // Must be all zeros after the first zero
- for (; p1 < pchCommand + COMMAND_SIZE; p1++)
- if (*p1 != 0)
- return false;
- }
- else if (*p1 < ' ' || *p1 > 0x7E)
- return false;
- }
-
- // Message size
- if (nMessageSize > MAX_SIZE)
- {
- printf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand().c_str(), nMessageSize);
- return false;
- }
-
- return true;
- }
-};
-
-
-
-
-
-
-static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
-
-class CAddress
-{
-public:
- uint64 nServices;
- unsigned char pchReserved[12];
- unsigned int ip;
- unsigned short port;
-
- // disk and network only
- unsigned int nTime;
-
- // memory only
- unsigned int nLastTry;
-
- CAddress()
- {
- Init();
- }
-
- CAddress(unsigned int ipIn, unsigned short portIn=0, uint64 nServicesIn=NODE_NETWORK)
- {
- Init();
- ip = ipIn;
- port = htons(portIn == 0 ? GetDefaultPort() : portIn);
- nServices = nServicesIn;
- }
-
- explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=NODE_NETWORK)
- {
- Init();
- ip = sockaddr.sin_addr.s_addr;
- port = sockaddr.sin_port;
- nServices = nServicesIn;
- }
-
- explicit CAddress(const char* pszIn, int portIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK)
- {
- Init();
- Lookup(pszIn, *this, nServicesIn, fNameLookup, portIn);
- }
-
- explicit CAddress(const char* pszIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK)
- {
- Init();
- Lookup(pszIn, *this, nServicesIn, fNameLookup, 0, true);
- }
-
- explicit CAddress(std::string strIn, int portIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK)
- {
- Init();
- Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, portIn);
- }
-
- explicit CAddress(std::string strIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK)
- {
- Init();
- Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, 0, true);
- }
-
- void Init()
- {
- nServices = NODE_NETWORK;
- memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
- ip = INADDR_NONE;
- port = htons(GetDefaultPort());
- nTime = 100000000;
- nLastTry = 0;
- }
-
- IMPLEMENT_SERIALIZE
- (
- if (fRead)
- const_cast<CAddress*>(this)->Init();
- if (nType & SER_DISK)
- READWRITE(nVersion);
- if ((nType & SER_DISK) || (nVersion >= 31402 && !(nType & SER_GETHASH)))
- READWRITE(nTime);
- READWRITE(nServices);
- READWRITE(FLATDATA(pchReserved)); // for IPv6
- READWRITE(ip);
- READWRITE(port);
- )
-
- friend inline bool operator==(const CAddress& a, const CAddress& b)
- {
- return (memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)) == 0 &&
- a.ip == b.ip &&
- a.port == b.port);
- }
-
- friend inline bool operator!=(const CAddress& a, const CAddress& b)
- {
- return (!(a == b));
- }
-
- friend inline bool operator<(const CAddress& a, const CAddress& b)
- {
- int ret = memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved));
- if (ret < 0)
- return true;
- else if (ret == 0)
- {
- if (ntohl(a.ip) < ntohl(b.ip))
- return true;
- else if (a.ip == b.ip)
- return ntohs(a.port) < ntohs(b.port);
- }
- return false;
- }
-
- std::vector<unsigned char> GetKey() const
- {
- CDataStream ss;
- ss.reserve(18);
- ss << FLATDATA(pchReserved) << ip << port;
-
- #if defined(_MSC_VER) && _MSC_VER < 1300
- return std::vector<unsigned char>((unsigned char*)&ss.begin()[0], (unsigned char*)&ss.end()[0]);
- #else
- return std::vector<unsigned char>(ss.begin(), ss.end());
- #endif
- }
-
- struct sockaddr_in GetSockAddr() const
- {
- struct sockaddr_in sockaddr;
- memset(&sockaddr, 0, sizeof(sockaddr));
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_addr.s_addr = ip;
- sockaddr.sin_port = port;
- return sockaddr;
- }
-
- bool IsIPv4() const
- {
- return (memcmp(pchReserved, pchIPv4, sizeof(pchIPv4)) == 0);
- }
-
- bool IsRFC1918() const
- {
- return IsIPv4() && (GetByte(3) == 10 ||
- (GetByte(3) == 192 && GetByte(2) == 168) ||
- (GetByte(3) == 172 &&
- (GetByte(2) >= 16 && GetByte(2) <= 31)));
- }
-
- bool IsRFC3927() const
- {
- return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254);
- }
-
- bool IsLocal() const
- {
- return IsIPv4() && (GetByte(3) == 127 ||
- GetByte(3) == 0);
- }
-
- bool IsRoutable() const
- {
- return IsValid() &&
- !(IsRFC1918() || IsRFC3927() || IsLocal());
- }
-
- bool IsValid() const
- {
- // Clean up 3-byte shifted addresses caused by garbage in size field
- // of addr messages from versions before 0.2.9 checksum.
- // Two consecutive addr messages look like this:
- // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26...
- // so if the first length field is garbled, it reads the second batch
- // of addr misaligned by 3 bytes.
- if (memcmp(pchReserved, pchIPv4+3, sizeof(pchIPv4)-3) == 0)
- return false;
-
- return (ip != 0 && ip != INADDR_NONE && port != htons(USHRT_MAX));
- }
-
- unsigned char GetByte(int n) const
- {
- return ((unsigned char*)&ip)[3-n];
- }
-
- std::string ToStringIPPort() const
- {
- return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
- }
-
- std::string ToStringIP() const
- {
- return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
- }
-
- std::string ToStringPort() const
- {
- return strprintf("%u", ntohs(port));
- }
-
- std::string ToString() const
- {
- return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
- }
-
- void print() const
- {
- printf("CAddress(%s)\n", ToString().c_str());
- }
-};
-
-
-
-
-
-
-
enum
{
MSG_TX = 1,
MSG_BLOCK,
};
-static const char* ppszTypeName[] =
-{
- "ERROR",
- "tx",
- "block",
-};
-
-class CInv
-{
-public:
- int type;
- uint256 hash;
-
- CInv()
- {
- type = 0;
- hash = 0;
- }
-
- CInv(int typeIn, const uint256& hashIn)
- {
- type = typeIn;
- hash = hashIn;
- }
-
- CInv(const std::string& strType, const uint256& hashIn)
- {
- int i;
- for (i = 1; i < ARRAYLEN(ppszTypeName); i++)
- {
- if (strType == ppszTypeName[i])
- {
- type = i;
- break;
- }
- }
- if (i == ARRAYLEN(ppszTypeName))
- throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType.c_str()));
- hash = hashIn;
- }
-
- IMPLEMENT_SERIALIZE
- (
- READWRITE(type);
- READWRITE(hash);
- )
-
- friend inline bool operator<(const CInv& a, const CInv& b)
- {
- return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
- }
-
- bool IsKnownType() const
- {
- return (type >= 1 && type < ARRAYLEN(ppszTypeName));
- }
-
- const char* GetCommand() const
- {
- if (!IsKnownType())
- throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type));
- return ppszTypeName[type];
- }
-
- std::string ToString() const
- {
- return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,20).c_str());
- }
-
- void print() const
- {
- printf("CInv(%s)\n", ToString().c_str());
- }
-};
-
-
-
-
-
class CRequestTracker
{
public:
@@ -476,10 +77,8 @@ extern bool fClient;
extern bool fAllowDNS;
extern uint64 nLocalServices;
extern CAddress addrLocalHost;
-extern CNode* pnodeLocalHost;
extern uint64 nLocalHostNonce;
extern boost::array<int, 10> vnThreadsRunning;
-extern SOCKET hListenSocket;
extern std::vector<CNode*> vNodes;
extern CCriticalSection cs_vNodes;
diff --git a/src/protocol.cpp b/src/protocol.cpp
new file mode 100644
index 0000000000..48784b9cfb
--- /dev/null
+++ b/src/protocol.cpp
@@ -0,0 +1,312 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2011 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+
+#include "protocol.h"
+#include "util.h"
+
+#ifndef __WXMSW__
+# include <arpa/inet.h>
+#endif
+
+// Prototypes from net.h, but that header (currently) stinks, can't #include it without breaking things
+bool Lookup(const char *pszName, std::vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
+bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
+
+static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
+static const char* ppszTypeName[] =
+{
+ "ERROR",
+ "tx",
+ "block",
+};
+
+CMessageHeader::CMessageHeader()
+{
+ memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));
+ memset(pchCommand, 0, sizeof(pchCommand));
+ pchCommand[1] = 1;
+ nMessageSize = -1;
+ nChecksum = 0;
+}
+
+CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn)
+{
+ memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));
+ strncpy(pchCommand, pszCommand, COMMAND_SIZE);
+ nMessageSize = nMessageSizeIn;
+ nChecksum = 0;
+}
+
+std::string CMessageHeader::GetCommand() const
+{
+ if (pchCommand[COMMAND_SIZE-1] == 0)
+ return std::string(pchCommand, pchCommand + strlen(pchCommand));
+ else
+ return std::string(pchCommand, pchCommand + COMMAND_SIZE);
+}
+
+bool CMessageHeader::IsValid() const
+{
+ // Check start string
+ if (memcmp(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)) != 0)
+ return false;
+
+ // Check the command string for errors
+ for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++)
+ {
+ if (*p1 == 0)
+ {
+ // Must be all zeros after the first zero
+ for (; p1 < pchCommand + COMMAND_SIZE; p1++)
+ if (*p1 != 0)
+ return false;
+ }
+ else if (*p1 < ' ' || *p1 > 0x7E)
+ return false;
+ }
+
+ // Message size
+ if (nMessageSize > MAX_SIZE)
+ {
+ printf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand().c_str(), nMessageSize);
+ return false;
+ }
+
+ return true;
+}
+
+CAddress::CAddress()
+{
+ Init();
+}
+
+CAddress::CAddress(unsigned int ipIn, unsigned short portIn, uint64 nServicesIn)
+{
+ Init();
+ ip = ipIn;
+ port = htons(portIn == 0 ? GetDefaultPort() : portIn);
+ nServices = nServicesIn;
+}
+
+CAddress::CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn)
+{
+ Init();
+ ip = sockaddr.sin_addr.s_addr;
+ port = sockaddr.sin_port;
+ nServices = nServicesIn;
+}
+
+CAddress::CAddress(const char* pszIn, int portIn, bool fNameLookup, uint64 nServicesIn)
+{
+ Init();
+ Lookup(pszIn, *this, nServicesIn, fNameLookup, portIn);
+}
+
+CAddress::CAddress(const char* pszIn, bool fNameLookup, uint64 nServicesIn)
+{
+ Init();
+ Lookup(pszIn, *this, nServicesIn, fNameLookup, 0, true);
+}
+
+CAddress::CAddress(std::string strIn, int portIn, bool fNameLookup, uint64 nServicesIn)
+{
+ Init();
+ Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, portIn);
+}
+
+CAddress::CAddress(std::string strIn, bool fNameLookup, uint64 nServicesIn)
+{
+ Init();
+ Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, 0, true);
+}
+
+void CAddress::Init()
+{
+ nServices = NODE_NETWORK;
+ memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
+ ip = INADDR_NONE;
+ port = htons(GetDefaultPort());
+ nTime = 100000000;
+ nLastTry = 0;
+}
+
+bool operator==(const CAddress& a, const CAddress& b)
+{
+ return (memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)) == 0 &&
+ a.ip == b.ip &&
+ a.port == b.port);
+}
+
+bool operator!=(const CAddress& a, const CAddress& b)
+{
+ return (!(a == b));
+}
+
+bool operator<(const CAddress& a, const CAddress& b)
+{
+ int ret = memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved));
+ if (ret < 0)
+ return true;
+ else if (ret == 0)
+ {
+ if (ntohl(a.ip) < ntohl(b.ip))
+ return true;
+ else if (a.ip == b.ip)
+ return ntohs(a.port) < ntohs(b.port);
+ }
+ return false;
+}
+
+std::vector<unsigned char> CAddress::GetKey() const
+{
+ CDataStream ss;
+ ss.reserve(18);
+ ss << FLATDATA(pchReserved) << ip << port;
+
+ #if defined(_MSC_VER) && _MSC_VER < 1300
+ return std::vector<unsigned char>((unsigned char*)&ss.begin()[0], (unsigned char*)&ss.end()[0]);
+ #else
+ return std::vector<unsigned char>(ss.begin(), ss.end());
+ #endif
+}
+
+struct sockaddr_in CAddress::GetSockAddr() const
+{
+ struct sockaddr_in sockaddr;
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_addr.s_addr = ip;
+ sockaddr.sin_port = port;
+ return sockaddr;
+}
+
+bool CAddress::IsIPv4() const
+{
+ return (memcmp(pchReserved, pchIPv4, sizeof(pchIPv4)) == 0);
+}
+
+bool CAddress::IsRFC1918() const
+{
+ return IsIPv4() && (GetByte(3) == 10 ||
+ (GetByte(3) == 192 && GetByte(2) == 168) ||
+ (GetByte(3) == 172 &&
+ (GetByte(2) >= 16 && GetByte(2) <= 31)));
+}
+
+bool CAddress::IsRFC3927() const
+{
+ return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254);
+}
+
+bool CAddress::IsLocal() const
+{
+ return IsIPv4() && (GetByte(3) == 127 ||
+ GetByte(3) == 0);
+}
+
+bool CAddress::IsRoutable() const
+{
+ return IsValid() &&
+ !(IsRFC1918() || IsRFC3927() || IsLocal());
+}
+
+bool CAddress::IsValid() const
+{
+ // Clean up 3-byte shifted addresses caused by garbage in size field
+ // of addr messages from versions before 0.2.9 checksum.
+ // Two consecutive addr messages look like this:
+ // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26...
+ // so if the first length field is garbled, it reads the second batch
+ // of addr misaligned by 3 bytes.
+ if (memcmp(pchReserved, pchIPv4+3, sizeof(pchIPv4)-3) == 0)
+ return false;
+
+ return (ip != 0 && ip != INADDR_NONE && port != htons(USHRT_MAX));
+}
+
+unsigned char CAddress::GetByte(int n) const
+{
+ return ((unsigned char*)&ip)[3-n];
+}
+
+std::string CAddress::ToStringIPPort() const
+{
+ return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
+}
+
+std::string CAddress::ToStringIP() const
+{
+ return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
+}
+
+std::string CAddress::ToStringPort() const
+{
+ return strprintf("%u", ntohs(port));
+}
+
+std::string CAddress::ToString() const
+{
+ return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
+}
+
+void CAddress::print() const
+{
+ printf("CAddress(%s)\n", ToString().c_str());
+}
+
+CInv::CInv()
+{
+ type = 0;
+ hash = 0;
+}
+
+CInv::CInv(int typeIn, const uint256& hashIn)
+{
+ type = typeIn;
+ hash = hashIn;
+}
+
+CInv::CInv(const std::string& strType, const uint256& hashIn)
+{
+ int i;
+ for (i = 1; i < ARRAYLEN(ppszTypeName); i++)
+ {
+ if (strType == ppszTypeName[i])
+ {
+ type = i;
+ break;
+ }
+ }
+ if (i == ARRAYLEN(ppszTypeName))
+ throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType.c_str()));
+ hash = hashIn;
+}
+
+bool operator<(const CInv& a, const CInv& b)
+{
+ return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
+}
+
+bool CInv::IsKnownType() const
+{
+ return (type >= 1 && type < ARRAYLEN(ppszTypeName));
+}
+
+const char* CInv::GetCommand() const
+{
+ if (!IsKnownType())
+ throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type));
+ return ppszTypeName[type];
+}
+
+std::string CInv::ToString() const
+{
+ return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,20).c_str());
+}
+
+void CInv::print() const
+{
+ printf("CInv(%s)\n", ToString().c_str());
+}
diff --git a/src/protocol.h b/src/protocol.h
new file mode 100644
index 0000000000..53d3eef4d5
--- /dev/null
+++ b/src/protocol.h
@@ -0,0 +1,150 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2011 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef __cplusplus
+# error This header can only be compiled as C++.
+#endif
+
+#ifndef __INCLUDED_PROTOCOL_H__
+#define __INCLUDED_PROTOCOL_H__
+
+#include "serialize.h"
+#include <string>
+#include "uint256.h"
+
+extern bool fTestNet;
+static inline unsigned short GetDefaultPort(const bool testnet = fTestNet)
+{
+ return testnet ? 18333 : 8333;
+}
+
+//
+// Message header
+// (4) message start
+// (12) command
+// (4) size
+// (4) checksum
+
+extern unsigned char pchMessageStart[4];
+
+class CMessageHeader
+{
+ public:
+ CMessageHeader();
+ CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn);
+
+ std::string GetCommand() const;
+ bool IsValid() const;
+
+ IMPLEMENT_SERIALIZE
+ (
+ READWRITE(FLATDATA(pchMessageStart));
+ READWRITE(FLATDATA(pchCommand));
+ READWRITE(nMessageSize);
+ if (nVersion >= 209)
+ READWRITE(nChecksum);
+ )
+
+ // TODO: make private (improves encapsulation)
+ public:
+ enum { COMMAND_SIZE=12 };
+ char pchMessageStart[sizeof(::pchMessageStart)];
+ char pchCommand[COMMAND_SIZE];
+ unsigned int nMessageSize;
+ unsigned int nChecksum;
+};
+
+enum
+{
+ NODE_NETWORK = (1 << 0),
+};
+
+class CAddress
+{
+ public:
+ CAddress();
+ CAddress(unsigned int ipIn, unsigned short portIn=0, uint64 nServicesIn=NODE_NETWORK);
+ explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=NODE_NETWORK);
+ explicit CAddress(const char* pszIn, int portIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK);
+ explicit CAddress(const char* pszIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK);
+ explicit CAddress(std::string strIn, int portIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK);
+ explicit CAddress(std::string strIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK);
+
+ void Init();
+
+ IMPLEMENT_SERIALIZE
+ (
+ if (fRead)
+ const_cast<CAddress*>(this)->Init();
+ if (nType & SER_DISK)
+ READWRITE(nVersion);
+ if ((nType & SER_DISK) || (nVersion >= 31402 && !(nType & SER_GETHASH)))
+ READWRITE(nTime);
+ READWRITE(nServices);
+ READWRITE(FLATDATA(pchReserved)); // for IPv6
+ READWRITE(ip);
+ READWRITE(port);
+ )
+
+ friend bool operator==(const CAddress& a, const CAddress& b);
+ friend bool operator!=(const CAddress& a, const CAddress& b);
+ friend bool operator<(const CAddress& a, const CAddress& b);
+
+ std::vector<unsigned char> GetKey() const;
+ struct sockaddr_in GetSockAddr() const;
+ bool IsIPv4() const;
+ bool IsRFC1918() const;
+ bool IsRFC3927() const;
+ bool IsLocal() const;
+ bool IsRoutable() const;
+ bool IsValid() const;
+ unsigned char GetByte(int n) const;
+ std::string ToStringIPPort() const;
+ std::string ToStringIP() const;
+ std::string ToStringPort() const;
+ std::string ToString() const;
+ void print() const;
+
+ // TODO: make private (improves encapsulation)
+ public:
+ uint64 nServices;
+ unsigned char pchReserved[12];
+ unsigned int ip;
+ unsigned short port;
+
+ // disk and network only
+ unsigned int nTime;
+
+ // memory only
+ unsigned int nLastTry;
+};
+
+class CInv
+{
+ public:
+ CInv();
+ CInv(int typeIn, const uint256& hashIn);
+ CInv(const std::string& strType, const uint256& hashIn);
+
+ IMPLEMENT_SERIALIZE
+ (
+ READWRITE(type);
+ READWRITE(hash);
+ )
+
+ friend bool operator<(const CInv& a, const CInv& b);
+
+ bool IsKnownType() const;
+ const char* GetCommand() const;
+ std::string ToString() const;
+ void print() const;
+
+ // TODO: make private (improves encapsulation)
+ public:
+ int type;
+ uint256 hash;
+};
+
+#endif // __INCLUDED_PROTOCOL_H__
diff --git a/src/script.cpp b/src/script.cpp
index 0308177d44..12d3f9e83a 100644
--- a/src/script.cpp
+++ b/src/script.cpp
@@ -1033,48 +1033,45 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash
return false;
// Compile solution
- CRITICAL_BLOCK(keystore.cs_KeyStore)
+ BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
{
- BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
+ if (item.first == OP_PUBKEY)
{
- if (item.first == OP_PUBKEY)
+ // Sign
+ const valtype& vchPubKey = item.second;
+ CKey key;
+ if (!keystore.GetKey(Hash160(vchPubKey), key))
+ return false;
+ if (key.GetPubKey() != vchPubKey)
+ return false;
+ if (hash != 0)
{
- // Sign
- const valtype& vchPubKey = item.second;
- CKey key;
- if (!keystore.GetKey(Hash160(vchPubKey), key))
- return false;
- if (key.GetPubKey() != vchPubKey)
+ vector<unsigned char> vchSig;
+ if (!key.Sign(hash, vchSig))
return false;
- if (hash != 0)
- {
- vector<unsigned char> vchSig;
- if (!key.Sign(hash, vchSig))
- return false;
- vchSig.push_back((unsigned char)nHashType);
- scriptSigRet << vchSig;
- }
+ vchSig.push_back((unsigned char)nHashType);
+ scriptSigRet << vchSig;
}
- else if (item.first == OP_PUBKEYHASH)
+ }
+ else if (item.first == OP_PUBKEYHASH)
+ {
+ // Sign and give pubkey
+ CKey key;
+ if (!keystore.GetKey(uint160(item.second), key))
+ return false;
+ if (hash != 0)
{
- // Sign and give pubkey
- CKey key;
- if (!keystore.GetKey(uint160(item.second), key))
+ vector<unsigned char> vchSig;
+ if (!key.Sign(hash, vchSig))
return false;
- if (hash != 0)
- {
- vector<unsigned char> vchSig;
- if (!key.Sign(hash, vchSig))
- return false;
- vchSig.push_back((unsigned char)nHashType);
- scriptSigRet << vchSig << key.GetPubKey();
- }
- }
- else
- {
- return false;
+ vchSig.push_back((unsigned char)nHashType);
+ scriptSigRet << vchSig << key.GetPubKey();
}
}
+ else
+ {
+ return false;
+ }
}
return true;
@@ -1095,35 +1092,31 @@ bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
return false;
// Compile solution
- CRITICAL_BLOCK(keystore.cs_KeyStore)
+ BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
{
- BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
+ if (item.first == OP_PUBKEY)
{
- if (item.first == OP_PUBKEY)
- {
- const valtype& vchPubKey = item.second;
- vector<unsigned char> vchPubKeyFound;
- if (!keystore.GetPubKey(Hash160(vchPubKey), vchPubKeyFound))
- return false;
- if (vchPubKeyFound != vchPubKey)
- return false;
- }
- else if (item.first == OP_PUBKEYHASH)
- {
- if (!keystore.HaveKey(uint160(item.second)))
- return false;
- }
- else
- {
+ const valtype& vchPubKey = item.second;
+ vector<unsigned char> vchPubKeyFound;
+ if (!keystore.GetPubKey(Hash160(vchPubKey), vchPubKeyFound))
return false;
- }
+ if (vchPubKeyFound != vchPubKey)
+ return false;
+ }
+ else if (item.first == OP_PUBKEYHASH)
+ {
+ if (!keystore.HaveKey(uint160(item.second)))
+ return false;
+ }
+ else
+ {
+ return false;
}
}
return true;
}
-// requires either keystore==0, or a lock on keystore->cs_KeyStore
bool static ExtractAddressInner(const CScript& scriptPubKey, const CKeyStore* keystore, CBitcoinAddress& addressRet)
{
vector<pair<opcodetype, valtype> > vSolution;
@@ -1147,8 +1140,7 @@ bool static ExtractAddressInner(const CScript& scriptPubKey, const CKeyStore* ke
bool ExtractAddress(const CScript& scriptPubKey, const CKeyStore* keystore, CBitcoinAddress& addressRet)
{
if (keystore)
- CRITICAL_BLOCK(keystore->cs_KeyStore)
- return ExtractAddressInner(scriptPubKey, keystore, addressRet);
+ return ExtractAddressInner(scriptPubKey, keystore, addressRet);
else
return ExtractAddressInner(scriptPubKey, NULL, addressRet);
return false;
diff --git a/src/serialize.h b/src/serialize.h
index b169f75b2a..09e4035fae 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -64,10 +64,13 @@ static const int VERSION = 32500;
static const char* pszSubVer = "";
static const bool VERSION_IS_BETA = true;
-
-
-
-
+// Used to bypass the rule against non-const reference to temporary
+// where it makes sense with wrappers such as CFlatData or CTxDB
+template<typename T>
+inline T& REF(const T& val)
+{
+ return const_cast<T&>(val);
+}
/////////////////////////////////////////////////////////////////
//
diff --git a/src/ui.cpp b/src/ui.cpp
index 372808f1ae..198a27209a 100644
--- a/src/ui.cpp
+++ b/src/ui.cpp
@@ -708,7 +708,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
CBitcoinAddress address;
if (ExtractAddress(txout.scriptPubKey, pwalletMain, address))
{
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+ CRITICAL_BLOCK(pwalletMain->cs_wallet)
{
//strDescription += _("Received payment to ");
//strDescription += _("Received with address ");
@@ -792,7 +792,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
}
string strDescription = _("To: ");
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+ CRITICAL_BLOCK(pwalletMain->cs_wallet)
if (pwalletMain->mapAddressBook.count(address) && !pwalletMain->mapAddressBook[address].empty())
strDescription += pwalletMain->mapAddressBook[address] + " ";
strDescription += strAddress;
@@ -862,7 +862,7 @@ void CMainFrame::OnIdle(wxIdleEvent& event)
// Collect list of wallet transactions and sort newest first
bool fEntered = false;
vector<pair<unsigned int, uint256> > vSorted;
- TRY_CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
+ TRY_CRITICAL_BLOCK(pwalletMain->cs_wallet)
{
printf("RefreshListCtrl starting\n");
fEntered = true;
@@ -890,7 +890,7 @@ void CMainFrame::OnIdle(wxIdleEvent& event)
if (fShutdown)
return;
bool fEntered = false;
- TRY_CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
+ TRY_CRITICAL_BLOCK(pwalletMain->cs_wallet)
{
fEntered = true;
uint256& hash = vSorted[i++].second;
@@ -913,7 +913,7 @@ void CMainFrame::OnIdle(wxIdleEvent& event)
static int64 nLastTime;
if (GetTime() > nLastTime + 30)
{
- TRY_CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
+ TRY_CRITICAL_BLOCK(pwalletMain->cs_wallet)
{
nLastTime = GetTime();
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
@@ -937,7 +937,7 @@ void CMainFrame::RefreshStatusColumn()
if (nTop == nLastTop && pindexLastBest == pindexBest)
return;
- TRY_CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
+ TRY_CRITICAL_BLOCK(pwalletMain->cs_wallet)
{
int nStart = nTop;
int nEnd = min(nStart + 100, m_listCtrl->GetItemCount());
@@ -1057,7 +1057,7 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
// Update listctrl contents
if (!pwalletMain->vWalletUpdated.empty())
{
- TRY_CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
+ TRY_CRITICAL_BLOCK(pwalletMain->cs_wallet)
{
string strTop;
if (m_listCtrl->GetItemCount())
@@ -1075,7 +1075,7 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
}
// Balance total
- TRY_CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
+ TRY_CRITICAL_BLOCK(pwalletMain->cs_wallet)
{
fPaintedBalance = true;
m_staticTextBalance->SetLabel(FormatMoney(pwalletMain->GetBalance()) + " ");
@@ -1247,83 +1247,80 @@ void CMainFrame::OnMenuOptionsChangeWalletPassphrase(wxCommandEvent& event)
strOldWalletPass = wxGetPasswordFromUser(_("Enter the current passphrase to the wallet."),
_("Passphrase")).ToStdString();
- CRITICAL_BLOCK(pwalletMain->cs_vMasterKey)
- {
- bool fWasLocked = pwalletMain->IsLocked();
- pwalletMain->Lock();
+ bool fWasLocked = pwalletMain->IsLocked();
+ pwalletMain->Lock();
- if (!strOldWalletPass.size() || !pwalletMain->Unlock(strOldWalletPass))
- {
- fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0');
- munlock(&strOldWalletPass[0], strOldWalletPass.capacity());
- wxMessageBox(_("The passphrase entered for the wallet decryption was incorrect."), "Bitcoin", wxOK | wxICON_ERROR);
- return;
- }
+ if (!strOldWalletPass.size() || !pwalletMain->Unlock(strOldWalletPass))
+ {
+ fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0');
+ munlock(&strOldWalletPass[0], strOldWalletPass.capacity());
+ wxMessageBox(_("The passphrase entered for the wallet decryption was incorrect."), "Bitcoin", wxOK | wxICON_ERROR);
+ return;
+ }
- if (fWasLocked)
- pwalletMain->Lock();
+ if (fWasLocked)
+ pwalletMain->Lock();
- string strNewWalletPass;
- strNewWalletPass.reserve(100);
- mlock(&strNewWalletPass[0], strNewWalletPass.capacity());
+ string strNewWalletPass;
+ strNewWalletPass.reserve(100);
+ mlock(&strNewWalletPass[0], strNewWalletPass.capacity());
- // obtain new wallet encrypt/decrypt key, from passphrase
- // Note that the passphrase is not mlock()d during this entry and could potentially
- // be obtained from disk long after bitcoin has run.
- strNewWalletPass = wxGetPasswordFromUser(_("Enter the new passphrase for the wallet."),
- _("Passphrase")).ToStdString();
+ // obtain new wallet encrypt/decrypt key, from passphrase
+ // Note that the passphrase is not mlock()d during this entry and could potentially
+ // be obtained from disk long after bitcoin has run.
+ strNewWalletPass = wxGetPasswordFromUser(_("Enter the new passphrase for the wallet."),
+ _("Passphrase")).ToStdString();
- if (!strNewWalletPass.size())
- {
- fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0');
- fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0');
- munlock(&strOldWalletPass[0], strOldWalletPass.capacity());
- munlock(&strNewWalletPass[0], strNewWalletPass.capacity());
- wxMessageBox(_("Error: The supplied passphrase was too short."), "Bitcoin", wxOK | wxICON_ERROR);
- return;
- }
+ if (!strNewWalletPass.size())
+ {
+ fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0');
+ fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0');
+ munlock(&strOldWalletPass[0], strOldWalletPass.capacity());
+ munlock(&strNewWalletPass[0], strNewWalletPass.capacity());
+ wxMessageBox(_("Error: The supplied passphrase was too short."), "Bitcoin", wxOK | wxICON_ERROR);
+ return;
+ }
- string strNewWalletPassTest;
- strNewWalletPassTest.reserve(100);
- mlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity());
+ string strNewWalletPassTest;
+ strNewWalletPassTest.reserve(100);
+ mlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity());
- // obtain new wallet encrypt/decrypt key, from passphrase
- // Note that the passphrase is not mlock()d during this entry and could potentially
- // be obtained from disk long after bitcoin has run.
- strNewWalletPassTest = wxGetPasswordFromUser(_("Re-enter the new passphrase for the wallet."),
- _("Passphrase")).ToStdString();
+ // obtain new wallet encrypt/decrypt key, from passphrase
+ // Note that the passphrase is not mlock()d during this entry and could potentially
+ // be obtained from disk long after bitcoin has run.
+ strNewWalletPassTest = wxGetPasswordFromUser(_("Re-enter the new passphrase for the wallet."),
+ _("Passphrase")).ToStdString();
- if (strNewWalletPassTest != strNewWalletPass)
- {
- fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0');
- fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0');
- fill(strNewWalletPassTest.begin(), strNewWalletPassTest.end(), '\0');
- munlock(&strOldWalletPass[0], strOldWalletPass.capacity());
- munlock(&strNewWalletPass[0], strNewWalletPass.capacity());
- munlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity());
- wxMessageBox(_("Error: the supplied passphrases didn't match."), "Bitcoin", wxOK | wxICON_ERROR);
- return;
- }
+ if (strNewWalletPassTest != strNewWalletPass)
+ {
+ fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0');
+ fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0');
+ fill(strNewWalletPassTest.begin(), strNewWalletPassTest.end(), '\0');
+ munlock(&strOldWalletPass[0], strOldWalletPass.capacity());
+ munlock(&strNewWalletPass[0], strNewWalletPass.capacity());
+ munlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity());
+ wxMessageBox(_("Error: the supplied passphrases didn't match."), "Bitcoin", wxOK | wxICON_ERROR);
+ return;
+ }
- if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass))
- {
- fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0');
- fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0');
- fill(strNewWalletPassTest.begin(), strNewWalletPassTest.end(), '\0');
- munlock(&strOldWalletPass[0], strOldWalletPass.capacity());
- munlock(&strNewWalletPass[0], strNewWalletPass.capacity());
- munlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity());
- wxMessageBox(_("The passphrase entered for the wallet decryption was incorrect."), "Bitcoin", wxOK | wxICON_ERROR);
- return;
- }
+ if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass))
+ {
fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0');
fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0');
fill(strNewWalletPassTest.begin(), strNewWalletPassTest.end(), '\0');
munlock(&strOldWalletPass[0], strOldWalletPass.capacity());
munlock(&strNewWalletPass[0], strNewWalletPass.capacity());
munlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity());
- wxMessageBox(_("Wallet Passphrase Changed."), "Bitcoin");
+ wxMessageBox(_("The passphrase entered for the wallet decryption was incorrect."), "Bitcoin", wxOK | wxICON_ERROR);
+ return;
}
+ fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0');
+ fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0');
+ fill(strNewWalletPassTest.begin(), strNewWalletPassTest.end(), '\0');
+ munlock(&strOldWalletPass[0], strOldWalletPass.capacity());
+ munlock(&strNewWalletPass[0], strNewWalletPass.capacity());
+ munlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity());
+ wxMessageBox(_("Wallet Passphrase Changed."), "Bitcoin");
}
void CMainFrame::OnMenuOptionsOptions(wxCommandEvent& event)
@@ -1387,21 +1384,21 @@ void CMainFrame::OnButtonNew(wxCommandEvent& event)
string strName = dialog.GetValue();
string strAddress;
- CRITICAL_BLOCK(pwalletMain->cs_vMasterKey)
- {
- bool fWasLocked = pwalletMain->IsLocked();
- if (!GetWalletPassphrase())
- return;
- // Generate new key
- strAddress = CBitcoinAddress(pwalletMain->GetOrReuseKeyFromPool()).ToString();
+ bool fWasLocked = pwalletMain->IsLocked();
+ if (!GetWalletPassphrase())
+ return;
- if (fWasLocked)
- pwalletMain->Lock();
- }
+ // Generate new key
+ std::vector<unsigned char> newKey;
+ pwalletMain->GetKeyFromPool(newKey, true);
+ strAddress = CBitcoinAddress(newKey).ToString();
+
+ if (fWasLocked)
+ pwalletMain->Lock();
// Save
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+ CRITICAL_BLOCK(pwalletMain->cs_wallet)
pwalletMain->SetAddressBookName(strAddress, strName);
SetDefaultReceivingAddress(strAddress);
}
@@ -1420,7 +1417,7 @@ void CMainFrame::OnListItemActivated(wxListEvent& event)
{
uint256 hash((string)GetItemText(m_listCtrl, event.GetIndex(), 1));
CWalletTx wtx;
- CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
+ CRITICAL_BLOCK(pwalletMain->cs_wallet)
{
map<uint256, CWalletTx>::iterator mi = pwalletMain->mapWallet.find(hash);
if (mi == pwalletMain->mapWallet.end())
@@ -1451,7 +1448,7 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails
#ifdef __WXMSW__
SetSize(nScaleX * GetSize().GetWidth(), nScaleY * GetSize().GetHeight());
#endif
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+ CRITICAL_BLOCK(pwalletMain->cs_wallet)
{
string strHTML;
strHTML.reserve(4000);
@@ -1662,7 +1659,7 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails
strHTML += HtmlEscape(wtx.ToString(), true);
strHTML += "<br><b>Inputs:</b><br>";
- CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
+ CRITICAL_BLOCK(pwalletMain->cs_wallet)
{
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
{
@@ -2160,38 +2157,42 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event)
if (fBitcoinAddress)
{
+ bool fWasLocked = pwalletMain->IsLocked();
+ if (!GetWalletPassphrase())
+ return;
+
+ string strError;
CRITICAL_BLOCK(cs_main)
- CRITICAL_BLOCK(pwalletMain->cs_vMasterKey)
+ CRITICAL_BLOCK(pwalletMain->cs_wallet)
{
- bool fWasLocked = pwalletMain->IsLocked();
- if (!GetWalletPassphrase())
- return;
-
// Send to bitcoin address
CScript scriptPubKey;
scriptPubKey.SetBitcoinAddress(address);
- string strError = pwalletMain->SendMoney(scriptPubKey, nValue, wtx, true);
- if (strError == "")
- wxMessageBox(_("Payment sent "), _("Sending..."));
- else if (strError == "ABORTED")
- {
- if (fWasLocked)
- pwalletMain->Lock();
- return; // leave send dialog open
- }
- else
- {
- wxMessageBox(strError + " ", _("Sending..."));
- EndModal(false);
- if (fWasLocked)
- pwalletMain->Lock();
- return;
- }
-
+ strError = pwalletMain->SendMoney(scriptPubKey, nValue, wtx, true);
+ }
+ if (strError == "")
+ {
+ pframeMain->RefreshListCtrl();
+ wxMessageBox(_("Payment sent "), _("Sending..."));
+ }
+ else if (strError == "ABORTED")
+ {
+ if (fWasLocked)
+ pwalletMain->Lock();
+ return; // leave send dialog open
+ }
+ else
+ {
+ wxMessageBox(strError + " ", _("Sending..."));
+ EndModal(false);
if (fWasLocked)
pwalletMain->Lock();
- }
+ return;
+ }
+
+ if (fWasLocked)
+ pwalletMain->Lock();
}
else
{
@@ -2212,7 +2213,7 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event)
return;
}
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+ CRITICAL_BLOCK(pwalletMain->cs_wallet)
if (!pwalletMain->mapAddressBook.count(address))
pwalletMain->SetAddressBookName(strAddress, "");
@@ -2464,83 +2465,89 @@ void CSendingDialog::OnReply2(CDataStream& vRecv)
return;
}
- CRITICAL_BLOCK(cs_main)
+ // Pay
+ if (!Status(_("Creating transaction...")))
+ return;
+ if (nPrice + nTransactionFee > pwalletMain->GetBalance())
{
- // Pay
- if (!Status(_("Creating transaction...")))
- return;
- if (nPrice + nTransactionFee > pwalletMain->GetBalance())
- {
- Error(_("Insufficient funds"));
- return;
- }
+ Error(_("Insufficient funds"));
+ return;
+ }
- CReserveKey reservekey(pwalletMain);
- int64 nFeeRequired;
- CRITICAL_BLOCK(pwalletMain->cs_vMasterKey)
- {
- bool fWasLocked = pwalletMain->IsLocked();
- if (!GetWalletPassphrase())
- return;
+ CReserveKey reservekey(pwalletMain);
+ int64 nFeeRequired;
+ bool fWasLocked = pwalletMain->IsLocked();
+ if (!GetWalletPassphrase())
+ return;
- if (!pwalletMain->CreateTransaction(scriptPubKey, nPrice, wtx, reservekey, nFeeRequired))
- {
- if (nPrice + nFeeRequired > pwalletMain->GetBalance())
- Error(strprintf(_("This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds"), FormatMoney(nFeeRequired).c_str()));
- else
- Error(_("Transaction creation failed"));
- return;
- }
+ bool fTxCreated = false;
+ CRITICAL_BLOCK(cs_main)
+ CRITICAL_BLOCK(pwalletMain->cs_wallet)
+ {
+ fTxCreated = pwalletMain->CreateTransaction(scriptPubKey, nPrice, wtx, reservekey, nFeeRequired);
+ }
+ if (!fTxCreated)
+ {
+ if (nPrice + nFeeRequired > pwalletMain->GetBalance())
+ Error(strprintf(_("This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds"), FormatMoney(nFeeRequired).c_str()));
+ else
+ Error(_("Transaction creation failed"));
+ return;
+ }
- if (fWasLocked)
- pwalletMain->Lock();
- }
+ if (fWasLocked)
+ pwalletMain->Lock();
- // Transaction fee
- if (!ThreadSafeAskFee(nFeeRequired, _("Sending..."), this))
- {
- Error(_("Transaction aborted"));
- return;
- }
+ // Transaction fee
+ if (!ThreadSafeAskFee(nFeeRequired, _("Sending..."), this))
+ {
+ Error(_("Transaction aborted"));
+ return;
+ }
- // Make sure we're still connected
- CNode* pnode = ConnectNode(addr, 2 * 60 * 60);
- if (!pnode)
- {
- Error(_("Lost connection, transaction cancelled"));
- return;
- }
+ // Make sure we're still connected
+ CNode* pnode = ConnectNode(addr, 2 * 60 * 60);
+ if (!pnode)
+ {
+ Error(_("Lost connection, transaction cancelled"));
+ return;
+ }
- // Last chance to cancel
- Sleep(50);
+ // Last chance to cancel
+ Sleep(50);
+ if (!Status())
+ return;
+ fCanCancel = false;
+ if (fAbort)
+ {
+ fCanCancel = true;
if (!Status())
return;
fCanCancel = false;
- if (fAbort)
- {
- fCanCancel = true;
- if (!Status())
- return;
- fCanCancel = false;
- }
- if (!Status(_("Sending payment...")))
- return;
+ }
+ if (!Status(_("Sending payment...")))
+ return;
- // Commit
- if (!pwalletMain->CommitTransaction(wtx, reservekey))
- {
- 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."));
- return;
- }
+ // Commit
+ bool fTxCommitted = false;
+ CRITICAL_BLOCK(cs_main)
+ CRITICAL_BLOCK(pwalletMain->cs_wallet)
+ {
+ fTxCommitted = pwalletMain->CommitTransaction(wtx, reservekey);
+ }
+ if (!fTxCommitted)
+ {
+ 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."));
+ return;
+ }
- // Send payment tx to seller, with response going to OnReply3 via event handler
- CWalletTx wtxSend = wtx;
- wtxSend.fFromMe = false;
- pnode->PushRequest("submitorder", wtxSend, SendingDialogOnReply3, this);
+ // Send payment tx to seller, with response going to OnReply3 via event handler
+ CWalletTx wtxSend = wtx;
+ wtxSend.fFromMe = false;
+ pnode->PushRequest("submitorder", wtxSend, SendingDialogOnReply3, this);
- Status(_("Waiting for confirmation..."));
- MainFrameRepaint();
- }
+ Status(_("Waiting for confirmation..."));
+ MainFrameRepaint();
}
void SendingDialogOnReply3(void* parg, CDataStream& vRecv)
@@ -2621,8 +2628,7 @@ CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInit
m_listCtrlReceiving->SetFocus();
// Fill listctrl with address book data
- CRITICAL_BLOCK(pwalletMain->cs_KeyStore)
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+ CRITICAL_BLOCK(pwalletMain->cs_wallet)
{
string strDefaultReceiving = (string)pframeMain->m_textCtrlAddress->GetValue();
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
@@ -2683,7 +2689,7 @@ void CAddressBookDialog::OnListEndLabelEdit(wxListEvent& event)
if (event.IsEditCancelled())
return;
string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1);
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+ CRITICAL_BLOCK(pwalletMain->cs_wallet)
pwalletMain->SetAddressBookName(strAddress, string(event.GetText()));
pframeMain->RefreshListCtrl();
}
@@ -2719,7 +2725,7 @@ void CAddressBookDialog::OnButtonDelete(wxCommandEvent& event)
if (m_listCtrl->GetItemState(nIndex, wxLIST_STATE_SELECTED))
{
string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1);
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+ CRITICAL_BLOCK(pwalletMain->cs_wallet)
pwalletMain->DelAddressBookName(strAddress);
m_listCtrl->DeleteItem(nIndex);
}
@@ -2779,7 +2785,7 @@ void CAddressBookDialog::OnButtonEdit(wxCommandEvent& event)
}
// Write back
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+ CRITICAL_BLOCK(pwalletMain->cs_wallet)
{
if (strAddress != strAddressOrg)
pwalletMain->DelAddressBookName(strAddressOrg);
@@ -2819,22 +2825,21 @@ void CAddressBookDialog::OnButtonNew(wxCommandEvent& event)
return;
strName = dialog.GetValue();
- CRITICAL_BLOCK(pwalletMain->cs_vMasterKey)
- {
- bool fWasLocked = pwalletMain->IsLocked();
- if (!GetWalletPassphrase())
- return;
+ bool fWasLocked = pwalletMain->IsLocked();
+ if (!GetWalletPassphrase())
+ return;
- // Generate new key
- strAddress = CBitcoinAddress(pwalletMain->GetOrReuseKeyFromPool()).ToString();
+ // Generate new key
+ std::vector<unsigned char> newKey;
+ pwalletMain->GetKeyFromPool(newKey, true);
+ strAddress = CBitcoinAddress(newKey).ToString();
- if (fWasLocked)
- pwalletMain->Lock();
- }
+ if (fWasLocked)
+ pwalletMain->Lock();
}
// Add to list and select it
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+ CRITICAL_BLOCK(pwalletMain->cs_wallet)
pwalletMain->SetAddressBookName(strAddress, strName);
int nIndex = InsertLine(m_listCtrl, strName, strAddress);
SetSelection(m_listCtrl, nIndex);
diff --git a/src/util.cpp b/src/util.cpp
index 974e54c391..3c53771baf 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -940,17 +940,21 @@ static std::map<std::pair<CCriticalSection*, CCriticalSection*>, LockStack> lock
static boost::thread_specific_ptr<LockStack> lockstack;
-static void potential_deadlock_detected(const LockStack& s1, const LockStack& s2)
+static void potential_deadlock_detected(const std::pair<CCriticalSection*, CCriticalSection*>& mismatch, const LockStack& s1, const LockStack& s2)
{
printf("POTENTIAL DEADLOCK DETECTED\n");
printf("Previous lock order was:\n");
BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, CLockLocation)& i, s2)
{
+ if (i.first == mismatch.first) printf(" (1)");
+ if (i.first == mismatch.second) printf(" (2)");
printf(" %s %s:%d\n", i.second.mutexName.c_str(), i.second.sourceFile.c_str(), i.second.sourceLine);
}
printf("Current lock order is:\n");
BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, CLockLocation)& i, s1)
{
+ if (i.first == mismatch.first) printf(" (1)");
+ if (i.first == mismatch.second) printf(" (2)");
printf(" %s %s:%d\n", i.second.mutexName.c_str(), i.second.sourceFile.c_str(), i.second.sourceLine);
}
}
@@ -977,7 +981,7 @@ static void push_lock(CCriticalSection* c, const CLockLocation& locklocation)
std::pair<CCriticalSection*, CCriticalSection*> p2 = std::make_pair(c, i.first);
if (lockorders.count(p2))
{
- potential_deadlock_detected(lockorders[p2], lockorders[p1]);
+ potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]);
break;
}
}
diff --git a/src/util.h b/src/util.h
index 7fd224cbe7..fabcaf9303 100644
--- a/src/util.h
+++ b/src/util.h
@@ -67,14 +67,6 @@ typedef unsigned long long uint64;
// This is needed because the foreach macro can't get over the comma in pair<t1, t2>
#define PAIRTYPE(t1, t2) std::pair<t1, t2>
-// Used to bypass the rule against non-const reference to temporary
-// where it makes sense with wrappers such as CFlatData or CTxDB
-template<typename T>
-inline T& REF(const T& val)
-{
- return (T&)val;
-}
-
// Align by increasing pointer, must have extra space at end of buffer
template <size_t nBytes, typename T>
T* alignup(T* p)
diff --git a/src/wallet.cpp b/src/wallet.cpp
index 076a9f8eed..9c04e37fe6 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -33,7 +33,7 @@ bool CWallet::AddCryptedKey(const vector<unsigned char> &vchPubKey, const vector
return false;
if (!fFileBacked)
return true;
- CRITICAL_BLOCK(cs_pwalletdbEncryption)
+ CRITICAL_BLOCK(cs_wallet)
{
if (pwalletdbEncryption)
return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret);
@@ -44,14 +44,13 @@ bool CWallet::AddCryptedKey(const vector<unsigned char> &vchPubKey, const vector
bool CWallet::Unlock(const string& strWalletPassphrase)
{
- CRITICAL_BLOCK(cs_vMasterKey)
- {
- if (!IsLocked())
- return false;
+ if (!IsLocked())
+ return false;
- CCrypter crypter;
- CKeyingMaterial vMasterKey;
+ CCrypter crypter;
+ CKeyingMaterial vMasterKey;
+ CRITICAL_BLOCK(cs_wallet)
BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
{
if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
@@ -61,16 +60,15 @@ bool CWallet::Unlock(const string& strWalletPassphrase)
if (CCryptoKeyStore::Unlock(vMasterKey))
return true;
}
- }
return false;
}
bool CWallet::ChangeWalletPassphrase(const string& strOldWalletPassphrase, const string& strNewWalletPassphrase)
{
- CRITICAL_BLOCK(cs_vMasterKey)
- {
- bool fWasLocked = IsLocked();
+ bool fWasLocked = IsLocked();
+ CRITICAL_BLOCK(cs_wallet)
+ {
Lock();
CCrypter crypter;
@@ -79,7 +77,7 @@ bool CWallet::ChangeWalletPassphrase(const string& strOldWalletPassphrase, const
{
if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
return false;
- if(!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
+ if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
return false;
if (CCryptoKeyStore::Unlock(vMasterKey))
{
@@ -107,6 +105,7 @@ bool CWallet::ChangeWalletPassphrase(const string& strOldWalletPassphrase, const
}
}
}
+
return false;
}
@@ -125,44 +124,42 @@ public:
bool CWallet::EncryptWallet(const string& strWalletPassphrase)
{
- CRITICAL_BLOCK(cs_KeyStore)
- CRITICAL_BLOCK(cs_vMasterKey)
- CRITICAL_BLOCK(cs_pwalletdbEncryption)
- {
- if (IsCrypted())
- return false;
+ if (IsCrypted())
+ return false;
- CKeyingMaterial vMasterKey;
- RandAddSeedPerfmon();
+ CKeyingMaterial vMasterKey;
+ RandAddSeedPerfmon();
- vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
- RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
+ vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
+ RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
- CMasterKey kMasterKey;
+ CMasterKey kMasterKey;
- RandAddSeedPerfmon();
- kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
- RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
+ RandAddSeedPerfmon();
+ kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
+ RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
- CCrypter crypter;
- int64 nStartTime = GetTimeMillis();
- crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
- kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime));
+ CCrypter crypter;
+ int64 nStartTime = GetTimeMillis();
+ crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
+ kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime));
- nStartTime = GetTimeMillis();
- crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
- kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
+ nStartTime = GetTimeMillis();
+ crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
+ kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
- if (kMasterKey.nDeriveIterations < 25000)
- kMasterKey.nDeriveIterations = 25000;
+ if (kMasterKey.nDeriveIterations < 25000)
+ kMasterKey.nDeriveIterations = 25000;
- printf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
+ printf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
- if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
- return false;
- if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
- return false;
+ if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
+ return false;
+ if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
+ return false;
+ CRITICAL_BLOCK(cs_wallet)
+ {
mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
if (fFileBacked)
{
@@ -191,6 +188,7 @@ bool CWallet::EncryptWallet(const string& strWalletPassphrase)
Lock();
}
+
return true;
}
@@ -199,7 +197,7 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx)
// Anytime a signature is successfully verified, it's proof the outpoint is spent.
// Update the wallet spent flag if it doesn't know due to wallet.dat being
// restored from backup or the user making copies of wallet.dat.
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(cs_wallet)
{
BOOST_FOREACH(const CTxIn& txin, tx.vin)
{
@@ -222,7 +220,7 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx)
bool CWallet::AddToWallet(const CWalletTx& wtxIn)
{
uint256 hash = wtxIn.GetHash();
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(cs_wallet)
{
// Inserts only if not already there, returns tx inserted or tx found
pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
@@ -270,8 +268,12 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
{
if (txout.scriptPubKey == scriptDefaultKey)
{
- SetDefaultKey(GetOrReuseKeyFromPool());
- SetAddressBookName(CBitcoinAddress(vchDefaultKey), "");
+ std::vector<unsigned char> newDefaultKey;
+ if (GetKeyFromPool(newDefaultKey, false))
+ {
+ SetDefaultKey(newDefaultKey);
+ SetAddressBookName(CBitcoinAddress(vchDefaultKey), "");
+ }
}
}
#endif
@@ -290,18 +292,21 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate)
{
uint256 hash = tx.GetHash();
- bool fExisted = mapWallet.count(hash);
- if (fExisted && !fUpdate) return false;
- if (fExisted || IsMine(tx) || IsFromMe(tx))
+ CRITICAL_BLOCK(cs_wallet)
{
- CWalletTx wtx(this,tx);
- // Get merkle branch if transaction was found in a block
- if (pblock)
- wtx.SetMerkleBranch(pblock);
- return AddToWallet(wtx);
+ bool fExisted = mapWallet.count(hash);
+ if (fExisted && !fUpdate) return false;
+ if (fExisted || IsMine(tx) || IsFromMe(tx))
+ {
+ CWalletTx wtx(this,tx);
+ // Get merkle branch if transaction was found in a block
+ if (pblock)
+ wtx.SetMerkleBranch(pblock);
+ return AddToWallet(wtx);
+ }
+ else
+ WalletUpdateSpent(tx);
}
- else
- WalletUpdateSpent(tx);
return false;
}
@@ -309,7 +314,7 @@ bool CWallet::EraseFromWallet(uint256 hash)
{
if (!fFileBacked)
return false;
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(cs_wallet)
{
if (mapWallet.erase(hash))
CWalletDB(strWalletFile).EraseTx(hash);
@@ -320,7 +325,7 @@ bool CWallet::EraseFromWallet(uint256 hash)
bool CWallet::IsMine(const CTxIn &txin) const
{
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(cs_wallet)
{
map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
if (mi != mapWallet.end())
@@ -336,7 +341,7 @@ bool CWallet::IsMine(const CTxIn &txin) const
int64 CWallet::GetDebit(const CTxIn &txin) const
{
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(cs_wallet)
{
map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
if (mi != mapWallet.end())
@@ -352,19 +357,6 @@ int64 CWallet::GetDebit(const CTxIn &txin) const
int64 CWalletTx::GetTxTime() const
{
- if (!fTimeReceivedIsTxTime && hashBlock != 0)
- {
- // If we did not receive the transaction directly, we rely on the block's
- // time to figure out when it happened. We use the median over a range
- // of blocks to try to filter out inaccurate block times.
- map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
- if (mi != mapBlockIndex.end())
- {
- CBlockIndex* pindex = (*mi).second;
- if (pindex)
- return pindex->GetMedianTime();
- }
- }
return nTimeReceived;
}
@@ -372,7 +364,7 @@ int CWalletTx::GetRequestCount() const
{
// Returns -1 if it wasn't being tracked
int nRequests = -1;
- CRITICAL_BLOCK(pwallet->cs_mapRequestCount)
+ CRITICAL_BLOCK(pwallet->cs_wallet)
{
if (IsCoinBase())
{
@@ -478,7 +470,7 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, i
nSent += s.second;
nFee = allFee;
}
- CRITICAL_BLOCK(pwallet->cs_mapAddressBook)
+ CRITICAL_BLOCK(pwallet->cs_wallet)
{
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived)
{
@@ -508,7 +500,7 @@ void CWalletTx::AddSupportingTransactions(CTxDB& txdb)
vWorkQueue.push_back(txin.prevout.hash);
// This critsect is OK because txdb is already open
- CRITICAL_BLOCK(pwallet->cs_mapWallet)
+ CRITICAL_BLOCK(pwallet->cs_wallet)
{
map<uint256, const CMerkleTx*> mapWalletPrev;
set<uint256> setAlreadyDone;
@@ -564,7 +556,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
int ret = 0;
CBlockIndex* pindex = pindexStart;
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(cs_wallet)
{
while (pindex)
{
@@ -585,7 +577,7 @@ void CWallet::ReacceptWalletTransactions()
{
CTxDB txdb("r");
bool fRepeat = true;
- while (fRepeat) CRITICAL_BLOCK(cs_mapWallet)
+ while (fRepeat) CRITICAL_BLOCK(cs_wallet)
{
fRepeat = false;
vector<CDiskTxPos> vMissingTx;
@@ -688,7 +680,7 @@ void CWallet::ResendWalletTransactions()
// Rebroadcast any of our txes that aren't in a block yet
printf("ResendWalletTransactions()\n");
CTxDB txdb("r");
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(cs_wallet)
{
// Sort them in chronological order
multimap<unsigned int, CWalletTx*> mapSorted;
@@ -722,7 +714,7 @@ void CWallet::ResendWalletTransactions()
int64 CWallet::GetBalance() const
{
int64 nTotal = 0;
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(cs_wallet)
{
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
{
@@ -764,7 +756,7 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe
vector<pair<int64, pair<const CWalletTx*,unsigned int> > > vValue;
int64 nTotalLower = 0;
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(cs_wallet)
{
vector<const CWalletTx*> vCoins;
vCoins.reserve(mapWallet.size());
@@ -922,10 +914,10 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CW
wtxNew.pwallet = this;
CRITICAL_BLOCK(cs_main)
+ CRITICAL_BLOCK(cs_wallet)
{
// txdb must be opened before the mapWallet lock
CTxDB txdb("r");
- CRITICAL_BLOCK(cs_mapWallet)
{
nFeeRet = nTransactionFee;
loop
@@ -1036,9 +1028,9 @@ bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& w
bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
{
CRITICAL_BLOCK(cs_main)
+ CRITICAL_BLOCK(cs_wallet)
{
printf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
- CRITICAL_BLOCK(cs_mapWallet)
{
// This is only to keep the database open to defeat the auto-flush for the
// duration of this scope. This is the only place where this optimization
@@ -1068,8 +1060,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
}
// Track how many getdata requests our transaction gets
- CRITICAL_BLOCK(cs_mapRequestCount)
- mapRequestCount[wtxNew.GetHash()] = 0;
+ mapRequestCount[wtxNew.GetHash()] = 0;
// Broadcast
if (!wtxNew.AcceptToMemoryPool())
@@ -1087,29 +1078,26 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
-// requires cs_main lock
string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
{
CReserveKey reservekey(this);
int64 nFeeRequired;
- CRITICAL_BLOCK(cs_vMasterKey)
+
+ if (IsLocked())
{
- if (IsLocked())
- {
- string strError = _("Error: Wallet locked, unable to create transaction ");
- printf("SendMoney() : %s", strError.c_str());
- return strError;
- }
- if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired))
- {
- string strError;
- if (nValue + nFeeRequired > GetBalance())
- strError = strprintf(_("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds "), FormatMoney(nFeeRequired).c_str());
- else
- strError = _("Error: Transaction creation failed ");
- printf("SendMoney() : %s", strError.c_str());
- return strError;
- }
+ string strError = _("Error: Wallet locked, unable to create transaction ");
+ printf("SendMoney() : %s", strError.c_str());
+ return strError;
+ }
+ if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired))
+ {
+ string strError;
+ if (nValue + nFeeRequired > GetBalance())
+ strError = strprintf(_("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds "), FormatMoney(nFeeRequired).c_str());
+ else
+ strError = _("Error: Transaction creation failed ");
+ printf("SendMoney() : %s", strError.c_str());
+ return strError;
}
if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."), NULL))
@@ -1124,7 +1112,6 @@ string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew,
-// requires cs_main lock
string CWallet::SendMoneyToBitcoinAddress(const CBitcoinAddress& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
{
// Check amount
@@ -1158,7 +1145,10 @@ int CWallet::LoadWallet(bool& fFirstRunRet)
// Create new keyUser and set as default key
RandAddSeedPerfmon();
- SetDefaultKey(GetOrReuseKeyFromPool());
+ std::vector<unsigned char> newDefaultKey;
+ if (!GetKeyFromPool(newDefaultKey, false))
+ return DB_LOAD_FAIL;
+ SetDefaultKey(newDefaultKey);
if (!SetAddressBookName(CBitcoinAddress(vchDefaultKey), ""))
return DB_LOAD_FAIL;
}
@@ -1187,7 +1177,7 @@ bool CWallet::DelAddressBookName(const CBitcoinAddress& address)
void CWallet::PrintWallet(const CBlock& block)
{
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(cs_wallet)
{
if (mapWallet.count(block.vtx[0].GetHash()))
{
@@ -1200,7 +1190,7 @@ void CWallet::PrintWallet(const CBlock& block)
bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx)
{
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(cs_wallet)
{
map<uint256, CWalletTx>::iterator mi = mapWallet.find(hashTx);
if (mi != mapWallet.end())
@@ -1233,10 +1223,7 @@ bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut)
bool CWallet::TopUpKeyPool()
{
- CRITICAL_BLOCK(cs_main)
- CRITICAL_BLOCK(cs_mapWallet)
- CRITICAL_BLOCK(cs_setKeyPool)
- CRITICAL_BLOCK(cs_vMasterKey)
+ CRITICAL_BLOCK(cs_wallet)
{
if (IsLocked())
return false;
@@ -1263,9 +1250,7 @@ void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
{
nIndex = -1;
keypool.vchPubKey.clear();
- CRITICAL_BLOCK(cs_main)
- CRITICAL_BLOCK(cs_mapWallet)
- CRITICAL_BLOCK(cs_setKeyPool)
+ CRITICAL_BLOCK(cs_wallet)
{
if (!IsLocked())
TopUpKeyPool();
@@ -1293,10 +1278,7 @@ void CWallet::KeepKey(int64 nIndex)
if (fFileBacked)
{
CWalletDB walletdb(strWalletFile);
- CRITICAL_BLOCK(cs_main)
- {
- walletdb.ErasePool(nIndex);
- }
+ walletdb.ErasePool(nIndex);
}
printf("keypool keep %"PRI64d"\n", nIndex);
}
@@ -1304,20 +1286,33 @@ void CWallet::KeepKey(int64 nIndex)
void CWallet::ReturnKey(int64 nIndex)
{
// Return to key pool
- CRITICAL_BLOCK(cs_setKeyPool)
+ CRITICAL_BLOCK(cs_wallet)
setKeyPool.insert(nIndex);
printf("keypool return %"PRI64d"\n", nIndex);
}
-vector<unsigned char> CWallet::GetOrReuseKeyFromPool()
+bool CWallet::GetKeyFromPool(vector<unsigned char>& result, bool fAllowReuse)
{
int64 nIndex = 0;
CKeyPool keypool;
- ReserveKeyFromKeyPool(nIndex, keypool);
- if(nIndex == -1)
- return vchDefaultKey;
- KeepKey(nIndex);
- return keypool.vchPubKey;
+ CRITICAL_BLOCK(cs_wallet)
+ {
+ ReserveKeyFromKeyPool(nIndex, keypool);
+ if (nIndex == -1)
+ {
+ if (fAllowReuse && !vchDefaultKey.empty())
+ {
+ result = vchDefaultKey;
+ return true;
+ }
+ if (IsLocked()) return false;
+ result = GenerateNewKey();
+ return true;
+ }
+ KeepKey(nIndex);
+ result = keypool.vchPubKey;
+ }
+ return true;
}
int64 CWallet::GetOldestKeyPoolTime()
diff --git a/src/wallet.h b/src/wallet.h
index cc1dde5b0f..b6df1aa0e1 100644
--- a/src/wallet.h
+++ b/src/wallet.h
@@ -20,14 +20,14 @@ private:
bool SelectCoins(int64 nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
CWalletDB *pwalletdbEncryption;
- CCriticalSection cs_pwalletdbEncryption;
public:
+ mutable CCriticalSection cs_wallet;
+
bool fFileBacked;
std::string strWalletFile;
std::set<int64> setKeyPool;
- CCriticalSection cs_setKeyPool;
typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
MasterKeyMap mapMasterKeys;
@@ -47,15 +47,12 @@ public:
pwalletdbEncryption = NULL;
}
- mutable CCriticalSection cs_mapWallet;
std::map<uint256, CWalletTx> mapWallet;
std::vector<uint256> vWalletUpdated;
std::map<uint256, int> mapRequestCount;
- mutable CCriticalSection cs_mapRequestCount;
std::map<CBitcoinAddress, std::string> mapAddressBook;
- mutable CCriticalSection cs_mapAddressBook;
std::vector<unsigned char> vchDefaultKey;
@@ -89,7 +86,7 @@ public:
void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool);
void KeepKey(int64 nIndex);
void ReturnKey(int64 nIndex);
- std::vector<unsigned char> GetOrReuseKeyFromPool();
+ bool GetKeyFromPool(std::vector<unsigned char> &key, bool fAllowReuse=true);
int64 GetOldestKeyPoolTime();
bool IsMine(const CTxIn& txin) const;
@@ -108,7 +105,7 @@ public:
{
CBitcoinAddress address;
if (ExtractAddress(txout.scriptPubKey, this, address))
- CRITICAL_BLOCK(cs_mapAddressBook)
+ CRITICAL_BLOCK(cs_wallet)
if (!mapAddressBook.count(address))
return true;
return false;
@@ -172,15 +169,13 @@ public:
int LoadWallet(bool& fFirstRunRet);
// bool BackupWallet(const std::string& strDest);
- // requires cs_mapAddressBook lock
bool SetAddressBookName(const CBitcoinAddress& address, const std::string& strName);
- // requires cs_mapAddressBook lock
bool DelAddressBookName(const CBitcoinAddress& address);
void UpdatedTransaction(const uint256 &hashTx)
{
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(cs_wallet)
vWalletUpdated.push_back(hashTx);
}
@@ -188,7 +183,7 @@ public:
void Inventory(const uint256 &hash)
{
- CRITICAL_BLOCK(cs_mapRequestCount)
+ CRITICAL_BLOCK(cs_wallet)
{
std::map<uint256, int>::iterator mi = mapRequestCount.find(hash);
if (mi != mapRequestCount.end())