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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/multi_block_state_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ pub trait MultiBlockClientTrait<C: ChainClientTrait + Send + Sync + 'static, MC:
async fn get_min_nominator_bond(&self, storage: &S) -> Result<u128, Box<dyn std::error::Error + Send + Sync>>;
async fn get_min_validator_bond(&self, storage: &S) -> Result<u128, Box<dyn std::error::Error + Send + Sync>>;
async fn get_staking_validator_count(&self, storage: &S) -> Result<u32, Box<dyn std::error::Error + Send + Sync>>;
async fn get_total_issuance(&self, storage: &S) -> Result<u128, Box<dyn std::error::Error + Send + Sync>>;
async fn fetch_paged_voter_snapshot(&self, storage: &S, round: u32, page: u32) -> Result<VoterSnapshotPage<MC>, Box<dyn std::error::Error + Send + Sync>>;
async fn fetch_paged_target_snapshot(&self, storage: &S, round: u32, page: u32) -> Result<TargetSnapshotPage<MC>, Box<dyn std::error::Error + Send + Sync>>;
async fn get_validator_prefs(&self, storage: &S, validator: AccountId) -> Result<ValidatorPrefs, Box<dyn std::error::Error + Send + Sync>>;
Expand Down Expand Up @@ -309,6 +310,15 @@ impl<C: ChainClientTrait + Send + Sync + 'static, MC: MinerConfig + Send + Sync
Ok(validator_count)
}

async fn get_total_issuance(&self, storage: &S) -> Result<u128, Box<dyn std::error::Error + Send + Sync>> {
let storage_key = subxt::dynamic::storage("Balances", "TotalIssuance", vec![]);
let total_issuance_entry = storage.fetch(&storage_key)
.await?
.ok_or("Balances::TotalIssuance not found")?;
let total_issuance: u128 = codec::Decode::decode(&mut total_issuance_entry.encoded())?;
Ok(total_issuance)
}

async fn fetch_paged_voter_snapshot(&self, storage: &S, round: u32, page: u32) -> Result<VoterSnapshotPage<MC>, Box<dyn std::error::Error + Send + Sync>> {
let storage_key = subxt::dynamic::storage(
"MultiBlockElection",
Expand Down
19 changes: 15 additions & 4 deletions src/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ where
let validators = raw_client.get_validators(block_details.block_hash).await?;
let validator_set: HashSet<AccountId> = validators.iter().cloned().collect();

// Fetch total issuance for CurrencyToVote scaling
let total_issuance = client.get_total_issuance(&block_details.storage).await?;
let currency_to_vote_factor = (total_issuance / u64::MAX as u128).max(1);

// Prepare data for ElectionSnapshotPage
let mut list_bags = raw_client.get_all_list_bags(block_details.block_hash).await?;
list_bags.sort_by(|a, b| b.cmp(a));
Expand Down Expand Up @@ -219,7 +223,10 @@ where
Ok(_) => return Ok(None),
Err(e) => return Err(e.to_string()),
};


// Apply CurrencyToVote scaling
let vote_weight = (stake.active / currency_to_vote_factor) as u64;

let nominations = client.get_nominator(storage, voter.clone()).await
.map_err(|e| e.to_string())?;

Expand All @@ -231,12 +238,12 @@ where
let targets_mc = BoundedVec::try_from(
targets.into_iter().map(|t| t.into()).collect::<Vec<AccountId>>()
).map_err(|_| "Too many targets in voter".to_string())?;
return Ok(Some((voter, stake.active as u64, targets_mc)));
return Ok(Some((voter, vote_weight, targets_mc)));
}
} else if validator_set.contains(&voter) {
return Ok(Some((
voter.clone(),
stake.active as u64,
vote_weight,
BoundedVec::try_from(vec![voter]).map_err(|_| "Too many targets")?
)));
}
Expand Down Expand Up @@ -478,6 +485,10 @@ mod tests {
.expect_get_min_validator_bond()
.returning(|_storage: &MockDummyStorage| Ok(0));

mock_client
.expect_get_total_issuance()
.returning(|_storage: &MockDummyStorage| Ok(1_000_000_000_000_000_000u128));

let mut raw_client = MockRawClientTrait::<MockRpcClient>::new();

raw_client
Expand Down Expand Up @@ -673,4 +684,4 @@ mod tests {
min_validator_bond: 0,
});
}
}
}