SIGN IN SIGN UP
FuelLabs / fuel-core UNCLAIMED

Rust full node implementation of the Fuel v2 protocol.

0 0 15 Rust

Use hash-based balance_root and state_root fields (#3099)

## Description

@xgreenx writes on
[slack](https://fuellabs.slack.com/archives/C01KVGRDZHB/p1755856188397269?thread_ts=1749203886.570819&cid=C01KVGRDZHB):

> Storing storage slots in the transaction makes the blob really, really
big; it can even be bigger than the allowance for the block, but we will
only know about its size after the execution. So having a malleable list
of storage slots is a bad idea, not taking into account that it is not
compressible and will make p2p worse.
Also, on the fraud-proving side, in the case of the Validium solution,
these storage slots are useless, because we need to prove in one go the
latest values for storage slots(which requires a global merkle root). In
the case of V2 fraud proof solution(where we prove the execution only of
the transaction), it is more useful because it allows executing the
transaction in one go(assuming storage slots are correct). But it is
needed only in the case that a block producer used incorrect values
during the execution of the transaction.
We can get almost the same properties by going another route:
> 1. Use a hash of all storage slots/balances(hash over sorted list of
(Key, Option<Value>)) and use balance_root and state_root fields in the
input and output.
> 2. For input of the contract, we will use all storage slots/balances
accessed during the execution, even if the value for them is None in the
storage. In this case, we can be sure that the block producer listed all
the required information to execute the transaction.
> 3. Output will contain a hash of the same storage slots/balances after
the execution.
> 4. Regular blocks and transactions that we use to sync with the
network(and on UI) will not be affected. But anyone will be able to
request additional metadata for a transaction, like storage slots before
and after the execution(we will store them in the off-chain database).
> 5. For the validium case, we will just create a global merkle root of
the storage and balances for all contracts. It will be much faster,
because it is just one bulk update into SMT(a bulk update of 100_000
updates is faster than 100_000 single updates in 50-100 times).
> 6. In the case of V2 fraud proofs, the case with incorrect initial
values is already a 2-round game; we will just add an additional round,
where the block producer should reveal initial values(it can be done
on-chain or off-chain). If we don't want to have an additional step
here, then we can post this data along with transactions to DA.
In this case, we don't change the layout of the transaction(we use all
the fields that we have right now; the tx_pointer field is useless in
this context, but it is fine). We don't affect the network. This
information will be accessible via GraphQL.
Implementation, then, is very straightforward and fast. The only problem
that we need to solve is how to post the old state of the network(old
storage slots and balances before we started to use this approach with
storage slots). But we have this issue regardless of the approach we
use. So it is a separate topic.

## Checklist
- [ ] Breaking changes are clearly marked as such in the PR description
and changelog
- [ ] New behavior is reflected in tests
- [ ] [The specification](https://github.com/FuelLabs/fuel-specs/)
matches the implemented behavior (link update PR if changes are needed)

### Before requesting review
- [ ] I have reviewed the code myself
- [x] I have created follow-up issues caused by this PR and linked them
here

---------

Co-authored-by: green <xgreenx9999@gmail.com>
H
Hannes Karppila committed
5bda22ece0a324239fe5407ba7baf13a978f4165
Parent: 0803cac
Committed by GitHub <noreply@github.com> on 10/17/2025, 2:06:47 PM