fix: fix mutex results

This commit is contained in:
Alex 2025-05-05 18:57:33 +03:00
parent 7baec6736b
commit 47f21aecdc
11 changed files with 69 additions and 27 deletions

View File

@ -1,4 +1,4 @@
import { extractContinuations, Context } from '@coinweb/contract-kit'; import { extractContinuations, Context, MethodCallback as MethodCallbackOrig } from '@coinweb/contract-kit';
import { import {
getContextCall, getContextCall,
getContextGenesis, getContextGenesis,
@ -54,6 +54,18 @@ export async function executeHandler(contractModule: ContractHandlers): Promise<
}; };
const method = getMethodName(context); const method = getMethodName(context);
const handler = getMethodHandler(contractModule, method); const handler = getMethodHandler(contractModule, method);
console.log('EXECUTE >>>', method);
try {
const txs = await handler(context); const txs = await handler(context);
writeToResultFile(txs); writeToResultFile(txs);
} catch (error) {
if (error instanceof Error) {
console.log('ERROR >>>', error.message);
console.log('ERROR >>>', error.stack);
} else {
console.log('ERROR >>>', error);
}
throw error;
}
} }

View File

@ -68,8 +68,10 @@ export const extractOps = ({
if (isResolvedBlockOp(op)) { if (isResolvedBlockOp(op)) {
const { first } = op.BlockOp.blocks_on[0][0]; const { first } = op.BlockOp.blocks_on[0][0];
console.log('first >>>', JSON.stringify(first));
//Maybe it is needed to check more conditions here //Maybe it is needed to check more conditions here
if (Array.isArray(first) && first[0] === resultKey) { if (Array.isArray(first)) {
switch (first[0]) { switch (first[0]) {
case resultKey: { case resultKey: {
const nextAfterBlock = resolvedOps[i + 1]; const nextAfterBlock = resolvedOps[i + 1];
@ -112,8 +114,11 @@ export const extractOps = ({
const execOpResultClaim = extractRead(nextAfterBlock)?.[0]?.content; const execOpResultClaim = extractRead(nextAfterBlock)?.[0]?.content;
console.log('nextAfterBlock >>>', JSON.stringify(nextAfterBlock));
console.log('execOpResultClaim >>>', JSON.stringify(execOpResultClaim));
if (!execOpResultClaim) { if (!execOpResultClaim) {
throw new Error('Wrong mutex exec result'); throw new Error('Wrong mutex exec result claim');
} }
executedOps = execOpResultClaim.body as MutexExecOpsResult; executedOps = execOpResultClaim.body as MutexExecOpsResult;
@ -143,21 +148,27 @@ export const extractOps = ({
const allOps: ResolvedOp[] = []; const allOps: ResolvedOp[] = [];
for (let i = 0; i < resolvedOps.length + executedOps.length; i++) { const totalOpsCount = extractedOps.length + executedOps.length;
for (let i = 0; i < totalOpsCount; i++) {
console.log('i >>>', i);
console.log('execOpsIndexes.includes(i) >>>', execOpsIndexes.includes(i));
if (execOpsIndexes.includes(i)) { if (execOpsIndexes.includes(i)) {
const op = executedOps.shift(); const op = executedOps.shift();
if (!op) { if (!op) {
throw new Error('Wrong mutex exec result'); throw new Error('Wrong mutex exec result place');
} }
console.log('op >>>', JSON.stringify(op));
if (op.ok) { if (op.ok) {
allOps.push(op.resolved); allOps.push(op.resolved);
} else { } else {
allOps.push({ SlotOp: { ok: false, error: op.error } }); allOps.push({ SlotOp: { ok: false, error: op.error } });
} }
} else { } else {
const op = resolvedOps.shift(); const op = extractedOps.shift();
if (!op) { if (!op) {
throw new Error('Contract call args parsing error'); throw new Error('Contract call args parsing error');

View File

@ -7,7 +7,7 @@ import {
extractRead, extractRead,
PreparedOperation, PreparedOperation,
} from '@coinweb/contract-kit'; } from '@coinweb/contract-kit';
import { getCallParameters, getContractArguments, getContractIssuer } from 'lib/onchain'; import { getCallParameters, getContractIssuer, getMethodArguments } from 'lib/onchain';
import { TypedClaim } from 'lib/shared'; import { TypedClaim } from 'lib/shared';
import { constructMutexExecOpsClaimStore } from '../claims'; import { constructMutexExecOpsClaimStore } from '../claims';
@ -20,7 +20,7 @@ export const execOps = (context: Context) => {
const { availableCweb } = getCallParameters(context); const { availableCweb } = getCallParameters(context);
const issuer = getContractIssuer(context); const issuer = getContractIssuer(context);
const [ops, processId, execId] = getContractArguments<MutexExecOpArgs>(context); const [ops, processId, execId] = getMethodArguments<MutexExecOpArgs>(context);
const lockQueue = extractRead(extractContractArgs(context.tx)[0])?.map( const lockQueue = extractRead(extractContractArgs(context.tx)[0])?.map(
({ content }) => content as TypedClaim<MutexLockState> ({ content }) => content as TypedClaim<MutexLockState>
@ -29,6 +29,10 @@ export const execOps = (context: Context) => {
let availableOps: PreparedOperation[] = []; let availableOps: PreparedOperation[] = [];
const unavailableIndexes: number[] = []; const unavailableIndexes: number[] = [];
console.log('extractContractArgs(context.tx) >>>', JSON.stringify(extractContractArgs(context.tx)));
console.log('ops >>>', JSON.stringify(ops));
console.log('lockQueue >>>', JSON.stringify(lockQueue));
if (!lockQueue) { if (!lockQueue) {
availableOps = ops; availableOps = ops;
} else { } else {

View File

@ -1,11 +1,11 @@
import { constructContinueTx, Context } from '@coinweb/contract-kit'; import { constructContinueTx, Context } from '@coinweb/contract-kit';
import { getContractArguments } from 'lib/onchain'; import { getMethodArguments } from 'lib/onchain';
import { constructMutexBlockLockClaimStore } from '../claims/mutexBlockLock'; import { constructMutexBlockLockClaimStore } from '../claims/mutexBlockLock';
import { MutexNotifyLockArgs } from '../types'; import { MutexNotifyLockArgs } from '../types';
export const notifyLock = (context: Context) => { export const notifyLock = (context: Context) => {
const [lockId] = getContractArguments<MutexNotifyLockArgs>(context); const [lockId] = getMethodArguments<MutexNotifyLockArgs>(context);
return [constructContinueTx(context, [constructMutexBlockLockClaimStore({ lockId })])]; return [constructContinueTx(context, [constructMutexBlockLockClaimStore({ lockId })])];
}; };

View File

@ -6,7 +6,7 @@ import {
extractRead, extractRead,
passCwebFrom, passCwebFrom,
} from '@coinweb/contract-kit'; } from '@coinweb/contract-kit';
import { getCallParameters, getContractArguments, getContractIssuer } from 'lib/onchain'; import { getCallParameters, getContractIssuer, getMethodArguments } from 'lib/onchain';
import { MutexPreReadTakeOpsArgs, MutexSaveExecOpResultArgs } from '../types'; import { MutexPreReadTakeOpsArgs, MutexSaveExecOpResultArgs } from '../types';
@ -16,7 +16,7 @@ export const preReadExecTakeOps = (context: Context) => {
const { availableCweb } = getCallParameters(context); const { availableCweb } = getCallParameters(context);
const issuer = getContractIssuer(context); const issuer = getContractIssuer(context);
const [execId, unavailableIndexes, ops] = getContractArguments<MutexPreReadTakeOpsArgs>(context); const [execId, unavailableIndexes, ops] = getMethodArguments<MutexPreReadTakeOpsArgs>(context);
const storedCweb = extractContractArgs(context.tx) const storedCweb = extractContractArgs(context.tx)
.map((op) => BigInt(extractRead(op)?.[0]?.content.fees_stored ?? 0)) .map((op) => BigInt(extractRead(op)?.[0]?.content.fees_stored ?? 0))

View File

@ -1,5 +1,5 @@
import { constructContinueTx, Context, extractContractArgs } from '@coinweb/contract-kit'; import { constructContinueTx, Context, extractContractArgs } from '@coinweb/contract-kit';
import { getCallParameters, getContractArguments } from 'lib/onchain'; import { getCallParameters, getMethodArguments } from 'lib/onchain';
import { constructMutexExecOpsClaimStore } from '../claims'; import { constructMutexExecOpsClaimStore } from '../claims';
import { MutexExecOpsResult, MutexSaveExecOpResultArgs } from '../types'; import { MutexExecOpsResult, MutexSaveExecOpResultArgs } from '../types';
@ -7,7 +7,7 @@ import { MutexExecOpsResult, MutexSaveExecOpResultArgs } from '../types';
export const saveExecOpResult = (context: Context) => { export const saveExecOpResult = (context: Context) => {
const { availableCweb } = getCallParameters(context); const { availableCweb } = getCallParameters(context);
const [execId, unavailableIndexes] = getContractArguments<MutexSaveExecOpResultArgs>(context); const [execId, unavailableIndexes] = getMethodArguments<MutexSaveExecOpResultArgs>(context);
const resolvedOps = extractContractArgs(context.tx); const resolvedOps = extractContractArgs(context.tx);
const result = new Array(resolvedOps.length + unavailableIndexes.length) const result = new Array(resolvedOps.length + unavailableIndexes.length)

View File

@ -1,5 +1,5 @@
import { constructContinueTx, constructContractRef, constructTake, Context, passCwebFrom } from '@coinweb/contract-kit'; import { constructContinueTx, constructContractRef, constructTake, Context, passCwebFrom } from '@coinweb/contract-kit';
import { getCallParameters, getContractArguments, getContractIssuer } from 'lib/onchain'; import { getCallParameters, getContractIssuer, getMethodArguments } from 'lib/onchain';
import { constructMutexLockClaimKey } from '../claims'; import { constructMutexLockClaimKey } from '../claims';
import { lockFee } from '../settings'; import { lockFee } from '../settings';
@ -11,7 +11,7 @@ export const mutexUnlock = (context: Context) => {
const { availableCweb } = getCallParameters(context); const { availableCweb } = getCallParameters(context);
const issuer = getContractIssuer(context); const issuer = getContractIssuer(context);
const [lockId, timestamp] = getContractArguments<MutexUnlockArgs>(context); const [lockId, timestamp] = getMethodArguments<MutexUnlockArgs>(context);
return [ return [
constructContinueTx( constructContinueTx(

View File

@ -1,5 +1,5 @@
import { constructContinueTx, constructContractRef, Context } from '@coinweb/contract-kit'; import { constructContinueTx, constructContractRef, Context } from '@coinweb/contract-kit';
import { getContractArguments, getContractIssuer } from 'lib/onchain'; import { getContractIssuer, getMethodArguments } from 'lib/onchain';
import { waitSteps } from '../settings'; import { waitSteps } from '../settings';
import { MutexNotifyLockArgs, MutexWaitNotifyArgs } from '../types'; import { MutexNotifyLockArgs, MutexWaitNotifyArgs } from '../types';
@ -8,7 +8,7 @@ import { notifyLockMethodName } from './names';
export const wait = (context: Context) => { export const wait = (context: Context) => {
const issuer = getContractIssuer(context); const issuer = getContractIssuer(context);
const [step, lockId] = getContractArguments<MutexWaitNotifyArgs>(context); const [step, lockId] = getMethodArguments<MutexWaitNotifyArgs>(context);
//Including the notifyLock method as step //Including the notifyLock method as step
if (step + 1 < waitSteps) { if (step + 1 < waitSteps) {

View File

@ -15,7 +15,7 @@ import { ExecutorMethodArgs, PreparedExtendedStoreOp, PreparedOp, ResolvedOp, Re
import { constructFundsClaimRangRead, constructFundsClaimStore } from '../../claims/funds'; import { constructFundsClaimRangRead, constructFundsClaimStore } from '../../claims/funds';
import { constructResultBlockFilter, constructResultClaimTake, resultKey } from '../../claims/result'; import { constructResultBlockFilter, constructResultClaimTake, resultKey } from '../../claims/result';
import { context, getRawContext } from '../../context'; import { context, getRawContext } from '../../context';
import { constructExecOpsCall, constructLockCall, constructUnlockCall } from '../../mutex'; import { constructExecOpsCall, constructLockCall, constructUnlockCall, mutexExecOpsKey } from '../../mutex';
import { import {
isPreparedExecOp, isPreparedExecOp,
isPreparedLockOp, isPreparedLockOp,
@ -47,7 +47,7 @@ export const prepareInThreadTxs = ({
const restOfAvailableCweb = availableCweb - outThreadFee; const restOfAvailableCweb = availableCweb - outThreadFee;
const fee = BigInt(takeOps.length) * 100n - 3000n; const fee = BigInt(takeOps.length) * 100n + 3000n; //TODO: Remove magic numbers
const restOfCweb = restOfAvailableCweb + storedCweb - fee; const restOfCweb = restOfAvailableCweb + storedCweb - fee;
const txs = const txs =
@ -115,10 +115,25 @@ export const prepareInThreadTxs = ({
break; break;
} }
case isPreparedStoreOp(op): case isPreparedStoreOp(op): {
case isPreparedTakeOp(op): { if ((op.StoreOp.key.first_part as [string])[0] !== resultKey) {
preparedExecOps.push(op); preparedExecOps.push(op);
excOpsIndexes.push(i); excOpsIndexes.push(i);
} else {
callArgs.push(op);
txFee += 100n;
}
break;
}
case isPreparedTakeOp(op): {
//TODO: simplify to decrease coupling
if ((op.TakeOp.key.first_part as [string])[0] !== mutexExecOpsKey) {
preparedExecOps.push(op);
excOpsIndexes.push(i);
} else {
callArgs.push(op);
txFee += 100n;
}
break; break;
} }
case isPreparedLockOp(op): { case isPreparedLockOp(op): {

View File

@ -27,7 +27,7 @@ export const prepareTx = (
const { availableCweb, takeOps, storedCweb } = context.funds; const { availableCweb, takeOps, storedCweb } = context.funds;
const { user } = context; const { user } = context;
const fee = BigInt(takeOps.length) * 100n - 3000n; const fee = BigInt(takeOps.length) * 100n + 3000n; //TODO: Remove magic numbers
const restOfCweb = availableCweb + storedCweb - fee; const restOfCweb = availableCweb + storedCweb - fee;
const txs = const txs =

View File

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