1
1
// Copyright (c) RoochNetwork
2
2
// SPDX-License-Identifier: Apache-2.0
3
3
4
- use anyhow:: Result ;
4
+ use anyhow:: { ensure , Error , Result } ;
5
5
use jsonrpsee:: core:: client:: ClientT ;
6
6
use jsonrpsee:: http_client:: { HttpClient , HttpClientBuilder } ;
7
- use move_core_types:: language_storage:: ModuleId ;
7
+ use move_core_types:: account_address:: AccountAddress ;
8
+ use move_core_types:: language_storage:: { ModuleId , StructTag } ;
8
9
use move_core_types:: metadata:: Metadata ;
9
- use move_core_types:: resolver:: ModuleResolver ;
10
+ use move_core_types:: resolver:: { ModuleResolver , ResourceResolver } ;
10
11
use moveos_types:: access_path:: AccessPath ;
12
+ use moveos_types:: h256:: H256 ;
11
13
use moveos_types:: move_std:: string:: MoveString ;
14
+ use moveos_types:: moveos_std:: account:: Account ;
12
15
use moveos_types:: moveos_std:: move_module:: MoveModule ;
13
- use moveos_types:: state:: ObjectState ;
16
+ use moveos_types:: moveos_std:: object:: { ObjectID , ObjectMeta , RawField } ;
17
+ use moveos_types:: state:: { FieldKey , MoveType , ObjectState } ;
18
+ use moveos_types:: state_resolver:: { StateKV , StateResolver , StatelessResolver } ;
14
19
use moveos_types:: {
15
20
function_return_value:: FunctionResult , module_binding:: MoveFunctionCaller ,
16
21
moveos_std:: tx_context:: TxContext , transaction:: FunctionCall ,
@@ -109,7 +114,7 @@ impl ModuleResolver for &Client {
109
114
fn get_module ( & self , id : & ModuleId ) -> Result < Option < Vec < u8 > > > {
110
115
tokio:: task:: block_in_place ( || {
111
116
Handle :: current ( ) . block_on ( async {
112
- let mut states = self . rooch . get_states ( AccessPath :: module ( id) ) . await ?;
117
+ let mut states = self . rooch . get_states ( None , AccessPath :: module ( id) ) . await ?;
113
118
states
114
119
. pop ( )
115
120
. flatten ( )
@@ -123,3 +128,111 @@ impl ModuleResolver for &Client {
123
128
} )
124
129
}
125
130
}
131
+
132
+ #[ derive( Clone ) ]
133
+ pub struct ClientResolver {
134
+ root : ObjectMeta ,
135
+ client : Client ,
136
+ }
137
+
138
+ impl ClientResolver {
139
+ pub fn new ( client : Client , root : ObjectMeta ) -> Self {
140
+ Self { root, client }
141
+ }
142
+ }
143
+
144
+ impl ResourceResolver for ClientResolver {
145
+ fn get_resource_with_metadata (
146
+ & self ,
147
+ address : & AccountAddress ,
148
+ resource_tag : & StructTag ,
149
+ _metadata : & [ Metadata ] ,
150
+ ) -> std:: result:: Result < ( Option < Vec < u8 > > , usize ) , Error > {
151
+ let account_object_id = Account :: account_object_id ( * address) ;
152
+
153
+ let key = FieldKey :: derive_resource_key ( resource_tag) ;
154
+ let result = self
155
+ . get_field ( & account_object_id, & key) ?
156
+ . map ( |s| {
157
+ ensure ! (
158
+ s. match_dynamic_field_type( MoveString :: type_tag( ) , resource_tag. clone( ) . into( ) ) ,
159
+ "Resource type mismatch, expected field value type: {:?}, actual: {:?}" ,
160
+ resource_tag,
161
+ s. object_type( )
162
+ ) ;
163
+ let field = RawField :: parse_resource_field ( & s. value , resource_tag. clone ( ) . into ( ) ) ?;
164
+ Ok ( field. value )
165
+ } )
166
+ . transpose ( ) ;
167
+
168
+ match result {
169
+ Ok ( opt) => {
170
+ if let Some ( data) = opt {
171
+ Ok ( ( Some ( data) , 0 ) )
172
+ } else {
173
+ Ok ( ( None , 0 ) )
174
+ }
175
+ }
176
+ Err ( err) => Err ( err) ,
177
+ }
178
+ }
179
+ }
180
+
181
+ impl ModuleResolver for ClientResolver {
182
+ fn get_module_metadata ( & self , _module_id : & ModuleId ) -> Vec < Metadata > {
183
+ vec ! [ ]
184
+ }
185
+
186
+ fn get_module ( & self , id : & ModuleId ) -> std:: result:: Result < Option < Vec < u8 > > , Error > {
187
+ ( & self . client ) . get_module ( id)
188
+ }
189
+ }
190
+
191
+ impl StatelessResolver for ClientResolver {
192
+ fn get_field_at ( & self , state_root : H256 , key : & FieldKey ) -> Result < Option < ObjectState > , Error > {
193
+ tokio:: task:: block_in_place ( || {
194
+ Handle :: current ( ) . block_on ( async {
195
+ let access_path = AccessPath :: object ( ObjectID :: new ( key. 0 ) ) ;
196
+ let mut object_state_view_list = self
197
+ . client
198
+ . rooch
199
+ . get_states ( Some ( hex:: encode ( state_root. 0 . as_slice ( ) ) ) , access_path)
200
+ . await ?;
201
+ Ok ( object_state_view_list. pop ( ) . flatten ( ) . map ( |state_view| {
202
+ let v: ObjectState = state_view. into ( ) ;
203
+ v
204
+ } ) )
205
+ } )
206
+ } )
207
+ }
208
+
209
+ fn list_fields_at (
210
+ & self ,
211
+ state_root : H256 ,
212
+ cursor : Option < FieldKey > ,
213
+ limit : usize ,
214
+ ) -> Result < Vec < StateKV > > {
215
+ tokio:: task:: block_in_place ( || {
216
+ Handle :: current ( ) . block_on ( async {
217
+ let object_id = ObjectID :: new ( state_root. 0 ) ;
218
+ let field_cursor = cursor. map ( |field_key| field_key. to_hex_literal ( ) ) ;
219
+ let fields_states = self
220
+ . client
221
+ . rooch
222
+ . list_field_states ( object_id. into ( ) , field_cursor, Some ( limit as u64 ) , None )
223
+ . await ?;
224
+ Ok ( fields_states
225
+ . data
226
+ . iter ( )
227
+ . map ( |item| StateKV :: from ( ( item. field_key . into ( ) , item. state . clone ( ) . into ( ) ) ) )
228
+ . collect ( ) )
229
+ } )
230
+ } )
231
+ }
232
+ }
233
+
234
+ impl StateResolver for ClientResolver {
235
+ fn root ( & self ) -> & ObjectMeta {
236
+ & self . root
237
+ }
238
+ }
0 commit comments