From 95a2ac9adcd6dde3499ec3a6d72597e22f2f0d4a Mon Sep 17 00:00:00 2001 From: jaypan Date: Wed, 18 Dec 2024 16:45:43 +0100 Subject: [PATCH 1/6] Add commission rate and the wait list --- pallets/parachain-staking/src/lib.rs | 3 +- .../parachain-staking/ParachainStaking.sol | 5 ++ precompiles/parachain-staking/src/lib.rs | 51 +++++++++++++++++-- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/pallets/parachain-staking/src/lib.rs b/pallets/parachain-staking/src/lib.rs index 31669ea6..97bea90c 100644 --- a/pallets/parachain-staking/src/lib.rs +++ b/pallets/parachain-staking/src/lib.rs @@ -576,9 +576,10 @@ pub mod pallet { /// /// It maps from an account to its information. /// Moreover, it counts the number of candidates. + /// Precompiles will call this structure to list all #[pallet::storage] #[pallet::getter(fn candidate_pool)] - pub(crate) type CandidatePool = CountedStorageMap< + pub type CandidatePool = CountedStorageMap< _, Twox64Concat, T::AccountId, diff --git a/precompiles/parachain-staking/ParachainStaking.sol b/precompiles/parachain-staking/ParachainStaking.sol index a4b5b782..0ef1c503 100644 --- a/precompiles/parachain-staking/ParachainStaking.sol +++ b/precompiles/parachain-staking/ParachainStaking.sol @@ -16,12 +16,17 @@ interface ParachainStaking { struct CollatorInfo { bytes32 owner; uint256 amount; + uint256 commission; } /// Get all collator informations // selector: 0xaaacb283 function getCollatorList() external view returns (CollatorInfo[] memory); + /// Get all wait informations + // selector: 0x83d2afed + function getWaitList() external view returns (CollatorInfo[] memory); + /// Join the set of delegators by delegating to a collator candidate /// selector: 0xd9f511cd function joinDelegators(bytes32 collator, uint256 stake) external; diff --git a/precompiles/parachain-staking/src/lib.rs b/precompiles/parachain-staking/src/lib.rs index 39a0f6e7..e38b7ef0 100644 --- a/precompiles/parachain-staking/src/lib.rs +++ b/precompiles/parachain-staking/src/lib.rs @@ -50,6 +50,7 @@ pub struct ParachainStakingPrecompile(PhantomData); pub struct CollatorInfo { owner: H256, amount: U256, + commission: U256, } #[precompile_utils::precompile] @@ -73,13 +74,53 @@ where handle.record_db_read::(7200)?; - Ok(parachain_staking::Pallet::::top_candidates() + let all_collators = parachain_staking::CandidatePool::::iter() + .map(|(_id, stake_info)| { + CollatorInfo { + owner: H256::from( as Into<[u8; 32]>>::into(stake_info.id)), + amount: stake_info.stake.into(), + commission: U256::from(stake_info.commission.deconstruct() as u128), + } + }).collect::>(); + let top_candiate = parachain_staking::Pallet::::top_candidates() .into_iter() - .map(|stake_info| CollatorInfo { - owner: H256::from( as Into<[u8; 32]>>::into(stake_info.owner)), - amount: stake_info.amount.into(), + .map(|stake_info| { + H256::from( as Into<[u8; 32]>>::into(stake_info.owner)) }) - .collect::>()) + .collect::>(); + let candidate_list = all_collators + .into_iter() + .filter(|x| top_candiate.contains(&x.owner)); + Ok(candidate_list.collect::>()) + } + + #[precompile::public("getWaitList()")] + #[precompile::public("get_wait_list()")] + #[precompile::view] + fn get_wait_list(handle: &mut impl PrecompileHandle) -> EvmResult> { + // CandidatePool: UnBoundedVec(AccountId(32) + Balance(16)) + // we account for a theoretical 150 pool. + + handle.record_db_read::(7200)?; + + let all_collators = parachain_staking::CandidatePool::::iter() + .map(|(_id, stake_info)| { + CollatorInfo { + owner: H256::from( as Into<[u8; 32]>>::into(stake_info.id)), + amount: stake_info.stake.into(), + commission: U256::from(stake_info.commission.deconstruct() as u128), + } + }).collect::>(); + let top_candiate = parachain_staking::Pallet::::top_candidates() + .into_iter() + .map(|stake_info| { + H256::from( as Into<[u8; 32]>>::into(stake_info.owner)) + }) + .collect::>(); + let candidate_list = all_collators + .into_iter() + .filter(|x| !top_candiate.contains(&x.owner)); + Ok(candidate_list.collect::>()) } #[precompile::public("joinDelegators(bytes32,uint256)")] From ee6644f3b69cc2e3924b23f26743d0904b9909ca Mon Sep 17 00:00:00 2001 From: jaypan Date: Wed, 18 Dec 2024 17:21:59 +0100 Subject: [PATCH 2/6] Fix fmt --- precompiles/parachain-staking/src/lib.rs | 34 ++++++++++-------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/precompiles/parachain-staking/src/lib.rs b/precompiles/parachain-staking/src/lib.rs index e38b7ef0..9697264b 100644 --- a/precompiles/parachain-staking/src/lib.rs +++ b/precompiles/parachain-staking/src/lib.rs @@ -75,22 +75,19 @@ where handle.record_db_read::(7200)?; let all_collators = parachain_staking::CandidatePool::::iter() - .map(|(_id, stake_info)| { - CollatorInfo { - owner: H256::from( as Into<[u8; 32]>>::into(stake_info.id)), - amount: stake_info.stake.into(), - commission: U256::from(stake_info.commission.deconstruct() as u128), - } - }).collect::>(); + .map(|(_id, stake_info)| CollatorInfo { + owner: H256::from( as Into<[u8; 32]>>::into(stake_info.id)), + amount: stake_info.stake.into(), + commission: U256::from(stake_info.commission.deconstruct() as u128), + }) + .collect::>(); let top_candiate = parachain_staking::Pallet::::top_candidates() .into_iter() .map(|stake_info| { H256::from( as Into<[u8; 32]>>::into(stake_info.owner)) }) .collect::>(); - let candidate_list = all_collators - .into_iter() - .filter(|x| top_candiate.contains(&x.owner)); + let candidate_list = all_collators.into_iter().filter(|x| top_candiate.contains(&x.owner)); Ok(candidate_list.collect::>()) } @@ -104,22 +101,19 @@ where handle.record_db_read::(7200)?; let all_collators = parachain_staking::CandidatePool::::iter() - .map(|(_id, stake_info)| { - CollatorInfo { - owner: H256::from( as Into<[u8; 32]>>::into(stake_info.id)), - amount: stake_info.stake.into(), - commission: U256::from(stake_info.commission.deconstruct() as u128), - } - }).collect::>(); + .map(|(_id, stake_info)| CollatorInfo { + owner: H256::from( as Into<[u8; 32]>>::into(stake_info.id)), + amount: stake_info.stake.into(), + commission: U256::from(stake_info.commission.deconstruct() as u128), + }) + .collect::>(); let top_candiate = parachain_staking::Pallet::::top_candidates() .into_iter() .map(|stake_info| { H256::from( as Into<[u8; 32]>>::into(stake_info.owner)) }) .collect::>(); - let candidate_list = all_collators - .into_iter() - .filter(|x| !top_candiate.contains(&x.owner)); + let candidate_list = all_collators.into_iter().filter(|x| !top_candiate.contains(&x.owner)); Ok(candidate_list.collect::>()) } From 2e1dd53e99e4a72d2dabf076bc32e82605e4a167 Mon Sep 17 00:00:00 2001 From: jaypan Date: Wed, 18 Dec 2024 18:24:28 +0100 Subject: [PATCH 3/6] Fix the test fails --- precompiles/parachain-staking/src/tests.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/precompiles/parachain-staking/src/tests.rs b/precompiles/parachain-staking/src/tests.rs index c45ceca3..de1b2c92 100644 --- a/precompiles/parachain-staking/src/tests.rs +++ b/precompiles/parachain-staking/src/tests.rs @@ -102,10 +102,12 @@ fn collator_list_test() { CollatorInfo { owner: convert_mock_account_by_u8_list(MockPeaqAccount::Alice), amount: U256::from(110), + commission: U256::from(0), }, CollatorInfo { owner: convert_mock_account_by_u8_list(MockPeaqAccount::Charlie), amount: U256::from(20), + commission: U256::from(0), }, ]); }); From 3f1255514a97a28b7eae6dd5bef40b5c7c54fabb Mon Sep 17 00:00:00 2001 From: jaypan Date: Wed, 18 Dec 2024 19:59:04 +0100 Subject: [PATCH 4/6] Fix the logic to take the first top n --- pallets/parachain-staking/src/lib.rs | 3 ++- precompiles/parachain-staking/src/lib.rs | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pallets/parachain-staking/src/lib.rs b/pallets/parachain-staking/src/lib.rs index 97bea90c..d36dba90 100644 --- a/pallets/parachain-staking/src/lib.rs +++ b/pallets/parachain-staking/src/lib.rs @@ -540,9 +540,10 @@ pub mod pallet { } /// The maximum number of collator candidates selected at each round. + /// precompiles will call this #[pallet::storage] #[pallet::getter(fn max_selected_candidates)] - pub(crate) type MaxSelectedCandidates = StorageValue<_, u32, ValueQuery>; + pub type MaxSelectedCandidates = StorageValue<_, u32, ValueQuery>; /// Current round number and next round scheduled transition. #[pallet::storage] diff --git a/precompiles/parachain-staking/src/lib.rs b/precompiles/parachain-staking/src/lib.rs index 9697264b..8fa5971e 100644 --- a/precompiles/parachain-staking/src/lib.rs +++ b/precompiles/parachain-staking/src/lib.rs @@ -112,6 +112,7 @@ where .map(|stake_info| { H256::from( as Into<[u8; 32]>>::into(stake_info.owner)) }) + .take(parachain_staking::MaxSelectedCandidates::::get() as usize) .collect::>(); let candidate_list = all_collators.into_iter().filter(|x| !top_candiate.contains(&x.owner)); Ok(candidate_list.collect::>()) From b4474c3db2eca283b3cf362b4f16b2dedfc6c2c2 Mon Sep 17 00:00:00 2001 From: jaypan Date: Wed, 18 Dec 2024 21:07:33 +0100 Subject: [PATCH 5/6] Use the session list instead of top candidate and should use total stakinig --- precompiles/parachain-staking/Cargo.toml | 2 +- precompiles/parachain-staking/src/lib.rs | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/precompiles/parachain-staking/Cargo.toml b/precompiles/parachain-staking/Cargo.toml index 7d4e9a2e..1356b531 100644 --- a/precompiles/parachain-staking/Cargo.toml +++ b/precompiles/parachain-staking/Cargo.toml @@ -10,6 +10,7 @@ authors = [ "Peaq" ] precompile-utils = { path = "../utils", default-features = false } parachain-staking = { path = "../../pallets/parachain-staking", default-features = false } address-unification = { path = "../../pallets/address-unification", default-features = false } +pallet-session = { workspace = true, default-features = false } # Substrate parity-scale-codec = { workspace = true, features = ["max-encoded-len"] } @@ -36,7 +37,6 @@ precompile-utils = { path = "../utils", features = [ "std", "testing" ] } pallet-timestamp = { workspace = true, features = [ "std" ] } scale-info = { workspace = true } pallet-authorship = { workspace = true, default-features = false } -pallet-session = { workspace = true, default-features = false } [features] default = ["std", "experimental"] diff --git a/precompiles/parachain-staking/src/lib.rs b/precompiles/parachain-staking/src/lib.rs index 8fa5971e..2f173fdc 100644 --- a/precompiles/parachain-staking/src/lib.rs +++ b/precompiles/parachain-staking/src/lib.rs @@ -56,7 +56,7 @@ pub struct CollatorInfo { #[precompile_utils::precompile] impl ParachainStakingPrecompile where - Runtime: parachain_staking::Config + pallet_evm::Config, + Runtime: parachain_staking::Config + pallet_evm::Config + pallet_session::Config, Runtime::RuntimeCall: Dispatchable + GetDispatchInfo, ::RuntimeOrigin: From>, Runtime::RuntimeCall: From>, @@ -77,7 +77,7 @@ where let all_collators = parachain_staking::CandidatePool::::iter() .map(|(_id, stake_info)| CollatorInfo { owner: H256::from( as Into<[u8; 32]>>::into(stake_info.id)), - amount: stake_info.stake.into(), + amount: stake_info.total.into(), commission: U256::from(stake_info.commission.deconstruct() as u128), }) .collect::>(); @@ -103,18 +103,17 @@ where let all_collators = parachain_staking::CandidatePool::::iter() .map(|(_id, stake_info)| CollatorInfo { owner: H256::from( as Into<[u8; 32]>>::into(stake_info.id)), - amount: stake_info.stake.into(), + amount: stake_info.total.into(), commission: U256::from(stake_info.commission.deconstruct() as u128), }) .collect::>(); - let top_candiate = parachain_staking::Pallet::::top_candidates() + let validators = pallet_session::Pallet::::validators() .into_iter() - .map(|stake_info| { - H256::from( as Into<[u8; 32]>>::into(stake_info.owner)) + .map(|info| { + H256::from( as Into<[u8; 32]>>::into(info)) }) - .take(parachain_staking::MaxSelectedCandidates::::get() as usize) .collect::>(); - let candidate_list = all_collators.into_iter().filter(|x| !top_candiate.contains(&x.owner)); + let candidate_list = all_collators.into_iter().filter(|x| !validators.contains(&x.owner)); Ok(candidate_list.collect::>()) } From 40860fbd17a8a2aec9b310118604c61d77e2c831 Mon Sep 17 00:00:00 2001 From: jaypan Date: Wed, 18 Dec 2024 21:09:34 +0100 Subject: [PATCH 6/6] Fix fmt --- precompiles/parachain-staking/src/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/precompiles/parachain-staking/src/lib.rs b/precompiles/parachain-staking/src/lib.rs index 2f173fdc..83894f78 100644 --- a/precompiles/parachain-staking/src/lib.rs +++ b/precompiles/parachain-staking/src/lib.rs @@ -109,9 +109,7 @@ where .collect::>(); let validators = pallet_session::Pallet::::validators() .into_iter() - .map(|info| { - H256::from( as Into<[u8; 32]>>::into(info)) - }) + .map(|info| H256::from( as Into<[u8; 32]>>::into(info))) .collect::>(); let candidate_list = all_collators.into_iter().filter(|x| !validators.contains(&x.owner)); Ok(candidate_list.collect::>())