UNPKG

@guaritos/tracer-engine

Version:

A highly performant and scalable multi-hop, time-aware tracer for account-based blockchain transactions, designed for off-chain risk assessment and flow analysis.

82 lines 3.29 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TracerEngine = exports.TraceResult = void 0; const subgraph_1 = require("./items/subgraph"); const ttr_1 = require("./strategies/ttr"); const pino = require('pino'); class TraceResult { constructor() { this.strategy_snap_shot_items = {}; this.rank_items = {}; } } exports.TraceResult = TraceResult; class TracerEngine { constructor(source, options) { this.class_name = "TracerEngine"; this.log = pino({ transport: { target: 'pino-pretty' } }); this.enable_log = false; this.strategy = new ttr_1.TTRRedirect(source); if (options && options.enable_log) this.enable_log = options.enable_log; } *push_pop(node, edges) { this.enable_log && this.log.info(`[${this.class_name}] Pushing: ${node}, with ${edges.length} transfer`); this.strategy.push(node, edges); // generate a strategy context item const snapshot_data = this.strategy.get_context_snapshot(); yield new subgraph_1.StrategySnapshotItem(snapshot_data); const ranks = this.strategy.get_node_rank(); yield new subgraph_1.RankItem(ranks); // pop account from the strategy const [popped_node, context_kwargs] = this.strategy.pop(); if (popped_node === null) { return; } this.enable_log && this.log.info(`[${this.class_name}] Popping: ${popped_node}, with args {residual: ${context_kwargs.residual}, allow_all_token: ${context_kwargs.allow_all_tokens}}`); let pop_item = new subgraph_1.PopItem(popped_node); pop_item.set_context_kwargs(context_kwargs); yield pop_item; } async startTrace(get_edges, trace_options) { let result = new TraceResult(); let depth = 0; const edges = await get_edges(this.strategy.source, trace_options?.filters); const start_time = Date.now(); let data = this.push_pop(this.strategy.source, edges); let curr = data.next(); while (!curr.done) { if (trace_options && trace_options.max_depth && depth > trace_options.max_depth) { break; } // StrategySnapshotItem result.strategy_snap_shot_items = curr.value.data; // RankItem curr = data.next(); result.rank_items = curr.value.data; // PopItem or empty return; curr = data.next(); if (curr.done) { break; } else if (curr.value instanceof subgraph_1.PopItem) { const node = curr.value.node; if (!node) break; data = this.push_pop(node, await get_edges(node, trace_options?.filters)); curr = data.next(); } depth++; } const end_time = Date.now(); const time_elapsed = end_time - start_time; this.enable_log && this.log.info(`${this.class_name} Finish tracing after ${new Date(time_elapsed).toISOString().slice(11, 19)}`); return result; } } exports.TracerEngine = TracerEngine; //# sourceMappingURL=tracer_engine.js.map