11import { join } from "node:path" ;
22import { PutObjectCommand , S3Client } from "@aws-sdk/client-s3" ;
3- import type {
4- EIP1193Parameters ,
5- HttpTransportConfig ,
6- PublicRpcSchema ,
7- } from "viem" ;
3+ import { type EthCallRequest , EthCallSpy } from "@gearbox-protocol/sdk/dev" ;
84import type { Config } from "./config/index.js" ;
95import { DI } from "./di.js" ;
106import { type ILogger , Logger } from "./log/index.js" ;
117
12- type DetectedCall = EIP1193Parameters < PublicRpcSchema > & {
13- headers ?: Record < string , string > ;
14- } ;
15-
168/**
179 * This is temporary solution to diagnose bug where compressor occasionally returns many accounts with HF = 0
1810 */
@@ -24,50 +16,25 @@ export default class MulticallSpy {
2416 @DI . Inject ( DI . Config )
2517 config ! : Config ;
2618
19+ public readonly spy : EthCallSpy ;
2720 #client = new S3Client ( { } ) ;
28- #detectedCalls: DetectedCall [ ] = [ ] ;
29- #detectedBlock = 0n ;
30-
31- public multicallRequestSpy : Required < HttpTransportConfig > [ "onFetchRequest" ] =
32- async request => {
33- if ( ! this . config . debugScanner || this . config . optimistic ) {
34- return ;
35- }
36- const data = ( await request . json ( ) ) as EIP1193Parameters < PublicRpcSchema > ;
37- const blockNumber = isGetCreditAccountsMulticall ( data ) ;
38- if ( blockNumber ) {
39- this . #storeCall( blockNumber , data ) ;
40- this . log . debug (
41- `stored getCreditAccounts multicall at block ${ blockNumber } , total calls: ${ this . #detectedCalls. length } ` ,
42- ) ;
43- }
44- } ;
4521
46- public multicallResponseSpy : Required < HttpTransportConfig > [ "onFetchResponse" ] =
47- async response => {
48- if ( ! this . config . debugScanner || this . config . optimistic ) {
49- return ;
50- }
51- const copy = response . clone ( ) ;
52- const resp = await copy . json ( ) ;
53- const id = ( resp as any ) . id as number ;
54- const call = this . #detectedCalls. find ( c => "id" in c && c . id === id ) ;
55- if ( call ) {
56- call . headers = Object . fromEntries ( response . headers . entries ( ) ) ;
57- }
58- } ;
22+ constructor ( ) {
23+ this . spy = new EthCallSpy (
24+ isGetCreditAccountsMulticall ,
25+ this . log ,
26+ this . config . debugScanner && ! this . config . optimistic ,
27+ ) ;
28+ }
5929
6030 public async dumpCalls ( ) : Promise < void > {
61- if ( ! this . config . debugScanner || this . config . optimistic ) {
62- return ;
63- }
6431 if ( ! this . config . outS3Bucket ) {
6532 this . log . error ( "outS3Bucket is not set" ) ;
6633 return ;
6734 }
6835 const key = join (
6936 this . config . outS3Prefix ,
70- `getCreditAccounts_${ this . # detectedBlock} .json` ,
37+ `getCreditAccounts_${ this . spy . detectedBlock } .json` ,
7138 ) ;
7239 const s3Url = `s3://${ this . config . outS3Bucket } /${ key } ` ;
7340 try {
@@ -77,42 +44,27 @@ export default class MulticallSpy {
7744 Bucket : this . config . outS3Bucket ,
7845 Key : key ,
7946 ContentType : "application/json" ,
80- Body : JSON . stringify ( this . # detectedCalls) ,
47+ Body : JSON . stringify ( this . spy . detectedCalls ) ,
8148 } ) ,
8249 ) ;
8350 this . log . debug ( `uploaded to ${ s3Url } ` ) ;
8451 } catch ( e ) {
8552 this . log . error ( e , `failed to upload to ${ s3Url } ` ) ;
8653 }
8754 }
88-
89- #storeCall(
90- blockNumber : bigint ,
91- data : EIP1193Parameters < PublicRpcSchema > ,
92- ) : void {
93- if ( blockNumber !== this . #detectedBlock) {
94- this . #detectedBlock = blockNumber ;
95- this . #detectedCalls = [ ] ;
96- }
97- this . #detectedCalls. push ( data ) ;
98- }
9955}
10056
10157/**
10258 * Detects multicalls to CreditAccounts.getCreditAccounts
10359 * @param data
10460 * @returns block number if it's a getCreditAccounts multicall, undefined otherwise
10561 */
106- function isGetCreditAccountsMulticall (
107- data : EIP1193Parameters < PublicRpcSchema > ,
108- ) : bigint | undefined {
62+ function isGetCreditAccountsMulticall ( data : EthCallRequest ) : boolean {
10963 try {
11064 if (
11165 data . method === "eth_call" &&
11266 // detect eth_call to multicall3: 0xca11bde05977b3631167028862be2a173976ca11
11367 data . params [ 0 ] . to === "0xca11bde05977b3631167028862be2a173976ca11" &&
114- typeof data . params [ 1 ] === "string" &&
115- data . params [ 1 ] ?. startsWith ( "0x" ) && // non-latest block
11668 // that contain CA compressor: "0x4115708Fc8fe6bB392De2e0C21c2C81dA2222394"
11769 data . params [ 0 ] . data ?. includes (
11870 "4115708fc8fe6bb392de2e0c21c2c81da2222394" ,
@@ -125,7 +77,8 @@ function isGetCreditAccountsMulticall(
12577 ( data . params [ 0 ] . data ?. includes ( "f43bdb34" ) ||
12678 data . params [ 0 ] . data ?. includes ( "8b59b911" ) )
12779 ) {
128- return BigInt ( data . params [ 1 ] ) ;
80+ return true ;
12981 }
13082 } catch { }
83+ return false ;
13184}
0 commit comments