Skip to content

Commit

Permalink
405 create new reward distribution pallet (#413)
Browse files Browse the repository at this point in the history
* Add basics for reward-distribution pallet

* Finish base logic

* Include `tests` module

* Fix tests not included in `clients-info` crate

* Rewrite tests and mock

* Fix tests and mock

* Fix benchmarking.rs

* Configure reward-distribution pallet in testchain runtime

* Generate `default_weights.rs`

* Amend test

* Fix `clients_info` test

* Update metadata-standalone.scale
  • Loading branch information
ebma authored Oct 12, 2023
1 parent e55c981 commit 0289e93
Show file tree
Hide file tree
Showing 15 changed files with 563 additions and 57 deletions.
20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ members = [
"pallets/nomination",
"pallets/oracle",
"pallets/reward",
"pallets/reward-distribution",
"pallets/staking",
"pallets/stellar-relay",
"pallets/vault-registry",
Expand Down
Binary file modified clients/runtime/metadata-standalone.scale
Binary file not shown.
3 changes: 3 additions & 0 deletions pallets/clients-info/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ mod benchmarking;
#[cfg(test)]
mod mock;

#[cfg(test)]
mod tests;

type NameOf<T> = BoundedVec<u8, <T as pallet::Config>::MaxNameLength>;
type UriOf<T> = BoundedVec<u8, <T as pallet::Config>::MaxUriLength>;

Expand Down
122 changes: 67 additions & 55 deletions pallets/clients-info/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,75 +1,87 @@

use crate::{
mock::*,
pallet::{CurrentClientReleases, PendingClientReleases},
upgrade_client_releases::*,
ClientRelease, UriOf,
};
use frame_support::BoundedVec;
use sp_core::H256;
use sp_std::vec;
use std::collections::HashMap;
use upgrade_client_releases::*;
use crate::mock::*;


#[cfg(test)]
#[test]
fn test_client_pending_release_migration() {
run_test(|| {
let vault_key = b"vault".to_vec();
run_test(|| {
let vault_key = b"vault".to_vec();

let pre_migration_pending_releases: HashMap<_, _> = vec![
(
vault_key.clone(),
ClientRelease {
uri: BoundedVec::try_from(b"https://github.com/pendulum-chain/spacewalk"
.to_vec()).unwrap(),
checksum: H256::default(),
}
),
].into_iter().collect();
pre_migration_pending_releases.iter().for_each(|(key, value)| {
PendingClientReleases::<Test>::insert(BoundedVec::try_from(key.clone()).unwrap(), value.clone());
});
let pre_migration_pending_releases: HashMap<_, _> = vec![(
vault_key.clone(),
ClientRelease {
uri: BoundedVec::try_from(b"https://github.com/pendulum-chain/spacewalk".to_vec())
.unwrap(),
checksum: H256::default(),
},
)]
.into_iter()
.collect();
pre_migration_pending_releases.iter().for_each(|(key, value)| {
PendingClientReleases::<Test>::insert(
BoundedVec::try_from(key.clone()).unwrap(),
value.clone(),
);
});

let pre_migration_current_releases: HashMap<_, _> = vec![
(
vault_key.clone(),
ClientRelease {
uri: BoundedVec::try_from(b"https://github.com/pendulum-chain/spacewalk"
.to_vec()).unwrap(),
checksum: H256::default(),
}
),
].into_iter().collect();
pre_migration_current_releases.iter().for_each(|(key, value)| {
CurrentClientReleases::<Test>::insert(BoundedVec::try_from(key.clone()).unwrap(), value.clone());
});
let pre_migration_current_releases: HashMap<_, _> = vec![(
vault_key.clone(),
ClientRelease {
uri: BoundedVec::try_from(b"https://github.com/pendulum-chain/spacewalk".to_vec())
.unwrap(),
checksum: H256::default(),
},
)]
.into_iter()
.collect();
pre_migration_current_releases.iter().for_each(|(key, value)| {
CurrentClientReleases::<Test>::insert(
BoundedVec::try_from(key.clone()).unwrap(),
value.clone(),
);
});

try_upgrade_current_client_releases::<Test>();
try_upgrade_current_client_releases::<Test>();

let pending_releases = PendingClientReleases::<Test>::iter_values().collect::<Vec<_>>();
assert_eq!(pending_releases.is_empty(), true);
let pending_releases = PendingClientReleases::<Test>::iter_values().collect::<Vec<_>>();
assert_eq!(pending_releases.is_empty(), true);

let current_releases = CurrentClientReleases::<Test>::iter()
.map(|(key, value)| (key.to_vec(), value))
.collect::<HashMap<_, _>>();
assert_eq!(
current_releases.get(&vault_key),
pre_migration_pending_releases.get(&vault_key)
);
});
let current_releases = CurrentClientReleases::<Test>::iter()
.map(|(key, value)| (key.to_vec(), value))
.collect::<HashMap<_, _>>();
assert_eq!(
current_releases.get(&vault_key),
pre_migration_pending_releases.get(&vault_key)
);
});
}

#[cfg(test)]
#[test]
fn test_decode_bounded_vec() {
run_test(|| {
let key = vec![0; 255];
run_test(|| {
let key = BoundedVec::try_from(b"vault".to_vec()).expect("should be able to convert");

let uri_vec = b"http:://localhost:8080".to_vec();
let uri: UriOf<Test> =
BoundedVec::try_from(uri_vec.clone()).expect("should be able to convert");

let checksum: <Test as frame_system::Config>::Hash = H256::default();

let client_release: ClientRelease<UriOf<Test>, <Test as frame_system::Config>::Hash> =
ClientRelease { uri, checksum };

CurrentClientReleases::<Test>::insert(
key.clone(),
ClientRelease {
uri: vec![1; 255],
checksum: H256::default(),
},
);
CurrentClientReleases::<Test>::insert(key.clone(), client_release);

let client_release = crate::CurrentClientReleases::<Test>::get(BoundedVec::try_from(key).unwrap());
assert_eq!(client_release.map(|c| c.uri.to_vec()), Some(vec![1; 255]));
});
let client_release = CurrentClientReleases::<Test>::get(key.clone());
assert_eq!(client_release.map(|c| c.uri.to_vec()), Some(uri_vec));
});
}
48 changes: 48 additions & 0 deletions pallets/reward-distribution/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
[package]
name = "reward-distribution"
authors = ["Pendulum Chain <https://github.com/pendulum-chain>"]
version = "0.1.0"
edition = "2021"

[dependencies]
codec = { package = "parity-scale-codec", version = "3.1.5", default-features = false, features = ["derive", "max-encoded-len"] }
scale-info = { version = "2.2.0", default-features = false, features = ["derive"] }
serde = { version = "1.0.130", default-features = false, features = ["derive"], optional = true }

# Substrate dependencies
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40", default-features = false }
sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40", default-features = false }
sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40", default-features = false }
sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40", default-features = false }
sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40", default-features = false }

frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40", default-features = false }
frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40", default-features = false }
frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40", default-features = false, optional = true }

pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40", default-features = false }

security = { path = "../security", default-features = false }

[features]
default = ["std"]
std = [
"serde",
"codec/std",
"scale-info/std",
"sp-arithmetic/std",
"sp-core/std",
"sp-io/std",
"sp-runtime/std",
"sp-std/std",
"frame-support/std",
"frame-system/std",
"frame-benchmarking/std",
"pallet-balances/std",
"security/std",
]
runtime-benchmarks = [
"frame-benchmarking",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
]
39 changes: 39 additions & 0 deletions pallets/reward-distribution/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Reward distribution pallet

This pallet contains the logic to distribute rewards to the Spacewalk vault clients and their nominators.

## Testing

To run the tests use:

```bash
cargo test --package reward-distribution --features runtime-benchmarks
```

## Benchmarking

Build the node with the `runtime-benchmarks` feature:

```bash
cargo build --package spacewalk-standalone --release --features runtime-benchmarks
```

```bash
# Show benchmarks for this pallet
./target/release/spacewalk-standalone benchmark pallet -p reward-distribution -e '*' --list
```

Run the benchmarking for a pallet:

```bash
./target/release/spacewalk-standalone benchmark pallet \
--chain=dev \
--pallet=reward-distribution \
--extrinsic='*' \
--steps=100 \
--repeat=10 \
--wasm-execution=compiled \
--output=pallets/reward-distribution/src/default_weights.rs \
--template=./.maintain/frame-weight-template.hbs
```

28 changes: 28 additions & 0 deletions pallets/reward-distribution/src/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use super::*;
use frame_benchmarking::v2::{benchmarks, impl_benchmark_test_suite};
use frame_system::RawOrigin;
use sp_std::vec;

#[allow(unused)]
use super::Pallet as RewardDistribution;

#[benchmarks]
pub mod benchmarks {
use super::*;

#[benchmark]
fn set_reward_per_block() {
let new_reward_per_block = Default::default();

#[extrinsic_call]
_(RawOrigin::Root, new_reward_per_block);

assert_eq!(RewardDistribution::<T>::reward_per_block(), Some(new_reward_per_block));
}

impl_benchmark_test_suite!(
RewardDistribution,
crate::mock::ExtBuilder::build(),
crate::mock::Test
);
}
67 changes: 67 additions & 0 deletions pallets/reward-distribution/src/default_weights.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@

//! Autogenerated weights for reward_distribution
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
//! DATE: 2023-10-10, STEPS: `100`, REPEAT: `10`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `Marcels-MBP`, CPU: `<UNKNOWN>`
//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024
// Executed Command:
// ./target/release/spacewalk-standalone
// benchmark
// pallet
// --chain=dev
// --pallet=reward-distribution
// --extrinsic=*
// --steps=100
// --repeat=10
// --wasm-execution=compiled
// --output=pallets/reward-distribution/src/default_weights.rs
// --template=./.maintain/frame-weight-template.hbs

#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
#![allow(unused_imports)]
#![allow(missing_docs)]

use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
use core::marker::PhantomData;

/// Weight functions needed for reward_distribution.
pub trait WeightInfo {
fn set_reward_per_block() -> Weight;
}

/// Weights for reward_distribution using the Substrate node and recommended hardware.
pub struct SubstrateWeight<T>(PhantomData<T>);
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
/// Storage: RewardDistribution RewardsAdaptedAt (r:0 w:1)
/// Proof: RewardDistribution RewardsAdaptedAt (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
/// Storage: RewardDistribution RewardPerBlock (r:0 w:1)
/// Proof: RewardDistribution RewardPerBlock (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
fn set_reward_per_block() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 3_000_000 picoseconds.
Weight::from_parts(4_000_000, 0)
.saturating_add(T::DbWeight::get().writes(2_u64))
}
}

// For backwards compatibility and tests
impl WeightInfo for () {
/// Storage: RewardDistribution RewardsAdaptedAt (r:0 w:1)
/// Proof: RewardDistribution RewardsAdaptedAt (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
/// Storage: RewardDistribution RewardPerBlock (r:0 w:1)
/// Proof: RewardDistribution RewardPerBlock (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
fn set_reward_per_block() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 3_000_000 picoseconds.
Weight::from_parts(4_000_000, 0)
.saturating_add(RocksDbWeight::get().writes(2_u64))
}
}
Loading

0 comments on commit 0289e93

Please sign in to comment.