fix: small fixes and refactor

This commit is contained in:
Alex 2025-05-05 12:21:50 +03:00
parent 3f640d90ce
commit 7baec6736b
32 changed files with 166 additions and 157 deletions

View File

@ -12,6 +12,10 @@ export const constructCwebMain = (methods: Record<string, (...args: any[]) => Pr
const module: ContractHandlers = { handlers: {} };
Object.entries(methods).forEach(([name, handler]) => {
if (name.startsWith('_')) {
throw new Error('Do not start method names with "_" because they are reserved for internal use');
}
addMethodHandler(module, name, executor(handler));
});

View File

@ -10,8 +10,8 @@ import {
import { CwebTake } from '@coinweb/contract-kit/dist/types/operations/take';
import { getCallParameters, getContractIssuer } from 'lib/onchain';
import { pushAwaitedOp } from '../../../dist/onchain/ops';
import { ExecutorMethodArgs, ResolvedOp } from '../../types';
import { pushAwaitedTask } from '../promisifiedFeatures';
import { uuid } from '../utils';
import { extractOps } from './extractOps';
@ -102,7 +102,7 @@ export const handleContext = (ctx: Context) => {
};
if (executionOpsTakeOp) {
pushAwaitedOp(executionOpsTakeOp);
pushAwaitedTask(executionOpsTakeOp);
}
return !!executionOpsTakeOp; //This is a flag to check if the execution should restart / TODO: refactor;

View File

@ -2,7 +2,7 @@ import { constructTake, extractRead, GRead, GTake, ResolvedOperation, ResolvedRe
import { CwebTake } from '@coinweb/contract-kit/dist/types/operations/take';
import { ResolvedOp, TypedClaim } from '../../types';
import { resultKey } from '../claims/result';
import { resultKey } from '../claims';
import { mutexBlockLockKey, mutexBlockUnlockKey, mutexExecOpsKey, MutexExecOpsResult } from '../mutex';
import { isResolvedBlockOp, isResolvedReadOp, isResolvedTakeOp } from '../utils';

View File

@ -2,7 +2,7 @@
import { Context, NewTx, getMethodArguments, isSelfCall } from '@coinweb/contract-kit';
import { context, getRawContext, handleContext } from './context';
import { pushResolvedOp } from './promisifiedOps/resolved';
import { pushResolvedOp } from './promisifiedFeatures/runtime/resolvedOps';
import { constructTx } from './utils';
let abortExecution: ((result: boolean) => void) | null = null;

View File

@ -1,4 +1,4 @@
import { markTaskBatch } from './promisifiedOps/awaited';
import { markTaskBatch } from './promisifiedFeatures/runtime/awaitedTasks';
import { getBatchId } from './utils';
export const opMarker = Symbol('opMarker');

View File

@ -1,3 +1,3 @@
export * from './context';
export * from './executor';
export * from './promisifiedOps';
export * from './promisifiedFeatures/features';
export * from './constructCwebMain';

View File

@ -8,7 +8,7 @@ import {
ContractIssuer,
} from '@coinweb/contract-kit';
export const mutexBlockLockKey = 'mutex_block_lock';
export const mutexBlockLockKey = '_mutex_block_lock';
export const constructMutexBlockLockClaimKey = (lockId: string) => constructClaimKey([mutexBlockLockKey], [lockId]);

View File

@ -10,7 +10,7 @@ import {
GStore,
} from '@coinweb/contract-kit';
export const mutexBlockUnlockKey = 'mutex_block_unlock';
export const mutexBlockUnlockKey = '_mutex_block_unlock';
export const constructMutexBlockUnlockClaimKey = (uniqueId: string) =>
constructClaimKey([mutexBlockUnlockKey], [uniqueId]);

View File

@ -14,7 +14,7 @@ import { toHex } from 'lib/shared';
import { MutexExecOpsResult } from '../types';
export const mutexExecOpsKey = 'mutex_exec_ops';
export const mutexExecOpsKey = '_mutex_exec_ops';
export const constructMutexExecOpsClaimKey = (execId: string) => constructClaimKey([mutexExecOpsKey], [execId]);

View File

@ -6,13 +6,13 @@ import {
ContractIssuer,
GRead,
} from '@coinweb/contract-kit';
import { CwebRead } from '@coinweb/contract-kit/dist/esm/operations/read';
import { CwebRead } from '@coinweb/contract-kit/dist/types/operations/read';
import { toHex } from 'lib/shared';
import { rangeReadLimit } from '../settings';
import { LockedKey, MutexLockState } from '../types';
export const mutexLockKey = 'mutex_lock';
export const mutexLockKey = '_mutex_lock';
export const constructMutexLockFirstPart = () => [mutexLockKey];

View File

@ -1,14 +1,13 @@
import { constructStore } from '@coinweb/contract-kit/dist/esm/operations/store';
import { constructResultClaim } from '../claims/result';
import { context } from '../context';
import { stopExecution } from '../executor';
import { opMarker } from '../global';
import { isResolvedChildOp, isResolvedExecOp, isResolvedSlotOp } from '../utils';
import { uuid } from '../utils';
import { getAwaitedTasks, pushAwaitedTask } from './awaited';
import { getUsedOps, saveUsedOps, shiftResolvedOp } from './resolved';
import { constructResultClaim } from '../../../claims/result';
import { context } from '../../../context';
import { stopExecution } from '../../../executor';
import { opMarker } from '../../../global';
import { isResolvedChildOp, isResolvedExecOp, isResolvedSlotOp } from '../../../utils';
import { uuid } from '../../../utils';
import { getAwaitedTasks, pushAwaitedTask } from '../../runtime/awaitedTasks';
import { getUsedOps, saveUsedOps, shiftResolvedOp } from '../../runtime/resolvedOps';
let isRootDetected = false;

View File

@ -0,0 +1 @@
export * from './cwait';

View File

@ -0,0 +1,3 @@
export * from './cwait';
export * from './mutex';
export * from './ops';

View File

@ -0,0 +1 @@
export * from './lock';

View File

@ -0,0 +1,78 @@
import { getTime } from 'lib/onchain';
import { opMarker } from '../../../global';
import { LockedKey } from '../../../mutex';
import { isResolvedLockOp, isResolvedSlotOp, isResolvedUnlockOp, uuid } from '../../../utils';
import { pushAwaitedTask, shiftResolvedOp } from '../../runtime';
const unlock = (lockId: string, timestamp: number) => {
console.log('lockOp');
let opMarkerValue = false;
const result = new Promise<void>((resolve, reject) => {
try {
const { op, isOp } = shiftResolvedOp();
if (!isOp) {
pushAwaitedTask({ UnlockOp: { lockId, timestamp } });
opMarkerValue = true;
} else {
if (isResolvedSlotOp(op)) {
console.log('unlockOp-slotOp');
return;
}
if (!isResolvedUnlockOp(op)) {
console.log('unlockOp-error');
throw new Error('Unlock operation not found');
}
resolve();
}
} catch (error) {
reject(error);
}
});
(result as Promise<void> & { [opMarker]: boolean })[opMarker] = opMarkerValue;
return result;
};
export const lock = (keys: LockedKey[] | LockedKey) => {
console.log('lockOp');
let opMarkerValue = false;
const result = new Promise<() => Promise<void>>((resolve, reject) => {
try {
const { op, isOp } = shiftResolvedOp();
if (!isOp) {
pushAwaitedTask({
LockOp: { lockId: uuid(), keys: Array.isArray(keys) ? keys : [keys], timestamp: getTime() },
});
opMarkerValue = true;
} else {
if (isResolvedSlotOp(op)) {
console.log('lockOp-slotOp');
return;
}
if (!isResolvedLockOp(op)) {
console.log('lockOp-error');
throw new Error('Lock operation not found');
}
const result = op.LockOp;
resolve(() => unlock(result.lockId, result.timestamp));
}
} catch (error) {
reject(error);
}
});
(result as Promise<() => Promise<void>> & { [opMarker]: boolean })[opMarker] = opMarkerValue;
return result;
};

View File

@ -1,9 +1,8 @@
import { BlockFilter, constructBlock, extractBlock } from '@coinweb/contract-kit';
import { opMarker } from '../../global';
import { isResolvedBlockOp, isResolvedSlotOp } from '../../utils';
import { pushAwaitedTask } from '../awaited';
import { shiftResolvedOp } from '../resolved';
import { opMarker } from '../../../global';
import { isResolvedBlockOp, isResolvedSlotOp } from '../../../utils';
import { pushAwaitedTask, shiftResolvedOp } from '../../runtime';
export const blockOp = (filters: BlockFilter[]) => {
console.log('blockOp');

View File

@ -1,12 +1,11 @@
import { Claim, ClaimKey, constructRangeRead, extractRead } from '@coinweb/contract-kit';
import { ClaimRange } from '@coinweb/contract-kit/dist/types/operations/read';
import { TypedClaim } from '../../../types';
import { context } from '../../context';
import { opMarker } from '../../global';
import { isResolvedReadOp, isResolvedSlotOp } from '../../utils';
import { pushAwaitedTask } from '../awaited';
import { shiftResolvedOp } from '../resolved';
import { TypedClaim } from '../../../../types';
import { context } from '../../../context';
import { opMarker } from '../../../global';
import { isResolvedReadOp, isResolvedSlotOp } from '../../../utils';
import { pushAwaitedTask, shiftResolvedOp } from '../../runtime';
export const rangeReadOp = <TClaims extends Claim[] = TypedClaim[]>(
firstPart: ClaimKey['first_part'],

View File

@ -1,11 +1,10 @@
import { Claim, ClaimKey, constructRead, extractRead } from '@coinweb/contract-kit';
import { TypedClaim } from '../../../types';
import { context } from '../../context';
import { opMarker } from '../../global';
import { isResolvedReadOp, isResolvedSlotOp } from '../../utils';
import { pushAwaitedTask } from '../awaited';
import { shiftResolvedOp } from '../resolved';
import { TypedClaim } from '../../../../types';
import { context } from '../../../context';
import { opMarker } from '../../../global';
import { isResolvedReadOp, isResolvedSlotOp } from '../../../utils';
import { pushAwaitedTask, shiftResolvedOp } from '../../runtime';
export const readOp = <TClaim extends Claim = TypedClaim>(key: ClaimKey) => {
console.log('readOp');

View File

@ -1,10 +1,9 @@
import { Claim, constructStore } from '@coinweb/contract-kit';
import { extractStore } from '@coinweb/contract-kit/dist/esm/operations/store';
import { opMarker } from '../../global';
import { isResolvedSlotOp, isResolvedStoreOp } from '../../utils';
import { pushAwaitedTask } from '../awaited';
import { shiftResolvedOp } from '../resolved';
import { opMarker } from '../../../global';
import { isResolvedSlotOp, isResolvedStoreOp } from '../../../utils';
import { pushAwaitedTask, shiftResolvedOp } from '../../runtime';
export const storeOp = (claim: Claim, storeCweb?: bigint) => {
console.log('storeOp');

View File

@ -1,10 +1,9 @@
import { Claim, ClaimKey, constructTake, extractTake } from '@coinweb/contract-kit';
import { TypedClaim } from '../../../types';
import { opMarker } from '../../global';
import { isResolvedSlotOp, isResolvedTakeOp } from '../../utils';
import { pushAwaitedTask } from '../awaited';
import { shiftResolvedOp } from '../resolved';
import { TypedClaim } from '../../../../types';
import { opMarker } from '../../../global';
import { isResolvedSlotOp, isResolvedTakeOp } from '../../../utils';
import { pushAwaitedTask, shiftResolvedOp } from '../../runtime';
export const takeOp = <TClaim extends Claim = TypedClaim>(key: ClaimKey) => {
console.log('takeOp');

View File

@ -0,0 +1,2 @@
export * from './runtime';
export * from './features';

View File

@ -1,4 +1,4 @@
import { PreparedOp, Task } from '../../types';
import { PreparedOp, Task } from '../../../types';
const awaitedTasks: Task[] = [];

View File

@ -0,0 +1,2 @@
export * from './awaitedTasks';
export * from './resolvedOps';

View File

@ -1,4 +1,4 @@
import { ResolvedOp } from '../../types';
import { ResolvedOp } from '../../../types';
const resolvedOps: ResolvedOp[] = [];

View File

@ -1,4 +0,0 @@
export * from './awaited';
export * from './cwait';
export * from './ops';
export * from './resolved';

View File

@ -1,42 +0,0 @@
import { ResolvedLockOp } from '../../../types';
import { opMarker } from '../../global';
import { LockedKey } from '../../mutex';
import { isResolvedLockOp, isResolvedSlotOp, uuid } from '../../utils';
import { pushAwaitedTask } from '../awaited';
import { shiftResolvedOp } from '../resolved';
export const lockOp = (keys: LockedKey[] | LockedKey) => {
console.log('lockOp');
let opMarkerValue = false;
const result = new Promise<ResolvedLockOp['LockOp']>((resolve, reject) => {
try {
const { op, isOp } = shiftResolvedOp();
if (!isOp) {
pushAwaitedTask({ LockOp: { lockId: uuid(), keys: Array.isArray(keys) ? keys : [keys] } });
opMarkerValue = true;
} else {
if (isResolvedSlotOp(op)) {
console.log('storeOp-slotOp');
return;
}
if (!isResolvedLockOp(op)) {
console.log('lockOp-error');
throw new Error('Lock operation not found');
}
const result = op.LockOp;
resolve(result);
}
} catch (error) {
reject(error);
}
});
(result as Promise<ResolvedLockOp['LockOp']> & { [opMarker]: boolean })[opMarker] = opMarkerValue;
return result;
};

View File

@ -1,38 +0,0 @@
import { opMarker } from '../../global';
import { isResolvedSlotOp, isResolvedUnlockOp } from '../../utils';
import { pushAwaitedTask } from '../awaited';
import { shiftResolvedOp } from '../resolved';
export const unlock = (lockId: string) => {
console.log('lockOp');
let opMarkerValue = false;
const result = new Promise<void>((resolve, reject) => {
try {
const { op, isOp } = shiftResolvedOp();
if (!isOp) {
pushAwaitedTask({ UnlockOp: { lockId } });
opMarkerValue = true;
} else {
if (isResolvedSlotOp(op)) {
console.log('unlockOp-slotOp');
return;
}
if (!isResolvedUnlockOp(op)) {
console.log('unlockOp-error');
throw new Error('Unlock operation not found');
}
resolve();
}
} catch (error) {
reject(error);
}
});
(result as Promise<void> & { [opMarker]: boolean })[opMarker] = opMarkerValue;
return result;
};

View File

@ -152,6 +152,22 @@ export const prepareInThreadTxs = ({
resolvedChildOps.push({ SlotOp: { ok: true } });
});
if (preparedExecOps.length > 0) {
const execId = uuid();
const { callInfo, fee, ops } = constructExecOpsCall({
issuer: context.issuer,
ops: preparedExecOps,
processId: context.thisId,
execId,
});
childCalls.push({ callInfo });
txFee += fee;
callArgs.push(...ops);
}
const returnTxs: NewTx[] = [];
if (callArgs.length) {
@ -230,21 +246,5 @@ export const prepareInThreadTxs = ({
}
}
if (preparedExecOps.length > 0) {
const execId = uuid();
const { callInfo, fee, ops } = constructExecOpsCall({
issuer: context.issuer,
ops: preparedExecOps,
processId: context.thisId,
execId,
});
childCalls.push({ callInfo });
txFee += fee;
callArgs.push(...ops);
}
return { txs: returnTxs, calls: callsPrepared, txFee };
};

View File

@ -35,7 +35,7 @@ export const prepareOutThreadTxs = ({
const preparedCalls: FullCallInfo[] = [];
const preparedOps: PreparedOperation[] = [];
const preparedStoreAndTakes: (PreparedExtendedStoreOp | GTake<CwebTake>)[] = [];
const preparedExecOps: (PreparedExtendedStoreOp | GTake<CwebTake>)[] = [];
let txFee = 0n;
let callsPrepared = 0;
@ -77,7 +77,7 @@ export const prepareOutThreadTxs = ({
}
case isPreparedStoreOp(op):
case isPreparedTakeOp(op): {
preparedStoreAndTakes.push(op);
preparedExecOps.push(op);
break;
}
case isPreparedLockOp(op): {
@ -107,10 +107,10 @@ export const prepareOutThreadTxs = ({
siblingCallResolvedOps.push({ SlotOp: { ok: true } });
});
if (preparedStoreAndTakes.length > 0) {
if (preparedExecOps.length > 0) {
const { callInfo, fee } = constructExecOpsCall({
issuer: context.issuer,
ops: preparedStoreAndTakes,
ops: preparedExecOps,
processId: context.thisId,
});
@ -118,9 +118,17 @@ export const prepareOutThreadTxs = ({
txFee += fee;
}
if (preparedCalls.length > 0 || preparedOps.length > 0) {
return {
txs: [constructContinueTx(getRawContext(), preparedOps, preparedCalls)],
txFee,
calls: callsPrepared,
};
}
return {
txs: [constructContinueTx(getRawContext(), preparedOps, preparedCalls)],
txFee,
calls: callsPrepared,
txs: [],
txFee: 0n,
calls: 0,
};
};

View File

@ -1,7 +1,7 @@
import { constructContinueTx, NewTx, passCwebFrom, sendCwebInterface } from '@coinweb/contract-kit';
import { context, getRawContext } from '../../context';
import { getAwaitedTasks } from '../../promisifiedOps';
import { getAwaitedTasks } from '../../promisifiedFeatures';
import { prepareInThreadTxs } from './prepareInThreadTxs';
import { prepareOutThreadTxs } from './prepareOutThreadTxs';

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="0xbf9ca1687e3441bed1afd495405778a9c06c2f5173829d47d9b87dfb150063d8"
VITE_CONTRACT_ADDRESS="0xa99515a81ee23d07dd08a72ec06646374d28df16de9ccdde16ed7e421ad26c83"