Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion depends/patches/fontconfig/gperf_header_regen.patch
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ commit 7b6eb33ecd88768b28c67ce5d2d68a7eed5936b6
Author: fanquake <fanquake@gmail.com>
Date: Tue Aug 25 14:34:53 2020 +0800

Remove rule that causes inadvertant header regeneration
Remove rule that causes inadvertent header regeneration

Otherwise the makefile will needlessly attempt to re-generate the
headers with gperf. This can be dropped once the upstream build is fixed.
Expand Down
5 changes: 3 additions & 2 deletions src/bench/block_assemble.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <consensus/validation.h>
#include <script/standard.h>
#include <test/util/mining.h>
#include <test/util/script.h>
#include <test/util/setup_common.h>
#include <test/util/wallet.h>
#include <txmempool.h>
Expand All @@ -31,7 +32,7 @@ static void AssembleBlock(benchmark::Bench& bench)
std::array<CTransactionRef, NUM_BLOCKS - COINBASE_MATURITY + 1> txs;
for (size_t b{0}; b < NUM_BLOCKS; ++b) {
CMutableTransaction tx;
tx.vin.push_back(MineBlock(test_setup->m_node, SCRIPT_PUB));
tx.vin.push_back(MineBlock(test_setup->m_node, P2SH_OP_TRUE));
tx.vin.back().scriptSig = scriptSig;
tx.vout.emplace_back(1337, SCRIPT_PUB);
if (NUM_BLOCKS - b >= COINBASE_MATURITY)
Expand All @@ -47,7 +48,7 @@ static void AssembleBlock(benchmark::Bench& bench)
}

bench.minEpochIterations(700).run([&] {
PrepareBlock(test_setup->m_node, SCRIPT_PUB);
PrepareBlock(test_setup->m_node, P2SH_OP_TRUE);
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/core_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ bool DecodeHexBlockHeader(CBlockHeader&, const std::string& hex_header);
/**
* Parse a hex string into 256 bits
* @param[in] strHex a hex-formatted, 64-character string
* @param[out] result the result of the parasing
* @param[out] result the result of the parsing
* @returns true if successful, false if not
*
* @see ParseHashV for an RPC-oriented version of this
Expand Down
2 changes: 1 addition & 1 deletion src/merkleblock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::ve
//if we do not have this assert, we can hit a memory access violation when indexing into vTxid
assert(vTxid.size() != 0);
if (height == 0) {
// hash at height 0 is the txids themself
// hash at height 0 is the txids themselves
return vTxid[pos];
} else {
// calculate left hash
Expand Down
2 changes: 1 addition & 1 deletion src/qt/bitcoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ static void RegisterMetaTypes()
#ifdef ENABLE_WALLET
qRegisterMetaType<WalletModel*>();
#endif
// Register typedefs (see http://qt-project.org/doc/qt-5/qmetatype.html#qRegisterMetaType)
// Register typedefs (see https://doc.qt.io/qt-5/qmetatype.html#qRegisterMetaType)
// IMPORTANT: if CAmount is no longer a typedef use the normal variant above (see https://doc.qt.io/qt-5/qmetatype.html#qRegisterMetaType-1)
qRegisterMetaType<CAmount>("CAmount");
qRegisterMetaType<size_t>("size_t");
Expand Down
35 changes: 18 additions & 17 deletions src/qt/test/rpcnestedtests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
#include <univalue.h>
#include <util/system.h>

#include <llmq/context.h>
#include <QTest>

#include <QDir>
#include <QtGlobal>
#include <string>
#include <stdexcept>

static RPCHelpMan rpcNestedTest_rpc()
{
Expand All @@ -26,23 +26,25 @@ static RPCHelpMan rpcNestedTest_rpc()
{"arg2", RPCArg::Type::STR, RPCArg::Optional::OMITTED, ""},
{"arg3", RPCArg::Type::STR, RPCArg::Optional::OMITTED, ""},
},
{},
RPCResult{RPCResult::Type::ANY, "", ""},
RPCExamples{""},
[](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
return request.params.write(0, 0);
},
};
}

static const CRPCCommand vRPCCommands[] = {
{"test", &rpcNestedTest_rpc},
{"rpcNestedTest", &rpcNestedTest_rpc},
};

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]);
for (const auto& c : vRPCCommands) {
tableRPC.appendCommand(c.name, &c);
}

TestingSetup test;
m_node.setContext(&test.m_node);
Expand Down Expand Up @@ -70,13 +72,13 @@ void RPCNestedTests::rpcNestedTests()
RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo "); //whitespace at the end will be tolerated
QVERIFY(result.substr(0,1) == "{");

(RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo()[\"chain\"]")); //Quote path identifier are allowed, but look after a child containing the quotes in the key
RPCConsole::RPCExecuteCommandLine(m_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(m_node, result, "createrawtransaction [] {} 0")); //parameter not in brackets are allowed
(RPCConsole::RPCExecuteCommandLine(m_node, result2, "createrawtransaction([],{},0)")); //parameter in brackets are allowed
RPCConsole::RPCExecuteCommandLine(m_node, result, "createrawtransaction [] {} 0"); //parameter not in brackets are allowed
RPCConsole::RPCExecuteCommandLine(m_node, result2, "createrawtransaction([],{},0)"); //parameter in brackets are allowed
QVERIFY(result == result2);
(RPCConsole::RPCExecuteCommandLine(m_node, result2, "createrawtransaction( [], {} , 0 )")); //whitespace between parameters is allowed
RPCConsole::RPCExecuteCommandLine(m_node, result2, "createrawtransaction( [], {} , 0 )"); //whitespace between parameters is allowed
QVERIFY(result == result2);

RPCConsole::RPCExecuteCommandLine(m_node, result, "getblock(getbestblockhash())[tx][0]", &filtered);
Expand Down Expand Up @@ -125,14 +127,13 @@ void RPCNestedTests::rpcNestedTests()
RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest( abc , cba )");
QVERIFY(result == "[\"abc\",\"cba\"]");

// 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(m_node, result, "getblockchaininfo() .\n"), std::runtime_error); //invalid syntax
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo() getblockchaininfo()"), std::runtime_error); //invalid syntax
(RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo(")); //tolerate non closing brackets if we have no arguments
(RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo()()()")); //tolerate non command brackts
RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo("); //tolerate non closing brackets if we have no arguments
RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo()()()"); //tolerate non command brackets
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo(True)"), UniValue); //invalid argument
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(m_node, result, "a(getblockchaininfo(True))"), UniValue); //method not found
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest abc,,abc"), std::runtime_error); //don't tollerate empty arguments when using ,
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest(abc,,abc)"), std::runtime_error); //don't tollerate empty arguments when using ,
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest(abc,,)"), std::runtime_error); //don't tollerate empty arguments when using ,
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest abc,,abc"), std::runtime_error); //don't tolerate empty arguments when using ,
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest(abc,,abc)"), std::runtime_error); //don't tolerate empty arguments when using ,
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest(abc,,)"), std::runtime_error); //don't tolerate empty arguments when using ,
}
2 changes: 1 addition & 1 deletion src/qt/walletcontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ WalletModel* WalletController::getOrCreateWallet(std::unique_ptr<interfaces::Wal

connect(wallet_model, &WalletModel::unload, this, [this, wallet_model] {
// Defer removeAndDeleteWallet when no modal widget is active.
// TODO: remove this workaround by removing usage of QDiallog::exec.
// TODO: remove this workaround by removing usage of QDialog::exec.
if (QApplication::activeModalWidget()) {
connect(qApp, &QApplication::focusWindowChanged, wallet_model, [this, wallet_model]() {
if (!QApplication::activeModalWidget()) {
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1392,7 +1392,7 @@ static RPCHelpMan echo(const std::string& name)
{"arg8", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""},
{"arg9", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""},
},
RPCResult{RPCResult::Type::NONE, "", "Returns whatever was passed in"},
RPCResult{RPCResult::Type::ANY, "", "Returns whatever was passed in"},
RPCExamples{""},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/rawtransaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,7 @@ static RPCHelpMan createrawtransaction()
"For compatibility reasons, a dictionary, which holds the key-value pairs directly, is also\n"
" accepted as second parameter.",
{
{"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "",
{"", RPCArg::Type::OBJ_USER_KEYS, RPCArg::Optional::OMITTED, "",
{
{"address", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "A key-value pair. The key (string) is the Dash address, the value (float or string) is the amount in " + CURRENCY_UNIT},
},
Expand Down
5 changes: 3 additions & 2 deletions src/rpc/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,9 @@ static RPCHelpMan help()
{"command", RPCArg::Type::STR, /* default */ "all commands", "The command to get help on"},
{"subcommand", RPCArg::Type::STR, /* default */ "all subcommands", "The subcommand to get help on."},
},
RPCResult{
RPCResult::Type::STR, "", "The help text"
{
RPCResult{RPCResult::Type::STR, "", "The help text"},
RPCResult{RPCResult::Type::ANY, "", ""},
},
RPCExamples{""},
[&](const RPCHelpMan& self, const JSONRPCRequest& jsonRequest) -> UniValue
Expand Down
42 changes: 41 additions & 1 deletion src/rpc/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@ std::string RPCResults::ToDescriptionString() const
{
std::string result;
for (const auto& r : m_results) {
if (r.m_type == RPCResult::Type::ANY) continue; // for testing only
if (r.m_cond.empty()) {
result += "\nResult:\n";
} else {
Expand All @@ -493,7 +494,7 @@ std::string RPCExamples::ToDescriptionString() const
return m_examples.empty() ? m_examples : "\nExamples:\n" + m_examples;
}

UniValue RPCHelpMan::HandleRequest(const JSONRPCRequest& request)
UniValue RPCHelpMan::HandleRequest(const JSONRPCRequest& request) const
{
if (request.mode == JSONRPCRequest::GET_ARGS) {
return GetArgMap();
Expand Down Expand Up @@ -710,6 +711,9 @@ void RPCResult::ToSections(Sections& sections, const OuterType outer_type, const
sections.PushSection({indent + "..." + maybe_separator, m_description});
return;
}
case Type::ANY: {
CHECK_NONFATAL(false); // Only for testing
}
case Type::NONE: {
sections.PushSection({indent + "null" + maybe_separator, Description("json null")});
return;
Expand Down Expand Up @@ -775,6 +779,42 @@ void RPCResult::ToSections(Sections& sections, const OuterType outer_type, const
CHECK_NONFATAL(false);
}

bool RPCResult::MatchesType(const UniValue& result) const
{
switch (m_type) {
case Type::ELISION: {
return false;
}
case Type::ANY: {
return true;
}
case Type::NONE: {
return UniValue::VNULL == result.getType();
}
case Type::STR:
case Type::STR_HEX: {
return UniValue::VSTR == result.getType();
}
case Type::NUM:
case Type::STR_AMOUNT:
case Type::NUM_TIME: {
return UniValue::VNUM == result.getType();
}
case Type::BOOL: {
return UniValue::VBOOL == result.getType();
}
case Type::ARR_FIXED:
case Type::ARR: {
return UniValue::VARR == result.getType();
}
case Type::OBJ_DYN:
case Type::OBJ: {
return UniValue::VOBJ == result.getType();
}
} // no default case, so the compiler can warn about missing cases
CHECK_NONFATAL(false);
}

std::string RPCArg::ToStringObj(const bool oneline) const
{
std::string res;
Expand Down
9 changes: 6 additions & 3 deletions src/rpc/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ struct RPCArg {
m_oneline_description{std::move(oneline_description)},
m_type_str{std::move(type_str)}
{
CHECK_NONFATAL(type != Type::ARR && type != Type::OBJ);
CHECK_NONFATAL(type != Type::ARR && type != Type::OBJ && type != Type::OBJ_USER_KEYS);
}

RPCArg(
Expand All @@ -194,7 +194,7 @@ struct RPCArg {
m_oneline_description{std::move(oneline_description)},
m_type_str{std::move(type_str)}
{
CHECK_NONFATAL(type == Type::ARR || type == Type::OBJ);
CHECK_NONFATAL(type == Type::ARR || type == Type::OBJ || type == Type::OBJ_USER_KEYS);
}

bool IsOptional() const;
Expand Down Expand Up @@ -230,6 +230,7 @@ struct RPCResult {
NUM,
BOOL,
NONE,
ANY, //!< Special type to disable type checks (for testing only)
STR_AMOUNT, //!< Special string to represent a floating point amount
STR_HEX, //!< Special string with only hex chars
OBJ_DYN, //!< Special dictionary with keys that are not literals
Expand Down Expand Up @@ -302,6 +303,8 @@ struct RPCResult {
std::string ToStringObj() const;
/** Return the description string, including the result type. */
std::string ToDescriptionString() const;
/** Check whether the result JSON type matches. */
bool MatchesType(const UniValue& result) const;
};

struct RPCResults {
Expand Down Expand Up @@ -340,7 +343,7 @@ class RPCHelpMan
using RPCMethodImpl = std::function<UniValue(const RPCHelpMan&, const JSONRPCRequest&)>;
RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples, RPCMethodImpl fun);

UniValue HandleRequest(const JSONRPCRequest& request);
UniValue HandleRequest(const JSONRPCRequest& request) const;
std::string ToString() const;
/** Return the named args that need to be converted from string to another JSON type */
UniValue GetArgMap() const;
Expand Down
24 changes: 8 additions & 16 deletions src/test/script_standard_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,23 +159,20 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
s.clear();
s << ToByteVector(pubkey) << OP_CHECKSIG;
BOOST_CHECK(ExtractDestination(s, address));
BOOST_CHECK(std::get_if<PKHash>(&address) &&
*std::get_if<PKHash>(&address) == PKHash(pubkey));
BOOST_CHECK(std::get<PKHash>(address) == PKHash(pubkey));

// TxoutType::PUBKEYHASH
s.clear();
s << OP_DUP << OP_HASH160 << ToByteVector(pubkey.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
BOOST_CHECK(ExtractDestination(s, address));
BOOST_CHECK(std::get_if<PKHash>(&address) &&
*std::get_if<PKHash>(&address) == PKHash(pubkey));
BOOST_CHECK(std::get<PKHash>(address) == PKHash(pubkey));

// TxoutType::SCRIPTHASH
CScript redeemScript(s); // initialize with leftover P2PKH script
s.clear();
s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
BOOST_CHECK(ExtractDestination(s, address));
BOOST_CHECK(std::get_if<ScriptHash>(&address) &&
*std::get_if<ScriptHash>(&address) == ScriptHash(redeemScript));
BOOST_CHECK(std::get<ScriptHash>(address) == ScriptHash(redeemScript));

// TxoutType::MULTISIG
s.clear();
Expand Down Expand Up @@ -209,8 +206,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations)
BOOST_CHECK_EQUAL(whichType, TxoutType::PUBKEY);
BOOST_CHECK_EQUAL(addresses.size(), 1U);
BOOST_CHECK_EQUAL(nRequired, 1);
BOOST_CHECK(std::get_if<PKHash>(&addresses[0]) &&
*std::get_if<PKHash>(&addresses[0]) == PKHash(pubkeys[0]));
BOOST_CHECK(std::get<PKHash>(addresses[0]) == PKHash(pubkeys[0]));

// TxoutType::PUBKEYHASH
s.clear();
Expand All @@ -219,8 +215,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations)
BOOST_CHECK_EQUAL(whichType, TxoutType::PUBKEYHASH);
BOOST_CHECK_EQUAL(addresses.size(), 1U);
BOOST_CHECK_EQUAL(nRequired, 1);
BOOST_CHECK(std::get_if<PKHash>(&addresses[0]) &&
*std::get_if<PKHash>(&addresses[0]) == PKHash(pubkeys[0]));
BOOST_CHECK(std::get<PKHash>(addresses[0]) == PKHash(pubkeys[0]));

// TxoutType::SCRIPTHASH
CScript redeemScript(s); // initialize with leftover P2PKH script
Expand All @@ -230,8 +225,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations)
BOOST_CHECK_EQUAL(whichType, TxoutType::SCRIPTHASH);
BOOST_CHECK_EQUAL(addresses.size(), 1U);
BOOST_CHECK_EQUAL(nRequired, 1);
BOOST_CHECK(std::get_if<ScriptHash>(&addresses[0]) &&
*std::get_if<ScriptHash>(&addresses[0]) == ScriptHash(redeemScript));
BOOST_CHECK(std::get<ScriptHash>(addresses[0]) == ScriptHash(redeemScript));

// TxoutType::MULTISIG
s.clear();
Expand All @@ -243,10 +237,8 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations)
BOOST_CHECK_EQUAL(whichType, TxoutType::MULTISIG);
BOOST_CHECK_EQUAL(addresses.size(), 2U);
BOOST_CHECK_EQUAL(nRequired, 2);
BOOST_CHECK(std::get_if<PKHash>(&addresses[0]) &&
*std::get_if<PKHash>(&addresses[0]) == PKHash(pubkeys[0]));
BOOST_CHECK(std::get_if<PKHash>(&addresses[1]) &&
*std::get_if<PKHash>(&addresses[1]) == PKHash(pubkeys[1]));
BOOST_CHECK(std::get<PKHash>(addresses[0]) == PKHash(pubkeys[0]));
BOOST_CHECK(std::get<PKHash>(addresses[1]) == PKHash(pubkeys[1]));

// TxoutType::NULL_DATA
s.clear();
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/rpcwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ static RPCHelpMan listaddressgroupings()
{
{RPCResult::Type::ARR, "", "",
{
{RPCResult::Type::ARR, "", "",
{RPCResult::Type::ARR_FIXED, "", "",
{
{RPCResult::Type::STR, "address", "The Dash address"},
{RPCResult::Type::STR_AMOUNT, "amount", "The amount in " + CURRENCY_UNIT},
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/sqlite.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class SQLiteBatch : public DatabaseBatch
explicit SQLiteBatch(SQLiteDatabase& database);
~SQLiteBatch() override { Close(); }

/* No-op. See commeng on SQLiteDatabase::Flush */
/* No-op. See comment on SQLiteDatabase::Flush */
void Flush() override {}

void Close() override;
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/walletdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
uint256 checksum;
ssValue >> checksum;
if (!(checksum_valid = Hash(vchPrivKey) == checksum)) {
strErr = "Error reading wallet database: Crypted key corrupt";
strErr = "Error reading wallet database: Encrypted key corrupt";
return false;
}
}
Expand Down
Loading