Skip to content
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

Merged
merged 15 commits into from
Sep 30, 2021
Merged

Signed Frontier-specific extrinsic #482

merged 15 commits into from
Sep 30, 2021

Conversation

sorpaas
Copy link
Member

@sorpaas sorpaas commented Sep 27, 2021

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-specific EthereumTransaction 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 to AccountId?

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 in CheckedExtrinsic.

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 and fp_self_contained::UncheckedExtrinsic. This will also require you to implement SelfContainedCall trait for runtime Call, which the node template contains sample code.

@sorpaas sorpaas marked this pull request as ready for review September 29, 2021 20:45
@sorpaas sorpaas merged commit 88cf884 into master Sep 30, 2021
@sorpaas sorpaas deleted the sp-signed-transaction branch September 30, 2021 11:49
@sorpaas sorpaas mentioned this pull request Sep 30, 2021
Comment on lines +17 to +22
/// 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>,
);
Copy link
Contributor

@JoshOrndorff JoshOrndorff Sep 30, 2021

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,
}

Copy link
Member Author

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.

abhijeetbhagat pushed a commit to web3labs/frontier that referenced this pull request Jan 11, 2023
* 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants