Giter Club home page Giter Club logo

Comments (10)

digorithm avatar digorithm commented on August 27, 2024 1

Update: managed to replicate, have a few ideas of what might be causing it. Will post an update soon!

from fuels-rs.

digorithm avatar digorithm commented on August 27, 2024 1

Alright, this was a tricky one to debug, and it highlights some shortcomings in the fuel-core and the SDK. Many thanks to @Voxelot for helping me

The issue begins at this fundamental truth: every call we make at the SDK/client level generates a transaction.

That means we don't have a concept of read-only .call()-like method. Like this for instance.

That said... Sushi Sway is doing a couple of things:

  1. deposit (write)
  2. check balance ("read")
  3. withdraw (write)
  4. check the balance again ("read")

The issue here is that (2) and (4), the two checks, look like this:

let balance_of_check0 = mycontract_mod::BalanceOfInput {
    address: [10; 32],
    asset_id: [0; 32],
};

let initial_bal = contract_instance
    .balance_of(balance_of_check0) // <--- first call to balance_of
    .call()
    .await
    .unwrap();

and

let balance_of_check1 = mycontract_mod::BalanceOfInput {
    address: [10; 32],
    asset_id: [0; 32],
};

let final_bal = contract_instance
    .balance_of(balance_of_check1) // <--- second call to balance_of
    .call()
    .await
    .unwrap();

Notice that, because balance_of_check1 and balance_of_check0 are the same (same address and asset_id), the transactions generated by balance_of will be the same. Meaning the same transaction id, meaning OutputAlreadyExists.

The shortcoming on our end is that a method that's supposed to be read-only is actually generating a transaction when it shouldn't. But we don't have an API for read-only yet.

Short-term very weird workaround: make BalanceOfInput have an unused RNG-based field so that balance_of_check0 and balance_of_check1 are different and will then generate different transactions, avoiding the collision.

The actual solution, as suggested in a conversation with @Voxelot, to split the generated methods (by the abigen) between .send() (or something) that will actually create a transaction and a .call(), that underneath will use fuel-core's dry-run to not create a transaction, meaning these read-only functions can be called many times and not cause tx id collision.

cc @adlerjohn once we agree on the solution, the semantics, and the naming of .call() and .send() I'll create an issue so that we can tackle it asap.

from fuels-rs.

adlerjohn avatar adlerjohn commented on August 27, 2024 1

Yeah, makes sense to separate call and send in the same way as Ethereum, and using dry run. Good work debugging!

from fuels-rs.

adlerjohn avatar adlerjohn commented on August 27, 2024 1

Should this issue be transferred to fuels-rs @digorithm ?

from fuels-rs.

adlerjohn avatar adlerjohn commented on August 27, 2024 1

Note that we also need a solution for non-view-only calls that happen to modify state rather than being inherently view-only. This could be accomplished by inserting a random coin input. Or better, a change output to a random address!

from fuels-rs.

adlerjohn avatar adlerjohn commented on August 27, 2024

Does this happen when running tests sequentially? My first guess is that if you run tests more than once, it'll try to deploy the same contracts again. Since they already exist in the state, you'll get that error. If can be fixed by clearning ~/.fuel and restarting your node. Or, running the node with an in-memory db: --fuel-core --db-type in-memory.

from fuels-rs.

ControlCplusControlV avatar ControlCplusControlV commented on August 27, 2024

It still seems to be happening even if I comment out all the other tests, rm ~/.fuel and restart my computer, not sure what is causing it then. Can you replicate?

from fuels-rs.

adlerjohn avatar adlerjohn commented on August 27, 2024

Guessing this is probably an SDK issue then. cc @digorithm to triage.

from fuels-rs.

digorithm avatar digorithm commented on August 27, 2024

That's odd. I always get this error when deploying a contract already deployed, as expected. And then removing the fuel dir does it for me.

Weird that removing the dir isn't resolving the issue in your case, I'll do some triaging today!

from fuels-rs.

digorithm avatar digorithm commented on August 27, 2024

Tracking this here #90

from fuels-rs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.