aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authors_nakamoto <s_nakamoto@1a98c847-1fd6-4fd8-948a-caf3550aa51b>2010-06-10 23:10:30 +0000
committers_nakamoto <s_nakamoto@1a98c847-1fd6-4fd8-948a-caf3550aa51b>2010-06-10 23:10:30 +0000
commit3b318ed09588d383e7a1d79b167e71386205db63 (patch)
tree0a34330f01acf1a2cd18f5a9f8c36ec29216a3e8
parentd9dac6772f58e79cce0e2417c083547326056cc8 (diff)
downloadbitcoin-3b318ed09588d383e7a1d79b167e71386205db63.tar.xz
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
-rw-r--r--db.cpp9
-rw-r--r--db.h5
-rw-r--r--init.cpp31
-rw-r--r--irc.cpp1
-rw-r--r--main.cpp109
-rw-r--r--main.h3
-rw-r--r--net.cpp9
-rw-r--r--net.h10
-rw-r--r--rpc.cpp197
-rw-r--r--serialize.h2
-rw-r--r--ui.cpp9
-rw-r--r--uibase.cpp2
-rw-r--r--uibase.h2
-rw-r--r--uint256.h5
-rw-r--r--uiproject.fbp6
-rw-r--r--util.h9
16 files changed, 267 insertions, 142 deletions
diff --git a/db.cpp b/db.cpp
index 51cbb309b4..e0a672b1ee 100644
--- a/db.cpp
+++ b/db.cpp
@@ -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();
diff --git a/db.h b/db.h
index 0b778d5fea..29ff1994c3 100644
--- a/db.h
+++ b/db.h
@@ -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);
diff --git a/init.cpp b/init.cpp
index 833a8a3f0b..ecb1709c11 100644
--- a/init.cpp
+++ b/init.cpp
@@ -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
diff --git a/irc.cpp b/irc.cpp
index de0b997abe..673baebeb2 100644
--- a/irc.cpp
+++ b/irc.cpp
@@ -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;
diff --git a/main.cpp b/main.cpp
index 05a182c183..aef68838cb 100644
--- a/main.cpp
+++ b/main.cpp
@@ -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;
diff --git a/main.h b/main.h
index 83b8469937..d8f257b7df 100644
--- a/main.h
+++ b/main.h
@@ -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);
diff --git a/net.cpp b/net.cpp
index fbfa746221..c5659dc923 100644
--- a/net.cpp
+++ b/net.cpp
@@ -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)
diff --git a/net.h b/net.h
index 46344ed928..9ce848f636 100644
--- a/net.h
+++ b/net.h
@@ -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
diff --git a/rpc.cpp b/rpc.cpp
index d988786ef1..a9f16e6354 100644
--- a/rpc.cpp
+++ b/rpc.cpp
@@ -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();
-
- //
- // 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]);
-
- // Execute
- Value result = CallRPC(strMethod, params);
+ 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 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
+ result = CallRPC(strMethod, params);
+ }
// Print result
string strResult = (result.type() == str_type ? result.get_str() : write_string(result, true));
diff --git a/serialize.h b/serialize.h
index 2292651e83..25dcfb4746 100644
--- a/serialize.h
+++ b/serialize.h
@@ -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";
diff --git a/ui.cpp b/ui.cpp
index e86456a021..a21cd436c4 100644
--- a/ui.cpp
+++ b/ui.cpp
@@ -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();
diff --git a/uibase.cpp b/uibase.cpp
index 5fd83ee4df..56d52e316e 100644
--- a/uibase.cpp
+++ b/uibase.cpp
@@ -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 );
diff --git a/uibase.h b/uibase.h
index 331934b826..b1e32cb8ea 100644
--- a/uibase.h
+++ b/uibase.h
@@ -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();
};
diff --git a/uint256.h b/uint256.h
index 6976d9dc00..e6a4eeeb8d 100644
--- a/uint256.h
+++ b/uint256.h
@@ -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)
diff --git a/uiproject.fbp b/uiproject.fbp
index 58146ae5eb..779d9d4e55 100644
--- a/uiproject.fbp
+++ b/uiproject.fbp
@@ -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>
diff --git a/util.h b/util.h
index 1a25c7ddcc..40d46bc174 100644
--- a/util.h
+++ b/util.h
@@ -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)