trevor/read-txs-nov-8
Trevor Porter 4 weeks ago
parent 969a229778
commit 2d428f40b1
  1. 21
      typescript/infra/scripts/safes/parse-multicall.ts
  2. 106
      typescript/infra/src/tx/transaction-reader.ts

@ -1,6 +1,8 @@
import { normalizeConfig } from '@hyperlane-xyz/sdk';
import { stringifyObject, strip0x } from '@hyperlane-xyz/utils'; import { stringifyObject, strip0x } from '@hyperlane-xyz/utils';
import { TransactionReader } from '../../src/tx/transaction-reader.js'; import { TransactionReader } from '../../src/tx/transaction-reader.js';
import { readYaml } from '../../src/utils/utils.js';
import { getArgs } from '../agent-utils.js'; import { getArgs } from '../agent-utils.js';
import { getEnvironmentConfig, getHyperlaneCore } from '../core-utils.js'; import { getEnvironmentConfig, getHyperlaneCore } from '../core-utils.js';
@ -12,17 +14,32 @@ async function main() {
const multiProvider = await config.getMultiProvider(); const multiProvider = await config.getMultiProvider();
const { chainAddresses } = await getHyperlaneCore(environment, multiProvider); const { chainAddresses } = await getHyperlaneCore(environment, multiProvider);
// const yaml: any = readYaml('/Users/trevor/example-mismatch.yaml');
// const mismatch = yaml[0];
// const normalizedDerived = normalizeConfig(mismatch.derivedConfig);
// const normalizedExpected = normalizeConfig(mismatch.expectedIsmConfig);
// console.log('\n\n\n\n\n\nDerived:', stringifyObject(normalizedDerived, 'yaml', 2));
// console.log('\n\n\n\n\n\nExpected:', stringifyObject(normalizedExpected, 'yaml', 2));
// return;
const reader = new TransactionReader( const reader = new TransactionReader(
environment, environment,
multiProvider, multiProvider,
'ethereum', 'ethereum',
chainAddresses, chainAddresses,
config.core,
); );
const results = await reader.read('ethereum', tx); const results = await reader.read('ethereum', tx);
console.log('results', results);
console.log(stringifyObject(results, 'yaml', 2)); console.log(stringifyObject(results, 'yaml', 2));
if (reader.errors.length) {
console.error('❌❌❌❌❌ Encountered fatal errors ❌❌❌❌❌');
console.log(stringifyObject(reader.errors, 'yaml', 2));
console.error('❌❌❌❌❌ Encountered fatal errors ❌❌❌❌❌');
process.exit(1);
}
} }
main().catch((err) => { main().catch((err) => {

@ -4,20 +4,26 @@ import {
MetaTransactionData, MetaTransactionData,
OperationType, OperationType,
} from '@safe-global/safe-core-sdk-types'; } from '@safe-global/safe-core-sdk-types';
import { deepEqual } from 'assert';
import { BigNumber, ethers } from 'ethers'; import { BigNumber, ethers } from 'ethers';
import { import {
AnnotatedEV5Transaction, AnnotatedEV5Transaction,
ChainMap, ChainMap,
ChainName, ChainName,
CoreConfig,
EvmIsmReader,
HyperlaneReader, HyperlaneReader,
InterchainAccount, InterchainAccount,
MultiProvider, MultiProvider,
coreFactories,
interchainAccountFactories, interchainAccountFactories,
normalizeConfig,
} from '@hyperlane-xyz/sdk'; } from '@hyperlane-xyz/sdk';
import { import {
addressToBytes32, addressToBytes32,
bytes32ToAddress, bytes32ToAddress,
deepEquals,
eqAddress, eqAddress,
retryAsync, retryAsync,
sleep, sleep,
@ -60,6 +66,7 @@ export class TransactionReader extends HyperlaneReader {
readonly multiProvider: MultiProvider, readonly multiProvider: MultiProvider,
readonly chain: ChainName, readonly chain: ChainName,
readonly chainAddresses: ChainMap<Record<string, string>>, readonly chainAddresses: ChainMap<Record<string, string>>,
readonly coreConfig: ChainMap<CoreConfig>,
) { ) {
super(multiProvider, chain); super(multiProvider, chain);
} }
@ -74,11 +81,16 @@ export class TransactionReader extends HyperlaneReader {
} }
async doRead(chain: ChainName, tx: AnnotatedEV5Transaction): Promise<any> { async doRead(chain: ChainName, tx: AnnotatedEV5Transaction): Promise<any> {
// If it's an ICA // If it's to an ICA
if (this.isIcaTransaction(chain, tx)) { if (this.isIcaTransaction(chain, tx)) {
return this.readIcaTransaction(chain, tx); return this.readIcaTransaction(chain, tx);
} }
// If it's to a Mailbox
if (this.isMailboxTransaction(chain, tx)) {
return this.readMailboxTransaction(chain, tx);
}
if (await this.isMultisendTransaction(chain, tx)) { if (await this.isMultisendTransaction(chain, tx)) {
return this.readMultisendTransaction(chain, tx); return this.readMultisendTransaction(chain, tx);
} }
@ -163,6 +175,88 @@ export class TransactionReader extends HyperlaneReader {
}); });
} }
private async readMailboxTransaction(
chain: ChainName,
tx: AnnotatedEV5Transaction,
): Promise<any> {
if (!tx.data) {
console.log('No data in mailbox transaction');
return undefined;
}
const { symbol } = await this.multiProvider.getNativeToken(chain);
const decoded = coreFactories.mailbox.interface.parseTransaction({
data: tx.data,
value: tx.value,
});
const args = formatFunctionFragmentArgs(
decoded.args,
decoded.functionFragment,
);
let prettyArgs = args;
if (decoded.functionFragment.name === 'setDefaultIsm') {
prettyArgs = await this.formatMailboxSetDefaultIsm(chain, args);
}
return {
signature: decoded.signature,
args: prettyArgs,
};
}
ismDerivationsInProgress: ChainMap<boolean> = {};
private async formatMailboxSetDefaultIsm(
chain: ChainName,
args: Record<string, any>,
): Promise<any> {
const { _module: module } = args;
const reader = new EvmIsmReader(this.multiProvider, chain);
const startTime = Date.now();
console.log('Deriving ISM config...', chain);
this.ismDerivationsInProgress[chain] = true;
const derivedConfig = await reader.deriveIsmConfig(module);
delete this.ismDerivationsInProgress[chain];
console.log(
'Finished deriving ISM config',
chain,
'in',
(Date.now() - startTime) / (1000 * 60),
'mins',
);
const remainingInProgress = Object.keys(this.ismDerivationsInProgress);
console.log(
'Remaining derivations in progress:',
remainingInProgress.length,
'chains',
remainingInProgress,
);
const expectedIsmConfig = this.coreConfig[chain].defaultIsm;
let insight = '✅ matches expected ISM config';
if (
!deepEquals(
normalizeConfig(derivedConfig),
normalizeConfig(expectedIsmConfig),
)
) {
this.errors.push({
chain: chain,
module,
derivedConfig,
expectedIsmConfig,
info: 'Incorrect default ISM being set',
});
insight = `❌ fatal mismatch of ISM config`;
}
return {
module,
insight,
};
}
private async readIcaCall( private async readIcaCall(
chain: ChainName, chain: ChainName,
args: Record<string, any>, args: Record<string, any>,
@ -334,6 +428,13 @@ export class TransactionReader extends HyperlaneReader {
); );
} }
isMailboxTransaction(chain: ChainName, tx: AnnotatedEV5Transaction): boolean {
return (
tx.to !== undefined &&
eqAddress(tx.to, this.chainAddresses[chain].mailbox)
);
}
async isMultisendTransaction( async isMultisendTransaction(
chain: ChainName, chain: ChainName,
tx: AnnotatedEV5Transaction, tx: AnnotatedEV5Transaction,
@ -362,8 +463,7 @@ export class TransactionReader extends HyperlaneReader {
} }
const safe = safes[chain]; const safe = safes[chain];
if (!safe) {
if (safe) {
return undefined; return undefined;
} }

Loading…
Cancel
Save