Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,161 changes: 1,211 additions & 950 deletions Cargo.lock

Large diffs are not rendered by default.

21 changes: 11 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,19 @@ tokio = { version = "1.25", features = ["macros", "rt-multi-thread", "sync", "si
pin-project-lite = "0.2"

# subxt
subxt = "0.25.0"
subxt = "0.27.1"
scale-value = "0.6.0"

# substrate
sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" }
frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" }
frame-election-provider-support = { git = "https://github.com/paritytech/substrate", branch = "master" }
pallet-election-provider-multi-phase = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-npos-elections = { git = "https://github.com/paritytech/substrate", branch = "master" }
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-version = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-io = "17.0.0"
frame-system = "16.0.0"
frame-election-provider-support = "16.0.0"
pallet-election-provider-multi-phase = "15.0.0"
sp-npos-elections = "14.0.0"
frame-support = "16.0.0"
sp-version = "16.0.0"
sp-core = "16.0.0"
sp-runtime = "18.0.0"

# prometheus
prometheus = "0.13"
Expand All @@ -40,7 +41,7 @@ once_cell = "1.17"

[dev-dependencies]
assert_cmd = "2.0"
sp-storage = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-storage = "11.0.0"

[features]
default = ["polkadot", "kusama", "westend"]
Expand Down
15 changes: 9 additions & 6 deletions src/dry_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ where

let account_info = api
.storage()
.fetch(&runtime::storage().system().account(signer.account_id()), None)
.at(None)
.await?
.fetch(&runtime::storage().system().account(signer.account_id()))
.await?
.ok_or(Error::AccountDoesNotExists)?;

Expand All @@ -44,9 +46,11 @@ where

let round = api
.storage()
.fetch(&runtime::storage().election_provider_multi_phase().round(), config.at)
.at(config.at)
.await?
.fetch(&runtime::storage().election_provider_multi_phase().round())
.await?
.expect("The round must exist");
.unwrap_or(1);

let raw_solution = RawSolution { solution, score, round };
let nonce = api.rpc().system_account_next_index(signer.account_id()).await?;
Expand All @@ -68,8 +72,7 @@ where
log::info!(target: LOG_TARGET, "dry-run outcome is {:?}", outcome);

match outcome {
Ok(Ok(())) => Ok(()),
Ok(Err(e)) => Err(Error::Other(format!("{:?}", e))),
Err(e) => Err(Error::Other(format!("{:?}", e))),
Ok(()) => Ok(()),
Err(e) => Err(Error::Other(format!("{e:?}"))),
}
}
18 changes: 12 additions & 6 deletions src/epm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,14 @@ impl EpmConstant {
Self { epm: EPM_PALLET_NAME, constant }
}

const fn to_parts(&self) -> (&'static str, &'static str) {
const fn to_parts(self) -> (&'static str, &'static str) {
(self.epm, self.constant)
}
}

fn to_string(&self) -> String {
format!("{}::{}", self.epm, self.constant)
impl std::fmt::Display for EpmConstant {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("{}::{}", self.epm, self.constant))
}
}

Expand Down Expand Up @@ -138,7 +140,7 @@ pub async fn signed_submission_at<S: NposSolution + Decode + TypeInfo + 'static>
let scale_idx = Value::u128(idx as u128);
let addr = subxt::dynamic::storage(EPM_PALLET_NAME, "SignedSubmissionsMap", vec![scale_idx]);

match api.storage().fetch(&addr, Some(at)).await {
match api.storage().at(Some(at)).await?.fetch(&addr).await {
Ok(Some(val)) => {
let submissions = Decode::decode(&mut val.encoded())?;
Ok(Some(submissions))
Expand All @@ -164,13 +166,17 @@ where
{
let RoundSnapshot { voters, targets } = api
.storage()
.fetch(&runtime::storage().election_provider_multi_phase().snapshot(), hash)
.at(hash)
.await?
.fetch(&runtime::storage().election_provider_multi_phase().snapshot())
.await?
.unwrap_or_default();

let desired_targets = api
.storage()
.fetch(&runtime::storage().election_provider_multi_phase().desired_targets(), hash)
.at(hash)
.await?
.fetch(&runtime::storage().election_provider_multi_phase().desired_targets())
.await?
.unwrap_or_default();

Expand Down
2 changes: 0 additions & 2 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.

use crate::prelude::sp_core;

#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("Failed to parse log directive: `{0}´")]
Expand Down
4 changes: 2 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ async fn run_command(

/// Runs until the RPC connection fails or updating the metadata failed.
async fn runtime_upgrade_task(api: SubxtClient, tx: oneshot::Sender<Error>) {
let updater = api.subscribe_to_updates();
let updater = api.updater();

let mut update_stream = match updater.runtime_updates().await {
Ok(u) => u,
Expand Down Expand Up @@ -184,7 +184,7 @@ async fn runtime_upgrade_task(api: SubxtClient, tx: oneshot::Sender<Error>) {
match updater.apply_update(update) {
Ok(()) => {
if let Err(e) = epm::update_metadata_constants(&api).await {
let _ = tx.send(e.into());
let _ = tx.send(e);
return
}
prometheus::on_runtime_upgrade();
Expand Down
68 changes: 39 additions & 29 deletions src/monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ use jsonrpsee::{core::Error as JsonRpseeError, types::error::CallError};
use pallet_election_provider_multi_phase::{RawSolution, SolutionOf};
use sp_runtime::Perbill;
use std::sync::Arc;
use subxt::{error::RpcError, rpc::Subscription, tx::TxStatus, Error as SubxtError};
use subxt::{
config::Header as _, error::RpcError, rpc::Subscription, tx::TxStatus, Error as SubxtError,
};
use tokio::sync::Mutex;

pub async fn monitor_cmd<T>(api: SubxtClient, config: MonitorConfig) -> Result<(), Error>
Expand All @@ -45,7 +47,12 @@ where

let account_info = {
let addr = runtime::storage().system().account(signer.account_id());
api.storage().fetch(&addr, None).await?.ok_or(Error::AccountDoesNotExists)?
api.storage()
.at(None)
.await?
.fetch(&addr)
.await?
.ok_or(Error::AccountDoesNotExists)?
};

log::info!(target: LOG_TARGET, "Loaded account {}, {:?}", signer, account_info);
Expand Down Expand Up @@ -97,10 +104,13 @@ where
submit_lock.clone(),
));

let account_info = {
let addr = runtime::storage().system().account(signer.account_id());
api.storage().fetch(&addr, None).await?.ok_or(Error::AccountDoesNotExists)?
};
let account_info = api
.storage()
.at(None)
.await?
.fetch(&runtime::storage().system().account(signer.account_id()))
.await?
.ok_or(Error::AccountDoesNotExists)?;
// this is lossy but fine for now.
prometheus::set_balance(account_info.data.free as f64);
}
Expand Down Expand Up @@ -206,15 +216,19 @@ async fn mine_and_submit_solution<T>(
return
}

let round = match api
.storage()
.fetch(&runtime::storage().election_provider_multi_phase().round(), Some(hash))
.await
{
Ok(Some(round)) => round,
// Default round is 1
// https://github.com/paritytech/substrate/blob/49b06901eb65f2c61ff0934d66987fd955d5b8f5/frame/election-provider-multi-phase/src/lib.rs#L1188
Ok(None) => 1,
let fut = async {
api.storage()
.at(Some(hash))
.await?
.fetch(&runtime::storage().election_provider_multi_phase().round())
.await
// Default round is 1
// https://github.com/paritytech/substrate/blob/49b06901eb65f2c61ff0934d66987fd955d5b8f5/frame/election-provider-multi-phase/src/lib.rs#L1188
.map(|r| r.unwrap_or(1))
};

let round = match fut.await {
Ok(round) => round,
Err(e) => {
log::error!(target: LOG_TARGET, "Mining solution failed: {:?}", e);
kill_main_task_if_critical_err(&tx, e.into());
Expand Down Expand Up @@ -371,15 +385,12 @@ async fn ensure_signed_phase(api: &SubxtClient, hash: Hash) -> Result<(), Error>
use pallet_election_provider_multi_phase::Phase;

let addr = runtime::storage().election_provider_multi_phase().current_phase();
let res = api.storage().fetch(&addr, Some(hash)).await;

match res {
Ok(Some(Phase::Signed)) => Ok(()),
Ok(Some(_)) => Err(Error::IncorrectPhase),
// Default phase is None
// https://github.com/paritytech/substrate/blob/49b06901eb65f2c61ff0934d66987fd955d5b8f5/frame/election-provider-multi-phase/src/lib.rs#L1193
Ok(None) => Err(Error::IncorrectPhase),
Err(e) => Err(e.into()),
let phase = api.storage().at(Some(hash)).await?.fetch(&addr).await?;

if let Some(Phase::Signed) = phase {
Ok(())
} else {
Err(Error::IncorrectPhase)
}
}

Expand All @@ -393,7 +404,7 @@ where
T: NposSolution + scale_info::TypeInfo + Decode + 'static,
{
let addr = runtime::storage().election_provider_multi_phase().signed_submission_indices();
let indices = api.storage().fetch_or_default(&addr, Some(at)).await?;
let indices = api.storage().at(Some(at)).await?.fetch_or_default(&addr).await?;

for (_score, _, idx) in indices.0 {
let submission = epm::signed_submission_at::<T>(idx, at, api).await?;
Expand All @@ -420,7 +431,7 @@ async fn ensure_solution_passes_strategy(
}

let addr = runtime::storage().election_provider_multi_phase().signed_submission_indices();
let indices = api.storage().fetch_or_default(&addr, Some(at)).await?;
let indices = api.storage().at(Some(at)).await?.fetch_or_default(&addr).await?;

log::debug!(target: LOG_TARGET, "submitted solutions: {:?}", indices.0);

Expand Down Expand Up @@ -452,9 +463,8 @@ async fn submit_and_watch_solution<T: MinerConfig + Send + Sync + 'static>(

if dry_run {
match api.rpc().dry_run(xt.encoded(), None).await? {
Ok(Ok(())) => (),
Ok(Err(e)) => return Err(Error::TransactionRejected(format!("{:?}", e))),
Err(e) => return Err(Error::TransactionRejected(e.to_string())),
Ok(()) => (),
Err(e) => return Err(Error::TransactionRejected(format!("{e:?}"))),
};
}

Expand Down
4 changes: 2 additions & 2 deletions src/opt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,10 @@ impl std::str::FromStr for Chain {
}
}

impl TryFrom<subxt::rpc::RuntimeVersion> for Chain {
impl TryFrom<subxt::rpc::types::RuntimeVersion> for Chain {
type Error = Error;

fn try_from(rv: subxt::rpc::RuntimeVersion) -> Result<Self, Error> {
fn try_from(rv: subxt::rpc::types::RuntimeVersion) -> Result<Self, Error> {
let json = rv
.other
.get("specName")
Expand Down
45 changes: 22 additions & 23 deletions src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,16 @@ pub use pallet_election_provider_multi_phase::{Miner, MinerConfig};
use once_cell::sync::OnceCell;

/// The account id type.
pub type AccountId = subxt::ext::sp_core::crypto::AccountId32;
pub type AccountId = subxt::utils::AccountId32;
/// The header type. We re-export it here, but we can easily get it from block as well.
pub type Header =
subxt::ext::sp_runtime::generic::Header<u32, subxt::ext::sp_runtime::traits::BlakeTwo256>;
subxt::config::substrate::SubstrateHeader<u32, subxt::config::substrate::BlakeTwo256>;
/// The header type. We re-export it here, but we can easily get it from block as well.
pub type Hash = sp_core::H256;
/// Balance type
pub type Balance = u128;

pub use subxt::ext::{
sp_core,
sp_runtime::traits::{Block as BlockT, Header as HeaderT},
};
pub use sp_runtime::traits::{Block as BlockT, Header as HeaderT};

/// Default URI to connect to.
///
Expand All @@ -58,7 +55,7 @@ pub type Pair = sp_core::sr25519::Pair;
pub type Accuracy = sp_runtime::Perbill;

/// Extrinsics params used on all chains.
pub use subxt::tx::PolkadotExtrinsicParamsBuilder as ExtrinsicParams;
pub use subxt::config::polkadot::PolkadotExtrinsicParamsBuilder as ExtrinsicParams;

/// Subxt client used by the staking miner on all chains.
pub type SubxtClient = subxt::OnlineClient<Config>;
Expand All @@ -76,23 +73,25 @@ pub type SignedSubmission<S> =
derive_for_type(
type = "pallet_election_provider_multi_phase::RoundSnapshot",
derive = "Default"
),
substitute_type(type = "sp_arithmetic::per_things::PerU16", with = "::sp_runtime::PerU16"),
substitute_type(
type = "pallet_election_provider_multi_phase::RawSolution",
with = "::pallet_election_provider_multi_phase::RawSolution"
),
substitute_type(
type = "sp_npos_elections::ElectionScore",
with = "::sp_npos_elections::ElectionScore"
),
substitute_type(
type = "pallet_election_provider_multi_phase::Phase",
with = "::pallet_election_provider_multi_phase::Phase"
),
substitute_type(
type = "pallet_election_provider_multi_phase::SolutionOrSnapshotSize",
with = "::pallet_election_provider_multi_phase::SolutionOrSnapshotSize"
)
)]
pub mod runtime {
#[subxt(substitute_type = "sp_arithmetic::per_things::PerU16")]
use ::sp_runtime::PerU16;

#[subxt(substitute_type = "pallet_election_provider_multi_phase::RawSolution")]
use ::pallet_election_provider_multi_phase::RawSolution;

#[subxt(substitute_type = "sp_npos_elections::ElectionScore")]
use ::sp_npos_elections::ElectionScore;

#[subxt(substitute_type = "pallet_election_provider_multi_phase::Phase")]
use ::pallet_election_provider_multi_phase::Phase;

#[subxt(substitute_type = "pallet_election_provider_multi_phase::SolutionOrSnapshotSize")]
use ::pallet_election_provider_multi_phase::SolutionOrSnapshotSize;
}
pub mod runtime {}

pub static SHARED_CLIENT: OnceCell<SubxtClient> = OnceCell::new();
2 changes: 1 addition & 1 deletion src/prometheus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ mod hidden {
}

pub fn observe_submit_and_watch_duration(time: f64) {
SUBMIT_SOLUTION_AND_WATCH_DURATION.set(time as f64);
SUBMIT_SOLUTION_AND_WATCH_DURATION.set(time);
}

pub fn observe_mined_solution_duration(time: f64) {
Expand Down
2 changes: 1 addition & 1 deletion src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub struct Signer {

impl std::fmt::Display for Signer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.signer.address())
write!(f, "{:?}", self.signer.address())
}
}

Expand Down
3 changes: 2 additions & 1 deletion tests/monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub mod common;
use assert_cmd::cargo::cargo_bin;
use codec::Decode;
use common::{init_logger, run_polkadot_node, KillChildOnDrop};
use sp_core::Bytes;
use sp_storage::StorageChangeSet;
use staking_miner::{
opt::Chain,
Expand All @@ -15,7 +16,7 @@ use std::{
process,
time::{Duration, Instant},
};
use subxt::{ext::sp_core::Bytes, rpc::rpc_params};
use subxt::rpc::rpc_params;
use tokio::time::timeout;

const MAX_DURATION_FOR_SUBMIT_SOLUTION: Duration = Duration::from_secs(60 * 15);
Expand Down