diff --git a/prdoc/pr_9988.prdoc b/prdoc/pr_9988.prdoc new file mode 100644 index 0000000000000..e35f69bc8d5f1 --- /dev/null +++ b/prdoc/pr_9988.prdoc @@ -0,0 +1,8 @@ +title: '[pallet-revive] improve revive genesis config' +doc: +- audience: Runtime Dev + description: |- + GenesisConfig: make sure that contracts are brought to existence by minting e.d first +crates: +- name: pallet-revive + bump: patch diff --git a/substrate/frame/revive/src/lib.rs b/substrate/frame/revive/src/lib.rs index b83cd2962acec..31e96769bef77 100644 --- a/substrate/frame/revive/src/lib.rs +++ b/substrate/frame/revive/src/lib.rs @@ -743,6 +743,10 @@ pub mod pallet { for genesis::Account { address, balance, nonce, contract_data } in &self.accounts { let account_id = T::AddressMapper::to_account_id(address); + if !System::::account_exists(&account_id) { + let _ = T::Currency::mint_into(&account_id, T::Currency::minimum_balance()); + } + frame_system::Account::::mutate(&account_id, |info| { info.nonce = (*nonce).into(); }); diff --git a/substrate/frame/revive/src/tests.rs b/substrate/frame/revive/src/tests.rs index 5a7df62f35710..38fb4117ac122 100644 --- a/substrate/frame/revive/src/tests.rs +++ b/substrate/frame/revive/src/tests.rs @@ -518,7 +518,7 @@ impl Default for Origin { #[test] fn ext_builder_with_genesis_config_works() { let pvm_contract = Account { - address: BOB_ADDR, + address: crate::H160::repeat_byte(0x42), balance: U256::from(100_000_100), nonce: 42, contract_data: Some(ContractData { @@ -528,11 +528,17 @@ fn ext_builder_with_genesis_config_works() { }; let evm_contract = Account { - address: CHARLIE_ADDR, + address: crate::H160::repeat_byte(0x43), balance: U256::from(1_000_00_100), nonce: 43, contract_data: Some(ContractData { - code: vec![revm::bytecode::opcode::RETURN], + code: vec![ + revm::bytecode::opcode::PUSH1, + 0x00, + revm::bytecode::opcode::PUSH1, + 0x00, + revm::bytecode::opcode::RETURN, + ], storage: [([3u8; 32].into(), [4u8; 32].into())].into_iter().collect(), }), }; @@ -561,6 +567,11 @@ fn ext_builder_with_genesis_config_works() { for contract in [pvm_contract, evm_contract] { let contract_data = contract.contract_data.unwrap(); let contract_info = test_utils::get_contract(&contract.address); + + assert!(System::account_exists(&::AddressMapper::to_account_id( + &contract.address + ))); + assert_eq!( PristineCode::::get(&contract_info.code_hash).unwrap(), contract_data.code @@ -574,6 +585,10 @@ fn ext_builder_with_genesis_config_works() { Ok(Some(value.0.to_vec())) ); } + + // Check that we can call contract created at genesis + let result = builder::bare_call(contract.address).build_and_unwrap_result(); + assert!(!result.did_revert()); } }); }