Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
9776284
Add GlobalExecutionContext class to manage state calls
joaosreis Nov 26, 2024
29d6d28
Enhance state management by integrating GlobalExecutionContext for pr…
joaosreis Nov 26, 2024
ca8cbbc
Add async-mutex dependency to package.json and package-lock.json
joaosreis Dec 4, 2024
d1c22fd
Refactor state management to use mutex for exclusive access in get() …
joaosreis Dec 4, 2024
293b65a
Refactor state management to use a promise queue for exclusive access…
joaosreis Dec 6, 2024
7c8a29c
Add OperationQueue for managing asynchronous operations in state mana…
joaosreis Dec 18, 2024
050daf9
Refactor OperationQueue and State classes to improve asynchronous ope…
joaosreis Dec 19, 2024
84111f2
Implement OperationQueue for managing asynchronous operations in Stat…
joaosreis Dec 19, 2024
70e4c04
WIP
joaosreis Dec 20, 2024
d7d059c
Remove debug logging from getBalance and mint methods in Balances class
joaosreis Jan 10, 2025
6b73fbd
Add comments and cleanup
joaosreis Jan 10, 2025
cdc903e
Remove unnecessary isToEnqueue
joaosreis Jan 10, 2025
e4a6638
Refactor OperationQueue to simplify queue management
joaosreis Jan 10, 2025
2672d27
Remove isToEnqueue assignment in state decorator
joaosreis Jan 10, 2025
3a98cf1
Remove unnecessary isToEnqueue property from StateMap class
joaosreis Jan 10, 2025
ff3dc6e
Remove enqueuement from StateMap
joaosreis Jan 10, 2025
9dbb218
Simplify State
joaosreis Jan 10, 2025
7b6e624
Make stack library private
ejMina226 Dec 6, 2024
5deb490
Resolve ordering
ejMina226 Dec 13, 2024
1e9323f
Update logs
ejMina226 Dec 13, 2024
0cc86da
Add logs
ejMina226 Dec 13, 2024
bebeda9
Fix comments
ejMina226 Dec 13, 2024
5e7acfa
Remove async-mutex dependency from package-lock.json
joaosreis Jan 10, 2025
01e7f79
Revert change
joaosreis Jan 10, 2025
356cf11
Revert more changes
joaosreis Jan 10, 2025
c0a3721
Merge remote-tracking branch 'origin/develop' into feature/state-exec…
joaosreis Jan 10, 2025
e242173
More cleanups
joaosreis Jan 10, 2025
8bb6b68
Add comments and docs to OperationQueue
joaosreis Jan 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/common/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ export * from "./trees/InMemoryMerkleTreeStorage";
export * from "./trees/RollupMerkleTree";
export * from "./events/EventEmitterProxy";
export * from "./trees/MockAsyncMerkleStore";
export * from "./operationQueue";
37 changes: 37 additions & 0 deletions packages/common/src/operationQueue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
export type AsyncOperation<T> = () => Promise<T>;

export class OperationQueue {
private queue: Promise<void>;

constructor() {
// Start with a resolved promise
this.queue = Promise.resolve();
}

/**
* Queue an operation to be executed
* @param operation - The operation to queue
* @returns A promise that resolves when the operation is completed
*/
public queueOperation<T>(operation: AsyncOperation<T>): Promise<T> {
// Chain the operation to the end of the queue and store the result
// of the queued operation to return to the caller if he wants to wait
// for it
const result = this.queue.then(() => operation());

// Update the queue and discard any errors
this.queue = result.then(
() => undefined,
() => undefined
);
return result;
}

/**
* Wait for all operations to complete
* @returns A promise that resolves when all operations are completed
*/
public async onCompleted(): Promise<void> {
await this.queue;
}
}
6 changes: 6 additions & 0 deletions packages/module/src/method/runtimeMethod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ export function toWrappedMethod(
...args
): Promise<MethodPublicOutput> => {
await Reflect.apply(moduleMethod, this, args);
// await pending state operations to complete
await container
.resolve(RuntimeMethodExecutionContext)
.operationQueue.onCompleted();
const {
result: { stateTransitions, status, events },
} = executionContext.current();
Expand Down Expand Up @@ -285,6 +289,8 @@ function runtimeMethodInternal(options: {
let result: unknown;
try {
result = await Reflect.apply(simulatedMethod, this, args);
// await pending state operations to complete
await executionContext.operationQueue.onCompleted();
} finally {
executionContext.afterMethod();
}
Expand Down
52 changes: 30 additions & 22 deletions packages/protocol/src/state/State.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,18 +130,22 @@ export class State<Value> extends Mixin(WithPath, WithStateServiceProvider) {
*
* @returns Option representation of the current state.
*/
public async get(): Promise<Option<Value>> {
const option = await this.witnessFromState();
public async get() {
return await container
.resolve(RuntimeMethodExecutionContext)
.operationQueue.queueOperation(async () => {
const option = await this.witnessFromState();

this.hasPathOrFail();
this.hasPathOrFail();

const stateTransition = StateTransition.from(this.path, option);
const stateTransition = StateTransition.from(this.path, option);

container
.resolve(RuntimeMethodExecutionContext)
.addStateTransition(stateTransition);
container
.resolve(RuntimeMethodExecutionContext)
.addStateTransition(stateTransition);

return option;
return option;
});
}

/**
Expand All @@ -156,20 +160,24 @@ export class State<Value> extends Mixin(WithPath, WithStateServiceProvider) {
* @param value - Value to be set as the current state
*/
public async set(value: Value) {
// link the transition to the current state
const fromOption = await this.witnessFromState();
const toOption = Option.fromValue(value, this.valueType);

this.hasPathOrFail();

const stateTransition = StateTransition.fromTo(
this.path,
fromOption,
toOption
);

container
return await container
.resolve(RuntimeMethodExecutionContext)
.addStateTransition(stateTransition);
.operationQueue.queueOperation(async () => {
// link the transition to the current state
const fromOption = await this.witnessFromState();
const toOption = Option.fromValue(value, this.valueType);

this.hasPathOrFail();

const stateTransition = StateTransition.fromTo(
this.path,
fromOption,
toOption
);

container
.resolve(RuntimeMethodExecutionContext)
.addStateTransition(stateTransition);
});
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Bool, FlexibleProvablePure, Provable, Struct } from "o1js";
import { singleton } from "tsyringe";
import {
OperationQueue,
ProvableMethodExecutionContext,
ProvableMethodExecutionResult,
} from "@proto-kit/common";
Expand Down Expand Up @@ -63,6 +64,8 @@ export class RuntimeMethodExecutionContext extends ProvableMethodExecutionContex

private isSimulated: boolean = false;

public operationQueue = new OperationQueue();

private assertSetupCalled(): asserts this is {
input: RuntimeMethodExecutionData;
} {
Expand Down
Loading