mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-20 03:31:03 +00:00
Add extrinsic to improve position in a bag of bags-list (#9829)
* pallet-bags-list: Add `put_in_front_of` extrinsic This PR adds the extrinsic `put_in_front_of` which allows the user to specify a `lighter` and `heavier` account within the same bag. The extrinsic will move `heavier` directly in front of `lighter`. The parameter names refer to the fact that `lighter` must have a lower `VoteWeight` then `heavier`. In the ideal use case, where a user wants to improve the position of their account within a bag, the user would iterate the bag, starting from the head, and find the first node who's `VoteWeight` is less than theirs. They would then supply the `id` of the node as the `lighter` argument and their own `id` as the `heavier` argument. * Test & Benchmarks * Respect line width * Remove List::put_in_fron_of tests; Remove AlreadyHigher error * The dispatch origin for this call must be ... * Add some periods * Add back test to list module: put_in_front_of_exits_early_if_bag_not_found * add test tests::pallet::heavier_is_head_lighter_is_not_terminal * Cater for edge case of heavier being head * Add ExtBuilder::add_aux_data; try to make some tests use simpler data * Update frame/bags-list/src/list/tests.rs * make insert_at_unchecked infallible * Make it permissioned - only callable by heavier * Add test cases for insert_at_unchecked * Move counter update to insert_at; fix comments * Address some feedback * Make voteweight constructed with parameter_types * Always set vote weight for Ids in build * Add skip_genesis_ids * Do not pass weight fn to List put_in_front_of * Remove remants of CounterForListNodes * fmt * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_bags_list --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/bags-list/src/weights.rs --template=./.maintain/frame-weight-template.hbs * Delete messed up weights file * Some place holder stuff so we can run bench in CI * Fix * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_bags_list --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/bags-list/src/weights.rs --template=./.maintain/frame-weight-template.hbs * Update frame/bags-list/src/list/mod.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * fmt * Log + debug assert when refetching an Id Co-authored-by: Parity Bot <admin@parity.io> Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com>
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use frame_support::{assert_ok, assert_storage_noop, traits::IntegrityTest};
|
||||
use frame_support::{assert_noop, assert_ok, assert_storage_noop, traits::IntegrityTest};
|
||||
|
||||
use super::*;
|
||||
use frame_election_provider_support::SortedListProvider;
|
||||
@@ -35,7 +35,7 @@ mod pallet {
|
||||
);
|
||||
|
||||
// when increasing vote weight to the level of non-existent bag
|
||||
NextVoteWeight::set(2_000);
|
||||
StakingMock::set_vote_weight_of(&42, 2_000);
|
||||
assert_ok!(BagsList::rebag(Origin::signed(0), 42));
|
||||
|
||||
// then a new bag is created and the id moves into it
|
||||
@@ -45,7 +45,7 @@ mod pallet {
|
||||
);
|
||||
|
||||
// when decreasing weight within the range of the current bag
|
||||
NextVoteWeight::set(1001);
|
||||
StakingMock::set_vote_weight_of(&42, 1_001);
|
||||
assert_ok!(BagsList::rebag(Origin::signed(0), 42));
|
||||
|
||||
// then the id does not move
|
||||
@@ -55,7 +55,7 @@ mod pallet {
|
||||
);
|
||||
|
||||
// when reducing weight to the level of a non-existent bag
|
||||
NextVoteWeight::set(30);
|
||||
StakingMock::set_vote_weight_of(&42, 30);
|
||||
assert_ok!(BagsList::rebag(Origin::signed(0), 42));
|
||||
|
||||
// then a new bag is created and the id moves into it
|
||||
@@ -65,7 +65,7 @@ mod pallet {
|
||||
);
|
||||
|
||||
// when increasing weight to the level of a pre-existing bag
|
||||
NextVoteWeight::set(500);
|
||||
StakingMock::set_vote_weight_of(&42, 500);
|
||||
assert_ok!(BagsList::rebag(Origin::signed(0), 42));
|
||||
|
||||
// then the id moves into that bag
|
||||
@@ -85,7 +85,7 @@ mod pallet {
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![2, 3, 4])]);
|
||||
|
||||
// when
|
||||
NextVoteWeight::set(10);
|
||||
StakingMock::set_vote_weight_of(&4, 10);
|
||||
assert_ok!(BagsList::rebag(Origin::signed(0), 4));
|
||||
|
||||
// then
|
||||
@@ -93,6 +93,7 @@ mod pallet {
|
||||
assert_eq!(Bag::<Runtime>::get(1_000).unwrap(), Bag::new(Some(2), Some(3), 1_000));
|
||||
|
||||
// when
|
||||
StakingMock::set_vote_weight_of(&3, 10);
|
||||
assert_ok!(BagsList::rebag(Origin::signed(0), 3));
|
||||
|
||||
// then
|
||||
@@ -103,6 +104,7 @@ mod pallet {
|
||||
assert_eq!(get_list_as_ids(), vec![2u32, 1, 4, 3]);
|
||||
|
||||
// when
|
||||
StakingMock::set_vote_weight_of(&2, 10);
|
||||
assert_ok!(BagsList::rebag(Origin::signed(0), 2));
|
||||
|
||||
// then
|
||||
@@ -117,7 +119,7 @@ mod pallet {
|
||||
fn rebag_head_works() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
// when
|
||||
NextVoteWeight::set(10);
|
||||
StakingMock::set_vote_weight_of(&2, 10);
|
||||
assert_ok!(BagsList::rebag(Origin::signed(0), 2));
|
||||
|
||||
// then
|
||||
@@ -125,6 +127,7 @@ mod pallet {
|
||||
assert_eq!(Bag::<Runtime>::get(1_000).unwrap(), Bag::new(Some(3), Some(4), 1_000));
|
||||
|
||||
// when
|
||||
StakingMock::set_vote_weight_of(&3, 10);
|
||||
assert_ok!(BagsList::rebag(Origin::signed(0), 3));
|
||||
|
||||
// then
|
||||
@@ -132,6 +135,7 @@ mod pallet {
|
||||
assert_eq!(Bag::<Runtime>::get(1_000).unwrap(), Bag::new(Some(4), Some(4), 1_000));
|
||||
|
||||
// when
|
||||
StakingMock::set_vote_weight_of(&4, 10);
|
||||
assert_ok!(BagsList::rebag(Origin::signed(0), 4));
|
||||
|
||||
// then
|
||||
@@ -196,6 +200,249 @@ mod pallet {
|
||||
assert_storage_noop!(assert!(BagsList::rebag(Origin::signed(0), 10).is_ok()));
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn put_in_front_of_two_node_bag_heavier_is_tail() {
|
||||
ExtBuilder::default()
|
||||
.skip_genesis_ids()
|
||||
.add_ids(vec![(10, 15), (11, 16)])
|
||||
.build_and_execute(|| {
|
||||
// given
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(20, vec![10, 11])]);
|
||||
|
||||
// when
|
||||
assert_ok!(BagsList::put_in_front_of(Origin::signed(11), 10));
|
||||
|
||||
// then
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(20, vec![11, 10])]);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn put_in_front_of_two_node_bag_heavier_is_head() {
|
||||
ExtBuilder::default()
|
||||
.skip_genesis_ids()
|
||||
.add_ids(vec![(11, 16), (10, 15)])
|
||||
.build_and_execute(|| {
|
||||
// given
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(20, vec![11, 10])]);
|
||||
|
||||
// when
|
||||
assert_ok!(BagsList::put_in_front_of(Origin::signed(11), 10));
|
||||
|
||||
// then
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(20, vec![11, 10])]);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn put_in_front_of_non_terminal_nodes_heavier_behind() {
|
||||
ExtBuilder::default().add_ids(vec![(5, 1_000)]).build_and_execute(|| {
|
||||
// given
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![2, 3, 4, 5])]);
|
||||
|
||||
StakingMock::set_vote_weight_of(&3, 999);
|
||||
|
||||
// when
|
||||
assert_ok!(BagsList::put_in_front_of(Origin::signed(4), 3));
|
||||
|
||||
// then
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![2, 4, 3, 5])]);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn put_in_front_of_non_terminal_nodes_heavier_in_front() {
|
||||
ExtBuilder::default()
|
||||
.add_ids(vec![(5, 1_000), (6, 1_000)])
|
||||
.build_and_execute(|| {
|
||||
// given
|
||||
assert_eq!(
|
||||
List::<Runtime>::get_bags(),
|
||||
vec![(10, vec![1]), (1_000, vec![2, 3, 4, 5, 6])]
|
||||
);
|
||||
|
||||
StakingMock::set_vote_weight_of(&5, 999);
|
||||
|
||||
// when
|
||||
assert_ok!(BagsList::put_in_front_of(Origin::signed(3), 5));
|
||||
|
||||
// then
|
||||
assert_eq!(
|
||||
List::<Runtime>::get_bags(),
|
||||
vec![(10, vec![1]), (1_000, vec![2, 4, 3, 5, 6])]
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn put_in_front_of_lighter_is_head_heavier_is_non_terminal() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
// given
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![2, 3, 4])]);
|
||||
|
||||
StakingMock::set_vote_weight_of(&2, 999);
|
||||
|
||||
// when
|
||||
assert_ok!(BagsList::put_in_front_of(Origin::signed(3), 2));
|
||||
|
||||
// then
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![3, 2, 4])]);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn put_in_front_of_heavier_is_tail_lighter_is_non_terminal() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
// given
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![2, 3, 4])]);
|
||||
|
||||
StakingMock::set_vote_weight_of(&3, 999);
|
||||
|
||||
// when
|
||||
assert_ok!(BagsList::put_in_front_of(Origin::signed(4), 3));
|
||||
|
||||
// then
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![2, 4, 3])]);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn put_in_front_of_heavier_is_tail_lighter_is_head() {
|
||||
ExtBuilder::default().add_ids(vec![(5, 1_000)]).build_and_execute(|| {
|
||||
// given
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![2, 3, 4, 5])]);
|
||||
|
||||
StakingMock::set_vote_weight_of(&2, 999);
|
||||
|
||||
// when
|
||||
assert_ok!(BagsList::put_in_front_of(Origin::signed(5), 2));
|
||||
|
||||
// then
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![5, 2, 3, 4])]);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn put_in_front_of_heavier_is_head_lighter_is_not_terminal() {
|
||||
ExtBuilder::default().add_ids(vec![(5, 1_000)]).build_and_execute(|| {
|
||||
// given
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![2, 3, 4, 5])]);
|
||||
|
||||
StakingMock::set_vote_weight_of(&4, 999);
|
||||
|
||||
// when
|
||||
BagsList::put_in_front_of(Origin::signed(2), 4).unwrap();
|
||||
|
||||
// then
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![3, 2, 4, 5])]);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn put_in_front_of_lighter_is_tail_heavier_is_not_terminal() {
|
||||
ExtBuilder::default().add_ids(vec![(5, 900)]).build_and_execute(|| {
|
||||
// given
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![2, 3, 4, 5])]);
|
||||
|
||||
// when
|
||||
BagsList::put_in_front_of(Origin::signed(3), 5).unwrap();
|
||||
|
||||
// then
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![2, 4, 3, 5])]);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn put_in_front_of_lighter_is_tail_heavier_is_head() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
// given
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![2, 3, 4])]);
|
||||
|
||||
StakingMock::set_vote_weight_of(&4, 999);
|
||||
|
||||
// when
|
||||
BagsList::put_in_front_of(Origin::signed(2), 4).unwrap();
|
||||
|
||||
// then
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![3, 2, 4])]);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn put_in_front_of_errors_if_heavier_is_less_than_lighter() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
// given
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![2, 3, 4])]);
|
||||
|
||||
StakingMock::set_vote_weight_of(&3, 999);
|
||||
|
||||
// then
|
||||
assert_noop!(
|
||||
BagsList::put_in_front_of(Origin::signed(3), 2),
|
||||
crate::pallet::Error::<Runtime>::NotHeavier
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn put_in_front_of_errors_if_heavier_is_equal_weight_to_lighter() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
// given
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![2, 3, 4])]);
|
||||
|
||||
// then
|
||||
assert_noop!(
|
||||
BagsList::put_in_front_of(Origin::signed(3), 4),
|
||||
crate::pallet::Error::<Runtime>::NotHeavier
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn put_in_front_of_errors_if_nodes_not_found() {
|
||||
// `heavier` not found
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
// given
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![2, 3, 4])]);
|
||||
|
||||
assert!(!ListNodes::<Runtime>::contains_key(5));
|
||||
|
||||
// then
|
||||
assert_noop!(
|
||||
BagsList::put_in_front_of(Origin::signed(5), 4),
|
||||
crate::pallet::Error::<Runtime>::IdNotFound
|
||||
);
|
||||
});
|
||||
|
||||
// `lighter` not found
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
// given
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![2, 3, 4])]);
|
||||
|
||||
assert!(!ListNodes::<Runtime>::contains_key(5));
|
||||
|
||||
// then
|
||||
assert_noop!(
|
||||
BagsList::put_in_front_of(Origin::signed(4), 5),
|
||||
crate::pallet::Error::<Runtime>::IdNotFound
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn put_in_front_of_errors_if_nodes_not_in_same_bag() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
// given
|
||||
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![2, 3, 4])]);
|
||||
|
||||
// then
|
||||
assert_noop!(
|
||||
BagsList::put_in_front_of(Origin::signed(4), 1),
|
||||
crate::pallet::Error::<Runtime>::NotInSameBag
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
mod sorted_list_provider {
|
||||
|
||||
Reference in New Issue
Block a user