Skip to content

Conversation

@s0me0ne-unkn0wn
Copy link
Contributor

@s0me0ne-unkn0wn s0me0ne-unkn0wn commented May 16, 2025

@s0me0ne-unkn0wn s0me0ne-unkn0wn changed the title Add RFC-144 RFC-145: Remove the host-side runtime memory allocator May 16, 2025
@anaelleltd anaelleltd added the Proposed Is awaiting 3 formal reviews. label May 31, 2025
@s0me0ne-unkn0wn
Copy link
Contributor Author

@anaelleltd anaelleltd added Reviewed Is ready for on-chain voting. and removed Proposed Is awaiting 3 formal reviews. labels Aug 27, 2025
@athei
Copy link

athei commented Sep 8, 2025

Thanks. Didn't get around to review, yet. The priorities shifted a bit. But eventually we want that. Quick question: Why does paritytech/polkadot-sdk#8866 merge into paritytech/polkadot-sdk#8641.

Can't they be merged individually to master?

@s0me0ne-unkn0wn
Copy link
Contributor Author

@athei Probably they can, it's just much more convenient that way. E.g., we're introducing a new version of a host function and attribute it with #[version(3, register_only)], and the second PR changes it to just #[version(3)]. If the base branch for the second PR were master, then after the first PR is merged, a merge conflict would arise in the second PR for every such change. And having they chained makes things natural: as soon as the first PR is merged to master, the second PR's base branch will be updated to master automatically, hopefully avoiding any merge conflicts.

@athei
Copy link

athei commented Sep 8, 2025

Ahh I see you still intent to merge paritytech/polkadot-sdk#8641 in first. Then all good 👍


##### Results

The result is the length of the output stored in the buffer provided in `out`. If the buffer is not large enough to accommodate the data, the latter will be truncated, but the full length of the output data will always be returned.
Copy link

Choose a reason for hiding this comment

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

Is it actually useful to write partial data? I'd imagine you'll never actually make any use of the partially written output and just immediately retry with a bigger buffer, no? In which case writing out partial data seems like a waste of CPU cycles.

(This comment also applies to other host functions.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fair enough 🤷‍♂️
Maybe not in every case, but mostly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm reopening this discussion because of problems found. Indeed, sometimes we consciously want partial reads from storage, as in .decode_len(), where only CompactU32 is read at the beginning of the value.

Allowing partial reads only in storage::read would make interfaces inconsistent, and allowing it everywhere introduces an overhead. Does it make sense to introduce an argument to storage::read that allows for partial reads? Or an entirely new function specifically for storage partial reads?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm proceeding with a boolean allow_partial argument for storage-reading functions (2ec2eaf), lmk if there are any better ideas.

Copy link

@athei athei left a comment

Choose a reason for hiding this comment

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

Sorry for the long delay. I have finally time to review this now.

@athei
Copy link

athei commented Dec 21, 2025

Finally went through the whole RFC. Looks good. Just found a few nits.

I also recommend:

  1. Moving the entry point changes to the top
  2. Explicitly state state that only one style of entry points can be used and they cannot be mixed
  3. Explicitly state that old entry point means that the new versions fail static validation
  4. Explicitly state that new entry point means that usage of deprecated host functions fail static validation

Copy link

@athei athei left a comment

Choose a reason for hiding this comment

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

Looks good. Just some nit around the wording of the meta field.

@P1sar
Copy link

P1sar commented Jan 8, 2026

Hey @bkchr and @koute could one of you please take a look at this PR when you have a moment? Thanks!


##### Arguments

* `out` is a pointer-size ([Definition 216](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer-size)) to a buffer where the SCALE-encoded storage root, calculated after committing all the existing operations, will be stored. The value is actually stored only if the buffer is large enough. Otherwise, the buffer is not written into and its contents are unchanged.
Copy link
Member

Choose a reason for hiding this comment

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

Could we hard-code this to 32 byte instead of returning the length? I dont see much use to return it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe the point of having it SCALE-encoded is that the storage root type is generic. I'll check it once more just in case

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay, so in the current reference implementation storage backend is generic over the hasher type used to produce hashes, so we don't know what the root hash length is. On the other hand, we're specifying exactly Polkadot here and not some other network, and it already has established practice in that sense. I would leave it as is for now, but I'm leaving this discussion thread open to collect opinions.

##### Arguments

* `key_in` is a pointer-size ([Definition 216](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer-size)) to a buffer containing a storage key;
* `key_out` is a pointer-size ([Definition 216](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer-size)) to an output buffer where the next key in the storage in the lexicographical order will be written. The value is actually stored only if the buffer is large enough. Otherwise, the buffer is not written into and its contents are unchanged.
Copy link
Member

Choose a reason for hiding this comment

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

The runtime will be generally a bit more careful then what keys it puts into storage, or? We dont want it to suddenly do 2x as many calls just because its default key_out is too small.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it's a matter of providing a reasonable buffer by default. If a runtime author wants giant keys, let him provide giant defaults ;)

Copy link

@koute koute left a comment

Choose a reason for hiding this comment

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

Looks much better! Nice job!

This gets a tentative 👍 from me assuming last remaining comments are addressed.

Copy link
Contributor

@bkchr bkchr left a comment

Choose a reason for hiding this comment

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

Generally looking good! Ty for the work!

I left some nitpicks. Sometimes we are using i64 as return value and some times i32 when we don't return a size and just communicate the result. AFAIR WASM abi is different for both of them. So, we should maybe just always use i32 when we only communicate a result?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Reviewed Is ready for on-chain voting.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants