// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2009-2012 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.
obj.push_back(Pair("keypoolsize", pwalletMain->GetKeyPoolSize()));
obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee)));
if (pwalletMain->IsCrypted())
- obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime));
+ obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime / 1000));
obj.push_back(Pair("errors", GetWarnings("statusbar")));
return obj;
}
"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
- string strAddress = PubKeyToAddress(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(strAddress, strAccount);
+ pwalletMain->SetAddressBookName(address, strAccount);
- return strAddress;
+ return address.ToString();
}
-// requires cs_main, cs_mapWallet, cs_mapAddressBook locks
-string GetAccountAddress(string strAccount, bool bForceNew=false)
+CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
{
- string strAddress;
-
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())
- {
- 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;
- }
- }
-
- // Generate a new key
- if (account.vchPubKey.empty() || bForceNew || bKeyUsed)
+ // 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)
{
- if (pwalletMain->GetKeyPoolSize() < 1)
- {
- if (bKeyUsed || bForceNew)
- throw JSONRPCError(-12, "Error: Keypool ran out, please call topupkeypool first");
- }
- else
- {
- account.vchPubKey = pwalletMain->GetOrReuseKeyFromPool();
- string strAddress = PubKeyToAddress(account.vchPubKey);
- pwalletMain->SetAddressBookName(strAddress, strAccount);
- walletdb.WriteAccount(strAccount, account);
- }
+ const CWalletTx& wtx = (*it).second;
+ BOOST_FOREACH(const CTxOut& txout, wtx.vout)
+ if (txout.scriptPubKey == scriptPubKey)
+ bKeyUsed = true;
}
}
- strAddress = PubKeyToAddress(account.vchPubKey);
+ // 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 strAddress;
+ return CBitcoinAddress(account.vchPubKey);
}
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);
- }
+ ret = GetAccountAddress(strAccount).ToString();
return ret;
}
"setaccount <bitcoinaddress> <account>\n"
"Sets the account associated with the given address.");
- string strAddress = params[0].get_str();
- uint160 hash160;
- bool isValid = AddressToHash160(strAddress, hash160);
- if (!isValid)
+ CBitcoinAddress address(params[0].get_str());
+ if (!address.IsValid())
throw JSONRPCError(-5, "Invalid bitcoin address");
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(strAddress))
- {
- string strOldAccount = pwalletMain->mapAddressBook[strAddress];
- if (strAddress == GetAccountAddress(strOldAccount))
- GetAccountAddress(strOldAccount, true);
- }
-
- pwalletMain->SetAddressBookName(strAddress, strAccount);
+ string strOldAccount = pwalletMain->mapAddressBook[address];
+ if (address == GetAccountAddress(strOldAccount))
+ GetAccountAddress(strOldAccount, true);
}
+ pwalletMain->SetAddressBookName(address, strAccount);
+
return Value::null;
}
"getaccount <bitcoinaddress>\n"
"Returns the account associated with the given address.");
- string strAddress = params[0].get_str();
+ CBitcoinAddress address(params[0].get_str());
+ if (!address.IsValid())
+ throw JSONRPCError(-5, "Invalid bitcoin address");
string strAccount;
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
- {
- map<string, string>::iterator mi = pwalletMain->mapAddressBook.find(strAddress);
- 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;
}
// 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(string, string)& item, pwalletMain->mapAddressBook)
- {
- const string& strAddress = item.first;
- const string& strName = item.second;
- if (strName == strAccount)
- {
- // We're only adding valid bitcoin addresses and not ip addresses
- CScript scriptPubKey;
- if (scriptPubKey.SetBitcoinAddress(strAddress))
- ret.push_back(strAddress);
- }
- }
+ const CBitcoinAddress& address = item.first;
+ const string& strName = item.second;
+ if (strName == strAccount)
+ ret.push_back(address.ToString());
}
return ret;
}
"sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to]\n"
"<amount> is a real and is rounded to the nearest 0.00000001");
- string strAddress = params[0].get_str();
+ CBitcoinAddress address(params[0].get_str());
+ if (!address.IsValid())
+ throw JSONRPCError(-5, "Invalid bitcoin address");
// Amount
int64 nAmount = AmountFromValue(params[1]);
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(strAddress, 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();
}
"Returns the total amount received by <bitcoinaddress> in transactions with at least [minconf] confirmations.");
// Bitcoin address
- string strAddress = params[0].get_str();
+ CBitcoinAddress address = CBitcoinAddress(params[0].get_str());
CScript scriptPubKey;
- if (!scriptPubKey.SetBitcoinAddress(strAddress))
+ if (!address.IsValid())
throw JSONRPCError(-5, "Invalid bitcoin address");
+ scriptPubKey.SetBitcoinAddress(address);
if (!IsMine(*pwalletMain,scriptPubKey))
return (double)0.0;
// 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);
}
-void GetAccountPubKeys(string strAccount, set<CScript>& setPubKey)
+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(string, string)& item, pwalletMain->mapAddressBook)
- {
- const string& strAddress = item.first;
- const string& strName = item.second;
- if (strName == strAccount)
- {
- // We're only counting our own valid bitcoin addresses and not ip addresses
- CScript scriptPubKey;
- if (scriptPubKey.SetBitcoinAddress(strAddress))
- if (IsMine(*pwalletMain,scriptPubKey))
- setPubKey.insert(scriptPubKey);
- }
- }
+ const CBitcoinAddress& address = item.first;
+ const string& strName = item.second;
+ if (strName == strAccount)
+ setAddress.insert(address);
}
}
// Get the set of pub keys that have the label
string strAccount = AccountFromValue(params[0]);
- set<CScript> setPubKey;
- GetAccountPubKeys(strAccount, setPubKey);
+ set<CBitcoinAddress> setAddress;
+ GetAccountAddresses(strAccount, setAddress);
// 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 (setPubKey.count(txout.scriptPubKey))
- 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;
}
}
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;
}
int64 allGeneratedImmature, allGeneratedMature, allFee;
allGeneratedImmature = allGeneratedMature = allFee = 0;
string strSentAccount;
- list<pair<string, int64> > listReceived;
- list<pair<string, int64> > listSent;
+ list<pair<CBitcoinAddress, int64> > listReceived;
+ list<pair<CBitcoinAddress, int64> > listSent;
wtx.GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount);
if (wtx.GetDepthInMainChain() >= nMinDepth)
- BOOST_FOREACH(const PAIRTYPE(string,int64)& r, listReceived)
+ BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived)
nBalance += r.second;
- BOOST_FOREACH(const PAIRTYPE(string,int64)& r, listSent)
+ BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listSent)
nBalance -= r.second;
nBalance -= allFee;
nBalance += allGeneratedMature;
string strFrom = AccountFromValue(params[0]);
string strTo = AccountFromValue(params[1]);
int64 nAmount = AmountFromValue(params[2]);
- int nMinDepth = 1;
if (params.size() > 3)
- nMinDepth = params[3].get_int();
+ // unused parameter, used to be nMinDepth, keep type-checking it though
+ (void)params[3].get_int();
string strComment;
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;
}
"<amount> is a real and is rounded to the nearest 0.00000001");
string strAccount = AccountFromValue(params[0]);
- string strAddress = params[1].get_str();
+ CBitcoinAddress address(params[1].get_str());
+ if (!address.IsValid())
+ throw JSONRPCError(-5, "Invalid bitcoin address");
int64 nAmount = AmountFromValue(params[2]);
int nMinDepth = 1;
if (params.size() > 3)
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(strAddress, 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();
}
if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty())
wtx.mapValue["comment"] = params[3].get_str();
- set<string> setAddress;
+ set<CBitcoinAddress> setAddress;
vector<pair<CScript, int64> > vecSend;
int64 totalAmount = 0;
BOOST_FOREACH(const Pair& s, sendTo)
{
- uint160 hash160;
- string strAddress = s.name_;
+ CBitcoinAddress address(s.name_);
+ if (!address.IsValid())
+ throw JSONRPCError(-5, string("Invalid bitcoin address:")+s.name_);
- if (setAddress.count(strAddress))
- throw JSONRPCError(-8, string("Invalid parameter, duplicated address: ")+strAddress);
- setAddress.insert(strAddress);
+ if (setAddress.count(address))
+ throw JSONRPCError(-8, string("Invalid parameter, duplicated address: ")+s.name_);
+ setAddress.insert(address);
CScript scriptPubKey;
- if (!scriptPubKey.SetBitcoinAddress(strAddress))
- throw JSONRPCError(-5, string("Invalid bitcoin address:")+strAddress);
+ scriptPubKey.SetBitcoinAddress(address);
int64 nAmount = AmountFromValue(s.value_);
totalAmount += nAmount;
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();
}
fIncludeEmpty = params[1].get_bool();
// Tally
- map<uint160, tallyitem> mapTally;
- CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
+ map<CBitcoinAddress, tallyitem> mapTally;
+ 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)
+ 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)
- {
- // Only counting our own bitcoin addresses and not ip addresses
- uint160 hash160 = txout.scriptPubKey.GetBitcoinAddressHash160();
- if (hash160 == 0 || !mapPubKeys.count(hash160)) // IsMine
- continue;
-
- tallyitem& item = mapTally[hash160];
- 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(string, string)& item, pwalletMain->mapAddressBook)
- {
- const string& strAddress = item.first;
- const string& strAccount = item.second;
- uint160 hash160;
- if (!AddressToHash160(strAddress, hash160))
- continue;
- map<uint160, tallyitem>::iterator it = mapTally.find(hash160);
- 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", strAddress));
- 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);
}
}
{
int64 nGeneratedImmature, nGeneratedMature, nFee;
string strSentAccount;
- list<pair<string, int64> > listReceived;
- list<pair<string, int64> > listSent;
+ list<pair<CBitcoinAddress, int64> > listReceived;
+ list<pair<CBitcoinAddress, int64> > listSent;
wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
bool fAllAccounts = (strAccount == string("*"));
// Sent
if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
{
- BOOST_FOREACH(const PAIRTYPE(string, int64)& s, listSent)
+ BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent)
{
Object entry;
entry.push_back(Pair("account", strSentAccount));
- entry.push_back(Pair("address", s.first));
+ entry.push_back(Pair("address", s.first.ToString()));
entry.push_back(Pair("category", "send"));
entry.push_back(Pair("amount", ValueFromAmount(-s.second)));
entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
// 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(string, 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));
- 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)
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();
- for (std::advance(it, nFrom); 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)
nMinDepth = params[0].get_int();
map<string, int64> mapAccountBalances;
- CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
- {
- BOOST_FOREACH(const PAIRTYPE(string, string)& entry, pwalletMain->mapAddressBook) {
- uint160 hash160;
- if(AddressToHash160(entry.first, hash160) && mapPubKeys.count(hash160)) // 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<string, int64> > listReceived;
- list<pair<string, int64> > listSent;
- wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
- mapAccountBalances[strSentAccount] -= nFee;
- BOOST_FOREACH(const PAIRTYPE(string, int64)& s, listSent)
- mapAccountBalances[strSentAccount] -= s.second;
- if (wtx.GetDepthInMainChain() >= nMinDepth)
- {
- mapAccountBalances[""] += nGeneratedMature;
- BOOST_FOREACH(const PAIRTYPE(string, 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;
}
}
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;
}
"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.");
void ThreadCleanWalletPassphrase(void* parg)
{
- int64 nMyWakeTime = GetTime() + *((int*)parg);
+ int64 nMyWakeTime = GetTimeMillis() + *((int64*)parg) * 1000;
+
+ ENTER_CRITICAL_SECTION(cs_nWalletUnlockTime);
if (nWalletUnlockTime == 0)
{
- CRITICAL_BLOCK(cs_nWalletUnlockTime)
+ nWalletUnlockTime = nMyWakeTime;
+
+ do
{
- nWalletUnlockTime = nMyWakeTime;
- }
+ if (nWalletUnlockTime==0)
+ break;
+ int64 nToSleep = nWalletUnlockTime - GetTimeMillis();
+ if (nToSleep <= 0)
+ break;
+
+ LEAVE_CRITICAL_SECTION(cs_nWalletUnlockTime);
+ Sleep(nToSleep);
+ ENTER_CRITICAL_SECTION(cs_nWalletUnlockTime);
- while (GetTime() < nWalletUnlockTime)
- Sleep(GetTime() - nWalletUnlockTime);
+ } while(1);
- CRITICAL_BLOCK(cs_nWalletUnlockTime)
+ if (nWalletUnlockTime)
{
nWalletUnlockTime = 0;
+ pwalletMain->Lock();
}
}
else
{
- CRITICAL_BLOCK(cs_nWalletUnlockTime)
- {
- if (nWalletUnlockTime < nMyWakeTime)
- nWalletUnlockTime = nMyWakeTime;
- }
- free(parg);
- return;
+ if (nWalletUnlockTime < nMyWakeTime)
+ nWalletUnlockTime = nMyWakeTime;
}
- pwalletMain->Lock();
+ LEAVE_CRITICAL_SECTION(cs_nWalletUnlockTime);
- delete (int*)parg;
+ delete (int64*)parg;
}
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());
+ int64* pnSleepTime = new int64(params[1].get_int64());
CreateThread(ThreadCleanWalletPassphrase, pnSleepTime);
return Value::null;
if (!pwalletMain->IsCrypted())
throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletlock was called.");
- pwalletMain->Lock();
CRITICAL_BLOCK(cs_nWalletUnlockTime)
{
+ pwalletMain->Lock();
nWalletUnlockTime = 0;
}
if (pwalletMain->IsCrypted())
throw JSONRPCError(-15, "Error: running with an encrypted wallet, but encryptwallet was called.");
+#ifdef GUI
+ // shutting down via RPC while the GUI is running does not work (yet):
+ throw runtime_error("Not Yet Implemented: use GUI to encrypt wallet, not RPC command");
+#endif
+
string strWalletPass;
strWalletPass.reserve(100);
mlock(&strWalletPass[0], strWalletPass.capacity());
fill(strWalletPass.begin(), strWalletPass.end(), '\0');
munlock(&strWalletPass[0], strWalletPass.capacity());
- return Value::null;
+ // BDB seems to have a bad habit of writing old data into
+ // slack space in .dat files; that is bad if the old data is
+ // unencrypted private keys. So:
+ CreateThread(Shutdown, NULL);
+ return "wallet encrypted; bitcoin server stopping, restart to run with encrypted wallet";
}
"validateaddress <bitcoinaddress>\n"
"Return information about <bitcoinaddress>.");
- string strAddress = params[0].get_str();
- uint160 hash160;
- bool isValid = AddressToHash160(strAddress, hash160);
+ CBitcoinAddress address(params[0].get_str());
+ bool isValid = address.IsValid();
Object ret;
ret.push_back(Pair("isvalid", isValid));
{
// Call Hash160ToAddress() so we always return current ADDRESSVERSION
// version of the address:
- string currentAddress = Hash160ToAddress(hash160);
+ string currentAddress = address.ToString();
ret.push_back(Pair("address", currentAddress));
- ret.push_back(Pair("ismine", (mapPubKeys.count(hash160) > 0)));
- CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
- {
- if (pwalletMain->mapAddressBook.count(currentAddress))
- ret.push_back(Pair("account", pwalletMain->mapAddressBook[currentAddress]));
- }
+ ret.push_back(Pair("ismine", (pwalletMain->HaveKey(address) > 0)));
+ if (pwalletMain->mapAddressBook.count(address))
+ ret.push_back(Pair("account", pwalletMain->mapAddressBook[address]));
}
return ret;
}
if (IsInitialBlockDownload())
throw JSONRPCError(-10, "Bitcoin is downloading blocks...");
- static map<uint256, pair<CBlock*, unsigned int> > mapNewBlock;
+ typedef map<uint256, pair<CBlock*, CScript> > mapNewBlock_t;
+ static mapNewBlock_t mapNewBlock;
static vector<CBlock*> vNewBlock;
static CReserveKey reservekey(pwalletMain);
}
// Update nTime
- pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+ pblock->UpdateTime(pindexPrev);
pblock->nNonce = 0;
// Update nExtraNonce
static unsigned int nExtraNonce = 0;
- static int64 nPrevTime = 0;
- IncrementExtraNonce(pblock, pindexPrev, nExtraNonce, nPrevTime);
+ IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
// Save
- mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, nExtraNonce);
+ mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig);
// Prebuild hash buffers
char pmidstate[32];
if (!mapNewBlock.count(pdata->hashMerkleRoot))
return false;
CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first;
- unsigned int nExtraNonce = mapNewBlock[pdata->hashMerkleRoot].second;
pblock->nTime = pdata->nTime;
pblock->nNonce = pdata->nNonce;
- pblock->vtx[0].vin[0].scriptSig = CScript() << pblock->nBits << CBigNum(nExtraNonce);
+ pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second;
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
return CheckWork(pblock, *pwalletMain, reservekey);
"getinfo",
"getnewaddress",
"getaccountaddress",
- "setlabel",
+ "setlabel", // deprecated
"getaccount",
"getlabel", // deprecated
"getaddressesbyaccount",
if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
{
+ unsigned char rand_pwd[32];
+ RAND_bytes(rand_pwd, 32);
string strWhatAmI = "To use bitcoind";
if (mapArgs.count("-server"))
strWhatAmI = strprintf(_("To use the %s option"), "\"-server\"");
else if (mapArgs.count("-daemon"))
strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\"");
PrintConsole(
- _("Warning: %s, you must set rpcpassword=<password>\nin the configuration file: %s\n"
+ _("Warning: %s, you must set a rpcpassword in the configuration file:\n %s\n"
+ "It is recommended you use the following random password:\n"
+ "rpcuser=bitcoinrpc\n"
+ "rpcpassword=%s\n"
+ "(you do not need to remember this password)\n"
"If the file does not exist, create it with owner-readable-only file permissions.\n"),
strWhatAmI.c_str(),
- GetConfigFile().c_str());
+ GetConfigFile().c_str(),
+ EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str());
CreateThread(Shutdown, NULL);
return;
}
}
if (!HTTPAuthorized(mapHeaders))
{
- // Deter brute-forcing short passwords
- if (mapArgs["-rpcpassword"].size() < 15)
- Sleep(50);
+ printf("ThreadRPCServer incorrect password attempt from %s\n",peer.address().to_string().c_str());
+ /* Deter brute-forcing short passwords.
+ If this results in a DOS the user really
+ shouldn't have their RPC port exposed.*/
+ if (mapArgs["-rpcpassword"].size() < 20)
+ Sleep(250);
stream << HTTPReply(401, "") << std::flush;
- printf("ThreadRPCServer incorrect password attempt\n");
continue;
}
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);
if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "getreceivedbylabel" && n > 1) ConvertTo<boost::int64_t>(params[1]); // deprecated
if (strMethod == "getallreceived" && n > 0) ConvertTo<boost::int64_t>(params[0]); // deprecated
- if (strMethod == "getallreceived" && n > 1) ConvertTo<bool>(params[1]);
+ if (strMethod == "getallreceived" && n > 1) ConvertTo<bool>(params[1]); // deprecated
if (strMethod == "listreceivedbyaddress" && n > 0) ConvertTo<boost::int64_t>(params[0]);
if (strMethod == "listreceivedbyaddress" && n > 1) ConvertTo<bool>(params[1]);
if (strMethod == "listreceivedbyaccount" && n > 0) ConvertTo<boost::int64_t>(params[0]);