From bd15f2963120353e9f15cd688fa1fc20d29501be Mon Sep 17 00:00:00 2001 From: chase-45 Date: Wed, 1 Nov 2023 22:19:55 -0400 Subject: [PATCH] abstract handler typing changes --- blockchain-watcher/src/environment.ts | 26 ++- .../src/handlers/AbstractHandler.ts | 14 +- .../src/handlers/deliveryEventHandler.ts | 186 +++++++++--------- .../src/handlers/sendEventHandler.ts | 138 ++++++------- .../src/watchers/AbstractWatcher.ts | 6 +- blockchain-watcher/src/watchers/EvmWatcher.ts | 4 +- 6 files changed, 187 insertions(+), 187 deletions(-) diff --git a/blockchain-watcher/src/environment.ts b/blockchain-watcher/src/environment.ts index daf31462..4ef030bf 100644 --- a/blockchain-watcher/src/environment.ts +++ b/blockchain-watcher/src/environment.ts @@ -73,7 +73,7 @@ type HandlerConfig = { type ConfigFile = { network: Network; supportedChains: ChainId[]; - rpcs: { chain: ChainId; rpcs: string[] }[]; + rpcs: { chain: ChainId; rpc: string }[]; handlers: HandlerConfig[]; }; @@ -82,7 +82,7 @@ type Environment = { configurationPath: any; configuration: ConfigFile; supportedChains: ChainId[]; - rpcs: Map; + rpcs: Map; logger: winston.Logger; }; @@ -112,21 +112,17 @@ export async function initializeEnvironment(configurationPath: string) { } const configRpcs = json.rpcs; - const rpcs = new Map(); + const rpcs = new Map(); for (const chain of supportedChains) { - let rpcArray: string[] = []; configRpcs.forEach((item: any) => { //double equals for string/int equality if (item.chain == chain) { - rpcArray = item.rpcs; + if (!item.rpc) { + throw new Error(`No RPC provided for chain ${chain}`); + } + rpcs.set(chain, item.rpc); } }); - - if (rpcArray.length === 0) { - throw new Error(`No RPCs provided for chain ${chain}`); - } - - rpcs.set(chain, rpcArray); } environment = { @@ -161,16 +157,16 @@ export function createWatchers( ): AbstractWatcher[] { const watchers: AbstractWatcher[] = []; for (const chain of env.supportedChains) { - const rpcs = env.rpcs.get(chain); - if (!rpcs) { - throw new Error(`No RPCs provided for chain ${chain}`); + const rpc = env.rpcs.get(chain); + if (!rpc) { + throw new Error(`No RPC provided for chain ${chain}`); } const watcher = new EvmWatcher( toChainName(chain) + " Watcher", env.network, handlers, chain, - rpcs, + rpc, env.logger ); watchers.push(watcher); diff --git a/blockchain-watcher/src/handlers/AbstractHandler.ts b/blockchain-watcher/src/handlers/AbstractHandler.ts index 8fc2a0f1..b90c7cc0 100644 --- a/blockchain-watcher/src/handlers/AbstractHandler.ts +++ b/blockchain-watcher/src/handlers/AbstractHandler.ts @@ -2,17 +2,17 @@ import { ChainId, Network } from "@certusone/wormhole-sdk"; import { v4 as uuidv4 } from "uuid"; const { createHash } = require("crypto"); -type SyntheticEvent = { +type SyntheticEvent = { eventName: string; eventVersion: number; eventChain: ChainId; observationTimestamp: number; uuid: string; //UUID for the event, good for deduping dataHash: string; //sha256 hash of the event data, good for deduping - data: any; + data: T; }; -export default abstract class EventHandler { +export default abstract class AbstractHandler { public name: string; constructor(name: string) { @@ -40,7 +40,7 @@ export default abstract class EventHandler { public abstract handleEventEvm( chainId: ChainId, ...args: any - ): Promise; + ): Promise[]>; public abstract getContractAddressEvm( network: Network, chainId: ChainId @@ -50,7 +50,7 @@ export default abstract class EventHandler { //Wrapper function to hand into EVM rpc provider. //The wrapper is necessary otherwise we can't figure out which chain ID the event came from. - public getEventListener(handler: EventHandler, chainId: ChainId) { + public getEventListener(handler: AbstractHandler, chainId: ChainId) { //@ts-ignore return (...args) => { // @ts-ignore @@ -84,8 +84,8 @@ export default abstract class EventHandler { private wrapEvent( chainId: ChainId, version: number, - data: any - ): SyntheticEvent { + data: T + ): SyntheticEvent { return { eventName: this.name, eventVersion: version, diff --git a/blockchain-watcher/src/handlers/deliveryEventHandler.ts b/blockchain-watcher/src/handlers/deliveryEventHandler.ts index 402abd89..c5b343ad 100644 --- a/blockchain-watcher/src/handlers/deliveryEventHandler.ts +++ b/blockchain-watcher/src/handlers/deliveryEventHandler.ts @@ -1,103 +1,105 @@ -import { TypedEvent } from "@certusone/wormhole-sdk/lib/cjs/ethers-contracts/common"; -import { ethers } from "ethers"; -import { getEnvironment } from "../environment"; -import { CHAIN_ID_TO_NAME, ChainId, Network } from "@certusone/wormhole-sdk"; -import AbstractHandler from "./AbstractHandler"; +//TODO refactor this to use the new event handler system +export {}; +// import { TypedEvent } from "@certusone/wormhole-sdk/lib/cjs/ethers-contracts/common"; +// import { ethers } from "ethers"; +// import { getEnvironment } from "../environment"; +// import { CHAIN_ID_TO_NAME, ChainId, Network } from "@certusone/wormhole-sdk"; +// import AbstractHandler from "./AbstractHandler"; -//TODOD consider additional fields: -// - timestamp -// - block number -// - call data -// - transaction cost -// - full transaction receipt -export type WormholeRelayerDeliveryEventRecord = { - environment: string; - chainId: ChainId; - txHash: string; - recipientContract: string; - sourceChain: number; - sequence: string; - deliveryVaaHash: string; - status: number; - gasUsed: string; - refundStatus: number; - additionalStatusInfo: string; - overridesInfo: string; -}; +// //TODOD consider additional fields: +// // - timestamp +// // - block number +// // - call data +// // - transaction cost +// // - full transaction receipt +// export type WormholeRelayerDeliveryEventRecord = { +// environment: string; +// chainId: ChainId; +// txHash: string; +// recipientContract: string; +// sourceChain: number; +// sequence: string; +// deliveryVaaHash: string; +// status: number; +// gasUsed: string; +// refundStatus: number; +// additionalStatusInfo: string; +// overridesInfo: string; +// }; -//TODO implement this such that it pushes the event to a database -async function persistRecord(record: WormholeRelayerDeliveryEventRecord) { - console.log(JSON.stringify(record)); -} +// //TODO implement this such that it pushes the event to a database +// async function persistRecord(record: WormholeRelayerDeliveryEventRecord) { +// console.log(JSON.stringify(record)); +// } -function getEventAbi(): string[] { - return [ - "event Delivery(address indexed recipientContract, uint16 indexed sourceChain, uint64 indexed sequence, bytes32 deliveryVaaHash, uint8 status, uint256 gasUsed, uint8 refundStatus, bytes additionalStatusInfo, bytes overridesInfo)", - ]; -} +// function getEventAbi(): string[] { +// return [ +// "event Delivery(address indexed recipientContract, uint16 indexed sourceChain, uint64 indexed sequence, bytes32 deliveryVaaHash, uint8 status, uint256 gasUsed, uint8 refundStatus, bytes additionalStatusInfo, bytes overridesInfo)", +// ]; +// } -function getEventSignatureEvm(): string { - return "Delivery(address,uint16,uint64,bytes32,uint8,uint256,uint8,bytes,bytes)"; -} +// function getEventSignatureEvm(): string { +// return "Delivery(address,uint16,uint64,bytes32,uint8,uint256,uint8,bytes,bytes)"; +// } -async function handleEventEvm( - chainId: ChainId, - eventObj: ethers.Event -): Promise { - console.log( - `Received Delivery event for Wormhole Relayer Contract, txHash: ${eventObj.transactionHash}` - ); - const environment = await getEnvironment(); - const txHash = eventObj.transactionHash; - var abi = getEventAbi(); - var iface = new ethers.utils.Interface(abi); - var parsedLog = iface.parseLog(eventObj); +// async function handleEventEvm( +// chainId: ChainId, +// eventObj: ethers.Event +// ): Promise> { +// console.log( +// `Received Delivery event for Wormhole Relayer Contract, txHash: ${eventObj.transactionHash}` +// ); +// const environment = await getEnvironment(); +// const txHash = eventObj.transactionHash; +// var abi = getEventAbi(); +// var iface = new ethers.utils.Interface(abi); +// var parsedLog = iface.parseLog(eventObj); - const recipientContract = parsedLog.args[0]; - const sourceChain = parsedLog.args[1]; - const sequence = parsedLog.args[2].toString(); - const deliveryVaaHash = parsedLog.args[3]; - const status = parsedLog.args[4]; - const gasUsed = parsedLog.args[5].toString(); - const refundStatus = parsedLog.args[6]; - const additionalStatusInfo = parsedLog.args[7]; - const overridesInfo = parsedLog.args[8]; +// const recipientContract = parsedLog.args[0]; +// const sourceChain = parsedLog.args[1]; +// const sequence = parsedLog.args[2].toString(); +// const deliveryVaaHash = parsedLog.args[3]; +// const status = parsedLog.args[4]; +// const gasUsed = parsedLog.args[5].toString(); +// const refundStatus = parsedLog.args[6]; +// const additionalStatusInfo = parsedLog.args[7]; +// const overridesInfo = parsedLog.args[8]; - return { - environment: environment.network, - chainId, - txHash, - recipientContract, - sourceChain, - sequence, - deliveryVaaHash, - status, - gasUsed, - refundStatus, - additionalStatusInfo, - overridesInfo, - }; -} +// return AbstractHandler.prototype.wrapEvent(chainId, 1, { +// environment: environment.network, +// chainId, +// txHash, +// recipientContract, +// sourceChain, +// sequence, +// deliveryVaaHash, +// status, +// gasUsed, +// refundStatus, +// additionalStatusInfo, +// overridesInfo, +// }); +// } -function getContractAddressEvm(network: Network, chainId: ChainId): string { - return ""; //TODO //getWormholeRelayerAddressWrapped(CHAIN_ID_TO_NAME[chainId], network); -} +// function getContractAddressEvm(network: Network, chainId: ChainId): string { +// return ""; //TODO //getWormholeRelayerAddressWrapped(CHAIN_ID_TO_NAME[chainId], network); +// } -function shouldSupportChain(network: Network, chainId: ChainId): boolean { - return true; //TODO currently the supported chains are determined by the relayer contract, so this is trivially true. - //It might not be true in the future. -} +// function shouldSupportChain(network: Network, chainId: ChainId): boolean { +// return true; //TODO currently the supported chains are determined by the relayer contract, so this is trivially true. +// //It might not be true in the future. +// } -const WormholeRelayerEventHandler: AbstractHandler = - { - name: "Wormhole Relayer Delivery Event Handler", - getEventSignatureEvm, - getEventAbiEvm: getEventAbi, - handleEventEvm, - persistRecord, - getContractAddressEvm, - shouldSupportChain, - getEventListener: AbstractHandler.prototype.getEventListener, //TODO not any of this - }; +// const WormholeRelayerEventHandler: AbstractHandler = +// { +// name: "Wormhole Relayer Delivery Event Handler", +// getEventSignatureEvm, +// getEventAbiEvm: getEventAbi, +// handleEventEvm, +// persistRecord, +// getContractAddressEvm, +// shouldSupportChain, +// getEventListener: AbstractHandler.prototype.getEventListener, //TODO not any of this +// }; -export default WormholeRelayerEventHandler; +// export default WormholeRelayerEventHandler; diff --git a/blockchain-watcher/src/handlers/sendEventHandler.ts b/blockchain-watcher/src/handlers/sendEventHandler.ts index cd1c5434..bb6a8ee7 100644 --- a/blockchain-watcher/src/handlers/sendEventHandler.ts +++ b/blockchain-watcher/src/handlers/sendEventHandler.ts @@ -1,78 +1,80 @@ -import { TypedEvent } from "@certusone/wormhole-sdk/lib/cjs/ethers-contracts/common"; -import { ethers } from "ethers"; -import { getEnvironment } from "../environment"; -import { CHAIN_ID_TO_NAME, ChainId, Network } from "@certusone/wormhole-sdk"; -import AbstractHandler from "./AbstractHandler"; +//TODO refactor this to use the new event handler system +export {}; +// import { TypedEvent } from "@certusone/wormhole-sdk/lib/cjs/ethers-contracts/common"; +// import { ethers } from "ethers"; +// import { getEnvironment } from "../environment"; +// import { CHAIN_ID_TO_NAME, ChainId, Network } from "@certusone/wormhole-sdk"; +// import AbstractHandler from "./AbstractHandler"; -//TODOD consider additional fields: -// - timestamp -// - entire transaction receipt -// - deduplication info -export type WormholeRelayerSendEventRecord = { - environment: string; - chainId: ChainId; - txHash: string; - sequence: string; - deliveryQuote: string; - paymentForExtraReceiverValue: string; -}; +// //TODOD consider additional fields: +// // - timestamp +// // - entire transaction receipt +// // - deduplication info +// export type WormholeRelayerSendEventRecord = { +// environment: string; +// chainId: ChainId; +// txHash: string; +// sequence: string; +// deliveryQuote: string; +// paymentForExtraReceiverValue: string; +// }; -//TODO implement this such that it pushes the event to a database -async function persistRecord(record: WormholeRelayerSendEventRecord) { - console.log(JSON.stringify(record)); -} +// //TODO implement this such that it pushes the event to a database +// async function persistRecord(record: WormholeRelayerSendEventRecord) { +// console.log(JSON.stringify(record)); +// } -function getEventAbiEvm(): string[] { - return [ - "event SendEvent(uint64 indexed sequence, uint256 deliveryQuote, uint256 paymentForExtraReceiverValue)", - ]; -} +// function getEventAbiEvm(): string[] { +// return [ +// "event SendEvent(uint64 indexed sequence, uint256 deliveryQuote, uint256 paymentForExtraReceiverValue)", +// ]; +// } -async function handleEventEvm( - chainId: ChainId, - eventObj: ethers.Event -): Promise { - console.log( - `Received Send event for Wormhole Relayer Contract, txHash: ${eventObj.transactionHash}` - ); - const abi = getEventAbiEvm(); - var iface = new ethers.utils.Interface(abi); - var parsedLog = iface.parseLog(eventObj); +// async function handleEventEvm( +// chainId: ChainId, +// eventObj: ethers.Event +// ): Promise { +// console.log( +// `Received Send event for Wormhole Relayer Contract, txHash: ${eventObj.transactionHash}` +// ); +// const abi = getEventAbiEvm(); +// var iface = new ethers.utils.Interface(abi); +// var parsedLog = iface.parseLog(eventObj); - return { - //TODO env type broke - environment: await getEnvironment().network, - chainId: chainId, - txHash: eventObj.transactionHash, - sequence: parsedLog.args[0].toString(), - deliveryQuote: parsedLog.args[1].toString(), - paymentForExtraReceiverValue: parsedLog.args[2].toString(), - }; -} +// return { +// //TODO env type broke +// environment: await getEnvironment().network, +// chainId: chainId, +// txHash: eventObj.transactionHash, +// sequence: parsedLog.args[0].toString(), +// deliveryQuote: parsedLog.args[1].toString(), +// paymentForExtraReceiverValue: parsedLog.args[2].toString(), +// }; +// } -function getContractAddressEvm(network: Network, chainId: ChainId): string { - return ""; //TODO //getWormholeRelayerAddressWrapped(CHAIN_ID_TO_NAME[chainId], network); -} +// function getContractAddressEvm(network: Network, chainId: ChainId): string { +// return ""; //TODO //getWormholeRelayerAddressWrapped(CHAIN_ID_TO_NAME[chainId], network); +// } -function shouldSupportChain(network: Network, chainId: ChainId): boolean { - return true; //TODO currently the supported chains are determined by the relayer contract, so this is trivially true. - //It might not be true in the future. -} +// function shouldSupportChain(network: Network, chainId: ChainId): boolean { +// return true; //TODO currently the supported chains are determined by the relayer contract, so this is trivially true. +// //It might not be true in the future. +// } -function getEventSignatureEvm(): string { - return "SendEvent(uint64,uint256,uint256)"; -} +// function getEventSignatureEvm(): string { +// return "SendEvent(uint64,uint256,uint256)"; +// } -const WormholeRelayerSendEventHandler: AbstractHandler = - { - name: "Wormhole Relayer Send Event Handler", - getEventSignatureEvm, - getEventAbiEvm, - handleEventEvm, - persistRecord, - getContractAddressEvm, - shouldSupportChain, - getEventListener: AbstractHandler.prototype.getEventListener, //TODO not any of this - }; +// const WormholeRelayerSendEventHandler: AbstractHandler = +// { +// name: "Wormhole Relayer Send Event Handler", +// getEventSignatureEvm, +// getEventAbiEvm, +// handleEventEvm, +// persistRecord, +// getContractAddressEvm, +// shouldSupportChain, +// getEventListener: AbstractHandler.prototype.getEventListener, //TODO not any of this +// }; -export default WormholeRelayerSendEventHandler; +// export default WormholeRelayerSendEventHandler; diff --git a/blockchain-watcher/src/watchers/AbstractWatcher.ts b/blockchain-watcher/src/watchers/AbstractWatcher.ts index d57f4d5f..db43f9a3 100644 --- a/blockchain-watcher/src/watchers/AbstractWatcher.ts +++ b/blockchain-watcher/src/watchers/AbstractWatcher.ts @@ -7,7 +7,7 @@ export default abstract class AbstractWatcher { public environment: Network; public events: AbstractHandler[]; public chain: ChainId; - public rpcs: string[]; + public rpc: string; public logger: any; //TODO add persistence module(s) as class fields @@ -18,14 +18,14 @@ export default abstract class AbstractWatcher { environment: Network, events: AbstractHandler[], chain: ChainId, - rpcs: string[], + rpc: string, logger: any ) { this.watcherName = watcherName; this.environment = environment; this.events = events; this.chain = chain; - this.rpcs = rpcs; + this.rpc = rpc; this.logger = logger; } diff --git a/blockchain-watcher/src/watchers/EvmWatcher.ts b/blockchain-watcher/src/watchers/EvmWatcher.ts index ea11e1f2..a6de4f38 100644 --- a/blockchain-watcher/src/watchers/EvmWatcher.ts +++ b/blockchain-watcher/src/watchers/EvmWatcher.ts @@ -8,10 +8,10 @@ export default class EvmWatcher extends AbstractWatcher { environment: Network, events: AbstractHandler[], chain: ChainId, - rpcs: string[], + rpc: string, logger: any ) { - super(watcherName, environment, events, chain, rpcs, logger); + super(watcherName, environment, events, chain, rpc, logger); } async startWebsocketProcessor(): Promise {