You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The messages! macro of the pdsl_model (Fleetwood abstractions) currently cannot automatically generate unique message selectors at compile-time. Note that we are not interested at all in any kind of operations done during runtime since users of the smart contracts would have to pay lots of gas for that. This is due to the fact that Rust's current const_fn feature is very constrained and does not allow for many use cases.
In spite of this the current messages! macro has a built-in message id parameter.
messages!{0 => Inc(by: u32); // This message get selected for function selectors of '0'1 => Get() -> u32; // ... and this for '1'}
The advantage of this is that a user can simply choose their own message selectors and it should also be very easy to keep them unique - at least as long as the list of messages is short enough.
Another advantage is that this manual system is very transparent and allows for easy testing of smart contract execution.
As soon as Rust's const_fn feature matures and allows for more scenarios we can think about soft deprecating the manual message selector or just make it optional.
ABI Design
For automatic message selector generation we need the following attributes:
A message selector must be:
Unique over all messages that belong to the same state.
Unique over all messages with different signatures (name, params, ret-ty).
Independent of ordering in the file.
Shall be stable across compilations, chains and compilers.
When Rust is ready to implement this functionality at compile-time it should have the following structure - or a similar one.
For this we would take into consideration the following traits that have to be implemented for all states or messages respectively.
/// A message with an expected input type and output (result) type.pubtraitMessage{/// The expected input type, also known as parameter types.typeInput: parity_codec::Decode;/// The output of the message, also known as return type.typeOutput: parity_codec::Encode;/// The name of the message.////// # Note////// This must be a valid Rust identifier.constNAME:&'static [u8];}/// Types implementing this type can be used as contract state.pubtraitContractState:AllocateUsing + Flush{/// The name of the contract state.////// # Note////// - This must be a valid Rust identifier./// - Normally this reflects the name of the contract.constNAME:&'static str;}
For message selector generation we concatenate byte sequences together that we will hash with a stable (crypto) hashing algorithm.
For a message M with parameters P_n, 0 <= n < N and return type R that operates on state S the sequence will be the following:
S::NAME.as_bytes
~ 0xFF
~ M::NAME.as_bytes
forall p: P where n € [0, N) do: ~ 0xFE ~ p.signature
~ 0xFD ~ R.signature
Where ~ is the concat operator for byte sequences and .signature is yielding a byte sequence representation of a type at compile-time, similar to Rust's typename intrinsic.
We want to use this signatures instead of a raw transformation to the underlying types since we want distinction between (bool, u32) and types like Option<u32> that could be structured similarly internally. This allows us to abstract away from internal data structure layout.
Note again that all these computation must be happening at compilation time.
None of this must ever run at smart contract execution time due to gas costs.
Examples
Given
state!{structAdder{
val: u32}}messages!{Inc(by: u32);
Get() -> u32;
/// Returns `true` if the stored value is less than `rhs`.LessThan(rhs: u32) -> bool;
}
We would receive the following byte sequences for messages Inc, Get and LessThan when being used on state Adder:
Problem
The
messages!
macro of thepdsl_model
(Fleetwood abstractions) currently cannot automatically generate unique message selectors at compile-time. Note that we are not interested at all in any kind of operations done during runtime since users of the smart contracts would have to pay lots of gas for that. This is due to the fact that Rust's currentconst_fn
feature is very constrained and does not allow for many use cases.In spite of this the current
messages!
macro has a built-in message id parameter.The advantage of this is that a user can simply choose their own message selectors and it should also be very easy to keep them unique - at least as long as the list of messages is short enough.
Another advantage is that this manual system is very transparent and allows for easy testing of smart contract execution.
As soon as Rust's
const_fn
feature matures and allows for more scenarios we can think about soft deprecating the manual message selector or just make it optional.ABI Design
For automatic message selector generation we need the following attributes:
A message selector must be:
When Rust is ready to implement this functionality at compile-time it should have the following structure - or a similar one.
For this we would take into consideration the following traits that have to be implemented for all states or messages respectively.
For message selector generation we concatenate byte sequences together that we will hash with a stable (crypto) hashing algorithm.
For a message
M
with parametersP_n
, 0 <=n
< N and return typeR
that operates on stateS
the sequence will be the following:Where
~
is the concat operator for byte sequences and.signature
is yielding a byte sequence representation of a type at compile-time, similar to Rust'stypename
intrinsic.We want to use this signatures instead of a raw transformation to the underlying types since we want distinction between
(bool, u32)
and types likeOption<u32>
that could be structured similarly internally. This allows us to abstract away from internal data structure layout.Note again that all these computation must be happening at compilation time.
None of this must ever run at smart contract execution time due to gas costs.
Examples
Given
We would receive the following byte sequences for messages
Inc
,Get
andLessThan
when being used on stateAdder
:Inc(by: u32)
canonicalized toInc(u32)
0x4164646572
~0xFF
~0x496E63
~0xFE
~0x753332
Get() -> u32
0x4164646572
~0xFF
~0x476574
~0xFD
~0x753332
LessThan(rhs: u32) -> bool
canonicalized toLessThan(u32) -> bool
0x4164646572
~0xFF
~0x4C6573735468616E
~0xFE
~0x753332
~0xFD
~0x626F6F6C
The text was updated successfully, but these errors were encountered: