From 28b6bc99ac9fd3706a3efdebd4b3b7d46d4e6fa5 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 15 Apr 2023 05:23:57 -0400 Subject: [PATCH] Update to the latest subxt Writes a custom unsigned extrinic creator due to subxt having an internal error with the scale metadata. While the code in our scope increased, it's much more ergonomic to our usage. We may end up rewriting most of subxt, eventually. --- Cargo.lock | 91 ++++++++++++++----- substrate/client/Cargo.toml | 2 +- substrate/client/src/serai/in_instructions.rs | 12 +-- substrate/client/src/serai/mod.rs | 35 ++++--- substrate/client/src/serai/scale_value.rs | 5 +- substrate/client/src/serai/tokens.rs | 8 +- substrate/client/src/serai/validator_sets.rs | 8 +- 7 files changed, 105 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a9a6fa81..f8de2698 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8441,16 +8441,58 @@ dependencies = [ [[package]] name = "scale-decode" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d823d4be477fc33321f93d08fb6c2698273d044f01362dc27573a750deb7c233" +checksum = "c7e5527e4b3bf079d4c0b2f253418598c380722ba37ef20fac9088081407f2b6" dependencies = [ "parity-scale-codec", + "primitive-types", "scale-bits", + "scale-decode-derive", "scale-info", "thiserror", ] +[[package]] +name = "scale-decode-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b38741b2f78e4391b94eac6b102af0f6ea2b0f7fe65adb55d7f4004f507854db" +dependencies = [ + "darling", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "scale-encode" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15546e5efbb45f0fc2291f7e202dee8623274c5d8bbfdf9c6886cc8b44a7ced3" +dependencies = [ + "parity-scale-codec", + "primitive-types", + "scale-bits", + "scale-encode-derive", + "scale-info", + "thiserror", +] + +[[package]] +name = "scale-encode-derive" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd983cf0a9effd76138554ead18a6de542d1af175ac12fd5e91836c5c0268082" +dependencies = [ + "darling", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "scale-info" version = "2.5.0" @@ -8479,15 +8521,16 @@ dependencies = [ [[package]] name = "scale-value" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16a5e7810815bd295da73e4216d1dfbced3c7c7c7054d70fa5f6e4c58123fff4" +checksum = "11f549769261561e6764218f847e500588f9a79a289de49ce92f9e26642a3574" dependencies = [ "either", "frame-metadata", "parity-scale-codec", "scale-bits", "scale-decode", + "scale-encode", "scale-info", "serde", "thiserror", @@ -9363,16 +9406,16 @@ dependencies = [ [[package]] name = "sp-core-hashing" -version = "6.0.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc2d1947252b7a4e403b0a260f596920443742791765ec111daa2bbf98eff25" +checksum = "27449abdfbe41b473e625bce8113745e81d65777dd1d5a8462cf24137930dad8" dependencies = [ - "blake2", + "blake2b_simd", "byteorder", "digest 0.10.6", "sha2 0.10.6", "sha3", - "sp-std 6.0.0", + "sp-std 7.0.0", "twox-hash", ] @@ -9629,9 +9672,9 @@ source = "git+https://github.com/serai-dex/substrate#db8ca563accf52d0a3e0aa68f9c [[package]] name = "sp-std" -version = "6.0.0" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af0ee286f98455272f64ac5bb1384ff21ac029fbb669afbaf48477faff12760e" +checksum = "1de8eef39962b5b97478719c493bed2926cf70cb621005bbf68ebe58252ff986" [[package]] name = "sp-storage" @@ -10010,13 +10053,14 @@ checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" [[package]] name = "subxt" -version = "0.27.1" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54639dba6a113584083968b6a8f457dedae612abe1bd214762101ca29f12e332" +checksum = "53b9c4ddefcb2d87eb18a6336f65635c29208f766d0deefaa2a1a19f7426a993" dependencies = [ "base58", "blake2", "derivative", + "either", "frame-metadata", "futures", "getrandom 0.2.9", @@ -10028,11 +10072,12 @@ dependencies = [ "primitive-types", "scale-bits", "scale-decode", + "scale-encode", "scale-info", "scale-value", "serde", "serde_json", - "sp-core-hashing 6.0.0", + "sp-core-hashing 8.0.0", "subxt-macro", "subxt-metadata", "thiserror", @@ -10041,9 +10086,9 @@ dependencies = [ [[package]] name = "subxt-codegen" -version = "0.27.1" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e86cb719003f1cedf2710a6e55ca4c37aba4c989bbd3b81dd1c52af9e4827e" +checksum = "e924f41069e9273236398ff89662d6d336468a5d94faac812129d44547db0e7f" dependencies = [ "darling", "frame-metadata", @@ -10051,20 +10096,20 @@ dependencies = [ "hex", "jsonrpsee", "parity-scale-codec", - "proc-macro-error", "proc-macro2", "quote", "scale-info", "subxt-metadata", "syn 1.0.109", + "thiserror", "tokio", ] [[package]] name = "subxt-macro" -version = "0.27.1" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74c08de402a78c4c06c3ee3702c80e519efdcb65911348e018b6998d04404916" +checksum = "ced0b043a069ee039f8700d3dfda01be156e4229c82277c305bc8e79a7dd855d" dependencies = [ "darling", "proc-macro-error", @@ -10074,14 +10119,14 @@ dependencies = [ [[package]] name = "subxt-metadata" -version = "0.27.1" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2593ab5f53435e6352675af4f9851342607f37785d84c7a3fb3139550d3c35f0" +checksum = "18be3b8f4308fe7369ee1df66ae59c2eca79de20eab57b0f41c75736e843300f" dependencies = [ "frame-metadata", "parity-scale-codec", "scale-info", - "sp-core-hashing 6.0.0", + "sp-core-hashing 8.0.0", ] [[package]] @@ -12044,9 +12089,9 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" [[package]] name = "yap" -version = "0.7.2" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc77f52dc9e9b10d55d3f4462c3b7fc393c4f17975d641542833ab2d3bc26ef" +checksum = "e2a7eb6d82a11e4d0b8e6bda8347169aff4ccd8235d039bba7c47482d977dcf7" [[package]] name = "yasna" diff --git a/substrate/client/Cargo.toml b/substrate/client/Cargo.toml index a6c553f9..192f6241 100644 --- a/substrate/client/Cargo.toml +++ b/substrate/client/Cargo.toml @@ -21,7 +21,7 @@ scale-info = { version = "2", optional = true } serai-runtime = { path = "../runtime", version = "0.1" } sp-core = { git = "https://github.com/serai-dex/substrate" } -subxt = { version = "0.27", default-features = false, features = ["jsonrpsee-ws"], optional = true } +subxt = { version = "0.28", default-features = false, features = ["jsonrpsee-ws"], optional = true } bitcoin = { version = "0.30", optional = true } diff --git a/substrate/client/src/serai/in_instructions.rs b/substrate/client/src/serai/in_instructions.rs index 0efe40c0..aa0cfd78 100644 --- a/substrate/client/src/serai/in_instructions.rs +++ b/substrate/client/src/serai/in_instructions.rs @@ -2,11 +2,9 @@ use serai_runtime::{in_instructions, InInstructions, Runtime}; pub use in_instructions::primitives; use primitives::SignedBatch; -use subxt::{tx, utils::Encoded}; +use subxt::utils::Encoded; -use crate::{Serai, SeraiError, scale_composite}; - -const PALLET: &str = "InInstructions"; +use crate::{Serai, SeraiError}; pub type InInstructionsEvent = in_instructions::Event; @@ -23,10 +21,6 @@ impl Serai { } pub fn execute_batch(&self, batch: SignedBatch) -> Result { - self.unsigned(&tx::dynamic( - PALLET, - "execute_batch", - scale_composite(in_instructions::Call::::execute_batch { batch }), - )) + self.unsigned::(&in_instructions::Call::::execute_batch { batch }) } } diff --git a/substrate/client/src/serai/mod.rs b/substrate/client/src/serai/mod.rs index 8962a2b6..c6d508ea 100644 --- a/substrate/client/src/serai/mod.rs +++ b/substrate/client/src/serai/mod.rs @@ -2,8 +2,7 @@ use thiserror::Error; use scale::{Encode, Decode}; mod scale_value; -pub(crate) use scale_value::{scale_value, scale_composite}; -use subxt::ext::scale_value::Value; +pub(crate) use scale_value::{Value, Composite, scale_value, scale_composite}; use sp_core::{Pair as PairTrait, sr25519::Pair}; @@ -16,7 +15,7 @@ use subxt::{ substrate::{BlakeTwo256, SubstrateHeader}, extrinsic_params::{BaseExtrinsicParams, BaseExtrinsicParamsBuilder}, }, - tx::{Signer, DynamicTxPayload, TxClient}, + tx::{Signer, Payload, TxClient}, rpc::types::ChainBlock, Config as SubxtConfig, OnlineClient, }; @@ -89,9 +88,7 @@ impl Serai { debug_assert!(storage.validate(&address).is_ok(), "invalid storage address"); storage - .at(Some(block.into())) - .await - .map_err(SeraiError::RpcError)? + .at(block.into()) .fetch(&address) .await .map_err(SeraiError::RpcError)? @@ -105,8 +102,7 @@ impl Serai { filter: impl Fn(&E) -> bool, ) -> Result, SeraiError> { let mut res = vec![]; - for event in self.0.events().at(Some(block.into())).await.map_err(SeraiError::RpcError)?.iter() - { + for event in self.0.events().at(block.into()).await.map_err(SeraiError::RpcError)?.iter() { let event = event.map_err(|_| SeraiError::InvalidRuntime)?; if PalletInfo::index::

().unwrap() == usize::from(event.pallet_index()) { let mut with_variant: &[u8] = @@ -198,17 +194,28 @@ impl Serai { .map_err(SeraiError::RpcError) } - pub fn unsigned(&self, payload: &DynamicTxPayload<'static>) -> Result { - TxClient::new(self.0.offline()) - .create_unsigned(payload) - .map(|tx| Encoded(tx.into_encoded())) - .map_err(|_| SeraiError::InvalidRuntime) + pub fn unsigned(&self, call: &C) -> Result { + // TODO: Should Serai purge the old transaction code AND set this to 0/1? + const TRANSACTION_VERSION: u8 = 4; + + // Protocol version + let mut bytes = vec![TRANSACTION_VERSION]; + + // Pallet index + bytes.push(u8::try_from(PalletInfo::index::

().unwrap()).unwrap()); + // Call + bytes.extend(call.encode()); + + // Prefix the length + let mut complete_bytes = scale::Compact(u32::try_from(bytes.len()).unwrap()).encode(); + complete_bytes.extend(bytes); + Ok(Encoded(complete_bytes)) } pub fn sign>( &self, signer: &S, - payload: &DynamicTxPayload<'static>, + payload: &Payload>, nonce: u32, params: BaseExtrinsicParamsBuilder, ) -> Result { diff --git a/substrate/client/src/serai/scale_value.rs b/substrate/client/src/serai/scale_value.rs index 6dc52298..17b5c3ad 100644 --- a/substrate/client/src/serai/scale_value.rs +++ b/substrate/client/src/serai/scale_value.rs @@ -1,6 +1,9 @@ use ::scale::Encode; use scale_info::{MetaType, TypeInfo, Registry, PortableRegistry}; -use subxt::ext::scale_value::{Composite, ValueDef, Value, scale}; + +use subxt::ext::scale_value; +pub(crate) use scale_value::{Composite, Value}; +use scale_value::{ValueDef, scale}; pub(crate) fn scale_value(value: V) -> Value { let mut registry = Registry::new(); diff --git a/substrate/client/src/serai/tokens.rs b/substrate/client/src/serai/tokens.rs index f77e34e1..d57ce71c 100644 --- a/substrate/client/src/serai/tokens.rs +++ b/substrate/client/src/serai/tokens.rs @@ -6,9 +6,9 @@ use serai_runtime::{ pub use tokens::primitives; use primitives::OutInstruction; -use subxt::tx::{self, DynamicTxPayload}; +use subxt::tx::Payload; -use crate::{Serai, SeraiError, scale_value, scale_composite}; +use crate::{Serai, SeraiError, Composite, scale_value, scale_composite}; const PALLET: &str = "Tokens"; @@ -54,8 +54,8 @@ impl Serai { )) } - pub fn burn(balance: Balance, instruction: OutInstruction) -> DynamicTxPayload<'static> { - tx::dynamic( + pub fn burn(balance: Balance, instruction: OutInstruction) -> Payload> { + Payload::new( PALLET, "burn", scale_composite(tokens::Call::::burn { balance, instruction }), diff --git a/substrate/client/src/serai/validator_sets.rs b/substrate/client/src/serai/validator_sets.rs index e62aabfe..018cbe75 100644 --- a/substrate/client/src/serai/validator_sets.rs +++ b/substrate/client/src/serai/validator_sets.rs @@ -2,9 +2,9 @@ use serai_runtime::{validator_sets, ValidatorSets, Runtime}; pub use validator_sets::primitives; use primitives::{ValidatorSet, ValidatorSetData, KeyPair}; -use subxt::tx::{self, DynamicTxPayload}; +use subxt::tx::Payload; -use crate::{primitives::NetworkId, Serai, SeraiError, scale_value, scale_composite}; +use crate::{primitives::NetworkId, Serai, SeraiError, Composite, scale_value, scale_composite}; const PALLET: &str = "ValidatorSets"; @@ -58,8 +58,8 @@ impl Serai { .await } - pub fn vote(network: NetworkId, key_pair: KeyPair) -> DynamicTxPayload<'static> { - tx::dynamic( + pub fn vote(network: NetworkId, key_pair: KeyPair) -> Payload> { + Payload::new( PALLET, "vote", scale_composite(validator_sets::Call::::vote { network, key_pair }),