From d683db372ec7f6c80f1a2abbe07878851b360645 Mon Sep 17 00:00:00 2001 From: rzadp Date: Thu, 7 Sep 2023 21:23:12 +0200 Subject: [PATCH] Find inlined referendum --- dist/index.js | 15 +++++++++------ src/find-referendum.test.ts | 36 +++++++++++++++++++++++++++++++++++- src/find-referendum.ts | 19 +++++++++++++------ 3 files changed, 57 insertions(+), 13 deletions(-) diff --git a/dist/index.js b/dist/index.js index 0538ee1..8adb2da 100644 --- a/dist/index.js +++ b/dist/index.js @@ -67491,7 +67491,7 @@ const api_1 = __nccwpck_require__(47196); const constants_1 = __nccwpck_require__(69042); /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment */ const findReferendum = async (opts) => { - const api = new api_1.ApiPromise({ provider: new api_1.WsProvider(constants_1.PROVIDER_URL) }); + const api = new api_1.ApiPromise({ provider: new api_1.WsProvider(opts.providerUrl ?? constants_1.PROVIDER_URL) }); await api.isReadyOrError; const apiAt = await api.at(opts.blockHash); // The `referendumInfoFor()` function exposes more data at blocks before the referendum got approved. @@ -67501,14 +67501,17 @@ const findReferendum = async (opts) => { if (event.event.section === "fellowshipReferenda" && event.event.method === "Confirmed") { const [referendumIndex] = event.event.data; const info = (await apiAtPrev.query.fellowshipReferenda.referendumInfoFor(referendumIndex)).toJSON(); - // TODO: Handle inlined proposal as well. - // https://github.com/paritytech/rfc-action/issues/12 - const proposalHash = info?.ongoing?.proposal?.lookup?.hash; - if (proposalHash === api.tx.system.remark(opts.parseRFCResult.approveRemarkText).method.hash.toHex()) { + /** + * Checks if the given transaction (expected remark), + * matches what is found in the on-chain referendum we currently iterate over. + */ + const remarkMatchesProposal = (tx) => info?.ongoing?.proposal?.lookup?.hash === tx.method.hash.toHex() || + info?.ongoing?.proposal?.inline === tx.method.toHex(); + if (remarkMatchesProposal(api.tx.system.remark(opts.parseRFCResult.approveRemarkText))) { await api.disconnect(); return { approved: true }; } - if (proposalHash === api.tx.system.remark(opts.parseRFCResult.rejectRemarkText).method.hash.toHex()) { + if (remarkMatchesProposal(api.tx.system.remark(opts.parseRFCResult.rejectRemarkText))) { await api.disconnect(); return { approved: false }; } diff --git a/src/find-referendum.test.ts b/src/find-referendum.test.ts index fc1e105..170aa71 100644 --- a/src/find-referendum.test.ts +++ b/src/find-referendum.test.ts @@ -4,7 +4,7 @@ import { findReferendum } from "./find-referendum"; import { getApproveRemarkText, getRejectRemarkText } from "./parse-RFC"; describe("findReferendum", () => { - test("Finds the 0014 referendum", async () => { + test("Finds the 0014 referendum with a lookup", async () => { // https://collectives.polkassembly.io/member-referenda/16 const rfcNumber = "0014"; const text = fs.readFileSync("src/examples/0014-improve-locking-mechanism-for-parachains.md").toString(); @@ -20,4 +20,38 @@ describe("findReferendum", () => { expect(result && "approved" in result && result.approved).toBeTruthy(); }); + + test.skip("Finds the (inlined) 0014 referendum", async () => { + /** + * This is a semi-manual test. + * It requires you to run a local Kusama node, create a referendum and wait for it to be confirmed. + * Use the following for the inlined remark: + * 0x000049015246435f415050524f564528303031342c6261383431386663343664323531616366646433393630346335666536656133643639656434363465643431313364353065383265613163373132613434666329 + * + * It could be made more automatic similarly to the setup in the tip bot: + * https://github.com/paritytech/substrate-tip-bot/blob/master/README.md#end-to-end-tests + * + * However, once a first inlined RFC referendum ends up on-chain we could use that for testing. + * (because these tests are read-only). + */ + + // The blockhash where the referendum with inlined proposal got confirmed. + const blockHash = "0x???"; + const providerUrl = "ws://localhost:9944"; + + const rfcNumber = "0014"; + const text = fs.readFileSync("src/examples/0014-improve-locking-mechanism-for-parachains.md").toString(); + const result = await findReferendum({ + providerUrl, + blockHash, + parseRFCResult: { + rfcNumber, + rfcFileRawUrl: "", + approveRemarkText: getApproveRemarkText(rfcNumber, text), + rejectRemarkText: getRejectRemarkText(rfcNumber, text), + }, + }); + + expect(result && "approved" in result && result.approved).toBeTruthy(); + }); }); diff --git a/src/find-referendum.ts b/src/find-referendum.ts index 0229cf5..6c8e5a2 100644 --- a/src/find-referendum.ts +++ b/src/find-referendum.ts @@ -1,4 +1,5 @@ import { ApiPromise, WsProvider } from "@polkadot/api"; +import type { SubmittableExtrinsic } from "@polkadot/api/promise/types"; import { PROVIDER_URL } from "./constants"; import { ParseRFCResult } from "./parse-RFC"; @@ -8,8 +9,9 @@ import { ParseRFCResult } from "./parse-RFC"; export const findReferendum = async (opts: { parseRFCResult: ParseRFCResult; blockHash: string; + providerUrl?: string | undefined; }): Promise => { - const api = new ApiPromise({ provider: new WsProvider(PROVIDER_URL) }); + const api = new ApiPromise({ provider: new WsProvider(opts.providerUrl ?? PROVIDER_URL) }); await api.isReadyOrError; const apiAt = await api.at(opts.blockHash); @@ -24,15 +26,20 @@ export const findReferendum = async (opts: { string, any >; - // TODO: Handle inlined proposal as well. - // https://github.com/paritytech/rfc-action/issues/12 - const proposalHash = info?.ongoing?.proposal?.lookup?.hash; - if (proposalHash === api.tx.system.remark(opts.parseRFCResult.approveRemarkText).method.hash.toHex()) { + /** + * Checks if the given transaction (expected remark), + * matches what is found in the on-chain referendum we currently iterate over. + */ + const remarkMatchesProposal = (tx: SubmittableExtrinsic): boolean => + info?.ongoing?.proposal?.lookup?.hash === tx.method.hash.toHex() || + info?.ongoing?.proposal?.inline === tx.method.toHex(); + + if (remarkMatchesProposal(api.tx.system.remark(opts.parseRFCResult.approveRemarkText))) { await api.disconnect(); return { approved: true }; } - if (proposalHash === api.tx.system.remark(opts.parseRFCResult.rejectRemarkText).method.hash.toHex()) { + if (remarkMatchesProposal(api.tx.system.remark(opts.parseRFCResult.rejectRemarkText))) { await api.disconnect(); return { approved: false }; }