-
Notifications
You must be signed in to change notification settings - Fork 249
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
Add contract creation allow lists to EVM domains #3350
base: main
Are you sure you want to change the base?
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
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.
Make sense overall. Left questions on penalizing malicious operator including these txns in bundle
@@ -633,6 +634,7 @@ fn test_bundle_format_verification() { | |||
bundle_slot_probability: (1, 1), | |||
operator_allow_list: OperatorAllowList::Anyone, | |||
initial_balances: Default::default(), | |||
initial_evm_contract_creation_allow_list: None, | |||
}; |
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.
maybe add another test with some address included ?
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.
I'd like to do this after the API is stable, so I don't have to rework the tests multiple times.
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.
Test matrix:
- Instantiate domain with allow list, using all allow list combinations below
- Instantiate domain without allow list (existing tests)
- Update allow list using call, with all allow list combinations below
- Migration v2 to v3 storage format (Taurus only)
Test contract allow/deny for all combinations of:
- Anyone vs Empty vs 1 Account vs Multiple Accounts (First vs not First)
- Signer vs Not Signer vs Unsigned
- Contract vs Non-Contract vs Deeply nested (contract vs non-contract)
- Ethereum (self-contained) vs EVM (signed extension) calls
-
legacy vs vs eip1559 vs eip2930
-
- Ethereum (self-contained) vs EVM (signed extension) calls
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
@@ -161,7 +162,7 @@ pub type BlockTreeNodeFor<T> = crate::block_tree::BlockTreeNode< | |||
>; | |||
|
|||
/// The current storage version. | |||
const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); |
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 this due to Taurus being on storage version 2 already ?
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.
Yes, in this branch: https://github.com/autonomys/subspace/tree/taurus-runtime-upgrade
Here's the exact change:
https://github.com/autonomys/subspace/pull/3342/files#diff-9f80450addc12cd3b681275c6acb663003edc27c2d8eeeb1f26147df9f8e5bbeR164
subspace/crates/pallet-domains/src/lib.rs
Line 164 in a19ba3d
const STORAGE_VERSION: StorageVersion = StorageVersion::new(2); |
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.
if that is the case, we can manually bump right before we do taurus upgrade no ?
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.
I've finished about half the tests, see the checklist in the comments
@@ -161,7 +162,7 @@ pub type BlockTreeNodeFor<T> = crate::block_tree::BlockTreeNode< | |||
>; | |||
|
|||
/// The current storage version. | |||
const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); |
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.
Yes, in this branch: https://github.com/autonomys/subspace/tree/taurus-runtime-upgrade
Here's the exact change:
https://github.com/autonomys/subspace/pull/3342/files#diff-9f80450addc12cd3b681275c6acb663003edc27c2d8eeeb1f26147df9f8e5bbeR164
subspace/crates/pallet-domains/src/lib.rs
Line 164 in a19ba3d
const STORAGE_VERSION: StorageVersion = StorageVersion::new(2); |
@@ -633,6 +634,7 @@ fn test_bundle_format_verification() { | |||
bundle_slot_probability: (1, 1), | |||
operator_allow_list: OperatorAllowList::Anyone, | |||
initial_balances: Default::default(), | |||
initial_evm_contract_creation_allow_list: None, | |||
}; |
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.
Test matrix:
- Instantiate domain with allow list, using all allow list combinations below
- Instantiate domain without allow list (existing tests)
- Update allow list using call, with all allow list combinations below
- Migration v2 to v3 storage format (Taurus only)
Test contract allow/deny for all combinations of:
- Anyone vs Empty vs 1 Account vs Multiple Accounts (First vs not First)
- Signer vs Not Signer vs Unsigned
- Contract vs Non-Contract vs Deeply nested (contract vs non-contract)
- Ethereum (self-contained) vs EVM (signed extension) calls
-
legacy vs vs eip1559 vs eip2930
-
- Ethereum (self-contained) vs EVM (signed extension) calls
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as outdated.
This comment was marked as outdated.
b5c3e27
to
d50d942
Compare
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.
Left some questions.
there are a lot of changes between the commits that is very confusing. Not a blocker for this PR
origin: OriginFor<T>, | ||
contract_creation_allowed_by: PermissionedActionAllowedBy<T::AccountId>, | ||
) -> DispatchResult { | ||
ensure_root(origin)?; |
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 is fine to expect as sudo but ideally a domain owner should be able to update this allowlist instead of sudo so that Consensus sudo is not always required and is also a longer process.
Currently domain owner can update the XDM allow list that is initiated from the Consensus chain so I see no reason why the same domain owner should not be able to update this list as to who can create contracts as well.
Thoughts @dariolina
Apologies for not bringing this earlier.
domains/runtime/evm/src/lib.rs
Outdated
/// Rejects contracts that can't be created under the current allow list. | ||
/// Returns false if the call is a contract call, and the account is *not* allowed to call it. | ||
/// Otherwise, returns true. | ||
pub fn is_create_contract_allowed(call: &RuntimeCall, signer: &AccountId) -> bool { |
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 fn can be simplied but no string opinion if it increases readability
ContractCreationAllowedBy::<T>::get() | ||
.map(|allowed_by| allowed_by.is_allowed(signer)) | ||
.unwrap_or_default() | ||
.unwrap_or(true) |
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.
shouldn't this be false instead ?
// Unlike domain instantiation, no storage value means "anyone can create contracts". | ||
ContractCreationAllowedBy::<T>::get() | ||
.map(|allowed_by| allowed_by.is_anyone_allowed()) | ||
.unwrap_or(true) |
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.
same here. Shouldn't this be false ?
@@ -207,6 +207,774 @@ pub fn generate_evm_account_list( | |||
} | |||
} | |||
|
|||
#[tokio::test(flavor = "multi_thread")] | |||
async fn test_evm_domain_create_contracts_with_allow_list() { |
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 is a very big test. Can we split it to test multiple cases in different tests ?
produce_blocks!(ferdie, alice, 3).await.unwrap(); | ||
|
||
// add domain to consensus chain allowlist | ||
ferdie |
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.
Why do we need to open a channel between consensus and domain for this tests ?
@@ -161,7 +162,7 @@ pub type BlockTreeNodeFor<T> = crate::block_tree::BlockTreeNode< | |||
>; | |||
|
|||
/// The current storage version. | |||
const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); |
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.
if that is the case, we can manually bump right before we do taurus upgrade no ?
@@ -121,7 +121,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { | |||
spec_name: Cow::Borrowed("subspace"), | |||
impl_name: Cow::Borrowed("subspace"), | |||
authoring_version: 0, | |||
spec_version: 2, | |||
// TODO: before deploying the next runtime version to mainnet or taurus, bump this version | |||
spec_version: 11, |
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.
even this one, let not bump it.
when wwe create a taurus upgrade branch, we can bump it then.
TODO might be noise here
How to review this PR
This PR is the second in a series of PRs which add "private EVM" functionality to subspace. The accompanying spec PR is subspace/protocol-specs#55 and user documentation is TODO.
The first PR in the series is #3359, it moves some test code around, and makes minor fixes.
The third PR in the series is #3360, it applies these changes and a storage migration to the Taurus runtime. (This storage isn't currently deployed on mainnet, so a migration isn't needed there.)
What it does
This PR adds a pallet which filters ethereum contract creation using an allow list. The allow list can be updated by the domain sudo account.
By default, all accounts can create contracts, to maintain compatibility with existing EVM domains. But the chainspec can be configured with an initial allow list of accounts. For our "private" EVM, that will be the domain sudo.
Close #3344.
This PR doesn't do a dynamic check for the domain sudo inside the pallet or runtime. We decided that isn't needed, because we can add the sudo account in the chainspec, or they can add themselves to the list using the (sudo) call provided by the pallet.
Part of #3353.
Other Changes
This PR makes it easier to add further code which:
EvmOnchainStateApi
runtime API, and contract address calculation functionIt also simplifies some existing code which was doing those things.
Bug Fixes
Fixes some transfer prevention extension code, which recursed through
pallet-utility
calls to use an iterator loop instead. The calls are checked in the same order, but references to the "Call stack" are stored on the heap instead. This avoids stack overflow for deeply nested calls.Fixes some bugs in test-only code which made it harder to use.
TODOs
Code contributor checklist: