Skip to content

Commit 29011d0

Browse files
committed
[avalanche] Add a getflakyproofs RPC to retrieve the list of flaky proofs
Summary: This returns the list of proofs added via the setflakyproof RPC. Depends on D16368. Test Plan: ./test/functional/test_runner.py abc_mining_stakingrewards Reviewers: #bitcoin_abc, PiRK Reviewed By: #bitcoin_abc, PiRK Differential Revision: https://reviews.bitcoinabc.org/D16369
1 parent 40e6953 commit 29011d0

File tree

4 files changed

+132
-1
lines changed

4 files changed

+132
-1
lines changed

doc/release-notes.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ This release includes the following features and fixes:
1010
- The `getstakingreward` RPC now returns the `proofid` of the staking reward
1111
winner in addition to the payout script.
1212
- A new `setflakyproof` RPC instructs the node to also accept an alternative
13-
staking reward winner when the flaky proof would have been selected.
13+
staking reward winner when the flaky proof would have been selected. The list
14+
of these flaky proofs can be retrieved via the `getflakyproofs` RPC.

src/avalanche/peermanager.h

+5
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,11 @@ class PeerManager {
443443

444444
bool setFlaky(const ProofId &proofid);
445445
bool unsetFlaky(const ProofId &proofid);
446+
template <typename Callable> void forEachFlakyProof(Callable &&func) const {
447+
for (const auto &p : manualFlakyProofids) {
448+
func(p);
449+
}
450+
}
446451

447452
template <typename Callable>
448453
void updateAvailabilityScores(const double decayFactor,

src/rpc/avalanche.cpp

+74
Original file line numberDiff line numberDiff line change
@@ -1669,6 +1669,79 @@ static RPCHelpMan setflakyproof() {
16691669
}};
16701670
}
16711671

1672+
static RPCHelpMan getflakyproofs() {
1673+
return RPCHelpMan{
1674+
"getflakyproofs",
1675+
"List the flaky proofs (set via setflakyproof).\n",
1676+
{},
1677+
RPCResult{
1678+
RPCResult::Type::ARR,
1679+
"flaky_proofs",
1680+
"",
1681+
{{
1682+
RPCResult::Type::OBJ,
1683+
"proof",
1684+
"",
1685+
{{
1686+
{RPCResult::Type::STR_HEX, "proofid",
1687+
"The hex encoded proof identifier."},
1688+
{RPCResult::Type::STR_AMOUNT, "staked_amount",
1689+
"The proof stake amount, only present if the proof is "
1690+
"known."},
1691+
{RPCResult::Type::OBJ,
1692+
"payout",
1693+
"The proof payout script, only present if the proof is "
1694+
"known.",
1695+
{
1696+
{RPCResult::Type::STR, "asm", "Decoded payout script"},
1697+
{RPCResult::Type::STR_HEX, "hex",
1698+
"Raw payout script in hex format"},
1699+
{RPCResult::Type::STR, "type",
1700+
"The output type (e.g. " + GetAllOutputTypes() + ")"},
1701+
{RPCResult::Type::NUM, "reqSigs",
1702+
"The required signatures"},
1703+
{RPCResult::Type::ARR,
1704+
"addresses",
1705+
"",
1706+
{
1707+
{RPCResult::Type::STR, "address",
1708+
"eCash address"},
1709+
}},
1710+
}},
1711+
}},
1712+
}},
1713+
},
1714+
RPCExamples{HelpExampleRpc("getflakyproofs", "")},
1715+
[&](const RPCHelpMan &self, const Config &config,
1716+
const JSONRPCRequest &request) -> UniValue {
1717+
NodeContext &node = EnsureAnyNodeContext(request.context);
1718+
avalanche::Processor &avalanche = EnsureAvalanche(node);
1719+
1720+
UniValue flakyProofs(UniValue::VARR);
1721+
avalanche.withPeerManager([&flakyProofs](
1722+
avalanche::PeerManager &pm) {
1723+
pm.forEachFlakyProof([&](const avalanche::ProofId &proofid) {
1724+
UniValue flakyProof(UniValue::VOBJ);
1725+
flakyProof.pushKV("proofid", proofid.GetHex());
1726+
1727+
const auto proof = pm.getProof(proofid);
1728+
if (proof) {
1729+
flakyProof.pushKV("staked_amount",
1730+
proof->getStakedAmount());
1731+
UniValue payout(UniValue::VOBJ);
1732+
ScriptPubKeyToUniv(proof->getPayoutScript(), payout,
1733+
/*fIncludeHex=*/true);
1734+
flakyProof.pushKV("payout", payout);
1735+
}
1736+
1737+
flakyProofs.push_back(flakyProof);
1738+
});
1739+
});
1740+
1741+
return flakyProofs;
1742+
}};
1743+
}
1744+
16721745
void RegisterAvalancheRPCCommands(CRPCTable &t) {
16731746
// clang-format off
16741747
static const CRPCCommand commands[] = {
@@ -1695,6 +1768,7 @@ void RegisterAvalancheRPCCommands(CRPCTable &t) {
16951768
{ "avalanche", verifyavalancheproof, },
16961769
{ "avalanche", verifyavalanchedelegation, },
16971770
{ "avalanche", setflakyproof, },
1771+
{ "avalanche", getflakyproofs, },
16981772
};
16991773
// clang-format on
17001774

test/functional/abc_mining_stakingrewards.py

+51
Original file line numberDiff line numberDiff line change
@@ -328,15 +328,66 @@ def finalize_proof(proofid):
328328

329329
proofids.append(last_proofid)
330330

331+
flaky_proofs = node.getflakyproofs()
332+
assert_equal(len(flaky_proofs), len(proofids))
333+
assert last_proofid in [p["proofid"] for p in flaky_proofs]
334+
331335
for i in range(QUORUM_NODE_COUNT, 1, -1):
332336
reward = node.getstakingreward(tiphash)
333337
assert_equal(len(reward), i)
334338

335339
last_proofid = proofids.pop()
336340
assert node.setflakyproof(last_proofid, False)
337341

342+
flaky_proofs = node.getflakyproofs()
343+
assert_equal(len(flaky_proofs), len(proofids))
344+
assert last_proofid not in [p["proofid"] for p in flaky_proofs]
345+
338346
assert_equal(len(node.getstakingreward(tiphash)), 1)
339347

348+
# Add an unknown proof, check the stake amount and payout are not
349+
# returned but the proofid always is
350+
unknown_proofid = uint256_hex(0)
351+
assert node.setflakyproof(unknown_proofid, True)
352+
flaky_proofs = node.getflakyproofs()
353+
assert_equal(len(flaky_proofs), 1)
354+
flaky_proof = flaky_proofs[0]
355+
assert_equal(
356+
flaky_proof,
357+
{
358+
"proofid": unknown_proofid,
359+
},
360+
)
361+
assert node.setflakyproof(unknown_proofid, False)
362+
assert_equal(node.getflakyproofs(), [])
363+
364+
known_proofid = node.getstakingreward(blockhash=tiphash, recompute=True)[0][
365+
"proofid"
366+
]
367+
assert node.setflakyproof(known_proofid, True)
368+
flaky_proofs = node.getflakyproofs()
369+
assert_equal(len(flaky_proofs), 1)
370+
flaky_proof = flaky_proofs[0]
371+
staked_amount = node.decodeavalancheproof(
372+
node.getrawavalancheproof(known_proofid)["proof"]
373+
)["staked_amount"]
374+
assert_equal(
375+
flaky_proof,
376+
{
377+
"proofid": known_proofid,
378+
"staked_amount": Decimal(staked_amount),
379+
"payout": {
380+
"asm": "OP_DUP OP_HASH160 0000000000000000000000000000000000000000 OP_EQUALVERIFY OP_CHECKSIG",
381+
"hex": "76a914000000000000000000000000000000000000000088ac",
382+
"reqSigs": 1,
383+
"type": "pubkeyhash",
384+
"addresses": [ADDRESS_ECREG_UNSPENDABLE],
385+
},
386+
},
387+
)
388+
assert node.setflakyproof(known_proofid, False)
389+
assert_equal(node.getflakyproofs(), [])
390+
340391

341392
if __name__ == "__main__":
342393
AbcMiningStakingRewardsTest().main()

0 commit comments

Comments
 (0)