@@ -53,27 +53,28 @@ impl StakingPrecompile {
53
53
. map_or_else ( vec:: Vec :: new, |slice| slice. to_vec ( ) ) ; // Avoiding borrowing conflicts
54
54
55
55
match method_id {
56
- id if id == get_method_id ( "addStake(bytes32,uint16 )" ) => {
56
+ id if id == get_method_id ( "addStake(bytes32,uint256 )" ) => {
57
57
Self :: add_stake ( handle, & method_input)
58
58
}
59
- id if id == get_method_id ( "removeStake(bytes32,uint256,uint16 )" ) => {
59
+ id if id == get_method_id ( "removeStake(bytes32,uint256,uint256 )" ) => {
60
60
Self :: remove_stake ( handle, & method_input)
61
61
}
62
62
id if id == get_method_id ( "getStakeColdkey(bytes32)" ) => {
63
63
Self :: get_stake_coldkey ( & method_input)
64
64
}
65
+ id if id == get_method_id ( "getStake(bytes32,bytes32,uint256)" ) => {
66
+ Self :: get_stake ( & method_input)
67
+ }
65
68
_ => Err ( PrecompileFailure :: Error {
66
69
exit_status : ExitError :: InvalidRange ,
67
70
} ) ,
68
71
}
69
72
}
70
73
71
74
fn add_stake ( handle : & mut impl PrecompileHandle , data : & [ u8 ] ) -> PrecompileResult {
72
- let hotkey = Self :: parse_ss58 ( data) ?. into ( ) ;
75
+ let hotkey = Self :: parse_key ( data) ?. into ( ) ;
73
76
let amount: U256 = handle. context ( ) . apparent_value ;
74
-
75
- // TODO: Use netuid method parameter here
76
- let netuid: u16 = 0 ;
77
+ let netuid = Self :: parse_netuid ( data, 0x3E ) ?;
77
78
78
79
let amount_sub =
79
80
<Runtime as pallet_evm:: Config >:: BalanceConverter :: into_substrate_balance ( amount)
@@ -88,11 +89,10 @@ impl StakingPrecompile {
88
89
// Dispatch the add_stake call
89
90
Self :: dispatch ( handle, call)
90
91
}
91
- fn remove_stake ( handle : & mut impl PrecompileHandle , data : & [ u8 ] ) -> PrecompileResult {
92
- let hotkey = Self :: parse_ss58 ( data) ?. into ( ) ;
93
92
94
- // TODO: Use netuid method parameter here
95
- let netuid: u16 = 0 ;
93
+ fn remove_stake ( handle : & mut impl PrecompileHandle , data : & [ u8 ] ) -> PrecompileResult {
94
+ let hotkey = Self :: parse_key ( data) ?. into ( ) ;
95
+ let netuid = Self :: parse_netuid ( data, 0x5E ) ?;
96
96
97
97
// We have to treat this as uint256 (because of Solidity ABI encoding rules, it pads uint64),
98
98
// but this will never exceed 8 bytes, se we will ignore higher bytes and will only use lower
@@ -114,11 +114,10 @@ impl StakingPrecompile {
114
114
}
115
115
116
116
fn get_stake_coldkey ( data : & [ u8 ] ) -> PrecompileResult {
117
- // TODO: rename parse_ss58 to parse_key or something?
118
- let coldkey: AccountId32 = Self :: parse_ss58 ( data) ?. into ( ) ;
117
+ let coldkey: AccountId32 = Self :: parse_key ( data) ?. into ( ) ;
119
118
120
119
// get total stake of coldkey
121
- let total_stake = pallet_subtensor:: TotalColdkeyStake :: < Runtime > :: get ( coldkey) ;
120
+ let total_stake = pallet_subtensor:: Pallet :: < Runtime > :: get_total_stake_for_coldkey ( & coldkey) ;
122
121
let result_u256 = U256 :: from ( total_stake) ;
123
122
let mut result = [ 0_u8 ; 32 ] ;
124
123
U256 :: to_big_endian ( & result_u256, & mut result) ;
@@ -129,15 +128,68 @@ impl StakingPrecompile {
129
128
} )
130
129
}
131
130
132
- fn parse_ss58 ( data : & [ u8 ] ) -> Result < [ u8 ; 32 ] , PrecompileFailure > {
133
- if data. len ( ) < 32 {
131
+ fn get_stake ( data : & [ u8 ] ) -> PrecompileResult {
132
+ let ( hotkey, coldkey) = Self :: parse_hotkey_coldkey ( data) ?;
133
+ let netuid: u16 = Self :: parse_netuid ( data, 0x5E ) ?;
134
+
135
+ let stake = pallet_subtensor:: Pallet :: < Runtime > :: get_stake_for_hotkey_and_coldkey_on_subnet (
136
+ & hotkey. into ( ) ,
137
+ & coldkey. into ( ) ,
138
+ netuid,
139
+ ) ;
140
+
141
+ // Convert to EVM decimals
142
+ let stake_u256 = U256 :: from ( stake) ;
143
+ let stake_eth =
144
+ <Runtime as pallet_evm:: Config >:: BalanceConverter :: into_evm_balance ( stake_u256)
145
+ . ok_or ( ExitError :: InvalidRange ) ?;
146
+
147
+ // Format output
148
+ let mut result = [ 0_u8 ; 32 ] ;
149
+ U256 :: to_big_endian ( & stake_eth, & mut result) ;
150
+
151
+ Ok ( PrecompileOutput {
152
+ exit_status : ExitSucceed :: Returned ,
153
+ output : result. into ( ) ,
154
+ } )
155
+ }
156
+
157
+ fn parse_hotkey_coldkey ( data : & [ u8 ] ) -> Result < ( [ u8 ; 32 ] , [ u8 ; 32 ] ) , PrecompileFailure > {
158
+ if data. len ( ) < 64 {
134
159
return Err ( PrecompileFailure :: Error {
135
160
exit_status : ExitError :: InvalidRange ,
136
161
} ) ;
137
162
}
138
163
let mut hotkey = [ 0u8 ; 32 ] ;
139
164
hotkey. copy_from_slice ( get_slice ( data, 0 , 32 ) ?) ;
140
- Ok ( hotkey)
165
+ let mut coldkey = [ 0u8 ; 32 ] ;
166
+ coldkey. copy_from_slice ( get_slice ( data, 32 , 64 ) ?) ;
167
+ Ok ( ( hotkey, coldkey) )
168
+ }
169
+
170
+ fn parse_key ( data : & [ u8 ] ) -> Result < [ u8 ; 32 ] , PrecompileFailure > {
171
+ if data. len ( ) < 32 {
172
+ return Err ( PrecompileFailure :: Error {
173
+ exit_status : ExitError :: InvalidRange ,
174
+ } ) ;
175
+ }
176
+ let mut key = [ 0u8 ; 32 ] ;
177
+ key. copy_from_slice ( get_slice ( data, 0 , 32 ) ?) ;
178
+ Ok ( key)
179
+ }
180
+
181
+ fn parse_netuid ( data : & [ u8 ] , offset : usize ) -> Result < u16 , PrecompileFailure > {
182
+ if data. len ( ) < offset + 2 {
183
+ return Err ( PrecompileFailure :: Error {
184
+ exit_status : ExitError :: InvalidRange ,
185
+ } ) ;
186
+ }
187
+
188
+ let mut netuid_bytes = [ 0u8 ; 2 ] ;
189
+ netuid_bytes. copy_from_slice ( get_slice ( data, offset, offset + 2 ) ?) ;
190
+ let netuid: u16 = netuid_bytes[ 1 ] as u16 | ( ( netuid_bytes[ 0 ] as u16 ) << 8u16 ) ;
191
+
192
+ Ok ( netuid)
141
193
}
142
194
143
195
fn dispatch ( handle : & mut impl PrecompileHandle , call : RuntimeCall ) -> PrecompileResult {
@@ -164,9 +216,12 @@ impl StakingPrecompile {
164
216
exit_status : ExitSucceed :: Returned ,
165
217
output : vec ! [ ] ,
166
218
} ) ,
167
- Err ( _) => Err ( PrecompileFailure :: Error {
168
- exit_status : ExitError :: Other ( "Subtensor call failed" . into ( ) ) ,
169
- } ) ,
219
+ Err ( _) => {
220
+ log:: warn!( "Returning error PrecompileFailure::Error" ) ;
221
+ Err ( PrecompileFailure :: Error {
222
+ exit_status : ExitError :: Other ( "Subtensor call failed" . into ( ) ) ,
223
+ } )
224
+ }
170
225
}
171
226
}
172
227
0 commit comments