wip: use callstack

This commit is contained in:
Alex 2025-04-15 10:14:51 +03:00
parent bb6d584ed2
commit a0516f67ae
3 changed files with 158 additions and 81 deletions

View File

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import {
Context,
extractContractArgs,
@ -15,6 +16,7 @@ import { ResolvedOp, Task } from '../types';
import { context, getRawContext, setRawContext } from './context';
import { getAwaitedOps } from './promisifiedOps/awaited';
import { pushResolvedOp } from './promisifiedOps/resolved';
import { extractRootParent, getRoot, setRoot } from './utils';
let abortExecution: ((result: boolean) => void) | null = null;
@ -22,39 +24,50 @@ const handleState = () => {
const ctx = getRawContext();
const resolvedOps = extractContractArgs(ctx.tx);
const methodArgs = getMethodArguments(ctx) as [unknown, unknown[], ResolvedOp[]];
const methodArgs = getMethodArguments(ctx) as [unknown, unknown[], ResolvedOp[], string?];
const initialArgs = methodArgs[1] ?? [];
const previousOps = methodArgs[2] ?? [];
const allResolvedOps = [...previousOps, ...resolvedOps];
const root = methodArgs[3];
pushResolvedOp(allResolvedOps);
return {
args: initialArgs,
methodName: methodArgs[0] as string,
ops: allResolvedOps,
isChildCall: previousOps.length > 0,
isChildCall: resolvedOps.length > 0,
root,
};
};
export const executor =
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(method: (...args: any[]) => Promise<void>) =>
async (ctx: Context): Promise<NewTx[]> => {
console.log('executor-start');
setRawContext(ctx);
type Method = (...args: any[]) => Promise<void>;
const { args, methodName, ops, isChildCall } = handleState();
type Resolver = (
currentMethod: Method,
args: any[],
resolve: (value: boolean | PromiseLike<boolean>) => void,
reject: (reason?: any) => void,
isChildCall: boolean,
rootParent?: string,
root?: string
) => void;
if (isChildCall && !isSelfCall(ctx)) {
throw new Error('Only contract itself can call it');
const resolver: Resolver = (currentMethod, args, resolve, reject, isChildCall, root) => {
if (!isChildCall) {
extractRootParent(resolver.name);
} else {
if (!root) {
console.log('executor-root-not-set');
throw new Error('Root root is not set');
}
const execution = new Promise<boolean>((resolve, reject) => {
abortExecution = resolve;
setRoot(root);
}
method(...args).then(
currentMethod(...args).then(
() => {
console.log('executor-resolved');
resolve(true);
@ -64,6 +77,27 @@ export const executor =
reject();
}
);
};
export const executor =
(method: (...args: any[]) => Promise<void>) =>
async (ctx: Context): Promise<NewTx[]> => {
console.log('executor-start');
setRawContext(ctx);
const { args, methodName, ops, isChildCall, root } = handleState();
if (isChildCall && !isSelfCall(ctx)) {
throw new Error('Only contract itself can call it');
}
const execution = new Promise<boolean>((resolve, reject) => {
abortExecution = resolve;
resolver(method, args, resolve, reject, isChildCall, root);
}).catch((error) => {
console.error(error);
throw error;
});
//@ts-expect-error
@ -111,11 +145,8 @@ export const executor =
methodName,
methodArgs: [
args,
[
...ops,
...Array(awaitedOps.length).fill({ SlotOp: 0 } satisfies ResolvedOp),
] satisfies ResolvedOp[],
isFullyExecuted,
[...ops, ...Array(awaitedOps.length).fill({ SlotOp: 0 } satisfies ResolvedOp)] satisfies ResolvedOp[],
getRoot(),
callArgs,
awaitedOps,
],

View File

@ -1,10 +1,56 @@
export const getStack = ({ skip = 0 }: { skip?: number } = {}) =>
new Error().stack
?.split('\n')
let rootParent = '';
let root = '';
export const extractRootParent = (name: string) => {
const stack = getStackItems();
if (stack[0] === name) {
rootParent = name;
return;
}
};
export const getStackItems = ({ skip = 0 }: { skip?: number } = {}) => {
const slugs = new Error()
.stack!.split('\n')
.slice(2 + skip)
.map((line) => {
const match = line.match(/at\s+([^\s(]+)/);
return match ? match[1] : '';
})
.filter((name) => name && name !== 'Promise')
.join('@') || '';
.filter((name) => name && !['<anonymous>', 'Promise'].includes(name));
return slugs;
};
export const getStack = ({ skip = 0 }: { skip?: number } = {}) => {
const items = getStackItems({ skip });
if (rootParent) {
const rootIndex = items.findLastIndex((item) => item === rootParent);
if (rootIndex !== -1) {
const pureSlugs = items.slice(0, rootIndex);
return pureSlugs.join('@') || '@';
}
}
if (!root) {
console.log('set root');
console.log(JSON.stringify(items));
console.log(items.at(-1));
root = items.at(-1) ?? '';
}
return items.join('@') || '@';
};
export const getRoot = () => {
return root;
};
export const setRoot = (value: string) => {
root = value;
};

View File

@ -1,4 +1,4 @@
VITE_API_URL='https://api-cloud.coinweb.io/wallet'
VITE_EXPLORER_URL='https://explorer.coinweb.io'
VITE_CONTRACT_ADDRESS="0xd0b364db47a35710320a815fbcae80435ae83e0a1730e70529f1b0b2a6b7bfd5"
VITE_CONTRACT_ADDRESS="0x6fd41997fb840f91cc9d3b1bf69015dc2cef975015b52d53bf04f4380ddd66c4"