Skip to main content

revive_env/
lib.rs

1//! This module provides an externalities builder for setting an environment with the Revive
2//! runtime.
3//!
4//! It is heavily inspired from here: <https://github.com/paritytech/revive/blob/56aadce0a9554e68a08feb35cffb65574d7a618b/crates/runner/src/lib.rs#L69>
5//!
6//! THIS IS WORK IN PROGRESS. It is not yet complete and may change in the future.
7#![allow(clippy::disallowed_macros)]
8use polkadot_sdk::{
9    frame_support::traits::{OnGenesis, fungible::Mutate},
10    frame_system::{self, Pallet},
11    pallet_balances,
12    pallet_revive::{self, AccountId32Mapper, AddressMapper},
13    polkadot_runtime_common::BuildStorage,
14    sp_core::H160,
15    sp_io,
16    sp_keystore::{KeystoreExt, testing::MemoryKeystore},
17    sp_runtime::AccountId32,
18    sp_tracing,
19};
20
21pub use crate::runtime::{
22    Balance, Balances, BlockAuthor, GasScale, NativeToEthRatio, Runtime, RuntimeHoldReason, System,
23    Timestamp,
24};
25pub use polkadot_sdk::parachains_common::AccountId;
26mod runtime;
27
28/// Externalities builder
29#[derive(Default)]
30pub struct ExtBuilder {
31    // List of endowments at genesis
32    balance_genesis_config: Vec<(AccountId32, Balance)>,
33}
34
35impl ExtBuilder {
36    /// Set the balance of an account at genesis
37    pub fn balance_genesis_config(self, value: Vec<(H160, Balance)>) -> Self {
38        Self {
39            balance_genesis_config: value
40                .iter()
41                .map(|(address, balance)| {
42                    let acc: AccountId32 =
43                        AccountId32Mapper::<Runtime>::to_fallback_account_id(address);
44                    (acc, *balance)
45                })
46                .collect(),
47        }
48    }
49
50    /// Build the externalities
51    pub fn build(self) -> sp_io::TestExternalities {
52        sp_tracing::try_init_simple();
53        let mut t = frame_system::GenesisConfig::<Runtime>::default().build_storage().unwrap();
54
55        pallet_balances::GenesisConfig::<Runtime> {
56            balances: self.balance_genesis_config,
57            dev_accounts: None,
58        }
59        .assimilate_storage(&mut t)
60        .unwrap();
61
62        pallet_revive::GenesisConfig::<Runtime>::default().assimilate_storage(&mut t).unwrap();
63        let mut ext = sp_io::TestExternalities::new(t);
64        ext.register_extension(KeystoreExt::new(MemoryKeystore::new()));
65        ext.execute_with(|| {
66            Pallet::<Runtime>::on_genesis();
67            System::set_block_number(0);
68
69            // Set a large balance for pallet account to handle storage deposits during contract
70            // migration Using a reasonable large value to avoid overflow when minting
71            let pallet_account = pallet_revive::Pallet::<Runtime>::account_id();
72            let large_balance: Balance = 1_000_000_000_000_000_000_000_000_000_u128;
73            let _ = <Runtime as pallet_revive::Config>::Currency::mint_into(
74                &pallet_account,
75                large_balance,
76            );
77
78            let _ = pallet_revive::Pallet::<Runtime>::map_account(
79                frame_system::RawOrigin::Signed(pallet_account).into(),
80            );
81        });
82        ext.commit_all().unwrap();
83        ext
84    }
85}
86
87#[cfg(test)]
88mod tests {
89    use super::*;
90
91    #[test]
92    fn test_externalities_works() {
93        let mut ext = ExtBuilder::default()
94            .balance_genesis_config(vec![(H160::from_low_u64_be(1), 1000)])
95            .build();
96        ext.execute_with(|| {
97            assert_eq!(
98                pallet_balances::Pallet::<Runtime>::free_balance(
99                    AccountId32Mapper::<Runtime>::to_fallback_account_id(&H160::from_low_u64_be(1))
100                ),
101                1000
102            );
103        });
104    }
105
106    #[test]
107    fn test_changing_block_number() {
108        let mut ext = ExtBuilder::default().build();
109        ext.execute_with(|| {
110            assert_eq!(System::block_number(), 0);
111            System::set_block_number(5);
112            assert_eq!(System::block_number(), 5);
113        });
114    }
115}