-
Notifications
You must be signed in to change notification settings - Fork 29
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
Add a compact
flag to Field
#42
Conversation
By default, parity-scale-codec does not provide Encode/Decode impls for an owned String. This is only provided under the "full" feature which is not used by the substrate runtime, because it should not be used for consensus critical code. So in order for the CompactForm to be integrated into the substrate runtime, or wherever the "full" feature cannot be used, then we must parameterize the `String` type so that it can be both an `&'static str` on the runtime side where it is encoded, and a `String` in client/consuming code where it is decoded.
Add a `compact` member to `Field` to indicate it is `scale_codec::Compact`
…ncoded/decoded as a SCALE Compact type
Have you considered making use of the actual type metadata in order to infer types that are wrapped in a |
@Robbepop you mean that a field For example: #[derive(Encode)]
pub enum MultiAddress<AccountId, AccountIndex> {
/// It's an account ID (pubkey).
Id(AccountId),
/// It's an account index.
Index(#[codec(compact)] AccountIndex),
/// It's some arbitrary raw bytes.
Raw(Vec<u8>),
/// It's a 32 byte representation.
Address32([u8; 32]),
/// Its a 20 byte representation.
Address20([u8; 20]),
} …expands to this: impl<AccountId, AccountIndex> _parity_scale_codec::Encode for MultiAddress<AccountId, AccountIndex>
where
AccountId: _parity_scale_codec::Encode,
AccountId: _parity_scale_codec::Encode,
AccountIndex: _parity_scale_codec::HasCompact,
{
fn encode_to<__CodecOutputEdqy: _parity_scale_codec::Output>(
&self,
__codec_dest_edqy: &mut __CodecOutputEdqy,
) {
match *self {
MultiAddress::Id(ref aa) => {
__codec_dest_edqy.push_byte(0usize as u8);
__codec_dest_edqy.push(aa);
}
MultiAddress::Index(ref aa) => {
__codec_dest_edqy.push_byte(1usize as u8);
{
__codec_dest_edqy.push (&<<AccountIndex as _parity_scale_codec::HasCompact>::Type as _parity_scale_codec::EncodeAsRef< '_ , AccountIndex >>::RefType::from(aa));
}
}
MultiAddress::Raw(ref aa) => {
__codec_dest_edqy.push_byte(2usize as u8);
__codec_dest_edqy.push(aa);
}
MultiAddress::Address32(ref aa) => {
__codec_dest_edqy.push_byte(3usize as u8);
__codec_dest_edqy.push(aa);
}
MultiAddress::Address20(ref aa) => {
__codec_dest_edqy.push_byte(4usize as u8);
__codec_dest_edqy.push(aa);
}
_ => (),
}
}
} |
/// This field should be encode/decoded as a | ||
/// [`Compact`](parity_scale_codec::Compact) field | ||
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "is_false", default))] | ||
compact: bool, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think an even more compact representation for the exact same use case would be to use yet another enum variant in order to represent compacted types. The idea is to add another variant Compact(TypeDefCompact<T>)
to the TypeDef
enum: https://docs.rs/scale-info/0.4.1/scale_info/enum.TypeDef.html
The TypeDefCompact
type internally could look like this:
pub struct TypeDefCompact<T>
where
T: Form = MetaForm
{
#[serde(rename = "type")]
type_param: T::Type,
}
Then instead of requiring each type to have this bool
field we'd simply have a compact variant only for those type definitions that are actually compactly encoded. Since this is kind of a special case this design would suite much better. Also it would better reflect the encoding structure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At first glance I think this solution is more elegant than having the field, while still making it a first class citizen (unlike just using a type e.g. Compact<T>
.
Closing in favour of #58 |
Closes #8
Builds on #41
Adds a
compact
boolean toField
to signal that the type should be encoded/decoded as aparity_scale_codec::Compact
type.This is WIP and does not yet change the derive macro to use the new flag.The code here takes the first approach outlined in #8, using a flag. The reasoning is to try the simplest thing that works and see where it takes us. The preferred approach outlined by @Robbepop, leveraging the existing machinery to derive
Compact<T>
is elegant but given the scary expansion of#[codec(compact)]
(see comment below) I'm not sure if it is actually workable (tbh I haven't tried yet).