From 515c38ef411391e88767011cd29e4324e95445ce Mon Sep 17 00:00:00 2001 From: timbrinded <79199034+timbrinded@users.noreply.github.com> Date: Wed, 15 Mar 2023 17:34:36 +0000 Subject: [PATCH] updated utils pkg --- .changeset/empty-swans-cough.md | 5 ++ packages/util/src/functions/block.ts | 75 ++++++++++++++------------ packages/util/src/functions/logging.ts | 46 ++++++++++++++++ 3 files changed, 93 insertions(+), 33 deletions(-) create mode 100644 .changeset/empty-swans-cough.md create mode 100644 packages/util/src/functions/logging.ts diff --git a/.changeset/empty-swans-cough.md b/.changeset/empty-swans-cough.md new file mode 100644 index 00000000..d14ec729 --- /dev/null +++ b/.changeset/empty-swans-cough.md @@ -0,0 +1,5 @@ +--- +"@moonsong-labs/moonwall-util": patch +--- + +QoL - Added logging utils diff --git a/packages/util/src/functions/block.ts b/packages/util/src/functions/block.ts index 4ea70f47..2ea5dd59 100644 --- a/packages/util/src/functions/block.ts +++ b/packages/util/src/functions/block.ts @@ -4,16 +4,14 @@ import { BlockHash, RuntimeDispatchInfo, Event, + Extrinsic, + RuntimeDispatchInfoV1, + DispatchError, + DispatchInfo, } from "@polkadot/types/interfaces"; -import { - FrameSystemEventRecord, - SpWeightsWeightV2Weight, -} from "@polkadot/types/lookup"; +import { FrameSystemEventRecord, SpWeightsWeightV2Weight } from "@polkadot/types/lookup"; import { u32, u64, u128, Option, GenericExtrinsic } from "@polkadot/types"; -import type { - Block, - AccountId20, -} from "@polkadot/types/interfaces/runtime/types"; +import type { Block, AccountId20 } from "@polkadot/types/interfaces/runtime/types"; import type { TxWithEvent } from "@polkadot/api-derive/types"; import type { ITuple } from "@polkadot/types-codec/types"; import Bottleneck from "bottleneck"; @@ -81,16 +79,12 @@ export const getBlockExtrinsic = async ( ); const extrinsic = extIndex > -1 ? block.extrinsics[extIndex] : null; const events = records - .filter( - ({ phase }) => - phase.isApplyExtrinsic && phase.asApplyExtrinsic.eq(extIndex) - ) + .filter(({ phase }) => phase.isApplyExtrinsic && phase.asApplyExtrinsic.eq(extIndex)) .map(({ event }) => event); const resultEvent = events.find( (event) => event.section === "system" && - (event.method === "ExtrinsicSuccess" || - event.method === "ExtrinsicFailed") + (event.method === "ExtrinsicSuccess" || event.method === "ExtrinsicFailed") ); return { block, extrinsic, events, resultEvent }; }; @@ -104,9 +98,7 @@ export const checkBlockFinalized = async (api: ApiPromise, number: number) => { return { number, finalized: ( - await (api.rpc as any).moon.isBlockFinalized( - await api.rpc.chain.getBlockHash(number) - ) + await (api.rpc as any).moon.isBlockFinalized(await api.rpc.chain.getBlockHash(number)) ).isTrue, }; }; @@ -138,11 +130,7 @@ export const fetchHistoricBlockNum = async ( ); }; -export const getBlockArray = async ( - api: ApiPromise, - timePeriod: number, - limiter?: Bottleneck -) => { +export const getBlockArray = async (api: ApiPromise, timePeriod: number, limiter?: Bottleneck) => { /** @brief Returns an sequential array of block numbers from a given period of time in the past @param api Connected ApiPromise to perform queries on @@ -153,12 +141,8 @@ export const getBlockArray = async ( if (limiter == null) { limiter = new Bottleneck({ maxConcurrent: 10, minTime: 100 }); } - const finalizedHead = await limiter.schedule(() => - api.rpc.chain.getFinalizedHead() - ); - const signedBlock = await limiter.schedule(() => - api.rpc.chain.getBlock(finalizedHead) - ); + const finalizedHead = await limiter.schedule(() => api.rpc.chain.getFinalizedHead()); + const signedBlock = await limiter.schedule(() => api.rpc.chain.getBlock(finalizedHead)); const lastBlockNumber = signedBlock.block.header.number.toNumber(); const lastBlockTime = getBlockTime(signedBlock); @@ -176,11 +160,7 @@ export const getBlockArray = async ( }; export function extractWeight( - weightV1OrV2: - | u64 - | Option - | SpWeightsWeightV2Weight - | Option + weightV1OrV2: u64 | Option | SpWeightsWeightV2Weight | Option ) { if ("isSome" in weightV1OrV2) { const weight = weightV1OrV2.unwrap(); @@ -220,3 +200,32 @@ export function extractPreimageDeposit( amount: deposit[1], }; } + +export function mapExtrinsics( + extrinsics: Extrinsic[], + records: FrameSystemEventRecord[], + fees?: RuntimeDispatchInfo[] | RuntimeDispatchInfoV1[] +): TxWithEventAndFee[] { + return extrinsics.map((extrinsic, index): TxWithEventAndFee => { + let dispatchError: DispatchError | undefined; + let dispatchInfo: DispatchInfo | undefined; + + const events = records + .filter(({ phase }) => phase.isApplyExtrinsic && phase.asApplyExtrinsic.eq(index)) + .map(({ event }) => { + if (event.section === "system") { + if (event.method === "ExtrinsicSuccess") { + dispatchInfo = event.data[0] as any as DispatchInfo; + } else if (event.method === "ExtrinsicFailed") { + dispatchError = event.data[0] as any as DispatchError; + dispatchInfo = event.data[1] as any as DispatchInfo; + } + } + + return event as any; + }); + // TODO: Fix below to work with new weights + //@ts-expect-error + return { dispatchError, dispatchInfo, events, extrinsic, fee: fees ? fees[index] : undefined }; + }); +} diff --git a/packages/util/src/functions/logging.ts b/packages/util/src/functions/logging.ts new file mode 100644 index 00000000..a2218812 --- /dev/null +++ b/packages/util/src/functions/logging.ts @@ -0,0 +1,46 @@ +import { ApiPromise } from "@polkadot/api"; +import { mapExtrinsics } from "./block.js"; + +export function log(...msg: any[]) { + if (process.argv && process.argv[2] && process.argv[2] === "--printlogs") { + console.log(...msg); + } +} + +export const printTokens = (api: ApiPromise, tokens: bigint, decimals = 2, pad = 9) => { + return `${( + Math.ceil(Number(tokens / 10n ** BigInt(api.registry.chainDecimals[0] - decimals))) / + 10 ** decimals + ) + .toString() + .padStart(pad)} ${api.registry.chainTokens[0]}`; +}; + +export const printEvents = async (api: ApiPromise, blockHash?: string) => { + blockHash = blockHash != undefined ? blockHash : (await api.rpc.chain.getBlockHash()).toString(); + const apiAt = await api.at(blockHash); + const { block } = await api.rpc.chain.getBlock(blockHash); + const allRecords = (await apiAt.query.system.events()) as any; + + const txsWithEvents = mapExtrinsics(block.extrinsics, allRecords); + + console.log(`===== Block #${block.header.number.toString()}: ${blockHash}`); + console.log(block.header.toHuman()); + console.log( + txsWithEvents + .map( + ({ extrinsic, events }, i) => + ` [${i}]: ${extrinsic.method.section.toString()}. ` + + `${extrinsic.method.method.toString()}\n` + + ` - 0x${Buffer.from(extrinsic.data).toString("hex")}\n${events + .map( + (event) => + ` * ${event.section.toString()}.${event.method.toString()}:\n${event.data + .map((datum) => ` - ${datum.toHex()}`) + .join("\n")}` + ) + .join("\n")}` + ) + .join("\n") + ); +};