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

pallet-xvm refactor #980

Merged
merged 27 commits into from
Jul 28, 2023
Merged

pallet-xvm refactor #980

merged 27 commits into from
Jul 28, 2023

Conversation

shaunxw
Copy link
Member

@shaunxw shaunxw commented Jul 20, 2023

Pull Request Summary

Refactor pallet-xvm.

API (re)design goal:

  • Less abstraction, easier to read and maintain
  • Simplify API for runtime integrations
  • Make calls overhead easy to benchmark
  • No need to loop all VMs to match the VmId to execute

In addition to API design changes, there are some notable improvements:

  • Benchmark & replace call overheads placeholder.
  • XVM call context can't be set by callers anymore, but only by the runtime, for obvious security reasons.
  • Calling the same VM via XVM is not allowed.
  • Take call overheads into consideration for weight limits.
  • Record cost in XVM precompile.
  • XvmExecutionResult::UnknownError is expanded to detailed error codes.
  • Trace EVM call results, instead of only tracing on success.

Design overview:

pub enum VmId {
    Evm = 0x0F,
    Wasm = 0x1F,
}

pub struct Context {
    pub source_vm_id: VmId,
    pub weight_limit: Weight,
}

pub trait XvmCall<AccountId> {
    fn call(
        context: Context,
        vm_id: VmId,
        source: AccountId,
        target: Vec<u8>,
        input: Vec<u8>,
    ) -> CallResult;
}

impl<T: Config> XvmCall<T::AccountId> for Pallet<T> {
    fn call(...) -> XvmCallResult {
        // Pallet implementation, be able to skip call execution to benchmark overhead
        Pallet::<T>::do_call(...)
    }
}

impl<T: Config> Pallet<T> {
    fn do_call(...) -> XvmCallResult {
        // ... ensure source_vm != vm_id

        // ... calls EVM or WASM depending on `vm_id`
        match vm_id {
            Vm::Evm => Pallet::<T>::evm_call(...),
            Vm::Wasm => Pallet::<T>::wasm_call(...),
        }
    }
    
    fn evm_call(...) -> ... { /* same to previous EVM impl, be able to skip execution */ }
    fn wasm_call(...) -> ... { /* same to previous WASM impl, be able to skip execution */ }
    
    // benchmark overhead
    #[cfg(feature = "runtime-benchmarks")]
    pub fn call_without_execution(...) -> ... {
        // skip execution
        Self::do_call(...)
    }
}

Check list

  • added or updated unit tests
  • updated Astar official documentation
  • added OnRuntimeUpgrade hook for precompile revert code registration
  • updated spec version
  • updated semver

@shaunxw shaunxw added the other PR/issue is related to third-party, scripts or other things which don't have definite label. label Jul 20, 2023
Copy link
Member

@Dinonard Dinonard 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 both pros & cons here.

The pros:

  • should make development, testing & integration much easier
  • removes lot of the unnecessary code, which was just dragging on for over a year
  • clarity

The cons:

  • makes everything tightly coupled

We should be able to achieve benchmarking with the old approach too, I guess.

All that being said, IMHO we should focus on the functionality & usability instead of making various abstractions to cover whatever possible future scenarios might require but without even properly implementing support for the 2 VMs we have.

If required, we can always refactor in the future, when we have more knowledge & actually understand the problems of potential future VMs.

@shaunxw
Copy link
Member Author

shaunxw commented Jul 21, 2023

Agreed. We need to make a compromise between pragmatism and "design patterns". The previous design could be abstracted further to replace pallet-contracts / pallet-ethereum-checked deps with traits, but it doesn't really help with practicality. We're not building a common lib that is meant to be as flexible as possible, but specifically for Shibuya/Shiden/Astar.

The complexity multi-VMs brings is already quite a mental burden for devs. Personally, I prefer to make the XVM impl dead simple so that everyone can review it easily, without hopping through extra traits, macros, crate features, and runtime configs to understand what is happening.

As you mentioned, if more decoupling is required in the future, I'm always ready to refactor it again to fit the needs.

Copy link
Member

@ashutoshvarma ashutoshvarma left a comment

Choose a reason for hiding this comment

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

It's much cleaner and readable than before for sure.

As I state in my previous reviews for pallet_ethereum_checked, I'm still not comfortable with extra if-else for serving runtime benchmarks only.
Is there a way to completely keep runtime-benchmarks logic behind a feature gate or something more cleaner? but if that's the only way to do this then it's fine

pallets/xvm/src/lib.rs Outdated Show resolved Hide resolved
pallets/xvm/src/lib.rs Outdated Show resolved Hide resolved
pallets/xvm/src/lib.rs Outdated Show resolved Hide resolved
@shaunxw
Copy link
Member Author

shaunxw commented Jul 21, 2023

Is there a way to completely keep runtime-benchmarks logic behind a feature gate or something more cleaner? but if that's the only way to do this then it's fine

I did try feature gates, but unfortunately, they either don't work or would make the code difficult to read. One of the main issues is that if the behavior is different under different features, unit tests would fail with some features on. They can be solved with more feature gates added to unit tests, but believe me, you don't want to read that kind of code.

I'm happy to update if any doable nice clean solution is suggested.

@shaunxw
Copy link
Member Author

shaunxw commented Jul 26, 2023

/bench shibuya-dev pallet_xvm

@github-actions
Copy link

Benchmarks job is scheduled at https://github.com/AstarNetwork/Astar/actions/runs/5667322955.
Please wait for a while.
Branch: feat/pallet-xvm-refactor
SHA: 6b22ce6

@github-actions
Copy link

Benchmark job failed.
Please check https://github.com/AstarNetwork/Astar/actions/runs/5667322955.

@shaunxw
Copy link
Member Author

shaunxw commented Jul 26, 2023

/bench shibuya-dev pallet_xvm

@github-actions
Copy link

Benchmarks job is scheduled at https://github.com/AstarNetwork/Astar/actions/runs/5669003650.
Please wait for a while.
Branch: feat/pallet-xvm-refactor
SHA: 61220e6

@github-actions
Copy link

Benchmarks have been finished.
You can download artifacts if exists https://github.com/AstarNetwork/Astar/actions/runs/5669003650.

@shaunxw shaunxw marked this pull request as ready for review July 26, 2023 23:00
precompiles/xvm/src/lib.rs Show resolved Hide resolved
pallets/xvm/src/lib.rs Show resolved Hide resolved
pallets/xvm/src/lib.rs Outdated Show resolved Hide resolved
pallets/xvm/src/lib.rs Show resolved Hide resolved
@shaunxw
Copy link
Member Author

shaunxw commented Jul 27, 2023

/bench shibuya-dev pallet_xvm

@github-actions
Copy link

Benchmarks job is scheduled at https://github.com/AstarNetwork/Astar/actions/runs/5679384396.
Please wait for a while.
Branch: feat/pallet-xvm-refactor
SHA: 7482e7b

@github-actions
Copy link

Benchmarks have been finished.
You can download artifacts if exists https://github.com/AstarNetwork/Astar/actions/runs/5679384396.

@shaunxw
Copy link
Member Author

shaunxw commented Jul 27, 2023

/bench shibuya-dev pallet_xvm

@github-actions
Copy link

Benchmarks job is scheduled at https://github.com/AstarNetwork/Astar/actions/runs/5680132481.
Please wait for a while.
Branch: feat/pallet-xvm-refactor
SHA: ff3b41f

@github-actions
Copy link

Benchmarks have been finished.
You can download artifacts if exists https://github.com/AstarNetwork/Astar/actions/runs/5680132481.

@github-actions
Copy link

Code Coverage

Package Line Rate Branch Rate Health
pallets/dapps-staking/src 81% 0%
precompiles/substrate-ecdsa/src 78% 0%
precompiles/utils/src 70% 0%
pallets/xc-asset-config/src 54% 0%
precompiles/assets-erc20/src 76% 0%
precompiles/xcm/src 84% 0%
precompiles/xvm/src 67% 0%
primitives/src 69% 0%
primitives/src/xcm 67% 0%
chain-extensions/types/dapps-staking/src 0% 0%
pallets/pallet-xcm/src 53% 0%
pallets/custom-signatures/src 51% 0%
chain-extensions/types/assets/src 0% 0%
chain-extensions/xvm/src 0% 0%
precompiles/sr25519/src 79% 0%
chain-extensions/pallet-assets/src 0% 0%
pallets/xvm/src 0% 0%
precompiles/utils/macro/src 0% 0%
pallets/ethereum-checked/src 48% 0%
chain-extensions/dapps-staking/src 0% 0%
pallets/collator-selection/src 69% 0%
pallets/block-reward/src 85% 0%
pallets/contracts-migration/src 0% 0%
chain-extensions/types/xvm/src 0% 0%
precompiles/dapps-staking/src 93% 0%
pallets/dapps-staking/src/pallet 85% 0%
Summary 55% (2271 / 4108) 0% (0 / 0)

Minimum allowed line rate is 50%

@shaunxw shaunxw merged commit 18ff2b9 into master Jul 28, 2023
@shaunxw shaunxw deleted the feat/pallet-xvm-refactor branch July 28, 2023 03:23
@ashutoshvarma ashutoshvarma mentioned this pull request Aug 14, 2023
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
other PR/issue is related to third-party, scripts or other things which don't have definite label.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants