diff --git a/pallets/parachain-staking/src/lib.rs b/pallets/parachain-staking/src/lib.rs index 31669ea6..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] @@ -576,9 +577,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/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/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..83894f78 100644 --- a/precompiles/parachain-staking/src/lib.rs +++ b/precompiles/parachain-staking/src/lib.rs @@ -50,12 +50,13 @@ pub struct ParachainStakingPrecompile(PhantomData); pub struct CollatorInfo { owner: H256, amount: U256, + commission: U256, } #[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>, @@ -73,13 +74,45 @@ 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.total.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.total.into(), + commission: U256::from(stake_info.commission.deconstruct() as u128), + }) + .collect::>(); + let validators = pallet_session::Pallet::::validators() + .into_iter() + .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::>()) } #[precompile::public("joinDelegators(bytes32,uint256)")] 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), }, ]); });