mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 12:02:48 +01:00
Merge pull request #4632 from Munkybooty/backports-0.19-pr11
Backports 0.19 pr11
This commit is contained in:
commit
19149f50f4
@ -47,9 +47,9 @@ OSX_PLIST=$(top_builddir)/share/qt/Info.plist #not installed
|
||||
OSX_QT_TRANSLATIONS = ar,bg,ca,cs,da,de,es,fa,fi,fr,gd,gl,he,hu,it,ja,ko,lt,lv,pl,pt,ru,sk,sl,sv,uk,zh_CN,zh_TW
|
||||
|
||||
DIST_CONTRIB = \
|
||||
$(top_srcdir)/contrib/debian/copyright \
|
||||
$(top_srcdir)/contrib/linearize/linearize-data.py \
|
||||
$(top_srcdir)/contrib/linearize/linearize-hashes.py
|
||||
|
||||
DIST_SHARE = \
|
||||
$(top_srcdir)/share/genbuild.sh \
|
||||
$(top_srcdir)/share/rpcauth
|
||||
|
5
doc/release-notes-14982.md
Normal file
5
doc/release-notes-14982.md
Normal file
@ -0,0 +1,5 @@
|
||||
New RPCs
|
||||
--------
|
||||
|
||||
- The RPC `getrpcinfo` returns runtime details of the RPC server. At the moment
|
||||
it returns the active commands and the corresponding execution time.
|
@ -59,10 +59,11 @@ const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const {
|
||||
return pindex;
|
||||
}
|
||||
|
||||
CBlockIndex* CChain::FindEarliestAtLeast(int64_t nTime) const
|
||||
CBlockIndex* CChain::FindEarliestAtLeast(int64_t nTime, int height) const
|
||||
{
|
||||
std::vector<CBlockIndex*>::const_iterator lower = std::lower_bound(vChain.begin(), vChain.end(), nTime,
|
||||
[](CBlockIndex* pBlock, const int64_t& time) -> bool { return pBlock->GetBlockTimeMax() < time; });
|
||||
std::pair<int64_t, int> blockparams = std::make_pair(nTime, height);
|
||||
std::vector<CBlockIndex*>::const_iterator lower = std::lower_bound(vChain.begin(), vChain.end(), blockparams,
|
||||
[](CBlockIndex* pBlock, const std::pair<int64_t, int>& blockparams) -> bool { return pBlock->GetBlockTimeMax() < blockparams.first || pBlock->nHeight < blockparams.second; });
|
||||
return (lower == vChain.end() ? nullptr : *lower);
|
||||
}
|
||||
|
||||
|
@ -430,8 +430,8 @@ public:
|
||||
/** Find the last common block between this chain and a block index entry. */
|
||||
const CBlockIndex *FindFork(const CBlockIndex *pindex) const;
|
||||
|
||||
/** Find the earliest block with timestamp equal or greater than the given. */
|
||||
CBlockIndex* FindEarliestAtLeast(int64_t nTime) const;
|
||||
/** Find the earliest block with timestamp equal or greater than the given time and height equal or greater than the given height. */
|
||||
CBlockIndex* FindEarliestAtLeast(int64_t nTime, int height) const;
|
||||
};
|
||||
|
||||
#endif // BITCOIN_CHAIN_H
|
||||
|
@ -702,7 +702,7 @@ void SetupServerArgs()
|
||||
gArgs.AddArg("-platform-user=<user>", "Set the username for the \"platform user\", a restricted user intended to be used by Dash Platform, to the specified username.", ArgsManager::ALLOW_ANY, OptionsCategory::MASTERNODE);
|
||||
|
||||
gArgs.AddArg("-acceptnonstdtxn", strprintf("Relay and mine \"non-standard\" transactions (%sdefault: %u)", "testnet/regtest only; ", !testnetChainParams->RequireStandard()), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
|
||||
gArgs.AddArg("-dustrelayfee=<amt>", strprintf("Fee rate (in %s/kB) used to defined dust, the value of an output such that it will cost more than its value in fees at this fee rate to spend it. (default: %s)", CURRENCY_UNIT, FormatMoney(DUST_RELAY_TX_FEE)), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
|
||||
gArgs.AddArg("-dustrelayfee=<amt>", strprintf("Fee rate (in %s/kB) used to define dust, the value of an output such that it will cost more than its value in fees at this fee rate to spend it. (default: %s)", CURRENCY_UNIT, FormatMoney(DUST_RELAY_TX_FEE)), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
|
||||
gArgs.AddArg("-incrementalrelayfee=<amt>", strprintf("Fee rate (in %s/kB) used to define cost of relay, used for mempool limiting and BIP 125 replacement. (default: %s)", CURRENCY_UNIT, FormatMoney(DEFAULT_INCREMENTAL_RELAY_FEE)), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
|
||||
gArgs.AddArg("-bytespersigop", strprintf("Equivalent bytes per sigop in transactions for relay and mining (default: %u)", DEFAULT_BYTES_PER_SIGOP), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
|
||||
gArgs.AddArg("-datacarrier", strprintf("Relay and mine data carrier transactions (default: %u)", DEFAULT_ACCEPT_DATACARRIER), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
|
||||
|
@ -89,30 +89,16 @@ class LockImpl : public Chain::Lock, public UniqueLock<CCriticalSection>
|
||||
CBlockIndex* block = ::ChainActive()[height];
|
||||
return block && ((block->nStatus & BLOCK_HAVE_DATA) != 0) && block->nTx > 0;
|
||||
}
|
||||
Optional<int> findFirstBlockWithTime(int64_t time, uint256* hash) override
|
||||
Optional<int> findFirstBlockWithTimeAndHeight(int64_t time, int height, uint256* hash) override
|
||||
{
|
||||
LockAnnotation lock(::cs_main);
|
||||
CBlockIndex* block = ::ChainActive().FindEarliestAtLeast(time);
|
||||
CBlockIndex* block = ::ChainActive().FindEarliestAtLeast(time, height);
|
||||
if (block) {
|
||||
if (hash) *hash = block->GetBlockHash();
|
||||
return block->nHeight;
|
||||
}
|
||||
return nullopt;
|
||||
}
|
||||
Optional<int> findFirstBlockWithTimeAndHeight(int64_t time, int height) override
|
||||
{
|
||||
// TODO: Could update CChain::FindEarliestAtLeast() to take a height
|
||||
// parameter and use it with std::lower_bound() to make this
|
||||
// implementation more efficient and allow combining
|
||||
// findFirstBlockWithTime and findFirstBlockWithTimeAndHeight into one
|
||||
// method.
|
||||
for (CBlockIndex* block = ::ChainActive()[height]; block; block = ::ChainActive().Next(block)) {
|
||||
if (block->GetBlockTime() >= time) {
|
||||
return block->nHeight;
|
||||
}
|
||||
}
|
||||
return nullopt;
|
||||
}
|
||||
Optional<int> findPruned(int start_height, Optional<int> stop_height) override
|
||||
{
|
||||
LockAnnotation lock(::cs_main);
|
||||
|
@ -99,21 +99,12 @@ public:
|
||||
//! pruned), and contains transactions.
|
||||
virtual bool haveBlockOnDisk(int height) = 0;
|
||||
|
||||
//! Return height of the first block in the chain with timestamp equal
|
||||
//! or greater than the given time, or nullopt if there is no block with
|
||||
//! a high enough timestamp. Also return the block hash as an optional
|
||||
//! output parameter (to avoid the cost of a second lookup in case this
|
||||
//! information is needed.)
|
||||
virtual Optional<int> findFirstBlockWithTime(int64_t time, uint256* hash) = 0;
|
||||
|
||||
//! Return height of the first block in the chain with timestamp equal
|
||||
//! or greater than the given time and height equal or greater than the
|
||||
//! given height, or nullopt if there is no such block.
|
||||
//!
|
||||
//! Calling this with height 0 is equivalent to calling
|
||||
//! findFirstBlockWithTime, but less efficient because it requires a
|
||||
//! linear instead of a binary search.
|
||||
virtual Optional<int> findFirstBlockWithTimeAndHeight(int64_t time, int height) = 0;
|
||||
//! given height, or nullopt if there is no block with a high enough
|
||||
//! timestamp and height. Also return the block hash as an optional output parameter
|
||||
//! (to avoid the cost of a second lookup in case this information is needed.)
|
||||
virtual Optional<int> findFirstBlockWithTimeAndHeight(int64_t time, int height, uint256* hash) = 0;
|
||||
|
||||
//! Return height of last block in the specified range which is pruned, or
|
||||
//! nullopt if no block in the range is pruned. Range is inclusive.
|
||||
|
@ -1206,7 +1206,7 @@ static UniValue pruneblockchain(const JSONRPCRequest& request)
|
||||
// too low to be a block time (corresponds to timestamp from Sep 2001).
|
||||
if (heightParam > 1000000000) {
|
||||
// Add a 2 hour buffer to include blocks which might have had old timestamps
|
||||
CBlockIndex* pindex = ::ChainActive().FindEarliestAtLeast(heightParam - TIMESTAMP_WINDOW);
|
||||
CBlockIndex* pindex = ::ChainActive().FindEarliestAtLeast(heightParam - TIMESTAMP_WINDOW, 0);
|
||||
if (!pindex) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Could not find block with at least the specified timestamp.");
|
||||
}
|
||||
|
@ -532,33 +532,44 @@ static UniValue decoderawtransaction(const JSONRPCRequest& request)
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::string GetAllOutputTypes()
|
||||
{
|
||||
std::string ret;
|
||||
for (int i = TX_NONSTANDARD; i <= TX_NULL_DATA; ++i) {
|
||||
if (i != TX_NONSTANDARD) ret += ", ";
|
||||
ret += GetTxnOutputType(static_cast<txnouttype>(i));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UniValue decodescript(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() != 1)
|
||||
throw std::runtime_error(
|
||||
RPCHelpMan{"decodescript",
|
||||
const RPCHelpMan help{"decodescript",
|
||||
"\nDecode a hex-encoded script.\n",
|
||||
{
|
||||
{"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded script"},
|
||||
},
|
||||
RPCResult{
|
||||
"{\n"
|
||||
" \"asm\":\"asm\", (string) Script public key\n"
|
||||
" \"hex\":\"hex\", (string) hex-encoded public key\n"
|
||||
" \"type\":\"type\", (string) The output type\n"
|
||||
" \"reqSigs\": n, (numeric) The required signatures\n"
|
||||
" \"addresses\": [ (json array of string)\n"
|
||||
" \"address\" (string) dash address\n"
|
||||
" \"asm\":\"asm\", (string) Script public key\n"
|
||||
" \"type\":\"type\", (string) The output type (e.g. "+GetAllOutputTypes()+")\n"
|
||||
" \"reqSigs\": n, (numeric) The required signatures\n"
|
||||
" \"addresses\": [ (json array of string)\n"
|
||||
" \"address\" (string) dash address\n"
|
||||
" ,...\n"
|
||||
" ],\n"
|
||||
" \"p2sh\",\"address\" (string) address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH).\n"
|
||||
" \"p2sh\":\"str\" (string) address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH).\n"
|
||||
"}\n"
|
||||
},
|
||||
RPCExamples{
|
||||
HelpExampleCli("decodescript", "\"hexstring\"")
|
||||
+ HelpExampleRpc("decodescript", "\"hexstring\"")
|
||||
},
|
||||
}.ToString());
|
||||
};
|
||||
|
||||
if (request.fHelp || !help.IsValidNumArgs(request.params.size())) {
|
||||
throw std::runtime_error(help.ToString());
|
||||
}
|
||||
|
||||
RPCTypeCheck(request.params, {UniValue::VSTR});
|
||||
|
||||
@ -570,7 +581,7 @@ static UniValue decodescript(const JSONRPCRequest& request)
|
||||
} else {
|
||||
// Empty scripts are valid
|
||||
}
|
||||
ScriptPubKeyToUniv(script, r, false);
|
||||
ScriptPubKeyToUniv(script, r, /* fIncludeHex */ false);
|
||||
|
||||
UniValue type;
|
||||
|
||||
|
@ -35,6 +35,35 @@ static bool ExecuteCommand(const CRPCCommand& command, const JSONRPCRequest& req
|
||||
// Any commands submitted by this user will have their commands filtered based on the mapPlatformRestrictions
|
||||
static const std::string defaultPlatformUser = "platform-user";
|
||||
|
||||
struct RPCCommandExecutionInfo
|
||||
{
|
||||
std::string method;
|
||||
int64_t start;
|
||||
};
|
||||
|
||||
struct RPCServerInfo
|
||||
{
|
||||
Mutex mutex;
|
||||
std::list<RPCCommandExecutionInfo> active_commands GUARDED_BY(mutex);
|
||||
};
|
||||
|
||||
static RPCServerInfo g_rpc_server_info;
|
||||
|
||||
struct RPCCommandExecution
|
||||
{
|
||||
std::list<RPCCommandExecutionInfo>::iterator it;
|
||||
explicit RPCCommandExecution(const std::string& method)
|
||||
{
|
||||
LOCK(g_rpc_server_info.mutex);
|
||||
it = g_rpc_server_info.active_commands.insert(g_rpc_server_info.active_commands.cend(), {method, GetTimeMicros()});
|
||||
}
|
||||
~RPCCommandExecution()
|
||||
{
|
||||
LOCK(g_rpc_server_info.mutex);
|
||||
g_rpc_server_info.active_commands.erase(it);
|
||||
}
|
||||
};
|
||||
|
||||
static struct CRPCSignals
|
||||
{
|
||||
boost::signals2::signal<void ()> Started;
|
||||
@ -191,11 +220,40 @@ static UniValue uptime(const JSONRPCRequest& jsonRequest)
|
||||
return GetTime() - GetStartupTime();
|
||||
}
|
||||
|
||||
static UniValue getrpcinfo(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() > 0) {
|
||||
throw std::runtime_error(
|
||||
RPCHelpMan{"getrpcinfo",
|
||||
"\nReturns details of the RPC server.\n",
|
||||
{},
|
||||
RPCResults{},
|
||||
RPCExamples{""},
|
||||
}.ToString()
|
||||
);
|
||||
}
|
||||
|
||||
LOCK(g_rpc_server_info.mutex);
|
||||
UniValue active_commands(UniValue::VARR);
|
||||
for (const RPCCommandExecutionInfo& info : g_rpc_server_info.active_commands) {
|
||||
UniValue entry(UniValue::VOBJ);
|
||||
entry.pushKV("method", info.method);
|
||||
entry.pushKV("duration", GetTimeMicros() - info.start);
|
||||
active_commands.push_back(entry);
|
||||
}
|
||||
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.pushKV("active_commands", active_commands);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
static const CRPCCommand vRPCCommands[] =
|
||||
{ // category name actor (function) argNames
|
||||
// --------------------- ------------------------ ----------------------- ----------
|
||||
/* Overall control/query calls */
|
||||
{ "control", "getrpcinfo", &getrpcinfo, {} },
|
||||
{ "control", "help", &help, {"command","subcommand"} },
|
||||
{ "control", "stop", &stop, {"wait"} },
|
||||
{ "control", "uptime", &uptime, {} },
|
||||
@ -495,6 +553,7 @@ static bool ExecuteCommand(const CRPCCommand& command, const JSONRPCRequest& req
|
||||
|
||||
try
|
||||
{
|
||||
RPCCommandExecution execution(request.strMethod);
|
||||
// Execute, convert arguments to array if necessary
|
||||
if (request.params.isObject()) {
|
||||
return command.actor(transformNamedArguments(request, command.argNames), result, last_handler);
|
||||
|
@ -135,7 +135,7 @@ BOOST_AUTO_TEST_CASE(findearliestatleast_test)
|
||||
// Pick a random element in vBlocksMain.
|
||||
int r = InsecureRandRange(vBlocksMain.size());
|
||||
int64_t test_time = vBlocksMain[r].nTime;
|
||||
CBlockIndex *ret = chain.FindEarliestAtLeast(test_time);
|
||||
CBlockIndex* ret = chain.FindEarliestAtLeast(test_time, 0);
|
||||
BOOST_CHECK(ret->nTimeMax >= test_time);
|
||||
BOOST_CHECK((ret->pprev==nullptr) || ret->pprev->nTimeMax < test_time);
|
||||
BOOST_CHECK(vBlocksMain[r].GetAncestor(ret->nHeight) == ret);
|
||||
@ -157,22 +157,34 @@ BOOST_AUTO_TEST_CASE(findearliestatleast_edge_test)
|
||||
CChain chain;
|
||||
chain.SetTip(&blocks.back());
|
||||
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(50)->nHeight, 0);
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(100)->nHeight, 0);
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(150)->nHeight, 3);
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(200)->nHeight, 3);
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(250)->nHeight, 6);
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(300)->nHeight, 6);
|
||||
BOOST_CHECK(!chain.FindEarliestAtLeast(350));
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(50, 0)->nHeight, 0);
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(100, 0)->nHeight, 0);
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(150, 0)->nHeight, 3);
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(200, 0)->nHeight, 3);
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(250, 0)->nHeight, 6);
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(300, 0)->nHeight, 6);
|
||||
BOOST_CHECK(!chain.FindEarliestAtLeast(350, 0));
|
||||
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(0)->nHeight, 0);
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(-1)->nHeight, 0);
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(0, 0)->nHeight, 0);
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(-1, 0)->nHeight, 0);
|
||||
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(std::numeric_limits<int64_t>::min())->nHeight, 0);
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(-int64_t(std::numeric_limits<unsigned int>::max()) - 1)->nHeight, 0);
|
||||
BOOST_CHECK(!chain.FindEarliestAtLeast(std::numeric_limits<int64_t>::max()));
|
||||
BOOST_CHECK(!chain.FindEarliestAtLeast(std::numeric_limits<unsigned int>::max()));
|
||||
BOOST_CHECK(!chain.FindEarliestAtLeast(int64_t(std::numeric_limits<unsigned int>::max()) + 1));
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(std::numeric_limits<int64_t>::min(), 0)->nHeight, 0);
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(-int64_t(std::numeric_limits<unsigned int>::max()) - 1, 0)->nHeight, 0);
|
||||
BOOST_CHECK(!chain.FindEarliestAtLeast(std::numeric_limits<int64_t>::max(), 0));
|
||||
BOOST_CHECK(!chain.FindEarliestAtLeast(std::numeric_limits<unsigned int>::max(), 0));
|
||||
BOOST_CHECK(!chain.FindEarliestAtLeast(int64_t(std::numeric_limits<unsigned int>::max()) + 1, 0));
|
||||
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(0, -1)->nHeight, 0);
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(0, 0)->nHeight, 0);
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(0, 3)->nHeight, 3);
|
||||
BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(0, 8)->nHeight, 8);
|
||||
BOOST_CHECK(!chain.FindEarliestAtLeast(0, 9));
|
||||
|
||||
CBlockIndex* ret1 = chain.FindEarliestAtLeast(100, 2);
|
||||
BOOST_CHECK(ret1->nTimeMax >= 100 && ret1->nHeight == 2);
|
||||
BOOST_CHECK(!chain.FindEarliestAtLeast(300, 9));
|
||||
CBlockIndex* ret2 = chain.FindEarliestAtLeast(200, 4);
|
||||
BOOST_CHECK(ret2->nTimeMax >= 200 && ret2->nHeight == 4);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
@ -49,6 +49,8 @@ public:
|
||||
bool m_avoid_partial_spends;
|
||||
//! Fee estimation mode to control arguments to estimateSmartFee
|
||||
FeeEstimateMode m_fee_mode;
|
||||
//! Minimum chain depth value for coin availability
|
||||
int m_min_depth{0};
|
||||
//! Controls which types of coins are allowed to be used (default: ALL_COINS)
|
||||
CoinType nCoinType;
|
||||
|
||||
|
@ -2205,7 +2205,7 @@ int64_t CWallet::RescanFromTime(int64_t startTime, const WalletRescanReserver& r
|
||||
uint256 start_block;
|
||||
{
|
||||
auto locked_chain = chain().lock();
|
||||
const Optional<int> start_height = locked_chain->findFirstBlockWithTime(startTime - TIMESTAMP_WINDOW, &start_block);
|
||||
const Optional<int> start_height = locked_chain->findFirstBlockWithTimeAndHeight(startTime - TIMESTAMP_WINDOW, 0, &start_block);
|
||||
const Optional<int> tip_height = locked_chain->getHeight();
|
||||
WalletLogPrintf("%s: Rescanning last %i blocks\n", __func__, tip_height && start_height ? *tip_height - *start_height + 1 : 0);
|
||||
}
|
||||
@ -3579,7 +3579,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
|
||||
{
|
||||
CAmount nAmountAvailable{0};
|
||||
std::vector<COutput> vAvailableCoins;
|
||||
AvailableCoins(*locked_chain, vAvailableCoins, true, &coin_control);
|
||||
AvailableCoins(*locked_chain, vAvailableCoins, true, &coin_control, 1, MAX_MONEY, MAX_MONEY, 0, coin_control.m_min_depth);
|
||||
CoinSelectionParams coin_selection_params; // Parameters for coin selection, init with dummy
|
||||
coin_selection_params.use_bnb = false; // never use BnB
|
||||
|
||||
@ -5223,7 +5223,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
||||
// unless a full rescan was requested
|
||||
if (gArgs.GetArg("-rescan", 0) != 2) {
|
||||
if (walletInstance->nTimeFirstKey) {
|
||||
if (Optional<int> first_block = locked_chain->findFirstBlockWithTimeAndHeight(walletInstance->nTimeFirstKey - TIMESTAMP_WINDOW, rescan_height)) {
|
||||
if (Optional<int> first_block = locked_chain->findFirstBlockWithTimeAndHeight(walletInstance->nTimeFirstKey - TIMESTAMP_WINDOW, rescan_height, nullptr)) {
|
||||
rescan_height = *first_block;
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
"""Test dashd shutdown."""
|
||||
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import assert_equal, get_rpc_proxy
|
||||
from test_framework.util import assert_equal, get_rpc_proxy, wait_until
|
||||
from threading import Thread
|
||||
|
||||
def test_long_call(node):
|
||||
@ -20,8 +20,14 @@ class ShutdownTest(BitcoinTestFramework):
|
||||
|
||||
def run_test(self):
|
||||
node = get_rpc_proxy(self.nodes[0].url, 1, timeout=600, coveragedir=self.nodes[0].coverage_dir)
|
||||
# Force connection establishment by executing a dummy command.
|
||||
node.getblockcount()
|
||||
Thread(target=test_long_call, args=(node,)).start()
|
||||
# wait 1 second to ensure event loop waits for current connections to close
|
||||
# Wait until the server is executing the above `waitfornewblock`.
|
||||
wait_until(lambda: len(self.nodes[0].getrpcinfo()['active_commands']) == 2)
|
||||
# Wait 1 second after requesting shutdown but not before the `stop` call
|
||||
# finishes. This is to ensure event loop waits for current connections
|
||||
# to close.
|
||||
self.stop_node(0, wait=1000)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
from test_framework.authproxy import JSONRPCException
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import assert_equal
|
||||
from test_framework.util import assert_equal, assert_greater_than_or_equal
|
||||
|
||||
def expect_http_status(expected_http_status, expected_rpc_code,
|
||||
fcn, *args):
|
||||
@ -22,6 +22,16 @@ class RPCInterfaceTest(BitcoinTestFramework):
|
||||
self.num_nodes = 1
|
||||
self.setup_clean_chain = True
|
||||
|
||||
def test_getrpcinfo(self):
|
||||
self.log.info("Testing getrpcinfo...")
|
||||
|
||||
info = self.nodes[0].getrpcinfo()
|
||||
assert_equal(len(info['active_commands']), 1)
|
||||
|
||||
command = info['active_commands'][0]
|
||||
assert_equal(command['method'], 'getrpcinfo')
|
||||
assert_greater_than_or_equal(command['duration'], 0)
|
||||
|
||||
def test_batch_request(self):
|
||||
self.log.info("Testing basic JSON-RPC batch request...")
|
||||
|
||||
@ -55,6 +65,7 @@ class RPCInterfaceTest(BitcoinTestFramework):
|
||||
expect_http_status(500, -8, self.nodes[0].getblockhash, 42)
|
||||
|
||||
def run_test(self):
|
||||
self.test_getrpcinfo()
|
||||
self.test_batch_request()
|
||||
self.test_http_status_codes()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user