Skip to content

Commit

Permalink
Auto publish contracts (#2099)
Browse files Browse the repository at this point in the history
* auto publish

* add call_address

* Apply review suggestions

* update tests

* update tests

* fix maintainer

* remove env_logger

* Apply suggestions from code review

Co-authored-by: Xiliang Chen <xlchen1291@gmail.com>

* Apply review suggestions

* format

Co-authored-by: Xiliang Chen <xlchen1291@gmail.com>
  • Loading branch information
zjb0807 and xlc authored May 16, 2022
1 parent 5378517 commit aa93133
Show file tree
Hide file tree
Showing 19 changed files with 8,087 additions and 5,470 deletions.
2 changes: 2 additions & 0 deletions modules/evm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ module-transaction-payment = { path = "../../modules/transaction-payment", defau
xcm-builder = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.19", default-features = false }

[dev-dependencies]
hex = "0.4"
env_logger = "0.9.0"
serde_json = "1.0.68"

[features]
default = ["std"]
Expand Down
18 changes: 5 additions & 13 deletions modules/evm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,10 +423,7 @@ pub mod module {
);

let out = runtime.machine().return_value();
<Pallet<T>>::create_contract(source, *address, out);

#[cfg(not(feature = "with-ethereum-compatibility"))]
<Pallet<T>>::mark_published(*address, None).expect("Genesis contract failed to publish");
<Pallet<T>>::create_contract(source, *address, true, out);

for (index, value) in &account.storage {
AccountStorages::<T>::insert(address, index, value);
Expand Down Expand Up @@ -1293,7 +1290,7 @@ impl<T: Config> Pallet<T> {
/// - Update codes info.
/// - Update maintainer of the contract.
/// - Save `code` if not saved yet.
pub fn create_contract(source: H160, address: H160, code: Vec<u8>) {
pub fn create_contract(source: H160, address: H160, publish: bool, code: Vec<u8>) {
let bounded_code: BoundedVec<u8, MaxCodeSize> = code
.try_into()
.expect("checked by create_contract_limit in ACALA_CONFIG; qed");
Expand All @@ -1302,13 +1299,8 @@ impl<T: Config> Pallet<T> {
}

// if source is account, the maintainer of the new contract is source.
// if source is contract, the maintainer of the new contract is the maintainer of the contract.
let maintainer = Self::accounts(source).map_or(source, |account_info| {
account_info
.contract_info
.map_or(source, |contract_info| contract_info.maintainer)
});

// if source is contract, the maintainer of the new contract is the source contract.
let maintainer = source;
let code_hash = code_hash(bounded_code.as_slice());
let code_size = bounded_code.len() as u32;

Expand All @@ -1318,7 +1310,7 @@ impl<T: Config> Pallet<T> {
#[cfg(feature = "with-ethereum-compatibility")]
published: true,
#[cfg(not(feature = "with-ethereum-compatibility"))]
published: false,
published: publish,
};

CodeInfos::<T>::mutate_exists(&code_hash, |maybe_code_info| {
Expand Down
17 changes: 10 additions & 7 deletions modules/evm/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,12 +218,13 @@ construct_runtime!(
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic,
{
System: frame_system::{Pallet, Call, Storage, Config, Event<T>},
EVM: evm_mod::{Pallet, Config<T>, Call, Storage, Event<T>},
Tokens: orml_tokens::{Pallet, Storage, Event<T>},
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
Currencies: orml_currencies::{Pallet, Call},
IdleScheduler: module_idle_scheduler::{Pallet, Call, Storage, Event<T>},
System: frame_system,
Timestamp: pallet_timestamp,
EVM: evm_mod,
Tokens: orml_tokens,
Balances: pallet_balances,
Currencies: orml_currencies,
IdleScheduler: module_idle_scheduler,
}
);

Expand Down Expand Up @@ -298,7 +299,9 @@ pub fn new_test_ext() -> sp_io::TestExternalities {
.unwrap();

let mut ext = sp_io::TestExternalities::new(t);
ext.execute_with(|| System::set_block_number(1));
ext.execute_with(|| {
System::set_block_number(1);
});
ext
}

Expand Down
44 changes: 24 additions & 20 deletions modules/evm/src/runner/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -792,13 +792,10 @@ impl<'vicinity, 'config, T: Config> StackStateT<'config> for SubstrateStackState
address
);

let caller: H160;
let mut substate = &self.substate;

loop {
// get maintainer from parent caller
// `enter_substate` will do `spit_child`
if substate.parent.is_none() {
// get maintainer from parent caller `enter_substate` will do `spit_child`
let parent = match self.substate.parent {
Some(ref parent) => parent,
None => {
log::error!(
target: "evm",
"get parent's maintainer failed. address: {:?}",
Expand All @@ -807,28 +804,35 @@ impl<'vicinity, 'config, T: Config> StackStateT<'config> for SubstrateStackState
debug_assert!(false);
return;
}
};

substate = substate.parent.as_ref().expect("has checked; qed");

if let Some(c) = substate.metadata().caller() {
// the caller maybe is contract and not published.
// get the parent's maintainer.
if !Pallet::<T>::is_account_empty(c) {
caller = *c;
break;
}
let caller = match parent.metadata().caller() {
Some(ref caller) => caller,
None => {
log::error!(
target: "evm",
"get parent's caller failed. address: {:?}",
address
);
debug_assert!(false);
return;
}
}
};

let is_published = self.substate.metadata.origin_code_address().map_or(false, |addr| {
Pallet::<T>::accounts(addr).map_or(false, |account| account.contract_info.map_or(false, |v| v.published))
});

log::debug!(
target: "evm",
"set_code: address: {:?}, maintainer: {:?}",
"set_code: address: {:?}, maintainer: {:?}, publish: {:?}",
address,
caller
caller,
is_published
);

let code_size = code.len() as u32;
Pallet::<T>::create_contract(caller, address, code);
Pallet::<T>::create_contract(*caller, address, is_published, code);

let used_storage = code_size.saturating_add(T::NewContractExtraBytes::get());
Pallet::<T>::update_contract_storage_size(&address, used_storage as i32);
Expand Down
14 changes: 14 additions & 0 deletions modules/evm/src/runner/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ pub struct StackSubstateMetadata<'config> {
caller: Option<H160>,
// save the contract to charge storage
target: Option<H160>,
// save the call contract address, publish status will sync from it.
origin_code_address: Option<H160>,
// this is needed only for evm-tests to keep track of dirty accounts
#[cfg(feature = "evm-tests")]
pub dirty_accounts: std::cell::RefCell<BTreeSet<H160>>,
Expand All @@ -167,6 +169,7 @@ impl<'config> StackSubstateMetadata<'config> {
accessed,
caller: None,
target: None,
origin_code_address: None,
#[cfg(feature = "evm-tests")]
dirty_accounts: std::cell::RefCell::new(BTreeSet::new()),
}
Expand Down Expand Up @@ -218,6 +221,7 @@ impl<'config> StackSubstateMetadata<'config> {
accessed: self.accessed.as_ref().map(|_| Accessed::default()),
caller: None,
target: None,
origin_code_address: self.origin_code_address,
#[cfg(feature = "evm-tests")]
dirty_accounts: std::cell::RefCell::new(BTreeSet::new()),
}
Expand Down Expand Up @@ -296,6 +300,14 @@ impl<'config> StackSubstateMetadata<'config> {
pub fn target_mut(&mut self) -> &mut Option<H160> {
&mut self.target
}

pub fn origin_code_address(&mut self) -> &Option<H160> {
&self.origin_code_address
}

pub fn origin_code_address_mut(&mut self) -> &mut Option<H160> {
&mut self.origin_code_address
}
}

pub trait StackState<'config>: Backend {
Expand Down Expand Up @@ -632,6 +644,8 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> StackExecu
Ok(()) => (),
Err(e) => return emit_exit!(e.into(), Vec::new()),
}
// set origin_code_address publish status will sync from it.
*self.state.metadata_mut().origin_code_address_mut() = Some(address);

// Initialize initial addresses for EIP-2929
if self.config.increase_state_access_gas {
Expand Down
Loading

0 comments on commit aa93133

Please sign in to comment.