Use scale-encode and scale-decode to encode and decode based on metadata (#842)

* WIP EncodeAsType and DecodeAsType

* remove silly cli experiment code

* Get things finally compiling with EncodeAsType and DecodeAsType

* update codegen test and WrapperKeepOpaque proper impl (in case it shows up in codegen)

* fix tests

* accomodate scale-value changes

* starting to migrate to EncodeAsType/DecodeAsType

* static event decoding and tx encoding to use DecodeAsFields/EncodeAsFields

* some tidy up and add decode(skip) attrs where needed

* fix root event decoding

* #[codec(skip)] will do, and combine map_key stuff into storage_address since it's all specific to that

* fmt and clippy

* update Cargo.lock

* remove patched scale-encode

* bump scale-encode to 0.1 and remove unused dep in testing crate

* update deps and use released scale-decode

* update scale-value to latest to remove git branch

* Apply suggestions from code review

Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com>

* remove sorting in derives/attr generation; spit them out in order given

* re-add derive sorting; it's a hashmap

* StaticTxPayload and DynamicTxPayload rolled into single Payload struct

* StaticStorageAddress and DynamicStorageAddress into single Address struct

* Fix storage address byte retrieval

* StaticConstantAddress and DynamicConstantAddress => Address

* Simplify storage codegen to fix test

* Add comments

* Alias to RuntimeEvent rather than making another, and prep for substituting call type

* remove unnecessary clone

* Fix docs and failing UI test

* root_bytes -> to_root_bytes

* document error case in StorageClient::address_bytes()

---------

Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com>
This commit is contained in:
James Wilson
2023-03-21 15:31:13 +00:00
committed by GitHub
parent c9527abaa8
commit c63ff6ec6d
50 changed files with 9965 additions and 6262 deletions
+36 -43
View File
@@ -28,25 +28,39 @@ pub trait ConstantAddress {
}
}
/// This represents a statically generated constant lookup address.
pub struct StaticConstantAddress<ReturnTy> {
pallet_name: &'static str,
constant_name: &'static str,
/// This represents the address of a constant.
pub struct Address<ReturnTy> {
pallet_name: Cow<'static, str>,
constant_name: Cow<'static, str>,
constant_hash: Option<[u8; 32]>,
_marker: std::marker::PhantomData<ReturnTy>,
}
impl<ReturnTy> StaticConstantAddress<ReturnTy> {
/// Create a new [`StaticConstantAddress`] that will be validated
/// The type of address typically used to return dynamic constant values.
pub type DynamicAddress = Address<DecodedValueThunk>;
impl<ReturnTy> Address<ReturnTy> {
/// Create a new [`Address`] to use to look up a constant.
pub fn new(pallet_name: impl Into<String>, constant_name: impl Into<String>) -> Self {
Self {
pallet_name: Cow::Owned(pallet_name.into()),
constant_name: Cow::Owned(constant_name.into()),
constant_hash: None,
_marker: std::marker::PhantomData,
}
}
/// Create a new [`Address`] that will be validated
/// against node metadata using the hash given.
pub fn new(
#[doc(hidden)]
pub fn new_static(
pallet_name: &'static str,
constant_name: &'static str,
hash: [u8; 32],
) -> Self {
Self {
pallet_name,
constant_name,
pallet_name: Cow::Borrowed(pallet_name),
constant_name: Cow::Borrowed(constant_name),
constant_hash: Some(hash),
_marker: std::marker::PhantomData,
}
@@ -63,42 +77,9 @@ impl<ReturnTy> StaticConstantAddress<ReturnTy> {
}
}
impl<ReturnTy: DecodeWithMetadata> ConstantAddress for StaticConstantAddress<ReturnTy> {
impl<ReturnTy: DecodeWithMetadata> ConstantAddress for Address<ReturnTy> {
type Target = ReturnTy;
fn pallet_name(&self) -> &str {
self.pallet_name
}
fn constant_name(&self) -> &str {
self.constant_name
}
fn validation_hash(&self) -> Option<[u8; 32]> {
self.constant_hash
}
}
/// This represents a dynamically generated constant address.
pub struct DynamicConstantAddress<'a> {
pallet_name: Cow<'a, str>,
constant_name: Cow<'a, str>,
}
/// Construct a new dynamic constant lookup.
pub fn dynamic<'a>(
pallet_name: impl Into<Cow<'a, str>>,
constant_name: impl Into<Cow<'a, str>>,
) -> DynamicConstantAddress<'a> {
DynamicConstantAddress {
pallet_name: pallet_name.into(),
constant_name: constant_name.into(),
}
}
impl<'a> ConstantAddress for DynamicConstantAddress<'a> {
type Target = DecodedValueThunk;
fn pallet_name(&self) -> &str {
&self.pallet_name
}
@@ -106,4 +87,16 @@ impl<'a> ConstantAddress for DynamicConstantAddress<'a> {
fn constant_name(&self) -> &str {
&self.constant_name
}
fn validation_hash(&self) -> Option<[u8; 32]> {
self.constant_hash
}
}
/// Construct a new dynamic constant lookup.
pub fn dynamic(
pallet_name: impl Into<String>,
constant_name: impl Into<String>,
) -> DynamicAddress {
DynamicAddress::new(pallet_name, constant_name)
}
+2 -2
View File
@@ -63,7 +63,7 @@ impl<T: Config, Client: OfflineClientT<T>> ConstantsClient<T, Client> {
pub fn at<Address: ConstantAddress>(
&self,
address: &Address,
) -> Result<<Address::Target as DecodeWithMetadata>::Target, Error> {
) -> Result<Address::Target, Error> {
let metadata = self.client.metadata();
// 1. Validate constant shape if hash given:
@@ -72,7 +72,7 @@ impl<T: Config, Client: OfflineClientT<T>> ConstantsClient<T, Client> {
// 2. Attempt to decode the constant into the type given:
let pallet = metadata.pallet(address.pallet_name())?;
let constant = pallet.constant(address.constant_name())?;
let value = Address::Target::decode_with_metadata(
let value = <Address::Target as DecodeWithMetadata>::decode_with_metadata(
&mut &*constant.value,
constant.ty.id(),
&metadata,
+2 -2
View File
@@ -9,8 +9,8 @@ mod constants_client;
pub use constant_address::{
dynamic,
Address,
ConstantAddress,
DynamicConstantAddress,
StaticConstantAddress,
DynamicAddress,
};
pub use constants_client::ConstantsClient;