Paste: RPCv1
Author: | Luke-Jr |
Mode: | patch |
Date: | Mon, 21 Feb 2011 00:11:24 |
Plain Text |
diff --git a/init.cpp b/init.cpp
index 04bdd68..ec843d8 100644
+++ b/init.cpp
@@ -185,6 +185,7 @@ bool AppInit2(int argc, char* argv[])
" -rpcport=<port> \t\t " + _("Listen for JSON-RPC connections on <port> (default: 8332)\n") +
" -rpcallowip=<ip> \t\t " + _("Allow JSON-RPC connections from specified IP address\n") +
" -rpcconnect=<ip> \t " + _("Send commands to node running on <ip> (default: 127.0.0.1)\n") +
+ " -rpcversion=<n> \t " + _("Send commands in RPC version <n>, default 0 (for now)\n") +
" -keypool=<n> \t " + _("Set key pool size to <n> (default: 100)\n") +
" -rescan \t " + _("Rescan the block chain for missing wallet transactions\n");
diff --git a/json/json_spirit_value.h b/json/json_spirit_value.h
index 7e83a2a..89be790 100644
+++ b/json/json_spirit_value.h
@@ -59,6 +59,8 @@ namespace json_spirit
bool is_uint64() const;
bool is_null() const;
+ bool is_amount() const;
+ void set_amount(bool);
const String_type& get_str() const;
const Object& get_obj() const;
@@ -88,6 +90,7 @@ namespace json_spirit
Value_type type_;
Variant v_;
bool is_uint64_;
+ bool is_amount_;
};
// vector objects
@@ -211,6 +214,7 @@ namespace json_spirit
template< class Config >
Value_impl< Config >::Value_impl()
: type_( null_type )
+ , is_amount_( false )
, is_uint64_( false )
{
}
@@ -219,6 +223,7 @@ namespace json_spirit
Value_impl< Config >::Value_impl( const Const_str_ptr value )
: type_( str_type )
, v_( String_type( value ) )
+ , is_amount_( false )
, is_uint64_( false )
{
}
@@ -227,6 +232,7 @@ namespace json_spirit
Value_impl< Config >::Value_impl( const String_type& value )
: type_( str_type )
, v_( value )
+ , is_amount_( false )
, is_uint64_( false )
{
}
@@ -235,6 +241,7 @@ namespace json_spirit
Value_impl< Config >::Value_impl( const Object& value )
: type_( obj_type )
, v_( value )
+ , is_amount_( false )
, is_uint64_( false )
{
}
@@ -243,6 +250,7 @@ namespace json_spirit
Value_impl< Config >::Value_impl( const Array& value )
: type_( array_type )
, v_( value )
+ , is_amount_( false )
, is_uint64_( false )
{
}
@@ -251,6 +259,7 @@ namespace json_spirit
Value_impl< Config >::Value_impl( bool value )
: type_( bool_type )
, v_( value )
+ , is_amount_( false )
, is_uint64_( false )
{
}
@@ -259,6 +268,7 @@ namespace json_spirit
Value_impl< Config >::Value_impl( int value )
: type_( int_type )
, v_( static_cast< boost::int64_t >( value ) )
+ , is_amount_( false )
, is_uint64_( false )
{
}
@@ -267,6 +277,7 @@ namespace json_spirit
Value_impl< Config >::Value_impl( boost::int64_t value )
: type_( int_type )
, v_( value )
+ , is_amount_( false )
, is_uint64_( false )
{
}
@@ -275,6 +286,7 @@ namespace json_spirit
Value_impl< Config >::Value_impl( boost::uint64_t value )
: type_( int_type )
, v_( static_cast< boost::int64_t >( value ) )
+ , is_amount_( false )
, is_uint64_( true )
{
}
@@ -283,6 +295,7 @@ namespace json_spirit
Value_impl< Config >::Value_impl( double value )
: type_( real_type )
, v_( value )
+ , is_amount_( false )
, is_uint64_( false )
{
}
@@ -291,6 +304,7 @@ namespace json_spirit
Value_impl< Config >::Value_impl( const Value_impl< Config >& other )
: type_( other.type() )
, v_( other.v_ )
+ , is_amount_( other.is_amount_ )
, is_uint64_( other.is_uint64_ )
{
}
@@ -303,6 +317,7 @@ namespace json_spirit
std::swap( type_, tmp.type_ );
std::swap( v_, tmp.v_ );
std::swap( is_uint64_, tmp.is_uint64_ );
+ std::swap( is_amount_, tmp.is_amount_ );
return *this;
}
@@ -330,6 +345,18 @@ namespace json_spirit
}
template< class Config >
+ bool Value_impl< Config >::is_amount() const
+ {
+ return is_amount_;
+ }
+
+ template< class Config >
+ void Value_impl< Config >::set_amount(bool nv)
+ {
+ is_amount_ = nv;
+ }
+
+ template< class Config >
bool Value_impl< Config >::is_null() const
{
return type() == null_type;
@@ -392,6 +419,11 @@ namespace json_spirit
template< class Config >
boost::int64_t Value_impl< Config >::get_int64() const
{
+ if( type() == real_type )
+ {
+ return static_cast< boost::int64_t >( get_real() );
+ }
+
check_type( int_type );
return boost::get< boost::int64_t >( v_ );
diff --git a/json/json_spirit_writer_template.h b/json/json_spirit_writer_template.h
index 28c49dd..98910a6 100644
+++ b/json/json_spirit_writer_template.h
@@ -161,6 +161,8 @@ namespace json_spirit
{
os_ << value.get_int64();
}
+ if (value.is_amount())
+ os_ << ".0";
}
void output( const String_type& s )
diff --git a/main.cpp b/main.cpp
index a47f3a9..cbbe795 100644
+++ b/main.cpp
@@ -3750,16 +3750,16 @@ bool SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, set<
int64 n = pcoin->GetCredit();
if (n <= 0)
continue;
+ if (n == nTargetValue)
{
setCoinsRet.insert(pcoin);
return true;
}
+ else if (n < nTargetValue + CENT)
+ {
+ vValue.push_back(make_pair(n, pcoin));
+ nTotalLower += n;
+ }
else if (n < nLowestLarger)
{
nLowestLarger = n;
@@ -3768,7 +3768,14 @@ bool SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, set<
}
}
+ if (nTotalLower == nTargetValue || nTotalLower == nTargetValue + CENT)
+ {
+ for (int i = 0; i < vValue.size(); ++i)
+ setCoinsRet.insert(vValue[i].second);
+ return true;
+ }
+
+ if (nTotalLower < nTargetValue + (pcoinLowestLarger ? CENT : 0))
{
if (pcoinLowestLarger == NULL)
return false;
@@ -3776,6 +3783,9 @@ bool SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, set<
return true;
}
+ if (nTotalLower >= nTargetValue + CENT)
+ nTargetValue += CENT;
+
// Solve subset sum by stochastic approximation
sort(vValue.rbegin(), vValue.rend());
vector<char> vfIncluded;
diff --git a/rpc.cpp b/rpc.cpp
index 69b09bc..21a098e 100644
+++ b/rpc.cpp
@@ -2,6 +2,8 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+#include <string.h>
+
#include "headers.h"
#include "cryptopp/sha.h"
#undef printf
@@ -12,6 +14,7 @@
#include <boost/asio/ssl.hpp>
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SSLStream;
#endif
+#include <boost/lexical_cast.hpp>
#include "json/json_spirit_reader_template.h"
#include "json/json_spirit_writer_template.h"
#include "json/json_spirit_utils.h"
@@ -25,7 +28,7 @@ using namespace boost::asio;
using namespace json_spirit;
void ThreadRPCServer2(void* parg);
+typedef Value(*rpcfn_type)(int, const Array& params, bool fHelp);
extern map<string, rpcfn_type> mapCallTable;
@@ -60,20 +63,41 @@ void PrintConsole(const char* format, ...)
}
+int64 AmountFromValue(int ver, const Value& value)
{
+ int64 nAmount;
+ if (!ver) {
double dAmount = value.get_real();
if (dAmount <= 0.0 || dAmount > 21000000.0)
throw JSONRPCError(-3, "Invalid amount");
+ nAmount = roundint64(dAmount * 100.00) * CENT;
+ }
+ else
+ nAmount = value.get_int64();
if (!MoneyRange(nAmount))
throw JSONRPCError(-3, "Invalid amount");
return nAmount;
}
+Value ValueFromAmount(int ver, int64 amount)
+{
+ if (!ver)
+ return (double)amount / (double)COIN;
+ Value rv((boost::int64_t)amount);
+ rv.set_amount(true);
+ return rv;
+}
+
+__deprecated__
+int64 AmountFromValue(const Value& value)
+{
+ return AmountFromValue(0, value);
+}
+
+__deprecated__
Value ValueFromAmount(int64 amount)
{
+ return ValueFromAmount(0, amount);
}
void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
@@ -100,7 +124,7 @@ string AccountFromValue(const Value& value)
///
+Value help(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() > 1)
throw runtime_error(
@@ -128,7 +152,7 @@ Value help(const Array& params, bool fHelp)
Array params;
rpcfn_type pfn = (*mi).second;
if (setDone.insert(pfn).second)
+ (*pfn)(ver, params, true);
}
catch (std::exception& e)
{
@@ -147,7 +171,7 @@ Value help(const Array& params, bool fHelp)
}
+Value stop(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
@@ -160,7 +184,7 @@ Value stop(const Array& params, bool fHelp)
}
+Value getblockcount(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
@@ -171,7 +195,7 @@ Value getblockcount(const Array& params, bool fHelp)
}
+Value getblocknumber(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
@@ -182,7 +206,7 @@ Value getblocknumber(const Array& params, bool fHelp)
}
+Value getconnectioncount(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
@@ -205,7 +229,7 @@ double GetDifficulty()
return dMinimum / dCurrently;
}
+Value getdifficulty(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
@@ -216,7 +240,7 @@ Value getdifficulty(const Array& params, bool fHelp)
}
+Value getgenerate(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
@@ -227,7 +251,7 @@ Value getgenerate(const Array& params, bool fHelp)
}
+Value setgenerate(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
@@ -255,7 +279,7 @@ Value setgenerate(const Array& params, bool fHelp)
}
+Value gethashespersec(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
@@ -268,7 +292,7 @@ Value gethashespersec(const Array& params, bool fHelp)
}
+Value getinfo(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
@@ -277,23 +301,24 @@ Value getinfo(const Array& params, bool fHelp)
Object obj;
obj.push_back(Pair("version", (int)VERSION));
+ obj.push_back(Pair("rpcversion", (int)ver));
+ obj.push_back(Pair("balance", ValueFromAmount(ver, GetBalance())));
+ obj.push_back(Pair("paytxfee", ValueFromAmount(ver, nTransactionFee)));
obj.push_back(Pair("blocks", (int)nBestHeight));
obj.push_back(Pair("connections", (int)vNodes.size()));
obj.push_back(Pair("proxy", (fUseProxy ? addrProxy.ToStringIPPort() : string())));
obj.push_back(Pair("generate", (bool)fGenerateBitcoins));
obj.push_back(Pair("genproclimit", (int)(fLimitProcessors ? nLimitProcessors : -1)));
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
+ obj.push_back(Pair("hashespersec", gethashespersec(ver, params, false)));
obj.push_back(Pair("testnet", fTestNet));
obj.push_back(Pair("keypoololdest", (boost::int64_t)GetOldestKeyPoolTime()));
obj.push_back(Pair("errors", GetWarnings("statusbar")));
return obj;
}
+Value getnewaddress(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() > 1)
throw runtime_error(
@@ -358,7 +383,7 @@ string GetAccountAddress(string strAccount, bool bForceNew=false)
return strAddress;
}
+Value getaccountaddress(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 1)
throw runtime_error(
@@ -373,7 +398,7 @@ Value getaccountaddress(const Array& params, bool fHelp)
+Value setaccount(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
@@ -401,7 +426,7 @@ Value setaccount(const Array& params, bool fHelp)
}
+Value getaccount(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 1)
throw runtime_error(
@@ -421,7 +446,7 @@ Value getaccount(const Array& params, bool fHelp)
}
+Value getaddressesbyaccount(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 1)
throw runtime_error(
@@ -450,7 +475,7 @@ Value getaddressesbyaccount(const Array& params, bool fHelp)
return ret;
}
+Value sendtoaddress(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() < 2 || params.size() > 4)
throw runtime_error(
@@ -460,7 +485,7 @@ Value sendtoaddress(const Array& params, bool fHelp)
string strAddress = params[0].get_str();
// Amount
+ int64 nAmount = AmountFromValue(ver, params[1]);
// Wallet comments
CWalletTx wtx;
@@ -476,7 +501,7 @@ Value sendtoaddress(const Array& params, bool fHelp)
}
+Value getreceivedbyaddress(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
@@ -513,7 +538,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
}
}
+ return ValueFromAmount(ver, nAmount);
}
@@ -538,7 +563,7 @@ void GetAccountPubKeys(string strAccount, set<CScript>& setPubKey)
}
+Value getreceivedbyaccount(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
@@ -572,7 +597,7 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
}
}
+ return ValueFromAmount(ver, nAmount);
}
@@ -610,7 +635,7 @@ int64 GetAccountBalance(const string& strAccount, int nMinDepth)
}
+Value getbalance(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() < 0 || params.size() > 2)
throw runtime_error(
@@ -618,8 +643,9 @@ Value getbalance(const Array& params, bool fHelp)
"If [account] is not specified, returns the server's total available balance.\n"
"If [account] is specified, returns the balance in the account.");
+ if (params.size() == 0) {
+ return ValueFromAmount(ver, GetBalance());
+ }
if (params[0].get_str() == "*") {
// Calculate total balance a different way from GetBalance()
@@ -648,7 +674,7 @@ Value getbalance(const Array& params, bool fHelp)
nBalance += allGenerated;
}
printf("Found %d accounts\n", vAccounts.size());
+ return ValueFromAmount(ver, nBalance);
}
string strAccount = AccountFromValue(params[0]);
@@ -658,11 +684,11 @@ Value getbalance(const Array& params, bool fHelp)
int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
+ return ValueFromAmount(ver, nBalance);
}
+Value movecmd(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() < 3 || params.size() > 5)
throw runtime_error(
@@ -671,7 +697,7 @@ Value movecmd(const Array& params, bool fHelp)
string strFrom = AccountFromValue(params[0]);
string strTo = AccountFromValue(params[1]);
+ int64 nAmount = AmountFromValue(ver, params[2]);
int nMinDepth = 1;
if (params.size() > 3)
nMinDepth = params[3].get_int();
@@ -725,7 +751,7 @@ Value movecmd(const Array& params, bool fHelp)
}
+Value sendfrom(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() < 3 || params.size() > 6)
throw runtime_error(
@@ -734,7 +760,7 @@ Value sendfrom(const Array& params, bool fHelp)
string strAccount = AccountFromValue(params[0]);
string strAddress = params[1].get_str();
+ int64 nAmount = AmountFromValue(ver, params[2]);
int nMinDepth = 1;
if (params.size() > 3)
nMinDepth = params[3].get_int();
@@ -775,7 +801,7 @@ struct tallyitem
}
};
+Value ListReceived(int ver, const Array& params, bool fByAccounts)
{
// Minimum confirmations
int nMinDepth = 1;
@@ -851,7 +877,7 @@ Value ListReceived(const Array& params, bool fByAccounts)
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(ver, nAmount)));
obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf)));
ret.push_back(obj);
}
@@ -867,7 +893,7 @@ Value ListReceived(const Array& params, bool fByAccounts)
Object obj;
obj.push_back(Pair("account", (*it).first));
obj.push_back(Pair("label", (*it).first)); // deprecated
+ obj.push_back(Pair("amount", ValueFromAmount(ver, nAmount)));
obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf)));
ret.push_back(obj);
}
@@ -876,7 +902,7 @@ Value ListReceived(const Array& params, bool fByAccounts)
return ret;
}
+Value listreceivedbyaddress(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() > 2)
throw runtime_error(
@@ -889,10 +915,10 @@ Value listreceivedbyaddress(const Array& params, bool fHelp)
" \"amount\" : total amount received by the address\n"
" \"confirmations\" : number of confirmations of the most recent transaction included");
+ return ListReceived(ver, params, false);
}
+Value listreceivedbyaccount(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() > 2)
throw runtime_error(
@@ -904,10 +930,10 @@ Value listreceivedbyaccount(const Array& params, bool fHelp)
" \"amount\" : total amount received by addresses with this account\n"
" \"confirmations\" : number of confirmations of the most recent transaction included");
+ return ListReceived(ver, params, true);
}
+void ListTransactions(int ver, const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret)
{
int64 nGenerated, nFee;
string strSentAccount;
@@ -923,7 +949,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
Object entry;
entry.push_back(Pair("account", string("")));
entry.push_back(Pair("category", "generate"));
+ entry.push_back(Pair("amount", ValueFromAmount(ver, nGenerated)));
if (fLong)
WalletTxToJSON(wtx, entry);
ret.push_back(entry);
@@ -938,8 +964,8 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
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(ver, -s.second)));
+ entry.push_back(Pair("fee", ValueFromAmount(ver, -nFee)));
if (fLong)
WalletTxToJSON(wtx, entry);
ret.push_back(entry);
@@ -961,7 +987,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
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(ver, r.second)));
if (fLong)
WalletTxToJSON(wtx, entry);
ret.push_back(entry);
@@ -971,7 +997,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
}
+void AcentryToJSON(int ver, const CAccountingEntry& acentry, const string& strAccount, Array& ret)
{
bool fAllAccounts = (strAccount == string("*"));
@@ -981,14 +1007,14 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Ar
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(ver, acentry.nCreditDebit)));
entry.push_back(Pair("otheraccount", acentry.strOtherAccount));
entry.push_back(Pair("comment", acentry.strComment));
ret.push_back(entry);
}
}
+Value listtransactions(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() > 2)
throw runtime_error(
@@ -1029,10 +1055,10 @@ Value listtransactions(const Array& params, bool fHelp)
{
CWalletTx *const pwtx = (*it).second.first;
if (pwtx != 0)
+ ListTransactions(ver, *pwtx, strAccount, 0, true, ret);
CAccountingEntry *const pacentry = (*it).second.second;
if (pacentry != 0)
+ AcentryToJSON(ver, *pacentry, strAccount, ret);
if (ret.size() >= nCount) break;
}
@@ -1051,7 +1077,7 @@ Value listtransactions(const Array& params, bool fHelp)
return ret;
}
+Value listaccounts(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() > 1)
throw runtime_error(
@@ -1099,12 +1125,12 @@ Value listaccounts(const Array& params, bool fHelp)
Object ret;
foreach(const PAIRTYPE(string, int64)& accountBalance, mapAccountBalances) {
+ ret.push_back(Pair(accountBalance.first, ValueFromAmount(ver, accountBalance.second)));
}
return ret;
}
+Value gettransaction(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 1)
throw runtime_error(
@@ -1126,14 +1152,14 @@ Value gettransaction(const Array& params, bool fHelp)
int64 nNet = nCredit - nDebit;
int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0);
+ entry.push_back(Pair("amount", ValueFromAmount(ver, nNet - nFee)));
if (wtx.IsFromMe())
+ entry.push_back(Pair("fee", ValueFromAmount(ver, nFee)));
WalletTxToJSON(mapWallet[hash], entry);
Array details;
+ ListTransactions(ver, mapWallet[hash], "*", 0, false, details);
entry.push_back(Pair("details", details));
}
@@ -1141,7 +1167,7 @@ Value gettransaction(const Array& params, bool fHelp)
}
+Value backupwallet(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 1)
throw runtime_error(
@@ -1155,7 +1181,7 @@ Value backupwallet(const Array& params, bool fHelp)
}
+Value validateaddress(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 1)
throw runtime_error(
@@ -1185,7 +1211,7 @@ Value validateaddress(const Array& params, bool fHelp)
}
+Value getwork(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() > 1)
throw runtime_error(
@@ -1806,6 +1832,21 @@ void ThreadRPCServer2(void* parg)
if (valMethod.type() != str_type)
throw JSONRPCError(-32600, "Method must be a string");
string strMethod = valMethod.get_str();
+ int APIVersion = 0;
+ {
+ size_t nlen;
+ const char*data;
+ if (strMethod.size() > 10
+ && 0 == strncmp(data = strMethod.data(), "bitcoin.", 8)
+ && (nlen = strMethod.find('.', 8)) != string::npos) {
+ nlen -= 8;
+ char ndata[nlen + 1];
+ memcpy(ndata, data + 8, nlen);
+ ndata[nlen] = '\0';
+ APIVersion = atoi(ndata);
+ strMethod.erase(0, 9 + nlen);
+ }
+ }
if (strMethod != "getwork")
printf("ThreadRPCServer method=%s\n", strMethod.c_str());
@@ -1832,7 +1873,7 @@ void ThreadRPCServer2(void* parg)
try
{
// Execute
+ Value result = (*(*mi).second)(APIVersion, params, false);
// Send reply
string strReply = JSONRPCReply(result, Value::null, id);
@@ -1938,6 +1979,18 @@ void ConvertTo(Value& value)
}
}
+void ConvertToAmount(int ver, Value& value)
+{
+ switch (ver) {
+ case 0:
+ ConvertTo<double>(value);
+ break;
+ default:
+ ConvertTo<boost::int64_t>(value);
+ value.set_amount(true);
+ }
+}
+
int CommandLineRPC(int argc, char *argv[])
{
string strPrint;
@@ -1951,6 +2004,8 @@ int CommandLineRPC(int argc, char *argv[])
argv++;
}
+ int64 APIVersion = GetArg("-rpcversion", 0);
+
// Method
if (argc < 2)
throw runtime_error("too few parameters");
@@ -1967,7 +2022,7 @@ int CommandLineRPC(int argc, char *argv[])
//
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) ConvertToAmount(APIVersion, 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 == "getreceivedbyaccount" && n > 1) ConvertTo<boost::int64_t>(params[1]);
@@ -1981,13 +2036,16 @@ int CommandLineRPC(int argc, char *argv[])
if (strMethod == "listreceivedbylabel" && n > 0) ConvertTo<boost::int64_t>(params[0]); // deprecated
if (strMethod == "listreceivedbylabel" && n > 1) ConvertTo<bool>(params[1]); // deprecated
if (strMethod == "getbalance" && n > 1) ConvertTo<boost::int64_t>(params[1]);
+ if (strMethod == "move" && n > 2) ConvertToAmount(APIVersion, params[2]);
if (strMethod == "move" && n > 3) ConvertTo<boost::int64_t>(params[3]);
+ if (strMethod == "sendfrom" && n > 2) ConvertToAmount(APIVersion, 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 > 0) ConvertTo<boost::int64_t>(params[0]);
+ if (APIVersion)
+ strMethod.insert(0, "bitcoin." + boost::lexical_cast<string>(APIVersion) + '.');
+
// Execute
Object reply = CallRPC(strMethod, params);
diff --git a/util.h b/util.h
index c69bf1c..69fd2ea 100644
+++ b/util.h
@@ -17,6 +17,14 @@ typedef unsigned long long uint64;
#define __forceinline inline
#endif
+#ifndef __deprecated__
+# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+# define __deprecated__ __attribute ((__deprecated__))
+# else
+# define __deprecated /* noop */
+# endif
+#endif
+
#define foreach BOOST_FOREACH
#define loop for (;;)
#define BEGIN(a) ((char*)&(a))
Author: | Luke-Jr |
Mode: | patch |
Date: | Mon, 21 Feb 2011 03:30:52 |
Plain Text |
diff --git a/init.cpp b/init.cpp
index 04bdd68..ec843d8 100644
+++ b/init.cpp
@@ -185,6 +185,7 @@ bool AppInit2(int argc, char* argv[])
" -rpcport=<port> \t\t " + _("Listen for JSON-RPC connections on <port> (default: 8332)\n") +
" -rpcallowip=<ip> \t\t " + _("Allow JSON-RPC connections from specified IP address\n") +
" -rpcconnect=<ip> \t " + _("Send commands to node running on <ip> (default: 127.0.0.1)\n") +
+ " -rpcversion=<n> \t " + _("Send commands in RPC version <n>, default 0 (for now)\n") +
" -keypool=<n> \t " + _("Set key pool size to <n> (default: 100)\n") +
" -rescan \t " + _("Rescan the block chain for missing wallet transactions\n");
diff --git a/json/json_spirit_value.h b/json/json_spirit_value.h
index 7e83a2a..89be790 100644
+++ b/json/json_spirit_value.h
@@ -59,6 +59,8 @@ namespace json_spirit
bool is_uint64() const;
bool is_null() const;
+ bool is_amount() const;
+ void set_amount(bool);
const String_type& get_str() const;
const Object& get_obj() const;
@@ -88,6 +90,7 @@ namespace json_spirit
Value_type type_;
Variant v_;
bool is_uint64_;
+ bool is_amount_;
};
// vector objects
@@ -211,6 +214,7 @@ namespace json_spirit
template< class Config >
Value_impl< Config >::Value_impl()
: type_( null_type )
+ , is_amount_( false )
, is_uint64_( false )
{
}
@@ -219,6 +223,7 @@ namespace json_spirit
Value_impl< Config >::Value_impl( const Const_str_ptr value )
: type_( str_type )
, v_( String_type( value ) )
+ , is_amount_( false )
, is_uint64_( false )
{
}
@@ -227,6 +232,7 @@ namespace json_spirit
Value_impl< Config >::Value_impl( const String_type& value )
: type_( str_type )
, v_( value )
+ , is_amount_( false )
, is_uint64_( false )
{
}
@@ -235,6 +241,7 @@ namespace json_spirit
Value_impl< Config >::Value_impl( const Object& value )
: type_( obj_type )
, v_( value )
+ , is_amount_( false )
, is_uint64_( false )
{
}
@@ -243,6 +250,7 @@ namespace json_spirit
Value_impl< Config >::Value_impl( const Array& value )
: type_( array_type )
, v_( value )
+ , is_amount_( false )
, is_uint64_( false )
{
}
@@ -251,6 +259,7 @@ namespace json_spirit
Value_impl< Config >::Value_impl( bool value )
: type_( bool_type )
, v_( value )
+ , is_amount_( false )
, is_uint64_( false )
{
}
@@ -259,6 +268,7 @@ namespace json_spirit
Value_impl< Config >::Value_impl( int value )
: type_( int_type )
, v_( static_cast< boost::int64_t >( value ) )
+ , is_amount_( false )
, is_uint64_( false )
{
}
@@ -267,6 +277,7 @@ namespace json_spirit
Value_impl< Config >::Value_impl( boost::int64_t value )
: type_( int_type )
, v_( value )
+ , is_amount_( false )
, is_uint64_( false )
{
}
@@ -275,6 +286,7 @@ namespace json_spirit
Value_impl< Config >::Value_impl( boost::uint64_t value )
: type_( int_type )
, v_( static_cast< boost::int64_t >( value ) )
+ , is_amount_( false )
, is_uint64_( true )
{
}
@@ -283,6 +295,7 @@ namespace json_spirit
Value_impl< Config >::Value_impl( double value )
: type_( real_type )
, v_( value )
+ , is_amount_( false )
, is_uint64_( false )
{
}
@@ -291,6 +304,7 @@ namespace json_spirit
Value_impl< Config >::Value_impl( const Value_impl< Config >& other )
: type_( other.type() )
, v_( other.v_ )
+ , is_amount_( other.is_amount_ )
, is_uint64_( other.is_uint64_ )
{
}
@@ -303,6 +317,7 @@ namespace json_spirit
std::swap( type_, tmp.type_ );
std::swap( v_, tmp.v_ );
std::swap( is_uint64_, tmp.is_uint64_ );
+ std::swap( is_amount_, tmp.is_amount_ );
return *this;
}
@@ -330,6 +345,18 @@ namespace json_spirit
}
template< class Config >
+ bool Value_impl< Config >::is_amount() const
+ {
+ return is_amount_;
+ }
+
+ template< class Config >
+ void Value_impl< Config >::set_amount(bool nv)
+ {
+ is_amount_ = nv;
+ }
+
+ template< class Config >
bool Value_impl< Config >::is_null() const
{
return type() == null_type;
@@ -392,6 +419,11 @@ namespace json_spirit
template< class Config >
boost::int64_t Value_impl< Config >::get_int64() const
{
+ if( type() == real_type )
+ {
+ return static_cast< boost::int64_t >( get_real() );
+ }
+
check_type( int_type );
return boost::get< boost::int64_t >( v_ );
diff --git a/json/json_spirit_writer_template.h b/json/json_spirit_writer_template.h
index 28c49dd..98910a6 100644
+++ b/json/json_spirit_writer_template.h
@@ -161,6 +161,8 @@ namespace json_spirit
{
os_ << value.get_int64();
}
+ if (value.is_amount())
+ os_ << ".0";
}
void output( const String_type& s )
diff --git a/rpc.cpp b/rpc.cpp
index 69b09bc..21a098e 100644
+++ b/rpc.cpp
@@ -2,6 +2,8 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+#include <string.h>
+
#include "headers.h"
#include "cryptopp/sha.h"
#undef printf
@@ -12,6 +14,7 @@
#include <boost/asio/ssl.hpp>
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SSLStream;
#endif
+#include <boost/lexical_cast.hpp>
#include "json/json_spirit_reader_template.h"
#include "json/json_spirit_writer_template.h"
#include "json/json_spirit_utils.h"
@@ -25,7 +28,7 @@ using namespace boost::asio;
using namespace json_spirit;
void ThreadRPCServer2(void* parg);
+typedef Value(*rpcfn_type)(int, const Array& params, bool fHelp);
extern map<string, rpcfn_type> mapCallTable;
@@ -60,20 +63,41 @@ void PrintConsole(const char* format, ...)
}
+int64 AmountFromValue(int ver, const Value& value)
{
+ int64 nAmount;
+ if (!ver) {
double dAmount = value.get_real();
if (dAmount <= 0.0 || dAmount > 21000000.0)
throw JSONRPCError(-3, "Invalid amount");
+ nAmount = roundint64(dAmount * 100.00) * CENT;
+ }
+ else
+ nAmount = value.get_int64();
if (!MoneyRange(nAmount))
throw JSONRPCError(-3, "Invalid amount");
return nAmount;
}
+Value ValueFromAmount(int ver, int64 amount)
+{
+ if (!ver)
+ return (double)amount / (double)COIN;
+ Value rv((boost::int64_t)amount);
+ rv.set_amount(true);
+ return rv;
+}
+
+__deprecated__
+int64 AmountFromValue(const Value& value)
+{
+ return AmountFromValue(0, value);
+}
+
+__deprecated__
Value ValueFromAmount(int64 amount)
{
+ return ValueFromAmount(0, amount);
}
void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
@@ -100,7 +124,7 @@ string AccountFromValue(const Value& value)
///
+Value help(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() > 1)
throw runtime_error(
@@ -128,7 +152,7 @@ Value help(const Array& params, bool fHelp)
Array params;
rpcfn_type pfn = (*mi).second;
if (setDone.insert(pfn).second)
+ (*pfn)(ver, params, true);
}
catch (std::exception& e)
{
@@ -147,7 +171,7 @@ Value help(const Array& params, bool fHelp)
}
+Value stop(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
@@ -160,7 +184,7 @@ Value stop(const Array& params, bool fHelp)
}
+Value getblockcount(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
@@ -171,7 +195,7 @@ Value getblockcount(const Array& params, bool fHelp)
}
+Value getblocknumber(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
@@ -182,7 +206,7 @@ Value getblocknumber(const Array& params, bool fHelp)
}
+Value getconnectioncount(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
@@ -205,7 +229,7 @@ double GetDifficulty()
return dMinimum / dCurrently;
}
+Value getdifficulty(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
@@ -216,7 +240,7 @@ Value getdifficulty(const Array& params, bool fHelp)
}
+Value getgenerate(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
@@ -227,7 +251,7 @@ Value getgenerate(const Array& params, bool fHelp)
}
+Value setgenerate(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
@@ -255,7 +279,7 @@ Value setgenerate(const Array& params, bool fHelp)
}
+Value gethashespersec(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
@@ -268,7 +292,7 @@ Value gethashespersec(const Array& params, bool fHelp)
}
+Value getinfo(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
@@ -277,23 +301,24 @@ Value getinfo(const Array& params, bool fHelp)
Object obj;
obj.push_back(Pair("version", (int)VERSION));
+ obj.push_back(Pair("rpcversion", (int)ver));
+ obj.push_back(Pair("balance", ValueFromAmount(ver, GetBalance())));
+ obj.push_back(Pair("paytxfee", ValueFromAmount(ver, nTransactionFee)));
obj.push_back(Pair("blocks", (int)nBestHeight));
obj.push_back(Pair("connections", (int)vNodes.size()));
obj.push_back(Pair("proxy", (fUseProxy ? addrProxy.ToStringIPPort() : string())));
obj.push_back(Pair("generate", (bool)fGenerateBitcoins));
obj.push_back(Pair("genproclimit", (int)(fLimitProcessors ? nLimitProcessors : -1)));
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
+ obj.push_back(Pair("hashespersec", gethashespersec(ver, params, false)));
obj.push_back(Pair("testnet", fTestNet));
obj.push_back(Pair("keypoololdest", (boost::int64_t)GetOldestKeyPoolTime()));
obj.push_back(Pair("errors", GetWarnings("statusbar")));
return obj;
}
+Value getnewaddress(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() > 1)
throw runtime_error(
@@ -358,7 +383,7 @@ string GetAccountAddress(string strAccount, bool bForceNew=false)
return strAddress;
}
+Value getaccountaddress(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 1)
throw runtime_error(
@@ -373,7 +398,7 @@ Value getaccountaddress(const Array& params, bool fHelp)
+Value setaccount(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
@@ -401,7 +426,7 @@ Value setaccount(const Array& params, bool fHelp)
}
+Value getaccount(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 1)
throw runtime_error(
@@ -421,7 +446,7 @@ Value getaccount(const Array& params, bool fHelp)
}
+Value getaddressesbyaccount(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 1)
throw runtime_error(
@@ -450,7 +475,7 @@ Value getaddressesbyaccount(const Array& params, bool fHelp)
return ret;
}
+Value sendtoaddress(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() < 2 || params.size() > 4)
throw runtime_error(
@@ -460,7 +485,7 @@ Value sendtoaddress(const Array& params, bool fHelp)
string strAddress = params[0].get_str();
// Amount
+ int64 nAmount = AmountFromValue(ver, params[1]);
// Wallet comments
CWalletTx wtx;
@@ -476,7 +501,7 @@ Value sendtoaddress(const Array& params, bool fHelp)
}
+Value getreceivedbyaddress(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
@@ -513,7 +538,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
}
}
+ return ValueFromAmount(ver, nAmount);
}
@@ -538,7 +563,7 @@ void GetAccountPubKeys(string strAccount, set<CScript>& setPubKey)
}
+Value getreceivedbyaccount(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
@@ -572,7 +597,7 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
}
}
+ return ValueFromAmount(ver, nAmount);
}
@@ -610,7 +635,7 @@ int64 GetAccountBalance(const string& strAccount, int nMinDepth)
}
+Value getbalance(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() < 0 || params.size() > 2)
throw runtime_error(
@@ -618,8 +643,9 @@ Value getbalance(const Array& params, bool fHelp)
"If [account] is not specified, returns the server's total available balance.\n"
"If [account] is specified, returns the balance in the account.");
+ if (params.size() == 0) {
+ return ValueFromAmount(ver, GetBalance());
+ }
if (params[0].get_str() == "*") {
// Calculate total balance a different way from GetBalance()
@@ -648,7 +674,7 @@ Value getbalance(const Array& params, bool fHelp)
nBalance += allGenerated;
}
printf("Found %d accounts\n", vAccounts.size());
+ return ValueFromAmount(ver, nBalance);
}
string strAccount = AccountFromValue(params[0]);
@@ -658,11 +684,11 @@ Value getbalance(const Array& params, bool fHelp)
int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
+ return ValueFromAmount(ver, nBalance);
}
+Value movecmd(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() < 3 || params.size() > 5)
throw runtime_error(
@@ -671,7 +697,7 @@ Value movecmd(const Array& params, bool fHelp)
string strFrom = AccountFromValue(params[0]);
string strTo = AccountFromValue(params[1]);
+ int64 nAmount = AmountFromValue(ver, params[2]);
int nMinDepth = 1;
if (params.size() > 3)
nMinDepth = params[3].get_int();
@@ -725,7 +751,7 @@ Value movecmd(const Array& params, bool fHelp)
}
+Value sendfrom(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() < 3 || params.size() > 6)
throw runtime_error(
@@ -734,7 +760,7 @@ Value sendfrom(const Array& params, bool fHelp)
string strAccount = AccountFromValue(params[0]);
string strAddress = params[1].get_str();
+ int64 nAmount = AmountFromValue(ver, params[2]);
int nMinDepth = 1;
if (params.size() > 3)
nMinDepth = params[3].get_int();
@@ -775,7 +801,7 @@ struct tallyitem
}
};
+Value ListReceived(int ver, const Array& params, bool fByAccounts)
{
// Minimum confirmations
int nMinDepth = 1;
@@ -851,7 +877,7 @@ Value ListReceived(const Array& params, bool fByAccounts)
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(ver, nAmount)));
obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf)));
ret.push_back(obj);
}
@@ -867,7 +893,7 @@ Value ListReceived(const Array& params, bool fByAccounts)
Object obj;
obj.push_back(Pair("account", (*it).first));
obj.push_back(Pair("label", (*it).first)); // deprecated
+ obj.push_back(Pair("amount", ValueFromAmount(ver, nAmount)));
obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf)));
ret.push_back(obj);
}
@@ -876,7 +902,7 @@ Value ListReceived(const Array& params, bool fByAccounts)
return ret;
}
+Value listreceivedbyaddress(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() > 2)
throw runtime_error(
@@ -889,10 +915,10 @@ Value listreceivedbyaddress(const Array& params, bool fHelp)
" \"amount\" : total amount received by the address\n"
" \"confirmations\" : number of confirmations of the most recent transaction included");
+ return ListReceived(ver, params, false);
}
+Value listreceivedbyaccount(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() > 2)
throw runtime_error(
@@ -904,10 +930,10 @@ Value listreceivedbyaccount(const Array& params, bool fHelp)
" \"amount\" : total amount received by addresses with this account\n"
" \"confirmations\" : number of confirmations of the most recent transaction included");
+ return ListReceived(ver, params, true);
}
+void ListTransactions(int ver, const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret)
{
int64 nGenerated, nFee;
string strSentAccount;
@@ -923,7 +949,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
Object entry;
entry.push_back(Pair("account", string("")));
entry.push_back(Pair("category", "generate"));
+ entry.push_back(Pair("amount", ValueFromAmount(ver, nGenerated)));
if (fLong)
WalletTxToJSON(wtx, entry);
ret.push_back(entry);
@@ -938,8 +964,8 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
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(ver, -s.second)));
+ entry.push_back(Pair("fee", ValueFromAmount(ver, -nFee)));
if (fLong)
WalletTxToJSON(wtx, entry);
ret.push_back(entry);
@@ -961,7 +987,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
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(ver, r.second)));
if (fLong)
WalletTxToJSON(wtx, entry);
ret.push_back(entry);
@@ -971,7 +997,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
}
+void AcentryToJSON(int ver, const CAccountingEntry& acentry, const string& strAccount, Array& ret)
{
bool fAllAccounts = (strAccount == string("*"));
@@ -981,14 +1007,14 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Ar
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(ver, acentry.nCreditDebit)));
entry.push_back(Pair("otheraccount", acentry.strOtherAccount));
entry.push_back(Pair("comment", acentry.strComment));
ret.push_back(entry);
}
}
+Value listtransactions(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() > 2)
throw runtime_error(
@@ -1029,10 +1055,10 @@ Value listtransactions(const Array& params, bool fHelp)
{
CWalletTx *const pwtx = (*it).second.first;
if (pwtx != 0)
+ ListTransactions(ver, *pwtx, strAccount, 0, true, ret);
CAccountingEntry *const pacentry = (*it).second.second;
if (pacentry != 0)
+ AcentryToJSON(ver, *pacentry, strAccount, ret);
if (ret.size() >= nCount) break;
}
@@ -1051,7 +1077,7 @@ Value listtransactions(const Array& params, bool fHelp)
return ret;
}
+Value listaccounts(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() > 1)
throw runtime_error(
@@ -1099,12 +1125,12 @@ Value listaccounts(const Array& params, bool fHelp)
Object ret;
foreach(const PAIRTYPE(string, int64)& accountBalance, mapAccountBalances) {
+ ret.push_back(Pair(accountBalance.first, ValueFromAmount(ver, accountBalance.second)));
}
return ret;
}
+Value gettransaction(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 1)
throw runtime_error(
@@ -1126,14 +1152,14 @@ Value gettransaction(const Array& params, bool fHelp)
int64 nNet = nCredit - nDebit;
int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0);
+ entry.push_back(Pair("amount", ValueFromAmount(ver, nNet - nFee)));
if (wtx.IsFromMe())
+ entry.push_back(Pair("fee", ValueFromAmount(ver, nFee)));
WalletTxToJSON(mapWallet[hash], entry);
Array details;
+ ListTransactions(ver, mapWallet[hash], "*", 0, false, details);
entry.push_back(Pair("details", details));
}
@@ -1141,7 +1167,7 @@ Value gettransaction(const Array& params, bool fHelp)
}
+Value backupwallet(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 1)
throw runtime_error(
@@ -1155,7 +1181,7 @@ Value backupwallet(const Array& params, bool fHelp)
}
+Value validateaddress(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() != 1)
throw runtime_error(
@@ -1185,7 +1211,7 @@ Value validateaddress(const Array& params, bool fHelp)
}
+Value getwork(int ver, const Array& params, bool fHelp)
{
if (fHelp || params.size() > 1)
throw runtime_error(
@@ -1806,6 +1832,21 @@ void ThreadRPCServer2(void* parg)
if (valMethod.type() != str_type)
throw JSONRPCError(-32600, "Method must be a string");
string strMethod = valMethod.get_str();
+ int APIVersion = 0;
+ {
+ size_t nlen;
+ const char*data;
+ if (strMethod.size() > 10
+ && 0 == strncmp(data = strMethod.data(), "bitcoin.", 8)
+ && (nlen = strMethod.find('.', 8)) != string::npos) {
+ nlen -= 8;
+ char ndata[nlen + 1];
+ memcpy(ndata, data + 8, nlen);
+ ndata[nlen] = '\0';
+ APIVersion = atoi(ndata);
+ strMethod.erase(0, 9 + nlen);
+ }
+ }
if (strMethod != "getwork")
printf("ThreadRPCServer method=%s\n", strMethod.c_str());
@@ -1832,7 +1873,7 @@ void ThreadRPCServer2(void* parg)
try
{
// Execute
+ Value result = (*(*mi).second)(APIVersion, params, false);
// Send reply
string strReply = JSONRPCReply(result, Value::null, id);
@@ -1938,6 +1979,18 @@ void ConvertTo(Value& value)
}
}
+void ConvertToAmount(int ver, Value& value)
+{
+ switch (ver) {
+ case 0:
+ ConvertTo<double>(value);
+ break;
+ default:
+ ConvertTo<boost::int64_t>(value);
+ value.set_amount(true);
+ }
+}
+
int CommandLineRPC(int argc, char *argv[])
{
string strPrint;
@@ -1951,6 +2004,8 @@ int CommandLineRPC(int argc, char *argv[])
argv++;
}
+ int64 APIVersion = GetArg("-rpcversion", 0);
+
// Method
if (argc < 2)
throw runtime_error("too few parameters");
@@ -1967,7 +2022,7 @@ int CommandLineRPC(int argc, char *argv[])
//
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) ConvertToAmount(APIVersion, 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 == "getreceivedbyaccount" && n > 1) ConvertTo<boost::int64_t>(params[1]);
@@ -1981,13 +2036,16 @@ int CommandLineRPC(int argc, char *argv[])
if (strMethod == "listreceivedbylabel" && n > 0) ConvertTo<boost::int64_t>(params[0]); // deprecated
if (strMethod == "listreceivedbylabel" && n > 1) ConvertTo<bool>(params[1]); // deprecated
if (strMethod == "getbalance" && n > 1) ConvertTo<boost::int64_t>(params[1]);
+ if (strMethod == "move" && n > 2) ConvertToAmount(APIVersion, params[2]);
if (strMethod == "move" && n > 3) ConvertTo<boost::int64_t>(params[3]);
+ if (strMethod == "sendfrom" && n > 2) ConvertToAmount(APIVersion, 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 > 0) ConvertTo<boost::int64_t>(params[0]);
+ if (APIVersion)
+ strMethod.insert(0, "bitcoin." + boost::lexical_cast<string>(APIVersion) + '.');
+
// Execute
Object reply = CallRPC(strMethod, params);
diff --git a/util.h b/util.h
index c69bf1c..69fd2ea 100644
+++ b/util.h
@@ -17,6 +17,14 @@ typedef unsigned long long uint64;
#define __forceinline inline
#endif
+#ifndef __deprecated__
+# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+# define __deprecated__ __attribute ((__deprecated__))
+# else
+# define __deprecated /* noop */
+# endif
+#endif
+
#define foreach BOOST_FOREACH
#define loop for (;;)
#define BEGIN(a) ((char*)&(a))
New Annotation