Skip to content

Commit 98ec7c9

Browse files
committed
PR review
1 parent c625065 commit 98ec7c9

File tree

2 files changed

+38
-54
lines changed

2 files changed

+38
-54
lines changed

precompiles/dispatch-lockdrop/src/lib.rs

+19-54
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,19 @@
2020

2121
extern crate alloc;
2222

23-
use alloc::format;
2423
use core::marker::PhantomData;
25-
use fp_evm::{ExitError, PrecompileFailure, PrecompileHandle};
24+
use fp_evm::PrecompileHandle;
2625
use frame_support::pallet_prelude::IsType;
27-
use frame_support::{codec::DecodeLimit as _, dispatch::Pays, traits::Get};
26+
use frame_support::weights::Weight;
27+
use frame_support::{codec::DecodeLimit as _, traits::Get};
2828
use frame_support::{
2929
dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo},
3030
traits::ConstU32,
3131
};
3232
use frame_system::Config;
3333
use pallet_evm::GasWeightMapping;
3434
use pallet_evm_precompile_dispatch::DispatchValidateT;
35-
use precompile_utils::prelude::{revert, BoundedBytes, UnboundedBytes};
35+
use precompile_utils::prelude::{revert, BoundedBytes, RuntimeHelper, UnboundedBytes};
3636
use precompile_utils::EvmResult;
3737
use sp_core::{crypto::AccountId32, H160, H256};
3838
use sp_io::hashing::keccak_256;
@@ -81,72 +81,37 @@ where
8181
pubkey
8282
);
8383

84-
let target_gas = handle.gas_limit();
8584
let caller: H160 = handle.context().caller.into();
8685
let input: Vec<u8> = call.into();
8786

88-
// 1. Decode the call
89-
let call = Runtime::RuntimeCall::decode_with_depth_limit(DecodeLimit::get(), &mut &*input)
90-
.map_err(|_| revert("could not decode call"))?;
87+
// Record the cost of the call to ensure there is no free execution
88+
handle.record_cost(Runtime::GasWeightMapping::weight_to_gas(
89+
Weight::from_parts(1_000_000u64, 0),
90+
))?;
9191

92-
// 2. Charge the max amount of weight ref_time and
93-
// later when call is successfully dispatched,
94-
// charge proof_size and refund the ref_time difference.
95-
// Note: adding hard coded ref_time corresponding to the blake2b Hash
96-
// and the keccak256 Hash based on the weight of UA::claim_default_evm_address()
97-
let info = call.get_dispatch_info();
98-
let weight = info.weight.ref_time().saturating_add(40_000_000u64);
99-
if let Some(gas) = target_gas {
100-
if !(weight <= Runtime::GasWeightMapping::gas_to_weight(gas, false).ref_time()) {
101-
return Err(PrecompileFailure::Error {
102-
exit_status: ExitError::OutOfGas,
103-
});
104-
}
105-
}
106-
handle.record_external_cost(Some(weight), None)?;
107-
108-
// 3. Ensure that the caller matches the public key
92+
// Ensure that the caller matches the public key
10993
if caller != Self::get_evm_address_from_pubkey(pubkey.as_bytes()) {
11094
let message: &str = "caller does not match the public key";
11195
log::trace!(target: LOG_TARGET, "{}", message);
11296
return Err(revert(message));
11397
}
11498

115-
// 4. Derive the AccountId from the ECDSA compressed Public key
99+
// Derive the account id from the public key
116100
let origin = Self::get_account_id_from_pubkey(pubkey.as_bytes())
117101
.ok_or(revert("could not derive AccountId from pubkey"))?;
118102

119-
// 5. validate the call
103+
// Decode the call
104+
let call = Runtime::RuntimeCall::decode_with_depth_limit(DecodeLimit::get(), &mut &*input)
105+
.map_err(|_| revert("could not decode call"))?;
106+
107+
// Validate the call - ensure that the call is allowed in filter
120108
DispatchValidator::validate_before_dispatch(&origin, &call)
121109
.map_or_else(|| Ok(()), |_| Err(revert("could not validate call")))?;
122110

123-
// 6. Dispatch the call
124-
match call.dispatch(Some(origin).into()) {
125-
Ok(post_info) => {
126-
if post_info.pays_fee(&info) == Pays::Yes {
127-
let actual_weight = post_info.actual_weight.unwrap_or(info.weight);
128-
handle.record_external_cost(None, Some(info.weight.proof_size()))?;
129-
130-
handle.refund_external_cost(
131-
Some(
132-
info.weight
133-
.ref_time()
134-
.saturating_sub(actual_weight.ref_time()),
135-
),
136-
None,
137-
);
138-
}
139-
140-
Ok(true)
141-
}
142-
Err(e) => {
143-
log::trace!(target: LOG_TARGET, "{:?}", e);
144-
Err(revert(format!(
145-
"dispatch execution failed: {}",
146-
<&'static str>::from(e)
147-
)))
148-
}
149-
}
111+
// Dispatch the call and handle the cost
112+
RuntimeHelper::<Runtime>::try_dispatch_runtime_call(handle, Some(origin).into(), call)?;
113+
114+
Ok(true)
150115
}
151116

152117
fn get_account_id_from_pubkey(pubkey: &[u8]) -> Option<<Runtime as Config>::AccountId> {

precompiles/utils/src/substrate.rs

+19
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,25 @@ where
112112
Runtime::RuntimeCall: From<Call>,
113113
{
114114
let call = Runtime::RuntimeCall::from(call);
115+
Self::do_try_dispatch(handle, origin, call)
116+
}
117+
118+
/// Try to dispatch a Runtime call.
119+
/// Return an error if there are not enough gas, or if the call fails.
120+
/// If successful returns the used gas using the Runtime GasWeightMapping.
121+
pub fn try_dispatch_runtime_call(
122+
handle: &mut impl PrecompileHandle,
123+
origin: <Runtime::RuntimeCall as Dispatchable>::RuntimeOrigin,
124+
call: Runtime::RuntimeCall,
125+
) -> Result<PostDispatchInfo, TryDispatchError> {
126+
Self::do_try_dispatch(handle, origin, call)
127+
}
128+
129+
fn do_try_dispatch(
130+
handle: &mut impl PrecompileHandle,
131+
origin: <Runtime::RuntimeCall as Dispatchable>::RuntimeOrigin,
132+
call: Runtime::RuntimeCall,
133+
) -> Result<PostDispatchInfo, TryDispatchError> {
115134
let dispatch_info = call.get_dispatch_info();
116135

117136
Self::record_weight_v2_cost(handle, dispatch_info.weight).map_err(TryDispatchError::Evm)?;

0 commit comments

Comments
 (0)