18
18
19
19
#![ cfg_attr( not( feature = "std" ) , no_std) ]
20
20
21
+ use astar_primitives:: xvm:: { CallError , Context , VmId , XvmCall } ;
21
22
use frame_support:: dispatch:: Encode ;
22
23
use pallet_contracts:: {
23
24
chain_extension:: { ChainExtension , Environment , Ext , InitState , RetVal } ,
24
25
Origin ,
25
26
} ;
26
- use pallet_xvm:: XvmContext ;
27
27
use sp_runtime:: DispatchError ;
28
28
use sp_std:: marker:: PhantomData ;
29
29
use xvm_chain_extension_types:: { XvmCallArgs , XvmExecutionResult } ;
30
30
31
31
enum XvmFuncId {
32
- XvmCall ,
32
+ Call ,
33
33
// TODO: expand with other calls too
34
34
}
35
35
@@ -38,7 +38,7 @@ impl TryFrom<u16> for XvmFuncId {
38
38
39
39
fn try_from ( value : u16 ) -> Result < Self , Self :: Error > {
40
40
match value {
41
- 1 => Ok ( XvmFuncId :: XvmCall ) ,
41
+ 1 => Ok ( XvmFuncId :: Call ) ,
42
42
_ => Err ( DispatchError :: Other (
43
43
"Unsupported func id in Xvm chain extension" ,
44
44
) ) ,
@@ -47,17 +47,18 @@ impl TryFrom<u16> for XvmFuncId {
47
47
}
48
48
49
49
/// XVM chain extension.
50
- pub struct XvmExtension < T > ( PhantomData < T > ) ;
50
+ pub struct XvmExtension < T , XC > ( PhantomData < ( T , XC ) > ) ;
51
51
52
- impl < T > Default for XvmExtension < T > {
52
+ impl < T , XC > Default for XvmExtension < T , XC > {
53
53
fn default ( ) -> Self {
54
54
XvmExtension ( PhantomData )
55
55
}
56
56
}
57
57
58
- impl < T > ChainExtension < T > for XvmExtension < T >
58
+ impl < T , XC > ChainExtension < T > for XvmExtension < T , XC >
59
59
where
60
- T : pallet_contracts:: Config + pallet_xvm:: Config ,
60
+ T : pallet_contracts:: Config ,
61
+ XC : XvmCall < T :: AccountId > ,
61
62
{
62
63
fn call < E : Ext > ( & mut self , env : Environment < E , InitState > ) -> Result < RetVal , DispatchError >
63
64
where
@@ -67,13 +68,13 @@ where
67
68
let mut env = env. buf_in_buf_out ( ) ;
68
69
69
70
match func_id {
70
- XvmFuncId :: XvmCall => {
71
+ XvmFuncId :: Call => {
71
72
// 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
73
75
// We don't track used proof size, so we can't refund after.
74
76
// 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 ) ) ?;
77
78
78
79
let caller = match env. ext ( ) . caller ( ) . clone ( ) {
79
80
Origin :: Signed ( address) => address,
@@ -82,47 +83,60 @@ where
82
83
target: "xvm-extension::xvm_call" ,
83
84
"root origin not supported"
84
85
) ;
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
+ ) ) ;
87
89
}
88
90
} ;
89
91
90
92
let XvmCallArgs { vm_id, to, input } = env. read_as_unbounded ( env. in_len ( ) ) ?;
91
93
92
94
let _origin_address = env. ext ( ) . address ( ) . clone ( ) ;
93
95
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,
98
99
} ;
99
100
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) ;
102
112
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
+ } ;
104
117
env. adjust_weight ( charged_weight, actual_weight) ;
105
118
106
119
match call_result {
107
- Ok ( success ) => {
120
+ Ok ( info ) => {
108
121
log:: trace!(
109
122
target: "xvm-extension::xvm_call" ,
110
- "success : {:?}" , success
123
+ "info : {:?}" , info
111
124
) ;
112
125
113
- let buffer: sp_std:: vec:: Vec < _ > = success . output ( ) . encode ( ) ;
126
+ let buffer: sp_std:: vec:: Vec < _ > = info . output . encode ( ) ;
114
127
env. write ( & buffer, false , None ) ?;
115
- Ok ( RetVal :: Converging ( XvmExecutionResult :: Success as u32 ) )
128
+ Ok ( RetVal :: Converging ( XvmExecutionResult :: Ok . into ( ) ) )
116
129
}
117
130
118
- Err ( failure ) => {
131
+ Err ( err ) => {
119
132
log:: trace!(
120
133
target: "xvm-extension::xvm_call" ,
121
- "failure : {:?}" , failure
134
+ "err : {:?}" , err
122
135
) ;
123
136
124
137
// 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 ( ) ) )
126
140
}
127
141
}
128
142
}
0 commit comments