3
3
4
4
use crate :: field_mask:: FieldMaskTree ;
5
5
use crate :: field_mask:: FieldMaskUtil ;
6
- use crate :: message:: MessageMerge ;
7
6
use crate :: message:: MessageMergeFrom ;
8
7
use crate :: proto:: google:: rpc:: bad_request:: FieldViolation ;
9
8
use crate :: proto:: rpc:: v2beta:: BatchGetTransactionsRequest ;
10
9
use crate :: proto:: rpc:: v2beta:: BatchGetTransactionsResponse ;
10
+ use crate :: proto:: rpc:: v2beta:: Event ;
11
11
use crate :: proto:: rpc:: v2beta:: ExecutedTransaction ;
12
12
use crate :: proto:: rpc:: v2beta:: GetTransactionRequest ;
13
13
use crate :: proto:: rpc:: v2beta:: Transaction ;
@@ -21,6 +21,7 @@ use crate::RpcService;
21
21
use prost_types:: FieldMask ;
22
22
use sui_sdk_types:: TransactionDigest ;
23
23
use sui_types:: base_types:: ObjectID ;
24
+ use sui_types:: sui_sdk_types_conversions:: struct_tag_sdk_to_core;
24
25
25
26
#[ tracing:: instrument( skip( service) ) ]
26
27
pub fn get_transaction (
@@ -57,7 +58,8 @@ pub fn get_transaction(
57
58
58
59
let transaction_read = service. reader . get_transaction_read ( transaction_digest) ?;
59
60
60
- Ok ( ExecutedTransaction :: merge_from (
61
+ Ok ( transaction_to_response (
62
+ service,
61
63
transaction_read,
62
64
& read_mask,
63
65
) )
@@ -95,100 +97,129 @@ pub fn batch_get_transactions(
95
97
. reader
96
98
. get_transaction_read ( digest)
97
99
. map ( |transaction_read| {
98
- ExecutedTransaction :: merge_from ( transaction_read, & read_mask)
100
+ transaction_to_response ( service , transaction_read, & read_mask)
99
101
} )
100
102
} )
101
103
. collect :: < Result < _ , _ > > ( ) ?;
102
104
103
105
Ok ( BatchGetTransactionsResponse { transactions } )
104
106
}
105
107
106
- impl MessageMerge < crate :: reader:: TransactionRead > for ExecutedTransaction {
107
- fn merge (
108
- & mut self ,
109
- source : crate :: reader:: TransactionRead ,
110
- mask : & crate :: field_mask:: FieldMaskTree ,
111
- ) {
112
- if mask. contains ( Self :: DIGEST_FIELD . name ) {
113
- self . digest = Some ( source. digest . to_string ( ) ) ;
114
- }
108
+ fn transaction_to_response (
109
+ service : & RpcService ,
110
+ source : crate :: reader:: TransactionRead ,
111
+ mask : & crate :: field_mask:: FieldMaskTree ,
112
+ ) -> ExecutedTransaction {
113
+ let mut message = ExecutedTransaction :: default ( ) ;
115
114
116
- if let Some ( submask ) = mask. subtree ( Self :: TRANSACTION_FIELD . name ) {
117
- self . transaction = Some ( Transaction :: merge_from ( source. transaction , & submask ) ) ;
118
- }
115
+ if mask. contains ( ExecutedTransaction :: DIGEST_FIELD . name ) {
116
+ message . digest = Some ( source. digest . to_string ( ) ) ;
117
+ }
119
118
120
- if let Some ( submask) = mask. subtree ( Self :: SIGNATURES_FIELD . name ) {
121
- self . signatures = source
122
- . signatures
123
- . into_iter ( )
124
- . map ( |s| UserSignature :: merge_from ( s, & submask) )
125
- . collect ( ) ;
126
- }
119
+ if let Some ( submask) = mask. subtree ( ExecutedTransaction :: TRANSACTION_FIELD . name ) {
120
+ message. transaction = Some ( Transaction :: merge_from ( source. transaction , & submask) ) ;
121
+ }
127
122
128
- if let Some ( submask) = mask. subtree ( Self :: EFFECTS_FIELD . name ) {
129
- let mut effects = TransactionEffects :: merge_from ( & source. effects , & submask) ;
130
-
131
- if let Some ( object_types) = source. object_types {
132
- if submask. contains ( TransactionEffects :: CHANGED_OBJECTS_FIELD . name ) {
133
- for changed_object in effects. changed_objects . iter_mut ( ) {
134
- let Ok ( object_id) = changed_object. object_id ( ) . parse :: < ObjectID > ( ) else {
135
- continue ;
136
- } ;
137
-
138
- if let Some ( ty) = object_types. get ( & object_id) {
139
- changed_object. object_type = Some ( match ty {
140
- sui_types:: base_types:: ObjectType :: Package => "package" . to_owned ( ) ,
141
- sui_types:: base_types:: ObjectType :: Struct ( struct_tag) => {
142
- struct_tag. to_canonical_string ( true )
143
- }
144
- } ) ;
145
- }
123
+ if let Some ( submask) = mask. subtree ( ExecutedTransaction :: SIGNATURES_FIELD . name ) {
124
+ message. signatures = source
125
+ . signatures
126
+ . into_iter ( )
127
+ . map ( |s| UserSignature :: merge_from ( s, & submask) )
128
+ . collect ( ) ;
129
+ }
130
+
131
+ if let Some ( submask) = mask. subtree ( ExecutedTransaction :: EFFECTS_FIELD . name ) {
132
+ let mut effects = TransactionEffects :: merge_from ( & source. effects , & submask) ;
133
+
134
+ if let Some ( object_types) = source. object_types {
135
+ if submask. contains ( TransactionEffects :: CHANGED_OBJECTS_FIELD . name ) {
136
+ for changed_object in effects. changed_objects . iter_mut ( ) {
137
+ let Ok ( object_id) = changed_object. object_id ( ) . parse :: < ObjectID > ( ) else {
138
+ continue ;
139
+ } ;
140
+
141
+ if let Some ( ty) = object_types. get ( & object_id) {
142
+ changed_object. object_type = Some ( match ty {
143
+ sui_types:: base_types:: ObjectType :: Package => "package" . to_owned ( ) ,
144
+ sui_types:: base_types:: ObjectType :: Struct ( struct_tag) => {
145
+ struct_tag. to_canonical_string ( true )
146
+ }
147
+ } ) ;
146
148
}
147
149
}
150
+ }
148
151
149
- if submask. contains ( TransactionEffects :: UNCHANGED_SHARED_OBJECTS_FIELD . name ) {
150
- for unchanged_shared_object in effects. unchanged_shared_objects . iter_mut ( ) {
151
- let Ok ( object_id) = unchanged_shared_object. object_id ( ) . parse :: < ObjectID > ( )
152
- else {
153
- continue ;
154
- } ;
155
-
156
- if let Some ( ty) = object_types. get ( & object_id) {
157
- unchanged_shared_object. object_type = Some ( match ty {
158
- sui_types:: base_types:: ObjectType :: Package => "package" . to_owned ( ) ,
159
- sui_types:: base_types:: ObjectType :: Struct ( struct_tag) => {
160
- struct_tag. to_canonical_string ( true )
161
- }
162
- } ) ;
163
- }
152
+ if submask. contains ( TransactionEffects :: UNCHANGED_SHARED_OBJECTS_FIELD . name ) {
153
+ for unchanged_shared_object in effects. unchanged_shared_objects . iter_mut ( ) {
154
+ let Ok ( object_id) = unchanged_shared_object. object_id ( ) . parse :: < ObjectID > ( )
155
+ else {
156
+ continue ;
157
+ } ;
158
+
159
+ if let Some ( ty) = object_types. get ( & object_id) {
160
+ unchanged_shared_object. object_type = Some ( match ty {
161
+ sui_types:: base_types:: ObjectType :: Package => "package" . to_owned ( ) ,
162
+ sui_types:: base_types:: ObjectType :: Struct ( struct_tag) => {
163
+ struct_tag. to_canonical_string ( true )
164
+ }
165
+ } ) ;
164
166
}
165
167
}
166
168
}
167
-
168
- self . effects = Some ( effects) ;
169
169
}
170
170
171
- if let Some ( submask) = mask. subtree ( Self :: EVENTS_FIELD . name ) {
172
- self . events = source
173
- . events
174
- . map ( |events| TransactionEvents :: merge_from ( events, & submask) ) ;
175
- }
171
+ message. effects = Some ( effects) ;
172
+ }
176
173
177
- if mask. contains ( Self :: CHECKPOINT_FIELD . name ) {
178
- self . checkpoint = source. checkpoint ;
179
- }
174
+ if let Some ( submask) = mask. subtree ( ExecutedTransaction :: EVENTS_FIELD . name ) {
175
+ message. events = source. events . map ( |events| {
176
+ let mut message = TransactionEvents :: merge_from ( events. clone ( ) , & submask) ;
177
+
178
+ if let Some ( event_mask) = submask. subtree ( TransactionEvents :: EVENTS_FIELD . name ) {
179
+ if event_mask. contains ( Event :: JSON_FIELD . name ) {
180
+ for ( message, event) in message. events . iter_mut ( ) . zip ( & events. 0 ) {
181
+ message. json = struct_tag_sdk_to_core ( event. type_ . clone ( ) )
182
+ . ok ( )
183
+ . and_then ( |struct_tag| {
184
+ let layout = service
185
+ . reader
186
+ . inner ( )
187
+ . get_struct_layout ( & struct_tag)
188
+ . ok ( )
189
+ . flatten ( ) ?;
190
+ Some ( ( layout, & event. contents ) )
191
+ } )
192
+ . and_then ( |( layout, contents) | {
193
+ sui_types:: proto_value:: ProtoVisitor :: default ( )
194
+ . deserialize_value ( contents, & layout)
195
+ . map_err ( |e| tracing:: debug!( "unable to convert to JSON: {e}" ) )
196
+ . ok ( )
197
+ . map ( Box :: new)
198
+ } ) ;
199
+ }
200
+ }
201
+ }
180
202
181
- if mask . contains ( Self :: TIMESTAMP_FIELD . name ) {
182
- self . timestamp = source . timestamp_ms . map ( timestamp_ms_to_proto ) ;
183
- }
203
+ message
204
+ } ) ;
205
+ }
184
206
185
- if mask. contains ( Self :: BALANCE_CHANGES_FIELD . name ) {
186
- self . balance_changes = source
187
- . balance_changes
188
- . map ( |balance_changes| balance_changes . into_iter ( ) . map ( Into :: into ) . collect ( ) )
189
- . unwrap_or_default ( ) ;
190
- }
207
+ if mask. contains ( ExecutedTransaction :: CHECKPOINT_FIELD . name ) {
208
+ message . checkpoint = source. checkpoint ;
209
+ }
210
+
211
+ if mask . contains ( ExecutedTransaction :: TIMESTAMP_FIELD . name ) {
212
+ message . timestamp = source . timestamp_ms . map ( timestamp_ms_to_proto ) ;
191
213
}
214
+
215
+ if mask. contains ( ExecutedTransaction :: BALANCE_CHANGES_FIELD . name ) {
216
+ message. balance_changes = source
217
+ . balance_changes
218
+ . map ( |balance_changes| balance_changes. into_iter ( ) . map ( Into :: into) . collect ( ) )
219
+ . unwrap_or_default ( ) ;
220
+ }
221
+
222
+ message
192
223
}
193
224
194
225
impl From < sui_types:: balance_change:: BalanceChange > for crate :: proto:: rpc:: v2beta:: BalanceChange {
0 commit comments