Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrap promises and cross contract calls #6

Closed
MaksymZavershynskyi opened this issue Jun 8, 2019 · 3 comments
Closed

Wrap promises and cross contract calls #6

MaksymZavershynskyi opened this issue Jun 8, 2019 · 3 comments

Comments

@MaksymZavershynskyi
Copy link
Contributor

We need to wrap promises and cross contract calls in some familiar abstractions, e.g. Futures or async/await.

@think-in-universe
Copy link
Member

do we have any plan to work on the futures or async/await syntax?

@austinabell
Copy link
Contributor

This isn't currently feasible with NEAR's async programming model. Rust async primitives assume you can continue to run the current process and poll to return the yielded future type. This is under the assumption that another task/thread will progress this future. This can't be applied here because the future that we would be awaiting is planned to be executed n blocks in the future (depending on how many blocks it takes for the async call), but the current method must execute in the current block. Thus, we cannot pass the data back to the current method.

Trying to force this model just for the syntactic familiarity would add confusion and lead to some janky patterns that don't fit well with NEAR's VM. I'd like to hear if someone has an idea on how this can be done cleanly that would be an improvement over what exists.

@formula1
Copy link

formula1 commented Feb 4, 2022

Overall Idea - Mutation listeners

I have no idea how rust works but instead of async await, intercontract interaction can be based on "before mutate", "after full mutate" and 'on property mutate'

In each method in a contract, they have a few dependency lists

  • before mutate - A list of addresses that should resolve to smart contracts
    • These are read only
  • after full mutate - A list of addresses that should resolve to smart contracts
    • These can mutate other contracts
    • May be useful for smart contracts to check if they have a 0 balance on their bank account
      • At the start of a smart contract, they may be at 100
      • But then the smart contract itself sends it's balance to a pool for some reason
      • So another smart contract, based on the fact it has 0 balance, sends more money in automatically
  • on property mutate
    • These probably should be read only
    • If a smart contract only care's that certian properties and don't need to worry about everything, they can listen to this specific property update.
    • I don't think it's a good idea to mutate a contract based off an event though the smart contract may be able to mutate themselves

Then when a method on the contract is running

  • It checks what addresses are before mutate
    • for each address it grabs the previous state
    • These contracts can be run in parrallel
  • It checks what addresses are after mutate
    • These contracts must be run synchronously, though their dependencies may be able to be run in parrallel

It is up to the developer to install the library and cast an address as the desired class though since addresses can just be users.

A few issues

  • two contracts want to manipulate eachother at the same time
    • if A.method mutates properties that B.method doesn't need, great
    • if B.method mutates properties that A.method doesn't need, great
    • if A.method mutates properties that B.method needs but not the other way, B.method goes first
    • same only in reverse this
    • If A.method mutates properties that B.method needs and B.method mutates properties that A.method needs
      • we get an issue
      • Perhaps this can be detected during compilation can cause a failure to build
      • how does updating a smart contract work now? I suspect the individual has to support old functions.
      • But preventing people from updating smart contracts may be able to solve this issue
  • Another issue is if two contracts want to mutate another contract in the same block. Who goes first?
    • If for example two smart contracts have a shared bank account and both trying to withdraw 100 dollars when only 150 is available, we have an issue
    • And the logistics of making a developer have to handle multiple people all requesting to use the same method at once seems insane but perhaps it's necessary.
      • For a mutation, you get a list of addresses all trying to do the same thing and the arguments they provided rather than just a single address calling the function
    • I suppose this can be a basic smart contract issue that near may have already solved
  • Another issue is if a smart contract only wants to listen to mutations after everyother smart contract has mutated itself
    • While it makes sense for self mutation to go first
    • If a smart contract were to for example withdraw more money only after they were to go to negative or 0 balance, they want to wait until other smart contracts have finished mutating
    • Perhaps it is fine for them to check during each mutation
      • withdraw(sum){ balance < sum && withdraw(100); send(currentAddress, sum) }

But at least this way they don't have to implement some sort of loop. things can just be synchronous

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

No branches or pull requests

4 participants