sway icon indicating copy to clipboard operation
sway copied to clipboard

Storage is not initialized and will revert on `read()`

Open hal3e opened this issue 2 years ago • 5 comments

Given the contract code:

contract;

storage {
    x: u64 = 64,
}

abi MyContract {
    #[storage(read)]
    fn get_value() -> u64;
}  
  
impl MyContract for Contract {
    #[storage(read)]
    fn get_value() -> u64 {
        storage.x.read()
    }
}

storage.x.read() will revert because we call unwrap() on a None value.

To recreate follow the steps from the fuel book: https://fuelbook.fuel.network/master/quickstart/smart-contract.html, and use the contract example above.

hal3e avatar Jun 06 '23 10:06 hal3e

Cannot repro this, added a new test to the suite based on the contract provided: https://github.com/FuelLabs/sway/commit/98d8d78a6e76c6c927ace3b68138fe7b37d5ee03

It runs successfully, deploys the contract, calls get_value and returns the expected initial value of 64 in storage.

tritao avatar Jun 13 '23 09:06 tritao

I tried it again.

  • Created a new project with forc init.
  • Added tests with cargo generate --init fuellabs/sway templates/sway-test-rs --name {SOME_NAME}.
  • Built with forc 0.40.0.
  • Ran tests with cargo test ( used fuels-rs 0.42 and fuel-core 0.18.2)

I still get the Revert(0) panic

hal3e avatar Jun 13 '23 10:06 hal3e

@hal3e Followed your instructions and still everything passes.

running 1 test
test can_get_contract_id ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.33s

I guess the only difference is I'm on a slightly more recent Forc version (733d9b58865b71cbfdd3f50e0d88e57487856833):

forc 0.40.1
Fuel Orchestrator

Do I need any custom changes to the harness.rs to trigger it or just the default generated version triggers it on your end?

tritao avatar Jun 13 '23 13:06 tritao

Thanks for looking into this.

You have to call the method. Here is what I did:

use fuels::{prelude::*, types::ContractId};

// Load abi from json
abigen!(Contract(
    name = "MyContract",
    abi = "out/debug/{SOME_NAME}-abi.json"
));

async fn get_contract_instance() -> (MyContract<WalletUnlocked>, ContractId) {
    // Launch a local network and deploy the contract
    let mut wallets = launch_custom_provider_and_get_wallets(
        WalletsConfig::new(
            Some(1),             /* Single wallet */
            Some(1),             /* Single coin (UTXO) */
            Some(1_000_000_000), /* Amount per coin */
        ),
        None,
        None,
    )
    .await;
    let wallet = wallets.pop().unwrap();

    let id = Contract::load_from(
        "./out/debug/predicate-true.bin",
        LoadConfiguration::default(),
    )
    .unwrap()
    .deploy(&wallet, TxParameters::default())
    .await
    .unwrap();

    let instance = MyContract::new(id.clone(), wallet);

    (instance, id.into())
}

#[tokio::test]
async fn can_get_value() {
    let (instance, _id) = get_contract_instance().await;

    instance.methods().get_value().call().await.unwrap();
}

SOME_NAME - use your project name. FYI I also tried the test with forc 0.40.1 and I get the same revert.

hal3e avatar Jun 13 '23 13:06 hal3e

Cool, thanks for the help.

I can repro it now:

thread 'can_get_contract_id' panicked at 'called `Result::unwrap()` on an `Err` value: RevertTransactionError { reason: "Revert(0)", revert_id: 0, receipts: [Call { id: 0000000000000000000000000000000000000000000000000000000000000000, to: 6d24908d1dda644c74a7071206305b2015c5da47cd927d9da3bd3f0bd3ba6a37, amount: 0, asset_id: 0000000000000000000000000000000000000000000000000000000000000000, gas: 1000000, param1: 3444169300, param2: 1, pc: 11624, is: 11624 }, Revert { id: 6d24908d1dda644c74a7071206305b2015c5da47cd927d9da3bd3f0bd3ba6a37, ra: 0, pc: 11908, is: 11624 }, ScriptResult { result: Revert, gas_used: 319 }] }', tests/harness.rs:41:49

Not really sure what's going on, the same test works when run on the compiler test suite (which also runs and calls the method, and returns the correct value).

tritao avatar Jun 13 '23 15:06 tritao