warp-contracts / warp

An implementation of the Arweave SmartWeave smart contracts protocol.
MIT License
159 stars 44 forks source link

fix: refactor the internal writes #290

Closed ppedziwiatr closed 1 year ago

ppedziwiatr commented 1 year ago

Introduce the "uncommited state" - each contract on the call tree for a given interaction should have its own uncommited state. This state should be used during the evaluation of the internal writes. e.g. if Contract A writes to Contract B - and we're reading the state of the Contract B:

  1. Read the state of the Contract B up to the internal write interaction
  2. for the internal write interaction - set the uncommited state for contract B to current state
  3. read the state of the contract A (the one that performs write on contract B)
  4. at the time the Contract A tries to perform a write on Contract B - read Contract B state from the contract.parent().uncommitedState, where contract = Contract A contract.parent() = Contract B and perform the write. The result of the write should be stored in contract.parent().uncommitedState
  5. After returning with evaluiation to Contract B - load its state from contract.uncommitedState

Watch out while evaluating the writes from the 'caller' (i.e. the one that is performing a write) contract perspective.

At the end of the evaluation of each interaction of the 'root' contract (i.e. the that user is trying to read via contract.readState() - commit all "uncommited states" in the root contract's call tree (i.e. store the results in the SDK cache).

This change should also allow to remove the "inf. loop fix" (which protects agains falling into inf. call loop when contracts are interacting with each other (Contract A reads/writes to Contract B, where Contract B reads/writes to A, etc...) and simplify the evaluator code.

This should also allow to achieve https://github.com/warp-contracts/warp/issues/195

ppedziwiatr commented 1 year ago

since 1.2.49