mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-25 09:25:46 +00:00
pallet-evm: refactor duplicate code in call/create/create2 (#4922)
* pallet-evm: refactor duplicate code in call/create/create2 * Bump runtime version
This commit is contained in:
@@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
|
|||||||
// implementation changes and behavior does not, then leave spec_version as
|
// implementation changes and behavior does not, then leave spec_version as
|
||||||
// is and increment impl_version.
|
// is and increment impl_version.
|
||||||
spec_version: 217,
|
spec_version: 217,
|
||||||
impl_version: 0,
|
impl_version: 1,
|
||||||
apis: RUNTIME_API_VERSIONS,
|
apis: RUNTIME_API_VERSIONS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+100
-141
@@ -232,54 +232,22 @@ decl_module! {
|
|||||||
nonce: Option<U256>,
|
nonce: Option<U256>,
|
||||||
) -> DispatchResult {
|
) -> DispatchResult {
|
||||||
let sender = ensure_signed(origin)?;
|
let sender = ensure_signed(origin)?;
|
||||||
ensure!(gas_price >= T::FeeCalculator::min_gas_price(), Error::<T>::GasPriceTooLow);
|
|
||||||
let source = T::ConvertAccountId::convert_account_id(&sender);
|
let source = T::ConvertAccountId::convert_account_id(&sender);
|
||||||
|
|
||||||
let vicinity = Vicinity {
|
Self::execute_evm(
|
||||||
gas_price,
|
|
||||||
origin: source,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut backend = Backend::<T>::new(&vicinity);
|
|
||||||
let mut executor = StackExecutor::new_with_precompile(
|
|
||||||
&backend,
|
|
||||||
gas_limit as usize,
|
|
||||||
&backend::GASOMETER_CONFIG,
|
|
||||||
T::Precompiles::execute,
|
|
||||||
);
|
|
||||||
|
|
||||||
let total_fee = gas_price.checked_mul(U256::from(gas_limit))
|
|
||||||
.ok_or(Error::<T>::FeeOverflow)?;
|
|
||||||
let total_payment = value.checked_add(total_fee).ok_or(Error::<T>::PaymentOverflow)?;
|
|
||||||
let source_account = Accounts::get(&source);
|
|
||||||
ensure!(source_account.balance >= total_payment, Error::<T>::BalanceLow);
|
|
||||||
executor.withdraw(source, total_fee).map_err(|_| Error::<T>::WithdrawFailed)?;
|
|
||||||
|
|
||||||
if let Some(nonce) = nonce {
|
|
||||||
ensure!(source_account.nonce == nonce, Error::<T>::InvalidNonce);
|
|
||||||
}
|
|
||||||
|
|
||||||
let reason = executor.transact_call(
|
|
||||||
source,
|
source,
|
||||||
target,
|
|
||||||
value,
|
value,
|
||||||
input,
|
gas_limit,
|
||||||
gas_limit as usize,
|
gas_price,
|
||||||
);
|
nonce,
|
||||||
|
|executor| ((), executor.transact_call(
|
||||||
let ret = match reason {
|
source,
|
||||||
ExitReason::Succeed(_) => Ok(()),
|
target,
|
||||||
ExitReason::Error(_) => Err(Error::<T>::ExitReasonFailed),
|
value,
|
||||||
ExitReason::Revert(_) => Err(Error::<T>::ExitReasonRevert),
|
input,
|
||||||
ExitReason::Fatal(_) => Err(Error::<T>::ExitReasonFatal),
|
gas_limit as usize,
|
||||||
};
|
)),
|
||||||
let actual_fee = executor.fee(gas_price);
|
).map_err(Into::into)
|
||||||
executor.deposit(source, total_fee.saturating_sub(actual_fee));
|
|
||||||
|
|
||||||
let (values, logs) = executor.deconstruct();
|
|
||||||
backend.apply(values, logs, true);
|
|
||||||
|
|
||||||
ret.map_err(Into::into)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Issue an EVM create operation. This is similar to a contract creation transaction in
|
/// Issue an EVM create operation. This is similar to a contract creation transaction in
|
||||||
@@ -294,60 +262,28 @@ decl_module! {
|
|||||||
nonce: Option<U256>,
|
nonce: Option<U256>,
|
||||||
) -> DispatchResult {
|
) -> DispatchResult {
|
||||||
let sender = ensure_signed(origin)?;
|
let sender = ensure_signed(origin)?;
|
||||||
ensure!(gas_price >= T::FeeCalculator::min_gas_price(), Error::<T>::GasPriceTooLow);
|
|
||||||
|
|
||||||
let source = T::ConvertAccountId::convert_account_id(&sender);
|
let source = T::ConvertAccountId::convert_account_id(&sender);
|
||||||
|
|
||||||
let vicinity = Vicinity {
|
let create_address = Self::execute_evm(
|
||||||
gas_price,
|
|
||||||
origin: source,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut backend = Backend::<T>::new(&vicinity);
|
|
||||||
let mut executor = StackExecutor::new_with_precompile(
|
|
||||||
&backend,
|
|
||||||
gas_limit as usize,
|
|
||||||
&backend::GASOMETER_CONFIG,
|
|
||||||
T::Precompiles::execute,
|
|
||||||
);
|
|
||||||
|
|
||||||
let total_fee = gas_price.checked_mul(U256::from(gas_limit))
|
|
||||||
.ok_or(Error::<T>::FeeOverflow)?;
|
|
||||||
let total_payment = value.checked_add(total_fee).ok_or(Error::<T>::PaymentOverflow)?;
|
|
||||||
let source_account = Accounts::get(&source);
|
|
||||||
ensure!(source_account.balance >= total_payment, Error::<T>::BalanceLow);
|
|
||||||
executor.withdraw(source, total_fee).map_err(|_| Error::<T>::WithdrawFailed)?;
|
|
||||||
|
|
||||||
if let Some(nonce) = nonce {
|
|
||||||
ensure!(source_account.nonce == nonce, Error::<T>::InvalidNonce);
|
|
||||||
}
|
|
||||||
|
|
||||||
let create_address = executor.create_address(
|
|
||||||
evm::CreateScheme::Legacy { caller: source }
|
|
||||||
);
|
|
||||||
let reason = executor.transact_create(
|
|
||||||
source,
|
source,
|
||||||
value,
|
value,
|
||||||
init,
|
gas_limit,
|
||||||
gas_limit as usize,
|
gas_price,
|
||||||
);
|
nonce,
|
||||||
|
|executor| {
|
||||||
let ret = match reason {
|
(executor.create_address(
|
||||||
ExitReason::Succeed(_) => {
|
evm::CreateScheme::Legacy { caller: source },
|
||||||
Module::<T>::deposit_event(Event::Created(create_address));
|
), executor.transact_create(
|
||||||
Ok(())
|
source,
|
||||||
|
value,
|
||||||
|
init,
|
||||||
|
gas_limit as usize,
|
||||||
|
))
|
||||||
},
|
},
|
||||||
ExitReason::Error(_) => Err(Error::<T>::ExitReasonFailed),
|
)?;
|
||||||
ExitReason::Revert(_) => Err(Error::<T>::ExitReasonRevert),
|
|
||||||
ExitReason::Fatal(_) => Err(Error::<T>::ExitReasonFatal),
|
|
||||||
};
|
|
||||||
let actual_fee = executor.fee(gas_price);
|
|
||||||
executor.deposit(source, total_fee.saturating_sub(actual_fee));
|
|
||||||
|
|
||||||
let (values, logs) = executor.deconstruct();
|
Module::<T>::deposit_event(Event::Created(create_address));
|
||||||
backend.apply(values, logs, true);
|
Ok(())
|
||||||
|
|
||||||
ret.map_err(Into::into)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Issue an EVM create2 operation.
|
/// Issue an EVM create2 operation.
|
||||||
@@ -362,62 +298,30 @@ decl_module! {
|
|||||||
nonce: Option<U256>,
|
nonce: Option<U256>,
|
||||||
) -> DispatchResult {
|
) -> DispatchResult {
|
||||||
let sender = ensure_signed(origin)?;
|
let sender = ensure_signed(origin)?;
|
||||||
ensure!(gas_price >= T::FeeCalculator::min_gas_price(), Error::<T>::GasPriceTooLow);
|
|
||||||
|
|
||||||
let source = T::ConvertAccountId::convert_account_id(&sender);
|
let source = T::ConvertAccountId::convert_account_id(&sender);
|
||||||
|
|
||||||
let vicinity = Vicinity {
|
|
||||||
gas_price,
|
|
||||||
origin: source,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut backend = Backend::<T>::new(&vicinity);
|
|
||||||
let mut executor = StackExecutor::new_with_precompile(
|
|
||||||
&backend,
|
|
||||||
gas_limit as usize,
|
|
||||||
&backend::GASOMETER_CONFIG,
|
|
||||||
T::Precompiles::execute,
|
|
||||||
);
|
|
||||||
|
|
||||||
let total_fee = gas_price.checked_mul(U256::from(gas_limit))
|
|
||||||
.ok_or(Error::<T>::FeeOverflow)?;
|
|
||||||
let total_payment = value.checked_add(total_fee).ok_or(Error::<T>::PaymentOverflow)?;
|
|
||||||
let source_account = Accounts::get(&source);
|
|
||||||
ensure!(source_account.balance >= total_payment, Error::<T>::BalanceLow);
|
|
||||||
executor.withdraw(source, total_fee).map_err(|_| Error::<T>::WithdrawFailed)?;
|
|
||||||
|
|
||||||
if let Some(nonce) = nonce {
|
|
||||||
ensure!(source_account.nonce == nonce, Error::<T>::InvalidNonce);
|
|
||||||
}
|
|
||||||
|
|
||||||
let code_hash = H256::from_slice(Keccak256::digest(&init).as_slice());
|
let code_hash = H256::from_slice(Keccak256::digest(&init).as_slice());
|
||||||
let create_address = executor.create_address(
|
let create_address = Self::execute_evm(
|
||||||
evm::CreateScheme::Create2 { caller: source, code_hash, salt }
|
|
||||||
);
|
|
||||||
let reason = executor.transact_create2(
|
|
||||||
source,
|
source,
|
||||||
value,
|
value,
|
||||||
init,
|
gas_limit,
|
||||||
salt,
|
gas_price,
|
||||||
gas_limit as usize,
|
nonce,
|
||||||
);
|
|executor| {
|
||||||
|
(executor.create_address(
|
||||||
let ret = match reason {
|
evm::CreateScheme::Create2 { caller: source, code_hash, salt },
|
||||||
ExitReason::Succeed(_) => {
|
), executor.transact_create2(
|
||||||
Module::<T>::deposit_event(Event::Created(create_address));
|
source,
|
||||||
Ok(())
|
value,
|
||||||
|
init,
|
||||||
|
salt,
|
||||||
|
gas_limit as usize,
|
||||||
|
))
|
||||||
},
|
},
|
||||||
ExitReason::Error(_) => Err(Error::<T>::ExitReasonFailed),
|
)?;
|
||||||
ExitReason::Revert(_) => Err(Error::<T>::ExitReasonRevert),
|
|
||||||
ExitReason::Fatal(_) => Err(Error::<T>::ExitReasonFatal),
|
|
||||||
};
|
|
||||||
let actual_fee = executor.fee(gas_price);
|
|
||||||
executor.deposit(source, total_fee.saturating_sub(actual_fee));
|
|
||||||
|
|
||||||
let (values, logs) = executor.deconstruct();
|
Module::<T>::deposit_event(Event::Created(create_address));
|
||||||
backend.apply(values, logs, true);
|
Ok(())
|
||||||
|
|
||||||
ret.map_err(Into::into)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -454,4 +358,59 @@ impl<T: Trait> Module<T> {
|
|||||||
AccountCodes::remove(address);
|
AccountCodes::remove(address);
|
||||||
AccountStorages::remove_prefix(address);
|
AccountStorages::remove_prefix(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Execute an EVM operation.
|
||||||
|
fn execute_evm<F, R>(
|
||||||
|
source: H160,
|
||||||
|
value: U256,
|
||||||
|
gas_limit: u32,
|
||||||
|
gas_price: U256,
|
||||||
|
nonce: Option<U256>,
|
||||||
|
f: F,
|
||||||
|
) -> Result<R, Error<T>> where
|
||||||
|
F: FnOnce(&mut StackExecutor<Backend<T>>) -> (R, ExitReason),
|
||||||
|
{
|
||||||
|
ensure!(gas_price >= T::FeeCalculator::min_gas_price(), Error::<T>::GasPriceTooLow);
|
||||||
|
|
||||||
|
let vicinity = Vicinity {
|
||||||
|
gas_price,
|
||||||
|
origin: source,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut backend = Backend::<T>::new(&vicinity);
|
||||||
|
let mut executor = StackExecutor::new_with_precompile(
|
||||||
|
&backend,
|
||||||
|
gas_limit as usize,
|
||||||
|
&backend::GASOMETER_CONFIG,
|
||||||
|
T::Precompiles::execute,
|
||||||
|
);
|
||||||
|
|
||||||
|
let total_fee = gas_price.checked_mul(U256::from(gas_limit))
|
||||||
|
.ok_or(Error::<T>::FeeOverflow)?;
|
||||||
|
let total_payment = value.checked_add(total_fee).ok_or(Error::<T>::PaymentOverflow)?;
|
||||||
|
let source_account = Accounts::get(&source);
|
||||||
|
ensure!(source_account.balance >= total_payment, Error::<T>::BalanceLow);
|
||||||
|
executor.withdraw(source, total_fee).map_err(|_| Error::<T>::WithdrawFailed)?;
|
||||||
|
|
||||||
|
if let Some(nonce) = nonce {
|
||||||
|
ensure!(source_account.nonce == nonce, Error::<T>::InvalidNonce);
|
||||||
|
}
|
||||||
|
|
||||||
|
let (retv, reason) = f(&mut executor);
|
||||||
|
|
||||||
|
let ret = match reason {
|
||||||
|
ExitReason::Succeed(_) => Ok(retv),
|
||||||
|
ExitReason::Error(_) => Err(Error::<T>::ExitReasonFailed),
|
||||||
|
ExitReason::Revert(_) => Err(Error::<T>::ExitReasonRevert),
|
||||||
|
ExitReason::Fatal(_) => Err(Error::<T>::ExitReasonFatal),
|
||||||
|
};
|
||||||
|
|
||||||
|
let actual_fee = executor.fee(gas_price);
|
||||||
|
executor.deposit(source, total_fee.saturating_sub(actual_fee));
|
||||||
|
|
||||||
|
let (values, logs) = executor.deconstruct();
|
||||||
|
backend.apply(values, logs, true);
|
||||||
|
|
||||||
|
ret
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user