Skip to content

Commit 13397dc

Browse files
author
MarcoFalke
committed
Merge #19056: rpc: Make gettxoutsetinfo/GetUTXOStats interruptible
fa75692 rpc: Make gettxoutsetinfo/GetUTXOStats interruptible (MarcoFalke) fa7fc5a rpc: factor out RpcInterruptionPoint from dumptxoutset (MarcoFalke) Pull request description: Make it interruptible, so that shutdown doesn't block for up to one hour. Fixes (partially) #13217 ACKs for top commit: Empact: Code Review ACK bitcoin/bitcoin@fa75692 laanwj: Code review ACK fa75692 Tree-SHA512: 298261e0ff7d79fab542b8f6828cc0ac451cbafe396d5f0816c9d36437faba1330f5c4cb2a25c5540e202bfb9783da6ec858bd453056ce488d21e36335d3d42c
2 parents d3b0ef8 + fa75692 commit 13397dc

File tree

5 files changed

+18
-9
lines changed

5 files changed

+18
-9
lines changed

src/node/coinstats.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ static void ApplyStats(CCoinsStats &stats, CHashWriter& ss, const uint256& hash,
3333
}
3434

3535
//! Calculate statistics about the unspent transaction output set
36-
bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats)
36+
bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, const std::function<void()>& interruption_point)
3737
{
3838
stats = CCoinsStats();
3939
std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor());
@@ -49,6 +49,7 @@ bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats)
4949
uint256 prevkey;
5050
std::map<uint32_t, Coin> outputs;
5151
while (pcursor->Valid()) {
52+
interruption_point();
5253
COutPoint key;
5354
Coin coin;
5455
if (pcursor->GetKey(key) && pcursor->GetValue(coin)) {

src/node/coinstats.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <uint256.h>
1111

1212
#include <cstdint>
13+
#include <functional>
1314

1415
class CCoinsView;
1516

@@ -29,6 +30,6 @@ struct CCoinsStats
2930
};
3031

3132
//! Calculate statistics about the unspent transaction output set
32-
bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats);
33+
bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, const std::function<void()>& interruption_point = {});
3334

3435
#endif // BITCOIN_NODE_COINSTATS_H

src/rpc/blockchain.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,7 @@ static UniValue gettxoutsetinfo(const JSONRPCRequest& request)
996996
::ChainstateActive().ForceFlushStateToDisk();
997997

998998
CCoinsView* coins_view = WITH_LOCK(cs_main, return &ChainstateActive().CoinsDB());
999-
if (GetUTXOStats(coins_view, stats)) {
999+
if (GetUTXOStats(coins_view, stats, RpcInterruptionPoint)) {
10001000
ret.pushKV("height", (int64_t)stats.nHeight);
10011001
ret.pushKV("bestblock", stats.hashBlock.GetHex());
10021002
ret.pushKV("transactions", (int64_t)stats.nTransactions);
@@ -1974,6 +1974,7 @@ bool FindScriptPubKey(std::atomic<int>& scan_progress, const std::atomic<bool>&
19741974
Coin coin;
19751975
if (!cursor->GetKey(key) || !cursor->GetValue(coin)) return false;
19761976
if (++count % 8192 == 0) {
1977+
RpcInterruptionPoint();
19771978
if (should_abort) {
19781979
// allow to abort the scan via the abort reference
19791980
return false;
@@ -2317,7 +2318,7 @@ UniValue dumptxoutset(const JSONRPCRequest& request)
23172318

23182319
::ChainstateActive().ForceFlushStateToDisk();
23192320

2320-
if (!GetUTXOStats(&::ChainstateActive().CoinsDB(), stats)) {
2321+
if (!GetUTXOStats(&::ChainstateActive().CoinsDB(), stats, RpcInterruptionPoint)) {
23212322
throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
23222323
}
23232324

@@ -2335,9 +2336,7 @@ UniValue dumptxoutset(const JSONRPCRequest& request)
23352336
unsigned int iter{0};
23362337

23372338
while (pcursor->Valid()) {
2338-
if (iter % 5000 == 0 && !IsRPCRunning()) {
2339-
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down");
2340-
}
2339+
if (iter % 5000 == 0) RpcInterruptionPoint();
23412340
++iter;
23422341
if (pcursor->GetKey(key) && pcursor->GetValue(coin)) {
23432342
afile << key;

src/rpc/server.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
#include <util/strencodings.h>
1212
#include <util/system.h>
1313

14-
#include <boost/signals2/signal.hpp>
1514
#include <boost/algorithm/string/classification.hpp>
1615
#include <boost/algorithm/string/split.hpp>
16+
#include <boost/signals2/signal.hpp>
1717

1818
#include <memory> // for unique_ptr
1919
#include <unordered_map>
@@ -309,6 +309,11 @@ bool IsRPCRunning()
309309
return g_rpc_running;
310310
}
311311

312+
void RpcInterruptionPoint()
313+
{
314+
if (!IsRPCRunning()) throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down");
315+
}
316+
312317
void SetRPCWarmupStatus(const std::string& newStatus)
313318
{
314319
LOCK(cs_rpcWarmup);

src/rpc/server.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
#include <amount.h>
1010
#include <rpc/request.h>
1111

12+
#include <functional>
1213
#include <map>
1314
#include <stdint.h>
1415
#include <string>
15-
#include <functional>
1616

1717
#include <univalue.h>
1818

@@ -29,6 +29,9 @@ namespace RPCServer
2929
/** Query whether RPC is running */
3030
bool IsRPCRunning();
3131

32+
/** Throw JSONRPCError if RPC is not running */
33+
void RpcInterruptionPoint();
34+
3235
/**
3336
* Set the RPC warmup status. When this is done, all RPC calls will error out
3437
* immediately with RPC_IN_WARMUP.

0 commit comments

Comments
 (0)