Skip to content

Commit

Permalink
feat: log every rpc call across all the viem clients used (#85)
Browse files Browse the repository at this point in the history
  • Loading branch information
jahabeebs authored Nov 8, 2024
1 parent 2c02271 commit e9893cd
Show file tree
Hide file tree
Showing 12 changed files with 225 additions and 56 deletions.
1 change: 1 addition & 0 deletions apps/agent/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const main = async (): Promise<void> => {
config.protocolProvider.rpcsConfig,
config.protocolProvider.contracts,
config.protocolProvider.privateKey,
logger,
blockNumberService,
);

Expand Down
3 changes: 2 additions & 1 deletion apps/scripts/utilities/approveAccountingModules.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ProtocolProvider } from "@ebo-agent/automated-dispute/src/index.js";
import { mockLogger } from "@ebo-agent/automated-dispute/tests/mocks/logger.mocks.js";
import { Caip2ChainId } from "@ebo-agent/shared";
import * as dotenv from "dotenv";
import { Address, Hex, isHex } from "viem";
Expand Down Expand Up @@ -102,7 +103,7 @@ const rpcConfig = {

const contracts = env.CONTRACTS_ADDRESSES;

const provider = new ProtocolProvider(rpcConfig, contracts, env.PRIVATE_KEY as Hex);
const provider = new ProtocolProvider(rpcConfig, contracts, env.PRIVATE_KEY as Hex, mockLogger());

/**
* Approves the necessary modules by calling approveModule on ProtocolProvider.
Expand Down
63 changes: 50 additions & 13 deletions packages/automated-dispute/src/providers/protocolProvider.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BlockNumberService, UnsupportedChain } from "@ebo-agent/blocknumber";
import { Caip2ChainId, HexUtils, UnixTimestamp } from "@ebo-agent/shared";
import { Caip2ChainId, HexUtils, ILogger, UnixTimestamp } from "@ebo-agent/shared";
import {
Account,
Address,
Expand Down Expand Up @@ -114,12 +114,14 @@ export class ProtocolProvider implements IProtocolProvider {
* @param rpcConfig The configuration for RPC connections including URLs, timeout, retry interval, and transaction receipt confirmations
* @param contracts The addresses of the protocol contracts that will be instantiated
* @param privateKey The private key of the account that will be used to interact with the contracts
* @param logger The logger instance
* @param blockNumberService The service that will be used to fetch block numbers
*/
constructor(
private readonly rpcConfig: ProtocolRpcConfig,
contracts: ProtocolContractsAddresses,
privateKey: Hex,
private readonly logger: ILogger,
blockNumberService?: BlockNumberService,
) {
const l1Chain = this.getViemChain(rpcConfig.l1.chainId);
Expand Down Expand Up @@ -206,12 +208,7 @@ export class ProtocolProvider implements IProtocolProvider {
return createPublicClient({
chain: chain,
transport: fallback(
urls.map((url) =>
http(url, {
timeout: timeout,
retryDelay: retryInterval,
}),
),
urls.map((url) => this.createHttpTransportWithLogging(url, timeout, retryInterval)),
),
});
}
Expand All @@ -227,17 +224,57 @@ export class ProtocolProvider implements IProtocolProvider {
return createWalletClient({
chain: chain,
transport: fallback(
urls.map((url) =>
http(url, {
timeout: timeout,
retryDelay: retryInterval,
}),
),
urls.map((url) => this.createHttpTransportWithLogging(url, timeout, retryInterval)),
),
account: account,
});
}

/**
* Creates an HTTP transport with logging capabilities for requests and responses.
*
* This function sets up a custom HTTP transport that logs the details of each
* HTTP request and response, including the URL, method, headers, and body.
* The logging captures and logs the cloned `Request` and `Response` objects,
* ensuring the original objects remain unaltered.
*
* @param {string} url - The base URL for the HTTP transport.
* @param {number} timeout - The timeout duration in milliseconds for each HTTP request.
* @param {number} retryInterval - The delay in milliseconds before retrying a failed request.
* @returns {HttpTransport} The configured HTTP transport with logging enabled.
*
*/
private createHttpTransportWithLogging(
url: string,
timeout: number,
retryInterval: number,
): HttpTransport {
return http(url, {
timeout: timeout,
retryDelay: retryInterval,
onFetchRequest: async (request) => {
const reqObject = {
url: request.url,
method: request.method,
headers: Array.from(request.headers.entries()),
body: await request.clone().text(),
};

this.logger.debug(`Fetch Request`, reqObject);
},
onFetchResponse: async (response) => {
const respObject = {
url: response.url,
status: response.status,
headers: Array.from(response.headers.entries()),
body: await response.clone().text(),
};

this.logger.debug(`Fetch Response`, respObject);
},
});
}

private getViemChain(chainId: Caip2ChainId): Chain {
switch (chainId) {
case "eip155:1":
Expand Down
22 changes: 14 additions & 8 deletions packages/automated-dispute/tests/mocks/eboActor.mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,9 @@ import { Mutex } from "async-mutex";
import { Block, pad } from "viem";
import { vi } from "vitest";

import { NotificationService } from "../../src/index.js";
import { ProtocolProvider } from "../../src/providers/index.js";
import {
EboActor,
EboMemoryRegistry,
NotificationService,
ProphetCodec,
} from "../../src/services/index.js";
import { EboActor, EboMemoryRegistry, ProphetCodec } from "../../src/services/index.js";
import {
Dispute,
DisputeId,
Expand Down Expand Up @@ -55,6 +51,7 @@ export function buildEboActor(request: Request, logger: ILogger) {
},
DEFAULT_MOCKED_PROTOCOL_CONTRACTS,
mockedPrivateKey,
logger,
);

vi.spyOn(protocolProvider.read, "getEscalation").mockResolvedValue({
Expand Down Expand Up @@ -101,7 +98,17 @@ export function buildEboActor(request: Request, logger: ILogger) {
const eventProcessingMutex = new Mutex();

const notificationService: NotificationService = {
notifyError: vi.fn().mockResolvedValue(undefined),
send: vi.fn().mockResolvedValue(undefined),
sendOrThrow: vi.fn().mockResolvedValue(undefined),
createErrorMessage: vi
.fn()
.mockImplementation((defaultMessage: string, context?: unknown, err?: unknown) => {
return {
title: defaultMessage,
description: err instanceof Error ? err.message : undefined,
};
}),
sendError: vi.fn().mockResolvedValue(undefined),
};

const actor = new EboActor(
Expand Down Expand Up @@ -200,7 +207,6 @@ export function buildDispute(
): Dispute {
const baseDispute: Dispute = {
id: attributes.id || (pad("0x03") as DisputeId),
status: "Active",
createdAt: {
timestamp: (response.createdAt.timestamp + 1n) as UnixTimestamp,
blockNumber: response.createdAt.blockNumber + 1n,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
export function buildEboProcessor(
logger: ILogger,
accountingModules: AccountingModules = {
requestModule: "0x01",
responseModule: "0x02",
escalationModule: "0x03",
},
Expand Down Expand Up @@ -57,6 +56,7 @@ export function buildEboProcessor(
},
DEFAULT_MOCKED_PROTOCOL_CONTRACTS,
mockedPrivateKey,
logger,
blockNumberService,
);

Expand Down
10 changes: 8 additions & 2 deletions packages/automated-dispute/tests/services/eboActor/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,14 @@ export const DEFAULT_MOCKED_REQUEST_CREATED_DATA: Request = {

export const DEFAULT_MOCKED_DISPUTE_DATA: Dispute = {
id: pad("0x03") as DisputeId,
createdAt: 1625097800n,
status: "Active",
createdAt: {
timestamp: 1625097600n as UnixTimestamp,
blockNumber: 1n,
logIndex: 0,
},
decodedData: {
status: "Active",
},
prophetData: {
disputer: "0x5678901234567890123456789012345678901234",
proposer: DEFAULT_MOCKED_RESPONSE_DATA.prophetData.proposer,
Expand Down
Loading

0 comments on commit e9893cd

Please sign in to comment.