-
Notifications
You must be signed in to change notification settings - Fork 498
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
Signed Frontier-specific extrinsic #482
Conversation
/// A extrinsic right from the external world. This is unchecked and so | ||
/// can contain a signature. | ||
#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo)] | ||
pub struct UncheckedExtrinsic<Address, Call, Signature, Extra: SignedExtension>( | ||
pub sp_runtime::generic::UncheckedExtrinsic<Address, Call, Signature, Extra>, | ||
); |
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.
This wrapping technique makes a lot of sense. I could imagine using this same technique in a repo that brings bitcoin compatibility to substrate. Same for any other existing-chain-compatibility.
If I want a chain that uses frontier and also the bitcoin-compatibility stuff, I would want to compose the unchecked extrinsic wrappers from both repos. Therefore, I think it would be cool to be generic over the thing you're wrapping.
pub struct FrontierUncheckedExtrinsic<I: Extrinsic + Checkable + ...>{
pub inner: I,
}
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.
We can't yet do that now cause the struct relies on the specific information available in UncheckedExtrinsic
, but I agree this is the direction to go.
* Signed custom extrinsic implementation * Fix some compile issues * Fully verify the transaction in UncheckedExtrinsic * Propogate hash information to runtime * Generalize the ethereum signature verification to SelfContainedCall * Rename fp-ethereum to fp-self-contained * Add new origin to pallet-ethereum * Define the actual new origin type * Add EnsureEthereumTransaction origin check * Remove validate_unsigned and add self-contained check * Finish template build * Run rustfmt * Fix tests * Fix lints * Use where OriginFor<T> clause instead of Config::Origin
This is based on @xlc's work.
Use a Frontier-specific extrinsic struct, so that we don't have to treat Ethereum transactions as "unsigned". This is generalized to suit Frontier library's need, namely that we must support multiple different
AccountId
implementations.Transaction struct is backward-compatible by marking certain call functions as "self-contained". A custom
CheckedExtrinsic
struct is then used to dispatch it under a Frontier-specificEthereumTransaction
origin, which is later read by the runtime.The code now should be able to verify an Ethereum transaction as safe as a Substrate extrinsic. This also includes any gas limit or nonce related data, as now we use the same code path and do the verifications in exact same places as it happens on Substrate extrinsics.
FAQ
Why do we have to define our own
CheckedExtrinsic
given that Ethereum transaction senders already have mappings toAccountId
?We must not use any existing
SignedExtensions
. They added things that should have been signed by the signature, but we don't have the means for additional signatures. In addition, if included, they will lead to double charge of transaction fees and other unwanted side effects.The
SignedExtensions
invocation logic is handled inCheckedExtrinsic
.Upgrade notice
To use the new code, you need to change in your runtime checked and unchecked extrinsics to point to
fp_self_contained::CheckedExtrinsic
andfp_self_contained::UncheckedExtrinsic
. This will also require you to implementSelfContainedCall
trait for runtimeCall
, which the node template contains sample code.