automatically change displayed address whenever it receives anything,

added help and -? for daemon command line rpc commands,
only relay addr messages to 5 random nodes to save bandwidth,
started setting wtx.fFromMe flag,
trickle out tx inventory messages to protect privacy
 -- version 0.2.10

git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@81 1a98c847-1fd6-4fd8-948a-caf3550aa51b
This commit is contained in:
s_nakamoto 2010-06-10 23:10:30 +00:00
parent 2ca1758832
commit f93d5f9ffe
16 changed files with 265 additions and 140 deletions

9
db.cpp
View file

@ -511,9 +511,9 @@ bool LoadAddresses()
// CWalletDB
//
bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet)
bool CWalletDB::LoadWallet()
{
vchDefaultKeyRet.clear();
vchDefaultKey.clear();
int nFileVersion = 0;
// Modify defaults
@ -587,7 +587,7 @@ bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet)
}
else if (strType == "defaultkey")
{
ssValue >> vchDefaultKeyRet;
ssValue >> vchDefaultKey;
}
else if (strType == "version")
{
@ -650,8 +650,7 @@ bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet)
bool LoadWallet(bool& fFirstRunRet)
{
fFirstRunRet = false;
vector<unsigned char> vchDefaultKey;
if (!CWalletDB("cr+").LoadWallet(vchDefaultKey))
if (!CWalletDB("cr+").LoadWallet())
return false;
fFirstRunRet = vchDefaultKey.empty();

5
db.h
View file

@ -14,9 +14,11 @@ class CWalletTx;
extern map<string, string> mapAddressBook;
extern CCriticalSection cs_mapAddressBook;
extern vector<unsigned char> vchDefaultKey;
extern bool fClient;
extern unsigned int nWalletDBUpdated;
extern DbEnv dbenv;
@ -373,6 +375,7 @@ public:
bool WriteDefaultKey(const vector<unsigned char>& vchPubKey)
{
vchDefaultKey = vchPubKey;
nWalletDBUpdated++;
return Write(string("defaultkey"), vchPubKey);
}
@ -390,7 +393,7 @@ public:
return Write(make_pair(string("setting"), strKey), value);
}
bool LoadWallet(vector<unsigned char>& vchDefaultKeyRet);
bool LoadWallet();
};
bool LoadWallet(bool& fFirstRunRet);

View file

@ -339,22 +339,27 @@ bool CMyApp::OnInit2()
if (mapArgs.count("-?") || mapArgs.count("--help"))
{
wxString strUsage = string() +
_("Usage: bitcoin [options]") + "\t\t\t\t\t\t\n" +
_("Options:\n") +
" -gen \t\t " + _("Generate coins\n") +
" -gen=0 \t\t " + _("Don't generate coins\n") +
" -min \t\t " + _("Start minimized\n") +
" -datadir=<dir> \t " + _("Specify data directory\n") +
" -proxy=<ip:port>\t " + _("Connect through socks4 proxy\n") +
" -addnode=<ip> \t " + _("Add a node to connect to\n") +
" -connect=<ip> \t " + _("Connect only to the specified node\n") +
" -? \t\t " + _("This help message\n");
_("Usage:") + "\t\t\t\t\t\t\t\t\t\t\n" +
" bitcoin [options] \t" + "\n" +
" bitcoin [command] \t" + _("Send command to bitcoin running with -server or -daemon\n") +
" bitcoin [command] -? \t" + _("Get help for a command\n") +
" bitcoin help \t" + _("List commands\n") +
_("Options:\n") +
" -gen \t " + _("Generate coins\n") +
" -gen=0 \t " + _("Don't generate coins\n") +
" -min \t " + _("Start minimized\n") +
" -datadir=<dir> \t " + _("Specify data directory\n") +
" -proxy=<ip:port>\t " + _("Connect through socks4 proxy\n") +
" -addnode=<ip> \t " + _("Add a node to connect to\n") +
" -connect=<ip> \t " + _("Connect only to the specified node\n") +
" -server \t " + _("Accept command line and JSON-RPC commands\n") +
" -daemon \t " + _("Run in the background as a daemon and accept commands\n") +
" -? \t " + _("This help message\n");
if (fWindows && fGUI)
{
// Remove spaces, the tabs make the columns line up in the message box
for (int i = 0; i < 50; i++)
strUsage.Replace(" \t", "\t");
// Tabs make the columns line up in the message box
wxMessageBox(strUsage, "Bitcoin", wxOK);
}
else

View file

@ -159,7 +159,6 @@ bool Wait(int nSeconds)
void ThreadIRCSeed(void* parg)
{
printf("ThreadIRCSeed started\n");
SetThreadPriority(THREAD_PRIORITY_NORMAL);
int nErrorWait = 10;
int nRetryWait = 10;
bool fNameInUse = false;

109
main.cpp
View file

@ -49,6 +49,8 @@ CCriticalSection cs_mapRequestCount;
map<string, string> mapAddressBook;
CCriticalSection cs_mapAddressBook;
vector<unsigned char> vchDefaultKey;
// Settings
int fGenerateBitcoins = false;
int64 nTransactionFee = 0;
@ -142,6 +144,19 @@ bool AddToWallet(const CWalletTx& wtxIn)
if (!wtx.WriteToDisk())
return false;
// If default receiving address gets used, replace it with a new one
CScript scriptDefaultKey;
scriptDefaultKey.SetBitcoinAddress(vchDefaultKey);
foreach(const CTxOut& txout, wtx.vout)
{
if (txout.scriptPubKey == scriptDefaultKey)
{
CWalletDB walletdb;
walletdb.WriteDefaultKey(GenerateNewKey());
walletdb.WriteName(PubKeyToAddress(vchDefaultKey), "");
}
}
// Notify UI
vWalletUpdated.push_back(hash);
}
@ -1753,8 +1768,6 @@ bool ProcessMessages(CNode* pfrom)
{
// Rewind and wait for rest of message
///// need a mechanism to give up waiting for overlong message size error
if (fDebug)
printf("message-break\n");
vRecv.insert(vRecv.begin(), vHeaderSave.begin(), vHeaderSave.end());
break;
}
@ -1922,19 +1935,26 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (fShutdown)
return true;
addr.nTime = GetAdjustedTime() - 2 * 60 * 60;
if (pfrom->fGetAddr)
if (pfrom->fGetAddr || vAddr.size() > 10)
addr.nTime -= 5 * 24 * 60 * 60;
AddAddress(addr, false);
pfrom->AddAddressKnown(addr);
if (!pfrom->fGetAddr && addr.IsRoutable())
{
// Put on lists to send to other nodes
// Relay to a limited number of other nodes
CRITICAL_BLOCK(cs_vNodes)
{
multimap<int, CNode*> mapMix;
foreach(CNode* pnode, vNodes)
pnode->PushAddress(addr);
mapMix.insert(make_pair(GetRand(INT_MAX), pnode));
int nRelayNodes = 5;
for (multimap<int, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
((*mi).second)->PushAddress(addr);
}
}
}
pfrom->fGetAddr = false;
if (vAddr.size() < 1000)
pfrom->fGetAddr = false;
}
@ -2177,6 +2197,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
uint256 hashReply;
CWalletTx wtxNew;
vRecv >> hashReply >> wtxNew;
wtxNew.fFromMe = false;
// Broadcast
if (!wtxNew.AcceptWalletTransaction())
@ -2242,7 +2263,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
bool SendMessages(CNode* pto)
bool SendMessages(CNode* pto, bool fSendTrickle)
{
CRITICAL_BLOCK(cs_main)
{
@ -2273,15 +2294,6 @@ bool SendMessages(CNode* pto)
}
}
// Delay tx inv messages to protect privacy,
// trickle them out to a few nodes at a time.
bool fSendTxInv = false;
if (GetTimeMillis() > pto->nNextSendTxInv)
{
pto->nNextSendTxInv = GetTimeMillis() + 3000 + GetRand(2000);
fSendTxInv = true;
}
// Resend wallet transactions that haven't gotten in a block yet
ResendWalletTransactions();
@ -2289,24 +2301,27 @@ bool SendMessages(CNode* pto)
//
// Message: addr
//
vector<CAddress> vAddr;
vAddr.reserve(pto->vAddrToSend.size());
foreach(const CAddress& addr, pto->vAddrToSend)
if (fSendTrickle)
{
// returns true if wasn't already contained in the set
if (pto->setAddrKnown.insert(addr).second)
vector<CAddress> vAddr;
vAddr.reserve(pto->vAddrToSend.size());
foreach(const CAddress& addr, pto->vAddrToSend)
{
vAddr.push_back(addr);
if (vAddr.size() >= 1000)
// returns true if wasn't already contained in the set
if (pto->setAddrKnown.insert(addr).second)
{
pto->PushMessage("addr", vAddr);
vAddr.clear();
vAddr.push_back(addr);
if (vAddr.size() >= 1000)
{
pto->PushMessage("addr", vAddr);
vAddr.clear();
}
}
}
pto->vAddrToSend.clear();
if (!vAddr.empty())
pto->PushMessage("addr", vAddr);
}
pto->vAddrToSend.clear();
if (!vAddr.empty())
pto->PushMessage("addr", vAddr);
//
@ -2320,11 +2335,40 @@ bool SendMessages(CNode* pto)
vInvWait.reserve(pto->vInventoryToSend.size());
foreach(const CInv& inv, pto->vInventoryToSend)
{
// delay txes
if (!fSendTxInv && inv.type == MSG_TX)
{
vInvWait.push_back(inv);
if (pto->setInventoryKnown.count(inv))
continue;
// trickle out tx inv to protect privacy
if (inv.type == MSG_TX && !fSendTrickle)
{
// 1/4 of tx invs blast to all immediately
static uint256 hashSalt;
if (hashSalt == 0)
RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt));
uint256 hashRand = (inv.hash ^ hashSalt);
hashRand = Hash(BEGIN(hashRand), END(hashRand));
bool fTrickleWait = ((hashRand & 3) != 0);
// always trickle our own transactions
if (!fTrickleWait)
{
TRY_CRITICAL_BLOCK(cs_mapWallet)
{
map<uint256, CWalletTx>::iterator mi = mapWallet.find(inv.hash);
if (mi != mapWallet.end())
{
CWalletTx& wtx = (*mi).second;
if (wtx.fFromMe)
fTrickleWait = true;
}
}
}
if (fTrickleWait)
{
vInvWait.push_back(inv);
continue;
}
}
// returns true if wasn't already contained in the set
@ -2852,6 +2896,7 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK
{
wtxNew.vin.clear();
wtxNew.vout.clear();
wtxNew.fFromMe = true;
if (nValue < 0)
return false;
int64 nValueOut = nValue;

3
main.h
View file

@ -38,6 +38,7 @@ extern map<uint256, int> mapRequestCount;
extern CCriticalSection cs_mapRequestCount;
extern map<string, string> mapAddressBook;
extern CCriticalSection cs_mapAddressBook;
extern vector<unsigned char> vchDefaultKey;
// Settings
extern int fGenerateBitcoins;
@ -66,7 +67,7 @@ bool LoadBlockIndex(bool fAllowNew=true);
void PrintBlockTree();
bool ProcessMessages(CNode* pfrom);
bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv);
bool SendMessages(CNode* pto);
bool SendMessages(CNode* pto, bool fSendTrickle);
int64 GetBalance();
bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet);
bool CommitTransaction(CWalletTx& wtxNew, const CKey& key);

View file

@ -1019,7 +1019,6 @@ void ThreadMessageHandler2(void* parg)
SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
while (!fShutdown)
{
// Poll the connected nodes for messages
vector<CNode*> vNodesCopy;
CRITICAL_BLOCK(cs_vNodes)
{
@ -1027,6 +1026,11 @@ void ThreadMessageHandler2(void* parg)
foreach(CNode* pnode, vNodesCopy)
pnode->AddRef();
}
// Poll the connected nodes for messages
CNode* pnodeTrickle = NULL;
if (!vNodesCopy.empty())
pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
foreach(CNode* pnode, vNodesCopy)
{
// Receive messages
@ -1037,10 +1041,11 @@ void ThreadMessageHandler2(void* parg)
// Send messages
TRY_CRITICAL_BLOCK(pnode->cs_vSend)
SendMessages(pnode);
SendMessages(pnode, pnode == pnodeTrickle);
if (fShutdown)
return;
}
CRITICAL_BLOCK(cs_vNodes)
{
foreach(CNode* pnode, vNodesCopy)

10
net.h
View file

@ -12,7 +12,7 @@ extern int nBestHeight;
static const unsigned short DEFAULT_PORT = htons(8333);
#define DEFAULT_PORT htons(8333)
static const unsigned int PUBLISH_HOPS = 5;
enum
{
@ -522,7 +522,6 @@ public:
vector<CInv> vInventoryToSend;
CCriticalSection cs_inventory;
multimap<int64, CInv> mapAskFor;
int64 nNextSendTxInv;
// publish and subscription
vector<char> vfSubscribe;
@ -536,6 +535,12 @@ public:
vSend.SetVersion(0);
vRecv.SetType(SER_NETWORK);
vRecv.SetVersion(0);
// Version 0.2 obsoletes 20 Feb 2012
if (GetTime() > 1329696000)
{
vSend.SetVersion(209);
vRecv.SetVersion(209);
}
nLastSend = 0;
nLastRecv = 0;
nLastSendEmpty = GetTime();
@ -556,7 +561,6 @@ public:
hashLastGetBlocksEnd = 0;
nStartingHeight = -1;
fGetAddr = false;
nNextSendTxInv = 0;
vfSubscribe.assign(256, false);
// Push a version message

193
rpc.cpp
View file

@ -18,6 +18,8 @@ using boost::asio::ip::tcp;
using namespace json_spirit;
void ThreadRPCServer2(void* parg);
typedef Value(*rpcfn_type)(const Array& params, bool fHelp);
extern map<string, rpcfn_type> mapCallTable;
@ -31,11 +33,40 @@ void ThreadRPCServer2(void* parg);
Value stop(const Array& params)
Value help(const Array& params, bool fHelp)
{
if (params.size() != 0)
if (fHelp || params.size() != 0)
throw runtime_error(
"stop (no parameters)\n"
"help\n"
"List commands.");
string strRet;
for (map<string, rpcfn_type>::iterator mi = mapCallTable.begin(); mi != mapCallTable.end(); ++mi)
{
try
{
Array params;
(*(*mi).second)(params, true);
}
catch (std::exception& e)
{
// Help text is returned in an exception
string strHelp = string(e.what());
if (strHelp.find('\n') != -1)
strHelp = strHelp.substr(0, strHelp.find('\n'));
strRet += strHelp + "\n";
}
}
strRet = strRet.substr(0,strRet.size()-1);
return strRet;
}
Value stop(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
"stop\n"
"Stop bitcoin server.");
// Shutdown will take long enough that the response should get back
@ -44,33 +75,33 @@ Value stop(const Array& params)
}
Value getblockcount(const Array& params)
Value getblockcount(const Array& params, bool fHelp)
{
if (params.size() != 0)
if (fHelp || params.size() != 0)
throw runtime_error(
"getblockcount (no parameters)\n"
"getblockcount\n"
"Returns the number of blocks in the longest block chain.");
return nBestHeight + 1;
}
Value getblocknumber(const Array& params)
Value getblocknumber(const Array& params, bool fHelp)
{
if (params.size() != 0)
if (fHelp || params.size() != 0)
throw runtime_error(
"getblocknumber (no parameters)\n"
"getblocknumber\n"
"Returns the block number of the latest block in the longest block chain.");
return nBestHeight;
}
Value getconnectioncount(const Array& params)
Value getconnectioncount(const Array& params, bool fHelp)
{
if (params.size() != 0)
if (fHelp || params.size() != 0)
throw runtime_error(
"getconnectioncount (no parameters)\n"
"getconnectioncount\n"
"Returns the number of connections to other nodes.");
return (int)vNodes.size();
@ -89,42 +120,42 @@ double GetDifficulty()
return dMinimum / dCurrently;
}
Value getdifficulty(const Array& params)
Value getdifficulty(const Array& params, bool fHelp)
{
if (params.size() != 0)
if (fHelp || params.size() != 0)
throw runtime_error(
"getdifficulty (no parameters)\n"
"getdifficulty\n"
"Returns the proof-of-work difficulty as a multiple of the minimum difficulty.");
return GetDifficulty();
}
Value getbalance(const Array& params)
Value getbalance(const Array& params, bool fHelp)
{
if (params.size() != 0)
if (fHelp || params.size() != 0)
throw runtime_error(
"getbalance (no parameters)\n"
"getbalance\n"
"Returns the server's available balance.");
return ((double)GetBalance() / (double)COIN);
}
Value getgenerate(const Array& params)
Value getgenerate(const Array& params, bool fHelp)
{
if (params.size() != 0)
if (fHelp || params.size() != 0)
throw runtime_error(
"getgenerate (no parameters)\n"
"getgenerate\n"
"Returns true or false.");
return (bool)fGenerateBitcoins;
}
Value setgenerate(const Array& params)
Value setgenerate(const Array& params, bool fHelp)
{
if (params.size() < 1 || params.size() > 2)
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
"setgenerate <generate> [genproclimit]\n"
"<generate> is true or false to turn generation on or off.\n"
@ -148,11 +179,11 @@ Value setgenerate(const Array& params)
}
Value getinfo(const Array& params)
Value getinfo(const Array& params, bool fHelp)
{
if (params.size() != 0)
if (fHelp || params.size() != 0)
throw runtime_error(
"getinfo (no parameters)");
"getinfo");
Object obj;
obj.push_back(Pair("balance", (double)GetBalance() / (double)COIN));
@ -166,9 +197,9 @@ Value getinfo(const Array& params)
}
Value getnewaddress(const Array& params)
Value getnewaddress(const Array& params, bool fHelp)
{
if (params.size() > 1)
if (fHelp || params.size() > 1)
throw runtime_error(
"getnewaddress [label]\n"
"Returns a new bitcoin address for receiving payments. "
@ -188,9 +219,9 @@ Value getnewaddress(const Array& params)
}
Value setlabel(const Array& params)
Value setlabel(const Array& params, bool fHelp)
{
if (params.size() < 1 || params.size() > 2)
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
"setlabel <bitcoinaddress> <label>\n"
"Sets the label associated with the given address.");
@ -205,9 +236,9 @@ Value setlabel(const Array& params)
}
Value getlabel(const Array& params)
Value getlabel(const Array& params, bool fHelp)
{
if (params.size() != 1)
if (fHelp || params.size() != 1)
throw runtime_error(
"getlabel <bitcoinaddress>\n"
"Returns the label associated with the given address.");
@ -225,9 +256,9 @@ Value getlabel(const Array& params)
}
Value getaddressesbylabel(const Array& params)
Value getaddressesbylabel(const Array& params, bool fHelp)
{
if (params.size() != 1)
if (fHelp || params.size() != 1)
throw runtime_error(
"getaddressesbylabel <label>\n"
"Returns the list of addresses with the given label.");
@ -255,9 +286,9 @@ Value getaddressesbylabel(const Array& params)
}
Value sendtoaddress(const Array& params)
Value sendtoaddress(const Array& params, bool fHelp)
{
if (params.size() < 2 || params.size() > 4)
if (fHelp || params.size() < 2 || params.size() > 4)
throw runtime_error(
"sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to]\n"
"<amount> is a real and is rounded to the nearest 0.01");
@ -283,9 +314,9 @@ Value sendtoaddress(const Array& params)
}
Value listtransactions(const Array& params)
Value listtransactions(const Array& params, bool fHelp)
{
if (params.size() > 2)
if (fHelp || params.size() > 2)
throw runtime_error(
"listtransactions [count=10] [includegenerated=false]\n"
"Returns up to [count] most recent transactions.");
@ -304,9 +335,9 @@ Value listtransactions(const Array& params)
}
Value getreceivedbyaddress(const Array& params)
Value getreceivedbyaddress(const Array& params, bool fHelp)
{
if (params.size() < 1 || params.size() > 2)
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
"getreceivedbyaddress <bitcoinaddress> [minconf=1]\n"
"Returns the total amount received by <bitcoinaddress> in transactions with at least [minconf] confirmations.");
@ -345,9 +376,9 @@ Value getreceivedbyaddress(const Array& params)
}
Value getreceivedbylabel(const Array& params)
Value getreceivedbylabel(const Array& params, bool fHelp)
{
if (params.size() < 1 || params.size() > 2)
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
"getreceivedbylabel <label> [minconf=1]\n"
"Returns the total amount received by addresses with <label> in transactions with at least [minconf] confirmations.");
@ -508,9 +539,9 @@ Value ListReceived(const Array& params, bool fByLabels)
return ret;
}
Value listreceivedbyaddress(const Array& params)
Value listreceivedbyaddress(const Array& params, bool fHelp)
{
if (params.size() > 2)
if (fHelp || params.size() > 2)
throw runtime_error(
"listreceivedbyaddress [minconf=1] [includeempty=false]\n"
"[minconf] is the minimum number of confirmations before payments are included.\n"
@ -524,9 +555,9 @@ Value listreceivedbyaddress(const Array& params)
return ListReceived(params, false);
}
Value listreceivedbylabel(const Array& params)
Value listreceivedbylabel(const Array& params, bool fHelp)
{
if (params.size() > 2)
if (fHelp || params.size() > 2)
throw runtime_error(
"listreceivedbylabel [minconf=1] [includeempty=false]\n"
"[minconf] is the minimum number of confirmations before payments are included.\n"
@ -555,9 +586,9 @@ Value listreceivedbylabel(const Array& params)
// Call Table
//
typedef Value(*rpcfn_type)(const Array& params);
pair<string, rpcfn_type> pCallTable[] =
{
make_pair("help", &help),
make_pair("stop", &stop),
make_pair("getblockcount", &getblockcount),
make_pair("getblocknumber", &getblocknumber),
@ -760,7 +791,7 @@ void ThreadRPCServer2(void* parg)
map<string, rpcfn_type>::iterator mi = mapCallTable.find(strMethod);
if (mi == mapCallTable.end())
throw runtime_error("Method not found.");
Value result = (*(*mi).second)(params);
Value result = (*(*mi).second)(params, false);
// Send reply
string strReply = JSONRPCReply(result, Value::null, id);
@ -847,32 +878,50 @@ int CommandLineRPC(int argc, char *argv[])
if (!mapCallTable.count(strMethod))
throw runtime_error(strprintf("unknown command: %s", strMethod.c_str()));
// Parameters default to strings
Array params;
for (int i = 2; i < argc; i++)
params.push_back(argv[i]);
int n = params.size();
Value result;
if (argc == 3 && strcmp(argv[2], "-?") == 0)
{
// Call help locally, help text is returned in an exception
try
{
map<string, rpcfn_type>::iterator mi = mapCallTable.find(strMethod);
Array params;
(*(*mi).second)(params, true);
}
catch (std::exception& e)
{
result = e.what();
}
}
else
{
// Parameters default to strings
Array params;
for (int i = 2; i < argc; i++)
params.push_back(argv[i]);
int n = params.size();
//
// Special case other types
//
if (strMethod == "setgenerate" && n > 0) ConvertTo<bool>(params[0]);
if (strMethod == "setgenerate" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]);
if (strMethod == "listtransactions" && n > 0) ConvertTo<boost::int64_t>(params[0]);
if (strMethod == "listtransactions" && n > 1) ConvertTo<bool>(params[1]);
if (strMethod == "getamountreceived" && n > 1) ConvertTo<boost::int64_t>(params[1]); // deprecated
if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "getreceivedbylabel" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "getallreceived" && n > 0) ConvertTo<boost::int64_t>(params[0]); // deprecated
if (strMethod == "getallreceived" && n > 1) ConvertTo<bool>(params[1]);
if (strMethod == "listreceivedbyaddress" && n > 0) ConvertTo<boost::int64_t>(params[0]);
if (strMethod == "listreceivedbyaddress" && n > 1) ConvertTo<bool>(params[1]);
if (strMethod == "listreceivedbylabel" && n > 0) ConvertTo<boost::int64_t>(params[0]);
if (strMethod == "listreceivedbylabel" && n > 1) ConvertTo<bool>(params[1]);
//
// Special case non-string parameter types
//
if (strMethod == "setgenerate" && n > 0) ConvertTo<bool>(params[0]);
if (strMethod == "setgenerate" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]);
if (strMethod == "listtransactions" && n > 0) ConvertTo<boost::int64_t>(params[0]);
if (strMethod == "listtransactions" && n > 1) ConvertTo<bool>(params[1]);
if (strMethod == "getamountreceived" && n > 1) ConvertTo<boost::int64_t>(params[1]); // deprecated
if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "getreceivedbylabel" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "getallreceived" && n > 0) ConvertTo<boost::int64_t>(params[0]); // deprecated
if (strMethod == "getallreceived" && n > 1) ConvertTo<bool>(params[1]);
if (strMethod == "listreceivedbyaddress" && n > 0) ConvertTo<boost::int64_t>(params[0]);
if (strMethod == "listreceivedbyaddress" && n > 1) ConvertTo<bool>(params[1]);
if (strMethod == "listreceivedbylabel" && n > 0) ConvertTo<boost::int64_t>(params[0]);
if (strMethod == "listreceivedbylabel" && n > 1) ConvertTo<bool>(params[1]);
// Execute
Value result = CallRPC(strMethod, params);
// Execute
result = CallRPC(strMethod, params);
}
// Print result
string strResult = (result.type() == str_type ? result.get_str() : write_string(result, true));

View file

@ -19,7 +19,7 @@ class CScript;
class CDataStream;
class CAutoFile;
static const int VERSION = 209;
static const int VERSION = 210;
static const char* pszSubVer = ".0";

9
ui.cpp
View file

@ -1016,6 +1016,11 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
if (fDebug && GetTime() - nThreadSocketHandlerHeartbeat > 60)
m_statusBar->SetStatusText(" ERROR: ThreadSocketHandler has stopped", 0);
// Update receiving address
string strDefaultAddress = PubKeyToAddress(vchDefaultKey);
if (m_textCtrlAddress->GetValue() != strDefaultAddress)
m_textCtrlAddress->SetValue(strDefaultAddress);
}
@ -2087,7 +2092,9 @@ void CSendingDialog::OnReply2(CDataStream& vRecv)
}
// Send payment tx to seller, with response going to OnReply3 via event handler
pnode->PushRequest("submitorder", wtx, SendingDialogOnReply3, this);
CWalletTx wtxSend = wtx;
wtxSend.fFromMe = false;
pnode->PushRequest("submitorder", wtxSend, SendingDialogOnReply3, this);
Status(_("Waiting for confirmation..."));
MainFrameRepaint();

View file

@ -616,7 +616,7 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin
fgSizer1->Add( 0, 0, 0, wxEXPAND, 5 );
m_staticTextInstructions = new wxStaticText( this, wxID_ANY, _("Enter the recipient's IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, \nor Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) if recipient is not online."), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextInstructions = new wxStaticText( this, wxID_ANY, _("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) or IP address (e.g. 123.45.6.7)"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextInstructions->Wrap( -1 );
fgSizer1->Add( m_staticTextInstructions, 0, wxTOP|wxRIGHT|wxLEFT, 5 );

View file

@ -275,7 +275,7 @@ class CSendDialogBase : public wxDialog
public:
CSendDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Send Coins"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 675,312 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
CSendDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Send Coins"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 675,298 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~CSendDialogBase();
};

View file

@ -388,7 +388,6 @@ typedef base_uint<256> base_uint256;
//
// uint160 and uint256 could be implemented as templates, but to keep
// compile errors and debugging cleaner, they're copy and pasted.
// It's safe to search and replace 160 with 256 and vice versa.
//
@ -405,6 +404,8 @@ public:
uint160()
{
for (int i = 0; i < WIDTH; i++)
pn[i] = 0;
}
uint160(const basetype& b)
@ -517,6 +518,8 @@ public:
uint256()
{
for (int i = 0; i < WIDTH; i++)
pn[i] = 0;
}
uint256(const basetype& b)

View file

@ -18,7 +18,7 @@
<property name="relative_path">1</property>
<property name="use_enum">0</property>
<property name="use_microsoft_bom">0</property>
<object class="Frame" expanded="1">
<object class="Frame" expanded="0">
<property name="bg">wxSYS_COLOUR_BTNFACE</property>
<property name="center"></property>
<property name="context_help"></property>
@ -3317,7 +3317,7 @@
<property name="minimum_size"></property>
<property name="name">CSendDialogBase</property>
<property name="pos"></property>
<property name="size">675,312</property>
<property name="size">675,298</property>
<property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
<property name="subclass"></property>
<property name="title">Send Coins</property>
@ -3408,7 +3408,7 @@
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Enter the recipient&apos;s IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, &#x0A;or Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) if recipient is not online.</property>
<property name="label">Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) or IP address (e.g. 123.45.6.7)</property>
<property name="maximum_size"></property>
<property name="minimum_size"></property>
<property name="name">m_staticTextInstructions</property>

9
util.h
View file

@ -520,8 +520,13 @@ inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=fa
inline void SetThreadPriority(int nPriority)
{
// threads are processes on linux, so PRIO_PROCESS affects just the one thread
setpriority(PRIO_PROCESS, getpid(), nPriority);
// It's unclear if it's even possible to change thread priorities on Linux,
// but we really and truly need it for the generation threads.
#ifdef PRIO_THREAD
setpriority(PRIO_THREAD, 0, nPriority);
#else
setpriority(PRIO_PROCESS, 0, nPriority);
#endif
}
inline bool TerminateThread(pthread_t hthread, unsigned int nExitCode)