Skip to content

Conversation

@teor2345
Copy link
Member

This PR adds substrate weights for the permissioned EVM extension that checks if contract creation is allowed.

We decided to use the default benchmark file template in PR #3129, but that template assumes the file is outside the crate. We might want to add a template which replaces the crate name with literally crate. (But is otherwise the same as the default.)

Close #3530.

Code contributor checklist:

@teor2345 teor2345 self-assigned this May 28, 2025
@teor2345 teor2345 added the execution Subspace execution label May 28, 2025
@teor2345 teor2345 enabled auto-merge May 28, 2025 05:40
@teor2345 teor2345 marked this pull request as draft June 2, 2025 01:31
auto-merge was automatically disabled June 2, 2025 01:31

Pull request was converted to draft

@teor2345 teor2345 force-pushed the evm-create-ext-weights branch from 97fd4bc to da4803a Compare June 10, 2025 04:05
@teor2345 teor2345 marked this pull request as ready for review June 10, 2025 04:05
@teor2345 teor2345 requested a review from nazar-pc as a code owner June 10, 2025 04:05
Copy link
Member Author

@teor2345 teor2345 left a comment

Choose a reason for hiding this comment

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

This is now ready for another review.

@teor2345 teor2345 enabled auto-merge June 10, 2025 04:07
@teor2345 teor2345 requested a review from vedhavyas June 10, 2025 23:30
@teor2345 teor2345 force-pushed the evm-create-ext-weights branch from c8701d8 to 2ef4eba Compare June 11, 2025 00:16
@teor2345 teor2345 force-pushed the evm-create-ext-weights branch from 2ef4eba to 7ea98c2 Compare June 11, 2025 00:32
Copy link
Contributor

@vedhavyas vedhavyas left a comment

Choose a reason for hiding this comment

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

I see only benmarks for signed calls. what about unsigned calls ?

@teor2345 teor2345 force-pushed the evm-create-ext-weights branch from 7ea98c2 to f949403 Compare June 12, 2025 00:54
Copy link
Member Author

@teor2345 teor2345 left a comment

Choose a reason for hiding this comment

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

I found some ways to simplify the code a bit, and implemented bare self-contained call extension weights.

I see only benmarks for signed calls. what about unsigned calls ?

The signed and unsigned codepaths are almost identical, so there's no point in having a separate benchmark. The only difference is a HashSet lookup on the signed path, which makes it a tiny amount more expensive:

pub fn is_create_contract_allowed<Runtime>(
call: &RuntimeCallFor<Runtime>,
signer: &EthereumAccountId,
) -> (bool, u32)
where
Runtime: frame_system::Config<AccountId = EthereumAccountId>
+ pallet_ethereum::Config
+ pallet_evm::Config
+ crate::Config,
RuntimeCallFor<Runtime>:
MaybeIntoEthCall<Runtime> + MaybeIntoEvmCall<Runtime> + MaybeNestedCall<Runtime>,
Result<pallet_ethereum::RawOrigin, OriginFor<Runtime>>: From<OriginFor<Runtime>>,
{
// If the account is allowed to create contracts, or it's not a contract call, return true.
// Only enters allocating code if this account can't create contracts.
if crate::Pallet::<Runtime>::is_allowed_to_create_contracts(signer) {
return (true, 0);
}
let (is_create, call_count) = is_create_contract::<Runtime>(call);
(!is_create, call_count)
}
/// If anyone is allowed to create contracts, allows contracts. Otherwise, rejects contracts.
/// Returns false if the call is a contract call, and there is a specific (possibly empty) allow
/// list. Otherwise, returns true.
pub fn is_create_unsigned_contract_allowed<Runtime>(call: &RuntimeCallFor<Runtime>) -> (bool, u32)
where
Runtime: frame_system::Config + pallet_ethereum::Config + pallet_evm::Config + crate::Config,
RuntimeCallFor<Runtime>:
MaybeIntoEthCall<Runtime> + MaybeIntoEvmCall<Runtime> + MaybeNestedCall<Runtime>,
Result<pallet_ethereum::RawOrigin, OriginFor<Runtime>>: From<OriginFor<Runtime>>,
{
// If any account is allowed to create contracts, or it's not a contract call, return true.
// Only enters allocating code if there is a contract creation filter.
if crate::Pallet::<Runtime>::is_allowed_to_create_unsigned_contracts() {
return (true, 0);
}
let (is_create, call_count) = is_create_contract::<Runtime>(call);
(!is_create, call_count)
}

pub fn is_allowed(&self, who: &AccountId) -> bool {
match self {
PermissionedActionAllowedBy::Accounts(accounts) => accounts.contains(who),
PermissionedActionAllowedBy::Anyone => true,
}
}
pub fn is_anyone_allowed(&self) -> bool {
matches!(self, PermissionedActionAllowedBy::Anyone)
}

This is explained in the benchmark comments here:
https://github.com/autonomys/subspace/pull/3554/files#diff-ea89c9f2e5298171277613b2228895b8521f1d3bd265b436caa2d04269c43f1eR78

A similar logic applies to self-contained calls, which make exactly the same method calls as signed calls, and do similar checks, but inside the fp_self_contained::SelfContainedCall implementation.

@teor2345 teor2345 force-pushed the evm-create-ext-weights branch from f949403 to 9f5c715 Compare June 12, 2025 01:04
@teor2345 teor2345 requested a review from vedhavyas June 12, 2025 21:40
@teor2345
Copy link
Member Author

This is ready for another review.

@teor2345 teor2345 mentioned this pull request Jun 13, 2025
1 task
@teor2345
Copy link
Member Author

@NingLin-P the weights in this PR are only used in one runtime, can you confirm that it is ok to do it this way, or would you like them moved into the runtime itself?

@vedhavyas
Copy link
Contributor

the weights in this PR are only used in one runtime, can you confirm that it is ok to do it this way, or would you like them moved into the runtime itself?

Have they been generated from the reference machine ?
If not, then you should generate from reference machine and add new weights to runtime weights module

@teor2345
Copy link
Member Author

the weights in this PR are only used in one runtime, can you confirm that it is ok to do it this way, or would you like them moved into the runtime itself?

Have they been generated from the reference machine ? If not, then you should generate from reference machine and add new weights to runtime weights module

This PR has already been mostly reviewed, so I'd like to avoid blocking merging this PR on other related tasks.

We have multiple weights that need to be re-generated on the reference machine and moved to the runtimes:

It seems easier to do them both at the same time in a separate PR. As part of that PR I'd also like to update the benchmark script so it automatically picks up new weights (ticket #3582).

We're also missing the documentation for the reference machine benchmarking process/hardware (#3587), which makes it harder to do benchmarking on the reference machine. @NingLin-P did you document the reference benchmarking process somewhere?

@NingLin-P
Copy link
Contributor

@NingLin-P the weights in this PR are only used in one runtime, can you confirm that it is ok to do it this way, or would you like them moved into the runtime itself?

I think we can keep the weight in pallet_evm_tracker for testing usage in the test evm runtime, but please also add pallet_evm_tracker to this list:

evm_domain_runtime_pallets=(

So next time when we update the weight with the reference machine, this extension weight will also be updated automatically.

@teor2345 teor2345 added this pull request to the merge queue Jun 16, 2025
Merged via the queue into main with commit 17c28e2 Jun 16, 2025
20 of 21 checks passed
@teor2345 teor2345 deleted the evm-create-ext-weights branch June 16, 2025 14:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

execution Subspace execution

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add extension weights for EVM contract creation (permissioned EVM)

4 participants