ixc_schema

Crates.ioixc_schema
lib.rsixc_schema
version0.0.4
sourcesrc
created_at2024-09-19 17:09:16.226355
updated_at2024-10-11 21:58:30.880881
descriptionInterchain SDK Schema
homepage
repositoryhttps://github.com/cosmos/cosmos-sdk
max_upload_size
id1380500
size127,640
Marko (tac0turtle)

documentation

README

WARNING: This is an API preview! Expect major bugs, glaring omissions, and breaking changes!

This crate defines the encoding traits and schemas for the Interchain SDK which can be used in message parameter and return types, serializable structs and enums, and objects in storage.

Basic Types

The basic types supported intrinsically are:

  • [u8], [u16], [u32], [u64], [u128]
  • [i8], [i16], [i32], [i64], [i128]
  • [bool]
  • String or [&str]
  • [ixc_message_api::AccountID]
  • [simple_time::Time] and [simple_time::Duration]
  • [Option<T>] where T is any supported type (except for another Option)
  • Vec<T> or &[T]

Custom types may be derived using the [SchemaValue] derive macro. As a general rule, if a type implements [SchemaValue] it can be used as a function or struct parameter.

Supported Encodings

Similar to the Serde framework, ixc_schema types can support multiple encodings through different implementations of the [encoder::Encoder] and [decoder::Decoder] traits. Unlike Serde, these traits are object safe and dynamic dispatch is used wherever possible so that code size does not expand due to Rust's mono-morphization of generics

Currently only a simple native binary encoding is supported but protobuf, JSON, and encodings to other popular VM formats are planned in the future.

Memory Management

If you read the list of supported types carefully, you may notice that borrowed strings and slices are both supported. This means that we can define types with lifetimes and deserialize borrowed data, just like in the popular Serde framework. Ex:

pub struct Coin<'a> {
  pub denom: &'a str,
  pub amount: u128,  
}

We improve upon Serde's approach with a memory management system to properly deal with cases where we simply cannot borrow directly from the input data. In Serde, if we deserialize the above Coin structure from JSON input, it wil work some of the time but will fail with an error whenever the input data contains JSON escape characters (ex. "foo\tbar"). This is because a borrowed data structure must have some owner, but in Serde the only possible owner is the input itself.

In ixc_schema we use a bump allocator under the hood to hold onto any intermediate allocation that must take place to be able to borrow not just strings, but slices of any sort of data. When data is decoded there is a "memory manager" that holds onto the original input data and any temporary allocations and then deallocates them in mass when we're done with the data. Because decoding is a phase-oriented operation, this model works well and is very efficient. Because of this property, ixc_schema can support complex data structures and manage memory correctly, without needing to interact with the general purpose Rust global allocator. With this model, in the future it will likely be possible to build crates targeting virtual machines such as WebAssembly in no_std mode without any sort of global allocator.

To make the best use of the built-in bump allocator, it is recommended to avoid uses of String and Vec<T> in favor of [&str] and &[T] respectively. You can also use Cow<str> and Cow<[T]> to have the optionality to use borrowed or owned data.

Commit count: 13661

cargo fmt