stellar-plus
Version:
beta version of stellar-plus, an all-in-one sdk for the Stellar blockchain
117 lines (116 loc) • 5.09 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProfilerPlugin = void 0;
const tslib_1 = require("tslib");
const stellar_sdk_1 = require("@stellar/stellar-sdk");
const types_1 = require("../../../../../../stellar-plus/core/pipelines/soroban-transaction/types");
const extract_transaction_resources_1 = require("../../../../../../stellar-plus/utils/pipeline/plugins/simulate-transaction/extract-transaction-resources");
const extract_fee_charged_1 = require("../../../../../../stellar-plus/utils/pipeline/plugins/soroban-get-transaction/extract-fee-charged");
const index_1 = require("../../../../../../stellar-plus/utils/profiler/profiling-handler/index");
class ProfilerPlugin {
constructor() {
this.type = types_1.SorobanTransactionPipelineType.id;
this.name = 'ProfilerPlugin';
this.timers = {};
this.logs = {};
this.plugins = [];
this.extractResources = (resources, itemId) => {
this.verifyLogEntry(itemId);
this.logs[itemId].resources = Object.assign({}, resources);
};
this.extractFeeCharged = (output, itemId) => {
this.verifyLogEntry(itemId);
this.logs[itemId].feeCharged = Number(output.feeCharged);
};
this.injectPlugins = (item) => {
const updatedItem = Object.assign(Object.assign({}, item), { options: item.options ? Object.assign({}, item.options) : {} });
updatedItem.options.executionPlugins = updatedItem.options.executionPlugins
? [...updatedItem.options.executionPlugins, ...this.plugins]
: [...this.plugins];
return updatedItem;
};
this.getMethodNameFromOperation = (operation) => {
if (operation.body().switch() === stellar_sdk_1.xdr.OperationType.invokeHostFunction()) {
const hostFunction = operation.body().invokeHostFunctionOp();
if (hostFunction.hostFunction().switch() === stellar_sdk_1.xdr.HostFunctionType.hostFunctionTypeInvokeContract()) {
const invokeContractHostFunction = hostFunction.hostFunction().invokeContract();
return invokeContractHostFunction.functionName();
}
if (hostFunction.hostFunction().switch() === stellar_sdk_1.xdr.HostFunctionType.hostFunctionTypeUploadContractWasm()) {
return 'uploadContractWasm';
}
if (hostFunction.hostFunction().switch() === stellar_sdk_1.xdr.HostFunctionType.hostFunctionTypeCreateContract()) {
return 'createContract';
}
return hostFunction.hostFunction().switch().name;
}
return operation.body().switch().name;
};
this.data = new index_1.ProfilingHandler();
this.costHandler = this.data.resourceHandler;
this.plugins.push(new extract_transaction_resources_1.ExtractTransactionResourcesPlugin(this.extractResources));
this.plugins.push(new extract_fee_charged_1.ExtractFeeChargedPlugin(this.extractFeeCharged));
}
preProcess(item, meta) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
this.startTimer(meta.itemId);
this.createLogEntry(item, meta);
return this.injectPlugins(item);
});
}
postProcess(item, meta) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
this.stopTimer(meta.itemId);
this.setStatus(meta.itemId, 'success');
this.log(meta);
return item;
});
}
processError(error, meta) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
this.stopTimer(meta.itemId);
this.setStatus(meta.itemId, 'error');
this.log(meta);
return error;
});
}
startTimer(id) {
this.timers[id] = {
start: Date.now(),
end: 0,
};
}
stopTimer(id) {
this.verifyLogEntry(id);
this.timers[id] = {
start: this.timers[id].start,
end: Date.now(),
};
}
setStatus(id, status) {
this.verifyLogEntry(id);
this.logs[id].status = status;
}
//todo: move error to StellarPlusError
verifyLogEntry(logId) {
if (!this.logs[logId]) {
throw new Error(`log entry not found for item ${logId}`);
}
}
createLogEntry(item, meta) {
const methodName = this.getMethodNameFromOperation(item.operations[0]);
const logEntry = {
methodName,
status: 'running',
feeCharged: 0,
elapsedTime: '',
resources: {},
};
this.logs[meta.itemId] = logEntry;
}
log(meta) {
const logId = meta.itemId;
this.costHandler(this.logs[logId].methodName, this.logs[logId].resources, this.timers[logId].end - this.timers[logId].start, this.logs[logId].feeCharged);
}
}
exports.ProfilerPlugin = ProfilerPlugin;