Skip to content

Commit 63d0b93

Browse files
committed
Merge bitcoin/bitcoin#29845: rpc: return warnings as an array instead of just a single one
42fb531 rpc: return warnings as an array instead of just a single one (stickies-v) Pull request description: The RPC documentation for `getblockchaininfo`, `getmininginfo` and `getnetworkinfo` states that "warnings" returns "any network and blockchain warnings". In practice, only a single warning (i.e. the latest one that is set) is returned, the other ones are ignored. Fix that by returning all warnings as an array. As a side benefit, clean up the GetWarnings() logic. Since this PR changes the RPC result schema, I've added release notes. Users can temporarily revert to the old results by using `-deprecatedrpc=warnings`, until it's removed in a future version. --- Some historical context from git log: - when `GetWarnings` was introduced in 4019262, it was used in the `getinfo` RPC, where only a [single error/warning was returned](bitcoin/bitcoin@4019262#diff-7442c48d42cd5455a79915a0f00cce5e13359db46437a32b812876edb0a5ccddR250) (similar to how it is now). - later on, "warnings" RPC response fields were introduced, e.g. in ef2a3de, with the description [stating](bitcoin/bitcoin@ef2a3de#diff-1021bd3c74415ad9719bd764ad6ca35af5dfb33b1cd863c0be49bdf52518af54R411) that it returned "any network warnings" but in practice still only a single warning was returned ACKs for top commit: achow101: re-ACK 42fb531 tdb3: Re ACK for 42fb531 TheCharlatan: ACK 42fb531 maflcko: ACK 42fb531 🔺 Tree-SHA512: 4225ed8979cd5f030dec785a80e7452a041ad5703445da79d2906ada983ed0bbe7b15889d663d75aae4a77d92e302c93e93eca185c7bd47c9cce29e12f752bd3
2 parents fdb41e0 + 42fb531 commit 63d0b93

File tree

10 files changed

+71
-37
lines changed

10 files changed

+71
-37
lines changed

doc/release-notes-29845.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
RPC
2+
---
3+
4+
- the `warnings` field in `getblockchaininfo`, `getmininginfo` and
5+
`getnetworkinfo` now returns all the active node warnings as an array
6+
of strings, instead of just a single warning. The current behaviour
7+
can temporarily be restored by running bitcoind with configuration
8+
option `-deprecatedrpc=warnings`.

src/node/interfaces.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include <util/check.h>
4848
#include <util/result.h>
4949
#include <util/signalinterrupt.h>
50+
#include <util/string.h>
5051
#include <util/translation.h>
5152
#include <validation.h>
5253
#include <validationinterface.h>
@@ -91,7 +92,7 @@ class NodeImpl : public Node
9192
explicit NodeImpl(NodeContext& context) { setContext(&context); }
9293
void initLogging() override { InitLogging(args()); }
9394
void initParameterInteraction() override { InitParameterInteraction(args()); }
94-
bilingual_str getWarnings() override { return GetWarnings(true); }
95+
bilingual_str getWarnings() override { return Join(GetWarnings(), Untranslated("<hr />")); }
9596
int getExitStatus() override { return Assert(m_context)->exit_status.load(); }
9697
uint32_t getLogCategories() override { return LogInstance().GetCategoryMask(); }
9798
bool baseInitialize() override

src/rpc/blockchain.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
#include <validation.h>
4848
#include <validationinterface.h>
4949
#include <versionbits.h>
50-
#include <warnings.h>
5150

5251
#include <stdint.h>
5352

@@ -1260,7 +1259,14 @@ RPCHelpMan getblockchaininfo()
12601259
{RPCResult::Type::NUM, "pruneheight", /*optional=*/true, "height of the last block pruned, plus one (only present if pruning is enabled)"},
12611260
{RPCResult::Type::BOOL, "automatic_pruning", /*optional=*/true, "whether automatic pruning is enabled (only present if pruning is enabled)"},
12621261
{RPCResult::Type::NUM, "prune_target_size", /*optional=*/true, "the target size used by pruning (only present if automatic pruning is enabled)"},
1263-
{RPCResult::Type::STR, "warnings", "any network and blockchain warnings"},
1262+
(IsDeprecatedRPCEnabled("warnings") ?
1263+
RPCResult{RPCResult::Type::STR, "warnings", "any network and blockchain warnings (DEPRECATED)"} :
1264+
RPCResult{RPCResult::Type::ARR, "warnings", "any network and blockchain warnings (run with `-deprecatedrpc=warnings` to return the latest warning as a single string)",
1265+
{
1266+
{RPCResult::Type::STR, "", "warning"},
1267+
}
1268+
}
1269+
),
12641270
}},
12651271
RPCExamples{
12661272
HelpExampleCli("getblockchaininfo", "")
@@ -1298,7 +1304,7 @@ RPCHelpMan getblockchaininfo()
12981304
}
12991305
}
13001306

1301-
obj.pushKV("warnings", GetWarnings(false).original);
1307+
obj.pushKV("warnings", GetNodeWarnings(IsDeprecatedRPCEnabled("warnings")));
13021308
return obj;
13031309
},
13041310
};

src/rpc/mining.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
#include <util/translation.h>
4040
#include <validation.h>
4141
#include <validationinterface.h>
42-
#include <warnings.h>
4342

4443
#include <memory>
4544
#include <stdint.h>
@@ -426,7 +425,14 @@ static RPCHelpMan getmininginfo()
426425
{RPCResult::Type::NUM, "networkhashps", "The network hashes per second"},
427426
{RPCResult::Type::NUM, "pooledtx", "The size of the mempool"},
428427
{RPCResult::Type::STR, "chain", "current network name (main, test, signet, regtest)"},
429-
{RPCResult::Type::STR, "warnings", "any network and blockchain warnings"},
428+
(IsDeprecatedRPCEnabled("warnings") ?
429+
RPCResult{RPCResult::Type::STR, "warnings", "any network and blockchain warnings (DEPRECATED)"} :
430+
RPCResult{RPCResult::Type::ARR, "warnings", "any network and blockchain warnings (run with `-deprecatedrpc=warnings` to return the latest warning as a single string)",
431+
{
432+
{RPCResult::Type::STR, "", "warning"},
433+
}
434+
}
435+
),
430436
}},
431437
RPCExamples{
432438
HelpExampleCli("getmininginfo", "")
@@ -448,7 +454,7 @@ static RPCHelpMan getmininginfo()
448454
obj.pushKV("networkhashps", getnetworkhashps().HandleRequest(request));
449455
obj.pushKV("pooledtx", (uint64_t)mempool.size());
450456
obj.pushKV("chain", chainman.GetParams().GetChainTypeString());
451-
obj.pushKV("warnings", GetWarnings(false).original);
457+
obj.pushKV("warnings", GetNodeWarnings(IsDeprecatedRPCEnabled("warnings")));
452458
return obj;
453459
},
454460
};

src/rpc/net.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
#include <util/time.h>
3030
#include <util/translation.h>
3131
#include <validation.h>
32-
#include <warnings.h>
3332

3433
#include <optional>
3534

@@ -657,7 +656,14 @@ static RPCHelpMan getnetworkinfo()
657656
{RPCResult::Type::NUM, "score", "relative score"},
658657
}},
659658
}},
660-
{RPCResult::Type::STR, "warnings", "any network and blockchain warnings"},
659+
(IsDeprecatedRPCEnabled("warnings") ?
660+
RPCResult{RPCResult::Type::STR, "warnings", "any network and blockchain warnings (DEPRECATED)"} :
661+
RPCResult{RPCResult::Type::ARR, "warnings", "any network and blockchain warnings (run with `-deprecatedrpc=warnings` to return the latest warning as a single string)",
662+
{
663+
{RPCResult::Type::STR, "", "warning"},
664+
}
665+
}
666+
),
661667
}
662668
},
663669
RPCExamples{
@@ -707,7 +713,7 @@ static RPCHelpMan getnetworkinfo()
707713
}
708714
}
709715
obj.pushKV("localaddresses", localAddresses);
710-
obj.pushKV("warnings", GetWarnings(false).original);
716+
obj.pushKV("warnings", GetNodeWarnings(IsDeprecatedRPCEnabled("warnings")));
711717
return obj;
712718
},
713719
};

src/rpc/util.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,19 @@
1818
#include <script/signingprovider.h>
1919
#include <script/solver.h>
2020
#include <tinyformat.h>
21+
#include <univalue.h>
2122
#include <util/check.h>
2223
#include <util/result.h>
2324
#include <util/strencodings.h>
2425
#include <util/string.h>
2526
#include <util/translation.h>
27+
#include <warnings.h>
2628

2729
#include <algorithm>
2830
#include <iterator>
2931
#include <string_view>
3032
#include <tuple>
33+
#include <utility>
3134

3235
const std::string UNIX_EPOCH_TIME = "UNIX epoch time";
3336
const std::string EXAMPLE_ADDRESS[2] = {"bc1q09vm5lfy0j5reeulh4x5752q25uqqvz34hufdl", "bc1q02ad21edsxd23d32dfgqqsz4vv4nmtfzuklhy3"};
@@ -1357,3 +1360,17 @@ void PushWarnings(const std::vector<bilingual_str>& warnings, UniValue& obj)
13571360
if (warnings.empty()) return;
13581361
obj.pushKV("warnings", BilingualStringsToUniValue(warnings));
13591362
}
1363+
1364+
UniValue GetNodeWarnings(bool use_deprecated)
1365+
{
1366+
if (use_deprecated) {
1367+
const auto all_warnings{GetWarnings()};
1368+
return all_warnings.empty() ? "" : all_warnings.back().original;
1369+
}
1370+
1371+
UniValue warnings{UniValue::VARR};
1372+
for (auto&& warning : GetWarnings()) {
1373+
warnings.push_back(std::move(warning.original));
1374+
}
1375+
return warnings;
1376+
}

src/rpc/util.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,4 +513,6 @@ class RPCHelpMan
513513
void PushWarnings(const UniValue& warnings, UniValue& obj);
514514
void PushWarnings(const std::vector<bilingual_str>& warnings, UniValue& obj);
515515

516+
UniValue GetNodeWarnings(bool use_deprecated);
517+
516518
#endif // BITCOIN_RPC_UTIL_H

src/warnings.cpp

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
#include <common/system.h>
1313
#include <sync.h>
14-
#include <util/string.h>
1514
#include <util/translation.h>
1615

1716
#include <optional>
@@ -39,37 +38,30 @@ void SetMedianTimeOffsetWarning(std::optional<bilingual_str> warning)
3938
LOCK(g_warnings_mutex);
4039
g_timeoffset_warning = warning;
4140
}
42-
bilingual_str GetWarnings(bool verbose)
41+
42+
std::vector<bilingual_str> GetWarnings()
4343
{
44-
bilingual_str warnings_concise;
45-
std::vector<bilingual_str> warnings_verbose;
44+
std::vector<bilingual_str> warnings;
4645

4746
LOCK(g_warnings_mutex);
4847

4948
// Pre-release build warning
5049
if (!CLIENT_VERSION_IS_RELEASE) {
51-
warnings_concise = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications");
52-
warnings_verbose.emplace_back(warnings_concise);
50+
warnings.emplace_back(_("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications"));
5351
}
5452

5553
// Misc warnings like out of disk space and clock is wrong
5654
if (!g_misc_warnings.empty()) {
57-
warnings_concise = g_misc_warnings;
58-
warnings_verbose.emplace_back(warnings_concise);
55+
warnings.emplace_back(g_misc_warnings);
5956
}
6057

6158
if (fLargeWorkInvalidChainFound) {
62-
warnings_concise = _("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.");
63-
warnings_verbose.emplace_back(warnings_concise);
59+
warnings.emplace_back(_("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."));
6460
}
6561

6662
if (g_timeoffset_warning) {
67-
warnings_verbose.emplace_back(g_timeoffset_warning.value());
68-
}
69-
70-
if (verbose) {
71-
return Join(warnings_verbose, Untranslated("<hr />"));
63+
warnings.emplace_back(g_timeoffset_warning.value());
7264
}
7365

74-
return warnings_concise;
66+
return warnings;
7567
}

src/warnings.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,15 @@
88

99
#include <optional>
1010
#include <string>
11+
#include <vector>
1112

1213
struct bilingual_str;
1314

1415
void SetMiscWarning(const bilingual_str& warning);
1516
void SetfLargeWorkInvalidChainFound(bool flag);
1617
/** Pass std::nullopt to disable the warning */
1718
void SetMedianTimeOffsetWarning(std::optional<bilingual_str> warning);
18-
/** Format a string that describes several potential problems detected by the core.
19-
* @param[in] verbose bool
20-
* - if true, get all warnings separated by <hr />
21-
* - if false, get the most important warning
22-
* @returns the warning string
23-
*/
24-
bilingual_str GetWarnings(bool verbose);
19+
/** Return potential problems detected by the node. */
20+
std::vector<bilingual_str> GetWarnings();
2521

2622
#endif // BITCOIN_WARNINGS_H

test/functional/feature_versionbits_warning.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ def run_test(self):
7373
self.generatetoaddress(node, VB_PERIOD - VB_THRESHOLD + 1, node_deterministic_address)
7474

7575
# Check that we're not getting any versionbit-related errors in get*info()
76-
assert not VB_PATTERN.match(node.getmininginfo()["warnings"])
77-
assert not VB_PATTERN.match(node.getnetworkinfo()["warnings"])
76+
assert not VB_PATTERN.match(",".join(node.getmininginfo()["warnings"]))
77+
assert not VB_PATTERN.match(",".join(node.getnetworkinfo()["warnings"]))
7878

7979
# Build one period of blocks with VB_THRESHOLD blocks signaling some unknown bit
8080
self.send_blocks_with_version(peer, VB_THRESHOLD, VB_UNKNOWN_VERSION)
@@ -94,8 +94,8 @@ def run_test(self):
9494
# Generating one more block will be enough to generate an error.
9595
self.generatetoaddress(node, 1, node_deterministic_address)
9696
# Check that get*info() shows the versionbits unknown rules warning
97-
assert WARN_UNKNOWN_RULES_ACTIVE in node.getmininginfo()["warnings"]
98-
assert WARN_UNKNOWN_RULES_ACTIVE in node.getnetworkinfo()["warnings"]
97+
assert WARN_UNKNOWN_RULES_ACTIVE in ",".join(node.getmininginfo()["warnings"])
98+
assert WARN_UNKNOWN_RULES_ACTIVE in ",".join(node.getnetworkinfo()["warnings"])
9999
# Check that the alert file shows the versionbits unknown rules warning
100100
self.wait_until(lambda: self.versionbits_in_alert_file())
101101

0 commit comments

Comments
 (0)