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

Evm part 2 #1349

Merged
merged 21 commits into from
May 24, 2023
Merged

Evm part 2 #1349

merged 21 commits into from
May 24, 2023

Conversation

branan
Copy link
Contributor

@branan branan commented May 17, 2023

Description

This brings the EVM support to Altair and Centrifuge runtimes, with additional restrictions compared to the Development runtime. I particular:

  • The production runtimes filter all non-root calls to the EVM pallet
  • The production runtimes disallow creating contracts via the EVM RPC calls

Changes and Descriptions

  • Add EVM support to Altair runtime
  • Add EVM support to Centrifuge runtime
  • Add EVM support to altair/centrifuge node services
  • Various minor EVM cleanups

Checklist:

  • I have added Rust doc comments to structs, enums, traits and functions
  • I have made corresponding changes to the documentation
  • I have performed a self-review of my code
  • I have added tests that prove my fix is effective or that my feature works

Branan Riley added 7 commits May 16, 2023 14:19
This adds EVM support to the Altair and Centrifuge runtimes,
with the following caveats:

* All EVM pallet functionality is filtered on the substrate side
* The EVM `create` RPC is filtered in the runtimes

This allows EVM RPC calls to be made to invoke precompiles or
smart contracts deployed by Governance (root).
@branan

This comment was marked as outdated.

@branan
Copy link
Contributor Author

branan commented May 17, 2023

There are no benchmarks in this version of Frontier 🎉. It'll be something to add in 0.9.40

Copy link
Contributor

@thea-leake thea-leake left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if it's still supposed to be marked as draft as per PR comment, but looks good to me :)

runtime/altair/src/lib.rs Show resolved Hide resolved
runtime/development/src/evm.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@NunoAlexandre NunoAlexandre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing that popped up for me on this first round. Will give it a more detailed looked later 👍

Copy link
Contributor

@NunoAlexandre NunoAlexandre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing major :)

runtime/altair/src/evm.rs Outdated Show resolved Hide resolved
runtime/altair/src/evm.rs Outdated Show resolved Hide resolved
Comment on lines +33 to +45
pub struct FindAuthorTruncated<F>(PhantomData<F>);
impl<F: FindAuthor<u32>> FindAuthor<H160> for FindAuthorTruncated<F> {
fn find_author<'a, I>(digests: I) -> Option<H160>
where
I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,
{
if let Some(author_index) = F::find_author(digests) {
let authority_id = Aura::authorities()[author_index as usize].clone();
return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24]));
}
None
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This kind of runtime-agnostic trait impl could to to runtime-commons and just be referenced in the different runtimes instead of duplicated in all of them 🧹

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it needs to be made generic over the Runtime (that Aura in there is really pallet_aura::Pallet::<Runtime>), but indeed could be made properly runtime agnostic. Worth doing for sure

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, my bad, I didn't spot the Aura bit 🙃 I don't know how to make stuff generic over a runtime when referencing a specific pallet from that runtime tho.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add a Get<Vec<Authorities>> and impl that for Aura in the actual runtime. But feel like this makes it more opaque than actually easier to understand.

Branan Riley and others added 7 commits May 22, 2023 14:53
The `create` runtime API is used for the `call` and `estimate_gas`
RPCs, but not for transactions stored in a block.

Transactions in a block are encoded as wrapped extrinsics. This
wrapping is done by the `fp_rpc::ConvertTransaction` runtime API. I
don't believe filtering at this conversion point is safe, since a
malicious node could choose to create a transaction differently and
still add it to the pool.

Instead, we do the filtering on conversion from an "unchecked" to a
"checked" extrinsic. For both Substrate and Ethereum transactions,
this conversion typically involves just validating that transaction
fees can be paid, that signatures are valid, etc. We add additional
logic to catch EVM create invocations and indicate that such
transactions are invalid.
Co-authored-by: Nuno Alexandre <[email protected]>
mustermeiszer
mustermeiszer previously approved these changes May 23, 2023
Copy link
Collaborator

@mustermeiszer mustermeiszer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice and clean!! Thanks a lot @branan!

Comment on lines +69 to +70
#[clap(long)]
pub enable_dev_signer: bool,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe default to false

WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bool in clap defaults to false implicitly

This brings EVM account conversion and connectors DomainAccount
conversion into one single location.

Moving forward, this can be expanded to support account conversions
across multiple sources using xcm v3 MultiLocations. But as we are
still on XCM v2 we don't have the necessary XCM primitives yet.
impl<R> Convert<DomainAddress, AccountId> for AccountConverter<R> {
fn convert(domain_address: DomainAddress) -> AccountId {
match domain_address {
DomainAddress::Centrifuge(addr) => AccountId::new(addr),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NunoAlexandre this behavior is different from what DomainAddress::into_address_truncating did. This is a direct unwrapping, whereas into_address_truncating would have done something like [<tag_bytes>,<truncated_address>]. I didn't see anything in the comments or commit messages that made that behavior seem intentional, and there were no tests that covered it.

We can change this so that DomainAddress::Centrifuge encodes into something different if we so desire

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, good point. For all I know, this is exactly what we want since the idea of DomainAddress::Centrifuge(address) is exactly to represent a direct account address on the Centrifuge chain.

@branan
Copy link
Contributor Author

branan commented May 24, 2023

Regarding account conversion:

  • The MultiLocation based idea won't work until we're on XCM V3. We're still on polkadot v0.9.37 and v2, which is missing several pieces we need to represent addresses correctly. Since for now we only need EVM account conversion, I've gone ahead and implemented without going through MultiLocation.
  • I've also skipped the Runtime API for now - the EVM account conversion is very simple to implement in JS, and it makes more sense to introduce the runtime APIs in terms of MultiLocations when we have the updated XCM version.

We do still now have a single, central location to expand account conversion as we need it, which is the important part.

@NunoAlexandre
Copy link
Contributor

Regarding account conversion:

  • The MultiLocation based idea won't work until we're on XCM V3. We're still on polkadot v0.9.37 and v2, which is missing several pieces we need to represent addresses correctly. Since for now we only need EVM account conversion, I've gone ahead and implemented without going through MultiLocation.

The update to 0.9.38 is pretty much finalised apart from a few failing tests so you can always choose to rebase this branch :) Out of curiosity, what's missing in 0.9.37/xcm v2 that would help us represent addresses correctly?

@branan
Copy link
Contributor Author

branan commented May 24, 2023

Out of curiosity, what's missing in 0.9.37/xcm v2 that would help us represent addresses correctly?

Junction::GlobalConsensus and NetworkId::Ethereum are necessary to represent an EVM chain (or the EVM component of our chain). They're freshly-added in XCMv3

@NunoAlexandre
Copy link
Contributor

Out of curiosity, what's missing in 0.9.37/xcm v2 that would help us represent addresses correctly?

Junction::GlobalConsensus and NetworkId::Ethereum are necessary to represent an EVM chain (or the EVM component of our chain). They're freshly-added in XCMv3

Makes sense 👍

@mustermeiszer mustermeiszer added D2-notify Pull request can be merged and notification about changes should be documented. D7-essential Pull request essentially changes code. New Release needed. Audit would be nice. D9-needsaudit Pull request touches sensitiv code parts and must be audited (externally). labels May 24, 2023
@branan branan enabled auto-merge (squash) May 24, 2023 16:32
@branan
Copy link
Contributor Author

branan commented May 24, 2023

I've flipped the auto-merge switch, this is ready for final review 🎉

@branan
Copy link
Contributor Author

branan commented May 24, 2023

I think that final thumbs from @NunoAlexandre and @mustermeiszer will be enough to satisfy the codeowners checks (though any other final review is appreciated)

Copy link
Collaborator

@mustermeiszer mustermeiszer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-approve! Thanks for pushing this

@branan branan merged commit b829c36 into main May 24, 2023
@NunoAlexandre NunoAlexandre deleted the evm-part-2 branch May 25, 2023 06:55
@NunoAlexandre NunoAlexandre mentioned this pull request May 25, 2023
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
D2-notify Pull request can be merged and notification about changes should be documented. D7-essential Pull request essentially changes code. New Release needed. Audit would be nice. D9-needsaudit Pull request touches sensitiv code parts and must be audited (externally).
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants