-
Notifications
You must be signed in to change notification settings - Fork 8
fix: #60, Check if preimage exists on chain before creating a proposal #61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,8 @@ | ||
| const { getConfiguration } = require("opstooling-js-style/src/eslint/configuration"); | ||
|
|
||
| module.exports = getConfiguration({ typescript: { rootDir: __dirname } }); | ||
| const conf = getConfiguration({ typescript: { rootDir: __dirname } }); | ||
|
|
||
| conf.overrides[0].rules["@typescript-eslint/no-misused-promises"] = "off"; | ||
| conf.overrides[0].rules["no-async-promise-executor"] = "off"; | ||
|
|
||
| module.exports = conf; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,11 +2,13 @@ import "@polkadot/api-augment"; | |
| import "@polkadot/types-augment"; | ||
| import { ApiPromise } from "@polkadot/api"; | ||
| import { KeyringPair } from "@polkadot/keyring/types"; | ||
| import { ISubmittableResult } from "@polkadot/types/types"; | ||
| import { blake2AsHex } from "@polkadot/util-crypto"; | ||
| import assert from "assert"; | ||
| import { Probot } from "probot"; | ||
|
|
||
| import { getChainConfig, getTipUrl } from "./chain-config"; | ||
| import { State, TipRequest, TipResult } from "./types"; | ||
| import { ContributorAccount, State, TipRequest, TipResult } from "./types"; | ||
| import { formatReason, tipSizeToOpenGovTrack } from "./util"; | ||
|
|
||
| export async function tipOpenGov(opts: { | ||
|
|
@@ -29,40 +31,75 @@ export async function tipOpenGov(opts: { | |
| if ("error" in track) { | ||
| return { success: false, errorMessage: track.error }; | ||
| } | ||
| const contributorAddress = contributor.account.address; | ||
|
|
||
| const proposalTx = api.tx.utility.batch([ | ||
| api.tx.system.remark(formatReason(tipRequest)), | ||
| api.tx.treasury.spend(track.value.toString(), contributor.account.address), | ||
| api.tx.treasury.spend(track.value.toString(), contributorAddress), | ||
| ]); | ||
| const encodedProposal = proposalTx.method.toHex(); | ||
| const proposalHash = blake2AsHex(encodedProposal); | ||
| const encodedLength = Math.ceil((encodedProposal.length - 2) / 2); | ||
|
|
||
| const preimage_unsub = await api.tx.preimage | ||
| .notePreimage(encodedProposal) | ||
| .signAndSend(botTipAccount, { nonce: -1 }, (result) => { | ||
| if (result.status.isInBlock) { | ||
| bot.log(`Preimage Upload included at blockHash ${result.status.asInBlock.toString()}`); | ||
| } else if (result.status.isFinalized) { | ||
| bot.log(`Preimage Upload finalized at blockHash ${result.status.asFinalized.toString()}`); | ||
| preimage_unsub(); | ||
| } | ||
| }); | ||
| console.log(`encodedLength: ${encodedLength}`); | ||
|
|
||
| const referenda_unsub = await api.tx.referenda | ||
| .submit( | ||
| // TODO: There should be a way to set those types properly. | ||
| { Origins: track.track } as any, // eslint-disable-line | ||
| { Lookup: { hash: proposalHash, length: proposalTx.length - 1 } }, | ||
| { after: 10 } as any, // eslint-disable-line | ||
| ) | ||
| .signAndSend(botTipAccount, { nonce: -1 }, (result) => { | ||
| if (result.status.isInBlock) { | ||
| bot.log(`Tip referendum included at blockHash ${result.status.asInBlock.toString()}`); | ||
| } else if (result.status.isFinalized) { | ||
| bot.log(`Tip referendum finalized at blockHash ${result.status.asFinalized.toString()}`); | ||
| referenda_unsub(); | ||
| } | ||
| }); | ||
| return await new Promise(async (resolve, reject) => { | ||
| // create a preimage from opengov with the encodedProposal above | ||
| const preimageUnsubscribe = await api.tx.preimage | ||
| .notePreimage(encodedProposal) | ||
| .signAndSend(botTipAccount, { nonce: -1 }, async (result) => { | ||
| await signAndSendCallback(bot, contributor.account, "preimage", preimageUnsubscribe, result) | ||
| .then(async () => { | ||
| const readPreimage = await api.query.preimage.statusFor(proposalHash); | ||
|
|
||
| return { success: true, tipUrl: getTipUrl(contributor.account.network) }; | ||
| if (readPreimage.isEmpty) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Asking for understanding:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
this is what happens with creating a preimage
|
||
| reject(new Error(`Preimage for ${proposalHash} was not found, check if the bot has enough funds.`)); | ||
| } | ||
|
|
||
| const proposalUnsubscribe = await api.tx.referenda | ||
| .submit( | ||
| // TODO: There should be a way to set those types properly. | ||
| { Origins: track.track } as never, | ||
| { Lookup: { hash: proposalHash, length: proposalTx.length - 1 } }, | ||
| { after: 10 } as never, | ||
| ) | ||
| .signAndSend(botTipAccount, { nonce: -1 }, async (refResult) => { | ||
| await signAndSendCallback(bot, contributor.account, "referendum", proposalUnsubscribe, refResult) | ||
| .then(resolve) | ||
| .catch(reject); | ||
| }); | ||
| }) | ||
| .catch(reject); | ||
| }); | ||
| }); | ||
| } | ||
|
|
||
| async function signAndSendCallback( | ||
| bot: Probot, | ||
| contributor: ContributorAccount, | ||
| type: "preimage" | "referendum", | ||
| unsubscribe: () => void, | ||
| result: ISubmittableResult, | ||
| ): Promise<TipResult> { | ||
| return await new Promise((resolve, reject) => { | ||
| if (result.status.isInBlock) { | ||
| bot.log(`${type} for ${contributor.address} included at blockHash ${result.status.asInBlock.toString()}`); | ||
| } else if (result.status.isFinalized) { | ||
| bot.log(`Tip for ${contributor.address} ${type} finalized at blockHash ${result.status.asFinalized.toString()}`); | ||
| unsubscribe(); | ||
| resolve({ success: true, tipUrl: getTipUrl(contributor.network) }); | ||
| } else if ( | ||
| result.status.isDropped || | ||
| result.status.isInvalid || | ||
| result.status.isUsurped || | ||
| result.status.isRetracted || | ||
| result.status.isBroadcast | ||
| ) { | ||
| const msg = `Tip for ${contributor.address} ${type} status is 👎: ${result.status.type}`; | ||
| bot.log(msg, result.status); | ||
| reject({ success: false, errorMessage: msg }); | ||
| } else { | ||
| bot.log(`Tip for ${contributor.address} ${type} status: ${result.status.type}`, result.status); | ||
| } | ||
| }); | ||
| } | ||






There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this calculation? It needs to be the SCALE encoded length.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
before it was
proposalTx.length - 1, but this I took from https://github.com/polkadot-js/apps/blob/2d295e33f9d37d6582d97b9e93df81d16e1950e2/packages/page-preimages/src/Preimages/Add/Partial.tsx#L44@ggwpez could you please explain what is SCALE encoded?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It first does
toHexand then uses(x - 2) / 2to get the number of bytes in the hex string… wtfMaybe there is no easier way to encode it or something. Ideal would be an
encodeorencodedLengthfunction.Otherwise just add a test; i dont want to block over this if it works.
SCALE is the encoding that Substrate/Polkadot uses for mostly everything. Especially stuff like transactions and their arguments (so also preimages).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll investigate and we will add tests for sure