Skip to content

Commit

Permalink
chore(sdk): definte basic trace handling schema (stephenh#95)
Browse files Browse the repository at this point in the history
  • Loading branch information
zfy0701 authored Sep 15, 2022
1 parent bec632b commit 9e95f6f
Show file tree
Hide file tree
Showing 7 changed files with 294 additions and 38 deletions.
8 changes: 7 additions & 1 deletion protos/processor.proto
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ message ContractConfig {
ContractInfo contract = 1;
repeated BlockHandlerConfig block_configs = 7;
repeated LogHandlerConfig log_configs = 3;
repeated TraceHandlerConfig trace_configs = 2;
uint64 start_block = 4;
uint64 end_block = 5;
InstructionHandlerConfig instruction_config = 6;
Expand Down Expand Up @@ -81,6 +82,11 @@ message BlockHandlerConfig {
int32 handler_id = 1;
}

message TraceHandlerConfig {
string signature = 1;
int32 handler_id = 2;
}

message LogHandlerConfig {
repeated LogFilter filters = 1;
int32 handler_id = 2;
Expand Down Expand Up @@ -111,7 +117,7 @@ message ProcessLogsResponse {
}

message ProcessTracesRequest {
repeated LogBinding log_bindings = 1;
repeated TraceBinding trace_bindings = 1;
}

message ProcessTracesResponse {
Expand Down
34 changes: 34 additions & 0 deletions sdk/src/base-processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,26 @@ import { BoundContractView, Context, ContractView } from './context'
import { ProcessResult } from './gen/processor/protos/processor'
import { BindInternalOptions, BindOptions } from './bind-options'
import { PromiseOrVoid } from './promise-or-void'
import { Trace } from './trace'
import { utils } from 'ethers'

export class EventsHandler {
filters: EventFilter[]
handler: (event: Log) => Promise<ProcessResult>
}

export class TraceHandler {
signature: string
handler: (trace: Trace) => Promise<ProcessResult>
}

export abstract class BaseProcessor<
TContract extends BaseContract,
TBoundContractView extends BoundContractView<TContract, ContractView<TContract>>
> {
blockHandlers: ((block: Block) => Promise<ProcessResult>)[] = []
eventHandlers: EventsHandler[] = []
traceHandlers: TraceHandler[] = []

name: string
config: BindInternalOptions
Expand Down Expand Up @@ -128,4 +136,30 @@ export abstract class BaseProcessor<
return handler(log, ctx)
}, _filters)
}

public onTrace(
signature: string,
handler: (trace: Trace, ctx: Context<TContract, TBoundContractView>) => PromiseOrVoid
) {
const chainId = this.getChainId()
const contractView = this.CreateBoundContractView()

this.traceHandlers.push({
signature,
handler: async function (trace: Trace) {
const contractInterface = contractView.rawContract.interface
const fragment = contractInterface.getFunction(signature)
trace.args = contractInterface._abiCoder.decode(fragment.inputs, utils.hexDataSlice(trace.action.input, 4))

const ctx = new Context<TContract, TBoundContractView>(contractView, chainId, undefined, undefined, trace)
await handler(trace, ctx)
return {
gauges: ctx.gauges,
counters: ctx.counters,
logs: [],
}
},
})
return this
}
}
37 changes: 23 additions & 14 deletions sdk/src/context.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
import { CounterResult, GaugeResult } from './gen/processor/protos/processor'
import { CounterResult, GaugeResult, LogResult } from './gen/processor/protos/processor'
import { BaseContract, EventFilter } from 'ethers'
import { Block, Log } from '@ethersproject/abstract-provider'
import { Meter } from './meter'
import Long from 'long'
import { Trace } from './trace'

export class EthContext {
export class BaseContext {
gauges: GaugeResult[] = []
counters: CounterResult[] = []
logs: LogResult[] = []
meter: Meter

constructor() {
this.meter = new Meter(this)
}
}

export class EthContext extends BaseContext {
chainId: number
log?: Log
block?: Block
trace?: Trace
blockNumber: Long
gauges: GaugeResult[] = []
counters: CounterResult[] = []
meter: Meter

constructor(chainId: number, block?: Block, log?: Log) {
constructor(chainId: number, block?: Block, log?: Log, trace?: Trace) {
super()
this.chainId = chainId
this.log = log
this.block = block
Expand All @@ -22,7 +33,6 @@ export class EthContext {
} else if (block) {
this.blockNumber = Long.fromNumber(block.number)
}
this.meter = new Meter(this)
}
}

Expand All @@ -31,11 +41,13 @@ export class Context<
TContractBoundView extends BoundContractView<TContract, ContractView<TContract>>
> extends EthContext {
contract: TContractBoundView
address: string

constructor(view: TContractBoundView, chainId: number, block?: Block, log?: Log) {
super(chainId, block, log)
constructor(view: TContractBoundView, chainId: number, block?: Block, log?: Log, trace?: Trace) {
super(chainId, block, log, trace)
view.context = this
this.contract = view
this.address = view.rawContract.address
}
}

Expand Down Expand Up @@ -79,14 +91,11 @@ export class BoundContractView<TContract extends BaseContract, TContractView ext
}
}

export class SolanaContext {
gauges: GaugeResult[] = []
counters: CounterResult[] = []
meter: Meter

export class SolanaContext extends BaseContext {
address: string

constructor(address: string) {
super()
this.meter = new Meter(this)
this.address = address
}
Expand Down
117 changes: 104 additions & 13 deletions sdk/src/gen/processor/protos/processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ export interface ContractConfig {
contract: ContractInfo | undefined;
blockConfigs: BlockHandlerConfig[];
logConfigs: LogHandlerConfig[];
traceConfigs: TraceHandlerConfig[];
startBlock: Long;
endBlock: Long;
instructionConfig: InstructionHandlerConfig | undefined;
Expand Down Expand Up @@ -151,6 +152,11 @@ export interface BlockHandlerConfig {
handlerId: number;
}

export interface TraceHandlerConfig {
signature: string;
handlerId: number;
}

export interface LogHandlerConfig {
filters: LogFilter[];
handlerId: number;
Expand Down Expand Up @@ -180,7 +186,7 @@ export interface ProcessLogsResponse {
}

export interface ProcessTracesRequest {
logBindings: LogBinding[];
traceBindings: TraceBinding[];
}

export interface ProcessTracesResponse {
Expand Down Expand Up @@ -524,6 +530,7 @@ function createBaseContractConfig(): ContractConfig {
contract: undefined,
blockConfigs: [],
logConfigs: [],
traceConfigs: [],
startBlock: Long.UZERO,
endBlock: Long.UZERO,
instructionConfig: undefined,
Expand All @@ -545,6 +552,9 @@ export const ContractConfig = {
for (const v of message.logConfigs) {
LogHandlerConfig.encode(v!, writer.uint32(26).fork()).ldelim();
}
for (const v of message.traceConfigs) {
TraceHandlerConfig.encode(v!, writer.uint32(18).fork()).ldelim();
}
if (!message.startBlock.isZero()) {
writer.uint32(32).uint64(message.startBlock);
}
Expand Down Expand Up @@ -583,6 +593,11 @@ export const ContractConfig = {
LogHandlerConfig.decode(reader, reader.uint32())
);
break;
case 2:
message.traceConfigs.push(
TraceHandlerConfig.decode(reader, reader.uint32())
);
break;
case 4:
message.startBlock = reader.uint64() as Long;
break;
Expand Down Expand Up @@ -617,6 +632,9 @@ export const ContractConfig = {
logConfigs: Array.isArray(object?.logConfigs)
? object.logConfigs.map((e: any) => LogHandlerConfig.fromJSON(e))
: [],
traceConfigs: Array.isArray(object?.traceConfigs)
? object.traceConfigs.map((e: any) => TraceHandlerConfig.fromJSON(e))
: [],
startBlock: isSet(object.startBlock)
? Long.fromValue(object.startBlock)
: Long.UZERO,
Expand Down Expand Up @@ -652,6 +670,13 @@ export const ContractConfig = {
} else {
obj.logConfigs = [];
}
if (message.traceConfigs) {
obj.traceConfigs = message.traceConfigs.map((e) =>
e ? TraceHandlerConfig.toJSON(e) : undefined
);
} else {
obj.traceConfigs = [];
}
message.startBlock !== undefined &&
(obj.startBlock = (message.startBlock || Long.UZERO).toString());
message.endBlock !== undefined &&
Expand All @@ -675,6 +700,8 @@ export const ContractConfig = {
object.blockConfigs?.map((e) => BlockHandlerConfig.fromPartial(e)) || [];
message.logConfigs =
object.logConfigs?.map((e) => LogHandlerConfig.fromPartial(e)) || [];
message.traceConfigs =
object.traceConfigs?.map((e) => TraceHandlerConfig.fromPartial(e)) || [];
message.startBlock =
object.startBlock !== undefined && object.startBlock !== null
? Long.fromValue(object.startBlock)
Expand Down Expand Up @@ -994,6 +1021,68 @@ export const BlockHandlerConfig = {
},
};

function createBaseTraceHandlerConfig(): TraceHandlerConfig {
return { signature: "", handlerId: 0 };
}

export const TraceHandlerConfig = {
encode(
message: TraceHandlerConfig,
writer: _m0.Writer = _m0.Writer.create()
): _m0.Writer {
if (message.signature !== "") {
writer.uint32(10).string(message.signature);
}
if (message.handlerId !== 0) {
writer.uint32(16).int32(message.handlerId);
}
return writer;
},

decode(input: _m0.Reader | Uint8Array, length?: number): TraceHandlerConfig {
const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseTraceHandlerConfig();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1:
message.signature = reader.string();
break;
case 2:
message.handlerId = reader.int32();
break;
default:
reader.skipType(tag & 7);
break;
}
}
return message;
},

fromJSON(object: any): TraceHandlerConfig {
return {
signature: isSet(object.signature) ? String(object.signature) : "",
handlerId: isSet(object.handlerId) ? Number(object.handlerId) : 0,
};
},

toJSON(message: TraceHandlerConfig): unknown {
const obj: any = {};
message.signature !== undefined && (obj.signature = message.signature);
message.handlerId !== undefined &&
(obj.handlerId = Math.round(message.handlerId));
return obj;
},

fromPartial(object: DeepPartial<TraceHandlerConfig>): TraceHandlerConfig {
const message = createBaseTraceHandlerConfig();
message.signature = object.signature ?? "";
message.handlerId = object.handlerId ?? 0;
return message;
},
};

function createBaseLogHandlerConfig(): LogHandlerConfig {
return { filters: [], handlerId: 0 };
}
Expand Down Expand Up @@ -1400,16 +1489,16 @@ export const ProcessLogsResponse = {
};

function createBaseProcessTracesRequest(): ProcessTracesRequest {
return { logBindings: [] };
return { traceBindings: [] };
}

export const ProcessTracesRequest = {
encode(
message: ProcessTracesRequest,
writer: _m0.Writer = _m0.Writer.create()
): _m0.Writer {
for (const v of message.logBindings) {
LogBinding.encode(v!, writer.uint32(10).fork()).ldelim();
for (const v of message.traceBindings) {
TraceBinding.encode(v!, writer.uint32(10).fork()).ldelim();
}
return writer;
},
Expand All @@ -1425,7 +1514,9 @@ export const ProcessTracesRequest = {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1:
message.logBindings.push(LogBinding.decode(reader, reader.uint32()));
message.traceBindings.push(
TraceBinding.decode(reader, reader.uint32())
);
break;
default:
reader.skipType(tag & 7);
Expand All @@ -1437,28 +1528,28 @@ export const ProcessTracesRequest = {

fromJSON(object: any): ProcessTracesRequest {
return {
logBindings: Array.isArray(object?.logBindings)
? object.logBindings.map((e: any) => LogBinding.fromJSON(e))
traceBindings: Array.isArray(object?.traceBindings)
? object.traceBindings.map((e: any) => TraceBinding.fromJSON(e))
: [],
};
},

toJSON(message: ProcessTracesRequest): unknown {
const obj: any = {};
if (message.logBindings) {
obj.logBindings = message.logBindings.map((e) =>
e ? LogBinding.toJSON(e) : undefined
if (message.traceBindings) {
obj.traceBindings = message.traceBindings.map((e) =>
e ? TraceBinding.toJSON(e) : undefined
);
} else {
obj.logBindings = [];
obj.traceBindings = [];
}
return obj;
},

fromPartial(object: DeepPartial<ProcessTracesRequest>): ProcessTracesRequest {
const message = createBaseProcessTracesRequest();
message.logBindings =
object.logBindings?.map((e) => LogBinding.fromPartial(e)) || [];
message.traceBindings =
object.traceBindings?.map((e) => TraceBinding.fromPartial(e)) || [];
return message;
},
};
Expand Down
Loading

0 comments on commit 9e95f6f

Please sign in to comment.