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:
@@ -1,6 +1,6 @@
|
|||||||
# PEZKUWI MAİNNET KRİTİK DURUM
|
# PEZKUWI MAİNNET KRİTİK DURUM
|
||||||
|
|
||||||
**Son Guncelleme:** 2026-02-15 UTC
|
**Son Guncelleme:** 2026-02-16 UTC
|
||||||
**Bu dosyayi her oturum basinda OKU!**
|
**Bu dosyayi her oturum basinda OKU!**
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -149,11 +149,22 @@ Note: Mnemonic stored locally, NOT in repo. Check /home/mamostehp/res/
|
|||||||
- [x] Zagros gereksiz validator servisleri temizlendi (~68GB kazanildi)
|
- [x] Zagros gereksiz validator servisleri temizlendi (~68GB kazanildi)
|
||||||
- [x] Zagros collator'lara --rpc-cors all eklendi
|
- [x] Zagros collator'lara --rpc-cors all eklendi
|
||||||
- [x] Zagros nginx Host header duzeltildi
|
- [x] Zagros nginx Host header duzeltildi
|
||||||
|
- [x] Noter delegasyonu ile staking score sistemi (People Chain spec 1_020_007)
|
||||||
|
|
||||||
### Bekleyen Isler
|
### Bekleyen Isler
|
||||||
1. [ ] Nova Wallet uyumluluk testi (NominationPoolsApi eklenince)
|
1. [ ] Nova Wallet uyumluluk testi (NominationPoolsApi eklenince)
|
||||||
2. [ ] Zagros teyrchain'leri 1_020_004'e upgrade et (relay zaten 1_020_004)
|
2. [ ] Zagros teyrchain'leri 1_020_004'e upgrade et (relay zaten 1_020_004)
|
||||||
3. [ ] Public RPC endpointlerini test et ve dokumanla
|
3. [ ] Public RPC endpointlerini test et ve dokumanla
|
||||||
|
4. [ ] People Chain runtime upgrade 1_020_006 → 1_020_007 (noter delegasyonu deploy)
|
||||||
|
5. [ ] Relay Chain: pezpallet_staking_score'u runtime'dan cikar (sonraki relay upgrade'de)
|
||||||
|
|
||||||
|
### Onemli Not: Relay Chain pezpallet_staking_score Uyumsuzlugu
|
||||||
|
Relay Chain runtime'inda (`pezkuwi/runtime/pezkuwichain/src/lib.rs:596`) eski bir
|
||||||
|
`pezpallet_staking_score::Config` implementasyonu var (`type StakingInfo`). Bu trait
|
||||||
|
palet kaynaginda artik mevcut degil — noter delegasyonu modeline gecildi.
|
||||||
|
**Mainnet:** Halihazirda calisan runtime (spec 1_020_004) eski binary ile derlendi,
|
||||||
|
sorun yok. Bir sonraki Relay Chain runtime upgrade'inde bu palet cikarilir.
|
||||||
|
Ayrica `welati/src/mock.rs` da ayni sekilde guncellenmeli.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
Generated
-1
@@ -14932,7 +14932,6 @@ dependencies = [
|
|||||||
"pezpallet-session-benchmarking",
|
"pezpallet-session-benchmarking",
|
||||||
"pezpallet-staking",
|
"pezpallet-staking",
|
||||||
"pezpallet-staking-runtime-api",
|
"pezpallet-staking-runtime-api",
|
||||||
"pezpallet-staking-score",
|
|
||||||
"pezpallet-state-trie-migration",
|
"pezpallet-state-trie-migration",
|
||||||
"pezpallet-sudo",
|
"pezpallet-sudo",
|
||||||
"pezpallet-timestamp",
|
"pezpallet-timestamp",
|
||||||
|
|||||||
@@ -27,12 +27,13 @@ serde = { version = "1.0.197", default-features = false, features = [
|
|||||||
# PezkuwiChain primitives
|
# PezkuwiChain primitives
|
||||||
pezkuwi-primitives = { workspace = true, default-features = false }
|
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]
|
[dev-dependencies]
|
||||||
pezframe-support = { workspace = true, features = ["std"] }
|
|
||||||
pezframe-system = { workspace = true, features = ["std"] }
|
|
||||||
pezpallet-balances = { workspace = true, features = ["std"] }
|
pezpallet-balances = { workspace = true, features = ["std"] }
|
||||||
pezsp-io = { workspace = true, features = ["std"] }
|
pezsp-io = { workspace = true, features = ["std"] }
|
||||||
pezsp-runtime = { workspace = true, features = ["std"] }
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
@@ -41,7 +42,9 @@ std = [
|
|||||||
"pezframe-benchmarking?/std",
|
"pezframe-benchmarking?/std",
|
||||||
"pezframe-support/std",
|
"pezframe-support/std",
|
||||||
"pezframe-system/std",
|
"pezframe-system/std",
|
||||||
|
"pezpallet-balances?/std",
|
||||||
"pezkuwi-primitives/std",
|
"pezkuwi-primitives/std",
|
||||||
|
"pezsp-io?/std",
|
||||||
"pezsp-runtime/std",
|
"pezsp-runtime/std",
|
||||||
"pezsp-std/std",
|
"pezsp-std/std",
|
||||||
"scale-info/std",
|
"scale-info/std",
|
||||||
@@ -53,6 +56,8 @@ runtime-benchmarks = [
|
|||||||
"pezframe-system/runtime-benchmarks",
|
"pezframe-system/runtime-benchmarks",
|
||||||
"pezkuwi-primitives/runtime-benchmarks",
|
"pezkuwi-primitives/runtime-benchmarks",
|
||||||
"pezsp-runtime/runtime-benchmarks",
|
"pezsp-runtime/runtime-benchmarks",
|
||||||
|
"pezpallet-balances/runtime-benchmarks",
|
||||||
|
"pezsp-io/runtime-benchmarks",
|
||||||
]
|
]
|
||||||
try-runtime = [
|
try-runtime = [
|
||||||
"pezframe-benchmarking?/try-runtime",
|
"pezframe-benchmarking?/try-runtime",
|
||||||
@@ -60,6 +65,7 @@ try-runtime = [
|
|||||||
"pezframe-system/try-runtime",
|
"pezframe-system/try-runtime",
|
||||||
"pezkuwi-primitives/try-runtime",
|
"pezkuwi-primitives/try-runtime",
|
||||||
"pezsp-runtime/try-runtime",
|
"pezsp-runtime/try-runtime",
|
||||||
|
"pezpallet-balances?/try-runtime"
|
||||||
]
|
]
|
||||||
serde = [
|
serde = [
|
||||||
"codec/serde",
|
"codec/serde",
|
||||||
|
|||||||
@@ -282,25 +282,12 @@ impl pezpallet_identity_kyc::Config for Test {
|
|||||||
type DefaultReferrer = DefaultReferrerKyc;
|
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
|
// Staking Score Configuration
|
||||||
impl pezpallet_staking_score::Config for Test {
|
impl pezpallet_staking_score::Config for Test {
|
||||||
type WeightInfo = ();
|
|
||||||
type Balance = Balance;
|
type Balance = Balance;
|
||||||
type StakingInfo = MockStakingInfo;
|
type OnStakingUpdate = ();
|
||||||
|
type WeightInfo = ();
|
||||||
|
type NoterChecker = ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Referral Configuration
|
// Referral Configuration
|
||||||
|
|||||||
@@ -111,7 +111,6 @@ pezkuwi-runtime-teyrchains = { workspace = true }
|
|||||||
pezkuwi-teyrchain-primitives = { workspace = true }
|
pezkuwi-teyrchain-primitives = { workspace = true }
|
||||||
|
|
||||||
# Custom Pezkuwi Pallets
|
# Custom Pezkuwi Pallets
|
||||||
pezpallet-staking-score = { workspace = true }
|
|
||||||
pezpallet-validator-pool = { workspace = true }
|
pezpallet-validator-pool = { workspace = true }
|
||||||
|
|
||||||
xcm = { workspace = true }
|
xcm = { workspace = true }
|
||||||
@@ -184,7 +183,6 @@ std = [
|
|||||||
"pezpallet-session-benchmarking?/std",
|
"pezpallet-session-benchmarking?/std",
|
||||||
"pezpallet-session/std",
|
"pezpallet-session/std",
|
||||||
"pezpallet-staking-runtime-api/std",
|
"pezpallet-staking-runtime-api/std",
|
||||||
"pezpallet-staking-score/std",
|
|
||||||
"pezpallet-staking/std",
|
"pezpallet-staking/std",
|
||||||
"pezpallet-state-trie-migration/std",
|
"pezpallet-state-trie-migration/std",
|
||||||
"pezpallet-sudo/std",
|
"pezpallet-sudo/std",
|
||||||
@@ -277,7 +275,6 @@ runtime-benchmarks = [
|
|||||||
"pezpallet-session-benchmarking/runtime-benchmarks",
|
"pezpallet-session-benchmarking/runtime-benchmarks",
|
||||||
"pezpallet-session/runtime-benchmarks",
|
"pezpallet-session/runtime-benchmarks",
|
||||||
"pezpallet-staking-runtime-api/runtime-benchmarks",
|
"pezpallet-staking-runtime-api/runtime-benchmarks",
|
||||||
"pezpallet-staking-score/runtime-benchmarks",
|
|
||||||
"pezpallet-staking/runtime-benchmarks",
|
"pezpallet-staking/runtime-benchmarks",
|
||||||
"pezpallet-state-trie-migration/runtime-benchmarks",
|
"pezpallet-state-trie-migration/runtime-benchmarks",
|
||||||
"pezpallet-sudo/runtime-benchmarks",
|
"pezpallet-sudo/runtime-benchmarks",
|
||||||
@@ -360,7 +357,6 @@ try-runtime = [
|
|||||||
"pezpallet-scheduler/try-runtime",
|
"pezpallet-scheduler/try-runtime",
|
||||||
"pezpallet-session-benchmarking?/try-runtime",
|
"pezpallet-session-benchmarking?/try-runtime",
|
||||||
"pezpallet-session/try-runtime",
|
"pezpallet-session/try-runtime",
|
||||||
"pezpallet-staking-score/try-runtime",
|
|
||||||
"pezpallet-staking/try-runtime",
|
"pezpallet-staking/try-runtime",
|
||||||
"pezpallet-state-trie-migration/try-runtime",
|
"pezpallet-state-trie-migration/try-runtime",
|
||||||
"pezpallet-sudo/try-runtime",
|
"pezpallet-sudo/try-runtime",
|
||||||
|
|||||||
@@ -565,40 +565,6 @@ impl pezpallet_staking::Config for Runtime {
|
|||||||
type BenchmarkingConfig = PezkuwiStakingBenchmarkingConfig;
|
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
|
// FAST UNSTAKE CONFIGURATION
|
||||||
// =====================================================
|
// =====================================================
|
||||||
@@ -1605,9 +1571,6 @@ construct_runtime! {
|
|||||||
// TNPoS Validator Pool - Shadow Mode (runs parallel to NPoS)
|
// TNPoS Validator Pool - Shadow Mode (runs parallel to NPoS)
|
||||||
ValidatorPool: pezpallet_validator_pool = 91,
|
ValidatorPool: pezpallet_validator_pool = 91,
|
||||||
|
|
||||||
// Staking Score - Time-weighted staking reputation score
|
|
||||||
StakingScore: pezpallet_staking_score = 92,
|
|
||||||
|
|
||||||
// Root testing pezpallet.
|
// Root testing pezpallet.
|
||||||
RootTesting: pezpallet_root_testing = 249,
|
RootTesting: pezpallet_root_testing = 249,
|
||||||
|
|
||||||
@@ -1859,7 +1822,6 @@ mod benches {
|
|||||||
[pezpallet_whitelist, Whitelist]
|
[pezpallet_whitelist, Whitelist]
|
||||||
// Pezkuwichain Custom Pallets
|
// Pezkuwichain Custom Pallets
|
||||||
[pezpallet_validator_pool, ValidatorPool]
|
[pezpallet_validator_pool, ValidatorPool]
|
||||||
[pezpallet_staking_score, StakingScore]
|
|
||||||
// XCM
|
// XCM
|
||||||
[pezpallet_xcm, PalletXcmExtrinsicsBenchmark::<Runtime>]
|
[pezpallet_xcm, PalletXcmExtrinsicsBenchmark::<Runtime>]
|
||||||
[pezpallet_xcm_benchmarks::fungible, pezpallet_xcm_benchmarks::fungible::Pezpallet::<Runtime>]
|
[pezpallet_xcm_benchmarks::fungible, pezpallet_xcm_benchmarks::fungible::Pezpallet::<Runtime>]
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "pezkuwi-sdk"
|
name = "pezkuwi-sdk"
|
||||||
version = "0.0.0"
|
|
||||||
description = "Pezkuwi SDK umbrella crate."
|
description = "Pezkuwi SDK umbrella crate."
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
|
||||||
|
|||||||
+13
-40
@@ -23,7 +23,7 @@ const ASSET_HUB_PARA_ID: u32 = 1000;
|
|||||||
|
|
||||||
// NominationPools pallet index on Asset Hub
|
// NominationPools pallet index on Asset Hub
|
||||||
const NOM_POOLS_PALLET_INDEX: u8 = 81; // 0x51
|
const NOM_POOLS_PALLET_INDEX: u8 = 81; // 0x51
|
||||||
// set_configs call index
|
// set_configs call index
|
||||||
const SET_CONFIGS_CALL_INDEX: u8 = 11; // 0x0b
|
const SET_CONFIGS_CALL_INDEX: u8 = 11; // 0x0b
|
||||||
|
|
||||||
/// SCALE encode ConfigOp::Noop
|
/// SCALE encode ConfigOp::Noop
|
||||||
@@ -74,9 +74,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let relay_url =
|
let relay_url =
|
||||||
std::env::var("RPC_URL").unwrap_or_else(|_| "ws://217.77.6.126:9944".to_string());
|
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")
|
let min_join_hez: u128 =
|
||||||
.unwrap_or_else(|_| "10".to_string())
|
std::env::var("MIN_JOIN_BOND").unwrap_or_else(|_| "10".to_string()).parse()?;
|
||||||
.parse()?;
|
|
||||||
let min_create_hez: u128 = std::env::var("MIN_CREATE_BOND")
|
let min_create_hez: u128 = std::env::var("MIN_CREATE_BOND")
|
||||||
.unwrap_or_else(|_| "10000".to_string())
|
.unwrap_or_else(|_| "10000".to_string())
|
||||||
.parse()?;
|
.parse()?;
|
||||||
@@ -87,10 +86,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
println!("Relay RPC: {}", relay_url);
|
println!("Relay RPC: {}", relay_url);
|
||||||
println!("Asset Hub Para ID: {}", ASSET_HUB_PARA_ID);
|
println!("Asset Hub Para ID: {}", ASSET_HUB_PARA_ID);
|
||||||
println!("MinJoinBond: {} HEZ ({} TYR)", min_join_hez, min_join_bond);
|
println!("MinJoinBond: {} HEZ ({} TYR)", min_join_hez, min_join_bond);
|
||||||
println!(
|
println!("MinCreateBond: {} HEZ ({} TYR)", min_create_hez, min_create_bond);
|
||||||
"MinCreateBond: {} HEZ ({} TYR)",
|
|
||||||
min_create_hez, min_create_bond
|
|
||||||
);
|
|
||||||
|
|
||||||
// Connect to relay chain
|
// Connect to relay chain
|
||||||
let api = OnlineClient::<PezkuwiConfig>::from_insecure_url(&relay_url).await?;
|
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
|
// Encode the NominationPools::set_configs call for Asset Hub
|
||||||
let encoded_call = encode_set_configs_call(min_join_bond, min_create_bond);
|
let encoded_call = encode_set_configs_call(min_join_bond, min_create_bond);
|
||||||
println!(
|
println!("Encoded call: {} bytes (0x{})", encoded_call.len(), hex::encode(&encoded_call));
|
||||||
"Encoded call: {} bytes (0x{})",
|
|
||||||
encoded_call.len(),
|
|
||||||
hex::encode(&encoded_call)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Build XCM destination: V3 MultiLocation { parents: 0, interior: X1(Teyrchain(1000)) }
|
// Build XCM destination: V3 MultiLocation { parents: 0, interior: X1(Teyrchain(1000)) }
|
||||||
let dest = Value::unnamed_variant(
|
let dest = Value::unnamed_variant(
|
||||||
@@ -136,23 +128,14 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
Value::named_variant(
|
Value::named_variant(
|
||||||
"UnpaidExecution",
|
"UnpaidExecution",
|
||||||
[
|
[
|
||||||
(
|
("weight_limit", Value::unnamed_variant("Unlimited", vec![])),
|
||||||
"weight_limit",
|
("check_origin", Value::unnamed_variant("None", vec![])),
|
||||||
Value::unnamed_variant("Unlimited", vec![]),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"check_origin",
|
|
||||||
Value::unnamed_variant("None", vec![]),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Value::named_variant(
|
Value::named_variant(
|
||||||
"Transact",
|
"Transact",
|
||||||
[
|
[
|
||||||
(
|
("origin_kind", Value::unnamed_variant("Superuser", vec![])),
|
||||||
"origin_kind",
|
|
||||||
Value::unnamed_variant("Superuser", vec![]),
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
"require_weight_at_most",
|
"require_weight_at_most",
|
||||||
Value::named_composite([
|
Value::named_composite([
|
||||||
@@ -167,8 +150,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Wrap in XcmPallet.send
|
// Wrap in XcmPallet.send
|
||||||
let xcm_send =
|
let xcm_send = pezkuwi_subxt::dynamic::tx("XcmPallet", "send", vec![dest, message]);
|
||||||
pezkuwi_subxt::dynamic::tx("XcmPallet", "send", vec![dest, message]);
|
|
||||||
|
|
||||||
// Wrap in sudo_unchecked_weight (no weight limit for sudo)
|
// Wrap in sudo_unchecked_weight (no weight limit for sudo)
|
||||||
let sudo_call = pezkuwi_subxt::dynamic::tx(
|
let sudo_call = pezkuwi_subxt::dynamic::tx(
|
||||||
@@ -188,15 +170,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
// Submit and watch
|
// Submit and watch
|
||||||
use pezkuwi_subxt::tx::TxStatus;
|
use pezkuwi_subxt::tx::TxStatus;
|
||||||
|
|
||||||
let tx_progress = api
|
let tx_progress =
|
||||||
.tx()
|
api.tx().sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair).await?;
|
||||||
.sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
println!(
|
println!("TX hash: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||||
"TX hash: 0x{}",
|
|
||||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
|
||||||
);
|
|
||||||
println!("Watching TX status...");
|
println!("Watching TX status...");
|
||||||
|
|
||||||
let mut progress = tx_progress;
|
let mut progress = tx_progress;
|
||||||
@@ -212,11 +189,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
println!(" TX SUCCESS!");
|
println!(" TX SUCCESS!");
|
||||||
for event in events.iter() {
|
for event in events.iter() {
|
||||||
if let Ok(ev) = event {
|
if let Ok(ev) = event {
|
||||||
println!(
|
println!(" Event: {}::{}", ev.pallet_name(), ev.variant_name());
|
||||||
" 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())
|
.unwrap_or_else(|_| "499000".to_string())
|
||||||
.parse()?;
|
.parse()?;
|
||||||
let bond_planck = bond_hez * PLANCKS_PER_HEZ;
|
let bond_planck = bond_hez * PLANCKS_PER_HEZ;
|
||||||
let skip: usize = std::env::var("SKIP")
|
let skip: usize =
|
||||||
.unwrap_or_else(|_| "0".to_string())
|
std::env::var("SKIP").unwrap_or_else(|_| "0".to_string()).parse().unwrap_or(0);
|
||||||
.parse()
|
|
||||||
.unwrap_or(0);
|
|
||||||
|
|
||||||
println!("RPC: {}", url);
|
println!("RPC: {}", url);
|
||||||
println!("Wallets file: {}", wallets_file);
|
println!("Wallets file: {}", wallets_file);
|
||||||
@@ -90,33 +88,24 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
println!(" Account: {}", account);
|
println!(" Account: {}", account);
|
||||||
|
|
||||||
// staking.bond_extra(max_additional: Balance)
|
// staking.bond_extra(max_additional: Balance)
|
||||||
let bond_extra_tx = pezkuwi_subxt::dynamic::tx(
|
let bond_extra_tx =
|
||||||
"Staking",
|
pezkuwi_subxt::dynamic::tx("Staking", "bond_extra", vec![Value::u128(bond_planck)]);
|
||||||
"bond_extra",
|
|
||||||
vec![Value::u128(bond_planck)],
|
|
||||||
);
|
|
||||||
|
|
||||||
use pezkuwi_subxt::tx::TxStatus;
|
use pezkuwi_subxt::tx::TxStatus;
|
||||||
let mut tx_ok = false;
|
let mut tx_ok = false;
|
||||||
|
|
||||||
for attempt in 0..3 {
|
for attempt in 0..3 {
|
||||||
let tx_progress = match api
|
let tx_progress =
|
||||||
.tx()
|
match api.tx().sign_and_submit_then_watch_default(&bond_extra_tx, &keypair).await {
|
||||||
.sign_and_submit_then_watch_default(&bond_extra_tx, &keypair)
|
Ok(p) => p,
|
||||||
.await
|
Err(e) => {
|
||||||
{
|
println!(" SUBMIT ERROR (attempt {}): {}", attempt + 1, e);
|
||||||
Ok(p) => p,
|
tokio::time::sleep(std::time::Duration::from_secs(12)).await;
|
||||||
Err(e) => {
|
continue;
|
||||||
println!(" SUBMIT ERROR (attempt {}): {}", attempt + 1, e);
|
},
|
||||||
tokio::time::sleep(std::time::Duration::from_secs(12)).await;
|
};
|
||||||
continue;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
println!(
|
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||||
" TX: 0x{}",
|
|
||||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut progress = tx_progress;
|
let mut progress = tx_progress;
|
||||||
loop {
|
loop {
|
||||||
@@ -198,10 +187,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
println!("\n=== RESULTS ===");
|
println!("\n=== RESULTS ===");
|
||||||
println!("Success: {}/{}", success_count, stash_wallets.len() - skip);
|
println!("Success: {}/{}", success_count, stash_wallets.len() - skip);
|
||||||
println!("Failed: {}/{}", fail_count, stash_wallets.len() - skip);
|
println!("Failed: {}/{}", fail_count, stash_wallets.len() - skip);
|
||||||
println!(
|
println!("Total bonded: {} HEZ", bond_hez * success_count as u128);
|
||||||
"Total bonded: {} HEZ",
|
|
||||||
bond_hez * success_count as u128
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-61
@@ -85,13 +85,7 @@ fn build_pool_configs(wallets: Vec<WalletInfo>) -> Vec<PoolConfig> {
|
|||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, w)| {
|
.map(|(i, w)| {
|
||||||
let stake_hez = base_stake.saturating_sub(i as u128 * 10_000);
|
let stake_hez = base_stake.saturating_sub(i as u128 * 10_000);
|
||||||
PoolConfig {
|
PoolConfig { name: w.name, mnemonic: w.mnemonic, ss58: w.ss58, transfer_hez, stake_hez }
|
||||||
name: w.name,
|
|
||||||
mnemonic: w.mnemonic,
|
|
||||||
ss58: w.ss58,
|
|
||||||
transfer_hez,
|
|
||||||
stake_hez,
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
@@ -104,26 +98,20 @@ async fn wait_for_success(
|
|||||||
loop {
|
loop {
|
||||||
let status = progress.next().await;
|
let status = progress.next().await;
|
||||||
match status {
|
match status {
|
||||||
Some(Ok(TxStatus::InBestBlock(details))) => {
|
Some(Ok(TxStatus::InBestBlock(details))) => match details.wait_for_success().await {
|
||||||
match details.wait_for_success().await {
|
Ok(events) => {
|
||||||
Ok(events) => {
|
println!(" {} SUCCESS!", label);
|
||||||
println!(" {} SUCCESS!", label);
|
for event in events.iter() {
|
||||||
for event in events.iter() {
|
if let Ok(ev) = event {
|
||||||
if let Ok(ev) = event {
|
println!(" {}::{}", ev.pallet_name(), ev.variant_name());
|
||||||
println!(
|
|
||||||
" {}::{}",
|
|
||||||
ev.pallet_name(),
|
|
||||||
ev.variant_name()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return Ok(true);
|
}
|
||||||
},
|
return Ok(true);
|
||||||
Err(e) => {
|
},
|
||||||
println!(" {} DISPATCH ERROR: {}", label, e);
|
Err(e) => {
|
||||||
return Ok(false);
|
println!(" {} DISPATCH ERROR: {}", label, e);
|
||||||
},
|
return Ok(false);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
Some(Ok(TxStatus::Error { message })) => {
|
Some(Ok(TxStatus::Error { message })) => {
|
||||||
println!(" {} TX ERROR: {}", label, message);
|
println!(" {} TX ERROR: {}", label, message);
|
||||||
@@ -158,13 +146,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
// Parse CLI args
|
// Parse CLI args
|
||||||
let args: Vec<String> = std::env::args().collect();
|
let args: Vec<String> = std::env::args().collect();
|
||||||
let phase = args.get(1).map(|s| s.as_str()).unwrap_or("all");
|
let phase = args.get(1).map(|s| s.as_str()).unwrap_or("all");
|
||||||
let skip: usize = std::env::var("SKIP")
|
let skip: usize =
|
||||||
.unwrap_or_else(|_| "0".to_string())
|
std::env::var("SKIP").unwrap_or_else(|_| "0".to_string()).parse().unwrap_or(0);
|
||||||
.parse()
|
|
||||||
.unwrap_or(0);
|
|
||||||
|
|
||||||
let rpc =
|
let rpc = std::env::var("ASSET_HUB_RPC").unwrap_or_else(|_| DEFAULT_ASSET_HUB_RPC.to_string());
|
||||||
std::env::var("ASSET_HUB_RPC").unwrap_or_else(|_| DEFAULT_ASSET_HUB_RPC.to_string());
|
|
||||||
|
|
||||||
println!("=== NOMINATION POOL CREATOR ===");
|
println!("=== NOMINATION POOL CREATOR ===");
|
||||||
println!("Asset Hub RPC: {}", rpc);
|
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_mn = Mnemonic::from_str(&founder_mnemonic())?;
|
||||||
let founder_keypair = Keypair::from_phrase(&founder_mn, None)?;
|
let founder_keypair = Keypair::from_phrase(&founder_mn, None)?;
|
||||||
println!(
|
println!("Founder: {}\n", founder_keypair.public_key().to_account_id());
|
||||||
"Founder: {}\n",
|
|
||||||
founder_keypair.public_key().to_account_id()
|
|
||||||
);
|
|
||||||
|
|
||||||
for (i, pool) in pool_configs.iter().enumerate().skip(skip) {
|
for (i, pool) in pool_configs.iter().enumerate().skip(skip) {
|
||||||
println!(
|
println!(
|
||||||
@@ -228,10 +210,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
println!(
|
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||||
" TX: 0x{}",
|
|
||||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
|
||||||
);
|
|
||||||
|
|
||||||
tx_ok = wait_for_success(tx_progress, "TRANSFER").await?;
|
tx_ok = wait_for_success(tx_progress, "TRANSFER").await?;
|
||||||
if tx_ok {
|
if tx_ok {
|
||||||
@@ -314,10 +293,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
println!(
|
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||||
" TX: 0x{}",
|
|
||||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
|
||||||
);
|
|
||||||
|
|
||||||
create_ok = wait_for_success(tx_progress, "CREATE_POOL").await?;
|
create_ok = wait_for_success(tx_progress, "CREATE_POOL").await?;
|
||||||
if create_ok {
|
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;
|
tokio::time::sleep(std::time::Duration::from_secs(12)).await;
|
||||||
|
|
||||||
// Query LastPoolId to get the pool_id
|
// Query LastPoolId to get the pool_id
|
||||||
let last_pool_query = pezkuwi_subxt::dynamic::storage::<(), Value>(
|
let last_pool_query =
|
||||||
"NominationPools",
|
pezkuwi_subxt::dynamic::storage::<(), Value>("NominationPools", "LastPoolId");
|
||||||
"LastPoolId",
|
|
||||||
);
|
|
||||||
let storage_client = api.storage().at_latest().await?;
|
let storage_client = api.storage().at_latest().await?;
|
||||||
let last_pool = storage_client
|
let last_pool = storage_client.entry(last_pool_query)?.try_fetch(()).await?;
|
||||||
.entry(last_pool_query)?
|
|
||||||
.try_fetch(())
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let pool_id = match last_pool {
|
let pool_id = match last_pool {
|
||||||
Some(val) => {
|
Some(val) => {
|
||||||
@@ -369,10 +340,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let metadata_tx = pezkuwi_subxt::dynamic::tx(
|
let metadata_tx = pezkuwi_subxt::dynamic::tx(
|
||||||
"NominationPools",
|
"NominationPools",
|
||||||
"set_metadata",
|
"set_metadata",
|
||||||
vec![
|
vec![Value::u128(pool_id as u128), Value::from_bytes(&name_bytes)],
|
||||||
Value::u128(pool_id as u128),
|
|
||||||
Value::from_bytes(&name_bytes),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let tx_progress = match api
|
let tx_progress = match api
|
||||||
@@ -387,10 +355,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
println!(
|
println!(" METADATA TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||||
" METADATA TX: 0x{}",
|
|
||||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
|
||||||
);
|
|
||||||
|
|
||||||
let ok = wait_for_success(tx_progress, "SET_METADATA").await?;
|
let ok = wait_for_success(tx_progress, "SET_METADATA").await?;
|
||||||
if ok {
|
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
|
// Wait between pools
|
||||||
if i + 1 < pool_configs.len() {
|
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());
|
println!("Sudo account: {}\n", keypair.public_key().to_account_id());
|
||||||
|
|
||||||
// Staking::ForceEra storage key (verified twox128)
|
// Staking::ForceEra storage key (verified twox128)
|
||||||
let force_era_key = hex::decode(
|
let force_era_key =
|
||||||
"5f3e4907f716ac89b6347d15ececedcaf7dad0317324aecae8744b87fc95f2f3",
|
hex::decode("5f3e4907f716ac89b6347d15ececedcaf7dad0317324aecae8744b87fc95f2f3")?;
|
||||||
)?;
|
|
||||||
// NotForcing = enum variant 0 = 0x00
|
// NotForcing = enum variant 0 = 0x00
|
||||||
let not_forcing_value = vec![0x00u8];
|
let not_forcing_value = vec![0x00u8];
|
||||||
|
|
||||||
println!(
|
println!("Storage key: 0x{}", hex::encode(&force_era_key));
|
||||||
"Storage key: 0x{}",
|
println!("New value: 0x{} (NotForcing)", hex::encode(¬_forcing_value));
|
||||||
hex::encode(&force_era_key)
|
|
||||||
);
|
|
||||||
println!(
|
|
||||||
"New value: 0x{} (NotForcing)",
|
|
||||||
hex::encode(¬_forcing_value)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Build: system.setStorage(items: Vec<(Key, Value)>)
|
// Build: system.setStorage(items: Vec<(Key, Value)>)
|
||||||
let set_storage_call = pezkuwi_subxt::dynamic::tx(
|
let set_storage_call = pezkuwi_subxt::dynamic::tx(
|
||||||
@@ -54,24 +47,14 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Wrap in sudo
|
// Wrap in sudo
|
||||||
let sudo_call = pezkuwi_subxt::dynamic::tx(
|
let sudo_call = pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![set_storage_call.into_value()]);
|
||||||
"Sudo",
|
|
||||||
"sudo",
|
|
||||||
vec![set_storage_call.into_value()],
|
|
||||||
);
|
|
||||||
|
|
||||||
println!("\nSubmitting sudo(system.setStorage)...");
|
println!("\nSubmitting sudo(system.setStorage)...");
|
||||||
|
|
||||||
use pezkuwi_subxt::tx::TxStatus;
|
use pezkuwi_subxt::tx::TxStatus;
|
||||||
let tx_progress = api
|
let tx_progress = api.tx().sign_and_submit_then_watch_default(&sudo_call, &keypair).await?;
|
||||||
.tx()
|
|
||||||
.sign_and_submit_then_watch_default(&sudo_call, &keypair)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
println!(
|
println!("TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||||
"TX: 0x{}",
|
|
||||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut progress = tx_progress;
|
let mut progress = tx_progress;
|
||||||
loop {
|
loop {
|
||||||
@@ -83,11 +66,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let mut sudid = false;
|
let mut sudid = false;
|
||||||
for event in events.iter() {
|
for event in events.iter() {
|
||||||
if let Ok(ev) = event {
|
if let Ok(ev) = event {
|
||||||
println!(
|
println!(" Event: {}::{}", ev.pallet_name(), ev.variant_name());
|
||||||
" Event: {}::{}",
|
|
||||||
ev.pallet_name(),
|
|
||||||
ev.variant_name()
|
|
||||||
);
|
|
||||||
if ev.pallet_name() == "Sudo" && ev.variant_name() == "Sudid" {
|
if ev.pallet_name() == "Sudo" && ev.variant_name() == "Sudid" {
|
||||||
sudid = true;
|
sudid = true;
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-36
@@ -20,7 +20,7 @@ const PEOPLE_CHAIN_PARA_ID: u32 = 1004;
|
|||||||
|
|
||||||
// Tiki pallet index on People Chain
|
// Tiki pallet index on People Chain
|
||||||
const TIKI_PALLET_INDEX: u8 = 61; // 0x3d
|
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
|
const FORCE_MINT_CALL_INDEX: u8 = 2; // 0x02
|
||||||
|
|
||||||
/// Encode Tiki::force_mint_citizen_nft(dest) for People Chain
|
/// 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(
|
Value::named_variant(
|
||||||
"UnpaidExecution",
|
"UnpaidExecution",
|
||||||
[
|
[
|
||||||
(
|
("weight_limit", Value::unnamed_variant("Unlimited", vec![])),
|
||||||
"weight_limit",
|
("check_origin", Value::unnamed_variant("None", vec![])),
|
||||||
Value::unnamed_variant("Unlimited", vec![]),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"check_origin",
|
|
||||||
Value::unnamed_variant("None", vec![]),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Value::named_variant(
|
Value::named_variant(
|
||||||
"Transact",
|
"Transact",
|
||||||
[
|
[
|
||||||
(
|
("origin_kind", Value::unnamed_variant("Superuser", vec![])),
|
||||||
"origin_kind",
|
|
||||||
Value::unnamed_variant("Superuser", vec![]),
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
"require_weight_at_most",
|
"require_weight_at_most",
|
||||||
Value::named_composite([
|
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());
|
std::env::var("RPC_URL").unwrap_or_else(|_| "ws://217.77.6.126:9944".to_string());
|
||||||
|
|
||||||
// Skip first N validators (already minted)
|
// Skip first N validators (already minted)
|
||||||
let skip: usize = std::env::var("SKIP")
|
let skip: usize =
|
||||||
.unwrap_or_else(|_| "0".to_string())
|
std::env::var("SKIP").unwrap_or_else(|_| "0".to_string()).parse().unwrap_or(0);
|
||||||
.parse()
|
|
||||||
.unwrap_or(0);
|
|
||||||
|
|
||||||
println!("Relay RPC: {}", relay_url);
|
println!("Relay RPC: {}", relay_url);
|
||||||
println!("People Chain Para ID: {}", PEOPLE_CHAIN_PARA_ID);
|
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);
|
let (dest, message) = build_xcm_sudo_transact(&encoded_call);
|
||||||
|
|
||||||
// Wrap in xcmPallet.send then sudo
|
// Wrap in xcmPallet.send then sudo
|
||||||
let xcm_send =
|
let xcm_send = pezkuwi_subxt::dynamic::tx("XcmPallet", "send", vec![dest, message]);
|
||||||
pezkuwi_subxt::dynamic::tx("XcmPallet", "send", vec![dest, message]);
|
|
||||||
|
|
||||||
let sudo_call = pezkuwi_subxt::dynamic::tx(
|
let sudo_call = pezkuwi_subxt::dynamic::tx(
|
||||||
"Sudo",
|
"Sudo",
|
||||||
@@ -196,11 +184,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
// Retry up to 3 times on submit error
|
// Retry up to 3 times on submit error
|
||||||
let mut tx_progress_opt = None;
|
let mut tx_progress_opt = None;
|
||||||
for attempt in 0..3 {
|
for attempt in 0..3 {
|
||||||
match api
|
match api.tx().sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair).await {
|
||||||
.tx()
|
|
||||||
.sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(p) => {
|
Ok(p) => {
|
||||||
tx_progress_opt = Some(p);
|
tx_progress_opt = Some(p);
|
||||||
break;
|
break;
|
||||||
@@ -220,10 +204,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
println!(
|
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||||
" TX: 0x{}",
|
|
||||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut progress = tx_progress;
|
let mut progress = tx_progress;
|
||||||
let mut tx_ok = false;
|
let mut tx_ok = false;
|
||||||
@@ -237,9 +218,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let mut has_sent = false;
|
let mut has_sent = false;
|
||||||
for event in events.iter() {
|
for event in events.iter() {
|
||||||
if let Ok(ev) = event {
|
if let Ok(ev) = event {
|
||||||
if ev.pallet_name() == "Sudo"
|
if ev.pallet_name() == "Sudo" && ev.variant_name() == "Sudid" {
|
||||||
&& ev.variant_name() == "Sudid"
|
|
||||||
{
|
|
||||||
has_sudid = true;
|
has_sudid = true;
|
||||||
}
|
}
|
||||||
if ev.pallet_name() == "XcmPallet"
|
if ev.pallet_name() == "XcmPallet"
|
||||||
@@ -256,11 +235,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
println!(" WARNING: Missing expected events");
|
println!(" WARNING: Missing expected events");
|
||||||
for event in events.iter() {
|
for event in events.iter() {
|
||||||
if let Ok(ev) = event {
|
if let Ok(ev) = event {
|
||||||
println!(
|
println!(" {}::{}", ev.pallet_name(), ev.variant_name());
|
||||||
" {}::{}",
|
|
||||||
ev.pallet_name(),
|
|
||||||
ev.variant_name()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+75
-62
@@ -6,66 +6,79 @@ use std::str::FromStr;
|
|||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
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 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");
|
let message = std::env::var("MESSAGE").expect("MESSAGE env var required");
|
||||||
|
|
||||||
println!("RPC: {}", url);
|
println!("RPC: {}", url);
|
||||||
println!("Message: {}", message);
|
println!("Message: {}", message);
|
||||||
println!("Message bytes: {}", message.len());
|
println!("Message bytes: {}", message.len());
|
||||||
|
|
||||||
let api = OnlineClient::<PezkuwiConfig>::from_insecure_url(&url).await?;
|
let api = OnlineClient::<PezkuwiConfig>::from_insecure_url(&url).await?;
|
||||||
println!("Connected!");
|
println!("Connected!");
|
||||||
|
|
||||||
let mnemonic_str = std::env::var("SUDO_MNEMONIC").expect("SUDO_MNEMONIC required");
|
let mnemonic_str = std::env::var("SUDO_MNEMONIC").expect("SUDO_MNEMONIC required");
|
||||||
let mnemonic = Mnemonic::from_str(&mnemonic_str)?;
|
let mnemonic = Mnemonic::from_str(&mnemonic_str)?;
|
||||||
let keypair = Keypair::from_phrase(&mnemonic, None)?;
|
let keypair = Keypair::from_phrase(&mnemonic, None)?;
|
||||||
println!("Account: {}\n", keypair.public_key().to_account_id());
|
println!("Account: {}\n", keypair.public_key().to_account_id());
|
||||||
|
|
||||||
let remark_tx = pezkuwi_subxt::dynamic::tx(
|
let remark_tx = pezkuwi_subxt::dynamic::tx(
|
||||||
"System",
|
"System",
|
||||||
"remark_with_event",
|
"remark_with_event",
|
||||||
vec![Value::from_bytes(message.as_bytes())],
|
vec![Value::from_bytes(message.as_bytes())],
|
||||||
);
|
);
|
||||||
|
|
||||||
println!("Submitting remarkWithEvent...");
|
println!("Submitting remarkWithEvent...");
|
||||||
|
|
||||||
use pezkuwi_subxt::tx::TxStatus;
|
use pezkuwi_subxt::tx::TxStatus;
|
||||||
let tx_progress = api.tx()
|
let tx_progress = api.tx().sign_and_submit_then_watch_default(&remark_tx, &keypair).await?;
|
||||||
.sign_and_submit_then_watch_default(&remark_tx, &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()));
|
let mut progress = tx_progress;
|
||||||
|
loop {
|
||||||
let mut progress = tx_progress;
|
let status = progress.next().await;
|
||||||
loop {
|
match status {
|
||||||
let status = progress.next().await;
|
Some(Ok(TxStatus::Validated)) => println!(" Validated"),
|
||||||
match status {
|
Some(Ok(TxStatus::Broadcasted)) => println!(" Broadcasted"),
|
||||||
Some(Ok(TxStatus::Validated)) => println!(" Validated"),
|
Some(Ok(TxStatus::InBestBlock(details))) => {
|
||||||
Some(Ok(TxStatus::Broadcasted)) => println!(" Broadcasted"),
|
println!(" InBestBlock {:?}", details.block_hash());
|
||||||
Some(Ok(TxStatus::InBestBlock(details))) => {
|
match details.wait_for_success().await {
|
||||||
println!(" InBestBlock {:?}", details.block_hash());
|
Ok(events) => {
|
||||||
match details.wait_for_success().await {
|
println!(" SUCCESS!");
|
||||||
Ok(events) => {
|
for event in events.iter() {
|
||||||
println!(" SUCCESS!");
|
if let Ok(ev) = event {
|
||||||
for event in events.iter() {
|
println!(" {}::{}", ev.pallet_name(), ev.variant_name());
|
||||||
if let Ok(ev) = event {
|
}
|
||||||
println!(" {}::{}", ev.pallet_name(), ev.variant_name());
|
}
|
||||||
}
|
},
|
||||||
}
|
Err(e) => println!(" Error: {}", e),
|
||||||
},
|
}
|
||||||
Err(e) => println!(" Error: {}", e),
|
break;
|
||||||
}
|
},
|
||||||
break;
|
Some(Ok(TxStatus::Error { message })) => {
|
||||||
},
|
println!(" ERROR: {}", message);
|
||||||
Some(Ok(TxStatus::Error { message })) => { println!(" ERROR: {}", message); break; },
|
break;
|
||||||
Some(Ok(TxStatus::Invalid { message })) => { println!(" INVALID: {}", message); break; },
|
},
|
||||||
Some(Ok(TxStatus::Dropped { message })) => { println!(" DROPPED: {}", message); break; },
|
Some(Ok(TxStatus::Invalid { message })) => {
|
||||||
Some(Err(e)) => { println!(" Error: {}", e); break; },
|
println!(" INVALID: {}", message);
|
||||||
None => { println!(" Stream ended"); break; },
|
break;
|
||||||
_ => {},
|
},
|
||||||
}
|
Some(Ok(TxStatus::Dropped { message })) => {
|
||||||
}
|
println!(" DROPPED: {}", message);
|
||||||
|
break;
|
||||||
println!("\nDone.");
|
},
|
||||||
Ok(())
|
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> {
|
fn validators() -> Vec<ValidatorInfo> {
|
||||||
vec![
|
vec![
|
||||||
ValidatorInfo { name: "Çiyager (Cihat Türkan)", ss58: "5GipBJs2uNWTCazyZQ2vG3DEqLz4tXNmNZtBAT1Mtm1orZ5i", staked_hez: 499_100 },
|
ValidatorInfo {
|
||||||
ValidatorInfo { name: "Mehmet Tunç", ss58: "5HWFZbhkZuTUySXu6ZXYKrTHBnWXHvWRKLozE22zhnwXGGxk", staked_hez: 499_100 },
|
name: "Çiyager (Cihat Türkan)",
|
||||||
ValidatorInfo { name: "Nagihan Akarsel", ss58: "5CrB5BWJfLNWEZAsAXDKXdJUGzFMXKvYnwRX4DVMcgBwxSdx", staked_hez: 499_100 },
|
ss58: "5GipBJs2uNWTCazyZQ2vG3DEqLz4tXNmNZtBAT1Mtm1orZ5i",
|
||||||
ValidatorInfo { name: "Sait Çürükkaya (Doktor Süleyman)", ss58: "5ELgySrX5ZyK7EWXjj6bAedyTCcTNWDANbiiipsT5gnpoCEp", staked_hez: 499_100 },
|
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 {
|
||||||
ValidatorInfo { name: "Kakaî Falah", ss58: "5Fs3P5tHuL9cvwPQojsheViRRAjFkMMFa32jAkDSwW9mbTfU", staked_hez: 499_100 },
|
name: "Mehmet Tunç",
|
||||||
ValidatorInfo { name: "Feryad Fazil Ömer", ss58: "5DXgq7uDXog6zcubT3wgtaYosoibjudz4w5ScPW2phLuAy3V", staked_hez: 499_100 },
|
ss58: "5HWFZbhkZuTUySXu6ZXYKrTHBnWXHvWRKLozE22zhnwXGGxk",
|
||||||
ValidatorInfo { name: "Mevlud Afand", ss58: "5FyFwbGLgPXun3azh6Gx83wCuUt5FTavb2WAVDYrjziVB9rN", staked_hez: 499_100 },
|
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 {
|
||||||
ValidatorInfo { name: "Zanyar Moradi", ss58: "5DFsm3BBEgHmSEZkvwGKB7c7tiH2avhfuQE1SEjfMDGuczsW", staked_hez: 499_100 },
|
name: "Nagihan Akarsel",
|
||||||
ValidatorInfo { name: "Heidar Ghorbani", ss58: "5HePVUXjGSM2hVZ1YMz2V3KoX6EdQNEmmzUnUvpfGV95ofUR", staked_hez: 499_100 },
|
ss58: "5CrB5BWJfLNWEZAsAXDKXdJUGzFMXKvYnwRX4DVMcgBwxSdx",
|
||||||
ValidatorInfo { name: "Farhad Salimi", ss58: "5GP4nAcwtETTg1oAHQNvevmmhG8GEstGQeCirKEhaDTwpFgx", staked_hez: 499_100 },
|
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 {
|
||||||
ValidatorInfo { name: "Arîn Mîrkan", ss58: "5GmuX11pN2fC4Fyq1V7MuiYt3aevZcVQs3HZWKyzmap9bKfe", staked_hez: 499_100 },
|
name: "Sait Çürükkaya (Doktor Süleyman)",
|
||||||
ValidatorInfo { name: "Ebu Leyla", ss58: "5FQptVCtM1qsxkLbQkATkw4Kio4M9LxWvM6TwgEo3QjmTXF3", staked_hez: 499_100 },
|
ss58: "5ELgySrX5ZyK7EWXjj6bAedyTCcTNWDANbiiipsT5gnpoCEp",
|
||||||
ValidatorInfo { name: "Rêvan Kobanê", ss58: "5E7VD2qmso1yRfyq3t9u2qhauAgtmjZTybVsCARF5Zz9bXy6", staked_hez: 499_100 },
|
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: "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 =
|
let relay_url =
|
||||||
std::env::var("RPC_URL").unwrap_or_else(|_| "ws://217.77.6.126:9944".to_string());
|
std::env::var("RPC_URL").unwrap_or_else(|_| "ws://217.77.6.126:9944".to_string());
|
||||||
let skip: usize = std::env::var("SKIP")
|
let skip: usize =
|
||||||
.unwrap_or_else(|_| "0".to_string())
|
std::env::var("SKIP").unwrap_or_else(|_| "0".to_string()).parse().unwrap_or(0);
|
||||||
.parse()
|
|
||||||
.unwrap_or(0);
|
|
||||||
|
|
||||||
let vals = validators();
|
let vals = validators();
|
||||||
println!("Relay RPC: {}", relay_url);
|
println!("Relay RPC: {}", relay_url);
|
||||||
@@ -155,10 +237,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
// Connect to relay chain
|
// Connect to relay chain
|
||||||
let api = OnlineClient::<PezkuwiConfig>::from_insecure_url(&relay_url).await?;
|
let api = OnlineClient::<PezkuwiConfig>::from_insecure_url(&relay_url).await?;
|
||||||
println!(
|
println!("Connected! specVersion: {}\n", api.runtime_version().spec_version);
|
||||||
"Connected! specVersion: {}\n",
|
|
||||||
api.runtime_version().spec_version
|
|
||||||
);
|
|
||||||
|
|
||||||
// Load sudo keypair
|
// Load sudo keypair
|
||||||
let mnemonic_str =
|
let mnemonic_str =
|
||||||
@@ -196,11 +275,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
println!(
|
println!(" Call: {} bytes (0x{}...)", call.len(), hex::encode(&call[..6]));
|
||||||
" Call: {} bytes (0x{}...)",
|
|
||||||
call.len(),
|
|
||||||
hex::encode(&call[..6])
|
|
||||||
);
|
|
||||||
|
|
||||||
// Build XCM message
|
// Build XCM message
|
||||||
let (dest, message) = build_xcm_values(&call);
|
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;
|
use pezkuwi_subxt::tx::TxStatus;
|
||||||
let mut tx_progress_opt = None;
|
let mut tx_progress_opt = None;
|
||||||
for attempt in 0..3 {
|
for attempt in 0..3 {
|
||||||
match api
|
match api.tx().sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair).await {
|
||||||
.tx()
|
|
||||||
.sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(p) => {
|
Ok(p) => {
|
||||||
tx_progress_opt = Some(p);
|
tx_progress_opt = Some(p);
|
||||||
break;
|
break;
|
||||||
@@ -249,10 +320,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
println!(
|
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||||
" TX: 0x{}",
|
|
||||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut progress = tx_progress;
|
let mut progress = tx_progress;
|
||||||
let mut tx_ok = false;
|
let mut tx_ok = false;
|
||||||
@@ -283,11 +351,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
println!(" WARNING: Events:");
|
println!(" WARNING: Events:");
|
||||||
for event in events.iter() {
|
for event in events.iter() {
|
||||||
if let Ok(ev) = event {
|
if let Ok(ev) = event {
|
||||||
println!(
|
println!(" {}::{}", ev.pallet_name(), ev.variant_name());
|
||||||
" {}::{}",
|
|
||||||
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>> {
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
println!("=== SET POOL METADATA ===\n");
|
println!("=== SET POOL METADATA ===\n");
|
||||||
|
|
||||||
let start_id: u32 = std::env::var("START_ID")
|
let start_id: u32 = std::env::var("START_ID").unwrap_or_else(|_| "1".to_string()).parse()?;
|
||||||
.unwrap_or_else(|_| "1".to_string())
|
|
||||||
.parse()?;
|
|
||||||
|
|
||||||
let rpc =
|
let rpc = std::env::var("ASSET_HUB_RPC").unwrap_or_else(|_| DEFAULT_ASSET_HUB_RPC.to_string());
|
||||||
std::env::var("ASSET_HUB_RPC").unwrap_or_else(|_| DEFAULT_ASSET_HUB_RPC.to_string());
|
|
||||||
|
|
||||||
let api = OnlineClient::<PezkuwiConfig>::from_insecure_url(&rpc).await?;
|
let api = OnlineClient::<PezkuwiConfig>::from_insecure_url(&rpc).await?;
|
||||||
println!("Connected to Asset Hub!\n");
|
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 {
|
if let Some(val) = last_pool {
|
||||||
let decoded = val.decode()?;
|
let decoded = val.decode()?;
|
||||||
println!("LastPoolId raw value: {:?}", decoded);
|
println!("LastPoolId raw value: {:?}", decoded);
|
||||||
println!(
|
println!("LastPoolId as_u128: {:?}", decoded.as_u128());
|
||||||
"LastPoolId as_u128: {:?}",
|
|
||||||
decoded.as_u128()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let wallets = load_wallets();
|
let wallets = load_wallets();
|
||||||
|
|
||||||
for (i, wallet) in wallets.iter().enumerate() {
|
for (i, wallet) in wallets.iter().enumerate() {
|
||||||
let pool_id = start_id + i as u32;
|
let pool_id = start_id + i as u32;
|
||||||
println!(
|
println!("--- [{}/{}] Pool {} -> '{}' ---", i + 1, wallets.len(), pool_id, wallet.name);
|
||||||
"--- [{}/{}] Pool {} -> '{}' ---",
|
|
||||||
i + 1,
|
|
||||||
wallets.len(),
|
|
||||||
pool_id,
|
|
||||||
wallet.name
|
|
||||||
);
|
|
||||||
|
|
||||||
let mnemonic = Mnemonic::from_str(&wallet.mnemonic)?;
|
let mnemonic = Mnemonic::from_str(&wallet.mnemonic)?;
|
||||||
let keypair = Keypair::from_phrase(&mnemonic, None)?;
|
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;
|
tokio::time::sleep(std::time::Duration::from_secs(18)).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
let tx_progress = match api
|
let tx_progress =
|
||||||
.tx()
|
match api.tx().sign_and_submit_then_watch_default(&metadata_tx, &keypair).await {
|
||||||
.sign_and_submit_then_watch_default(&metadata_tx, &keypair)
|
Ok(p) => p,
|
||||||
.await
|
Err(e) => {
|
||||||
{
|
println!(" SUBMIT ERROR (attempt {}): {}", attempt + 1, e);
|
||||||
Ok(p) => p,
|
continue;
|
||||||
Err(e) => {
|
},
|
||||||
println!(" SUBMIT ERROR (attempt {}): {}", attempt + 1, e);
|
};
|
||||||
continue;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
println!(
|
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||||
" TX: 0x{}",
|
|
||||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
|
||||||
);
|
|
||||||
|
|
||||||
use pezkuwi_subxt::tx::TxStatus;
|
use pezkuwi_subxt::tx::TxStatus;
|
||||||
let mut progress = tx_progress;
|
let mut progress = tx_progress;
|
||||||
@@ -130,11 +112,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
println!(" SUCCESS!");
|
println!(" SUCCESS!");
|
||||||
for event in events.iter() {
|
for event in events.iter() {
|
||||||
if let Ok(ev) = event {
|
if let Ok(ev) = event {
|
||||||
println!(
|
println!(" {}::{}", ev.pallet_name(), ev.variant_name());
|
||||||
" {}::{}",
|
|
||||||
ev.pallet_name(),
|
|
||||||
ev.variant_name()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ok = true;
|
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 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")
|
let amount_hez: u128 =
|
||||||
.unwrap_or_else(|_| "500000".to_string())
|
std::env::var("AMOUNT_HEZ").unwrap_or_else(|_| "500000".to_string()).parse()?;
|
||||||
.parse()?;
|
|
||||||
let amount_planck = amount_hez * PLANCKS_PER_HEZ;
|
let amount_planck = amount_hez * PLANCKS_PER_HEZ;
|
||||||
let skip: usize = std::env::var("SKIP")
|
let skip: usize =
|
||||||
.unwrap_or_else(|_| "0".to_string())
|
std::env::var("SKIP").unwrap_or_else(|_| "0".to_string()).parse().unwrap_or(0);
|
||||||
.parse()
|
|
||||||
.unwrap_or(0);
|
|
||||||
|
|
||||||
println!("RPC: {}", url);
|
println!("RPC: {}", url);
|
||||||
println!("Amount per validator: {} HEZ ({} TYR)", amount_hez, amount_planck);
|
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;
|
let mut tx_ok = false;
|
||||||
|
|
||||||
for attempt in 0..3 {
|
for attempt in 0..3 {
|
||||||
let tx_progress = match api
|
let tx_progress =
|
||||||
.tx()
|
match api.tx().sign_and_submit_then_watch_default(&transfer_tx, &keypair).await {
|
||||||
.sign_and_submit_then_watch_default(&transfer_tx, &keypair)
|
Ok(p) => p,
|
||||||
.await
|
Err(e) => {
|
||||||
{
|
println!(" SUBMIT ERROR (attempt {}): {}", attempt + 1, e);
|
||||||
Ok(p) => p,
|
tokio::time::sleep(std::time::Duration::from_secs(12)).await;
|
||||||
Err(e) => {
|
continue;
|
||||||
println!(" SUBMIT ERROR (attempt {}): {}", attempt + 1, e);
|
},
|
||||||
tokio::time::sleep(std::time::Duration::from_secs(12)).await;
|
};
|
||||||
continue;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
println!(
|
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||||
" TX: 0x{}",
|
|
||||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut progress = tx_progress;
|
let mut progress = tx_progress;
|
||||||
loop {
|
loop {
|
||||||
@@ -130,10 +121,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
if ev.pallet_name() == "Balances"
|
if ev.pallet_name() == "Balances"
|
||||||
&& ev.variant_name() == "Transfer"
|
&& ev.variant_name() == "Transfer"
|
||||||
{
|
{
|
||||||
println!(
|
println!(" SUCCESS: {} HEZ transferred", amount_hez);
|
||||||
" SUCCESS: {} HEZ transferred",
|
|
||||||
amount_hez
|
|
||||||
);
|
|
||||||
tx_ok = true;
|
tx_ok = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -200,10 +188,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
println!("\n=== RESULTS ===");
|
println!("\n=== RESULTS ===");
|
||||||
println!("Success: {}/{}", success_count, validators.len() - skip);
|
println!("Success: {}/{}", success_count, validators.len() - skip);
|
||||||
println!("Failed: {}/{}", fail_count, validators.len() - skip);
|
println!("Failed: {}/{}", fail_count, validators.len() - skip);
|
||||||
println!(
|
println!("Total transferred: {} HEZ", amount_hez * success_count as u128);
|
||||||
"Total transferred: {} HEZ",
|
|
||||||
amount_hez * success_count as u128
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
+90
-43
@@ -44,27 +44,90 @@ struct ValidatorInfo {
|
|||||||
|
|
||||||
fn validators() -> Vec<ValidatorInfo> {
|
fn validators() -> Vec<ValidatorInfo> {
|
||||||
vec![
|
vec![
|
||||||
ValidatorInfo { name: "Çiyager (Cihat Türkan)", ss58: "5GipBJs2uNWTCazyZQ2vG3DEqLz4tXNmNZtBAT1Mtm1orZ5i" },
|
ValidatorInfo {
|
||||||
ValidatorInfo { name: "Mehmet Tunç", ss58: "5HWFZbhkZuTUySXu6ZXYKrTHBnWXHvWRKLozE22zhnwXGGxk" },
|
name: "Çiyager (Cihat Türkan)",
|
||||||
ValidatorInfo { name: "Nagihan Akarsel", ss58: "5CrB5BWJfLNWEZAsAXDKXdJUGzFMXKvYnwRX4DVMcgBwxSdx" },
|
ss58: "5GipBJs2uNWTCazyZQ2vG3DEqLz4tXNmNZtBAT1Mtm1orZ5i",
|
||||||
ValidatorInfo { name: "Sait Çürükkaya (Doktor Süleyman)", ss58: "5ELgySrX5ZyK7EWXjj6bAedyTCcTNWDANbiiipsT5gnpoCEp" },
|
},
|
||||||
ValidatorInfo { name: "Evdile Koçer", ss58: "5GCZQNjRdHofEHPvVq4ePrfDYcjRzQ1HQ2awHMX6AawpRYuM" },
|
ValidatorInfo {
|
||||||
ValidatorInfo { name: "Mam Zeki", ss58: "5H8jTzi4Gm4rbFtXw6h5enhLhgsuhNAqR5K2itmPiz83ymWy" },
|
name: "Mehmet Tunç",
|
||||||
ValidatorInfo { name: "Kakaî Falah", ss58: "5Fs3P5tHuL9cvwPQojsheViRRAjFkMMFa32jAkDSwW9mbTfU" },
|
ss58: "5HWFZbhkZuTUySXu6ZXYKrTHBnWXHvWRKLozE22zhnwXGGxk",
|
||||||
ValidatorInfo { name: "Feryad Fazil Ömer", ss58: "5DXgq7uDXog6zcubT3wgtaYosoibjudz4w5ScPW2phLuAy3V" },
|
},
|
||||||
ValidatorInfo { name: "Mevlud Afand", ss58: "5FyFwbGLgPXun3azh6Gx83wCuUt5FTavb2WAVDYrjziVB9rN" },
|
ValidatorInfo {
|
||||||
ValidatorInfo { name: "Şêrko Fatih Şivandî", ss58: "5HEcuuypLDeJaSj6ZgH57aXhuviyeLNdw9QrCDJ8u6gsnjnL" },
|
name: "Nagihan Akarsel",
|
||||||
ValidatorInfo { name: "Ramin Hüseyin Penahi", ss58: "5EpmpTXbMXpz6ixy3WhutdzcexzPbvybNKv4eiiN1kvTnQH5" },
|
ss58: "5CrB5BWJfLNWEZAsAXDKXdJUGzFMXKvYnwRX4DVMcgBwxSdx",
|
||||||
ValidatorInfo { name: "Zanyar Moradi", ss58: "5DFsm3BBEgHmSEZkvwGKB7c7tiH2avhfuQE1SEjfMDGuczsW" },
|
},
|
||||||
ValidatorInfo { name: "Heidar Ghorbani", ss58: "5HePVUXjGSM2hVZ1YMz2V3KoX6EdQNEmmzUnUvpfGV95ofUR" },
|
ValidatorInfo {
|
||||||
ValidatorInfo { name: "Farhad Salimi", ss58: "5GP4nAcwtETTg1oAHQNvevmmhG8GEstGQeCirKEhaDTwpFgx" },
|
name: "Sait Çürükkaya (Doktor Süleyman)",
|
||||||
ValidatorInfo { name: "Vafa Azarbar", ss58: "5FYoCM3oeEGeoFY94EgXBhmABkRCabvPp72ur5bJNG3cK619" },
|
ss58: "5ELgySrX5ZyK7EWXjj6bAedyTCcTNWDANbiiipsT5gnpoCEp",
|
||||||
ValidatorInfo { name: "Dr. Aziz Mihemed", ss58: "5GspwkKF6aYzFkmAyBBQg7coSCSgDCore79fbW8uxJNAH347" },
|
},
|
||||||
ValidatorInfo { name: "Arîn Mîrkan", ss58: "5GmuX11pN2fC4Fyq1V7MuiYt3aevZcVQs3HZWKyzmap9bKfe" },
|
ValidatorInfo {
|
||||||
ValidatorInfo { name: "Ebu Leyla", ss58: "5FQptVCtM1qsxkLbQkATkw4Kio4M9LxWvM6TwgEo3QjmTXF3" },
|
name: "Evdile Koçer",
|
||||||
ValidatorInfo { name: "Rêvan Kobanê", ss58: "5E7VD2qmso1yRfyq3t9u2qhauAgtmjZTybVsCARF5Zz9bXy6" },
|
ss58: "5GCZQNjRdHofEHPvVq4ePrfDYcjRzQ1HQ2awHMX6AawpRYuM",
|
||||||
ValidatorInfo { name: "Amanj Babani", ss58: "5Ccz5W7Q21g4UPCytzHxD3VSMLJ1BbbWSkJKFwsNtYRk3HkX" },
|
},
|
||||||
ValidatorInfo { name: "Xosrow Gulan", ss58: "5D7WPmK1SAJyYDdCtgqEzGJpWXQe3Lj9FqWL8z9waLTkUNv3" },
|
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 =
|
let relay_url =
|
||||||
std::env::var("RPC_URL").unwrap_or_else(|_| "ws://217.77.6.126:9944".to_string());
|
std::env::var("RPC_URL").unwrap_or_else(|_| "ws://217.77.6.126:9944".to_string());
|
||||||
let skip: usize = std::env::var("SKIP")
|
let skip: usize =
|
||||||
.unwrap_or_else(|_| "0".to_string())
|
std::env::var("SKIP").unwrap_or_else(|_| "0".to_string()).parse().unwrap_or(0);
|
||||||
.parse()
|
|
||||||
.unwrap_or(0);
|
|
||||||
|
|
||||||
let vals = validators();
|
let vals = validators();
|
||||||
println!("Relay RPC: {}", relay_url);
|
println!("Relay RPC: {}", relay_url);
|
||||||
@@ -223,10 +284,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
// Connect to relay chain
|
// Connect to relay chain
|
||||||
let api = OnlineClient::<PezkuwiConfig>::from_insecure_url(&relay_url).await?;
|
let api = OnlineClient::<PezkuwiConfig>::from_insecure_url(&relay_url).await?;
|
||||||
println!(
|
println!("Connected! specVersion: {}\n", api.runtime_version().spec_version);
|
||||||
"Connected! specVersion: {}\n",
|
|
||||||
api.runtime_version().spec_version
|
|
||||||
);
|
|
||||||
|
|
||||||
// Load sudo keypair
|
// Load sudo keypair
|
||||||
let mnemonic_str =
|
let mnemonic_str =
|
||||||
@@ -281,11 +339,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
use pezkuwi_subxt::tx::TxStatus;
|
use pezkuwi_subxt::tx::TxStatus;
|
||||||
let mut tx_progress_opt = None;
|
let mut tx_progress_opt = None;
|
||||||
for attempt in 0..3 {
|
for attempt in 0..3 {
|
||||||
match api
|
match api.tx().sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair).await {
|
||||||
.tx()
|
|
||||||
.sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(p) => {
|
Ok(p) => {
|
||||||
tx_progress_opt = Some(p);
|
tx_progress_opt = Some(p);
|
||||||
break;
|
break;
|
||||||
@@ -306,10 +360,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
println!(
|
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||||
" TX: 0x{}",
|
|
||||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut progress = tx_progress;
|
let mut progress = tx_progress;
|
||||||
let mut tx_ok = false;
|
let mut tx_ok = false;
|
||||||
@@ -340,11 +391,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
println!(" WARNING: Events:");
|
println!(" WARNING: Events:");
|
||||||
for event in events.iter() {
|
for event in events.iter() {
|
||||||
if let Ok(ev) = event {
|
if let Ok(ev) = event {
|
||||||
println!(
|
println!(" {}::{}", ev.pallet_name(), ev.variant_name());
|
||||||
" {}::{}",
|
|
||||||
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;
|
tokio::time::sleep(std::time::Duration::from_secs(18)).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
let tx_progress = match api
|
let tx_progress = match api.tx().sign_and_submit_then_watch_default(&tx, signer).await {
|
||||||
.tx()
|
|
||||||
.sign_and_submit_then_watch_default(&tx, signer)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(p) => p,
|
Ok(p) => p,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!(" SUBMIT ERROR (attempt {}): {}", attempt + 1, e);
|
println!(" SUBMIT ERROR (attempt {}): {}", attempt + 1, e);
|
||||||
@@ -86,10 +82,7 @@ async fn submit_and_watch(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
println!(
|
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||||
" TX: 0x{}",
|
|
||||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut progress = tx_progress;
|
let mut progress = tx_progress;
|
||||||
loop {
|
loop {
|
||||||
@@ -101,11 +94,7 @@ async fn submit_and_watch(
|
|||||||
println!(" {} SUCCESS!", label);
|
println!(" {} SUCCESS!", label);
|
||||||
for event in events.iter() {
|
for event in events.iter() {
|
||||||
if let Ok(ev) = event {
|
if let Ok(ev) = event {
|
||||||
println!(
|
println!(" {}::{}", ev.pallet_name(), ev.variant_name());
|
||||||
" {}::{}",
|
|
||||||
ev.pallet_name(),
|
|
||||||
ev.variant_name()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
@@ -148,10 +137,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let ws = load_wallets();
|
let ws = load_wallets();
|
||||||
let args: Vec<String> = std::env::args().collect();
|
let args: Vec<String> = std::env::args().collect();
|
||||||
let phase = args.get(1).map(|s| s.as_str()).unwrap_or("all");
|
let phase = args.get(1).map(|s| s.as_str()).unwrap_or("all");
|
||||||
let skip: usize = std::env::var("SKIP")
|
let skip: usize =
|
||||||
.unwrap_or_else(|_| "0".to_string())
|
std::env::var("SKIP").unwrap_or_else(|_| "0".to_string()).parse().unwrap_or(0);
|
||||||
.parse()
|
|
||||||
.unwrap_or(0);
|
|
||||||
let rpc = std::env::var("PEOPLE_RPC").unwrap_or_else(|_| DEFAULT_PEOPLE_RPC.to_string());
|
let rpc = std::env::var("PEOPLE_RPC").unwrap_or_else(|_| DEFAULT_PEOPLE_RPC.to_string());
|
||||||
|
|
||||||
println!("=== WELATI CITIZENSHIP WORKFLOW ===");
|
println!("=== WELATI CITIZENSHIP WORKFLOW ===");
|
||||||
@@ -222,10 +209,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let tx = pezkuwi_subxt::dynamic::tx(
|
let tx = pezkuwi_subxt::dynamic::tx(
|
||||||
"IdentityKyc",
|
"IdentityKyc",
|
||||||
"apply_for_citizenship",
|
"apply_for_citizenship",
|
||||||
vec![
|
vec![Value::from_bytes(&identity_hash), Value::unnamed_variant("None", vec![])],
|
||||||
Value::from_bytes(&identity_hash),
|
|
||||||
Value::unnamed_variant("None", vec![]),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let ok = submit_and_watch(&api, tx, &keypair, "APPLY").await?;
|
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");
|
println!("=== ZAGROS: VALIDATOR DEREGISTRATION ===\n");
|
||||||
|
|
||||||
let url = std::env::var("RPC_URL").unwrap_or_else(|_| "ws://217.77.6.126:9948".to_string());
|
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")
|
let keep: usize = std::env::var("KEEP").unwrap_or_else(|_| "2".to_string()).parse()?;
|
||||||
.unwrap_or_else(|_| "2".to_string())
|
|
||||||
.parse()?;
|
|
||||||
let execute = std::env::var("EXECUTE").unwrap_or_default() == "1";
|
let execute = std::env::var("EXECUTE").unwrap_or_default() == "1";
|
||||||
|
|
||||||
println!("RPC: {}", url);
|
println!("RPC: {}", url);
|
||||||
@@ -61,15 +59,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
// QueuedKeys = Vec<(ValidatorId, Keys)>
|
// QueuedKeys = Vec<(ValidatorId, Keys)>
|
||||||
// Storage key: twox128("Session") + twox128("QueuedKeys")
|
// Storage key: twox128("Session") + twox128("QueuedKeys")
|
||||||
let queued_keys_key =
|
let queued_keys_key =
|
||||||
hex::decode("cec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903")
|
hex::decode("cec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903").unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let raw_data = api
|
let raw_data = api.storage().at_latest().await?.fetch_raw(queued_keys_key).await?;
|
||||||
.storage()
|
|
||||||
.at_latest()
|
|
||||||
.await?
|
|
||||||
.fetch_raw(queued_keys_key)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
if raw_data.is_empty() {
|
if raw_data.is_empty() {
|
||||||
println!("ERROR: QueuedKeys storage 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:
|
// But we need to verify this. Let's compute expected total size:
|
||||||
let expected_entry_size = 32 + (32 * 6 + 33); // 257
|
let expected_entry_size = 32 + (32 * 6 + 33); // 257
|
||||||
let expected_total = 1 + (count * expected_entry_size); // 1 byte compact + entries
|
let expected_total = 1 + (count * expected_entry_size); // 1 byte compact + entries
|
||||||
println!(
|
println!("Expected data size: {} bytes, actual: {} bytes", expected_total, raw_data.len());
|
||||||
"Expected data size: {} bytes, actual: {} bytes",
|
|
||||||
expected_total,
|
|
||||||
raw_data.len()
|
|
||||||
);
|
|
||||||
|
|
||||||
if raw_data.len() < offset + count * expected_entry_size {
|
if raw_data.len() < offset + count * expected_entry_size {
|
||||||
// Try without beefy (older runtime might not have it)
|
// Try without beefy (older runtime might not have it)
|
||||||
let entry_no_beefy = 32 + (32 * 6); // 224
|
let entry_no_beefy = 32 + (32 * 6); // 224
|
||||||
let expected_no_beefy = 1 + (count * entry_no_beefy);
|
let expected_no_beefy = 1 + (count * entry_no_beefy);
|
||||||
println!(
|
println!("Without beefy: expected {} bytes", expected_no_beefy);
|
||||||
"Without beefy: expected {} bytes",
|
|
||||||
expected_no_beefy
|
|
||||||
);
|
|
||||||
|
|
||||||
if raw_data.len() >= offset + count * entry_no_beefy {
|
if raw_data.len() >= offset + count * entry_no_beefy {
|
||||||
println!("Using SessionKeys without Beefy (6 keys x 32 bytes)");
|
println!("Using SessionKeys without Beefy (6 keys x 32 bytes)");
|
||||||
extract_and_process(
|
extract_and_process(&raw_data, offset, count, entry_no_beefy, keep, execute, &api)
|
||||||
&raw_data,
|
.await?;
|
||||||
offset,
|
|
||||||
count,
|
|
||||||
entry_no_beefy,
|
|
||||||
keep,
|
|
||||||
execute,
|
|
||||||
&api,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
} else {
|
} else {
|
||||||
// Auto-detect entry size
|
// Auto-detect entry size
|
||||||
let remaining = raw_data.len() - offset;
|
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={})",
|
"Auto-detected entry size: {} bytes (remaining={}, count={})",
|
||||||
entry_size, remaining, count
|
entry_size, remaining, count
|
||||||
);
|
);
|
||||||
extract_and_process(&raw_data, offset, count, entry_size, keep, execute, &api)
|
extract_and_process(&raw_data, offset, count, entry_size, keep, execute, &api).await?;
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
println!("Using SessionKeys with Beefy (6 keys x 32 + 33 beefy)");
|
println!("Using SessionKeys with Beefy (6 keys x 32 + 33 beefy)");
|
||||||
extract_and_process(
|
extract_and_process(&raw_data, offset, count, expected_entry_size, keep, execute, &api)
|
||||||
&raw_data,
|
.await?;
|
||||||
offset,
|
|
||||||
count,
|
|
||||||
expected_entry_size,
|
|
||||||
keep,
|
|
||||||
execute,
|
|
||||||
&api,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -202,22 +170,16 @@ async fn extract_and_process(
|
|||||||
vec![Value::unnamed_composite(validators_value)],
|
vec![Value::unnamed_composite(validators_value)],
|
||||||
);
|
);
|
||||||
|
|
||||||
let sudo_call =
|
let sudo_call = pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![deregister_call.into_value()]);
|
||||||
pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![deregister_call.into_value()]);
|
|
||||||
|
|
||||||
println!("Submitting sudo(validatorManager.deregister_validators)...\n");
|
println!("Submitting sudo(validatorManager.deregister_validators)...\n");
|
||||||
|
|
||||||
use pezkuwi_subxt::tx::TxStatus;
|
use pezkuwi_subxt::tx::TxStatus;
|
||||||
|
|
||||||
let tx_progress = api
|
let tx_progress =
|
||||||
.tx()
|
api.tx().sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair).await?;
|
||||||
.sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
println!(
|
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||||
" TX: 0x{}",
|
|
||||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut progress = tx_progress;
|
let mut progress = tx_progress;
|
||||||
let mut success = false;
|
let mut success = false;
|
||||||
@@ -237,9 +199,7 @@ async fn extract_and_process(
|
|||||||
if ev.pallet_name() == "ValidatorManager"
|
if ev.pallet_name() == "ValidatorManager"
|
||||||
&& ev.variant_name() == "ValidatorsDeregistered"
|
&& ev.variant_name() == "ValidatorsDeregistered"
|
||||||
{
|
{
|
||||||
println!(
|
println!(" >>> ValidatorsDeregistered event confirmed!");
|
||||||
" >>> ValidatorsDeregistered event confirmed!"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -273,10 +233,7 @@ async fn extract_and_process(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if success {
|
if success {
|
||||||
println!(
|
println!("\nSUCCESS! {} validators queued for deregistration.", to_remove.len());
|
||||||
"\nSUCCESS! {} validators queued for deregistration.",
|
|
||||||
to_remove.len()
|
|
||||||
);
|
|
||||||
println!("The change will take effect at current_session + 2.");
|
println!("The change will take effect at current_session + 2.");
|
||||||
println!("Monitor GRANDPA authorities to confirm.");
|
println!("Monitor GRANDPA authorities to confirm.");
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+17
-40
@@ -26,11 +26,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
// Storage keys
|
// Storage keys
|
||||||
let queued_keys_key =
|
let queued_keys_key =
|
||||||
hex::decode("cec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903")
|
hex::decode("cec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903").unwrap();
|
||||||
.unwrap();
|
|
||||||
let validators_to_retire_key =
|
let validators_to_retire_key =
|
||||||
hex::decode("084e7f70a295a190e2e33fd3f8cdfcc2b664fa73499821e43a617aa0e82b17b1")
|
hex::decode("084e7f70a295a190e2e33fd3f8cdfcc2b664fa73499821e43a617aa0e82b17b1").unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// Step 1: Check ValidatorsToRetire BEFORE
|
// Step 1: Check ValidatorsToRetire BEFORE
|
||||||
println!("=== STEP 1: Check ValidatorsToRetire BEFORE deregister ===");
|
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() {
|
if retire_before.is_empty() {
|
||||||
println!(" ValidatorsToRetire: EMPTY (as expected)\n");
|
println!(" ValidatorsToRetire: EMPTY (as expected)\n");
|
||||||
} else {
|
} else {
|
||||||
println!(
|
println!(" ValidatorsToRetire: {} bytes (already has data!)\n", retire_before.len());
|
||||||
" ValidatorsToRetire: {} bytes (already has data!)\n",
|
|
||||||
retire_before.len()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2: Get validator #5 from QueuedKeys
|
// Step 2: Get validator #5 from QueuedKeys
|
||||||
println!("=== STEP 2: Get test validator from QueuedKeys ===");
|
println!("=== STEP 2: Get test validator from QueuedKeys ===");
|
||||||
let raw_data = api
|
let raw_data = api.storage().at_latest().await?.fetch_raw(queued_keys_key).await?;
|
||||||
.storage()
|
|
||||||
.at_latest()
|
|
||||||
.await?
|
|
||||||
.fetch_raw(queued_keys_key)
|
|
||||||
.await?;
|
|
||||||
let count = (raw_data[0] >> 2) as usize;
|
let count = (raw_data[0] >> 2) as usize;
|
||||||
let remaining = raw_data.len() - 1;
|
let remaining = raw_data.len() - 1;
|
||||||
let entry_size = remaining / count;
|
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)
|
// Get validator #5 (index 4, the first one to remove)
|
||||||
let test_offset = 1 + 4 * entry_size;
|
let test_offset = 1 + 4 * entry_size;
|
||||||
let test_validator = raw_data[test_offset..test_offset + 32].to_vec();
|
let test_validator = raw_data[test_offset..test_offset + 32].to_vec();
|
||||||
println!(
|
println!(" Test validator (index 5): 0x{}\n", hex::encode(&test_validator));
|
||||||
" Test validator (index 5): 0x{}\n",
|
|
||||||
hex::encode(&test_validator)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Step 3: Load sudo key and submit deregister for ONE validator
|
// Step 3: Load sudo key and submit deregister for ONE validator
|
||||||
println!("=== STEP 3: 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");
|
std::env::var("SUDO_MNEMONIC").expect("SUDO_MNEMONIC environment variable required");
|
||||||
let mnemonic = Mnemonic::from_str(&mnemonic_str)?;
|
let mnemonic = Mnemonic::from_str(&mnemonic_str)?;
|
||||||
let sudo_keypair = Keypair::from_phrase(&mnemonic, None)?;
|
let sudo_keypair = Keypair::from_phrase(&mnemonic, None)?;
|
||||||
println!(
|
println!(" Sudo account: {}", sudo_keypair.public_key().to_account_id());
|
||||||
" Sudo account: {}",
|
|
||||||
sudo_keypair.public_key().to_account_id()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Try TWO different encoding approaches
|
// 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
|
// Print the encoded call data to debug
|
||||||
println!("\n Deregister call value: {:?}", deregister_call.call_data());
|
println!("\n Deregister call value: {:?}", deregister_call.call_data());
|
||||||
|
|
||||||
let sudo_call =
|
let sudo_call = pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![deregister_call.into_value()]);
|
||||||
pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![deregister_call.into_value()]);
|
|
||||||
|
|
||||||
println!("\n Submitting sudo(validatorManager.deregister_validators([1 validator]))...");
|
println!("\n Submitting sudo(validatorManager.deregister_validators([1 validator]))...");
|
||||||
|
|
||||||
use pezkuwi_subxt::tx::TxStatus;
|
use pezkuwi_subxt::tx::TxStatus;
|
||||||
|
|
||||||
let tx_progress = api
|
let tx_progress =
|
||||||
.tx()
|
api.tx().sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair).await?;
|
||||||
.sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
println!(
|
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||||
" TX: 0x{}",
|
|
||||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut progress = tx_progress;
|
let mut progress = tx_progress;
|
||||||
let mut success = false;
|
let mut success = false;
|
||||||
@@ -146,11 +124,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
&& ev.variant_name() == "ValidatorsDeregistered"
|
&& ev.variant_name() == "ValidatorsDeregistered"
|
||||||
{
|
{
|
||||||
// Try to decode the event data
|
// Try to decode the event data
|
||||||
println!(
|
println!(" >>> ValidatorsDeregistered event!");
|
||||||
" >>> ValidatorsDeregistered event!"
|
|
||||||
);
|
|
||||||
let bytes = ev.field_bytes();
|
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!(" ValidatorsToRetire: EMPTY !!! (deregister didn't populate storage!)");
|
||||||
println!(" THIS IS THE BUG!");
|
println!(" THIS IS THE BUG!");
|
||||||
} else {
|
} else {
|
||||||
println!(
|
println!(" ValidatorsToRetire: {} bytes", retire_after.len());
|
||||||
" ValidatorsToRetire: {} bytes",
|
|
||||||
retire_after.len()
|
|
||||||
);
|
|
||||||
println!(" Raw hex: 0x{}", hex::encode(&retire_after));
|
println!(" Raw hex: 0x{}", hex::encode(&retire_after));
|
||||||
|
|
||||||
// Decode it
|
// Decode it
|
||||||
|
|||||||
@@ -32,8 +32,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let force_era_call =
|
let force_era_call =
|
||||||
pezkuwi_subxt::dynamic::tx("Staking", "force_new_era", Vec::<Value>::new());
|
pezkuwi_subxt::dynamic::tx("Staking", "force_new_era", Vec::<Value>::new());
|
||||||
|
|
||||||
let sudo_tx =
|
let sudo_tx = pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![force_era_call.into_value()]);
|
||||||
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?;
|
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()));
|
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");
|
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 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")
|
let new_count: u32 =
|
||||||
.unwrap_or_else(|_| "4".to_string())
|
std::env::var("VALIDATOR_COUNT").unwrap_or_else(|_| "4".to_string()).parse()?;
|
||||||
.parse()?;
|
|
||||||
|
|
||||||
println!("RPC: {}", url);
|
println!("RPC: {}", url);
|
||||||
println!("Target validator count: {}", new_count);
|
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))
|
// Step 1: sudo(staking.setValidatorCount(new_count))
|
||||||
println!("[1/2] Setting validator count to {}...", new_count);
|
println!("[1/2] Setting validator count to {}...", new_count);
|
||||||
|
|
||||||
let set_count_call = pezkuwi_subxt::dynamic::tx("Staking", "set_validator_count", vec![
|
let set_count_call = pezkuwi_subxt::dynamic::tx(
|
||||||
Value::u128(new_count as u128),
|
"Staking",
|
||||||
]);
|
"set_validator_count",
|
||||||
|
vec![Value::u128(new_count as u128)],
|
||||||
|
);
|
||||||
|
|
||||||
let sudo_tx_1 =
|
let sudo_tx_1 = pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![set_count_call.into_value()]);
|
||||||
pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![set_count_call.into_value()]);
|
|
||||||
|
|
||||||
// Use sign_and_submit_default (does NOT wait for finalization)
|
// 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?;
|
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 =
|
let force_era_call =
|
||||||
pezkuwi_subxt::dynamic::tx("Staking", "force_new_era", Vec::<Value>::new());
|
pezkuwi_subxt::dynamic::tx("Staking", "force_new_era", Vec::<Value>::new());
|
||||||
|
|
||||||
let sudo_tx_2 =
|
let sudo_tx_2 = pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![force_era_call.into_value()]);
|
||||||
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?;
|
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()));
|
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");
|
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 url = std::env::var("RPC_URL").unwrap_or_else(|_| "ws://217.77.6.126:9948".to_string());
|
||||||
let keep: usize = std::env::var("KEEP")
|
let keep: usize = std::env::var("KEEP").unwrap_or_else(|_| "4".to_string()).parse()?;
|
||||||
.unwrap_or_else(|_| "4".to_string())
|
|
||||||
.parse()?;
|
|
||||||
|
|
||||||
println!("RPC: {}", url);
|
println!("RPC: {}", url);
|
||||||
println!("Keep: {} validators\n", keep);
|
println!("Keep: {} validators\n", keep);
|
||||||
|
|
||||||
let api = OnlineClient::<PezkuwiConfig>::from_insecure_url(&url).await?;
|
let api = OnlineClient::<PezkuwiConfig>::from_insecure_url(&url).await?;
|
||||||
println!(
|
println!("Connected! specVersion: {}\n", api.runtime_version().spec_version);
|
||||||
"Connected! specVersion: {}\n",
|
|
||||||
api.runtime_version().spec_version
|
|
||||||
);
|
|
||||||
|
|
||||||
// Verify genesis hash (Zagros = 0xbb4a61ab...)
|
// Verify genesis hash (Zagros = 0xbb4a61ab...)
|
||||||
let genesis = format!(
|
let genesis = format!("0x{}", hex::encode(api.genesis_hash().as_ref()));
|
||||||
"0x{}",
|
|
||||||
hex::encode(api.genesis_hash().as_ref())
|
|
||||||
);
|
|
||||||
println!("Genesis: {}", genesis);
|
println!("Genesis: {}", genesis);
|
||||||
if !genesis.starts_with("0xbb4a61ab") {
|
if !genesis.starts_with("0xbb4a61ab") {
|
||||||
println!("ERROR: This is NOT Zagros! Aborting.");
|
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
|
// Read QueuedKeys to get all validator AccountIds
|
||||||
let queued_keys_key =
|
let queued_keys_key =
|
||||||
hex::decode("cec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903")
|
hex::decode("cec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903").unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let raw_data = api
|
let raw_data = api.storage().at_latest().await?.fetch_raw(queued_keys_key).await?;
|
||||||
.storage()
|
|
||||||
.at_latest()
|
|
||||||
.await?
|
|
||||||
.fetch_raw(queued_keys_key)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let count = (raw_data[0] >> 2) as usize;
|
let count = (raw_data[0] >> 2) as usize;
|
||||||
let remaining = raw_data.len() - 1;
|
let remaining = raw_data.len() - 1;
|
||||||
@@ -101,10 +87,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
for v in to_remove {
|
for v in to_remove {
|
||||||
encoded_retire.extend_from_slice(v);
|
encoded_retire.extend_from_slice(v);
|
||||||
}
|
}
|
||||||
println!(
|
println!("\nSCALE-encoded ValidatorsToRetire: {} bytes", encoded_retire.len());
|
||||||
"\nSCALE-encoded ValidatorsToRetire: {} bytes",
|
|
||||||
encoded_retire.len()
|
|
||||||
);
|
|
||||||
println!(
|
println!(
|
||||||
" compact_length: 0x{} (count={})",
|
" compact_length: 0x{} (count={})",
|
||||||
hex::encode(&encode_compact(to_remove.len())),
|
hex::encode(&encode_compact(to_remove.len())),
|
||||||
@@ -113,13 +96,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
// Storage key for ValidatorsToRetire
|
// Storage key for ValidatorsToRetire
|
||||||
let validators_to_retire_key =
|
let validators_to_retire_key =
|
||||||
hex::decode("084e7f70a295a190e2e33fd3f8cdfcc2b664fa73499821e43a617aa0e82b17b1")
|
hex::decode("084e7f70a295a190e2e33fd3f8cdfcc2b664fa73499821e43a617aa0e82b17b1").unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
println!(
|
println!("\nStorage key: 0x{}", hex::encode(&validators_to_retire_key));
|
||||||
"\nStorage key: 0x{}",
|
|
||||||
hex::encode(&validators_to_retire_key)
|
|
||||||
);
|
|
||||||
println!(
|
println!(
|
||||||
"Storage value: 0x{}...({} bytes)",
|
"Storage value: 0x{}...({} bytes)",
|
||||||
hex::encode(&encoded_retire[..std::cmp::min(encoded_retire.len(), 40)]),
|
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");
|
std::env::var("SUDO_MNEMONIC").expect("SUDO_MNEMONIC environment variable required");
|
||||||
let mnemonic = Mnemonic::from_str(&mnemonic_str)?;
|
let mnemonic = Mnemonic::from_str(&mnemonic_str)?;
|
||||||
let sudo_keypair = Keypair::from_phrase(&mnemonic, None)?;
|
let sudo_keypair = Keypair::from_phrase(&mnemonic, None)?;
|
||||||
println!(
|
println!("\nSudo account: {}", sudo_keypair.public_key().to_account_id());
|
||||||
"\nSudo account: {}",
|
|
||||||
sudo_keypair.public_key().to_account_id()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Build sudo(system.setStorage(items))
|
// Build sudo(system.setStorage(items))
|
||||||
let set_storage_tx = pezkuwi_subxt::dynamic::tx(
|
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;
|
use pezkuwi_subxt::tx::TxStatus;
|
||||||
|
|
||||||
let tx_progress = api
|
let tx_progress =
|
||||||
.tx()
|
api.tx().sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair).await?;
|
||||||
.sign_and_submit_then_watch_default(&sudo_call, &sudo_keypair)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
println!(
|
println!(" TX: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||||
" TX: 0x{}",
|
|
||||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut progress = tx_progress;
|
let mut progress = tx_progress;
|
||||||
let mut success = false;
|
let mut success = false;
|
||||||
@@ -230,19 +201,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
{
|
{
|
||||||
Ok(data) => {
|
Ok(data) => {
|
||||||
let stored_count = (data[0] >> 2) as usize;
|
let stored_count = (data[0] >> 2) as usize;
|
||||||
println!(
|
println!("ValidatorsToRetire: {} entries ({} bytes)", stored_count, data.len());
|
||||||
"ValidatorsToRetire: {} entries ({} bytes)",
|
|
||||||
stored_count,
|
|
||||||
data.len()
|
|
||||||
);
|
|
||||||
if stored_count == to_remove.len() {
|
if stored_count == to_remove.len() {
|
||||||
println!("COUNT MATCHES! Storage write successful.");
|
println!("COUNT MATCHES! Storage write successful.");
|
||||||
} else {
|
} else {
|
||||||
println!(
|
println!("COUNT MISMATCH! Expected {}, got {}", to_remove.len(), stored_count);
|
||||||
"COUNT MISMATCH! Expected {}, got {}",
|
|
||||||
to_remove.len(),
|
|
||||||
stored_count
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
// Show first few
|
// Show first few
|
||||||
let mut off = 1;
|
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() {
|
let inner_call = match call_name.as_str() {
|
||||||
"setValidatorCount" => {
|
"setValidatorCount" => {
|
||||||
let count: u32 = std::env::var("COUNT")
|
let count: u32 = std::env::var("COUNT").unwrap_or_else(|_| "4".to_string()).parse()?;
|
||||||
.unwrap_or_else(|_| "4".to_string())
|
|
||||||
.parse()?;
|
|
||||||
println!("Setting validator count to {}", count);
|
println!("Setting validator count to {}", count);
|
||||||
pezkuwi_subxt::dynamic::tx("Staking", "set_validator_count", vec![Value::u128(
|
pezkuwi_subxt::dynamic::tx(
|
||||||
count as u128,
|
"Staking",
|
||||||
)])
|
"set_validator_count",
|
||||||
|
vec![Value::u128(count as u128)],
|
||||||
|
)
|
||||||
},
|
},
|
||||||
"forceNewEra" => {
|
"forceNewEra" => {
|
||||||
println!("Forcing new era");
|
println!("Forcing new era");
|
||||||
@@ -48,9 +48,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
},
|
},
|
||||||
"setStakingConfigs" => {
|
"setStakingConfigs" => {
|
||||||
// Set min_validator_count to 1 via set_staking_configs
|
// Set min_validator_count to 1 via set_staking_configs
|
||||||
let min_count: u32 = std::env::var("MIN_COUNT")
|
let min_count: u32 =
|
||||||
.unwrap_or_else(|_| "1".to_string())
|
std::env::var("MIN_COUNT").unwrap_or_else(|_| "1".to_string()).parse().unwrap();
|
||||||
.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");
|
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
|
// 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
|
// 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);
|
std::process::exit(1);
|
||||||
},
|
},
|
||||||
"setMinValidatorCount" => {
|
"setMinValidatorCount" => {
|
||||||
let min_count: u32 = std::env::var("MIN_COUNT")
|
let min_count: u32 =
|
||||||
.unwrap_or_else(|_| "1".to_string())
|
std::env::var("MIN_COUNT").unwrap_or_else(|_| "1".to_string()).parse().unwrap();
|
||||||
.parse().unwrap();
|
|
||||||
println!("Setting minimum validator count to {}", min_count);
|
println!("Setting minimum validator count to {}", min_count);
|
||||||
// Staking::set_staking_configs sets all params at once
|
// Staking::set_staking_configs sets all params at once
|
||||||
// Instead we should check if there's a direct setter
|
// 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)])
|
// ConfigOp: Noop=unnamed_variant("Noop",[]), Set=unnamed_variant("Set",[Value::u128(x)])
|
||||||
let noop = Value::unnamed_variant("Noop", Vec::<Value>::new());
|
let noop = Value::unnamed_variant("Noop", Vec::<Value>::new());
|
||||||
let set_val = Value::unnamed_variant("Set", vec![Value::u128(min_count as u128)]);
|
let set_val = Value::unnamed_variant("Set", vec![Value::u128(min_count as u128)]);
|
||||||
pezkuwi_subxt::dynamic::tx("Staking", "set_staking_configs", vec![
|
pezkuwi_subxt::dynamic::tx(
|
||||||
noop.clone(), // min_nominator_bond
|
"Staking",
|
||||||
noop.clone(), // min_validator_bond
|
"set_staking_configs",
|
||||||
noop.clone(), // max_nominator_count
|
vec![
|
||||||
noop.clone(), // max_validator_count
|
noop.clone(), // min_nominator_bond
|
||||||
noop.clone(), // chill_threshold
|
noop.clone(), // min_validator_bond
|
||||||
noop.clone(), // min_commission
|
noop.clone(), // max_nominator_count
|
||||||
noop.clone(), // max_staked_rewards (if exists)
|
noop.clone(), // max_validator_count
|
||||||
])
|
noop.clone(), // chill_threshold
|
||||||
|
noop.clone(), // min_commission
|
||||||
|
noop.clone(), // max_staked_rewards (if exists)
|
||||||
|
],
|
||||||
|
)
|
||||||
},
|
},
|
||||||
"setStorage" => {
|
"setStorage" => {
|
||||||
// Set arbitrary storage via sudo(system.setStorage)
|
// Set arbitrary storage via sudo(system.setStorage)
|
||||||
let key_hex =
|
let key_hex = std::env::var("STORAGE_KEY").expect("STORAGE_KEY env var required");
|
||||||
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 value_hex =
|
|
||||||
std::env::var("STORAGE_VALUE").expect("STORAGE_VALUE env var required");
|
|
||||||
println!("Setting storage key={} value={}", key_hex, value_hex);
|
println!("Setting storage key={} value={}", key_hex, value_hex);
|
||||||
|
|
||||||
let key_bytes = hex::decode(key_hex.trim_start_matches("0x")).unwrap();
|
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(&key_bytes),
|
||||||
Value::from_bytes(&value_bytes),
|
Value::from_bytes(&value_bytes),
|
||||||
]);
|
]);
|
||||||
pezkuwi_subxt::dynamic::tx("System", "set_storage", vec![
|
pezkuwi_subxt::dynamic::tx(
|
||||||
Value::unnamed_composite([item]),
|
"System",
|
||||||
])
|
"set_storage",
|
||||||
|
vec![Value::unnamed_composite([item])],
|
||||||
|
)
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
eprintln!("Unknown call: {}", call_name);
|
eprintln!("Unknown call: {}", call_name);
|
||||||
@@ -113,10 +115,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
println!("\nSubmitting...");
|
println!("\nSubmitting...");
|
||||||
|
|
||||||
// Use sign_and_submit_then_watch to see TX lifecycle
|
// Use sign_and_submit_then_watch to see TX lifecycle
|
||||||
let tx_progress = api
|
let tx_progress = api.tx().sign_and_submit_then_watch_default(&sudo_tx, &sudo_keypair).await?;
|
||||||
.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!("TX hash: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||||
println!("Watching TX status (Ctrl+C to abort)...");
|
println!("Watching TX status (Ctrl+C to abort)...");
|
||||||
@@ -137,11 +136,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
println!(" TX SUCCESS!");
|
println!(" TX SUCCESS!");
|
||||||
for event in events.iter() {
|
for event in events.iter() {
|
||||||
if let Ok(ev) = event {
|
if let Ok(ev) = event {
|
||||||
println!(
|
println!(" Event: {}::{}", ev.pallet_name(), ev.variant_name());
|
||||||
" 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 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 wasm_path = std::env::var("WASM_FILE").expect("WASM_FILE environment variable required");
|
||||||
let new_validator_count: u32 = std::env::var("VALIDATOR_COUNT")
|
let new_validator_count: u32 =
|
||||||
.unwrap_or_else(|_| "2".to_string())
|
std::env::var("VALIDATOR_COUNT").unwrap_or_else(|_| "2".to_string()).parse()?;
|
||||||
.parse()?;
|
|
||||||
|
|
||||||
println!("RPC: {}", url);
|
println!("RPC: {}", url);
|
||||||
println!("WASM: {}", wasm_path);
|
println!("WASM: {}", wasm_path);
|
||||||
@@ -32,7 +31,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
// Load WASM
|
// Load WASM
|
||||||
let wasm_data = std::fs::read(&wasm_path)?;
|
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
|
// Connect
|
||||||
let api = OnlineClient::<PezkuwiConfig>::from_insecure_url(&url).await?;
|
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)],
|
vec![Value::from_bytes(&wasm_data)],
|
||||||
);
|
);
|
||||||
|
|
||||||
let sudo_upgrade = pezkuwi_subxt::dynamic::tx("Sudo", "sudo_unchecked_weight", vec![
|
let sudo_upgrade = pezkuwi_subxt::dynamic::tx(
|
||||||
set_code.into_value(),
|
"Sudo",
|
||||||
Value::named_composite([
|
"sudo_unchecked_weight",
|
||||||
("ref_time", Value::u128(1u128)),
|
vec![
|
||||||
("proof_size", Value::u128(1u128)),
|
set_code.into_value(),
|
||||||
]),
|
Value::named_composite([
|
||||||
]);
|
("ref_time", Value::u128(1u128)),
|
||||||
|
("proof_size", Value::u128(1u128)),
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
use pezkuwi_subxt::tx::TxStatus;
|
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)
|
.sign_and_submit_then_watch_default(&sudo_upgrade, &sudo_keypair)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
println!(
|
println!(" TX submitted: 0x{}", hex::encode(tx_progress.extrinsic_hash().as_ref()));
|
||||||
" TX submitted: 0x{}",
|
|
||||||
hex::encode(tx_progress.extrinsic_hash().as_ref())
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut progress = tx_progress;
|
let mut progress = tx_progress;
|
||||||
let mut upgrade_ok = false;
|
let mut upgrade_ok = false;
|
||||||
@@ -152,11 +156,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
// Staking::ForceEra: 0x5f3e4907f716ac89b6347d15ececedcaf7dad0317324aecae8744b87fc95f2f3
|
// Staking::ForceEra: 0x5f3e4907f716ac89b6347d15ececedcaf7dad0317324aecae8744b87fc95f2f3
|
||||||
|
|
||||||
let validator_count_key =
|
let validator_count_key =
|
||||||
hex::decode("5f3e4907f716ac89b6347d15ececedca138e71612491192d68deab7e6f563fe1")
|
hex::decode("5f3e4907f716ac89b6347d15ececedca138e71612491192d68deab7e6f563fe1").unwrap();
|
||||||
.unwrap();
|
|
||||||
let force_era_key =
|
let force_era_key =
|
||||||
hex::decode("5f3e4907f716ac89b6347d15ececedcaf7dad0317324aecae8744b87fc95f2f3")
|
hex::decode("5f3e4907f716ac89b6347d15ececedcaf7dad0317324aecae8744b87fc95f2f3").unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// ValidatorCount is u32 LE
|
// ValidatorCount is u32 LE
|
||||||
let validator_count_value = new_validator_count.to_le_bytes().to_vec();
|
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 ValidatorCount = {}", new_validator_count);
|
||||||
println!("Setting ForceEra = ForceNew (0x01)");
|
println!("Setting ForceEra = ForceNew (0x01)");
|
||||||
|
|
||||||
let set_storage_tx = pezkuwi_subxt::dynamic::tx("System", "set_storage", vec![
|
let set_storage_tx = pezkuwi_subxt::dynamic::tx(
|
||||||
Value::unnamed_composite(vec![
|
"System",
|
||||||
|
"set_storage",
|
||||||
|
vec![Value::unnamed_composite(vec![
|
||||||
Value::unnamed_composite(vec![
|
Value::unnamed_composite(vec![
|
||||||
Value::from_bytes(&validator_count_key),
|
Value::from_bytes(&validator_count_key),
|
||||||
Value::from_bytes(&validator_count_value),
|
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_key),
|
||||||
Value::from_bytes(&force_era_value),
|
Value::from_bytes(&force_era_value),
|
||||||
]),
|
]),
|
||||||
]),
|
])],
|
||||||
]);
|
);
|
||||||
|
|
||||||
let sudo_storage = pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![
|
let sudo_storage =
|
||||||
set_storage_tx.into_value(),
|
pezkuwi_subxt::dynamic::tx("Sudo", "sudo", vec![set_storage_tx.into_value()]);
|
||||||
]);
|
|
||||||
|
|
||||||
let tx_progress2 = api2
|
let tx_progress2 = api2
|
||||||
.tx()
|
.tx()
|
||||||
.sign_and_submit_then_watch_default(&sudo_storage, &sudo_keypair)
|
.sign_and_submit_then_watch_default(&sudo_storage, &sudo_keypair)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
println!(
|
println!(" TX submitted: 0x{}", hex::encode(tx_progress2.extrinsic_hash().as_ref()));
|
||||||
" TX submitted: 0x{}",
|
|
||||||
hex::encode(tx_progress2.extrinsic_hash().as_ref())
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut progress2 = tx_progress2;
|
let mut progress2 = tx_progress2;
|
||||||
let mut storage_ok = false;
|
let mut storage_ok = false;
|
||||||
@@ -256,23 +256,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
println!("specVersion: {}", rv3.spec_version);
|
println!("specVersion: {}", rv3.spec_version);
|
||||||
|
|
||||||
// Read back storage to verify
|
// Read back storage to verify
|
||||||
let vc_bytes = api3
|
let vc_bytes = api3.storage().at_latest().await?.fetch_raw(validator_count_key).await?;
|
||||||
.storage()
|
|
||||||
.at_latest()
|
|
||||||
.await?
|
|
||||||
.fetch_raw(validator_count_key)
|
|
||||||
.await?;
|
|
||||||
if vc_bytes.len() >= 4 {
|
if vc_bytes.len() >= 4 {
|
||||||
let vc = u32::from_le_bytes([vc_bytes[0], vc_bytes[1], vc_bytes[2], vc_bytes[3]]);
|
let vc = u32::from_le_bytes([vc_bytes[0], vc_bytes[1], vc_bytes[2], vc_bytes[3]]);
|
||||||
println!("ValidatorCount: {}", vc);
|
println!("ValidatorCount: {}", vc);
|
||||||
}
|
}
|
||||||
|
|
||||||
let fe_bytes = api3
|
let fe_bytes = api3.storage().at_latest().await?.fetch_raw(force_era_key).await?;
|
||||||
.storage()
|
|
||||||
.at_latest()
|
|
||||||
.await?
|
|
||||||
.fetch_raw(force_era_key)
|
|
||||||
.await?;
|
|
||||||
if !fe_bytes.is_empty() {
|
if !fe_bytes.is_empty() {
|
||||||
let fe_name = match fe_bytes[0] {
|
let fe_name = match fe_bytes[0] {
|
||||||
0x00 => "NotForcing",
|
0x00 => "NotForcing",
|
||||||
|
|||||||
Reference in New Issue
Block a user