-
Notifications
You must be signed in to change notification settings - Fork 416
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dispatch Lockdrop account - Precompile #1142
Merged
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
a3cf9fe
Merge branch 'master' of github.com:AstarNetwork/Astar
PierreOssun 9aae4ae
Added rescue lockdrop precompile & tests
PierreOssun e9c0c8d
Added to local & Shibuya
PierreOssun 8179f1a
Merge branch 'master' of github.com:AstarNetwork/Astar into feat/evm-…
PierreOssun 0b20d11
refactor unsafe unwrap
PierreOssun 123c2b0
Added dispatch lockdrop precompile
PierreOssun 06ab9f5
deleted rescue lockdrop
PierreOssun 8532480
Added tests
PierreOssun eb0d085
clean code
PierreOssun f05afc8
fmt
PierreOssun b2989ef
PR review
PierreOssun a73eb88
clean code
PierreOssun 299cfe3
revert UA pallet changes
PierreOssun 85dd6d0
fmr
PierreOssun d6e38dc
PR review
PierreOssun ed2cea0
PR review
PierreOssun 357cb16
fmt
PierreOssun 304a56c
fixed weight
PierreOssun c625065
handle gas limit
PierreOssun 98ec7c9
PR review
PierreOssun c792797
fmt
PierreOssun 3605e75
Pr comments and added tests
PierreOssun File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
[package] | ||
name = "pallet-evm-precompile-dispatch-lockdrop" | ||
description = "Evm Precompile to dispatch calls for lockdrop accounts" | ||
version = "0.1.0" | ||
authors.workspace = true | ||
edition.workspace = true | ||
homepage.workspace = true | ||
repository.workspace = true | ||
|
||
[dependencies] | ||
fp-evm = { workspace = true } | ||
frame-support = { workspace = true } | ||
frame-system = { workspace = true } | ||
hex-literal = { workspace = true } | ||
libsecp256k1 = { workspace = true, features = ["hmac", "static-context"] } | ||
log = { workspace = true } | ||
pallet-evm = { workspace = true } | ||
pallet-evm-precompile-dispatch = { workspace = true } | ||
parity-scale-codec = { workspace = true } | ||
precompile-utils = { workspace = true } | ||
sp-core = { workspace = true } | ||
sp-io = { workspace = true } | ||
sp-runtime = { workspace = true } | ||
sp-std = { workspace = true } | ||
|
||
[dev-dependencies] | ||
astar-primitives = { workspace = true } | ||
ethers = { workspace = true } | ||
frame-system = { workspace = true } | ||
pallet-balances = { workspace = true } | ||
pallet-timestamp = { workspace = true } | ||
pallet-utility = { workspace = true } | ||
precompile-utils = { workspace = true, features = ["testing"] } | ||
scale-info = { workspace = true } | ||
sp-core = { workspace = true } | ||
sp-io = { workspace = true } | ||
sp-runtime = { workspace = true } | ||
sp-std = { workspace = true } | ||
|
||
[features] | ||
default = ["std"] | ||
std = [ | ||
"log/std", | ||
"libsecp256k1/std", | ||
"parity-scale-codec/std", | ||
"scale-info/std", | ||
"sp-std/std", | ||
"sp-core/std", | ||
"sp-io/std", | ||
"sp-runtime/std", | ||
"frame-support/std", | ||
"frame-system/std", | ||
"astar-primitives/std", | ||
"precompile-utils/std", | ||
"pallet-evm/std", | ||
"pallet-balances/std", | ||
"pallet-timestamp/std", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
pragma solidity ^0.8.0; | ||
|
||
/** | ||
* @title Dispatch Lockdrop calls interface. | ||
*/ | ||
|
||
/// Interface to dispatch lockdrop calls precompiled contract | ||
/// Pre-deployed at the address 0x0000000000000000000000000000000000005007 | ||
interface RescueLockdrop { | ||
/** | ||
* @dev Dispatch lockdrop call | ||
* @param call - SCALE-encoded call arguments | ||
* @param pubkey - full ECDSA pubkey 64 bytes | ||
* @return boolean confirming whether the call got successfully dispatched | ||
*/ | ||
function dispatch_lockdrop_call( | ||
bytes calldata call, | ||
bytes calldata pubkey | ||
) external returns (bool); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
// This file is part of Astar. | ||
|
||
// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. | ||
// SPDX-License-Identifier: GPL-3.0-or-later | ||
|
||
// Astar is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// (at your option) any later version. | ||
|
||
// Astar is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
// GNU General Public License for more details. | ||
|
||
// You should have received a copy of the GNU General Public License | ||
// along with Astar. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
#![cfg_attr(not(feature = "std"), no_std)] | ||
|
||
extern crate alloc; | ||
|
||
use core::marker::PhantomData; | ||
use fp_evm::PrecompileHandle; | ||
use frame_support::pallet_prelude::IsType; | ||
use frame_support::weights::Weight; | ||
use frame_support::{codec::DecodeLimit as _, traits::Get}; | ||
use frame_support::{ | ||
dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo}, | ||
traits::ConstU32, | ||
}; | ||
use frame_system::Config; | ||
use pallet_evm::GasWeightMapping; | ||
use pallet_evm_precompile_dispatch::DispatchValidateT; | ||
use precompile_utils::prelude::{revert, BoundedBytes, RuntimeHelper, UnboundedBytes}; | ||
use precompile_utils::EvmResult; | ||
use sp_core::{crypto::AccountId32, H160, H256}; | ||
use sp_io::hashing::keccak_256; | ||
use sp_std::vec::Vec; | ||
|
||
#[cfg(test)] | ||
mod mock; | ||
#[cfg(test)] | ||
mod tests; | ||
|
||
pub const LOG_TARGET: &str = "precompile::dispatch-lockdrop"; | ||
|
||
// ECDSA PublicKey | ||
type ECDSAPublic = ConstU32<64>; | ||
|
||
// `DecodeLimit` specifies the max depth a call can use when decoding, as unbounded depth | ||
// can be used to overflow the stack. | ||
// Default value is 8, which is the same as in XCM call decoding. | ||
pub struct DispatchLockdrop<Runtime, DispatchValidator, DecodeLimit = ConstU32<8>>( | ||
PhantomData<(Runtime, DispatchValidator, DecodeLimit)>, | ||
); | ||
|
||
#[precompile_utils::precompile] | ||
impl<Runtime, DispatchValidator, DecodeLimit> | ||
DispatchLockdrop<Runtime, DispatchValidator, DecodeLimit> | ||
where | ||
Runtime: pallet_evm::Config, | ||
<Runtime::RuntimeCall as Dispatchable>::RuntimeOrigin: From<Option<Runtime::AccountId>>, | ||
Runtime::RuntimeCall: Dispatchable<PostInfo = PostDispatchInfo> + GetDispatchInfo, | ||
<Runtime as Config>::AccountId: IsType<AccountId32>, | ||
<Runtime as Config>::AccountId: From<[u8; 32]>, | ||
DispatchValidator: | ||
DispatchValidateT<<Runtime as Config>::AccountId, <Runtime as Config>::RuntimeCall>, | ||
DecodeLimit: Get<u32>, | ||
{ | ||
#[precompile::public("dispatch_lockdrop_call(bytes,bytes)")] | ||
fn dispatch_lockdrop_call( | ||
handle: &mut impl PrecompileHandle, | ||
call: UnboundedBytes, | ||
pubkey: BoundedBytes<ECDSAPublic>, | ||
) -> EvmResult<bool> { | ||
log::trace!( | ||
target: LOG_TARGET, | ||
"raw arguments: call: {:?}, pubkey: {:?}", | ||
call, | ||
pubkey | ||
); | ||
|
||
let caller: H160 = handle.context().caller.into(); | ||
let input: Vec<u8> = call.into(); | ||
|
||
// Record a fixed amount of weight to ensure there is no free execution | ||
handle.record_cost(Runtime::GasWeightMapping::weight_to_gas( | ||
Weight::from_parts(1_000_000_000u64, 0), | ||
))?; | ||
|
||
// Ensure that the caller matches the public key | ||
if caller != Self::get_evm_address_from_pubkey(pubkey.as_bytes()) { | ||
let message: &str = "caller does not match the public key"; | ||
log::trace!(target: LOG_TARGET, "{}", message); | ||
return Err(revert(message)); | ||
} | ||
|
||
// Derive the account id from the public key | ||
let origin = Self::get_account_id_from_pubkey(pubkey.as_bytes()) | ||
.ok_or(revert("could not derive AccountId from pubkey"))?; | ||
|
||
// Decode the call | ||
let call = Runtime::RuntimeCall::decode_with_depth_limit(DecodeLimit::get(), &mut &*input) | ||
.map_err(|_| revert("could not decode call"))?; | ||
|
||
// Validate the call - ensure that the call is allowed in filter | ||
DispatchValidator::validate_before_dispatch(&origin, &call) | ||
.map_or_else(|| Ok(()), |_| Err(revert("invalid Call")))?; | ||
|
||
// Dispatch the call and handle the cost | ||
RuntimeHelper::<Runtime>::try_dispatch::<Runtime::RuntimeCall>( | ||
handle, | ||
Some(origin).into(), | ||
call, | ||
)?; | ||
|
||
Ok(true) | ||
} | ||
|
||
fn get_account_id_from_pubkey(pubkey: &[u8]) -> Option<<Runtime as Config>::AccountId> { | ||
libsecp256k1::PublicKey::parse_slice(pubkey, None) | ||
.map(|k| sp_io::hashing::blake2_256(k.serialize_compressed().as_ref()).into()) | ||
.ok() | ||
} | ||
|
||
fn get_evm_address_from_pubkey(pubkey: &[u8]) -> H160 { | ||
H160::from(H256::from_slice(&keccak_256(pubkey))) | ||
} | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to cover this case in unit tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a tests for it. Using the same pubkey & AccountId as from old pallet eth-sig
Astar/pallets/custom-signatures/src/tests.rs
Line 267 in 9395ce0