aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGavin Andresen <gavinandresen@gmail.com>2011-01-18 14:46:46 -0500
committerGavin Andresen <gavinandresen@gmail.com>2011-01-18 14:46:46 -0500
commitc9f70b381dc8ee4197fd5b3d4d20f302632da0ed (patch)
treec9de69cd651024487fed16ec890e20ef1e721202
parent86c2bdfd5d7773e94dda258c52d2dd056fcfb261 (diff)
parentb4671902f2c5aa1c95be547a61b0a72b8a3025de (diff)
downloadbitcoin-c9f70b381dc8ee4197fd5b3d4d20f302632da0ed.tar.xz
Merge branch 'integration' into FIXES
-rw-r--r--README.md19
-rw-r--r--init.cpp15
-rw-r--r--irc.cpp4
-rw-r--r--main.cpp55
-rw-r--r--main.h2
-rw-r--r--net.cpp8
-rw-r--r--rpc.cpp109
-rw-r--r--util.cpp2
-rw-r--r--util.h1
9 files changed, 145 insertions, 70 deletions
diff --git a/README.md b/README.md
index 4c8475c889..f13a79a987 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,13 @@
-Gavin's Bitcoin patches
-=======================
+Bitcoin integration/staging tree
-Branches here:
+Straw-man plan for Bitcoin development (open source vets, please slap me around and help make this better):
-* svn : up-to-date mirror of the 'production' Bitcoin (from http://sourceforge.net/projects/bitcoin/).
-* monitorreceived : Implements monitortransaction/monitorblocks/gettransaction/getblock RPC commands.
-* listtransactions: Implements new JSON-RPC command "listtransactions" (from jgarzik)
-* refundtransaction : Implements new JSON-RPC command "refundtransaction"
-* master : All of the above, merged together.
+Developers work in their own trees, then submit pull requests when they think their feature is ready.
+
+Requests get discussed (where? bitcoin forums?) and if there's broad consensus they're a good thing, well written, match coding style, etc. then they're merged into the 'master' branch.
+
+master branch is regularly built and tested (by who? need people willing to be quality assurance testers), and periodically pushed to the subversion repo to become the official, stable, released bitcoin.
+
+
+We'll create feature branches if/when there are major new features being worked on by several people.
-Code is hosted at github: http://github.com/gavinandresen/bitcoin-git
diff --git a/init.cpp b/init.cpp
index 61ca4d2bd5..e114d80727 100644
--- a/init.cpp
+++ b/init.cpp
@@ -181,7 +181,9 @@ bool AppInit2(int argc, char* argv[])
" -rpcpassword=<pw>\t " + _("Password for JSON-RPC connections\n") +
" -rpcport=<port> \t\t " + _("Listen for JSON-RPC connections on <port>\n") +
" -rpcallowip=<ip> \t\t " + _("Allow JSON-RPC connections from specified IP address\n") +
- " -rpcconnect=<ip> \t " + _("Send commands to node running on <ip>\n");
+ " -rpcconnect=<ip> \t " + _("Send commands to node running on <ip>\n") +
+ " -keypool=<n> \t " + _("Set key pool size to <n>\n") +
+ " -nolisten \t " + _("Don't accept connections from outside");
#ifdef USE_SSL
strUsage += string() +
@@ -211,6 +213,8 @@ bool AppInit2(int argc, char* argv[])
fPrintToDebugger = GetBoolArg("-printtodebugger");
fTestNet = GetBoolArg("-testnet");
+
+ fNoListen = GetBoolArg("-nolisten");
if (fCommandLine)
{
@@ -290,10 +294,13 @@ bool AppInit2(int argc, char* argv[])
// Bind to the port early so we can tell if another instance is already running.
string strErrors;
- if (!BindListenPort(strErrors))
+ if (!fNoListen)
{
- wxMessageBox(strErrors, "Bitcoin");
- return false;
+ if (!BindListenPort(strErrors))
+ {
+ wxMessageBox(strErrors, "Bitcoin");
+ return false;
+ }
}
//
diff --git a/irc.cpp b/irc.cpp
index aad9beb76e..5adaf11658 100644
--- a/irc.cpp
+++ b/irc.cpp
@@ -257,8 +257,10 @@ void ThreadIRCSeed(void* parg)
void ThreadIRCSeed2(void* parg)
{
- if (mapArgs.count("-connect"))
+ /* Dont advertise on IRC if we don't allow incoming connections */
+ if (mapArgs.count("-connect") || fNoListen)
return;
+
if (GetBoolArg("-noirc"))
return;
printf("ThreadIRCSeed started\n");
diff --git a/main.cpp b/main.cpp
index 8db6c394e8..b7dfd9fabe 100644
--- a/main.cpp
+++ b/main.cpp
@@ -395,9 +395,12 @@ int CWalletTx::GetRequestCount() const
}
void CWalletTx::GetAmounts(int64& nGenerated, list<pair<string, int64> >& listReceived,
- int64& nSent, int64& nFee, string& strSentAccount) const
+ list<pair<string, int64> >& listSent, int64& nFee, string& strSentAccount) const
{
- nGenerated = nSent = nFee = 0;
+ nGenerated = nFee = 0;
+ listReceived.clear();
+ listSent.clear();
+ strSentAccount = strFromAccount;
if (IsCoinBase())
{
@@ -406,24 +409,38 @@ void CWalletTx::GetAmounts(int64& nGenerated, list<pair<string, int64> >& listRe
return;
}
- // Received. Standard client will never generate a send-to-multiple-recipients,
+ // Compute fee:
+ int64 nDebit = GetDebit();
+ if (nDebit > 0) // debit>0 means we signed/sent this transaction
+ {
+ int64 nValueOut = GetValueOut();
+ nFee = nDebit - nValueOut;
+ }
+
+ // Sent/received. Standard client will never generate a send-to-multiple-recipients,
// but non-standard clients might (so return a list of address/amount pairs)
foreach(const CTxOut& txout, vout)
{
+ string address;
+ uint160 hash160;
vector<unsigned char> vchPubKey;
- if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey))
- listReceived.push_back(make_pair(PubKeyToAddress(vchPubKey), txout.nValue));
- }
+ if (ExtractHash160(txout.scriptPubKey, hash160))
+ address = Hash160ToAddress(hash160);
+ else if (ExtractPubKey(txout.scriptPubKey, false, vchPubKey))
+ address = PubKeyToAddress(vchPubKey);
+ else
+ address = " unknown "; // some type of weird non-standard transaction?
- // Sent
- int64 nDebit = GetDebit();
- if (nDebit > 0)
- {
- int64 nValueOut = GetValueOut();
- nFee = nDebit - nValueOut;
- nSent = nValueOut - GetChange();
- strSentAccount = strFromAccount;
+ if (nDebit > 0 && txout.IsChange())
+ continue;
+
+ if (nDebit > 0)
+ listSent.push_back(make_pair(address, txout.nValue));
+
+ if (txout.IsMine())
+ listReceived.push_back(make_pair(address, txout.nValue));
}
+
}
void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived,
@@ -431,17 +448,19 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, i
{
nGenerated = nReceived = nSent = nFee = 0;
- int64 allGenerated, allSent, allFee;
- allGenerated = allSent = allFee = 0;
+ int64 allGenerated, allFee;
+ allGenerated = allFee = 0;
string strSentAccount;
list<pair<string, int64> > listReceived;
- GetAmounts(allGenerated, listReceived, allSent, allFee, strSentAccount);
+ list<pair<string, int64> > listSent;
+ GetAmounts(allGenerated, listReceived, listSent, allFee, strSentAccount);
if (strAccount == "")
nGenerated = allGenerated;
if (strAccount == strSentAccount)
{
- nSent = allSent;
+ foreach(const PAIRTYPE(string,int64)& s, listSent)
+ nSent += s.second;
nFee = allFee;
}
CRITICAL_BLOCK(cs_mapAddressBook)
diff --git a/main.h b/main.h
index 11a5862cb0..3c7bcb22f0 100644
--- a/main.h
+++ b/main.h
@@ -874,7 +874,7 @@ public:
}
void GetAmounts(int64& nGenerated, list<pair<string /* address */, int64> >& listReceived,
- int64& nSent, int64& nFee, string& strSentAccount) const;
+ list<pair<string /* address */, int64> >& listSent, int64& nFee, string& strSentAccount) const;
void GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived,
int64& nSent, int64& nFee) const;
diff --git a/net.cpp b/net.cpp
index da7661962e..a626acd376 100644
--- a/net.cpp
+++ b/net.cpp
@@ -643,7 +643,9 @@ void ThreadSocketHandler2(void* parg)
FD_ZERO(&fdsetSend);
FD_ZERO(&fdsetError);
SOCKET hSocketMax = 0;
- FD_SET(hListenSocket, &fdsetRecv);
+
+ if(hListenSocket != INVALID_SOCKET)
+ FD_SET(hListenSocket, &fdsetRecv);
hSocketMax = max(hSocketMax, hListenSocket);
CRITICAL_BLOCK(cs_vNodes)
{
@@ -680,7 +682,7 @@ void ThreadSocketHandler2(void* parg)
//
// Accept new connections
//
- if (FD_ISSET(hListenSocket, &fdsetRecv))
+ if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
{
struct sockaddr_in sockaddr;
socklen_t len = sizeof(sockaddr);
@@ -1344,7 +1346,7 @@ void StartNode(void* parg)
#endif
printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
- if (fUseProxy || mapArgs.count("-connect"))
+ if (fUseProxy || mapArgs.count("-connect") || fNoListen)
{
// Proxies can't take incoming connections
addrLocalHost.ip = CAddress("0.0.0.0").ip;
diff --git a/rpc.cpp b/rpc.cpp
index 602de73e44..f80b24ea72 100644
--- a/rpc.cpp
+++ b/rpc.cpp
@@ -315,15 +315,9 @@ Value getnewaddress(const Array& params, bool fHelp)
}
-Value getaccountaddress(const Array& params, bool fHelp)
+string GetAccountAddress(string strAccount, bool bForceNew=false)
{
- if (fHelp || params.size() != 1)
- throw runtime_error(
- "getaccountaddress <account>\n"
- "Returns the current bitcoin address for receiving payments to this account.");
-
- // Parse the account first so we don't generate a key if there's an error
- string strAccount = AccountFromValue(params[0]);
+ string strAddress;
CRITICAL_BLOCK(cs_mapWallet)
{
@@ -350,7 +344,7 @@ Value getaccountaddress(const Array& params, bool fHelp)
}
// Generate a new key
- if (account.vchPubKey.empty())
+ if (account.vchPubKey.empty() || bForceNew)
{
account.vchPubKey = GetKeyFromKeyPool();
string strAddress = PubKeyToAddress(account.vchPubKey);
@@ -359,11 +353,26 @@ Value getaccountaddress(const Array& params, bool fHelp)
}
walletdb.TxnCommit();
- return PubKeyToAddress(account.vchPubKey);
+ strAddress = PubKeyToAddress(account.vchPubKey);
}
+ return strAddress;
+}
+
+Value getaccountaddress(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "getaccountaddress <account>\n"
+ "Returns the current bitcoin address for receiving payments to this account.");
+
+ // Parse the account first so we don't generate a key if there's an error
+ string strAccount = AccountFromValue(params[0]);
+
+ return GetAccountAddress(strAccount);
}
+
Value setaccount(const Array& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 2)
@@ -376,6 +385,17 @@ Value setaccount(const Array& params, bool fHelp)
if (params.size() > 1)
strAccount = AccountFromValue(params[1]);
+ // Detect when changing the account of an address that is the 'unused current key' of another account:
+ CRITICAL_BLOCK(cs_mapAddressBook)
+ {
+ if (mapAddressBook.count(strAddress))
+ {
+ string strOldAccount = mapAddressBook[strAddress];
+ if (strAddress == GetAccountAddress(strOldAccount))
+ GetAccountAddress(strOldAccount, true);
+ }
+ }
+
SetAddressBookName(strAddress, strAccount);
return Value::null;
}
@@ -857,12 +877,13 @@ Value listreceivedbyaccount(const Array& params, bool fHelp)
return ListReceived(params, true);
}
-void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, Array& ret)
+void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret)
{
- int64 nGenerated, nSent, nFee;
+ int64 nGenerated, nFee;
string strSentAccount;
list<pair<string, int64> > listReceived;
- wtx.GetAmounts(nGenerated, listReceived, nSent, nFee, strSentAccount);
+ list<pair<string, int64> > listSent;
+ wtx.GetAmounts(nGenerated, listReceived, listSent, nFee, strSentAccount);
bool fAllAccounts = (strAccount == string("*"));
@@ -873,20 +894,26 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
entry.push_back(Pair("account", string("")));
entry.push_back(Pair("category", "generate"));
entry.push_back(Pair("amount", ValueFromAmount(nGenerated)));
- WalletTxToJSON(wtx, entry);
+ if (fLong)
+ WalletTxToJSON(wtx, entry);
ret.push_back(entry);
}
// Sent
- if ((nSent != 0 || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
+ if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
{
- Object entry;
- entry.push_back(Pair("account", strSentAccount));
- entry.push_back(Pair("category", "send"));
- entry.push_back(Pair("amount", ValueFromAmount(-nSent)));
- entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
- WalletTxToJSON(wtx, entry);
- ret.push_back(entry);
+ foreach(const PAIRTYPE(string, int64)& s, listSent)
+ {
+ Object entry;
+ entry.push_back(Pair("account", strSentAccount));
+ entry.push_back(Pair("address", s.first));
+ entry.push_back(Pair("category", "send"));
+ entry.push_back(Pair("amount", ValueFromAmount(-s.second)));
+ entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
+ if (fLong)
+ WalletTxToJSON(wtx, entry);
+ ret.push_back(entry);
+ }
}
// Received
@@ -894,15 +921,22 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
CRITICAL_BLOCK(cs_mapAddressBook)
{
foreach(const PAIRTYPE(string, int64)& r, listReceived)
- if (mapAddressBook.count(r.first) && (fAllAccounts || mapAddressBook[r.first] == strAccount))
+ {
+ string account;
+ if (mapAddressBook.count(r.first))
+ account = mapAddressBook[r.first];
+ if (fAllAccounts || (account == strAccount))
{
Object entry;
- entry.push_back(Pair("account", mapAddressBook[r.first]));
+ 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)));
- WalletTxToJSON(wtx, entry);
+ if (fLong)
+ WalletTxToJSON(wtx, entry);
ret.push_back(entry);
}
+ }
}
}
@@ -916,6 +950,7 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Ar
Object entry;
entry.push_back(Pair("account", acentry.strAccount));
entry.push_back(Pair("category", "move"));
+ entry.push_back(Pair("time", (boost::int64_t)acentry.nTime));
entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit)));
entry.push_back(Pair("otheraccount", acentry.strOtherAccount));
entry.push_back(Pair("comment", acentry.strComment));
@@ -964,7 +999,7 @@ Value listtransactions(const Array& params, bool fHelp)
{
CWalletTx *const pwtx = (*it).second.first;
if (pwtx != 0)
- ListTransactions(*pwtx, strAccount, 0, ret);
+ ListTransactions(*pwtx, strAccount, 0, true, ret);
CAccountingEntry *const pacentry = (*it).second.second;
if (pacentry != 0)
AcentryToJSON(*pacentry, strAccount, ret);
@@ -994,8 +1029,8 @@ Value listaccounts(const Array& params, bool fHelp)
"Returns Object that has account names as keys, account balances as values.");
int nMinDepth = 1;
- if (params.size() > 1)
- nMinDepth = params[1].get_int();
+ if (params.size() > 0)
+ nMinDepth = params[0].get_int();
map<string, int64> mapAccountBalances;
CRITICAL_BLOCK(cs_mapWallet)
@@ -1007,11 +1042,14 @@ Value listaccounts(const Array& params, bool fHelp)
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
{
const CWalletTx& wtx = (*it).second;
- int64 nGenerated, nSent, nFee;
+ int64 nGenerated, nFee;
string strSentAccount;
list<pair<string, int64> > listReceived;
- wtx.GetAmounts(nGenerated, listReceived, nSent, nFee, strSentAccount);
- mapAccountBalances[strSentAccount] -= nSent+nFee;
+ list<pair<string, int64> > listSent;
+ wtx.GetAmounts(nGenerated, listReceived, listSent, nFee, strSentAccount);
+ mapAccountBalances[strSentAccount] -= nFee;
+ foreach(const PAIRTYPE(string, int64)& s, listSent)
+ mapAccountBalances[strSentAccount] -= s.second;
if (wtx.GetDepthInMainChain() >= nMinDepth)
{
mapAccountBalances[""] += nGenerated;
@@ -1048,7 +1086,7 @@ Value gettransaction(const Array& params, bool fHelp)
CRITICAL_BLOCK(cs_mapWallet)
{
if (!mapWallet.count(hash))
- throw JSONRPCError(-5, "Invalid transaction id");
+ throw JSONRPCError(-5, "Invalid or non-wallet transaction id");
const CWalletTx& wtx = mapWallet[hash];
int64 nCredit = wtx.GetCredit();
@@ -1059,7 +1097,12 @@ Value gettransaction(const Array& params, bool fHelp)
entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
if (wtx.IsFromMe())
entry.push_back(Pair("fee", ValueFromAmount(nFee)));
+
WalletTxToJSON(mapWallet[hash], entry);
+
+ Array details;
+ ListTransactions(mapWallet[hash], "*", 0, false, details);
+ entry.push_back(Pair("details", details));
}
return entry;
@@ -1911,7 +1954,7 @@ int CommandLineRPC(int argc, char *argv[])
if (strMethod == "sendfrom" && n > 2) ConvertTo<double>(params[2]);
if (strMethod == "sendfrom" && n > 3) ConvertTo<boost::int64_t>(params[3]);
if (strMethod == "listtransactions" && n > 1) ConvertTo<boost::int64_t>(params[1]);
- if (strMethod == "listaccounts" && n > 1) ConvertTo<boost::int64_t>(params[1]);
+ if (strMethod == "listaccounts" && n > 0) ConvertTo<boost::int64_t>(params[0]);
// Execute
Object reply = CallRPC(strMethod, params);
diff --git a/util.cpp b/util.cpp
index 42256a9d0c..694f913045 100644
--- a/util.cpp
+++ b/util.cpp
@@ -17,7 +17,7 @@ bool fDaemon = false;
bool fCommandLine = false;
string strMiscWarning;
bool fTestNet = false;
-
+bool fNoListen = false;
diff --git a/util.h b/util.h
index f57e401067..c69bf1ce17 100644
--- a/util.h
+++ b/util.h
@@ -146,6 +146,7 @@ extern bool fDaemon;
extern bool fCommandLine;
extern string strMiscWarning;
extern bool fTestNet;
+extern bool fNoListen;
void RandAddSeed();
void RandAddSeedPerfmon();