Skip to content

Add explanation about removing old keys while migrating state #2626

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 22, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 75 additions & 1 deletion docs/smart-contracts/release/upgrade.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ state, removes the `payments` vector and adds the information to the

<Github fname="lib.rs"
url="https://github.com/near-examples/update-migrate-rust/blob/main/basic-updates/update/src/migrate.rs"
start="3" end="46" />
start="3" end="51" />

</Language>

Expand All @@ -248,6 +248,80 @@ Notice that `migrate` is actually an
that **ignores** the existing state (`[#init(ignore_state)]`), thus being able
to execute and rewrite the state.

<details>

<summary> Why we should remove old structures from the state? </summary>

To understand why we should remove old structures from the state let's take a look to how the data is stored.

For example, if the old version of the contract stores two messages with payments according methods `get_messages` and `get_payments` will return the following results:

<details>
<summary>get_messags result</summary>
```bash
INFO --- Result -------------------------
| [
| {
| "premium": false,
| "sender": "test-ac-1719933221123-3.testnet",
| "text": "Hello"
| },
| {
| "premium": false,
| "sender": "test-ac-1719933221123-3.testnet",
| "text": "Hello"
| }
| ]
| ------------------------------------
```
</details>

<details>
<summary>get_payments result</summary>
```bash
INFO --- Result -------------------------
| [
| "10000000000000000000000",
| "10000000000000000000000"
| ]
| ------------------------------------
```
</details>

But if we take a look at the storage as text using following command, we will see that each payment is stored under its own key started with `p\` prefix.

```bash
near contract view-storage <CONTRACT_ID> all as-text network-config testnet now
```

<details>
<summary>Storage as text result</summary>
```bash
INFO Contract state (values):
| key: STATE
| value: \x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00m\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00p
| --------------------------------
| key: m\x00\x00\x00\x00\x00\x00\x00\x00
| value: \x00\x1f\x00\x00\x00test-ac-1719933221123-3.testnet\x05\x00\x00\x00Hello
| --------------------------------
| key: m\x01\x00\x00\x00\x00\x00\x00\x00
| value: \x00\x1f\x00\x00\x00test-ac-1719933221123-3.testnet\x05\x00\x00\x00Hello
| --------------------------------
| key: p\x00\x00\x00\x00\x00\x00\x00\x00
| value: \x00\x00@\xb2\xba\xc9\xe0\x19\x1e\x02\x00\x00\x00\x00\x00\x00
| --------------------------------
| key: p\x01\x00\x00\x00\x00\x00\x00\x00
| value: \x00\x00@\xb2\xba\xc9\xe0\x19\x1e\x02\x00\x00\x00\x00\x00\x00
| --------------------------------
```
</details>

That means that while migrating the state to a new version we need not only change the messages structure, but also remove all payments related keys from the state. Otherwise, the old keys will simply stay behind being orphan, still occupying space.

To remove them in `migrate` method, we call `clear()` method on payments vector in mutable `old_state` struct. This method removes all elements from the collection.

</details>

:::tip

You can follow a migration step by step in the
Expand Down
Loading