1
1
use anyhow:: Result ;
2
2
use everscale_types:: models:: {
3
3
AccountState , AccountStatus , ComputePhase , ComputePhaseSkipReason , CurrencyCollection ,
4
- ExecutedComputePhase , SkippedComputePhase , StateInit , TickTock ,
4
+ ExecutedComputePhase , IntAddr , IntMsgInfo , MsgType , SkippedComputePhase , StateInit , TickTock ,
5
5
} ;
6
6
use everscale_types:: num:: Tokens ;
7
7
use everscale_types:: prelude:: * ;
8
8
use num_bigint:: { BigInt , Sign } ;
9
- use tycho_vm:: { tuple, SafeRc , SmcInfoBase , Stack , VmState } ;
9
+ use tycho_vm:: { tuple, SafeRc , SmcInfoBase , Stack , Tuple , UnpackedInMsgSmcInfo , VmState } ;
10
10
11
11
use crate :: phase:: receive:: { MsgStateInit , ReceivedMessage } ;
12
12
use crate :: util:: {
@@ -147,6 +147,7 @@ impl ExecutorState<'_> {
147
147
} ) ;
148
148
return Ok ( res) ;
149
149
}
150
+
150
151
// Apply internal message state.
151
152
let state_libs;
152
153
let msg_libs;
@@ -180,7 +181,7 @@ impl ExecutorState<'_> {
180
181
& self . address . address
181
182
} ;
182
183
183
- if from_msg. hash != * target_hash || from_msg. parsed . split_depth . is_some ( ) {
184
+ if from_msg. root_hash ( ) != target_hash || from_msg. parsed . split_depth . is_some ( ) {
184
185
// State hash mismatch, cannot use this state.
185
186
// We also forbid using `split_depth` (for now).
186
187
res. compute_phase = ComputePhase :: Skipped ( SkippedComputePhase {
@@ -227,7 +228,7 @@ impl ExecutorState<'_> {
227
228
}
228
229
( Some ( from_msg) , AccountState :: Active ( StateInit { libraries, .. } ) ) => {
229
230
// Check if a state from the external message has the correct hash.
230
- if is_external && from_msg. hash != self . address . address {
231
+ if is_external && from_msg. root_hash ( ) != & self . address . address {
231
232
res. compute_phase = ComputePhase :: Skipped ( SkippedComputePhase {
232
233
reason : ComputePhaseSkipReason :: BadState ,
233
234
} ) ;
@@ -243,6 +244,12 @@ impl ExecutorState<'_> {
243
244
}
244
245
}
245
246
247
+ // Unpack internal message.
248
+ let unpacked_in_msg = match ctx. input . in_msg ( ) {
249
+ Some ( msg) => msg. make_tuple ( ) ?,
250
+ None => None ,
251
+ } ;
252
+
246
253
// Build VM stack and register info.
247
254
let stack = self . prepare_vm_stack ( ctx. input ) ;
248
255
@@ -262,9 +269,8 @@ impl ExecutorState<'_> {
262
269
. with_storage_fees ( ctx. storage_fee )
263
270
. require_ton_v6 ( )
264
271
. with_unpacked_config ( self . config . unpacked . as_tuple ( ) )
265
- . require_ton_v9 ( )
266
272
. require_ton_v11 ( )
267
- . with_in_message ( ctx . input . in_msg ( ) . map ( |x| & x . root ) ) ? ;
273
+ . with_unpacked_in_msg ( unpacked_in_msg ) ;
268
274
269
275
let libraries = ( msg_libs, state_libs, & self . params . libraries ) ;
270
276
let mut vm = VmState :: builder ( )
@@ -364,16 +370,16 @@ impl ExecutorState<'_> {
364
370
SafeRc :: new ( Stack :: with_items ( match input {
365
371
TransactionInput :: Ordinary ( msg) => {
366
372
tuple ! [
367
- int self . balance. tokens. into_inner ( ) ,
368
- int msg. balance_remaining. tokens. into_inner ( ) ,
373
+ int self . balance. tokens,
374
+ int msg. balance_remaining. tokens,
369
375
cell msg. root. clone( ) ,
370
376
slice msg. body. clone( ) ,
371
377
int if msg. is_external { -1 } else { 0 } ,
372
378
]
373
379
}
374
380
TransactionInput :: TickTock ( ty) => {
375
381
tuple ! [
376
- int self . balance. tokens. into_inner ( ) ,
382
+ int self . balance. tokens,
377
383
int BigInt :: from_bytes_be( Sign :: Plus , self . address. address. as_array( ) ) ,
378
384
int match ty {
379
385
TickTock :: Tick => 0 ,
@@ -386,6 +392,42 @@ impl ExecutorState<'_> {
386
392
}
387
393
}
388
394
395
+ impl ReceivedMessage {
396
+ fn make_tuple ( & self ) -> Result < Option < SafeRc < Tuple > > , everscale_types:: error:: Error > {
397
+ let mut cs = self . root . as_slice ( ) ?;
398
+ if MsgType :: load_from ( & mut cs) ? != MsgType :: Int {
399
+ return Ok ( None ) ;
400
+ }
401
+
402
+ // Get `src` addr range.
403
+ let src_addr_slice = {
404
+ let mut cs = cs;
405
+ // Skip flags.
406
+ cs. skip_first ( 3 , 0 ) ?;
407
+ let mut addr_slice = cs;
408
+ // Read `src`.
409
+ IntAddr :: load_from ( & mut cs) ?;
410
+ addr_slice. skip_last ( cs. size_bits ( ) , cs. size_refs ( ) ) ?;
411
+ addr_slice. range ( )
412
+ } ;
413
+
414
+ let info = IntMsgInfo :: load_from ( & mut cs) ?;
415
+
416
+ let unpacked = UnpackedInMsgSmcInfo {
417
+ bounce : info. bounce ,
418
+ bounced : info. bounced ,
419
+ src_addr : ( src_addr_slice, self . root . clone ( ) ) . into ( ) ,
420
+ fwd_fee : info. fwd_fee ,
421
+ created_lt : info. created_lt ,
422
+ created_at : info. created_at ,
423
+ original_value : info. value . tokens ,
424
+ remaining_value : self . balance_remaining . clone ( ) ,
425
+ state_init : self . init . as_ref ( ) . map ( |init| init. root . clone ( ) ) ,
426
+ } ;
427
+ Ok ( Some ( unpacked. into_tuple ( ) ) )
428
+ }
429
+ }
430
+
389
431
#[ cfg( test) ]
390
432
mod tests {
391
433
use everscale_asm_macros:: tvmasm;
0 commit comments