Merge bitcoin/bitcoin#25157: Fix -rpcwait with -netinfo returning negative time durations

3a998d2e37bf76667b08cd947807ada1305520d7 Use steady_clock in ConnectAndCallRPC and inline time call in loop conditional (Jon Atack)
3799d2dcdd736dd24850b192e1b264bee1cd5e5a Fix -rpcwait with -netinfo printing negative time durations (Jon Atack)

Pull request description:

  - Fix `bitcoin-cli -rpcwait -netinfo 1` returning negative time durations on its first invocation after node startup in the "send", "recv", and "age" columns (potentially the "txn" and "blk" columns also). To reproduce, start bitcoind on mainnet (for a longer startup time) and run `bitcoin-cli -rpcwait -netinfo <n>` where n is 1 or larger. The negative time durations are larger with a slower CPU speed or e.g. higher `checkblocks`/`checklevel` config option settings.

  Examples:
  ```
  <->   type   net  mping   ping send recv  txn  blk  hb addrp addrl  age id
  out manual onion               -126 -126                             -2  0
                       ms     ms  sec  sec  min  min                  min
  ```

  ```
  <->   type   net  mping   ping send recv  txn  blk  hb addrp addrl  age id
  out manual cjdns                -64  -64                             -1  0
                       ms     ms  sec  sec  min  min                  min
  ```
  ```
  <->   type   net  mping   ping send recv  txn  blk  hb addrp addrl  age id
  out manual  ipv4                -89  -89    *              .         -1  0
                       ms     ms  sec  sec  min  min                  min
  ```
  ```
  <->   type   net  mping   ping send recv  txn  blk  hb addrp addrl  age id
  out manual  ipv6               -133         *              .         -2  0
                       ms     ms  sec  sec  min  min                  min
  ```

  - Use `steady_clock` in ConnectAndCallRPC and inline the time call in the loop conditional to avoid unnecessary invocations and an unneeded local variable allocation.

ACKs for top commit:
  MarcoFalke:
    cr ACK 3a998d2e37bf76667b08cd947807ada1305520d7

Tree-SHA512: 141430d47189ad9f646ce8e51cb31c21b395f6294bb27ba9f7ae4c1e1505a63209a4a19662a0b462806437a9cfd07f1ea114e775adc2872d87397fe823f8b8dc
This commit is contained in:
MacroFake 2022-05-18 16:56:48 +02:00
commit 002411dc53
No known key found for this signature in database
GPG Key ID: CE2B75697E69A548

View File

@ -439,7 +439,6 @@ private:
if (conn_type == "addr-fetch") return "addr";
return "";
}
const int64_t m_time_now{count_seconds(Now<CliSeconds>())};
public:
static constexpr int ID_PEERINFO = 0;
@ -471,6 +470,7 @@ public:
if (networkinfo["version"].get_int() < 209900) {
throw std::runtime_error("-netinfo requires bitcoind server to be running v0.21.0 and up");
}
const int64_t time_now{count_seconds(Now<CliSeconds>())};
// Count peer connection totals, and if DetailsRequested(), store peer data in a vector of structs.
for (const UniValue& peer : batch[ID_PEERINFO]["result"].getValues()) {
@ -501,7 +501,7 @@ public:
const double min_ping{peer["minping"].isNull() ? -1 : peer["minping"].get_real()};
const double ping{peer["pingtime"].isNull() ? -1 : peer["pingtime"].get_real()};
const std::string addr{peer["addr"].get_str()};
const std::string age{conn_time == 0 ? "" : ToString((m_time_now - conn_time) / 60)};
const std::string age{conn_time == 0 ? "" : ToString((time_now - conn_time) / 60)};
const std::string sub_version{peer["subver"].get_str()};
const bool is_addr_relay_enabled{peer["addr_relay_enabled"].isNull() ? false : peer["addr_relay_enabled"].get_bool()};
const bool is_bip152_hb_from{peer["bip152_hb_from"].get_bool()};
@ -537,10 +537,10 @@ public:
peer.network,
PingTimeToString(peer.min_ping),
PingTimeToString(peer.ping),
peer.last_send ? ToString(m_time_now - peer.last_send) : "",
peer.last_recv ? ToString(m_time_now - peer.last_recv) : "",
peer.last_trxn ? ToString((m_time_now - peer.last_trxn) / 60) : peer.is_block_relay ? "*" : "",
peer.last_blck ? ToString((m_time_now - peer.last_blck) / 60) : "",
peer.last_send ? ToString(time_now - peer.last_send) : "",
peer.last_recv ? ToString(time_now - peer.last_recv) : "",
peer.last_trxn ? ToString((time_now - peer.last_trxn) / 60) : peer.is_block_relay ? "*" : "",
peer.last_blck ? ToString((time_now - peer.last_blck) / 60) : "",
strprintf("%s%s", peer.is_bip152_hb_to ? "." : " ", peer.is_bip152_hb_from ? "*" : " "),
m_max_addr_processed_length, // variable spacing
peer.addr_processed ? ToString(peer.addr_processed) : peer.is_addr_relay_enabled ? "" : ".",
@ -844,7 +844,7 @@ static UniValue ConnectAndCallRPC(BaseRequestHandler* rh, const std::string& str
// Execute and handle connection failures with -rpcwait.
const bool fWait = gArgs.GetBoolArg("-rpcwait", false);
const int timeout = gArgs.GetIntArg("-rpcwaittimeout", DEFAULT_WAIT_CLIENT_TIMEOUT);
const auto deadline{GetTime<std::chrono::microseconds>() + 1s * timeout};
const auto deadline{std::chrono::steady_clock::now() + 1s * timeout};
do {
try {
@ -857,8 +857,7 @@ static UniValue ConnectAndCallRPC(BaseRequestHandler* rh, const std::string& str
}
break; // Connection succeeded, no need to retry.
} catch (const CConnectionFailed& e) {
const auto now{GetTime<std::chrono::microseconds>()};
if (fWait && (timeout <= 0 || now < deadline)) {
if (fWait && (timeout <= 0 || std::chrono::steady_clock::now() < deadline)) {
UninterruptibleSleep(1s);
} else {
throw CConnectionFailed(strprintf("timeout on transient error: %s", e.what()));