From 2beb1974293a711581fa1af7a8639790781f6c34 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 21 Dec 2023 15:09:22 +0100 Subject: [PATCH] Revert "use subxt-signer to reduce the number of deps (#720)" (#743) * Revert "use `subxt-signer` to reduce the number of deps (#720)" This reverts commit eb767d00c1b6bc33e4f50471a73464b64549f821. * revert README changes --- Cargo.lock | 51 +++------------------------ Cargo.toml | 9 ++--- src/commands/dry_run.rs | 25 +++++--------- src/commands/monitor.rs | 25 +++++++------- src/error.rs | 8 ++--- src/helpers.rs | 28 --------------- src/lib.rs | 1 + src/main.rs | 1 + src/opt.rs | 3 +- src/prelude.rs | 16 +++++---- src/signer.rs | 76 +++++++++++++++++++++++++++++++++++++++++ 11 files changed, 122 insertions(+), 121 deletions(-) create mode 100644 src/signer.rs diff --git a/Cargo.lock b/Cargo.lock index f50a8f416..cb93540d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1979,7 +1979,6 @@ version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ea1015b5a70616b688dc230cfe50c8af89d972cb132d5a622814d29773b10b9" dependencies = [ - "rand 0.8.5", "rand_core 0.6.4", ] @@ -3201,12 +3200,10 @@ dependencies = [ "scale-value", "serde", "serde_json", - "sp-core", "sp-npos-elections", "sp-runtime", "sp-storage", "subxt", - "subxt-signer", "thiserror", "tokio", "tracing-subscriber 0.3.18", @@ -3931,16 +3928,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" dependencies = [ - "secp256k1-sys 0.6.1", -] - -[[package]] -name = "secp256k1" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2acea373acb8c21ecb5a23741452acd2593ed44ee3d343e72baaa143bc89d0d5" -dependencies = [ - "secp256k1-sys 0.9.1", + "secp256k1-sys", ] [[package]] @@ -3952,15 +3940,6 @@ dependencies = [ "cc", ] -[[package]] -name = "secp256k1-sys" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dd97a086ec737e30053fd5c46f097465d25bb81dd3608825f65298c4c98be83" -dependencies = [ - "cc", -] - [[package]] name = "secrecy" version = "0.8.0" @@ -4409,7 +4388,7 @@ dependencies = [ "regex", "scale-info", "schnorrkel 0.9.1", - "secp256k1 0.24.3", + "secp256k1", "secrecy", "serde", "sp-core-hashing", @@ -4513,7 +4492,7 @@ dependencies = [ "log", "parity-scale-codec", "rustversion", - "secp256k1 0.24.3", + "secp256k1", "sp-core", "sp-externalities", "sp-keystore", @@ -4902,7 +4881,9 @@ dependencies = [ "scale-value", "serde", "serde_json", + "sp-core", "sp-core-hashing", + "sp-runtime", "subxt-lightclient", "subxt-macro", "subxt-metadata", @@ -4973,28 +4954,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "subxt-signer" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05cc81461f8262b62acf7bfe178a45f22a40336a6ace6a3093bd3e22d7012ba3" -dependencies = [ - "bip39", - "hex", - "hmac 0.12.1", - "parity-scale-codec", - "pbkdf2 0.12.2", - "regex", - "schnorrkel 0.11.4", - "secp256k1 0.28.0", - "secrecy", - "sha2 0.10.8", - "sp-core-hashing", - "subxt", - "thiserror", - "zeroize", -] - [[package]] name = "syn" version = "1.0.109" diff --git a/Cargo.toml b/Cargo.toml index e9936ad5e..798306b39 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,19 +25,14 @@ pin-project-lite = "0.2" # subxt scale-value = "0.13" -subxt = "0.33" -subxt-signer = { version = "0.33", features = ["subxt"] } +subxt = { version = "0.33", features = ["substrate-compat"] } # polkadot-sdk frame-election-provider-support = "26.0.0" pallet-election-provider-multi-phase = "25.0.0" -frame-support = "26.0.0" sp-npos-elections = "24.0.0" -# Both `sp-runtime` and `sp-core` has plenty of dependencies -# and because `pallet-election-provider-multi-phase` is depending -# on them it's not much we can do it about it. +frame-support = "26.0.0" sp-runtime = "29.0.0" -sp-core = "26.0.0" # prometheus prometheus = "0.13" diff --git a/src/commands/dry_run.rs b/src/commands/dry_run.rs index 77bd1a6bf..c3b695a76 100644 --- a/src/commands/dry_run.rs +++ b/src/commands/dry_run.rs @@ -16,18 +16,14 @@ //! The dry-run command. +use pallet_election_provider_multi_phase::RawSolution; + use crate::{ - client::Client, - epm, - error::Error, - helpers::{signer_from_seed_or_path, storage_at}, - opt::Solver, - prelude::*, - static_types, + client::Client, epm, error::Error, helpers::storage_at, opt::Solver, prelude::*, + signer::Signer, static_types, }; use clap::Parser; use codec::Encode; -use pallet_election_provider_multi_phase::RawSolution; #[derive(Debug, Clone, Parser)] #[cfg_attr(test, derive(PartialEq))] @@ -103,22 +99,19 @@ where // If an account seed or path is provided, then do a dry run to the node. Otherwise, // we've logged the solution above and we do nothing else. if let Some(seed_or_path) = &config.seed_or_path { - let signer = signer_from_seed_or_path(seed_or_path)?; + let signer = Signer::new(seed_or_path)?; let account_info = storage - .fetch(&runtime::storage().system().account(signer.public_key().to_account_id())) + .fetch(&runtime::storage().system().account(signer.account_id())) .await? .ok_or(Error::AccountDoesNotExists)?; - log::info!(target: LOG_TARGET, "Loaded account {}, {:?}", signer.public_key().to_account_id(), account_info); + log::info!(target: LOG_TARGET, "Loaded account {}, {:?}", signer, account_info); - let nonce = client - .rpc() - .system_account_next_index(&signer.public_key().to_account_id()) - .await?; + let nonce = client.rpc().system_account_next_index(signer.account_id()).await?; let tx = epm::signed_solution(raw_solution)?; let xt = client.chain_api().tx().create_signed_with_nonce( &tx, - &signer, + &*signer, nonce, Default::default(), )?; diff --git a/src/commands/monitor.rs b/src/commands/monitor.rs index ccac98b40..754f7e28e 100644 --- a/src/commands/monitor.rs +++ b/src/commands/monitor.rs @@ -18,10 +18,12 @@ use crate::{ client::Client, epm, error::Error, - helpers::{kill_main_task_if_critical_err, signer_from_seed_or_path, TimedFuture}, + helpers::{kill_main_task_if_critical_err, TimedFuture}, opt::Solver, prelude::*, - prometheus, static_types, + prometheus, + signer::Signer, + static_types, }; use clap::Parser; use codec::{Decode, Encode}; @@ -169,10 +171,10 @@ where + 'static, T::Solution: Send, { - let signer = signer_from_seed_or_path(&config.seed_or_path)?; + let signer = Signer::new(&config.seed_or_path)?; let account_info = { - let addr = runtime::storage().system().account(signer.public_key().to_account_id()); + let addr = runtime::storage().system().account(signer.account_id()); client .chain_api() .storage() @@ -183,7 +185,7 @@ where .ok_or(Error::AccountDoesNotExists)? }; - log::info!(target: LOG_TARGET, "Loaded account {}, {:?}", signer.public_key().to_account_id(), account_info); + log::info!(target: LOG_TARGET, "Loaded account {}, {:?}", signer, account_info); if config.dry_run { // if we want to try-run, ensure the node supports it. @@ -241,7 +243,7 @@ where .storage() .at_latest() .await? - .fetch(&runtime::storage().system().account(signer.public_key().to_account_id())) + .fetch(&runtime::storage().system().account(signer.account_id())) .await? .ok_or(Error::AccountDoesNotExists)?; // this is lossy but fine for now. @@ -270,10 +272,7 @@ where // NOTE: as we try to send at each block then the nonce is used guard against // submitting twice. Because once a solution has been accepted on chain // the "next transaction" at a later block but with the same nonce will be rejected - let nonce = client - .rpc() - .system_account_next_index(&signer.public_key().to_account_id()) - .await?; + let nonce = client.rpc().system_account_next_index(signer.account_id()).await?; ensure_signed_phase(client.chain_api(), block_hash) .inspect_err(|e| { @@ -302,7 +301,7 @@ where ensure_no_previous_solution::( client.chain_api(), block_hash, - &signer.public_key().0.into(), + &signer.account_id().0.into(), ) .inspect_err(|e| { log::debug!( @@ -384,7 +383,7 @@ where ensure_no_previous_solution::( client.chain_api(), best_head, - &signer.public_key().0.into(), + &signer.account_id().0.into(), ) .inspect_err(|e| { log::debug!( @@ -544,7 +543,7 @@ async fn submit_and_watch_solution( client .chain_api() .tx() - .create_signed_with_nonce(&tx, &signer, nonce as u64, xt_cfg)?; + .create_signed_with_nonce(&tx, &*signer, nonce as u64, xt_cfg)?; if dry_run { let dry_run_bytes = client.rpc().dry_run(xt.encoded(), None).await?; diff --git a/src/error.rs b/src/error.rs index 51eedee05..0ec98aa93 100644 --- a/src/error.rs +++ b/src/error.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . +use crate::prelude::*; + #[derive(thiserror::Error, Debug)] pub enum Error { #[error("Failed to parse log directive: `{0}ยด")] @@ -24,10 +26,8 @@ pub enum Error { RpcError(#[from] jsonrpsee::core::Error), #[error("subxt error: `{0}`")] Subxt(#[from] subxt::Error), - #[error("SecretUri error: `{0}`")] - SecretUri(#[from] subxt_signer::SecretUriError), - #[error("Keypair error: `{0}`")] - Keypair(#[from] subxt_signer::sr25519::Error), + #[error("Crypto error: `{0:?}`")] + Crypto(sp_core::crypto::SecretStringError), #[error("Codec error: `{0}`")] Codec(#[from] codec::Error), #[error("Incorrect phase")] diff --git a/src/helpers.rs b/src/helpers.rs index 37795f7c0..50a29b955 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -23,7 +23,6 @@ use serde::Deserialize; use std::{ future::Future, pin::Pin, - str::FromStr, task::{Context, Poll}, time::{Duration, Instant}, }; @@ -153,30 +152,3 @@ pub async fn storage_at( api.storage().at_latest().await.map_err(Into::into) } } - -pub fn signer_from_seed_or_path(seed_or_path: &str) -> Result { - let seed_or_path = seed_or_path.trim(); - - let unchecked_secret = match std::fs::read(seed_or_path) { - Ok(s) => String::from_utf8(s).map_err(|e| Error::Other(e.to_string()))?, - Err(_) => seed_or_path.to_string(), - }; - - let secret = subxt_signer::SecretUri::from_str(&unchecked_secret)?; - Signer::from_uri(&secret).map_err(Into::into) -} - -#[cfg(test)] -#[test] -fn signer_parsing_works() { - assert!(signer_from_seed_or_path("//Alice").is_ok()); - assert!(signer_from_seed_or_path( - "0x1122334455667788112233445566778811223344556677881122334455667788" - ) - .is_ok()); - assert!(signer_from_seed_or_path( - "1122334455667788112233445566778811223344556677881122334455667788" - ) - .is_err()); - assert!(signer_from_seed_or_path("0x0").is_err()); -} diff --git a/src/lib.rs b/src/lib.rs index dc511219d..a78d9600c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,4 +24,5 @@ pub mod helpers; pub mod opt; pub mod prelude; pub mod prometheus; +pub mod signer; pub mod static_types; diff --git a/src/main.rs b/src/main.rs index 934a8ded3..2dde7e52e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,6 +36,7 @@ mod helpers; mod opt; mod prelude; mod prometheus; +mod signer; mod static_types; use clap::Parser; diff --git a/src/opt.rs b/src/opt.rs index 3bac15e4a..86a819428 100644 --- a/src/opt.rs +++ b/src/opt.rs @@ -17,8 +17,9 @@ use crate::error::Error; use clap::*; -use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; use sp_npos_elections::BalancingConfig; +use sp_runtime::DeserializeOwned; use std::{collections::HashMap, fmt, str::FromStr}; use subxt::backend::legacy::rpc_methods as subxt_rpc; diff --git a/src/prelude.rs b/src/prelude.rs index 222503efd..9d1e8d0d6 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -22,18 +22,17 @@ // re-exports. pub use pallet_election_provider_multi_phase::{Miner, MinerConfig}; +pub use subxt::ext::sp_core; /// The account id type. -pub type AccountId = subxt::utils::AccountId32; +pub type AccountId = sp_runtime::AccountId32; /// The header type. We re-export it here, but we can easily get it from block as well. pub type Header = subxt::config::substrate::SubstrateHeader; /// The header type. We re-export it here, but we can easily get it from block as well. -pub type Hash = subxt::utils::H256; +pub type Hash = sp_core::H256; /// Balance type pub type Balance = u128; -/// Signer type -/// The key pair type being used. We "strongly" assume sr25519 for simplicity. -pub type Signer = subxt_signer::sr25519::Keypair; +pub use subxt::ext::sp_runtime::traits::{Block as BlockT, Header as HeaderT}; /// Default URI to connect to. /// @@ -43,12 +42,17 @@ pub const DEFAULT_URI: &str = "ws://127.0.0.1:9944"; pub const DEFAULT_PROMETHEUS_PORT: u16 = 9999; /// The logging target. pub const LOG_TARGET: &str = "polkadot-staking-miner"; + +/// The key pair type being used. We "strongly" assume sr25519 for simplicity. +pub type Pair = sp_core::sr25519::Pair; + /// The accuracy that we use for election computation. pub type Accuracy = sp_runtime::Perbill; -/// Rpc client. + pub type RpcClient = subxt::backend::legacy::LegacyRpcMethods; /// Subxt client used by the staking miner on all chains. pub type ChainClient = subxt::OnlineClient; + /// Config used by the staking-miner pub type Config = subxt::PolkadotConfig; diff --git a/src/signer.rs b/src/signer.rs new file mode 100644 index 000000000..9b4ba75ce --- /dev/null +++ b/src/signer.rs @@ -0,0 +1,76 @@ +// Copyright 2021-2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Wrappers around creating a signer account. + +use crate::{error::Error, prelude::*}; +use sp_core::Pair as _; +use subxt::tx::Signer as _; + +// A signer type, parameterized for using with `subxt`. +pub type PairSigner = subxt::tx::PairSigner; + +// Signer wrapper. +// +// NOTE: both `Pair` and `PairSigner` are stored here so it can be cloned +// which is hack around that PairSigner !Clone. +pub struct Signer { + pair: Pair, + signer: PairSigner, +} + +impl std::fmt::Display for Signer { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self.signer.address()) + } +} + +impl Clone for Signer { + fn clone(&self) -> Self { + Self { pair: self.pair.clone(), signer: PairSigner::new(self.pair.clone()) } + } +} + +impl Signer { + pub fn new(mut seed_or_path: &str) -> Result { + seed_or_path = seed_or_path.trim(); + + let seed = match std::fs::read(seed_or_path) { + Ok(s) => String::from_utf8(s).map_err(|e| Error::Other(e.to_string()))?, + Err(_) => seed_or_path.to_string(), + }; + + let seed = seed.trim(); + let pair = Pair::from_string(seed, None).map_err(Error::Crypto)?; + let signer = PairSigner::new(pair.clone()); + + Ok(Self { pair, signer }) + } +} + +impl std::ops::Deref for Signer { + type Target = PairSigner; + + fn deref(&self) -> &Self::Target { + &self.signer + } +} + +impl std::ops::DerefMut for Signer { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.signer + } +}