From 1404c25e83763648c90709bbe97ee16d32475fd5 Mon Sep 17 00:00:00 2001 From: RodrigoAD <15104916+RodrigoAD@users.noreply.github.com> Date: Wed, 2 Mar 2022 17:46:16 +0100 Subject: [PATCH 1/6] transfer ownership checks --- .../src/commands/abstract/executionWrapper.ts | 14 ++++++-- .../contracts/ownership/acceptOwnership.ts | 32 +++++++++++++------ .../contracts/ownership/transferOwnership.ts | 24 +++++++++++++- .../gauntlet-terra-contracts/src/lib/rdd.ts | 30 +++++++++++++++++ .../src/commands/multisig.ts | 3 +- 5 files changed, 89 insertions(+), 14 deletions(-) diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/abstract/executionWrapper.ts b/packages-ts/gauntlet-terra-contracts/src/commands/abstract/executionWrapper.ts index 5192ef75..4c91f3a0 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/abstract/executionWrapper.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/abstract/executionWrapper.ts @@ -3,14 +3,21 @@ import { Result } from '@chainlink/gauntlet-core' import { TerraCommand, TransactionResponse } from '@chainlink/gauntlet-terra' import { AccAddress } from '@terra-money/terra.js' import { logger, prompt } from '@chainlink/gauntlet-core/dist/utils' +import { Query } from './inspectionWrapper' export type BeforeExecutionContext = { input: Input contractInput: ContractInput id: string contract: string + query: Query + flags: any } +export type BeforeExecute = ( + context: BeforeExecutionContext, +) => (signer: AccAddress) => Promise + export interface AbstractInstruction { examples?: string[] instruction: { @@ -21,7 +28,7 @@ export interface AbstractInstruction { makeInput: (flags: any, args: string[]) => Promise validateInput: (input: Input) => boolean makeContractInput: (input: Input) => Promise - beforeExecute?: (context: BeforeExecutionContext) => () => Promise + beforeExecute?: BeforeExecute afterExecute?: (response: Result) => any } @@ -53,12 +60,15 @@ export const instructionToCommand = (instruction: Abstract if (!instruction.validateInput(input)) { throw new Error(`Invalid input params: ${JSON.stringify(input)}`) } + const query: Query = this.provider.wasm.contractQuery.bind(this.provider.wasm) const contractInput = await instruction.makeContractInput(input) const beforeExecutionContext: BeforeExecutionContext = { input, contractInput, id, contract: this.args[0], + query, + flags, } this.beforeExecute = instruction.beforeExecute ? instruction.beforeExecute(beforeExecutionContext) @@ -79,7 +89,7 @@ export const instructionToCommand = (instruction: Abstract // TODO: Command should be built from gauntet-core await this.buildCommand(this.flags, this.args) // - await this.beforeExecute() + await this.beforeExecute(this.wallet.key.accAddress) let response = await this.command.execute() const data = this.afterExecute(response) if (data) { diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ownership/acceptOwnership.ts b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ownership/acceptOwnership.ts index 68946d99..8e1505c8 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ownership/acceptOwnership.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ownership/acceptOwnership.ts @@ -1,21 +1,32 @@ -import { AbstractInstruction } from '../../abstract/executionWrapper' +import { AbstractInstruction, BeforeExecute } from '../../abstract/executionWrapper' import { CATEGORIES } from '../../../lib/constants' import { CONTRACT_LIST } from '../../../lib/contracts' +import { logger, prompt } from '@chainlink/gauntlet-core/dist/utils' +import { getContractFromRDD, getRDD } from '../../../lib/rdd' type CommandInput = {} type ContractInput = {} -const makeCommandInput = async (flags: any, args: string[]): Promise => { - return {} -} - -const makeContractInput = async (input: CommandInput): Promise => { - return {} -} +const makeCommandInput = async (flags: any, args: string[]): Promise => ({}) +const makeContractInput = async (input: CommandInput): Promise => ({}) +const validateInput = (input: CommandInput): boolean => true -const validateInput = (input: CommandInput): boolean => { - return true +const beforeExecute: BeforeExecute = (context) => async (signer) => { + const currentOwner = await context.query(context.contract, 'owner') + if (!context.flags.rdd) { + logger.warn('No RDD flag provided. Accepting ownership without RDD check') + logger.info(`Accepting Ownership Transfer of contract with current owner ${currentOwner} to new owner `) + await prompt('Continue?') + return + } + const contract = getContractFromRDD(getRDD(context.flags.rdd), context.contract) + logger.info(`Accepting Ownership Transfer of contract of type "${contract.type}": + - Contract: ${contract.address} ${contract.description ? '- ' + contract.description : ''} + - Current Owner: ${currentOwner} + - Next Owner (Current signer): ${signer} + `) + await prompt('Continue?') } export const makeAcceptOwnershipInstruction = (contractId: CONTRACT_LIST) => { @@ -28,6 +39,7 @@ export const makeAcceptOwnershipInstruction = (contractId: CONTRACT_LIST) => { makeInput: makeCommandInput, validateInput: validateInput, makeContractInput: makeContractInput, + beforeExecute, } return acceptOwnershipInstruction diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ownership/transferOwnership.ts b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ownership/transferOwnership.ts index 30559fe5..a2bcce7e 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ownership/transferOwnership.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ownership/transferOwnership.ts @@ -1,7 +1,9 @@ import { AccAddress } from '@terra-money/terra.js' -import { AbstractInstruction } from '../../abstract/executionWrapper' +import { AbstractInstruction, BeforeExecute } from '../../abstract/executionWrapper' import { CATEGORIES } from '../../../lib/constants' import { CONTRACT_LIST } from '../../../lib/contracts' +import { getContractFromRDD, getRDD } from '../../../lib/rdd' +import { logger, prompt } from '@chainlink/gauntlet-core/dist/utils' type CommandInput = { to: string @@ -31,6 +33,25 @@ const validateInput = (input: CommandInput): boolean => { return true } +const beforeExecute: BeforeExecute = (context) => async () => { + const currentOwner = await context.query(context.contract, 'owner') + if (!context.flags.rdd) { + logger.warn('No RDD flag provided. Transferring without RDD check') + logger.info( + `Proposing Ownership Transfer of contract with current owner ${currentOwner} to new owner ${context.contractInput.to}`, + ) + await prompt('Continue?') + return + } + const contract = getContractFromRDD(getRDD(context.flags.rdd), context.contract) + logger.info(`Proposing Ownership Transfer of contract of type "${contract.type}": + - Contract: ${contract.address} ${contract.description ? '- ' + contract.description : ''} + - Current Owner: ${currentOwner} + - Next Owner: ${context.contractInput.to} + `) + await prompt('Continue?') +} + export const makeTransferOwnershipInstruction = (contractId: CONTRACT_LIST) => { const transferOwnershipInstruction: AbstractInstruction = { instruction: { @@ -41,6 +62,7 @@ export const makeTransferOwnershipInstruction = (contractId: CONTRACT_LIST) => { makeInput: makeCommandInput, validateInput: validateInput, makeContractInput: makeContractInput, + beforeExecute, } return transferOwnershipInstruction diff --git a/packages-ts/gauntlet-terra-contracts/src/lib/rdd.ts b/packages-ts/gauntlet-terra-contracts/src/lib/rdd.ts index 591aeb90..a735a5b2 100644 --- a/packages-ts/gauntlet-terra-contracts/src/lib/rdd.ts +++ b/packages-ts/gauntlet-terra-contracts/src/lib/rdd.ts @@ -21,3 +21,33 @@ export const getRDD = (path: string, fileDescription: string = 'RDD'): any => { ) } } + +export enum CONTRACT_TYPES { + PROXY = 'proxies', + FLAG = 'flags', + ACCESS_CONTROLLER = 'accessControllers', + CONTRACT = 'contracts', + VALIDATOR = 'validators', +} + +export type RDDContract = { + type: CONTRACT_TYPES + contract: any + address: string + description?: string +} + +export const getContractFromRDD = (rdd: any, address: string): RDDContract => { + return Object.values(CONTRACT_TYPES).reduce((agg, type) => { + const content = rdd[type]?.[address] + if (content) { + return { + type, + contract: content, + address, + ...((type === CONTRACT_TYPES.CONTRACT || type === CONTRACT_TYPES.PROXY) && { description: content.name }), + } + } + return agg + }, {} as RDDContract) +} diff --git a/packages-ts/gauntlet-terra-cw-plus/src/commands/multisig.ts b/packages-ts/gauntlet-terra-cw-plus/src/commands/multisig.ts index 5a991d71..10b788c1 100644 --- a/packages-ts/gauntlet-terra-cw-plus/src/commands/multisig.ts +++ b/packages-ts/gauntlet-terra-cw-plus/src/commands/multisig.ts @@ -29,6 +29,7 @@ export const wrapCommand = (command) => { this.multisig = process.env.CW3_FLEX_MULTISIG as AccAddress const c = new command(flags, args) as TerraCommand + await c.invokeMiddlewares(c, c.middlewares) this.command = c.buildCommand ? await c.buildCommand(flags, args) : c return this.command } @@ -167,7 +168,7 @@ export const wrapCommand = (command) => { } if (this.flags.execute) { - await this.command.beforeExecute() + await this.command.beforeExecute(this.multisig) await prompt(`Continue ${actionMessage[state.proposal.nextAction]} proposal?`) const tx = await this.signAndSend([rawTx]) From c82a47213b4b0deb3c656d8db4f1ad9bc86cc5c9 Mon Sep 17 00:00:00 2001 From: RodrigoAD <15104916+RodrigoAD@users.noreply.github.com> Date: Thu, 3 Mar 2022 10:46:40 +0100 Subject: [PATCH 2/6] inpect offchain config from event info --- .../src/commands/abstract/index.ts | 2 +- .../commands/abstract/inspectionWrapper.ts | 9 +- .../contracts/ocr2/inspection/inspect.ts | 117 ++++++++++++++++-- .../src/lib/encoding.ts | 2 +- .../src/lib/inspection.ts | 10 ++ .../src/lib/provider.ts | 28 +++++ .../src/commands/middlewares.ts | 2 +- 7 files changed, 154 insertions(+), 16 deletions(-) create mode 100644 packages-ts/gauntlet-terra-contracts/src/lib/inspection.ts create mode 100644 packages-ts/gauntlet-terra-contracts/src/lib/provider.ts diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/abstract/index.ts b/packages-ts/gauntlet-terra-contracts/src/commands/abstract/index.ts index 8cf99231..7e503d5d 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/abstract/index.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/abstract/index.ts @@ -167,7 +167,7 @@ export default class AbstractCommand extends TerraCommand { } abstractQuery: AbstractExecute = async (params: any, address: string) => { - logger.loading(`Calling ${this.opts.function} from contract ${this.opts.contract.id} at ${address}`) + logger.debug(`Calling ${this.opts.function} from contract ${this.opts.contract.id} at ${address}`) const result = await this.query(address, params) logger.debug(`Query finished with result: ${JSON.stringify(result)}`) return { diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/abstract/inspectionWrapper.ts b/packages-ts/gauntlet-terra-contracts/src/commands/abstract/inspectionWrapper.ts index bafef35c..53fa44f0 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/abstract/inspectionWrapper.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/abstract/inspectionWrapper.ts @@ -1,13 +1,14 @@ -import AbstractCommand, { makeAbstractCommand } from '.' +import { makeAbstractCommand } from '.' import { Result } from '@chainlink/gauntlet-core' import { TerraCommand, TransactionResponse } from '@chainlink/gauntlet-terra' import { logger } from '@chainlink/gauntlet-core/dist/utils' import { CATEGORIES } from '../../lib/constants' import { CONTRACT_LIST } from '../../lib/contracts' import { APIParams } from '@terra-money/terra.js/dist/client/lcd/APIRequester' +import { TxSearchOptions, TxSearchResult } from '@terra-money/terra.js' export type Query = (contractAddress: string, query: any, params?: APIParams) => Promise - +export type Search = (options: Partial) => Promise /** * Inspection commands need to match this interface * command: { @@ -34,6 +35,7 @@ export interface InspectInstruction { makeInspectionData: (query: Query) => (input: CommandInput) => Promise makeOnchainData: ( query: Query, + search: Search, ) => (instructionsData: any[], input: CommandInput, contractAddress: string) => Promise inspect: (expected: ContractExpectedInfo, data: ContractExpectedInfo) => boolean } @@ -71,7 +73,8 @@ export const instructionToInspectCommand = ( ) const query: Query = this.provider.wasm.contractQuery.bind(this.provider.wasm) - const onchainData = await inspectInstruction.makeOnchainData(query)(data, input, this.args[0]) + const search: Search = this.provider.tx.search.bind(this.provider.tx) + const onchainData = await inspectInstruction.makeOnchainData(query, search)(data, input, this.args[0]) const inspectData = await inspectInstruction.makeInspectionData(query)(input) const inspection = inspectInstruction.inspect(inspectData, onchainData) return { diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/inspection/inspect.ts b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/inspection/inspect.ts index 5d5aea3a..cf9e01de 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/inspection/inspect.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/inspection/inspect.ts @@ -2,10 +2,14 @@ import { BN, inspection, logger } from '@chainlink/gauntlet-core/dist/utils' import { CONTRACT_LIST } from '../../../../lib/contracts' import { CATEGORIES, TOKEN_UNIT } from '../../../../lib/constants' import { getRDD } from '../../../../lib/rdd' -import { InspectInstruction, instructionToInspectCommand, Query } from '../../../abstract/inspectionWrapper' +import { InspectInstruction, instructionToInspectCommand, Query, Search } from '../../../abstract/inspectionWrapper' +import { deserializeConfig } from '../../../../lib/encoding' +import { getOffchainConfigInput, OffchainConfig } from '../proposeOffchainConfig' +import { toComparableNumber, wrappedComparableLongNumber } from '../../../../lib/inspection' +import { filterTxsByEvent, getBlockTxs } from '../../../../lib/provider' +// Command input and expected info is the same here type ContractExpectedInfo = { - digest: string description: string decimals: string | number transmitters: string[] @@ -17,8 +21,10 @@ type ContractExpectedInfo = { recommendedGasPriceMicro: string transmissionPaymentGjuels: string } + offchainConfig: OffchainConfig totalOwed?: string linkAvailable?: string + owner?: string } const makeInput = async (flags: any, args: string[]): Promise => { @@ -33,7 +39,6 @@ const makeInput = async (flags: any, args: string[]): Promise async (input: ContractExpectedInfo): Promise => input -const makeOnchainData = (query: Query) => async ( +const makeOnchainData = (query: Query, search: Search) => async ( instructionsData: any[], input: ContractExpectedInfo, aggregator: string, @@ -64,6 +70,7 @@ const makeOnchainData = (query: Query) => async ( const requesterAC = instructionsData[6] const link = instructionsData[7] const linkAvailable = instructionsData[8] + const owner = instructionsData[9] const owedPerTransmitter: string[] = await Promise.all( transmitters.addresses.map((t) => { @@ -75,6 +82,13 @@ const makeOnchainData = (query: Query) => async ( }), ) + // The contract only stores the block where the config was accepted. The tx log contains the config + const setConfigTx = filterTxsByEvent(await getBlockTxs(search, latestConfigDetails.block_number), 'wasm-set_config') + const event = setConfigTx?.logs?.[0].eventsByType['wasm-set_config'] + const offchainConfig = event?.offchain_config + ? await deserializeConfig(Buffer.from(event.offchain_config[0], 'hex')) + : ({} as OffchainConfig) + return { description, decimals, @@ -83,21 +97,21 @@ const makeOnchainData = (query: Query) => async ( requesterAccessController: requesterAC, link, linkAvailable: linkAvailable.amount, - digest: Buffer.from(latestConfigDetails.config_digest).toString('hex'), billing: { observationPaymentGjuels: billing.observation_payment_gjuels, transmissionPaymentGjuels: billing.transmission_payment_gjuels, recommendedGasPriceMicro: billing.recommended_gas_price_micro, }, totalOwed: owedPerTransmitter.reduce((agg: BN, v) => agg.add(new BN(v)), new BN(0)).toString(), + owner, + offchainConfig, } } const inspect = (expected: ContractExpectedInfo, onchainData: ContractExpectedInfo): boolean => { - const inspections: inspection.Inspection[] = [ + let inspections: inspection.Inspection[] = [ inspection.makeInspection(onchainData.description, expected.description, 'Description'), inspection.makeInspection(onchainData.decimals, expected.decimals, 'Decimals'), - inspection.makeInspection(onchainData.digest, expected.digest, 'Offchain config digest'), inspection.makeInspection(onchainData.transmitters, expected.transmitters, 'Transmitters'), inspection.makeInspection( onchainData.billingAccessController, @@ -126,10 +140,85 @@ const inspect = (expected: ContractExpectedInfo, onchainData: ContractExpectedIn 'Transmission Payment', ), ] + + if (!!onchainData.offchainConfig.s) { + const offchainConfigInspections: inspection.Inspection[] = [ + inspection.makeInspection(onchainData.offchainConfig.s, expected.offchainConfig.s, 'Offchain Config "s"'), + inspection.makeInspection( + onchainData.offchainConfig.peerIds, + expected.offchainConfig.peerIds, + 'Offchain Config "peerIds"', + ), + inspection.makeInspection( + toComparableNumber(onchainData.offchainConfig.rMax), + toComparableNumber(expected.offchainConfig.rMax), + 'Offchain Config "rMax"', + ), + inspection.makeInspection( + onchainData.offchainConfig.offchainPublicKeys.map((k) => Buffer.from(k).toString('hex')), + expected.offchainConfig.offchainPublicKeys, + `Offchain Config "offchainPublicKeys"`, + ), + inspection.makeInspection( + onchainData.offchainConfig.reportingPluginConfig.alphaReportInfinite, + expected.offchainConfig.reportingPluginConfig.alphaReportInfinite, + 'Offchain Config "reportingPluginConfig.alphaReportInfinite"', + ), + inspection.makeInspection( + onchainData.offchainConfig.reportingPluginConfig.alphaAcceptInfinite, + expected.offchainConfig.reportingPluginConfig.alphaAcceptInfinite, + 'Offchain Config "reportingPluginConfig.alphaAcceptInfinite"', + ), + inspection.makeInspection( + wrappedComparableLongNumber(onchainData.offchainConfig.reportingPluginConfig.alphaReportPpb), + toComparableNumber(expected.offchainConfig.reportingPluginConfig.alphaReportPpb), + `Offchain Config "reportingPluginConfig.alphaReportPpb"`, + ), + inspection.makeInspection( + wrappedComparableLongNumber(onchainData.offchainConfig.reportingPluginConfig.alphaAcceptPpb), + toComparableNumber(expected.offchainConfig.reportingPluginConfig.alphaAcceptPpb), + `Offchain Config "reportingPluginConfig.alphaAcceptPpb"`, + ), + inspection.makeInspection( + wrappedComparableLongNumber(onchainData.offchainConfig.reportingPluginConfig.deltaCNanoseconds), + toComparableNumber(expected.offchainConfig.reportingPluginConfig.deltaCNanoseconds), + `Offchain Config "reportingPluginConfig.deltaCNanoseconds"`, + ), + ] + + const longNumberInspections = [ + 'deltaProgressNanoseconds', + 'deltaResendNanoseconds', + 'deltaRoundNanoseconds', + 'deltaGraceNanoseconds', + 'deltaStageNanoseconds', + 'maxDurationQueryNanoseconds', + 'maxDurationObservationNanoseconds', + 'maxDurationReportNanoseconds', + 'maxDurationShouldAcceptFinalizedReportNanoseconds', + 'maxDurationShouldTransmitAcceptedReportNanoseconds', + ].map((prop) => + inspection.makeInspection( + wrappedComparableLongNumber(onchainData.offchainConfig[prop]), + toComparableNumber(expected.offchainConfig[prop]), + `Offchain Config "${prop}"`, + ), + ) + + inspections = inspections.concat(offchainConfigInspections).concat(longNumberInspections) + } else { + logger.error('Could not get offchain config information from the contract. Skipping offchain config inspection') + } + logger.line() logger.info('Inspection results:') - logger.info(`LINK Available: ${onchainData.linkAvailable}`) - logger.info(`Total LINK Owed: ${onchainData.totalOwed}`) + logger.info(`Ownership: + - Owner: ${onchainData.owner} + `) + logger.info(`Funding: + - LINK Available: ${onchainData.linkAvailable} + - Total LINK Owed: ${onchainData.totalOwed} + `) const owedDiff = new BN(onchainData.linkAvailable).sub(new BN(onchainData.totalOwed)).div(new BN(TOKEN_UNIT)) if (owedDiff.lt(new BN(0))) { @@ -137,7 +226,11 @@ const inspect = (expected: ContractExpectedInfo, onchainData: ContractExpectedIn } else { logger.success(`LINK Balance can cover debt. LINK after payment: ${owedDiff.toString()}`) } - return inspection.inspect(inspections) + + const result = inspection.inspect(inspections) + logger.line() + + return result } const instruction: InspectInstruction = { @@ -183,6 +276,10 @@ const instruction: InspectInstruction = { contract: 'ocr2', function: 'link_available_for_payment', }, + { + contract: 'ocr2', + function: 'owner', + }, ], makeInput, makeInspectionData, diff --git a/packages-ts/gauntlet-terra-contracts/src/lib/encoding.ts b/packages-ts/gauntlet-terra-contracts/src/lib/encoding.ts index 289e3efc..6a2bf39f 100644 --- a/packages-ts/gauntlet-terra-contracts/src/lib/encoding.ts +++ b/packages-ts/gauntlet-terra-contracts/src/lib/encoding.ts @@ -19,7 +19,7 @@ export const serializeOffchainConfig = async (input: OffchainConfig): Promise { +export const deserializeConfig = (buffer: Buffer): OffchainConfig => { const proto = new Proto.Protobuf({ descriptor: descriptor }) const offchain = proto.decode('offchainreporting2_config.OffchainConfigProto', buffer) const reportingPluginConfig = proto.decode( diff --git a/packages-ts/gauntlet-terra-contracts/src/lib/inspection.ts b/packages-ts/gauntlet-terra-contracts/src/lib/inspection.ts new file mode 100644 index 00000000..69ca91fa --- /dev/null +++ b/packages-ts/gauntlet-terra-contracts/src/lib/inspection.ts @@ -0,0 +1,10 @@ +import { Proto } from '@chainlink/gauntlet-core/dist/crypto' +import { BN } from '@chainlink/gauntlet-core/dist/utils' + +export const toComparableNumber = (v: string | number) => new BN(v).toString() +export const toComparableLongNumber = (v: Long) => new BN(Proto.Protobuf.longToString(v)).toString() +export const wrappedComparableLongNumber = (v: any) => { + // Proto encoding will ignore falsy values. + if (!v) return '0' + return toComparableLongNumber(v) +} diff --git a/packages-ts/gauntlet-terra-contracts/src/lib/provider.ts b/packages-ts/gauntlet-terra-contracts/src/lib/provider.ts new file mode 100644 index 00000000..82d2f8b3 --- /dev/null +++ b/packages-ts/gauntlet-terra-contracts/src/lib/provider.ts @@ -0,0 +1,28 @@ +import { logger } from '@chainlink/gauntlet-core/dist/utils' +import { TxInfo } from '@terra-money/terra.js' +import { Search } from '../commands/abstract/inspectionWrapper' + +export const filterTxsByEvent = (txs: TxInfo[], event: string): TxInfo | undefined => { + const filteredTx = txs.filter((tx) => tx.logs?.some((log) => log.eventsByType[event]))?.[0] + return filteredTx +} + +export const getBlockTxs = async (search: Search, block: number, offset = 0): Promise => { + // recursive call to get every tx in the block. API has a 100 tx limit. Increasing the offset 100 every time + try { + const txs = await search({ + events: [ + { + key: 'tx.height', + value: String(block), + }, + ], + 'pagination.offset': String(offset), + }) + return txs.txs.concat(await getBlockTxs(search, block, offset + 100)) + } catch (e) { + logger.debug('No more txs in block') + } + + return [] +} diff --git a/packages-ts/gauntlet-terra/src/commands/middlewares.ts b/packages-ts/gauntlet-terra/src/commands/middlewares.ts index 9d16e54b..6a195600 100644 --- a/packages-ts/gauntlet-terra/src/commands/middlewares.ts +++ b/packages-ts/gauntlet-terra/src/commands/middlewares.ts @@ -37,7 +37,7 @@ export const withWallet: Middleware = async (c: TerraCommand, next: Next) => { } c.wallet = c.provider.wallet(key) - logger.info(`Operator address is ${c.wallet.key.accAddress}`) + logger.debug(`Operator address is ${c.wallet.key.accAddress}`) return next() } From 9929c89259ee5608ffb6d9419b8de56292924588 Mon Sep 17 00:00:00 2001 From: RodrigoAD <15104916+RodrigoAD@users.noreply.github.com> Date: Thu, 3 Mar 2022 13:52:29 +0100 Subject: [PATCH 3/6] provider in execution context. minor improvements --- .../src/commands/abstract/executionWrapper.ts | 30 ++++++++--------- .../commands/abstract/inspectionWrapper.ts | 16 +++------- .../src/commands/contracts/link/transfer.ts | 4 +-- .../src/commands/contracts/ocr2/deploy.ts | 5 ++- .../contracts/ocr2/inspection/inspect.ts | 17 ++++++---- .../commands/contracts/ocr2/proposeConfig.ts | 4 +-- .../contracts/ocr2/proposeOffchainConfig.ts | 5 ++- .../src/commands/contracts/ocr2/setBilling.ts | 4 +-- .../contracts/ownership/acceptOwnership.ts | 6 ++-- .../contracts/ownership/transferOwnership.ts | 6 ++-- .../src/lib/provider.ts | 28 ---------------- packages-ts/gauntlet-terra/src/index.ts | 4 ++- .../gauntlet-terra/src/lib/provider.ts | 32 +++++++++++++++++++ .../src/lib/rdd.ts | 0 14 files changed, 80 insertions(+), 81 deletions(-) delete mode 100644 packages-ts/gauntlet-terra-contracts/src/lib/provider.ts create mode 100644 packages-ts/gauntlet-terra/src/lib/provider.ts rename packages-ts/{gauntlet-terra-contracts => gauntlet-terra}/src/lib/rdd.ts (100%) diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/abstract/executionWrapper.ts b/packages-ts/gauntlet-terra-contracts/src/commands/abstract/executionWrapper.ts index 4c91f3a0..753ae1f7 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/abstract/executionWrapper.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/abstract/executionWrapper.ts @@ -1,21 +1,20 @@ import AbstractCommand, { makeAbstractCommand } from '.' import { Result } from '@chainlink/gauntlet-core' import { TerraCommand, TransactionResponse } from '@chainlink/gauntlet-terra' -import { AccAddress } from '@terra-money/terra.js' +import { AccAddress, LCDClient } from '@terra-money/terra.js' import { logger, prompt } from '@chainlink/gauntlet-core/dist/utils' -import { Query } from './inspectionWrapper' -export type BeforeExecutionContext = { +export type ExecutionContext = { input: Input contractInput: ContractInput id: string contract: string - query: Query + provider: LCDClient flags: any } export type BeforeExecute = ( - context: BeforeExecutionContext, + context: ExecutionContext, ) => (signer: AccAddress) => Promise export interface AbstractInstruction { @@ -32,6 +31,12 @@ export interface AbstractInstruction { afterExecute?: (response: Result) => any } +const defaultBeforeExecute = (context: ExecutionContext) => async () => { + logger.loading(`Executing ${context.id} from contract ${context.contract}`) + logger.log('Input Params:', context.contractInput) + await prompt(`Continue?`) +} + export const instructionToCommand = (instruction: AbstractInstruction) => { const id = `${instruction.instruction.contract}:${instruction.instruction.function}` const category = `${instruction.instruction.category}` @@ -47,12 +52,6 @@ export const instructionToCommand = (instruction: Abstract super(flags, args) } - defaultBeforeExecute = (context: BeforeExecutionContext) => async () => { - logger.loading(`Executing ${context.id} from contract ${context.contract}`) - logger.log('Input Params:', context.contractInput) - await prompt(`Continue?`) - } - afterExecute = instruction.afterExecute || this.afterExecute buildCommand = async (flags, args): Promise => { @@ -60,19 +59,18 @@ export const instructionToCommand = (instruction: Abstract if (!instruction.validateInput(input)) { throw new Error(`Invalid input params: ${JSON.stringify(input)}`) } - const query: Query = this.provider.wasm.contractQuery.bind(this.provider.wasm) const contractInput = await instruction.makeContractInput(input) - const beforeExecutionContext: BeforeExecutionContext = { + const executionContext: ExecutionContext = { input, contractInput, id, contract: this.args[0], - query, + provider: this.provider, flags, } this.beforeExecute = instruction.beforeExecute - ? instruction.beforeExecute(beforeExecutionContext) - : this.defaultBeforeExecute(beforeExecutionContext) + ? instruction.beforeExecute(executionContext) + : defaultBeforeExecute(executionContext) const abstractCommand = await makeAbstractCommand(id, this.flags, this.args, contractInput) await abstractCommand.invokeMiddlewares(abstractCommand, abstractCommand.middlewares) diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/abstract/inspectionWrapper.ts b/packages-ts/gauntlet-terra-contracts/src/commands/abstract/inspectionWrapper.ts index 53fa44f0..5848d433 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/abstract/inspectionWrapper.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/abstract/inspectionWrapper.ts @@ -4,11 +4,8 @@ import { TerraCommand, TransactionResponse } from '@chainlink/gauntlet-terra' import { logger } from '@chainlink/gauntlet-core/dist/utils' import { CATEGORIES } from '../../lib/constants' import { CONTRACT_LIST } from '../../lib/contracts' -import { APIParams } from '@terra-money/terra.js/dist/client/lcd/APIRequester' -import { TxSearchOptions, TxSearchResult } from '@terra-money/terra.js' +import { LCDClient } from '@terra-money/terra.js' -export type Query = (contractAddress: string, query: any, params?: APIParams) => Promise -export type Search = (options: Partial) => Promise /** * Inspection commands need to match this interface * command: { @@ -32,10 +29,9 @@ export interface InspectInstruction { function: string }[] makeInput: (flags: any, args: string[]) => Promise - makeInspectionData: (query: Query) => (input: CommandInput) => Promise + makeInspectionData: (provider: LCDClient) => (input: CommandInput) => Promise makeOnchainData: ( - query: Query, - search: Search, + provider: LCDClient, ) => (instructionsData: any[], input: CommandInput, contractAddress: string) => Promise inspect: (expected: ContractExpectedInfo, data: ContractExpectedInfo) => boolean } @@ -72,10 +68,8 @@ export const instructionToInspectCommand = ( }), ) - const query: Query = this.provider.wasm.contractQuery.bind(this.provider.wasm) - const search: Search = this.provider.tx.search.bind(this.provider.tx) - const onchainData = await inspectInstruction.makeOnchainData(query, search)(data, input, this.args[0]) - const inspectData = await inspectInstruction.makeInspectionData(query)(input) + const onchainData = await inspectInstruction.makeOnchainData(this.provider)(data, input, this.args[0]) + const inspectData = await inspectInstruction.makeInspectionData(this.provider)(input) const inspection = inspectInstruction.inspect(inspectData, onchainData) return { data: inspection, diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/link/transfer.ts b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/link/transfer.ts index fe8a4f19..725838e8 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/link/transfer.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/link/transfer.ts @@ -1,6 +1,6 @@ import { BN, logger, prompt } from '@chainlink/gauntlet-core/dist/utils' import { CATEGORIES, TOKEN_DECIMALS } from '../../../lib/constants' -import { AbstractInstruction, BeforeExecutionContext, instructionToCommand } from '../../abstract/executionWrapper' +import { AbstractInstruction, ExecutionContext, instructionToCommand } from '../../abstract/executionWrapper' import { AccAddress } from '@terra-money/terra.js' type CommandInput = { @@ -35,7 +35,7 @@ const makeContractInput = async (input: CommandInput): Promise => } } -const beforeExecute = (context: BeforeExecutionContext) => async (): Promise => { +const beforeExecute = (context: ExecutionContext) => async (): Promise => { logger.info( `Transferring ${context.contractInput.amount} (${context.input.amount}) Tokens to ${context.contractInput.recipient}`, ) diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/deploy.ts b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/deploy.ts index 0a898772..9bccc741 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/deploy.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/deploy.ts @@ -1,7 +1,6 @@ -import { getRDD } from '../../../lib/rdd' +import { RDD } from '@chainlink/gauntlet-terra' import { instructionToCommand, AbstractInstruction } from '../../abstract/executionWrapper' import { CATEGORIES } from '../../../lib/constants' -import { CONTRACT_LIST } from '../../../lib/contracts' type CommandInput = { billingAccessController: string @@ -25,7 +24,7 @@ type ContractInput = { const makeCommandInput = async (flags: any, args: string[]): Promise => { if (flags.input) return flags.input as CommandInput - const rdd = getRDD(flags.rdd) + const rdd = RDD.getRDD(flags.rdd) const contract = args[0] const aggregator = rdd.contracts[contract] return { diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/inspection/inspect.ts b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/inspection/inspect.ts index cf9e01de..a19ce3de 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/inspection/inspect.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/inspection/inspect.ts @@ -1,12 +1,12 @@ import { BN, inspection, logger } from '@chainlink/gauntlet-core/dist/utils' +import { providerUtils, RDD } from '@chainlink/gauntlet-terra' import { CONTRACT_LIST } from '../../../../lib/contracts' import { CATEGORIES, TOKEN_UNIT } from '../../../../lib/constants' -import { getRDD } from '../../../../lib/rdd' -import { InspectInstruction, instructionToInspectCommand, Query, Search } from '../../../abstract/inspectionWrapper' +import { InspectInstruction, instructionToInspectCommand } from '../../../abstract/inspectionWrapper' import { deserializeConfig } from '../../../../lib/encoding' import { getOffchainConfigInput, OffchainConfig } from '../proposeOffchainConfig' import { toComparableNumber, wrappedComparableLongNumber } from '../../../../lib/inspection' -import { filterTxsByEvent, getBlockTxs } from '../../../../lib/provider' +import { LCDClient } from '@terra-money/terra.js' // Command input and expected info is the same here type ContractExpectedInfo = { @@ -29,7 +29,7 @@ type ContractExpectedInfo = { const makeInput = async (flags: any, args: string[]): Promise => { if (flags.input) return flags.input as ContractExpectedInfo - const rdd = getRDD(flags.rdd) + const rdd = RDD.getRDD(flags.rdd) const contract = args[0] const info = rdd.contracts[contract] const aggregatorOperators: string[] = info.oracles.map((o) => o.operator) @@ -56,7 +56,7 @@ const makeInput = async (flags: any, args: string[]): Promise async (input: ContractExpectedInfo): Promise => input -const makeOnchainData = (query: Query, search: Search) => async ( +const makeOnchainData = (provider: LCDClient) => async ( instructionsData: any[], input: ContractExpectedInfo, aggregator: string, @@ -74,7 +74,7 @@ const makeOnchainData = (query: Query, search: Search) => async ( const owedPerTransmitter: string[] = await Promise.all( transmitters.addresses.map((t) => { - return query(aggregator, { + return provider.wasm.contractQuery(aggregator, { owed_payment: { transmitter: t, }, @@ -83,7 +83,10 @@ const makeOnchainData = (query: Query, search: Search) => async ( ) // The contract only stores the block where the config was accepted. The tx log contains the config - const setConfigTx = filterTxsByEvent(await getBlockTxs(search, latestConfigDetails.block_number), 'wasm-set_config') + const setConfigTx = providerUtils.filterTxsByEvent( + await providerUtils.getBlockTxs(provider, latestConfigDetails.block_number), + 'wasm-set_config', + ) const event = setConfigTx?.logs?.[0].eventsByType['wasm-set_config'] const offchainConfig = event?.offchain_config ? await deserializeConfig(Buffer.from(event.offchain_config[0], 'hex')) diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/proposeConfig.ts b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/proposeConfig.ts index 7bac7818..30afe3ca 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/proposeConfig.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/proposeConfig.ts @@ -1,5 +1,5 @@ +import { RDD } from '@chainlink/gauntlet-terra' import { CATEGORIES } from '../../../lib/constants' -import { getRDD } from '../../../lib/rdd' import { AbstractInstruction, instructionToCommand } from '../../abstract/executionWrapper' type OnchainConfig = any @@ -23,7 +23,7 @@ type ContractInput = { const makeCommandInput = async (flags: any, args: string[]): Promise => { if (flags.input) return flags.input as CommandInput - const rdd = getRDD(flags.rdd) + const rdd = RDD.getRDD(flags.rdd) const contract = args[0] const aggregator = rdd.contracts[contract] const aggregatorOperators: any[] = aggregator.oracles.map((o) => rdd.operators[o.operator]) diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/proposeOffchainConfig.ts b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/proposeOffchainConfig.ts index c4af75ea..e07bdd41 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/proposeOffchainConfig.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/proposeOffchainConfig.ts @@ -1,10 +1,9 @@ -import { getRDD } from '../../../lib/rdd' +import { RDD } from '@chainlink/gauntlet-terra' import { AbstractInstruction, instructionToCommand } from '../../abstract/executionWrapper' import { time, BN } from '@chainlink/gauntlet-core/dist/utils' import { serializeOffchainConfig } from '../../../lib/encoding' import { ORACLES_MAX_LENGTH } from '../../../lib/constants' import { CATEGORIES } from '../../../lib/constants' -import { CONTRACT_LIST } from '../../../lib/contracts' type CommandInput = { proposalId: string @@ -89,7 +88,7 @@ export const getOffchainConfigInput = (rdd: any, contract: string): OffchainConf const makeCommandInput = async (flags: any, args: string[]): Promise => { if (flags.input) return flags.input as CommandInput - const rdd = getRDD(flags.rdd) + const rdd = RDD.getRDD(flags.rdd) const contract = args[0] return { diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/setBilling.ts b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/setBilling.ts index 0d436ca1..22b28916 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/setBilling.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/setBilling.ts @@ -1,5 +1,5 @@ import { BN } from '@chainlink/gauntlet-core/dist/utils' -import { getRDD } from '../../../lib/rdd' +import { RDD } from '@chainlink/gauntlet-terra' import { AbstractInstruction, instructionToCommand } from '../../abstract/executionWrapper' import { CATEGORIES } from '../../../lib/constants' import { CONTRACT_LIST } from '../../../lib/contracts' @@ -20,7 +20,7 @@ type ContractInput = { const makeCommandInput = async (flags: any, args: string[]): Promise => { if (flags.input) return flags.input as CommandInput - const rdd = getRDD(flags.rdd) + const rdd = RDD.getRDD(flags.rdd) const contract = args[0] const billingInfo = rdd.contracts[contract]?.billing return { diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ownership/acceptOwnership.ts b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ownership/acceptOwnership.ts index 8e1505c8..fa9e3464 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ownership/acceptOwnership.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ownership/acceptOwnership.ts @@ -1,8 +1,8 @@ import { AbstractInstruction, BeforeExecute } from '../../abstract/executionWrapper' +import { RDD } from '@chainlink/gauntlet-terra' import { CATEGORIES } from '../../../lib/constants' import { CONTRACT_LIST } from '../../../lib/contracts' import { logger, prompt } from '@chainlink/gauntlet-core/dist/utils' -import { getContractFromRDD, getRDD } from '../../../lib/rdd' type CommandInput = {} @@ -13,14 +13,14 @@ const makeContractInput = async (input: CommandInput): Promise => const validateInput = (input: CommandInput): boolean => true const beforeExecute: BeforeExecute = (context) => async (signer) => { - const currentOwner = await context.query(context.contract, 'owner') + const currentOwner = await context.provider.wasm.contractQuery(context.contract, 'owner' as any) if (!context.flags.rdd) { logger.warn('No RDD flag provided. Accepting ownership without RDD check') logger.info(`Accepting Ownership Transfer of contract with current owner ${currentOwner} to new owner `) await prompt('Continue?') return } - const contract = getContractFromRDD(getRDD(context.flags.rdd), context.contract) + const contract = RDD.getContractFromRDD(RDD.getRDD(context.flags.rdd), context.contract) logger.info(`Accepting Ownership Transfer of contract of type "${contract.type}": - Contract: ${contract.address} ${contract.description ? '- ' + contract.description : ''} - Current Owner: ${currentOwner} diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ownership/transferOwnership.ts b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ownership/transferOwnership.ts index a2bcce7e..f091e1d6 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ownership/transferOwnership.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ownership/transferOwnership.ts @@ -1,8 +1,8 @@ import { AccAddress } from '@terra-money/terra.js' +import { RDD } from '@chainlink/gauntlet-terra' import { AbstractInstruction, BeforeExecute } from '../../abstract/executionWrapper' import { CATEGORIES } from '../../../lib/constants' import { CONTRACT_LIST } from '../../../lib/contracts' -import { getContractFromRDD, getRDD } from '../../../lib/rdd' import { logger, prompt } from '@chainlink/gauntlet-core/dist/utils' type CommandInput = { @@ -34,7 +34,7 @@ const validateInput = (input: CommandInput): boolean => { } const beforeExecute: BeforeExecute = (context) => async () => { - const currentOwner = await context.query(context.contract, 'owner') + const currentOwner = await context.provider.wasm.contractQuery(context.contract, 'owner' as any) if (!context.flags.rdd) { logger.warn('No RDD flag provided. Transferring without RDD check') logger.info( @@ -43,7 +43,7 @@ const beforeExecute: BeforeExecute = (context) => a await prompt('Continue?') return } - const contract = getContractFromRDD(getRDD(context.flags.rdd), context.contract) + const contract = RDD.getContractFromRDD(RDD.getRDD(context.flags.rdd), context.contract) logger.info(`Proposing Ownership Transfer of contract of type "${contract.type}": - Contract: ${contract.address} ${contract.description ? '- ' + contract.description : ''} - Current Owner: ${currentOwner} diff --git a/packages-ts/gauntlet-terra-contracts/src/lib/provider.ts b/packages-ts/gauntlet-terra-contracts/src/lib/provider.ts deleted file mode 100644 index 82d2f8b3..00000000 --- a/packages-ts/gauntlet-terra-contracts/src/lib/provider.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { logger } from '@chainlink/gauntlet-core/dist/utils' -import { TxInfo } from '@terra-money/terra.js' -import { Search } from '../commands/abstract/inspectionWrapper' - -export const filterTxsByEvent = (txs: TxInfo[], event: string): TxInfo | undefined => { - const filteredTx = txs.filter((tx) => tx.logs?.some((log) => log.eventsByType[event]))?.[0] - return filteredTx -} - -export const getBlockTxs = async (search: Search, block: number, offset = 0): Promise => { - // recursive call to get every tx in the block. API has a 100 tx limit. Increasing the offset 100 every time - try { - const txs = await search({ - events: [ - { - key: 'tx.height', - value: String(block), - }, - ], - 'pagination.offset': String(offset), - }) - return txs.txs.concat(await getBlockTxs(search, block, offset + 100)) - } catch (e) { - logger.debug('No more txs in block') - } - - return [] -} diff --git a/packages-ts/gauntlet-terra/src/index.ts b/packages-ts/gauntlet-terra/src/index.ts index 5d73d8b8..b4b2a6a8 100644 --- a/packages-ts/gauntlet-terra/src/index.ts +++ b/packages-ts/gauntlet-terra/src/index.ts @@ -2,5 +2,7 @@ import TerraCommand from './commands/internal/terra' import { waitExecute } from './lib/execute' import { TransactionResponse } from './commands/types' import * as constants from './lib/constants' +import * as providerUtils from './lib/provider' +import * as RDD from './lib/rdd' -export { TerraCommand, waitExecute, TransactionResponse, constants } +export { TerraCommand, waitExecute, TransactionResponse, constants, providerUtils, RDD } diff --git a/packages-ts/gauntlet-terra/src/lib/provider.ts b/packages-ts/gauntlet-terra/src/lib/provider.ts new file mode 100644 index 00000000..218137a2 --- /dev/null +++ b/packages-ts/gauntlet-terra/src/lib/provider.ts @@ -0,0 +1,32 @@ +import { logger } from '@chainlink/gauntlet-core/dist/utils' +import { LCDClient, TxInfo } from '@terra-money/terra.js' + +export const filterTxsByEvent = (txs: TxInfo[], event: string): TxInfo | undefined => { + const filteredTx = txs.filter((tx) => tx.logs?.some((log) => log.eventsByType[event]))?.[0] + return filteredTx +} + +export const getBlockTxs = async (provider: LCDClient, block: number, offset = 0): Promise => { + // recursive call to get every tx in the block. API has a 100 tx limit. Increasing the offset 100 every time + try { + const txs = await provider.tx.search({ + events: [ + { + key: 'tx.height', + value: String(block), + }, + ], + 'pagination.offset': String(offset), + }) + return txs.txs.concat(await getBlockTxs(provider, block, offset + 100)) + } catch (e) { + const expectedError = 'page should be within' + if (!((e.response?.data?.message as string) || '').includes(expectedError)) { + logger.error(`Error fetching block ${block} and offset ${offset}: ${e.response?.data?.message || e.message}`) + return [] + } + logger.debug(`No more txs in block ${block}. Last offset ${offset}`) + } + + return [] +} diff --git a/packages-ts/gauntlet-terra-contracts/src/lib/rdd.ts b/packages-ts/gauntlet-terra/src/lib/rdd.ts similarity index 100% rename from packages-ts/gauntlet-terra-contracts/src/lib/rdd.ts rename to packages-ts/gauntlet-terra/src/lib/rdd.ts From 92d09d1ce25c4cec4c1a790b2604fa46c4356ee3 Mon Sep 17 00:00:00 2001 From: RodrigoAD <15104916+RodrigoAD@users.noreply.github.com> Date: Thu, 3 Mar 2022 16:25:35 +0100 Subject: [PATCH 4/6] updated test --- tests/e2e/smoke/gauntlet_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/smoke/gauntlet_test.go b/tests/e2e/smoke/gauntlet_test.go index ff39833d..59dcc445 100644 --- a/tests/e2e/smoke/gauntlet_test.go +++ b/tests/e2e/smoke/gauntlet_test.go @@ -116,7 +116,7 @@ var _ = Describe("Terra Gauntlet @gauntlet", func() { // ocr2:inspect results := gd.OcrInspect(gd.OCR, digest, gd.RddPath) - Expect(len(results)).Should(Equal(10), "Did not find the expected number of results in the output") + Expect(len(results)).Should(Equal(28), "Did not find the expected number of results in the output") for _, v := range results { Expect(v.Pass).Should(Equal(true), fmt.Sprintf("%s expected %s but actually %s", v.Key, v.Expected, v.Actual)) From e61d880c4fc8bd4eca815d67a4a32d8e02135c02 Mon Sep 17 00:00:00 2001 From: RodrigoAD <15104916+RodrigoAD@users.noreply.github.com> Date: Thu, 3 Mar 2022 17:49:57 +0100 Subject: [PATCH 5/6] hex to base64 --- .../src/commands/contracts/ocr2/inspection/inspect.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/inspection/inspect.ts b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/inspection/inspect.ts index a19ce3de..3ea04389 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/inspection/inspect.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/ocr2/inspection/inspect.ts @@ -89,7 +89,7 @@ const makeOnchainData = (provider: LCDClient) => async ( ) const event = setConfigTx?.logs?.[0].eventsByType['wasm-set_config'] const offchainConfig = event?.offchain_config - ? await deserializeConfig(Buffer.from(event.offchain_config[0], 'hex')) + ? await deserializeConfig(Buffer.from(event.offchain_config[0], 'base64')) : ({} as OffchainConfig) return { From c6b4d3e36a991ac665440075df3418fb28b0a647 Mon Sep 17 00:00:00 2001 From: Tate Date: Thu, 3 Mar 2022 10:00:48 -0700 Subject: [PATCH 6/6] Update guantlet e2e test to use an rdd with all non zero false values so the inspect command can check all values have changed No longer use the digest in the test as it is not needed --- tests/e2e/gauntlet_deployer.go | 3 +-- tests/e2e/rdd.go | 6 +++--- tests/e2e/smoke/gauntlet_test.go | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/tests/e2e/gauntlet_deployer.go b/tests/e2e/gauntlet_deployer.go index 23006ed7..781a14c8 100644 --- a/tests/e2e/gauntlet_deployer.go +++ b/tests/e2e/gauntlet_deployer.go @@ -354,13 +354,12 @@ func (gd *GauntletDeployer) AcceptProposal(ocr, proposalId, proposalDigest, rddP } // OcrInspect gets the inspections results data -func (gd *GauntletDeployer) OcrInspect(ocr, digest, rddPath string) map[string]InspectionResult { +func (gd *GauntletDeployer) OcrInspect(ocr, rddPath string) map[string]InspectionResult { UpdateReportName("inspect", gd.Cli) output, err := gd.Cli.ExecCommandWithRetries([]string{ "ocr2:inspect", gd.Cli.Flag("version", gd.Version), gd.Cli.Flag("rdd", rddPath), - gd.Cli.Flag("digest", digest), ocr, }, []string{ TERRA_COMMAND_ERROR, diff --git a/tests/e2e/rdd.go b/tests/e2e/rdd.go index 56d1a602..06c306c4 100644 --- a/tests/e2e/rdd.go +++ b/tests/e2e/rdd.go @@ -58,15 +58,15 @@ func NewRddContract(contractId string) *RddConfig { "deltaStage": "14s", "f": 1, "maxDurationObservation": "1s", - "maxDurationQuery": "0s", + "maxDurationQuery": "1s", "maxDurationReport": "5s", "maxDurationShouldAcceptFinalizedReport": "1s", "maxDurationShouldTransmitAcceptedReport": "1s", "rMax": 6, "reportingPluginConfig": map[string]interface{}{ - "alphaAcceptInfinite": false, + "alphaAcceptInfinite": true, "alphaAcceptPpb": "3000000", - "alphaReportInfinite": false, + "alphaReportInfinite": true, "alphaReportPpb": "3000000", "deltaC": "50s", }, diff --git a/tests/e2e/smoke/gauntlet_test.go b/tests/e2e/smoke/gauntlet_test.go index 59dcc445..4e8697cd 100644 --- a/tests/e2e/smoke/gauntlet_test.go +++ b/tests/e2e/smoke/gauntlet_test.go @@ -112,10 +112,10 @@ var _ = Describe("Terra Gauntlet @gauntlet", func() { gd.ProposalDigest = gd.FinalizeProposal(gd.OCR, gd.ProposalId, gd.RddPath) // ocr2:accept_proposal - digest := gd.AcceptProposal(gd.OCR, gd.ProposalId, gd.ProposalDigest, gd.RddPath) + gd.AcceptProposal(gd.OCR, gd.ProposalId, gd.ProposalDigest, gd.RddPath) // ocr2:inspect - results := gd.OcrInspect(gd.OCR, digest, gd.RddPath) + results := gd.OcrInspect(gd.OCR, gd.RddPath) Expect(len(results)).Should(Equal(28), "Did not find the expected number of results in the output") for _, v := range results { Expect(v.Pass).Should(Equal(true), fmt.Sprintf("%s expected %s but actually %s", v.Key, v.Expected, v.Actual))