Merge branch 'FSM' of https://github.com/jl777/komodo into jl777-FSM
merge
This commit is contained in:
1674
src/rpc/blockchain.cpp
Normal file
1674
src/rpc/blockchain.cpp
Normal file
File diff suppressed because it is too large
Load Diff
214
src/rpc/client.cpp
Normal file
214
src/rpc/client.cpp
Normal file
@@ -0,0 +1,214 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "rpc/client.h"
|
||||
#include "rpc/protocol.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <set>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <univalue.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class CRPCConvertParam
|
||||
{
|
||||
public:
|
||||
std::string methodName; //! method whose params want conversion
|
||||
int paramIdx; //! 0-based idx of param to convert
|
||||
};
|
||||
|
||||
static const CRPCConvertParam vRPCConvertParams[] =
|
||||
{
|
||||
{ "stop", 0 },
|
||||
{ "setmocktime", 0 },
|
||||
{ "getaddednodeinfo", 0 },
|
||||
{ "setgenerate", 0 },
|
||||
{ "setgenerate", 1 },
|
||||
{ "generate", 0 },
|
||||
{ "getnetworkhashps", 0 },
|
||||
{ "getnetworkhashps", 1 },
|
||||
{ "getnetworksolps", 0 },
|
||||
{ "getnetworksolps", 1 },
|
||||
{ "sendtoaddress", 1 },
|
||||
{ "sendtoaddress", 4 },
|
||||
{ "settxfee", 0 },
|
||||
{ "getreceivedbyaddress", 1 },
|
||||
{ "getreceivedbyaccount", 1 },
|
||||
{ "listreceivedbyaddress", 0 },
|
||||
{ "listreceivedbyaddress", 1 },
|
||||
{ "listreceivedbyaddress", 2 },
|
||||
{ "listreceivedbyaccount", 0 },
|
||||
{ "listreceivedbyaccount", 1 },
|
||||
{ "listreceivedbyaccount", 2 },
|
||||
{ "getbalance", 1 },
|
||||
{ "getbalance", 2 },
|
||||
{ "getblockhash", 0 },
|
||||
{ "move", 2 },
|
||||
{ "move", 3 },
|
||||
{ "sendfrom", 2 },
|
||||
{ "sendfrom", 3 },
|
||||
{ "listtransactions", 1 },
|
||||
{ "listtransactions", 2 },
|
||||
{ "listtransactions", 3 },
|
||||
{ "listaccounts", 0 },
|
||||
{ "listaccounts", 1 },
|
||||
{ "walletpassphrase", 1 },
|
||||
{ "getblocktemplate", 0 },
|
||||
{ "listsinceblock", 1 },
|
||||
{ "listsinceblock", 2 },
|
||||
{ "sendmany", 1 },
|
||||
{ "sendmany", 2 },
|
||||
{ "sendmany", 4 },
|
||||
{ "addmultisigaddress", 0 },
|
||||
{ "addmultisigaddress", 1 },
|
||||
{ "createmultisig", 0 },
|
||||
{ "createmultisig", 1 },
|
||||
{ "listunspent", 0 },
|
||||
{ "listunspent", 1 },
|
||||
{ "listunspent", 2 },
|
||||
{ "getblock", 1 },
|
||||
{ "getblockheader", 1 },
|
||||
{ "gettransaction", 1 },
|
||||
{ "getrawtransaction", 1 },
|
||||
{ "createrawtransaction", 0 },
|
||||
{ "createrawtransaction", 1 },
|
||||
{ "createrawtransaction", 2 },
|
||||
{ "createrawtransaction", 3 },
|
||||
{ "signrawtransaction", 1 },
|
||||
{ "signrawtransaction", 2 },
|
||||
{ "sendrawtransaction", 1 },
|
||||
{ "fundrawtransaction", 1 },
|
||||
{ "gettxout", 1 },
|
||||
{ "gettxout", 2 },
|
||||
{ "gettxoutproof", 0 },
|
||||
{ "lockunspent", 0 },
|
||||
{ "lockunspent", 1 },
|
||||
{ "importprivkey", 2 },
|
||||
{ "importaddress", 2 },
|
||||
{ "verifychain", 0 },
|
||||
{ "verifychain", 1 },
|
||||
{ "keypoolrefill", 0 },
|
||||
{ "getrawmempool", 0 },
|
||||
{ "estimatefee", 0 },
|
||||
{ "estimatepriority", 0 },
|
||||
{ "prioritisetransaction", 1 },
|
||||
{ "prioritisetransaction", 2 },
|
||||
{ "setban", 2 },
|
||||
{ "setban", 3 },
|
||||
{ "getblockhashes", 0 },
|
||||
{ "getblockhashes", 1 },
|
||||
{ "getblockhashes", 2 },
|
||||
{ "getspentinfo", 0},
|
||||
{ "getaddresstxids", 0},
|
||||
{ "getaddressbalance", 0},
|
||||
{ "getaddressdeltas", 0},
|
||||
{ "getaddressutxos", 0},
|
||||
{ "getaddressmempool", 0},
|
||||
{ "zcrawjoinsplit", 1 },
|
||||
{ "zcrawjoinsplit", 2 },
|
||||
{ "zcrawjoinsplit", 3 },
|
||||
{ "zcrawjoinsplit", 4 },
|
||||
{ "zcbenchmark", 1 },
|
||||
{ "zcbenchmark", 2 },
|
||||
{ "getblocksubsidy", 0},
|
||||
{ "z_listaddresses", 0},
|
||||
{ "z_listreceivedbyaddress", 1},
|
||||
{ "z_listunspent", 0 },
|
||||
{ "z_listunspent", 1 },
|
||||
{ "z_listunspent", 2 },
|
||||
{ "z_listunspent", 3 },
|
||||
{ "z_getbalance", 1},
|
||||
{ "z_gettotalbalance", 0},
|
||||
{ "z_gettotalbalance", 1},
|
||||
{ "z_gettotalbalance", 2},
|
||||
{ "z_mergetoaddress", 0},
|
||||
{ "z_mergetoaddress", 2},
|
||||
{ "z_mergetoaddress", 3},
|
||||
{ "z_mergetoaddress", 4},
|
||||
{ "z_sendmany", 1},
|
||||
{ "z_sendmany", 2},
|
||||
{ "z_sendmany", 3},
|
||||
{ "z_shieldcoinbase", 2},
|
||||
{ "z_shieldcoinbase", 3},
|
||||
{ "z_getoperationstatus", 0},
|
||||
{ "z_getoperationresult", 0},
|
||||
{ "z_importkey", 1 },
|
||||
{ "paxprice", 4 },
|
||||
{ "paxprices", 3 },
|
||||
{ "paxpending", 0 },
|
||||
{ "notaries", 2 },
|
||||
{ "minerids", 1 },
|
||||
{ "kvsearch", 1 },
|
||||
{ "kvupdate", 4 },
|
||||
{ "z_importkey", 2 },
|
||||
{ "z_importviewingkey", 2 },
|
||||
{ "z_getpaymentdisclosure", 1},
|
||||
{ "z_getpaymentdisclosure", 2},
|
||||
// crosschain
|
||||
{ "assetchainproof", 1},
|
||||
{ "crosschainproof", 1},
|
||||
{ "getproofroot", 2},
|
||||
{ "height_MoM", 1},
|
||||
{ "calc_MoM", 2},
|
||||
};
|
||||
|
||||
class CRPCConvertTable
|
||||
{
|
||||
private:
|
||||
std::set<std::pair<std::string, int> > members;
|
||||
|
||||
public:
|
||||
CRPCConvertTable();
|
||||
|
||||
bool convert(const std::string& method, int idx) {
|
||||
return (members.count(std::make_pair(method, idx)) > 0);
|
||||
}
|
||||
};
|
||||
|
||||
CRPCConvertTable::CRPCConvertTable()
|
||||
{
|
||||
const unsigned int n_elem =
|
||||
(sizeof(vRPCConvertParams) / sizeof(vRPCConvertParams[0]));
|
||||
|
||||
for (unsigned int i = 0; i < n_elem; i++) {
|
||||
members.insert(std::make_pair(vRPCConvertParams[i].methodName,
|
||||
vRPCConvertParams[i].paramIdx));
|
||||
}
|
||||
}
|
||||
|
||||
static CRPCConvertTable rpcCvtTable;
|
||||
|
||||
/** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null)
|
||||
* as well as objects and arrays.
|
||||
*/
|
||||
UniValue ParseNonRFCJSONValue(const std::string& strVal)
|
||||
{
|
||||
UniValue jVal;
|
||||
if (!jVal.read(std::string("[")+strVal+std::string("]")) ||
|
||||
!jVal.isArray() || jVal.size()!=1)
|
||||
throw runtime_error(string("Error JSON:")+strVal);
|
||||
return jVal[0];
|
||||
}
|
||||
|
||||
/** Convert strings to command-specific RPC representation */
|
||||
UniValue RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams)
|
||||
{
|
||||
UniValue params(UniValue::VARR);
|
||||
|
||||
for (unsigned int idx = 0; idx < strParams.size(); idx++) {
|
||||
const std::string& strVal = strParams[idx];
|
||||
if (!rpcCvtTable.convert(strMethod, idx)) {
|
||||
// insert string value directly
|
||||
params.push_back(strVal);
|
||||
} else {
|
||||
// parse string as JSON, insert bool/number/object/etc. value
|
||||
params.push_back(ParseNonRFCJSONValue(strVal));
|
||||
}
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
17
src/rpc/client.h
Normal file
17
src/rpc/client.h
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_RPCCLIENT_H
|
||||
#define BITCOIN_RPCCLIENT_H
|
||||
|
||||
#include <univalue.h>
|
||||
|
||||
UniValue RPCConvertValues(const std::string& strMethod, const std::vector<std::string>& strParams);
|
||||
/** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null)
|
||||
* as well as objects and arrays.
|
||||
*/
|
||||
UniValue ParseNonRFCJSONValue(const std::string& strVal);
|
||||
|
||||
#endif // BITCOIN_RPCCLIENT_H
|
||||
313
src/rpc/crosschain.cpp
Normal file
313
src/rpc/crosschain.cpp
Normal file
@@ -0,0 +1,313 @@
|
||||
#include "amount.h"
|
||||
#include "chain.h"
|
||||
#include "chainparams.h"
|
||||
#include "checkpoints.h"
|
||||
#include "crosschain.h"
|
||||
#include "notarisationdb.h"
|
||||
#include "importcoin.h"
|
||||
#include "base58.h"
|
||||
#include "consensus/validation.h"
|
||||
#include "cc/eval.h"
|
||||
#include "cc/utils.h"
|
||||
#include "main.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "rpc/server.h"
|
||||
#include "sync.h"
|
||||
#include "util.h"
|
||||
#include "script/script.h"
|
||||
#include "script/script_error.h"
|
||||
#include "script/sign.h"
|
||||
#include "script/standard.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <univalue.h>
|
||||
#include <regex>
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
int32_t komodo_MoM(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip);
|
||||
int32_t komodo_MoMoMdata(char *hexstr,int32_t hexsize,struct komodo_ccdataMoMoM *mdata,char *symbol,int32_t kmdheight,int32_t notarized_height);
|
||||
struct komodo_ccdata_entry *komodo_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t kmdstarti,int32_t kmdendi);
|
||||
uint256 komodo_calcMoM(int32_t height,int32_t MoMdepth);
|
||||
|
||||
|
||||
UniValue assetchainproof(const UniValue& params, bool fHelp)
|
||||
{
|
||||
uint256 hash;
|
||||
|
||||
// parse params and get notarisation data for tx
|
||||
if ( fHelp || params.size() != 1)
|
||||
throw runtime_error("assetchainproof needs a txid");
|
||||
|
||||
hash = uint256S(params[0].get_str());
|
||||
|
||||
auto proof = GetAssetchainProof(hash);
|
||||
auto proofData = E_MARSHAL(ss << proof);
|
||||
return HexStr(proofData);
|
||||
}
|
||||
|
||||
|
||||
UniValue crosschainproof(const UniValue& params, bool fHelp)
|
||||
{
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
//fprintf(stderr,"crosschainproof needs to be implemented\n");
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
UniValue height_MoM(const UniValue& params, bool fHelp)
|
||||
{
|
||||
int32_t height,depth,notarized_height,MoMoMdepth,MoMoMoffset,kmdstarti,kmdendi; uint256 MoM,MoMoM,kmdtxid; uint32_t timestamp = 0; UniValue ret(UniValue::VOBJ); UniValue a(UniValue::VARR);
|
||||
if ( fHelp || params.size() != 1 )
|
||||
throw runtime_error("height_MoM height\n");
|
||||
LOCK(cs_main);
|
||||
height = atoi(params[0].get_str().c_str());
|
||||
if ( height <= 0 )
|
||||
{
|
||||
if ( chainActive.Tip() == 0 )
|
||||
{
|
||||
ret.push_back(Pair("error",(char *)"no active chain yet"));
|
||||
return(ret);
|
||||
}
|
||||
height = chainActive.Tip()->GetHeight();
|
||||
}
|
||||
//fprintf(stderr,"height_MoM height.%d\n",height);
|
||||
depth = komodo_MoM(¬arized_height,&MoM,&kmdtxid,height,&MoMoM,&MoMoMoffset,&MoMoMdepth,&kmdstarti,&kmdendi);
|
||||
ret.push_back(Pair("coin",(char *)(ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL)));
|
||||
ret.push_back(Pair("height",height));
|
||||
ret.push_back(Pair("timestamp",(uint64_t)timestamp));
|
||||
if ( depth > 0 )
|
||||
{
|
||||
ret.push_back(Pair("depth",depth));
|
||||
ret.push_back(Pair("notarized_height",notarized_height));
|
||||
ret.push_back(Pair("MoM",MoM.GetHex()));
|
||||
ret.push_back(Pair("kmdtxid",kmdtxid.GetHex()));
|
||||
if ( ASSETCHAINS_SYMBOL[0] != 0 )
|
||||
{
|
||||
ret.push_back(Pair("MoMoM",MoMoM.GetHex()));
|
||||
ret.push_back(Pair("MoMoMoffset",MoMoMoffset));
|
||||
ret.push_back(Pair("MoMoMdepth",MoMoMdepth));
|
||||
ret.push_back(Pair("kmdstarti",kmdstarti));
|
||||
ret.push_back(Pair("kmdendi",kmdendi));
|
||||
}
|
||||
} else ret.push_back(Pair("error",(char *)"no MoM for height"));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
UniValue MoMoMdata(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if ( fHelp || params.size() != 3 )
|
||||
throw runtime_error("MoMoMdata symbol kmdheight ccid\n");
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
char* symbol = (char *)params[0].get_str().c_str();
|
||||
int kmdheight = atoi(params[1].get_str().c_str());
|
||||
uint32_t ccid = atoi(params[2].get_str().c_str());
|
||||
ret.push_back(Pair("coin",symbol));
|
||||
ret.push_back(Pair("kmdheight",kmdheight));
|
||||
ret.push_back(Pair("ccid", (int) ccid));
|
||||
|
||||
uint256 destNotarisationTxid;
|
||||
std::vector<uint256> moms;
|
||||
uint256 MoMoM = CalculateProofRoot(symbol, ccid, kmdheight, moms, destNotarisationTxid);
|
||||
|
||||
UniValue valMoms(UniValue::VARR);
|
||||
for (int i=0; i<moms.size(); i++) valMoms.push_back(moms[i].GetHex());
|
||||
ret.push_back(Pair("MoMs", valMoms));
|
||||
ret.push_back(Pair("notarization_hash", destNotarisationTxid.GetHex()));
|
||||
ret.push_back(Pair("MoMoM", MoMoM.GetHex()));
|
||||
auto vmomomdata = E_MARSHAL(ss << MoMoM; ss << ((uint32_t)0));
|
||||
ret.push_back(Pair("data", HexStr(vmomomdata)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
UniValue calc_MoM(const UniValue& params, bool fHelp)
|
||||
{
|
||||
int32_t height,MoMdepth; uint256 MoM; UniValue ret(UniValue::VOBJ); UniValue a(UniValue::VARR);
|
||||
if ( fHelp || params.size() != 2 )
|
||||
throw runtime_error("calc_MoM height MoMdepth\n");
|
||||
LOCK(cs_main);
|
||||
height = atoi(params[0].get_str().c_str());
|
||||
MoMdepth = atoi(params[1].get_str().c_str());
|
||||
if ( height <= 0 || MoMdepth <= 0 || MoMdepth >= height )
|
||||
throw runtime_error("calc_MoM illegal height or MoMdepth\n");
|
||||
//fprintf(stderr,"height_MoM height.%d\n",height);
|
||||
MoM = komodo_calcMoM(height,MoMdepth);
|
||||
ret.push_back(Pair("coin",(char *)(ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL)));
|
||||
ret.push_back(Pair("height",height));
|
||||
ret.push_back(Pair("MoMdepth",MoMdepth));
|
||||
ret.push_back(Pair("MoM",MoM.GetHex()));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
UniValue migrate_converttoexport(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 3)
|
||||
throw runtime_error(
|
||||
"migrate_converttoexport rawTx dest_symbol export_amount\n"
|
||||
"\nConvert a raw transaction to a cross-chain export.\n"
|
||||
"If neccesary, the transaction should be funded using fundrawtransaction.\n"
|
||||
"Finally, the transaction should be signed using signrawtransaction\n"
|
||||
"The finished export transaction, plus the payouts, should be passed to "
|
||||
"the \"migrate_createimporttransaction\" method on a KMD node to get the corresponding "
|
||||
"import transaction.\n"
|
||||
);
|
||||
|
||||
if (ASSETCHAINS_CC < KOMODO_FIRSTFUNGIBLEID)
|
||||
throw runtime_error("-ac_cc < KOMODO_FIRSTFUNGIBLEID");
|
||||
|
||||
if (ASSETCHAINS_SYMBOL[0] == 0)
|
||||
throw runtime_error("Must be called on assetchain");
|
||||
|
||||
vector<uint8_t> txData(ParseHexV(params[0], "argument 1"));
|
||||
CMutableTransaction tx;
|
||||
if (!E_UNMARSHAL(txData, ss >> tx))
|
||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
|
||||
|
||||
string targetSymbol = params[1].get_str();
|
||||
if (targetSymbol.size() == 0 || targetSymbol.size() > 32)
|
||||
throw runtime_error("targetSymbol length must be >0 and <=32");
|
||||
|
||||
if (strcmp(ASSETCHAINS_SYMBOL,targetSymbol.c_str()) == 0)
|
||||
throw runtime_error("cant send a coin to the same chain");
|
||||
|
||||
CAmount burnAmount = AmountFromValue(params[2]);
|
||||
if (burnAmount <= 0)
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for export");
|
||||
if (burnAmount > 1000000LL*COIN)
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for export, cannot export more than 1 million coins per export.");
|
||||
{
|
||||
CAmount needed = 0;
|
||||
for (int i=0; i<tx.vout.size(); i++) needed += tx.vout[i].nValue;
|
||||
if (burnAmount < needed)
|
||||
throw runtime_error("export_amount too small");
|
||||
}
|
||||
|
||||
CTxOut burnOut = MakeBurnOutput(burnAmount, ASSETCHAINS_CC, targetSymbol, tx.vout);
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
ret.push_back(Pair("payouts", HexStr(E_MARSHAL(ss << tx.vout))));
|
||||
tx.vout.clear();
|
||||
tx.vout.push_back(burnOut);
|
||||
ret.push_back(Pair("exportTx", HexStr(E_MARSHAL(ss << tx))));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The process to migrate funds
|
||||
*
|
||||
* Create a transaction on assetchain:
|
||||
*
|
||||
* generaterawtransaction
|
||||
* migrate_converttoexport
|
||||
* fundrawtransaction
|
||||
* signrawtransaction
|
||||
*
|
||||
* migrate_createimportransaction
|
||||
* migrate_completeimporttransaction
|
||||
*/
|
||||
|
||||
UniValue migrate_createimporttransaction(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 2)
|
||||
throw runtime_error("migrate_createimporttransaction burnTx payouts\n\n"
|
||||
"Create an importTx given a burnTx and the corresponding payouts, hex encoded");
|
||||
|
||||
if (ASSETCHAINS_CC < KOMODO_FIRSTFUNGIBLEID)
|
||||
throw runtime_error("-ac_cc < KOMODO_FIRSTFUNGIBLEID");
|
||||
|
||||
if (ASSETCHAINS_SYMBOL[0] == 0)
|
||||
throw runtime_error("Must be called on assetchain");
|
||||
|
||||
vector<uint8_t> txData(ParseHexV(params[0], "argument 1"));
|
||||
|
||||
CTransaction burnTx;
|
||||
if (!E_UNMARSHAL(txData, ss >> burnTx))
|
||||
throw runtime_error("Couldn't parse burnTx");
|
||||
|
||||
|
||||
vector<CTxOut> payouts;
|
||||
if (!E_UNMARSHAL(ParseHexV(params[1], "argument 2"), ss >> payouts))
|
||||
throw runtime_error("Couldn't parse payouts");
|
||||
|
||||
uint256 txid = burnTx.GetHash();
|
||||
TxProof proof = GetAssetchainProof(burnTx.GetHash());
|
||||
|
||||
CTransaction importTx = MakeImportCoinTransaction(proof, burnTx, payouts);
|
||||
return HexStr(E_MARSHAL(ss << importTx));
|
||||
}
|
||||
|
||||
|
||||
UniValue migrate_completeimporttransaction(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error("migrate_completeimporttransaction importTx\n\n"
|
||||
"Takes a cross chain import tx with proof generated on assetchain "
|
||||
"and extends proof to target chain proof root");
|
||||
|
||||
if (ASSETCHAINS_SYMBOL[0] != 0)
|
||||
throw runtime_error("Must be called on KMD");
|
||||
|
||||
CTransaction importTx;
|
||||
if (!E_UNMARSHAL(ParseHexV(params[0], "argument 1"), ss >> importTx))
|
||||
throw runtime_error("Couldn't parse importTx");
|
||||
|
||||
CompleteImportTransaction(importTx);
|
||||
|
||||
return HexStr(E_MARSHAL(ss << importTx));
|
||||
}
|
||||
|
||||
|
||||
UniValue getNotarisationsForBlock(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error("getNotarisationsForBlock blockHash\n\n"
|
||||
"Takes a block hash and returns notarisation transactions "
|
||||
"within the block");
|
||||
|
||||
uint256 blockHash = uint256S(params[0].get_str());
|
||||
|
||||
NotarisationsInBlock nibs;
|
||||
GetBlockNotarisations(blockHash, nibs);
|
||||
UniValue out(UniValue::VARR);
|
||||
BOOST_FOREACH(const Notarisation& n, nibs)
|
||||
{
|
||||
UniValue item(UniValue::VARR);
|
||||
item.push_back(n.first.GetHex());
|
||||
item.push_back(HexStr(E_MARSHAL(ss << n.second)));
|
||||
out.push_back(item);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
UniValue scanNotarisationsDB(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() < 2 || params.size() > 3)
|
||||
throw runtime_error("scanNotarisationsDB blockHeight symbol [blocksLimit=1440]\n\n"
|
||||
"Scans notarisationsdb backwards from height for a notarisation"
|
||||
" of given symbol");
|
||||
int height = atoi(params[0].get_str().c_str());
|
||||
std::string symbol = params[1].get_str().c_str();
|
||||
|
||||
int limit = 1440;
|
||||
if (params.size() > 2) {
|
||||
limit = atoi(params[2].get_str().c_str());
|
||||
}
|
||||
|
||||
if (height == 0) {
|
||||
height = chainActive.Height();
|
||||
}
|
||||
|
||||
Notarisation nota;
|
||||
int matchedHeight = ScanNotarisationsDB(height, symbol, limit, nota);
|
||||
if (!matchedHeight) return NullUniValue;
|
||||
UniValue out(UniValue::VOBJ);
|
||||
out.pushKV("height", matchedHeight);
|
||||
out.pushKV("hash", nota.first.GetHex());
|
||||
out.pushKV("opreturn", HexStr(E_MARSHAL(ss << nota.second)));
|
||||
return out;
|
||||
}
|
||||
1013
src/rpc/mining.cpp
Normal file
1013
src/rpc/mining.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1410
src/rpc/misc.cpp
Normal file
1410
src/rpc/misc.cpp
Normal file
File diff suppressed because it is too large
Load Diff
673
src/rpc/net.cpp
Normal file
673
src/rpc/net.cpp
Normal file
@@ -0,0 +1,673 @@
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "rpc/server.h"
|
||||
|
||||
#include "clientversion.h"
|
||||
#include "main.h"
|
||||
#include "net.h"
|
||||
#include "netbase.h"
|
||||
#include "protocol.h"
|
||||
#include "sync.h"
|
||||
#include "timedata.h"
|
||||
#include "util.h"
|
||||
#include "version.h"
|
||||
#include "deprecation.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <univalue.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
UniValue getconnectioncount(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
"getconnectioncount\n"
|
||||
"\nReturns the number of connections to other nodes.\n"
|
||||
"\nbResult:\n"
|
||||
"n (numeric) The connection count\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("getconnectioncount", "")
|
||||
+ HelpExampleRpc("getconnectioncount", "")
|
||||
);
|
||||
|
||||
LOCK2(cs_main, cs_vNodes);
|
||||
|
||||
return (int)vNodes.size();
|
||||
}
|
||||
|
||||
UniValue ping(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
"ping\n"
|
||||
"\nRequests that a ping be sent to all other nodes, to measure ping time.\n"
|
||||
"Results provided in getpeerinfo, pingtime and pingwait fields are decimal seconds.\n"
|
||||
"Ping command is handled in queue with all other commands, so it measures processing backlog, not just network ping.\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("ping", "")
|
||||
+ HelpExampleRpc("ping", "")
|
||||
);
|
||||
|
||||
// Request that each node send a ping during next message processing pass
|
||||
LOCK2(cs_main, cs_vNodes);
|
||||
|
||||
BOOST_FOREACH(CNode* pNode, vNodes) {
|
||||
pNode->fPingQueued = true;
|
||||
}
|
||||
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
static void CopyNodeStats(std::vector<CNodeStats>& vstats)
|
||||
{
|
||||
vstats.clear();
|
||||
|
||||
LOCK(cs_vNodes);
|
||||
vstats.reserve(vNodes.size());
|
||||
BOOST_FOREACH(CNode* pnode, vNodes) {
|
||||
CNodeStats stats;
|
||||
pnode->copyStats(stats);
|
||||
vstats.push_back(stats);
|
||||
}
|
||||
}
|
||||
|
||||
UniValue getpeerinfo(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
"getpeerinfo\n"
|
||||
"\nReturns data about each connected network node as a json array of objects.\n"
|
||||
"\nbResult:\n"
|
||||
"[\n"
|
||||
" {\n"
|
||||
" \"id\": n, (numeric) Peer index\n"
|
||||
" \"addr\":\"host:port\", (string) The ip address and port of the peer\n"
|
||||
" \"addrlocal\":\"ip:port\", (string) local address\n"
|
||||
" \"services\":\"xxxxxxxxxxxxxxxx\", (string) The services offered\n"
|
||||
" \"lastsend\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last send\n"
|
||||
" \"lastrecv\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last receive\n"
|
||||
" \"bytessent\": n, (numeric) The total bytes sent\n"
|
||||
" \"bytesrecv\": n, (numeric) The total bytes received\n"
|
||||
" \"conntime\": ttt, (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n"
|
||||
" \"timeoffset\": ttt, (numeric) The time offset in seconds\n"
|
||||
" \"pingtime\": n, (numeric) ping time\n"
|
||||
" \"pingwait\": n, (numeric) ping wait\n"
|
||||
" \"version\": v, (numeric) The peer version, such as 170002\n"
|
||||
" \"subver\": \"/MagicBean:x.y.z[-v]/\", (string) The string version\n"
|
||||
" \"inbound\": true|false, (boolean) Inbound (true) or Outbound (false)\n"
|
||||
" \"startingheight\": n, (numeric) The starting height (block) of the peer\n"
|
||||
" \"banscore\": n, (numeric) The ban score\n"
|
||||
" \"synced_headers\": n, (numeric) The last header we have in common with this peer\n"
|
||||
" \"synced_blocks\": n, (numeric) The last block we have in common with this peer\n"
|
||||
" \"inflight\": [\n"
|
||||
" n, (numeric) The heights of blocks we're currently asking from this peer\n"
|
||||
" ...\n"
|
||||
" ]\n"
|
||||
" }\n"
|
||||
" ,...\n"
|
||||
"]\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("getpeerinfo", "")
|
||||
+ HelpExampleRpc("getpeerinfo", "")
|
||||
);
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
vector<CNodeStats> vstats;
|
||||
CopyNodeStats(vstats);
|
||||
|
||||
UniValue ret(UniValue::VARR);
|
||||
|
||||
BOOST_FOREACH(const CNodeStats& stats, vstats) {
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
CNodeStateStats statestats;
|
||||
bool fStateStats = GetNodeStateStats(stats.nodeid, statestats);
|
||||
obj.push_back(Pair("id", stats.nodeid));
|
||||
obj.push_back(Pair("addr", stats.addrName));
|
||||
if (!(stats.addrLocal.empty()))
|
||||
obj.push_back(Pair("addrlocal", stats.addrLocal));
|
||||
obj.push_back(Pair("services", strprintf("%016x", stats.nServices)));
|
||||
obj.push_back(Pair("lastsend", stats.nLastSend));
|
||||
obj.push_back(Pair("lastrecv", stats.nLastRecv));
|
||||
obj.push_back(Pair("bytessent", stats.nSendBytes));
|
||||
obj.push_back(Pair("bytesrecv", stats.nRecvBytes));
|
||||
obj.push_back(Pair("conntime", stats.nTimeConnected));
|
||||
obj.push_back(Pair("timeoffset", stats.nTimeOffset));
|
||||
obj.push_back(Pair("pingtime", stats.dPingTime));
|
||||
if (stats.dPingWait > 0.0)
|
||||
obj.push_back(Pair("pingwait", stats.dPingWait));
|
||||
obj.push_back(Pair("version", stats.nVersion));
|
||||
// Use the sanitized form of subver here, to avoid tricksy remote peers from
|
||||
// corrupting or modifying the JSON output by putting special characters in
|
||||
// their ver message.
|
||||
obj.push_back(Pair("subver", stats.cleanSubVer));
|
||||
obj.push_back(Pair("inbound", stats.fInbound));
|
||||
obj.push_back(Pair("startingheight", stats.nStartingHeight));
|
||||
if (fStateStats) {
|
||||
obj.push_back(Pair("banscore", statestats.nMisbehavior));
|
||||
obj.push_back(Pair("synced_headers", statestats.nSyncHeight));
|
||||
obj.push_back(Pair("synced_blocks", statestats.nCommonHeight));
|
||||
UniValue heights(UniValue::VARR);
|
||||
BOOST_FOREACH(int height, statestats.vHeightInFlight) {
|
||||
heights.push_back(height);
|
||||
}
|
||||
obj.push_back(Pair("inflight", heights));
|
||||
}
|
||||
obj.push_back(Pair("whitelisted", stats.fWhitelisted));
|
||||
|
||||
ret.push_back(obj);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t KOMODO_LONGESTCHAIN;
|
||||
int32_t komodo_longestchain()
|
||||
{
|
||||
static int32_t depth;
|
||||
int32_t ht,n=0,num=0,maxheight=0,height = 0;
|
||||
if ( depth < 0 )
|
||||
depth = 0;
|
||||
if ( depth == 0 )
|
||||
{
|
||||
depth++;
|
||||
vector<CNodeStats> vstats;
|
||||
{
|
||||
//LOCK(cs_main);
|
||||
CopyNodeStats(vstats);
|
||||
}
|
||||
BOOST_FOREACH(const CNodeStats& stats, vstats)
|
||||
{
|
||||
//fprintf(stderr,"komodo_longestchain iter.%d\n",n);
|
||||
CNodeStateStats statestats;
|
||||
bool fStateStats = GetNodeStateStats(stats.nodeid,statestats);
|
||||
if ( statestats.nSyncHeight < 0 )
|
||||
continue;
|
||||
ht = 0;
|
||||
if ( stats.nStartingHeight > ht )
|
||||
ht = stats.nStartingHeight;
|
||||
if ( statestats.nSyncHeight > ht )
|
||||
ht = statestats.nSyncHeight;
|
||||
if ( statestats.nCommonHeight > ht )
|
||||
ht = statestats.nCommonHeight;
|
||||
if ( maxheight == 0 || ht > maxheight*1.01 )
|
||||
maxheight = ht, num = 1;
|
||||
else if ( ht > maxheight*0.99 )
|
||||
num++;
|
||||
if ( ht > height )
|
||||
height = ht;
|
||||
}
|
||||
depth--;
|
||||
if ( num > (n >> 1) )
|
||||
{
|
||||
extern char ASSETCHAINS_SYMBOL[];
|
||||
if ( 0 && height != KOMODO_LONGESTCHAIN )
|
||||
fprintf(stderr,"set %s KOMODO_LONGESTCHAIN <- %d\n",ASSETCHAINS_SYMBOL,height);
|
||||
KOMODO_LONGESTCHAIN = height;
|
||||
return(height);
|
||||
}
|
||||
KOMODO_LONGESTCHAIN = 0;
|
||||
}
|
||||
return(KOMODO_LONGESTCHAIN);
|
||||
}
|
||||
|
||||
UniValue addnode(const UniValue& params, bool fHelp)
|
||||
{
|
||||
string strCommand;
|
||||
if (params.size() == 2)
|
||||
strCommand = params[1].get_str();
|
||||
if (fHelp || params.size() != 2 ||
|
||||
(strCommand != "onetry" && strCommand != "add" && strCommand != "remove"))
|
||||
throw runtime_error(
|
||||
"addnode \"node\" \"add|remove|onetry\"\n"
|
||||
"\nAttempts add or remove a node from the addnode list.\n"
|
||||
"Or try a connection to a node once.\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"node\" (string, required) The node (see getpeerinfo for nodes)\n"
|
||||
"2. \"command\" (string, required) 'add' to add a node to the list, 'remove' to remove a node from the list, 'onetry' to try a connection to the node once\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("addnode", "\"192.168.0.6:8233\" \"onetry\"")
|
||||
+ HelpExampleRpc("addnode", "\"192.168.0.6:8233\", \"onetry\"")
|
||||
);
|
||||
|
||||
string strNode = params[0].get_str();
|
||||
|
||||
if (strCommand == "onetry")
|
||||
{
|
||||
CAddress addr;
|
||||
OpenNetworkConnection(addr, NULL, strNode.c_str());
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
LOCK(cs_vAddedNodes);
|
||||
vector<string>::iterator it = vAddedNodes.begin();
|
||||
for(; it != vAddedNodes.end(); it++)
|
||||
if (strNode == *it)
|
||||
break;
|
||||
|
||||
if (strCommand == "add")
|
||||
{
|
||||
if (it != vAddedNodes.end())
|
||||
throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Node already added");
|
||||
vAddedNodes.push_back(strNode);
|
||||
}
|
||||
else if(strCommand == "remove")
|
||||
{
|
||||
if (it == vAddedNodes.end())
|
||||
throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
|
||||
vAddedNodes.erase(it);
|
||||
}
|
||||
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
UniValue disconnectnode(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error(
|
||||
"disconnectnode \"node\" \n"
|
||||
"\nImmediately disconnects from the specified node.\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"node\" (string, required) The node (see getpeerinfo for nodes)\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("disconnectnode", "\"192.168.0.6:8233\"")
|
||||
+ HelpExampleRpc("disconnectnode", "\"192.168.0.6:8233\"")
|
||||
);
|
||||
|
||||
CNode* pNode = FindNode(params[0].get_str());
|
||||
if (pNode == NULL)
|
||||
throw JSONRPCError(RPC_CLIENT_NODE_NOT_CONNECTED, "Node not found in connected nodes");
|
||||
|
||||
pNode->fDisconnect = true;
|
||||
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
UniValue getaddednodeinfo(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() < 1 || params.size() > 2)
|
||||
throw runtime_error(
|
||||
"getaddednodeinfo dns ( \"node\" )\n"
|
||||
"\nReturns information about the given added node, or all added nodes\n"
|
||||
"(note that onetry addnodes are not listed here)\n"
|
||||
"If dns is false, only a list of added nodes will be provided,\n"
|
||||
"otherwise connected information will also be available.\n"
|
||||
"\nArguments:\n"
|
||||
"1. dns (boolean, required) If false, only a list of added nodes will be provided, otherwise connected information will also be available.\n"
|
||||
"2. \"node\" (string, optional) If provided, return information about this specific node, otherwise all nodes are returned.\n"
|
||||
"\nResult:\n"
|
||||
"[\n"
|
||||
" {\n"
|
||||
" \"addednode\" : \"192.168.0.201\", (string) The node ip address\n"
|
||||
" \"connected\" : true|false, (boolean) If connected\n"
|
||||
" \"addresses\" : [\n"
|
||||
" {\n"
|
||||
" \"address\" : \"192.168.0.201:8233\", (string) The Komodo server host and port\n"
|
||||
" \"connected\" : \"outbound\" (string) connection, inbound or outbound\n"
|
||||
" }\n"
|
||||
" ,...\n"
|
||||
" ]\n"
|
||||
" }\n"
|
||||
" ,...\n"
|
||||
"]\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("getaddednodeinfo", "true")
|
||||
+ HelpExampleCli("getaddednodeinfo", "true \"192.168.0.201\"")
|
||||
+ HelpExampleRpc("getaddednodeinfo", "true, \"192.168.0.201\"")
|
||||
);
|
||||
|
||||
bool fDns = params[0].get_bool();
|
||||
|
||||
list<string> laddedNodes(0);
|
||||
if (params.size() == 1)
|
||||
{
|
||||
LOCK(cs_vAddedNodes);
|
||||
BOOST_FOREACH(const std::string& strAddNode, vAddedNodes)
|
||||
laddedNodes.push_back(strAddNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
string strNode = params[1].get_str();
|
||||
LOCK(cs_vAddedNodes);
|
||||
BOOST_FOREACH(const std::string& strAddNode, vAddedNodes) {
|
||||
if (strAddNode == strNode)
|
||||
{
|
||||
laddedNodes.push_back(strAddNode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (laddedNodes.size() == 0)
|
||||
throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
|
||||
}
|
||||
|
||||
UniValue ret(UniValue::VARR);
|
||||
if (!fDns)
|
||||
{
|
||||
BOOST_FOREACH (const std::string& strAddNode, laddedNodes) {
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("addednode", strAddNode));
|
||||
ret.push_back(obj);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
list<pair<string, vector<CService> > > laddedAddreses(0);
|
||||
BOOST_FOREACH(const std::string& strAddNode, laddedNodes) {
|
||||
vector<CService> vservNode(0);
|
||||
if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0))
|
||||
laddedAddreses.push_back(make_pair(strAddNode, vservNode));
|
||||
else
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("addednode", strAddNode));
|
||||
obj.push_back(Pair("connected", false));
|
||||
UniValue addresses(UniValue::VARR);
|
||||
obj.push_back(Pair("addresses", addresses));
|
||||
}
|
||||
}
|
||||
|
||||
LOCK(cs_vNodes);
|
||||
for (list<pair<string, vector<CService> > >::iterator it = laddedAddreses.begin(); it != laddedAddreses.end(); it++)
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("addednode", it->first));
|
||||
|
||||
UniValue addresses(UniValue::VARR);
|
||||
bool fConnected = false;
|
||||
BOOST_FOREACH(const CService& addrNode, it->second) {
|
||||
bool fFound = false;
|
||||
UniValue node(UniValue::VOBJ);
|
||||
node.push_back(Pair("address", addrNode.ToString()));
|
||||
BOOST_FOREACH(CNode* pnode, vNodes) {
|
||||
if (pnode->addr == addrNode)
|
||||
{
|
||||
fFound = true;
|
||||
fConnected = true;
|
||||
node.push_back(Pair("connected", pnode->fInbound ? "inbound" : "outbound"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!fFound)
|
||||
node.push_back(Pair("connected", "false"));
|
||||
addresses.push_back(node);
|
||||
}
|
||||
obj.push_back(Pair("connected", fConnected));
|
||||
obj.push_back(Pair("addresses", addresses));
|
||||
ret.push_back(obj);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
UniValue getnettotals(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() > 0)
|
||||
throw runtime_error(
|
||||
"getnettotals\n"
|
||||
"\nReturns information about network traffic, including bytes in, bytes out,\n"
|
||||
"and current time.\n"
|
||||
"\nResult:\n"
|
||||
"{\n"
|
||||
" \"totalbytesrecv\": n, (numeric) Total bytes received\n"
|
||||
" \"totalbytessent\": n, (numeric) Total bytes sent\n"
|
||||
" \"timemillis\": t (numeric) Total cpu time\n"
|
||||
"}\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("getnettotals", "")
|
||||
+ HelpExampleRpc("getnettotals", "")
|
||||
);
|
||||
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("totalbytesrecv", CNode::GetTotalBytesRecv()));
|
||||
obj.push_back(Pair("totalbytessent", CNode::GetTotalBytesSent()));
|
||||
obj.push_back(Pair("timemillis", GetTimeMillis()));
|
||||
return obj;
|
||||
}
|
||||
|
||||
static UniValue GetNetworksInfo()
|
||||
{
|
||||
UniValue networks(UniValue::VARR);
|
||||
for(int n=0; n<NET_MAX; ++n)
|
||||
{
|
||||
enum Network network = static_cast<enum Network>(n);
|
||||
if(network == NET_UNROUTABLE)
|
||||
continue;
|
||||
proxyType proxy;
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
GetProxy(network, proxy);
|
||||
obj.push_back(Pair("name", GetNetworkName(network)));
|
||||
obj.push_back(Pair("limited", IsLimited(network)));
|
||||
obj.push_back(Pair("reachable", IsReachable(network)));
|
||||
obj.push_back(Pair("proxy", proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string()));
|
||||
obj.push_back(Pair("proxy_randomize_credentials", proxy.randomize_credentials));
|
||||
networks.push_back(obj);
|
||||
}
|
||||
return networks;
|
||||
}
|
||||
|
||||
UniValue getdeprecationinfo(const UniValue& params, bool fHelp)
|
||||
{
|
||||
const CChainParams& chainparams = Params();
|
||||
if (fHelp || params.size() != 0 || chainparams.NetworkIDString() != "main")
|
||||
throw runtime_error(
|
||||
"getdeprecationinfo\n"
|
||||
"Returns an object containing current version and deprecation block height. Applicable only on mainnet.\n"
|
||||
"\nResult:\n"
|
||||
"{\n"
|
||||
" \"version\": xxxxx, (numeric) the server version\n"
|
||||
" \"subversion\": \"/MagicBean:x.y.z[-v]/\", (string) the server subversion string\n"
|
||||
" \"deprecationheight\": xxxxx, (numeric) the block height at which this version will deprecate and shut down\n"
|
||||
"}\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("getdeprecationinfo", "")
|
||||
+ HelpExampleRpc("getdeprecationinfo", "")
|
||||
);
|
||||
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("version", CLIENT_VERSION));
|
||||
obj.push_back(Pair("subversion",
|
||||
FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>())));
|
||||
obj.push_back(Pair("deprecationheight", DEPRECATION_HEIGHT));
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
UniValue getnetworkinfo(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
"getnetworkinfo\n"
|
||||
"Returns an object containing various state info regarding P2P networking.\n"
|
||||
"\nResult:\n"
|
||||
"{\n"
|
||||
" \"version\": xxxxx, (numeric) the server version\n"
|
||||
" \"subversion\": \"/MagicBean:x.y.z[-v]/\", (string) the server subversion string\n"
|
||||
" \"protocolversion\": xxxxx, (numeric) the protocol version\n"
|
||||
" \"localservices\": \"xxxxxxxxxxxxxxxx\", (string) the services we offer to the network\n"
|
||||
" \"timeoffset\": xxxxx, (numeric) the time offset\n"
|
||||
" \"connections\": xxxxx, (numeric) the number of connections\n"
|
||||
" \"networks\": [ (array) information per network\n"
|
||||
" {\n"
|
||||
" \"name\": \"xxx\", (string) network (ipv4, ipv6 or onion)\n"
|
||||
" \"limited\": true|false, (boolean) is the network limited using -onlynet?\n"
|
||||
" \"reachable\": true|false, (boolean) is the network reachable?\n"
|
||||
" \"proxy\": \"host:port\" (string) the proxy that is used for this network, or empty if none\n"
|
||||
" }\n"
|
||||
" ,...\n"
|
||||
" ],\n"
|
||||
" \"relayfee\": x.xxxxxxxx, (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n"
|
||||
" \"localaddresses\": [ (array) list of local addresses\n"
|
||||
" {\n"
|
||||
" \"address\": \"xxxx\", (string) network address\n"
|
||||
" \"port\": xxx, (numeric) network port\n"
|
||||
" \"score\": xxx (numeric) relative score\n"
|
||||
" }\n"
|
||||
" ,...\n"
|
||||
" ]\n"
|
||||
" \"warnings\": \"...\" (string) any network warnings (such as alert messages) \n"
|
||||
"}\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("getnetworkinfo", "")
|
||||
+ HelpExampleRpc("getnetworkinfo", "")
|
||||
);
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("version", CLIENT_VERSION));
|
||||
obj.push_back(Pair("subversion", strSubVersion));
|
||||
obj.push_back(Pair("protocolversion",PROTOCOL_VERSION));
|
||||
obj.push_back(Pair("localservices", strprintf("%016x", nLocalServices)));
|
||||
obj.push_back(Pair("timeoffset", GetTimeOffset()));
|
||||
obj.push_back(Pair("connections", (int)vNodes.size()));
|
||||
obj.push_back(Pair("networks", GetNetworksInfo()));
|
||||
obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())));
|
||||
UniValue localAddresses(UniValue::VARR);
|
||||
{
|
||||
LOCK(cs_mapLocalHost);
|
||||
BOOST_FOREACH(const PAIRTYPE(CNetAddr, LocalServiceInfo) &item, mapLocalHost)
|
||||
{
|
||||
UniValue rec(UniValue::VOBJ);
|
||||
rec.push_back(Pair("address", item.first.ToString()));
|
||||
rec.push_back(Pair("port", item.second.nPort));
|
||||
rec.push_back(Pair("score", item.second.nScore));
|
||||
localAddresses.push_back(rec);
|
||||
}
|
||||
}
|
||||
obj.push_back(Pair("localaddresses", localAddresses));
|
||||
obj.push_back(Pair("warnings", GetWarnings("statusbar")));
|
||||
return obj;
|
||||
}
|
||||
|
||||
UniValue setban(const UniValue& params, bool fHelp)
|
||||
{
|
||||
string strCommand;
|
||||
if (params.size() >= 2)
|
||||
strCommand = params[1].get_str();
|
||||
if (fHelp || params.size() < 2 ||
|
||||
(strCommand != "add" && strCommand != "remove"))
|
||||
throw runtime_error(
|
||||
"setban \"ip(/netmask)\" \"add|remove\" (bantime) (absolute)\n"
|
||||
"\nAttempts add or remove a IP/Subnet from the banned list.\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"ip(/netmask)\" (string, required) The IP/Subnet (see getpeerinfo for nodes ip) with a optional netmask (default is /32 = single ip)\n"
|
||||
"2. \"command\" (string, required) 'add' to add a IP/Subnet to the list, 'remove' to remove a IP/Subnet from the list\n"
|
||||
"3. \"bantime\" (numeric, optional) time in seconds how long (or until when if [absolute] is set) the ip is banned (0 or empty means using the default time of 24h which can also be overwritten by the -bantime startup argument)\n"
|
||||
"4. \"absolute\" (boolean, optional) If set, the bantime must be a absolute timestamp in seconds since epoch (Jan 1 1970 GMT)\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("setban", "\"192.168.0.6\" \"add\" 86400")
|
||||
+ HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"")
|
||||
+ HelpExampleRpc("setban", "\"192.168.0.6\", \"add\" 86400")
|
||||
);
|
||||
|
||||
CSubNet subNet;
|
||||
CNetAddr netAddr;
|
||||
bool isSubnet = false;
|
||||
|
||||
if (params[0].get_str().find("/") != string::npos)
|
||||
isSubnet = true;
|
||||
|
||||
if (!isSubnet)
|
||||
netAddr = CNetAddr(params[0].get_str());
|
||||
else
|
||||
subNet = CSubNet(params[0].get_str());
|
||||
|
||||
if (! (isSubnet ? subNet.IsValid() : netAddr.IsValid()) )
|
||||
throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Invalid IP/Subnet");
|
||||
|
||||
if (strCommand == "add")
|
||||
{
|
||||
if (isSubnet ? CNode::IsBanned(subNet) : CNode::IsBanned(netAddr))
|
||||
throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: IP/Subnet already banned");
|
||||
|
||||
int64_t banTime = 0; //use standard bantime if not specified
|
||||
if (params.size() >= 3 && !params[2].isNull())
|
||||
banTime = params[2].get_int64();
|
||||
|
||||
bool absolute = false;
|
||||
if (params.size() == 4 && params[3].isTrue())
|
||||
absolute = true;
|
||||
|
||||
isSubnet ? CNode::Ban(subNet, banTime, absolute) : CNode::Ban(netAddr, banTime, absolute);
|
||||
|
||||
//disconnect possible nodes
|
||||
while(CNode *bannedNode = (isSubnet ? FindNode(subNet) : FindNode(netAddr)))
|
||||
bannedNode->fDisconnect = true;
|
||||
}
|
||||
else if(strCommand == "remove")
|
||||
{
|
||||
if (!( isSubnet ? CNode::Unban(subNet) : CNode::Unban(netAddr) ))
|
||||
throw JSONRPCError(RPC_MISC_ERROR, "Error: Unban failed");
|
||||
}
|
||||
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
UniValue listbanned(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
"listbanned\n"
|
||||
"\nList all banned IPs/Subnets.\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("listbanned", "")
|
||||
+ HelpExampleRpc("listbanned", "")
|
||||
);
|
||||
|
||||
std::map<CSubNet, int64_t> banMap;
|
||||
CNode::GetBanned(banMap);
|
||||
|
||||
UniValue bannedAddresses(UniValue::VARR);
|
||||
for (std::map<CSubNet, int64_t>::iterator it = banMap.begin(); it != banMap.end(); it++)
|
||||
{
|
||||
UniValue rec(UniValue::VOBJ);
|
||||
rec.push_back(Pair("address", (*it).first.ToString()));
|
||||
rec.push_back(Pair("banned_until", (*it).second));
|
||||
bannedAddresses.push_back(rec);
|
||||
}
|
||||
|
||||
return bannedAddresses;
|
||||
}
|
||||
|
||||
UniValue clearbanned(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
"clearbanned\n"
|
||||
"\nClear all banned IPs.\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("clearbanned", "")
|
||||
+ HelpExampleRpc("clearbanned", "")
|
||||
);
|
||||
|
||||
CNode::ClearBanned();
|
||||
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
static const CRPCCommand commands[] =
|
||||
{ // category name actor (function) okSafeMode
|
||||
// --------------------- ------------------------ ----------------------- ----------
|
||||
{ "network", "getconnectioncount", &getconnectioncount, true },
|
||||
{ "network", "getdeprecationinfo", &getdeprecationinfo, true },
|
||||
{ "network", "ping", &ping, true },
|
||||
{ "network", "getpeerinfo", &getpeerinfo, true },
|
||||
{ "network", "addnode", &addnode, true },
|
||||
{ "network", "disconnectnode", &disconnectnode, true },
|
||||
{ "network", "getaddednodeinfo", &getaddednodeinfo, true },
|
||||
{ "network", "getnettotals", &getnettotals, true },
|
||||
{ "network", "getnetworkinfo", &getnetworkinfo, true },
|
||||
{ "network", "setban", &setban, true },
|
||||
{ "network", "listbanned", &listbanned, true },
|
||||
{ "network", "clearbanned", &clearbanned, true },
|
||||
};
|
||||
|
||||
void RegisterNetRPCCommands(CRPCTable &tableRPC)
|
||||
{
|
||||
for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
|
||||
tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
|
||||
}
|
||||
127
src/rpc/protocol.cpp
Normal file
127
src/rpc/protocol.cpp
Normal file
@@ -0,0 +1,127 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "rpc/protocol.h"
|
||||
|
||||
#include "random.h"
|
||||
#include "tinyformat.h"
|
||||
#include "util.h"
|
||||
#include "utilstrencodings.h"
|
||||
#include "utiltime.h"
|
||||
#include "version.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility,
|
||||
* but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were
|
||||
* unspecified (HTTP errors and contents of 'error').
|
||||
*
|
||||
* 1.0 spec: http://json-rpc.org/wiki/specification
|
||||
* 1.2 spec: http://jsonrpc.org/historical/json-rpc-over-http.html
|
||||
*/
|
||||
|
||||
string JSONRPCRequest(const string& strMethod, const UniValue& params, const UniValue& id)
|
||||
{
|
||||
UniValue request(UniValue::VOBJ);
|
||||
request.push_back(Pair("method", strMethod));
|
||||
request.push_back(Pair("params", params));
|
||||
request.push_back(Pair("id", id));
|
||||
return request.write() + "\n";
|
||||
}
|
||||
|
||||
UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id)
|
||||
{
|
||||
UniValue reply(UniValue::VOBJ);
|
||||
if (!error.isNull())
|
||||
reply.push_back(Pair("result", NullUniValue));
|
||||
else
|
||||
reply.push_back(Pair("result", result));
|
||||
reply.push_back(Pair("error", error));
|
||||
reply.push_back(Pair("id", id));
|
||||
return reply;
|
||||
}
|
||||
|
||||
string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id)
|
||||
{
|
||||
UniValue reply = JSONRPCReplyObj(result, error, id);
|
||||
return reply.write() + "\n";
|
||||
}
|
||||
|
||||
UniValue JSONRPCError(int code, const string& message)
|
||||
{
|
||||
UniValue error(UniValue::VOBJ);
|
||||
error.push_back(Pair("code", code));
|
||||
error.push_back(Pair("message", message));
|
||||
return error;
|
||||
}
|
||||
|
||||
/** Username used when cookie authentication is in use (arbitrary, only for
|
||||
* recognizability in debugging/logging purposes)
|
||||
*/
|
||||
static const std::string COOKIEAUTH_USER = "__cookie__";
|
||||
/** Default name for auth cookie file */
|
||||
static const std::string COOKIEAUTH_FILE = ".cookie";
|
||||
|
||||
boost::filesystem::path GetAuthCookieFile()
|
||||
{
|
||||
boost::filesystem::path path(GetArg("-rpccookiefile", COOKIEAUTH_FILE));
|
||||
if (!path.is_complete()) path = GetDataDir() / path;
|
||||
return path;
|
||||
}
|
||||
|
||||
bool GenerateAuthCookie(std::string *cookie_out)
|
||||
{
|
||||
unsigned char rand_pwd[32];
|
||||
GetRandBytes(rand_pwd, 32);
|
||||
std::string cookie = COOKIEAUTH_USER + ":" + EncodeBase64(&rand_pwd[0],32);
|
||||
|
||||
/** the umask determines what permissions are used to create this file -
|
||||
* these are set to 077 in init.cpp unless overridden with -sysperms.
|
||||
*/
|
||||
std::ofstream file;
|
||||
boost::filesystem::path filepath = GetAuthCookieFile();
|
||||
file.open(filepath.string().c_str());
|
||||
if (!file.is_open()) {
|
||||
LogPrintf("Unable to open cookie authentication file %s for writing\n", filepath.string());
|
||||
return false;
|
||||
}
|
||||
file << cookie;
|
||||
file.close();
|
||||
LogPrintf("Generated RPC authentication cookie %s\n", filepath.string());
|
||||
|
||||
if (cookie_out)
|
||||
*cookie_out = cookie;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetAuthCookie(std::string *cookie_out)
|
||||
{
|
||||
std::ifstream file;
|
||||
std::string cookie;
|
||||
boost::filesystem::path filepath = GetAuthCookieFile();
|
||||
file.open(filepath.string().c_str());
|
||||
if (!file.is_open())
|
||||
return false;
|
||||
std::getline(file, cookie);
|
||||
file.close();
|
||||
|
||||
if (cookie_out)
|
||||
*cookie_out = cookie;
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeleteAuthCookie()
|
||||
{
|
||||
try {
|
||||
boost::filesystem::remove(GetAuthCookieFile());
|
||||
} catch (const boost::filesystem::filesystem_error& e) {
|
||||
LogPrintf("%s: Unable to remove random auth cookie file: %s\n", __func__, e.what());
|
||||
}
|
||||
}
|
||||
|
||||
93
src/rpc/protocol.h
Normal file
93
src/rpc/protocol.h
Normal file
@@ -0,0 +1,93 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_RPCPROTOCOL_H
|
||||
#define BITCOIN_RPCPROTOCOL_H
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <univalue.h>
|
||||
|
||||
//! HTTP status codes
|
||||
enum HTTPStatusCode
|
||||
{
|
||||
HTTP_OK = 200,
|
||||
HTTP_BAD_REQUEST = 400,
|
||||
HTTP_UNAUTHORIZED = 401,
|
||||
HTTP_FORBIDDEN = 403,
|
||||
HTTP_NOT_FOUND = 404,
|
||||
HTTP_BAD_METHOD = 405,
|
||||
HTTP_INTERNAL_SERVER_ERROR = 500,
|
||||
HTTP_SERVICE_UNAVAILABLE = 503,
|
||||
};
|
||||
|
||||
//! Bitcoin RPC error codes
|
||||
enum RPCErrorCode
|
||||
{
|
||||
//! Standard JSON-RPC 2.0 errors
|
||||
RPC_INVALID_REQUEST = -32600,
|
||||
RPC_METHOD_NOT_FOUND = -32601,
|
||||
RPC_INVALID_PARAMS = -32602,
|
||||
RPC_INTERNAL_ERROR = -32603,
|
||||
RPC_PARSE_ERROR = -32700,
|
||||
|
||||
//! General application defined errors
|
||||
RPC_MISC_ERROR = -1, //! std::exception thrown in command handling
|
||||
RPC_FORBIDDEN_BY_SAFE_MODE = -2, //! Server is in safe mode, and command is not allowed in safe mode
|
||||
RPC_TYPE_ERROR = -3, //! Unexpected type was passed as parameter
|
||||
RPC_INVALID_ADDRESS_OR_KEY = -5, //! Invalid address or key
|
||||
RPC_OUT_OF_MEMORY = -7, //! Ran out of memory during operation
|
||||
RPC_INVALID_PARAMETER = -8, //! Invalid, missing or duplicate parameter
|
||||
RPC_DATABASE_ERROR = -20, //! Database error
|
||||
RPC_DESERIALIZATION_ERROR = -22, //! Error parsing or validating structure in raw format
|
||||
RPC_VERIFY_ERROR = -25, //! General error during transaction or block submission
|
||||
RPC_VERIFY_REJECTED = -26, //! Transaction or block was rejected by network rules
|
||||
RPC_VERIFY_ALREADY_IN_CHAIN = -27, //! Transaction already in chain
|
||||
RPC_IN_WARMUP = -28, //! Client still warming up
|
||||
|
||||
//! Aliases for backward compatibility
|
||||
RPC_TRANSACTION_ERROR = RPC_VERIFY_ERROR,
|
||||
RPC_TRANSACTION_REJECTED = RPC_VERIFY_REJECTED,
|
||||
RPC_TRANSACTION_ALREADY_IN_CHAIN= RPC_VERIFY_ALREADY_IN_CHAIN,
|
||||
|
||||
//! P2P client errors
|
||||
RPC_CLIENT_NOT_CONNECTED = -9, //! Bitcoin is not connected
|
||||
RPC_CLIENT_IN_INITIAL_DOWNLOAD = -10, //! Still downloading initial blocks
|
||||
RPC_CLIENT_NODE_ALREADY_ADDED = -23, //! Node is already added
|
||||
RPC_CLIENT_NODE_NOT_ADDED = -24, //! Node has not been added before
|
||||
RPC_CLIENT_NODE_NOT_CONNECTED = -29, //! Node to disconnect not found in connected nodes
|
||||
RPC_CLIENT_INVALID_IP_OR_SUBNET = -30, //! Invalid IP/Subnet
|
||||
|
||||
//! Wallet errors
|
||||
RPC_WALLET_ERROR = -4, //! Unspecified problem with wallet (key not found etc.)
|
||||
RPC_WALLET_INSUFFICIENT_FUNDS = -6, //! Not enough funds in wallet or account
|
||||
RPC_WALLET_ACCOUNTS_UNSUPPORTED = -11, //! Accounts are unsupported
|
||||
RPC_WALLET_KEYPOOL_RAN_OUT = -12, //! Keypool ran out, call keypoolrefill first
|
||||
RPC_WALLET_UNLOCK_NEEDED = -13, //! Enter the wallet passphrase with walletpassphrase first
|
||||
RPC_WALLET_PASSPHRASE_INCORRECT = -14, //! The wallet passphrase entered was incorrect
|
||||
RPC_WALLET_WRONG_ENC_STATE = -15, //! Command given in wrong wallet encryption state (encrypting an encrypted wallet etc.)
|
||||
RPC_WALLET_ENCRYPTION_FAILED = -16, //! Failed to encrypt the wallet
|
||||
RPC_WALLET_ALREADY_UNLOCKED = -17, //! Wallet is already unlocked
|
||||
};
|
||||
|
||||
std::string JSONRPCRequest(const std::string& strMethod, const UniValue& params, const UniValue& id);
|
||||
UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id);
|
||||
std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id);
|
||||
UniValue JSONRPCError(int code, const std::string& message);
|
||||
|
||||
/** Get name of RPC authentication cookie file */
|
||||
boost::filesystem::path GetAuthCookieFile();
|
||||
/** Generate a new RPC authentication cookie and write it to disk */
|
||||
bool GenerateAuthCookie(std::string *cookie_out);
|
||||
/** Read the RPC authentication cookie from disk */
|
||||
bool GetAuthCookie(std::string *cookie_out);
|
||||
/** Delete RPC authentication cookie from disk */
|
||||
void DeleteAuthCookie();
|
||||
|
||||
#endif // BITCOIN_RPCPROTOCOL_H
|
||||
1313
src/rpc/rawtransaction.cpp
Normal file
1313
src/rpc/rawtransaction.cpp
Normal file
File diff suppressed because it is too large
Load Diff
32
src/rpc/register.h
Normal file
32
src/rpc/register.h
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2009-2016 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_RPCREGISTER_H
|
||||
#define BITCOIN_RPCREGISTER_H
|
||||
|
||||
/** These are in one header file to avoid creating tons of single-function
|
||||
* headers for everything under src/rpc/ */
|
||||
class CRPCTable;
|
||||
|
||||
/** Register block chain RPC commands */
|
||||
void RegisterBlockchainRPCCommands(CRPCTable &tableRPC);
|
||||
/** Register P2P networking RPC commands */
|
||||
void RegisterNetRPCCommands(CRPCTable &tableRPC);
|
||||
/** Register miscellaneous RPC commands */
|
||||
void RegisterMiscRPCCommands(CRPCTable &tableRPC);
|
||||
/** Register mining RPC commands */
|
||||
void RegisterMiningRPCCommands(CRPCTable &tableRPC);
|
||||
/** Register raw transaction RPC commands */
|
||||
void RegisterRawTransactionRPCCommands(CRPCTable &tableRPC);
|
||||
|
||||
static inline void RegisterAllCoreRPCCommands(CRPCTable &tableRPC)
|
||||
{
|
||||
RegisterBlockchainRPCCommands(tableRPC);
|
||||
RegisterNetRPCCommands(tableRPC);
|
||||
RegisterMiscRPCCommands(tableRPC);
|
||||
RegisterMiningRPCCommands(tableRPC);
|
||||
RegisterRawTransactionRPCCommands(tableRPC);
|
||||
}
|
||||
|
||||
#endif
|
||||
821
src/rpc/server.cpp
Normal file
821
src/rpc/server.cpp
Normal file
@@ -0,0 +1,821 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "rpc/server.h"
|
||||
|
||||
#include "init.h"
|
||||
#include "key_io.h"
|
||||
#include "random.h"
|
||||
#include "sync.h"
|
||||
#include "ui_interface.h"
|
||||
#include "util.h"
|
||||
#include "utilstrencodings.h"
|
||||
#include "asyncrpcqueue.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <univalue.h>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/iostreams/concepts.hpp>
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/signals2/signal.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/algorithm/string/case_conv.hpp> // for to_upper()
|
||||
|
||||
using namespace RPCServer;
|
||||
using namespace std;
|
||||
|
||||
static bool fRPCRunning = false;
|
||||
static bool fRPCInWarmup = true;
|
||||
static std::string rpcWarmupStatus("RPC server started");
|
||||
static CCriticalSection cs_rpcWarmup;
|
||||
/* Timer-creating functions */
|
||||
static std::vector<RPCTimerInterface*> timerInterfaces;
|
||||
/* Map of name to timer.
|
||||
* @note Can be changed to std::unique_ptr when C++11 */
|
||||
static std::map<std::string, boost::shared_ptr<RPCTimerBase> > deadlineTimers;
|
||||
|
||||
static struct CRPCSignals
|
||||
{
|
||||
boost::signals2::signal<void ()> Started;
|
||||
boost::signals2::signal<void ()> Stopped;
|
||||
boost::signals2::signal<void (const CRPCCommand&)> PreCommand;
|
||||
boost::signals2::signal<void (const CRPCCommand&)> PostCommand;
|
||||
} g_rpcSignals;
|
||||
|
||||
void RPCServer::OnStarted(boost::function<void ()> slot)
|
||||
{
|
||||
g_rpcSignals.Started.connect(slot);
|
||||
}
|
||||
|
||||
void RPCServer::OnStopped(boost::function<void ()> slot)
|
||||
{
|
||||
g_rpcSignals.Stopped.connect(slot);
|
||||
}
|
||||
|
||||
void RPCServer::OnPreCommand(boost::function<void (const CRPCCommand&)> slot)
|
||||
{
|
||||
g_rpcSignals.PreCommand.connect(boost::bind(slot, _1));
|
||||
}
|
||||
|
||||
void RPCServer::OnPostCommand(boost::function<void (const CRPCCommand&)> slot)
|
||||
{
|
||||
g_rpcSignals.PostCommand.connect(boost::bind(slot, _1));
|
||||
}
|
||||
|
||||
void RPCTypeCheck(const UniValue& params,
|
||||
const list<UniValue::VType>& typesExpected,
|
||||
bool fAllowNull)
|
||||
{
|
||||
size_t i = 0;
|
||||
BOOST_FOREACH(UniValue::VType t, typesExpected)
|
||||
{
|
||||
if (params.size() <= i)
|
||||
break;
|
||||
|
||||
const UniValue& v = params[i];
|
||||
if (!((v.type() == t) || (fAllowNull && (v.isNull()))))
|
||||
{
|
||||
string err = strprintf("Expected type %s, got %s",
|
||||
uvTypeName(t), uvTypeName(v.type()));
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, err);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void RPCTypeCheckObj(const UniValue& o,
|
||||
const map<string, UniValue::VType>& typesExpected,
|
||||
bool fAllowNull)
|
||||
{
|
||||
BOOST_FOREACH(const PAIRTYPE(string, UniValue::VType)& t, typesExpected)
|
||||
{
|
||||
const UniValue& v = find_value(o, t.first);
|
||||
if (!fAllowNull && v.isNull())
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first));
|
||||
|
||||
if (!((v.type() == t.second) || (fAllowNull && (v.isNull()))))
|
||||
{
|
||||
string err = strprintf("Expected type %s for %s, got %s",
|
||||
uvTypeName(t.second), t.first, uvTypeName(v.type()));
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CAmount AmountFromValue(const UniValue& value)
|
||||
{
|
||||
if (!value.isNum() && !value.isStr())
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number or string");
|
||||
CAmount amount;
|
||||
if (!ParseFixedPoint(value.getValStr(), 8, &amount))
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
|
||||
if (!MoneyRange(amount))
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Amount out of range");
|
||||
return amount;
|
||||
}
|
||||
|
||||
UniValue ValueFromAmount(const CAmount& amount)
|
||||
{
|
||||
bool sign = amount < 0;
|
||||
int64_t n_abs = (sign ? -amount : amount);
|
||||
int64_t quotient = n_abs / COIN;
|
||||
int64_t remainder = n_abs % COIN;
|
||||
return UniValue(UniValue::VNUM,
|
||||
strprintf("%s%d.%08d", sign ? "-" : "", quotient, remainder));
|
||||
}
|
||||
|
||||
uint256 ParseHashV(const UniValue& v, string strName)
|
||||
{
|
||||
string strHex;
|
||||
if (v.isStr())
|
||||
strHex = v.get_str();
|
||||
if (!IsHex(strHex)) // Note: IsHex("") is false
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
|
||||
uint256 result;
|
||||
result.SetHex(strHex);
|
||||
return result;
|
||||
}
|
||||
uint256 ParseHashO(const UniValue& o, string strKey)
|
||||
{
|
||||
return ParseHashV(find_value(o, strKey), strKey);
|
||||
}
|
||||
vector<unsigned char> ParseHexV(const UniValue& v, string strName)
|
||||
{
|
||||
string strHex;
|
||||
if (v.isStr())
|
||||
strHex = v.get_str();
|
||||
if (!IsHex(strHex))
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
|
||||
return ParseHex(strHex);
|
||||
}
|
||||
vector<unsigned char> ParseHexO(const UniValue& o, string strKey)
|
||||
{
|
||||
return ParseHexV(find_value(o, strKey), strKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: This interface may still be subject to change.
|
||||
*/
|
||||
|
||||
std::string CRPCTable::help(const std::string& strCommand) const
|
||||
{
|
||||
string strRet;
|
||||
string category;
|
||||
set<rpcfn_type> setDone;
|
||||
vector<pair<string, const CRPCCommand*> > vCommands;
|
||||
|
||||
for (map<string, const CRPCCommand*>::const_iterator mi = mapCommands.begin(); mi != mapCommands.end(); ++mi)
|
||||
vCommands.push_back(make_pair(mi->second->category + mi->first, mi->second));
|
||||
sort(vCommands.begin(), vCommands.end());
|
||||
|
||||
BOOST_FOREACH(const PAIRTYPE(string, const CRPCCommand*)& command, vCommands)
|
||||
{
|
||||
const CRPCCommand *pcmd = command.second;
|
||||
string strMethod = pcmd->name;
|
||||
// We already filter duplicates, but these deprecated screw up the sort order
|
||||
if (strMethod.find("label") != string::npos)
|
||||
continue;
|
||||
if ((strCommand != "" || pcmd->category == "hidden") && strMethod != strCommand)
|
||||
continue;
|
||||
try
|
||||
{
|
||||
UniValue params;
|
||||
rpcfn_type pfn = pcmd->actor;
|
||||
if (setDone.insert(pfn).second)
|
||||
(*pfn)(params, true);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
// Help text is returned in an exception
|
||||
string strHelp = string(e.what());
|
||||
if (strCommand == "")
|
||||
{
|
||||
if (strHelp.find('\n') != string::npos)
|
||||
strHelp = strHelp.substr(0, strHelp.find('\n'));
|
||||
|
||||
if (category != pcmd->category)
|
||||
{
|
||||
if (!category.empty())
|
||||
strRet += "\n";
|
||||
category = pcmd->category;
|
||||
string firstLetter = category.substr(0,1);
|
||||
boost::to_upper(firstLetter);
|
||||
strRet += "== " + firstLetter + category.substr(1) + " ==\n";
|
||||
}
|
||||
}
|
||||
strRet += strHelp + "\n";
|
||||
}
|
||||
}
|
||||
if (strRet == "")
|
||||
strRet = strprintf("help: unknown command: %s\n", strCommand);
|
||||
strRet = strRet.substr(0,strRet.size()-1);
|
||||
return strRet;
|
||||
}
|
||||
|
||||
UniValue help(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() > 1)
|
||||
throw runtime_error(
|
||||
"help ( \"command\" )\n"
|
||||
"\nList all commands, or get help for a specified command.\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"command\" (string, optional) The command to get help on\n"
|
||||
"\nResult:\n"
|
||||
"\"text\" (string) The help text\n"
|
||||
);
|
||||
|
||||
string strCommand;
|
||||
if (params.size() > 0)
|
||||
strCommand = params[0].get_str();
|
||||
|
||||
return tableRPC.help(strCommand);
|
||||
}
|
||||
|
||||
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
void GenerateBitcoins(bool b, CWallet *pw, int t);
|
||||
#else
|
||||
void GenerateBitcoins(bool b, CWallet *pw);
|
||||
#endif
|
||||
|
||||
|
||||
UniValue stop(const UniValue& params, bool fHelp)
|
||||
{
|
||||
char buf[66+128];
|
||||
// Accept the deprecated and ignored 'detach' boolean argument
|
||||
if (fHelp || params.size() > 1)
|
||||
throw runtime_error(
|
||||
"stop\n"
|
||||
"\nStop Komodo server.");
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
GenerateBitcoins(false, pwalletMain, 0);
|
||||
#else
|
||||
GenerateBitcoins(false, 0);
|
||||
#endif
|
||||
|
||||
// Shutdown will take long enough that the response should get back
|
||||
StartShutdown();
|
||||
sprintf(buf,"%s server stopping",ASSETCHAINS_SYMBOL[0] != 0 ? ASSETCHAINS_SYMBOL : "Komodo");
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call Table
|
||||
*/
|
||||
static const CRPCCommand vRPCCommands[] =
|
||||
{ // category name actor (function) okSafeMode
|
||||
// --------------------- ------------------------ ----------------------- ----------
|
||||
/* Overall control/query calls */
|
||||
{ "control", "help", &help, true },
|
||||
{ "control", "getiguanajson", &getiguanajson, true },
|
||||
{ "control", "getnotarysendmany", &getnotarysendmany, true },
|
||||
{ "control", "stop", &stop, true },
|
||||
|
||||
/* P2P networking */
|
||||
{ "network", "getnetworkinfo", &getnetworkinfo, true },
|
||||
{ "network", "getdeprecationinfo", &getdeprecationinfo, true },
|
||||
{ "network", "addnode", &addnode, true },
|
||||
{ "network", "disconnectnode", &disconnectnode, true },
|
||||
{ "network", "getaddednodeinfo", &getaddednodeinfo, true },
|
||||
{ "network", "getconnectioncount", &getconnectioncount, true },
|
||||
{ "network", "getnettotals", &getnettotals, true },
|
||||
{ "network", "getpeerinfo", &getpeerinfo, true },
|
||||
{ "network", "ping", &ping, true },
|
||||
{ "network", "setban", &setban, true },
|
||||
{ "network", "listbanned", &listbanned, true },
|
||||
{ "network", "clearbanned", &clearbanned, true },
|
||||
|
||||
/* Block chain and UTXO */
|
||||
{ "blockchain", "coinsupply", &coinsupply, true },
|
||||
{ "blockchain", "getblockchaininfo", &getblockchaininfo, true },
|
||||
{ "blockchain", "getbestblockhash", &getbestblockhash, true },
|
||||
{ "blockchain", "getblockcount", &getblockcount, true },
|
||||
{ "blockchain", "getblock", &getblock, true },
|
||||
{ "blockchain", "getblockdeltas", &getblockdeltas, false },
|
||||
{ "blockchain", "getblockhashes", &getblockhashes, true },
|
||||
{ "blockchain", "getblockhash", &getblockhash, true },
|
||||
{ "blockchain", "getblockheader", &getblockheader, true },
|
||||
{ "blockchain", "getchaintips", &getchaintips, true },
|
||||
{ "blockchain", "getdifficulty", &getdifficulty, true },
|
||||
{ "blockchain", "getmempoolinfo", &getmempoolinfo, true },
|
||||
{ "blockchain", "getrawmempool", &getrawmempool, true },
|
||||
{ "blockchain", "gettxout", &gettxout, true },
|
||||
{ "blockchain", "gettxoutproof", &gettxoutproof, true },
|
||||
{ "blockchain", "verifytxoutproof", &verifytxoutproof, true },
|
||||
{ "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true },
|
||||
{ "blockchain", "verifychain", &verifychain, true },
|
||||
{ "blockchain", "getspentinfo", &getspentinfo, false },
|
||||
//{ "blockchain", "paxprice", &paxprice, true },
|
||||
//{ "blockchain", "paxpending", &paxpending, true },
|
||||
//{ "blockchain", "paxprices", &paxprices, true },
|
||||
{ "blockchain", "notaries", ¬aries, true },
|
||||
//{ "blockchain", "height_MoM", &height_MoM, true },
|
||||
//{ "blockchain", "txMoMproof", &txMoMproof, true },
|
||||
{ "blockchain", "minerids", &minerids, true },
|
||||
{ "blockchain", "kvsearch", &kvsearch, true },
|
||||
{ "blockchain", "kvupdate", &kvupdate, true },
|
||||
|
||||
/* Cross chain utilities */
|
||||
{ "crosschain", "MoMoMdata", &MoMoMdata, true },
|
||||
{ "crosschain", "calc_MoM", &calc_MoM, true },
|
||||
{ "crosschain", "height_MoM", &height_MoM, true },
|
||||
{ "crosschain", "assetchainproof", &assetchainproof, true },
|
||||
{ "crosschain", "crosschainproof", &crosschainproof, true },
|
||||
{ "crosschain", "getNotarisationsForBlock", &getNotarisationsForBlock, true },
|
||||
{ "crosschain", "scanNotarisationsDB", &scanNotarisationsDB, true },
|
||||
{ "crosschain", "migrate_converttoexport", &migrate_converttoexport, true },
|
||||
{ "crosschain", "migrate_createimporttransaction", &migrate_createimporttransaction, true },
|
||||
{ "crosschain", "migrate_completeimporttransaction", &migrate_completeimporttransaction, true },
|
||||
|
||||
/* Mining */
|
||||
{ "mining", "getblocktemplate", &getblocktemplate, true },
|
||||
{ "mining", "getmininginfo", &getmininginfo, true },
|
||||
{ "mining", "getlocalsolps", &getlocalsolps, true },
|
||||
{ "mining", "getnetworksolps", &getnetworksolps, true },
|
||||
{ "mining", "getnetworkhashps", &getnetworkhashps, true },
|
||||
{ "mining", "prioritisetransaction", &prioritisetransaction, true },
|
||||
{ "mining", "submitblock", &submitblock, true },
|
||||
{ "mining", "getblocksubsidy", &getblocksubsidy, true },
|
||||
|
||||
#ifdef ENABLE_MINING
|
||||
/* Coin generation */
|
||||
{ "generating", "getgenerate", &getgenerate, true },
|
||||
{ "generating", "setgenerate", &setgenerate, true },
|
||||
{ "generating", "generate", &generate, true },
|
||||
#endif
|
||||
|
||||
/* Raw transactions */
|
||||
{ "rawtransactions", "createrawtransaction", &createrawtransaction, true },
|
||||
{ "rawtransactions", "decoderawtransaction", &decoderawtransaction, true },
|
||||
{ "rawtransactions", "decodescript", &decodescript, true },
|
||||
{ "rawtransactions", "getrawtransaction", &getrawtransaction, true },
|
||||
{ "rawtransactions", "sendrawtransaction", &sendrawtransaction, false },
|
||||
{ "rawtransactions", "signrawtransaction", &signrawtransaction, false }, /* uses wallet if enabled */
|
||||
#ifdef ENABLE_WALLET
|
||||
{ "rawtransactions", "fundrawtransaction", &fundrawtransaction, false },
|
||||
#endif
|
||||
|
||||
// auction
|
||||
{ "auction", "auctionaddress", &auctionaddress, true },
|
||||
|
||||
// lotto
|
||||
{ "lotto", "lottoaddress", &lottoaddress, true },
|
||||
|
||||
// fsm
|
||||
{ "FSM", "FSMaddress", &FSMaddress, true },
|
||||
{ "FSM", "FSMcreate", &FSMcreate, true },
|
||||
{ "FSM", "FSMlist", &FSMlist, true },
|
||||
{ "FSM", "FSMinfo", &FSMinfo, true },
|
||||
|
||||
// rewards
|
||||
{ "rewards", "rewardslist", &rewardslist, true },
|
||||
{ "rewards", "rewardsinfo", &rewardsinfo, true },
|
||||
{ "rewards", "rewardscreatefunding", &rewardscreatefunding, true },
|
||||
{ "rewards", "rewardsaddfunding", &rewardsaddfunding, true },
|
||||
{ "rewards", "rewardslock", &rewardslock, true },
|
||||
{ "rewards", "rewardsunlock", &rewardsunlock, true },
|
||||
{ "rewards", "rewardsaddress", &rewardsaddress, true },
|
||||
|
||||
// faucet
|
||||
{ "faucet", "faucetinfo", &faucetinfo, true },
|
||||
{ "faucet", "faucetfund", &faucetfund, true },
|
||||
{ "faucet", "faucetget", &faucetget, true },
|
||||
{ "faucet", "faucetaddress", &faucetaddress, true },
|
||||
|
||||
// Heir
|
||||
{ "heir", "heiraddress", &heiraddress, true },
|
||||
|
||||
// Channels
|
||||
{ "channels", "channelsaddress", &channelsaddress, true },
|
||||
{ "channels", "channelsinfo", &channelsinfo, true },
|
||||
{ "channels", "channelsopen", &channelsopen, true },
|
||||
{ "channels", "channelspayment", &channelspayment, true },
|
||||
{ "channels", "channelsclose", &channelsclose, true },
|
||||
{ "channels", "channelsrefund", &channelsrefund, true },
|
||||
|
||||
// Oracles
|
||||
{ "oracles", "oraclesaddress", &oraclesaddress, true },
|
||||
{ "oracles", "oracleslist", &oracleslist, true },
|
||||
{ "oracles", "oraclesinfo", &oraclesinfo, true },
|
||||
{ "oracles", "oraclescreate", &oraclescreate, true },
|
||||
{ "oracles", "oraclesregister", &oraclesregister, true },
|
||||
{ "oracles", "oraclessubscribe", &oraclessubscribe, true },
|
||||
{ "oracles", "oraclesdata", &oraclesdata, true },
|
||||
{ "oracles", "oraclessamples", &oraclessamples, true },
|
||||
|
||||
// Prices
|
||||
{ "prices", "pricesaddress", &pricesaddress, true },
|
||||
{ "prices", "priceslist", &priceslist, true },
|
||||
{ "prices", "pricesinfo", &pricesinfo, true },
|
||||
{ "prices", "pricescreate", &pricescreate, true },
|
||||
{ "prices", "pricesaddfunding", &pricesaddfunding, true },
|
||||
{ "prices", "pricesbet", &pricesbet, true },
|
||||
{ "prices", "pricesstatus", &pricesstatus, true },
|
||||
{ "prices", "pricesfinish", &pricesfinish, true },
|
||||
|
||||
// Pegs
|
||||
{ "pegs", "pegsaddress", &pegsaddress, true },
|
||||
|
||||
// Triggers
|
||||
{ "triggers", "triggersaddress", &triggersaddress, true },
|
||||
|
||||
// Payments
|
||||
{ "payments", "paymentsaddress", &paymentsaddress, true },
|
||||
|
||||
// Gateways
|
||||
{ "gateways", "gatewaysaddress", &gatewaysaddress, true },
|
||||
{ "gateways", "gatewayslist", &gatewayslist, true },
|
||||
{ "gateways", "gatewaysinfo", &gatewaysinfo, true },
|
||||
{ "gateways", "gatewaysbind", &gatewaysbind, true },
|
||||
{ "gateways", "gatewaysdeposit", &gatewaysdeposit, true },
|
||||
{ "gateways", "gatewaysclaim", &gatewaysclaim, true },
|
||||
{ "gateways", "gatewayswithdraw", &gatewayswithdraw, true },
|
||||
{ "gateways", "gatewayspartialsign", &gatewayspartialsign, true },
|
||||
{ "gateways", "gatewayscompletesigning", &gatewayscompletesigning, true },
|
||||
{ "gateways", "gatewaysmarkdone", &gatewaysmarkdone, true },
|
||||
{ "gateways", "gatewayspending", &gatewayspending, true },
|
||||
{ "gateways", "gatewaysprocessed", &gatewaysprocessed, true },
|
||||
{ "gateways", "gatewaysmultisig", &gatewaysmultisig, true },
|
||||
|
||||
// dice
|
||||
{ "dice", "dicelist", &dicelist, true },
|
||||
{ "dice", "diceinfo", &diceinfo, true },
|
||||
{ "dice", "dicefund", &dicefund, true },
|
||||
{ "dice", "diceaddfunds", &diceaddfunds, true },
|
||||
{ "dice", "dicebet", &dicebet, true },
|
||||
{ "dice", "dicefinish", &dicefinish, true },
|
||||
{ "dice", "dicestatus", &dicestatus, true },
|
||||
{ "dice", "diceaddress", &diceaddress, true },
|
||||
|
||||
// tokens
|
||||
{ "tokens", "tokeninfo", &tokeninfo, true },
|
||||
{ "tokens", "tokenlist", &tokenlist, true },
|
||||
{ "tokens", "tokenorders", &tokenorders, true },
|
||||
{ "tokens", "tokenaddress", &tokenaddress, true },
|
||||
{ "tokens", "tokenbalance", &tokenbalance, true },
|
||||
{ "tokens", "tokencreate", &tokencreate, true },
|
||||
{ "tokens", "tokentransfer", &tokentransfer, true },
|
||||
{ "tokens", "tokenbid", &tokenbid, true },
|
||||
{ "tokens", "tokencancelbid", &tokencancelbid, true },
|
||||
{ "tokens", "tokenfillbid", &tokenfillbid, true },
|
||||
{ "tokens", "tokenask", &tokenask, true },
|
||||
//{ "tokens", "tokenswapask", &tokenswapask, true },
|
||||
{ "tokens", "tokencancelask", &tokencancelask, true },
|
||||
{ "tokens", "tokenfillask", &tokenfillask, true },
|
||||
//{ "tokens", "tokenfillswap", &tokenfillswap, true },
|
||||
{ "tokens", "tokenconvert", &tokenconvert, true },
|
||||
|
||||
/* Address index */
|
||||
{ "addressindex", "getaddressmempool", &getaddressmempool, true },
|
||||
{ "addressindex", "getaddressutxos", &getaddressutxos, false },
|
||||
{ "addressindex", "getaddressdeltas", &getaddressdeltas, false },
|
||||
{ "addressindex", "getaddresstxids", &getaddresstxids, false },
|
||||
{ "addressindex", "getaddressbalance", &getaddressbalance, false },
|
||||
{ "addressindex", "getsnapshot", &getsnapshot, false },
|
||||
|
||||
/* Utility functions */
|
||||
{ "util", "createmultisig", &createmultisig, true },
|
||||
{ "util", "validateaddress", &validateaddress, true }, /* uses wallet if enabled */
|
||||
{ "util", "verifymessage", &verifymessage, true },
|
||||
{ "util", "txnotarizedconfirmed", &txnotarizedconfirmed, true },
|
||||
{ "util", "estimatefee", &estimatefee, true },
|
||||
{ "util", "estimatepriority", &estimatepriority, true },
|
||||
{ "util", "z_validateaddress", &z_validateaddress, true }, /* uses wallet if enabled */
|
||||
{ "util", "jumblr_deposit", &jumblr_deposit, true },
|
||||
{ "util", "jumblr_secret", &jumblr_secret, true },
|
||||
{ "util", "jumblr_pause", &jumblr_pause, true },
|
||||
{ "util", "jumblr_resume", &jumblr_resume, true },
|
||||
|
||||
{ "util", "invalidateblock", &invalidateblock, true },
|
||||
{ "util", "reconsiderblock", &reconsiderblock, true },
|
||||
/* Not shown in help */
|
||||
{ "hidden", "setmocktime", &setmocktime, true },
|
||||
#ifdef ENABLE_WALLET
|
||||
/* Wallet */
|
||||
{ "wallet", "resendwallettransactions", &resendwallettransactions, true},
|
||||
{ "wallet", "addmultisigaddress", &addmultisigaddress, true },
|
||||
{ "wallet", "backupwallet", &backupwallet, true },
|
||||
{ "wallet", "dumpprivkey", &dumpprivkey, true },
|
||||
{ "wallet", "dumpwallet", &dumpwallet, true },
|
||||
{ "wallet", "encryptwallet", &encryptwallet, true },
|
||||
{ "wallet", "getaccountaddress", &getaccountaddress, true },
|
||||
{ "wallet", "getaccount", &getaccount, true },
|
||||
{ "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true },
|
||||
{ "wallet", "cleanwallettransactions", &cleanwallettransactions, false },
|
||||
{ "wallet", "getbalance", &getbalance, false },
|
||||
{ "wallet", "getbalance64", &getbalance64, false },
|
||||
{ "wallet", "getnewaddress", &getnewaddress, true },
|
||||
// { "wallet", "getnewaddress64", &getnewaddress64, true },
|
||||
{ "wallet", "getrawchangeaddress", &getrawchangeaddress, true },
|
||||
{ "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false },
|
||||
{ "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false },
|
||||
{ "wallet", "gettransaction", &gettransaction, false },
|
||||
{ "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false },
|
||||
{ "wallet", "getwalletinfo", &getwalletinfo, false },
|
||||
{ "wallet", "importprivkey", &importprivkey, true },
|
||||
{ "wallet", "importwallet", &importwallet, true },
|
||||
{ "wallet", "importaddress", &importaddress, true },
|
||||
{ "wallet", "keypoolrefill", &keypoolrefill, true },
|
||||
{ "wallet", "listaccounts", &listaccounts, false },
|
||||
{ "wallet", "listaddressgroupings", &listaddressgroupings, false },
|
||||
{ "wallet", "listlockunspent", &listlockunspent, false },
|
||||
{ "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false },
|
||||
{ "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false },
|
||||
{ "wallet", "listsinceblock", &listsinceblock, false },
|
||||
{ "wallet", "listtransactions", &listtransactions, false },
|
||||
{ "wallet", "listunspent", &listunspent, false },
|
||||
{ "wallet", "lockunspent", &lockunspent, true },
|
||||
{ "wallet", "move", &movecmd, false },
|
||||
{ "wallet", "sendfrom", &sendfrom, false },
|
||||
{ "wallet", "sendmany", &sendmany, false },
|
||||
{ "wallet", "sendtoaddress", &sendtoaddress, false },
|
||||
{ "wallet", "setaccount", &setaccount, true },
|
||||
{ "wallet", "setpubkey", &setpubkey, true },
|
||||
{ "wallet", "settxfee", &settxfee, true },
|
||||
{ "wallet", "signmessage", &signmessage, true },
|
||||
{ "wallet", "walletlock", &walletlock, true },
|
||||
{ "wallet", "walletpassphrasechange", &walletpassphrasechange, true },
|
||||
{ "wallet", "walletpassphrase", &walletpassphrase, true },
|
||||
{ "wallet", "zcbenchmark", &zc_benchmark, true },
|
||||
{ "wallet", "zcrawkeygen", &zc_raw_keygen, true },
|
||||
{ "wallet", "zcrawjoinsplit", &zc_raw_joinsplit, true },
|
||||
{ "wallet", "zcrawreceive", &zc_raw_receive, true },
|
||||
{ "wallet", "zcsamplejoinsplit", &zc_sample_joinsplit, true },
|
||||
{ "wallet", "z_listreceivedbyaddress",&z_listreceivedbyaddress,false },
|
||||
{ "wallet", "z_getbalance", &z_getbalance, false },
|
||||
{ "wallet", "z_gettotalbalance", &z_gettotalbalance, false },
|
||||
{ "wallet", "z_mergetoaddress", &z_mergetoaddress, false },
|
||||
{ "wallet", "z_sendmany", &z_sendmany, false },
|
||||
{ "wallet", "z_shieldcoinbase", &z_shieldcoinbase, false },
|
||||
{ "wallet", "z_getoperationstatus", &z_getoperationstatus, true },
|
||||
{ "wallet", "z_getoperationresult", &z_getoperationresult, true },
|
||||
{ "wallet", "z_listoperationids", &z_listoperationids, true },
|
||||
{ "wallet", "z_getnewaddress", &z_getnewaddress, true },
|
||||
{ "wallet", "z_listaddresses", &z_listaddresses, true },
|
||||
{ "wallet", "z_exportkey", &z_exportkey, true },
|
||||
{ "wallet", "z_importkey", &z_importkey, true },
|
||||
{ "wallet", "z_exportviewingkey", &z_exportviewingkey, true },
|
||||
{ "wallet", "z_importviewingkey", &z_importviewingkey, true },
|
||||
{ "wallet", "z_exportwallet", &z_exportwallet, true },
|
||||
{ "wallet", "z_importwallet", &z_importwallet, true },
|
||||
|
||||
// TODO: rearrange into another category
|
||||
{ "disclosure", "z_getpaymentdisclosure", &z_getpaymentdisclosure, true },
|
||||
{ "disclosure", "z_validatepaymentdisclosure", &z_validatepaymentdisclosure, true }
|
||||
#endif // ENABLE_WALLET
|
||||
};
|
||||
|
||||
CRPCTable::CRPCTable()
|
||||
{
|
||||
unsigned int vcidx;
|
||||
for (vcidx = 0; vcidx < (sizeof(vRPCCommands) / sizeof(vRPCCommands[0])); vcidx++)
|
||||
{
|
||||
const CRPCCommand *pcmd;
|
||||
|
||||
pcmd = &vRPCCommands[vcidx];
|
||||
mapCommands[pcmd->name] = pcmd;
|
||||
}
|
||||
}
|
||||
|
||||
const CRPCCommand *CRPCTable::operator[](const std::string &name) const
|
||||
{
|
||||
map<string, const CRPCCommand*>::const_iterator it = mapCommands.find(name);
|
||||
if (it == mapCommands.end())
|
||||
return NULL;
|
||||
return (*it).second;
|
||||
}
|
||||
|
||||
bool CRPCTable::appendCommand(const std::string& name, const CRPCCommand* pcmd)
|
||||
{
|
||||
if (IsRPCRunning())
|
||||
return false;
|
||||
|
||||
// don't allow overwriting for now
|
||||
map<string, const CRPCCommand*>::const_iterator it = mapCommands.find(name);
|
||||
if (it != mapCommands.end())
|
||||
return false;
|
||||
|
||||
mapCommands[name] = pcmd;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StartRPC()
|
||||
{
|
||||
LogPrint("rpc", "Starting RPC\n");
|
||||
fRPCRunning = true;
|
||||
g_rpcSignals.Started();
|
||||
|
||||
// Launch one async rpc worker. The ability to launch multiple workers is not recommended at present and thus the option is disabled.
|
||||
getAsyncRPCQueue()->addWorker();
|
||||
/*
|
||||
int n = GetArg("-rpcasyncthreads", 1);
|
||||
if (n<1) {
|
||||
LogPrintf("ERROR: Invalid value %d for -rpcasyncthreads. Must be at least 1.\n", n);
|
||||
strerr = strprintf(_("An error occurred while setting up the Async RPC threads, invalid parameter value of %d (must be at least 1)."), n);
|
||||
uiInterface.ThreadSafeMessageBox(strerr, "", CClientUIInterface::MSG_ERROR);
|
||||
StartShutdown();
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < n; i++)
|
||||
getAsyncRPCQueue()->addWorker();
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
void InterruptRPC()
|
||||
{
|
||||
LogPrint("rpc", "Interrupting RPC\n");
|
||||
// Interrupt e.g. running longpolls
|
||||
fRPCRunning = false;
|
||||
}
|
||||
|
||||
void StopRPC()
|
||||
{
|
||||
LogPrint("rpc", "Stopping RPC\n");
|
||||
deadlineTimers.clear();
|
||||
g_rpcSignals.Stopped();
|
||||
|
||||
// Tells async queue to cancel all operations and shutdown.
|
||||
LogPrintf("%s: waiting for async rpc workers to stop\n", __func__);
|
||||
getAsyncRPCQueue()->closeAndWait();
|
||||
}
|
||||
|
||||
bool IsRPCRunning()
|
||||
{
|
||||
return fRPCRunning;
|
||||
}
|
||||
|
||||
void SetRPCWarmupStatus(const std::string& newStatus)
|
||||
{
|
||||
LOCK(cs_rpcWarmup);
|
||||
rpcWarmupStatus = newStatus;
|
||||
}
|
||||
|
||||
void SetRPCWarmupFinished()
|
||||
{
|
||||
LOCK(cs_rpcWarmup);
|
||||
assert(fRPCInWarmup);
|
||||
fRPCInWarmup = false;
|
||||
}
|
||||
|
||||
bool RPCIsInWarmup(std::string *outStatus)
|
||||
{
|
||||
LOCK(cs_rpcWarmup);
|
||||
if (outStatus)
|
||||
*outStatus = rpcWarmupStatus;
|
||||
return fRPCInWarmup;
|
||||
}
|
||||
|
||||
void JSONRequest::parse(const UniValue& valRequest)
|
||||
{
|
||||
// Parse request
|
||||
if (!valRequest.isObject())
|
||||
throw JSONRPCError(RPC_INVALID_REQUEST, "Invalid Request object");
|
||||
const UniValue& request = valRequest.get_obj();
|
||||
|
||||
// Parse id now so errors from here on will have the id
|
||||
id = find_value(request, "id");
|
||||
|
||||
// Parse method
|
||||
UniValue valMethod = find_value(request, "method");
|
||||
if (valMethod.isNull())
|
||||
throw JSONRPCError(RPC_INVALID_REQUEST, "Missing method");
|
||||
if (!valMethod.isStr())
|
||||
throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string");
|
||||
strMethod = valMethod.get_str();
|
||||
if (strMethod != "getblocktemplate")
|
||||
LogPrint("rpc", "ThreadRPCServer method=%s\n", SanitizeString(strMethod));
|
||||
|
||||
// Parse params
|
||||
UniValue valParams = find_value(request, "params");
|
||||
if (valParams.isArray())
|
||||
params = valParams.get_array();
|
||||
else if (valParams.isNull())
|
||||
params = UniValue(UniValue::VARR);
|
||||
else
|
||||
throw JSONRPCError(RPC_INVALID_REQUEST, "Params must be an array");
|
||||
}
|
||||
|
||||
static UniValue JSONRPCExecOne(const UniValue& req)
|
||||
{
|
||||
UniValue rpc_result(UniValue::VOBJ);
|
||||
|
||||
JSONRequest jreq;
|
||||
try {
|
||||
jreq.parse(req);
|
||||
|
||||
UniValue result = tableRPC.execute(jreq.strMethod, jreq.params);
|
||||
rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id);
|
||||
}
|
||||
catch (const UniValue& objError)
|
||||
{
|
||||
rpc_result = JSONRPCReplyObj(NullUniValue, objError, jreq.id);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
rpc_result = JSONRPCReplyObj(NullUniValue,
|
||||
JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
|
||||
}
|
||||
|
||||
return rpc_result;
|
||||
}
|
||||
|
||||
std::string JSONRPCExecBatch(const UniValue& vReq)
|
||||
{
|
||||
UniValue ret(UniValue::VARR);
|
||||
for (size_t reqIdx = 0; reqIdx < vReq.size(); reqIdx++)
|
||||
ret.push_back(JSONRPCExecOne(vReq[reqIdx]));
|
||||
|
||||
return ret.write() + "\n";
|
||||
}
|
||||
|
||||
UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms) const
|
||||
{
|
||||
// Return immediately if in warmup
|
||||
{
|
||||
LOCK(cs_rpcWarmup);
|
||||
if (fRPCInWarmup)
|
||||
throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus);
|
||||
}
|
||||
|
||||
//printf("RPC call: %s\n", strMethod.c_str());
|
||||
|
||||
// Find method
|
||||
const CRPCCommand *pcmd = tableRPC[strMethod];
|
||||
if (!pcmd)
|
||||
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
|
||||
|
||||
g_rpcSignals.PreCommand(*pcmd);
|
||||
|
||||
try
|
||||
{
|
||||
// Execute
|
||||
return pcmd->actor(params, false);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
throw JSONRPCError(RPC_MISC_ERROR, e.what());
|
||||
}
|
||||
|
||||
g_rpcSignals.PostCommand(*pcmd);
|
||||
}
|
||||
|
||||
std::string HelpExampleCli(const std::string& methodname, const std::string& args)
|
||||
{
|
||||
return "> komodo-cli " + methodname + " " + args + "\n";
|
||||
}
|
||||
|
||||
std::string HelpExampleRpc(const std::string& methodname, const std::string& args)
|
||||
{
|
||||
return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\":\"curltest\", "
|
||||
"\"method\": \"" + methodname + "\", \"params\": [" + args + "] }' -H 'content-type: text/plain;' http://127.0.0.1:7771/\n";
|
||||
}
|
||||
|
||||
string experimentalDisabledHelpMsg(const string& rpc, const string& enableArg)
|
||||
{
|
||||
return "\nWARNING: " + rpc + " is disabled.\n"
|
||||
"To enable it, restart zcashd with the -experimentalfeatures and\n"
|
||||
"-" + enableArg + " commandline options, or add these two lines\n"
|
||||
"to the zcash.conf file:\n\n"
|
||||
"experimentalfeatures=1\n"
|
||||
+ enableArg + "=1\n";
|
||||
}
|
||||
|
||||
void RPCRegisterTimerInterface(RPCTimerInterface *iface)
|
||||
{
|
||||
timerInterfaces.push_back(iface);
|
||||
}
|
||||
|
||||
void RPCUnregisterTimerInterface(RPCTimerInterface *iface)
|
||||
{
|
||||
std::vector<RPCTimerInterface*>::iterator i = std::find(timerInterfaces.begin(), timerInterfaces.end(), iface);
|
||||
assert(i != timerInterfaces.end());
|
||||
timerInterfaces.erase(i);
|
||||
}
|
||||
|
||||
void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds)
|
||||
{
|
||||
if (timerInterfaces.empty())
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "No timer handler registered for RPC");
|
||||
deadlineTimers.erase(name);
|
||||
RPCTimerInterface* timerInterface = timerInterfaces[0];
|
||||
LogPrint("rpc", "queue run of timer %s in %i seconds (using %s)\n", name, nSeconds, timerInterface->Name());
|
||||
deadlineTimers.insert(std::make_pair(name, boost::shared_ptr<RPCTimerBase>(timerInterface->NewTimer(func, nSeconds*1000))));
|
||||
}
|
||||
|
||||
CRPCTable tableRPC;
|
||||
|
||||
// Return async rpc queue
|
||||
std::shared_ptr<AsyncRPCQueue> getAsyncRPCQueue()
|
||||
{
|
||||
return AsyncRPCQueue::sharedInstance();
|
||||
}
|
||||
441
src/rpc/server.h
Normal file
441
src/rpc/server.h
Normal file
@@ -0,0 +1,441 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_RPCSERVER_H
|
||||
#define BITCOIN_RPCSERVER_H
|
||||
|
||||
#include "amount.h"
|
||||
#include "rpc/protocol.h"
|
||||
#include "uint256.h"
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/function.hpp>
|
||||
|
||||
#include <univalue.h>
|
||||
|
||||
class AsyncRPCQueue;
|
||||
class CRPCCommand;
|
||||
|
||||
namespace RPCServer
|
||||
{
|
||||
void OnStarted(boost::function<void ()> slot);
|
||||
void OnStopped(boost::function<void ()> slot);
|
||||
void OnPreCommand(boost::function<void (const CRPCCommand&)> slot);
|
||||
void OnPostCommand(boost::function<void (const CRPCCommand&)> slot);
|
||||
}
|
||||
|
||||
class CBlockIndex;
|
||||
class CNetAddr;
|
||||
|
||||
class JSONRequest
|
||||
{
|
||||
public:
|
||||
UniValue id;
|
||||
std::string strMethod;
|
||||
UniValue params;
|
||||
|
||||
JSONRequest() { id = NullUniValue; }
|
||||
void parse(const UniValue& valRequest);
|
||||
};
|
||||
|
||||
/** Query whether RPC is running */
|
||||
bool IsRPCRunning();
|
||||
|
||||
/** Get the async queue*/
|
||||
std::shared_ptr<AsyncRPCQueue> getAsyncRPCQueue();
|
||||
|
||||
|
||||
/**
|
||||
* Set the RPC warmup status. When this is done, all RPC calls will error out
|
||||
* immediately with RPC_IN_WARMUP.
|
||||
*/
|
||||
void SetRPCWarmupStatus(const std::string& newStatus);
|
||||
/* Mark warmup as done. RPC calls will be processed from now on. */
|
||||
void SetRPCWarmupFinished();
|
||||
|
||||
/* returns the current warmup state. */
|
||||
bool RPCIsInWarmup(std::string *statusOut);
|
||||
|
||||
/**
|
||||
* Type-check arguments; throws JSONRPCError if wrong type given. Does not check that
|
||||
* the right number of arguments are passed, just that any passed are the correct type.
|
||||
* Use like: RPCTypeCheck(params, boost::assign::list_of(str_type)(int_type)(obj_type));
|
||||
*/
|
||||
void RPCTypeCheck(const UniValue& params,
|
||||
const std::list<UniValue::VType>& typesExpected, bool fAllowNull=false);
|
||||
|
||||
/*
|
||||
Check for expected keys/value types in an Object.
|
||||
Use like: RPCTypeCheckObj(object, boost::assign::map_list_of("name", str_type)("value", int_type));
|
||||
*/
|
||||
void RPCTypeCheckObj(const UniValue& o,
|
||||
const std::map<std::string, UniValue::VType>& typesExpected, bool fAllowNull=false);
|
||||
|
||||
/** Opaque base class for timers returned by NewTimerFunc.
|
||||
* This provides no methods at the moment, but makes sure that delete
|
||||
* cleans up the whole state.
|
||||
*/
|
||||
class RPCTimerBase
|
||||
{
|
||||
public:
|
||||
virtual ~RPCTimerBase() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* RPC timer "driver".
|
||||
*/
|
||||
class RPCTimerInterface
|
||||
{
|
||||
public:
|
||||
virtual ~RPCTimerInterface() {}
|
||||
/** Implementation name */
|
||||
virtual const char *Name() = 0;
|
||||
/** Factory function for timers.
|
||||
* RPC will call the function to create a timer that will call func in *millis* milliseconds.
|
||||
* @note As the RPC mechanism is backend-neutral, it can use different implementations of timers.
|
||||
* This is needed to cope with the case in which there is no HTTP server, but
|
||||
* only GUI RPC console, and to break the dependency of rpcserver on httprpc.
|
||||
*/
|
||||
virtual RPCTimerBase* NewTimer(boost::function<void(void)>& func, int64_t millis) = 0;
|
||||
};
|
||||
|
||||
/** Register factory function for timers */
|
||||
void RPCRegisterTimerInterface(RPCTimerInterface *iface);
|
||||
/** Unregister factory function for timers */
|
||||
void RPCUnregisterTimerInterface(RPCTimerInterface *iface);
|
||||
|
||||
/**
|
||||
* Run func nSeconds from now.
|
||||
* Overrides previous timer <name> (if any).
|
||||
*/
|
||||
void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds);
|
||||
|
||||
typedef UniValue(*rpcfn_type)(const UniValue& params, bool fHelp);
|
||||
|
||||
class CRPCCommand
|
||||
{
|
||||
public:
|
||||
std::string category;
|
||||
std::string name;
|
||||
rpcfn_type actor;
|
||||
bool okSafeMode;
|
||||
};
|
||||
|
||||
/**
|
||||
* Bitcoin RPC command dispatcher.
|
||||
*/
|
||||
class CRPCTable
|
||||
{
|
||||
private:
|
||||
std::map<std::string, const CRPCCommand*> mapCommands;
|
||||
public:
|
||||
CRPCTable();
|
||||
const CRPCCommand* operator[](const std::string& name) const;
|
||||
std::string help(const std::string& name) const;
|
||||
|
||||
/**
|
||||
* Execute a method.
|
||||
* @param method Method to execute
|
||||
* @param params UniValue Array of arguments (JSON objects)
|
||||
* @returns Result of the call.
|
||||
* @throws an exception (UniValue) when an error happens.
|
||||
*/
|
||||
UniValue execute(const std::string &method, const UniValue ¶ms) const;
|
||||
|
||||
|
||||
/**
|
||||
* Appends a CRPCCommand to the dispatch table.
|
||||
* Returns false if RPC server is already running (dump concurrency protection).
|
||||
* Commands cannot be overwritten (returns false).
|
||||
*/
|
||||
bool appendCommand(const std::string& name, const CRPCCommand* pcmd);
|
||||
};
|
||||
|
||||
extern CRPCTable tableRPC;
|
||||
|
||||
/**
|
||||
* Utilities: convert hex-encoded Values
|
||||
* (throws error if not hex).
|
||||
*/
|
||||
extern uint256 ParseHashV(const UniValue& v, std::string strName);
|
||||
extern uint256 ParseHashO(const UniValue& o, std::string strKey);
|
||||
extern std::vector<unsigned char> ParseHexV(const UniValue& v, std::string strName);
|
||||
extern std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey);
|
||||
|
||||
extern int64_t nWalletUnlockTime;
|
||||
extern CAmount AmountFromValue(const UniValue& value);
|
||||
extern UniValue ValueFromAmount(const CAmount& amount);
|
||||
extern double GetDifficulty(const CBlockIndex* blockindex = NULL);
|
||||
extern double GetNetworkDifficulty(const CBlockIndex* blockindex = NULL);
|
||||
extern std::string HelpRequiringPassphrase();
|
||||
extern std::string HelpExampleCli(const std::string& methodname, const std::string& args);
|
||||
extern std::string HelpExampleRpc(const std::string& methodname, const std::string& args);
|
||||
|
||||
extern void EnsureWalletIsUnlocked();
|
||||
|
||||
bool StartRPC();
|
||||
void InterruptRPC();
|
||||
void StopRPC();
|
||||
std::string JSONRPCExecBatch(const UniValue& vReq);
|
||||
|
||||
extern std::string experimentalDisabledHelpMsg(const std::string& rpc, const std::string& enableArg);
|
||||
|
||||
extern UniValue getconnectioncount(const UniValue& params, bool fHelp); // in rpcnet.cpp
|
||||
extern UniValue getaddressmempool(const UniValue& params, bool fHelp);
|
||||
extern UniValue getaddressutxos(const UniValue& params, bool fHelp);
|
||||
extern UniValue getaddressdeltas(const UniValue& params, bool fHelp);
|
||||
extern UniValue getaddresstxids(const UniValue& params, bool fHelp);
|
||||
extern UniValue getsnapshot(const UniValue& params, bool fHelp);
|
||||
extern UniValue getaddressbalance(const UniValue& params, bool fHelp);
|
||||
extern UniValue getpeerinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue ping(const UniValue& params, bool fHelp);
|
||||
extern UniValue addnode(const UniValue& params, bool fHelp);
|
||||
extern UniValue disconnectnode(const UniValue& params, bool fHelp);
|
||||
extern UniValue getaddednodeinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue getnettotals(const UniValue& params, bool fHelp);
|
||||
extern UniValue setban(const UniValue& params, bool fHelp);
|
||||
extern UniValue listbanned(const UniValue& params, bool fHelp);
|
||||
extern UniValue clearbanned(const UniValue& params, bool fHelp);
|
||||
|
||||
extern UniValue dumpprivkey(const UniValue& params, bool fHelp); // in rpcdump.cpp
|
||||
extern UniValue importprivkey(const UniValue& params, bool fHelp);
|
||||
extern UniValue importaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue dumpwallet(const UniValue& params, bool fHelp);
|
||||
extern UniValue importwallet(const UniValue& params, bool fHelp);
|
||||
|
||||
extern UniValue getgenerate(const UniValue& params, bool fHelp); // in rpcmining.cpp
|
||||
extern UniValue setgenerate(const UniValue& params, bool fHelp);
|
||||
extern UniValue generate(const UniValue& params, bool fHelp);
|
||||
extern UniValue getlocalsolps(const UniValue& params, bool fHelp);
|
||||
extern UniValue getnetworksolps(const UniValue& params, bool fHelp);
|
||||
extern UniValue getnetworkhashps(const UniValue& params, bool fHelp);
|
||||
extern UniValue getmininginfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue prioritisetransaction(const UniValue& params, bool fHelp);
|
||||
extern UniValue getblocktemplate(const UniValue& params, bool fHelp);
|
||||
extern UniValue submitblock(const UniValue& params, bool fHelp);
|
||||
extern UniValue estimatefee(const UniValue& params, bool fHelp);
|
||||
extern UniValue estimatepriority(const UniValue& params, bool fHelp);
|
||||
extern UniValue coinsupply(const UniValue& params, bool fHelp);
|
||||
extern UniValue tokeninfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue tokenlist(const UniValue& params, bool fHelp);
|
||||
extern UniValue tokenorders(const UniValue& params, bool fHelp);
|
||||
extern UniValue tokenbalance(const UniValue& params, bool fHelp);
|
||||
extern UniValue tokenaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue tokencreate(const UniValue& params, bool fHelp);
|
||||
extern UniValue tokentransfer(const UniValue& params, bool fHelp);
|
||||
extern UniValue tokenbid(const UniValue& params, bool fHelp);
|
||||
extern UniValue tokencancelbid(const UniValue& params, bool fHelp);
|
||||
extern UniValue tokenfillbid(const UniValue& params, bool fHelp);
|
||||
extern UniValue tokenask(const UniValue& params, bool fHelp);
|
||||
extern UniValue tokencancelask(const UniValue& params, bool fHelp);
|
||||
extern UniValue tokenfillask(const UniValue& params, bool fHelp);
|
||||
extern UniValue tokenconvert(const UniValue& params, bool fHelp);
|
||||
extern UniValue heiraddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue channelsaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue oraclesaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue oracleslist(const UniValue& params, bool fHelp);
|
||||
extern UniValue oraclesinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue oraclescreate(const UniValue& params, bool fHelp);
|
||||
extern UniValue oraclesregister(const UniValue& params, bool fHelp);
|
||||
extern UniValue oraclessubscribe(const UniValue& params, bool fHelp);
|
||||
extern UniValue oraclesdata(const UniValue& params, bool fHelp);
|
||||
extern UniValue oraclessamples(const UniValue& params, bool fHelp);
|
||||
extern UniValue pricesaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue priceslist(const UniValue& params, bool fHelp);
|
||||
extern UniValue pricesinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue pricescreate(const UniValue& params, bool fHelp);
|
||||
extern UniValue pricesaddfunding(const UniValue& params, bool fHelp);
|
||||
extern UniValue pricesbet(const UniValue& params, bool fHelp);
|
||||
extern UniValue pricesstatus(const UniValue& params, bool fHelp);
|
||||
extern UniValue pricesfinish(const UniValue& params, bool fHelp);
|
||||
extern UniValue pegsaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue triggersaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue paymentsaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue gatewaysaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue gatewayslist(const UniValue& params, bool fHelp);
|
||||
extern UniValue gatewaysinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue gatewaysbind(const UniValue& params, bool fHelp);
|
||||
extern UniValue gatewaysdeposit(const UniValue& params, bool fHelp);
|
||||
extern UniValue gatewaysclaim(const UniValue& params, bool fHelp);
|
||||
extern UniValue gatewayswithdraw(const UniValue& params, bool fHelp);
|
||||
extern UniValue gatewayspartialsign(const UniValue& params, bool fHelp);
|
||||
extern UniValue gatewayscompletesigning(const UniValue& params, bool fHelp);
|
||||
extern UniValue gatewaysmarkdone(const UniValue& params, bool fHelp);
|
||||
extern UniValue gatewayspending(const UniValue& params, bool fHelp);
|
||||
extern UniValue gatewaysprocessed(const UniValue& params, bool fHelp);
|
||||
extern UniValue gatewaysmultisig(const UniValue& params, bool fHelp);
|
||||
extern UniValue channelsinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue channelsopen(const UniValue& params, bool fHelp);
|
||||
extern UniValue channelspayment(const UniValue& params, bool fHelp);
|
||||
extern UniValue channelsclose(const UniValue& params, bool fHelp);
|
||||
extern UniValue channelsrefund(const UniValue& params, bool fHelp);
|
||||
|
||||
//extern UniValue tokenswapask(const UniValue& params, bool fHelp);
|
||||
//extern UniValue tokenfillswap(const UniValue& params, bool fHelp);
|
||||
extern UniValue faucetfund(const UniValue& params, bool fHelp);
|
||||
extern UniValue faucetget(const UniValue& params, bool fHelp);
|
||||
extern UniValue faucetaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue faucetinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue rewardsinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue rewardslist(const UniValue& params, bool fHelp);
|
||||
extern UniValue rewardsaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue rewardscreatefunding(const UniValue& params, bool fHelp);
|
||||
extern UniValue rewardsaddfunding(const UniValue& params, bool fHelp);
|
||||
extern UniValue rewardslock(const UniValue& params, bool fHelp);
|
||||
extern UniValue rewardsunlock(const UniValue& params, bool fHelp);
|
||||
extern UniValue diceaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue dicefund(const UniValue& params, bool fHelp);
|
||||
extern UniValue dicelist(const UniValue& params, bool fHelp);
|
||||
extern UniValue diceinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue diceaddfunds(const UniValue& params, bool fHelp);
|
||||
extern UniValue dicebet(const UniValue& params, bool fHelp);
|
||||
extern UniValue dicefinish(const UniValue& params, bool fHelp);
|
||||
extern UniValue dicestatus(const UniValue& params, bool fHelp);
|
||||
extern UniValue lottoaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue FSMaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue FSMcreate(const UniValue& params, bool fHelp);
|
||||
extern UniValue FSMlist(const UniValue& params, bool fHelp);
|
||||
extern UniValue FSMinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue auctionaddress(const UniValue& params, bool fHelp);
|
||||
|
||||
extern UniValue getnewaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
//extern UniValue getnewaddress64(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue getaccountaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue getrawchangeaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue setaccount(const UniValue& params, bool fHelp);
|
||||
extern UniValue getaccount(const UniValue& params, bool fHelp);
|
||||
extern UniValue getaddressesbyaccount(const UniValue& params, bool fHelp);
|
||||
extern UniValue sendtoaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue signmessage(const UniValue& params, bool fHelp);
|
||||
extern UniValue verifymessage(const UniValue& params, bool fHelp);
|
||||
extern UniValue getreceivedbyaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue getreceivedbyaccount(const UniValue& params, bool fHelp);
|
||||
extern UniValue cleanwallettransactions(const UniValue& params, bool fHelp);
|
||||
extern UniValue getbalance(const UniValue& params, bool fHelp);
|
||||
extern UniValue getbalance64(const UniValue& params, bool fHelp);
|
||||
extern UniValue getunconfirmedbalance(const UniValue& params, bool fHelp);
|
||||
extern UniValue movecmd(const UniValue& params, bool fHelp);
|
||||
extern UniValue sendfrom(const UniValue& params, bool fHelp);
|
||||
extern UniValue sendmany(const UniValue& params, bool fHelp);
|
||||
extern UniValue addmultisigaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue createmultisig(const UniValue& params, bool fHelp);
|
||||
extern UniValue listreceivedbyaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue listreceivedbyaccount(const UniValue& params, bool fHelp);
|
||||
extern UniValue listtransactions(const UniValue& params, bool fHelp);
|
||||
extern UniValue listaddressgroupings(const UniValue& params, bool fHelp);
|
||||
extern UniValue listaccounts(const UniValue& params, bool fHelp);
|
||||
extern UniValue listsinceblock(const UniValue& params, bool fHelp);
|
||||
extern UniValue gettransaction(const UniValue& params, bool fHelp);
|
||||
extern UniValue backupwallet(const UniValue& params, bool fHelp);
|
||||
extern UniValue keypoolrefill(const UniValue& params, bool fHelp);
|
||||
extern UniValue walletpassphrase(const UniValue& params, bool fHelp);
|
||||
extern UniValue walletpassphrasechange(const UniValue& params, bool fHelp);
|
||||
extern UniValue walletlock(const UniValue& params, bool fHelp);
|
||||
extern UniValue encryptwallet(const UniValue& params, bool fHelp);
|
||||
extern UniValue validateaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue txnotarizedconfirmed(const UniValue& params, bool fHelp);
|
||||
extern UniValue getinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue getiguanajson(const UniValue& params, bool fHelp);
|
||||
extern UniValue getnotarysendmany(const UniValue& params, bool fHelp);
|
||||
extern UniValue setpubkey(const UniValue& params, bool fHelp);
|
||||
extern UniValue getwalletinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue getblockchaininfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue getnetworkinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue getdeprecationinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue setmocktime(const UniValue& params, bool fHelp);
|
||||
extern UniValue resendwallettransactions(const UniValue& params, bool fHelp);
|
||||
extern UniValue zc_benchmark(const UniValue& params, bool fHelp);
|
||||
extern UniValue zc_raw_keygen(const UniValue& params, bool fHelp);
|
||||
extern UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp);
|
||||
extern UniValue zc_raw_receive(const UniValue& params, bool fHelp);
|
||||
extern UniValue zc_sample_joinsplit(const UniValue& params, bool fHelp);
|
||||
|
||||
extern UniValue jumblr_deposit(const UniValue& params, bool fHelp);
|
||||
extern UniValue jumblr_secret(const UniValue& params, bool fHelp);
|
||||
extern UniValue jumblr_pause(const UniValue& params, bool fHelp);
|
||||
extern UniValue jumblr_resume(const UniValue& params, bool fHelp);
|
||||
|
||||
extern UniValue getrawtransaction(const UniValue& params, bool fHelp); // in rcprawtransaction.cpp
|
||||
extern UniValue listunspent(const UniValue& params, bool fHelp);
|
||||
extern UniValue lockunspent(const UniValue& params, bool fHelp);
|
||||
extern UniValue listlockunspent(const UniValue& params, bool fHelp);
|
||||
extern UniValue createrawtransaction(const UniValue& params, bool fHelp);
|
||||
extern UniValue decoderawtransaction(const UniValue& params, bool fHelp);
|
||||
extern UniValue decodescript(const UniValue& params, bool fHelp);
|
||||
extern UniValue fundrawtransaction(const UniValue& params, bool fHelp);
|
||||
extern UniValue signrawtransaction(const UniValue& params, bool fHelp);
|
||||
extern UniValue sendrawtransaction(const UniValue& params, bool fHelp);
|
||||
extern UniValue gettxoutproof(const UniValue& params, bool fHelp);
|
||||
extern UniValue verifytxoutproof(const UniValue& params, bool fHelp);
|
||||
|
||||
extern UniValue getblockcount(const UniValue& params, bool fHelp); // in rpcblockchain.cpp
|
||||
extern UniValue getbestblockhash(const UniValue& params, bool fHelp);
|
||||
extern UniValue getdifficulty(const UniValue& params, bool fHelp);
|
||||
extern UniValue settxfee(const UniValue& params, bool fHelp);
|
||||
extern UniValue getmempoolinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue getrawmempool(const UniValue& params, bool fHelp);
|
||||
extern UniValue getblockhashes(const UniValue& params, bool fHelp);
|
||||
extern UniValue getblockdeltas(const UniValue& params, bool fHelp);
|
||||
extern UniValue getblockhash(const UniValue& params, bool fHelp);
|
||||
extern UniValue getblockheader(const UniValue& params, bool fHelp);
|
||||
extern UniValue getblock(const UniValue& params, bool fHelp);
|
||||
extern UniValue gettxoutsetinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue gettxout(const UniValue& params, bool fHelp);
|
||||
extern UniValue verifychain(const UniValue& params, bool fHelp);
|
||||
extern UniValue getchaintips(const UniValue& params, bool fHelp);
|
||||
extern UniValue invalidateblock(const UniValue& params, bool fHelp);
|
||||
extern UniValue reconsiderblock(const UniValue& params, bool fHelp);
|
||||
extern UniValue getspentinfo(const UniValue& params, bool fHelp);
|
||||
|
||||
extern UniValue getblocksubsidy(const UniValue& params, bool fHelp);
|
||||
|
||||
extern UniValue z_exportkey(const UniValue& params, bool fHelp); // in rpcdump.cpp
|
||||
extern UniValue z_importkey(const UniValue& params, bool fHelp); // in rpcdump.cpp
|
||||
extern UniValue z_exportviewingkey(const UniValue& params, bool fHelp); // in rpcdump.cpp
|
||||
extern UniValue z_importviewingkey(const UniValue& params, bool fHelp); // in rpcdump.cpp
|
||||
extern UniValue z_getnewaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_listaddresses(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_exportwallet(const UniValue& params, bool fHelp); // in rpcdump.cpp
|
||||
extern UniValue z_importwallet(const UniValue& params, bool fHelp); // in rpcdump.cpp
|
||||
extern UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_getbalance(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_gettotalbalance(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_mergetoaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_sendmany(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_shieldcoinbase(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_getoperationstatus(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_getoperationresult(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_listoperationids(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_validateaddress(const UniValue& params, bool fHelp); // in rpcmisc.cpp
|
||||
extern UniValue z_getpaymentdisclosure(const UniValue& params, bool fHelp); // in rpcdisclosure.cpp
|
||||
extern UniValue z_validatepaymentdisclosure(const UniValue ¶ms, bool fHelp); // in rpcdisclosure.cpp
|
||||
|
||||
extern UniValue MoMoMdata(const UniValue& params, bool fHelp);
|
||||
extern UniValue calc_MoM(const UniValue& params, bool fHelp);
|
||||
extern UniValue height_MoM(const UniValue& params, bool fHelp);
|
||||
extern UniValue assetchainproof(const UniValue& params, bool fHelp);
|
||||
extern UniValue crosschainproof(const UniValue& params, bool fHelp);
|
||||
extern UniValue getNotarisationsForBlock(const UniValue& params, bool fHelp);
|
||||
extern UniValue scanNotarisationsDB(const UniValue& params, bool fHelp);
|
||||
extern UniValue migrate_converttoexport(const UniValue& params, bool fHelp);
|
||||
extern UniValue migrate_createimporttransaction(const UniValue& params, bool fHelp);
|
||||
extern UniValue migrate_completeimporttransaction(const UniValue& params, bool fHelp);
|
||||
|
||||
extern UniValue notaries(const UniValue& params, bool fHelp);
|
||||
extern UniValue minerids(const UniValue& params, bool fHelp);
|
||||
extern UniValue kvsearch(const UniValue& params, bool fHelp);
|
||||
extern UniValue kvupdate(const UniValue& params, bool fHelp);
|
||||
extern UniValue paxprice(const UniValue& params, bool fHelp);
|
||||
extern UniValue paxpending(const UniValue& params, bool fHelp);
|
||||
extern UniValue paxprices(const UniValue& params, bool fHelp);
|
||||
extern UniValue paxdeposit(const UniValue& params, bool fHelp);
|
||||
extern UniValue paxwithdraw(const UniValue& params, bool fHelp);
|
||||
|
||||
#endif // BITCOIN_RPCSERVER_H
|
||||
Reference in New Issue
Block a user