Skip to content

Conversation

@joaosreis
Copy link
Collaborator

This PR creates a queue-like mechanism for the state methods with a method that can be awaited until all the queued promises are resolved. This method is then called after a runtime method executes, which makes is so that these state operations are executed in the proper runtime moment (and in the order they are queued) even if the user misses to await them.
This helps mitigate the issue of missing awaits to state methods (#199), ensuring these are properly executed if they are runtime methods top level calls, but not if the runtime method calls some other method with state calls and this method is not awaited, because then the runtime method execution can finish before the other method had the chance to queue the operations. An example of such behavior would be:

@runtimeMethod()
  public async addBalance(
    tokenId: TokenId,
    address: PublicKey,
    amount: Balance
  ): Promise<void> {
    const circulatingSupply = await this.circulatingSupply.get();
    const newCirculatingSupply = Balance.from(circulatingSupply.value).add(
      amount
    );
    assert(
      newCirculatingSupply.lessThanOrEqual(this.config.totalSupply),
      "Circulating supply would be higher than total supply"
    );
    this.circulatingSupply.set(newCirculatingSupply);
    this.mint(tokenId, address, amount); // missing await in a method that calls state methods
}

However, if we deconstruct the mint method into

const key = new BalancesKey({ tokenId, address });
const balanceOption = await this.balances.get(key);
const balance = Balance.Unsafe.fromField(balanceOption.value.value);
const newBalance = balance.add(amount);
this.balances.set(key, newBalance);

this code will now work despite the missing awaits in the state set calls.

I also tested adding a 50ms delay timeout to the queue onCompleted method in an attempt to help these other missing awaits catchup, but ended up not adding it as I felt that it might not work if the complexity of the runtime methods increases as well because this doesn't ensure the linearity of these calls.

joaosreis and others added 28 commits November 26, 2024 09:47
… in get() and set() methods; remove GlobalExecutionContext class
…ration handling; replace promise chaining with a queue system for better management of pending operations
…e class; refactor get() and set() methods to utilize the new queue system
@joaosreis joaosreis self-assigned this Jan 10, 2025
@joaosreis joaosreis requested a review from rpanic January 10, 2025 11:01
@joaosreis joaosreis requested review from ejMina226, maht0rz and rpanic and removed request for rpanic January 10, 2025 11:01
@rpanic
Copy link
Member

rpanic commented Apr 1, 2025

Not really the approach we were going for, closing in favor of a future implementation

@rpanic rpanic closed this Apr 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants