From c082e527fec4b104beebb06956b2d14e61de8c81 Mon Sep 17 00:00:00 2001 From: haerdib Date: Wed, 6 Dec 2023 13:25:45 +0100 Subject: [PATCH 1/5] update jsonrpsee to v0.20 --- Cargo.lock | 28 ++++++++++------------------ Cargo.toml | 2 +- src/rpc/jsonrpsee_client/mod.rs | 8 +++----- 3 files changed, 14 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 159393931..4053075c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2399,9 +2399,9 @@ dependencies = [ [[package]] name = "jsonrpsee" -version = "0.16.3" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "367a292944c07385839818bb71c8d76611138e2dedb0677d035b8da21d29c78b" +checksum = "affdc52f7596ccb2d7645231fc6163bb314630c989b64998f3699a28b4d5d4dc" dependencies = [ "jsonrpsee-client-transport", "jsonrpsee-core", @@ -2410,14 +2410,13 @@ dependencies = [ [[package]] name = "jsonrpsee-client-transport" -version = "0.16.3" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8b3815d9f5d5de348e5f162b316dc9cdf4548305ebb15b4eb9328e66cf27d7a" +checksum = "b5b005c793122d03217da09af68ba9383363caa950b90d3436106df8cabce935" dependencies = [ "futures-util", "http", "jsonrpsee-core", - "jsonrpsee-types", "pin-project", "rustls-native-certs", "soketto", @@ -2426,20 +2425,19 @@ dependencies = [ "tokio-rustls", "tokio-util", "tracing", - "webpki-roots", + "url", ] [[package]] name = "jsonrpsee-core" -version = "0.16.3" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b5dde66c53d6dcdc8caea1874a45632ec0fcf5b437789f1e45766a1512ce803" +checksum = "da2327ba8df2fdbd5e897e2b5ed25ce7f299d345b9736b6828814c3dbd1fd47b" dependencies = [ "anyhow", "async-lock", "async-trait", "beef", - "futures-channel", "futures-timer", "futures-util", "jsonrpsee-types", @@ -2453,9 +2451,9 @@ dependencies = [ [[package]] name = "jsonrpsee-types" -version = "0.16.3" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245ba8e5aa633dd1c1e4fae72bce06e71f42d34c14a2767c6b4d173b57bee5e5" +checksum = "5be0be325642e850ed0bdff426674d2e66b2b7117c9be23a7caef68a2902b7d9" dependencies = [ "anyhow", "beef", @@ -6785,7 +6783,7 @@ version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "digest 0.10.7", "rand 0.8.5", "static_assertions", @@ -7247,12 +7245,6 @@ dependencies = [ "wasmparser", ] -[[package]] -name = "webpki-roots" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" - [[package]] name = "wide" version = "0.7.13" diff --git a/Cargo.toml b/Cargo.toml index 847705dec..c5cf7d37e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,7 @@ url = { version = "2.0.0", optional = true } # websocket dependent features futures = { version = "0.3", optional = true } -jsonrpsee = { version = "0.16", optional = true, features = ["async-client", "client-ws-transport", "jsonrpsee-types"] } +jsonrpsee = { version = "0.20.3", optional = true, features = ["async-client", "client-ws-transport-native-tls", "jsonrpsee-types"] } tungstenite = { version = "0.20.1", optional = true, features = ["native-tls"] } ws = { version = "0.9.2", optional = true, features = ["ssl"] } diff --git a/src/rpc/jsonrpsee_client/mod.rs b/src/rpc/jsonrpsee_client/mod.rs index 987a5dfb3..66910d7d9 100644 --- a/src/rpc/jsonrpsee_client/mod.rs +++ b/src/rpc/jsonrpsee_client/mod.rs @@ -14,7 +14,7 @@ use crate::rpc::{Error, Request, Result, RpcParams, Subscribe}; use futures::executor::block_on; use jsonrpsee::{ - client_transport::ws::{Uri, WsTransportClientBuilder}, + client_transport::ws::{Url, WsTransportClientBuilder}, core::{ client::{Client, ClientBuilder, ClientT, SubscriptionClientT}, traits::ToRpcParams, @@ -43,14 +43,12 @@ impl JsonrpseeClient { } pub async fn async_new(url: &str) -> Result { - let uri: Uri = url.parse().map_err(|e| Error::Client(Box::new(e)))?; + let uri: Url = url.parse().map_err(|e| Error::Client(Box::new(e)))?; let (tx, rx) = WsTransportClientBuilder::default() .build(uri) .await .map_err(|e| Error::Client(Box::new(e)))?; - let client = ClientBuilder::default() - .max_notifs_per_subscription(4096) - .build_with_tokio(tx, rx); + let client = ClientBuilder::default().build_with_tokio(tx, rx); Ok(Self { inner: Arc::new(client) }) } } From aa44a075fc83aeb6233dd444a8a9633d856b8205 Mon Sep 17 00:00:00 2001 From: haerdib Date: Wed, 6 Dec 2023 13:31:47 +0100 Subject: [PATCH 2/5] update client-keystore --- Cargo.lock | 16 +++++----------- client-keystore/Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4053075c0..bcc4e71d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -455,15 +455,9 @@ dependencies = [ [[package]] name = "array-bytes" -version = "4.2.0" +version = "6.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52f63c5c1316a16a4b35eaac8b76a98248961a533f061684cb2a7cb0eafb6c6" - -[[package]] -name = "array-bytes" -version = "6.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b1c5a481ec30a5abd8dfbd94ab5cf1bb4e9a66be7f1b3b322f2f1170c200fd" +checksum = "6f840fb7195bcfc5e17ea40c26e5ce6d5b9ce5d584466e17703209657e459ae0" [[package]] name = "arrayref" @@ -5131,7 +5125,7 @@ name = "sc-keystore" version = "4.0.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=master#f1bfc08038252caf7f1225f668b4518a6149bb24" dependencies = [ - "array-bytes 6.1.0", + "array-bytes", "parking_lot", "serde_json", "sp-application-crypto", @@ -5739,7 +5733,7 @@ name = "sp-core" version = "21.0.0" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=master#f1bfc08038252caf7f1225f668b4518a6149bb24" dependencies = [ - "array-bytes 6.1.0", + "array-bytes", "bandersnatch_vrfs", "bip39", "bitflags 1.3.2", @@ -6376,7 +6370,7 @@ dependencies = [ name = "substrate-client-keystore" version = "0.9.1" dependencies = [ - "array-bytes 4.2.0", + "array-bytes", "async-trait", "parking_lot", "sc-keystore", diff --git a/client-keystore/Cargo.toml b/client-keystore/Cargo.toml index b4eb8d016..fd9e34020 100644 --- a/client-keystore/Cargo.toml +++ b/client-keystore/Cargo.toml @@ -6,7 +6,7 @@ license = "Apache-2.0" edition = "2021" [dependencies] -array-bytes = "4.1" +array-bytes = "6.2.2" async-trait = "0.1.52" parking_lot = "0.12.0" serde_json = "1.0.79" From 83710755f239f22d3db79c4230217c04be004310 Mon Sep 17 00:00:00 2001 From: haerdib Date: Wed, 6 Dec 2023 13:48:54 +0100 Subject: [PATCH 3/5] fix clippy --- client-keystore/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client-keystore/src/lib.rs b/client-keystore/src/lib.rs index 7083beeae..a599b12e9 100644 --- a/client-keystore/src/lib.rs +++ b/client-keystore/src/lib.rs @@ -470,7 +470,7 @@ impl KeystoreInner { /// Returns `None` if the keystore only exists in-memory and there isn't any path to provide. fn key_file_path(&self, public: &[u8], key_type: KeyTypeId) -> Option { let mut buf = self.path.as_ref()?.clone(); - let key_type = array_bytes::bytes2hex("", &key_type.0); + let key_type = array_bytes::bytes2hex("", key_type.0); let key = array_bytes::bytes2hex("", public); buf.push(key_type + key.as_str()); Some(buf) From b8d7324c39cc838901a0860c20714d4ba883889a Mon Sep 17 00:00:00 2001 From: haerdib Date: Wed, 6 Dec 2023 15:57:32 +0100 Subject: [PATCH 4/5] update scale --- Cargo.lock | 54 ++- node-api/Cargo.toml | 5 +- node-api/src/events/event_details.rs | 2 +- node-api/src/events/mod.rs | 39 +-- node-api/src/lib.rs | 1 - node-api/src/scale_value/decode.rs | 492 --------------------------- node-api/src/scale_value/encode.rs | 264 -------------- node-api/src/scale_value/mod.rs | 58 ---- node-api/src/scale_value/value.rs | 484 -------------------------- 9 files changed, 55 insertions(+), 1344 deletions(-) delete mode 100644 node-api/src/scale_value/decode.rs delete mode 100644 node-api/src/scale_value/encode.rs delete mode 100644 node-api/src/scale_value/mod.rs delete mode 100644 node-api/src/scale_value/value.rs diff --git a/Cargo.lock b/Cargo.lock index bcc4e71d4..e1d8b9adc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,7 +55,7 @@ dependencies = [ "bitvec", "derive_more", "either", - "frame-metadata", + "frame-metadata 16.0.0", "hex", "log", "parity-scale-codec", @@ -63,6 +63,7 @@ dependencies = [ "scale-decode", "scale-encode", "scale-info", + "scale-value", "serde", "serde_json", "sp-application-crypto", @@ -1697,6 +1698,17 @@ dependencies = [ "sp-tracing", ] +[[package]] +name = "frame-metadata" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "878babb0b136e731cc77ec2fd883ff02745ff21e6fb662729953d44923df009c" +dependencies = [ + "cfg-if 1.0.0", + "parity-scale-codec", + "scale-info", +] + [[package]] name = "frame-metadata" version = "16.0.0" @@ -1718,7 +1730,7 @@ dependencies = [ "bitflags 1.3.2", "docify", "environmental", - "frame-metadata", + "frame-metadata 16.0.0", "frame-support-procedural", "impl-trait-for-tuples", "k256", @@ -5147,10 +5159,11 @@ dependencies = [ [[package]] name = "scale-decode" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea509715113edab351e1f4d51fba6b186653259049a1155b52e2e994dd2f0e6d" +checksum = "7caaf753f8ed1ab4752c6afb20174f03598c664724e0e32628e161c21000ff76" dependencies = [ + "derive_more", "parity-scale-codec", "primitive-types", "scale-bits", @@ -5161,9 +5174,9 @@ dependencies = [ [[package]] name = "scale-decode-derive" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66c9d7a1341497e9d016722144310de3dc6c933909c0376017c88f65092fff37" +checksum = "d3475108a1b62c7efd1b5c65974f30109a598b2f45f23c9ae030acb9686966db" dependencies = [ "darling", "proc-macro-crate", @@ -5174,10 +5187,11 @@ dependencies = [ [[package]] name = "scale-encode" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6f51bc8cd927dab2f4567b1a8a8e9d7fd5d0866f2dbc7c84fc97cfa9383a26" +checksum = "6d70cb4b29360105483fac1ed567ff95d65224a14dd275b6303ed0a654c78de5" dependencies = [ + "derive_more", "parity-scale-codec", "primitive-types", "scale-bits", @@ -5188,9 +5202,9 @@ dependencies = [ [[package]] name = "scale-encode-derive" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28be1877787156a2df01be3c029b92bdffa6b6a9748d4996e383fff218c88f3" +checksum = "995491f110efdc6bea96d6a746140e32bfceb4ea47510750a5467295a4707a25" dependencies = [ "darling", "proc-macro-crate", @@ -5225,6 +5239,22 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "scale-value" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58223c7691bf0bd46b43c9aea6f0472d1067f378d574180232358d7c6e0a8089" +dependencies = [ + "derive_more", + "either", + "frame-metadata 15.1.0", + "parity-scale-codec", + "scale-bits", + "scale-decode", + "scale-encode", + "scale-info", +] + [[package]] name = "schannel" version = "0.1.22" @@ -5906,7 +5936,7 @@ name = "sp-metadata-ir" version = "0.1.0" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=master#f1bfc08038252caf7f1225f668b4518a6149bb24" dependencies = [ - "frame-metadata", + "frame-metadata 16.0.0", "parity-scale-codec", "scale-info", "sp-std", @@ -6329,7 +6359,7 @@ dependencies = [ "ac-primitives", "async-trait", "derive_more", - "frame-metadata", + "frame-metadata 16.0.0", "frame-support", "futures", "futures-util", diff --git a/node-api/Cargo.toml b/node-api/Cargo.toml index fd5a9e1d4..2b079a3d0 100644 --- a/node-api/Cargo.toml +++ b/node-api/Cargo.toml @@ -18,8 +18,9 @@ frame-metadata = { version = "16.0", default-features = false, features = ["curr hex = { version = "0.4.3", default-features = false } log = { version = "0.4.14", default-features = false } scale-bits = { version = "0.4.0", default-features = false, features = ["scale-info", "serde"] } -scale-decode = { version = "0.8.0", default-features = false, features = ["primitive-types", "derive"] } -scale-encode = { version = "0.4.0", default-features = false, features = ["bits", "primitive-types", "derive"] } +scale-value = { version = "0.13.0", default-features = false } +scale-decode = { version = "0.10.0", default-features = false, features = ["primitive-types", "derive"] } +scale-encode = { version = "0.5.0", default-features = false, features = ["bits", "primitive-types", "derive"] } scale-info = { version = "2.0.1", features = ["derive", "decode", "bitvec"], default-features = false } serde = { version = "1.0.136", features = ["derive"], default-features = false } serde_json = { version = "1.0.79", default-features = false, features = ["alloc"] } diff --git a/node-api/src/events/event_details.rs b/node-api/src/events/event_details.rs index f2cf3c753..31d625c59 100644 --- a/node-api/src/events/event_details.rs +++ b/node-api/src/events/event_details.rs @@ -11,13 +11,13 @@ use crate::{ error::{DispatchError, Error}, metadata::{MetadataError, PalletMetadata}, - scale_value::{Composite, TypeId}, Metadata, Phase, StaticEvent, }; use alloc::{sync::Arc, vec::Vec}; use codec::Decode; use log::*; use scale_decode::DecodeAsFields; +use scale_value::{scale::TypeId, Composite}; /// The event details. /// Based on subxt EventDetails. diff --git a/node-api/src/events/mod.rs b/node-api/src/events/mod.rs index ad5f29e70..d76bf3e85 100644 --- a/node-api/src/events/mod.rs +++ b/node-api/src/events/mod.rs @@ -134,6 +134,12 @@ impl Events { self.find::().next().transpose() } + /// Iterate through the events using metadata to dynamically decode and skip + /// them, and return the last event found which decodes to the provided `Ev` type. + pub fn find_last(&self) -> Result, Error> { + self.find::().last().transpose() + } + /// Find an event that decodes to the type provided. Returns true if it was found. pub fn has(&self) -> Result { Ok(self.find::().next().transpose()?.is_some()) @@ -144,7 +150,6 @@ impl Events { mod tests { use super::*; use crate::{ - scale_value::Value, test_utils::{ event_record, events, events_raw, metadata_with_version, SupportedMetadataVersions, }, @@ -152,6 +157,7 @@ mod tests { }; use codec::Encode; use scale_info::TypeInfo; + use scale_value::Value; use sp_core::H256; use test_case::test_case; @@ -171,25 +177,7 @@ mod tests { /// Compare some actual [`RawEventDetails`] with a hand-constructed /// (probably) [`TestRawEventDetails`]. - pub fn assert_raw_events_match( - // Just for convenience, pass in the metadata type constructed - // by the `metadata` function above to simplify caller code. - metadata: &Metadata, - actual: EventDetails, - expected: TestRawEventDetails, - ) { - let types = &metadata.runtime_metadata().types; - - // Make sure that the bytes handed back line up with the fields handed back; - // encode the fields back into bytes and they should be equal. - let actual_fields = actual.field_values().expect("can decode field values (1)"); - let mut actual_bytes = vec![]; - for field in actual_fields.into_values() { - crate::scale_value::encode_as_type(&field, field.context, types, &mut actual_bytes) - .expect("should be able to encode properly"); - } - assert_eq!(actual_bytes, actual.field_bytes()); - + pub fn assert_raw_events_match(actual: EventDetails, expected: TestRawEventDetails) { let actual_fields_no_context: Vec<_> = actual .field_values() .expect("can decode field values (2)") @@ -228,7 +216,6 @@ mod tests { let mut event_details = events.iter(); assert_raw_events_match( - &metadata, event_details.next().unwrap().unwrap(), TestRawEventDetails { phase: Phase::ApplyExtrinsic(123), @@ -277,7 +264,6 @@ mod tests { let mut event_details = events.iter(); assert_raw_events_match( - &metadata, event_details.next().unwrap().unwrap(), TestRawEventDetails { index: 0, @@ -290,7 +276,6 @@ mod tests { }, ); assert_raw_events_match( - &metadata, event_details.next().unwrap().unwrap(), TestRawEventDetails { index: 1, @@ -303,7 +288,6 @@ mod tests { }, ); assert_raw_events_match( - &metadata, event_details.next().unwrap().unwrap(), TestRawEventDetails { index: 2, @@ -348,7 +332,6 @@ mod tests { let mut events_iter = events.iter(); assert_raw_events_match( - &metadata, events_iter.next().unwrap().unwrap(), TestRawEventDetails { index: 0, @@ -361,7 +344,6 @@ mod tests { }, ); assert_raw_events_match( - &metadata, events_iter.next().unwrap().unwrap(), TestRawEventDetails { index: 1, @@ -400,7 +382,6 @@ mod tests { // Dynamically decode: let mut event_details = events.iter(); assert_raw_events_match( - &metadata, event_details.next().unwrap().unwrap(), TestRawEventDetails { index: 0, @@ -439,7 +420,6 @@ mod tests { // Dynamically decode: let mut event_details = events.iter(); assert_raw_events_match( - &metadata, event_details.next().unwrap().unwrap(), TestRawEventDetails { index: 0, @@ -448,7 +428,7 @@ mod tests { pallet_index: 0, variant: "A".to_string(), variant_index: 0, - fields: vec![Value::u128(1)], + fields: vec![Value::unnamed_composite(vec![Value::u128(1)])], }, ); assert!(event_details.next().is_none()); @@ -482,7 +462,6 @@ mod tests { // Dynamically decode: let mut event_details = events.iter(); assert_raw_events_match( - &metadata, event_details.next().unwrap().unwrap(), TestRawEventDetails { index: 0, diff --git a/node-api/src/lib.rs b/node-api/src/lib.rs index ef72be468..c7aeefe0c 100644 --- a/node-api/src/lib.rs +++ b/node-api/src/lib.rs @@ -29,7 +29,6 @@ pub use scale_decode::DecodeAsType; pub mod error; pub mod events; pub mod metadata; -pub mod scale_value; pub mod storage; #[cfg(any(feature = "mocks", test))] diff --git a/node-api/src/scale_value/decode.rs b/node-api/src/scale_value/decode.rs deleted file mode 100644 index 31eb59bec..000000000 --- a/node-api/src/scale_value/decode.rs +++ /dev/null @@ -1,492 +0,0 @@ -// This file was taken from scale-value (Parity Technologies (UK)) -// https://github.com/paritytech/scale-value/ -// And was adapted by Supercomputing Systems AG. -// -// Copyright 2019-2022 Parity Technologies (UK) Ltd, Supercomputing Systems AG. -// This file is licensed as Apache-2.0 -// see LICENSE for license details. - -//! Based on https://github.com/paritytech/scale-value/blob/430bfaf8f302dfcfc45d8d63c687628fd9b7fc25/src/scale_impls/decode.rs - -use super::TypeId; -use crate::scale_value::{Composite, Primitive, Value, ValueDef, Variant}; -use alloc::{borrow::ToOwned, vec::Vec}; -use scale_decode::FieldIter; -use scale_info::{form::PortableForm, Path, PortableRegistry}; - -// This is emitted if something goes wrong decoding into a Value. -pub use scale_decode::visitor::DecodeError as VisitorDecodeError; - -/// Decode data according to the [`TypeId`] provided. -/// The provided pointer to the data slice will be moved forwards as needed -/// depending on what was decoded. -pub fn decode_value_as_type( - data: &mut &[u8], - ty_id: TypeId, - types: &PortableRegistry, -) -> Result, VisitorDecodeError> { - scale_decode::visitor::decode_with_visitor(data, ty_id, types, DecodeValueVisitor) -} - -// Sequences, Tuples and Arrays all have the same methods, so decode them in the same way: -macro_rules! to_unnamed_composite { - ($value:ident, $type_id:ident) => {{ - let mut vals = Vec::with_capacity($value.remaining()); - while let Some(val) = $value.decode_item(DecodeValueVisitor) { - let val = val?; - vals.push(val); - } - Ok(Value { value: ValueDef::Composite(Composite::Unnamed(vals)), context: $type_id.0 }) - }}; -} - -// We can't implement this on `Value` because we have no TypeId to assign to the value. -impl scale_decode::DecodeAsFields for Composite { - fn decode_as_fields<'info>( - input: &mut &[u8], - fields: &mut dyn FieldIter<'info>, - types: &'info PortableRegistry, - ) -> Result { - // Build a Composite type to pass to a one-off visitor: - static EMPTY_PATH: &Path = &Path { segments: Vec::new() }; - let mut composite = - scale_decode::visitor::types::Composite::new(input, EMPTY_PATH, fields, types); - // Decode into a Composite value from this: - let val = visit_composite(&mut composite); - // Consume remaining bytes and update input cursor: - composite.skip_decoding()?; - *input = composite.bytes_from_undecoded(); - - val.map_err(From::from) - } -} - -/// A [`scale_decode::Visitor`] implementation for decoding into [`Value`]s. -pub struct DecodeValueVisitor; - -impl scale_decode::IntoVisitor for Value { - type Visitor = DecodeValueVisitor; - fn into_visitor() -> Self::Visitor { - DecodeValueVisitor - } -} - -impl scale_decode::visitor::Visitor for DecodeValueVisitor { - type Value<'scale, 'info> = Value; - type Error = VisitorDecodeError; - - fn visit_bool<'scale, 'info>( - self, - value: bool, - type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - Ok(Value::bool(value).map_context(|_| type_id.0)) - } - fn visit_char<'scale, 'info>( - self, - value: char, - type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - Ok(Value::char(value).map_context(|_| type_id.0)) - } - fn visit_u8<'scale, 'info>( - self, - value: u8, - type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - self.visit_u128(value as u128, type_id) - } - fn visit_u16<'scale, 'info>( - self, - value: u16, - type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - self.visit_u128(value as u128, type_id) - } - fn visit_u32<'scale, 'info>( - self, - value: u32, - type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - self.visit_u128(value as u128, type_id) - } - fn visit_u64<'scale, 'info>( - self, - value: u64, - type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - self.visit_u128(value as u128, type_id) - } - fn visit_u128<'scale, 'info>( - self, - value: u128, - type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - Ok(Value::u128(value).map_context(|_| type_id.0)) - } - fn visit_u256<'info>( - self, - value: &'_ [u8; 32], - type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - Ok(Value { value: ValueDef::Primitive(Primitive::U256(*value)), context: type_id.0 }) - } - fn visit_i8<'scale, 'info>( - self, - value: i8, - type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - self.visit_i128(value as i128, type_id) - } - fn visit_i16<'scale, 'info>( - self, - value: i16, - type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - self.visit_i128(value as i128, type_id) - } - fn visit_i32<'scale, 'info>( - self, - value: i32, - type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - self.visit_i128(value as i128, type_id) - } - fn visit_i64<'scale, 'info>( - self, - value: i64, - type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - self.visit_i128(value as i128, type_id) - } - fn visit_i128<'scale, 'info>( - self, - value: i128, - type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - Ok(Value::i128(value).map_context(|_| type_id.0)) - } - fn visit_i256<'info>( - self, - value: &'_ [u8; 32], - type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - Ok(Value { value: ValueDef::Primitive(Primitive::U256(*value)), context: type_id.0 }) - } - fn visit_sequence<'scale, 'info>( - self, - value: &mut scale_decode::visitor::types::Sequence<'scale, 'info>, - type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - to_unnamed_composite!(value, type_id) - } - fn visit_tuple<'scale, 'info>( - self, - value: &mut scale_decode::visitor::types::Tuple<'scale, 'info>, - type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - to_unnamed_composite!(value, type_id) - } - fn visit_array<'scale, 'info>( - self, - value: &mut scale_decode::visitor::types::Array<'scale, 'info>, - type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - to_unnamed_composite!(value, type_id) - } - fn visit_bitsequence<'scale, 'info>( - self, - value: &mut scale_decode::visitor::types::BitSequence<'scale>, - type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - let bits: Result<_, _> = value.decode()?.collect(); - Ok(Value { value: ValueDef::BitSequence(bits?), context: type_id.0 }) - } - fn visit_str<'scale, 'info>( - self, - value: &mut scale_decode::visitor::types::Str<'scale>, - type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - Ok(Value::string(value.as_str()?).map_context(|_| type_id.0)) - } - fn visit_variant<'scale, 'info>( - self, - value: &mut scale_decode::visitor::types::Variant<'scale, 'info>, - type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - let values = visit_composite(value.fields())?; - Ok(Value { - value: ValueDef::Variant(Variant { name: value.name().to_owned(), values }), - context: type_id.0, - }) - } - fn visit_composite<'scale, 'info>( - self, - value: &mut scale_decode::visitor::types::Composite<'scale, 'info>, - type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - Ok(Value { value: ValueDef::Composite(visit_composite(value)?), context: type_id.0 }) - } -} - -/// Extract a named/unnamed Composite type out of scale_decode's Composite. -fn visit_composite( - value: &mut scale_decode::visitor::types::Composite<'_, '_>, -) -> Result, VisitorDecodeError> { - let len = value.remaining(); - // if no fields, we'll always assume unnamed. - let named = len > 0 && !value.has_unnamed_fields(); - - if named { - let mut vals = Vec::with_capacity(len); - let mut name = value.peek_name(); - while let Some(v) = value.decode_item(DecodeValueVisitor) { - let v = v?; - vals.push((name.expect("all fields should be named; we have checked").to_owned(), v)); - // get the next field name now we've decoded one. - name = value.peek_name(); - } - Ok(Composite::Named(vals)) - } else { - let mut vals = Vec::with_capacity(len); - while let Some(v) = value.decode_item(DecodeValueVisitor) { - let v = v?; - vals.push(v); - } - Ok(Composite::Unnamed(vals)) - } -} - -#[cfg(test)] -mod test { - - use super::*; - use codec::{Compact, Encode}; - - /// Given a type definition, return the PortableType and PortableRegistry - /// that our decode functions expect. - fn make_type() -> (TypeId, PortableRegistry) { - let m = scale_info::MetaType::new::(); - let mut types = scale_info::Registry::new(); - let id = types.register_type(&m); - let portable_registry: PortableRegistry = types.into(); - - (id.id, portable_registry) - } - - /// Given a value to encode, and a representation of the decoded value, check that our decode functions - /// successfully decodes the type to the expected value, based on the implicit SCALE type info that the type - /// carries - fn encode_decode_check(val: T, exp: Value<()>) { - encode_decode_check_explicit_info::(val, exp) - } - - /// Given a value to encode, a type to decode it back into, and a representation of - /// the decoded value, check that our decode functions successfully decodes as expected. - fn encode_decode_check_explicit_info( - val: T, - ex: Value<()>, - ) { - let encoded = val.encode(); - let encoded = &mut &*encoded; - - let (id, portable_registry) = make_type::(); - - // Can we decode? - let val = decode_value_as_type(encoded, id, &portable_registry).expect("decoding failed"); - // Is the decoded value what we expected? - assert_eq!(val.remove_context(), ex, "decoded value does not look like what we expected"); - // Did decoding consume all of the encoded bytes, as expected? - assert_eq!(encoded.len(), 0, "decoding did not consume all of the encoded bytes"); - } - - #[test] - fn decode_primitives() { - encode_decode_check(true, Value::bool(true)); - encode_decode_check(false, Value::bool(false)); - encode_decode_check_explicit_info::('a' as u32, Value::char('a')); - encode_decode_check("hello", Value::string("hello")); - encode_decode_check( - "hello".to_string(), // String or &str (above) decode OK - Value::string("hello"), - ); - encode_decode_check(123u8, Value::u128(123)); - encode_decode_check(123u16, Value::u128(123)); - encode_decode_check(123u32, Value::u128(123)); - encode_decode_check(123u64, Value::u128(123)); - encode_decode_check(123u128, Value::u128(123)); - //// Todo [jsdw]: Can we test this if we need a TypeInfo param?: - // encode_decode_check_explicit_info( - // [123u8; 32], // Anything 32 bytes long will do here - // Value::u256([123u8; 32]), - // ); - encode_decode_check(123i8, Value::i128(123)); - encode_decode_check(123i16, Value::i128(123)); - encode_decode_check(123i32, Value::i128(123)); - encode_decode_check(123i64, Value::i128(123)); - encode_decode_check(123i128, Value::i128(123)); - //// Todo [jsdw]: Can we test this if we need a TypeInfo param?: - // encode_decode_check_explicit_info( - // [123u8; 32], // Anything 32 bytes long will do here - // Value::i256([123u8; 32]), - // ); - } - - #[test] - fn decode_compact_primitives() { - encode_decode_check(Compact(123u8), Value::u128(123)); - encode_decode_check(Compact(123u16), Value::u128(123)); - encode_decode_check(Compact(123u32), Value::u128(123)); - encode_decode_check(Compact(123u64), Value::u128(123)); - encode_decode_check(Compact(123u128), Value::u128(123)); - } - - #[test] - fn decode_compact_named_wrapper_struct() { - // A struct that can be compact encoded: - #[derive(Encode, scale_info::TypeInfo)] - struct MyWrapper { - inner: u32, - } - impl From> for MyWrapper { - fn from(val: Compact) -> MyWrapper { - val.0 - } - } - impl codec::CompactAs for MyWrapper { - type As = u32; - - fn encode_as(&self) -> &Self::As { - &self.inner - } - fn decode_from(inner: Self::As) -> Result { - Ok(MyWrapper { inner }) - } - } - - encode_decode_check(Compact(MyWrapper { inner: 123 }), Value::u128(123)); - } - - #[test] - fn decode_compact_unnamed_wrapper_struct() { - // A struct that can be compact encoded: - #[derive(Encode, scale_info::TypeInfo)] - struct MyWrapper(u32); - impl From> for MyWrapper { - fn from(val: Compact) -> MyWrapper { - val.0 - } - } - impl codec::CompactAs for MyWrapper { - type As = u32; - - // Node the requirement to return something with a lifetime tied - // to self here. This means that we can't implement this for things - // more complex than wrapper structs (eg `Foo(u32,u32,u32,u32)`) without - // shenanigans, meaning that (hopefully) supporting wrapper struct - // decoding and nothing fancier is sufficient. - fn encode_as(&self) -> &Self::As { - &self.0 - } - fn decode_from(inner: Self::As) -> Result { - Ok(MyWrapper(inner)) - } - } - - encode_decode_check(Compact(MyWrapper(123)), Value::u128(123)); - } - - #[test] - fn decode_sequence_array_tuple_types() { - encode_decode_check( - vec![1i32, 2, 3], - Value::unnamed_composite(vec![Value::i128(1), Value::i128(2), Value::i128(3)]), - ); - encode_decode_check( - [1i32, 2, 3], // compile-time length known - Value::unnamed_composite(vec![Value::i128(1), Value::i128(2), Value::i128(3)]), - ); - encode_decode_check( - (1i32, true, 123456u128), - Value::unnamed_composite(vec![Value::i128(1), Value::bool(true), Value::u128(123456)]), - ); - } - - #[test] - fn decode_variant_types() { - #[derive(Encode, scale_info::TypeInfo)] - enum MyEnum { - Foo(bool), - Bar { hi: String, other: u128 }, - } - - encode_decode_check( - MyEnum::Foo(true), - Value::unnamed_variant("Foo", vec![Value::bool(true)]), - ); - encode_decode_check( - MyEnum::Bar { hi: "hello".to_string(), other: 123 }, - Value::named_variant( - "Bar", - vec![ - ("hi".to_string(), Value::string("hello".to_string())), - ("other".to_string(), Value::u128(123)), - ], - ), - ); - } - - #[test] - fn decode_composite_types() { - #[derive(Encode, scale_info::TypeInfo)] - struct Unnamed(bool, String, Vec); - - #[derive(Encode, scale_info::TypeInfo)] - struct Named { - is_valid: bool, - name: String, - bytes: Vec, - } - - encode_decode_check( - Unnamed(true, "James".into(), vec![1, 2, 3]), - Value::unnamed_composite(vec![ - Value::bool(true), - Value::string("James".to_string()), - Value::unnamed_composite(vec![Value::u128(1), Value::u128(2), Value::u128(3)]), - ]), - ); - encode_decode_check( - Named { is_valid: true, name: "James".into(), bytes: vec![1, 2, 3] }, - Value::named_composite(vec![ - ("is_valid", Value::bool(true)), - ("name", Value::string("James".to_string())), - ( - "bytes", - Value::unnamed_composite(vec![Value::u128(1), Value::u128(2), Value::u128(3)]), - ), - ]), - ); - } - - #[test] - fn decoding_zero_length_composites_always_unnamed() { - // The scale-info repr is just a composite, so we don't really track - // whether the thing was named or not. either Value will convert back ok anyway. - #[derive(Encode, scale_info::TypeInfo)] - struct Named {} - #[derive(Encode, scale_info::TypeInfo)] - struct Unnamed(); - - encode_decode_check(Unnamed(), Value::unnamed_composite(vec![])); - encode_decode_check(Named {}, Value::unnamed_composite(vec![])); - } - - #[test] - fn decode_bit_sequence() { - use scale_bits::bits; - - // scale-decode already tests this more thoroughly: - encode_decode_check(bits![0, 1, 1, 0, 1, 0], Value::bit_sequence(bits![0, 1, 1, 0, 1, 0])); - } -} diff --git a/node-api/src/scale_value/encode.rs b/node-api/src/scale_value/encode.rs deleted file mode 100644 index 2439dffa1..000000000 --- a/node-api/src/scale_value/encode.rs +++ /dev/null @@ -1,264 +0,0 @@ -// This file was taken from scale-value (Parity Technologies (UK)) -// https://github.com/paritytech/scale-value/ -// And was adapted by Supercomputing Systems AG. -// -// Copyright 2019-2022 Parity Technologies (UK) Ltd, Supercomputing Systems AG. -// This file is licensed as Apache-2.0 -// see LICENSE for license details. - -//! Based on https://github.com/paritytech/scale-value/blob/430bfaf8f302dfcfc45d8d63c687628fd9b7fc25/src/scale_impls/encode.rs - -use crate::scale_value::{Composite, Primitive, Value, ValueDef, Variant}; -use alloc::{boxed::Box, string::ToString, vec::Vec}; -use codec::{Compact, Encode}; -use scale_encode::{ - error::{ErrorKind, Kind}, - Composite as EncodeComposite, EncodeAsFields, EncodeAsType, Error, FieldIter, - Variant as EncodeVariant, -}; -use scale_info::{PortableRegistry, TypeDef}; - -pub use scale_encode::Error as EncodeError; - -impl EncodeAsType for Value { - fn encode_as_type_to( - &self, - type_id: u32, - types: &PortableRegistry, - out: &mut Vec, - ) -> Result<(), Error> { - match &self.value { - ValueDef::Composite(val) => encode_composite(val, type_id, types, out), - ValueDef::Variant(val) => encode_variant(val, type_id, types, out), - ValueDef::Primitive(val) => encode_primitive(val, type_id, types, out), - ValueDef::BitSequence(_val) => unimplemented!(), - } - } -} - -impl EncodeAsFields for Value { - fn encode_as_fields_to( - &self, - fields: &mut dyn FieldIter<'_>, - types: &PortableRegistry, - out: &mut Vec, - ) -> Result<(), Error> { - match &self.value { - ValueDef::Composite(composite) => composite.encode_as_fields_to(fields, types, out), - _ => Err(Error::new(ErrorKind::Custom(Box::new( - "Cannot encode non-composite Value shape into fields".to_string(), - )))), - } - } -} - -impl EncodeAsFields for Composite { - fn encode_as_fields_to( - &self, - fields: &mut dyn FieldIter<'_>, - types: &PortableRegistry, - out: &mut Vec, - ) -> Result<(), Error> { - match self { - Composite::Named(vals) => { - let keyvals = - vals.iter().map(|(key, val)| (Some(&**key), val as &dyn EncodeAsType)); - EncodeComposite(keyvals).encode_as_fields_to(fields, types, out) - }, - Composite::Unnamed(vals) => { - let vals = vals.iter().map(|val| (None, val as &dyn EncodeAsType)); - EncodeComposite(vals).encode_as_fields_to(fields, types, out) - }, - } - } -} - -// A scale-value composite type can represent sequences, arrays, composites and tuples. `scale_encode`'s Composite helper -// can't handle encoding to sequences/arrays. However, we can encode safely into sequences here because we can inspect the -// values we have and more safely skip newtype wrappers without also skipping through types that might represent 1-value -// sequences/arrays for instance. -fn encode_composite( - value: &Composite, - mut type_id: u32, - types: &PortableRegistry, - out: &mut Vec, -) -> Result<(), Error> { - // Encode our composite Value as-is (pretty much; we will try to - // unwrap the Value only if we need primitives). - fn do_encode_composite( - value: &Composite, - type_id: u32, - types: &PortableRegistry, - out: &mut Vec, - ) -> Result<(), Error> { - let ty = types - .resolve(type_id) - .ok_or_else(|| Error::new(ErrorKind::TypeNotFound(type_id)))?; - match &ty.type_def { - TypeDef::Tuple(_) | TypeDef::Composite(_) => match value { - Composite::Named(vals) => { - let keyvals = - vals.iter().map(|(key, val)| (Some(&**key), val as &dyn EncodeAsType)); - EncodeComposite(keyvals).encode_as_type_to(type_id, types, out) - }, - Composite::Unnamed(vals) => { - let vals = vals.iter().map(|val| (None, val as &dyn EncodeAsType)); - EncodeComposite(vals).encode_as_type_to(type_id, types, out) - }, - }, - TypeDef::Sequence(seq) => { - // sequences start with compact encoded length: - Compact(value.len() as u32).encode_to(out); - match value { - Composite::Named(named_vals) => - for (name, val) in named_vals { - val.encode_as_type_to(seq.type_param.id, types, out) - .map_err(|e| e.at_field(name.to_string()))?; - }, - Composite::Unnamed(vals) => - for (idx, val) in vals.iter().enumerate() { - val.encode_as_type_to(seq.type_param.id, types, out) - .map_err(|e| e.at_idx(idx))?; - }, - } - Ok(()) - }, - TypeDef::Array(array) => { - let arr_ty = array.type_param.id; - if value.len() != array.len as usize { - return Err(Error::new(ErrorKind::WrongLength { - actual_len: value.len(), - expected_len: array.len as usize, - })) - } - - for (idx, val) in value.values().enumerate() { - val.encode_as_type_to(arr_ty, types, out).map_err(|e| e.at_idx(idx))?; - } - Ok(()) - }, - TypeDef::BitSequence(_seq) => unimplemented!(), - // For other types, skip our value past a 1-value composite and try again, else error. - _ => { - let mut values = value.values(); - match (values.next(), values.next()) { - // Exactly one value: - (Some(value), None) => value.encode_as_type_to(type_id, types, out), - // Some other number of values: - _ => Err(Error::new(ErrorKind::WrongShape { - actual: Kind::Tuple, - expected: type_id, - })), - } - }, - } - } - - // First, try and encode everything as-is, only writing to the output - // byte if the encoding is actually successful. This means that if the - // Value provided matches the structure of the TypeInfo exactly, things - // should always work. - let original_error = { - let mut temp_out = Vec::new(); - match do_encode_composite(value, type_id, types, &mut temp_out) { - Ok(()) => { - out.extend_from_slice(&temp_out); - return Ok(()) - }, - Err(e) => e, - } - }; - - // Next, unwrap any newtype wrappers from our TypeInfo and try again. If we - // can unwrap, then try to encode our Value to this immediately (this will work - // if the Value provided already ignored all newtype wrappers). If we have nothing - // to unwrap then ignore this extra encode attempt. - { - let inner_type_id = find_single_entry_with_same_repr(type_id, types); - if inner_type_id != type_id { - let mut temp_out = Vec::new(); - if let Ok(()) = do_encode_composite(value, inner_type_id, types, &mut temp_out) { - out.extend_from_slice(&temp_out); - return Ok(()) - } - type_id = inner_type_id; - } - } - - // Now, start peeling layers off our Value type in case some newtype wrappers - // were provided. We do this one layer at a time because it's difficult or - // impossible to know how to line values up with TypeInfo, so we can't just - // strip lots of layers from the Value straight away. We continue to ignore - // any errors here and will always return the original_error if we can't encode. - // Everything past the original attempt is just trying to be flexible, anyway. - while let Some(value) = get_only_value_from_composite(value) { - let mut temp_out = Vec::new(); - if let Ok(()) = value.encode_as_type_to(type_id, types, &mut temp_out) { - out.extend_from_slice(&temp_out); - return Ok(()) - } - } - - // return the original error we got back if none of the above is succcessful. - Err(original_error) -} - -// skip into the target type past any newtype wrapper like things: -fn find_single_entry_with_same_repr(type_id: u32, types: &PortableRegistry) -> u32 { - let Some(ty) = types.resolve(type_id) else { return type_id }; - match &ty.type_def { - TypeDef::Tuple(tuple) if tuple.fields.len() == 1 => - find_single_entry_with_same_repr(tuple.fields[0].id, types), - TypeDef::Composite(composite) if composite.fields.len() == 1 => - find_single_entry_with_same_repr(composite.fields[0].ty.id, types), - TypeDef::Array(arr) if arr.len == 1 => - find_single_entry_with_same_repr(arr.type_param.id, types), - _ => type_id, - } -} - -// if the composite type has exactly one value, return that Value, else return None. -fn get_only_value_from_composite(value: &'_ Composite) -> Option<&'_ Value> { - let mut values = value.values(); - match (values.next(), values.next()) { - (Some(value), None) => Some(value), - _ => None, - } -} - -fn encode_variant( - value: &Variant, - type_id: u32, - types: &PortableRegistry, - out: &mut Vec, -) -> Result<(), Error> { - match &value.values { - Composite::Named(vals) => { - let keyvals = vals.iter().map(|(key, val)| (Some(&**key), val as &dyn EncodeAsType)); - EncodeVariant { name: &value.name, fields: EncodeComposite(keyvals) } - .encode_as_type_to(type_id, types, out) - }, - Composite::Unnamed(vals) => { - let vals = vals.iter().map(|val| (None, val as &dyn EncodeAsType)); - EncodeVariant { name: &value.name, fields: EncodeComposite(vals) } - .encode_as_type_to(type_id, types, out) - }, - } -} - -fn encode_primitive( - value: &Primitive, - type_id: u32, - types: &PortableRegistry, - bytes: &mut Vec, -) -> Result<(), Error> { - match value { - Primitive::Bool(val) => val.encode_as_type_to(type_id, types, bytes), - Primitive::Char(val) => val.encode_as_type_to(type_id, types, bytes), - Primitive::String(val) => val.encode_as_type_to(type_id, types, bytes), - Primitive::U128(val) => val.encode_as_type_to(type_id, types, bytes), - Primitive::I128(val) => val.encode_as_type_to(type_id, types, bytes), - Primitive::U256(val) => val.encode_as_type_to(type_id, types, bytes), - Primitive::I256(val) => val.encode_as_type_to(type_id, types, bytes), - } -} diff --git a/node-api/src/scale_value/mod.rs b/node-api/src/scale_value/mod.rs deleted file mode 100644 index b6a421070..000000000 --- a/node-api/src/scale_value/mod.rs +++ /dev/null @@ -1,58 +0,0 @@ -// This file was taken from scale-value (Parity Technologies (UK)) -// https://github.com/paritytech/scale-value/ -// And was adapted by Supercomputing Systems AG. -// -// Copyright 2019-2022 Parity Technologies (UK) Ltd, Supercomputing Systems AG. -// This file is licensed as Apache-2.0 -// see LICENSE for license details. - -//! Decode helpers. -//! It was not possible to take the scale-value as crate, because it's not no_std compatible. -//! Based on https://github.com/paritytech/scale-value/blob/430bfaf8f302dfcfc45d8d63c687628fd9b7fc25/src/lib.rs - -mod decode; -mod encode; -mod value; - -// The value definition. -pub use value::{BitSequence, Composite, Primitive, Value, ValueDef, Variant}; - -/// A type ID which can be resolved into a type given a [`scale_info::PortableRegistry`]. -pub type TypeId = u32; - -pub use scale::*; -pub use scale_info::PortableRegistry; - -pub mod scale { - use super::TypeId; - pub use super::{ - decode::{DecodeValueVisitor, VisitorDecodeError}, - encode::EncodeError, - }; - use alloc::vec::Vec; - use scale_encode::EncodeAsType; - pub use scale_info::PortableRegistry; - - /// Attempt to decode some SCALE encoded bytes into a value, by providing a pointer - /// to the bytes (which will be moved forwards as bytes are used in the decoding), - /// a type ID, and a type registry from which we'll look up the relevant type information. - pub fn decode_as_type( - data: &mut &[u8], - ty_id: TypeId, - types: &PortableRegistry, - ) -> Result, VisitorDecodeError> { - crate::scale_value::decode::decode_value_as_type(data, ty_id, types) - } - - /// Attempt to encode some [`crate::Value`] into SCALE bytes, by providing a pointer to the - /// type ID that we'd like to encode it as, a type registry from which we'll look - /// up the relevant type information, and a buffer to encode the bytes to. - pub fn encode_as_type( - value: &super::Value, - ty_id: TypeId, - types: &PortableRegistry, - buf: &mut Vec, - ) -> Result<(), EncodeError> { - value.encode_as_type_to(ty_id, types, buf) - } -} diff --git a/node-api/src/scale_value/value.rs b/node-api/src/scale_value/value.rs deleted file mode 100644 index 2692fdd0f..000000000 --- a/node-api/src/scale_value/value.rs +++ /dev/null @@ -1,484 +0,0 @@ -// This file was taken from scale-value (Parity Technologies (UK)) -// https://github.com/paritytech/scale-value/ -// And was adapted by Supercomputing Systems AG. -// -// Copyright (C) 2022-2023 Parity Technologies (UK) Ltd. (admin@parity.io) -// This file is a part of the scale-value crate. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use alloc::{string::String, vec::Vec}; -use core::convert::From; -use either::Either; - -// We use this to represent BitSequence values, so expose it here. -pub use scale_bits::Bits as BitSequence; - -/// [`Value`] holds a representation of some value that has been decoded, as well as some arbitrary context. -/// -/// Not all SCALE encoded types have an similar-named value; for instance, the values corresponding to -/// sequence, array and composite types can all be represented with [`Composite`]. Only enough information -/// is preserved here to to be able to encode and decode SCALE bytes with a known type to and from [`Value`]s -/// losslessly. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Value { - /// The shape and associated data for this Value - pub value: ValueDef, - /// Some additional arbitrary context that can be associated with a value. - pub context: T, -} - -impl Value<()> { - /// Construct a named composite type from any type which produces a tuple of keys and values - /// when iterated over. - pub fn named_composite(vals: Vals) -> Self - where - S: Into, - Vals: IntoIterator)>, - { - Value { value: ValueDef::Composite(Composite::named(vals)), context: () } - } - /// Construct an unnamed composite type from any type which produces values - /// when iterated over. - pub fn unnamed_composite(vals: Vals) -> Self - where - Vals: IntoIterator>, - { - Value { value: ValueDef::Composite(Composite::unnamed(vals)), context: () } - } - /// Create a new variant value without additional context. - pub fn variant>(name: S, values: Composite<()>) -> Value<()> { - Value { value: ValueDef::Variant(Variant { name: name.into(), values }), context: () } - } - /// Create a new variant value with named fields and without additional context. - pub fn named_variant(name: S, fields: Vals) -> Value<()> - where - S: Into, - F: Into, - Vals: IntoIterator)>, - { - Value { value: ValueDef::Variant(Variant::named_fields(name, fields)), context: () } - } - /// Create a new variant value with tuple-like fields and without additional context. - pub fn unnamed_variant(name: S, fields: Vals) -> Value<()> - where - S: Into, - Vals: IntoIterator>, - { - Value { value: ValueDef::Variant(Variant::unnamed_fields(name, fields)), context: () } - } - /// Create a new bit sequence value without additional context. - pub fn bit_sequence(bits: BitSequence) -> Value<()> { - Value { value: ValueDef::BitSequence(bits), context: () } - } - /// Create a new primitive value without additional context. - pub fn primitive(primitive: Primitive) -> Value<()> { - Value { value: ValueDef::Primitive(primitive), context: () } - } - /// Create a new string value without additional context. - pub fn string>(val: S) -> Value<()> { - Value { value: ValueDef::Primitive(Primitive::String(val.into())), context: () } - } - /// Create a new boolean value without additional context. - pub fn bool(val: bool) -> Value<()> { - Value { value: ValueDef::Primitive(Primitive::Bool(val)), context: () } - } - /// Create a new char without additional context. - pub fn char(val: char) -> Value<()> { - Value { value: ValueDef::Primitive(Primitive::Char(val)), context: () } - } - /// Create a new unsigned integer without additional context. - pub fn u128(val: u128) -> Value<()> { - Value { value: ValueDef::Primitive(Primitive::u128(val)), context: () } - } - /// Create a new signed integer without additional context. - pub fn i128(val: i128) -> Value<()> { - Value { value: ValueDef::Primitive(Primitive::i128(val)), context: () } - } - /// Create a new Value from a set of bytes; useful for converting things like AccountIds. - pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Value<()> { - let vals: Vec<_> = bytes.as_ref().iter().map(|&b| Value::u128(b as u128)).collect(); - Value::unnamed_composite(vals) - } -} - -impl Value<()> { - /// Create a new value with no associated context. - pub fn without_context(value: ValueDef<()>) -> Value<()> { - Value { value, context: () } - } -} - -impl Value { - /// Create a new value with some associated context. - pub fn with_context(value: ValueDef, context: T) -> Value { - Value { value, context } - } - /// Remove the context. - pub fn remove_context(self) -> Value<()> { - self.map_context(|_| ()) - } - /// Map the context to some different type. - pub fn map_context(self, mut f: F) -> Value - where - F: Clone + FnMut(T) -> U, - { - Value { context: f(self.context), value: self.value.map_context(f) } - } - /// If the value is a boolean value, return it. - pub fn as_bool(&self) -> Option { - match &self.value { - ValueDef::Primitive(p) => p.as_bool(), - _ => None, - } - } - /// If the value is a char, return it. - pub fn as_char(&self) -> Option { - match &self.value { - ValueDef::Primitive(p) => p.as_char(), - _ => None, - } - } - /// If the value is a u128, return it. - pub fn as_u128(&self) -> Option { - match &self.value { - ValueDef::Primitive(p) => p.as_u128(), - _ => None, - } - } - /// If the value is an i128, return it. - pub fn as_i128(&self) -> Option { - match &self.value { - ValueDef::Primitive(p) => p.as_i128(), - _ => None, - } - } - /// If the value is a string, return it. - pub fn as_str(&self) -> Option<&str> { - match &self.value { - ValueDef::Primitive(p) => p.as_str(), - _ => None, - } - } -} - -/// The underlying shape of a given value. -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum ValueDef { - /// A named or unnamed struct-like, array-like or tuple-like set of values. - Composite(Composite), - /// An enum variant. - Variant(Variant), - /// A sequence of bits. - BitSequence(BitSequence), - /// Any of the primitive values we can have. - Primitive(Primitive), -} - -impl ValueDef { - /// Map the context to some different type. - pub fn map_context(self, f: F) -> ValueDef - where - F: Clone + FnMut(T) -> U, - { - match self { - ValueDef::Composite(val) => ValueDef::Composite(val.map_context(f)), - ValueDef::Variant(val) => ValueDef::Variant(val.map_context(f)), - ValueDef::BitSequence(val) => ValueDef::BitSequence(val), - ValueDef::Primitive(val) => ValueDef::Primitive(val), - } - } -} - -impl From for ValueDef { - fn from(val: BitSequence) -> Self { - ValueDef::BitSequence(val) - } -} - -impl From for Value<()> { - fn from(val: BitSequence) -> Self { - Value::without_context(val.into()) - } -} - -/// A named or unnamed struct-like, array-like or tuple-like set of values. -/// This is used to represent a range of composite values on their own, or -/// as values for a specific [`Variant`]. -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum Composite { - /// Eg `{ foo: 2, bar: false }` - Named(Vec<(String, Value)>), - /// Eg `(2, false)` - Unnamed(Vec>), -} - -impl Composite { - /// Construct a named composite type from any type which produces a tuple of keys and values - /// when iterated over. - pub fn named, Vals: IntoIterator)>>(vals: Vals) -> Self { - Composite::Named(vals.into_iter().map(|(n, v)| (n.into(), v)).collect()) - } - /// Construct an unnamed composite type from any type which produces values - /// when iterated over. - pub fn unnamed>>(vals: Vals) -> Self { - Composite::Unnamed(vals.into_iter().collect()) - } - /// Return the number of values stored in this composite type. - pub fn len(&self) -> usize { - match self { - Composite::Named(values) => values.len(), - Composite::Unnamed(values) => values.len(), - } - } - - /// Is the composite type empty? - pub fn is_empty(&self) -> bool { - match self { - Composite::Named(values) => values.is_empty(), - Composite::Unnamed(values) => values.is_empty(), - } - } - - /// Iterate over the values stored in this composite type. - pub fn values(&self) -> impl ExactSizeIterator> { - match self { - Composite::Named(values) => Either::Left(values.iter().map(|(_k, v)| v)), - Composite::Unnamed(values) => Either::Right(values.iter()), - } - } - - /// Iterate over the values stored in this composite type. - pub fn into_values(self) -> impl ExactSizeIterator> { - match self { - Composite::Named(values) => Either::Left(values.into_iter().map(|(_k, v)| v)), - Composite::Unnamed(values) => Either::Right(values.into_iter()), - } - } - - /// Map the context to some different type. - pub fn map_context(self, f: F) -> Composite - where - F: Clone + FnMut(T) -> U, - { - match self { - Composite::Named(values) => { - // Note: Optimally I'd pass `&mut f` into each iteration to avoid cloning, - // but this leads to a type recusion error because F becomes `&mut F`, which can - // (at type level) recurse here again and become `&mut &mut F` and so on. Since - // that's no good; just require `Clone` to avoid altering the type. - let vals = - values.into_iter().map(move |(k, v)| (k, v.map_context(f.clone()))).collect(); - Composite::Named(vals) - }, - Composite::Unnamed(values) => { - let vals = values.into_iter().map(move |v| v.map_context(f.clone())).collect(); - Composite::Unnamed(vals) - }, - } - } -} - -impl>> From> for Composite<()> { - fn from(vals: Vec) -> Self { - let vals = vals.into_iter().map(|v| v.into()).collect(); - Composite::Unnamed(vals) - } -} - -impl>> From> for ValueDef<()> { - fn from(vals: Vec) -> Self { - ValueDef::Composite(vals.into()) - } -} - -impl>> From> for Value<()> { - fn from(vals: Vec) -> Self { - Value::without_context(vals.into()) - } -} - -impl, V: Into>> From> for Composite<()> { - fn from(vals: Vec<(K, V)>) -> Self { - let vals = vals.into_iter().map(|(k, v)| (k.into(), v.into())).collect(); - Composite::Named(vals) - } -} - -impl, V: Into>> From> for ValueDef<()> { - fn from(vals: Vec<(K, V)>) -> Self { - ValueDef::Composite(vals.into()) - } -} - -impl, V: Into>> From> for Value<()> { - fn from(vals: Vec<(K, V)>) -> Self { - Value::without_context(vals.into()) - } -} - -impl From> for ValueDef { - fn from(val: Composite) -> Self { - ValueDef::Composite(val) - } -} - -impl From> for Value<()> { - fn from(val: Composite<()>) -> Self { - Value::without_context(ValueDef::Composite(val)) - } -} - -/// This represents the value of a specific variant from an enum, and contains -/// the name of the variant, and the named/unnamed values associated with it. -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct Variant { - /// The name of the variant. - pub name: String, - /// Values for each of the named or unnamed fields associated with this variant. - pub values: Composite, -} - -impl Variant { - /// Construct a variant with named fields. - pub fn named_fields(name: S, fields: Vals) -> Variant - where - S: Into, - K: Into, - Vals: IntoIterator)>, - { - Variant { name: name.into(), values: Composite::named(fields) } - } - /// Construct a variant with tuple-like fields. - pub fn unnamed_fields(name: S, fields: Vals) -> Variant - where - S: Into, - Vals: IntoIterator>, - { - Variant { name: name.into(), values: Composite::unnamed(fields) } - } - /// Map the context to some different type. - pub fn map_context(self, f: F) -> Variant - where - F: Clone + FnMut(T) -> U, - { - Variant { name: self.name, values: self.values.map_context(f) } - } -} - -impl From> for ValueDef { - fn from(val: Variant) -> Self { - ValueDef::Variant(val) - } -} - -impl From> for Value<()> { - fn from(val: Variant<()>) -> Self { - Value::without_context(ValueDef::Variant(val)) - } -} - -/// A "primitive" value (this includes strings). -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum Primitive { - /// A boolean value. - Bool(bool), - /// A single character. - Char(char), - /// A string. - String(String), - /// A u128 value. - U128(u128), - /// An i128 value. - I128(i128), - /// An unsigned 256 bit number (internally represented as a 32 byte array). - U256([u8; 32]), - /// A signed 256 bit number (internally represented as a 32 byte array). - I256([u8; 32]), -} - -impl Primitive { - /// Create a new unsigned integer without additional context. - pub fn u128(val: u128) -> Primitive { - Primitive::U128(val) - } - /// Create a new signed integer without additional context. - pub fn i128(val: i128) -> Primitive { - Primitive::I128(val) - } - /// If the primitive type is a boolean value, return it. - pub fn as_bool(&self) -> Option { - match self { - Primitive::Bool(b) => Some(*b), - _ => None, - } - } - /// If the primitive type is a char, return it. - pub fn as_char(&self) -> Option { - match self { - Primitive::Char(c) => Some(*c), - _ => None, - } - } - /// If the primitive type is a u128, return it. - pub fn as_u128(&self) -> Option { - match self { - Primitive::U128(n) => Some(*n), - _ => None, - } - } - /// If the primitive type is an i128, return it. - pub fn as_i128(&self) -> Option { - match self { - Primitive::I128(n) => Some(*n), - _ => None, - } - } - /// If the primitive type is a string, return it. - pub fn as_str(&self) -> Option<&str> { - match self { - Primitive::String(s) => Some(&**s), - _ => None, - } - } -} - -impl From for ValueDef { - fn from(val: Primitive) -> Self { - ValueDef::Primitive(val) - } -} - -macro_rules! impl_primitive_type { - ($($variant:ident($ty:ty),)*) => {$( - impl From<$ty> for Primitive { - fn from(val: $ty) -> Self { - Primitive::$variant(val) - } - } - - impl From<$ty> for ValueDef { - fn from(val: $ty) -> Self { - ValueDef::Primitive(val.into()) - } - } - - impl From<$ty> for Value<()> { - fn from(val: $ty) -> Self { - Value::without_context(val.into()) - } - } - )*} -} - -impl_primitive_type!(Bool(bool), Char(char), String(String), U128(u128), I128(i128),); From 3c6102d5b534fe9fad295db972b4a116b2b5ae26 Mon Sep 17 00:00:00 2001 From: haerdib Date: Wed, 6 Dec 2023 16:00:12 +0100 Subject: [PATCH 5/5] fix jsonrpsee client --- src/rpc/jsonrpsee_client/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/rpc/jsonrpsee_client/mod.rs b/src/rpc/jsonrpsee_client/mod.rs index 66910d7d9..ec2ff6616 100644 --- a/src/rpc/jsonrpsee_client/mod.rs +++ b/src/rpc/jsonrpsee_client/mod.rs @@ -48,7 +48,9 @@ impl JsonrpseeClient { .build(uri) .await .map_err(|e| Error::Client(Box::new(e)))?; - let client = ClientBuilder::default().build_with_tokio(tx, rx); + let client = ClientBuilder::default() + .max_buffer_capacity_per_subscription(4096) + .build_with_tokio(tx, rx); Ok(Self { inner: Arc::new(client) }) } }