Skip to content

Commit 18ff2b9

Browse files
authored
pallet-xvm refactor (#980)
* pallet-xvm refactor. * Add TODOs. * Update design. * Keep XVM call interface unified. * Renaming. * update & integration. * Update xvm precompiles mock & tests. * Replace 'UnknownError' with concrete errors. * Update CE & precompile. * Clean up. * Benchmarks and mock. * Updates for polkadot-v0.9.43. * Fix benchmarks. * Add benchmarking result and weight info. * Add license header to weight.rs. * Add pallet description docstring. * Record gas cost in XVM precompile. * Less weight is available with overheads cost. * Trace Ethereum transact result. * Handle record cost result. * Bump Shibuya semver and spec versoin. * Apply review suggestions. * Update with new benchmarking result. * Improve XVM call benchmarking. * Make local/shibuya/shiden/astar runtimes and client have the same semver. * Update with new benchmarking result.
1 parent 53500c1 commit 18ff2b9

File tree

34 files changed

+1013
-752
lines changed

34 files changed

+1013
-752
lines changed

Cargo.lock

+16-12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ pallet-collator-selection = { path = "./pallets/collator-selection", default-fea
273273
pallet-custom-signatures = { path = "./pallets/custom-signatures", default-features = false }
274274
pallet-dapps-staking = { path = "./pallets/dapps-staking", default-features = false }
275275
pallet-xc-asset-config = { path = "./pallets/xc-asset-config", default-features = false }
276-
pallet-xvm = { path = "./pallets/pallet-xvm", default-features = false }
276+
pallet-xvm = { path = "./pallets/xvm", default-features = false }
277277
pallet-xcm = { path = "./pallets/pallet-xcm", default-features = false }
278278
pallet-ethereum-checked = { path = "./pallets/ethereum-checked", default-features = false }
279279

bin/collator/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "astar-collator"
3-
version = "5.15.0"
3+
version = "5.16.0"
44
description = "Astar collator implementation in Rust."
55
build = "build.rs"
66
default-run = "astar-collator"

chain-extensions/types/xvm/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ homepage.workspace = true
99
repository.workspace = true
1010

1111
[dependencies]
12+
astar-primitives = { workspace = true }
1213
parity-scale-codec = { workspace = true }
1314
scale-info = { workspace = true }
1415
sp-runtime = { workspace = true }
@@ -21,4 +22,5 @@ std = [
2122
"scale-info/std",
2223
"sp-runtime/std",
2324
"sp-std/std",
25+
"astar-primitives/std",
2426
]

chain-extensions/types/xvm/src/lib.rs

+24-16
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,42 @@
1818

1919
#![cfg_attr(not(feature = "std"), no_std)]
2020

21+
use astar_primitives::xvm::CallError;
2122
use parity_scale_codec::{Decode, Encode};
22-
use sp_runtime::{DispatchError, ModuleError};
2323
use sp_std::vec::Vec;
2424

2525
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))]
2626
#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, Debug)]
2727
pub enum XvmExecutionResult {
2828
/// Success
29-
Success = 0,
30-
// TODO: expand this with concrete XVM errors
31-
/// Error not (yet) covered by a dedidacted code
32-
UnknownError = 255,
29+
Ok,
30+
/// Failure
31+
Err(u32),
3332
}
3433

35-
impl TryFrom<DispatchError> for XvmExecutionResult {
36-
type Error = DispatchError;
34+
impl From<CallError> for XvmExecutionResult {
35+
fn from(input: CallError) -> Self {
36+
use CallError::*;
3737

38-
fn try_from(input: DispatchError) -> Result<Self, Self::Error> {
39-
let _error_text = match input {
40-
DispatchError::Module(ModuleError { message, .. }) => message,
41-
_ => Some("No module error Info"),
38+
// `0` is reserved for `Ok`
39+
let error_code = match input {
40+
InvalidVmId => 1,
41+
SameVmCallNotAllowed => 2,
42+
InvalidTarget => 3,
43+
InputTooLarge => 4,
44+
BadOrigin => 5,
45+
ExecutionFailed(_) => 6,
4246
};
47+
Self::Err(error_code)
48+
}
49+
}
4350

44-
// TODO: expand this with concrete XVM errors (see dapps-staking types for example)
45-
Ok(XvmExecutionResult::UnknownError)
51+
impl From<XvmExecutionResult> for u32 {
52+
fn from(input: XvmExecutionResult) -> Self {
53+
match input {
54+
XvmExecutionResult::Ok => 0,
55+
XvmExecutionResult::Err(code) => code,
56+
}
4657
}
4758
}
4859

@@ -55,6 +66,3 @@ pub struct XvmCallArgs {
5566
/// Encoded call params
5667
pub input: Vec<u8>,
5768
}
58-
59-
pub const FRONTIER_VM_ID: u8 = 0x0F;
60-
pub const PARITY_WASM_VM_ID: u8 = 0x1F;

chain-extensions/xvm/Cargo.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "pallet-chain-extension-xvm"
3-
version = "0.1.0"
3+
version = "0.1.1"
44
license = "Apache-2.0"
55
description = "Chain extension for XVM"
66
authors.workspace = true
@@ -22,7 +22,7 @@ sp-runtime = { workspace = true }
2222
sp-std = { workspace = true }
2323

2424
# Astar
25-
pallet-xvm = { workspace = true }
25+
astar-primitives = { workspace = true }
2626
xvm-chain-extension-types = { workspace = true }
2727

2828
[features]
@@ -39,5 +39,5 @@ std = [
3939
"sp-core/std",
4040
"sp-runtime/std",
4141
# Astar
42-
"pallet-xvm/std",
42+
"astar-primitives/std",
4343
]

chain-extensions/xvm/src/lib.rs

+41-27
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,18 @@
1818

1919
#![cfg_attr(not(feature = "std"), no_std)]
2020

21+
use astar_primitives::xvm::{CallError, Context, VmId, XvmCall};
2122
use frame_support::dispatch::Encode;
2223
use pallet_contracts::{
2324
chain_extension::{ChainExtension, Environment, Ext, InitState, RetVal},
2425
Origin,
2526
};
26-
use pallet_xvm::XvmContext;
2727
use sp_runtime::DispatchError;
2828
use sp_std::marker::PhantomData;
2929
use xvm_chain_extension_types::{XvmCallArgs, XvmExecutionResult};
3030

3131
enum XvmFuncId {
32-
XvmCall,
32+
Call,
3333
// TODO: expand with other calls too
3434
}
3535

@@ -38,7 +38,7 @@ impl TryFrom<u16> for XvmFuncId {
3838

3939
fn try_from(value: u16) -> Result<Self, Self::Error> {
4040
match value {
41-
1 => Ok(XvmFuncId::XvmCall),
41+
1 => Ok(XvmFuncId::Call),
4242
_ => Err(DispatchError::Other(
4343
"Unsupported func id in Xvm chain extension",
4444
)),
@@ -47,17 +47,18 @@ impl TryFrom<u16> for XvmFuncId {
4747
}
4848

4949
/// XVM chain extension.
50-
pub struct XvmExtension<T>(PhantomData<T>);
50+
pub struct XvmExtension<T, XC>(PhantomData<(T, XC)>);
5151

52-
impl<T> Default for XvmExtension<T> {
52+
impl<T, XC> Default for XvmExtension<T, XC> {
5353
fn default() -> Self {
5454
XvmExtension(PhantomData)
5555
}
5656
}
5757

58-
impl<T> ChainExtension<T> for XvmExtension<T>
58+
impl<T, XC> ChainExtension<T> for XvmExtension<T, XC>
5959
where
60-
T: pallet_contracts::Config + pallet_xvm::Config,
60+
T: pallet_contracts::Config,
61+
XC: XvmCall<T::AccountId>,
6162
{
6263
fn call<E: Ext>(&mut self, env: Environment<E, InitState>) -> Result<RetVal, DispatchError>
6364
where
@@ -67,13 +68,13 @@ where
6768
let mut env = env.buf_in_buf_out();
6869

6970
match func_id {
70-
XvmFuncId::XvmCall => {
71+
XvmFuncId::Call => {
7172
// We need to immediately charge for the worst case scenario. Gas equals Weight in pallet-contracts context.
72-
let remaining_weight = env.ext().gas_meter().gas_left();
73+
let weight_limit = env.ext().gas_meter().gas_left();
74+
// TODO: track proof size in align fees ticket
7375
// We don't track used proof size, so we can't refund after.
7476
// So we will charge a 32KB dummy value as a temporary replacement.
75-
let charged_weight =
76-
env.charge_weight(remaining_weight.set_proof_size(32 * 1024))?;
77+
let charged_weight = env.charge_weight(weight_limit.set_proof_size(32 * 1024))?;
7778

7879
let caller = match env.ext().caller().clone() {
7980
Origin::Signed(address) => address,
@@ -82,47 +83,60 @@ where
8283
target: "xvm-extension::xvm_call",
8384
"root origin not supported"
8485
);
85-
// TODO: expand XvmErrors with BadOrigin
86-
return Ok(RetVal::Converging(XvmExecutionResult::UnknownError as u32));
86+
return Ok(RetVal::Converging(
87+
XvmExecutionResult::from(CallError::BadOrigin).into(),
88+
));
8789
}
8890
};
8991

9092
let XvmCallArgs { vm_id, to, input } = env.read_as_unbounded(env.in_len())?;
9193

9294
let _origin_address = env.ext().address().clone();
9395
let _value = env.ext().value_transferred();
94-
let xvm_context = XvmContext {
95-
id: vm_id,
96-
max_weight: remaining_weight,
97-
env: None,
96+
let xvm_context = Context {
97+
source_vm_id: VmId::Wasm,
98+
weight_limit,
9899
};
99100

100-
let call_result =
101-
pallet_xvm::Pallet::<T>::xvm_bare_call(xvm_context, caller, to, input);
101+
let vm_id = {
102+
match TryInto::<VmId>::try_into(vm_id) {
103+
Ok(id) => id,
104+
Err(err) => {
105+
// TODO: Propagate error
106+
let result = Into::<XvmExecutionResult>::into(err);
107+
return Ok(RetVal::Converging(result.into()));
108+
}
109+
}
110+
};
111+
let call_result = XC::call(xvm_context, vm_id, caller, to, input);
102112

103-
let actual_weight = pallet_xvm::consumed_weight(&call_result);
113+
let actual_weight = match call_result {
114+
Ok(ref info) => info.used_weight,
115+
Err(ref err) => err.used_weight,
116+
};
104117
env.adjust_weight(charged_weight, actual_weight);
105118

106119
match call_result {
107-
Ok(success) => {
120+
Ok(info) => {
108121
log::trace!(
109122
target: "xvm-extension::xvm_call",
110-
"success: {:?}", success
123+
"info: {:?}", info
111124
);
112125

113-
let buffer: sp_std::vec::Vec<_> = success.output().encode();
126+
let buffer: sp_std::vec::Vec<_> = info.output.encode();
114127
env.write(&buffer, false, None)?;
115-
Ok(RetVal::Converging(XvmExecutionResult::Success as u32))
128+
Ok(RetVal::Converging(XvmExecutionResult::Ok.into()))
116129
}
117130

118-
Err(failure) => {
131+
Err(err) => {
119132
log::trace!(
120133
target: "xvm-extension::xvm_call",
121-
"failure: {:?}", failure
134+
"err: {:?}", err
122135
);
123136

124137
// TODO Propagate error
125-
Ok(RetVal::Converging(XvmExecutionResult::UnknownError as u32))
138+
let result = Into::<XvmExecutionResult>::into(err.error);
139+
Ok(RetVal::Converging(result.into()))
126140
}
127141
}
128142
}

pallets/ethereum-checked/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
//!
2121
//! ## Overview
2222
//!
23-
//! A `pallet-ethererum` like pallet that execute transactions from checked source,
23+
//! A `pallet-ethereum like pallet that execute transactions from checked source,
2424
//! like XCM remote call, cross-VM call, etc. Only `Call` transactions are supported
2525
//! (no `Create`).
2626
//!

0 commit comments

Comments
 (0)