forked from witnet/witnet-rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(data_structures): adapt stakes tracker to latest specs
fix witnet#2398
- Loading branch information
1 parent
f9790bc
commit 1ac0787
Showing
10 changed files
with
719 additions
and
487 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
#[macro_use] | ||
extern crate bencher; | ||
use bencher::Bencher; | ||
use rand::Rng; | ||
use witnet_data_structures::staking::prelude::*; | ||
|
||
fn populate(b: &mut Bencher) { | ||
let mut stakes = Stakes::<String, u64, u64, u64>::default(); | ||
let mut i = 1; | ||
|
||
b.iter(|| { | ||
let address = format!("{i}"); | ||
let coins = i; | ||
let epoch = i; | ||
stakes.add_stake(address, coins, epoch).unwrap(); | ||
|
||
i += 1; | ||
}); | ||
} | ||
|
||
fn rank(b: &mut Bencher) { | ||
let mut stakes = Stakes::<String, u64, u64, u64>::default(); | ||
let mut i = 1; | ||
|
||
let stakers = 100_000; | ||
let rf = 10; | ||
|
||
let mut rng = rand::thread_rng(); | ||
|
||
loop { | ||
let coins = i; | ||
let epoch = i; | ||
let address = format!("{}", rng.gen::<u64>()); | ||
|
||
stakes.add_stake(address, coins, epoch).unwrap(); | ||
|
||
i += 1; | ||
|
||
if i == stakers { | ||
break; | ||
} | ||
} | ||
|
||
b.iter(|| { | ||
let rank = stakes.rank(Capability::Mining, i); | ||
let mut top = rank.take((stakers / rf) as usize); | ||
let _first = top.next(); | ||
let _last = top.last(); | ||
|
||
i += 1; | ||
}) | ||
} | ||
|
||
fn query_power(b: &mut Bencher) { | ||
let mut stakes = Stakes::<String, u64, u64, u64>::default(); | ||
let mut i = 1; | ||
|
||
let stakers = 100_000; | ||
|
||
loop { | ||
let coins = i; | ||
let epoch = i; | ||
let address = format!("{i}"); | ||
|
||
stakes.add_stake(address, coins, epoch).unwrap(); | ||
|
||
i += 1; | ||
|
||
if i == stakers { | ||
break; | ||
} | ||
} | ||
|
||
i = 1; | ||
|
||
b.iter(|| { | ||
let address = format!("{i}"); | ||
let _power = stakes.query_power(&address, Capability::Mining, i); | ||
|
||
i += 1; | ||
}) | ||
} | ||
|
||
benchmark_main!(benches); | ||
benchmark_group!(benches, populate, rank, query_power); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
use std::rc::Rc; | ||
use std::sync::RwLock; | ||
|
||
use super::prelude::*; | ||
|
||
/// Type alias for a reference-counted and read-write-locked instance of `Stake`. | ||
pub type SyncStake<Address, Coins, Epoch, Power> = Rc<RwLock<Stake<Address, Coins, Epoch, Power>>>; | ||
|
||
/// Couples an amount of coins and an address together. This is to be used in `Stakes` as the index | ||
/// of the `by_coins` index.. | ||
#[derive(Eq, Ord, PartialEq, PartialOrd)] | ||
pub struct CoinsAndAddress<Coins, Address> { | ||
/// An amount of coins. | ||
pub coins: Coins, | ||
/// The address of a staker. | ||
pub address: Address, | ||
} | ||
|
||
/// Allows telling the `census` method in `Stakes` to source addresses from its internal `by_coins` | ||
/// following different strategies. | ||
#[repr(u8)] | ||
#[derive(Clone, Copy, Debug)] | ||
pub enum CensusStrategy { | ||
/// Retrieve all addresses, ordered by decreasing power. | ||
All = 0, | ||
/// Retrieve every Nth address, ordered by decreasing power. | ||
StepBy(usize) = 1, | ||
/// Retrieve the most powerful N addresses, ordered by decreasing power. | ||
Take(usize) = 2, | ||
/// Retrieve a total of N addresses, evenly distributed from the index, ordered by decreasing | ||
/// power. | ||
Evenly(usize) = 3, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/// A minimum stakeable amount needs to exist to prevent spamming of the tracker. | ||
pub const MINIMUM_STAKEABLE_AMOUNT_WITS: u64 = 100; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
use std::sync::PoisonError; | ||
|
||
/// All errors related to the staking functionality. | ||
#[derive(Debug, PartialEq)] | ||
pub enum StakesError<Address, Coins, Epoch> { | ||
/// The amount of coins being staked or the amount that remains after unstaking is below the | ||
/// minimum stakeable amount. | ||
AmountIsBelowMinimum { | ||
/// The number of coins being staked or remaining after staking. | ||
amount: Coins, | ||
/// The minimum stakeable amount. | ||
minimum: Coins, | ||
}, | ||
/// Tried to query `Stakes` for information that belongs to the past. | ||
EpochInThePast { | ||
/// The Epoch being referred. | ||
epoch: Epoch, | ||
/// The latest Epoch. | ||
latest: Epoch, | ||
}, | ||
/// An operation thrown an Epoch value that overflows. | ||
EpochOverflow { | ||
/// The computed Epoch value. | ||
computed: u64, | ||
/// The maximum Epoch. | ||
maximum: Epoch, | ||
}, | ||
/// Tried to query `Stakes` for the address of a staker that is not registered in `Stakes`. | ||
IdentityNotFound { | ||
/// The unknown address. | ||
identity: Address, | ||
}, | ||
/// Tried to obtain a lock on a write-locked piece of data that is already locked. | ||
PoisonedLock, | ||
} | ||
|
||
impl<T, Address, Coins, Epoch> From<PoisonError<T>> for StakesError<Address, Coins, Epoch> { | ||
fn from(_value: PoisonError<T>) -> Self { | ||
StakesError::PoisonedLock | ||
} | ||
} |
Oops, something went wrong.