fix: remove staking-score from relay chain, fix CI quick-checks
- Remove pezpallet_staking_score from relay chain runtime (noter model lives on People Chain only) - Update welati mock to current staking-score Config trait - Fix staking-score feature propagation (zepter: std, runtime-benchmarks) - Format vendor subxt example files (rustfmt) - Regenerate umbrella crate - Update CRITICAL_STATE.md with noter delegation status
This commit is contained in:
Generated
-1
@@ -14932,7 +14932,6 @@ dependencies = [
|
||||
"pezpallet-session-benchmarking",
|
||||
"pezpallet-staking",
|
||||
"pezpallet-staking-runtime-api",
|
||||
"pezpallet-staking-score",
|
||||
"pezpallet-state-trie-migration",
|
||||
"pezpallet-sudo",
|
||||
"pezpallet-timestamp",
|
||||
|
||||
@@ -27,12 +27,13 @@ serde = { version = "1.0.197", default-features = false, features = [
|
||||
# PezkuwiChain primitives
|
||||
pezkuwi-primitives = { workspace = true, default-features = false }
|
||||
|
||||
# dev / test dependencies (also used as optional for feature propagation)
|
||||
pezpallet-balances = { workspace = true, default-features = false, optional = true }
|
||||
pezsp-io = { workspace = true, default-features = false, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
pezframe-support = { workspace = true, features = ["std"] }
|
||||
pezframe-system = { workspace = true, features = ["std"] }
|
||||
pezpallet-balances = { workspace = true, features = ["std"] }
|
||||
pezsp-io = { workspace = true, features = ["std"] }
|
||||
pezsp-runtime = { workspace = true, features = ["std"] }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
@@ -41,7 +42,9 @@ std = [
|
||||
"pezframe-benchmarking?/std",
|
||||
"pezframe-support/std",
|
||||
"pezframe-system/std",
|
||||
"pezpallet-balances?/std",
|
||||
"pezkuwi-primitives/std",
|
||||
"pezsp-io?/std",
|
||||
"pezsp-runtime/std",
|
||||
"pezsp-std/std",
|
||||
"scale-info/std",
|
||||
@@ -53,6 +56,8 @@ runtime-benchmarks = [
|
||||
"pezframe-system/runtime-benchmarks",
|
||||
"pezkuwi-primitives/runtime-benchmarks",
|
||||
"pezsp-runtime/runtime-benchmarks",
|
||||
"pezpallet-balances/runtime-benchmarks",
|
||||
"pezsp-io/runtime-benchmarks",
|
||||
]
|
||||
try-runtime = [
|
||||
"pezframe-benchmarking?/try-runtime",
|
||||
@@ -60,6 +65,7 @@ try-runtime = [
|
||||
"pezframe-system/try-runtime",
|
||||
"pezkuwi-primitives/try-runtime",
|
||||
"pezsp-runtime/try-runtime",
|
||||
"pezpallet-balances?/try-runtime"
|
||||
]
|
||||
serde = [
|
||||
"codec/serde",
|
||||
|
||||
@@ -282,25 +282,12 @@ impl pezpallet_identity_kyc::Config for Test {
|
||||
type DefaultReferrer = DefaultReferrerKyc;
|
||||
}
|
||||
|
||||
// Mock StakingInfo provider - SADECE BİR KEZ TANIMLA
|
||||
pub struct MockStakingInfo;
|
||||
impl pezpallet_staking_score::StakingInfoProvider<AccountId, Balance> for MockStakingInfo {
|
||||
fn get_staking_details(
|
||||
_account: &AccountId,
|
||||
) -> Option<pezpallet_staking_score::StakingDetails<Balance>> {
|
||||
Some(pezpallet_staking_score::StakingDetails {
|
||||
staked_amount: 1000u128,
|
||||
nominations_count: 0,
|
||||
unlocking_chunks_count: 0,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Staking Score Configuration
|
||||
impl pezpallet_staking_score::Config for Test {
|
||||
type WeightInfo = ();
|
||||
type Balance = Balance;
|
||||
type StakingInfo = MockStakingInfo;
|
||||
type OnStakingUpdate = ();
|
||||
type WeightInfo = ();
|
||||
type NoterChecker = ();
|
||||
}
|
||||
|
||||
// Referral Configuration
|
||||
|
||||
@@ -111,7 +111,6 @@ pezkuwi-runtime-teyrchains = { workspace = true }
|
||||
pezkuwi-teyrchain-primitives = { workspace = true }
|
||||
|
||||
# Custom Pezkuwi Pallets
|
||||
pezpallet-staking-score = { workspace = true }
|
||||
pezpallet-validator-pool = { workspace = true }
|
||||
|
||||
xcm = { workspace = true }
|
||||
@@ -184,7 +183,6 @@ std = [
|
||||
"pezpallet-session-benchmarking?/std",
|
||||
"pezpallet-session/std",
|
||||
"pezpallet-staking-runtime-api/std",
|
||||
"pezpallet-staking-score/std",
|
||||
"pezpallet-staking/std",
|
||||
"pezpallet-state-trie-migration/std",
|
||||
"pezpallet-sudo/std",
|
||||
@@ -277,7 +275,6 @@ runtime-benchmarks = [
|
||||
"pezpallet-session-benchmarking/runtime-benchmarks",
|
||||
"pezpallet-session/runtime-benchmarks",
|
||||
"pezpallet-staking-runtime-api/runtime-benchmarks",
|
||||
"pezpallet-staking-score/runtime-benchmarks",
|
||||
"pezpallet-staking/runtime-benchmarks",
|
||||
"pezpallet-state-trie-migration/runtime-benchmarks",
|
||||
"pezpallet-sudo/runtime-benchmarks",
|
||||
@@ -360,7 +357,6 @@ try-runtime = [
|
||||
"pezpallet-scheduler/try-runtime",
|
||||
"pezpallet-session-benchmarking?/try-runtime",
|
||||
"pezpallet-session/try-runtime",
|
||||
"pezpallet-staking-score/try-runtime",
|
||||
"pezpallet-staking/try-runtime",
|
||||
"pezpallet-state-trie-migration/try-runtime",
|
||||
"pezpallet-sudo/try-runtime",
|
||||
|
||||
@@ -565,40 +565,6 @@ impl pezpallet_staking::Config for Runtime {
|
||||
type BenchmarkingConfig = PezkuwiStakingBenchmarkingConfig;
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// STAKING SCORE CONFIGURATION
|
||||
// =====================================================
|
||||
|
||||
/// Relay Chain StakingInfoProvider - reads directly from pezpallet_staking
|
||||
/// This is the REAL implementation that accesses actual staking data
|
||||
pub struct RelayStakingInfoProvider;
|
||||
|
||||
impl pezpallet_staking_score::StakingInfoProvider<AccountId, Balance> for RelayStakingInfoProvider {
|
||||
fn get_staking_details(
|
||||
who: &AccountId,
|
||||
) -> Option<pezpallet_staking_score::StakingDetails<Balance>> {
|
||||
// Get staking ledger from pezpallet_staking
|
||||
let ledger = pezpallet_staking::Ledger::<Runtime>::get(who)?;
|
||||
|
||||
// Get nominations if any
|
||||
let nominations_count = pezpallet_staking::Nominators::<Runtime>::get(who)
|
||||
.map(|n| n.targets.len() as u32)
|
||||
.unwrap_or(0);
|
||||
|
||||
Some(pezpallet_staking_score::StakingDetails {
|
||||
staked_amount: ledger.active,
|
||||
nominations_count,
|
||||
unlocking_chunks_count: ledger.unlocking.len() as u32,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl pezpallet_staking_score::Config for Runtime {
|
||||
type Balance = Balance;
|
||||
type StakingInfo = RelayStakingInfoProvider;
|
||||
type WeightInfo = pezpallet_staking_score::weights::BizinikiwiWeight<Runtime>;
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// FAST UNSTAKE CONFIGURATION
|
||||
// =====================================================
|
||||
@@ -1605,9 +1571,6 @@ construct_runtime! {
|
||||
// TNPoS Validator Pool - Shadow Mode (runs parallel to NPoS)
|
||||
ValidatorPool: pezpallet_validator_pool = 91,
|
||||
|
||||
// Staking Score - Time-weighted staking reputation score
|
||||
StakingScore: pezpallet_staking_score = 92,
|
||||
|
||||
// Root testing pezpallet.
|
||||
RootTesting: pezpallet_root_testing = 249,
|
||||
|
||||
@@ -1859,7 +1822,6 @@ mod benches {
|
||||
[pezpallet_whitelist, Whitelist]
|
||||
// Pezkuwichain Custom Pallets
|
||||
[pezpallet_validator_pool, ValidatorPool]
|
||||
[pezpallet_staking_score, StakingScore]
|
||||
// XCM
|
||||
[pezpallet_xcm, PalletXcmExtrinsicsBenchmark::<Runtime>]
|
||||
[pezpallet_xcm_benchmarks::fungible, pezpallet_xcm_benchmarks::fungible::Pezpallet::<Runtime>]
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
[package]
|
||||
name = "pezkuwi-sdk"
|
||||
version = "0.0.0"
|
||||
description = "Pezkuwi SDK umbrella crate."
|
||||
license = "Apache-2.0"
|
||||
|
||||
|
||||
+13
-40
@@ -23,7 +23,7 @@ const ASSET_HUB_PARA_ID: u32 = 1000;
|
||||
|
||||
// NominationPools pallet index on Asset Hub
|
||||
const NOM_POOLS_PALLET_INDEX: u8 = 81; // 0x51
|
||||
// set_configs call index
|
||||
// set_configs call index
|
||||
const SET_CONFIGS_CALL_INDEX: u8 = 11; // 0x0b
|
||||
|
||||
/// SCALE encode ConfigOp::Noop
|
||||
@@ -74,9 +74,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let relay_url =
|
||||
std::env::var("RPC_URL").unwrap_or_else(|_| "ws://217.77.6.126:9944".to_string());
|
||||
|
||||
let min_join_hez: u128 = std::env::var("MIN_JOIN_BOND")
|
||||
.unwrap_or_else(|_| "10".to_string())
|
||||
.parse()?;
|
||||
let min_join_hez: u128 =
|
||||
std::env::var("MIN_JOIN_BOND").unwrap_or_else(|_| "10".to_string()).parse()?;
|
||||
let min_create_hez: u128 = std::env::var("MIN_CREATE_BOND")
|
||||
.unwrap_or_else(|_| "10000".to_string())
|
||||
.parse()?;
|
||||
@@ -87,10 +86,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("Relay RPC: {}", relay_url);
|
||||
println!("Asset Hub Para ID: {}", ASSET_HUB_PARA_ID);
|
||||
println!("MinJoinBond: {} HEZ ({} TYR)", min_join_hez, min_join_bond);
|
||||
println!(
|
||||
"MinCreateBond: {} HEZ ({} TYR)",
|
||||
min_create_hez, min_create_bond
|
||||
);
|
||||
println!("MinCreateBond: {} HEZ ({} TYR)", min_create_hez, min_create_bond);
|
||||
|
||||
// Connect to relay chain
|
||||
let api = OnlineClient::<PezkuwiConfig>::from_insecure_url(&relay_url).await?;
|
||||
@@ -105,11 +101,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
// Encode the NominationPools::set_configs call for Asset Hub
|
||||
let encoded_call = encode_set_configs_call(min_join_bond, min_create_bond);
|
||||
println!(
|
||||
"Encoded call: {} bytes (0x{})",
|
||||
encoded_call.len(),
|
||||
hex::encode(&encoded_call)
|
||||
);
|
||||
println!("Encoded call: {} bytes (0x{})", encoded_call.len(), hex::encode(&encoded_call));
|
||||
|
||||
// Build XCM destination: V3 MultiLocation { parents: 0, interior: X1(Teyrchain(1000)) }
|
||||
let dest = Value::unnamed_variant(
|
||||
@@ -136,23 +128,14 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
Value::named_variant(
|
||||
"UnpaidExecution",
|
||||
[
|
||||
(
|
||||
"weight_limit",
|
||||
Value::unnamed_variant("Unlimited", vec![]),
|
||||
),
|
||||
(
|
||||
"check_origin",
|
||||
Value::unnamed_variant("None", vec![]),
|
||||
),
|
||||
("weight_limit", Value::unnamed_variant("Unlimited", vec![])),
|
||||
("check_origin", Value::unnamed_variant("None", vec![])),
|
||||
],
|
||||
),
|
||||
Value::named_variant(
|
||||
"Transact",
|
||||
[
|
||||
(
|
||||
"origin_kind",
|
||||
Value::unnamed_variant("Superuser", vec![]),
|
||||
),
|
||||
("origin_kind", Value::unnamed_variant("Superuser", vec![])),
|
||||
(
|
||||
"require_weight_at_most",
|
||||
Value::named_composite([
|
||||
@@ -167,8 +150,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
);
|
||||
|
||||
// Wrap in XcmPallet.send
|
||||
let xcm_send =
|
||||
pezkuwi_subxt::dynamic::tx("XcmPallet", "send", vec![dest, message]);
|
||||
let xcm_send = pezkuwi_subxt::dynamic::tx("XcmPallet", "send", vec![dest, message]);
|
||||
|
||||
// Wrap in sudo_unchecked_weight (no weight limit for sudo)
|
||||
let sudo_call = pezkuwi_subxt::dynamic::tx(
|
||||
@@ -188,15 +170,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Submit and watch
|
||||
use pezkuwi_subxt::tx::TxStatus;
|
||||
|
||||
let tx_progress = api
|
||||
.tx()
|
||||
.sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair)
|
||||
.await?;
|
||||
let tx_progress =
|
||||
api.tx().sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair).await?;
|
||||
|
||||
println!(
|
||||
"TX hash: 0x{}",
|
||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
||||
);
|
||||
println!("TX hash: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||
println!("Watching TX status...");
|
||||
|
||||
let mut progress = tx_progress;
|
||||
@@ -212,11 +189,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!(" TX SUCCESS!");
|
||||
for event in events.iter() {
|
||||
if let Ok(ev) = event {
|
||||
println!(
|
||||
" Event: {}::{}",
|
||||
ev.pallet_name(),
|
||||
ev.variant_name()
|
||||
);
|
||||
println!(" Event: {}::{}", ev.pallet_name(), ev.variant_name());
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
+15
-29
@@ -28,10 +28,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.unwrap_or_else(|_| "499000".to_string())
|
||||
.parse()?;
|
||||
let bond_planck = bond_hez * PLANCKS_PER_HEZ;
|
||||
let skip: usize = std::env::var("SKIP")
|
||||
.unwrap_or_else(|_| "0".to_string())
|
||||
.parse()
|
||||
.unwrap_or(0);
|
||||
let skip: usize =
|
||||
std::env::var("SKIP").unwrap_or_else(|_| "0".to_string()).parse().unwrap_or(0);
|
||||
|
||||
println!("RPC: {}", url);
|
||||
println!("Wallets file: {}", wallets_file);
|
||||
@@ -90,33 +88,24 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!(" Account: {}", account);
|
||||
|
||||
// staking.bond_extra(max_additional: Balance)
|
||||
let bond_extra_tx = pezkuwi_subxt::dynamic::tx(
|
||||
"Staking",
|
||||
"bond_extra",
|
||||
vec![Value::u128(bond_planck)],
|
||||
);
|
||||
let bond_extra_tx =
|
||||
pezkuwi_subxt::dynamic::tx("Staking", "bond_extra", vec![Value::u128(bond_planck)]);
|
||||
|
||||
use pezkuwi_subxt::tx::TxStatus;
|
||||
let mut tx_ok = false;
|
||||
|
||||
for attempt in 0..3 {
|
||||
let tx_progress = match api
|
||||
.tx()
|
||||
.sign_and_submit_then_watch_default(&bond_extra_tx, &keypair)
|
||||
.await
|
||||
{
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
println!(" SUBMIT ERROR (attempt {}): {}", attempt + 1, e);
|
||||
tokio::time::sleep(std::time::Duration::from_secs(12)).await;
|
||||
continue;
|
||||
},
|
||||
};
|
||||
let tx_progress =
|
||||
match api.tx().sign_and_submit_then_watch_default(&bond_extra_tx, &keypair).await {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
println!(" SUBMIT ERROR (attempt {}): {}", attempt + 1, e);
|
||||
tokio::time::sleep(std::time::Duration::from_secs(12)).await;
|
||||
continue;
|
||||
},
|
||||
};
|
||||
|
||||
println!(
|
||||
" TX: 0x{}",
|
||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
||||
);
|
||||
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||
|
||||
let mut progress = tx_progress;
|
||||
loop {
|
||||
@@ -198,10 +187,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("\n=== RESULTS ===");
|
||||
println!("Success: {}/{}", success_count, stash_wallets.len() - skip);
|
||||
println!("Failed: {}/{}", fail_count, stash_wallets.len() - skip);
|
||||
println!(
|
||||
"Total bonded: {} HEZ",
|
||||
bond_hez * success_count as u128
|
||||
);
|
||||
println!("Total bonded: {} HEZ", bond_hez * success_count as u128);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
+29
-61
@@ -85,13 +85,7 @@ fn build_pool_configs(wallets: Vec<WalletInfo>) -> Vec<PoolConfig> {
|
||||
.enumerate()
|
||||
.map(|(i, w)| {
|
||||
let stake_hez = base_stake.saturating_sub(i as u128 * 10_000);
|
||||
PoolConfig {
|
||||
name: w.name,
|
||||
mnemonic: w.mnemonic,
|
||||
ss58: w.ss58,
|
||||
transfer_hez,
|
||||
stake_hez,
|
||||
}
|
||||
PoolConfig { name: w.name, mnemonic: w.mnemonic, ss58: w.ss58, transfer_hez, stake_hez }
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
@@ -104,26 +98,20 @@ async fn wait_for_success(
|
||||
loop {
|
||||
let status = progress.next().await;
|
||||
match status {
|
||||
Some(Ok(TxStatus::InBestBlock(details))) => {
|
||||
match details.wait_for_success().await {
|
||||
Ok(events) => {
|
||||
println!(" {} SUCCESS!", label);
|
||||
for event in events.iter() {
|
||||
if let Ok(ev) = event {
|
||||
println!(
|
||||
" {}::{}",
|
||||
ev.pallet_name(),
|
||||
ev.variant_name()
|
||||
);
|
||||
}
|
||||
Some(Ok(TxStatus::InBestBlock(details))) => match details.wait_for_success().await {
|
||||
Ok(events) => {
|
||||
println!(" {} SUCCESS!", label);
|
||||
for event in events.iter() {
|
||||
if let Ok(ev) = event {
|
||||
println!(" {}::{}", ev.pallet_name(), ev.variant_name());
|
||||
}
|
||||
return Ok(true);
|
||||
},
|
||||
Err(e) => {
|
||||
println!(" {} DISPATCH ERROR: {}", label, e);
|
||||
return Ok(false);
|
||||
},
|
||||
}
|
||||
}
|
||||
return Ok(true);
|
||||
},
|
||||
Err(e) => {
|
||||
println!(" {} DISPATCH ERROR: {}", label, e);
|
||||
return Ok(false);
|
||||
},
|
||||
},
|
||||
Some(Ok(TxStatus::Error { message })) => {
|
||||
println!(" {} TX ERROR: {}", label, message);
|
||||
@@ -158,13 +146,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Parse CLI args
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
let phase = args.get(1).map(|s| s.as_str()).unwrap_or("all");
|
||||
let skip: usize = std::env::var("SKIP")
|
||||
.unwrap_or_else(|_| "0".to_string())
|
||||
.parse()
|
||||
.unwrap_or(0);
|
||||
let skip: usize =
|
||||
std::env::var("SKIP").unwrap_or_else(|_| "0".to_string()).parse().unwrap_or(0);
|
||||
|
||||
let rpc =
|
||||
std::env::var("ASSET_HUB_RPC").unwrap_or_else(|_| DEFAULT_ASSET_HUB_RPC.to_string());
|
||||
let rpc = std::env::var("ASSET_HUB_RPC").unwrap_or_else(|_| DEFAULT_ASSET_HUB_RPC.to_string());
|
||||
|
||||
println!("=== NOMINATION POOL CREATOR ===");
|
||||
println!("Asset Hub RPC: {}", rpc);
|
||||
@@ -182,10 +167,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
let founder_mn = Mnemonic::from_str(&founder_mnemonic())?;
|
||||
let founder_keypair = Keypair::from_phrase(&founder_mn, None)?;
|
||||
println!(
|
||||
"Founder: {}\n",
|
||||
founder_keypair.public_key().to_account_id()
|
||||
);
|
||||
println!("Founder: {}\n", founder_keypair.public_key().to_account_id());
|
||||
|
||||
for (i, pool) in pool_configs.iter().enumerate().skip(skip) {
|
||||
println!(
|
||||
@@ -228,10 +210,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
},
|
||||
};
|
||||
|
||||
println!(
|
||||
" TX: 0x{}",
|
||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
||||
);
|
||||
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||
|
||||
tx_ok = wait_for_success(tx_progress, "TRANSFER").await?;
|
||||
if tx_ok {
|
||||
@@ -314,10 +293,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
},
|
||||
};
|
||||
|
||||
println!(
|
||||
" TX: 0x{}",
|
||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
||||
);
|
||||
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||
|
||||
create_ok = wait_for_success(tx_progress, "CREATE_POOL").await?;
|
||||
if create_ok {
|
||||
@@ -335,15 +311,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tokio::time::sleep(std::time::Duration::from_secs(12)).await;
|
||||
|
||||
// Query LastPoolId to get the pool_id
|
||||
let last_pool_query = pezkuwi_subxt::dynamic::storage::<(), Value>(
|
||||
"NominationPools",
|
||||
"LastPoolId",
|
||||
);
|
||||
let last_pool_query =
|
||||
pezkuwi_subxt::dynamic::storage::<(), Value>("NominationPools", "LastPoolId");
|
||||
let storage_client = api.storage().at_latest().await?;
|
||||
let last_pool = storage_client
|
||||
.entry(last_pool_query)?
|
||||
.try_fetch(())
|
||||
.await?;
|
||||
let last_pool = storage_client.entry(last_pool_query)?.try_fetch(()).await?;
|
||||
|
||||
let pool_id = match last_pool {
|
||||
Some(val) => {
|
||||
@@ -369,10 +340,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let metadata_tx = pezkuwi_subxt::dynamic::tx(
|
||||
"NominationPools",
|
||||
"set_metadata",
|
||||
vec![
|
||||
Value::u128(pool_id as u128),
|
||||
Value::from_bytes(&name_bytes),
|
||||
],
|
||||
vec![Value::u128(pool_id as u128), Value::from_bytes(&name_bytes)],
|
||||
);
|
||||
|
||||
let tx_progress = match api
|
||||
@@ -387,10 +355,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
},
|
||||
};
|
||||
|
||||
println!(
|
||||
" METADATA TX: 0x{}",
|
||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
||||
);
|
||||
println!(" METADATA TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||
|
||||
let ok = wait_for_success(tx_progress, "SET_METADATA").await?;
|
||||
if ok {
|
||||
@@ -401,7 +366,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
}
|
||||
}
|
||||
|
||||
println!(" Pool '{}' (ID: {}) created with {} HEZ\n", pool.name, pool_id, pool.stake_hez);
|
||||
println!(
|
||||
" Pool '{}' (ID: {}) created with {} HEZ\n",
|
||||
pool.name, pool_id, pool.stake_hez
|
||||
);
|
||||
|
||||
// Wait between pools
|
||||
if i + 1 < pool_configs.len() {
|
||||
|
||||
+8
-29
@@ -28,20 +28,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("Sudo account: {}\n", keypair.public_key().to_account_id());
|
||||
|
||||
// Staking::ForceEra storage key (verified twox128)
|
||||
let force_era_key = hex::decode(
|
||||
"5f3e4907f716ac89b6347d15ececedcaf7dad0317324aecae8744b87fc95f2f3",
|
||||
)?;
|
||||
let force_era_key =
|
||||
hex::decode("5f3e4907f716ac89b6347d15ececedcaf7dad0317324aecae8744b87fc95f2f3")?;
|
||||
// NotForcing = enum variant 0 = 0x00
|
||||
let not_forcing_value = vec![0x00u8];
|
||||
|
||||
println!(
|
||||
"Storage key: 0x{}",
|
||||
hex::encode(&force_era_key)
|
||||
);
|
||||
println!(
|
||||
"New value: 0x{} (NotForcing)",
|
||||
hex::encode(¬_forcing_value)
|
||||
);
|
||||
println!("Storage key: 0x{}", hex::encode(&force_era_key));
|
||||
println!("New value: 0x{} (NotForcing)", hex::encode(¬_forcing_value));
|
||||
|
||||
// Build: system.setStorage(items: Vec<(Key, Value)>)
|
||||
let set_storage_call = pezkuwi_subxt::dynamic::tx(
|
||||
@@ -54,24 +47,14 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
);
|
||||
|
||||
// Wrap in sudo
|
||||
let sudo_call = pezkuwi_subxt::dynamic::tx(
|
||||
"Sudo",
|
||||
"sudo",
|
||||
vec![set_storage_call.into_value()],
|
||||
);
|
||||
let sudo_call = pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![set_storage_call.into_value()]);
|
||||
|
||||
println!("\nSubmitting sudo(system.setStorage)...");
|
||||
|
||||
use pezkuwi_subxt::tx::TxStatus;
|
||||
let tx_progress = api
|
||||
.tx()
|
||||
.sign_and_submit_then_watch_default(&sudo_call, &keypair)
|
||||
.await?;
|
||||
let tx_progress = api.tx().sign_and_submit_then_watch_default(&sudo_call, &keypair).await?;
|
||||
|
||||
println!(
|
||||
"TX: 0x{}",
|
||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
||||
);
|
||||
println!("TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||
|
||||
let mut progress = tx_progress;
|
||||
loop {
|
||||
@@ -83,11 +66,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut sudid = false;
|
||||
for event in events.iter() {
|
||||
if let Ok(ev) = event {
|
||||
println!(
|
||||
" Event: {}::{}",
|
||||
ev.pallet_name(),
|
||||
ev.variant_name()
|
||||
);
|
||||
println!(" Event: {}::{}", ev.pallet_name(), ev.variant_name());
|
||||
if ev.pallet_name() == "Sudo" && ev.variant_name() == "Sudid" {
|
||||
sudid = true;
|
||||
}
|
||||
|
||||
+11
-36
@@ -20,7 +20,7 @@ const PEOPLE_CHAIN_PARA_ID: u32 = 1004;
|
||||
|
||||
// Tiki pallet index on People Chain
|
||||
const TIKI_PALLET_INDEX: u8 = 61; // 0x3d
|
||||
// force_mint_citizen_nft call index
|
||||
// force_mint_citizen_nft call index
|
||||
const FORCE_MINT_CALL_INDEX: u8 = 2; // 0x02
|
||||
|
||||
/// Encode Tiki::force_mint_citizen_nft(dest) for People Chain
|
||||
@@ -61,23 +61,14 @@ fn build_xcm_sudo_transact(encoded_call: &[u8]) -> (Value, Value) {
|
||||
Value::named_variant(
|
||||
"UnpaidExecution",
|
||||
[
|
||||
(
|
||||
"weight_limit",
|
||||
Value::unnamed_variant("Unlimited", vec![]),
|
||||
),
|
||||
(
|
||||
"check_origin",
|
||||
Value::unnamed_variant("None", vec![]),
|
||||
),
|
||||
("weight_limit", Value::unnamed_variant("Unlimited", vec![])),
|
||||
("check_origin", Value::unnamed_variant("None", vec![])),
|
||||
],
|
||||
),
|
||||
Value::named_variant(
|
||||
"Transact",
|
||||
[
|
||||
(
|
||||
"origin_kind",
|
||||
Value::unnamed_variant("Superuser", vec![]),
|
||||
),
|
||||
("origin_kind", Value::unnamed_variant("Superuser", vec![])),
|
||||
(
|
||||
"require_weight_at_most",
|
||||
Value::named_composite([
|
||||
@@ -127,10 +118,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
std::env::var("RPC_URL").unwrap_or_else(|_| "ws://217.77.6.126:9944".to_string());
|
||||
|
||||
// Skip first N validators (already minted)
|
||||
let skip: usize = std::env::var("SKIP")
|
||||
.unwrap_or_else(|_| "0".to_string())
|
||||
.parse()
|
||||
.unwrap_or(0);
|
||||
let skip: usize =
|
||||
std::env::var("SKIP").unwrap_or_else(|_| "0".to_string()).parse().unwrap_or(0);
|
||||
|
||||
println!("Relay RPC: {}", relay_url);
|
||||
println!("People Chain Para ID: {}", PEOPLE_CHAIN_PARA_ID);
|
||||
@@ -175,8 +164,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let (dest, message) = build_xcm_sudo_transact(&encoded_call);
|
||||
|
||||
// Wrap in xcmPallet.send then sudo
|
||||
let xcm_send =
|
||||
pezkuwi_subxt::dynamic::tx("XcmPallet", "send", vec![dest, message]);
|
||||
let xcm_send = pezkuwi_subxt::dynamic::tx("XcmPallet", "send", vec![dest, message]);
|
||||
|
||||
let sudo_call = pezkuwi_subxt::dynamic::tx(
|
||||
"Sudo",
|
||||
@@ -196,11 +184,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Retry up to 3 times on submit error
|
||||
let mut tx_progress_opt = None;
|
||||
for attempt in 0..3 {
|
||||
match api
|
||||
.tx()
|
||||
.sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair)
|
||||
.await
|
||||
{
|
||||
match api.tx().sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair).await {
|
||||
Ok(p) => {
|
||||
tx_progress_opt = Some(p);
|
||||
break;
|
||||
@@ -220,10 +204,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
},
|
||||
};
|
||||
|
||||
println!(
|
||||
" TX: 0x{}",
|
||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
||||
);
|
||||
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||
|
||||
let mut progress = tx_progress;
|
||||
let mut tx_ok = false;
|
||||
@@ -237,9 +218,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut has_sent = false;
|
||||
for event in events.iter() {
|
||||
if let Ok(ev) = event {
|
||||
if ev.pallet_name() == "Sudo"
|
||||
&& ev.variant_name() == "Sudid"
|
||||
{
|
||||
if ev.pallet_name() == "Sudo" && ev.variant_name() == "Sudid" {
|
||||
has_sudid = true;
|
||||
}
|
||||
if ev.pallet_name() == "XcmPallet"
|
||||
@@ -256,11 +235,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!(" WARNING: Missing expected events");
|
||||
for event in events.iter() {
|
||||
if let Ok(ev) = event {
|
||||
println!(
|
||||
" {}::{}",
|
||||
ev.pallet_name(),
|
||||
ev.variant_name()
|
||||
);
|
||||
println!(" {}::{}", ev.pallet_name(), ev.variant_name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+75
-62
@@ -6,66 +6,79 @@ use std::str::FromStr;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let url = std::env::var("RPC_URL").unwrap_or_else(|_| "ws://217.77.6.126:9944".to_string());
|
||||
let message = std::env::var("MESSAGE").expect("MESSAGE env var required");
|
||||
|
||||
println!("RPC: {}", url);
|
||||
println!("Message: {}", message);
|
||||
println!("Message bytes: {}", message.len());
|
||||
|
||||
let api = OnlineClient::<PezkuwiConfig>::from_insecure_url(&url).await?;
|
||||
println!("Connected!");
|
||||
|
||||
let mnemonic_str = std::env::var("SUDO_MNEMONIC").expect("SUDO_MNEMONIC required");
|
||||
let mnemonic = Mnemonic::from_str(&mnemonic_str)?;
|
||||
let keypair = Keypair::from_phrase(&mnemonic, None)?;
|
||||
println!("Account: {}\n", keypair.public_key().to_account_id());
|
||||
|
||||
let remark_tx = pezkuwi_subxt::dynamic::tx(
|
||||
"System",
|
||||
"remark_with_event",
|
||||
vec![Value::from_bytes(message.as_bytes())],
|
||||
);
|
||||
|
||||
println!("Submitting remarkWithEvent...");
|
||||
|
||||
use pezkuwi_subxt::tx::TxStatus;
|
||||
let tx_progress = api.tx()
|
||||
.sign_and_submit_then_watch_default(&remark_tx, &keypair)
|
||||
.await?;
|
||||
|
||||
println!("TX hash: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||
|
||||
let mut progress = tx_progress;
|
||||
loop {
|
||||
let status = progress.next().await;
|
||||
match status {
|
||||
Some(Ok(TxStatus::Validated)) => println!(" Validated"),
|
||||
Some(Ok(TxStatus::Broadcasted)) => println!(" Broadcasted"),
|
||||
Some(Ok(TxStatus::InBestBlock(details))) => {
|
||||
println!(" InBestBlock {:?}", details.block_hash());
|
||||
match details.wait_for_success().await {
|
||||
Ok(events) => {
|
||||
println!(" SUCCESS!");
|
||||
for event in events.iter() {
|
||||
if let Ok(ev) = event {
|
||||
println!(" {}::{}", ev.pallet_name(), ev.variant_name());
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => println!(" Error: {}", e),
|
||||
}
|
||||
break;
|
||||
},
|
||||
Some(Ok(TxStatus::Error { message })) => { println!(" ERROR: {}", message); break; },
|
||||
Some(Ok(TxStatus::Invalid { message })) => { println!(" INVALID: {}", message); break; },
|
||||
Some(Ok(TxStatus::Dropped { message })) => { println!(" DROPPED: {}", message); break; },
|
||||
Some(Err(e)) => { println!(" Error: {}", e); break; },
|
||||
None => { println!(" Stream ended"); break; },
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
println!("\nDone.");
|
||||
Ok(())
|
||||
let url = std::env::var("RPC_URL").unwrap_or_else(|_| "ws://217.77.6.126:9944".to_string());
|
||||
let message = std::env::var("MESSAGE").expect("MESSAGE env var required");
|
||||
|
||||
println!("RPC: {}", url);
|
||||
println!("Message: {}", message);
|
||||
println!("Message bytes: {}", message.len());
|
||||
|
||||
let api = OnlineClient::<PezkuwiConfig>::from_insecure_url(&url).await?;
|
||||
println!("Connected!");
|
||||
|
||||
let mnemonic_str = std::env::var("SUDO_MNEMONIC").expect("SUDO_MNEMONIC required");
|
||||
let mnemonic = Mnemonic::from_str(&mnemonic_str)?;
|
||||
let keypair = Keypair::from_phrase(&mnemonic, None)?;
|
||||
println!("Account: {}\n", keypair.public_key().to_account_id());
|
||||
|
||||
let remark_tx = pezkuwi_subxt::dynamic::tx(
|
||||
"System",
|
||||
"remark_with_event",
|
||||
vec![Value::from_bytes(message.as_bytes())],
|
||||
);
|
||||
|
||||
println!("Submitting remarkWithEvent...");
|
||||
|
||||
use pezkuwi_subxt::tx::TxStatus;
|
||||
let tx_progress = api.tx().sign_and_submit_then_watch_default(&remark_tx, &keypair).await?;
|
||||
|
||||
println!("TX hash: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||
|
||||
let mut progress = tx_progress;
|
||||
loop {
|
||||
let status = progress.next().await;
|
||||
match status {
|
||||
Some(Ok(TxStatus::Validated)) => println!(" Validated"),
|
||||
Some(Ok(TxStatus::Broadcasted)) => println!(" Broadcasted"),
|
||||
Some(Ok(TxStatus::InBestBlock(details))) => {
|
||||
println!(" InBestBlock {:?}", details.block_hash());
|
||||
match details.wait_for_success().await {
|
||||
Ok(events) => {
|
||||
println!(" SUCCESS!");
|
||||
for event in events.iter() {
|
||||
if let Ok(ev) = event {
|
||||
println!(" {}::{}", ev.pallet_name(), ev.variant_name());
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => println!(" Error: {}", e),
|
||||
}
|
||||
break;
|
||||
},
|
||||
Some(Ok(TxStatus::Error { message })) => {
|
||||
println!(" ERROR: {}", message);
|
||||
break;
|
||||
},
|
||||
Some(Ok(TxStatus::Invalid { message })) => {
|
||||
println!(" INVALID: {}", message);
|
||||
break;
|
||||
},
|
||||
Some(Ok(TxStatus::Dropped { message })) => {
|
||||
println!(" DROPPED: {}", message);
|
||||
break;
|
||||
},
|
||||
Some(Err(e)) => {
|
||||
println!(" Error: {}", e);
|
||||
break;
|
||||
},
|
||||
None => {
|
||||
println!(" Stream ended");
|
||||
break;
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
println!("\nDone.");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
+112
-48
@@ -33,27 +33,111 @@ struct ValidatorInfo {
|
||||
|
||||
fn validators() -> Vec<ValidatorInfo> {
|
||||
vec![
|
||||
ValidatorInfo { name: "Çiyager (Cihat Türkan)", ss58: "5GipBJs2uNWTCazyZQ2vG3DEqLz4tXNmNZtBAT1Mtm1orZ5i", staked_hez: 499_100 },
|
||||
ValidatorInfo { name: "Mehmet Tunç", ss58: "5HWFZbhkZuTUySXu6ZXYKrTHBnWXHvWRKLozE22zhnwXGGxk", staked_hez: 499_100 },
|
||||
ValidatorInfo { name: "Nagihan Akarsel", ss58: "5CrB5BWJfLNWEZAsAXDKXdJUGzFMXKvYnwRX4DVMcgBwxSdx", staked_hez: 499_100 },
|
||||
ValidatorInfo { name: "Sait Çürükkaya (Doktor Süleyman)", ss58: "5ELgySrX5ZyK7EWXjj6bAedyTCcTNWDANbiiipsT5gnpoCEp", staked_hez: 499_100 },
|
||||
ValidatorInfo { name: "Evdile Koçer", ss58: "5GCZQNjRdHofEHPvVq4ePrfDYcjRzQ1HQ2awHMX6AawpRYuM", staked_hez: 499_100 },
|
||||
ValidatorInfo { name: "Mam Zeki", ss58: "5H8jTzi4Gm4rbFtXw6h5enhLhgsuhNAqR5K2itmPiz83ymWy", staked_hez: 499_100 },
|
||||
ValidatorInfo { name: "Kakaî Falah", ss58: "5Fs3P5tHuL9cvwPQojsheViRRAjFkMMFa32jAkDSwW9mbTfU", staked_hez: 499_100 },
|
||||
ValidatorInfo { name: "Feryad Fazil Ömer", ss58: "5DXgq7uDXog6zcubT3wgtaYosoibjudz4w5ScPW2phLuAy3V", staked_hez: 499_100 },
|
||||
ValidatorInfo { name: "Mevlud Afand", ss58: "5FyFwbGLgPXun3azh6Gx83wCuUt5FTavb2WAVDYrjziVB9rN", staked_hez: 499_100 },
|
||||
ValidatorInfo { name: "Şêrko Fatih Şivandî", ss58: "5HEcuuypLDeJaSj6ZgH57aXhuviyeLNdw9QrCDJ8u6gsnjnL", staked_hez: 499_100 },
|
||||
ValidatorInfo { name: "Ramin Hüseyin Penahi", ss58: "5EpmpTXbMXpz6ixy3WhutdzcexzPbvybNKv4eiiN1kvTnQH5", staked_hez: 499_100 },
|
||||
ValidatorInfo { name: "Zanyar Moradi", ss58: "5DFsm3BBEgHmSEZkvwGKB7c7tiH2avhfuQE1SEjfMDGuczsW", staked_hez: 499_100 },
|
||||
ValidatorInfo { name: "Heidar Ghorbani", ss58: "5HePVUXjGSM2hVZ1YMz2V3KoX6EdQNEmmzUnUvpfGV95ofUR", staked_hez: 499_100 },
|
||||
ValidatorInfo { name: "Farhad Salimi", ss58: "5GP4nAcwtETTg1oAHQNvevmmhG8GEstGQeCirKEhaDTwpFgx", staked_hez: 499_100 },
|
||||
ValidatorInfo { name: "Vafa Azarbar", ss58: "5FYoCM3oeEGeoFY94EgXBhmABkRCabvPp72ur5bJNG3cK619", staked_hez: 499_100 },
|
||||
ValidatorInfo { name: "Dr. Aziz Mihemed", ss58: "5GspwkKF6aYzFkmAyBBQg7coSCSgDCore79fbW8uxJNAH347", staked_hez: 499_100 },
|
||||
ValidatorInfo { name: "Arîn Mîrkan", ss58: "5GmuX11pN2fC4Fyq1V7MuiYt3aevZcVQs3HZWKyzmap9bKfe", staked_hez: 499_100 },
|
||||
ValidatorInfo { name: "Ebu Leyla", ss58: "5FQptVCtM1qsxkLbQkATkw4Kio4M9LxWvM6TwgEo3QjmTXF3", staked_hez: 499_100 },
|
||||
ValidatorInfo { name: "Rêvan Kobanê", ss58: "5E7VD2qmso1yRfyq3t9u2qhauAgtmjZTybVsCARF5Zz9bXy6", staked_hez: 499_100 },
|
||||
ValidatorInfo { name: "Amanj Babani", ss58: "5Ccz5W7Q21g4UPCytzHxD3VSMLJ1BbbWSkJKFwsNtYRk3HkX", staked_hez: 499_100 },
|
||||
ValidatorInfo { name: "Xosrow Gulan", ss58: "5D7WPmK1SAJyYDdCtgqEzGJpWXQe3Lj9FqWL8z9waLTkUNv3", staked_hez: 499_100 },
|
||||
ValidatorInfo {
|
||||
name: "Çiyager (Cihat Türkan)",
|
||||
ss58: "5GipBJs2uNWTCazyZQ2vG3DEqLz4tXNmNZtBAT1Mtm1orZ5i",
|
||||
staked_hez: 499_100,
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Mehmet Tunç",
|
||||
ss58: "5HWFZbhkZuTUySXu6ZXYKrTHBnWXHvWRKLozE22zhnwXGGxk",
|
||||
staked_hez: 499_100,
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Nagihan Akarsel",
|
||||
ss58: "5CrB5BWJfLNWEZAsAXDKXdJUGzFMXKvYnwRX4DVMcgBwxSdx",
|
||||
staked_hez: 499_100,
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Sait Çürükkaya (Doktor Süleyman)",
|
||||
ss58: "5ELgySrX5ZyK7EWXjj6bAedyTCcTNWDANbiiipsT5gnpoCEp",
|
||||
staked_hez: 499_100,
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Evdile Koçer",
|
||||
ss58: "5GCZQNjRdHofEHPvVq4ePrfDYcjRzQ1HQ2awHMX6AawpRYuM",
|
||||
staked_hez: 499_100,
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Mam Zeki",
|
||||
ss58: "5H8jTzi4Gm4rbFtXw6h5enhLhgsuhNAqR5K2itmPiz83ymWy",
|
||||
staked_hez: 499_100,
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Kakaî Falah",
|
||||
ss58: "5Fs3P5tHuL9cvwPQojsheViRRAjFkMMFa32jAkDSwW9mbTfU",
|
||||
staked_hez: 499_100,
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Feryad Fazil Ömer",
|
||||
ss58: "5DXgq7uDXog6zcubT3wgtaYosoibjudz4w5ScPW2phLuAy3V",
|
||||
staked_hez: 499_100,
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Mevlud Afand",
|
||||
ss58: "5FyFwbGLgPXun3azh6Gx83wCuUt5FTavb2WAVDYrjziVB9rN",
|
||||
staked_hez: 499_100,
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Şêrko Fatih Şivandî",
|
||||
ss58: "5HEcuuypLDeJaSj6ZgH57aXhuviyeLNdw9QrCDJ8u6gsnjnL",
|
||||
staked_hez: 499_100,
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Ramin Hüseyin Penahi",
|
||||
ss58: "5EpmpTXbMXpz6ixy3WhutdzcexzPbvybNKv4eiiN1kvTnQH5",
|
||||
staked_hez: 499_100,
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Zanyar Moradi",
|
||||
ss58: "5DFsm3BBEgHmSEZkvwGKB7c7tiH2avhfuQE1SEjfMDGuczsW",
|
||||
staked_hez: 499_100,
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Heidar Ghorbani",
|
||||
ss58: "5HePVUXjGSM2hVZ1YMz2V3KoX6EdQNEmmzUnUvpfGV95ofUR",
|
||||
staked_hez: 499_100,
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Farhad Salimi",
|
||||
ss58: "5GP4nAcwtETTg1oAHQNvevmmhG8GEstGQeCirKEhaDTwpFgx",
|
||||
staked_hez: 499_100,
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Vafa Azarbar",
|
||||
ss58: "5FYoCM3oeEGeoFY94EgXBhmABkRCabvPp72ur5bJNG3cK619",
|
||||
staked_hez: 499_100,
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Dr. Aziz Mihemed",
|
||||
ss58: "5GspwkKF6aYzFkmAyBBQg7coSCSgDCore79fbW8uxJNAH347",
|
||||
staked_hez: 499_100,
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Arîn Mîrkan",
|
||||
ss58: "5GmuX11pN2fC4Fyq1V7MuiYt3aevZcVQs3HZWKyzmap9bKfe",
|
||||
staked_hez: 499_100,
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Ebu Leyla",
|
||||
ss58: "5FQptVCtM1qsxkLbQkATkw4Kio4M9LxWvM6TwgEo3QjmTXF3",
|
||||
staked_hez: 499_100,
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Rêvan Kobanê",
|
||||
ss58: "5E7VD2qmso1yRfyq3t9u2qhauAgtmjZTybVsCARF5Zz9bXy6",
|
||||
staked_hez: 499_100,
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Amanj Babani",
|
||||
ss58: "5Ccz5W7Q21g4UPCytzHxD3VSMLJ1BbbWSkJKFwsNtYRk3HkX",
|
||||
staked_hez: 499_100,
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Xosrow Gulan",
|
||||
ss58: "5D7WPmK1SAJyYDdCtgqEzGJpWXQe3Lj9FqWL8z9waLTkUNv3",
|
||||
staked_hez: 499_100,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@@ -143,10 +227,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
let relay_url =
|
||||
std::env::var("RPC_URL").unwrap_or_else(|_| "ws://217.77.6.126:9944".to_string());
|
||||
let skip: usize = std::env::var("SKIP")
|
||||
.unwrap_or_else(|_| "0".to_string())
|
||||
.parse()
|
||||
.unwrap_or(0);
|
||||
let skip: usize =
|
||||
std::env::var("SKIP").unwrap_or_else(|_| "0".to_string()).parse().unwrap_or(0);
|
||||
|
||||
let vals = validators();
|
||||
println!("Relay RPC: {}", relay_url);
|
||||
@@ -155,10 +237,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
// Connect to relay chain
|
||||
let api = OnlineClient::<PezkuwiConfig>::from_insecure_url(&relay_url).await?;
|
||||
println!(
|
||||
"Connected! specVersion: {}\n",
|
||||
api.runtime_version().spec_version
|
||||
);
|
||||
println!("Connected! specVersion: {}\n", api.runtime_version().spec_version);
|
||||
|
||||
// Load sudo keypair
|
||||
let mnemonic_str =
|
||||
@@ -196,11 +275,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
0,
|
||||
0,
|
||||
);
|
||||
println!(
|
||||
" Call: {} bytes (0x{}...)",
|
||||
call.len(),
|
||||
hex::encode(&call[..6])
|
||||
);
|
||||
println!(" Call: {} bytes (0x{}...)", call.len(), hex::encode(&call[..6]));
|
||||
|
||||
// Build XCM message
|
||||
let (dest, message) = build_xcm_values(&call);
|
||||
@@ -224,11 +299,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
use pezkuwi_subxt::tx::TxStatus;
|
||||
let mut tx_progress_opt = None;
|
||||
for attempt in 0..3 {
|
||||
match api
|
||||
.tx()
|
||||
.sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair)
|
||||
.await
|
||||
{
|
||||
match api.tx().sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair).await {
|
||||
Ok(p) => {
|
||||
tx_progress_opt = Some(p);
|
||||
break;
|
||||
@@ -249,10 +320,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
},
|
||||
};
|
||||
|
||||
println!(
|
||||
" TX: 0x{}",
|
||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
||||
);
|
||||
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||
|
||||
let mut progress = tx_progress;
|
||||
let mut tx_ok = false;
|
||||
@@ -283,11 +351,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!(" WARNING: Events:");
|
||||
for event in events.iter() {
|
||||
if let Ok(ev) = event {
|
||||
println!(
|
||||
" {}::{}",
|
||||
ev.pallet_name(),
|
||||
ev.variant_name()
|
||||
);
|
||||
println!(" {}::{}", ev.pallet_name(), ev.variant_name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-36
@@ -48,12 +48,9 @@ fn load_wallets() -> Vec<WalletInfo> {
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("=== SET POOL METADATA ===\n");
|
||||
|
||||
let start_id: u32 = std::env::var("START_ID")
|
||||
.unwrap_or_else(|_| "1".to_string())
|
||||
.parse()?;
|
||||
let start_id: u32 = std::env::var("START_ID").unwrap_or_else(|_| "1".to_string()).parse()?;
|
||||
|
||||
let rpc =
|
||||
std::env::var("ASSET_HUB_RPC").unwrap_or_else(|_| DEFAULT_ASSET_HUB_RPC.to_string());
|
||||
let rpc = std::env::var("ASSET_HUB_RPC").unwrap_or_else(|_| DEFAULT_ASSET_HUB_RPC.to_string());
|
||||
|
||||
let api = OnlineClient::<PezkuwiConfig>::from_insecure_url(&rpc).await?;
|
||||
println!("Connected to Asset Hub!\n");
|
||||
@@ -66,23 +63,14 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
if let Some(val) = last_pool {
|
||||
let decoded = val.decode()?;
|
||||
println!("LastPoolId raw value: {:?}", decoded);
|
||||
println!(
|
||||
"LastPoolId as_u128: {:?}",
|
||||
decoded.as_u128()
|
||||
);
|
||||
println!("LastPoolId as_u128: {:?}", decoded.as_u128());
|
||||
}
|
||||
|
||||
let wallets = load_wallets();
|
||||
|
||||
for (i, wallet) in wallets.iter().enumerate() {
|
||||
let pool_id = start_id + i as u32;
|
||||
println!(
|
||||
"--- [{}/{}] Pool {} -> '{}' ---",
|
||||
i + 1,
|
||||
wallets.len(),
|
||||
pool_id,
|
||||
wallet.name
|
||||
);
|
||||
println!("--- [{}/{}] Pool {} -> '{}' ---", i + 1, wallets.len(), pool_id, wallet.name);
|
||||
|
||||
let mnemonic = Mnemonic::from_str(&wallet.mnemonic)?;
|
||||
let keypair = Keypair::from_phrase(&mnemonic, None)?;
|
||||
@@ -102,22 +90,16 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tokio::time::sleep(std::time::Duration::from_secs(18)).await;
|
||||
}
|
||||
|
||||
let tx_progress = match api
|
||||
.tx()
|
||||
.sign_and_submit_then_watch_default(&metadata_tx, &keypair)
|
||||
.await
|
||||
{
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
println!(" SUBMIT ERROR (attempt {}): {}", attempt + 1, e);
|
||||
continue;
|
||||
},
|
||||
};
|
||||
let tx_progress =
|
||||
match api.tx().sign_and_submit_then_watch_default(&metadata_tx, &keypair).await {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
println!(" SUBMIT ERROR (attempt {}): {}", attempt + 1, e);
|
||||
continue;
|
||||
},
|
||||
};
|
||||
|
||||
println!(
|
||||
" TX: 0x{}",
|
||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
||||
);
|
||||
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||
|
||||
use pezkuwi_subxt::tx::TxStatus;
|
||||
let mut progress = tx_progress;
|
||||
@@ -130,11 +112,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!(" SUCCESS!");
|
||||
for event in events.iter() {
|
||||
if let Ok(ev) = event {
|
||||
println!(
|
||||
" {}::{}",
|
||||
ev.pallet_name(),
|
||||
ev.variant_name()
|
||||
);
|
||||
println!(" {}::{}", ev.pallet_name(), ev.variant_name());
|
||||
}
|
||||
}
|
||||
ok = true;
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
//! Test start_score_tracking on People Chain
|
||||
//!
|
||||
//! 1. Transfer small amount from founder to validator on People Chain
|
||||
//! 2. Call start_score_tracking() from validator account
|
||||
//! 3. Verify StakingStartBlock was set
|
||||
//!
|
||||
//! FOUNDER_MNEMONIC="..." VALIDATOR_MNEMONIC="..." cargo run --release -p pezkuwi-subxt --example test_start_tracking
|
||||
|
||||
#![allow(missing_docs)]
|
||||
use pezkuwi_subxt::dynamic::Value;
|
||||
use pezkuwi_subxt::utils::AccountId32;
|
||||
use pezkuwi_subxt::{OnlineClient, PezkuwiConfig};
|
||||
use pezkuwi_subxt_signer::bip39::Mnemonic;
|
||||
use pezkuwi_subxt_signer::sr25519::Keypair;
|
||||
use std::str::FromStr;
|
||||
|
||||
const PEOPLE_RPC: &str = "ws://217.77.6.126:41944";
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("=== TEST: start_score_tracking on People Chain ===\n");
|
||||
|
||||
let founder_mnemonic_str =
|
||||
std::env::var("FOUNDER_MNEMONIC").expect("FOUNDER_MNEMONIC env var required");
|
||||
let validator_mnemonic_str =
|
||||
std::env::var("VALIDATOR_MNEMONIC").expect("VALIDATOR_MNEMONIC env var required");
|
||||
|
||||
let founder_mnemonic = Mnemonic::from_str(&founder_mnemonic_str)?;
|
||||
let founder_keypair = Keypair::from_phrase(&founder_mnemonic, None)?;
|
||||
let founder_account = AccountId32(founder_keypair.public_key().0);
|
||||
|
||||
let validator_mnemonic = Mnemonic::from_str(&validator_mnemonic_str)?;
|
||||
let validator_keypair = Keypair::from_phrase(&validator_mnemonic, None)?;
|
||||
let validator_account = AccountId32(validator_keypair.public_key().0);
|
||||
|
||||
println!("Founder: {}", founder_account);
|
||||
println!("Validator: {}", validator_account);
|
||||
|
||||
println!("\nConnecting to People Chain: {}", PEOPLE_RPC);
|
||||
let api = OnlineClient::<PezkuwiConfig>::from_insecure_url(PEOPLE_RPC).await?;
|
||||
println!("Connected (spec_version: {})\n", api.runtime_version().spec_version);
|
||||
|
||||
// Step 1: Transfer 10 HEZ from founder to validator for tx fees
|
||||
let transfer_amount: u128 = 10_000_000_000_000; // 10 HEZ
|
||||
println!("--- Step 1: Transfer 10 HEZ to validator for fees ---");
|
||||
|
||||
let transfer = pezkuwi_subxt::dynamic::tx(
|
||||
"Balances",
|
||||
"transfer_keep_alive",
|
||||
vec![
|
||||
Value::unnamed_variant("Id", [Value::from_bytes(&validator_account.0)]),
|
||||
Value::u128(transfer_amount),
|
||||
],
|
||||
);
|
||||
|
||||
let progress = api.tx().sign_and_submit_then_watch_default(&transfer, &founder_keypair).await?;
|
||||
println!("TX: 0x{}", hex::encode(progress.extrinsic_hash().as_ref()));
|
||||
let events = progress.wait_for_finalized_success().await?;
|
||||
println!("Transfer finalized!");
|
||||
for ev in events.iter() {
|
||||
if let Ok(ev) = ev {
|
||||
if ev.pallet_name() == "Balances" {
|
||||
println!(" {}::{}", ev.pallet_name(), ev.variant_name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2: Call start_score_tracking from validator
|
||||
println!("\n--- Step 2: start_score_tracking() ---");
|
||||
|
||||
let start_tracking =
|
||||
pezkuwi_subxt::dynamic::tx("StakingScore", "start_score_tracking", Vec::<Value>::new());
|
||||
|
||||
let progress = api
|
||||
.tx()
|
||||
.sign_and_submit_then_watch_default(&start_tracking, &validator_keypair)
|
||||
.await?;
|
||||
println!("TX: 0x{}", hex::encode(progress.extrinsic_hash().as_ref()));
|
||||
|
||||
match progress.wait_for_finalized_success().await {
|
||||
Ok(events) => {
|
||||
println!("start_score_tracking SUCCESS!");
|
||||
for ev in events.iter() {
|
||||
if let Ok(ev) = ev {
|
||||
let p = ev.pallet_name();
|
||||
if p == "StakingScore" || p == "Trust" || p == "System" {
|
||||
println!(" {}::{}", p, ev.variant_name());
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
println!("start_score_tracking FAILED: {:?}", e);
|
||||
},
|
||||
}
|
||||
|
||||
// Step 3: Verify StakingStartBlock was set
|
||||
println!("\n--- Step 3: Verify StakingStartBlock ---");
|
||||
|
||||
let query = pezkuwi_subxt::dynamic::storage::<(AccountId32,), Value>(
|
||||
"StakingScore",
|
||||
"StakingStartBlock",
|
||||
);
|
||||
let storage = api.storage().at_latest().await?;
|
||||
match storage.entry(query)?.try_fetch((validator_account.clone(),)).await? {
|
||||
Some(val) => {
|
||||
let decoded = val.decode()?;
|
||||
println!("StakingStartBlock for validator: {:?}", decoded);
|
||||
},
|
||||
None => {
|
||||
println!("StakingStartBlock: NOT SET (ERROR!)");
|
||||
},
|
||||
}
|
||||
|
||||
// Step 4: Check TrustScore
|
||||
println!("\n--- Step 4: Check TrustScore ---");
|
||||
let query = pezkuwi_subxt::dynamic::storage::<(AccountId32,), Value>("Trust", "TrustScores");
|
||||
match storage.entry(query)?.try_fetch((validator_account.clone(),)).await? {
|
||||
Some(val) => {
|
||||
let decoded = val.decode()?;
|
||||
println!("TrustScore for validator: {:?}", decoded);
|
||||
},
|
||||
None => {
|
||||
println!("TrustScore: NOT SET (may need on_initialize cycle)");
|
||||
},
|
||||
}
|
||||
|
||||
println!("\n=== TEST COMPLETE ===");
|
||||
Ok(())
|
||||
}
|
||||
+16
-31
@@ -44,14 +44,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
];
|
||||
|
||||
let url = std::env::var("RPC_URL").unwrap_or_else(|_| "ws://217.77.6.126:9944".to_string());
|
||||
let amount_hez: u128 = std::env::var("AMOUNT_HEZ")
|
||||
.unwrap_or_else(|_| "500000".to_string())
|
||||
.parse()?;
|
||||
let amount_hez: u128 =
|
||||
std::env::var("AMOUNT_HEZ").unwrap_or_else(|_| "500000".to_string()).parse()?;
|
||||
let amount_planck = amount_hez * PLANCKS_PER_HEZ;
|
||||
let skip: usize = std::env::var("SKIP")
|
||||
.unwrap_or_else(|_| "0".to_string())
|
||||
.parse()
|
||||
.unwrap_or(0);
|
||||
let skip: usize =
|
||||
std::env::var("SKIP").unwrap_or_else(|_| "0".to_string()).parse().unwrap_or(0);
|
||||
|
||||
println!("RPC: {}", url);
|
||||
println!("Amount per validator: {} HEZ ({} TYR)", amount_hez, amount_planck);
|
||||
@@ -100,23 +97,17 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut tx_ok = false;
|
||||
|
||||
for attempt in 0..3 {
|
||||
let tx_progress = match api
|
||||
.tx()
|
||||
.sign_and_submit_then_watch_default(&transfer_tx, &keypair)
|
||||
.await
|
||||
{
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
println!(" SUBMIT ERROR (attempt {}): {}", attempt + 1, e);
|
||||
tokio::time::sleep(std::time::Duration::from_secs(12)).await;
|
||||
continue;
|
||||
},
|
||||
};
|
||||
let tx_progress =
|
||||
match api.tx().sign_and_submit_then_watch_default(&transfer_tx, &keypair).await {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
println!(" SUBMIT ERROR (attempt {}): {}", attempt + 1, e);
|
||||
tokio::time::sleep(std::time::Duration::from_secs(12)).await;
|
||||
continue;
|
||||
},
|
||||
};
|
||||
|
||||
println!(
|
||||
" TX: 0x{}",
|
||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
||||
);
|
||||
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||
|
||||
let mut progress = tx_progress;
|
||||
loop {
|
||||
@@ -130,10 +121,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
if ev.pallet_name() == "Balances"
|
||||
&& ev.variant_name() == "Transfer"
|
||||
{
|
||||
println!(
|
||||
" SUCCESS: {} HEZ transferred",
|
||||
amount_hez
|
||||
);
|
||||
println!(" SUCCESS: {} HEZ transferred", amount_hez);
|
||||
tx_ok = true;
|
||||
}
|
||||
}
|
||||
@@ -200,10 +188,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("\n=== RESULTS ===");
|
||||
println!("Success: {}/{}", success_count, validators.len() - skip);
|
||||
println!("Failed: {}/{}", fail_count, validators.len() - skip);
|
||||
println!(
|
||||
"Total transferred: {} HEZ",
|
||||
amount_hez * success_count as u128
|
||||
);
|
||||
println!("Total transferred: {} HEZ", amount_hez * success_count as u128);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
+90
-43
@@ -44,27 +44,90 @@ struct ValidatorInfo {
|
||||
|
||||
fn validators() -> Vec<ValidatorInfo> {
|
||||
vec![
|
||||
ValidatorInfo { name: "Çiyager (Cihat Türkan)", ss58: "5GipBJs2uNWTCazyZQ2vG3DEqLz4tXNmNZtBAT1Mtm1orZ5i" },
|
||||
ValidatorInfo { name: "Mehmet Tunç", ss58: "5HWFZbhkZuTUySXu6ZXYKrTHBnWXHvWRKLozE22zhnwXGGxk" },
|
||||
ValidatorInfo { name: "Nagihan Akarsel", ss58: "5CrB5BWJfLNWEZAsAXDKXdJUGzFMXKvYnwRX4DVMcgBwxSdx" },
|
||||
ValidatorInfo { name: "Sait Çürükkaya (Doktor Süleyman)", ss58: "5ELgySrX5ZyK7EWXjj6bAedyTCcTNWDANbiiipsT5gnpoCEp" },
|
||||
ValidatorInfo { name: "Evdile Koçer", ss58: "5GCZQNjRdHofEHPvVq4ePrfDYcjRzQ1HQ2awHMX6AawpRYuM" },
|
||||
ValidatorInfo { name: "Mam Zeki", ss58: "5H8jTzi4Gm4rbFtXw6h5enhLhgsuhNAqR5K2itmPiz83ymWy" },
|
||||
ValidatorInfo { name: "Kakaî Falah", ss58: "5Fs3P5tHuL9cvwPQojsheViRRAjFkMMFa32jAkDSwW9mbTfU" },
|
||||
ValidatorInfo { name: "Feryad Fazil Ömer", ss58: "5DXgq7uDXog6zcubT3wgtaYosoibjudz4w5ScPW2phLuAy3V" },
|
||||
ValidatorInfo { name: "Mevlud Afand", ss58: "5FyFwbGLgPXun3azh6Gx83wCuUt5FTavb2WAVDYrjziVB9rN" },
|
||||
ValidatorInfo { name: "Şêrko Fatih Şivandî", ss58: "5HEcuuypLDeJaSj6ZgH57aXhuviyeLNdw9QrCDJ8u6gsnjnL" },
|
||||
ValidatorInfo { name: "Ramin Hüseyin Penahi", ss58: "5EpmpTXbMXpz6ixy3WhutdzcexzPbvybNKv4eiiN1kvTnQH5" },
|
||||
ValidatorInfo { name: "Zanyar Moradi", ss58: "5DFsm3BBEgHmSEZkvwGKB7c7tiH2avhfuQE1SEjfMDGuczsW" },
|
||||
ValidatorInfo { name: "Heidar Ghorbani", ss58: "5HePVUXjGSM2hVZ1YMz2V3KoX6EdQNEmmzUnUvpfGV95ofUR" },
|
||||
ValidatorInfo { name: "Farhad Salimi", ss58: "5GP4nAcwtETTg1oAHQNvevmmhG8GEstGQeCirKEhaDTwpFgx" },
|
||||
ValidatorInfo { name: "Vafa Azarbar", ss58: "5FYoCM3oeEGeoFY94EgXBhmABkRCabvPp72ur5bJNG3cK619" },
|
||||
ValidatorInfo { name: "Dr. Aziz Mihemed", ss58: "5GspwkKF6aYzFkmAyBBQg7coSCSgDCore79fbW8uxJNAH347" },
|
||||
ValidatorInfo { name: "Arîn Mîrkan", ss58: "5GmuX11pN2fC4Fyq1V7MuiYt3aevZcVQs3HZWKyzmap9bKfe" },
|
||||
ValidatorInfo { name: "Ebu Leyla", ss58: "5FQptVCtM1qsxkLbQkATkw4Kio4M9LxWvM6TwgEo3QjmTXF3" },
|
||||
ValidatorInfo { name: "Rêvan Kobanê", ss58: "5E7VD2qmso1yRfyq3t9u2qhauAgtmjZTybVsCARF5Zz9bXy6" },
|
||||
ValidatorInfo { name: "Amanj Babani", ss58: "5Ccz5W7Q21g4UPCytzHxD3VSMLJ1BbbWSkJKFwsNtYRk3HkX" },
|
||||
ValidatorInfo { name: "Xosrow Gulan", ss58: "5D7WPmK1SAJyYDdCtgqEzGJpWXQe3Lj9FqWL8z9waLTkUNv3" },
|
||||
ValidatorInfo {
|
||||
name: "Çiyager (Cihat Türkan)",
|
||||
ss58: "5GipBJs2uNWTCazyZQ2vG3DEqLz4tXNmNZtBAT1Mtm1orZ5i",
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Mehmet Tunç",
|
||||
ss58: "5HWFZbhkZuTUySXu6ZXYKrTHBnWXHvWRKLozE22zhnwXGGxk",
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Nagihan Akarsel",
|
||||
ss58: "5CrB5BWJfLNWEZAsAXDKXdJUGzFMXKvYnwRX4DVMcgBwxSdx",
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Sait Çürükkaya (Doktor Süleyman)",
|
||||
ss58: "5ELgySrX5ZyK7EWXjj6bAedyTCcTNWDANbiiipsT5gnpoCEp",
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Evdile Koçer",
|
||||
ss58: "5GCZQNjRdHofEHPvVq4ePrfDYcjRzQ1HQ2awHMX6AawpRYuM",
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Mam Zeki",
|
||||
ss58: "5H8jTzi4Gm4rbFtXw6h5enhLhgsuhNAqR5K2itmPiz83ymWy",
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Kakaî Falah",
|
||||
ss58: "5Fs3P5tHuL9cvwPQojsheViRRAjFkMMFa32jAkDSwW9mbTfU",
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Feryad Fazil Ömer",
|
||||
ss58: "5DXgq7uDXog6zcubT3wgtaYosoibjudz4w5ScPW2phLuAy3V",
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Mevlud Afand",
|
||||
ss58: "5FyFwbGLgPXun3azh6Gx83wCuUt5FTavb2WAVDYrjziVB9rN",
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Şêrko Fatih Şivandî",
|
||||
ss58: "5HEcuuypLDeJaSj6ZgH57aXhuviyeLNdw9QrCDJ8u6gsnjnL",
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Ramin Hüseyin Penahi",
|
||||
ss58: "5EpmpTXbMXpz6ixy3WhutdzcexzPbvybNKv4eiiN1kvTnQH5",
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Zanyar Moradi",
|
||||
ss58: "5DFsm3BBEgHmSEZkvwGKB7c7tiH2avhfuQE1SEjfMDGuczsW",
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Heidar Ghorbani",
|
||||
ss58: "5HePVUXjGSM2hVZ1YMz2V3KoX6EdQNEmmzUnUvpfGV95ofUR",
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Farhad Salimi",
|
||||
ss58: "5GP4nAcwtETTg1oAHQNvevmmhG8GEstGQeCirKEhaDTwpFgx",
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Vafa Azarbar",
|
||||
ss58: "5FYoCM3oeEGeoFY94EgXBhmABkRCabvPp72ur5bJNG3cK619",
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Dr. Aziz Mihemed",
|
||||
ss58: "5GspwkKF6aYzFkmAyBBQg7coSCSgDCore79fbW8uxJNAH347",
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Arîn Mîrkan",
|
||||
ss58: "5GmuX11pN2fC4Fyq1V7MuiYt3aevZcVQs3HZWKyzmap9bKfe",
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Ebu Leyla",
|
||||
ss58: "5FQptVCtM1qsxkLbQkATkw4Kio4M9LxWvM6TwgEo3QjmTXF3",
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Rêvan Kobanê",
|
||||
ss58: "5E7VD2qmso1yRfyq3t9u2qhauAgtmjZTybVsCARF5Zz9bXy6",
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Amanj Babani",
|
||||
ss58: "5Ccz5W7Q21g4UPCytzHxD3VSMLJ1BbbWSkJKFwsNtYRk3HkX",
|
||||
},
|
||||
ValidatorInfo {
|
||||
name: "Xosrow Gulan",
|
||||
ss58: "5D7WPmK1SAJyYDdCtgqEzGJpWXQe3Lj9FqWL8z9waLTkUNv3",
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@@ -207,10 +270,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
let relay_url =
|
||||
std::env::var("RPC_URL").unwrap_or_else(|_| "ws://217.77.6.126:9944".to_string());
|
||||
let skip: usize = std::env::var("SKIP")
|
||||
.unwrap_or_else(|_| "0".to_string())
|
||||
.parse()
|
||||
.unwrap_or(0);
|
||||
let skip: usize =
|
||||
std::env::var("SKIP").unwrap_or_else(|_| "0".to_string()).parse().unwrap_or(0);
|
||||
|
||||
let vals = validators();
|
||||
println!("Relay RPC: {}", relay_url);
|
||||
@@ -223,10 +284,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
// Connect to relay chain
|
||||
let api = OnlineClient::<PezkuwiConfig>::from_insecure_url(&relay_url).await?;
|
||||
println!(
|
||||
"Connected! specVersion: {}\n",
|
||||
api.runtime_version().spec_version
|
||||
);
|
||||
println!("Connected! specVersion: {}\n", api.runtime_version().spec_version);
|
||||
|
||||
// Load sudo keypair
|
||||
let mnemonic_str =
|
||||
@@ -281,11 +339,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
use pezkuwi_subxt::tx::TxStatus;
|
||||
let mut tx_progress_opt = None;
|
||||
for attempt in 0..3 {
|
||||
match api
|
||||
.tx()
|
||||
.sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair)
|
||||
.await
|
||||
{
|
||||
match api.tx().sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair).await {
|
||||
Ok(p) => {
|
||||
tx_progress_opt = Some(p);
|
||||
break;
|
||||
@@ -306,10 +360,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
},
|
||||
};
|
||||
|
||||
println!(
|
||||
" TX: 0x{}",
|
||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
||||
);
|
||||
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||
|
||||
let mut progress = tx_progress;
|
||||
let mut tx_ok = false;
|
||||
@@ -340,11 +391,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!(" WARNING: Events:");
|
||||
for event in events.iter() {
|
||||
if let Ok(ev) = event {
|
||||
println!(
|
||||
" {}::{}",
|
||||
ev.pallet_name(),
|
||||
ev.variant_name()
|
||||
);
|
||||
println!(" {}::{}", ev.pallet_name(), ev.variant_name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-22
@@ -74,11 +74,7 @@ async fn submit_and_watch(
|
||||
tokio::time::sleep(std::time::Duration::from_secs(18)).await;
|
||||
}
|
||||
|
||||
let tx_progress = match api
|
||||
.tx()
|
||||
.sign_and_submit_then_watch_default(&tx, signer)
|
||||
.await
|
||||
{
|
||||
let tx_progress = match api.tx().sign_and_submit_then_watch_default(&tx, signer).await {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
println!(" SUBMIT ERROR (attempt {}): {}", attempt + 1, e);
|
||||
@@ -86,10 +82,7 @@ async fn submit_and_watch(
|
||||
},
|
||||
};
|
||||
|
||||
println!(
|
||||
" TX: 0x{}",
|
||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
||||
);
|
||||
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||
|
||||
let mut progress = tx_progress;
|
||||
loop {
|
||||
@@ -101,11 +94,7 @@ async fn submit_and_watch(
|
||||
println!(" {} SUCCESS!", label);
|
||||
for event in events.iter() {
|
||||
if let Ok(ev) = event {
|
||||
println!(
|
||||
" {}::{}",
|
||||
ev.pallet_name(),
|
||||
ev.variant_name()
|
||||
);
|
||||
println!(" {}::{}", ev.pallet_name(), ev.variant_name());
|
||||
}
|
||||
}
|
||||
return Ok(true);
|
||||
@@ -148,10 +137,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let ws = load_wallets();
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
let phase = args.get(1).map(|s| s.as_str()).unwrap_or("all");
|
||||
let skip: usize = std::env::var("SKIP")
|
||||
.unwrap_or_else(|_| "0".to_string())
|
||||
.parse()
|
||||
.unwrap_or(0);
|
||||
let skip: usize =
|
||||
std::env::var("SKIP").unwrap_or_else(|_| "0".to_string()).parse().unwrap_or(0);
|
||||
let rpc = std::env::var("PEOPLE_RPC").unwrap_or_else(|_| DEFAULT_PEOPLE_RPC.to_string());
|
||||
|
||||
println!("=== WELATI CITIZENSHIP WORKFLOW ===");
|
||||
@@ -222,10 +209,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let tx = pezkuwi_subxt::dynamic::tx(
|
||||
"IdentityKyc",
|
||||
"apply_for_citizenship",
|
||||
vec![
|
||||
Value::from_bytes(&identity_hash),
|
||||
Value::unnamed_variant("None", vec![]),
|
||||
],
|
||||
vec![Value::from_bytes(&identity_hash), Value::unnamed_variant("None", vec![])],
|
||||
);
|
||||
|
||||
let ok = submit_and_watch(&api, tx, &keypair, "APPLY").await?;
|
||||
|
||||
+16
-59
@@ -45,9 +45,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("=== ZAGROS: VALIDATOR DEREGISTRATION ===\n");
|
||||
|
||||
let url = std::env::var("RPC_URL").unwrap_or_else(|_| "ws://217.77.6.126:9948".to_string());
|
||||
let keep: usize = std::env::var("KEEP")
|
||||
.unwrap_or_else(|_| "2".to_string())
|
||||
.parse()?;
|
||||
let keep: usize = std::env::var("KEEP").unwrap_or_else(|_| "2".to_string()).parse()?;
|
||||
let execute = std::env::var("EXECUTE").unwrap_or_default() == "1";
|
||||
|
||||
println!("RPC: {}", url);
|
||||
@@ -61,15 +59,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// QueuedKeys = Vec<(ValidatorId, Keys)>
|
||||
// Storage key: twox128("Session") + twox128("QueuedKeys")
|
||||
let queued_keys_key =
|
||||
hex::decode("cec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903")
|
||||
.unwrap();
|
||||
hex::decode("cec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903").unwrap();
|
||||
|
||||
let raw_data = api
|
||||
.storage()
|
||||
.at_latest()
|
||||
.await?
|
||||
.fetch_raw(queued_keys_key)
|
||||
.await?;
|
||||
let raw_data = api.storage().at_latest().await?.fetch_raw(queued_keys_key).await?;
|
||||
|
||||
if raw_data.is_empty() {
|
||||
println!("ERROR: QueuedKeys storage is empty!");
|
||||
@@ -95,33 +87,18 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// But we need to verify this. Let's compute expected total size:
|
||||
let expected_entry_size = 32 + (32 * 6 + 33); // 257
|
||||
let expected_total = 1 + (count * expected_entry_size); // 1 byte compact + entries
|
||||
println!(
|
||||
"Expected data size: {} bytes, actual: {} bytes",
|
||||
expected_total,
|
||||
raw_data.len()
|
||||
);
|
||||
println!("Expected data size: {} bytes, actual: {} bytes", expected_total, raw_data.len());
|
||||
|
||||
if raw_data.len() < offset + count * expected_entry_size {
|
||||
// Try without beefy (older runtime might not have it)
|
||||
let entry_no_beefy = 32 + (32 * 6); // 224
|
||||
let expected_no_beefy = 1 + (count * entry_no_beefy);
|
||||
println!(
|
||||
"Without beefy: expected {} bytes",
|
||||
expected_no_beefy
|
||||
);
|
||||
println!("Without beefy: expected {} bytes", expected_no_beefy);
|
||||
|
||||
if raw_data.len() >= offset + count * entry_no_beefy {
|
||||
println!("Using SessionKeys without Beefy (6 keys x 32 bytes)");
|
||||
extract_and_process(
|
||||
&raw_data,
|
||||
offset,
|
||||
count,
|
||||
entry_no_beefy,
|
||||
keep,
|
||||
execute,
|
||||
&api,
|
||||
)
|
||||
.await?;
|
||||
extract_and_process(&raw_data, offset, count, entry_no_beefy, keep, execute, &api)
|
||||
.await?;
|
||||
} else {
|
||||
// Auto-detect entry size
|
||||
let remaining = raw_data.len() - offset;
|
||||
@@ -130,21 +107,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
"Auto-detected entry size: {} bytes (remaining={}, count={})",
|
||||
entry_size, remaining, count
|
||||
);
|
||||
extract_and_process(&raw_data, offset, count, entry_size, keep, execute, &api)
|
||||
.await?;
|
||||
extract_and_process(&raw_data, offset, count, entry_size, keep, execute, &api).await?;
|
||||
}
|
||||
} else {
|
||||
println!("Using SessionKeys with Beefy (6 keys x 32 + 33 beefy)");
|
||||
extract_and_process(
|
||||
&raw_data,
|
||||
offset,
|
||||
count,
|
||||
expected_entry_size,
|
||||
keep,
|
||||
execute,
|
||||
&api,
|
||||
)
|
||||
.await?;
|
||||
extract_and_process(&raw_data, offset, count, expected_entry_size, keep, execute, &api)
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -202,22 +170,16 @@ async fn extract_and_process(
|
||||
vec![Value::unnamed_composite(validators_value)],
|
||||
);
|
||||
|
||||
let sudo_call =
|
||||
pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![deregister_call.into_value()]);
|
||||
let sudo_call = pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![deregister_call.into_value()]);
|
||||
|
||||
println!("Submitting sudo(validatorManager.deregister_validators)...\n");
|
||||
|
||||
use pezkuwi_subxt::tx::TxStatus;
|
||||
|
||||
let tx_progress = api
|
||||
.tx()
|
||||
.sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair)
|
||||
.await?;
|
||||
let tx_progress =
|
||||
api.tx().sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair).await?;
|
||||
|
||||
println!(
|
||||
" TX: 0x{}",
|
||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
||||
);
|
||||
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||
|
||||
let mut progress = tx_progress;
|
||||
let mut success = false;
|
||||
@@ -237,9 +199,7 @@ async fn extract_and_process(
|
||||
if ev.pallet_name() == "ValidatorManager"
|
||||
&& ev.variant_name() == "ValidatorsDeregistered"
|
||||
{
|
||||
println!(
|
||||
" >>> ValidatorsDeregistered event confirmed!"
|
||||
);
|
||||
println!(" >>> ValidatorsDeregistered event confirmed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -273,10 +233,7 @@ async fn extract_and_process(
|
||||
}
|
||||
|
||||
if success {
|
||||
println!(
|
||||
"\nSUCCESS! {} validators queued for deregistration.",
|
||||
to_remove.len()
|
||||
);
|
||||
println!("\nSUCCESS! {} validators queued for deregistration.", to_remove.len());
|
||||
println!("The change will take effect at current_session + 2.");
|
||||
println!("Monitor GRANDPA authorities to confirm.");
|
||||
} else {
|
||||
|
||||
+17
-40
@@ -26,11 +26,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
// Storage keys
|
||||
let queued_keys_key =
|
||||
hex::decode("cec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903")
|
||||
.unwrap();
|
||||
hex::decode("cec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903").unwrap();
|
||||
let validators_to_retire_key =
|
||||
hex::decode("084e7f70a295a190e2e33fd3f8cdfcc2b664fa73499821e43a617aa0e82b17b1")
|
||||
.unwrap();
|
||||
hex::decode("084e7f70a295a190e2e33fd3f8cdfcc2b664fa73499821e43a617aa0e82b17b1").unwrap();
|
||||
|
||||
// Step 1: Check ValidatorsToRetire BEFORE
|
||||
println!("=== STEP 1: Check ValidatorsToRetire BEFORE deregister ===");
|
||||
@@ -43,20 +41,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
if retire_before.is_empty() {
|
||||
println!(" ValidatorsToRetire: EMPTY (as expected)\n");
|
||||
} else {
|
||||
println!(
|
||||
" ValidatorsToRetire: {} bytes (already has data!)\n",
|
||||
retire_before.len()
|
||||
);
|
||||
println!(" ValidatorsToRetire: {} bytes (already has data!)\n", retire_before.len());
|
||||
}
|
||||
|
||||
// Step 2: Get validator #5 from QueuedKeys
|
||||
println!("=== STEP 2: Get test validator from QueuedKeys ===");
|
||||
let raw_data = api
|
||||
.storage()
|
||||
.at_latest()
|
||||
.await?
|
||||
.fetch_raw(queued_keys_key)
|
||||
.await?;
|
||||
let raw_data = api.storage().at_latest().await?.fetch_raw(queued_keys_key).await?;
|
||||
let count = (raw_data[0] >> 2) as usize;
|
||||
let remaining = raw_data.len() - 1;
|
||||
let entry_size = remaining / count;
|
||||
@@ -70,10 +60,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Get validator #5 (index 4, the first one to remove)
|
||||
let test_offset = 1 + 4 * entry_size;
|
||||
let test_validator = raw_data[test_offset..test_offset + 32].to_vec();
|
||||
println!(
|
||||
" Test validator (index 5): 0x{}\n",
|
||||
hex::encode(&test_validator)
|
||||
);
|
||||
println!(" Test validator (index 5): 0x{}\n", hex::encode(&test_validator));
|
||||
|
||||
// Step 3: Load sudo key and submit deregister for ONE validator
|
||||
println!("=== STEP 3: Submit deregister for ONE validator ===");
|
||||
@@ -81,10 +68,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
std::env::var("SUDO_MNEMONIC").expect("SUDO_MNEMONIC environment variable required");
|
||||
let mnemonic = Mnemonic::from_str(&mnemonic_str)?;
|
||||
let sudo_keypair = Keypair::from_phrase(&mnemonic, None)?;
|
||||
println!(
|
||||
" Sudo account: {}",
|
||||
sudo_keypair.public_key().to_account_id()
|
||||
);
|
||||
println!(" Sudo account: {}", sudo_keypair.public_key().to_account_id());
|
||||
|
||||
// Try TWO different encoding approaches
|
||||
|
||||
@@ -110,22 +94,16 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Print the encoded call data to debug
|
||||
println!("\n Deregister call value: {:?}", deregister_call.call_data());
|
||||
|
||||
let sudo_call =
|
||||
pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![deregister_call.into_value()]);
|
||||
let sudo_call = pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![deregister_call.into_value()]);
|
||||
|
||||
println!("\n Submitting sudo(validatorManager.deregister_validators([1 validator]))...");
|
||||
|
||||
use pezkuwi_subxt::tx::TxStatus;
|
||||
|
||||
let tx_progress = api
|
||||
.tx()
|
||||
.sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair)
|
||||
.await?;
|
||||
let tx_progress =
|
||||
api.tx().sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair).await?;
|
||||
|
||||
println!(
|
||||
" TX: 0x{}",
|
||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
||||
);
|
||||
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||
|
||||
let mut progress = tx_progress;
|
||||
let mut success = false;
|
||||
@@ -146,11 +124,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
&& ev.variant_name() == "ValidatorsDeregistered"
|
||||
{
|
||||
// Try to decode the event data
|
||||
println!(
|
||||
" >>> ValidatorsDeregistered event!"
|
||||
);
|
||||
println!(" >>> ValidatorsDeregistered event!");
|
||||
let bytes = ev.field_bytes();
|
||||
println!(" >>> Event field bytes ({} bytes): 0x{}", bytes.len(), hex::encode(&bytes[..std::cmp::min(bytes.len(), 128)]));
|
||||
println!(
|
||||
" >>> Event field bytes ({} bytes): 0x{}",
|
||||
bytes.len(),
|
||||
hex::encode(&bytes[..std::cmp::min(bytes.len(), 128)])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,10 +184,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!(" ValidatorsToRetire: EMPTY !!! (deregister didn't populate storage!)");
|
||||
println!(" THIS IS THE BUG!");
|
||||
} else {
|
||||
println!(
|
||||
" ValidatorsToRetire: {} bytes",
|
||||
retire_after.len()
|
||||
);
|
||||
println!(" ValidatorsToRetire: {} bytes", retire_after.len());
|
||||
println!(" Raw hex: 0x{}", hex::encode(&retire_after));
|
||||
|
||||
// Decode it
|
||||
|
||||
@@ -32,8 +32,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let force_era_call =
|
||||
pezkuwi_subxt::dynamic::tx("Staking", "force_new_era", Vec::<Value>::new());
|
||||
|
||||
let sudo_tx =
|
||||
pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![force_era_call.into_value()]);
|
||||
let sudo_tx = pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![force_era_call.into_value()]);
|
||||
|
||||
let tx_hash = api.tx().sign_and_submit_default(&sudo_tx, &sudo_keypair).await?;
|
||||
println!("Submitted! TX hash: 0x{}", hex::encode(tx_hash.as_ref()));
|
||||
|
||||
@@ -21,9 +21,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("=== ZAGROS VALIDATOR COUNT REDUCTION ===\n");
|
||||
|
||||
let url = std::env::var("RPC_URL").unwrap_or_else(|_| "ws://217.77.6.126:9948".to_string());
|
||||
let new_count: u32 = std::env::var("VALIDATOR_COUNT")
|
||||
.unwrap_or_else(|_| "4".to_string())
|
||||
.parse()?;
|
||||
let new_count: u32 =
|
||||
std::env::var("VALIDATOR_COUNT").unwrap_or_else(|_| "4".to_string()).parse()?;
|
||||
|
||||
println!("RPC: {}", url);
|
||||
println!("Target validator count: {}", new_count);
|
||||
@@ -43,12 +42,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Step 1: sudo(staking.setValidatorCount(new_count))
|
||||
println!("[1/2] Setting validator count to {}...", new_count);
|
||||
|
||||
let set_count_call = pezkuwi_subxt::dynamic::tx("Staking", "set_validator_count", vec![
|
||||
Value::u128(new_count as u128),
|
||||
]);
|
||||
let set_count_call = pezkuwi_subxt::dynamic::tx(
|
||||
"Staking",
|
||||
"set_validator_count",
|
||||
vec![Value::u128(new_count as u128)],
|
||||
);
|
||||
|
||||
let sudo_tx_1 =
|
||||
pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![set_count_call.into_value()]);
|
||||
let sudo_tx_1 = pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![set_count_call.into_value()]);
|
||||
|
||||
// Use sign_and_submit_default (does NOT wait for finalization)
|
||||
let tx_hash_1 = api.tx().sign_and_submit_default(&sudo_tx_1, &sudo_keypair).await?;
|
||||
@@ -64,8 +64,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let force_era_call =
|
||||
pezkuwi_subxt::dynamic::tx("Staking", "force_new_era", Vec::<Value>::new());
|
||||
|
||||
let sudo_tx_2 =
|
||||
pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![force_era_call.into_value()]);
|
||||
let sudo_tx_2 = pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![force_era_call.into_value()]);
|
||||
|
||||
let tx_hash_2 = api.tx().sign_and_submit_default(&sudo_tx_2, &sudo_keypair).await?;
|
||||
println!(" Submitted! TX hash: 0x{}", hex::encode(tx_hash_2.as_ref()));
|
||||
|
||||
+14
-51
@@ -30,24 +30,16 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("=== ZAGROS: SET ValidatorsToRetire via setStorage ===\n");
|
||||
|
||||
let url = std::env::var("RPC_URL").unwrap_or_else(|_| "ws://217.77.6.126:9948".to_string());
|
||||
let keep: usize = std::env::var("KEEP")
|
||||
.unwrap_or_else(|_| "4".to_string())
|
||||
.parse()?;
|
||||
let keep: usize = std::env::var("KEEP").unwrap_or_else(|_| "4".to_string()).parse()?;
|
||||
|
||||
println!("RPC: {}", url);
|
||||
println!("Keep: {} validators\n", keep);
|
||||
|
||||
let api = OnlineClient::<PezkuwiConfig>::from_insecure_url(&url).await?;
|
||||
println!(
|
||||
"Connected! specVersion: {}\n",
|
||||
api.runtime_version().spec_version
|
||||
);
|
||||
println!("Connected! specVersion: {}\n", api.runtime_version().spec_version);
|
||||
|
||||
// Verify genesis hash (Zagros = 0xbb4a61ab...)
|
||||
let genesis = format!(
|
||||
"0x{}",
|
||||
hex::encode(api.genesis_hash().as_ref())
|
||||
);
|
||||
let genesis = format!("0x{}", hex::encode(api.genesis_hash().as_ref()));
|
||||
println!("Genesis: {}", genesis);
|
||||
if !genesis.starts_with("0xbb4a61ab") {
|
||||
println!("ERROR: This is NOT Zagros! Aborting.");
|
||||
@@ -57,15 +49,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
// Read QueuedKeys to get all validator AccountIds
|
||||
let queued_keys_key =
|
||||
hex::decode("cec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903")
|
||||
.unwrap();
|
||||
hex::decode("cec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903").unwrap();
|
||||
|
||||
let raw_data = api
|
||||
.storage()
|
||||
.at_latest()
|
||||
.await?
|
||||
.fetch_raw(queued_keys_key)
|
||||
.await?;
|
||||
let raw_data = api.storage().at_latest().await?.fetch_raw(queued_keys_key).await?;
|
||||
|
||||
let count = (raw_data[0] >> 2) as usize;
|
||||
let remaining = raw_data.len() - 1;
|
||||
@@ -101,10 +87,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
for v in to_remove {
|
||||
encoded_retire.extend_from_slice(v);
|
||||
}
|
||||
println!(
|
||||
"\nSCALE-encoded ValidatorsToRetire: {} bytes",
|
||||
encoded_retire.len()
|
||||
);
|
||||
println!("\nSCALE-encoded ValidatorsToRetire: {} bytes", encoded_retire.len());
|
||||
println!(
|
||||
" compact_length: 0x{} (count={})",
|
||||
hex::encode(&encode_compact(to_remove.len())),
|
||||
@@ -113,13 +96,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
// Storage key for ValidatorsToRetire
|
||||
let validators_to_retire_key =
|
||||
hex::decode("084e7f70a295a190e2e33fd3f8cdfcc2b664fa73499821e43a617aa0e82b17b1")
|
||||
.unwrap();
|
||||
hex::decode("084e7f70a295a190e2e33fd3f8cdfcc2b664fa73499821e43a617aa0e82b17b1").unwrap();
|
||||
|
||||
println!(
|
||||
"\nStorage key: 0x{}",
|
||||
hex::encode(&validators_to_retire_key)
|
||||
);
|
||||
println!("\nStorage key: 0x{}", hex::encode(&validators_to_retire_key));
|
||||
println!(
|
||||
"Storage value: 0x{}...({} bytes)",
|
||||
hex::encode(&encoded_retire[..std::cmp::min(encoded_retire.len(), 40)]),
|
||||
@@ -131,10 +110,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
std::env::var("SUDO_MNEMONIC").expect("SUDO_MNEMONIC environment variable required");
|
||||
let mnemonic = Mnemonic::from_str(&mnemonic_str)?;
|
||||
let sudo_keypair = Keypair::from_phrase(&mnemonic, None)?;
|
||||
println!(
|
||||
"\nSudo account: {}",
|
||||
sudo_keypair.public_key().to_account_id()
|
||||
);
|
||||
println!("\nSudo account: {}", sudo_keypair.public_key().to_account_id());
|
||||
|
||||
// Build sudo(system.setStorage(items))
|
||||
let set_storage_tx = pezkuwi_subxt::dynamic::tx(
|
||||
@@ -152,15 +128,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
use pezkuwi_subxt::tx::TxStatus;
|
||||
|
||||
let tx_progress = api
|
||||
.tx()
|
||||
.sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair)
|
||||
.await?;
|
||||
let tx_progress =
|
||||
api.tx().sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair).await?;
|
||||
|
||||
println!(
|
||||
" TX: 0x{}",
|
||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
||||
);
|
||||
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||
|
||||
let mut progress = tx_progress;
|
||||
let mut success = false;
|
||||
@@ -230,19 +201,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
{
|
||||
Ok(data) => {
|
||||
let stored_count = (data[0] >> 2) as usize;
|
||||
println!(
|
||||
"ValidatorsToRetire: {} entries ({} bytes)",
|
||||
stored_count,
|
||||
data.len()
|
||||
);
|
||||
println!("ValidatorsToRetire: {} entries ({} bytes)", stored_count, data.len());
|
||||
if stored_count == to_remove.len() {
|
||||
println!("COUNT MATCHES! Storage write successful.");
|
||||
} else {
|
||||
println!(
|
||||
"COUNT MISMATCH! Expected {}, got {}",
|
||||
to_remove.len(),
|
||||
stored_count
|
||||
);
|
||||
println!("COUNT MISMATCH! Expected {}, got {}", to_remove.len(), stored_count);
|
||||
}
|
||||
// Show first few
|
||||
let mut off = 1;
|
||||
|
||||
+32
-37
@@ -30,13 +30,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
let inner_call = match call_name.as_str() {
|
||||
"setValidatorCount" => {
|
||||
let count: u32 = std::env::var("COUNT")
|
||||
.unwrap_or_else(|_| "4".to_string())
|
||||
.parse()?;
|
||||
let count: u32 = std::env::var("COUNT").unwrap_or_else(|_| "4".to_string()).parse()?;
|
||||
println!("Setting validator count to {}", count);
|
||||
pezkuwi_subxt::dynamic::tx("Staking", "set_validator_count", vec![Value::u128(
|
||||
count as u128,
|
||||
)])
|
||||
pezkuwi_subxt::dynamic::tx(
|
||||
"Staking",
|
||||
"set_validator_count",
|
||||
vec![Value::u128(count as u128)],
|
||||
)
|
||||
},
|
||||
"forceNewEra" => {
|
||||
println!("Forcing new era");
|
||||
@@ -48,9 +48,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
},
|
||||
"setStakingConfigs" => {
|
||||
// Set min_validator_count to 1 via set_staking_configs
|
||||
let min_count: u32 = std::env::var("MIN_COUNT")
|
||||
.unwrap_or_else(|_| "1".to_string())
|
||||
.parse().unwrap();
|
||||
let min_count: u32 =
|
||||
std::env::var("MIN_COUNT").unwrap_or_else(|_| "1".to_string()).parse().unwrap();
|
||||
println!("Setting staking configs: min_nominator_bond=Noop, min_validator_bond=Noop, max_nominator_count=Noop, max_validator_count=Noop, chill_threshold=Noop, min_commission=Noop");
|
||||
// Actually we need to set min_validator_count directly
|
||||
// Let's use a different approach - call set_staking_configs with all Noop except what we need
|
||||
@@ -61,9 +60,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
std::process::exit(1);
|
||||
},
|
||||
"setMinValidatorCount" => {
|
||||
let min_count: u32 = std::env::var("MIN_COUNT")
|
||||
.unwrap_or_else(|_| "1".to_string())
|
||||
.parse().unwrap();
|
||||
let min_count: u32 =
|
||||
std::env::var("MIN_COUNT").unwrap_or_else(|_| "1".to_string()).parse().unwrap();
|
||||
println!("Setting minimum validator count to {}", min_count);
|
||||
// Staking::set_staking_configs sets all params at once
|
||||
// Instead we should check if there's a direct setter
|
||||
@@ -72,22 +70,24 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// ConfigOp: Noop=unnamed_variant("Noop",[]), Set=unnamed_variant("Set",[Value::u128(x)])
|
||||
let noop = Value::unnamed_variant("Noop", Vec::<Value>::new());
|
||||
let set_val = Value::unnamed_variant("Set", vec![Value::u128(min_count as u128)]);
|
||||
pezkuwi_subxt::dynamic::tx("Staking", "set_staking_configs", vec![
|
||||
noop.clone(), // min_nominator_bond
|
||||
noop.clone(), // min_validator_bond
|
||||
noop.clone(), // max_nominator_count
|
||||
noop.clone(), // max_validator_count
|
||||
noop.clone(), // chill_threshold
|
||||
noop.clone(), // min_commission
|
||||
noop.clone(), // max_staked_rewards (if exists)
|
||||
])
|
||||
pezkuwi_subxt::dynamic::tx(
|
||||
"Staking",
|
||||
"set_staking_configs",
|
||||
vec![
|
||||
noop.clone(), // min_nominator_bond
|
||||
noop.clone(), // min_validator_bond
|
||||
noop.clone(), // max_nominator_count
|
||||
noop.clone(), // max_validator_count
|
||||
noop.clone(), // chill_threshold
|
||||
noop.clone(), // min_commission
|
||||
noop.clone(), // max_staked_rewards (if exists)
|
||||
],
|
||||
)
|
||||
},
|
||||
"setStorage" => {
|
||||
// Set arbitrary storage via sudo(system.setStorage)
|
||||
let key_hex =
|
||||
std::env::var("STORAGE_KEY").expect("STORAGE_KEY env var required");
|
||||
let value_hex =
|
||||
std::env::var("STORAGE_VALUE").expect("STORAGE_VALUE env var required");
|
||||
let key_hex = std::env::var("STORAGE_KEY").expect("STORAGE_KEY env var required");
|
||||
let value_hex = std::env::var("STORAGE_VALUE").expect("STORAGE_VALUE env var required");
|
||||
println!("Setting storage key={} value={}", key_hex, value_hex);
|
||||
|
||||
let key_bytes = hex::decode(key_hex.trim_start_matches("0x")).unwrap();
|
||||
@@ -98,9 +98,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
Value::from_bytes(&key_bytes),
|
||||
Value::from_bytes(&value_bytes),
|
||||
]);
|
||||
pezkuwi_subxt::dynamic::tx("System", "set_storage", vec![
|
||||
Value::unnamed_composite([item]),
|
||||
])
|
||||
pezkuwi_subxt::dynamic::tx(
|
||||
"System",
|
||||
"set_storage",
|
||||
vec![Value::unnamed_composite([item])],
|
||||
)
|
||||
},
|
||||
_ => {
|
||||
eprintln!("Unknown call: {}", call_name);
|
||||
@@ -113,10 +115,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("\nSubmitting...");
|
||||
|
||||
// Use sign_and_submit_then_watch to see TX lifecycle
|
||||
let tx_progress = api
|
||||
.tx()
|
||||
.sign_and_submit_then_watch_default(&sudo_tx, &sudo_keypair)
|
||||
.await?;
|
||||
let tx_progress = api.tx().sign_and_submit_then_watch_default(&sudo_tx, &sudo_keypair).await?;
|
||||
|
||||
println!("TX hash: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||
println!("Watching TX status (Ctrl+C to abort)...");
|
||||
@@ -137,11 +136,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!(" TX SUCCESS!");
|
||||
for event in events.iter() {
|
||||
if let Ok(ev) = event {
|
||||
println!(
|
||||
" Event: {}::{}",
|
||||
ev.pallet_name(),
|
||||
ev.variant_name()
|
||||
);
|
||||
println!(" Event: {}::{}", ev.pallet_name(), ev.variant_name());
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
+32
-42
@@ -22,9 +22,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
let url = std::env::var("RPC_URL").unwrap_or_else(|_| "ws://217.77.6.126:9948".to_string());
|
||||
let wasm_path = std::env::var("WASM_FILE").expect("WASM_FILE environment variable required");
|
||||
let new_validator_count: u32 = std::env::var("VALIDATOR_COUNT")
|
||||
.unwrap_or_else(|_| "2".to_string())
|
||||
.parse()?;
|
||||
let new_validator_count: u32 =
|
||||
std::env::var("VALIDATOR_COUNT").unwrap_or_else(|_| "2".to_string()).parse()?;
|
||||
|
||||
println!("RPC: {}", url);
|
||||
println!("WASM: {}", wasm_path);
|
||||
@@ -32,7 +31,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
// Load WASM
|
||||
let wasm_data = std::fs::read(&wasm_path)?;
|
||||
println!("WASM size: {} bytes ({:.2} MB)", wasm_data.len(), wasm_data.len() as f64 / 1_048_576.0);
|
||||
println!(
|
||||
"WASM size: {} bytes ({:.2} MB)",
|
||||
wasm_data.len(),
|
||||
wasm_data.len() as f64 / 1_048_576.0
|
||||
);
|
||||
|
||||
// Connect
|
||||
let api = OnlineClient::<PezkuwiConfig>::from_insecure_url(&url).await?;
|
||||
@@ -58,13 +61,17 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
vec![Value::from_bytes(&wasm_data)],
|
||||
);
|
||||
|
||||
let sudo_upgrade = pezkuwi_subxt::dynamic::tx("Sudo", "sudo_unchecked_weight", vec![
|
||||
set_code.into_value(),
|
||||
Value::named_composite([
|
||||
("ref_time", Value::u128(1u128)),
|
||||
("proof_size", Value::u128(1u128)),
|
||||
]),
|
||||
]);
|
||||
let sudo_upgrade = pezkuwi_subxt::dynamic::tx(
|
||||
"Sudo",
|
||||
"sudo_unchecked_weight",
|
||||
vec![
|
||||
set_code.into_value(),
|
||||
Value::named_composite([
|
||||
("ref_time", Value::u128(1u128)),
|
||||
("proof_size", Value::u128(1u128)),
|
||||
]),
|
||||
],
|
||||
);
|
||||
|
||||
use pezkuwi_subxt::tx::TxStatus;
|
||||
|
||||
@@ -73,10 +80,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.sign_and_submit_then_watch_default(&sudo_upgrade, &sudo_keypair)
|
||||
.await?;
|
||||
|
||||
println!(
|
||||
" TX submitted: 0x{}",
|
||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
||||
);
|
||||
println!(" TX submitted: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||
|
||||
let mut progress = tx_progress;
|
||||
let mut upgrade_ok = false;
|
||||
@@ -152,11 +156,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Staking::ForceEra: 0x5f3e4907f716ac89b6347d15ececedcaf7dad0317324aecae8744b87fc95f2f3
|
||||
|
||||
let validator_count_key =
|
||||
hex::decode("5f3e4907f716ac89b6347d15ececedca138e71612491192d68deab7e6f563fe1")
|
||||
.unwrap();
|
||||
hex::decode("5f3e4907f716ac89b6347d15ececedca138e71612491192d68deab7e6f563fe1").unwrap();
|
||||
let force_era_key =
|
||||
hex::decode("5f3e4907f716ac89b6347d15ececedcaf7dad0317324aecae8744b87fc95f2f3")
|
||||
.unwrap();
|
||||
hex::decode("5f3e4907f716ac89b6347d15ececedcaf7dad0317324aecae8744b87fc95f2f3").unwrap();
|
||||
|
||||
// ValidatorCount is u32 LE
|
||||
let validator_count_value = new_validator_count.to_le_bytes().to_vec();
|
||||
@@ -166,8 +168,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("Setting ValidatorCount = {}", new_validator_count);
|
||||
println!("Setting ForceEra = ForceNew (0x01)");
|
||||
|
||||
let set_storage_tx = pezkuwi_subxt::dynamic::tx("System", "set_storage", vec![
|
||||
Value::unnamed_composite(vec![
|
||||
let set_storage_tx = pezkuwi_subxt::dynamic::tx(
|
||||
"System",
|
||||
"set_storage",
|
||||
vec![Value::unnamed_composite(vec![
|
||||
Value::unnamed_composite(vec![
|
||||
Value::from_bytes(&validator_count_key),
|
||||
Value::from_bytes(&validator_count_value),
|
||||
@@ -176,22 +180,18 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
Value::from_bytes(&force_era_key),
|
||||
Value::from_bytes(&force_era_value),
|
||||
]),
|
||||
]),
|
||||
]);
|
||||
])],
|
||||
);
|
||||
|
||||
let sudo_storage = pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![
|
||||
set_storage_tx.into_value(),
|
||||
]);
|
||||
let sudo_storage =
|
||||
pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![set_storage_tx.into_value()]);
|
||||
|
||||
let tx_progress2 = api2
|
||||
.tx()
|
||||
.sign_and_submit_then_watch_default(&sudo_storage, &sudo_keypair)
|
||||
.await?;
|
||||
|
||||
println!(
|
||||
" TX submitted: 0x{}",
|
||||
hex::encode(tx_progress2.extrinsic_hash().as_ref())
|
||||
);
|
||||
println!(" TX submitted: 0x{}", hex::encode(tx_progress2.extrinsic_hash().as_ref()));
|
||||
|
||||
let mut progress2 = tx_progress2;
|
||||
let mut storage_ok = false;
|
||||
@@ -256,23 +256,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("specVersion: {}", rv3.spec_version);
|
||||
|
||||
// Read back storage to verify
|
||||
let vc_bytes = api3
|
||||
.storage()
|
||||
.at_latest()
|
||||
.await?
|
||||
.fetch_raw(validator_count_key)
|
||||
.await?;
|
||||
let vc_bytes = api3.storage().at_latest().await?.fetch_raw(validator_count_key).await?;
|
||||
if vc_bytes.len() >= 4 {
|
||||
let vc = u32::from_le_bytes([vc_bytes[0], vc_bytes[1], vc_bytes[2], vc_bytes[3]]);
|
||||
println!("ValidatorCount: {}", vc);
|
||||
}
|
||||
|
||||
let fe_bytes = api3
|
||||
.storage()
|
||||
.at_latest()
|
||||
.await?
|
||||
.fetch_raw(force_era_key)
|
||||
.await?;
|
||||
let fe_bytes = api3.storage().at_latest().await?.fetch_raw(force_era_key).await?;
|
||||
if !fe_bytes.is_empty() {
|
||||
let fe_name = match fe_bytes[0] {
|
||||
0x00 => "NotForcing",
|
||||
|
||||
Reference in New Issue
Block a user