sway/docs
zees-dev 0ac606c132
forc-call detailed vm-interpreter call traces (#7251)
## Description

This PR updates the `forc call` functionality to provide detailed call
traces.
This is achieved via retrieving `Vec<StorageReadReplayEvent>` from
transactions (dry-run and/or live mode) and executing these in a
vm-interpreter.
- The approach is inspired by code snippets from this repo:
https://github.com/FuelLabs/execution-trace

### Additional `forc-call` updates:
- introduction of contract address labelling via `--label
<contract-addr>:<name>`
- introduction of providing additional contract abis via `--contract-abi
<contract-addr>:<abi-file-or-url>`

#### Example

Assume the following 2 contracts - where `demo-caller` calls `demo`
contract:
- `demo`:
`0xe84e278cb083a5b3ff871f1d3de26fdd13ae044070e1bbda18b60a13f98bb295`
- `demo-caller`:
`0xed4437b191cc78a02df048f21a73df37f1627efdde7d7e4232468b9de9d83485`

<details>
<summary>demo contract source</summary>

```sway
contract;

use std::{logging::log};

struct Adder {
    vals: (u64, u64),
}

abi Demo {
    #[storage(read)]
    fn get_count() -> u64;

    #[storage(read, write)]
    fn increment_count(adder: Adder);
}

storage {
    count: u64 = 0,
}

impl Demo for Contract {
    #[storage(read)]
    fn get_count() -> u64 {
        storage.count.read() + 1
    }

    #[storage(read, write)]
    fn increment_count(adder: Adder) {
        let new_count = storage.count.read() + adder.vals.0 + adder.vals.1;
        storage.count.write(new_count);
        log(new_count);
    }
}
```
</details>

<details>
<summary>demo-caller contract source</summary>

```sway
contract;

use std::contract_id::ContractId;

struct Adder {
    vals: (u64, u64),
}

abi Demo {
    #[storage(read)]
    fn get_count() -> u64;
    
    #[storage(read, write)]
    fn increment_count(adder: Adder);
}

abi DemoCaller {
    #[storage(read, write)]
    fn call_increment_count(adder: Adder) -> u64;
    
    #[storage(read)]
    fn check_current_count() -> u64;
}

const CONTRACT_ID = 0xe84e278cb083a5b3ff871f1d3de26fdd13ae044070e1bbda18b60a13f98bb295;

impl DemoCaller for Contract {
    #[storage(read, write)]
    fn call_increment_count(adder: Adder) -> u64 {
        let demo = abi(Demo, CONTRACT_ID);
        demo.increment_count(adder);
        log("incremented count");
        log(demo.get_count());
        log("done");
        demo.increment_count(Adder { vals: (5, 2) });
        demo.get_count()
    }
    
    #[storage(read)]
    fn check_current_count() -> u64 {
        let demo = abi(Demo, CONTRACT_ID);
        demo.get_count()
    }
}
```
</details>

**Previous functionality**:

```sh
cargo run -p forc-client --bin forc-call -- \
  --abi ./demo/demo-caller/out/release/demo-caller-abi.json \
  ed4437b191cc78a02df048f21a73df37f1627efdde7d7e4232468b9de9d83485 \
  call_increment_count "{(1,1)}" -vvv
```

**Output**:
<img width="721" alt="Screenshot 2025-06-24 at 12 14 53 PM"
src="https://github.com/user-attachments/assets/2ef77293-54eb-46c3-989a-b7f8cf9d236c"
/>

**Updated functionality**:
```sh
cargo run -p forc-client --bin forc-call -- \
  --abi ./demo/demo-caller/out/release/demo-caller-abi.json \
  ed4437b191cc78a02df048f21a73df37f1627efdde7d7e4232468b9de9d83485 \
  --contract-abi e84e278cb083a5b3ff871f1d3de26fdd13ae044070e1bbda18b60a13f98bb295:./demo/demo/out/release/demo-abi.json \
  --label ed4437b191cc78a02df048f21a73df37f1627efdde7d7e4232468b9de9d83485:demo-caller \
  --label e84e278cb083a5b3ff871f1d3de26fdd13ae044070e1bbda18b60a13f98bb295:demo \
  call_increment_count "{(1,1)}" -vv
```

**Output**:
<img width="760" alt="Screenshot 2025-06-24 at 12 15 25 PM"
src="https://github.com/user-attachments/assets/442c0a97-80f8-46b6-bdf9-d67952c28b58"
/>

### Other misc. improvements to `forc-call`
- refactor of the forc-call verbosity levels and functions (arguably
cleaner code)
- re-write of the tracing to simply process receipts and indent via
stack - instead of recursively constructing node-call tree
- closes https://github.com/FuelLabs/sway/issues/7197

## AI description

This pull request introduces significant enhancements to the `forc call`
functionality, improving usability, debugging, and trace readability for
multi-contract interactions.
The changes include support for labeled contract addresses, additional
ABI files for better decoding, and updates to verbosity levels.
Additionally, dependencies and internal parsing logic have been updated
to support these features.

### Enhancements to `forc call` functionality:

* **Support for labeled contract addresses:**
- Added the `--label` flag to allow users to assign human-readable
labels to contract addresses in transaction traces, improving
readability.
[[1]](diffhunk://#diff-466e2f9659cab303594eb73a846768ecdbc1a13030e5869cdac51ddde87dd313R289-R302)
[[2]](diffhunk://#diff-4ee92d729fce66f7e7aed1fc29b41834951eb63198e0da747b9b9e45d13f717bR248-R320)
- Updated documentation to include examples of using labels in traces.
[[1]](diffhunk://#diff-4ee92d729fce66f7e7aed1fc29b41834951eb63198e0da747b9b9e45d13f717bR63-R73)
[[2]](diffhunk://#diff-466e2f9659cab303594eb73a846768ecdbc1a13030e5869cdac51ddde87dd313R184-R193)

* **Support for additional ABIs:**
- Introduced the `--contract-abi` flag to specify additional contract
ABIs for decoding function signatures, parameters, and return values in
multi-contract interactions.
[[1]](diffhunk://#diff-466e2f9659cab303594eb73a846768ecdbc1a13030e5869cdac51ddde87dd313R289-R302)
[[2]](diffhunk://#diff-466e2f9659cab303594eb73a846768ecdbc1a13030e5869cdac51ddde87dd313R209-R217)
  - Updated the parsing logic to handle additional ABIs and labels.
- Documentation now includes examples and explanations for using
additional ABIs.
[[1]](diffhunk://#diff-4ee92d729fce66f7e7aed1fc29b41834951eb63198e0da747b9b9e45d13f717bR102-R115)
[[2]](diffhunk://#diff-4ee92d729fce66f7e7aed1fc29b41834951eb63198e0da747b9b9e45d13f717bR248-R320)

* **Improved verbosity and tracing:**
- Adjusted verbosity levels to make transaction traces available at
`-vv` instead of `-vvv`.
- Enhanced trace output to include labeled contract addresses and
decoded function information.
[[1]](diffhunk://#diff-4ee92d729fce66f7e7aed1fc29b41834951eb63198e0da747b9b9e45d13f717bL253-R333)
[[2]](diffhunk://#diff-4ee92d729fce66f7e7aed1fc29b41834951eb63198e0da747b9b9e45d13f717bR357-R413)

### Dependency and internal updates:

* **Dependency additions:**
- Added `fuel-core-storage` as a dependency in `Cargo.toml` to support
new features.
[[1]](diffhunk://#diff-2e9d962a08321605940b5a657135052fbcef87b5e360662bb527c96d9a615542R93)
[[2]](diffhunk://#diff-f0f5128eecb15714bd0a80d1f03d87a84f375d0598471bb27e3bb388c188550cR49)

* **Parsing and execution logic:**
- Refactored `forc-client` to include reusable functions for parsing
ABIs and labels.
- Updated the `call_function` logic to handle additional ABIs and
integrate with the new dry-run execution method.
[[1]](diffhunk://#diff-7da99987eeed69f070b781a5692d3acc7028308b8538ca129d79452ccc057fdeR54-R64)
[[2]](diffhunk://#diff-7da99987eeed69f070b781a5692d3acc7028308b8538ca129d79452ccc057fdeL137-R172)

## Checklist

- [ ] I have linked to any relevant issues.
- [ x] I have commented my code, particularly in hard-to-understand
areas.
- [x] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [ ] I have requested a review from the relevant team or maintainers.

---------

Co-authored-by: z <zees-dev@users.noreply.github.com>
Co-authored-by: kaya <20915464+kayagokalp@users.noreply.github.com>
2025-06-30 19:14:25 +12:00
..
book forc-call detailed vm-interpreter call traces (#7251) 2025-06-30 19:14:25 +12:00
reference Defining, parsing, and checking #[attribute]s (#6986) 2025-03-24 09:34:31 +11:00
slides Merge std and core libraries (#6729) 2025-03-12 23:52:38 +01:00
breaking-release-checklist.md Add docs for error handling (ABI errors, panic, error_type, error) (#7249) 2025-06-23 13:15:50 +00:00
internals.md Implements fully working hierarchical lexical scopes. (#6784) 2025-01-13 11:02:20 +11:00