@@ -4,7 +4,7 @@ use alloc::format;
4
4
use core:: marker:: PhantomData ;
5
5
6
6
use frame_support:: dispatch:: { GetDispatchInfo , Pays } ;
7
- use frame_system :: RawOrigin ;
7
+
8
8
use pallet_evm:: {
9
9
ExitError , ExitSucceed , GasWeightMapping , IsPrecompileResult , Precompile , PrecompileFailure ,
10
10
PrecompileHandle , PrecompileOutput , PrecompileResult , PrecompileSet ,
@@ -17,19 +17,25 @@ use sp_runtime::{traits::Dispatchable, AccountId32};
17
17
18
18
use crate :: { Runtime , RuntimeCall } ;
19
19
20
+ use frame_system:: RawOrigin ;
21
+
22
+ use sp_std:: vec;
23
+
20
24
// Include custom precompiles
21
25
mod balance_transfer;
22
26
mod ed25519;
23
27
mod metagraph;
28
+ mod neuron;
24
29
mod staking;
30
+ mod subnet;
25
31
26
32
use balance_transfer:: * ;
27
33
use ed25519:: * ;
28
34
use metagraph:: * ;
35
+ use neuron:: * ;
29
36
use staking:: * ;
30
-
37
+ use subnet :: * ;
31
38
pub struct FrontierPrecompiles < R > ( PhantomData < R > ) ;
32
-
33
39
impl < R > Default for FrontierPrecompiles < R >
34
40
where
35
41
R : pallet_evm:: Config ,
46
52
pub fn new ( ) -> Self {
47
53
Self ( Default :: default ( ) )
48
54
}
49
- pub fn used_addresses ( ) -> [ H160 ; 11 ] {
55
+ pub fn used_addresses ( ) -> [ H160 ; 13 ] {
50
56
[
51
57
hash ( 1 ) ,
52
58
hash ( 2 ) ,
58
64
hash ( EDVERIFY_PRECOMPILE_INDEX ) ,
59
65
hash ( BALANCE_TRANSFER_INDEX ) ,
60
66
hash ( STAKING_PRECOMPILE_INDEX ) ,
67
+ hash ( SUBNET_PRECOMPILE_INDEX ) ,
61
68
hash ( METAGRAPH_PRECOMPILE_INDEX ) ,
69
+ hash ( NEURON_PRECOMPILE_INDEX ) ,
62
70
]
63
71
}
64
72
}
83
91
Some ( BalanceTransferPrecompile :: execute ( handle) )
84
92
}
85
93
a if a == hash ( STAKING_PRECOMPILE_INDEX ) => Some ( StakingPrecompile :: execute ( handle) ) ,
94
+ a if a == hash ( SUBNET_PRECOMPILE_INDEX ) => Some ( SubnetPrecompile :: execute ( handle) ) ,
86
95
a if a == hash ( METAGRAPH_PRECOMPILE_INDEX ) => {
87
96
Some ( MetagraphPrecompile :: execute ( handle) )
88
97
}
98
+ a if a == hash ( NEURON_PRECOMPILE_INDEX ) => Some ( NeuronPrecompile :: execute ( handle) ) ,
89
99
90
100
_ => None ,
91
101
}
@@ -113,31 +123,55 @@ pub fn get_method_id(method_signature: &str) -> [u8; 4] {
113
123
[ hash[ 0 ] , hash[ 1 ] , hash[ 2 ] , hash[ 3 ] ]
114
124
}
115
125
116
- /// Convert bytes to AccountId32 with PrecompileFailure as Error
117
- /// which consumes all gas
118
- ///
119
- pub fn bytes_to_account_id ( account_id_bytes : & [ u8 ] ) -> Result < AccountId32 , PrecompileFailure > {
120
- AccountId32 :: try_from ( account_id_bytes) . map_err ( |_| {
121
- log:: info!( "Error parsing account id bytes {:?}" , account_id_bytes) ;
122
- PrecompileFailure :: Error {
123
- exit_status : ExitError :: InvalidRange ,
124
- }
125
- } )
126
- }
127
-
128
126
/// Takes a slice from bytes with PrecompileFailure as Error
129
127
///
130
128
pub fn get_slice ( data : & [ u8 ] , from : usize , to : usize ) -> Result < & [ u8 ] , PrecompileFailure > {
131
129
let maybe_slice = data. get ( from..to) ;
132
130
if let Some ( slice) = maybe_slice {
133
131
Ok ( slice)
134
132
} else {
133
+ log:: error!(
134
+ "fail to get slice from data, {:?}, from {}, to {}" ,
135
+ & data,
136
+ from,
137
+ to
138
+ ) ;
135
139
Err ( PrecompileFailure :: Error {
136
140
exit_status : ExitError :: InvalidRange ,
137
141
} )
138
142
}
139
143
}
140
144
145
+ pub fn get_pubkey ( data : & [ u8 ] ) -> Result < ( AccountId32 , vec:: Vec < u8 > ) , PrecompileFailure > {
146
+ let mut pubkey = [ 0u8 ; 32 ] ;
147
+ pubkey. copy_from_slice ( get_slice ( data, 0 , 32 ) ?) ;
148
+
149
+ Ok ( (
150
+ pubkey. into ( ) ,
151
+ data. get ( 4 ..)
152
+ . map_or_else ( vec:: Vec :: new, |slice| slice. to_vec ( ) ) ,
153
+ ) )
154
+ }
155
+
156
+ fn parse_netuid ( data : & [ u8 ] , offset : usize ) -> Result < u16 , PrecompileFailure > {
157
+ if data. len ( ) < offset + 2 {
158
+ return Err ( PrecompileFailure :: Error {
159
+ exit_status : ExitError :: InvalidRange ,
160
+ } ) ;
161
+ }
162
+
163
+ let mut netuid_bytes = [ 0u8 ; 2 ] ;
164
+ netuid_bytes. copy_from_slice ( get_slice ( data, offset, offset + 2 ) ?) ;
165
+ let netuid: u16 = netuid_bytes[ 1 ] as u16 | ( ( netuid_bytes[ 0 ] as u16 ) << 8u16 ) ;
166
+
167
+ Ok ( netuid)
168
+ }
169
+
170
+ fn contract_to_origin ( contract : & [ u8 ; 32 ] ) -> Result < RawOrigin < AccountId32 > , PrecompileFailure > {
171
+ let ( account_id, _) = get_pubkey ( contract) ?;
172
+ Ok ( RawOrigin :: Signed ( account_id) )
173
+ }
174
+
141
175
/// Dispatches a runtime call, but also checks and records the gas costs.
142
176
fn try_dispatch_runtime_call (
143
177
handle : & mut impl PrecompileHandle ,
0 commit comments