UniValue CallRPC(std::string args) { std::vector<std::string> vArgs; boost::split(vArgs, args, boost::is_any_of(" \t")); std::string strMethod = vArgs[0]; vArgs.erase(vArgs.begin()); JSONRPCRequest request; request.strMethod = strMethod; request.params = RPCConvertValues(strMethod, vArgs); request.fHelp = false; if (RPCIsInWarmup(nullptr)) SetRPCWarmupFinished(); try { UniValue result = tableRPC.execute(request); return result; } catch (const UniValue& objError) { throw std::runtime_error(find_value(objError, "message").get_str()); } }
void RPCNestedTests::rpcNestedTests() { UniValue jsonRPCError; // do some test setup // could be moved to a more generic place when we add more tests on QT level const CChainParams& chainparams = Params(); RegisterAllCoreRPCCommands(tableRPC); tableRPC.appendCommand("rpcNestedTest", &vRPCCommands[0]); ClearDatadirCache(); std::string path = QDir::tempPath().toStdString() + "/" + strprintf("test_bitcoin_qt_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000))); QDir dir(QString::fromStdString(path)); dir.mkpath("."); ForceSetArg("-datadir", path); //mempool.setSanityCheck(1.0); pblocktree = new CBlockTreeDB(1 << 20, true); pcoinsdbview = new CCoinsViewDB(1 << 23, true); pcoinsTip = new CCoinsViewCache(pcoinsdbview); InitBlockIndex(chainparams); { CValidationState state; bool ok = ActivateBestChain(state, chainparams); QVERIFY(ok); } SetRPCWarmupFinished(); std::string result; std::string result2; std::string filtered; RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo()[chain]", &filtered); //simple result filtering with path QVERIFY(result=="main"); QVERIFY(filtered == "getblockchaininfo()[chain]"); RPCConsole::RPCExecuteCommandLine(result, "getblock(getbestblockhash())"); //simple 2 level nesting RPCConsole::RPCExecuteCommandLine(result, "getblock(getblock(getbestblockhash())[hash], true)"); RPCConsole::RPCExecuteCommandLine(result, "getblock( getblock( getblock(getbestblockhash())[hash] )[hash], true)"); //4 level nesting with whitespace, filtering path and boolean parameter RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo"); QVERIFY(result.substr(0,1) == "{"); RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo()"); QVERIFY(result.substr(0,1) == "{"); RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo "); //whitespace at the end will be tolerated QVERIFY(result.substr(0,1) == "{"); (RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo()[\"chain\"]")); //Quote path identifier are allowed, but look after a child contaning the quotes in the key QVERIFY(result == "null"); (RPCConsole::RPCExecuteCommandLine(result, "createrawtransaction [] {} 0")); //parameter not in brackets are allowed (RPCConsole::RPCExecuteCommandLine(result2, "createrawtransaction([],{},0)")); //parameter in brackets are allowed QVERIFY(result == result2); (RPCConsole::RPCExecuteCommandLine(result2, "createrawtransaction( [], {} , 0 )")); //whitespace between parametres is allowed QVERIFY(result == result2); RPCConsole::RPCExecuteCommandLine(result, "getblock(getbestblockhash())[tx][0]", &filtered); QVERIFY(result == "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"); QVERIFY(filtered == "getblock(getbestblockhash())[tx][0]"); RPCConsole::RPCParseCommandLine(result, "importprivkey", false, &filtered); QVERIFY(filtered == "importprivkey(…)"); RPCConsole::RPCParseCommandLine(result, "signmessagewithprivkey abc", false, &filtered); QVERIFY(filtered == "signmessagewithprivkey(…)"); RPCConsole::RPCParseCommandLine(result, "signmessagewithprivkey abc,def", false, &filtered); QVERIFY(filtered == "signmessagewithprivkey(…)"); RPCConsole::RPCParseCommandLine(result, "signrawtransaction(abc)", false, &filtered); QVERIFY(filtered == "signrawtransaction(…)"); RPCConsole::RPCParseCommandLine(result, "walletpassphrase(help())", false, &filtered); QVERIFY(filtered == "walletpassphrase(…)"); RPCConsole::RPCParseCommandLine(result, "walletpassphrasechange(help(walletpassphrasechange(abc)))", false, &filtered); QVERIFY(filtered == "walletpassphrasechange(…)"); RPCConsole::RPCParseCommandLine(result, "help(encryptwallet(abc, def))", false, &filtered); QVERIFY(filtered == "help(encryptwallet(…))"); RPCConsole::RPCParseCommandLine(result, "help(importprivkey())", false, &filtered); QVERIFY(filtered == "help(importprivkey(…))"); RPCConsole::RPCParseCommandLine(result, "help(importprivkey(help()))", false, &filtered); QVERIFY(filtered == "help(importprivkey(…))"); RPCConsole::RPCParseCommandLine(result, "help(importprivkey(abc), walletpassphrase(def))", false, &filtered); QVERIFY(filtered == "help(importprivkey(…), walletpassphrase(…))"); RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest"); QVERIFY(result == "[]"); RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest ''"); QVERIFY(result == "[\"\"]"); RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest \"\""); QVERIFY(result == "[\"\"]"); RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest '' abc"); QVERIFY(result == "[\"\",\"abc\"]"); RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest abc '' abc"); QVERIFY(result == "[\"abc\",\"\",\"abc\"]"); RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest abc abc"); QVERIFY(result == "[\"abc\",\"abc\"]"); RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest abc\t\tabc"); QVERIFY(result == "[\"abc\",\"abc\"]"); RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest(abc )"); QVERIFY(result == "[\"abc\"]"); RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest( abc )"); QVERIFY(result == "[\"abc\"]"); RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest( abc , cba )"); QVERIFY(result == "[\"abc\",\"cba\"]"); #if QT_VERSION >= 0x050300 // do the QVERIFY_EXCEPTION_THROWN checks only with Qt5.3 and higher (QVERIFY_EXCEPTION_THROWN was introduced in Qt5.3) QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo() .\n"), std::runtime_error); //invalid syntax QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo() getblockchaininfo()"), std::runtime_error); //invalid syntax (RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo(")); //tolerate non closing brackets if we have no arguments (RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo()()()")); //tolerate non command brackts QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo(True)"), UniValue); //invalid argument QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "a(getblockchaininfo(True))"), UniValue); //method not found QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest abc,,abc"), std::runtime_error); //don't tollerate empty arguments when using , QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest(abc,,abc)"), std::runtime_error); //don't tollerate empty arguments when using , QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest(abc,,)"), std::runtime_error); //don't tollerate empty arguments when using , #endif delete pcoinsTip; delete pcoinsdbview; delete pblocktree; boost::filesystem::remove_all(boost::filesystem::path(path)); }
void RPCNestedTests::rpcNestedTests() { // do some test setup // could be moved to a more generic place when we add more tests on QT level tableRPC.appendCommand("rpcNestedTest", &vRPCCommands[0]); //mempool.setSanityCheck(1.0); TestingSetup test; SetRPCWarmupFinished(); std::string result; std::string result2; std::string filtered; auto node = interfaces::MakeNode(); RPCConsole::RPCExecuteCommandLine(*node, result, "getblockchaininfo()[chain]", &filtered); //simple result filtering with path QVERIFY(result=="main"); QVERIFY(filtered == "getblockchaininfo()[chain]"); RPCConsole::RPCExecuteCommandLine(*node, result, "getblock(getbestblockhash())"); //simple 2 level nesting RPCConsole::RPCExecuteCommandLine(*node, result, "getblock(getblock(getbestblockhash())[hash], true)"); RPCConsole::RPCExecuteCommandLine(*node, result, "getblock( getblock( getblock(getbestblockhash())[hash] )[hash], true)"); //4 level nesting with whitespace, filtering path and boolean parameter RPCConsole::RPCExecuteCommandLine(*node, result, "getblockchaininfo"); QVERIFY(result.substr(0,1) == "{"); RPCConsole::RPCExecuteCommandLine(*node, result, "getblockchaininfo()"); QVERIFY(result.substr(0,1) == "{"); RPCConsole::RPCExecuteCommandLine(*node, result, "getblockchaininfo "); //whitespace at the end will be tolerated QVERIFY(result.substr(0,1) == "{"); (RPCConsole::RPCExecuteCommandLine(*node, result, "getblockchaininfo()[\"chain\"]")); //Quote path identifier are allowed, but look after a child containing the quotes in the key QVERIFY(result == "null"); (RPCConsole::RPCExecuteCommandLine(*node, result, "createrawtransaction [] {} 0")); //parameter not in brackets are allowed (RPCConsole::RPCExecuteCommandLine(*node, result2, "createrawtransaction([],{},0)")); //parameter in brackets are allowed QVERIFY(result == result2); (RPCConsole::RPCExecuteCommandLine(*node, result2, "createrawtransaction( [], {} , 0 )")); //whitespace between parameters is allowed QVERIFY(result == result2); RPCConsole::RPCExecuteCommandLine(*node, result, "getblock(getbestblockhash())[tx][0]", &filtered); QVERIFY(result == "97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9"); QVERIFY(filtered == "getblock(getbestblockhash())[tx][0]"); RPCConsole::RPCParseCommandLine(nullptr, result, "importprivkey", false, &filtered); QVERIFY(filtered == "importprivkey(…)"); RPCConsole::RPCParseCommandLine(nullptr, result, "signmessagewithprivkey abc", false, &filtered); QVERIFY(filtered == "signmessagewithprivkey(…)"); RPCConsole::RPCParseCommandLine(nullptr, result, "signmessagewithprivkey abc,def", false, &filtered); QVERIFY(filtered == "signmessagewithprivkey(…)"); RPCConsole::RPCParseCommandLine(nullptr, result, "signrawtransactionwithkey(abc)", false, &filtered); QVERIFY(filtered == "signrawtransactionwithkey(…)"); RPCConsole::RPCParseCommandLine(nullptr, result, "walletpassphrase(help())", false, &filtered); QVERIFY(filtered == "walletpassphrase(…)"); RPCConsole::RPCParseCommandLine(nullptr, result, "walletpassphrasechange(help(walletpassphrasechange(abc)))", false, &filtered); QVERIFY(filtered == "walletpassphrasechange(…)"); RPCConsole::RPCParseCommandLine(nullptr, result, "help(encryptwallet(abc, def))", false, &filtered); QVERIFY(filtered == "help(encryptwallet(…))"); RPCConsole::RPCParseCommandLine(nullptr, result, "help(importprivkey())", false, &filtered); QVERIFY(filtered == "help(importprivkey(…))"); RPCConsole::RPCParseCommandLine(nullptr, result, "help(importprivkey(help()))", false, &filtered); QVERIFY(filtered == "help(importprivkey(…))"); RPCConsole::RPCParseCommandLine(nullptr, result, "help(importprivkey(abc), walletpassphrase(def))", false, &filtered); QVERIFY(filtered == "help(importprivkey(…), walletpassphrase(…))"); RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest"); QVERIFY(result == "[]"); RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest ''"); QVERIFY(result == "[\"\"]"); RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest \"\""); QVERIFY(result == "[\"\"]"); RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest '' abc"); QVERIFY(result == "[\"\",\"abc\"]"); RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest abc '' abc"); QVERIFY(result == "[\"abc\",\"\",\"abc\"]"); RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest abc abc"); QVERIFY(result == "[\"abc\",\"abc\"]"); RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest abc\t\tabc"); QVERIFY(result == "[\"abc\",\"abc\"]"); RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest(abc )"); QVERIFY(result == "[\"abc\"]"); RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest( abc )"); QVERIFY(result == "[\"abc\"]"); RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest( abc , cba )"); QVERIFY(result == "[\"abc\",\"cba\"]"); #if QT_VERSION >= 0x050300 // do the QVERIFY_EXCEPTION_THROWN checks only with Qt5.3 and higher (QVERIFY_EXCEPTION_THROWN was introduced in Qt5.3) QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(*node, result, "getblockchaininfo() .\n"), std::runtime_error); //invalid syntax QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(*node, result, "getblockchaininfo() getblockchaininfo()"), std::runtime_error); //invalid syntax (RPCConsole::RPCExecuteCommandLine(*node, result, "getblockchaininfo(")); //tolerate non closing brackets if we have no arguments (RPCConsole::RPCExecuteCommandLine(*node, result, "getblockchaininfo()()()")); //tolerate non command brackts QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(*node, result, "getblockchaininfo(True)"), UniValue); //invalid argument QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(*node, result, "a(getblockchaininfo(True))"), UniValue); //method not found QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest abc,,abc"), std::runtime_error); //don't tollerate empty arguments when using , QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest(abc,,abc)"), std::runtime_error); //don't tollerate empty arguments when using , QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest(abc,,)"), std::runtime_error); //don't tollerate empty arguments when using , #endif }