Skip to content

Dynamic storage opcodes: base instructions#640

Merged
Dentosal merged 36 commits intomasterfrom
dento/dyn-storage
Apr 14, 2026
Merged

Dynamic storage opcodes: base instructions#640
Dentosal merged 36 commits intomasterfrom
dento/dyn-storage

Conversation

@Dentosal
Copy link
Copy Markdown
Member

@Dentosal Dentosal commented Dec 15, 2025

Discussed in #517. VM impl PR: FuelLabs/fuel-vm#982

Adds a minimal set of opcodes required to operate with dynamic (variable-sized) storage slots. More instructions can be added later to speed up common operations, as discussed in #517.

This PR marks sequential bulk read and write opcodes as deprecated. There's no process for actually removing opcodes, but simply including DEPRECATED in the heading informs readers that they ought to be careful. Most imporatantly, the sequential read opcode now panics if attempting to read slots with size other than 32 bytes. The sequential clear instuction still works as expected and is kept as-is.

The PR also clarifies how the old storarge instructions interact with variable sized slots.

Before requesting review

  • I have reviewed the code myself

@Dentosal Dentosal self-assigned this Dec 15, 2025
@cursor
Copy link
Copy Markdown

cursor Bot commented Dec 15, 2025

PR Summary

Medium Risk
Specification-only changes, but they redefine contract state instruction semantics (including new panic conditions) and add new opcodes/consensus parameter docs, which can affect implementers and tooling if misinterpreted.

Overview
Documents the new dynamic (variable-sized) contract storage slot instruction set, adding SCLR, SRDD/SRDI, SWRD/SWRI, SUPD/SUPI, and SPLD, plus updated semantics for SRW to support word reads at an offset.

Marks legacy bulk 32-byte slot ops (SCWQ, SRWQ, SWWQ) as DEPRECATED and clarifies their behavior/limitations with variable-sized slots (notably new panics when slot sizes don’t match expectations). Also adds a short spec note that storage accesses are cached across contract call boundaries, and introduces the MAX_STORAGE_SLOT_LENGTH consensus parameter plus a few new spellcheck dictionary entries.

Reviewed by Cursor Bugbot for commit 73e150b. Bugbot is set up for automated code reviews on this repo. Configure here.

@Dentosal
Copy link
Copy Markdown
Member Author

Meeting notes 2025-12-17:

  • Use $err to signal errors instead of a status output register (new opcodes only, of course)
  • Change SLEN to load the value to a "staging area", add separate opcodes to memcopy from it
  • Remove write status
  • New storage clear opcode without status
  • Document the slot size limit
  • SRW: add immediate offset
  • Buffer extend support to SUPD/SUPI

I'll update the PR to include these.

Comment thread src/fuel-vm/instruction-set.md Outdated
@Dentosal Dentosal requested a review from a team January 12, 2026 12:39
Comment thread src/fuel-vm/instruction-set.md
Comment thread src/fuel-vm/index.md Outdated
Comment thread src/fuel-vm/instruction-set.md
Co-authored-by: Brandon Kite <brandonkite92@gmail.com>
Comment thread src/fuel-vm/instruction-set.md Outdated
@ironcev
Copy link
Copy Markdown
Member

ironcev commented Apr 9, 2026

👍

Comment thread src/fuel-vm/index.md Outdated
Comment thread src/fuel-vm/instruction-set.md Outdated
Comment thread src/fuel-vm/instruction-set.md Outdated
Comment thread src/fuel-vm/instruction-set.md Outdated
Comment thread src/fuel-vm/instruction-set.md Outdated
Comment thread src/fuel-vm/instruction-set.md Outdated
Comment thread src/fuel-vm/instruction-set.md Outdated
Comment thread src/fuel-vm/instruction-set.md Outdated
Comment thread src/fuel-vm/instruction-set.md Outdated
Comment thread src/fuel-vm/instruction-set.md Outdated
@ironcev ironcev mentioned this pull request Apr 9, 2026
12 tasks
Dentosal and others added 4 commits April 9, 2026 17:06
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
Dentosal and others added 15 commits April 9, 2026 17:08
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: SRDI panic condition references wrong register
    • Updated the SRDI panic bound check to use STATE[MEM[$rB, 32]], matching the instruction operation and SRDD behavior.

Create PR

Or push these changes by commenting:

@cursor push 6123ebaf91
Preview (6123ebaf91)
diff --git a/src/fuel-vm/instruction-set.md b/src/fuel-vm/instruction-set.md
--- a/src/fuel-vm/instruction-set.md
+++ b/src/fuel-vm/instruction-set.md
@@ -2425,7 +2425,7 @@
 - `$rB + 32` overflows or `> VM_MAX_RAM`
 - `$rA + imm` overflows or `> VM_MAX_RAM`
 - The memory range `MEM[$rA, imm]` does not pass [ownership check](./index.md#ownership)
-- `$rC + imm` overflows or `> len(STATE[MEM[$rC, 32]])`
+- `$rC + imm` overflows or `> len(STATE[MEM[$rB, 32]])`
 - `$fp == 0` (in the script context)
 
 Register `$err` will be set to `1` if the slot did not exist, and `0` otherwise. If the slot didn't exist, memory is not modified.

This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.

Comment thread src/fuel-vm/instruction-set.md Outdated
@Dentosal Dentosal requested a review from ironcev April 10, 2026 13:42
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 36b4bf3. Configure here.

Comment thread src/fuel-vm/instruction-set.md
Comment thread src/fuel-vm/instruction-set.md
ironcev
ironcev previously approved these changes Apr 14, 2026
@Dentosal Dentosal merged commit dd11147 into master Apr 14, 2026
10 checks passed
@Dentosal Dentosal deleted the dento/dyn-storage branch April 14, 2026 08:54
ironcev added a commit to FuelLabs/sway that referenced this pull request Apr 16, 2026
## Description

This PR is a step in implementing #7560. It adds compiler support for
[dynamic storage
opcodes](FuelLabs/fuel-specs#640) by:
- supporting all opcodes in `asm` blocks.
- adding IR instructions for all opcodes.

Note that the `FuelVmInstruction::StatePreload` IR instruction returns
zero if the slot is not used, but also if it is used and contains
zero-sized content. The reason is that zero-sized storage types, like,
e.g. `StorageVec`, have special semantics in the storage API and the
`storage_api` does not write zero-sized types into storage, nor reads
them. Modeling the IR instruction this way preserves this semantics and
allows for more efficient implementation that is actually needed in the
API. (Returning both the length and the existence information would
require a stack allocation and more gas expensive compilation for
something that is actually not used.)

This API semantics might be changed to support zero-sized types like any
other types. This would be a separate breaking change and a part of
[Configurable and composable storage
RFC](FuelLabs/sway-rfcs#40).

Meanwhile, if a distinction between unused and zero-sized used slot is
needed while preloading, it can be achieved by using the `SPLD` opcode
in `asm` block.

## Checklist

- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [ ] 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.
- [x] 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).
- [x] I have requested a review from the relevant team or maintainers.
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

Successfully merging this pull request may close these issues.

4 participants