From 2e35546ee57dc3d5389b4133ac10adc70075b0df Mon Sep 17 00:00:00 2001 From: George Mitenkov Date: Thu, 12 Jun 2025 00:55:37 +0100 Subject: [PATCH 001/260] [vm] Visibility checks refactoring and tests (#16799) Downstreamed-from: 05ee3be7c657dbb23749e77b1c0224ee563fc159 --- .../move/move-vm/runtime/src/interpreter.rs | 146 +++++++----------- .../move-vm/runtime/src/loader/function.rs | 12 +- .../move-vm/runtime/src/loader/modules.rs | 11 +- .../runtime/src/runtime_type_checks.rs | 103 +++++++++++- .../cross_function_call.exp | 10 -- .../cross_function_call.mvir | 31 ---- .../cross_module_call.exp | 46 ++++++ .../cross_module_call.mvir | 106 +++++++++++++ .../cross_module_call_generic.exp | 46 ++++++ .../cross_module_call_generic.mvir | 106 +++++++++++++ .../cross_module_call_native.exp | 19 +++ .../cross_module_call_native.mvir | 24 +++ .../cross_native_function_call.exp | 10 -- .../cross_native_function_call.mvir | 19 --- 14 files changed, 523 insertions(+), 166 deletions(-) delete mode 100644 third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_function_call.exp delete mode 100644 third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_function_call.mvir create mode 100644 third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call.mvir create mode 100644 third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call_generic.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call_generic.mvir create mode 100644 third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call_native.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call_native.mvir delete mode 100644 third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_native_function_call.exp delete mode 100644 third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_native_function_call.mvir diff --git a/third_party/move/move-vm/runtime/src/interpreter.rs b/third_party/move/move-vm/runtime/src/interpreter.rs index 49c7cddb741..951fb02cdf2 100644 --- a/third_party/move/move-vm/runtime/src/interpreter.rs +++ b/third_party/move/move-vm/runtime/src/interpreter.rs @@ -185,7 +185,10 @@ impl InterpreterImpl<'_> { } } - fn load_generic_function( + /// Loads a generic function with instantiated type arguments. Does not perform any checks if + /// the function is callable (i.e., visible to the caller). The visibility check should be done + /// at the call-site. + fn load_generic_function_no_visibility_checks( &mut self, module_storage: &impl ModuleStorage, current_frame: &Frame, @@ -198,15 +201,12 @@ impl InterpreterImpl<'_> { let function = current_frame .build_loaded_function_from_instantiation_and_ty_args(module_storage, idx, ty_args) .map_err(|e| self.set_location(e))?; - - if self.vm_config.paranoid_type_checks { - self.check_friend_or_private_call(¤t_frame.function, &function)?; - } - Ok(function) } - fn load_function( + /// Loads a non-generic function. Does not perform any checks if the function is callable + /// (i.e., visible to the caller). The visibility check should be done at the call-site. + fn load_function_no_visibility_checks( &mut self, module_storage: &impl ModuleStorage, current_frame: &Frame, @@ -215,11 +215,6 @@ impl InterpreterImpl<'_> { let function = current_frame .build_loaded_function_from_handle_and_ty_args(module_storage, fh_idx, vec![]) .map_err(|e| self.set_location(e))?; - - if self.vm_config.paranoid_type_checks { - self.check_friend_or_private_call(¤t_frame.function, &function)?; - } - Ok(function) } @@ -372,11 +367,12 @@ impl InterpreterImpl<'_> { (Rc::clone(&entry.0), Rc::clone(&entry.1)) }, btree_map::Entry::Vacant(entry) => { - let function = Rc::new(self.load_function( - module_storage, - ¤t_frame, - fh_idx, - )?); + let function = + Rc::new(self.load_function_no_visibility_checks( + module_storage, + ¤t_frame, + fh_idx, + )?); let frame_cache = FrameTypeCache::make_rc_for_function(&function); @@ -392,7 +388,7 @@ impl InterpreterImpl<'_> { } } } else { - let function = Rc::::new(self.load_function( + let function = Rc::new(self.load_function_no_visibility_checks( module_storage, ¤t_frame, fh_idx, @@ -401,16 +397,17 @@ impl InterpreterImpl<'_> { (function, frame_cache) }; + RTTCheck::check_call_visibility( + ¤t_frame.function, + &function, + CallType::Regular, + ) + .map_err(|err| set_err_info!(current_frame, err))?; + // Charge gas - let module_id = function.module_id().ok_or_else(|| { - let err = PartialVMError::new_invariant_violation( - "Failed to get native function module id", - ); - set_err_info!(current_frame, err) - })?; gas_meter .charge_call( - module_id, + function.owner_as_module()?.self_id(), function.name(), self.operand_stack .last_n(function.param_tys().len()) @@ -467,13 +464,14 @@ impl InterpreterImpl<'_> { (Rc::clone(&entry.0), Rc::clone(&entry.1)) }, btree_map::Entry::Vacant(entry) => { - let function = - Rc::::new(self.load_generic_function( + let function = Rc::::new( + self.load_generic_function_no_visibility_checks( module_storage, ¤t_frame, gas_meter, idx, - )?); + )?, + ); let frame_cache = FrameTypeCache::make_rc_for_function(&function); @@ -489,28 +487,29 @@ impl InterpreterImpl<'_> { } } } else { - let function = Rc::::new(self.load_generic_function( - module_storage, - ¤t_frame, - gas_meter, - idx, - )?); + let function = Rc::::new( + self.load_generic_function_no_visibility_checks( + module_storage, + ¤t_frame, + gas_meter, + idx, + )?, + ); let frame_cache = FrameTypeCache::make_rc(); (function, frame_cache) }; - let module_id = function - .module_id() - .ok_or_else(|| { - PartialVMError::new_invariant_violation( - "Failed to get native function module id", - ) - }) - .map_err(|e| set_err_info!(current_frame, e))?; + RTTCheck::check_call_visibility( + ¤t_frame.function, + &function, + CallType::Regular, + ) + .map_err(|err| set_err_info!(current_frame, err))?; + // Charge gas gas_meter .charge_call_generic( - module_id, + function.owner_as_module()?.self_id(), function.name(), function .ty_args() @@ -606,6 +605,13 @@ impl InterpreterImpl<'_> { .with_resolved_function(module_storage, |f| Ok(f.clone())) .map_err(|e| set_err_info!(current_frame, e))?; + RTTCheck::check_call_visibility( + ¤t_frame.function, + &callee, + CallType::ClosureDynamicDispatch, + ) + .map_err(|err| set_err_info!(current_frame, err))?; + // Charge gas for call and for the parameters. The current APIs // require an ExactSizeIterator to be passed for charge_call, so // some acrobatics is needed (sigh). @@ -627,10 +633,6 @@ impl InterpreterImpl<'_> { ) .map_err(|e| set_err_info!(current_frame, e))?; - // In difference to regular calls, we skip visibility check. - // It is possible to call a private function of another module via - // a closure. - // Call function if callee.is_native() { self.call_native::( @@ -950,19 +952,11 @@ impl InterpreterImpl<'_> { ty_args, )?; - if target_func.is_friend_or_private() - || target_func.module_id() == function.module_id() - { - return Err(PartialVMError::new(StatusCode::RUNTIME_DISPATCH_ERROR) - .with_message( - "Invoking private or friend function during dispatch".to_string(), - )); - } - - if target_func.is_native() { - return Err(PartialVMError::new(StatusCode::RUNTIME_DISPATCH_ERROR) - .with_message("Invoking native function during dispatch".to_string())); - } + RTTCheck::check_call_visibility( + function, + &target_func, + CallType::NativeDynamicDispatch, + )?; // Checking type of the dispatch target function // @@ -1033,38 +1027,6 @@ impl InterpreterImpl<'_> { } } - /// Make sure only private/friend function can only be invoked by modules under the same address. - fn check_friend_or_private_call( - &self, - caller: &LoadedFunction, - callee: &LoadedFunction, - ) -> VMResult<()> { - if callee.is_friend_or_private() { - match (caller.module_id(), callee.module_id()) { - (Some(caller_id), Some(callee_id)) => { - if caller_id.address() == callee_id.address() { - Ok(()) - } else { - Err(self.set_location(PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR) - .with_message( - format!("Private/Friend function invokation error, caller: {:?}::{:?}, callee: {:?}::{:?}", caller_id, caller.name(), callee_id, callee.name()), - ))) - } - }, - _ => Err(self.set_location( - PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR) - .with_message(format!( - "Private/Friend function invokation error caller: {:?}, callee {:?}", - caller.name(), - callee.name() - )), - )), - } - } else { - Ok(()) - } - } - /// Perform a binary operation to two values at the top of the stack. fn binop(&mut self, f: F) -> PartialVMResult<()> where diff --git a/third_party/move/move-vm/runtime/src/loader/function.rs b/third_party/move/move-vm/runtime/src/loader/function.rs index 7e3952f508c..fc45927f4d2 100644 --- a/third_party/move/move-vm/runtime/src/loader/function.rs +++ b/third_party/move/move-vm/runtime/src/loader/function.rs @@ -374,7 +374,7 @@ impl LoadedFunction { /// Returns true if the loaded function has friend or private visibility. pub fn is_friend_or_private(&self) -> bool { - self.function.is_friend() || self.function.is_private() + self.is_friend() || self.is_private() } /// Returns true if the loaded function has public visibility. @@ -382,6 +382,16 @@ impl LoadedFunction { self.function.is_public() } + /// Returns true if the loaded function has friend visibility. + pub fn is_friend(&self) -> bool { + self.function.is_friend() + } + + /// Returns true if the loaded function has private visibility. + pub fn is_private(&self) -> bool { + self.function.is_private() + } + /// Returns an error if the loaded function is **NOT** an entry function. pub fn is_entry_or_err(&self) -> VMResult<()> { if !self.function.is_entry() { diff --git a/third_party/move/move-vm/runtime/src/loader/modules.rs b/third_party/move/move-vm/runtime/src/loader/modules.rs index 0597fafb5e1..9c74c67ec14 100644 --- a/third_party/move/move-vm/runtime/src/loader/modules.rs +++ b/third_party/move/move-vm/runtime/src/loader/modules.rs @@ -32,7 +32,7 @@ use move_vm_types::loaded_data::{ struct_name_indexing::{StructNameIndex, StructNameIndexMap}, }; use std::{ - collections::{BTreeMap, HashMap}, + collections::{BTreeMap, BTreeSet, HashMap}, fmt::Debug, ops::Deref, sync::Arc, @@ -93,6 +93,10 @@ pub struct Module { // `VecMutBorrow(SignatureIndex)`, the `SignatureIndex` maps to a single `SignatureToken`, and // hence, a single type. pub(crate) single_signature_token_map: BTreeMap, + + // Friends of this module. Needed for re-entrancy visibility checks if lazy loading is enabled. + // Particularly, if a callee has friend visibility, the caller's module must be in this set. + pub(crate) friends: BTreeSet, } #[derive(Clone, Debug)] @@ -153,6 +157,10 @@ impl Module { let _timer = VM_TIMER.timer_with_label("Module::new"); let id = module.self_id(); + let friends = module + .immediate_friends_iter() + .map(|(addr, name)| ModuleId::new(*addr, name.to_owned())) + .collect::>(); let mut structs = vec![]; let mut struct_instantiations = vec![]; @@ -373,6 +381,7 @@ impl Module { function_map, struct_map, single_signature_token_map, + friends, }) } diff --git a/third_party/move/move-vm/runtime/src/runtime_type_checks.rs b/third_party/move/move-vm/runtime/src/runtime_type_checks.rs index 8c4fc1f117a..f2ea8378fdc 100644 --- a/third_party/move/move-vm/runtime/src/runtime_type_checks.rs +++ b/third_party/move/move-vm/runtime/src/runtime_type_checks.rs @@ -1,12 +1,15 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::{frame::Frame, frame_type_cache::FrameTypeCache, interpreter::Stack, LoadedFunction}; +use crate::{ + frame::Frame, frame_type_cache::FrameTypeCache, interpreter::Stack, + reentrancy_checker::CallType, LoadedFunction, +}; use move_binary_format::{errors::*, file_format::Bytecode}; use move_core_types::{ ability::{Ability, AbilitySet}, function::ClosureMask, - vm_status::StatusCode, + vm_status::{sub_status::unknown_invariant_violation::EPARANOID_FAILURE, StatusCode}, }; use move_vm_types::loaded_data::runtime_types::{Type, TypeBuilder}; @@ -32,6 +35,57 @@ pub(crate) trait RuntimeTypeCheck { /// For any other checks are performed externally fn should_perform_checks() -> bool; + + /// Performs a runtime check of the caller is allowed to call the callee for any type of call, + /// including native dynamic dispatch or calling a closure. + fn check_call_visibility( + caller: &LoadedFunction, + callee: &LoadedFunction, + call_type: CallType, + ) -> PartialVMResult<()> { + match call_type { + CallType::Regular => { + // We only need to check cross-contract calls. + if caller.module_id() == callee.module_id() { + return Ok(()); + } + Self::check_cross_module_regular_call_visibility(caller, callee) + }, + CallType::ClosureDynamicDispatch => { + // In difference to regular calls, we skip visibility check. It is possible to call + // a private function of another module via a closure. + Ok(()) + }, + CallType::NativeDynamicDispatch => { + // Dynamic dispatch may fail at runtime and this is ok. Hence, these errors are not + // invariant violations as they cannot be checked at compile- or load-time. + // + // Note: native dispatch cannot call into the same module, otherwise the reentrancy + // check is broken. For more details, see AIP-73: + // https://github.com/aptos-foundation/AIPs/blob/main/aips/aip-73.md + if callee.is_friend_or_private() || callee.module_id() == caller.module_id() { + return Err(PartialVMError::new(StatusCode::RUNTIME_DISPATCH_ERROR) + .with_message( + "Invoking private or friend function during dispatch".to_string(), + )); + } + + if callee.is_native() { + return Err(PartialVMError::new(StatusCode::RUNTIME_DISPATCH_ERROR) + .with_message("Invoking native function during dispatch".to_string())); + } + Ok(()) + }, + } + } + + /// Performs a runtime check of the caller is allowed to call a cross-module callee. Applies + /// only on regular static calls (no dynamic dispatch!), with caller and callee being coming + /// from different modules. + fn check_cross_module_regular_call_visibility( + caller: &LoadedFunction, + callee: &LoadedFunction, + ) -> PartialVMResult<()>; } fn verify_pack<'a>( @@ -173,6 +227,13 @@ impl RuntimeTypeCheck for NoRuntimeTypeCheck { fn should_perform_checks() -> bool { false } + + fn check_cross_module_regular_call_visibility( + _caller: &LoadedFunction, + _callee: &LoadedFunction, + ) -> PartialVMResult<()> { + Ok(()) + } } impl RuntimeTypeCheck for FullRuntimeTypeCheck { @@ -784,4 +845,42 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { fn should_perform_checks() -> bool { true } + + fn check_cross_module_regular_call_visibility( + caller: &LoadedFunction, + callee: &LoadedFunction, + ) -> PartialVMResult<()> { + if callee.is_private() { + let msg = format!( + "Function {}::{} cannot be called because it is private", + callee.module_or_script_id(), + callee.name() + ); + return Err( + PartialVMError::new_invariant_violation(msg).with_sub_status(EPARANOID_FAILURE) + ); + } + + if callee.is_friend() { + let callee_module = callee.owner_as_module().map_err(|err| err.to_partial())?; + if !caller + .module_id() + .is_some_and(|id| callee_module.friends.contains(id)) + { + let msg = format!( + "Function {}::{} cannot be called because it has friend visibility, but {} \ + is not {}'s friend", + callee.module_or_script_id(), + callee.name(), + caller.module_or_script_id(), + callee.module_or_script_id() + ); + return Err( + PartialVMError::new_invariant_violation(msg).with_sub_status(EPARANOID_FAILURE) + ); + } + } + + Ok(()) + } } diff --git a/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_function_call.exp b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_function_call.exp deleted file mode 100644 index 2355ce3a2e2..00000000000 --- a/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_function_call.exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 3 tasks - -task 2 'run'. lines 24-31: -Error: Script execution failed with VMError: { - major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_function_call.mvir b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_function_call.mvir deleted file mode 100644 index 62edd9cfc16..00000000000 --- a/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_function_call.mvir +++ /dev/null @@ -1,31 +0,0 @@ -//# publish -module 0x2.A { - struct C has drop { x: u64 } - - make(): Self.C { - label b0: - return C { x: 0}; - } -} - -//# publish -module 0x3.B { - import 0x2.A; - - public make(): A.C { - let v: A.C; - label b0: - v = A.make(); - - return move(v); - } -} - -//# run --signers 0x1 -import 0x3.B; -import 0x2.A; -main(account: signer) { -label b0: - _ = B.make(); - return; -} diff --git a/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call.exp b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call.exp new file mode 100644 index 00000000000..00f6b1128c4 --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call.exp @@ -0,0 +1,46 @@ +processed 13 tasks + +task 4 'run'. lines 72-72: +Error: Function execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x2::a, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 7 'run'. lines 78-78: +Error: Function execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x2::c, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 8 'run'. lines 80-80: +Error: Function execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x2::c, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 0)], +} + +task 10 'run'. lines 84-90: +Error: Script execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 11 'run'. lines 92-98: +Error: Script execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call.mvir b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call.mvir new file mode 100644 index 00000000000..73757b18a88 --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call.mvir @@ -0,0 +1,106 @@ +//# publish +module 0x2.a { + // Empty module for 0x2::b to link against when declaring as a friend. +} + +//# publish +module 0x2.b { + friend 0x2.a; + + private_function() { + label b0: + return; + } + + public(friend) friend_function() { + label b0: + return; + } + + public public_function() { + label b0: + return; + } +} + +//# publish +module 0x2.a { + import 0x2.b; + + public call_private_function() { + label b0: + b.private_function(); + return; + } + + public call_friend_function() { + label b0: + b.friend_function(); + return; + } + + public call_public_function() { + label b0: + b.public_function(); + return; + } +} + +//# publish +module 0x2.c { + import 0x2.b; + + public call_private_function() { + label b0: + b.private_function(); + return; + } + + public call_friend_function() { + label b0: + b.friend_function(); + return; + } + + public call_public_function() { + label b0: + b.public_function(); + return; + } +} + +//# run 0x2::a::call_private_function + +//# run 0x2::a::call_friend_function + +//# run 0x2::a::call_public_function + +//# run 0x2::c::call_private_function + +//# run 0x2::c::call_friend_function + +//# run 0x2::c::call_public_function + +//# run --signers 0x1 +import 0x2.b; +main(account: signer) { +label b0: + b.private_function(); + return; +} + +//# run --signers 0x1c +import 0x2.b; +main(account: signer) { +label b0: + b.friend_function(); + return; +} + +//# run --signers 0x1 +import 0x2.b; +main(account: signer) { +label b0: + b.public_function(); + return; +} diff --git a/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call_generic.exp b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call_generic.exp new file mode 100644 index 00000000000..00f6b1128c4 --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call_generic.exp @@ -0,0 +1,46 @@ +processed 13 tasks + +task 4 'run'. lines 72-72: +Error: Function execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x2::a, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 7 'run'. lines 78-78: +Error: Function execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x2::c, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 8 'run'. lines 80-80: +Error: Function execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x2::c, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 0)], +} + +task 10 'run'. lines 84-90: +Error: Script execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 11 'run'. lines 92-98: +Error: Script execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call_generic.mvir b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call_generic.mvir new file mode 100644 index 00000000000..7169a6e0df2 --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call_generic.mvir @@ -0,0 +1,106 @@ +//# publish +module 0x2.a { + // Empty module for 0x2::b to link against when declaring as a friend. +} + +//# publish +module 0x2.b { + friend 0x2.a; + + private_function() { + label b0: + return; + } + + public(friend) friend_function() { + label b0: + return; + } + + public public_function() { + label b0: + return; + } +} + +//# publish +module 0x2.a { + import 0x2.b; + + public call_private_function() { + label b0: + b.private_function(); + return; + } + + public call_friend_function() { + label b0: + b.friend_function(); + return; + } + + public call_public_function() { + label b0: + b.public_function(); + return; + } +} + +//# publish +module 0x2.c { + import 0x2.b; + + public call_private_function() { + label b0: + b.private_function(); + return; + } + + public call_friend_function() { + label b0: + b.friend_function(); + return; + } + + public call_public_function() { + label b0: + b.public_function(); + return; + } +} + +//# run 0x2::a::call_private_function + +//# run 0x2::a::call_friend_function + +//# run 0x2::a::call_public_function + +//# run 0x2::c::call_private_function + +//# run 0x2::c::call_friend_function + +//# run 0x2::c::call_public_function + +//# run --signers 0x1 +import 0x2.b; +main(account: signer) { +label b0: + b.private_function(); + return; +} + +//# run --signers 0x1 +import 0x2.b; +main(account: signer) { +label b0: + b.friend_function(); + return; +} + +//# run --signers 0x1 +import 0x2.b; +main(account: signer) { +label b0: + b.public_function(); + return; +} diff --git a/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call_native.exp b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call_native.exp new file mode 100644 index 00000000000..14dffb4ad58 --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call_native.exp @@ -0,0 +1,19 @@ +processed 3 tasks + +task 1 'run'. lines 14-14: +Error: Function execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x2::a, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 2 'run'. lines 16-24: +Error: Script execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 3)], +} diff --git a/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call_native.mvir b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call_native.mvir new file mode 100644 index 00000000000..8103799c0ac --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_call_native.mvir @@ -0,0 +1,24 @@ +//# publish +module 0x2.a { + import 0x1.string; + + public test() { + let b: vector; + label b0: + b = vec_pack_0(); + _ = string.internal_check_utf8(&b); + return; +} +} + +//# run 0x2::a::test + +//# run --signers 0x1 +import 0x1.string; +main(account: signer) { + let b: vector; +label b0: + b = vec_pack_0(); + _ = string.internal_check_utf8(&b); + return; +} diff --git a/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_native_function_call.exp b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_native_function_call.exp deleted file mode 100644 index dc82e72d6ec..00000000000 --- a/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_native_function_call.exp +++ /dev/null @@ -1,10 +0,0 @@ -processed 2 tasks - -task 1 'run'. lines 13-19: -Error: Script execution failed with VMError: { - major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, - sub_status: None, - location: script, - indices: [], - offsets: [], -} diff --git a/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_native_function_call.mvir b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_native_function_call.mvir deleted file mode 100644 index a657f6024d9..00000000000 --- a/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_native_function_call.mvir +++ /dev/null @@ -1,19 +0,0 @@ -//# publish -module 0x2.A { - import 0x1.string; - public test() { - let b: vector; - label b0: - b = vec_pack_0(); - _ = string.internal_check_utf8(&b); - return; - } -} - -//# run --signers 0x1 -import 0x2.A; -main(account: signer) { -label b0: - A.test(); - return; -} From bd5fbf2d64819ec12811a1bed4675f3dd162763f Mon Sep 17 00:00:00 2001 From: Teng Zhang Date: Thu, 12 Jun 2025 05:01:14 +0000 Subject: [PATCH 002/260] [tests][compiler-v2] add tests for enum and function values (#16824) * add unit tests * add e2e test * refactor Downstreamed-from: f44878795b67fbdcf22c16130616374383b5311e --- .../src/tests/enum_upgrade_fv.rs | 197 ++++++++++++++++++ aptos-move/e2e-move-tests/src/tests/mod.rs | 1 + .../tests/ability-check/fv_enum_err.exp | 13 ++ .../tests/ability-check/fv_enum_err.move | 32 +++ .../fv_enum_wrapper_err.exp | 9 + .../fv_enum_wrapper_err.move | 19 ++ .../no-v1-comparison/closures/fv_enum.exp | 1 + .../no-v1-comparison/closures/fv_enum.move | 84 ++++++++ 8 files changed, 356 insertions(+) create mode 100644 aptos-move/e2e-move-tests/src/tests/enum_upgrade_fv.rs create mode 100644 third_party/move/move-compiler-v2/tests/ability-check/fv_enum_err.exp create mode 100644 third_party/move/move-compiler-v2/tests/ability-check/fv_enum_err.move create mode 100644 third_party/move/move-compiler-v2/tests/bytecode-generator/fv_enum_wrapper_err.exp create mode 100644 third_party/move/move-compiler-v2/tests/bytecode-generator/fv_enum_wrapper_err.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/fv_enum.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/fv_enum.move diff --git a/aptos-move/e2e-move-tests/src/tests/enum_upgrade_fv.rs b/aptos-move/e2e-move-tests/src/tests/enum_upgrade_fv.rs new file mode 100644 index 00000000000..bdd8b965fe5 --- /dev/null +++ b/aptos-move/e2e-move-tests/src/tests/enum_upgrade_fv.rs @@ -0,0 +1,197 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Tests for enum type upgrade compatibility + +use crate::{assert_success, assert_vm_status, tests::common, MoveHarness}; +use aptos_framework::BuildOptions; +use aptos_language_e2e_tests::account::Account; +use aptos_package_builder::PackageBuilder; +use aptos_types::{account_address::AccountAddress, transaction::TransactionStatus}; +use move_core_types::vm_status::StatusCode; + +#[test] +fn enum_upgrade() { + let mut h = MoveHarness::new(); + let acc = h.new_account_at(AccountAddress::from_hex_literal("0x815").unwrap()); + + // Initial publish + let result = publish( + &mut h, + &acc, + r#" + module 0x815::m { + enum Data has key { + V1{x: ||T has copy + store } + } + } + "#, + ); + assert_success!(result); + + // incompatible variant + let result = publish( + &mut h, + &acc, + r#" + module 0x815::m { + enum Data has key { + V1 {x: ||T has store} + } + } + "#, + ); + assert_vm_status!(result, StatusCode::BACKWARD_INCOMPATIBLE_MODULE_UPDATE); + + // identical variant + let result = publish( + &mut h, + &acc, + r#" + module 0x815::m { + enum Data has key { + V1 {x: ||T has copy + store + drop} + } + } + "#, + ); + assert_vm_status!(result, StatusCode::BACKWARD_INCOMPATIBLE_MODULE_UPDATE); + + // prepare test for executing function value stored in an enum + let result = publish( + &mut h, + &acc, + r#" + module 0x815::m { + use std::signer; + enum Data has key { + V1 {x: ||T has copy + store} + } + + public fun make_data(f: ||T has copy + drop + store): Data { + Data::V1 {x: f} + } + + public fun store_v1(s: &signer, data: Data) { + move_to(s, data); + } + + public fun retrieve_data_and_execute(s: &signer): T { + let data = borrow_global>(signer::address_of(s)); + (data.x)() + } + + } + + module 0x815::n { + use 0x815::m; + + public fun f(x: u64): u64 { + x + 3 + } + + public entry fun create_store_data(s: &signer) { + let k = 3; + let f: ||u64 has copy + drop + store = || f(k); + m::store_v1(s, m::make_data(f)); + } + + public entry fun execute_stored_data(s: &signer) { + assert!(m::retrieve_data_and_execute(s) == 6, 99); + } + + } + "#, + ); + assert_success!(result); + + assert_success!(h.run_entry_function( + &acc, + str::parse("0x815::n::create_store_data").unwrap(), + vec![], + vec![], + )); + + assert_success!(h.run_entry_function( + &acc, + str::parse("0x815::n::execute_stored_data").unwrap(), + vec![], + vec![], + )); + + // update enum with a new variant + let result = publish( + &mut h, + &acc, + r#" + module 0x815::m { + use std::signer; + enum Data has key { + V1 {x: ||T has copy + store}, + V2 {x1: ||T has copy + drop + store, x: ||T has copy + store} + } + + public fun make_data(f: ||T has copy + drop + store): Data { + Data::V1 {x: f} + } + + public fun make_data_v2(f1: ||T has copy + drop + store, f2: ||T has copy + drop + store): Data { + Data::V2 {x1: f1, x: f2} + } + + public fun store_v1(s: &signer, data: Data) { + move_to(s, data); + } + + public fun retrieve_data_and_execute(s: &signer): T { + let data = borrow_global>(signer::address_of(s)); + (data.x)() + } + + } + + module 0x815::n { + use 0x815::m; + + public fun f(x: u64): u64 { + x + 3 + } + + public entry fun create_store_data(s: &signer) { + let k = 3; + let f: ||u64 has copy + drop + store = || f(k); + m::store_v1(s, m::make_data(f)); + } + + public entry fun execute_stored_data(s: &signer) { + assert!(m::retrieve_data_and_execute(s) == 6, 99); + } + + } + "#, + ); + assert_success!(result); + + // execution still exceeds after enum upgrade + assert_success!(h.run_entry_function( + &acc, + str::parse("0x815::n::execute_stored_data").unwrap(), + vec![], + vec![], + )); +} + +fn publish(h: &mut MoveHarness, account: &Account, source: &str) -> TransactionStatus { + let mut builder = PackageBuilder::new("Package"); + builder.add_source("m.move", source); + builder.add_local_dep( + "MoveStdlib", + &common::framework_dir_path("move-stdlib").to_string_lossy(), + ); + let path = builder.write_to_temp().unwrap(); + h.publish_package_with_options( + account, + path.path(), + BuildOptions::move_2().set_latest_language(), + ) +} diff --git a/aptos-move/e2e-move-tests/src/tests/mod.rs b/aptos-move/e2e-move-tests/src/tests/mod.rs index c432ce73def..87cb8e2f7d5 100644 --- a/aptos-move/e2e-move-tests/src/tests/mod.rs +++ b/aptos-move/e2e-move-tests/src/tests/mod.rs @@ -18,6 +18,7 @@ mod constructor_args; mod cryptoalgebra; mod dependencies; mod enum_upgrade; +mod enum_upgrade_fv; mod enum_variant_count; mod error_map; mod events; diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_enum_err.exp b/third_party/move/move-compiler-v2/tests/ability-check/fv_enum_err.exp new file mode 100644 index 00000000000..b4db6366a2a --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_enum_err.exp @@ -0,0 +1,13 @@ + +Diagnostics: +error: value of type `|&mut u64|u64 has copy + store` does not have the `drop` ability + ┌─ tests/ability-check/fv_enum_err.move:21:17 + │ +21 │ vector::pop_back(&mut v1); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^ implicitly dropped here since it is no longer used + +error: value of type `|&mut u64|u64 has copy + store` does not have the `drop` ability + ┌─ tests/ability-check/fv_enum_err.move:22:17 + │ +22 │ vector::pop_back(&mut v1); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^ implicitly dropped here since it is no longer used diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_enum_err.move b/third_party/move/move-compiler-v2/tests/ability-check/fv_enum_err.move new file mode 100644 index 00000000000..5c030935934 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_enum_err.move @@ -0,0 +1,32 @@ +module 0x66::fv_enum_basic { + use std::signer; + + #[persistent] + fun add_k_persistent_ref(x: &mut u64, k: u64): u64 { *x = *x + 1; *x + k } + + enum FunVec has key { + V1 { v1: vector<|&mut T|T has copy + store> }, + V2 { v0: u64, v1: vector<|&mut T|T has copy + store> }, + } + + fun test_fun_vec(s: &signer) { + use std::vector; + let k = 3; + let add_k: |&mut u64|u64 has copy + store + drop = |x: &mut u64| add_k_persistent_ref(x, k); + let v1 = FunVec::V1 { v1: vector[add_k, add_k] }; + move_to(s, v1); + let m = move_from>(signer::address_of(s)); + match (m) { + FunVec::V1 { v1 } => { + vector::pop_back(&mut v1); + vector::pop_back(&mut v1); + vector::destroy_empty(v1); + } + FunVec::V2 { v0: _, v1 } => { + vector::destroy_empty(v1); + assert!(false, 99); + } + }; + } + +} diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/fv_enum_wrapper_err.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/fv_enum_wrapper_err.exp new file mode 100644 index 00000000000..a53260ecfe8 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/fv_enum_wrapper_err.exp @@ -0,0 +1,9 @@ + +Diagnostics: +error: cannot select field `0` since it has different types in variants of enum `Wrapper` + ┌─ tests/bytecode-generator/fv_enum_wrapper_err.move:10:10 + │ +10 │ (f.0)() + │ ^ + │ + = field `0` has type `||u64 has copy + drop` in variant `B` and type `||u64 has copy` in variant `A` diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/fv_enum_wrapper_err.move b/third_party/move/move-compiler-v2/tests/bytecode-generator/fv_enum_wrapper_err.move new file mode 100644 index 00000000000..ddfb84f3369 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/fv_enum_wrapper_err.move @@ -0,0 +1,19 @@ +module 0x66::fv_enum_wrapper { + + enum Wrapper { + A(||u64 has copy), + B(||u64 has copy + drop), + } + + fun call(f: Wrapper): u64 + { + (f.0)() + } + + public fun test(): u64 + { + let a = Wrapper::A(|| 42); + call(a) + } + +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/fv_enum.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/fv_enum.exp new file mode 100644 index 00000000000..457ace9c4ac --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/fv_enum.exp @@ -0,0 +1 @@ +processed 4 tasks diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/fv_enum.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/fv_enum.move new file mode 100644 index 00000000000..c235583b528 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/fv_enum.move @@ -0,0 +1,84 @@ +//# publish +module 0x66::fv_enum_basic { + use std::signer; + enum Action has drop { + Noop, + Call(|u64|u64), + } + + fun square(x: u64): u64 { x * x } + + fun call_square(x: u64) { + let act = Action::Call(square); + let v = match (act) { + Action::Call(f) => f(x), + _ => 0 + }; + assert!(v == 49); + } + + enum Mapper has key { + Id(|T|R has copy + store), + Twice(Version), + } + + #[persistent] + fun add_k_persistent(x: u64, k: u64): u64 { x + k } + + enum Version has copy,store { + V1 { v1: |T|R has copy + store }, + } + + fun test_enum_in_another_enum(s: &signer) { + let k = 3; + let add_k: |u64|u64 has copy + store = |x: u64| add_k_persistent(x, k); + let v1 = Version::V1 { v1: add_k }; + move_to(s, Mapper::Twice(v1)); + let m = borrow_global>(signer::address_of(s)); + let v = match (m) { + Mapper::Twice(v1) => (v1.v1)((v1.v1)(10)), + Mapper::Id(f) => (*f)(10), + }; + assert!(v == 16, 99); + } + + #[persistent] + fun add_k_persistent_ref(x: &mut u64, k: u64): u64 { *x = *x + 1; *x + k } + + enum FunVec has key { + V1 { v1: vector<|&mut T|T has copy + store> }, + V2 { v0: u64, v1: vector<|&mut T|T has copy + store> }, + } + + fun test_fun_vec(s: &signer) { + use std::vector; + let k = 3; + let add_k: |&mut u64|u64 has copy + store + drop = |x: &mut u64| add_k_persistent_ref(x, k); + let v1 = FunVec::V1 { v1: vector[add_k, add_k] }; + move_to(s, v1); + let m = move_from>(signer::address_of(s)); + match (m) { + FunVec::V1 { v1 } => { + let add = vector::pop_back(&mut v1); + let v = 3; + let x = add(&mut v); + assert!(v == 4, 0); + assert!(x == 7, 1); + vector::push_back(&mut v1, add); + let m = FunVec::V2 { v0: 10, v1 }; + move_to(s, m); + } + FunVec::V2 { v0: _, v1 } => { + vector::destroy_empty(v1); + assert!(false, 2); + } + }; + } + +} + +//# run 0x66::fv_enum_basic::call_square --args 7 + +//# run 0x66::fv_enum_basic::test_enum_in_another_enum --signers 0x66 + +//# run 0x66::fv_enum_basic::test_fun_vec --signers 0x66 From f9370b03340de5e71ea165cb9c03742bf979c169 Mon Sep 17 00:00:00 2001 From: Rati Gelashvili Date: Sat, 14 Jun 2025 15:01:05 -0400 Subject: [PATCH 003/260] BlockSTMv2 PR [4/n]: Revamped combinatorial concurrent testing, cover code cache (#16738) * Revamped concurrent combinatorial testing. new code cache tests * Address comments Downstreamed-from: 96fa267b0271ab6996a8ac896ca227f3b9a11478 --- .../module_storage.rs | 2 +- .../state_view_adapter.rs | 2 +- .../aptos-vm-types/src/module_write_set.rs | 4 + aptos-move/aptos-vm/src/block_executor/mod.rs | 6 +- .../src/move_vm_ext/write_op_converter.rs | 3 +- .../block-executor/src/captured_reads.rs | 27 +- aptos-move/block-executor/src/code_cache.rs | 25 +- aptos-move/block-executor/src/executor.rs | 8 +- .../block-executor/src/limit_processor.rs | 9 +- .../src/proptest_types/baseline.rs | 1198 +++++++++++++---- .../src/proptest_types/bencher.rs | 7 +- .../src/proptest_types/delta_tests.rs | 100 ++ .../src/proptest_types/group_tests.rs | 170 +++ .../src/proptest_types/mock_executor.rs | 1012 ++++++++++++++ .../block-executor/src/proptest_types/mod.rs | 9 +- .../src/proptest_types/module_tests.rs | 164 +++ .../src/proptest_types/resource_tests.rs | 281 ++++ .../src/proptest_types/tests.rs | 726 ---------- .../src/proptest_types/types.rs | 1050 ++++++--------- aptos-move/block-executor/src/task.rs | 4 +- .../src/txn_last_input_output.rs | 9 +- .../block-executor/src/unit_tests/mod.rs | 252 ++-- aptos-move/block-executor/src/view.rs | 57 +- .../move-vm/runtime/src/loader/modules.rs | 38 + 24 files changed, 3322 insertions(+), 1841 deletions(-) create mode 100644 aptos-move/block-executor/src/proptest_types/delta_tests.rs create mode 100644 aptos-move/block-executor/src/proptest_types/group_tests.rs create mode 100644 aptos-move/block-executor/src/proptest_types/mock_executor.rs create mode 100644 aptos-move/block-executor/src/proptest_types/module_tests.rs create mode 100644 aptos-move/block-executor/src/proptest_types/resource_tests.rs delete mode 100644 aptos-move/block-executor/src/proptest_types/tests.rs diff --git a/aptos-move/aptos-vm-types/src/module_and_script_storage/module_storage.rs b/aptos-move/aptos-vm-types/src/module_and_script_storage/module_storage.rs index 39f02b8bcb0..1edce0e4aea 100644 --- a/aptos-move/aptos-vm-types/src/module_and_script_storage/module_storage.rs +++ b/aptos-move/aptos-vm-types/src/module_and_script_storage/module_storage.rs @@ -10,7 +10,7 @@ use move_vm_runtime::ModuleStorage; pub trait AptosModuleStorage: ModuleStorage { /// Returns the state value metadata associated with this module. The error is returned if /// there is a storage error. If the module does not exist, [None] is returned. - fn fetch_state_value_metadata( + fn get_module_state_value_metadata( &self, address: &AccountAddress, module_name: &IdentStr, diff --git a/aptos-move/aptos-vm-types/src/module_and_script_storage/state_view_adapter.rs b/aptos-move/aptos-vm-types/src/module_and_script_storage/state_view_adapter.rs index d439a3f3fad..1da5fc62c2b 100644 --- a/aptos-move/aptos-vm-types/src/module_and_script_storage/state_view_adapter.rs +++ b/aptos-move/aptos-vm-types/src/module_and_script_storage/state_view_adapter.rs @@ -159,7 +159,7 @@ where impl AptosModuleStorage for AptosCodeStorageAdapter<'_, S, E> { - fn fetch_state_value_metadata( + fn get_module_state_value_metadata( &self, address: &AccountAddress, module_name: &IdentStr, diff --git a/aptos-move/aptos-vm-types/src/module_write_set.rs b/aptos-move/aptos-vm-types/src/module_write_set.rs index 06ddf7b2669..47a30fa5f02 100644 --- a/aptos-move/aptos-vm-types/src/module_write_set.rs +++ b/aptos-move/aptos-vm-types/src/module_write_set.rs @@ -32,6 +32,10 @@ impl ModuleWrite { self.id.address() } + pub fn module_id(&self) -> &ModuleId { + &self.id + } + /// Returns the name of the module written. pub fn module_name(&self) -> &IdentStr { self.id.name() diff --git a/aptos-move/aptos-vm/src/block_executor/mod.rs b/aptos-move/aptos-vm/src/block_executor/mod.rs index 285a326f780..c26c7c627c9 100644 --- a/aptos-move/aptos-vm/src/block_executor/mod.rs +++ b/aptos-move/aptos-vm/src/block_executor/mod.rs @@ -195,13 +195,15 @@ impl BlockExecutorTransactionOutput for AptosTransactionOutput { } /// Should never be called after incorporating materialized output, as that consumes vm_output. - fn module_write_set(&self) -> BTreeMap> { + fn module_write_set(&self) -> Vec> { self.vm_output .lock() .as_ref() .expect("Output must be set to get module writes") .module_write_set() - .clone() + .values() + .cloned() + .collect() } /// Should never be called after incorporating materialized output, as that consumes vm_output. diff --git a/aptos-move/aptos-vm/src/move_vm_ext/write_op_converter.rs b/aptos-move/aptos-vm/src/move_vm_ext/write_op_converter.rs index 10cae90336a..55035b7ad8d 100644 --- a/aptos-move/aptos-vm/src/move_vm_ext/write_op_converter.rs +++ b/aptos-move/aptos-vm/src/move_vm_ext/write_op_converter.rs @@ -86,7 +86,8 @@ impl<'r> WriteOpConverter<'r> { let name = module_id.name(); // If state value metadata exists, this is a modification. - let state_value_metadata = module_storage.fetch_state_value_metadata(addr, name)?; + let state_value_metadata = + module_storage.get_module_state_value_metadata(addr, name)?; let op = if state_value_metadata.is_some() { Op::Modify(bytes) } else { diff --git a/aptos-move/block-executor/src/captured_reads.rs b/aptos-move/block-executor/src/captured_reads.rs index 90a5b94e574..346c2eea0ce 100644 --- a/aptos-move/block-executor/src/captured_reads.rs +++ b/aptos-move/block-executor/src/captured_reads.rs @@ -1049,7 +1049,10 @@ mod test { use super::*; use crate::{ code_cache_global::GlobalModuleCache, - proptest_types::types::{raw_metadata, KeyType, MockEvent, ValueType}, + proptest_types::{ + mock_executor::MockEvent, + types::{raw_metadata, KeyType, ValueType}, + }, }; use aptos_mvhashmap::{types::StorageVersion, MVHashMap}; use claims::{ @@ -1632,19 +1635,19 @@ mod test { assert_capture_get!( captured_reads, - KeyType::(10, false), + KeyType::(10), use_tag.then_some(30), legacy_reads ); assert_capture_get!( captured_reads, - KeyType::(11, false), + KeyType::(11), use_tag.then_some(30), deletion_reads ); assert_capture_get!( captured_reads, - KeyType::(15, false), + KeyType::(15), use_tag.then_some(30), with_metadata_reads ); @@ -1654,7 +1657,7 @@ mod test { #[test] fn metadata_for_group_member() { let captured_reads = test_captured_reads!(new); - captured_reads.get_by_kind(&KeyType::(21, false), Some(&10), ReadKind::Metadata); + captured_reads.get_by_kind(&KeyType::(21), Some(&10), ReadKind::Metadata); } macro_rules! assert_incorrect_use { @@ -1689,19 +1692,19 @@ mod test { assert_incorrect_use!( captured_reads, - KeyType::(10, false), + KeyType::(10), use_tag.then_some(30), legacy_reads ); assert_incorrect_use!( captured_reads, - KeyType::(11, false), + KeyType::(11), use_tag.then_some(30), deletion_reads ); assert_incorrect_use!( captured_reads, - KeyType::(15, false), + KeyType::(15), use_tag.then_some(30), with_metadata_reads ); @@ -1710,7 +1713,7 @@ mod test { assert!(!captured_reads.incorrect_use); for i in 0..3 { - let key = KeyType::(20 + i, false); + let key = KeyType::(20 + i); assert_ok!(captured_reads.capture_read( key, use_tag.then_some(30), @@ -1747,7 +1750,7 @@ mod test { assert!(!captured_reads.non_delayed_field_speculative_failure); assert!(!captured_reads.delayed_field_speculative_failure); - let key = KeyType::(20, false); + let key = KeyType::(20); assert_ok!(captured_reads.capture_read(key, use_tag.then_some(30), exists)); assert_err!(captured_reads.capture_read( key, @@ -1762,7 +1765,7 @@ mod test { captured_reads.incorrect_use = false; captured_reads.non_delayed_field_speculative_failure = false; captured_reads.delayed_field_speculative_failure = false; - let key = KeyType::(21, false); + let key = KeyType::(21); assert_ok!(captured_reads.capture_read(key, use_tag.then_some(30), deletion_metadata)); assert_err!(captured_reads.capture_read(key, use_tag.then_some(30), resolved)); assert!(captured_reads.non_delayed_field_speculative_failure); @@ -1776,7 +1779,7 @@ mod test { captured_reads.non_delayed_field_speculative_failure = false; captured_reads.delayed_field_speculative_failure = false; - let key = KeyType::(22, false); + let key = KeyType::(22); assert_ok!(captured_reads.capture_read(key, use_tag.then_some(30), metadata)); assert_err!(captured_reads.capture_read(key, use_tag.then_some(30), versioned_legacy)); assert!(captured_reads.non_delayed_field_speculative_failure); diff --git a/aptos-move/block-executor/src/code_cache.rs b/aptos-move/block-executor/src/code_cache.rs index 746e32f559a..f06d6d56252 100644 --- a/aptos-move/block-executor/src/code_cache.rs +++ b/aptos-move/block-executor/src/code_cache.rs @@ -8,6 +8,8 @@ use crate::{ }; use ambassador::delegate_to_methods; use aptos_mvhashmap::types::TxnIndex; +#[cfg(test)] +use aptos_types::on_chain_config::CurrentTimeMicroseconds; use aptos_types::{ executable::ModulePath, state_store::{state_value::StateValueMetadata, TStateView}, @@ -15,6 +17,8 @@ use aptos_types::{ vm::modules::AptosModuleExtension, }; use aptos_vm_types::module_and_script_storage::module_storage::AptosModuleStorage; +#[cfg(test)] +use fail::fail_point; use move_binary_format::{ errors::{Location, PartialVMResult, VMResult}, file_format::CompiledScript, @@ -182,17 +186,28 @@ impl> ModuleCache for LatestView<'_, } impl> AptosModuleStorage for LatestView<'_, T, S> { - fn fetch_state_value_metadata( + fn get_module_state_value_metadata( &self, address: &AccountAddress, module_name: &IdentStr, ) -> PartialVMResult> { let id = ModuleId::new(*address, module_name.to_owned()); - let state_value_metadata = self + let result = self .get_module_or_build_with(&id, self) - .map_err(|err| err.to_partial())? - .map(|(module, _)| module.extension().state_value_metadata().clone()); - Ok(state_value_metadata) + .map_err(|err| err.to_partial())?; + + // In order to test the module cache with combinatorial tests, we embed the version + // information into the state value metadata (execute_transaction has access via + // AptosModuleStorage trait only). + #[cfg(test)] + fail_point!("module_test", |_| { + Ok(result.clone().map(|(_, version)| { + let v = version.unwrap_or(u32::MAX) as u64; + StateValueMetadata::legacy(v, &CurrentTimeMicroseconds { microseconds: v }) + })) + }); + + Ok(result.map(|(module, _)| module.extension().state_value_metadata().clone())) } } diff --git a/aptos-move/block-executor/src/executor.rs b/aptos-move/block-executor/src/executor.rs index 1df7d8cae39..b1cce66ae43 100644 --- a/aptos-move/block-executor/src/executor.rs +++ b/aptos-move/block-executor/src/executor.rs @@ -670,7 +670,7 @@ where fn publish_module_writes( txn_idx: TxnIndex, - module_write_set: BTreeMap>, + module_write_set: Vec>, global_module_cache: &GlobalModuleCache< ModuleId, CompiledModule, @@ -680,7 +680,7 @@ where versioned_cache: &MVHashMap, runtime_environment: &RuntimeEnvironment, ) -> Result<(), PanicError> { - for (_, write) in module_write_set { + for write in module_write_set { Self::add_module_write_to_module_cache( write, txn_idx, @@ -1219,7 +1219,6 @@ where })?; let extension = Arc::new(AptosModuleExtension::new(state_value)); - global_module_cache.mark_overridden(&id); per_block_module_cache .insert_deserialized_module(id.clone(), compiled_module, extension, Some(txn_idx)) .map_err(|err| { @@ -1232,6 +1231,7 @@ where ); PanicError::CodeInvariantError(msg) })?; + global_module_cache.mark_overridden(&id); Ok(()) } @@ -1263,7 +1263,7 @@ where unsync_map.write(key, Arc::new(write_op), None); } - for (_, write) in output.module_write_set().into_iter() { + for write in output.module_write_set().into_iter() { Self::add_module_write_to_module_cache( write, txn_idx, diff --git a/aptos-move/block-executor/src/limit_processor.rs b/aptos-move/block-executor/src/limit_processor.rs index b65d474d096..9ff837ed48d 100644 --- a/aptos-move/block-executor/src/limit_processor.rs +++ b/aptos-move/block-executor/src/limit_processor.rs @@ -306,7 +306,10 @@ impl<'s, T: Transaction, S: TStateView> BlockGasLimitProcessor<'s, mod test { use super::*; use crate::{ - proptest_types::types::{KeyType, MockEvent, MockTransaction}, + proptest_types::{ + mock_executor::MockEvent, + types::{KeyType, MockTransaction}, + }, types::InputOutputKey, }; use aptos_types::state_store::{ @@ -413,8 +416,8 @@ mod test { reads .iter() .map(|key| match key { - InputOutputKey::Resource(k) => InputOutputKey::Resource(KeyType(*k, false)), - InputOutputKey::Group(k, t) => InputOutputKey::Group(KeyType(*k, false), *t), + InputOutputKey::Resource(k) => InputOutputKey::Resource(KeyType(*k)), + InputOutputKey::Group(k, t) => InputOutputKey::Group(KeyType(*k), *t), InputOutputKey::DelayedField(i) => InputOutputKey::DelayedField(*i), }) .collect() diff --git a/aptos-move/block-executor/src/proptest_types/baseline.rs b/aptos-move/block-executor/src/proptest_types/baseline.rs index 890f8b9ad0a..cec80f15f7f 100644 --- a/aptos-move/block-executor/src/proptest_types/baseline.rs +++ b/aptos-move/block-executor/src/proptest_types/baseline.rs @@ -2,70 +2,75 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -/// This file implements the baseline evaluation, performed sequentially, the output -/// of which is used to test the results of the block executor. The baseline must be -/// evaluated after the block executor has completed, as the transaction type used -/// for testing tracks the incarnation number, which is used to emulate dynamic behavior. -/// Dynamic behavior means that when a transaction is re-executed, it might read -/// different values and end up with a completely different behavior (be it read set, -/// write set, or executed code). In the tests, behavior changes based on the incarnation -/// number, and hence it is crucial for the baseline to know the final incarnation number -/// of each transaction of the tested block executor execution. use crate::{ errors::{BlockExecutionError, BlockExecutionResult}, - proptest_types::types::{ - raw_metadata, GroupSizeOrMetadata, MockOutput, MockTransaction, ValueType, RESERVED_TAG, - STORAGE_AGGREGATOR_VALUE, + proptest_types::{ + mock_executor::MockOutput, + types::{ + default_group_map, deserialize_to_delayed_field_id, deserialize_to_delayed_field_u128, + raw_metadata, serialize_from_delayed_field_u128, DeltaTestKind, GroupSizeOrMetadata, + MockIncarnation, MockTransaction, ValueType, RESERVED_TAG, STORAGE_AGGREGATOR_VALUE, + }, }, }; -use aptos_aggregator::delta_change_set::serialize; +use aptos_aggregator::delta_change_set::{serialize, DeltaOp}; +use aptos_mvhashmap::types::TxnIndex; use aptos_types::{ contract_event::TransactionEvent, state_store::state_value::StateValueMetadata, transaction::BlockOutput, write_set::TransactionWrite, }; -use aptos_vm_types::resource_group_adapter::group_size_as_sum; +use aptos_vm_types::{ + module_write_set::ModuleWrite, resolver::ResourceGroupSize, + resource_group_adapter::group_size_as_sum, +}; use bytes::Bytes; -use claims::{assert_matches, assert_none, assert_some, assert_some_eq}; -use itertools::izip; -use std::{collections::HashMap, fmt::Debug, hash::Hash, result::Result, sync::atomic::Ordering}; +use claims::{assert_gt, assert_matches, assert_none, assert_some, assert_some_eq}; +use move_core_types::language_storage::ModuleId; +use move_vm_types::delayed_values::delayed_field_id::DelayedFieldID; +use std::{ + cell::RefCell, + collections::{BTreeMap, HashMap}, + fmt::Debug, + hash::Hash, + result::Result, + sync::atomic::Ordering, +}; + +/// This file implements the baseline evaluation, performed sequentially, the output +/// of which is used to test the results of the block executor. The baseline must be +/// evaluated after the block executor has completed, as the transaction type used +/// for testing tracks the incarnation number, which is used to emulate dynamic behavior. +/// Dynamic behavior means that when a transaction is re-executed, it might read +/// different values and end up with a completely different behavior (be it read set, +/// write set, or executed code). In the tests, behavior changes based on the incarnation +/// number, and hence it is crucial for the baseline to know the final incarnation number +/// of each transaction of the tested block executor execution. +/// +/// The BaselineOutputBuilder is used to build the BaselineOutput. One difference between +/// resources and groups is that the resources are processed while building BaselineOutput, +/// while groups are processed while asserting the output. We may want to reconsider this +/// in the future, but for now it provides two different ways of testing similar invariants, +/// such as the handling of delayed fields and their IDs / values. +/// +/// TODO: Not yet tested or supported cases in the testing framework: +/// - Delayed field deletions. +/// - Writes & delta for the same resource. +/// - Multiple delta applications, including failures. +/// - Empty groups and group deletions. +/// - Gas limit with sequential execution. -// TODO: extend to derived values, and code. #[derive(Clone)] enum BaselineValue { GenericWrite(ValueType), Aggregator(u128), - Empty, -} - -// TODO: instead of the same Error on aggregator overflow / underflow, add a way to tell -// from the error and test it. -// enum AggregatorError { -// Overflow, -// Underflow, -// } - -impl BaselineValue { - // Compare to the read results during block execution. - pub(crate) fn assert_read_result(&self, bytes_read: &Option>) { - match (self, bytes_read) { - (BaselineValue::GenericWrite(v), Some(bytes)) => { - assert_some_eq!(v.extract_raw_bytes(), *bytes); - }, - (BaselineValue::GenericWrite(v), None) => { - assert_none!(v.extract_raw_bytes()); - }, - (BaselineValue::Aggregator(aggr_value), Some(bytes)) => { - assert_eq!(serialize(aggr_value), *bytes); - }, - (BaselineValue::Aggregator(_), None) => unreachable!( - "Deleted or non-existent value from storage can't match aggregator value" - ), - (BaselineValue::Empty, Some(bytes)) => { - assert_eq!(serialize(&STORAGE_AGGREGATOR_VALUE), *bytes); - }, - (BaselineValue::Empty, None) => (), - } - } + // Expected value and expected version of the delayed field. + DelayedField(u128, u32), + // If true, then baseline value (when non-empty), includes txn_idx + // serialized after STORAGE_AGGREGATOR_VALUE. This is used to test + // the delayed fields, as unlike AggregatorV1, the delayed fields + // exist within a larger resource, and the writer's index (for storage + // version max u32) is stored for testing in the same mock resource. + Empty(DeltaTestKind), } // The status of the baseline execution. @@ -77,6 +82,50 @@ enum BaselineStatus { GasLimitExceeded, } +// TODO: Update the GroupReadInfo struct to always set baseline value +// and simplify the comparison logic. +#[derive(Debug)] +struct GroupReadInfo { + group_key: K, + baseline_bytes: Option, + // Set when delayed field is contained. + maybe_delayed_field: Option<(u128, u32)>, +} + +impl GroupReadInfo { + // Compute group read results from group_reads and group_world + fn compute_from_group_reads( + group_reads: &Result, ()>, + group_world: &mut HashMap>, + ) -> Vec> { + group_reads + .as_ref() + .unwrap() + .iter() + .map(|(group_key, resource_tag, has_delayed_field)| { + if *has_delayed_field { + // Currently delayed fields are tested only with RESERVED_TAG. + assert_eq!(*resource_tag, RESERVED_TAG); + } + + let group = group_world + .entry(group_key.clone()) + .or_insert_with(default_group_map); + let baseline_bytes = group.get(resource_tag).cloned(); + let maybe_delayed_field = has_delayed_field.then(|| { + deserialize_to_delayed_field_u128(baseline_bytes.as_ref().unwrap()).unwrap() + }); + + GroupReadInfo { + group_key: group_key.clone(), + baseline_bytes, + maybe_delayed_field, + } + }) + .collect() + } +} + /// Sequential baseline of execution result for dummy transaction, containing a vector /// of BaselineValues for the reads of the (latest incarnation of the dummy) transaction. /// The size of the vector should be equal to the size of the block if the block execution @@ -86,11 +135,392 @@ enum BaselineStatus { /// /// For both read_values and resolved_deltas the keys are not included because they are /// in the same order as the reads and deltas in the Transaction::Write. -pub(crate) struct BaselineOutput { +pub(crate) struct BaselineOutput { + status: BaselineStatus, + read_values: Vec, ()>>, + resolved_deltas: Vec, ()>>, + group_reads: Vec, ()>>, + group_deltas: Vec, ()>>, + module_reads: Vec>, ()>>, + delayed_field_key_to_id_map: RefCell>, +} + +/// Builder for BaselineOutput to simplify construction +pub(crate) struct BaselineOutputBuilder { status: BaselineStatus, - read_values: Vec, ()>>, + read_values: Vec, ()>>, resolved_deltas: Vec, ()>>, - group_reads: Vec, ()>>, + group_reads: Vec, ()>>, + group_deltas: Vec, ()>>, + module_reads: Vec>, ()>>, + current_world: HashMap, + module_world: HashMap, + txn_read_write_resolved_deltas: HashMap, +} + +impl BaselineOutputBuilder { + /// Create a new builder + pub(crate) fn new() -> Self { + Self { + status: BaselineStatus::Success, + read_values: vec![], + resolved_deltas: vec![], + group_reads: vec![], + group_deltas: vec![], + module_reads: vec![], + current_world: HashMap::new(), + module_world: HashMap::new(), + txn_read_write_resolved_deltas: HashMap::new(), + } + } + + /// Build the final BaselineOutput + pub(crate) fn build(self) -> BaselineOutput { + BaselineOutput { + status: self.status, + read_values: self.read_values, + resolved_deltas: self.resolved_deltas, + group_reads: self.group_reads, + group_deltas: self.group_deltas, + module_reads: self.module_reads, + delayed_field_key_to_id_map: RefCell::new(HashMap::new()), + } + } + + /// Set the execution status + fn with_status(&mut self, status: BaselineStatus) -> &mut Self { + self.status = status; + self + } + + /// Add an empty successful transaction (for SkipRest) + fn with_empty_successful_transaction(&mut self) -> &mut Self { + self.read_values.push(Ok(vec![])); + self.resolved_deltas.push(Ok(HashMap::new())); + self + } + + /// Mark the transaction as failed by pushing errors to all result vectors + fn with_transaction_failed(&mut self) -> &mut Self { + self.read_values.push(Err(())); + self.resolved_deltas.push(Err(())); + self.group_reads.push(Err(())); + self.group_deltas.push(Err(())); + self.module_reads.push(Err(())); + self + } + + fn with_group_deltas(&mut self, deltas: Vec<(K, DeltaOp)>) -> &mut Self { + self.group_deltas.push(Ok(deltas)); + self + } + + fn with_module_reads(&mut self, module_ids: &[ModuleId]) -> &mut Self { + let result = Ok(module_ids + .iter() + .map(|module_id| self.module_world.get(module_id).cloned()) + .collect()); + self.module_reads.push(result); + self + } + + fn with_resource_reads( + &mut self, + reads: &[(K, bool)], + delta_test_kind: DeltaTestKind, + ) -> &mut Self { + let base_value = BaselineValue::Empty(delta_test_kind); + + let result = Ok(reads + .iter() + .map(|(k, has_deltas)| { + let baseline_value = self + .current_world + .entry(k.clone()) + .or_insert(base_value.clone()); + + let value = if delta_test_kind == DeltaTestKind::DelayedFields && *has_deltas { + match baseline_value { + BaselineValue::DelayedField(v, _) => { + self.txn_read_write_resolved_deltas.insert(k.clone(), *v); + baseline_value.clone() + }, + BaselineValue::Empty(delta_test_kind) => { + assert_eq!(*delta_test_kind, DeltaTestKind::DelayedFields); + self.txn_read_write_resolved_deltas + .insert(k.clone(), STORAGE_AGGREGATOR_VALUE); + BaselineValue::DelayedField(STORAGE_AGGREGATOR_VALUE, u32::MAX) + }, + BaselineValue::GenericWrite(_) => { + unreachable!("Delayed field testing should not have generic writes") + }, + BaselineValue::Aggregator(_) => { + unreachable!("Delayed field testing should not have aggregators") + }, + } + } else { + baseline_value.clone() + }; + (k.clone(), value) + }) + .collect()); + + self.read_values.push(result); + self + } + + fn with_resource_deltas( + &mut self, + resolved_deltas: Vec<(K, u128, Option)>, + delta_test_kind: DeltaTestKind, + ) -> &mut Self { + let mut result: HashMap = resolved_deltas + .into_iter() + .map(|(k, v, delayed_field_last_write_version)| { + match delta_test_kind { + DeltaTestKind::DelayedFields => { + self.current_world.insert( + k.clone(), + BaselineValue::DelayedField( + v, + delayed_field_last_write_version + .expect("Must be set by delta pre-processing"), + ), + ); + }, + DeltaTestKind::AggregatorV1 => { + // In this case transaction did not fail due to delta application + // errors, and thus we should update written_ and resolved_ worlds. + self.current_world + .insert(k.clone(), BaselineValue::Aggregator(v)); + }, + DeltaTestKind::None => { + unreachable!("None delta test kind should not be used for resource deltas"); + }, + } + (k, v) + }) + .collect(); + + for (k, v) in std::mem::take(&mut self.txn_read_write_resolved_deltas) { + result.entry(k).or_insert(v); + } + + self.resolved_deltas.push(Ok(result)); + self + } + + fn with_group_reads( + &mut self, + group_reads: &[(K, u32, bool)], + delta_test_kind: DeltaTestKind, + ) -> &mut Self { + let result = Ok(group_reads + .iter() + .map(|(k, tag, has_delayed_field)| { + if *has_delayed_field { + assert_eq!(*tag, RESERVED_TAG); + assert_eq!(delta_test_kind, DeltaTestKind::DelayedFields); + } + + (k.clone(), *tag, *has_delayed_field) + }) + .collect()); + self.group_reads.push(result); + self + } + + fn with_module_writes( + &mut self, + module_writes: &[ModuleWrite], + txn_idx: TxnIndex, + ) -> &mut Self { + for module_write in module_writes { + self.module_world + .insert(module_write.module_id().clone(), txn_idx); + } + self + } + + fn with_resource_writes( + &mut self, + writes: &[(K, ValueType, bool)], + delta_test_kind: DeltaTestKind, + txn_idx: usize, + ) -> &mut Self { + for (k, v, has_delta) in writes { + // Here we don't know IDs but we know values, so use the GenericWrite to store the + // expected value, and compare that against the actual read on delayed field that was + // performed during committed execution. + self.current_world.insert( + k.clone(), + if delta_test_kind == DeltaTestKind::DelayedFields && *has_delta { + BaselineValue::DelayedField( + match self.current_world.get(k) { + Some(BaselineValue::DelayedField(value, _)) => { + self.txn_read_write_resolved_deltas + .insert(k.clone(), *value); + *value + }, + Some(BaselineValue::GenericWrite(_)) => { + unreachable!("Delayed field testing should not have generic writes") + }, + Some(BaselineValue::Aggregator(_)) => { + unreachable!("Delayed field testing should not have aggregators") + }, + None | Some(BaselineValue::Empty(_)) => { + self.txn_read_write_resolved_deltas + .insert(k.clone(), STORAGE_AGGREGATOR_VALUE); + STORAGE_AGGREGATOR_VALUE + }, + }, + txn_idx as u32, + ) + } else { + BaselineValue::GenericWrite(v.clone()) + }, + ); + } + self + } + + /// Process a single delta and return the appropriate result. + /// + /// Returns an optional resource delta, if None, the caller should + /// mark the transaction as failed. + fn process_delta( + &mut self, + key: &K, + delta: &DeltaOp, + delta_test_kind: DeltaTestKind, + ) -> Option<(K, u128, Option)> { + let base_value = BaselineValue::Empty(delta_test_kind); + + // Delayed field last write version is used for delayed field testing only, making + // sure the writer index in the read results are compared against the correct write. + let (base, delayed_field_last_write_version) = + match self.current_world.entry(key.clone()).or_insert(base_value) { + BaselineValue::DelayedField(value, last_write_version) => { + (*value, Some(*last_write_version)) + }, + // Get base value from the latest write. + BaselineValue::GenericWrite(w_value) => { + if delta_test_kind == DeltaTestKind::DelayedFields { + let (value, last_write_version) = deserialize_to_delayed_field_u128( + &w_value + .extract_raw_bytes() + .expect("Deleted delayed fields not supported"), + ) + .expect("Must deserialize the delayed field base value"); + (value, Some(last_write_version)) + } else { + ( + w_value + .as_u128() + .expect("Delta to a non-existent aggregator") + .expect("Must deserialize the aggregator base value"), + None, + ) + } + }, + // Get base value from latest resolved aggregator value. + BaselineValue::Aggregator(value) => (*value, None), + // Storage always gets resolved to a default constant. + BaselineValue::Empty(delta_test_kind) => ( + STORAGE_AGGREGATOR_VALUE, + (*delta_test_kind == DeltaTestKind::DelayedFields).then_some(u32::MAX), + ), + }; + + match delta.apply_to(base) { + Err(_) => { + // Transaction does not take effect and we record delta application failure. + None + }, + Ok(resolved_value) => { + // Transaction succeeded, return the resolved delta + Some(( + key.clone(), + resolved_value, + delayed_field_last_write_version, + )) + }, + } + } + + /// Process all deltas for a transaction and handle failures internally + /// + /// Returns (success, group_deltas, resource_deltas) + /// If success is false, the transaction failed and the deltas should not be used + fn process_transaction_deltas( + &mut self, + deltas: &[(K, DeltaOp, Option)], + delta_test_kind: DeltaTestKind, + ) -> (bool, Vec<(K, DeltaOp)>, Vec<(K, u128, Option)>) { + let mut group_deltas = Vec::new(); + let mut resource_deltas = Vec::new(); + + for (k, delta, maybe_tag) in deltas { + if let Some(tag) = maybe_tag { + assert_eq!(*tag, RESERVED_TAG); + // This is a group delta + group_deltas.push((k.clone(), *delta)); + } else { + match self.process_delta(k, delta, delta_test_kind) { + Some(rd) => resource_deltas.push(rd), + None => { + self.with_transaction_failed(); + return (false, Vec::new(), Vec::new()); + }, + } + } + } + + (true, group_deltas, resource_deltas) + } + + /// Process a complete transaction + /// + /// Returns whether the gas limit was exceeded + fn process_transaction( + &mut self, + behavior: &MockIncarnation, + delta_test_kind: DeltaTestKind, + txn_idx: usize, + accumulated_gas: &mut u64, + maybe_block_gas_limit: Option, + ) -> bool { + // Process all deltas first + let (success, group_deltas, resource_deltas) = + self.process_transaction_deltas(&behavior.deltas, delta_test_kind); + + if !success { + return false; // Gas limit not exceeded, transaction failed + } + + // All remaining operations can be chained since the transaction is known to succeed + self.with_resource_reads(&behavior.resource_reads, delta_test_kind) + .with_module_reads(&behavior.module_reads) + .with_group_reads(&behavior.group_reads, delta_test_kind) + .with_group_deltas(group_deltas) + .with_resource_writes(&behavior.resource_writes, delta_test_kind, txn_idx) + .with_resource_deltas(resource_deltas, delta_test_kind) + .with_module_writes(&behavior.module_writes, txn_idx as TxnIndex); + + // Apply gas + *accumulated_gas += behavior.gas; + + // Check if gas limit exceeded + let gas_limit_exceeded = maybe_block_gas_limit + .map(|limit| *accumulated_gas >= limit) + .unwrap_or(false); + + if gas_limit_exceeded { + self.with_status(BaselineStatus::GasLimitExceeded); + } + + gas_limit_exceeded + } } impl BaselineOutput { @@ -100,285 +530,497 @@ impl BaselineOutput { txns: &[MockTransaction], maybe_block_gas_limit: Option, ) -> Self { - let mut current_world = HashMap::::new(); + let mut builder = BaselineOutputBuilder::new(); let mut accumulated_gas = 0; - let mut status = BaselineStatus::Success; - let mut read_values = vec![]; - let mut resolved_deltas = vec![]; - let mut group_reads = vec![]; - - for txn in txns.iter() { + for (txn_idx, txn) in txns.iter().enumerate() { match txn { MockTransaction::Abort => { - status = BaselineStatus::Aborted; + builder.with_status(BaselineStatus::Aborted); break; }, MockTransaction::SkipRest(gas) => { // In executor, SkipRest skips from the next index. Test assumes it's an empty // transaction, so create a successful empty reads and deltas. - read_values.push(Ok(vec![])); - resolved_deltas.push(Ok(HashMap::new())); + builder.with_empty_successful_transaction(); // gas in SkipRest is used for unit tests for now (can generalize when needed). assert_eq!(*gas, 0); - status = BaselineStatus::SkipRest; + builder.with_status(BaselineStatus::SkipRest); break; }, MockTransaction::Write { incarnation_counter, incarnation_behaviors, + delta_test_kind, } => { // Determine the behavior of the latest incarnation of the transaction. The index // is based on the value of the incarnation counter prior to the fetch_add during // the last mock execution, and is >= 1 because there is at least one execution. - let last_incarnation = (incarnation_counter.load(Ordering::SeqCst) - 1) - % incarnation_behaviors.len(); - - match incarnation_behaviors[last_incarnation] - .deltas - .iter() - .map(|(k, delta)| { - let base = match current_world - .entry(k.clone()) - .or_insert(BaselineValue::Empty) - { - // Get base value from the latest write. - BaselineValue::GenericWrite(w_value) => w_value - .as_u128() - .expect("Delta to a non-existent aggregator") - .expect("Must deserialize the aggregator base value"), - // Get base value from latest resolved aggregator value. - BaselineValue::Aggregator(value) => *value, - // Storage always gets resolved to a default constant. - BaselineValue::Empty => STORAGE_AGGREGATOR_VALUE, - }; - - delta - .apply_to(base) - .map(|resolved_value| (k.clone(), resolved_value)) - }) - .collect::, _>>() - { - Ok(txn_resolved_deltas) => { - // Update the read_values and resolved_deltas. Performing reads here is - // correct because written_ and resolved_ worlds have not been updated. - read_values.push(Ok(incarnation_behaviors[last_incarnation] - .reads - .iter() - .map(|k| { - current_world - .entry(k.clone()) - .or_insert(BaselineValue::Empty) - .clone() - }) - .collect())); - - resolved_deltas.push(Ok(txn_resolved_deltas - .into_iter() - .map(|(k, v)| { - // In this case transaction did not fail due to delta application - // errors, and thus we should update written_ and resolved_ worlds. - current_world.insert(k.clone(), BaselineValue::Aggregator(v)); - (k, v) - }) - .collect())); - - // We ensure that the latest state is always reflected in exactly one of - // the hashmaps, by possibly removing an element from the other Hashmap. - for (k, v) in incarnation_behaviors[last_incarnation].writes.iter() { - current_world - .insert(k.clone(), BaselineValue::GenericWrite(v.clone())); - } - - group_reads.push(Ok(incarnation_behaviors[last_incarnation] - .group_reads - .clone())); - - // Apply gas. - accumulated_gas += incarnation_behaviors[last_incarnation].gas; - if let Some(block_gas_limit) = maybe_block_gas_limit { - if accumulated_gas >= block_gas_limit { - status = BaselineStatus::GasLimitExceeded; - break; - } - } - }, - Err(_) => { - // Transaction does not take effect and we record delta application failure. - read_values.push(Err(())); - resolved_deltas.push(Err(())); - group_reads.push(Err(())); - }, + let incarnation_counter = incarnation_counter.load(Ordering::SeqCst); + // Mock execute_transaction call always increments the incarnation counter. + assert_gt!( + incarnation_counter, + 0, + "Mock execution of txn {txn_idx} never incremented incarnation" + ); + let last_incarnation = (incarnation_counter - 1) % incarnation_behaviors.len(); + + // Process the transaction + let gas_limit_exceeded = builder.process_transaction( + &incarnation_behaviors[last_incarnation], + *delta_test_kind, + txn_idx, + &mut accumulated_gas, + maybe_block_gas_limit, + ); + + // Break if gas limit exceeded + if gas_limit_exceeded { + break; } }, MockTransaction::InterruptRequested => unreachable!("Not tested with outputs"), } } - Self { - status, - read_values, - resolved_deltas, - group_reads, - } + // Initialize with empty delayed_field_key_to_id_map + let mut result = builder.build(); + result.delayed_field_key_to_id_map = RefCell::new(HashMap::new()); + result + } + + // Helper method to insert and validate delayed field IDs + fn insert_or_verify_delayed_field_id(&self, key: K, id: DelayedFieldID) { + let mut map = self.delayed_field_key_to_id_map.borrow_mut(); + assert!( + map.insert(key, id) + .map_or(true, |existing_id| existing_id == id), + "Inconsistent delayed field ID mapping" + ); + } + + // Verify the delayed field by checking ID, version, and value + fn verify_delayed_field( + &self, + bytes: &[u8], + baseline_key: &K, + expected_version: u32, + expected_value: u128, + delayed_field_reads: &mut impl Iterator, + ) { + // Deserialize the ID and version from bytes + let (id, version) = + deserialize_to_delayed_field_id(bytes).expect("Must deserialize delayed field tuple"); + + // Verify the version matches + assert_eq!( + expected_version, version, + "Version mismatch for delayed field" + ); + + // Get the corresponding delayed field read + let (delayed_id, value, key) = delayed_field_reads + .next() + .expect("Must have a delayed field read"); + + // Verify the ID, key, and value match + assert_eq!(id, delayed_id, "Delayed field ID mismatch"); + assert_eq!(*baseline_key, key, "Delayed field key mismatch"); + assert_eq!(expected_value, value, "Value mismatch for delayed field"); + + // Add ID to key map and assert consistency if already present + self.insert_or_verify_delayed_field_id(baseline_key.clone(), id); } fn assert_success(&self, block_output: &BlockOutput>) { - let base_map: HashMap = HashMap::from([(RESERVED_TAG, vec![0].into())]); let mut group_world = HashMap::new(); let mut group_metadata: HashMap> = HashMap::new(); - let results = block_output.get_transaction_outputs_forced(); - let committed = self.read_values.len(); - assert_eq!(self.resolved_deltas.len(), committed); - - // Check read values & delta writes. - izip!( - (0..committed), - results.iter().take(committed), - self.read_values.iter(), - self.resolved_deltas.iter(), - self.group_reads.iter(), - ) - .for_each(|(idx, output, reads, resolved_deltas, group_reads)| { - // Compute group read results. - let group_read_results: Vec> = group_reads - .as_ref() - .unwrap() - .iter() - .map(|(group_key, resource_tag)| { - let group_map = group_world.entry(group_key).or_insert(base_map.clone()); + let txn_outputs = block_output.get_transaction_outputs_forced(); - group_map.get(resource_tag).cloned() - }) - .collect(); - // Test group read results. - let read_len = reads.as_ref().unwrap().len(); + // Calculate the minimum number of valid iterations across all collections + let valid_txn_count = [ + txn_outputs.len(), + self.read_values.len(), + self.resolved_deltas.len(), + self.group_reads.len(), + self.group_deltas.len(), + self.module_reads.len(), + ] + .iter() + .min() + .copied() + .unwrap_or(0); - assert_eq!( - group_read_results.len(), - output.read_results.len() - read_len + // Process transactions up to the minimum valid count + for (txn_idx, txn_output) in txn_outputs.iter().enumerate().take(valid_txn_count) { + // Verify transaction wasn't skipped + assert!( + !txn_output.skipped, + "Error at txn {}: {:?}", + txn_idx, txn_output.maybe_error_msg ); - izip!( - output.read_results.iter().skip(read_len), - group_read_results.into_iter() - ) - .for_each(|(result_group_read, baseline_group_read)| { - assert!(result_group_read.clone().map(Into::::into) == baseline_group_read); - }); - for (group_key, size_or_metadata) in output.read_group_size_or_metadata.iter() { - let group_map = group_world.entry(group_key).or_insert(base_map.clone()); + // Compute group read information directly + let group_read_infos = GroupReadInfo::compute_from_group_reads( + &self.group_reads[txn_idx], + &mut group_world, + ); + + // Process resource and group read results and delayed field reads + let mut delayed_field_reads = txn_output.delayed_field_reads.clone().into_iter(); + let read_len = self.read_values[txn_idx].as_ref().unwrap().len(); + self.verify_resource_reads( + &self.read_values[txn_idx], + &txn_output.read_results[..read_len], + &mut delayed_field_reads, + ); + self.verify_group_reads( + &group_read_infos, + &txn_output.read_results[read_len..], + &mut delayed_field_reads, + ); + // Ensure all delayed field reads have been processed + assert_none!(delayed_field_reads.next()); - match size_or_metadata { - GroupSizeOrMetadata::Size(size) => { - let baseline_size = - group_size_as_sum(group_map.iter().map(|(t, v)| (t, v.len()))) - .unwrap() - .get(); + self.verify_module_reads( + &self.module_reads[txn_idx], + &txn_output.module_read_results, + txn_idx, + ); + self.verify_group_size_metadata(txn_output, &mut group_world, &group_metadata); + + // Process writes and deltas and update the group world. + self.process_group_writes(txn_output, &mut group_world, &mut group_metadata, txn_idx); + + let group_deltas = self.group_deltas[txn_idx].as_ref().unwrap(); + self.process_group_deltas(group_deltas, &mut group_world); + self.verify_groups_patched_write_set(txn_output, &group_world, group_deltas); + self.verify_materialized_deltas(txn_output, &self.resolved_deltas[txn_idx]); + } + // Check that remaining transactions are properly marked as skipped. + let mut write_summary_flag = true; + for txn_output in txn_outputs.iter().skip(valid_txn_count) { + // Ensure the transaction is skipped based on the output + assert!(txn_output.skipped); + + // materialized delta writes is only set by a callback for + // committed transactions, which requires getting write summary. + // However, the very first transaction that is not committed might + // be an exception, which is why we use a boolean flag. + if txn_output.materialized_delta_writes.get().is_some() { + let called_write_summary = txn_output.called_write_summary.get().is_some(); + assert!(write_summary_flag || called_write_summary); + write_summary_flag &= called_write_summary; + } + } + } + + fn verify_resource_reads( + &self, + reads: &Result, ()>, + read_results: &[Option>], + delayed_field_reads: &mut impl Iterator, + ) { + for ((baseline_key, baseline_read), result_read) in reads + .as_ref() + .expect("Aggregator failures not yet tested") + .iter() + .zip(read_results) + { + match (baseline_read, result_read) { + (BaselineValue::DelayedField(expected_value, expected_version), Some(bytes)) => { + self.verify_delayed_field( + bytes, + baseline_key, + *expected_version, + *expected_value, + delayed_field_reads, + ); + }, + (BaselineValue::DelayedField(_, _), None) => { + unreachable!("Deletes on delayed fields not yet tested"); + }, + (BaselineValue::GenericWrite(v), Some(bytes)) => { + assert_some_eq!(v.extract_raw_bytes(), *bytes); + }, + (BaselineValue::GenericWrite(v), None) => { + assert_none!(v.extract_raw_bytes()); + }, + (BaselineValue::Aggregator(aggr_value), Some(bytes)) => { + assert_eq!(serialize(aggr_value), *bytes); + }, + (BaselineValue::Aggregator(_), None) => { + unreachable!( + "Deleted or non-existent value from storage can't match aggregator value" + ); + }, + (BaselineValue::Empty(delta_test_kind), maybe_bytes) => match delta_test_kind { + DeltaTestKind::DelayedFields => { assert_eq!( - baseline_size, *size, - "ERR: idx = {} group_key {:?}, baseline size {} != output_size {}", - idx, group_key, baseline_size, size + maybe_bytes.as_ref().unwrap(), + &serialize_from_delayed_field_u128(STORAGE_AGGREGATOR_VALUE, u32::MAX) ); }, - GroupSizeOrMetadata::Metadata(metadata) => { - if !group_metadata.contains_key(group_key) { - assert_eq!( - *metadata, - Some(raw_metadata(5)) /* default metadata */ - ); - } else { - let baseline_metadata = - group_metadata.get(group_key).cloned().flatten(); - assert_eq!(*metadata, baseline_metadata); - } + DeltaTestKind::AggregatorV1 => { + assert_eq!(*maybe_bytes, Some(serialize(&STORAGE_AGGREGATOR_VALUE))); }, - } + DeltaTestKind::None => { + assert_none!(maybe_bytes); + }, + }, } + } + } + + fn verify_group_reads( + &self, + group_infos: &[GroupReadInfo], + read_results: &[Option>], + delayed_field_reads: &mut impl Iterator, + ) { + assert_eq!(group_infos.len(), read_results.len()); + + for (group_info, result_group_read) in group_infos.iter().zip(read_results) { + let result_bytes = result_group_read.clone().map(Into::::into); - // Test normal reads. - izip!( - reads + // Size check for all cases + if let (Some(result), Some(baseline)) = ( + result_group_read.as_ref(), + group_info.baseline_bytes.as_ref(), + ) { + assert_eq!(result.len(), baseline.len(), "Length mismatch for value"); + } + + match &group_info.maybe_delayed_field { + Some((expected_value, expected_version)) => { + // Extract bytes from the result and verify delayed field invariants. + let result_bytes = result_bytes.expect("Must have a result for verification"); + // Verify delayed field with all required parameters + self.verify_delayed_field( + result_bytes.as_ref(), + &group_info.group_key, + *expected_version, + *expected_value, + delayed_field_reads, + ); + }, + None => { + // Case 2: This is a regular value - just compare bytes directly + assert_eq!( + result_bytes, group_info.baseline_bytes, + "Result bytes don't match baseline value for regular field" + ); + }, + } + } + } + + fn verify_module_reads( + &self, + module_reads: &Result>, ()>, + module_read_results: &[Option], + txn_idx: usize, + ) { + for (module_read, baseline_module_read) in module_read_results + .iter() + .zip(module_reads.as_ref().expect("No delta failures").iter()) + { + assert_eq!( + module_read .as_ref() - .expect("Aggregator failures not yet tested") - .iter(), - output.read_results.iter().take(read_len) - ) - .for_each(|(baseline_read, result_read)| baseline_read.assert_read_result(result_read)); - - // Update group world. - for (group_key, v, group_size, updates) in output.group_writes.iter() { - group_metadata.insert(group_key.clone(), v.as_state_value_metadata()); - - let group_map = group_world.entry(group_key).or_insert(base_map.clone()); - for (tag, v) in updates { - if v.is_deletion() { - assert_some!(group_map.remove(tag)); + .map(|m| m.creation_time_usecs()) + .unwrap(), + baseline_module_read + .map(|i| i as u64) + .unwrap_or(u32::MAX as u64), + "for txn_idx = {}", + txn_idx + ); + } + } + + fn verify_group_size_metadata( + &self, + output: &MockOutput, + group_world: &mut HashMap>, + group_metadata: &HashMap>, + ) { + for (group_key, size_or_metadata) in output.read_group_size_or_metadata.iter() { + let group_map = group_world + .entry(group_key.clone()) + .or_insert_with(default_group_map); + + match size_or_metadata { + GroupSizeOrMetadata::Size(size) => { + let baseline_size = + group_size_as_sum(group_map.iter().map(|(t, v)| (t, v.len()))) + .unwrap() + .get(); + + assert_eq!( + baseline_size, *size, + "ERR: group_key {:?}, baseline size {} != output_size {}", + group_key, baseline_size, size + ); + }, + GroupSizeOrMetadata::Metadata(metadata) => { + if !group_metadata.contains_key(group_key) { + assert_eq!(*metadata, Some(raw_metadata(5)) /* default metadata */); } else { - let existed = group_map - .insert(*tag, v.extract_raw_bytes().unwrap()) - .is_some(); - assert_eq!(existed, v.is_modification()); + let baseline_metadata = group_metadata.get(group_key).cloned().flatten(); + assert_eq!(*metadata, baseline_metadata); + } + }, + } + } + } + + fn process_group_writes( + &self, + output: &MockOutput, + group_world: &mut HashMap>, + group_metadata: &mut HashMap>, + idx: usize, + ) { + for (group_key, v, group_size, updates) in output.group_writes.iter() { + group_metadata.insert(group_key.clone(), v.as_state_value_metadata()); + + let group_map = group_world + .entry(group_key.clone()) + .or_insert_with(default_group_map); + + for (tag, (v, maybe_layout)) in updates { + if v.is_deletion() { + assert_some!(group_map.remove(tag)); + } else { + let mut bytes = v.extract_raw_bytes().unwrap(); + + if maybe_layout.is_some() { + assert_eq!(*tag, RESERVED_TAG); + let (written_id, written_idx) = + deserialize_to_delayed_field_id(&bytes).unwrap(); + let (current_value, _) = deserialize_to_delayed_field_u128( + group_map.get(&RESERVED_TAG).unwrap(), + ) + .unwrap(); + assert_eq!(written_idx, idx as u32); + + // Use the helper method + self.insert_or_verify_delayed_field_id(group_key.clone(), written_id); + + bytes = serialize_from_delayed_field_u128(current_value, written_idx); } + + let existed = group_map.insert(*tag, bytes).is_some(); + assert_eq!(existed, v.is_modification()); } - let computed_size = - group_size_as_sum(group_map.iter().map(|(t, v)| (t, v.len()))).unwrap(); - assert_eq!(computed_size, *group_size); } - // Test recorded finalized group writes: it should contain the whole group, and - // as such, correspond to the contents of the group_world. - // TODO: figure out what can still be tested here, e.g. RESERVED_TAG - // let groups_tested = - // (output.group_writes.len() + group_reads.as_ref().unwrap().len()) > 0; - // for (group_key, _, finalized_updates) in output.recorded_groups.get().unwrap() { - // let baseline_group_map = - // group_world.entry(group_key).or_insert(base_map.clone()); - // assert_eq!(finalized_updates.len(), baseline_group_map.len()); - // if groups_tested { - // // RESERVED_TAG should always be contained. - // assert_ge!(finalized_updates.len(), 1); - - // for (tag, v) in finalized_updates.iter() { - // assert_eq!( - // v.bytes().unwrap(), - // baseline_group_map.get(tag).unwrap(), - // ); - // } - // } - // } - - let baseline_deltas = resolved_deltas - .as_ref() - .expect("Aggregator failures not yet tested"); - output - .materialized_delta_writes - .get() - .expect("Delta writes must be set") - .iter() - .for_each(|(k, result_delta_write)| { - assert_eq!( - *baseline_deltas.get(k).expect("Baseline must contain delta"), - result_delta_write - .as_u128() - .expect("Baseline must contain delta") - .expect("Must deserialize aggregator write value") - ); - }); - }); + let computed_size = + group_size_as_sum(group_map.iter().map(|(t, v)| (t, v.len()))).unwrap(); + assert_eq!(computed_size, *group_size); + } + } + + fn process_group_deltas( + &self, + group_deltas: &[(K, DeltaOp)], + group_world: &mut HashMap>, + ) { + for (key, delta) in group_deltas.iter() { + // Apply the delta and compute the new written value (retains txn_idx from the + // previous write but updates the value). + let value_with_delayed_field = group_world + .entry(key.clone()) + .or_insert_with(default_group_map) + .get_mut(&RESERVED_TAG) + .expect("RESERVED_TAG must exist"); + + let (value, version) = + deserialize_to_delayed_field_u128(value_with_delayed_field).unwrap(); + + let updated_value = delta + .apply_to(value) + .expect("Delta application failures not tested"); - results.iter().skip(committed).for_each(|output| { - // Ensure the transaction is skipped based on the output. - assert!(output.skipped); + *value_with_delayed_field = serialize_from_delayed_field_u128(updated_value, version); + } + } - // Implies that materialize_delta_writes was never called, as should - // be for skipped transactions. - assert_none!(output.materialized_delta_writes.get()); - }); + fn verify_groups_patched_write_set( + &self, + output: &MockOutput, + group_world: &HashMap>, + group_deltas: &[(K, DeltaOp)], + ) { + // TODO(BlockSTMv2: Do delta keys, as well as replaced_reads. + let patched_resource_write_set = output + .patched_resource_write_set + .get() + .expect("Patched resource write set must be set"); + + for (key, maybe_size) in output + .group_writes + .iter() + .map(|(k, _, size, _)| (k, Some(size))) + .chain(group_deltas.iter().map(|(k, _)| (k, None))) + { + let patched_group_bytes = patched_resource_write_set.get(key).unwrap(); + let expected_group_map = group_world.get(key).unwrap(); + + if patched_group_bytes.is_deletion() { + assert!(maybe_size.map_or(true, |size| *size == ResourceGroupSize::zero_combined())); + } else { + let bytes = patched_group_bytes.extract_raw_bytes().unwrap(); + assert!(maybe_size.map_or(true, |size| size.get() == bytes.len() as u64)); + let patched_group_map: BTreeMap = bcs::from_bytes(&bytes).unwrap(); + assert_eq!(patched_group_map, *expected_group_map); + } + } + } + + fn verify_materialized_deltas( + &self, + output: &MockOutput, + resolved_deltas: &Result, ()>, + ) { + let baseline_deltas = resolved_deltas + .as_ref() + .expect("Aggregator failures not yet tested"); + + output + .materialized_delta_writes + .get() + .expect("Delta writes must be set") + .iter() + .for_each(|(k, result_delta_write)| { + assert_eq!( + *baseline_deltas.get(k).expect("Baseline must contain delta"), + result_delta_write + .as_u128() + .expect("Baseline must contain delta") + .expect("Must deserialize aggregator write value") + ); + }); + + for (k, (_, _)) in output.reads_needing_exchange.iter() { + let patched_resource = output + .patched_resource_write_set + .get() + .unwrap() + .get(k) + .unwrap(); + + let baseline_value = *baseline_deltas.get(k).expect("Baseline must contain delta"); + let (patched_value, _) = + deserialize_to_delayed_field_u128(&patched_resource.extract_raw_bytes().unwrap()) + .unwrap(); + assert_eq!(patched_value, baseline_value); + } } // Used for testing, hence the function asserts the correctness conditions within diff --git a/aptos-move/block-executor/src/proptest_types/bencher.rs b/aptos-move/block-executor/src/proptest_types/bencher.rs index ceff511e145..11e43c38433 100644 --- a/aptos-move/block-executor/src/proptest_types/bencher.rs +++ b/aptos-move/block-executor/src/proptest_types/bencher.rs @@ -7,9 +7,8 @@ use crate::{ executor::BlockExecutor, proptest_types::{ baseline::BaselineOutput, - types::{ - KeyType, MockOutput, MockTask, MockTransaction, TransactionGen, TransactionGenParams, - }, + mock_executor::{MockOutput, MockTask}, + types::{KeyType, MockTransaction, TransactionGen, TransactionGenParams}, }, txn_commit_hook::NoOpTransactionCommitHook, txn_provider::default::DefaultTxnProvider, @@ -109,7 +108,7 @@ where let transactions: Vec<_> = transaction_gens .into_iter() - .map(|txn_gen| txn_gen.materialize(&key_universe, (false, false))) + .map(|txn_gen| txn_gen.materialize(&key_universe)) .collect(); let txns_provider = DefaultTxnProvider::new(transactions.clone()); diff --git a/aptos-move/block-executor/src/proptest_types/delta_tests.rs b/aptos-move/block-executor/src/proptest_types/delta_tests.rs new file mode 100644 index 00000000000..209c319b775 --- /dev/null +++ b/aptos-move/block-executor/src/proptest_types/delta_tests.rs @@ -0,0 +1,100 @@ +// Copyright © Aptos Foundation +// Parts of the project are originally copyright © Meta Platforms, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + proptest_types::{ + baseline::BaselineOutput, + mock_executor::{MockEvent, MockTask}, + resource_tests::{ + create_executor_thread_pool, execute_block_parallel, + generate_universe_and_transactions, get_gas_limit_variants, + }, + types::{DeltaDataView, KeyType, MockTransaction}, + }, + task::ExecutorTask, + txn_provider::default::DefaultTxnProvider, +}; +use proptest::test_runner::TestRunner; +use std::marker::PhantomData; +use test_case::test_case; + +fn run_transactions_deltas( + universe_size: usize, + transaction_count: usize, + use_gas_limit: bool, + num_executions: usize, + num_random_generations: usize, +) { + let executor_thread_pool = create_executor_thread_pool(); + + // The delta threshold controls how many keys / paths are guaranteed r/w resources even + // in the presence of deltas. + let delta_threshold = std::cmp::min(15, universe_size / 2); + + for _ in 0..num_random_generations { + let mut local_runner = TestRunner::default(); + + let (universe, transaction_gen) = generate_universe_and_transactions( + &mut local_runner, + universe_size, + transaction_count, + true, + ); + + // Do not allow deletions as resolver can't apply delta to a deleted aggregator. + let transactions: Vec, MockEvent>> = transaction_gen + .into_iter() + .map(|txn_gen| txn_gen.materialize_with_deltas(&universe, delta_threshold, false)) + .collect(); + let txn_provider = DefaultTxnProvider::new(transactions); + + let data_view = DeltaDataView::> { + phantom: PhantomData, + }; + + let gas_limits = get_gas_limit_variants(use_gas_limit, transaction_count); + + for maybe_block_gas_limit in gas_limits { + for _ in 0..num_executions { + let output = execute_block_parallel::< + MockTransaction, MockEvent>, + DeltaDataView>, + DefaultTxnProvider, MockEvent>>, + >( + executor_thread_pool.clone(), + maybe_block_gas_limit, + &txn_provider, + &data_view, + None, + ); + + BaselineOutput::generate(txn_provider.get_txns(), maybe_block_gas_limit) + .assert_parallel_output(&output); + } + } + } +} + +#[test_case(50, 1000, false, 10, 2 ; "deltas and writes")] +#[test_case(10, 1000, false, 10, 2 ; "deltas with small universe")] +#[test_case(50, 1000, true, 10, 2 ; "deltas and writes with gas limit")] +#[test_case(10, 1000, true, 10, 2 ; "deltas with small universe with gas limit")] +fn deltas_transaction_tests( + universe_size: usize, + transaction_count: usize, + use_gas_limit: bool, + num_executions: usize, + num_random_generations: usize, +) where + MockTask, MockEvent>: + ExecutorTask, MockEvent>>, +{ + run_transactions_deltas( + universe_size, + transaction_count, + use_gas_limit, + num_executions, + num_random_generations, + ); +} diff --git a/aptos-move/block-executor/src/proptest_types/group_tests.rs b/aptos-move/block-executor/src/proptest_types/group_tests.rs new file mode 100644 index 00000000000..b334495f790 --- /dev/null +++ b/aptos-move/block-executor/src/proptest_types/group_tests.rs @@ -0,0 +1,170 @@ +// Copyright © Aptos Foundation +// Parts of the project are originally copyright © Meta Platforms, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + code_cache_global_manager::AptosModuleCacheManagerGuard, + errors::SequentialBlockExecutionError, + executor::BlockExecutor, + proptest_types::{ + baseline::BaselineOutput, + mock_executor::{MockEvent, MockOutput, MockTask}, + resource_tests::{ + create_executor_thread_pool, execute_block_parallel, get_gas_limit_variants, + }, + types::{ + KeyType, MockTransaction, NonEmptyGroupDataView, TransactionGen, TransactionGenParams, + }, + }, + task::ExecutorTask, + txn_commit_hook::NoOpTransactionCommitHook, + txn_provider::default::DefaultTxnProvider, +}; +use aptos_types::block_executor::{ + config::BlockExecutorConfig, transaction_slice_metadata::TransactionSliceMetadata, +}; +use num_cpus; +use proptest::{collection::vec, prelude::*, strategy::ValueTree, test_runner::TestRunner}; +use std::sync::Arc; +use test_case::test_case; + +/// Create a data view for testing with non-empty groups +pub(crate) fn create_non_empty_group_data_view( + key_universe: &[[u8; 32]], + universe_size: usize, + delayed_field_testing: bool, +) -> NonEmptyGroupDataView> { + NonEmptyGroupDataView::> { + group_keys: key_universe[(universe_size - 3)..universe_size] + .iter() + .map(|k| KeyType(*k)) + .collect(), + delayed_field_testing, + } +} + +/// Run both parallel and sequential execution tests for a transaction provider +pub(crate) fn run_tests_with_groups( + executor_thread_pool: Arc, + gas_limits: Vec>, + transactions: Vec, MockEvent>>, + data_view: &NonEmptyGroupDataView>, + num_executions_parallel: usize, + num_executions_sequential: usize, +) { + let txn_provider = DefaultTxnProvider::new(transactions); + + // Run parallel execution tests + for maybe_block_gas_limit in gas_limits { + for _ in 0..num_executions_parallel { + let output = execute_block_parallel::< + MockTransaction, MockEvent>, + NonEmptyGroupDataView>, + DefaultTxnProvider, MockEvent>>, + >( + executor_thread_pool.clone(), + maybe_block_gas_limit, + &txn_provider, + data_view, + None, + ); + + BaselineOutput::generate(txn_provider.get_txns(), maybe_block_gas_limit) + .assert_parallel_output(&output); + } + } + + // Run sequential execution tests + for _ in 0..num_executions_sequential { + let mut guard = AptosModuleCacheManagerGuard::none(); + + let output = BlockExecutor::< + MockTransaction, MockEvent>, + MockTask, MockEvent>, + NonEmptyGroupDataView>, + NoOpTransactionCommitHook, MockEvent>, usize>, + DefaultTxnProvider, MockEvent>>, + >::new( + BlockExecutorConfig::new_no_block_limit(num_cpus::get()), + executor_thread_pool.clone(), + None, + ) + .execute_transactions_sequential( + &txn_provider, + data_view, + &TransactionSliceMetadata::unknown(), + &mut guard, + false, + ); + + BaselineOutput::generate(txn_provider.get_txns(), None).assert_output(&output.map_err( + |e| match e { + SequentialBlockExecutionError::ResourceGroupSerializationError => { + panic!("Unexpected error") + }, + SequentialBlockExecutionError::ErrorToReturn(err) => err, + }, + )); + } +} + +// TODO: Change some tests (e.g. second and fifth) to use gas limit: needs to handle error in mock executor. +#[test_case(50, 100, None, None, None, false, 30, 15 ; "basic group test")] +#[test_case(50, 1000, None, None, None, false, 20, 10 ; "basic group test 2")] +#[test_case(50, 1000, None, None, None, true, 20, 10 ; "basic group test 2 with gas limit")] +#[test_case(15, 1000, None, None, None, false, 5, 5 ; "small universe group test")] +#[test_case(20, 1000, Some(30), None, None, false, 10, 5 ; "group size pct1=30%")] +#[test_case(20, 1000, Some(80), None, None, false, 10, 5 ; "group size pct1=80%")] +#[test_case(20, 1000, Some(80), None, None, true, 10, 5 ; "group size pct1=80% with gas limit")] +#[test_case(20, 1000, Some(30), Some(80), None, false, 10, 5 ; "group size pct1=30%, pct2=80%")] +#[test_case(20, 1000, Some(30), Some(50), Some(70), false, 10, 5 ; "group size pct1=30%, pct2=50%, pct3=70%")] +fn non_empty_group_transaction_tests( + universe_size: usize, + transaction_count: usize, + group_size_pct1: Option, + group_size_pct2: Option, + group_size_pct3: Option, + use_gas_limit: bool, + num_executions_parallel: usize, + num_executions_sequential: usize, +) where + MockTask, MockEvent>: + ExecutorTask, MockEvent>>, +{ + let mut local_runner = TestRunner::default(); + + let key_universe = vec(any::<[u8; 32]>(), universe_size) + .new_tree(&mut local_runner) + .expect("creating a new value should succeed") + .current(); + + let transaction_gen = vec( + any_with::>(TransactionGenParams::new_dynamic()), + transaction_count, + ) + .new_tree(&mut local_runner) + .expect("creating a new value should succeed") + .current(); + + // Group size percentages for 3 groups + let group_size_pcts = [group_size_pct1, group_size_pct2, group_size_pct3]; + let transactions = transaction_gen + .into_iter() + .map(|txn_gen| { + txn_gen.materialize_groups::<[u8; 32], MockEvent>(&key_universe, group_size_pcts, None) + }) + .collect(); + + let data_view = create_non_empty_group_data_view(&key_universe, universe_size, false); + let executor_thread_pool = create_executor_thread_pool(); + let gas_limits = get_gas_limit_variants(use_gas_limit, transaction_count); + + run_tests_with_groups( + executor_thread_pool, + gas_limits, + transactions, + &data_view, + num_executions_parallel, + num_executions_sequential, + ); +} diff --git a/aptos-move/block-executor/src/proptest_types/mock_executor.rs b/aptos-move/block-executor/src/proptest_types/mock_executor.rs new file mode 100644 index 00000000000..b7aa740ff14 --- /dev/null +++ b/aptos-move/block-executor/src/proptest_types/mock_executor.rs @@ -0,0 +1,1012 @@ +// Copyright © Aptos Foundation +// Parts of the project are originally copyright © Meta Platforms, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + proptest_types::types::{ + deserialize_to_delayed_field_id, serialize_from_delayed_field_id, DeltaTestKind, + GroupSizeOrMetadata, MockIncarnation, MockTransaction, ValueType, RESERVED_TAG, + }, + task::{ExecutionStatus, ExecutorTask, TransactionOutput}, +}; +use aptos_aggregator::{ + bounded_math::SignedU128, + delayed_change::{DelayedApplyChange, DelayedChange}, + delta_change_set::{DeltaOp, DeltaWithMax}, + resolver::TAggregatorV1View, +}; +use aptos_mvhashmap::types::TxnIndex; +use aptos_types::{ + contract_event::TransactionEvent, + error::PanicError, + executable::ModulePath, + fee_statement::FeeStatement, + state_store::{state_value::StateValueMetadata, TStateView}, + transaction::BlockExecutableTransaction as Transaction, + write_set::{TransactionWrite, WriteOp, WriteOpKind}, +}; +use aptos_vm_environment::environment::AptosEnvironment; +use aptos_vm_types::{ + module_and_script_storage::code_storage::AptosCodeStorage, + module_write_set::ModuleWrite, + resolver::{ + BlockSynchronizationKillSwitch, ResourceGroupSize, TExecutorView, TResourceGroupView, + }, + resource_group_adapter::{ + decrement_size_for_remove_tag, group_tagged_resource_size, increment_size_for_add_tag, + }, +}; +use bytes::Bytes; +use claims::{assert_none, assert_ok}; +use move_core_types::{ + language_storage::ModuleId, + value::{MoveStructLayout, MoveTypeLayout}, + vm_status::StatusCode, +}; +use move_vm_types::delayed_values::delayed_field_id::DelayedFieldID; +use once_cell::sync::OnceCell; +use std::{ + collections::{BTreeMap, HashMap, HashSet}, + fmt::Debug, + hash::Hash, + marker::PhantomData, + sync::{atomic::Ordering, Arc}, +}; + +/// A lazily initialized empty struct layout used throughout tests +/// +/// This is an empty struct layout used specifically for testing delayed fields. +/// It's used when performing reads for resources that might contain delayed fields +/// to ensure consistent behavior across all test cases. +pub(crate) static MOCK_LAYOUT: once_cell::sync::Lazy = + once_cell::sync::Lazy::new(|| MoveTypeLayout::Struct(MoveStructLayout::new(vec![]))); + +/// Macro for returning an error directly when Result is an error +/// +/// This macro unwraps a Result or returns the error directly. +/// Used when the function returns the same error type as the Result. +/// +/// Usage: +/// try_with_direct!(result_expr) +#[macro_export] +macro_rules! try_with_direct { + ($expr:expr) => { + match $expr { + Ok(val) => val, + Err(e) => return e, + } + }; +} + +/// Macro for returning Err(e) when Result is an error +/// +/// This macro unwraps a Result or returns Err(e). +/// Used when the function returns Result. +/// +/// Usage: +/// try_with_error!(result_expr) +#[macro_export] +macro_rules! try_with_error { + ($expr:expr) => { + match $expr { + Ok(val) => val, + Err(e) => return Err(e), + } + }; +} + +/// Macro for returning an ExecutionStatus with error message +/// +/// This macro unwraps a Result or returns an error wrapped in +/// ExecutionStatus::Success(MockOutput::with_error(...)). +/// +/// Usage: +/// try_with_status!(result_expr, "error message") +#[macro_export] +macro_rules! try_with_status { + ($expr:expr, $msg:expr) => { + match $expr { + Ok(val) => val, + Err(e) => { + return Err(ExecutionStatus::Success(MockOutput::with_error(&format!( + "{}: {:?}", + $msg, e + )))) + }, + } + }; +} + +#[derive(Debug)] +pub(crate) struct MockOutput { + pub(crate) writes: Vec<(K, ValueType, Option>)>, + pub(crate) aggregator_v1_writes: Vec<(K, ValueType)>, + // Key, metadata_op, inner_ops + pub(crate) group_writes: Vec<( + K, + ValueType, + ResourceGroupSize, + BTreeMap>)>, + )>, + pub(crate) module_writes: Vec>, + pub(crate) deltas: Vec<(K, DeltaOp, Option<(DelayedFieldID, bool)>)>, + pub(crate) events: Vec, + pub(crate) read_results: Vec>>, + pub(crate) delayed_field_reads: Vec<(DelayedFieldID, u128, K)>, + pub(crate) module_read_results: Vec>, + pub(crate) read_group_size_or_metadata: Vec<(K, GroupSizeOrMetadata)>, + pub(crate) materialized_delta_writes: OnceCell>, + pub(crate) patched_resource_write_set: OnceCell>, + pub(crate) total_gas: u64, + pub(crate) called_write_summary: OnceCell<()>, + pub(crate) skipped: bool, + pub(crate) maybe_error_msg: Option, + pub(crate) reads_needing_exchange: HashMap)>, + pub(crate) group_reads_needing_exchange: HashMap, +} + +/// A builder for incrementally constructing MockOutput instances for cleaner code. +pub(crate) struct MockOutputBuilder { + pub(crate) output: MockOutput, +} + +impl MockOutputBuilder { + /// Create a new builder from mock incarnation. + pub(crate) fn from_mock_incarnation( + mock_incarnation: &MockIncarnation, + delta_test_kind: DeltaTestKind, + ) -> Self { + let output = MockOutput { + writes: Vec::with_capacity(mock_incarnation.resource_writes.len()), + aggregator_v1_writes: mock_incarnation + .resource_writes + .clone() + .into_iter() + .filter_map(|(k, v, has_delta)| { + (has_delta && delta_test_kind == DeltaTestKind::AggregatorV1).then_some((k, v)) + }) + .collect(), + group_writes: Vec::with_capacity(mock_incarnation.group_writes.len()), + module_writes: mock_incarnation.module_writes.clone(), + deltas: Vec::with_capacity(mock_incarnation.deltas.len()), + events: mock_incarnation.events.to_vec(), + read_results: Vec::with_capacity(mock_incarnation.resource_reads.len()), + delayed_field_reads: vec![], + module_read_results: Vec::with_capacity(mock_incarnation.module_reads.len()), + read_group_size_or_metadata: Vec::with_capacity(mock_incarnation.group_queries.len()), + materialized_delta_writes: OnceCell::new(), + patched_resource_write_set: OnceCell::new(), + total_gas: mock_incarnation.gas, + called_write_summary: OnceCell::new(), + skipped: false, + maybe_error_msg: None, + reads_needing_exchange: HashMap::new(), + group_reads_needing_exchange: HashMap::new(), + }; + + Self { output } + } + + /// This method reads metadata for each module ID in the provided list + /// and adds the results to the output. + /// + /// Returns self for method chaining + pub(crate) fn add_module_reads( + &mut self, + view: &S, + module_ids: &[ModuleId], + ) -> Result<&mut Self, ExecutionStatus, usize>> { + for module_id in module_ids { + let metadata = try_with_status!( + view.get_module_state_value_metadata(module_id.address(), module_id.name()), + "Failed to fetch module metadata" + ); + self.output.module_read_results.push(metadata); + } + + Ok(self) + } + + /// This method reads bytes for regular resources and handles delayed fields as needed. + /// + /// Returns self for method chaining + pub(crate) fn add_resource_reads( + &mut self, + view: &impl TExecutorView, + key_pairs: &[(K, bool)], + delayed_fields_enabled: bool, + ) -> Result<&mut Self, ExecutionStatus, usize>> { + for (key, has_deltas) in key_pairs { + match (has_deltas, delayed_fields_enabled) { + // Regular resource read (no delayed fields) + (false, false) | (false, true) => { + let v = try_with_status!( + view.get_resource_bytes(key, None), + "Failed to get resource bytes" + ); + self.add_read_result(v.map(Into::into)); + }, + // Aggregator V1 read + (true, false) => { + let v = try_with_status!( + view.get_aggregator_v1_state_value(key), + "Failed to get aggregator v1 state value" + ); + self.add_read_result(v.map(|state_value| state_value.bytes().clone().into())); + }, + // Delayed field read + (true, true) => { + let bytes = try_with_status!( + view.get_resource_bytes(key, Some(&*MOCK_LAYOUT)), + "Failed to get resource bytes with layout" + ) + .expect("In current tests, delayed field is always initialized"); + + // Add bytes to read_results first + self.add_read_result(Some(bytes.to_vec())); + + // Then perform delayed field read if bytes were returned + try_with_error!(self.add_delayed_field_from_read_result( + view, + key, + bytes.as_ref() + )); + }, + } + } + + Ok(self) + } + + /// This method reads resources from groups and handles delayed fields as needed. + /// + /// Returns self for method chaining + pub(crate) fn add_group_reads( + &mut self, + view: &(impl TResourceGroupView + + TExecutorView), + group_reads: &[(K, u32, bool)], + delayed_fields_enabled: bool, + ) -> Result<&mut Self, ExecutionStatus, usize>> { + for (group_key, resource_tag, has_delta) in group_reads { + let maybe_layout = + (*has_delta && delayed_fields_enabled && *resource_tag == RESERVED_TAG) + .then(|| (*MOCK_LAYOUT).clone()); + + let v = try_with_status!( + view.get_resource_from_group(group_key, resource_tag, maybe_layout.as_ref()), + "Failed to get resource from group" + ); + + self.add_read_result(v.clone().map(Into::into)); + + // Perform delayed field read if needed + if *has_delta && delayed_fields_enabled { + assert_eq!(*resource_tag, RESERVED_TAG); + try_with_error!(self.add_delayed_field_from_read_result( + view, + group_key, + v.expect("RESERVED_TAG always contains a value").as_ref(), + )); + } + } + + Ok(self) + } + + /// Add group size or metadata queries to the output + /// + /// This method queries either the size or metadata of resource groups + /// based on the query_metadata flag. + /// + /// Returns self for method chaining + pub(crate) fn add_group_queries( + &mut self, + view: &(impl TResourceGroupView + + TExecutorView), + group_queries: &[(K, bool)], + ) -> Result<&mut Self, ExecutionStatus, usize>> { + for (group_key, query_metadata) in group_queries { + let res = if *query_metadata { + // Query metadata + let v = try_with_status!( + view.get_resource_state_value_metadata(group_key), + "Failed to get resource state value metadata" + ); + GroupSizeOrMetadata::Metadata(v) + } else { + // Query size + let v = try_with_status!( + view.resource_group_size(group_key), + "Failed to get resource group size" + ); + GroupSizeOrMetadata::Size(v.get()) + }; + + self.output + .read_group_size_or_metadata + .push((group_key.clone(), res)); + } + + Ok(self) + } + + /// This method handles the complex logic of processing group writes, including: + /// - Getting the resource group size + /// - Processing inner operations for each tag + /// - Updating group size based on deletions and creations + /// - Adding the final group write to the output + /// + /// Returns self for method chaining + pub(crate) fn add_group_writes( + &mut self, + view: &View, + group_writes: &[(K, StateValueMetadata, HashMap)], + delayed_fields_enabled: bool, + txn_idx: u32, + ) -> Result<&mut Self, ExecutionStatus, usize>> + where + View: TResourceGroupView + + TExecutorView, + { + // Group writes + for (key, metadata, inner_ops) in group_writes { + let mut new_inner_ops = BTreeMap::new(); + + let mut new_group_size = try_with_status!( + view.resource_group_size(key), + "Failed to get resource group size" + ); + let group_size = new_group_size; + + for (tag, (inner_op, has_delayed_field)) in inner_ops.iter() { + let maybe_layout = + (*has_delayed_field && delayed_fields_enabled && *tag == RESERVED_TAG) + .then(|| MOCK_LAYOUT.clone()); + let exists = try_with_status!( + view.get_resource_from_group(key, tag, maybe_layout.as_ref(),), + "Failed to get resource from group" + ) + .is_some(); + assert!( + *tag != RESERVED_TAG || exists, + "RESERVED_TAG must always be present in groups in tests" + ); + + // inner op is either deletion or creation. + assert!(!inner_op.is_modification()); + + let mut new_inner_op = inner_op.clone(); + let mut new_inner_op_layout = None; + if *has_delayed_field && delayed_fields_enabled && new_inner_op.bytes().is_some() { + // For groups, delayed_fields_enabled should always be + // true when has_delta is true & tag is RESERVED_TAG. + assert!(*tag == RESERVED_TAG); + let prev_id = self.get_delayed_field_id_from_resource(view, key, Some(*tag))?; + new_inner_op.set_bytes(serialize_from_delayed_field_id(prev_id, txn_idx)); + new_inner_op_layout = Some(Arc::new(MOCK_LAYOUT.clone())); + } + + let maybe_op = if exists { + Some( + if new_inner_op.is_creation() + && (new_inner_op.bytes().unwrap()[0] % 4 < 3 || *tag == RESERVED_TAG) + { + ValueType::new( + new_inner_op.bytes().cloned(), + StateValueMetadata::none(), + WriteOpKind::Modification, + ) + } else { + ValueType::new(None, StateValueMetadata::none(), WriteOpKind::Deletion) + }, + ) + } else { + new_inner_op.is_creation().then(|| new_inner_op.clone()) + }; + + if let Some(new_inner_op) = maybe_op { + if exists { + let old_tagged_value_size = try_with_status!( + view.resource_size_in_group(key, tag), + "Failed to get resource size in group" + ); + let old_size = try_with_status!( + group_tagged_resource_size(tag, old_tagged_value_size), + "Failed to calculate group tagged resource size" + ); + + try_with_status!( + decrement_size_for_remove_tag(&mut new_group_size, old_size), + "Failed to decrement resource group size" + ); + } + if !new_inner_op.is_deletion() { + let new_size = try_with_status!( + group_tagged_resource_size( + tag, + new_inner_op.bytes().as_ref().unwrap().len(), + ), + "Failed to calculate group tagged resource size" + ); + + try_with_status!( + increment_size_for_add_tag(&mut new_group_size, new_size), + "Failed to increment resource group size" + ); + } + + new_inner_ops.insert(*tag, (new_inner_op, new_inner_op_layout)); + } + } + + if !new_inner_ops.is_empty() { + if group_size.get() > 0 && new_group_size.get() == 0 { + // Note: Even though currently the groups are never empty, speculatively the new + // size may still become zero, because atomicity is not guaranteed across + // existence queries: so even if RESERVED_TAG is present, a different tag might + // have been removed for exactly the same size. + self.output.group_writes.push(( + key.clone(), + ValueType::new(None, metadata.clone(), WriteOpKind::Deletion), + new_group_size, + new_inner_ops, + )); + } else { + let op_kind = if group_size.get() == 0 { + WriteOpKind::Creation + } else { + WriteOpKind::Modification + }; + + // Not testing metadata_op here, always modification. + self.output.group_writes.push(( + key.clone(), + ValueType::new(Some(Bytes::new()), metadata.clone(), op_kind), + new_group_size, + new_inner_ops, + )); + } + } + } + + Ok(self) + } + + /// This method handles regular resource writes and delayed fields as needed. + /// It processes writes and sets proper bytes for delayed fields. + /// + /// Returns self for method chaining + pub(crate) fn add_resource_writes( + &mut self, + view: &View, + resource_writes: &[(K, ValueType, bool)], + delayed_fields_enabled: bool, + txn_idx: u32, + ) -> Result<&mut Self, ExecutionStatus, usize>> + // Group view is because get_delayed_field_id_from_resource dispatches, but there is + // a TODO to have TExecutorView contain TResourceGroupView anyway. + where + View: TExecutorView + + TResourceGroupView, + { + for (k, new_value, has_delta) in resource_writes.iter() { + let mut value_to_add = new_value.clone(); + let mut value_to_add_layout = None; + if *has_delta && !delayed_fields_enabled { + // Already handled by aggregator_v1_writes. + continue; + } + + if *has_delta && delayed_fields_enabled && value_to_add.bytes().is_some() { + let prev_id = self.get_delayed_field_id_from_resource(view, k, None)?; + value_to_add.set_bytes(serialize_from_delayed_field_id(prev_id, txn_idx)); + value_to_add_layout = Some(Arc::new(MOCK_LAYOUT.clone())); + } + + self.output + .writes + .push((k.clone(), value_to_add, value_to_add_layout)); + } + + Ok(self) + } + + /// This method processes the deltas and adds them to the output. + /// It skips this step if delayed_fields_or_aggregator_v1 is true. + /// + /// Returns self for method chaining + pub(crate) fn add_deltas( + &mut self, + view: &(impl TExecutorView + + TResourceGroupView), + deltas: &[(K, DeltaOp, Option)], + delta_test_kind: DeltaTestKind, + ) -> Result<&mut Self, ExecutionStatus, usize>> { + match delta_test_kind { + DeltaTestKind::DelayedFields => { + for (k, delta, maybe_tag) in deltas { + let id = self.get_delayed_field_id_from_resource(view, k, *maybe_tag)?; + + // Currently, we test with base delta of 0 and a max value of u128::MAX. + let base_delta = &SignedU128::Positive(0); + let (delta_op, _, max_value) = delta.into_inner(); + let success = try_with_status!( + view.delayed_field_try_add_delta_outcome( + &id, base_delta, &delta_op, max_value + ), + "Failed to apply delta to delayed field" + ); + + self.output + .deltas + .push((k.clone(), *delta, Some((id, success)))); + } + }, + DeltaTestKind::AggregatorV1 => { + self.output + .deltas + .extend(deltas.iter().map(|(k, delta, maybe_tag)| { + assert_none!(maybe_tag, "AggregatorV1 not supported in groups"); + (k.clone(), *delta, None) + })); + }, + DeltaTestKind::None => {}, + } + + Ok(self) + } + + /// Build and return the final MockOutput + pub(crate) fn build(self) -> MockOutput { + self.output + } + + /// Helper to extract a delayed field ID for a resource key (assuming value is exchanged). + fn get_delayed_field_id_from_resource( + &mut self, + view: &(impl TExecutorView + + TResourceGroupView), + key: &K, + maybe_tag: Option, + ) -> Result, usize>> { + let bytes = match maybe_tag { + None => try_with_status!( + view.get_resource_bytes(key, Some(&*MOCK_LAYOUT)), + "Failed to get resource bytes" + ), + Some(tag) => try_with_status!( + view.get_resource_from_group(key, &tag, Some(&*MOCK_LAYOUT)), + "Failed to get resource bytes from group" + ), + } + .expect("In current tests, delayed field is always initialized"); + + if maybe_tag.is_some() { + // TODO: test metadata. + self.output + .group_reads_needing_exchange + .insert(key.clone(), StateValueMetadata::none()); + } else { + self.output.reads_needing_exchange.insert( + key.clone(), + (StateValueMetadata::none(), Arc::new(MOCK_LAYOUT.clone())), + ); + } + + Ok(deserialize_to_delayed_field_id(&bytes) + .expect("Must deserialize delayed field tuple") + .0) + } + + /// Perform a delayed field read and update the output accordingly. + /// Returns an error ExecutionStatus if the read fails. + fn add_delayed_field_from_read_result( + &mut self, + view: &impl TExecutorView, + key: &K, + bytes: &[u8], + ) -> Result<(), ExecutionStatus, usize>> { + let id = deserialize_to_delayed_field_id(bytes) + .expect("Must deserialize delayed field tuple") + .0; + + let v = try_with_status!( + view.get_delayed_field_value(&id), + "Failed to get delayed field value" + ); + + let value = v.into_aggregator_value().unwrap(); + self.output + .delayed_field_reads + .push((id, value, key.clone())); + Ok(()) + } + + /// Add a normal read result + fn add_read_result(&mut self, result: Option>) { + self.output.read_results.push(result); + } +} + +impl MockOutput { + // Helper method to create an empty MockOutput with common settings + pub(crate) fn skipped_output(error_msg: Option) -> Self { + Self { + writes: vec![], + aggregator_v1_writes: vec![], + group_writes: vec![], + module_writes: vec![], + deltas: vec![], + events: vec![], + read_results: vec![], + delayed_field_reads: vec![], + module_read_results: vec![], + read_group_size_or_metadata: vec![], + materialized_delta_writes: OnceCell::new(), + patched_resource_write_set: OnceCell::new(), + total_gas: 0, + called_write_summary: OnceCell::new(), + skipped: true, + maybe_error_msg: error_msg, + reads_needing_exchange: HashMap::new(), + group_reads_needing_exchange: HashMap::new(), + } + } + + // Helper method to create a MockOutput with an error message + pub(crate) fn with_error(error: impl std::fmt::Display) -> Self { + Self::skipped_output(Some(format!("{}", error))) + } + + // Helper method to create a MockOutput with a discard code + pub(crate) fn with_discard_code(code: StatusCode) -> Self { + Self::skipped_output(Some(format!("Discarded with code: {:?}", code))) + } +} + +impl TransactionOutput for MockOutput +where + K: PartialOrd + Ord + Send + Sync + Clone + Hash + Eq + ModulePath + Debug + 'static, + E: Send + Sync + Debug + Clone + TransactionEvent + 'static, +{ + type Txn = MockTransaction; + + // TODO[agg_v2](tests): Assigning MoveTypeLayout as None for all the writes for now. + // That means, the resources do not have any DelayedFields embedded in them. + // Change it to test resources with DelayedFields as well. + fn resource_write_set(&self) -> Vec<(K, Arc, Option>)> { + self.writes + .iter() + .map(|(key, value, maybe_layout)| { + (key.clone(), Arc::new(value.clone()), maybe_layout.clone()) + }) + .collect() + } + + fn module_write_set(&self) -> Vec> { + self.module_writes.clone() + } + + // Aggregator v1 writes are included in resource_write_set for tests (writes are produced + // for all keys including ones for v1_aggregators without distinguishing). + fn aggregator_v1_write_set(&self) -> BTreeMap { + self.aggregator_v1_writes.clone().into_iter().collect() + } + + fn aggregator_v1_delta_set(&self) -> Vec<(K, DeltaOp)> { + if !self.deltas.is_empty() && self.deltas[0].2.is_none() { + // When testing with delayed fields the Option is Some(id, success). + self.deltas + .iter() + .map(|(k, delta, _)| (k.clone(), *delta)) + .collect() + } else { + vec![] + } + } + + fn delayed_field_change_set(&self) -> BTreeMap> { + // TODO: also test creation of delayed fields. + if !self.deltas.is_empty() && self.deltas[0].2.is_some() { + self.deltas + .iter() + .filter_map(|(_, delta, maybe_id)| { + let (id, success) = maybe_id.unwrap(); + let (delta, _, _) = delta.into_inner(); + success.then(|| { + ( + id, + DelayedChange::Apply(DelayedApplyChange::AggregatorDelta { + delta: DeltaWithMax::new(delta, u128::MAX), + }), + ) + }) + }) + .collect() + } else { + BTreeMap::new() + } + } + + fn reads_needing_delayed_field_exchange( + &self, + ) -> Vec<( + ::Key, + StateValueMetadata, + Arc, + )> { + self.reads_needing_exchange + .iter() + .map(|(key, (metadata, layout))| (key.clone(), metadata.clone(), layout.clone())) + .collect() + } + + fn group_reads_needing_delayed_field_exchange( + &self, + ) -> Vec<(::Key, StateValueMetadata)> { + self.group_reads_needing_exchange + .iter() + .map(|(key, metadata)| (key.clone(), metadata.clone())) + .collect() + } + + fn resource_group_write_set( + &self, + ) -> Vec<( + K, + ValueType, + ResourceGroupSize, + BTreeMap>)>, + )> { + self.group_writes.clone() + } + + fn skip_output() -> Self { + Self::skipped_output(None) + } + + fn discard_output(discard_code: StatusCode) -> Self { + Self::with_discard_code(discard_code) + } + + fn output_approx_size(&self) -> u64 { + // TODO add block output limit testing + 0 + } + + fn get_write_summary( + &self, + ) -> HashSet< + crate::types::InputOutputKey< + ::Key, + ::Tag, + >, + > { + _ = self.called_write_summary.set(()); + HashSet::new() + } + + fn materialize_agg_v1( + &self, + _view: &impl TAggregatorV1View::Key>, + ) { + // TODO[agg_v2](tests): implement this method and compare + // against sequential execution results v. aggregator v1. + } + + // TODO[agg_v2](tests): Currently, appending None to all events, which means none of the + // events have aggregators. Test it with aggregators as well. + fn get_events(&self) -> Vec<(E, Option)> { + self.events.iter().map(|e| (e.clone(), None)).collect() + } + + fn incorporate_materialized_txn_output( + &self, + aggregator_v1_writes: Vec<(::Key, WriteOp)>, + patched_resource_write_set: Vec<( + ::Key, + ::Value, + )>, + _patched_events: Vec<::Event>, + ) -> Result<(), PanicError> { + assert_ok!(self + .patched_resource_write_set + .set(patched_resource_write_set.clone().into_iter().collect())); + assert_ok!(self.materialized_delta_writes.set(aggregator_v1_writes)); + // TODO: Also test patched events. + Ok(()) + } + + fn set_txn_output_for_non_dynamic_change_set(&self) { + // No compatibility issues here since the move-vm doesn't use the dynamic flag. + } + + fn fee_statement(&self) -> FeeStatement { + // First argument is supposed to be total (not important for the test though). + // Next two arguments are different kinds of execution gas that are counted + // towards the block limit. We split the total into two pieces for these arguments. + // TODO: add variety to generating fee statement based on total gas. + FeeStatement::new( + self.total_gas, + self.total_gas / 2, + (self.total_gas + 1) / 2, + 0, + 0, + ) + } + + fn is_retry(&self) -> bool { + self.skipped + } + + fn has_new_epoch_event(&self) -> bool { + false + } +} + +#[derive(Clone, Debug)] +pub(crate) struct MockEvent { + event_data: Vec, +} + +impl TransactionEvent for MockEvent { + fn get_event_data(&self) -> &[u8] { + &self.event_data + } + + fn set_event_data(&mut self, event_data: Vec) { + self.event_data = event_data; + } +} + +pub(crate) struct MockTask { + phantom_data: PhantomData<(K, E)>, +} + +impl MockTask { + pub fn new() -> Self { + Self { + phantom_data: PhantomData, + } + } +} + +impl ExecutorTask for MockTask +where + K: PartialOrd + Ord + Send + Sync + Clone + Hash + Eq + ModulePath + Debug + 'static, + E: Send + Sync + Debug + Clone + TransactionEvent + 'static, +{ + type Error = usize; + type Output = MockOutput; + type Txn = MockTransaction; + + fn init(_environment: &AptosEnvironment, _state_view: &impl TStateView) -> Self { + Self::new() + } + + fn execute_transaction( + &self, + view: &(impl TExecutorView + + TResourceGroupView + + AptosCodeStorage + + BlockSynchronizationKillSwitch), + txn: &Self::Txn, + txn_idx: TxnIndex, + ) -> ExecutionStatus { + match txn { + MockTransaction::Write { + incarnation_counter, + incarnation_behaviors, + delta_test_kind, + } => { + // Use incarnation counter value as an index to determine the read- + // and write-sets of the execution. Increment incarnation counter to + // simulate dynamic behavior when there are multiple possible read- + // and write-sets (i.e. each are selected round-robin). + let idx = incarnation_counter.fetch_add(1, Ordering::SeqCst); + let behavior = &incarnation_behaviors[idx % incarnation_behaviors.len()]; + + // Initialize the builder and use the railway pattern to execute builder operations. + let mut builder = + MockOutputBuilder::from_mock_incarnation(behavior, *delta_test_kind); + let builder_result = BuilderOperation::new(&mut builder) + .and_then(|b| b.add_module_reads(view, &behavior.module_reads)) + .and_then(|b| { + b.add_resource_reads( + view, + &behavior.resource_reads, + *delta_test_kind == DeltaTestKind::DelayedFields, + ) + }) + .and_then(|b| { + b.add_group_reads( + view, + &behavior.group_reads, + *delta_test_kind == DeltaTestKind::DelayedFields, + ) + }) + .and_then(|b| b.add_group_queries(view, &behavior.group_queries)) + .and_then(|b| { + b.add_group_writes( + view, + &behavior.group_writes, + *delta_test_kind == DeltaTestKind::DelayedFields, + txn_idx, + ) + }) + .and_then(|b| { + b.add_resource_writes( + view, + &behavior.resource_writes, + *delta_test_kind == DeltaTestKind::DelayedFields, + txn_idx, + ) + }) + .and_then(|b| b.add_deltas(view, &behavior.deltas, *delta_test_kind)) + .finish(); + + // Use the direct return variant for ExecutionStatus functions + try_with_direct!(builder_result); + + ExecutionStatus::Success(builder.build()) + }, + MockTransaction::SkipRest(gas) => { + let mut mock_output = MockOutput::skip_output(); + mock_output.total_gas = *gas; + ExecutionStatus::SkipRest(mock_output) + }, + MockTransaction::Abort => ExecutionStatus::Abort(txn_idx as usize), + MockTransaction::InterruptRequested => { + while !view.interrupt_requested() {} + ExecutionStatus::SkipRest(MockOutput::skip_output()) + }, + } + } + + fn is_transaction_dynamic_change_set_capable(_txn: &Self::Txn) -> bool { + true + } +} + +/// Railway-oriented pattern wrapper for builder operations +/// +/// This implements a simple railway-oriented pattern for chaining operations +/// that might fail, allowing for a cleaner code flow. +struct BuilderOperation<'a, K: Clone + Debug, E: Clone> { + builder: &'a mut MockOutputBuilder, + status: Option, usize>>, +} + +impl<'a, K: Clone + Debug, E: Clone> BuilderOperation<'a, K, E> { + fn new(builder: &'a mut MockOutputBuilder) -> Self { + Self { + builder, + status: None, + } + } + + fn and_then(mut self, op: F) -> Self + where + F: FnOnce( + &mut MockOutputBuilder, + ) + -> Result<&mut MockOutputBuilder, ExecutionStatus, usize>>, + { + if self.status.is_none() { + if let Err(status) = op(self.builder) { + self.status = Some(status); + } + } + self + } + + fn finish( + self, + ) -> Result<&'a mut MockOutputBuilder, ExecutionStatus, usize>> { + match self.status { + None => Ok(self.builder), + Some(status) => Err(status), + } + } +} diff --git a/aptos-move/block-executor/src/proptest_types/mod.rs b/aptos-move/block-executor/src/proptest_types/mod.rs index b90ad8dae83..17f3f0694e1 100644 --- a/aptos-move/block-executor/src/proptest_types/mod.rs +++ b/aptos-move/block-executor/src/proptest_types/mod.rs @@ -5,5 +5,12 @@ pub(crate) mod baseline; pub mod bencher; #[cfg(test)] -mod tests; +mod delta_tests; +#[cfg(test)] +mod group_tests; +pub(crate) mod mock_executor; +#[cfg(test)] +mod module_tests; +#[cfg(test)] +mod resource_tests; pub(crate) mod types; diff --git a/aptos-move/block-executor/src/proptest_types/module_tests.rs b/aptos-move/block-executor/src/proptest_types/module_tests.rs new file mode 100644 index 00000000000..8be5f949c03 --- /dev/null +++ b/aptos-move/block-executor/src/proptest_types/module_tests.rs @@ -0,0 +1,164 @@ +// Copyright © Aptos Foundation +// Parts of the project are originally copyright © Meta Platforms, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + proptest_types::{ + baseline::BaselineOutput, + mock_executor::{MockEvent, MockTask}, + resource_tests::{ + create_executor_thread_pool, execute_block_parallel, get_gas_limit_variants, + }, + types::{ + key_to_mock_module_id, KeyType, MockTransaction, TransactionGen, TransactionGenParams, + }, + }, + task::ExecutorTask, + txn_provider::default::DefaultTxnProvider, +}; +use aptos_types::state_store::MockStateView; +use fail::FailScenario; +use move_core_types::language_storage::ModuleId; +use proptest::{collection::vec, prelude::*, strategy::ValueTree, test_runner::TestRunner}; +use test_case::test_case; + +enum ModuleTestType { + // All transactions publish modules, and all accesses are module reads. + AllTransactionsAndAccesses, + // All transactions publish modules, but some accesses are not module reads. + AllTransactionsMixedAccesses, + // Some transactions publish modules and contain module reads. Other + // transactions do not publish modules and do not contain module reads. + MixedTransactionsMixedAccesses, +} + +fn execute_module_tests( + universe_size: usize, + transaction_count: usize, + use_gas_limit: bool, + modules_test_type: ModuleTestType, + num_executions: usize, + num_random_generations: usize, +) where + MockTask, MockEvent>: + ExecutorTask, MockEvent>>, +{ + let scenario = FailScenario::setup(); + assert!(fail::has_failpoints()); + fail::cfg("module_test", "return").unwrap(); + + let executor_thread_pool = create_executor_thread_pool(); + let mut runner = TestRunner::default(); + + let gas_limits = get_gas_limit_variants(use_gas_limit, transaction_count); + for maybe_block_gas_limit in gas_limits { + // Run the test cases directly + for _ in 0..num_random_generations { + // Generate universe + let universe = vec(any::<[u8; 32]>(), universe_size) + .new_tree(&mut runner) + .expect("creating universe should succeed") + .current(); + + // Generate transactions based on parameters + let transaction_strategy = match modules_test_type { + ModuleTestType::AllTransactionsAndAccesses => vec( + any_with::>( + TransactionGenParams::new_dynamic_modules_only(), + ), + transaction_count, + ), + ModuleTestType::AllTransactionsMixedAccesses + | ModuleTestType::MixedTransactionsMixedAccesses => vec( + any_with::>( + TransactionGenParams::new_dynamic_with_modules(), + ), + transaction_count, + ), + }; + + let transaction_gen = transaction_strategy + .new_tree(&mut runner) + .expect("creating transactions should succeed") + .current(); + + // Convert transactions to use modules. For mixed transactions, we convert every + // fifth transaction to use modules. + let transactions: Vec, MockEvent>> = transaction_gen + .into_iter() + .enumerate() + .map(|(i, txn_gen)| { + if i % 5 == 0 + || !matches!( + modules_test_type, + ModuleTestType::MixedTransactionsMixedAccesses + ) + { + txn_gen.materialize_modules(&universe) + } else { + txn_gen.materialize(&universe) + } + }) + .collect(); + + let txn_provider = DefaultTxnProvider::new(transactions); + let state_view = MockStateView::empty(); + + // Generate all potential module IDs that could be used in the tests + let all_module_ids = generate_all_potential_module_ids(&universe); + + // Run tests with fail point enabled to test the version metadata + for _ in 0..num_executions { + let output = execute_block_parallel::< + MockTransaction, MockEvent>, + MockStateView>, + DefaultTxnProvider, MockEvent>>, + >( + executor_thread_pool.clone(), + maybe_block_gas_limit, + &txn_provider, + &state_view, + Some(&all_module_ids), + ); + + BaselineOutput::generate(txn_provider.get_txns(), maybe_block_gas_limit) + .assert_parallel_output(&output); + } + } + } + scenario.teardown(); +} + +// Generate all potential module IDs that could be used in the tests +fn generate_all_potential_module_ids(universe: &[[u8; 32]]) -> Vec { + universe + .iter() + .map(|k| key_to_mock_module_id(&KeyType(*k), universe.len())) + .collect() +} + +// Test cases with various parameters +#[test_case(50, 100, false, ModuleTestType::AllTransactionsAndAccesses, 2, 3; "basic modules only test v1")] +#[test_case(50, 100, false, ModuleTestType::MixedTransactionsMixedAccesses, 2, 3; "basic mixed txn test with modules v1")] +#[test_case(50, 100, true, ModuleTestType::AllTransactionsAndAccesses, 2, 3; "modules only with gas limit")] +#[test_case(50, 100, false, ModuleTestType::AllTransactionsMixedAccesses, 2, 3; "mixed access with modules test")] +#[test_case(50, 100, true, ModuleTestType::AllTransactionsMixedAccesses, 2, 3; "mixed access with modules with gas limit")] +#[test_case(10, 1000, false, ModuleTestType::AllTransactionsAndAccesses, 2, 2; "small universe modules only")] +#[test_case(10, 1000, false, ModuleTestType::AllTransactionsMixedAccesses, 2, 2; "small universe mixed access with modules")] +fn module_transaction_tests( + universe_size: usize, + transaction_count: usize, + use_gas_limit: bool, + modules_test_type: ModuleTestType, + num_executions: usize, + num_random_generations: usize, +) { + execute_module_tests( + universe_size, + transaction_count, + use_gas_limit, + modules_test_type, + num_executions, + num_random_generations, + ); +} diff --git a/aptos-move/block-executor/src/proptest_types/resource_tests.rs b/aptos-move/block-executor/src/proptest_types/resource_tests.rs new file mode 100644 index 00000000000..bfeea6705f0 --- /dev/null +++ b/aptos-move/block-executor/src/proptest_types/resource_tests.rs @@ -0,0 +1,281 @@ +// Copyright © Aptos Foundation +// Parts of the project are originally copyright © Meta Platforms, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + code_cache_global_manager::AptosModuleCacheManagerGuard, + executor::BlockExecutor, + proptest_types::{ + baseline::BaselineOutput, + mock_executor::{MockEvent, MockOutput, MockTask}, + types::{KeyType, MockTransaction, TransactionGen, TransactionGenParams, MAX_GAS_PER_TXN}, + }, + task::ExecutorTask, + txn_commit_hook::NoOpTransactionCommitHook, + txn_provider::{default::DefaultTxnProvider, TxnProvider}, +}; +use aptos_types::{ + block_executor::{ + config::BlockExecutorConfig, transaction_slice_metadata::TransactionSliceMetadata, + }, + state_store::{state_value::StateValue, MockStateView, TStateView}, + transaction::{BlockExecutableTransaction as Transaction, BlockOutput}, + vm::modules::AptosModuleExtension, +}; +use move_core_types::language_storage::ModuleId; +use move_vm_runtime::Module; +use move_vm_types::code::ModuleCode; +use num_cpus; +use proptest::{ + collection::vec, + prelude::*, + sample::Index, + strategy::{Strategy, ValueTree}, + test_runner::TestRunner, +}; +use rand::Rng; +use std::{fmt::Debug, sync::Arc}; +use test_case::test_case; + +pub(crate) fn get_gas_limit_variants( + use_gas_limit: bool, + transaction_count: usize, +) -> Vec> { + if use_gas_limit { + vec![ + Some(rand::thread_rng().gen_range(0, (transaction_count as u64) * MAX_GAS_PER_TXN / 2)), + Some(0), + ] + } else { + vec![None] + } +} + +pub(crate) fn create_executor_thread_pool() -> Arc { + Arc::new( + rayon::ThreadPoolBuilder::new() + .num_threads(num_cpus::get()) + .build() + .unwrap(), + ) +} + +/// Populates a module cache manager guard with empty modules for testing. +/// This function creates empty modules for each ModuleId in the provided list and adds them to the guard's module cache. +/// +/// # Arguments +/// * `guard` - The AptosModuleCacheManagerGuard to populate with empty modules +/// * `module_ids` - A slice of ModuleIds to create empty modules for +/// +/// # Returns +/// The number of modules successfully added to the cache +pub(crate) fn populate_guard_with_modules( + guard: &mut AptosModuleCacheManagerGuard<'_>, + module_ids: &[ModuleId], +) { + for module_id in module_ids { + // Create an empty module for testing with Module::new_for_test + let module = Module::new_for_test(module_id.clone()); + + // Serialize the module + let mut serialized_bytes = Vec::new(); + module + .serialize(&mut serialized_bytes) + .expect("Failed to serialize compiled module"); + + // Create a ModuleCode::verified instance with the module + let module_code = Arc::new(ModuleCode::from_arced_verified( + Arc::new(module), + Arc::new(AptosModuleExtension::new(StateValue::new_legacy( + serialized_bytes.into(), + ))), + )); + + // Add the module to the cache + guard + .module_cache_mut() + .insert(module_id.clone(), module_code); + } +} + +pub(crate) fn execute_block_parallel( + executor_thread_pool: Arc, + block_gas_limit: Option, + txn_provider: &Provider, + data_view: &ViewType, + all_module_ids: Option<&[ModuleId]>, +) -> Result, MockEvent>>, ()> +where + TxnType: Transaction> + Debug + Clone + Send + Sync + 'static, + ViewType: TStateView + Sync + 'static, + Provider: TxnProvider + Sync + 'static, + MockTask, MockEvent>: ExecutorTask, +{ + let mut guard = AptosModuleCacheManagerGuard::none(); + + // If all_module_ids is provided, populate the guard with empty modules + if let Some(module_ids) = all_module_ids { + populate_guard_with_modules(&mut guard, module_ids); + } + + let config = BlockExecutorConfig::new_maybe_block_limit(num_cpus::get(), block_gas_limit); + + BlockExecutor::< + TxnType, + MockTask, MockEvent>, + ViewType, + NoOpTransactionCommitHook, MockEvent>, usize>, + Provider, + >::new(config, executor_thread_pool, None) + .execute_transactions_parallel( + txn_provider, + data_view, + &TransactionSliceMetadata::unknown(), + &mut guard, + ) +} + +pub(crate) fn generate_universe_and_transactions( + runner: &mut TestRunner, + universe_size: usize, + transaction_count: usize, + is_dynamic: bool, +) -> (Vec<[u8; 32]>, Vec>) { + let universe = vec(any::<[u8; 32]>(), universe_size) + .new_tree(runner) + .expect("creating universe should succeed") + .current(); + + let transaction_strategy = if is_dynamic { + vec( + any_with::>(TransactionGenParams::new_dynamic()), + transaction_count, + ) + } else { + vec(any::>(), transaction_count) + }; + + let transaction_gen = transaction_strategy + .new_tree(runner) + .expect("creating transactions should succeed") + .current(); + + (universe, transaction_gen) +} + +pub(crate) fn run_transactions_resources( + universe_size: usize, + transaction_count: usize, + abort_count: usize, + skip_rest_count: usize, + use_gas_limit: bool, + is_dynamic: bool, + num_executions: usize, + num_random_generations: usize, +) { + let executor_thread_pool = create_executor_thread_pool(); + let mut runner = TestRunner::default(); + + let gas_limits = get_gas_limit_variants(use_gas_limit, transaction_count); + for maybe_block_gas_limit in gas_limits { + // Run the test cases directly + for _ in 0..num_random_generations { + // Generate universe and transactions + let (universe, transaction_gen) = generate_universe_and_transactions( + &mut runner, + universe_size, + transaction_count, + is_dynamic, + ); + + // Generate abort and skip_rest transaction indices + let abort_strategy = vec(any::(), abort_count); + let skip_rest_strategy = vec(any::(), skip_rest_count); + + let abort_transactions = abort_strategy + .new_tree(&mut runner) + .expect("creating abort transactions should succeed") + .current(); + + let skip_rest_transactions = skip_rest_strategy + .new_tree(&mut runner) + .expect("creating skip_rest transactions should succeed") + .current(); + + // Create transactions + let mut transactions: Vec, MockEvent>> = + transaction_gen + .into_iter() + .map(|txn_gen| txn_gen.materialize(&universe)) + .collect(); + + // Apply modifications to transactions + let length = transactions.len(); + for i in abort_transactions { + *transactions.get_mut(i.index(length)).unwrap() = MockTransaction::Abort; + } + for i in skip_rest_transactions { + *transactions.get_mut(i.index(length)).unwrap() = MockTransaction::SkipRest(0); + } + + let txn_provider = DefaultTxnProvider::new(transactions); + let state_view = MockStateView::empty(); + for _ in 0..num_executions { + let output = execute_block_parallel::< + MockTransaction, MockEvent>, + MockStateView>, + DefaultTxnProvider, MockEvent>>, + >( + executor_thread_pool.clone(), + maybe_block_gas_limit, + &txn_provider, + &state_view, + None, + ); + + BaselineOutput::generate(txn_provider.get_txns(), maybe_block_gas_limit) + .assert_parallel_output(&output); + } + } + } +} + +// Regular tests with 2 repetitions +#[test_case(100, 4000, 0, 0, false, false, 2, 15; "no_early_termination")] +#[test_case(100, 4000, 0, 0, true, false, 2, 15; "no_early_termination_with_block_gas_limit")] +#[test_case(100, 4000, 1000, 0, false, false, 2, 15; "abort_only")] +#[test_case(100, 4000, 1000, 0, true, false, 2, 15; "abort_only_with_block_gas_limit")] +#[test_case(80, 300, 0, 5, false, false, 2, 15; "skip_rest_only")] +#[test_case(80, 300, 0, 5, true, false, 2, 15; "skip_rest_only_with_block_gas_limit")] +#[test_case(100, 5000, 5, 5, false, false, 2, 15; "mixed_transactions")] +#[test_case(100, 5000, 5, 5, true, false, 2, 15; "mixed_transactions_with_block_gas_limit")] +// Dynamic tests with 2 repetitions +#[test_case(100, 3000, 3, 3, false, true, 2, 15; "dynamic_read_writes_mixed")] +#[test_case(100, 3000, 3, 3, true, true, 2, 15; "dynamic_read_writes_mixed_with_block_gas_limit")] +// Dynamic tests with 5 repetitions +#[test_case(100, 3000, 0, 0, false, true, 5, 15; "dynamic_read_writes")] +#[test_case(100, 3000, 0, 0, true, true, 5, 15; "dynamic_read_writes_with_block_gas_limit")] +// Dynamic contended tests with 5 repetitions +#[test_case(10, 1000, 0, 0, false, true, 5, 15; "dynamic_read_writes_contended")] +#[test_case(10, 1000, 0, 0, true, true, 5, 15; "dynamic_read_writes_contended_with_block_gas_limit")] +fn resource_transaction_tests( + universe_size: usize, + transaction_count: usize, + abort_count: usize, + skip_rest_count: usize, + use_gas_limit: bool, + is_dynamic: bool, + num_executions: usize, + num_random_generations: usize, +) { + run_transactions_resources( + universe_size, + transaction_count, + abort_count, + skip_rest_count, + use_gas_limit, + is_dynamic, + num_executions, + num_random_generations, + ); +} diff --git a/aptos-move/block-executor/src/proptest_types/tests.rs b/aptos-move/block-executor/src/proptest_types/tests.rs deleted file mode 100644 index cf38694168a..00000000000 --- a/aptos-move/block-executor/src/proptest_types/tests.rs +++ /dev/null @@ -1,726 +0,0 @@ -// Copyright © Aptos Foundation -// Parts of the project are originally copyright © Meta Platforms, Inc. -// SPDX-License-Identifier: Apache-2.0 - -use crate::{ - code_cache_global_manager::AptosModuleCacheManagerGuard, - errors::SequentialBlockExecutionError, - executor::BlockExecutor, - proptest_types::{ - baseline::BaselineOutput, - types::{ - DeltaDataView, KeyType, MockEvent, MockOutput, MockTask, MockTransaction, - NonEmptyGroupDataView, TransactionGen, TransactionGenParams, MAX_GAS_PER_TXN, - }, - }, - txn_commit_hook::NoOpTransactionCommitHook, - txn_provider::default::DefaultTxnProvider, -}; -use aptos_types::{ - block_executor::{ - config::BlockExecutorConfig, transaction_slice_metadata::TransactionSliceMetadata, - }, - contract_event::TransactionEvent, - state_store::MockStateView, -}; -use claims::{assert_matches, assert_ok}; -use num_cpus; -use proptest::{ - collection::vec, - prelude::*, - sample::Index, - strategy::{Strategy, ValueTree}, - test_runner::TestRunner, -}; -use rand::Rng; -use std::{cmp::max, fmt::Debug, hash::Hash, marker::PhantomData, sync::Arc}; -use test_case::test_case; - -fn run_transactions( - key_universe: &[K], - transaction_gens: Vec>, - abort_transactions: Vec, - skip_rest_transactions: Vec, - num_repeat: usize, - module_access: (bool, bool), - maybe_block_gas_limit: Option, -) where - K: Hash + Clone + Debug + Eq + Send + Sync + PartialOrd + Ord + 'static, - V: Clone + Eq + Send + Sync + Arbitrary + 'static, - E: Send + Sync + Debug + Clone + TransactionEvent + 'static, - Vec: From, -{ - let mut transactions: Vec<_> = transaction_gens - .into_iter() - .map(|txn_gen| txn_gen.materialize(key_universe, module_access)) - .collect(); - - let length = transactions.len(); - for i in abort_transactions { - *transactions.get_mut(i.index(length)).unwrap() = MockTransaction::Abort; - } - for i in skip_rest_transactions { - *transactions.get_mut(i.index(length)).unwrap() = MockTransaction::SkipRest(0); - } - - let state_view = MockStateView::empty(); - - let executor_thread_pool = Arc::new( - rayon::ThreadPoolBuilder::new() - .num_threads(num_cpus::get()) - .build() - .unwrap(), - ); - - let txn_provider = DefaultTxnProvider::new(transactions); - for _ in 0..num_repeat { - let mut guard = AptosModuleCacheManagerGuard::none(); - - let output = BlockExecutor::< - MockTransaction, E>, - MockTask, E>, - MockStateView>, - NoOpTransactionCommitHook, E>, usize>, - DefaultTxnProvider, E>>, - >::new( - BlockExecutorConfig::new_maybe_block_limit(num_cpus::get(), maybe_block_gas_limit), - executor_thread_pool.clone(), - None, - ) - .execute_transactions_parallel( - &txn_provider, - &state_view, - &TransactionSliceMetadata::unknown(), - &mut guard, - ); - - if module_access.0 && module_access.1 { - assert_matches!(output, Err(())); - continue; - } - - BaselineOutput::generate(txn_provider.get_txns(), maybe_block_gas_limit) - .assert_parallel_output(&output); - } -} - -proptest! { - #![proptest_config(ProptestConfig::with_cases(32))] - #[test] - fn no_early_termination( - universe in vec(any::<[u8; 32]>(), 100), - transaction_gen in vec(any::>(), 4000).no_shrink(), - abort_transactions in vec(any::(), 0), - skip_rest_transactions in vec(any::(), 0), - ) { - run_transactions::<[u8; 32], [u8; 32], MockEvent>(&universe, transaction_gen, abort_transactions, skip_rest_transactions, 1, (false, false), None); - } - - #[test] - fn abort_only( - universe in vec(any::<[u8; 32]>(), 80), - transaction_gen in vec(any::>(), 300).no_shrink(), - abort_transactions in vec(any::(), 5), - skip_rest_transactions in vec(any::(), 0), - ) { - run_transactions::<[u8; 32], [u8; 32], MockEvent>(&universe, transaction_gen, abort_transactions, skip_rest_transactions, 1, (false, false), None); - } - - #[test] - fn skip_rest_only( - universe in vec(any::<[u8; 32]>(), 80), - transaction_gen in vec(any::>(), 300).no_shrink(), - abort_transactions in vec(any::(), 0), - skip_rest_transactions in vec(any::(), 5), - ) { - run_transactions::<[u8; 32], [u8; 32], MockEvent>(&universe, transaction_gen, abort_transactions, skip_rest_transactions, 1, (false, false), None); - } - - #[test] - fn mixed_transactions( - universe in vec(any::<[u8; 32]>(), 100), - transaction_gen in vec(any::>(), 5000).no_shrink(), - abort_transactions in vec(any::(), 5), - skip_rest_transactions in vec(any::(), 5), - ) { - run_transactions::<[u8; 32], [u8; 32], MockEvent>(&universe, transaction_gen, abort_transactions, skip_rest_transactions, 1, (false, false), None); - } - - #[test] - fn dynamic_read_writes_mixed( - universe in vec(any::<[u8; 32]>(), 100), - transaction_gen in vec(any_with::>(TransactionGenParams::new_dynamic()), 3000).no_shrink(), - abort_transactions in vec(any::(), 3), - skip_rest_transactions in vec(any::(), 3), - ) { - run_transactions::<[u8; 32], [u8; 32], MockEvent>(&universe, transaction_gen, abort_transactions, skip_rest_transactions, 1, (false, false), None); - } -} - -fn dynamic_read_writes_with_block_gas_limit(num_txns: usize, maybe_block_gas_limit: Option) { - let mut runner = TestRunner::default(); - - let universe = vec(any::<[u8; 32]>(), 100) - .new_tree(&mut runner) - .expect("creating a new value should succeed") - .current(); - let transaction_gen = vec( - any_with::>(TransactionGenParams::new_dynamic()), - num_txns, - ) - .new_tree(&mut runner) - .expect("creating a new value should succeed") - .current(); - - run_transactions::<[u8; 32], [u8; 32], MockEvent>( - &universe, - transaction_gen, - vec![], - vec![], - 100, - (false, false), - maybe_block_gas_limit, - ); -} - -fn deltas_writes_mixed_with_block_gas_limit(num_txns: usize, maybe_block_gas_limit: Option) { - let mut runner = TestRunner::default(); - - let universe = vec(any::<[u8; 32]>(), 50) - .new_tree(&mut runner) - .expect("creating a new value should succeed") - .current(); - let transaction_gen = vec( - any_with::>(TransactionGenParams::new_dynamic()), - num_txns, - ) - .new_tree(&mut runner) - .expect("creating a new value should succeed") - .current(); - - // Do not allow deletions as resolver can't apply delta to a deleted aggregator. - let transactions: Vec<_> = transaction_gen - .into_iter() - .map(|txn_gen| txn_gen.materialize_with_deltas(&universe, 15, false)) - .collect(); - let txn_provider = DefaultTxnProvider::new(transactions); - - let data_view = DeltaDataView::> { - phantom: PhantomData, - }; - - let executor_thread_pool = Arc::new( - rayon::ThreadPoolBuilder::new() - .num_threads(num_cpus::get()) - .build() - .unwrap(), - ); - - for _ in 0..20 { - let mut guard = AptosModuleCacheManagerGuard::none(); - - let output = BlockExecutor::< - MockTransaction, MockEvent>, - MockTask, MockEvent>, - DeltaDataView>, - NoOpTransactionCommitHook, MockEvent>, usize>, - DefaultTxnProvider, MockEvent>>, - >::new( - BlockExecutorConfig::new_maybe_block_limit(num_cpus::get(), maybe_block_gas_limit), - executor_thread_pool.clone(), - None, - ) - .execute_transactions_parallel( - &txn_provider, - &data_view, - &TransactionSliceMetadata::unknown(), - &mut guard, - ); - - BaselineOutput::generate(txn_provider.get_txns(), maybe_block_gas_limit) - .assert_parallel_output(&output); - } -} - -fn deltas_resolver_with_block_gas_limit(num_txns: usize, maybe_block_gas_limit: Option) { - let mut runner = TestRunner::default(); - - let universe = vec(any::<[u8; 32]>(), 50) - .new_tree(&mut runner) - .expect("creating a new value should succeed") - .current(); - let transaction_gen = vec( - any_with::>(TransactionGenParams::new_dynamic()), - num_txns, - ) - .new_tree(&mut runner) - .expect("creating a new value should succeed") - .current(); - - let data_view = DeltaDataView::> { - phantom: PhantomData, - }; - - // Do not allow deletes as that would panic in resolver. - let transactions: Vec<_> = transaction_gen - .into_iter() - .map(|txn_gen| txn_gen.materialize_with_deltas(&universe, 15, false)) - .collect(); - let txn_provider = DefaultTxnProvider::new(transactions); - - let executor_thread_pool = Arc::new( - rayon::ThreadPoolBuilder::new() - .num_threads(num_cpus::get()) - .build() - .unwrap(), - ); - - for _ in 0..20 { - let mut guard = AptosModuleCacheManagerGuard::none(); - - let output = BlockExecutor::< - MockTransaction, MockEvent>, - MockTask, MockEvent>, - DeltaDataView>, - NoOpTransactionCommitHook, MockEvent>, usize>, - DefaultTxnProvider, MockEvent>>, - >::new( - BlockExecutorConfig::new_maybe_block_limit(num_cpus::get(), maybe_block_gas_limit), - executor_thread_pool.clone(), - None, - ) - .execute_transactions_parallel( - &txn_provider, - &data_view, - &TransactionSliceMetadata::unknown(), - &mut guard, - ); - - BaselineOutput::generate(txn_provider.get_txns(), maybe_block_gas_limit) - .assert_parallel_output(&output); - } -} - -fn dynamic_read_writes_contended_with_block_gas_limit( - num_txns: usize, - maybe_block_gas_limit: Option, -) { - let mut runner = TestRunner::default(); - - let universe = vec(any::<[u8; 32]>(), 10) - .new_tree(&mut runner) - .expect("creating a new value should succeed") - .current(); - - let transaction_gen = vec( - any_with::>(TransactionGenParams::new_dynamic()), - num_txns, - ) - .new_tree(&mut runner) - .expect("creating a new value should succeed") - .current(); - - run_transactions::<[u8; 32], [u8; 32], MockEvent>( - &universe, - transaction_gen, - vec![], - vec![], - 100, - (false, false), - maybe_block_gas_limit, - ); -} - -fn publishing_fixed_params_with_block_gas_limit( - num_txns: usize, - maybe_block_gas_limit: Option, -) { - let mut runner = TestRunner::default(); - - let universe = vec(any::<[u8; 32]>(), 50) - .new_tree(&mut runner) - .expect("creating a new value should succeed") - .current(); - let transaction_gen = vec( - any_with::>(TransactionGenParams::new_dynamic()), - num_txns, - ) - .new_tree(&mut runner) - .expect("creating a new value should succeed") - .current(); - let indices = vec(any::(), 4) - .new_tree(&mut runner) - .expect("creating a new value should succeed") - .current(); - - // First 12 keys are normal paths, next 14 are module reads, then writes. - let mut transactions: Vec<_> = transaction_gen - .into_iter() - .map(|txn_gen| txn_gen.materialize_disjoint_module_rw(&universe[0..40], 12, 26)) - .collect(); - - // Adjust the writes of txn indices[0] to contain module write to key 42. - let w_index = indices[0].index(num_txns); - match transactions.get_mut(w_index).unwrap() { - MockTransaction::Write { - incarnation_counter: _, - incarnation_behaviors, - } => { - incarnation_behaviors.iter_mut().for_each(|behavior| { - assert!(!behavior.writes.is_empty()); - let insert_idx = indices[1].index(behavior.writes.len()); - let val = behavior.writes[0].1.clone(); - behavior - .writes - .insert(insert_idx, (KeyType(universe[42], true), val)); - }); - }, - _ => { - unreachable!(); - }, - }; - - let data_view = DeltaDataView::> { - phantom: PhantomData, - }; - - let executor_thread_pool = Arc::new( - rayon::ThreadPoolBuilder::new() - .num_threads(num_cpus::get()) - .build() - .unwrap(), - ); - - let txn_provider = DefaultTxnProvider::new(transactions.clone()); - // Confirm still no intersection - let mut guard = AptosModuleCacheManagerGuard::none(); - let output = BlockExecutor::< - MockTransaction, MockEvent>, - MockTask, MockEvent>, - DeltaDataView>, - NoOpTransactionCommitHook, MockEvent>, usize>, - DefaultTxnProvider, MockEvent>>, - >::new( - BlockExecutorConfig::new_maybe_block_limit(num_cpus::get(), maybe_block_gas_limit), - executor_thread_pool, - None, - ) - .execute_transactions_parallel( - &txn_provider, - &data_view, - &TransactionSliceMetadata::unknown(), - &mut guard, - ); - assert_ok!(output); - - // Adjust the reads of txn indices[2] to contain module read to key 42. - let r_index = indices[2].index(num_txns); - match transactions.get_mut(r_index).unwrap() { - MockTransaction::Write { - incarnation_counter: _, - incarnation_behaviors, - } => { - incarnation_behaviors.iter_mut().for_each(|behavior| { - assert!(!behavior.reads.is_empty()); - let insert_idx = indices[3].index(behavior.reads.len()); - behavior - .reads - .insert(insert_idx, KeyType(universe[42], true)); - }); - }, - _ => { - unreachable!(); - }, - }; - - let executor_thread_pool = Arc::new( - rayon::ThreadPoolBuilder::new() - .num_threads(num_cpus::get()) - .build() - .unwrap(), - ); - - let txn_provider = DefaultTxnProvider::new(transactions); - for _ in 0..200 { - let mut guard = AptosModuleCacheManagerGuard::none(); - - let output = BlockExecutor::< - MockTransaction, MockEvent>, - MockTask, MockEvent>, - DeltaDataView>, - NoOpTransactionCommitHook, MockEvent>, usize>, - DefaultTxnProvider, MockEvent>>, - >::new( - BlockExecutorConfig::new_maybe_block_limit( - num_cpus::get(), - Some(max(w_index, r_index) as u64 * MAX_GAS_PER_TXN + 1), - ), - executor_thread_pool.clone(), - None, - ) // Ensure enough gas limit to commit the module txns (4 is maximum gas per txn) - .execute_transactions_parallel( - &txn_provider, - &data_view, - &TransactionSliceMetadata::unknown(), - &mut guard, - ); - - assert_matches!(output, Err(())); - } -} - -#[test_case(1000, 100, 30, 15, 0)] -#[test_case(1000, 50, 20, 10, 0)] -#[test_case(1000, 15, 5, 5, 0)] -#[test_case(1000, 20, 10, 5, 1)] -#[test_case(1000, 20, 10, 5, 2)] -#[test_case(1000, 20, 10, 5, 3)] -#[test_case(1000, 20, 10, 5, 4)] -fn non_empty_group( - num_txns: usize, - key_universe_len: usize, - num_repeat_parallel: usize, - num_repeat_sequential: usize, - group_size_testing: usize, -) { - let mut runner = TestRunner::default(); - - let key_universe = vec(any::<[u8; 32]>(), key_universe_len) - .new_tree(&mut runner) - .expect("creating a new value should succeed") - .current(); - - let transaction_gen = vec( - any_with::>(TransactionGenParams::new_dynamic()), - num_txns, - ) - .new_tree(&mut runner) - .expect("creating a new value should succeed") - .current(); - - // Determines the probability that any given incarnation of an executed txn will query - // the size of a given group (3 groups). - let group_size_pcts = match group_size_testing { - 0 => [None, None, None], - 1 => [Some(30), None, None], - 2 => [Some(80), None, None], - 3 => [Some(30), Some(80), None], - 4 => [Some(30), Some(50), Some(70)], - _ => unreachable!("Unexpected test configuration"), - }; - - let transactions: Vec<_> = transaction_gen - .into_iter() - .map(|txn_gen| { - txn_gen.materialize_groups::<[u8; 32], MockEvent>(&key_universe, group_size_pcts) - }) - .collect(); - let txn_provider = DefaultTxnProvider::new(transactions); - - let data_view = NonEmptyGroupDataView::> { - group_keys: key_universe[(key_universe_len - 3)..key_universe_len] - .iter() - .map(|k| KeyType(*k, false)) - .collect(), - }; - - let executor_thread_pool = Arc::new( - rayon::ThreadPoolBuilder::new() - .num_threads(num_cpus::get()) - .build() - .unwrap(), - ); - - for _ in 0..num_repeat_parallel { - let mut guard = AptosModuleCacheManagerGuard::none(); - - let output = BlockExecutor::< - MockTransaction, MockEvent>, - MockTask, MockEvent>, - NonEmptyGroupDataView>, - NoOpTransactionCommitHook, MockEvent>, usize>, - DefaultTxnProvider, MockEvent>>, - >::new( - BlockExecutorConfig::new_no_block_limit(num_cpus::get()), - executor_thread_pool.clone(), - None, - ) - .execute_transactions_parallel( - &txn_provider, - &data_view, - &TransactionSliceMetadata::unknown(), - &mut guard, - ); - - BaselineOutput::generate(txn_provider.get_txns(), None).assert_parallel_output(&output); - } - - for _ in 0..num_repeat_sequential { - let mut guard = AptosModuleCacheManagerGuard::none(); - - let output = BlockExecutor::< - MockTransaction, MockEvent>, - MockTask, MockEvent>, - NonEmptyGroupDataView>, - NoOpTransactionCommitHook, MockEvent>, usize>, - DefaultTxnProvider, MockEvent>>, - >::new( - BlockExecutorConfig::new_no_block_limit(num_cpus::get()), - executor_thread_pool.clone(), - None, - ) - .execute_transactions_sequential( - &txn_provider, - &data_view, - &TransactionSliceMetadata::unknown(), - &mut guard, - false, - ); - // TODO: test dynamic disabled as well. - - BaselineOutput::generate(txn_provider.get_txns(), None).assert_output(&output.map_err( - |e| match e { - SequentialBlockExecutionError::ResourceGroupSerializationError => { - panic!("Unexpected error") - }, - SequentialBlockExecutionError::ErrorToReturn(err) => err, - }, - )); - } -} - -#[test] -fn dynamic_read_writes() { - dynamic_read_writes_with_block_gas_limit(3000, None); -} - -#[test] -fn deltas_writes_mixed() { - deltas_writes_mixed_with_block_gas_limit(1000, None); -} - -#[test] -fn deltas_resolver() { - deltas_resolver_with_block_gas_limit(1000, None); -} - -#[test] -fn dynamic_read_writes_contended() { - dynamic_read_writes_contended_with_block_gas_limit(1000, None); -} - -// TODO(loader_v2): Fix this test. -#[test] -#[ignore] -// Test a single transaction intersection interleaves with a lot of dependencies and -// not overlapping module r/w keys. -fn module_publishing_races() { - for _ in 0..5 { - publishing_fixed_params_with_block_gas_limit(300, None); - } -} - -// The following set of tests are the same tests as above with per-block gas limit. -proptest! { - #![proptest_config(ProptestConfig::with_cases(32))] - #[test] - fn no_early_termination_with_block_gas_limit( - universe in vec(any::<[u8; 32]>(), 100), - transaction_gen in vec(any::>(), 5000).no_shrink(), - abort_transactions in vec(any::(), 0), - skip_rest_transactions in vec(any::(), 0), - ) { - run_transactions::<[u8; 32], [u8; 32], MockEvent>(&universe, transaction_gen, abort_transactions, skip_rest_transactions, 1, (false, false), Some(rand::thread_rng().gen_range(0, 5000 * MAX_GAS_PER_TXN / 2))); - } - - #[test] - fn abort_only_with_block_gas_limit( - universe in vec(any::<[u8; 32]>(), 100), - transaction_gen in vec(any::>(), 10).no_shrink(), - abort_transactions in vec(any::(), 5), - skip_rest_transactions in vec(any::(), 0), - ) { - run_transactions::<[u8; 32], [u8; 32], MockEvent>(&universe, transaction_gen, abort_transactions, skip_rest_transactions, 1, (false, false), Some(rand::thread_rng().gen_range(0, 10 * MAX_GAS_PER_TXN / 2))); - } - - #[test] - fn skip_rest_only_with_block_gas_limit( - universe in vec(any::<[u8; 32]>(), 100), - transaction_gen in vec(any::>(), 5000).no_shrink(), - abort_transactions in vec(any::(), 0), - skip_rest_transactions in vec(any::(), 5), - ) { - run_transactions::<[u8; 32], [u8; 32], MockEvent>(&universe, transaction_gen, abort_transactions, skip_rest_transactions, 1, (false, false), Some(rand::thread_rng().gen_range(0, 5000 * MAX_GAS_PER_TXN / 2))); - } - - #[test] - fn mixed_transactions_with_block_gas_limit( - universe in vec(any::<[u8; 32]>(), 100), - transaction_gen in vec(any::>(), 5000).no_shrink(), - abort_transactions in vec(any::(), 5), - skip_rest_transactions in vec(any::(), 5), - ) { - run_transactions::<[u8; 32], [u8; 32], MockEvent>(&universe, transaction_gen, abort_transactions, skip_rest_transactions, 1, (false, false), Some(rand::thread_rng().gen_range(0, 5000 * MAX_GAS_PER_TXN / 2))); - } - - #[test] - fn dynamic_read_writes_mixed_with_block_gas_limit( - universe in vec(any::<[u8; 32]>(), 100), - transaction_gen in vec(any_with::>(TransactionGenParams::new_dynamic()), 5000).no_shrink(), - abort_transactions in vec(any::(), 3), - skip_rest_transactions in vec(any::(), 3), - ) { - run_transactions::<[u8; 32], [u8; 32], MockEvent>(&universe, transaction_gen, abort_transactions, skip_rest_transactions, 1, (false, false), Some(rand::thread_rng().gen_range(0, 5000 * MAX_GAS_PER_TXN / 2))); - } -} - -#[test] -fn dynamic_read_writes_with_block_gas_limit_test() { - dynamic_read_writes_with_block_gas_limit( - 3000, - // TODO: here and below, use proptest randomness, not thread_rng. - Some(rand::thread_rng().gen_range(0, 3000) as u64), - ); - dynamic_read_writes_with_block_gas_limit(3000, Some(0)); -} - -#[test] -fn deltas_writes_mixed_with_block_gas_limit_test() { - deltas_writes_mixed_with_block_gas_limit( - 1000, - Some(rand::thread_rng().gen_range(0, 1000) as u64), - ); - deltas_writes_mixed_with_block_gas_limit(1000, Some(0)); -} - -#[test] -fn deltas_resolver_with_block_gas_limit_test() { - deltas_resolver_with_block_gas_limit( - 1000, - Some(rand::thread_rng().gen_range(0, 1000 * MAX_GAS_PER_TXN / 2)), - ); - deltas_resolver_with_block_gas_limit(1000, Some(0)); -} - -#[test] -fn dynamic_read_writes_contended_with_block_gas_limit_test() { - dynamic_read_writes_contended_with_block_gas_limit( - 1000, - Some(rand::thread_rng().gen_range(0, 1000) as u64), - ); - dynamic_read_writes_contended_with_block_gas_limit(1000, Some(0)); -} - -// TODO(loader_v2): Fix this test. -#[test] -#[ignore] -// Test a single transaction intersection interleaves with a lot of dependencies and -// not overlapping module r/w keys. -fn module_publishing_races_with_block_gas_limit_test() { - for _ in 0..5 { - publishing_fixed_params_with_block_gas_limit( - 300, - Some(rand::thread_rng().gen_range(0, 300 * MAX_GAS_PER_TXN / 2)), - ); - } -} diff --git a/aptos-move/block-executor/src/proptest_types/types.rs b/aptos-move/block-executor/src/proptest_types/types.rs index cfed8fdfa68..9afc9c24dec 100644 --- a/aptos-move/block-executor/src/proptest_types/types.rs +++ b/aptos-move/block-executor/src/proptest_types/types.rs @@ -2,19 +2,11 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use crate::task::{ExecutionStatus, ExecutorTask, TransactionOutput}; -use aptos_aggregator::{ - delayed_change::DelayedChange, - delta_change_set::{delta_add, delta_sub, serialize, DeltaOp}, - resolver::TAggregatorV1View, -}; -use aptos_mvhashmap::types::TxnIndex; +use aptos_aggregator::delta_change_set::{delta_add, delta_sub, serialize, DeltaOp}; use aptos_types::{ account_address::AccountAddress, contract_event::TransactionEvent, - error::PanicError, executable::ModulePath, - fee_statement::FeeStatement, on_chain_config::CurrentTimeMicroseconds, state_store::{ errors::StateViewError, @@ -23,26 +15,17 @@ use aptos_types::{ StateViewId, TStateView, }, transaction::BlockExecutableTransaction as Transaction, - write_set::{TransactionWrite, WriteOp, WriteOpKind}, -}; -use aptos_vm_environment::environment::AptosEnvironment; -use aptos_vm_types::{ - module_and_script_storage::code_storage::AptosCodeStorage, - module_write_set::ModuleWrite, - resolver::{ - BlockSynchronizationKillSwitch, ResourceGroupSize, TExecutorView, TResourceGroupView, - }, - resource_group_adapter::{ - decrement_size_for_remove_tag, group_tagged_resource_size, increment_size_for_add_tag, - }, + write_set::{TransactionWrite, WriteOpKind}, }; +use aptos_vm_types::module_write_set::ModuleWrite; use bytes::Bytes; -use claims::{assert_ge, assert_le, assert_ok}; +use claims::{assert_ge, assert_le}; use move_core_types::{ - ident_str, identifier::IdentStr, language_storage::ModuleId, value::MoveTypeLayout, + identifier::{IdentStr, Identifier}, + language_storage::ModuleId, }; -use move_vm_types::delayed_values::delayed_field_id::DelayedFieldID; -use once_cell::sync::OnceCell; +use move_vm_runtime::Module; +use move_vm_types::delayed_values::delayed_field_id::{DelayedFieldID, ExtractUniqueIndex}; use proptest::{arbitrary::Arbitrary, collection::vec, prelude::*, proptest, sample::Index}; use proptest_derive::Arbitrary; use std::{ @@ -50,10 +33,7 @@ use std::{ fmt::Debug, hash::{Hash, Hasher}, marker::PhantomData, - sync::{ - atomic::{AtomicUsize, Ordering}, - Arc, - }, + sync::{atomic::AtomicUsize, Arc}, }; // Should not be possible to overflow or underflow, as each delta is at most 100 in the tests. @@ -92,27 +72,49 @@ where pub(crate) struct NonEmptyGroupDataView { pub(crate) group_keys: HashSet, + // When we are testing with delayed fields, currently deletion is not supported, + // so we need to return for each key that can contain a delayed field. for groups, + // the reserved tag is the only such key, and we simply return a value for all + // non-group keys to ensure the test runs. + pub(crate) delayed_field_testing: bool, +} + +pub(crate) fn default_group_map() -> BTreeMap { + let bytes: Bytes = bcs::to_bytes(&( + STORAGE_AGGREGATOR_VALUE, + // u32::MAX represents storage version. + u32::MAX, + )) + .unwrap() + .into(); + + BTreeMap::from([(RESERVED_TAG, bytes)]) } impl TStateView for NonEmptyGroupDataView where - K: PartialOrd + Ord + Send + Sync + Clone + Hash + Eq + ModulePath + 'static, + K: Debug + PartialOrd + Ord + Send + Sync + Clone + Hash + Eq + ModulePath + 'static, { type Key = K; // Contains mock storage value with a non-empty group (w. value at RESERVED_TAG). fn get_state_value(&self, key: &K) -> Result, StateViewError> { - if self.group_keys.contains(key) { - let group: BTreeMap = BTreeMap::from([(RESERVED_TAG, vec![0].into())]); - - let bytes = bcs::to_bytes(&group).unwrap(); - Ok(Some(StateValue::new_with_metadata( - bytes.into(), - raw_metadata(5), - ))) - } else { - Ok(None) - } + Ok(self + .group_keys + .contains(key) + .then(|| { + let bytes = bcs::to_bytes(&default_group_map()).unwrap(); + StateValue::new_with_metadata(bytes.into(), raw_metadata(5)) + }) + .or_else(|| { + self.delayed_field_testing.then(|| { + StateValue::new_legacy(serialize_delayed_field_tuple(&( + STORAGE_AGGREGATOR_VALUE, + // u32::MAX represents storage version. + u32::MAX, + ))) + }) + })) } fn id(&self) -> StateViewId { @@ -132,16 +134,11 @@ where pub(crate) struct KeyType( /// Wrapping the types used for testing to add ModulePath trait implementation (below). pub K, - /// The bool field determines for testing purposes, whether the key will be interpreted - /// as a module access path. In this case, if a module path is both read and written - /// during parallel execution, ModulePathReadWrite must be returned and the - /// block execution must fall back to the sequential execution. - pub bool, ); impl ModulePath for KeyType { fn is_module_path(&self) -> bool { - self.1 + false } fn from_address_and_module_name(_address: &AccountAddress, _module_name: &IdentStr) -> Self { @@ -150,7 +147,7 @@ impl ModulePath for KeyType } // TODO: this is now very similar to WriteOp, should be a wrapper and remove boilerplate below. -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] pub(crate) struct ValueType { /// Wrapping the types used for testing to add TransactionWrite trait implementation (below). bytes: Option, @@ -267,15 +264,15 @@ impl TransactionWrite for ValueType { } fn set_bytes(&mut self, bytes: Bytes) { - self.bytes = bytes.into(); + self.bytes = Some(bytes); } } #[derive(Clone, Copy)] pub(crate) struct TransactionGenParams { - /// Each transaction's read-set consists of between 1 and read_size-1 many reads. + /// Each transaction's read-set consists of between 1 and read_size many reads. read_size: usize, - /// Each mock execution will produce between 1 and output_size-1 many writes and deltas. + /// Each mock execution will produce between 1 and output_size many writes and deltas. output_size: usize, /// The number of different incarnation behaviors that a mock execution of the transaction /// may exhibit. For instance, incarnation_alternatives = 1 corresponds to a "static" @@ -289,13 +286,13 @@ pub(crate) struct TransactionGenParams { pub(crate) struct TransactionGen> + Arbitrary + Clone + Debug + Eq + 'static> { /// Generate keys for possible read-sets of the transaction based on the above parameters. #[proptest( - strategy = "vec(vec(any::(), 1..params.read_size), params.incarnation_alternatives)" + strategy = "vec(vec(any::(), 1..=params.read_size), params.incarnation_alternatives)" )] reads: Vec>, /// Generate keys and values for possible write-sets based on above transaction gen parameters. /// Based on how the test is configured, some of these "writes" will convert to deltas. #[proptest( - strategy = "vec(vec((any::(), any::()), 1..params.output_size), \ + strategy = "vec(vec((any::(), any::()), 1..=params.output_size), \ params.incarnation_alternatives)" )] modifications: Vec>, @@ -322,18 +319,31 @@ pub(crate) struct TransactionGen> + Arbitrary + Clone + Debug + /// first and also records the latest incarnations of each transaction (that is committed). /// Then we can generate the baseline by sequentially executing the behavior prescribed for /// those latest incarnations. +/// +/// TODO(BlockSTMv2): Mock incarnation & behavior generation should also be separated out +/// and refactored into e.g. a builder pattern. In particular, certain materialization methods +/// transform generated resource reads and writes into group or module reads and writes. +/// It would be more natural to maintain an internal builder state of the mock transaction +/// generation process and then finalize it into the desired format. Additionally, the +/// internal fields should contain structs instead of less readable tuples. #[derive(Clone, Debug)] pub(crate) struct MockIncarnation { /// A vector of keys to be read during mock incarnation execution. - pub(crate) reads: Vec, + /// bool indicates that the path contains deltas, i.e. AggregatorV1 or DelayedFields. + pub(crate) resource_reads: Vec<(K, bool)>, /// A vector of keys and corresponding values to be written during mock incarnation execution. - pub(crate) writes: Vec<(K, ValueType)>, - pub(crate) group_reads: Vec<(K, u32)>, - pub(crate) group_writes: Vec<(K, StateValueMetadata, HashMap)>, + /// bool indicates that the path contains deltas, i.e. AggregatorV1 or DelayedFields. + pub(crate) resource_writes: Vec<(K, ValueType, bool)>, + pub(crate) group_reads: Vec<(K, u32, bool)>, + pub(crate) group_writes: Vec<(K, StateValueMetadata, HashMap)>, + // For testing get_module_or_build_with and insert_verified_module interfaces. + pub(crate) module_reads: Vec, + pub(crate) module_writes: Vec>, /// Keys to query group size for - false is querying size, true is querying metadata. pub(crate) group_queries: Vec<(K, bool)>, - /// A vector of keys and corresponding deltas to be produced during mock incarnation execution. - pub(crate) deltas: Vec<(K, DeltaOp)>, + /// A vector of keys and corresponding deltas to be produced during mock incarnation + /// execution. For delayed fields in groups, the Option is set to Some(tag). + pub(crate) deltas: Vec<(K, DeltaOp, Option)>, /// A vector of events. pub(crate) events: Vec, metadata_seeds: [u64; 3], @@ -346,19 +356,21 @@ impl MockIncarnation { /// into another one with group_reads / group_writes / group_queries set. Hence, the constructor /// here always sets it to an empty vector. pub(crate) fn new_with_metadata_seeds( - reads: Vec, - writes: Vec<(K, ValueType)>, - deltas: Vec<(K, DeltaOp)>, + resource_reads: Vec<(K, bool)>, + resource_writes: Vec<(K, ValueType, bool)>, + deltas: Vec<(K, DeltaOp, Option)>, events: Vec, metadata_seeds: [u64; 3], gas: u64, ) -> Self { Self { - reads, - writes, + resource_reads, + resource_writes, group_reads: vec![], group_writes: vec![], group_queries: vec![], + module_reads: vec![], + module_writes: vec![], deltas, events, metadata_seeds, @@ -367,18 +379,20 @@ impl MockIncarnation { } pub(crate) fn new( - reads: Vec, - writes: Vec<(K, ValueType)>, - deltas: Vec<(K, DeltaOp)>, + resource_reads: Vec<(K, bool)>, + resource_writes: Vec<(K, ValueType, bool)>, + deltas: Vec<(K, DeltaOp, Option)>, events: Vec, gas: u64, ) -> Self { Self { - reads, - writes, + resource_reads, + resource_writes, group_reads: vec![], group_writes: vec![], group_queries: vec![], + module_reads: vec![], + module_writes: vec![], deltas, events, metadata_seeds: [0; 3], @@ -387,6 +401,13 @@ impl MockIncarnation { } } +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub(crate) enum DeltaTestKind { + DelayedFields, + AggregatorV1, + None, +} + /// A mock transaction that could be used to test the correctness and throughput of the system. /// To test transaction behavior where reads and writes might be dynamic (depend on previously /// read values), different read and writes sets are generated and used depending on the incarnation @@ -403,6 +424,8 @@ pub(crate) enum MockTransaction { /// A vector of mock behaviors prescribed for each incarnation of the transaction, chosen /// round robin depending on the incarnation counter value). incarnation_behaviors: Vec>, + /// If we are testing with deltas, are we testing delayed_fields? (or AggregatorV1). + delta_test_kind: DeltaTestKind, }, /// Skip the execution of trailing transactions. SkipRest(u64), @@ -415,6 +438,7 @@ impl MockTransaction { Self::Write { incarnation_counter: Arc::new(AtomicUsize::new(0)), incarnation_behaviors: vec![behavior], + delta_test_kind: DeltaTestKind::None, } } @@ -422,7 +446,28 @@ impl MockTransaction { Self::Write { incarnation_counter: Arc::new(AtomicUsize::new(0)), incarnation_behaviors: behaviors, + delta_test_kind: DeltaTestKind::None, + } + } + + pub(crate) fn with_delayed_fields_testing(mut self) -> Self { + if let Self::Write { + delta_test_kind, .. + } = &mut self + { + *delta_test_kind = DeltaTestKind::DelayedFields; + } + self + } + + pub(crate) fn with_aggregator_v1_testing(mut self) -> Self { + if let Self::Write { + delta_test_kind, .. + } = &mut self + { + *delta_test_kind = DeltaTestKind::AggregatorV1; } + self } pub(crate) fn into_behaviors(self) -> Vec> { @@ -464,34 +509,104 @@ impl TransactionGenParams { incarnation_alternatives: 5, } } + + // The read and write will be converted to a module read and write. + pub fn new_dynamic_modules_only() -> Self { + TransactionGenParams { + read_size: 1, + output_size: 1, + incarnation_alternatives: 5, + } + } + + // Last read and write will be converted to module reads and writes. + pub fn new_dynamic_with_modules() -> Self { + TransactionGenParams { + read_size: 3, + output_size: 3, + incarnation_alternatives: 5, + } + } } impl Default for TransactionGenParams { fn default() -> Self { TransactionGenParams { read_size: 10, - output_size: 5, + output_size: 1, incarnation_alternatives: 1, } } } -// TODO: move generation to separate file. -// TODO: consider adding writes to reads (read-before-write). Similar behavior to the Move-VM -// and may force more testing (since we check read results). +/// A simple enum to represent either a write or a delta operation result +enum WriteDeltaVariant { + Write(W), + Delta(D), +} + +fn is_delta_on(index: usize, delta_threshold: Option) -> bool { + delta_threshold.is_some_and(|threshold| threshold <= index) +} + impl> + Arbitrary + Clone + Debug + Eq + Sync + Send> TransactionGen { + /// Determines whether to generate a delta operation or a write operation based on parameters + /// + /// # Arguments + /// * `is_delta_path` - attempt to generate a delta value first + /// * `value` - The value to process + /// * `delta_threshold` - All indices below this threshold will be writes (not deltas) + /// * `allow_deletes` - Whether deletion operations are allowed + /// + /// # Returns + /// Either a delta operation or a write operation with its is_aggregator_v1 flag + fn generate_write_or_delta( + is_delta_path: bool, + value: &V, + key: KeyType, + allow_deletes: bool, + ) -> WriteDeltaVariant<(KeyType, ValueType), (KeyType, DeltaOp)> { + // First check if this should be a delta + if is_delta_path { + let val_u128 = ValueType::from_value(value.clone(), true) + .as_u128() + .unwrap() + .unwrap(); + + // Not all values become deltas - some remain as normal writes + if val_u128 % 10 != 0 { + let delta = if val_u128 % 10 < 5 { + delta_sub(val_u128 % 100, u128::MAX) + } else { + delta_add(val_u128 % 100, u128::MAX) + }; + return WriteDeltaVariant::Delta((key, delta)); + } + } + + // Otherwise create a normal write + let val_u128 = ValueType::from_value(value.clone(), true) + .as_u128() + .unwrap() + .unwrap(); + let is_deletion = allow_deletes && val_u128 % 23 == 0; + let mut write_value = ValueType::from_value(value.clone(), !is_deletion); + write_value.metadata = raw_metadata((val_u128 >> 64) as u64); + + WriteDeltaVariant::Write((key, write_value)) + } + fn writes_and_deltas_from_gen( // TODO: disentangle writes and deltas. universe: &[K], gen: Vec>, - module_write_fn: &dyn Fn(usize) -> bool, - delta_fn: &dyn Fn(usize, &V) -> Option, allow_deletes: bool, + delta_threshold: Option, ) -> Vec<( - /* writes = */ Vec<(KeyType, ValueType)>, + /* writes = */ Vec<(KeyType, ValueType, bool)>, /* deltas = */ Vec<(KeyType, DeltaOp)>, )> { - let mut ret = vec![]; + let mut ret = Vec::with_capacity(gen.len()); for write_gen in gen.into_iter() { let mut keys_modified = BTreeSet::new(); let mut incarnation_writes = vec![]; @@ -501,18 +616,19 @@ impl> + Arbitrary + Clone + Debug + Eq + Sync + Send> Transactio let key = universe[i].clone(); if !keys_modified.contains(&key) { keys_modified.insert(key.clone()); - match delta_fn(i, &value) { - Some(delta) => incarnation_deltas.push((KeyType(key, false), delta)), - None => { - // One out of 23 writes will be a deletion - let val_u128 = ValueType::from_value(value.clone(), true) - .as_u128() - .unwrap() - .unwrap(); - let is_deletion = allow_deletes && val_u128 % 23 == 0; - let mut value = ValueType::from_value(value.clone(), !is_deletion); - value.metadata = raw_metadata((val_u128 >> 64) as u64); - incarnation_writes.push((KeyType(key, module_write_fn(i)), value)); + + let is_delta_path = is_delta_on(i, delta_threshold); + match Self::generate_write_or_delta( + is_delta_path, + &value, + KeyType(key), + allow_deletes, + ) { + WriteDeltaVariant::Write((key, value)) => { + incarnation_writes.push((key, value, is_delta_path)); + }, + WriteDeltaVariant::Delta((key, delta)) => { + incarnation_deltas.push((key, delta)); }, } } @@ -525,15 +641,15 @@ impl> + Arbitrary + Clone + Debug + Eq + Sync + Send> Transactio fn reads_from_gen( universe: &[K], gen: Vec>, - module_read_fn: &dyn Fn(usize) -> bool, - ) -> Vec>> { + delta_threshold: Option, + ) -> Vec, bool)>> { let mut ret = vec![]; for read_gen in gen.into_iter() { - let mut incarnation_reads: Vec> = vec![]; + let mut incarnation_reads: Vec<(KeyType, bool)> = vec![]; for idx in read_gen.into_iter() { let i = idx.index(universe.len()); let key = universe[i].clone(); - incarnation_reads.push(KeyType(key, module_read_fn(i))); + incarnation_reads.push((KeyType(key), is_delta_on(i, delta_threshold))); } ret.push(incarnation_reads); } @@ -569,20 +685,17 @@ impl> + Arbitrary + Clone + Debug + Eq + Sync + Send> Transactio >( self, universe: &[K], - module_read_fn: &dyn Fn(usize) -> bool, - module_write_fn: &dyn Fn(usize) -> bool, - delta_fn: &dyn Fn(usize, &V) -> Option, allow_deletes: bool, + delta_threshold: Option, ) -> MockTransaction, E> { - let reads = Self::reads_from_gen(universe, self.reads, &module_read_fn); + let reads = Self::reads_from_gen(universe, self.reads, delta_threshold); let gas = Self::gas_from_gen(self.gas); let behaviors = Self::writes_and_deltas_from_gen( universe, self.modifications, - &module_write_fn, - &delta_fn, allow_deletes, + delta_threshold, ) .into_iter() .zip(reads) @@ -603,7 +716,11 @@ impl> + Arbitrary + Clone + Debug + Eq + Sync + Send> Transactio MockIncarnation::new_with_metadata_seeds( reads, writes, - deltas, + // materialize_groups sets the Option to a tag as needed. + deltas + .into_iter() + .map(|(k, delta)| (k, delta, None)) + .collect(), vec![], // events metadata_seeds, gas, @@ -620,22 +737,43 @@ impl> + Arbitrary + Clone + Debug + Eq + Sync + Send> Transactio >( self, universe: &[K], - // Are writes and reads module access (same access path). - module_access: (bool, bool), ) -> MockTransaction, E> { - let is_module_read = |_| -> bool { module_access.1 }; - let is_module_write = |_| -> bool { module_access.0 }; - let is_delta = |_, _: &V| -> Option { None }; - // Module deletion isn't allowed. - let allow_deletes = !(module_access.0 || module_access.1); + self.new_mock_write_txn(universe, true, None) + } - self.new_mock_write_txn( - universe, - &is_module_read, - &is_module_write, - &is_delta, - allow_deletes, - ) + pub(crate) fn materialize_modules< + K: Clone + Hash + Debug + Eq + Ord, + E: Send + Sync + Debug + Clone + TransactionEvent, + >( + self, + universe: &[K], + ) -> MockTransaction, E> { + let universe_len = universe.len(); + + let mut behaviors = self + .new_mock_write_txn(universe, false, None) + .into_behaviors(); + + behaviors.iter_mut().for_each(|behavior| { + // Handle writes + let (key_to_convert, mut value, _) = behavior.resource_writes.pop().unwrap(); + let module_id = key_to_mock_module_id(&key_to_convert, universe_len); + + // Serialize a module and store it in bytes so deserialization can succeed. + let mut serialized_bytes = vec![]; + Module::new_for_test(module_id.clone()) + .serialize(&mut serialized_bytes) + .expect("Failed to serialize compiled module"); + value.bytes = Some(serialized_bytes.into()); + + behavior.module_writes = vec![ModuleWrite::new(module_id, value)]; + + // Handle reads. + let (key_to_convert, _) = behavior.resource_reads.pop().unwrap(); + behavior.module_reads = vec![key_to_mock_module_id(&key_to_convert, universe_len)]; + }); + + MockTransaction::from_behaviors(behaviors) } // Generates a mock txn without group reads/writes and converts it to have group @@ -647,27 +785,18 @@ impl> + Arbitrary + Clone + Debug + Eq + Sync + Send> Transactio self, universe: &[K], group_size_query_pcts: [Option; 3], + delta_threshold: Option, ) -> MockTransaction, E> { let universe_len = universe.len(); assert_ge!(universe_len, 3, "Universe must have size >= 3"); - let is_module_read = |_| -> bool { false }; - let is_module_write = |_| -> bool { false }; - let is_delta = |_, _: &V| -> Option { None }; - let group_size_query_indicators = Self::group_size_indicator_from_gen(self.group_size_indicators.clone()); let mut behaviors = self - .new_mock_write_txn( - &universe[0..universe.len() - 3], - &is_module_read, - &is_module_write, - &is_delta, - false, - ) + .new_mock_write_txn(&universe[0..universe.len() - 3], false, delta_threshold) .into_behaviors(); - let key_to_group = |key: &KeyType| -> Option<(usize, u32)> { + let key_to_group = |key: &KeyType| -> Option<(usize, u32, bool)> { let mut hasher = DefaultHasher::new(); key.hash(&mut hasher); let bytes = hasher.finish().to_be_bytes(); @@ -676,55 +805,93 @@ impl> + Arbitrary + Clone + Debug + Eq + Sync + Send> Transactio let group_key_idx = bytes[1] % 4; - (group_key_idx < 3).then_some((group_key_idx as usize, tag)) + // 3/4 of the time key will map to group - rest are normal resource accesses. + (group_key_idx < 3).then_some((group_key_idx as usize, tag, group_key_idx > 0)) }; for (behavior_idx, behavior) in behaviors.iter_mut().enumerate() { let mut reads = vec![]; let mut group_reads = vec![]; - for read_key in behavior.reads.clone() { - assert!(read_key != KeyType(universe[universe_len - 1].clone(), false)); - assert!(read_key != KeyType(universe[universe_len - 2].clone(), false)); - assert!(read_key != KeyType(universe[universe_len - 3].clone(), false)); + for (read_key, contains_delta) in behavior.resource_reads.clone() { + assert!(read_key != KeyType(universe[universe_len - 1].clone())); + assert!(read_key != KeyType(universe[universe_len - 2].clone())); + assert!(read_key != KeyType(universe[universe_len - 3].clone())); match key_to_group(&read_key) { - Some((idx, tag)) => group_reads.push(( - KeyType(universe[universe_len - 1 - idx].clone(), false), - tag, - )), - None => reads.push(read_key), + Some((idx, tag, has_delayed_field)) => { + // Custom logic for has_delayed_fields for groups: shadowing + // the flag of the original read. + group_reads.push(( + KeyType(universe[universe_len - 1 - idx].clone()), + tag, + // Reserved tag is configured to have delayed fields. + has_delayed_field && tag == RESERVED_TAG && delta_threshold.is_some(), + )) + }, + None => reads.push((read_key, contains_delta)), } } let mut writes = vec![]; let mut group_writes = vec![]; let mut inner_ops = vec![HashMap::new(); 3]; - for (write_key, value) in behavior.writes.clone() { + for (write_key, value, has_delayed_field) in behavior.resource_writes.clone() { match key_to_group(&write_key) { - Some((key_idx, tag)) => { + Some((key_idx, tag, has_delayed_field)) => { + // Same shadowing of has_delayed_field variable and logic as above. if tag != RESERVED_TAG || !value.is_deletion() { - inner_ops[key_idx].insert(tag, value); + inner_ops[key_idx] + .insert(tag, (value, has_delayed_field && tag == RESERVED_TAG)); } }, - None => writes.push((write_key, value)), + None => { + writes.push((write_key, value, has_delayed_field)); + }, } } for (idx, inner_ops) in inner_ops.into_iter().enumerate() { if !inner_ops.is_empty() { group_writes.push(( - KeyType(universe[universe_len - 1 - idx].clone(), false), + KeyType(universe[universe_len - 1 - idx].clone()), raw_metadata(behavior.metadata_seeds[idx]), inner_ops, )); } } - // Group test does not handle deltas (different view, no default storage value). - assert!(behavior.deltas.is_empty()); - behavior.reads = reads; - behavior.writes = writes; + // Group test does not handle deltas for aggregator v1(different view, no default + // storage value). However, it does handle deltas (added below) for delayed fields. + assert!(delta_threshold.is_some() || behavior.deltas.is_empty()); + behavior.resource_reads = reads; + behavior.resource_writes = writes; behavior.group_reads = group_reads; behavior.group_writes = group_writes; + if delta_threshold.is_some() { + // TODO: We can have a threshold over which we create a delta for RESERVED_TAG, + // because currently only RESERVED_TAG in a group contains a delayed field. + let mut delta_for_keys = [false; 3]; + behavior.deltas = behavior + .deltas + .iter() + .filter_map(|(key, delta, maybe_tag)| { + if let Some((idx, _, has_delayed_field)) = key_to_group(key) { + if has_delayed_field && !delta_for_keys[idx] { + delta_for_keys[idx] = true; + Some(( + KeyType(universe[universe_len - 1 - idx].clone()), + *delta, + Some(RESERVED_TAG), + )) + } else { + None + } + } else { + Some((key.clone(), *delta, *maybe_tag)) + } + }) + .collect(); + } + behavior.group_queries = group_size_query_pcts .iter() .enumerate() @@ -739,7 +906,7 @@ impl> + Arbitrary + Clone + Debug + Eq + Sync + Send> Transactio }; (indicator < *size_query_pct).then(|| { ( - KeyType(universe[universe_len - 1 - idx].clone(), false), + KeyType(universe[universe_len - 1 - idx].clone()), // TODO: handle metadata queries more uniformly w. size. indicator % 2 == 0, ) @@ -750,7 +917,13 @@ impl> + Arbitrary + Clone + Debug + Eq + Sync + Send> Transactio .collect(); } - MockTransaction::from_behaviors(behaviors) + // When delayed fields are not enabled, the flag is ignored, so we can always + // set with_delayed_fields here. + if delta_threshold.is_some() { + MockTransaction::from_behaviors(behaviors).with_delayed_fields_testing() + } else { + MockTransaction::from_behaviors(behaviors) + } } pub(crate) fn materialize_with_deltas< @@ -762,294 +935,9 @@ impl> + Arbitrary + Clone + Debug + Eq + Sync + Send> Transactio delta_threshold: usize, allow_deletes: bool, ) -> MockTransaction, E> { - let is_module_read = |_| -> bool { false }; - let is_module_write = |_| -> bool { false }; - let is_delta = |i, v: &V| -> Option { - if i >= delta_threshold { - let val = ValueType::from_value(v.clone(), true) - .as_u128() - .unwrap() - .unwrap(); - if val % 10 == 0 { - None - } else if val % 10 < 5 { - Some(delta_sub(val % 100, u128::MAX)) - } else { - Some(delta_add(val % 100, u128::MAX)) - } - } else { - None - } - }; - - self.new_mock_write_txn( - universe, - &is_module_read, - &is_module_write, - &is_delta, - allow_deletes, - ) - } - - pub(crate) fn materialize_disjoint_module_rw< - K: Clone + Hash + Debug + Eq + Ord, - E: Send + Sync + Debug + Clone + TransactionEvent, - >( - self, - universe: &[K], - // keys generated with indices from read_threshold to write_threshold will be - // treated as module access only in reads. keys generated with indices from - // write threshold to universe.len() will be treated as module access only in - // writes. This way there will be module accesses but no intersection. - read_threshold: usize, - write_threshold: usize, - ) -> MockTransaction, E> { - assert!(read_threshold < universe.len()); - assert!(write_threshold > read_threshold); - assert!(write_threshold < universe.len()); - - let is_module_read = |i| -> bool { i >= read_threshold && i < write_threshold }; - let is_module_write = |i| -> bool { i >= write_threshold }; - let is_delta = |_, _: &V| -> Option { None }; - - self.new_mock_write_txn( - universe, - &is_module_read, - &is_module_write, - &is_delta, - false, // Module deletion isn't allowed - ) - } -} - -/////////////////////////////////////////////////////////////////////////// -// Mock transaction executor implementation. -/////////////////////////////////////////////////////////////////////////// - -pub(crate) struct MockTask { - phantom_data: PhantomData<(K, E)>, -} - -impl MockTask { - pub fn new() -> Self { - Self { - phantom_data: PhantomData, - } - } -} - -impl ExecutorTask for MockTask -where - K: PartialOrd + Ord + Send + Sync + Clone + Hash + Eq + ModulePath + Debug + 'static, - E: Send + Sync + Debug + Clone + TransactionEvent + 'static, -{ - type Error = usize; - type Output = MockOutput; - type Txn = MockTransaction; - - fn init(_environment: &AptosEnvironment, _state_view: &impl TStateView) -> Self { - Self::new() - } - - fn execute_transaction( - &self, - view: &(impl TExecutorView - + TResourceGroupView - + AptosCodeStorage - + BlockSynchronizationKillSwitch), - txn: &Self::Txn, - txn_idx: TxnIndex, - ) -> ExecutionStatus { - match txn { - MockTransaction::Write { - incarnation_counter, - incarnation_behaviors, - } => { - // Use incarnation counter value as an index to determine the read- - // and write-sets of the execution. Increment incarnation counter to - // simulate dynamic behavior when there are multiple possible read- - // and write-sets (i.e. each are selected round-robin). - let idx = incarnation_counter.fetch_add(1, Ordering::SeqCst); - - let behavior = &incarnation_behaviors[idx % incarnation_behaviors.len()]; - - // Reads - let mut read_results = vec![]; - for k in behavior.reads.iter() { - // TODO: later test errors as well? (by fixing state_view behavior). - // TODO: test aggregator reads. - if !k.is_module_path() { - // TODO: also prop test modules - match view.get_resource_bytes(k, None) { - Ok(v) => read_results.push(v.map(Into::into)), - Err(_) => read_results.push(None), - } - } - } - // Read from groups. - // TODO: also read group sizes (if there are any group reads). - for (group_key, resource_tag) in behavior.group_reads.iter() { - match view.get_resource_from_group(group_key, resource_tag, None) { - Ok(v) => read_results.push(v.map(Into::into)), - Err(_) => read_results.push(None), - } - } - - let read_group_size_or_metadata = behavior - .group_queries - .iter() - .map(|(group_key, query_metadata)| { - let res = if *query_metadata { - GroupSizeOrMetadata::Metadata( - view.get_resource_state_value_metadata(group_key) - .expect("Group must exist and size computation must succeed"), - ) - } else { - GroupSizeOrMetadata::Size( - view.resource_group_size(group_key) - .expect("Group must exist and size computation must succeed") - .get(), - ) - }; - - (group_key.clone(), res) - }) - .collect(); - - let mut group_writes = vec![]; - for (key, metadata, inner_ops) in behavior.group_writes.iter() { - let mut new_inner_ops = HashMap::new(); - let group_size = view.resource_group_size(key).unwrap(); - let mut new_group_size = view.resource_group_size(key).unwrap(); - for (tag, inner_op) in inner_ops.iter() { - let exists = view - .get_resource_from_group(key, tag, None) - .unwrap() - .is_some(); - assert!( - *tag != RESERVED_TAG || exists, - "RESERVED_TAG must always be present in groups in tests" - ); - - // inner op is either deletion or creation. - assert!(!inner_op.is_modification()); - - let maybe_op = if exists { - Some( - if inner_op.is_creation() - && (inner_op.bytes().unwrap()[0] % 4 < 3 - || *tag == RESERVED_TAG) - { - ValueType::new( - inner_op.bytes.clone(), - StateValueMetadata::none(), - WriteOpKind::Modification, - ) - } else { - ValueType::new( - None, - StateValueMetadata::none(), - WriteOpKind::Deletion, - ) - }, - ) - } else { - inner_op.is_creation().then(|| inner_op.clone()) - }; - - if let Some(new_inner_op) = maybe_op { - if exists { - let old_tagged_value_size = - view.resource_size_in_group(key, tag).unwrap(); - let old_size = - group_tagged_resource_size(tag, old_tagged_value_size).unwrap(); - // let _ = - // decrement_size_for_remove_tag(&mut new_group_size, old_size); - if decrement_size_for_remove_tag(&mut new_group_size, old_size) - .is_err() - { - // Check it only happens for speculative executions that may not - // commit by returning incorrect (empty) output. - return ExecutionStatus::Success(MockOutput::skip_output()); - } - } - if !new_inner_op.is_deletion() { - let new_size = group_tagged_resource_size( - tag, - inner_op.bytes.as_ref().unwrap().len(), - ) - .unwrap(); - if increment_size_for_add_tag(&mut new_group_size, new_size) - .is_err() - { - // Check it only happens for speculative executions that may not - // commit by returning incorrect (empty) output. - return ExecutionStatus::Success(MockOutput::skip_output()); - } - } - - new_inner_ops.insert(*tag, new_inner_op); - } - } - - if !new_inner_ops.is_empty() { - if group_size.get() > 0 - && new_group_size == ResourceGroupSize::zero_combined() - { - // TODO: reserved tag currently prevents this code from being run. - // Group got deleted. - group_writes.push(( - key.clone(), - ValueType::new(None, metadata.clone(), WriteOpKind::Deletion), - new_group_size, - new_inner_ops, - )); - } else { - let op_kind = if group_size.get() == 0 { - WriteOpKind::Creation - } else { - WriteOpKind::Modification - }; - - // Not testing metadata_op here, always modification. - group_writes.push(( - key.clone(), - ValueType::new(Some(Bytes::new()), metadata.clone(), op_kind), - new_group_size, - new_inner_ops, - )); - } - } - } - - // generate group_writes. - ExecutionStatus::Success(MockOutput { - writes: behavior.writes.clone(), - group_writes, - deltas: behavior.deltas.clone(), - events: behavior.events.to_vec(), - read_results, - read_group_size_or_metadata, - materialized_delta_writes: OnceCell::new(), - total_gas: behavior.gas, - skipped: false, - }) - }, - MockTransaction::SkipRest(gas) => { - let mut mock_output = MockOutput::skip_output(); - mock_output.total_gas = *gas; - ExecutionStatus::SkipRest(mock_output) - }, - MockTransaction::Abort => ExecutionStatus::Abort(txn_idx as usize), - MockTransaction::InterruptRequested => { - while !view.interrupt_requested() {} - ExecutionStatus::SkipRest(MockOutput::skip_output()) - }, - } - } - - fn is_transaction_dynamic_change_set_capable(_txn: &Self::Txn) -> bool { - true + // Enable delta generation for this specific method + self.new_mock_write_txn(universe, allow_deletes, Some(delta_threshold)) + .with_aggregator_v1_testing() } } @@ -1063,232 +951,92 @@ pub(crate) enum GroupSizeOrMetadata { Metadata(Option), } -#[derive(Debug)] -pub(crate) struct MockOutput { - pub(crate) writes: Vec<(K, ValueType)>, - // Key, metadata_op, inner_ops - pub(crate) group_writes: Vec<(K, ValueType, ResourceGroupSize, HashMap)>, - pub(crate) deltas: Vec<(K, DeltaOp)>, - pub(crate) events: Vec, - pub(crate) read_results: Vec>>, - pub(crate) read_group_size_or_metadata: Vec<(K, GroupSizeOrMetadata)>, - pub(crate) materialized_delta_writes: OnceCell>, - pub(crate) total_gas: u64, - pub(crate) skipped: bool, +// Utility function to convert a key to a mock module ID. It hashes the key +// to compute a consistent mock account address, with a fixed "test" module name. +pub(crate) fn key_to_mock_module_id( + key: &KeyType, + universe_len: usize, +) -> ModuleId { + let mut hasher = DefaultHasher::new(); + key.hash(&mut hasher); + let idx = (hasher.finish() % universe_len as u64) as usize; + let mut addr = [0u8; AccountAddress::LENGTH]; + addr[AccountAddress::LENGTH - 1] = idx as u8; + addr[AccountAddress::LENGTH - 2] = (idx >> 8) as u8; + ModuleId::new(AccountAddress::new(addr), Identifier::new("test").unwrap()) } -impl TransactionOutput for MockOutput -where - K: PartialOrd + Ord + Send + Sync + Clone + Hash + Eq + ModulePath + Debug + 'static, - E: Send + Sync + Debug + Clone + TransactionEvent + 'static, -{ - type Txn = MockTransaction; - - // TODO[agg_v2](tests): Assigning MoveTypeLayout as None for all the writes for now. - // That means, the resources do not have any DelayedFields embedded in them. - // Change it to test resources with DelayedFields as well. - fn resource_write_set(&self) -> Vec<(K, Arc, Option>)> { - self.writes - .iter() - .filter(|(k, _)| !k.is_module_path()) - .cloned() - .map(|(k, v)| (k, Arc::new(v), None)) - .collect() - } - - fn module_write_set(&self) -> BTreeMap> { - self.writes - .iter() - .filter(|(k, _)| k.is_module_path()) - .map(|(k, v)| { - let dummy_id = ModuleId::new(AccountAddress::ONE, ident_str!("dummy").to_owned()); - let write = ModuleWrite::new(dummy_id, v.clone()); - (k.clone(), write) - }) - .collect() - } - - // Aggregator v1 writes are included in resource_write_set for tests (writes are produced - // for all keys including ones for v1_aggregators without distinguishing). - fn aggregator_v1_write_set(&self) -> BTreeMap { - BTreeMap::new() - } - - fn aggregator_v1_delta_set(&self) -> Vec<(K, DeltaOp)> { - self.deltas.clone() - } - - fn delayed_field_change_set(&self) -> BTreeMap> { - // TODO[agg_v2](tests): add aggregators V2 to the proptest? - BTreeMap::new() - } - - fn reads_needing_delayed_field_exchange( - &self, - ) -> Vec<( - ::Key, - StateValueMetadata, - Arc, - )> { - // TODO[agg_v2](tests): add aggregators V2 to the proptest? - Vec::new() - } - - fn group_reads_needing_delayed_field_exchange( - &self, - ) -> Vec<(::Key, StateValueMetadata)> { - // TODO[agg_v2](tests): add aggregators V2 to the proptest? - Vec::new() - } - - // TODO[agg_v2](tests): Currently, appending None to all events, which means none of the - // events have aggregators. Test it with aggregators as well. - fn get_events(&self) -> Vec<(E, Option)> { - self.events.iter().map(|e| (e.clone(), None)).collect() - } - - // TODO[agg_v2](cleanup) Using the concrete type layout here. Should we find a way to use generics? - fn resource_group_write_set( - &self, - ) -> Vec<( - K, - ValueType, - ResourceGroupSize, - BTreeMap>)>, - )> { - self.group_writes - .iter() - .cloned() - .map(|(group_key, metadata_v, group_size, inner_ops)| { - ( - group_key, - metadata_v, - group_size, - inner_ops.into_iter().map(|(k, v)| (k, (v, None))).collect(), - ) - }) - .collect() - } - - fn skip_output() -> Self { - Self { - writes: vec![], - group_writes: vec![], - deltas: vec![], - events: vec![], - read_results: vec![], - read_group_size_or_metadata: vec![], - materialized_delta_writes: OnceCell::new(), - total_gas: 0, - skipped: true, - } - } - - fn discard_output(_discard_code: move_core_types::vm_status::StatusCode) -> Self { - Self { - writes: vec![], - group_writes: vec![], - deltas: vec![], - events: vec![], - read_results: vec![], - read_group_size_or_metadata: vec![], - materialized_delta_writes: OnceCell::new(), - total_gas: 0, - skipped: true, - } - } - - fn materialize_agg_v1( - &self, - _view: &impl TAggregatorV1View::Key>, - ) { - // TODO[agg_v2](tests): implement this method and compare - // against sequential execution results v. aggregator v1. - } - - fn incorporate_materialized_txn_output( - &self, - aggregator_v1_writes: Vec<(::Key, WriteOp)>, - patched_resource_write_set: Vec<( - ::Key, - ::Value, - )>, - _patched_events: Vec<::Event>, - ) -> Result<(), PanicError> { - let resources: HashMap<::Key, ::Value> = - patched_resource_write_set.clone().into_iter().collect(); - for (key, _, size, _) in &self.group_writes { - let v = resources.get(key).unwrap(); - if v.is_deletion() { - assert_eq!(*size, ResourceGroupSize::zero_combined()); - } else { - assert_eq!( - size.get(), - resources.get(key).unwrap().bytes().map_or(0, |b| b.len()) as u64 - ); - } - } - - assert_ok!(self.materialized_delta_writes.set(aggregator_v1_writes)); - // TODO[agg_v2](tests): Set the patched resource write set and events. But that requires the function - // to take &mut self as input - Ok(()) - } - - fn set_txn_output_for_non_dynamic_change_set(&self) { - // TODO[agg_v2](tests): anything to be added here for tests? - } - - fn fee_statement(&self) -> FeeStatement { - // First argument is supposed to be total (not important for the test though). - // Next two arguments are different kinds of execution gas that are counted - // towards the block limit. We split the total into two pieces for these arguments. - // TODO: add variety to generating fee statement based on total gas. - FeeStatement::new( - self.total_gas, - self.total_gas / 2, - (self.total_gas + 1) / 2, - 0, - 0, - ) - } - - fn is_retry(&self) -> bool { - self.skipped - } +// ID is just the unique index as u128. +pub(crate) fn serialize_from_delayed_field_u128(value_or_id: u128, version: u32) -> Bytes { + let tuple = (value_or_id, version); + serialize_delayed_field_tuple(&tuple) +} - fn has_new_epoch_event(&self) -> bool { - false - } +pub(crate) fn serialize_from_delayed_field_id( + delayed_field_id: DelayedFieldID, + version: u32, +) -> Bytes { + let tuple = (delayed_field_id.extract_unique_index() as u128, version); + serialize_delayed_field_tuple(&tuple) +} - fn output_approx_size(&self) -> u64 { - // TODO add block output limit testing - 0 - } +fn serialize_delayed_field_tuple(value: &(u128, u32)) -> Bytes { + bcs::to_bytes(value) + .expect("Failed to serialize (u128, u32) tuple") + .into() +} - fn get_write_summary( - &self, - ) -> HashSet< - crate::types::InputOutputKey< - ::Key, - ::Tag, - >, - > { - HashSet::new() - } +/// The width of the delayed field is not used in the tests, and fixed as 8 for +/// all delayed field constructions. However, only the real ID is actually +/// serialized and deserialized (together with the version). +pub(crate) fn deserialize_to_delayed_field_u128(bytes: &[u8]) -> Result<(u128, u32), bcs::Error> { + bcs::from_bytes::<(u128, u32)>(bytes) } -#[derive(Clone, Debug)] -pub(crate) struct MockEvent { - event_data: Vec, +pub(crate) fn deserialize_to_delayed_field_id( + bytes: &[u8], +) -> Result<(DelayedFieldID, u32), bcs::Error> { + let (id, version) = bcs::from_bytes::<(u128, u32)>(bytes)?; + Ok((DelayedFieldID::from((id as u32, 8)), version)) } -impl TransactionEvent for MockEvent { - fn get_event_data(&self) -> &[u8] { - &self.event_data +#[cfg(test)] +mod tests { + use super::*; + use test_case::test_case; + + #[test_case((0u128, 0u32) ; "zero values")] + #[test_case((1u128, 42u32) ; "small values")] + #[test_case((u128::MAX, u32::MAX) ; "maximum values")] + #[test_case((12345678u128, 87654321u32) ; "large values")] + fn test_serialize_deserialize_delayed_field_tuple(tuple: (u128, u32)) { + // Serialize and then deserialize + let serialized = serialize_delayed_field_tuple(&tuple); + let deserialized = deserialize_to_delayed_field_u128(&serialized).unwrap(); + + assert_eq!( + tuple, deserialized, + "Serialization/deserialization failed for tuple ({}, {})", + tuple.0, tuple.1 + ); } - fn set_event_data(&mut self, event_data: Vec) { - self.event_data = event_data; + #[test] + fn test_deserialize_delayed_field_tuple_invalid_data() { + // Test with invalid data that's too short + let invalid_data = vec![1, 2, 3]; + let result = deserialize_to_delayed_field_u128(&invalid_data); + assert!( + result.is_err(), + "Expected deserialization to fail with too short data" + ); + + // Test with empty data + let empty_data: Vec = vec![]; + let result = deserialize_to_delayed_field_u128(&empty_data); + assert!( + result.is_err(), + "Expected deserialization to fail with empty data" + ); } } diff --git a/aptos-move/block-executor/src/task.rs b/aptos-move/block-executor/src/task.rs index 9af3d0c6136..5964d57f905 100644 --- a/aptos-move/block-executor/src/task.rs +++ b/aptos-move/block-executor/src/task.rs @@ -109,9 +109,7 @@ pub trait TransactionOutput: Send + Sync + Debug { Option>, )>; - fn module_write_set( - &self, - ) -> BTreeMap<::Key, ModuleWrite<::Value>>; + fn module_write_set(&self) -> Vec::Value>>; fn aggregator_v1_write_set( &self, diff --git a/aptos-move/block-executor/src/txn_last_input_output.rs b/aptos-move/block-executor/src/txn_last_input_output.rs index 37b29dfe488..78970276ab7 100644 --- a/aptos-move/block-executor/src/txn_last_input_output.rs +++ b/aptos-move/block-executor/src/txn_last_input_output.rs @@ -26,7 +26,7 @@ use move_core_types::{language_storage::ModuleId, value::MoveTypeLayout}; use move_vm_runtime::Module; use move_vm_types::delayed_values::delayed_field_id::DelayedFieldID; use std::{ - collections::{BTreeMap, HashSet}, + collections::HashSet, fmt::Debug, iter::{empty, Iterator}, sync::Arc, @@ -258,10 +258,7 @@ impl, E: Debug + Send + Clone> }) } - pub(crate) fn module_write_set( - &self, - txn_idx: TxnIndex, - ) -> BTreeMap> { + pub(crate) fn module_write_set(&self, txn_idx: TxnIndex) -> Vec> { use ExecutionStatus as E; match self.outputs[txn_idx as usize] @@ -275,7 +272,7 @@ impl, E: Debug + Send + Clone> | E::DelayedFieldsCodeInvariantError(_) | E::SpeculativeExecutionAbortError(_), ) - | None => BTreeMap::new(), + | None => Vec::new(), } } diff --git a/aptos-move/block-executor/src/unit_tests/mod.rs b/aptos-move/block-executor/src/unit_tests/mod.rs index 3bba06ce546..4c5996fb1ef 100644 --- a/aptos-move/block-executor/src/unit_tests/mod.rs +++ b/aptos-move/block-executor/src/unit_tests/mod.rs @@ -10,9 +10,10 @@ use crate::{ executor::BlockExecutor, proptest_types::{ baseline::BaselineOutput, + mock_executor::{MockEvent, MockOutput, MockTask}, types::{ - DeltaDataView, KeyType, MockEvent, MockIncarnation, MockOutput, MockTask, - MockTransaction, NonEmptyGroupDataView, ValueType, + DeltaDataView, KeyType, MockIncarnation, MockTransaction, NonEmptyGroupDataView, + ValueType, }, }, scheduler::{ @@ -33,7 +34,7 @@ use aptos_types::{ }, contract_event::TransactionEvent, executable::ModulePath, - state_store::state_value::StateValueMetadata, + state_store::{state_value::StateValueMetadata, MockStateView}, write_set::WriteOpKind, }; use claims::{assert_matches, assert_ok}; @@ -51,20 +52,23 @@ use std::{ #[test] fn test_resource_group_deletion() { let mut group_creation: MockIncarnation, MockEvent> = - MockIncarnation::new(vec![KeyType::(1, false)], vec![], vec![], vec![], 10); + MockIncarnation::new(vec![(KeyType::(1), true)], vec![], vec![], vec![], 10); group_creation.group_writes.push(( - KeyType::(100, false), + KeyType::(100), StateValueMetadata::none(), - HashMap::from([(101, ValueType::from_value(vec![5], true))]), + HashMap::from([(101, (ValueType::from_value(vec![5], true), false))]), )); let mut group_deletion: MockIncarnation, MockEvent> = - MockIncarnation::new(vec![KeyType::(1, false)], vec![], vec![], vec![], 10); + MockIncarnation::new(vec![(KeyType::(1), true)], vec![], vec![], vec![], 10); group_deletion.group_writes.push(( - KeyType::(100, false), + KeyType::(100), StateValueMetadata::none(), HashMap::from([( 101, - ValueType::new(None, StateValueMetadata::none(), WriteOpKind::Deletion), + ( + ValueType::new(None, StateValueMetadata::none(), WriteOpKind::Deletion), + false, + ), )]), )); let t_0 = MockTransaction::from_behavior(group_creation); @@ -74,6 +78,7 @@ fn test_resource_group_deletion() { let data_view = NonEmptyGroupDataView::> { group_keys: HashSet::new(), + delayed_field_testing: false, }; let executor_thread_pool = Arc::new( rayon::ThreadPoolBuilder::new() @@ -115,20 +120,22 @@ fn test_resource_group_deletion() { #[test] fn resource_group_bcs_fallback() { let no_group_incarnation_1: MockIncarnation, MockEvent> = MockIncarnation::new( - vec![KeyType::(1, false)], + vec![(KeyType::(1), true)], vec![( - KeyType::(2, false), + KeyType::(2), ValueType::from_value(vec![5], true), + false, )], vec![], vec![], 10, ); let no_group_incarnation_2: MockIncarnation, MockEvent> = MockIncarnation::new( - vec![KeyType::(3, false), KeyType::(4, false)], + vec![(KeyType::(3), true), (KeyType::(4), true)], vec![( - KeyType::(1, false), + KeyType::(1), ValueType::from_value(vec![5], true), + false, )], vec![], vec![], @@ -138,17 +145,18 @@ fn resource_group_bcs_fallback() { let t_3 = MockTransaction::from_behavior(no_group_incarnation_2); let mut group_incarnation: MockIncarnation, MockEvent> = - MockIncarnation::new(vec![KeyType::(1, false)], vec![], vec![], vec![], 10); + MockIncarnation::new(vec![(KeyType::(1), true)], vec![], vec![], vec![], 10); group_incarnation.group_writes.push(( - KeyType::(100, false), + KeyType::(100), StateValueMetadata::none(), - HashMap::from([(101, ValueType::from_value(vec![5], true))]), + HashMap::from([(101, (ValueType::from_value(vec![5], true), false))]), )); let t_2 = MockTransaction::from_behavior(group_incarnation); let transactions = Vec::from([t_1, t_2, t_3]); let data_view = NonEmptyGroupDataView::> { group_keys: HashSet::new(), + delayed_field_testing: false, }; let executor_thread_pool = Arc::new( rayon::ThreadPoolBuilder::new() @@ -264,9 +272,7 @@ fn interrupt_requested() { let txn_provider = DefaultTxnProvider::new(transactions); let mut guard = AptosModuleCacheManagerGuard::none(); - let data_view = DeltaDataView::> { - phantom: PhantomData, - }; + let data_view = MockStateView::empty(); let executor_thread_pool = Arc::new( rayon::ThreadPoolBuilder::new() .num_threads(num_cpus::get()) @@ -276,7 +282,7 @@ fn interrupt_requested() { let block_executor = BlockExecutor::< MockTransaction, MockEvent>, MockTask, MockEvent>, - DeltaDataView>, + MockStateView>, NoOpTransactionCommitHook, MockEvent>, usize>, DefaultTxnProvider, MockEvent>>, >::new( @@ -298,10 +304,11 @@ fn interrupt_requested() { #[test] fn block_output_err_precedence() { let incarnation: MockIncarnation, MockEvent> = MockIncarnation::new( - vec![KeyType::(1, false)], + vec![(KeyType::(1), false)], vec![( - KeyType::(2, false), + KeyType::(2), ValueType::from_value(vec![5], true), + false, )], vec![], vec![], @@ -311,9 +318,7 @@ fn block_output_err_precedence() { let transactions = Vec::from([txn.clone(), txn]); let txn_provider = DefaultTxnProvider::new(transactions); - let data_view = DeltaDataView::> { - phantom: PhantomData, - }; + let data_view = MockStateView::empty(); let executor_thread_pool = Arc::new( rayon::ThreadPoolBuilder::new() .num_threads(num_cpus::get()) @@ -323,7 +328,7 @@ fn block_output_err_precedence() { let block_executor = BlockExecutor::< MockTransaction, MockEvent>, MockTask, MockEvent>, - DeltaDataView>, + MockStateView>, NoOpTransactionCommitHook, MockEvent>, usize>, DefaultTxnProvider, MockEvent>>, >::new( @@ -356,9 +361,7 @@ fn skip_rest_gas_limit() { let transactions = Vec::from([MockTransaction::SkipRest(10), MockTransaction::SkipRest(10)]); let txn_provider = DefaultTxnProvider::new(transactions); - let data_view = DeltaDataView::> { - phantom: PhantomData, - }; + let data_view = MockStateView::empty(); let executor_thread_pool = Arc::new( rayon::ThreadPoolBuilder::new() .num_threads(num_cpus::get()) @@ -368,7 +371,7 @@ fn skip_rest_gas_limit() { let block_executor = BlockExecutor::< MockTransaction, MockEvent>, MockTask, MockEvent>, - DeltaDataView>, + MockStateView>, NoOpTransactionCommitHook, MockEvent>, usize>, DefaultTxnProvider, MockEvent>>, >::new( @@ -388,15 +391,11 @@ fn skip_rest_gas_limit() { } // TODO: add unit test for block gas limit! -fn run_and_assert(transactions: Vec>) +fn run_and_assert(transactions: Vec>, use_delta_data_view: bool) where K: PartialOrd + Ord + Send + Sync + Clone + Hash + Eq + ModulePath + Debug + 'static, E: Send + Sync + Debug + Clone + TransactionEvent + 'static, { - let data_view = DeltaDataView:: { - phantom: PhantomData, - }; - let executor_thread_pool = Arc::new( rayon::ThreadPoolBuilder::new() .num_threads(num_cpus::get()) @@ -406,23 +405,49 @@ where let mut guard = AptosModuleCacheManagerGuard::none(); let txn_provider = DefaultTxnProvider::new(transactions); - let output = BlockExecutor::< - MockTransaction, - MockTask, - DeltaDataView, - NoOpTransactionCommitHook, usize>, - _, - >::new( - BlockExecutorConfig::new_no_block_limit(num_cpus::get()), - executor_thread_pool, - None, - ) - .execute_transactions_parallel( - &txn_provider, - &data_view, - &TransactionSliceMetadata::unknown(), - &mut guard, - ); + + let output = if use_delta_data_view { + let data_view = DeltaDataView:: { + phantom: PhantomData, + }; + + BlockExecutor::< + MockTransaction, + MockTask, + DeltaDataView, + NoOpTransactionCommitHook, usize>, + _, + >::new( + BlockExecutorConfig::new_no_block_limit(num_cpus::get()), + executor_thread_pool, + None, + ) + .execute_transactions_parallel( + &txn_provider, + &data_view, + &TransactionSliceMetadata::unknown(), + &mut guard, + ) + } else { + let data_view = MockStateView::empty(); + BlockExecutor::< + MockTransaction, + MockTask, + MockStateView, + NoOpTransactionCommitHook, usize>, + _, + >::new( + BlockExecutorConfig::new_no_block_limit(num_cpus::get()), + executor_thread_pool, + None, + ) + .execute_transactions_parallel( + &txn_provider, + &data_view, + &TransactionSliceMetadata::unknown(), + &mut guard, + ) + }; let baseline = BaselineOutput::generate(txn_provider.get_txns(), None); baseline.assert_parallel_output(&output); @@ -439,61 +464,62 @@ fn random_value(delete_value: bool) -> ValueType { fn empty_block() { // This test checks that we do not trigger asserts due to an empty block, e.g. in the // scheduler. Instead, parallel execution should gracefully early return empty output. - run_and_assert::, MockEvent>(vec![]); + run_and_assert::, MockEvent>(vec![], false); } #[test] fn delta_counters() { - let key = KeyType(random::<[u8; 32]>(), false); + // TODO(BlockSTMv2): Adjust these tests to also use V2. + let key = KeyType(random::<[u8; 32]>()); let mut transactions = vec![MockTransaction::from_behavior(MockIncarnation::< KeyType<[u8; 32]>, MockEvent, >::new( vec![], - vec![(key, random_value(false))], // writes + vec![(key, random_value(false), false)], // writes vec![], vec![], 1, // gas ))]; for _ in 0..50 { - transactions.push(MockTransaction::from_behavior(MockIncarnation::< - KeyType<[u8; 32]>, - MockEvent, - >::new( - vec![key], // reads - vec![], - vec![(key, delta_add(5, u128::MAX))], // deltas - vec![], - 1, // gas - ))); + transactions.push( + MockTransaction::from_behavior(MockIncarnation::, MockEvent>::new( + vec![(key, false)], // reads + vec![], + vec![(key, delta_add(5, u128::MAX), None)], // deltas + vec![], + 1, // gas + )) + .with_aggregator_v1_testing(), + ); } - transactions.push(MockTransaction::from_behavior(MockIncarnation::< - KeyType<[u8; 32]>, - MockEvent, - >::new( - vec![], - vec![(key, random_value(false))], // writes - vec![], - vec![], - 1, // gas - ))); - - for _ in 0..50 { - transactions.push(MockTransaction::from_behavior(MockIncarnation::< - KeyType<[u8; 32]>, - MockEvent, - >::new( - vec![key], // reads + transactions.push( + MockTransaction::from_behavior(MockIncarnation::, MockEvent>::new( + vec![], + vec![(key, random_value(false), false)], // writes vec![], - vec![(key, delta_sub(2, u128::MAX))], // deltas vec![], 1, // gas - ))); + )) + .with_aggregator_v1_testing(), + ); + + for _ in 0..50 { + transactions.push( + MockTransaction::from_behavior(MockIncarnation::, MockEvent>::new( + vec![(key, false)], // reads + vec![], + vec![(key, delta_sub(2, u128::MAX), None)], // deltas + vec![], + 1, // gas + )) + .with_aggregator_v1_testing(), + ); } - run_and_assert(transactions) + run_and_assert(transactions, true) } #[test] @@ -501,14 +527,12 @@ fn delta_chains() { let mut transactions = vec![]; // Generate a series of transactions add and subtract from an aggregator. - let keys: Vec> = (0..10) - .map(|_| KeyType(random::<[u8; 32]>(), false)) - .collect(); + let keys: Vec> = (0..10).map(|_| KeyType(random::<[u8; 32]>())).collect(); for i in 0..500 { transactions.push( MockTransaction::, MockEvent>::from_behavior(MockIncarnation::new( - keys.clone(), // reads + keys.clone().into_iter().map(|k| (k, true)).collect(), // reads vec![], keys.iter() .enumerate() @@ -526,17 +550,19 @@ fn delta_chains() { u128::MAX, DeltaHistory::new(), ), + None, )), false => None, }) .collect(), // deltas vec![], 1, // gas - )), + )) + .with_aggregator_v1_testing(), ); } - run_and_assert(transactions) + run_and_assert(transactions, true) } const TOTAL_KEY_NUM: u64 = 50; @@ -554,15 +580,15 @@ fn cycle_transactions() { KeyType<[u8; 32]>, MockEvent, >::new( - vec![KeyType(key, false)], // reads - vec![(KeyType(key, false), random_value(false))], // writes + vec![(KeyType(key), false)], // reads + vec![(KeyType(key), random_value(false), false)], // writes vec![], vec![], 1, // gas ))); } } - run_and_assert(transactions) + run_and_assert(transactions, false) } const NUM_BLOCKS: u64 = 10; @@ -572,7 +598,7 @@ const TXN_PER_BLOCK: u64 = 100; fn one_reads_all_barrier() { let mut transactions = vec![]; let keys: Vec> = (0..TXN_PER_BLOCK) - .map(|_| KeyType(random::<[u8; 32]>(), false)) + .map(|_| KeyType(random::<[u8; 32]>())) .collect(); for _ in 0..NUM_BLOCKS { for key in &keys { @@ -580,8 +606,8 @@ fn one_reads_all_barrier() { KeyType<[u8; 32]>, MockEvent, >::new( - vec![*key], // reads - vec![(*key, random_value(false))], // writes + vec![(*key, false)], // reads + vec![(*key, random_value(false), false)], // writes vec![], vec![], 1, // gas @@ -592,27 +618,27 @@ fn one_reads_all_barrier() { KeyType<[u8; 32]>, MockEvent, >::new( - keys.clone(), //reads + keys.clone().into_iter().map(|k| (k, false)).collect(), // reads vec![], vec![], vec![], 1, //gas ))); } - run_and_assert(transactions) + run_and_assert(transactions, false) } #[test] fn one_writes_all_barrier() { let mut transactions = vec![]; let keys: Vec> = (0..TXN_PER_BLOCK) - .map(|_| KeyType(random::<[u8; 32]>(), false)) + .map(|_| KeyType(random::<[u8; 32]>())) .collect(); for _ in 0..NUM_BLOCKS { for key in &keys { transactions.push(MockTransaction::from_behavior(MockIncarnation::new( - vec![*key], //reads - vec![(*key, random_value(false))], //writes + vec![(*key, false)], //reads + vec![(*key, random_value(false), false)], //writes vec![], vec![], 1, //gas @@ -623,23 +649,23 @@ fn one_writes_all_barrier() { KeyType<[u8; 32]>, MockEvent, >::new( - keys.clone(), // reads + keys.clone().into_iter().map(|k| (k, false)).collect(), // reads keys.iter() - .map(|key| (*key, random_value(false))) + .map(|key| (*key, random_value(false), false)) .collect::>(), //writes vec![], vec![], 1, // gas ))); } - run_and_assert(transactions) + run_and_assert(transactions, false) } #[test] fn early_aborts() { let mut transactions = vec![]; let keys: Vec<_> = (0..TXN_PER_BLOCK) - .map(|_| KeyType(random::<[u8; 32]>(), false)) + .map(|_| KeyType(random::<[u8; 32]>())) .collect(); for _ in 0..NUM_BLOCKS { @@ -648,8 +674,8 @@ fn early_aborts() { KeyType<[u8; 32]>, MockEvent, >::new( - vec![*key], // reads - vec![(*key, random_value(false))], // writes + vec![(*key, false)], // reads + vec![(*key, random_value(false), false)], // writes vec![], vec![], 1, // gas @@ -658,14 +684,14 @@ fn early_aborts() { // One transaction that triggers an abort transactions.push(MockTransaction::Abort) } - run_and_assert(transactions) + run_and_assert(transactions, false) } #[test] fn early_skips() { let mut transactions = vec![]; let keys: Vec<_> = (0..TXN_PER_BLOCK) - .map(|_| KeyType(random::<[u8; 32]>(), false)) + .map(|_| KeyType(random::<[u8; 32]>())) .collect(); for _ in 0..NUM_BLOCKS { @@ -674,8 +700,8 @@ fn early_skips() { KeyType<[u8; 32]>, MockEvent, >::new( - vec![*key], // reads - vec![(*key, random_value(false))], //writes + vec![(*key, false)], // reads + vec![(*key, random_value(false), false)], //writes vec![], vec![], 1, // gas @@ -684,7 +710,7 @@ fn early_skips() { // One transaction that triggers an abort transactions.push(MockTransaction::SkipRest(0)) } - run_and_assert(transactions) + run_and_assert(transactions, false) } #[test] diff --git a/aptos-move/block-executor/src/view.rs b/aptos-move/block-executor/src/view.rs index 20a795f5b4e..21ca7f48401 100644 --- a/aptos-move/block-executor/src/view.rs +++ b/aptos-move/block-executor/src/view.rs @@ -1871,7 +1871,10 @@ mod test { use super::*; use crate::{ captured_reads::{CapturedReads, DelayedFieldRead, DelayedFieldReadKind}, - proptest_types::types::{KeyType, MockEvent, ValueType}, + proptest_types::{ + mock_executor::MockEvent, + types::{KeyType, ValueType}, + }, scheduler::{DependencyResult, Scheduler, TWaitForDependency}, view::{delayed_field_try_add_delta_outcome_impl, get_delayed_field_value_impl, ViewState}, }; @@ -3004,14 +3007,14 @@ mod test { let views = holder.new_view(); assert_ok_eq!( - views.get_resource_state_value(&KeyType::(1, false), None), + views.get_resource_state_value(&KeyType::(1), None), None ); - assert_ok_eq!(views.resource_exists(&KeyType::(1, false)), false,); + assert_ok_eq!(views.resource_exists(&KeyType::(1)), false,); assert_ok_eq!( - views.get_resource_state_value_metadata(&KeyType::(1, false)), + views.get_resource_state_value_metadata(&KeyType::(1)), None, ); } @@ -3019,14 +3022,14 @@ mod test { #[test] fn test_non_value_reads_not_recorded() { let state_value = create_state_value(&Value::u64(12321), &MoveTypeLayout::U64); - let data = HashMap::from([(KeyType::(1, false), state_value.clone())]); + let data = HashMap::from([(KeyType::(1), state_value.clone())]); let holder = ComparisonHolder::new(data, 1000); let views = holder.new_view(); - assert_ok_eq!(views.resource_exists(&KeyType::(1, false)), true); + assert_ok_eq!(views.resource_exists(&KeyType::(1)), true); assert!(views - .get_resource_state_value_metadata(&KeyType::(1, false)) + .get_resource_state_value_metadata(&KeyType::(1)) .unwrap() .is_some(),); @@ -3061,21 +3064,18 @@ mod test { #[test] fn test_regular_read_operations() { let state_value = create_state_value(&Value::u64(12321), &MoveTypeLayout::U64); - let data = HashMap::from([(KeyType::(1, false), state_value.clone())]); + let data = HashMap::from([(KeyType::(1), state_value.clone())]); let holder = ComparisonHolder::new(data, 1000); let views = holder.new_view(); assert_ok_eq!( - views.get_resource_state_value(&KeyType::(1, false), None), + views.get_resource_state_value(&KeyType::(1), None), Some(state_value.clone()) ); assert_fetch_eq( - holder - .holder - .unsync_map - .fetch_data(&KeyType::(1, false)), + holder.holder.unsync_map.fetch_data(&KeyType::(1)), Some(TransactionWrite::from_state_value(Some(state_value))), None, ); @@ -3089,7 +3089,7 @@ mod test { create_struct_layout(create_aggregator_storage_layout(MoveTypeLayout::U64)); let value = create_struct_value(create_aggregator_value_u64(25, 30)); let state_value = create_state_value(&value, &storage_layout); - let data = HashMap::from([(KeyType::(1, false), state_value.clone())]); + let data = HashMap::from([(KeyType::(1), state_value.clone())]); let start_counter = 1000; let id = DelayedFieldID::new_with_width(start_counter, 8); @@ -3103,29 +3103,26 @@ mod test { match check_metadata { Some(true) => { views - .get_resource_state_value_metadata(&KeyType::(1, false)) + .get_resource_state_value_metadata(&KeyType::(1)) .unwrap(); }, Some(false) => { - assert_ok_eq!(views.resource_exists(&KeyType::(1, false)), true,); + assert_ok_eq!(views.resource_exists(&KeyType::(1)), true,); }, None => {}, }; let layout = create_struct_layout(create_aggregator_layout_u64()); assert_ok_eq!( - views.get_resource_state_value(&KeyType::(1, false), Some(&layout)), + views.get_resource_state_value(&KeyType::(1), Some(&layout)), Some(patched_state_value.clone()) ); assert!(views .get_reads_needing_exchange(&HashSet::from([id]), &HashSet::new()) .unwrap() - .contains_key(&KeyType(1, false))); + .contains_key(&KeyType::(1))); assert_fetch_eq( - holder - .holder - .unsync_map - .fetch_data(&KeyType::(1, false)), + holder.holder.unsync_map.fetch_data(&KeyType::(1)), Some(TransactionWrite::from_state_value(Some( patched_state_value, ))), @@ -3137,12 +3134,12 @@ mod test { fn test_read_operations() { let state_value_3 = create_state_value(&Value::u64(12321), &MoveTypeLayout::U64); let mut data = HashMap::new(); - data.insert(KeyType::(3, false), state_value_3.clone()); + data.insert(KeyType::(3), state_value_3.clone()); let storage_layout = create_struct_layout(create_aggregator_storage_layout(MoveTypeLayout::U64)); let value = create_struct_value(create_aggregator_value_u64(25, 30)); let state_value_4 = create_state_value(&value, &storage_layout); - data.insert(KeyType::(4, false), state_value_4); + data.insert(KeyType::(4), state_value_4); let start_counter = 1000; let id = DelayedFieldID::new_with_width(start_counter, 8); @@ -3151,20 +3148,20 @@ mod test { assert_eq!( views - .get_resource_state_value(&KeyType::(1, false), None) + .get_resource_state_value(&KeyType::(1), None) .unwrap(), None ); let layout = create_struct_layout(create_aggregator_layout_u64()); assert_eq!( views - .get_resource_state_value(&KeyType::(2, false), Some(&layout)) + .get_resource_state_value(&KeyType::(2), Some(&layout)) .unwrap(), None ); assert_eq!( views - .get_resource_state_value(&KeyType::(3, false), None) + .get_resource_state_value(&KeyType::(3), None) .unwrap(), Some(state_value_3.clone()) ); @@ -3176,14 +3173,14 @@ mod test { holder .versioned_map .data() - .fetch_data(&KeyType::(3, false), 1) + .fetch_data(&KeyType::(3), 1) ); let patched_value = create_struct_value(create_aggregator_value_u64(id.as_u64(), 30)); let state_value_4 = create_state_value(&patched_value, &storage_layout); assert_eq!( views - .get_resource_state_value(&KeyType::(4, false), Some(&layout)) + .get_resource_state_value(&KeyType::(4), Some(&layout)) .unwrap(), Some(state_value_4.clone()) ); @@ -3217,6 +3214,6 @@ mod test { // TODO[agg_v2](test): This assertion fails. // let data_read = DataRead::Versioned(Ok((1,0)), Arc::new(TransactionWrite::from_state_value(Some(state_value_4))), Some(Arc::new(layout))); - // assert!(read_set_with_delayed_fields.any(|x| x == (&KeyType::(4, false), &data_read))); + // assert!(read_set_with_delayed_fields.any(|x| x == (&KeyType::(4), &data_read))); } } diff --git a/third_party/move/move-vm/runtime/src/loader/modules.rs b/third_party/move/move-vm/runtime/src/loader/modules.rs index 9c74c67ec14..5846a7d5461 100644 --- a/third_party/move/move-vm/runtime/src/loader/modules.rs +++ b/third_party/move/move-vm/runtime/src/loader/modules.rs @@ -385,6 +385,44 @@ impl Module { }) } + /// Creates a new Module instance for testing purposes. + /// This method creates a minimal Module with empty contents. + #[cfg(any(test, feature = "testing"))] + pub fn new_for_test(module_id: ModuleId) -> Self { + use move_binary_format::file_format::empty_module; + + // Start with an empty module + let mut empty_module = empty_module(); + + // Update the module ID + empty_module.identifiers[0] = module_id.name().to_owned(); + empty_module.address_identifiers[0] = *module_id.address(); + + // Create necessary empty collections + let module_arc = Arc::new(empty_module); + + Self { + id: module_id, + size: 0, + module: module_arc, + structs: vec![], + struct_instantiations: vec![], + struct_variant_infos: vec![], + struct_variant_instantiation_infos: vec![], + function_refs: vec![], + function_defs: vec![], + function_instantiations: vec![], + field_handles: vec![], + field_instantiations: vec![], + variant_field_infos: vec![], + variant_field_instantiation_infos: vec![], + function_map: HashMap::new(), + struct_map: HashMap::new(), + single_signature_token_map: BTreeMap::new(), + friends: BTreeSet::new(), + } + } + fn make_struct_type( module: &CompiledModule, struct_def: &StructDefinition, From d0cc53cb67977c81184cd1c46b0f5cb5c62282fa Mon Sep 17 00:00:00 2001 From: Oliver He Date: Tue, 17 Jun 2025 04:52:31 -0400 Subject: [PATCH 004/260] Init experimental confidential asset module at genesis (#16869) * Init experimental confidential asset module at genesis * fmt * rename * dedupe Downstreamed-from: 4be96f623c2c9a0c07cf568dc659592de077c24d --- .../doc/confidential_asset.md | 86 +++++++++++++++++++ .../confidential_asset.move | 24 +++++- aptos-move/vm-genesis/src/lib.rs | 69 ++++++++++++++- .../move-core/types/src/language_storage.rs | 1 + .../src/account_config/constants/addresses.rs | 2 +- 5 files changed, 176 insertions(+), 6 deletions(-) diff --git a/aptos-move/framework/aptos-experimental/doc/confidential_asset.md b/aptos-move/framework/aptos-experimental/doc/confidential_asset.md index 3d0b0c0c233..b8178027de0 100644 --- a/aptos-move/framework/aptos-experimental/doc/confidential_asset.md +++ b/aptos-move/framework/aptos-experimental/doc/confidential_asset.md @@ -36,6 +36,7 @@ It enables private transfers by obfuscating token amounts while keeping sender a - [Function `disable_token`](#0x7_confidential_asset_disable_token) - [Function `set_auditor`](#0x7_confidential_asset_set_auditor) - [Function `has_confidential_asset_store`](#0x7_confidential_asset_has_confidential_asset_store) +- [Function `confidential_asset_controller_exists`](#0x7_confidential_asset_confidential_asset_controller_exists) - [Function `is_token_allowed`](#0x7_confidential_asset_is_token_allowed) - [Function `is_allow_list_enabled`](#0x7_confidential_asset_is_allow_list_enabled) - [Function `pending_balance`](#0x7_confidential_asset_pending_balance) @@ -67,6 +68,7 @@ It enables private transfers by obfuscating token amounts while keeping sender a - [Function `deserialize_auditor_eks`](#0x7_confidential_asset_deserialize_auditor_eks) - [Function `deserialize_auditor_amounts`](#0x7_confidential_asset_deserialize_auditor_amounts) - [Function `ensure_sufficient_fa`](#0x7_confidential_asset_ensure_sufficient_fa) +- [Function `init_module_for_genesis`](#0x7_confidential_asset_init_module_for_genesis)
use 0x1::bcs;
@@ -443,6 +445,26 @@ The confidential asset store has not been published for the given user-token pai
 
 
 
+
+
+The confidential asset controller is not installed.
+
+
+
const EFA_CONTROLLER_NOT_INSTALLED: u64 = 18;
+
+ + + + + +[TEST-ONLY] The confidential asset module initialization failed. + + +
const EINIT_MODULE_FAILED: u64 = 1000;
+
+ + + The provided auditors or auditor proofs are invalid. @@ -553,6 +575,16 @@ The maximum number of transactions can be aggregated on the pending balance befo + + +The testnet chain ID. + + +
const TESTNET_CHAIN_ID: u8 = 2;
+
+ + + ## Function `init_module` @@ -1302,6 +1334,32 @@ Checks if the user has a confidential asset store for the specified token. + + + + +## Function `confidential_asset_controller_exists` + +Checks if the confidential asset controller is installed. + + +
#[view]
+public fun confidential_asset_controller_exists(): bool
+
+ + + +
+Implementation + + +
public fun confidential_asset_controller_exists(): bool {
+    exists<FAController>(@aptos_experimental)
+}
+
+ + +
@@ -1360,6 +1418,7 @@ Otherwise, all tokens are allowed.
public fun is_allow_list_enabled(): bool acquires FAController {
+    assert!(confidential_asset_controller_exists(), error::invalid_state(EFA_CONTROLLER_NOT_INSTALLED));
     borrow_global<FAController>(@aptos_experimental).allow_list_enabled
 }
 
@@ -2482,6 +2541,33 @@ Returns Some(Object<Metadata>) if user has a suffucient amoun + + + + +## Function `init_module_for_genesis` + + + +
entry fun init_module_for_genesis(deployer: &signer)
+
+ + + +
+Implementation + + +
entry fun init_module_for_genesis(deployer: &signer) {
+    assert!(signer::address_of(deployer) == @aptos_experimental, error::invalid_argument(EINIT_MODULE_FAILED));
+    assert!(chain_id::get() != MAINNET_CHAIN_ID, error::invalid_state(EINIT_MODULE_FAILED));
+    assert!(chain_id::get() != TESTNET_CHAIN_ID, error::invalid_state(EINIT_MODULE_FAILED));
+    init_module(deployer)
+}
+
+ + +
diff --git a/aptos-move/framework/aptos-experimental/sources/confidential_asset/confidential_asset.move b/aptos-move/framework/aptos-experimental/sources/confidential_asset/confidential_asset.move index 32c07f8c04f..56262beceaa 100644 --- a/aptos-move/framework/aptos-experimental/sources/confidential_asset/confidential_asset.move +++ b/aptos-move/framework/aptos-experimental/sources/confidential_asset/confidential_asset.move @@ -82,6 +82,12 @@ module aptos_experimental::confidential_asset { /// Sender and recipient amounts encrypt different transfer amounts const EINVALID_SENDER_AMOUNT: u64 = 17; + /// The confidential asset controller is not installed. + const EFA_CONTROLLER_NOT_INSTALLED: u64 = 18; + + /// [TEST-ONLY] The confidential asset module initialization failed. + const EINIT_MODULE_FAILED: u64 = 1000; + // // Constants // @@ -92,6 +98,9 @@ module aptos_experimental::confidential_asset { /// The mainnet chain ID. If the chain ID is 1, the allow list is enabled. const MAINNET_CHAIN_ID: u8 = 1; + /// The testnet chain ID. + const TESTNET_CHAIN_ID: u8 = 2; + // // Structs // @@ -511,6 +520,12 @@ module aptos_experimental::confidential_asset { exists(get_user_address(user, token)) } + #[view] + /// Checks if the confidential asset controller is installed. + public fun confidential_asset_controller_exists(): bool { + exists(@aptos_experimental) + } + #[view] /// Checks if the token is allowed for confidential transfers. public fun is_token_allowed(token: Object): bool acquires FAController, FAConfig { @@ -532,6 +547,7 @@ module aptos_experimental::confidential_asset { /// If the allow list is enabled, only tokens from the allow list can be transferred. /// Otherwise, all tokens are allowed. public fun is_allow_list_enabled(): bool acquires FAController { + assert!(confidential_asset_controller_exists(), error::invalid_state(EFA_CONTROLLER_NOT_INSTALLED)); borrow_global(@aptos_experimental).allow_list_enabled } @@ -1080,10 +1096,16 @@ module aptos_experimental::confidential_asset { fa } + entry fun init_module_for_genesis(deployer: &signer) { + assert!(signer::address_of(deployer) == @aptos_experimental, error::invalid_argument(EINIT_MODULE_FAILED)); + assert!(chain_id::get() != MAINNET_CHAIN_ID, error::invalid_state(EINIT_MODULE_FAILED)); + assert!(chain_id::get() != TESTNET_CHAIN_ID, error::invalid_state(EINIT_MODULE_FAILED)); + init_module(deployer) + } + // // Test-only functions // - #[test_only] public fun init_module_for_testing(deployer: &signer) { init_module(deployer) diff --git a/aptos-move/vm-genesis/src/lib.rs b/aptos-move/vm-genesis/src/lib.rs index db59a96c5c4..4cdf1bd7be9 100644 --- a/aptos-move/vm-genesis/src/lib.rs +++ b/aptos-move/vm-genesis/src/lib.rs @@ -17,7 +17,10 @@ use aptos_gas_schedule::{ AptosGasParameters, InitialGasSchedule, ToOnChainGasSchedule, LATEST_GAS_FEATURE_VERSION, }; use aptos_types::{ - account_config::{self, aptos_test_root_address, events::NewEpochEvent, CORE_CODE_ADDRESS}, + account_config::{ + self, aptos_test_root_address, events::NewEpochEvent, CORE_CODE_ADDRESS, + EXPERIMENTAL_CODE_ADDRESS, + }, chain_id::ChainId, contract_event::{ContractEvent, ContractEventV1}, executable::ModulePath, @@ -320,6 +323,7 @@ pub fn encode_genesis_change_set( genesis_config.initial_jwks.clone(), genesis_config.keyless_groth16_vk.clone(), ); + initialize_confidential_asset(&mut session, &module_storage, chain_id); set_genesis_end(&mut session, &module_storage); // Reconfiguration should happen after all on-chain invocations. @@ -382,18 +386,19 @@ fn validate_genesis_config(genesis_config: &GenesisConfiguration) { ); } -fn exec_function( +fn exec_function_internal( session: &mut SessionExt, module_storage: &impl ModuleStorage, module_name: &str, function_name: &str, ty_args: Vec, args: Vec>, + address: AccountAddress, ) { let storage = TraversalStorage::new(); session .execute_function_bypass_visibility( - &ModuleId::new(CORE_CODE_ADDRESS, Identifier::new(module_name).unwrap()), + &ModuleId::new(address, Identifier::new(module_name).unwrap()), &Identifier::new(function_name).unwrap(), ty_args, args, @@ -403,7 +408,8 @@ fn exec_function( ) .unwrap_or_else(|e| { panic!( - "Error calling {}.{}: ({:#x}) {}", + "Error calling {}.{}.{}: ({:#x}) {}", + address, module_name, function_name, e.sub_status().unwrap_or_default(), @@ -412,6 +418,44 @@ fn exec_function( }); } +fn exec_function( + session: &mut SessionExt, + module_storage: &impl ModuleStorage, + module_name: &str, + function_name: &str, + ty_args: Vec, + args: Vec>, +) { + exec_function_internal( + session, + module_storage, + module_name, + function_name, + ty_args, + args, + CORE_CODE_ADDRESS, + ); +} + +fn exec_experimental_function( + session: &mut SessionExt, + module_storage: &impl ModuleStorage, + module_name: &str, + function_name: &str, + ty_args: Vec, + args: Vec>, +) { + exec_function_internal( + session, + module_storage, + module_name, + function_name, + ty_args, + args, + EXPERIMENTAL_CODE_ADDRESS, + ); +} + fn initialize( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, @@ -839,6 +883,23 @@ fn initialize_keyless_accounts( } } +fn initialize_confidential_asset( + session: &mut SessionExt, + module_storage: &impl AptosModuleStorage, + chain_id: ChainId, +) { + if !chain_id.is_mainnet() && !chain_id.is_testnet() { + exec_experimental_function( + session, + module_storage, + "confidential_asset", + "init_module_for_genesis", + vec![], + serialize_values(&vec![MoveValue::Signer(EXPERIMENTAL_CODE_ADDRESS)]), + ); + } +} + fn create_accounts( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, diff --git a/third_party/move/move-core/types/src/language_storage.rs b/third_party/move/move-core/types/src/language_storage.rs index 6abdb24bc1c..a14edfc6c4e 100644 --- a/third_party/move/move-core/types/src/language_storage.rs +++ b/third_party/move/move-core/types/src/language_storage.rs @@ -26,6 +26,7 @@ pub const RESOURCE_TAG: u8 = 1; pub const CORE_CODE_ADDRESS: AccountAddress = AccountAddress::ONE; pub const TOKEN_ADDRESS: AccountAddress = AccountAddress::THREE; pub const TOKEN_OBJECTS_ADDRESS: AccountAddress = AccountAddress::FOUR; +pub const EXPERIMENTAL_CODE_ADDRESS: AccountAddress = AccountAddress::SEVEN; #[derive(Serialize, Deserialize, Debug, PartialEq, Hash, Eq, Clone, PartialOrd, Ord)] #[cfg_attr( diff --git a/types/src/account_config/constants/addresses.rs b/types/src/account_config/constants/addresses.rs index c942549c12c..1f2ca58bf48 100644 --- a/types/src/account_config/constants/addresses.rs +++ b/types/src/account_config/constants/addresses.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::account_address::AccountAddress; -pub use move_core_types::language_storage::CORE_CODE_ADDRESS; +pub use move_core_types::language_storage::{CORE_CODE_ADDRESS, EXPERIMENTAL_CODE_ADDRESS}; pub fn aptos_test_root_address() -> AccountAddress { AccountAddress::from_hex_literal("0xA550C18") From 6aa620e1007ce767482284f8a782161acdb48b23 Mon Sep 17 00:00:00 2001 From: Jun Xu <5827713+junxzm1990@users.noreply.github.com> Date: Tue, 17 Jun 2025 15:33:26 -0600 Subject: [PATCH 005/260] enable comparison operations, lt/le/gt/ge, on non-integer types (#16812) Downstreamed-from: 91fb183db702574d448fe96e3d319d91b8139a4b --- .../src/tests/cmp_generic.data/pack/Move.toml | 6 + .../cmp_generic.data/pack/sources/test.move | 783 ++++++++++++++++++ .../tests/cmp_generic.data/script/Move.toml | 6 + .../script/sources/script.move | 8 + .../e2e-move-tests/src/tests/generic_cmp.rs | 158 ++++ aptos-move/e2e-move-tests/src/tests/mod.rs | 1 + .../src/expansion/dependency_ordering.rs | 37 +- .../src/env_pipeline/cmp_rewriter.rs | 368 ++++++++ .../move-compiler-v2/src/env_pipeline/mod.rs | 1 + .../move/move-compiler-v2/src/experiments.rs | 6 + third_party/move/move-compiler-v2/src/lib.rs | 24 +- .../move/move-model/src/builder/builtins.rs | 85 +- third_party/move/move-model/src/lib.rs | 21 + third_party/move/move-model/src/well_known.rs | 2 + 14 files changed, 1468 insertions(+), 38 deletions(-) create mode 100644 aptos-move/e2e-move-tests/src/tests/cmp_generic.data/pack/Move.toml create mode 100644 aptos-move/e2e-move-tests/src/tests/cmp_generic.data/pack/sources/test.move create mode 100644 aptos-move/e2e-move-tests/src/tests/cmp_generic.data/script/Move.toml create mode 100644 aptos-move/e2e-move-tests/src/tests/cmp_generic.data/script/sources/script.move create mode 100644 aptos-move/e2e-move-tests/src/tests/generic_cmp.rs create mode 100644 third_party/move/move-compiler-v2/src/env_pipeline/cmp_rewriter.rs diff --git a/aptos-move/e2e-move-tests/src/tests/cmp_generic.data/pack/Move.toml b/aptos-move/e2e-move-tests/src/tests/cmp_generic.data/pack/Move.toml new file mode 100644 index 00000000000..33398ec91b2 --- /dev/null +++ b/aptos-move/e2e-move-tests/src/tests/cmp_generic.data/pack/Move.toml @@ -0,0 +1,6 @@ +[package] +name = "generic_cmp" +version = "0.0.0" + +[dependencies] +AptosFramework = { local = "../../../../../framework/aptos-framework" } diff --git a/aptos-move/e2e-move-tests/src/tests/cmp_generic.data/pack/sources/test.move b/aptos-move/e2e-move-tests/src/tests/cmp_generic.data/pack/sources/test.move new file mode 100644 index 00000000000..498e79ae834 --- /dev/null +++ b/aptos-move/e2e-move-tests/src/tests/cmp_generic.data/pack/sources/test.move @@ -0,0 +1,783 @@ + /// Module for testing non-integer primitive types + module 0x99::primitive_cmp { + //* bool group + fun test_left_lt_right_bool(x: bool, y: bool): bool { + // a and b are created to test our optimization + let a = &x; + let b = &y; + + *a < *b && + x < y + } + fun test_left_le_right_bool(x: bool, y: bool): bool { + x <= y + } + fun test_left_gt_right_bool(x: bool, y: bool): bool { + x > y + } + fun test_left_ge_right_bool(x: bool, y: bool): bool { + x >= y + } + + //* address group + fun test_left_lt_right_address(x: address, y: address): bool { + // a and b are created to test our optimization + let a = &x; + let b = &y; + + *a < *b && + x < y + } + fun test_left_le_right_address(x: address, y: address): bool { + x <= y + } + fun test_left_gt_right_address(x: address, y: address): bool { + x > y + } + fun test_left_ge_right_address(x: address, y: address): bool { + x >= y + } + + //* vector group + fun test_left_lt_right_vector(x: vector, y: vector): bool { + // a and b are created to test our optimization + let a = &x; + let b = &y; + + *a < *b && + x < y + } + fun test_left_le_right_vector(x: vector, y: vector): bool { + x <= y + } + fun test_left_gt_right_vector(x: vector, y: vector): bool { + x > y + } + fun test_left_ge_right_vector(x: vector, y: vector): bool { + x >= y + } + + //* nested vector group + fun test_left_lt_right_nested_vector(x: vector>, y: vector>): bool { + // a and b are created to test our optimization + let a = &x; + let b = &y; + + *a < *b && + x < y + } + fun test_left_le_right_nested_vector(x: vector>, y: vector>): bool { + x <= y + } + fun test_left_gt_right_nested_vector(x: vector>, y: vector>): bool { + x > y + } + fun test_left_ge_right_nested_vector(x: vector>, y: vector>): bool { + x >= y + } + + //* entry functions for testing non-integer primitive types + entry fun test_bool(){ + let x = false; + let y = true; + assert!(test_left_lt_right_bool(x, y), 0); + assert!(test_left_le_right_bool(x, y), 0); + assert!(test_left_le_right_bool(x, x), 0); + assert!(test_left_le_right_bool(y, y), 0); + + assert!(test_left_gt_right_bool(y, x), 0); + assert!(test_left_ge_right_bool(y, x), 0); + assert!(test_left_ge_right_bool(x, x), 0); + assert!(test_left_ge_right_bool(y, y), 0); + } + + entry fun test_address(){ + let x = @0x1; + let y = @0x2; + assert!(test_left_lt_right_address(x, y), 0); + assert!(test_left_le_right_address(x, y), 0); + assert!(test_left_le_right_address(x, x), 0); + assert!(test_left_le_right_address(y, y), 0); + + assert!(test_left_gt_right_address(y, x), 0); + assert!(test_left_ge_right_address(y, x), 0); + assert!(test_left_ge_right_address(x, x), 0); + assert!(test_left_ge_right_address(y, y), 0); + } + + entry fun test_vector(){ + let x = vector[0u8, 1u8, 2u8, 3u8, 4u8, 5u8]; + let y = vector[0u8, 1u8, 2u8, 3u8, 4u8, 5u8, 6u8]; + let z = vector[1u8, 2u8, 3u8, 4u8, 5u8, 6u8]; + + assert!(test_left_lt_right_vector(x, y), 0); + assert!(test_left_lt_right_vector(y, z), 0); + assert!(test_left_lt_right_vector(x, z), 0); + + assert!(test_left_le_right_vector(x, y), 0); + assert!(test_left_le_right_vector(y, z), 0); + assert!(test_left_le_right_vector(x, z), 0); + assert!(test_left_le_right_vector(x, x), 0); + assert!(test_left_le_right_vector(y, y), 0); + assert!(test_left_le_right_vector(z, z), 0); + + assert!(test_left_gt_right_vector(y, x), 0); + assert!(test_left_gt_right_vector(z, y), 0); + assert!(test_left_gt_right_vector(z, x), 0); + + assert!(test_left_ge_right_vector(y, x), 0); + assert!(test_left_ge_right_vector(z, y), 0); + assert!(test_left_ge_right_vector(z, x), 0); + assert!(test_left_ge_right_vector(x, x), 0); + assert!(test_left_ge_right_vector(y, y), 0); + assert!(test_left_ge_right_vector(z, z), 0); + } + + entry fun test_nested_vector(){ + let x = vector[0u8, 1u8, 2u8, 3u8, 4u8, 5u8]; + let y = vector[0u8, 1u8, 2u8, 3u8, 4u8, 5u8, 6u8]; + let z = vector[1u8, 2u8, 3u8, 4u8, 5u8, 6u8]; + + let nested_1 = vector[x]; + let nested_2 = vector[x, x]; + let nested_3 = vector[x, y]; + let nested_4 = vector[x, y, z]; + let nested_5 = vector[x, z]; + let nested_6 = vector[y]; + let nested_7 = vector[y, y]; + let nested_8 = vector[y, z]; + let nested_9 = vector[z]; + let nested_10 = vector[z, z]; + + assert!(test_left_lt_right_nested_vector(nested_1, nested_2), 0); + assert!(test_left_lt_right_nested_vector(nested_2, nested_3), 0); + assert!(test_left_lt_right_nested_vector(nested_3, nested_4), 0); + assert!(test_left_lt_right_nested_vector(nested_4, nested_5), 0); + assert!(test_left_lt_right_nested_vector(nested_5, nested_6), 0); + assert!(test_left_lt_right_nested_vector(nested_6, nested_7), 0); + assert!(test_left_lt_right_nested_vector(nested_7, nested_8), 0); + assert!(test_left_lt_right_nested_vector(nested_8, nested_9), 0); + assert!(test_left_lt_right_nested_vector(nested_9, nested_10), 0); + + assert!(test_left_le_right_nested_vector(nested_1, nested_2), 0); + assert!(test_left_le_right_nested_vector(nested_2, nested_3), 0); + assert!(test_left_le_right_nested_vector(nested_3, nested_4), 0); + assert!(test_left_le_right_nested_vector(nested_4, nested_5), 0); + assert!(test_left_le_right_nested_vector(nested_5, nested_6), 0); + assert!(test_left_le_right_nested_vector(nested_6, nested_7), 0); + assert!(test_left_le_right_nested_vector(nested_7, nested_8), 0); + assert!(test_left_le_right_nested_vector(nested_8, nested_9), 0); + assert!(test_left_le_right_nested_vector(nested_9, nested_10), 0); + + assert!(test_left_gt_right_nested_vector(nested_2, nested_1), 0); + assert!(test_left_gt_right_nested_vector(nested_3, nested_2), 0); + assert!(test_left_gt_right_nested_vector(nested_4, nested_3), 0); + assert!(test_left_gt_right_nested_vector(nested_5, nested_4), 0); + assert!(test_left_gt_right_nested_vector(nested_6, nested_5), 0); + assert!(test_left_gt_right_nested_vector(nested_7, nested_6), 0); + assert!(test_left_gt_right_nested_vector(nested_8, nested_7), 0); + assert!(test_left_gt_right_nested_vector(nested_9, nested_8), 0); + assert!(test_left_gt_right_nested_vector(nested_10, nested_9), 0); + + assert!(test_left_ge_right_nested_vector(nested_2, nested_1), 0); + assert!(test_left_ge_right_nested_vector(nested_3, nested_2), 0); + assert!(test_left_ge_right_nested_vector(nested_4, nested_3), 0); + assert!(test_left_ge_right_nested_vector(nested_5, nested_4), 0); + assert!(test_left_ge_right_nested_vector(nested_6, nested_5), 0); + assert!(test_left_ge_right_nested_vector(nested_7, nested_6), 0); + assert!(test_left_ge_right_nested_vector(nested_8, nested_7), 0); + assert!(test_left_ge_right_nested_vector(nested_9, nested_8), 0); + assert!(test_left_ge_right_nested_vector(nested_10, nested_9), 0); + } +} + +/// Module for struct types + module 0x99::struct_cmp { + use std::cmp; + /// A simple struct + struct Int has drop, copy { + a: u8, + b: u16, + c: u32, + d: u64, + e: u128, + f: u256 + } + + /// A more complex struct + struct Complex has drop, copy { + a: u8, + b: Int, + } + + /// A more complex struct with vectors + struct ComplexWithVec has drop, copy { + a: u8, + b: Int, + c: vector, + d: vector> + } + + //* Simple struct group + fun test_simple_struct_lt(x: Int, y: Int): bool { + // a and b are created to test our optimization + let a = &x; + let b = &y; + + *a < *b && + x < y + } + fun test_simple_struct_le(x: Int, y: Int): bool { + x <= y + } + fun test_simple_struct_gt(x: Int, y: Int): bool { + x > y + } + fun test_simple_struct_ge(x: Int, y: Int): bool { + x >= y + } + + //* Complex struct group + fun test_complex_struct_lt(x: Complex, y: Complex): bool { + // a and b are created to test our optimization + let a = &x; + let b = &y; + + *a < *b && + x < y + } + fun test_complex_struct_le(x: Complex, y: Complex): bool { + x <= y + } + fun test_complex_struct_gt(x: Complex, y: Complex): bool { + x > y + } + fun test_complex_struct_ge(x: Complex, y: Complex): bool { + x >= y + } + + //* Complex struct with vector group + fun test_complex_struct_vec_lt(x: ComplexWithVec, y: ComplexWithVec): bool { + // a and b are created to test our optimization + let a = &x; + let b = &y; + + *a < *b && + x < y && + x.b < y.b && + x.c < y.c && + x.c[0] < y.c[0] && + x.d < y.d && + x.d[0] < y.d[0] && + x.d[0][0] < y.d[0][0] + } + + //* Enum as special struct group + fun test_special_struct_vec_lt(x: ComplexWithVec, y: ComplexWithVec): bool { + // a and b are created to test our optimization + let a = &cmp::compare(&x, &y); + let b = &cmp::compare(&y, &x); + + *a < *b && + cmp::compare(&x, &y) < cmp::compare(&y, &x) && + cmp::compare(&x.b, &y.b) < cmp::compare(&y.b, &x.b) && + cmp::compare(&x.c, &y.c) < cmp::compare(&y.c, &x.c) && + cmp::compare(&x.c[0], &y.c[0]) < cmp::compare(&y.c[0], &x.c[0]) && + cmp::compare(&x.d, &y.d) < cmp::compare(&y.d, &x.d) && + cmp::compare(&x.d[0], &y.d[0]) < cmp::compare(&y.d[0], &x.d[0]) && + cmp::compare(&x.d[0][0], &y.d[0][0]) < cmp::compare(&y.d[0][0], &x.d[0][0]) + } + + //* entry functions for testing struct types + entry fun test_simple_struct(){ + let x = Int { + a: 1, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6 + }; + let y = Int { + a: 2, + b: 3, + c: 4, + d: 5, + e: 6, + f: 7 + }; + + assert!(test_simple_struct_lt(x, y), 0); + assert!(test_simple_struct_le(x, y), 0); + assert!(test_simple_struct_le(x, x), 0); + assert!(test_simple_struct_le(y, y), 0); + + assert!(test_simple_struct_gt(y, x), 0); + assert!(test_simple_struct_ge(y, x), 0); + assert!(test_simple_struct_ge(x, x), 0); + assert!(test_simple_struct_ge(y, y), 0); + } + + entry fun test_complex_struct(){ + + let x = Complex { + a: 1, + b: Int { + a: 1, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6 + } + }; + + let y = Complex { + a: 2, + b: Int { + a: 1, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6 + } + }; + + assert!(test_complex_struct_lt(x, y), 0); + assert!(test_complex_struct_le(x, y), 0); + assert!(test_complex_struct_le(x, x), 0); + assert!(test_complex_struct_le(y, y), 0); + + assert!(test_complex_struct_gt(y, x), 0); + assert!(test_complex_struct_ge(y, x), 0); + assert!(test_complex_struct_ge(x, x), 0); + assert!(test_complex_struct_ge(y, y), 0); + } + + entry fun test_nested_complex_struct(){ + let x = ComplexWithVec { + a: 1, + b: Int { + a: 1, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6 + }, + c: vector[ + Int { + a: 1, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6 + }, + ], + d: vector[ + vector[ + Complex { + a: 1, + b: Int { + a: 1, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6 + } + } + ] + ], + }; + + let y = ComplexWithVec { + a: 2, + b: Int { + a: 2, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6 + }, + c: vector[ + Int { + a: 2, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6 + }, + ], + d: vector[ + vector[ + Complex { + a: 2, + b: Int { + a: 2, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6 + } + } + ] + ], + }; + + assert!(test_complex_struct_vec_lt(x, y), 0); + } + + entry fun test_special_complex_struct(){ + let x = ComplexWithVec { + a: 1, + b: Int { + a: 1, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6 + }, + c: vector[ + Int { + a: 1, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6 + }, + ], + d: vector[ + vector[ + Complex { + a: 1, + b: Int { + a: 1, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6 + } + } + ] + ], + }; + + let y = ComplexWithVec { + a: 2, + b: Int { + a: 2, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6 + }, + c: vector[ + Int { + a: 2, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6 + }, + ], + d: vector[ + vector[ + Complex { + a: 2, + b: Int { + a: 2, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6 + } + } + ] + ], + }; + + assert!(test_special_struct_vec_lt(x, y), 0); + } +} + +/// Module for testing generic types + module 0x99::generic_cmp { + use std::cmp; + public struct Int has drop, copy { + a: u8, + b: u16, + c: u32, + d: u64, + e: u128, + f: u256 + } + + public struct Complex has drop, copy { + a: u8, + b: Int, + } + + struct Foo has drop, copy { x: T } + + struct Bar has drop, copy { + x: T1, + y: vector, + } + + //* Simple generic arg group + fun test_generic_arg_lt(x: T, y: T): bool { + // a and b are created to test our optimization + let a = &cmp::compare(&x, &y); + let b = &cmp::compare(&y, &x); + + *a < *b && + x < y + } + fun test_generic_arg_le(x: T, y: T): bool { + x <= y + } + fun test_generic_arg_gt(x: T, y: T): bool { + x > y + } + fun test_generic_arg_ge(x: T, y: T): bool { + x >= y + } + + + //* Simple generic struct arg group + fun test_generic_struct_lt(x: Foo
, y: Foo
): bool { + // a and b are created to test our optimization + let a = &cmp::compare(&x, &y); + let b = &cmp::compare(&y, &x); + + *a < *b && + x < y && + x.x < y.x + } + fun test_generic_struct_le(x: Foo
, y: Foo
): bool { + + x <= y && + x.x <= y.x + } + fun test_generic_struct_gt(x: Foo
, y: Foo
): bool { + x > y && + x.x > y.x + } + fun test_generic_struct_ge(x: Foo
, y: Foo
): bool { + x >= y && + x.x >= y.x + } + + //* Complex generic struct arg group + public fun test_generic_complex_struct_lt(x: Bar, y: Bar): bool { + // a and b are created to test our optimization + let a = &cmp::compare(&x, &y); + let b = &cmp::compare(&y, &x); + + *a < *b && + x < y && + x.x < y.x && + x.y < y.y && + x.y[0] < y.y[0] + } + public fun test_generic_complex_struct_le(x: Bar, y: Bar): bool { + x <= y && + x.x <= y.x && + x.y <= y.y && + x.y[0] <= y.y[0] + } + public fun test_generic_complex_struct_gt(x: Bar, y: Bar): bool { + x > y && + x.x > y.x && + x.y > y.y && + x.y[0] > y.y[0] + } + public fun test_generic_complex_struct_ge(x: Bar, y: Bar): bool { + x >= y && + x.x >= y.x && + x.y >= y.y && + x.y[0] >= y.y[0] + } + + //* entry functions for testing generic types + entry fun test_generic_arg(){ + let x = @0x1; + let y = @0x2; + assert!(test_generic_arg_lt(x, y), 0); + assert!(test_generic_arg_le(x, y), 0); + assert!(test_generic_arg_le(x, x), 0); + assert!(test_generic_arg_le(y, y), 0); + + assert!(test_generic_arg_gt(y, x), 0); + assert!(test_generic_arg_ge(y, x), 0); + assert!(test_generic_arg_ge(x, x), 0); + assert!(test_generic_arg_ge(y, y), 0); + + } + + entry fun test_generic_struct(){ + let x = Foo
{x: @0x1}; + let y = Foo
{x: @0x2}; + + assert!(test_generic_struct_lt(x, y), 0); + assert!(test_generic_struct_le(x, y), 0); + assert!(test_generic_struct_le(x, x), 0); + assert!(test_generic_struct_le(y, y), 0); + + assert!(test_generic_struct_gt(y, x), 0); + assert!(test_generic_struct_ge(y, x), 0); + assert!(test_generic_struct_ge(x, x), 0); + assert!(test_generic_struct_ge(y, y), 0); + } + + entry fun test_generic_complex_struct(){ + let x = Bar { + x: Int{ + a: 1, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6 + }, + y: vector[ + Complex{ + a: 1, + b: Int { + a: 1, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6 + } + } + ] + }; + + let y = Bar { + x: Int{ + a: 2, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6 + }, + y: vector[ + Complex{ + a: 2, + b: Int { + a: 2, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6 + } + } + ] + }; + + assert!(test_generic_complex_struct_lt(x, y), 0); + assert!(test_generic_complex_struct_le(x, y), 0); + assert!(test_generic_complex_struct_le(x, x), 0); + assert!(test_generic_complex_struct_le(y, y), 0); + + assert!(test_generic_complex_struct_gt(y, x), 0); + assert!(test_generic_complex_struct_ge(y, x), 0); + assert!(test_generic_complex_struct_ge(x, x), 0); + assert!(test_generic_complex_struct_ge(y, y), 0); + } +} + +/// Modules for testing function values +module 0x99::module1 { + public fun test(): u64{ + 1 + } + public fun test1(): u64{ + 1 + } + public fun test2(_x: T){ + } + public fun test3(x: u64): u64{ + x + 1 + } +} +module 0x99::module2 { + public fun test(): u64{ + 1 + } +} + +/// Function values are compared in the following order: +/// 1. Module identification is compared by address and name +/// 2. Function name is compared based on identity string +/// 3. Type parameters are compared based on types (by discriminant index in their defining enum) +/// 4. Captured values are compared + +module 0x99::function_value_cmp { + use 0x99::module1 as module1; + use 0x99::module2 as module2; + + //* entry function for testing function values + entry fun test_module_name_cmp(){ + // f1 < f2 due to module name `module1` < `module2` + // - `f1` named to `closure#0module1::test;` + // - `f2` named to `closure#0module2::test;` + let f1: ||u64 has drop = module1::test; + let f2: ||u64 has drop = module2::test; + assert!(f1 < f2, 0); + } + entry fun test_function_name_cmp(){ + // f1 < f2 due to function name `test` < `test1` + // - `f1` named to `closure#0module1::test;` + // - `f2` named to `closure#0module1::test1;` + let f1: ||u64 has drop = module1::test; + let f2: ||u64 has drop = module1::test1; + assert!(f1 < f2, 0); + + // f3 < f4 due to function name by lambda order + // - `f3` named to `closure#0function_value_cmp::__lambda__1__test_function_name_cmp;` + // - `f4` named to `closure#0function_value_cmp::__lambda__2__test_function_name_cmp;` + let f3: ||u64 has drop = ||1; + let f4: ||u64 has drop = ||1; + assert!(f3 < f4, 0); + + // f5 < f6 due to function name by lambda order + // - `f5` named to `closure#0function_value_cmp::__lambda__3__test_function_name_cmp;` + // - `f6` named to `closure#0function_value_cmp::__lambda__4__test_function_name_cmp;` + let f5: ||u64 has drop = ||1; + let f6: ||u64 has drop = ||100; + assert!(f5 < f6, 0); + } + entry fun test_typed_arg_cmp(){ + // f1 < f2 due to type parameter `u8` < `u64` + let x: u8 = 1; + let y: u64 = 1; + let f1: || has drop = ||module1::test2(x); + let f2: || has drop = ||module1::test2(y); + assert!(f1 < f2, 0); + } + entry fun test_captured_var_cmp(){ + // f1 < f2 due to captured values `1` < `2` + let x = 1; + let y = 2; + let f1: ||u64 has drop = ||module1::test3(x); + let f2: ||u64 has drop = ||module1::test3(y); + assert!(f1 < f2, 0); + } +} diff --git a/aptos-move/e2e-move-tests/src/tests/cmp_generic.data/script/Move.toml b/aptos-move/e2e-move-tests/src/tests/cmp_generic.data/script/Move.toml new file mode 100644 index 00000000000..ea3a9ed9652 --- /dev/null +++ b/aptos-move/e2e-move-tests/src/tests/cmp_generic.data/script/Move.toml @@ -0,0 +1,6 @@ +[package] +name = "two_signer_cmp" +version = "0.0.0" + +[dependencies] +AptosFramework = { local = "../../../../../framework/aptos-framework" } diff --git a/aptos-move/e2e-move-tests/src/tests/cmp_generic.data/script/sources/script.move b/aptos-move/e2e-move-tests/src/tests/cmp_generic.data/script/sources/script.move new file mode 100644 index 00000000000..bdf4e4c325b --- /dev/null +++ b/aptos-move/e2e-move-tests/src/tests/cmp_generic.data/script/sources/script.move @@ -0,0 +1,8 @@ +script { + fun main( + first: signer, + second: signer + ) { + assert!(first <= second, 0); + } +} diff --git a/aptos-move/e2e-move-tests/src/tests/generic_cmp.rs b/aptos-move/e2e-move-tests/src/tests/generic_cmp.rs new file mode 100644 index 00000000000..5bf58919095 --- /dev/null +++ b/aptos-move/e2e-move-tests/src/tests/generic_cmp.rs @@ -0,0 +1,158 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Transactional tests for comparison operations, Lt/Le/Ge/Gt, over non-integer types, +//! introduced in Move language version 2.2 and onwards. + +use crate::{assert_success, tests::common, MoveHarness}; +use aptos_framework::{BuildOptions, BuiltPackage}; +use aptos_language_e2e_tests::account::TransactionBuilder; +use aptos_types::{account_address::AccountAddress, transaction::Script}; + +#[test] +fn function_generic_cmp() { + let mut h = MoveHarness::new(); + + // Load the code + let acc = h.new_account_at(AccountAddress::from_hex_literal("0x99").unwrap()); + assert_success!(h.publish_package_with_options( + &acc, + &common::test_dir_path("cmp_generic.data/pack"), + BuildOptions::move_2().set_latest_language() + )); + + assert_success!(h.run_entry_function( + &acc, + str::parse("0x99::primitive_cmp::test_bool").unwrap(), + vec![], + vec![], + )); + + assert_success!(h.run_entry_function( + &acc, + str::parse("0x99::primitive_cmp::test_address").unwrap(), + vec![], + vec![], + )); + + assert_success!(h.run_entry_function( + &acc, + str::parse("0x99::primitive_cmp::test_vector").unwrap(), + vec![], + vec![], + )); + + assert_success!(h.run_entry_function( + &acc, + str::parse("0x99::struct_cmp::test_simple_struct").unwrap(), + vec![], + vec![], + )); + + assert_success!(h.run_entry_function( + &acc, + str::parse("0x99::struct_cmp::test_complex_struct").unwrap(), + vec![], + vec![], + )); + + assert_success!(h.run_entry_function( + &acc, + str::parse("0x99::struct_cmp::test_nested_complex_struct").unwrap(), + vec![], + vec![], + )); + + assert_success!(h.run_entry_function( + &acc, + str::parse("0x99::struct_cmp::test_special_complex_struct").unwrap(), + vec![], + vec![], + )); + + assert_success!(h.run_entry_function( + &acc, + str::parse("0x99::generic_cmp::test_generic_arg").unwrap(), + vec![], + vec![], + )); + + assert_success!(h.run_entry_function( + &acc, + str::parse("0x99::generic_cmp::test_generic_struct").unwrap(), + vec![], + vec![], + )); + + assert_success!(h.run_entry_function( + &acc, + str::parse("0x99::generic_cmp::test_generic_complex_struct").unwrap(), + vec![], + vec![], + )); + + assert_success!(h.run_entry_function( + &acc, + str::parse("0x99::function_value_cmp::test_module_name_cmp").unwrap(), + vec![], + vec![], + )); + + assert_success!(h.run_entry_function( + &acc, + str::parse("0x99::function_value_cmp::test_function_name_cmp").unwrap(), + vec![], + vec![], + )); + + assert_success!(h.run_entry_function( + &acc, + str::parse("0x99::function_value_cmp::test_typed_arg_cmp").unwrap(), + vec![], + vec![], + )); + + assert_success!(h.run_entry_function( + &acc, + str::parse("0x99::function_value_cmp::test_captured_var_cmp").unwrap(), + vec![], + vec![], + )); +} + +/// Special case of comparing two signers +#[test] +fn function_signer_cmp() { + let mut h = MoveHarness::new(); + + let alice = h.new_account_at(AccountAddress::from_hex_literal("0xa11ce").unwrap()); + let bob = h.new_account_at(AccountAddress::from_hex_literal("0xb0b01").unwrap()); + + let build_options = BuildOptions { + with_srcs: false, + with_abis: false, + with_source_maps: false, + with_error_map: false, + ..BuildOptions::move_2().set_latest_language() + }; + + let package = BuiltPackage::build( + common::test_dir_path("cmp_generic.data/script"), + build_options, + ) + .expect("building package must succeed"); + + let code = package.extract_script_code()[0].clone(); + let script = Script::new(code, vec![], vec![]); + + let transaction = TransactionBuilder::new(alice.clone()) + .secondary_signers(vec![bob.clone()]) + .script(script) + .sequence_number(h.sequence_number(alice.address())) + .max_gas_amount(1_000_000) + .gas_unit_price(1) + .sign_multi_agent(); + + let output = h.executor.execute_transaction(transaction); + assert_success!(output.status().to_owned()); +} diff --git a/aptos-move/e2e-move-tests/src/tests/mod.rs b/aptos-move/e2e-move-tests/src/tests/mod.rs index 87cb8e2f7d5..fa60de62e35 100644 --- a/aptos-move/e2e-move-tests/src/tests/mod.rs +++ b/aptos-move/e2e-move-tests/src/tests/mod.rs @@ -28,6 +28,7 @@ mod function_values; mod fungible_asset; mod gas; mod generate_upgrade_script; +mod generic_cmp; mod governance_updates; mod infinite_loop; mod init_module; diff --git a/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/dependency_ordering.rs b/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/dependency_ordering.rs index 2b65661467e..5b0f9d72cc8 100644 --- a/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/dependency_ordering.rs +++ b/third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/dependency_ordering.rs @@ -37,7 +37,8 @@ pub fn verify( .map(|(mident, _)| mident) .collect::>(); let graph = dependency_graph(&module_neighbors, &imm_module_idents); - let graph = add_implicit_vector_dependencies(graph); + let graph = add_implicit_module_dependencies(graph, AccountAddress::ONE, "vector"); + let graph = add_implicit_module_dependencies(graph, AccountAddress::ONE, "cmp"); match petgraph_toposort(&graph, None) { Err(cycle_node) => { let cycle_ident = *cycle_node.node_id(); @@ -180,29 +181,31 @@ impl<'a> Context<'a> { } } -/// If the `vector` module is present in `graph`, then add dependency edges -/// from every module (not in the `vector` module's dependency closure) to the -/// `vector` module. This is because modules can have implicit dependencies -/// on the `vector` module. -fn add_implicit_vector_dependencies( - mut graph: DiGraphMap<&ModuleIdent, ()>, -) -> DiGraphMap<&ModuleIdent, ()> { - let vector_module = graph.nodes().find(|m| { - m.value.address.into_addr_bytes().into_inner() == AccountAddress::ONE - && m.value.module.0.value.as_str() == "vector" +/// If the target module (`module_address::module_name`) is present in `graph`, +/// then add dependency edges from every module (not in the target module's dependency closure) +/// to the target module. This is used to maintain implicit dependencies introduced +/// by the compiler between user modules and modules like `vector` or `cmp`. +fn add_implicit_module_dependencies<'a>( + mut graph: DiGraphMap<&'a ModuleIdent, ()>, + module_address: AccountAddress, + module_name: &str, +) -> DiGraphMap<&'a ModuleIdent, ()> { + let target_module = graph.nodes().find(|m| { + m.value.address.into_addr_bytes().into_inner() == module_address + && m.value.module.0.value.as_str() == module_name }); - if let Some(vector_module) = vector_module { - let mut dfs = Dfs::new(&graph, vector_module); + if let Some(target_module) = target_module { + let mut dfs = Dfs::new(&graph, target_module); // Get the transitive closure of the `vector` module and its dependencies. - let mut vector_dep_closure = BTreeSet::new(); + let mut target_dep_closure = BTreeSet::new(); while let Some(node) = dfs.next(&graph) { - vector_dep_closure.insert(node); + target_dep_closure.insert(node); } // For every module that is not in `vector_dep_closure`, add an edge to `vector_module`. let all_modules = graph.nodes().collect::>(); for module in all_modules { - if !vector_dep_closure.contains(module) { - graph.add_edge(module, vector_module, ()); + if !target_dep_closure.contains(module) { + graph.add_edge(module, target_module, ()); } } } diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/cmp_rewriter.rs b/third_party/move/move-compiler-v2/src/env_pipeline/cmp_rewriter.rs new file mode 100644 index 00000000000..25d883a90e3 --- /dev/null +++ b/third_party/move/move-compiler-v2/src/env_pipeline/cmp_rewriter.rs @@ -0,0 +1,368 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Comparison operation rewriter +//! - The in-house Lt/Le/Gt/Ge operations only allow integer operands. +//! - We visit Lt/Le/Gt/Ge operations +//! - If their operands are not references or integer primitive types, +//! - we rewrite the operation to use the `std::cmp::compare` function, +//! - and then interpret the result using `std::cmp::is_lt`, `std::cmp::is_le`, etc. +//! +//! Example: +//! x <= y +//! =======> +//! std::cmp::compare(&x, &y).std::cmp::is_le() +//! +//! Key impls +//! - `fn rewrite_cmp_operation`: +//! - Given an ast exp representing a comparison operation, e.g., `Call(Operation::Lt, [arg1, arg2])`, +//! - the function takes five steps: +//! 1. check if `arg1` and `arg2` can be transformed based on their types +//! 2. transform `arg1` and `arg2` into `&arg1` and `&arg2` +//! 3. create a call to `std::cmp::compare`: `exp1 = Call(MoveFunction(std::cmp::compare), [&arg1, &arg2])` +//! 4. create an immutable reference to the result of `std::cmp::compare`: `exp2 = Call(Borrow(Immutable), [exp1])` +//! 5. generate a final call of `is_lt / is_le / is_gt / is_ge` to interpret the result of `std::cmp::compare`: `exp3 = Call(MoveFunction(std::cmp::is_le), [exp2])` +//! - [TODO] An optimization to consider +//! - Once we have public enum, we can direly apply `==` to the result of `std::cmp::compare` (of the `Enum Ordering` type), +//! - which can avoid creating a reference to the result of `std::cmp::compare` and calling `is_lt / is_le / is_gt / is_ge`. +//! +//! +//! Important notes about linking `std::cmp` module: +//! - To ensure the `std::cmp` module is preserved in GlobalEnv during compilation, +//! - code is added in `third_party/move/move-model/src/lib.rs` to keep `std::cmp` and its dependencies during the ast expansion phase +//! - To ensure implicit dependencies introduced by comparison rewriting are maintained +//! - code is added in `third_party/move/move-compiler-v2/legacy-move-compiler/src/expansion/dependency_ordering.rs` to add dependency between every user module and `std::cmp`. +//! - If the user does not include `move-stdlib` for compilation, +//! - a compilation error "cannot find `std::cmp` module" will be raised. +//! +//! Important notes about specs +//! - No extensions are made to comparison operations in specs. +//! - Only primitive integer types are supported as before +//! + +use crate::env_pipeline::rewrite_target::{ + RewriteState, RewriteTarget, RewriteTargets, RewritingScope, +}; +use move_core_types::account_address::AccountAddress; +use move_model::{ + ast::{Address, Exp, ExpData, ModuleName, Operation}, + exp_rewriter::ExpRewriterFunctions, + model::{FunId, FunctionEnv, GlobalEnv, ModuleEnv, NodeId, QualifiedId}, + ty::*, + well_known, +}; +use std::{ + collections::{BTreeMap, BTreeSet}, + iter::Iterator, +}; + +/// Main interface for the comparison operation rewriter +pub fn rewrite(env: &mut GlobalEnv) { + // Create a shared CmpRewriter instance for processing all target functions + let mut rewriter = CmpRewriter::new(env); + let mut targets = RewriteTargets::create(env, RewritingScope::CompilationTarget); + let todo: BTreeSet<_> = targets.keys().collect(); + for target in todo { + if let RewriteTarget::MoveFun(func_id) = target { + let new_def = rewrite_target(&mut rewriter, func_id); + if let Some(def) = new_def { + *targets.state_mut(&target) = RewriteState::Def(def); + } + } + } + targets.write_to_env(env); +} + +/// Rewrite each target function +/// - The rewriting will go through the ExpRewriterFunctions trait +/// - On a `Call` operation, the transformation will be redirected to `rewrite_call` defined later +fn rewrite_target(rewriter: &mut CmpRewriter, func_id: QualifiedId) -> Option { + let func_env = rewriter.env.get_function(func_id); + let def_opt = func_env.get_def(); + if let Some(def) = def_opt { + let rewritten_def = rewriter.rewrite_exp(def.clone()); + if !ExpData::ptr_eq(&rewritten_def, def) { + return Some(rewritten_def); + } + } + None +} + +struct CmpRewriter<'env> { + env: &'env GlobalEnv, + cmp_module: Option>, + cmp_functions: BTreeMap<&'static str, FunctionEnv<'env>>, +} + +/// Override `rewrite_call` from `ExpRewriterFunctions` trait +impl ExpRewriterFunctions for CmpRewriter<'_> { + fn rewrite_call(&mut self, call_id: NodeId, oper: &Operation, args: &[Exp]) -> Option { + if matches!( + oper, + Operation::Lt | Operation::Le | Operation::Gt | Operation::Ge + ) { + self.rewrite_cmp_operation(call_id, oper, args) + } else { + None + } + } +} + +impl<'env> CmpRewriter<'env> { + /// Constants for the `std::cmp` module and its functions + const COMPARE: &'static str = "compare"; + const IS_GE: &'static str = "is_ge"; + const IS_GT: &'static str = "is_gt"; + const IS_LE: &'static str = "is_le"; + const IS_LT: &'static str = "is_lt"; + + fn new(env: &'env GlobalEnv) -> Self { + let cmp_module = Self::find_cmp_module(env); + let mut cmp_functions = BTreeMap::new(); + + if let Some(module) = &cmp_module { + for name in [ + Self::COMPARE, + Self::IS_LT, + Self::IS_LE, + Self::IS_GT, + Self::IS_GE, + ] { + if let Some(func) = Self::find_cmp_function(module, name) { + cmp_functions.insert(name, func); + } + } + } + + Self { + env, + cmp_module, + cmp_functions, + } + } + + /// Rewrite comparison operations + /// - Designs detailed in the beginning of this file + fn rewrite_cmp_operation( + &mut self, + call_id: NodeId, + cmp_op: &Operation, + args: &[Exp], + ) -> Option { + // Step 1: Check argument types + if args.iter().any(|arg| self.arg_cannot_transform(arg)) { + return None; + } + + // Step 2: Transform `arg1` and `arg2` into `&arg1` and `&arg2` + let transformed_args: Vec = args.iter().map(|arg| self.rewrite_cmp_arg(arg)).collect(); + + // Step 3: Create an inner call to `std::cmp::compare(&arg1, &arg2)` + let expected_arg_ty = self.env.get_node_type(args[0].as_ref().node_id()); + let call_cmp = self.generate_call_to_compare(call_id, transformed_args, expected_arg_ty)?; + + // Step 4: Create a immutable reference to the result of `std::cmp::compare(&arg1, &arg2)` + let immref_cmp_res = self.immborrow_compare_res(call_cmp); + + //Step 5: Generate a final call of `is_lt / is_le / is_gt / is_ge` to interpret the result of `std::cmp::compare` + self.generate_call_to_final_res(call_id, cmp_op, vec![immref_cmp_res]) + } + + /// Generate a call to `std::cmp::compare(&arg1, &arg2)` + fn generate_call_to_compare( + &self, + cmp_op_id: NodeId, + args: Vec, + expected_arg_ty: Type, + ) -> Option { + // Reuse the loc info of the original comparison operation + let cmp_loc = self.env.get_node_loc(cmp_op_id); + + // Check the `std::cmp` module + let cmp_module = match self.cmp_module.as_ref() { + Some(module) => module, + None => { + self.env.error( + &cmp_loc, + "cannot find `std::cmp` module. Include `move-stdlib` for compilation.", + ); + let invalid_id = self.env.new_node(self.env.internal_loc(), Type::Error); + return Some(ExpData::Invalid(invalid_id).into_exp()); + }, + }; + let cmp_module_id = cmp_module.get_id(); + + // Check the `std::cmp::compare` function + let compare_function = match self.cmp_functions.get(Self::COMPARE) { + Some(func) => func, + None => { + self.env.error(&cmp_loc, "cannot find `std::cmp::compare` function. Include `move-stdlib` for compilation."); + let invalid_id = self.env.new_node(self.env.internal_loc(), Type::Error); + return Some(ExpData::Invalid(invalid_id).into_exp()); + }, + }; + + // Create a new node sharing return type with `std::cmp::compare` + let cmp_ty = compare_function.get_result_type(); + let new_cmp_node = self.env.new_node(cmp_loc, cmp_ty.clone()); + + // `std::cmp::compare` takes a type parameter, + // which should be instantiated with the type of the actual arguments + self.env + .set_node_instantiation(new_cmp_node, vec![expected_arg_ty]); + + Some( + ExpData::Call( + new_cmp_node, + Operation::MoveFunction(cmp_module_id, compare_function.get_id()), + args, + ) + .into_exp(), + ) + } + + /// Create a new immutable reference for the result of `std::cmp::compare` + fn immborrow_compare_res(&self, call_cmp: Exp) -> Exp { + // Create a new immutable reference for the return value of `std::cmp::compare` + let call_cmp_id = call_cmp.node_id(); + let cmp_loc = self.env.get_node_loc(call_cmp_id); + let cmp_ty = self.env.get_node_type(call_cmp_id); + let new_ref_type = Type::Reference(ReferenceKind::Immutable, Box::new(cmp_ty)); + let new_ref_id = self.env.new_node(cmp_loc, new_ref_type); + + ExpData::Call( + new_ref_id, + Operation::Borrow(ReferenceKind::Immutable), + vec![call_cmp], + ) + .into_exp() + } + + /// Generate a final call to interpret the result of `std::cmp::compare` + fn generate_call_to_final_res( + &self, + ori_op_id: NodeId, + cmp_op: &Operation, + args: Vec, + ) -> Option { + // Reuse the loc info of the original comparison operation + let final_res_loc = self.env.get_node_loc(ori_op_id); + + // Check the `std::cmp` module + let cmp_module = match self.cmp_module.as_ref() { + Some(module) => module, + None => { + self.env + .error(&final_res_loc, "cannot find `std::cmp` module"); + let invalid_id = self.env.new_node(self.env.internal_loc(), Type::Error); + return Some(ExpData::Invalid(invalid_id).into_exp()); + }, + }; + let cmp_module_id = cmp_module.get_id(); + + let sym = match cmp_op { + Operation::Lt => Self::IS_LT, + Operation::Le => Self::IS_LE, + Operation::Gt => Self::IS_GT, + Operation::Ge => Self::IS_GE, + _ => return None, + }; + + // Check the `std::cmp::is_lt/is_le/is_gt/is_ge` function + let final_res_function = match self.cmp_functions.get(sym) { + Some(func) => func, + None => { + self.env.error( + &final_res_loc, + format!("cannot find `std::cmp::{}` function", sym).as_str(), + ); + let invalid_id = self.env.new_node(self.env.internal_loc(), Type::Error); + return Some(ExpData::Invalid(invalid_id).into_exp()); + }, + }; + + let final_res_ty = Type::Primitive(PrimitiveType::Bool); + let final_res_id = self.env.new_node(final_res_loc, final_res_ty.clone()); + Some( + ExpData::Call( + final_res_id, + Operation::MoveFunction(cmp_module_id, final_res_function.get_id()), + args, + ) + .into_exp(), + ) + } + + /// We cannot rewrite references or integer primitive types + /// - References are not allowed in Lt/Le/Gt/Ge operations + /// - Integer primitive types are supported by the VM natively + fn arg_cannot_transform(&mut self, arg: &Exp) -> bool { + let arg_ty = self.env.get_node_type(arg.as_ref().node_id()); + matches!( + arg_ty, + Type::Reference(_, _) + | Type::Primitive( + PrimitiveType::U8 + | PrimitiveType::U16 + | PrimitiveType::U32 + | PrimitiveType::U64 + | PrimitiveType::U128 + | PrimitiveType::U256 + | PrimitiveType::Num + ) + ) + } + + /// Insert a new immutable reference before the argument + fn rewrite_cmp_arg(&mut self, arg: &Exp) -> Exp { + if let Some(arg_ref) = self.remove_deref_from_arg(arg) { + return arg_ref; + } + // Insert a new immutable reference before the argument + let arg_loc = self.env.get_node_loc(arg.as_ref().node_id()); + let arg_ty = self.env.get_node_type(arg.as_ref().node_id()); + let new_ref_type = Type::Reference(ReferenceKind::Immutable, Box::new(arg_ty.clone())); + let new_ref_id = self.env.new_node(arg_loc, new_ref_type); + ExpData::Call( + new_ref_id, + Operation::Borrow(ReferenceKind::Immutable), + vec![arg.clone()], + ) + .into_exp() + } + + /// Optimization: if the argument is a dereference operation, we get the inner reference directly + fn remove_deref_from_arg(&mut self, arg: &Exp) -> Option { + if let ExpData::Call(_, Operation::Deref, deref_args) = arg.as_ref() { + debug_assert!( + deref_args.len() == 1, + "there should be exactly one argument for dereference" + ); + let deref_arg_ty = self.env.get_node_type(deref_args[0].as_ref().node_id()); + if let Type::Reference(ReferenceKind::Immutable, _) = deref_arg_ty { + // If the deref argument is an immutable reference, we can return it directly + return Some(deref_args[0].clone()); + } + } + None + } + + /// Find the `std::cmp` module + fn find_cmp_module(env: &'env GlobalEnv) -> Option> { + // Find the `std::cmp` module + let cmp_module_name = ModuleName::new( + Address::Numerical(AccountAddress::ONE), + env.symbol_pool().make(well_known::CMP_MODULE), + ); + env.find_module(&cmp_module_name) + } + + /// Find function from the `std::cmp` module + fn find_cmp_function( + cmp_module: &ModuleEnv<'env>, + func_name: &str, + ) -> Option> { + let compare_sym = cmp_module.symbol_pool().make(func_name); + cmp_module.find_function(compare_sym) + } +} diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/mod.rs b/third_party/move/move-compiler-v2/src/env_pipeline/mod.rs index fb2161ae5ee..029a395a0f6 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/mod.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/mod.rs @@ -11,6 +11,7 @@ use std::io::Write; pub mod acquires_checker; pub mod ast_simplifier; pub mod closure_checker; +pub mod cmp_rewriter; pub mod cyclic_instantiation_checker; pub mod flow_insensitive_checkers; pub mod function_checker; diff --git a/third_party/move/move-compiler-v2/src/experiments.rs b/third_party/move/move-compiler-v2/src/experiments.rs index 1a94e655181..615dd41c1c7 100644 --- a/third_party/move/move-compiler-v2/src/experiments.rs +++ b/third_party/move/move-compiler-v2/src/experiments.rs @@ -96,6 +96,11 @@ pub static EXPERIMENTS: Lazy> = Lazy::new(|| { .to_string(), default: Inherited(Experiment::CHECKS.to_string()), }, + Experiment { + name: Experiment::CMP_REWRITE.to_string(), + description: "Rewrite comparison operations".to_string(), + default: Given(true), + }, Experiment { name: Experiment::INLINING.to_string(), description: "Turns on or off inlining".to_string(), @@ -282,6 +287,7 @@ impl Experiment { pub const ATTACH_COMPILED_MODULE: &'static str = "attach-compiled-module"; pub const CFG_SIMPLIFICATION: &'static str = "cfg-simplification"; pub const CHECKS: &'static str = "checks"; + pub const CMP_REWRITE: &'static str = "cmp-rewrite"; pub const DEAD_CODE_ELIMINATION: &'static str = "dead-code-elimination"; pub const DUPLICATE_STRUCT_PARAMS_CHECK: &'static str = "duplicate-struct-params-check"; pub const FAIL_ON_WARNING: &'static str = "fail-on-warning"; diff --git a/third_party/move/move-compiler-v2/src/lib.rs b/third_party/move/move-compiler-v2/src/lib.rs index 223287b9a2f..eb4605484bf 100644 --- a/third_party/move/move-compiler-v2/src/lib.rs +++ b/third_party/move/move-compiler-v2/src/lib.rs @@ -17,11 +17,11 @@ pub mod plan_builder; use crate::{ diagnostics::Emitter, env_pipeline::{ - acquires_checker, ast_simplifier, closure_checker, cyclic_instantiation_checker, - flow_insensitive_checkers, function_checker, inliner, lambda_lifter, - lambda_lifter::LambdaLiftingOptions, model_ast_lints, recursive_struct_checker, - rewrite_target::RewritingScope, seqs_in_binop_checker, spec_checker, spec_rewriter, - unused_params_checker, EnvProcessorPipeline, + acquires_checker, ast_simplifier, closure_checker, cmp_rewriter, + cyclic_instantiation_checker, flow_insensitive_checkers, function_checker, inliner, + lambda_lifter, lambda_lifter::LambdaLiftingOptions, model_ast_lints, + recursive_struct_checker, rewrite_target::RewritingScope, seqs_in_binop_checker, + spec_checker, spec_rewriter, unused_params_checker, EnvProcessorPipeline, }, pipeline::{ ability_processor::AbilityProcessor, @@ -377,6 +377,20 @@ pub fn env_check_and_transform_pipeline<'a, 'b>(options: &'a Options) -> EnvProc env_pipeline.add("model AST lints", model_ast_lints::checker); } + // The comparison rewriter is a new features in Aptos Move 2.2 and onwards + let rewrite_cmp = options + .language_version + .unwrap_or_default() + .is_at_least(LanguageVersion::V2_2) + && options.experiment_on(Experiment::CMP_REWRITE); + + if rewrite_cmp { + env_pipeline.add("rewrite comparison operations", |env| { + // This rewrite is suggested to run before inlining to avoid repeated rewriting + cmp_rewriter::rewrite(env); + }); + } + if options.experiment_on(Experiment::INLINING) { let rewriting_scope = if options.whole_program { RewritingScope::Everything diff --git a/third_party/move/move-model/src/builder/builtins.rs b/third_party/move/move-model/src/builder/builtins.rs index e189c9a3db3..12d038b5867 100644 --- a/third_party/move/move-model/src/builder/builtins.rs +++ b/third_party/move/move-model/src/builder/builtins.rs @@ -7,6 +7,7 @@ use crate::{ ast::{Operation, TraceKind, Value}, builder::model_builder::{ConstEntry, EntryVisibility, ModelBuilder, SpecOrBuiltinFunEntry}, + metadata::LanguageVersion, model::{Parameter, TypeParameter, TypeParameterKind}, ty::{Constraint, PrimitiveType, ReferenceKind, Type}, }; @@ -165,6 +166,37 @@ pub(crate) fn declare_builtins(trans: &mut ModelBuilder) { visibility, ); } + }; + + // Declare the specification arithm ops, based on Num type. + declare_arithm_ops( + trans, + &[], + &BTreeMap::new(), + Type::new_prim(PrimitiveType::Num), + Spec, // visible only in the spec language + ); + // For the implementation arithm ops, we use a generic function with a constraint, + // conceptually: `fun _+_(x: A, y: A): A where A: u8|u16|..|u256`. + declare_arithm_ops( + trans, + &[param_t_decl.clone()], + &[( + 0, + Constraint::SomeNumber(PrimitiveType::all_int_types().into_iter().collect()), + )] + .into_iter() + .collect(), + param_t.clone(), + Impl, // visible only in the impl language + ); + + // Builtin function for comparison operations + let declare_cmp_ops = |trans: &mut ModelBuilder, + type_params: &[TypeParameter], + type_constraints: &BTreeMap, + ty: Type, + visibility: EntryVisibility| { for (op, oper) in [ (Lt, Operation::Lt), (Le, Operation::Le), @@ -185,28 +217,49 @@ pub(crate) fn declare_builtins(trans: &mut ModelBuilder) { } }; - // Declare the specification arithm ops, based on Num type. - declare_arithm_ops( + // Declare the specification cmp ops. + // Only Num type is supported for cmp ops in spec. + declare_cmp_ops( trans, &[], &BTreeMap::new(), Type::new_prim(PrimitiveType::Num), Spec, // visible only in the spec language ); - // For the implementation arithm ops, we use a generic function with a constraint, - // conceptually: `fun _+_(x: A, y: A): A where A: u8|u16|..|u256`. - declare_arithm_ops( - trans, - &[param_t_decl.clone()], - &[( - 0, - Constraint::SomeNumber(PrimitiveType::all_int_types().into_iter().collect()), - )] - .into_iter() - .collect(), - param_t.clone(), - Impl, // visible only in the impl language - ); + // Declare the implementation cmp ops + if trans + .env + .language_version() + .is_at_least(LanguageVersion::V2_2) + { + // For LanguageVersion::V2_2 and later, we support comparison on all non-reference types. + // - integer types supported by the VM natively + // - other types supported by the `compare` native function + // - implicitly through compiler rewrite at the AST level + declare_cmp_ops( + trans, + &[param_t_decl.clone()], + &[(0, Constraint::NoReference)].into_iter().collect(), + param_t.clone(), + Impl, // visible only in the impl language + ); + } else { + // For LanguageVersion::V2_1 and earlier, we support only integer types. + // We use a generic function with a constraint, conceptually: + // `fun _cmp_(x: A, y: A): bool where A: u8|u16|..|u256`. + declare_cmp_ops( + trans, + &[param_t_decl.clone()], + &[( + 0, + Constraint::SomeNumber(PrimitiveType::all_int_types().into_iter().collect()), + )] + .into_iter() + .collect(), + param_t.clone(), + Impl, // visible only in the impl language + ); + } declare_bin(trans, Range, Operation::Range, num_t, num_t, range_t, Spec); diff --git a/third_party/move/move-model/src/lib.rs b/third_party/move/move-model/src/lib.rs index 5e75c98db19..b74745af0bb 100644 --- a/third_party/move/move-model/src/lib.rs +++ b/third_party/move/move-model/src/lib.rs @@ -269,7 +269,10 @@ pub fn run_model_builder_with_options_and_compilation_flags< let mut visited_modules = BTreeSet::new(); // Extract the module dependency closure for the vector module let mut vector_and_its_dependencies = BTreeSet::new(); + // Extract the module dependency closure for the std::cmp module + let mut cmp_and_its_dependencies = BTreeSet::new(); let mut seen_vector = false; + let mut seen_cmp = false; for (_, mident, mdef) in &expansion_ast.modules { let src_file_hash = mdef.loc.file_hash(); if !dep_files.contains(&src_file_hash) { @@ -284,6 +287,15 @@ pub fn run_model_builder_with_options_and_compilation_flags< &mut vector_and_its_dependencies, ); } + if !seen_cmp && is_cmp(*mident) { + seen_cmp = true; + // Collect the cmp module and its dependencies. + collect_related_modules_recursive( + mident, + &expansion_ast.modules, + &mut cmp_and_its_dependencies, + ); + } } for sdef in expansion_ast.scripts.values() { let src_file_hash = sdef.loc.file_hash(); @@ -307,6 +319,9 @@ pub fn run_model_builder_with_options_and_compilation_flags< // E.g., index operation on a vector results in a call to `vector::borrow`. // TODO(#15483): consider refactoring code to avoid this special case. (vector_and_its_dependencies.contains(&mident.value) + // We also need to always include the `cmp` module and its dependencies, + // so that we can use interfaces offered by `cmp` to support comparison, Lt/Le/Gt/Ge, over non-integer types. + || cmp_and_its_dependencies.contains(&mident.value) || visited_modules.contains(&mident.value)) .then(|| { mdef.is_source_module = true; @@ -327,6 +342,12 @@ fn is_vector(module_ident: ModuleIdent_) -> bool { && module_ident.module.0.value.as_str() == "vector" } +/// Is `module_ident` the `0x1::cmp` module? +fn is_cmp(module_ident: ModuleIdent_) -> bool { + module_ident.address.into_addr_bytes().into_inner() == AccountAddress::ONE + && module_ident.module.0.value.as_str() == well_known::CMP_MODULE +} + fn run_move_checker(env: &mut GlobalEnv, program: E::Program) { let mut builder = ModelBuilder::new(env); for (module_count, (module_id, module_def)) in program diff --git a/third_party/move/move-model/src/well_known.rs b/third_party/move/move-model/src/well_known.rs index 68c67c087dc..c9cc893ee4d 100644 --- a/third_party/move/move-model/src/well_known.rs +++ b/third_party/move/move-model/src/well_known.rs @@ -42,6 +42,8 @@ pub const VECTOR_FUNCS_WITH_BYTECODE_INSTRS: &[&str] = &[ "swap", ]; +pub const CMP_MODULE: &str = "cmp"; + pub const TYPE_NAME_MOVE: &str = "type_info::type_name"; pub const TYPE_NAME_SPEC: &str = "type_info::$type_name"; pub const TYPE_INFO_MOVE: &str = "type_info::type_of"; From d58642de66f97863a8dcf51baee4536a3ad16b11 Mon Sep 17 00:00:00 2001 From: Vineeth Kashyap Date: Wed, 18 Jun 2025 16:47:28 -0400 Subject: [PATCH 006/260] [compiler-v2] Clarify internal compliler error messages (#16819) Downstreamed-from: d7d42b91b271b5ad4ad0bc5c54b7092e3e0dbcb4 --- .../src/file_format_generator/module_generator.rs | 11 ++++++++--- third_party/move/move-compiler-v2/src/lib.rs | 13 ++++++++----- .../tests/bytecode-verify-failure/equality.exp | 4 +++- .../tests/constants/large_vectors.no-optimize.exp | 4 +++- .../tests/no-recursive-check/no_recursive_check.exp | 4 +++- 5 files changed, 25 insertions(+), 11 deletions(-) diff --git a/third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs b/third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs index ab2b8fb6733..fa3642439bb 100644 --- a/third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs +++ b/third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs @@ -8,7 +8,7 @@ use crate::{ MAX_MODULE_COUNT, MAX_SIGNATURE_COUNT, MAX_STRUCT_COUNT, MAX_STRUCT_DEF_COUNT, MAX_STRUCT_DEF_INST_COUNT, MAX_STRUCT_VARIANT_COUNT, MAX_STRUCT_VARIANT_INST_COUNT, }, - Options, + Options, COMPILER_BUG_REPORT_MSG, }; use codespan_reporting::diagnostic::Severity; use itertools::Itertools; @@ -995,8 +995,13 @@ impl ModuleContext<'_> { } /// Emits an internal error at the location. - pub fn internal_error(&self, loc: impl AsRef, msg: impl AsRef) { - self.env.diag(Severity::Bug, loc.as_ref(), msg.as_ref()) + pub fn internal_error(&self, loc: impl AsRef, msg: impl AsRef + ToString) { + self.env.diag_with_notes( + Severity::Bug, + loc.as_ref(), + format!("compiler internal error: {}", msg.to_string()).as_str(), + vec![COMPILER_BUG_REPORT_MSG.to_string()], + ) } /// Check for a bound table index and report an error if its out of bound. All bounds diff --git a/third_party/move/move-compiler-v2/src/lib.rs b/third_party/move/move-compiler-v2/src/lib.rs index eb4605484bf..bcc18618334 100644 --- a/third_party/move/move-compiler-v2/src/lib.rs +++ b/third_party/move/move-compiler-v2/src/lib.rs @@ -72,6 +72,8 @@ pub use options::Options; use std::{collections::BTreeSet, path::Path}; const DEBUG: bool = false; +const COMPILER_BUG_REPORT_MSG: &str = + "please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue)"; /// Run Move compiler and print errors to stderr. pub fn run_move_compiler_to_stderr( @@ -655,13 +657,14 @@ fn report_bytecode_verification_error( env.to_loc(module_ir_loc) }); if e.status_type() != StatusType::Verification { - env.diag( + env.diag_with_notes( Severity::Bug, loc, &format!( - "unexpected error returned from bytecode verification. This is a compiler bug, consider reporting it.\n{:#?}", + "unexpected error returned from bytecode verification:\n{:#?}", e ), + vec![COMPILER_BUG_REPORT_MSG.to_string()], ) } else { let debug_info = if command_line::get_move_compiler_backtrace_from_env() { @@ -672,15 +675,15 @@ fn report_bytecode_verification_error( e.message().cloned().unwrap_or_else(|| "none".to_string()) ) }; - env.diag( + env.diag_with_notes( Severity::Bug, loc, &format!( - "bytecode verification failed with \ - unexpected status code `{:?}`. This is a compiler bug, consider reporting it.{}", + "bytecode verification failed with unexpected status code `{:?}`:{}", e.major_status(), debug_info ), + vec![COMPILER_BUG_REPORT_MSG.to_string()], ) } } diff --git a/third_party/move/move-compiler-v2/tests/bytecode-verify-failure/equality.exp b/third_party/move/move-compiler-v2/tests/bytecode-verify-failure/equality.exp index 601110318e5..cdeb24e656b 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-verify-failure/equality.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-verify-failure/equality.exp @@ -1,7 +1,9 @@ Diagnostics: -bug: file format generator: Inferred and Store AssignKind should be not appear here. +bug: compiler internal error: file format generator: Inferred and Store AssignKind should be not appear here. ┌─ tests/bytecode-verify-failure/equality.move:2:7 │ 2 │ fun equality(x: T, y: T): bool { │ ^^^^^^^^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/large_vectors.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/large_vectors.no-optimize.exp index ab002de457e..bd428897d63 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/constants/large_vectors.no-optimize.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/constants/large_vectors.no-optimize.exp @@ -2,12 +2,14 @@ processed 3 tasks task 0 'publish'. lines 1-15: Error: compilation errors: - bug: bytecode verification failed with unexpected status code `VALUE_STACK_OVERFLOW`. This is a compiler bug, consider reporting it. + bug: bytecode verification failed with unexpected status code `VALUE_STACK_OVERFLOW`: Error message: none ┌─ TEMPFILE:5:24 │ 5 │ let v = vector[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026]; │ ^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-check/no_recursive_check.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-check/no_recursive_check.exp index d19e007de6f..bdf9d66b02c 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-check/no_recursive_check.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-check/no_recursive_check.exp @@ -2,7 +2,7 @@ processed 2 tasks task 0 'publish'. lines 1-27: Error: compilation errors: - bug: bytecode verification failed with unexpected status code `RECURSIVE_STRUCT_DEFINITION`. This is a compiler bug, consider reporting it. + bug: bytecode verification failed with unexpected status code `RECURSIVE_STRUCT_DEFINITION`: Error message: none ┌─ TEMPFILE:2:1 │ @@ -14,6 +14,8 @@ Error message: none 22 │ │ } 23 │ │ } │ ╰─^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) From 235040b7764405c29f2bc6992c52c19096a1ff17 Mon Sep 17 00:00:00 2001 From: George Mitenkov Date: Mon, 23 Jun 2025 12:56:25 +0100 Subject: [PATCH 007/260] [vm] Remove captured layout compatibility check for closures (#16791) Downstreamed-from: 86c831261b36d38a40593df68808f78f14ec83db --- third_party/move/move-core/types/src/value.rs | 47 --------- .../move/move-vm/runtime/src/interpreter.rs | 2 +- .../move-vm/runtime/src/loader/function.rs | 95 +++---------------- 3 files changed, 16 insertions(+), 128 deletions(-) diff --git a/third_party/move/move-core/types/src/value.rs b/third_party/move/move-core/types/src/value.rs index 607670a64b9..d7e18c968c3 100644 --- a/third_party/move/move-core/types/src/value.rs +++ b/third_party/move/move-core/types/src/value.rs @@ -270,28 +270,6 @@ pub enum MoveTypeLayout { Function, } -impl MoveTypeLayout { - /// Determines whether the layout is serialization compatible with the other layout - /// (that is, any value serialized with this layout can be deserialized by the other). - pub fn is_compatible_with(&self, other: &Self) -> bool { - use MoveTypeLayout::*; - match (self, other) { - (Vector(t1), Vector(t2)) => t1.is_compatible_with(t2), - (Struct(s1), Struct(s2)) => s1.is_compatible_with(s2), - // For all other cases, equality is used - (t1, t2) => t1 == t2, - } - } - - pub fn is_compatible_with_slice(this: &[Self], other: &[Self]) -> bool { - this.len() == other.len() - && this - .iter() - .zip(other) - .all(|(t1, t2)| t1.is_compatible_with(t2)) - } -} - impl MoveValue { pub fn simple_deserialize(blob: &[u8], ty: &MoveTypeLayout) -> AResult { Ok(bcs::from_bytes_seed(ty, blob)?) @@ -510,31 +488,6 @@ impl MoveStructLayout { Self::WithVariants(variants) } - /// Determines whether the layout is serialization compatible with the other layout - /// (that is, any value serialized with this layout can be deserialized by the other). - /// This only will consider runtime variants, decorated variants are only compatible - /// if equal. - pub fn is_compatible_with(&self, other: &Self) -> bool { - use MoveStructLayout::*; - match (self, other) { - (RuntimeVariants(variants1), RuntimeVariants(variants2)) => { - variants1.len() <= variants2.len() - && variants1.iter().zip(variants2).all(|(fields1, fields2)| { - MoveTypeLayout::is_compatible_with_slice(fields1, fields2) - }) - }, - (Runtime(fields1), Runtime(fields2)) => { - fields1.len() == fields2.len() - && fields1 - .iter() - .zip(fields2) - .all(|(t1, t2)| t1.is_compatible_with(t2)) - }, - // All other cases require equality - (s1, s2) => s1 == s2, - } - } - pub fn fields(&self, variant: Option) -> &[MoveTypeLayout] { match self { Self::Runtime(vals) => vals, diff --git a/third_party/move/move-vm/runtime/src/interpreter.rs b/third_party/move/move-vm/runtime/src/interpreter.rs index 951fb02cdf2..6f9793f5983 100644 --- a/third_party/move/move-vm/runtime/src/interpreter.rs +++ b/third_party/move/move-vm/runtime/src/interpreter.rs @@ -602,7 +602,7 @@ impl InterpreterImpl<'_> { // Resolve the function. This may lead to loading the code related // to this function. let callee = lazy_function - .with_resolved_function(module_storage, |f| Ok(f.clone())) + .as_resolved(module_storage) .map_err(|e| set_err_info!(current_frame, e))?; RTTCheck::check_call_visibility( diff --git a/third_party/move/move-vm/runtime/src/loader/function.rs b/third_party/move/move-vm/runtime/src/loader/function.rs index fc45927f4d2..1b3e1851d14 100644 --- a/third_party/move/move-vm/runtime/src/loader/function.rs +++ b/third_party/move/move-vm/runtime/src/loader/function.rs @@ -5,7 +5,6 @@ use crate::{ loader::{access_specifier_loader::load_access_specifier, Module, Script}, native_functions::{NativeFunction, NativeFunctions, UnboxedNativeFunction}, - storage::ty_layout_converter::{LayoutConverter, StorageLayoutConverter}, ModuleStorage, RuntimeEnvironment, }; use better_any::{Tid, TidAble, TidExt}; @@ -23,7 +22,6 @@ use move_core_types::{ identifier::{IdentStr, Identifier}, language_storage, language_storage::{ModuleId, TypeTag}, - value::MoveTypeLayout, vm_status::StatusCode, }; use move_vm_types::{ @@ -190,17 +188,15 @@ impl LazyLoadedFunction { } } - /// Executed an action with the resolved loaded function. If the function hasn't been - /// loaded yet, it will be loaded now. - #[allow(unused)] - pub(crate) fn with_resolved_function( + /// If the function hasn't been resolved (loaded) yet, loads it. The gas is also charged for + /// function loading and any other module accesses. + pub(crate) fn as_resolved( &self, - storage: &dyn ModuleStorage, - action: impl FnOnce(Rc) -> PartialVMResult, - ) -> PartialVMResult { + module_storage: &impl ModuleStorage, + ) -> PartialVMResult> { let mut state = self.0.borrow_mut(); - match &mut *state { - LazyLoadedFunctionState::Resolved { fun, .. } => action(fun.clone()), + Ok(match &mut *state { + LazyLoadedFunctionState::Resolved { fun, .. } => fun.clone(), LazyLoadedFunctionState::Unresolved { data: SerializedFunctionData { @@ -209,82 +205,21 @@ impl LazyLoadedFunction { fun_id, ty_args, mask, - captured_layouts, + captured_layouts: _, }, } => { - let fun = - Self::resolve(storage, module_id, fun_id, ty_args, *mask, captured_layouts)?; - let result = action(fun.clone()); + let fun = module_storage + .load_function(module_id, fun_id, ty_args) + .map(Rc::new) + .map_err(|err| err.to_partial())?; *state = LazyLoadedFunctionState::Resolved { - fun, + fun: fun.clone(), ty_args: ty_args.clone(), mask: *mask, }; - result + fun }, - } - } - - /// Resolves a function into a loaded function. This verifies existence of the named - /// function as well as whether it has the type used for deserializing the captured values. - fn resolve( - module_storage: &dyn ModuleStorage, - module_id: &ModuleId, - fun_id: &IdentStr, - ty_args: &[TypeTag], - mask: ClosureMask, - captured_layouts: &[MoveTypeLayout], - ) -> PartialVMResult> { - let function = module_storage - .load_function(module_id, fun_id, ty_args) - .map_err(|err| err.to_partial())?; - - // Verify that the function argument types match the layouts used for deserialization. - // This is only done in paranoid mode. Since integrity of storage - // and guarantee of public function, this should not able to fail. - if module_storage - .runtime_environment() - .vm_config() - .paranoid_type_checks - { - // TODO(#15664): Determine whether we need to charge gas here. - let captured_arg_types = mask.extract(function.param_tys(), true); - let converter = StorageLayoutConverter::new(module_storage); - if captured_arg_types.len() != captured_layouts.len() { - return Err(PartialVMError::new(StatusCode::FUNCTION_RESOLUTION_FAILURE) - .with_message( - "captured argument count does not match declared parameters".to_string(), - )); - } - - let ty_builder = &module_storage.runtime_environment().vm_config().ty_builder; - for (actual_arg_ty, serialized_layout) in - captured_arg_types.into_iter().zip(captured_layouts) - { - // We do not allow function values to capture any delayed fields, for now. Note - // that this is enforced at serialization time. Here we cannot enforce it because - // function value could have stored an old version of an enum without an aggregator - // but the new layout has the new variant with the aggregator. In any case, the - // serializer will fail on this resolved closure if there is an attempt to put it - // back into storage. - let actual_arg_layout = if function.ty_args().is_empty() { - converter.type_to_type_layout(actual_arg_ty)? - } else { - let actual_arg_ty = - ty_builder.create_ty_with_subst(actual_arg_ty, function.ty_args())?; - converter.type_to_type_layout(&actual_arg_ty)? - }; - - if !serialized_layout.is_compatible_with(&actual_arg_layout) { - return Err(PartialVMError::new(StatusCode::FUNCTION_RESOLUTION_FAILURE) - .with_message( - "stored captured argument layout does not match declared parameters" - .to_string(), - )); - } - } - } - Ok(Rc::new(function)) + }) } } From 8b01dac2a1f94c85f42787b48069308f91db563e Mon Sep 17 00:00:00 2001 From: George Mitenkov Date: Mon, 23 Jun 2025 15:41:06 +0100 Subject: [PATCH 008/260] [lazy-loading] Loader traits, type depth calculations (#16459) Downstreamed-from: fb653b664917e7c906e33ca818b0d5c9997f18c8 --- .../aptos-vm-types/src/module_write_set.rs | 9 +- aptos-move/aptos-vm/src/aptos_vm.rs | 17 +- .../move/move-core/types/src/vm_status.rs | 10 +- .../src/tests/module_storage_tests.rs | 2 +- .../move/move-vm/runtime/src/interpreter.rs | 169 ++-- third_party/move/move-vm/runtime/src/lib.rs | 17 + .../move/move-vm/runtime/src/move_vm.rs | 35 +- .../src/storage/dependencies_gas_charging.rs | 2 +- .../src/storage/depth_formula_calculator.rs | 138 ---- .../runtime/src/storage/loader/eager.rs | 66 ++ .../runtime/src/storage/loader/lazy.rs | 94 +++ .../move-vm/runtime/src/storage/loader/mod.rs | 8 + .../runtime/src/storage/loader/test_utils.rs | 172 +++++ .../runtime/src/storage/loader/traits.rs | 28 + .../move/move-vm/runtime/src/storage/mod.rs | 3 +- .../runtime/src/storage/module_storage.rs | 7 +- .../runtime/src/storage/ty_depth_checker.rs | 730 ++++++++++++++++++ .../types/src/loaded_data/runtime_types.rs | 12 +- 18 files changed, 1245 insertions(+), 274 deletions(-) delete mode 100644 third_party/move/move-vm/runtime/src/storage/depth_formula_calculator.rs create mode 100644 third_party/move/move-vm/runtime/src/storage/loader/eager.rs create mode 100644 third_party/move/move-vm/runtime/src/storage/loader/lazy.rs create mode 100644 third_party/move/move-vm/runtime/src/storage/loader/mod.rs create mode 100644 third_party/move/move-vm/runtime/src/storage/loader/test_utils.rs create mode 100644 third_party/move/move-vm/runtime/src/storage/loader/traits.rs create mode 100644 third_party/move/move-vm/runtime/src/storage/ty_depth_checker.rs diff --git a/aptos-move/aptos-vm-types/src/module_write_set.rs b/aptos-move/aptos-vm-types/src/module_write_set.rs index 47a30fa5f02..7348bc998fd 100644 --- a/aptos-move/aptos-vm-types/src/module_write_set.rs +++ b/aptos-move/aptos-vm-types/src/module_write_set.rs @@ -102,8 +102,15 @@ impl ModuleWriteSet { module_storage: &'a impl ModuleStorage, ) -> impl Iterator>> { self.writes.iter_mut().map(move |(key, write)| { + // The unmetered access to module size is fine because: + // + // INVARIANT: + // If there is a write to the module at key K, it means the module at K has been read + // (in order to perform backward-compatibility checks) if it existed. + // If module at K previously did not exist, the read of previous size returns None. + // Because module with key K has been read, it must have been loaded and metered. let prev_size = module_storage - .fetch_module_size_in_bytes(write.module_address(), write.module_name()) + .unmetered_get_module_size(write.module_address(), write.module_name()) .map_err(|e| e.to_partial())? .unwrap_or(0) as u64; Ok(WriteOpInfo { diff --git a/aptos-move/aptos-vm/src/aptos_vm.rs b/aptos-move/aptos-vm/src/aptos_vm.rs index 32ff16e0c90..209c2914956 100644 --- a/aptos-move/aptos-vm/src/aptos_vm.rs +++ b/aptos-move/aptos-vm/src/aptos_vm.rs @@ -1389,7 +1389,7 @@ impl AptosVM { } let size_if_old_module_exists = module_storage - .fetch_module_size_in_bytes(addr, name)? + .unmetered_get_module_size(addr, name)? .map(|v| v as u64); if let Some(old_size) = size_if_old_module_exists { gas_meter @@ -2100,7 +2100,6 @@ impl AptosVM { &self, executor_view: &dyn ExecutorView, resource_group_view: &dyn ResourceGroupView, - module_storage: &impl AptosModuleStorage, change_set: &VMChangeSet, module_write_set: &ModuleWriteSet, ) -> PartialVMResult<()> { @@ -2110,12 +2109,13 @@ impl AptosVM { ); // All Move executions satisfy the read-before-write property. Thus, we need to read each - // access path that the write set is going to update. - for write in module_write_set.writes().values() { - // It is sufficient to simply get the size in order to enforce read-before-write. - module_storage - .fetch_module_size_in_bytes(write.module_address(), write.module_name()) - .map_err(|e| e.to_partial())?; + // access path that the write set is going to update (because the write set comes directly + // form the transaction payload). + for state_key in module_write_set.writes().keys() { + executor_view.read_state_value(state_key).map_err(|err| { + PartialVMError::new(StatusCode::STORAGE_ERROR) + .with_message(format!("Cannot read module at {:?}: {:?}", state_key, err)) + })?; } for (state_key, write_op) in change_set.resource_write_set().iter() { executor_view.get_resource_state_value(state_key, None)?; @@ -2173,7 +2173,6 @@ impl AptosVM { self.read_change_set( resolver.as_executor_view(), resolver.as_resource_group_view(), - code_storage, &change_set, &module_write_set, ) diff --git a/third_party/move/move-core/types/src/vm_status.rs b/third_party/move/move-core/types/src/vm_status.rs index 37e3c0eca77..677201cdecb 100644 --- a/third_party/move/move-core/types/src/vm_status.rs +++ b/third_party/move/move-core/types/src/vm_status.rs @@ -886,12 +886,14 @@ pub enum StatusCode { STRUCT_VARIANT_MISMATCH = 4038, // An unimplemented functionality in the VM. UNIMPLEMENTED_FUNCTIONALITY = 4039, + // Modules are cyclic (module A uses module B which uses module A). Detected at runtime in case + // module loading is performed lazily. + RUNTIME_CYCLIC_MODULE_DEPENDENCY = 4040, // Reserved error code for future use. Always keep this buffer of well-defined new codes. - RESERVED_RUNTIME_ERROR_1 = 4040, - RESERVED_RUNTIME_ERROR_2 = 4041, - RESERVED_RUNTIME_ERROR_3 = 4042, - RESERVED_RUNTIME_ERROR_4 = 4043, + RESERVED_RUNTIME_ERROR_1 = 4041, + RESERVED_RUNTIME_ERROR_2 = 4042, + RESERVED_RUNTIME_ERROR_3 = 4043, // A reserved status to represent an unknown vm status. // this is u64::MAX, but we can't pattern match on that, so put the hardcoded value in diff --git a/third_party/move/move-vm/integration-tests/src/tests/module_storage_tests.rs b/third_party/move/move-vm/integration-tests/src/tests/module_storage_tests.rs index 00424243732..32a78221a5a 100644 --- a/third_party/move/move-vm/integration-tests/src/tests/module_storage_tests.rs +++ b/third_party/move/move-vm/integration-tests/src/tests/module_storage_tests.rs @@ -56,7 +56,7 @@ fn test_module_does_not_exist() { let result = module_storage.check_module_exists(&AccountAddress::ZERO, ident_str!("a")); assert!(!assert_ok!(result)); - let result = module_storage.fetch_module_size_in_bytes(&AccountAddress::ZERO, ident_str!("a")); + let result = module_storage.unmetered_get_module_size(&AccountAddress::ZERO, ident_str!("a")); assert_none!(assert_ok!(result)); let result = module_storage.fetch_module_metadata(&AccountAddress::ZERO, ident_str!("a")); diff --git a/third_party/move/move-vm/runtime/src/interpreter.rs b/third_party/move/move-vm/runtime/src/interpreter.rs index 6f9793f5983..30c5c857944 100644 --- a/third_party/move/move-vm/runtime/src/interpreter.rs +++ b/third_party/move/move-vm/runtime/src/interpreter.rs @@ -20,8 +20,8 @@ use crate::{ verify_pack_closure, FullRuntimeTypeCheck, NoRuntimeTypeCheck, RuntimeTypeCheck, }, storage::{ - dependencies_gas_charging::check_dependencies_and_charge_gas, - depth_formula_calculator::DepthFormulaCalculator, + dependencies_gas_charging::check_dependencies_and_charge_gas, loader::traits::Loader, + ty_depth_checker::TypeDepthChecker, }, trace, LoadedFunction, ModuleStorage, RuntimeEnvironment, }; @@ -39,7 +39,6 @@ use move_core_types::{ language_storage::TypeTag, vm_status::{StatusCode, StatusType}, }; -use move_vm_metrics::{Timer, VM_TIMER}; use move_vm_types::{ debug_write, debug_writeln, gas::{GasMeter, SimpleInstruction}, @@ -86,7 +85,7 @@ pub(crate) trait InterpreterDebugInterface { /// /// An `Interpreter` instance is a stand alone execution context for a function. /// It mimics execution on a single thread, with an call stack and an operand stack. -pub(crate) struct InterpreterImpl<'ctx> { +pub(crate) struct InterpreterImpl<'ctx, LoaderImpl> { /// Operand stack, where Move `Value`s are stored for stack operations. pub(crate) operand_stack: Stack, /// The stack of active functions. @@ -97,6 +96,8 @@ pub(crate) struct InterpreterImpl<'ctx> { access_control: AccessControlState, /// Reentrancy checker. reentrancy_checker: ReentrancyChecker, + /// Checks depth of types of values. Used to bound packing too deep structs or vectors. + ty_depth_checker: &'ctx TypeDepthChecker<'ctx, LoaderImpl>, } struct TypeWithRuntimeEnvironment<'a, 'b> { @@ -118,6 +119,7 @@ impl Interpreter { args: Vec, data_cache: &mut TransactionDataCache, module_storage: &impl ModuleStorage, + ty_depth_checker: &TypeDepthChecker, resource_resolver: &impl ResourceResolver, gas_meter: &mut impl GasMeter, traversal_context: &mut TraversalContext, @@ -128,6 +130,7 @@ impl Interpreter { args, data_cache, module_storage, + ty_depth_checker, resource_resolver, gas_meter, traversal_context, @@ -136,7 +139,10 @@ impl Interpreter { } } -impl InterpreterImpl<'_> { +impl InterpreterImpl<'_, LoaderImpl> +where + LoaderImpl: Loader, +{ /// Entrypoint into the interpreter. All external calls need to be routed through this /// function. pub(crate) fn entrypoint( @@ -144,6 +150,7 @@ impl InterpreterImpl<'_> { args: Vec, data_cache: &mut TransactionDataCache, module_storage: &impl ModuleStorage, + ty_depth_checker: &TypeDepthChecker, resource_resolver: &impl ResourceResolver, gas_meter: &mut impl GasMeter, traversal_context: &mut TraversalContext, @@ -155,6 +162,7 @@ impl InterpreterImpl<'_> { vm_config: module_storage.runtime_environment().vm_config(), access_control: AccessControlState::default(), reentrancy_checker: ReentrancyChecker::default(), + ty_depth_checker, }; let function = Rc::new(function); @@ -311,6 +319,7 @@ impl InterpreterImpl<'_> { resource_resolver, module_storage, gas_meter, + traversal_context, ) .map_err(|err| self.attach_state_if_invariant_violation(err, ¤t_frame))?; @@ -1486,7 +1495,10 @@ impl InterpreterImpl<'_> { } } -impl InterpreterDebugInterface for InterpreterImpl<'_> { +impl InterpreterDebugInterface for InterpreterImpl<'_, LoaderImpl> +where + LoaderImpl: Loader, +{ #[allow(dead_code)] fn debug_print_stack_trace( &self, @@ -1675,100 +1687,6 @@ impl CallStack { } } -fn check_depth_of_type(module_storage: &impl ModuleStorage, ty: &Type) -> PartialVMResult<()> { - let _timer = VM_TIMER.timer_with_label("Interpreter::check_depth_of_type"); - - // Start at 1 since we always call this right before we add a new node to the value's depth. - let max_depth = match module_storage - .runtime_environment() - .vm_config() - .max_value_nest_depth - { - Some(max_depth) => max_depth, - None => return Ok(()), - }; - check_depth_of_type_impl(module_storage, ty, max_depth, 1)?; - Ok(()) -} - -fn check_depth_of_type_impl( - module_storage: &impl ModuleStorage, - ty: &Type, - max_depth: u64, - depth: u64, -) -> PartialVMResult { - macro_rules! check_depth { - ($additional_depth:expr) => {{ - let new_depth = depth.saturating_add($additional_depth); - if new_depth > max_depth { - return Err(PartialVMError::new(StatusCode::VM_MAX_VALUE_DEPTH_REACHED)); - } else { - new_depth - } - }}; - } - - // Calculate depth of the type itself - let ty_depth = match ty { - Type::Bool - | Type::U8 - | Type::U16 - | Type::U32 - | Type::U64 - | Type::U128 - | Type::U256 - | Type::Address - | Type::Signer => check_depth!(0), - // Even though this is recursive this is OK since the depth of this recursion is - // bounded by the depth of the type arguments, which we have already checked. - Type::Reference(ty) | Type::MutableReference(ty) => { - check_depth_of_type_impl(module_storage, ty, max_depth, check_depth!(1))? - }, - Type::Vector(ty) => { - check_depth_of_type_impl(module_storage, ty, max_depth, check_depth!(1))? - }, - Type::Struct { idx, .. } => { - let formula = - DepthFormulaCalculator::new(module_storage).calculate_depth_of_struct(idx)?; - check_depth!(formula.solve(&[])) - }, - // NB: substitution must be performed before calling this function - Type::StructInstantiation { idx, ty_args, .. } => { - // Calculate depth of all type arguments, and make sure they themselves are not too deep. - let ty_arg_depths = ty_args - .iter() - .map(|ty| { - // Ty args should be fully resolved and not need any type arguments - check_depth_of_type_impl(module_storage, ty, max_depth, check_depth!(0)) - }) - .collect::>>()?; - let formula = - DepthFormulaCalculator::new(module_storage).calculate_depth_of_struct(idx)?; - check_depth!(formula.solve(&ty_arg_depths)) - }, - Type::Function { args, results, .. } => { - let mut ty_max_depth = depth; - for ty in args.iter().chain(results) { - ty_max_depth = ty_max_depth.max(check_depth_of_type_impl( - module_storage, - ty, - max_depth, - check_depth!(1), - )?); - } - ty_max_depth - }, - Type::TyParam(_) => { - return Err( - PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR) - .with_message("Type parameter should be fully resolved".to_string()), - ) - }, - }; - - Ok(ty_depth) -} - /// An `ExitCode` from `execute_code_unit`. #[derive(Debug)] enum ExitCode { @@ -1782,11 +1700,12 @@ impl Frame { /// Execute a Move function until a return or a call opcode is found. fn execute_code( &mut self, - interpreter: &mut InterpreterImpl, + interpreter: &mut InterpreterImpl, data_cache: &mut TransactionDataCache, resource_resolver: &impl ResourceResolver, module_storage: &impl ModuleStorage, gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, ) -> VMResult { self.execute_code_impl::( interpreter, @@ -1794,6 +1713,7 @@ impl Frame { resource_resolver, module_storage, gas_meter, + traversal_context, ) .map_err(|e| { let e = if cfg!(feature = "testing") || cfg!(feature = "stacktrace") { @@ -1807,11 +1727,12 @@ impl Frame { fn execute_code_impl( &mut self, - interpreter: &mut InterpreterImpl, + interpreter: &mut InterpreterImpl, data_cache: &mut TransactionDataCache, resource_resolver: &impl ResourceResolver, module_storage: &impl ModuleStorage, gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, ) -> PartialVMResult { use SimpleInstruction as S; @@ -2081,11 +2002,15 @@ impl Frame { interpreter.operand_stack.push(field_ref)?; }, Bytecode::Pack(sd_idx) => { - let get_field_count_charge_gas_and_check_depth = + let mut get_field_count_charge_gas_and_check_depth = || -> PartialVMResult { let field_count = self.field_count(*sd_idx); let struct_type = self.get_struct_ty(*sd_idx); - check_depth_of_type(module_storage, &struct_type)?; + interpreter.ty_depth_checker.check_depth_of_type( + gas_meter, + traversal_context, + &struct_type, + )?; Ok(field_count) }; @@ -2116,7 +2041,11 @@ impl Frame { Bytecode::PackVariant(idx) => { let info = self.get_struct_variant_at(*idx); let struct_type = self.create_struct_ty(&info.definition_struct_type); - check_depth_of_type(module_storage, &struct_type)?; + interpreter.ty_depth_checker.check_depth_of_type( + gas_meter, + traversal_context, + &struct_type, + )?; gas_meter.charge_pack_variant( false, interpreter @@ -2146,7 +2075,11 @@ impl Frame { let (ty, ty_count) = frame_cache.get_struct_type(*si_idx, self)?; gas_meter.charge_create_ty(ty_count)?; - check_depth_of_type(module_storage, ty)?; + interpreter.ty_depth_checker.check_depth_of_type( + gas_meter, + traversal_context, + ty, + )?; Ok(self.field_instantiation_count(*si_idx)) }; @@ -2188,7 +2121,11 @@ impl Frame { let (ty, ty_count) = frame_cache.get_struct_variant_type(*si_idx, self)?; gas_meter.charge_create_ty(ty_count)?; - check_depth_of_type(module_storage, ty)?; + interpreter.ty_depth_checker.check_depth_of_type( + gas_meter, + traversal_context, + ty, + )?; let info = self.get_struct_variant_instantiation_at(*si_idx); gas_meter.charge_pack_variant( @@ -2238,7 +2175,11 @@ impl Frame { let (ty, ty_count) = frame_cache.get_struct_type(*si_idx, self)?; gas_meter.charge_create_ty(ty_count)?; - check_depth_of_type(module_storage, ty)?; + interpreter.ty_depth_checker.check_depth_of_type( + gas_meter, + traversal_context, + ty, + )?; let struct_ = interpreter.operand_stack.pop_as::()?; @@ -2261,7 +2202,11 @@ impl Frame { let (ty, ty_count) = frame_cache.get_struct_variant_type(*si_idx, self)?; gas_meter.charge_create_ty(ty_count)?; - check_depth_of_type(module_storage, ty)?; + interpreter.ty_depth_checker.check_depth_of_type( + gas_meter, + traversal_context, + ty, + )?; let struct_ = interpreter.operand_stack.pop_as::()?; @@ -2653,7 +2598,11 @@ impl Frame { Bytecode::VecPack(si, num) => { let (ty, ty_count) = frame_cache.get_signature_index_type(*si, self)?; gas_meter.charge_create_ty(ty_count)?; - check_depth_of_type(module_storage, ty)?; + interpreter.ty_depth_checker.check_depth_of_type( + gas_meter, + traversal_context, + ty, + )?; gas_meter.charge_vec_pack( make_ty!(ty), interpreter.operand_stack.last_n(*num as usize)?, diff --git a/third_party/move/move-vm/runtime/src/lib.rs b/third_party/move/move-vm/runtime/src/lib.rs index 47a517b585b..c0960a0ef73 100644 --- a/third_party/move/move-vm/runtime/src/lib.rs +++ b/third_party/move/move-vm/runtime/src/lib.rs @@ -44,6 +44,23 @@ pub use storage::{ unsync_code_storage::{AsUnsyncCodeStorage, UnsyncCodeStorage}, unsync_module_storage::{AsUnsyncModuleStorage, BorrowedOrOwned, UnsyncModuleStorage}, }, + loader::{eager::EagerLoader, lazy::LazyLoader, traits::Loader}, module_storage::{ambassador_impl_ModuleStorage, AsFunctionValueExtension, ModuleStorage}, publishing::{StagingModuleStorage, VerifiedModuleBundle}, }; + +#[macro_export] +macro_rules! dispatch_loader { + ($module_storage:expr, $loader:ident, $dispatch:stmt) => { + if $crate::WithRuntimeEnvironment::runtime_environment($module_storage) + .vm_config() + .enable_lazy_loading + { + let $loader = $crate::LazyLoader::new($module_storage); + $dispatch + } else { + let $loader = $crate::EagerLoader::new($module_storage); + $dispatch + } + }; +} diff --git a/third_party/move/move-vm/runtime/src/move_vm.rs b/third_party/move/move-vm/runtime/src/move_vm.rs index a261a3676cc..ccdeb834c03 100644 --- a/third_party/move/move-vm/runtime/src/move_vm.rs +++ b/third_party/move/move-vm/runtime/src/move_vm.rs @@ -4,10 +4,15 @@ use crate::{ data_cache::TransactionDataCache, + dispatch_loader, interpreter::Interpreter, module_traversal::TraversalContext, native_extensions::NativeContextExtensions, - storage::ty_layout_converter::{LayoutConverter, StorageLayoutConverter}, + storage::{ + loader::traits::Loader, + ty_depth_checker::TypeDepthChecker, + ty_layout_converter::{LayoutConverter, StorageLayoutConverter}, + }, AsFunctionValueExtension, LoadedFunction, ModuleStorage, }; use move_binary_format::{ @@ -60,6 +65,32 @@ impl MoveVM { extensions: &mut NativeContextExtensions, module_storage: &impl ModuleStorage, resource_resolver: &impl ResourceResolver, + ) -> VMResult { + dispatch_loader!(module_storage, loader, { + Self::execute_loaded_function_impl( + function, + serialized_args, + data_cache, + &loader, + gas_meter, + traversal_context, + extensions, + module_storage, + resource_resolver, + ) + }) + } + + pub fn execute_loaded_function_impl( + function: LoadedFunction, + serialized_args: Vec>, + data_cache: &mut TransactionDataCache, + loader: &impl Loader, + gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, + extensions: &mut NativeContextExtensions, + module_storage: &impl ModuleStorage, + resource_resolver: &impl ResourceResolver, ) -> VMResult { let vm_config = module_storage.runtime_environment().vm_config(); let ty_builder = &vm_config.ty_builder; @@ -80,11 +111,13 @@ impl MoveVM { let return_values = { let _timer = VM_TIMER.timer_with_label("Interpreter::entrypoint"); + let ty_depth_checker = TypeDepthChecker::new(loader); Interpreter::entrypoint( function, deserialized_args, data_cache, module_storage, + &ty_depth_checker, resource_resolver, gas_meter, traversal_context, diff --git a/third_party/move/move-vm/runtime/src/storage/dependencies_gas_charging.rs b/third_party/move/move-vm/runtime/src/storage/dependencies_gas_charging.rs index c00eb46cb2d..065b1ba04b4 100644 --- a/third_party/move/move-vm/runtime/src/storage/dependencies_gas_charging.rs +++ b/third_party/move/move-vm/runtime/src/storage/dependencies_gas_charging.rs @@ -102,7 +102,7 @@ where while let Some((addr, name)) = stack.pop() { let size = module_storage - .fetch_module_size_in_bytes(addr, name)? + .unmetered_get_module_size(addr, name)? .ok_or_else(|| module_linker_error!(addr, name))?; gas_meter .charge_dependency(false, addr, name, NumBytes::new(size as u64)) diff --git a/third_party/move/move-vm/runtime/src/storage/depth_formula_calculator.rs b/third_party/move/move-vm/runtime/src/storage/depth_formula_calculator.rs deleted file mode 100644 index d11d90d4241..00000000000 --- a/third_party/move/move-vm/runtime/src/storage/depth_formula_calculator.rs +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright (c) The Move Contributors -// SPDX-License-Identifier: Apache-2.0 - -use crate::ModuleStorage; -use move_binary_format::{ - errors::{PartialVMError, PartialVMResult}, - file_format::TypeParameterIndex, -}; -use move_core_types::vm_status::StatusCode; -use move_vm_types::loaded_data::{ - runtime_types::{DepthFormula, StructLayout, Type}, - struct_name_indexing::StructNameIndex, -}; -use std::collections::{BTreeMap, HashMap}; - -/// Calculates [DepthFormula] for struct types. Stores a cache of visited formulas. -pub(crate) struct DepthFormulaCalculator<'a, M> { - module_storage: &'a M, - visited_formulas: HashMap, -} - -impl<'a, M> DepthFormulaCalculator<'a, M> -where - M: ModuleStorage, -{ - pub(crate) fn new(module_storage: &'a M) -> Self { - Self { - module_storage, - visited_formulas: HashMap::new(), - } - } - - pub(crate) fn calculate_depth_of_struct( - &mut self, - struct_name_idx: &StructNameIndex, - ) -> PartialVMResult { - if let Some(depth_formula) = self.visited_formulas.get(struct_name_idx) { - return Ok(depth_formula.clone()); - } - - let struct_type = self - .module_storage - .fetch_struct_ty_by_idx(struct_name_idx)?; - let formulas = match &struct_type.layout { - StructLayout::Single(fields) => fields - .iter() - .map(|(_, field_ty)| self.calculate_depth_of_type(field_ty)) - .collect::>>()?, - StructLayout::Variants(variants) => variants - .iter() - .flat_map(|variant| variant.1.iter().map(|(_, ty)| ty)) - .map(|field_ty| self.calculate_depth_of_type(field_ty)) - .collect::>>()?, - }; - - let formula = DepthFormula::normalize(formulas); - if self - .visited_formulas - .insert(*struct_name_idx, formula.clone()) - .is_some() - { - // Same thread has put this entry previously, which means there is a recursion. - let struct_name = self - .module_storage - .runtime_environment() - .struct_name_index_map() - .idx_to_struct_name_ref(*struct_name_idx)?; - return Err( - PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR).with_message( - format!( - "Depth formula for struct '{}' is already cached by the same thread", - struct_name.as_ref(), - ), - ), - ); - } - Ok(formula) - } - - fn calculate_depth_of_type(&mut self, ty: &Type) -> PartialVMResult { - Ok(match ty { - Type::Bool - | Type::U8 - | Type::U64 - | Type::U128 - | Type::Address - | Type::Signer - | Type::U16 - | Type::U32 - | Type::U256 => DepthFormula::constant(1), - Type::Vector(ty) => { - let mut inner = self.calculate_depth_of_type(ty)?; - inner.scale(1); - inner - }, - Type::Reference(ty) | Type::MutableReference(ty) => { - let mut inner = self.calculate_depth_of_type(ty)?; - inner.scale(1); - inner - }, - Type::TyParam(ty_idx) => DepthFormula::type_parameter(*ty_idx), - Type::Struct { idx, .. } => { - let mut struct_formula = self.calculate_depth_of_struct(idx)?; - debug_assert!(struct_formula.terms.is_empty()); - struct_formula.scale(1); - struct_formula - }, - Type::StructInstantiation { idx, ty_args, .. } => { - let ty_arg_map = ty_args - .iter() - .enumerate() - .map(|(idx, ty)| { - let var = idx as TypeParameterIndex; - Ok((var, self.calculate_depth_of_type(ty)?)) - }) - .collect::>>()?; - let struct_formula = self.calculate_depth_of_struct(idx)?; - let mut subst_struct_formula = struct_formula.subst(ty_arg_map)?; - subst_struct_formula.scale(1); - subst_struct_formula - }, - Type::Function { - args, - results, - abilities: _, - } => { - let mut inner = DepthFormula::normalize( - args.iter() - .chain(results) - .map(|arg_ty| self.calculate_depth_of_type(arg_ty)) - .collect::>>()?, - ); - inner.scale(1); - inner - }, - }) - } -} diff --git a/third_party/move/move-vm/runtime/src/storage/loader/eager.rs b/third_party/move/move-vm/runtime/src/storage/loader/eager.rs new file mode 100644 index 00000000000..42003635648 --- /dev/null +++ b/third_party/move/move-vm/runtime/src/storage/loader/eager.rs @@ -0,0 +1,66 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + module_traversal::TraversalContext, + storage::loader::traits::{Loader, StructDefinitionLoader}, + ModuleStorage, RuntimeEnvironment, WithRuntimeEnvironment, +}; +use move_binary_format::errors::PartialVMResult; +use move_vm_types::{ + gas::DependencyGasMeter, + loaded_data::{runtime_types::StructType, struct_name_indexing::StructNameIndex}, +}; +use std::sync::Arc; + +/// Eager loader implementation used prior to lazy loading. It uses eager module verification by +/// loading and verifying the transitive closure of module's dependencies and friends. The gas is +/// metered at "entrypoints" (entry function or a script, dynamic dispatch) for the whole closure +/// at once. +pub struct EagerLoader<'a, T> { + module_storage: &'a T, +} + +impl<'a, T> EagerLoader<'a, T> +where + T: ModuleStorage, +{ + /// Returns a new eager loader. + pub fn new(module_storage: &'a T) -> Self { + Self { module_storage } + } +} + +impl<'a, T> WithRuntimeEnvironment for EagerLoader<'a, T> +where + T: ModuleStorage, +{ + fn runtime_environment(&self) -> &RuntimeEnvironment { + self.module_storage.runtime_environment() + } +} + +impl<'a, T> StructDefinitionLoader for EagerLoader<'a, T> +where + T: ModuleStorage, +{ + fn load_struct_definition( + &self, + _gas_meter: &mut impl DependencyGasMeter, + _traversal_context: &mut TraversalContext, + idx: &StructNameIndex, + ) -> PartialVMResult> { + let struct_name = self + .runtime_environment() + .struct_name_index_map() + .idx_to_struct_name_ref(*idx)?; + + self.module_storage.fetch_struct_ty( + struct_name.module.address(), + struct_name.module.name(), + struct_name.name.as_ident_str(), + ) + } +} + +impl<'a, T> Loader for EagerLoader<'a, T> where T: ModuleStorage {} diff --git a/third_party/move/move-vm/runtime/src/storage/loader/lazy.rs b/third_party/move/move-vm/runtime/src/storage/loader/lazy.rs new file mode 100644 index 00000000000..284e0e78ac2 --- /dev/null +++ b/third_party/move/move-vm/runtime/src/storage/loader/lazy.rs @@ -0,0 +1,94 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + module_traversal::TraversalContext, + storage::loader::traits::{Loader, StructDefinitionLoader}, + ModuleStorage, RuntimeEnvironment, WithRuntimeEnvironment, +}; +use move_binary_format::errors::PartialVMResult; +use move_core_types::{gas_algebra::NumBytes, language_storage::ModuleId}; +use move_vm_types::{ + gas::DependencyGasMeter, + loaded_data::{runtime_types::StructType, struct_name_indexing::StructNameIndex}, + module_linker_error, +}; +use std::sync::Arc; + +/// Loader implementation used after lazy loading is enabled. Every module access is metered +/// dynamically (if it is first access to a module with the current [TraversalContext], then gas is +/// charged). Module verification is lazy: there is no loading of transitive closure of module's +/// dependencies and friends when accessing a verified module, a function definition or a struct +/// definition. +pub struct LazyLoader<'a, T> { + module_storage: &'a T, +} + +impl<'a, T> LazyLoader<'a, T> +where + T: ModuleStorage, +{ + /// Returns a new lazy loader. + pub fn new(module_storage: &'a T) -> Self { + Self { module_storage } + } + + /// Charges gas for the module load if the module has not been loaded already. + fn charge_module( + &self, + gas_meter: &mut impl DependencyGasMeter, + traversal_context: &mut TraversalContext, + module_id: &ModuleId, + ) -> PartialVMResult<()> { + let module_id = traversal_context + .referenced_module_ids + .alloc(module_id.clone()); + let addr = module_id.address(); + let name = module_id.name(); + + if traversal_context.visit_if_not_special_address(addr, name) { + let size = self + .module_storage + .unmetered_get_module_size(addr, name) + .map_err(|err| err.to_partial())? + .ok_or_else(|| module_linker_error!(addr, name).to_partial())?; + gas_meter.charge_dependency(false, addr, name, NumBytes::new(size as u64))?; + } + Ok(()) + } +} + +impl<'a, T> WithRuntimeEnvironment for LazyLoader<'a, T> +where + T: ModuleStorage, +{ + fn runtime_environment(&self) -> &RuntimeEnvironment { + self.module_storage.runtime_environment() + } +} + +impl<'a, T> StructDefinitionLoader for LazyLoader<'a, T> +where + T: ModuleStorage, +{ + fn load_struct_definition( + &self, + gas_meter: &mut impl DependencyGasMeter, + traversal_context: &mut TraversalContext, + idx: &StructNameIndex, + ) -> PartialVMResult> { + let struct_name = self + .runtime_environment() + .struct_name_index_map() + .idx_to_struct_name_ref(*idx)?; + + self.charge_module(gas_meter, traversal_context, &struct_name.module)?; + self.module_storage.fetch_struct_ty( + struct_name.module.address(), + struct_name.module.name(), + struct_name.name.as_ident_str(), + ) + } +} + +impl<'a, T> Loader for LazyLoader<'a, T> where T: ModuleStorage {} diff --git a/third_party/move/move-vm/runtime/src/storage/loader/mod.rs b/third_party/move/move-vm/runtime/src/storage/loader/mod.rs new file mode 100644 index 00000000000..d09d46c287c --- /dev/null +++ b/third_party/move/move-vm/runtime/src/storage/loader/mod.rs @@ -0,0 +1,8 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +pub(crate) mod eager; +pub(crate) mod lazy; +#[cfg(test)] +pub(crate) mod test_utils; +pub(crate) mod traits; diff --git a/third_party/move/move-vm/runtime/src/storage/loader/test_utils.rs b/third_party/move/move-vm/runtime/src/storage/loader/test_utils.rs new file mode 100644 index 00000000000..b165ea16f63 --- /dev/null +++ b/third_party/move/move-vm/runtime/src/storage/loader/test_utils.rs @@ -0,0 +1,172 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + module_traversal::TraversalContext, storage::loader::traits::StructDefinitionLoader, + RuntimeEnvironment, WithRuntimeEnvironment, +}; +use claims::assert_none; +use move_binary_format::errors::{PartialVMError, PartialVMResult}; +use move_core_types::{ + ability::AbilitySet, identifier::Identifier, language_storage::ModuleId, vm_status::StatusCode, +}; +use move_vm_types::{ + gas::DependencyGasMeter, + loaded_data::{ + runtime_types::{AbilityInfo, StructIdentifier, StructLayout, StructType, Type}, + struct_name_indexing::StructNameIndex, + }, +}; +use smallbitvec::SmallBitVec; +use std::{cell::RefCell, collections::HashMap, str::FromStr, sync::Arc}; + +/// Creates a dummy struct definition. +pub(crate) fn struct_definition( + idx: StructNameIndex, + fields: Vec<(Identifier, Type)>, +) -> StructType { + StructType { + idx, + layout: StructLayout::Single(fields), + // Below is irrelevant for tests. + ty_params: vec![], + phantom_ty_params_mask: SmallBitVec::default(), + abilities: AbilitySet::EMPTY, + } +} + +/// Creates a dummy enum definition. +pub(crate) fn enum_definition( + idx: StructNameIndex, + variants: Vec<(Identifier, Vec<(Identifier, Type)>)>, +) -> StructType { + StructType { + idx, + layout: StructLayout::Variants(variants), + // Below is irrelevant for tests. + ty_params: vec![], + phantom_ty_params_mask: SmallBitVec::default(), + abilities: AbilitySet::EMPTY, + } +} + +/// Creates a dummy struct (or enum) type. +pub(crate) fn struct_ty(idx: StructNameIndex) -> Type { + Type::Struct { + idx, + // Below is irrelevant for tests. + ability: AbilityInfo::struct_(AbilitySet::EMPTY), + } +} + +/// Creates a dummy generic struct (or enum) type. +pub(crate) fn generic_struct_ty(idx: StructNameIndex, ty_args: Vec) -> Type { + Type::StructInstantiation { + idx, + ty_args: triomphe::Arc::new(ty_args), + // Below is irrelevant for tests. + ability: AbilityInfo::struct_(AbilitySet::EMPTY), + } +} + +/// Mocks struct definition loading, by holding a cache of [StructType]s and runtime environment. +pub(crate) struct MockStructDefinitionLoader { + runtime_environment: RuntimeEnvironment, + struct_definitions: RefCell>>, +} + +impl MockStructDefinitionLoader { + /// Returns an index for a struct name. The struct name is added to the environment. + pub(crate) fn get_struct_identifier(&self, struct_name: &str) -> StructNameIndex { + let struct_identifier = StructIdentifier { + module: ModuleId::from_str("0x1::foo").unwrap(), + name: Identifier::from_str(struct_name).unwrap(), + }; + self.runtime_environment + .struct_name_to_idx_for_test(struct_identifier) + .unwrap() + } + + /// Adds a dummy struct to the mock cache. + pub(crate) fn add_struct<'a>( + &self, + struct_name: &str, + field_struct_names: impl IntoIterator, + ) { + let fields = field_struct_names + .into_iter() + .map(|(name, field_ty)| { + let field_name = Identifier::from_str(name).unwrap(); + (field_name, field_ty) + }) + .collect(); + + let idx = self.get_struct_identifier(struct_name); + let struct_definition = struct_definition(idx, fields); + + assert_none!(self + .struct_definitions + .borrow_mut() + .insert(struct_definition.idx, Arc::new(struct_definition))); + } + + /// Adds a dummy enum to the mock cache. + pub(crate) fn add_enum<'a>( + &self, + struct_name: &str, + variant_field_struct_names: impl IntoIterator)>, + ) { + let variants = variant_field_struct_names + .into_iter() + .map(|(variant, fields)| { + let variant_name = Identifier::from_str(variant).unwrap(); + let fields = fields + .into_iter() + .map(|(name, field_ty)| { + let field_name = Identifier::from_str(name).unwrap(); + (field_name, field_ty) + }) + .collect::>(); + (variant_name, fields) + }) + .collect(); + + let idx = self.get_struct_identifier(struct_name); + let struct_definition = enum_definition(idx, variants); + + assert_none!(self + .struct_definitions + .borrow_mut() + .insert(struct_definition.idx, Arc::new(struct_definition))); + } +} + +impl Default for MockStructDefinitionLoader { + fn default() -> Self { + Self { + runtime_environment: RuntimeEnvironment::new(vec![]), + struct_definitions: RefCell::new(HashMap::new()), + } + } +} + +impl WithRuntimeEnvironment for MockStructDefinitionLoader { + fn runtime_environment(&self) -> &RuntimeEnvironment { + &self.runtime_environment + } +} + +impl StructDefinitionLoader for MockStructDefinitionLoader { + fn load_struct_definition( + &self, + _gas_meter: &mut impl DependencyGasMeter, + _traversal_context: &mut TraversalContext, + idx: &StructNameIndex, + ) -> PartialVMResult> { + self.struct_definitions + .borrow() + .get(idx) + .cloned() + .ok_or_else(|| PartialVMError::new(StatusCode::LINKER_ERROR)) + } +} diff --git a/third_party/move/move-vm/runtime/src/storage/loader/traits.rs b/third_party/move/move-vm/runtime/src/storage/loader/traits.rs new file mode 100644 index 00000000000..2f9a0572846 --- /dev/null +++ b/third_party/move/move-vm/runtime/src/storage/loader/traits.rs @@ -0,0 +1,28 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::{module_traversal::TraversalContext, WithRuntimeEnvironment}; +use move_binary_format::errors::PartialVMResult; +use move_vm_types::{ + gas::DependencyGasMeter, + loaded_data::{runtime_types::StructType, struct_name_indexing::StructNameIndex}, +}; +use std::sync::Arc; + +/// Provides access to struct definitions. +pub trait StructDefinitionLoader: WithRuntimeEnvironment { + /// Returns the struct definition corresponding to the specified index. The function may also + /// charge gas for loading the module where the struct is defined. Returns an error if such + /// metering fails, or if the struct / module where it is defined do not exist. + fn load_struct_definition( + &self, + gas_meter: &mut impl DependencyGasMeter, + traversal_context: &mut TraversalContext, + idx: &StructNameIndex, + ) -> PartialVMResult>; +} + +/// Encapsulates all possible module accesses in a safe, gas-metered way. This trait (and more +/// fine-grained) traits should be used when working with modules, functions, structs, and other +/// module information. +pub trait Loader: StructDefinitionLoader {} diff --git a/third_party/move/move-vm/runtime/src/storage/mod.rs b/third_party/move/move-vm/runtime/src/storage/mod.rs index 441c4d5283c..e9d326665be 100644 --- a/third_party/move/move-vm/runtime/src/storage/mod.rs +++ b/third_party/move/move-vm/runtime/src/storage/mod.rs @@ -1,7 +1,8 @@ // Copyright (c) The Move Contributors // SPDX-License-Identifier: Apache-2.0 -pub(crate) mod depth_formula_calculator; +pub(crate) mod loader; +pub(crate) mod ty_depth_checker; pub(crate) mod ty_tag_converter; mod verified_module_cache; diff --git a/third_party/move/move-vm/runtime/src/storage/module_storage.rs b/third_party/move/move-vm/runtime/src/storage/module_storage.rs index f3c4af9e11f..9bd2c5eadf2 100644 --- a/third_party/move/move-vm/runtime/src/storage/module_storage.rs +++ b/third_party/move/move-vm/runtime/src/storage/module_storage.rs @@ -59,7 +59,10 @@ pub trait ModuleStorage: WithRuntimeEnvironment { /// Returns the size of a module in bytes, or [None] otherwise. An error is returned if the /// there is a storage error. - fn fetch_module_size_in_bytes( + /// + /// Note: this API is not metered! It is only used to get the size of a module so that metering + /// can actually be implemented before loading a module. + fn unmetered_get_module_size( &self, address: &AccountAddress, module_name: &IdentStr, @@ -274,7 +277,7 @@ where .map(|(module, _)| module.extension().bytes().clone())) } - fn fetch_module_size_in_bytes( + fn unmetered_get_module_size( &self, address: &AccountAddress, module_name: &IdentStr, diff --git a/third_party/move/move-vm/runtime/src/storage/ty_depth_checker.rs b/third_party/move/move-vm/runtime/src/storage/ty_depth_checker.rs new file mode 100644 index 00000000000..1ad3c989922 --- /dev/null +++ b/third_party/move/move-vm/runtime/src/storage/ty_depth_checker.rs @@ -0,0 +1,730 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::{module_traversal::TraversalContext, storage::loader::traits::StructDefinitionLoader}; +use move_binary_format::{ + errors::{PartialVMError, PartialVMResult}, + file_format::TypeParameterIndex, +}; +use move_core_types::vm_status::StatusCode; +use move_vm_metrics::{Timer, VM_TIMER}; +use move_vm_types::{ + gas::DependencyGasMeter, + loaded_data::{ + runtime_types::{DepthFormula, StructIdentifier, StructLayout, Type}, + struct_name_indexing::StructNameIndex, + }, +}; +use std::{ + cell::RefCell, + collections::{BTreeMap, HashMap, HashSet}, + sync::Arc, +}; + +/// Checks depths for instantiated types. +/// +/// For structs, stores a cache of formulas. The cache is used for performance (avoid repeated +/// formula construction within a single transaction). +/// +/// While a formula is being constructed, also checks for cycles between struct definitions. That +/// is, cases like +/// ```text +/// struct A { b: B, } +/// struct B { a: A, } +/// ``` +/// are not allowed and constructing a formula for these types will fail. +pub(crate) struct TypeDepthChecker<'a, T> { + struct_definition_loader: &'a T, + /// If set, stores the maximum depth of a type allowed. Otherwise, checker is a no-op. + maybe_max_depth: Option, + /// Caches formulas visited so far. + formula_cache: RefCell>, +} + +impl<'a, T> TypeDepthChecker<'a, T> +where + T: StructDefinitionLoader, +{ + /// Creates a new depth checker for the specified loader to query struct definitions if needed. + pub(crate) fn new(struct_definition_loader: &'a T) -> Self { + let maybe_max_depth = struct_definition_loader + .runtime_environment() + .vm_config() + .max_value_nest_depth; + Self { + struct_definition_loader, + maybe_max_depth, + formula_cache: RefCell::new(HashMap::new()), + } + } + + /// Checks the depth of a type. If the type is too deep, returns an error. Note that the type + /// must be non-generic, i.e., all type substitutions must be performed. If needed, the check + /// traverses multiple modules where inner structs and their fields are defined. + pub(crate) fn check_depth_of_type( + &self, + gas_meter: &mut impl DependencyGasMeter, + traversal_context: &mut TraversalContext, + ty: &Type, + ) -> PartialVMResult<()> { + let max_depth = match self.maybe_max_depth { + Some(max_depth) => max_depth, + None => return Ok(()), + }; + + let _timer = VM_TIMER.timer_with_label("check_depth_of_type"); + + // Start at 1 since we always call this right before we add a new node to the value's depth. + self.recursive_check_depth_of_type(gas_meter, traversal_context, ty, max_depth, 1)?; + Ok(()) + } +} + +// Private interfaces below. +impl<'a, T> TypeDepthChecker<'a, T> +where + T: StructDefinitionLoader, +{ + /// Recursive implementation of type depth checks. For structs, computes and caches the depth + /// formula which is solved to get the actual depth and check it against the maximum allowed + /// value. + fn recursive_check_depth_of_type( + &self, + gas_meter: &mut impl DependencyGasMeter, + traversal_context: &mut TraversalContext, + ty: &Type, + max_depth: u64, + depth: u64, + ) -> PartialVMResult { + macro_rules! visit_struct { + ($idx:expr) => {{ + // Keeps track of formulas visited during construction (to detect cycles). Should + // always be empty before and after the formula is constructed end-to-end. + let mut currently_visiting = HashSet::new(); + let formula = self.calculate_struct_depth_formula( + gas_meter, + traversal_context, + &mut currently_visiting, + $idx, + )?; + if !currently_visiting.is_empty() { + let struct_name = self.get_struct_name($idx)?; + return Err(PartialVMError::new_invariant_violation(format!( + "Constructing a formula for {}::{}::{} has non-empty visiting set", + struct_name.module.address, struct_name.module.name, struct_name.name + ))); + } + formula + }}; + } + + macro_rules! check_depth { + ($additional_depth:expr) => {{ + let new_depth = depth.saturating_add($additional_depth); + if new_depth > max_depth { + return Err(PartialVMError::new(StatusCode::VM_MAX_VALUE_DEPTH_REACHED)); + } else { + new_depth + } + }}; + } + + let ty_depth = match ty { + Type::Bool + | Type::U8 + | Type::U16 + | Type::U32 + | Type::U64 + | Type::U128 + | Type::U256 + | Type::Address + | Type::Signer => check_depth!(0), + Type::Reference(ty) | Type::MutableReference(ty) => self + .recursive_check_depth_of_type( + gas_meter, + traversal_context, + ty, + max_depth, + check_depth!(1), + )?, + Type::Vector(ty) => self.recursive_check_depth_of_type( + gas_meter, + traversal_context, + ty, + max_depth, + check_depth!(1), + )?, + Type::Struct { idx, .. } => { + let formula = visit_struct!(idx); + check_depth!(formula.solve(&[])) + }, + Type::StructInstantiation { idx, ty_args, .. } => { + let ty_arg_depths = ty_args + .iter() + .map(|ty| { + self.recursive_check_depth_of_type( + gas_meter, + traversal_context, + ty, + max_depth, + check_depth!(0), + ) + }) + .collect::>>()?; + + let formula = visit_struct!(idx); + check_depth!(formula.solve(&ty_arg_depths)) + }, + Type::Function { args, results, .. } => { + let mut ty_max_depth = depth; + for ty in args.iter().chain(results) { + ty_max_depth = ty_max_depth.max(self.recursive_check_depth_of_type( + gas_meter, + traversal_context, + ty, + max_depth, + check_depth!(1), + )?); + } + ty_max_depth + }, + Type::TyParam(_) => { + return Err( + PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR) + .with_message("Type parameter should be fully resolved".to_string()), + ) + }, + }; + + Ok(ty_depth) + } + + /// Calculates the depth formula for a (possibly generic) struct or enum. Returns an error if + /// the struct definition is recursive: i.e., some struct A uses struct B that uses struct A. + fn calculate_struct_depth_formula( + &self, + gas_meter: &mut impl DependencyGasMeter, + traversal_context: &mut TraversalContext, + currently_visiting: &mut HashSet, + idx: &StructNameIndex, + ) -> PartialVMResult { + // If the struct is being visited, we found a recursive definition. + if currently_visiting.contains(idx) { + let struct_name = self.get_struct_name(idx)?; + let msg = format!( + "Definition of struct {}::{}::{} is recursive: failed to construct its depth formula", + struct_name.module.address, struct_name.module.name, struct_name.name + ); + return Err( + PartialVMError::new(StatusCode::RUNTIME_CYCLIC_MODULE_DEPENDENCY).with_message(msg), + ); + } + + // Otherwise, check if we cached it. + if let Some(formula) = self.formula_cache.borrow().get(idx) { + return Ok(formula.clone()); + } + + // Struct has not been visited, mark as being visited. + assert!(currently_visiting.insert(*idx)); + + // Recursively visit its fields to construct the formula. + let struct_definition = self.struct_definition_loader.load_struct_definition( + gas_meter, + traversal_context, + idx, + )?; + + let formulas = match &struct_definition.layout { + StructLayout::Single(fields) => fields + .iter() + .map(|(_, field_ty)| { + self.calculate_type_depth_formula( + gas_meter, + traversal_context, + currently_visiting, + field_ty, + ) + }) + .collect::>>()?, + StructLayout::Variants(variants) => variants + .iter() + .flat_map(|variant| variant.1.iter().map(|(_, ty)| ty)) + .map(|field_ty| { + self.calculate_type_depth_formula( + gas_meter, + traversal_context, + currently_visiting, + field_ty, + ) + }) + .collect::>>()?, + }; + let formula = DepthFormula::normalize(formulas); + + // Add the formula to cace list and remove it from the currently visited set. + assert!(currently_visiting.remove(idx)); + let prev = self + .formula_cache + .borrow_mut() + .insert(*idx, formula.clone()); + if prev.is_some() { + // Clear cache if there is an invariant violation, to be safe. + self.formula_cache.borrow_mut().clear(); + let struct_name = self.get_struct_name(idx)?; + let msg = format!( + "Depth formula for struct {}::{}::{} is already cached", + struct_name.module.address, struct_name.module.name, struct_name.name + ); + return Err(PartialVMError::new_invariant_violation(msg)); + } + + Ok(formula) + } + + /// Calculates the depth formula of the specified [Type]. There are no constraints on the type, + /// it can also be a generic type parameter. + fn calculate_type_depth_formula( + &self, + gas_meter: &mut impl DependencyGasMeter, + traversal_context: &mut TraversalContext, + currently_visiting: &mut HashSet, + ty: &Type, + ) -> PartialVMResult { + Ok(match ty { + Type::Bool + | Type::U8 + | Type::U64 + | Type::U128 + | Type::Address + | Type::Signer + | Type::U16 + | Type::U32 + | Type::U256 => DepthFormula::constant(1), + Type::Vector(ty) => self + .calculate_type_depth_formula(gas_meter, traversal_context, currently_visiting, ty)? + .scale(1), + Type::Reference(ty) | Type::MutableReference(ty) => self + .calculate_type_depth_formula(gas_meter, traversal_context, currently_visiting, ty)? + .scale(1), + Type::TyParam(ty_idx) => DepthFormula::type_parameter(*ty_idx), + Type::Struct { idx, .. } => { + let struct_formula = self.calculate_struct_depth_formula( + gas_meter, + traversal_context, + currently_visiting, + idx, + )?; + debug_assert!(struct_formula.terms.is_empty()); + struct_formula.scale(1) + }, + Type::StructInstantiation { idx, ty_args, .. } => { + let ty_arg_map = ty_args + .iter() + .enumerate() + .map(|(idx, ty)| { + let var = idx as TypeParameterIndex; + Ok(( + var, + self.calculate_type_depth_formula( + gas_meter, + traversal_context, + currently_visiting, + ty, + )?, + )) + }) + .collect::>>()?; + let struct_formula = self.calculate_struct_depth_formula( + gas_meter, + traversal_context, + currently_visiting, + idx, + )?; + struct_formula.subst(ty_arg_map)?.scale(1) + }, + Type::Function { + args, + results, + abilities: _, + } => { + let inner_formulas = args + .iter() + .chain(results) + .map(|ty| { + self.calculate_type_depth_formula( + gas_meter, + traversal_context, + currently_visiting, + ty, + ) + }) + .collect::>>()?; + DepthFormula::normalize(inner_formulas).scale(1) + }, + }) + } + + /// Returns the struct name for the specified index. + fn get_struct_name(&self, idx: &StructNameIndex) -> PartialVMResult> { + self.struct_definition_loader + .runtime_environment() + .struct_name_index_map() + .idx_to_struct_name_ref(*idx) + } +} + +// Test-only interfaces below. +#[cfg(test)] +impl<'a, T> TypeDepthChecker<'a, T> +where + T: StructDefinitionLoader, +{ + /// Creates a new depth checker for the specified loader and with specified maximum depth. + fn new_with_max_depth(struct_definition_loader: &'a T, max_depth: u64) -> Self { + Self { + struct_definition_loader, + maybe_max_depth: Some(max_depth), + formula_cache: RefCell::new(HashMap::new()), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + module_traversal::TraversalStorage, + storage::loader::test_utils::{generic_struct_ty, struct_ty, MockStructDefinitionLoader}, + }; + use claims::{assert_err, assert_ok}; + use move_vm_types::gas::UnmeteredGasMeter; + + #[test] + fn test_struct_definition_not_found_cache_consistency() { + let mut gas_meter = UnmeteredGasMeter; + let traversal_storage = TraversalStorage::new(); + let mut traversal_context = TraversalContext::new(&traversal_storage); + + let loader = MockStructDefinitionLoader::default(); + + // Create structs A and B with definition of C missing: + // + // struct A {} + // struct B { c: C, } + let a = loader.get_struct_identifier("A"); + let b = loader.get_struct_identifier("B"); + let c = loader.get_struct_identifier("C"); + loader.add_struct("A", vec![]); + loader.add_struct("B", vec![("c", struct_ty(c))]); + + let checker = TypeDepthChecker::new(&loader); + let mut currently_visiting = HashSet::new(); + + assert_ok!(checker.calculate_struct_depth_formula( + &mut gas_meter, + &mut traversal_context, + &mut currently_visiting, + &a + )); + assert!(currently_visiting.is_empty()); + assert_eq!(checker.formula_cache.borrow().len(), 1); + + let err = assert_err!(checker.calculate_struct_depth_formula( + &mut gas_meter, + &mut traversal_context, + &mut currently_visiting, + &b + )); + assert_eq!(err.major_status(), StatusCode::LINKER_ERROR); + assert_eq!(checker.formula_cache.borrow().len(), 1); + } + + #[test] + fn test_runtime_cyclic_module_dependency() { + let mut gas_meter = UnmeteredGasMeter; + let traversal_storage = TraversalStorage::new(); + let mut traversal_context = TraversalContext::new(&traversal_storage); + + let loader = MockStructDefinitionLoader::default(); + + // No cycles (structs and enums): + // + // struct A {} + // enum B { + // V1 { x: bool, }, + // V2 { a: A, }, + // } + let a = loader.get_struct_identifier("A"); + let b = loader.get_struct_identifier("B"); + loader.add_struct("A", vec![]); + loader.add_enum("B", vec![ + ("V1", vec![("x", Type::Bool)]), + ("V2", vec![("a", struct_ty(a))]), + ]); + + // Cycles between structs C and D, and between E and itself: + // + // struct C { d: D, } + // struct D { c: C, } + // struct E { e: E, } + let c = loader.get_struct_identifier("C"); + let d = loader.get_struct_identifier("D"); + let e = loader.get_struct_identifier("E"); + loader.add_struct("C", vec![("d", struct_ty(d))]); + loader.add_struct("D", vec![("c", struct_ty(c))]); + loader.add_struct("E", vec![("e", struct_ty(e))]); + + // Cycles between enums F and G. + // + // enum F { + // V0 { g: G, }, + // } + // enum G { + // V0 { fs: vector, }, + // } + let f = loader.get_struct_identifier("F"); + let g = loader.get_struct_identifier("G"); + loader.add_enum("F", vec![("V0", vec![("g", struct_ty(g))])]); + loader.add_enum("G", vec![("V0", vec![( + "fs", + Type::Vector(triomphe::Arc::new(struct_ty(f))), + )])]); + + let checker = TypeDepthChecker::new(&loader); + let mut currently_visiting = HashSet::new(); + + for idx in [a, b] { + assert_ok!(checker.calculate_struct_depth_formula( + &mut gas_meter, + &mut traversal_context, + &mut currently_visiting, + &idx + )); + assert!(currently_visiting.is_empty()); + } + + assert_eq!(checker.formula_cache.borrow().len(), 2); + + for idx in [c, d, e, f, g] { + let err = assert_err!(checker.calculate_struct_depth_formula( + &mut gas_meter, + &mut traversal_context, + &mut currently_visiting, + &idx + )); + assert_eq!( + err.major_status(), + StatusCode::RUNTIME_CYCLIC_MODULE_DEPENDENCY + ); + } + assert_eq!(checker.formula_cache.borrow().len(), 2); + } + + #[test] + fn test_runtime_cyclic_module_dependency_generic() { + let mut gas_meter = UnmeteredGasMeter; + let traversal_storage = TraversalStorage::new(); + let mut traversal_context = TraversalContext::new(&traversal_storage); + + let loader = MockStructDefinitionLoader::default(); + + // Simple struct to store in the checker cache to check cache consistency. + let a = loader.get_struct_identifier("A"); + loader.add_struct("A", vec![]); + + // Cycle between generic struct B and C: + // + // struct B { c: C } + // struct C { x: T, b: B } + let b = loader.get_struct_identifier("B"); + let c = loader.get_struct_identifier("C"); + loader.add_struct("B", vec![( + "c", + generic_struct_ty(c, vec![Type::TyParam(0)]), + )]); + loader.add_struct("C", vec![ + ("x", Type::TyParam(0)), + ("b", generic_struct_ty(b, vec![Type::TyParam(0)])), + ]); + + // Cycle between generic enum and generic struct: + // + // struct D { x: T, e: E, } + // enum E { + // V0 { ds: vector>, }, + // } + let d = loader.get_struct_identifier("D"); + let e = loader.get_struct_identifier("E"); + loader.add_struct("D", vec![ + ("x", Type::TyParam(0)), + ("e", generic_struct_ty(e, vec![Type::U8])), + ]); + loader.add_enum("E", vec![("V0", vec![( + "ds", + Type::Vector(triomphe::Arc::new(struct_ty(d))), + )])]); + + let checker = TypeDepthChecker::new(&loader); + let mut currently_visiting = HashSet::new(); + + assert_ok!(checker.calculate_struct_depth_formula( + &mut gas_meter, + &mut traversal_context, + &mut currently_visiting, + &a + )); + + assert!(currently_visiting.is_empty()); + assert_eq!(checker.formula_cache.borrow().len(), 1); + + for idx in [b, c, d, e] { + let err = assert_err!(checker.calculate_struct_depth_formula( + &mut gas_meter, + &mut traversal_context, + &mut currently_visiting, + &idx, + )); + assert_eq!( + err.major_status(), + StatusCode::RUNTIME_CYCLIC_MODULE_DEPENDENCY + ); + assert_eq!(checker.formula_cache.borrow().len(), 1); + } + } + + #[test] + fn test_runtime_non_cyclic_module_dependencies_generic() { + let mut gas_meter = UnmeteredGasMeter; + let traversal_storage = TraversalStorage::new(); + let mut traversal_context = TraversalContext::new(&traversal_storage); + + let loader = MockStructDefinitionLoader::default(); + + // These structs use definitions recursively but in type arguments, which is safe. + // + // struct A { x: T, } + // struct B { xs: A>>, } + // struct C { x: T, } + // struct D { xs: A>>, } + + let a = loader.get_struct_identifier("A"); + let b = loader.get_struct_identifier("B"); + let c = loader.get_struct_identifier("C"); + let d = loader.get_struct_identifier("D"); + + let a_u8_ty = generic_struct_ty(a, vec![Type::U8]); + let a_a_u8_ty = generic_struct_ty(a, vec![a_u8_ty.clone()]); + let a_a_a_u8_ty = generic_struct_ty(a, vec![a_a_u8_ty]); + let c_a_u8_ty = generic_struct_ty(c, vec![a_u8_ty]); + let a_c_a_u8_ty = generic_struct_ty(a, vec![c_a_u8_ty]); + + loader.add_struct("A", vec![("x", Type::TyParam(0))]); + loader.add_struct("B", vec![("xs", a_a_a_u8_ty)]); + loader.add_struct("C", vec![("x", Type::TyParam(0))]); + loader.add_struct("D", vec![("xs", a_c_a_u8_ty)]); + + let checker = TypeDepthChecker::new(&loader); + let mut currently_visiting = HashSet::new(); + + for idx in [a, b, c, d] { + assert_ok!(checker.calculate_struct_depth_formula( + &mut gas_meter, + &mut traversal_context, + &mut currently_visiting, + &idx, + )); + assert!(currently_visiting.is_empty()); + } + + assert_eq!(checker.formula_cache.borrow().len(), 4); + } + + #[test] + fn test_runtime_non_cyclic_module_dependencies() { + let mut gas_meter = UnmeteredGasMeter; + let traversal_storage = TraversalStorage::new(); + let mut traversal_context = TraversalContext::new(&traversal_storage); + + let loader = MockStructDefinitionLoader::default(); + + let a = loader.get_struct_identifier("A"); + let b = loader.get_struct_identifier("B"); + let c = loader.get_struct_identifier("C"); + + // These structs are not recursive. + // + // struct C {} + // struct B { c: C, } + // struct A { c: C, b: B, } + + loader.add_struct("C", vec![]); + loader.add_struct("B", vec![("c", struct_ty(c))]); + loader.add_struct("A", vec![("c", struct_ty(c)), ("b", struct_ty(b))]); + + for idx in [a, b, c] { + let checker = TypeDepthChecker::new(&loader); + let mut currently_visiting = HashSet::new(); + + assert_ok!(checker.calculate_struct_depth_formula( + &mut gas_meter, + &mut traversal_context, + &mut currently_visiting, + &idx, + )); + } + } + + #[test] + fn test_ty_to_deep() { + let mut gas_meter = UnmeteredGasMeter; + let traversal_storage = TraversalStorage::new(); + let mut traversal_context = TraversalContext::new(&traversal_storage); + + let loader = MockStructDefinitionLoader::default(); + + let a = loader.get_struct_identifier("A"); + let b = loader.get_struct_identifier("B"); + let c = loader.get_struct_identifier("C"); + + loader.add_struct("C", vec![("dummy", Type::Bool)]); + loader.add_struct("B", vec![("c", struct_ty(c))]); + loader.add_struct("A", vec![("b", struct_ty(b))]); + + let checker = TypeDepthChecker::new_with_max_depth(&loader, 2); + + assert_ok!(checker.check_depth_of_type(&mut gas_meter, &mut traversal_context, &Type::U8)); + + let vec_u8_ty = Type::Vector(triomphe::Arc::new(Type::U8)); + assert_ok!(checker.check_depth_of_type(&mut gas_meter, &mut traversal_context, &vec_u8_ty)); + + let vec_vec_u8_ty = Type::Vector(triomphe::Arc::new(vec_u8_ty.clone())); + assert_err!(checker.check_depth_of_type( + &mut gas_meter, + &mut traversal_context, + &vec_vec_u8_ty + )); + let ref_vec_u8_ty = Type::Reference(Box::new(vec_u8_ty)); + assert_err!(checker.check_depth_of_type( + &mut gas_meter, + &mut traversal_context, + &ref_vec_u8_ty + )); + + assert_ok!(checker.check_depth_of_type( + &mut gas_meter, + &mut traversal_context, + &struct_ty(c) + )); + assert_err!(checker.check_depth_of_type( + &mut gas_meter, + &mut traversal_context, + &struct_ty(b) + )); + assert_err!(checker.check_depth_of_type( + &mut gas_meter, + &mut traversal_context, + &struct_ty(a) + )); + } +} diff --git a/third_party/move/move-vm/types/src/loaded_data/runtime_types.rs b/third_party/move/move-vm/types/src/loaded_data/runtime_types.rs index 9707308a4b1..a46eabd5ec8 100644 --- a/third_party/move/move-vm/types/src/loaded_data/runtime_types.rs +++ b/third_party/move/move-vm/types/src/loaded_data/runtime_types.rs @@ -32,7 +32,6 @@ use std::{ }; use triomphe::Arc as TriompheArc; -#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Debug)] /// A formula describing the value depth of a type, using (the depths of) the type parameters as inputs. /// /// It has the form of `max(CBase, T1 + C1, T2 + C2, ..)` where `Ti` is the depth of the ith type parameter @@ -40,6 +39,7 @@ use triomphe::Arc as TriompheArc; /// /// This form has a special property: when you compute the max of multiple formulae, you can normalize /// them into a single formula. +#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Debug)] pub struct DepthFormula { pub terms: Vec<(TypeParameterIndex, u64)>, // Ti + Ci pub constant: Option, // Cbase @@ -93,14 +93,13 @@ impl DepthFormula { formulas.push(DepthFormula::constant(*constant)) } for (t_i, c_i) in terms { - let Some(mut u_form) = map.remove(t_i) else { + let Some(u_form) = map.remove(t_i) else { return Err( PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR) .with_message(format!("{t_i:?} missing mapping")), ); }; - u_form.scale(*c_i); - formulas.push(u_form) + formulas.push(u_form.scale(*c_i)) } Ok(DepthFormula::normalize(formulas)) } @@ -114,14 +113,15 @@ impl DepthFormula { depth } - pub fn scale(&mut self, c: u64) { - let Self { terms, constant } = self; + pub fn scale(mut self, c: u64) -> Self { + let Self { terms, constant } = &mut self; for (_t_i, c_i) in terms { *c_i = (*c_i).saturating_add(c); } if let Some(cbase) = constant.as_mut() { *cbase = (*cbase).saturating_add(c); } + self } } From 5c1979bcabcde945c1ce7f1f302bef0a0e8ae3b1 Mon Sep 17 00:00:00 2001 From: Jun Xu <5827713+junxzm1990@users.noreply.github.com> Date: Mon, 23 Jun 2025 16:39:34 -0600 Subject: [PATCH 009/260] add compiler tests and transactional tests for using function values as keys for storage (#16878) Downstreamed-from: e6d98a02af37f9d118e458582c74dec47d21424c --- .../fv_as_keys/compiler_ok_case.exp | 2 + .../fv_as_keys/compiler_ok_case.move | 25 ++ .../fv_as_keys/compiler_ok_case_enum.exp | 2 + .../fv_as_keys/compiler_ok_case_enum.move | 15 ++ .../fv_as_keys/missing_store.exp | 7 + .../fv_as_keys/missing_store.move | 21 ++ .../fv_as_keys/missing_store_enum.exp | 7 + .../fv_as_keys/missing_store_enum.move | 15 ++ .../ability-check/fv_as_keys/store_fv.exp | 9 + .../ability-check/fv_as_keys/store_fv.move | 21 ++ .../ability-check/fv_as_keys/store_lambda.exp | 10 + .../fv_as_keys/store_lambda.move | 16 ++ .../fv_as_keys/store_lambda_enum.exp | 10 + .../fv_as_keys/store_lambda_enum.move | 12 + .../no-v1-comparison/fv_as_keys.baseline.exp | 78 ++++++ .../tests/no-v1-comparison/fv_as_keys.exp | 78 ++++++ .../tests/no-v1-comparison/fv_as_keys.move | 251 ++++++++++++++++++ .../fv_as_keys.no-optimize.exp | 78 ++++++ .../no-v1-comparison/fv_as_keys.optimize.exp | 78 ++++++ .../transactional-tests/tests/tests.rs | 2 + 20 files changed, 737 insertions(+) create mode 100644 third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case.exp create mode 100644 third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case.move create mode 100644 third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case_enum.exp create mode 100644 third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case_enum.move create mode 100644 third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store.exp create mode 100644 third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store.move create mode 100644 third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store_enum.exp create mode 100644 third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store_enum.move create mode 100644 third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_fv.exp create mode 100644 third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_fv.move create mode 100644 third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda.exp create mode 100644 third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda.move create mode 100644 third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda_enum.exp create mode 100644 third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda_enum.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.baseline.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.no-optimize.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.optimize.exp diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case.exp b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case.exp new file mode 100644 index 00000000000..90b32906711 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case.exp @@ -0,0 +1,2 @@ + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case.move b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case.move new file mode 100644 index 00000000000..d8ff0f8328e --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case.move @@ -0,0 +1,25 @@ +module 0x99::basic_struct { + struct Wrapper has key { + fv: T + } + + #[persistent] + fun test(f: &||u64): u64 { + if (f == f) + 1 + else + 2 + } + + // all abilities satisfied + fun add_resource_with_struct(acc: &signer, f: | &||u64 |u64 has copy+store+drop) { + move_to>(acc, Wrapper { fv: f}); + } + + public fun test_driver(acc: &signer){ + // ok case + // note: while this case passes the compiler, it will not pass the VM because we cannot store functions with reference args + let f: | &||u64 |u64 has copy+store+drop = test; + add_resource_with_struct(acc, f); + } +} diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case_enum.exp b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case_enum.exp new file mode 100644 index 00000000000..90b32906711 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case_enum.exp @@ -0,0 +1,2 @@ + +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case_enum.move b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case_enum.move new file mode 100644 index 00000000000..4509789116a --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case_enum.move @@ -0,0 +1,15 @@ +module 0x99::basic_enum { + #[persistent] + fun increment_by_one(x: &mut u64): u64 { *x = *x + 1; *x } + + enum FV has key { + V1 { v1: |&mut T|T has copy+store}, + } + + fun test_fun_vec(s: &signer) { + // ok case + let f1: |&mut u64|u64 has copy+store = increment_by_one; + let v1 = FV::V1{v1: f1}; + move_to(s, v1); + } +} diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store.exp b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store.exp new file mode 100644 index 00000000000..6877d4385cf --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store.exp @@ -0,0 +1,7 @@ + +Diagnostics: +error: type `|&||u64|u64 has copy + drop` is missing required ability `store` + ┌─ tests/ability-check/fv_as_keys/missing_store.move:19:35 + │ +19 │ add_resource_with_struct(acc, f); + │ ^ diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store.move b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store.move new file mode 100644 index 00000000000..affa0fc0a35 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store.move @@ -0,0 +1,21 @@ +module 0x99::basic_struct { + struct Wrapper has key { + fv: T + } + + #[persistent] + fun test(f: &||u64): u64 { + 1 + } + + // all abilities satisfied + fun add_resource_with_struct(acc: &signer, f: | &||u64 |u64 has copy+store+drop) { + move_to>(acc, Wrapper { fv: f}); + } + + public fun test_driver(acc: &signer){ + // not ok case: cannot store functions without `store` + let f: | &||u64 |u64 has copy+drop = test; + add_resource_with_struct(acc, f); + } +} diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store_enum.exp b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store_enum.exp new file mode 100644 index 00000000000..7e6ffea6dc3 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store_enum.exp @@ -0,0 +1,7 @@ + +Diagnostics: +error: type `|&mut u64|u64 has copy` is missing required ability `store` + ┌─ tests/ability-check/fv_as_keys/missing_store_enum.move:12:29 + │ +12 │ let v1 = FV::V1{v1: f1}; + │ ^^ diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store_enum.move b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store_enum.move new file mode 100644 index 00000000000..dfee4998879 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/missing_store_enum.move @@ -0,0 +1,15 @@ +module 0x99::basic_enum { + #[persistent] + fun increment_by_one(x: &mut u64): u64 { *x = *x + 1; *x } + + enum FV has key { + V1 { v1: |&mut T|T has copy+store}, + } + + fun test_fun_vec(s: &signer) { + // not ok case: cannot store functions without `store` + let f1: |&mut u64|u64 has copy = increment_by_one; + let v1 = FV::V1{v1: f1}; + move_to(s, v1); + } +} diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_fv.exp b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_fv.exp new file mode 100644 index 00000000000..d425fc109f8 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_fv.exp @@ -0,0 +1,9 @@ + +Diagnostics: +error: Expected a struct type. Global storage operations are restricted to struct types declared in the current module. Found: '|&||u64|u64 has drop + store + key' + ┌─ tests/ability-check/fv_as_keys/store_fv.move:13:5 + │ +13 │ move_to<| &||u64 |u64 has store+drop+key>(acc, f); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ + │ Invalid call to MoveTo<|&||u64|u64 has drop + store + key>. diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_fv.move b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_fv.move new file mode 100644 index 00000000000..994c93d8420 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_fv.move @@ -0,0 +1,21 @@ +module 0x99::basic_struct { + struct Wrapper has key { + fv: T + } + + #[persistent] + fun test(f: &||u64): u64 { + 1 + } + + // not ok: storage mandates struct type + fun add_resource_with_fv(acc: &signer, f: | &||u64 |u64 has store+drop+key) { + move_to<| &||u64 |u64 has store+drop+key>(acc, f); + } + + public fun test_driver(acc: &signer){ + // not ok case: cannot put function values in storage directly + let f: | &||u64 |u64 has store+drop+key = test; + add_resource_with_fv(acc, f); + } +} diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda.exp b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda.exp new file mode 100644 index 00000000000..b3241dfc2bc --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda.exp @@ -0,0 +1,10 @@ + +Diagnostics: +error: function resulting from lambda lifting is missing the `store` ability + ┌─ tests/ability-check/fv_as_keys/store_lambda.move:13:48 + │ +13 │ let f: | &||u64 |u64 has copy+store+drop = |x| (*x)(); + │ ^^^^^^^^^^ + │ + = lambda cannot be reduced to partial application of existing function + = expected function type: `|&||u64|u64 has copy + drop + store` diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda.move b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda.move new file mode 100644 index 00000000000..801f58c6515 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda.move @@ -0,0 +1,16 @@ +module 0x99::basic_struct { + struct Wrapper has key { + fv: T + } + + // all abilities satisfied + fun add_resource_with_struct(acc: &signer, f: | &||u64 |u64 has copy+store+drop) { + move_to>(acc, Wrapper { fv: f}); + } + + public fun test_driver(acc: &signer){ + // not ok case: lambda functions have no `store` + let f: | &||u64 |u64 has copy+store+drop = |x| (*x)(); + add_resource_with_struct(acc, f); + } +} diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda_enum.exp b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda_enum.exp new file mode 100644 index 00000000000..011ebe00360 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda_enum.exp @@ -0,0 +1,10 @@ + +Diagnostics: +error: function resulting from lambda lifting is missing the `store` ability + ┌─ tests/ability-check/fv_as_keys/store_lambda_enum.move:8:48 + │ +8 │ let f1: |&mut u64|u64 has copy+store = |x| *x+1; + │ ^^^^^^^^ + │ + = lambda cannot be reduced to partial application of existing function + = expected function type: `|&mut u64|u64 has copy + store` diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda_enum.move b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda_enum.move new file mode 100644 index 00000000000..26483bf05dd --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_lambda_enum.move @@ -0,0 +1,12 @@ +module 0x99::basic_enum { + enum FV has key { + V1 { v1: |&mut T|T has copy+store}, + } + + fun test_fun_vec(s: &signer) { + // not ok case: cannot put function values in storage directly + let f1: |&mut u64|u64 has copy+store = |x| *x+1; + let v1 = FV::V1{v1: f1}; + move_to(s, v1); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.baseline.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.baseline.exp new file mode 100644 index 00000000000..73d90c2d1d0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.baseline.exp @@ -0,0 +1,78 @@ +processed 23 tasks + +task 6 'run'. lines 102-102: +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(4), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 8 'run'. lines 107-107: +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 10 'run'. lines 112-115: +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(6), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 13 'run'. lines 230-230: +Error: Function execution failed with VMError: { + message: Failed to move resource into 0000000000000000000000000000000000000000000000000000000000000001, + major_status: RESOURCE_ALREADY_EXISTS, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 5)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 18 'run'. lines 241-241: +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 20 'run'. lines 246-246: +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(6), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 22 'run'. lines 251-251: +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(9), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.exp new file mode 100644 index 00000000000..73d90c2d1d0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.exp @@ -0,0 +1,78 @@ +processed 23 tasks + +task 6 'run'. lines 102-102: +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(4), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 8 'run'. lines 107-107: +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 10 'run'. lines 112-115: +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(6), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 13 'run'. lines 230-230: +Error: Function execution failed with VMError: { + message: Failed to move resource into 0000000000000000000000000000000000000000000000000000000000000001, + major_status: RESOURCE_ALREADY_EXISTS, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 5)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 18 'run'. lines 241-241: +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 20 'run'. lines 246-246: +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(6), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 22 'run'. lines 251-251: +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(9), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.move new file mode 100644 index 00000000000..e35e75f6e57 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.move @@ -0,0 +1,251 @@ +/// Test cases for function values wrapped in structs as keys +//# publish +module 0x99::test_struct { + use std::signer; + + struct Wrapper has key, drop { + fv: |T|u64 has copy+store+drop + } + + #[persistent] + fun test(f: ||u64 has store+drop): u64 { + if (f() == 1) + 1 + else + 2 + } + + #[persistent] + fun test1(): u64 { + 1 + } + + #[persistent] + fun test2(): u64 { + 2 + } + + // store a function value of type `|T|u64` with `T = ||u64 has store+drop` + public fun init(acc: &signer){ + let f: | ||u64 has store+drop |u64 has copy+store+drop = |x| test(x); + move_to(acc, Wrapper { fv: f}); + } + + // check existence of a function value of type `|T|u64` with `T = ||u64 has store+drop` + // should return true + public fun test_exist(acc: &signer){ + let exist_res = exists>(signer::address_of(acc)); + assert!(exist_res); + } + + // check existence of a function value of type `|T|u64` with `T = u64` + // should return false due to incompatible T type + public fun test_not_exist_1(acc: &signer){ + let exist_res = exists>(signer::address_of(acc)); + assert!(!exist_res); + } + + // check existence of a function value of type `|T|u64` with `T = ||u64 has store` + // should return false due to T missing `drop` + public fun test_not_exist_2(acc: &signer){ + let exist_res = exists>(signer::address_of(acc)); + assert!(!exist_res); + } + + // check existence of a function value of type `|T|u64` with `T = ||u64 has store` + // should return false due to T additionally having `copy` + public fun test_not_exist_3(acc: &signer){ + let exist_res = exists>(signer::address_of(acc)); + assert!(!exist_res); + } + + // borrow function value of type `|T|u64` with `T = ||u64 has store+copy+drop` + // should fail due to T additionally having `copy` + public fun test_bad_borrow_from(acc: &signer){ + let f = borrow_global>(signer::address_of(acc)); + assert!((f.fv)(test1) == 1); + assert!((f.fv)(test2) == 2); + } + + // borrow function value of type `|T|u64` with `T = ||u64 has store+drop` + // should succeed + public fun test_borrow_from(acc: &signer){ + let f = borrow_global>(signer::address_of(acc)); + assert!((f.fv)(test1) == 1); + assert!((f.fv)(test2) == 2); + } + + // move function value of type `|T|u64` with `T = ||u64 has store+copy+drop` + // should fail due to T additionally having `copy` + public fun test_bad_move_from(acc: &signer){ + move_from>(signer::address_of(acc)); + } + + // move function value of type `|T|u64` with `T = ||u64 has store+drop` + // should succeed + public fun test_move_from(acc: &signer){ + move_from>(signer::address_of(acc)); + } +} + +//# run --verbose --signers 0x1 -- 0x99::test_struct::init + +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_exist + +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_1 + +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_2 + +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_not_exist_3 + +//expect to fail +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_bad_borrow_from + +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_borrow_from + +//expect to fail +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_bad_move_from + +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_move_from + +// expected to fail as the functon value has been removed above +//# run --verbose --signers 0x1 -- 0x99::test_struct::test_borrow_from + + +/// Test cases for function values wrapped in enums as keys +//# publish +module 0x99::test_enum { + use std::signer; + + enum Wrapper has key { + V1 {fv1: |T|u64 has copy + store}, + V2 {fv1: |T|u64 has copy + drop + store} + } + + + #[persistent] + fun test(f: ||u64 has store+drop): u64 { + if (f() == 1) + 1 + else + 2 + } + + #[persistent] + fun test1(): u64 { + 1 + } + + #[persistent] + fun test2(): u64 { + 2 + } + + // store a function value of type `|T|u64` with `T = ||u64 has store+drop` + public fun init(acc: &signer){ + let f1: | ||u64 has store+drop |u64 has copy+store = |x| test(x); + let v1 = Wrapper::V1{ fv1: f1 }; + move_to(acc, v1); + } + + // failed store because resource type already exists + public fun bad_init(acc: &signer){ + let f1: | ||u64 has store+drop |u64 has copy+drop+store = |x| test(x); + let v2 = Wrapper::V2{ fv1: f1 }; + move_to(acc, v2); + } + + // check existence of a function value of type `|T|u64` with `T = ||u64 has store+drop` + // should return true + public fun test_exist(acc: &signer){ + let exist_res = exists>(signer::address_of(acc)); + assert!(exist_res); + } + + // check existence of a function value of type `|T|u64` with `T = u64` + // should return true due to incompatible T type + public fun test_not_exist_1(acc: &signer){ + let exist_res = exists>(signer::address_of(acc)); + assert!(!exist_res); + } + + // check existence of a function value of type `|T|u64` with `T = ||u64 has store` + // should return true due to T missing `drop` + public fun test_not_exist_2(acc: &signer){ + let exist_res = exists>(signer::address_of(acc)); + assert!(!exist_res); + } + + // check existence of a function value of type `|T|u64` with `T = ||u64 has store` + // should return true due to T additionally having `copy` + public fun test_not_exist_3(acc: &signer){ + let exist_res = exists>(signer::address_of(acc)); + assert!(!exist_res); + } + + // borrow function value of type `|T|u64` with `T = ||u64 has store+copy+drop` + // should fail due to T additionally having `copy` + public fun test_bad_borrow_from(acc: &signer){ + borrow_global>(signer::address_of(acc)); + } + + // borrow function value of type `|T|u64` with `T = ||u64 has store+drop` + // should succeed + public fun test_borrow_from(acc: &signer){ + let f = borrow_global>(signer::address_of(acc)); + let res = match (f) { + V1{fv1} => (*fv1)(test1), + V2{fv1} => (*fv1)(test2) + }; + assert!(res == 1, 0); + } + + // move function value of type `|T|u64` with `T = ||u64 has store+copy+drop` + // should fail due to T additionally having `copy` + public fun test_bad_move_from(acc: &signer){ + let f = move_from>(signer::address_of(acc)); + let res = match (f) { + V1{fv1} => fv1(test1), + V2{fv1} => fv1(test2) + }; + assert!(res == 1, 0); + } + + // move function value of type `|T|u64` with `T = ||u64 has store+drop` + // should succeed + public fun test_move_from(acc: &signer){ + let f = move_from>(signer::address_of(acc)); + let res = match (f) { + V1{fv1} => fv1(test1), + V2{fv1} => fv1(test2) + }; + assert!(res == 1, 0); + } + +} + +//# run --verbose --signers 0x1 -- 0x99::test_enum::init + +//expect to fail +//# run --verbose --signers 0x1 -- 0x99::test_enum::bad_init + +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_exist + +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_1 + +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_2 + +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_not_exist_3 + +//expect to fail +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_bad_borrow_from + +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_borrow_from + +//expect to fail +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_bad_move_from + +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_move_from + +// expected to fail as the functon value has been removed above +//# run --verbose --signers 0x1 -- 0x99::test_enum::test_move_from diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.no-optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.no-optimize.exp new file mode 100644 index 00000000000..0e9098739ab --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.no-optimize.exp @@ -0,0 +1,78 @@ +processed 23 tasks + +task 6 'run'. lines 102-102: +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(4), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 8 'run'. lines 107-107: +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 10 'run'. lines 112-115: +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(6), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 13 'run'. lines 230-230: +Error: Function execution failed with VMError: { + message: Failed to move resource into 0000000000000000000000000000000000000000000000000000000000000001, + major_status: RESOURCE_ALREADY_EXISTS, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 7)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 18 'run'. lines 241-241: +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 20 'run'. lines 246-246: +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(6), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 22 'run'. lines 251-251: +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(9), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.optimize.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.optimize.exp new file mode 100644 index 00000000000..73d90c2d1d0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/fv_as_keys.optimize.exp @@ -0,0 +1,78 @@ +processed 23 tasks + +task 6 'run'. lines 102-102: +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(4), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 8 'run'. lines 107-107: +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 10 'run'. lines 112-115: +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_struct, + indices: [], + offsets: [(FunctionDefinitionIndex(6), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 13 'run'. lines 230-230: +Error: Function execution failed with VMError: { + message: Failed to move resource into 0000000000000000000000000000000000000000000000000000000000000001, + major_status: RESOURCE_ALREADY_EXISTS, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 5)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 18 'run'. lines 241-241: +Error: Function execution failed with VMError: { + message: Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(5), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 20 'run'. lines 246-246: +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(6), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} + +task 22 'run'. lines 251-251: +Error: Function execution failed with VMError: { + message: Failed to move resource from 0000000000000000000000000000000000000000000000000000000000000001, + major_status: MISSING_DATA, + sub_status: None, + location: 0x99::test_enum, + indices: [], + offsets: [(FunctionDefinitionIndex(9), 2)], + exec_state: Some(ExecutionState { stack_trace: [] }), +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs b/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs index 7916c1501db..fa0db422342 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs @@ -121,6 +121,8 @@ const SEPARATE_BASELINE: &[&str] = &[ "optimization/bug_14223_unused_non_droppable.move", // Flaky redundant unused assignment error "no-v1-comparison/enum/enum_scoping.move", + // Different error messages depending on optimizations or not + "no-v1-comparison/fv_as_keys.move", ]; fn get_config_by_name(name: &str) -> TestConfig { From 8d0a1be61fda046c8aa068a2a23f755faffabbfb Mon Sep 17 00:00:00 2001 From: Jun Xu <5827713+junxzm1990@users.noreply.github.com> Date: Tue, 24 Jun 2025 09:50:08 -0600 Subject: [PATCH 010/260] remove redundant comment in test case (#16929) Downstreamed-from: f1b55f5c682a57d80befb838fe1fc6946272129f --- .../tests/ability-check/fv_as_keys/compiler_ok_case.move | 1 - 1 file changed, 1 deletion(-) diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case.move b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case.move index d8ff0f8328e..f2821c6d729 100644 --- a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case.move +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/compiler_ok_case.move @@ -18,7 +18,6 @@ module 0x99::basic_struct { public fun test_driver(acc: &signer){ // ok case - // note: while this case passes the compiler, it will not pass the VM because we cannot store functions with reference args let f: | &||u64 |u64 has copy+store+drop = test; add_resource_with_struct(acc, f); } From 7d019c1d7037ba82f0b84e1a244761cd442dbd35 Mon Sep 17 00:00:00 2001 From: Teng Zhang Date: Tue, 24 Jun 2025 23:08:58 +0000 Subject: [PATCH 011/260] add native cmp (#16882) Downstreamed-from: 8255c8dd75f915034979fe32c3232e8a34b71eaa --- .../doc/transaction_validation.md | 2 +- .../sources/transaction_validation.spec.move | 2 +- aptos-move/framework/move-stdlib/doc/cmp.md | 185 ++++++++++- .../framework/move-stdlib/sources/cmp.move | 165 +++++++++- aptos-move/framework/src/aptos-natives.bpl | 180 ++++++++++- .../framework/tests/move_prover_tests.rs | 24 +- third_party/move/move-model/src/model.rs | 7 + third_party/move/move-model/src/ty.rs | 83 +++++ .../boogie-backend/src/bytecode_translator.rs | 289 +++++++++++++++++- .../move-prover/boogie-backend/src/lib.rs | 64 +++- .../boogie-backend/src/prelude/prelude.bpl | 2 + .../boogie-backend/src/spec_translator.rs | 11 +- 12 files changed, 968 insertions(+), 46 deletions(-) diff --git a/aptos-move/framework/aptos-framework/doc/transaction_validation.md b/aptos-move/framework/aptos-framework/doc/transaction_validation.md index 0c19498ab37..d49cef037cd 100644 --- a/aptos-move/framework/aptos-framework/doc/transaction_validation.md +++ b/aptos-move/framework/aptos-framework/doc/transaction_validation.md @@ -2043,7 +2043,7 @@ not equal the number of singers.
pragma aborts_if_is_partial;
 pragma verify_duration_estimate = 120;
 aborts_if !features::spec_is_enabled(features::FEE_PAYER_ENABLED);
-let gas_payer = create_signer::create_signer(fee_payer_address);
+let gas_payer = create_signer::spec_create_signer(fee_payer_address);
 include PrologueCommonAbortsIf {
     gas_payer,
     replay_protector: ReplayProtector::SequenceNumber(txn_sequence_number),
diff --git a/aptos-move/framework/aptos-framework/sources/transaction_validation.spec.move b/aptos-move/framework/aptos-framework/sources/transaction_validation.spec.move
index 23bedb16406..70fe400d7f8 100644
--- a/aptos-move/framework/aptos-framework/sources/transaction_validation.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/transaction_validation.spec.move
@@ -257,7 +257,7 @@ spec aptos_framework::transaction_validation {
         pragma verify_duration_estimate = 120;
 
         aborts_if !features::spec_is_enabled(features::FEE_PAYER_ENABLED);
-        let gas_payer = create_signer::create_signer(fee_payer_address);
+        let gas_payer = create_signer::spec_create_signer(fee_payer_address);
         include PrologueCommonAbortsIf {
             gas_payer,
             replay_protector: ReplayProtector::SequenceNumber(txn_sequence_number),
diff --git a/aptos-move/framework/move-stdlib/doc/cmp.md b/aptos-move/framework/move-stdlib/doc/cmp.md
index f6f43999bfe..e903b88ec00 100644
--- a/aptos-move/framework/move-stdlib/doc/cmp.md
+++ b/aptos-move/framework/move-stdlib/doc/cmp.md
@@ -14,7 +14,14 @@
 -  [Function `is_gt`](#0x1_cmp_is_gt)
 -  [Function `is_ge`](#0x1_cmp_is_ge)
 -  [Specification](#@Specification_0)
+    -  [Enum `Ordering`](#@Specification_0_Ordering)
     -  [Function `compare`](#@Specification_0_compare)
+    -  [Function `is_eq`](#@Specification_0_is_eq)
+    -  [Function `is_ne`](#@Specification_0_is_ne)
+    -  [Function `is_lt`](#@Specification_0_is_lt)
+    -  [Function `is_le`](#@Specification_0_is_le)
+    -  [Function `is_gt`](#@Specification_0_is_gt)
+    -  [Function `is_ge`](#@Specification_0_is_ge)
 
 
 
@@ -263,6 +270,74 @@ and if equal we proceed to the next. ## Specification + + +### Enum `Ordering` + + +
enum Ordering has copy, drop
+
+ + + +
+ +
+Less + + +
+Fields + + +
+
+ + +
+ +
+ +
+Equal + + +
+Fields + + +
+
+ + +
+ +
+ +
+Greater + + +
+Fields + + +
+
+ + +
+ +
+
+ + + +
pragma intrinsic;
+
+ + + ### Function `compare` @@ -274,7 +349,115 @@ and if equal we proceed to the next. -
pragma opaque;
+
pragma intrinsic;
+
+ + + + + +### Function `is_eq` + + +
public fun is_eq(self: &cmp::Ordering): bool
+
+ + + + +
pragma intrinsic;
+pragma opaque;
+pragma verify = false;
+
+ + + + + +### Function `is_ne` + + +
public fun is_ne(self: &cmp::Ordering): bool
+
+ + + + +
pragma intrinsic;
+pragma opaque;
+pragma verify = false;
+
+ + + + + +### Function `is_lt` + + +
public fun is_lt(self: &cmp::Ordering): bool
+
+ + + + +
pragma intrinsic;
+pragma opaque;
+pragma verify = false;
+
+ + + + + +### Function `is_le` + + +
public fun is_le(self: &cmp::Ordering): bool
+
+ + + + +
pragma intrinsic;
+pragma opaque;
+pragma verify = false;
+
+ + + + + +### Function `is_gt` + + +
public fun is_gt(self: &cmp::Ordering): bool
+
+ + + + +
pragma intrinsic;
+pragma opaque;
+pragma verify = false;
+
+ + + + + +### Function `is_ge` + + +
public fun is_ge(self: &cmp::Ordering): bool
+
+ + + + +
pragma intrinsic;
+pragma opaque;
+pragma verify = false;
 
diff --git a/aptos-move/framework/move-stdlib/sources/cmp.move b/aptos-move/framework/move-stdlib/sources/cmp.move index af90ff7b275..6356622367f 100644 --- a/aptos-move/framework/move-stdlib/sources/cmp.move +++ b/aptos-move/framework/move-stdlib/sources/cmp.move @@ -41,8 +41,47 @@ module std::cmp { } spec compare { - // TODO: temporary mockup. + pragma intrinsic; + } + + spec Ordering { + pragma intrinsic; + } + + spec is_eq { + pragma intrinsic; + pragma opaque; + pragma verify = false; + } + + spec is_ne { + pragma intrinsic; pragma opaque; + pragma verify = false; + } + + spec is_lt { + pragma intrinsic; + pragma opaque; + pragma verify = false; + } + + spec is_le { + pragma intrinsic; + pragma opaque; + pragma verify = false; + } + + spec is_gt { + pragma intrinsic; + pragma opaque; + pragma verify = false; + } + + spec is_ge { + pragma intrinsic; + pragma opaque; + pragma verify = false; } #[test_only] @@ -147,4 +186,128 @@ module std::cmp { assert!(compare(&SomeEnum::V5 { field_5: SimpleEnum::V { field: 5}}, &SomeEnum::V5 { field_5: SimpleEnum::V { field: 3}}) is Ordering::Greater, 13); assert!(compare(&SomeEnum::V5 { field_5: SimpleEnum::V { field: 3}}, &SomeEnum::V5 { field_5: SimpleEnum::V { field: 5}}) is Ordering::Less, 14); } + + #[verify_only] + fun test_verify_compare_preliminary_types() { + spec { + assert compare(1, 5).is_ne(); + assert !compare(1, 5).is_eq(); + assert compare(1, 5).is_lt(); + assert compare(1, 5).is_le(); + assert compare(5, 5).is_eq(); + assert !compare(5, 5).is_ne(); + assert !compare(5, 5).is_lt(); + assert compare(5, 5).is_le(); + assert !compare(7, 5).is_eq(); + assert compare(7, 5).is_ne(); + assert !compare(7, 5).is_lt(); + assert !compare(7, 5).is_le(); + assert compare(false, true).is_ne(); + assert compare(false, true).is_lt(); + assert compare(true, false).is_ge(); + assert compare(true, true).is_eq(); + }; + } + + #[verify_only] + fun test_verify_compare_vectors() { + let empty: vector = vector[]; + let v1 = vector[1 as u64]; + let v8 = vector[1 as u8, 2]; + let v32_1 = vector[1 as u32, 2, 3]; + let v32_2 = vector[5 as u32]; + spec { + assert compare(empty, v1) == Ordering::Less; + assert compare(empty, empty) == Ordering::Equal; + assert compare(v1, empty) == Ordering::Greater; + assert compare(v8, v8) == Ordering::Equal; + assert compare(v32_1, v32_2) is Ordering::Less; + assert compare(v32_2, v32_1) == Ordering::Greater; + }; + } + + #[verify_only] + struct SomeStruct has drop { + field_1: u64, + field_2: u64, + } + + #[verify_only] + fun test_verify_compare_structs() { + let s1 = SomeStruct { field_1: 1, field_2: 2}; + let s2 = SomeStruct { field_1: 1, field_2: 3}; + let s3 = SomeStruct { field_1: 1, field_2: 1}; + let s4 = SomeStruct { field_1: 2, field_2: 1}; + spec { + assert compare(s1, s1) == Ordering::Equal; + assert compare(s1, s2) == Ordering::Less; + assert compare(s1, s3) == Ordering::Greater; + assert compare(s4, s1) == Ordering::Greater; + }; + } + + #[verify_only] + fun test_verify_compare_vector_of_structs() { + let v1 = vector[SomeStruct { field_1: 1, field_2: 2}]; + let v2 = vector[SomeStruct { field_1: 1, field_2: 3}]; + spec { + assert compare(v1, v2) == Ordering::Less; + assert compare(v1, v1) == Ordering::Equal; + }; + } + + #[verify_only] + enum SomeEnum has drop { + V1 { field_1: u64 }, + V2 { field_2: u64 }, + V3 { field_3: SomeStruct }, + V4 { field_4: vector }, + V5 { field_5: SimpleEnum }, + } + + #[verify_only] + enum SimpleEnum has drop { + V { field: u64 }, + } + + #[verify_only] + fun test_verify_compare_enums() { + let e1 = SomeEnum::V1 { field_1: 6}; + let e2 = SomeEnum::V2 { field_2: 1}; + let e3 = SomeEnum::V3 { field_3: SomeStruct { field_1: 1, field_2: 2}}; + let e4 = SomeEnum::V4 { field_4: vector[1, 2]}; + let e5 = SomeEnum::V5 { field_5: SimpleEnum::V { field: 3}}; + spec { + assert compare(e1, e1) == Ordering::Equal; + assert compare(e1, e2) == Ordering::Less; + assert compare(e2, e1) == Ordering::Greater; + assert compare(e3, e4) == Ordering::Less; + assert compare(e5, e4) == Ordering::Greater; + }; + } + + #[verify_only] + struct SomeStruct_BV has copy,drop { + field: u64 + } + + spec SomeStruct_BV { + pragma bv=b"0"; + } + + #[verify_only] + fun test_compare_bv() { + let a = 1; + let b = 5; + let se_a = SomeStruct_BV { field: a}; + let se_b = SomeStruct_BV { field: b}; + let v_a = vector[a]; + let v_b = vector[b]; + spec { + assert compare(a, b) == Ordering::Less; + assert compare(se_a, se_b) == Ordering::Less; + assert compare(v_a, v_b) == Ordering::Less; + }; + } + } diff --git a/aptos-move/framework/src/aptos-natives.bpl b/aptos-move/framework/src/aptos-natives.bpl index e2c34cf5f21..0e433ccb33d 100644 --- a/aptos-move/framework/src/aptos-natives.bpl +++ b/aptos-move/framework/src/aptos-natives.bpl @@ -17,9 +17,167 @@ procedure {:inline 1} $1_object_exists_at{{S}}(object: int) returns (res: bool) {%- endfor %} +datatype $1_cmp_Ordering { + $1_cmp_Ordering_Less(), + $1_cmp_Ordering_Equal(), + $1_cmp_Ordering_Greater() +} +function $IsValid'$1_cmp_Ordering_Less'(s: $1_cmp_Ordering): bool { + true +} +function $IsValid'$1_cmp_Ordering_Equal'(s: $1_cmp_Ordering): bool { + true +} +function $IsValid'$1_cmp_Ordering_Greater'(s: $1_cmp_Ordering): bool { + true +} +function $IsValid'$1_cmp_Ordering'(s: $1_cmp_Ordering): bool { + true +} +function {:inline} $IsEqual'$1_cmp_Ordering'(s1: $1_cmp_Ordering, s2: $1_cmp_Ordering): bool { + s1 == s2 +} + +function $Arbitrary_value_of'$1_cmp_Ordering'(): $1_cmp_Ordering; + +function {:inline} $1_cmp_$compare'bool'(s1: bool, s2: bool): $1_cmp_Ordering { + if s1 == s2 then $1_cmp_Ordering_Equal() + else if s1 == true then $1_cmp_Ordering_Greater() + else + $1_cmp_Ordering_Less() +} + +procedure {:inline 1} $1_cmp_compare'bool'(s1: bool, s2: bool) returns ($ret0: $1_cmp_Ordering) { + $ret0 := $1_cmp_$compare'bool'(s1, s2); + return; +} + +function {:inline} $1_cmp_$compare'signer'(s1: $signer, s2: $signer): $1_cmp_Ordering { + if s1 == s2 then $1_cmp_Ordering_Equal() + else if s1 is $signer && s2 is $permissioned_signer then $1_cmp_Ordering_Less() + else if s1 is $permissioned_signer && s2 is $signer then $1_cmp_Ordering_Greater() + else if s1 is $signer then + $compare_int(s1 -> $addr, s2 -> $addr) + else if s1 -> $addr == s2 -> $addr then + $compare_int(s1 -> $permission_addr, s2 -> $permission_addr) + else + $compare_int(s1 -> $addr, s2 -> $addr) +} + +procedure {:inline 1} $1_cmp_compare'signer'(s1: $signer, s2: $signer) returns ($ret0: $1_cmp_Ordering) { + $ret0 := $1_cmp_$compare'signer'(s1, s2); + return; +} + +function $compare_int(s1: int, s2: int): $1_cmp_Ordering { + if s1 == s2 then $1_cmp_Ordering_Equal() + else if s1 > s2 then $1_cmp_Ordering_Greater() + else $1_cmp_Ordering_Less() +} + +function {:inline} $1_cmp_$compare'num'(s1: int, s2: int): $1_cmp_Ordering { + $compare_int(s1, s2) +} + +procedure {:inline 1} $1_cmp_compare'num'(s1: int, s2: int) returns ($ret0: $1_cmp_Ordering) { + $ret0 := $compare_int(s1, s2); + return; +} + +function {:inline} $1_cmp_$compare'int'(s1: int, s2: int): $1_cmp_Ordering { + $compare_int(s1, s2) +} + +procedure {:inline 1} $1_cmp_compare'int'(s1: int, s2: int) returns ($ret0: $1_cmp_Ordering) { + $ret0 := $compare_int(s1, s2); + return; +} + +{%- for impl in bv_instances %} + +function {:inline} $1_cmp_$compare'bv{{impl.base}}'(s1: bv{{impl.base}}, s2: bv{{impl.base}}): $1_cmp_Ordering { + if s1 == s2 then $1_cmp_Ordering_Equal() + else if $Gt'Bv{{impl.base}}'(s1,s2) then $1_cmp_Ordering_Greater() + else $1_cmp_Ordering_Less() +} + +procedure {:inline 1} $1_cmp_compare'bv{{impl.base}}'(s1: bv{{impl.base}}, s2: bv{{impl.base}}) returns ($ret0: $1_cmp_Ordering) { + $ret0 := $1_cmp_$compare'bv{{impl.base}}'(s1, s2); + return; +} + +{%- endfor %} + + +{%- for instance in cmp_int_instances -%} +{%- set S = instance.suffix -%} +{%- set T = instance.name -%} -{%- for instance in aggregator_v2_instances %} +function {:inline} $1_cmp_$compare'{{S}}'(s1: {{T}}, s2: {{T}}): $1_cmp_Ordering { + $compare_int(s1, s2) +} + + +procedure {:inline 1} $1_cmp_compare'{{S}}'(s1: {{T}}, s2: {{T}}) returns ($ret0: $1_cmp_Ordering) { + $ret0 := $compare_int(s1, s2); + return; +} + +{%- endfor %} + +{%- for instance in cmp_vector_instances -%} +{%- set S = instance.suffix -%} +{%- set T = instance.name -%} + + {% set concat_s = "/" ~ S ~"/" %} + {% set rest_s = concat_s | trim_start_matches(pat="/vec'") | trim_end_matches(pat="'/") %} + + + function {:inline} $1_cmp_$compare'{{S}}'(v1: {{T}}, v2: {{T}}): $1_cmp_Ordering { + if $IsEqual'{{S}}'(v1, v2) then $1_cmp_Ordering_Equal() + else if v1 -> l == 0 && v2 -> l != 0 then + $1_cmp_Ordering_Less() + else if v2 -> l == 0 && v1 -> l != 0 then + $1_cmp_Ordering_Greater() + else + $compare_vec'{{S}}'(v1, v2) + } + + procedure {:inline 1} $1_cmp_compare'{{S}}'(v1: {{T}}, v2: {{T}}) returns ($ret0: $1_cmp_Ordering) { + $ret0 := $1_cmp_$compare'{{S}}'(v1, v2); + return; + } + + function $compare_vec'{{S}}'(v1: {{T}}, v2: {{T}}): $1_cmp_Ordering; + axiom {:ctor "Vec"} (forall v1: {{T}}, v2: {{T}}, res: $1_cmp_Ordering :: + (var res := $compare_vec'{{S}}'(v1, v2); + if v1 -> l == 0 && v2 -> l != 0 then + res == $1_cmp_Ordering_Less() + else if v2 -> l == 0 && v1 -> l != 0 then + res == $1_cmp_Ordering_Greater() + else if ReadVec(v1, 0) == ReadVec(v2, 0) then res == $compare_vec'{{S}}'(RemoveAtVec(v1, 0), RemoveAtVec(v2, 0)) + else res == $1_cmp_$compare'{{rest_s}}'(ReadVec(v1, 0), ReadVec(v2, 0)))); + +{%- endfor %} + +{% for instance in cmp_table_instances -%} +{%- set S = instance.suffix -%} +{%- set T = instance.name -%} + + function {:inline} $1_cmp_$compare'{{S}}'(v1: {{T}}, v2: {{T}}): $1_cmp_Ordering { + $Arbitrary_value_of'$1_cmp_Ordering'() + } + + procedure {:inline 1} $1_cmp_compare'{{S}}'(v1: {{T}}, v2: {{T}}) returns ($ret0: $1_cmp_Ordering) { + $ret0 := $1_cmp_$compare'{{S}}'(v1, v2); + return; + } + +{%- endfor %} + + +{% for instance in aggregator_v2_instances %} {%- set S = instance.suffix -%} {%- set T = instance.name -%} @@ -234,6 +392,15 @@ function {:inline} $1_aggregator_v2_$read'{{S}}'(s: $1_aggregator_v2_Aggregator' function $1_aggregator_v2_$is_at_least_impl'{{S}}'(aggregator: $1_aggregator_v2_Aggregator'{{S}}', min_amount: {{T}}): bool; {% endif -%} +function {:inline} $1_cmp_$compare'$1_aggregator_v2_Aggregator'{{S}}''(s1: $1_aggregator_v2_Aggregator'{{S}}', s2: $1_aggregator_v2_Aggregator'{{S}}'): $1_cmp_Ordering { + $Arbitrary_value_of'$1_cmp_Ordering'() +} + +procedure {:inline 1} $1_cmp_compare'$1_aggregator_v2_Aggregator'{{S}}''(s1: $1_aggregator_v2_Aggregator'{{S}}', s2: $1_aggregator_v2_Aggregator'{{S}}') returns ($ret0: $1_cmp_Ordering) { + $ret0 := $1_cmp_$compare'$1_aggregator_v2_Aggregator'{{S}}''(s1, s2); + return; +} + {%- endfor %} // ================================================================================== @@ -305,6 +472,17 @@ axiom (forall limit: int :: {$1_aggregator_factory_spec_new_aggregator(limit)} (var agg := $1_aggregator_factory_spec_new_aggregator(limit); $1_aggregator_spec_aggregator_get_val(agg) == 0)); + +function {:inline} $1_cmp_$compare'$1_aggregator_Aggregator'(s1: $1_aggregator_Aggregator, s2: $1_aggregator_Aggregator): $1_cmp_Ordering { + $Arbitrary_value_of'$1_cmp_Ordering'() +} + +procedure {:inline 1} $1_cmp_compare'$1_aggregator_Aggregator'(s1: $1_aggregator_Aggregator, s2: $1_aggregator_Aggregator) returns ($ret0: $1_cmp_Ordering) { + $ret0 := $1_cmp_$compare'$1_aggregator_Aggregator'(s1, s2); + return; +} + + // ================================================================================== // Native for function_info diff --git a/aptos-move/framework/tests/move_prover_tests.rs b/aptos-move/framework/tests/move_prover_tests.rs index 99e54d3c612..f2e5dbbe037 100644 --- a/aptos-move/framework/tests/move_prover_tests.rs +++ b/aptos-move/framework/tests/move_prover_tests.rs @@ -78,28 +78,8 @@ pub fn run_prover_for_pkg( } #[test] -fn move_framework_prover_tests_shard1() { - run_prover_for_pkg("aptos-framework", 5, Some(1)); -} - -#[test] -fn move_framework_prover_tests_shard2() { - run_prover_for_pkg("aptos-framework", 5, Some(2)); -} - -#[test] -fn move_framework_prover_tests_shard3() { - run_prover_for_pkg("aptos-framework", 5, Some(3)); -} - -#[test] -fn move_framework_prover_tests_shard4() { - run_prover_for_pkg("aptos-framework", 5, Some(4)); -} - -#[test] -fn move_framework_prover_tests_shard5() { - run_prover_for_pkg("aptos-framework", 5, Some(5)); +fn move_framework_prover_tests() { + run_prover_for_pkg("aptos-framework", 1, None); } #[test] diff --git a/third_party/move/move-model/src/model.rs b/third_party/move/move-model/src/model.rs index 7e7903c951e..094535283e4 100644 --- a/third_party/move/move-model/src/model.rs +++ b/third_party/move/move-model/src/model.rs @@ -607,6 +607,8 @@ pub struct GlobalEnv { /// Whether the v2 compiler has generated this model. /// TODO: replace with a proper version number once we have this in file format pub(crate) generated_by_v2: bool, + /// A set of types that are instantiated in cmp module. + pub cmp_types: RefCell>, } /// A helper type for implementing fmt::Display depending on GlobalEnv @@ -668,6 +670,7 @@ impl GlobalEnv { address_alias_map: Default::default(), everything_is_target: Default::default(), generated_by_v2: false, + cmp_types: RefCell::new(Default::default()), } } @@ -3606,6 +3609,10 @@ impl<'env> ModuleEnv<'env> { || self.is_module_in_ext("table") || self.is_module_in_ext("table_with_length") } + + pub fn is_cmp(&self) -> bool { + self.is_module_in_std("cmp") + } } // ================================================================================================= diff --git a/third_party/move/move-model/src/ty.rs b/third_party/move/move-model/src/ty.rs index eba11991548..c32c3ca06d5 100644 --- a/third_party/move/move-model/src/ty.rs +++ b/third_party/move/move-model/src/ty.rs @@ -1086,6 +1086,89 @@ impl Type { matches!(self, Type::Var(_)) } + /// Returns all internal types contained in this type (including itself), skipping reference types. + pub fn get_all_contained_types_with_skip_reference(&self, env: &GlobalEnv) -> Vec { + match self { + Type::Primitive(_) => vec![self.clone()], + Type::Tuple(ts) => ts + .iter() + .flat_map(|t| t.get_all_contained_types_with_skip_reference(env)) + .collect(), + Type::Vector(et) => { + let mut types = et.get_all_contained_types_with_skip_reference(env); + types.push(self.clone()); + types + }, + Type::Struct(_, _, ts) => { + let struct_env = self.get_struct(env).unwrap().0; + let mut new_types = ts + .iter() + .zip(struct_env.data.type_params.iter()) + .filter(|(_, param)| !param.1.is_phantom) + .flat_map(|(t, _)| t.get_all_contained_types_with_skip_reference(env)) + .collect_vec(); + new_types.push(self.clone()); + if struct_env.has_variants() { + for variant in struct_env.get_variants() { + for field in struct_env.get_fields_of_variant(variant) { + new_types.extend( + field + .get_type() + .instantiate(ts) + .get_all_contained_types_with_skip_reference(env), + ); + } + } + } else { + for field in struct_env.get_fields() { + new_types.extend( + field + .get_type() + .instantiate(ts) + .get_all_contained_types_with_skip_reference(env), + ); + } + } + new_types + }, + Type::Fun(arg, result, _) => { + let mut types = arg.get_all_contained_types_with_skip_reference(env); + types.extend(result.get_all_contained_types_with_skip_reference(env)); + types + }, + Type::Reference(_, bt) => { + let mut types = bt.get_all_contained_types_with_skip_reference(env); + types.push(self.clone()); + types + }, + Type::TypeDomain(bt) => { + let mut types = bt.get_all_contained_types_with_skip_reference(env); + types.push(self.clone()); + types + }, + Type::ResourceDomain(_, _, Some(bt)) => { + let mut types = bt + .iter() + .flat_map(|t| t.get_all_contained_types_with_skip_reference(env)) + .collect_vec(); + types.push(self.clone()); + types + }, + Type::ResourceDomain(_, _, None) => { + vec![self.clone()] + }, + Type::Var(..) => { + vec![self.clone()] + }, + Type::Error => { + vec![self.clone()] + }, + Type::TypeParameter(..) => { + vec![self.clone()] + }, + } + } + /// Returns true if this is any number type. pub fn is_number(&self) -> bool { if let Type::Primitive(p) = self { diff --git a/third_party/move/move-prover/boogie-backend/src/bytecode_translator.rs b/third_party/move/move-prover/boogie-backend/src/bytecode_translator.rs index 23d8f831b64..05c48f192ce 100644 --- a/third_party/move/move-prover/boogie-backend/src/bytecode_translator.rs +++ b/third_party/move/move-prover/boogie-backend/src/bytecode_translator.rs @@ -150,6 +150,51 @@ impl<'env> BoogieTranslator<'env> { } } + #[allow(clippy::literal_string_with_formatting_args)] + fn emit_function(&self, writer: &CodeWriter, signature: &str, body_fn: impl Fn()) { + self.emit_function_with_attr(writer, "{:inline} ", signature, body_fn) + } + + #[allow(clippy::literal_string_with_formatting_args)] + fn emit_procedure(&self, writer: &CodeWriter, signature: &str, body_fn: impl Fn()) { + self.emit_procedure_with_attr(writer, "{:inline 1} ", signature, body_fn) + } + + fn emit_with_attr( + &self, + writer: &CodeWriter, + sig: &str, + attr: &str, + signature: &str, + body_fn: impl Fn(), + ) { + emitln!(writer, "{} {}{} {{", sig, attr, signature); + writer.indent(); + body_fn(); + writer.unindent(); + emitln!(writer, "}"); + } + + fn emit_function_with_attr( + &self, + writer: &CodeWriter, + attr: &str, + signature: &str, + body_fn: impl Fn(), + ) { + self.emit_with_attr(writer, "function", attr, signature, body_fn) + } + + fn emit_procedure_with_attr( + &self, + writer: &CodeWriter, + attr: &str, + signature: &str, + body_fn: impl Fn(), + ) { + self.emit_with_attr(writer, "procedure", attr, signature, body_fn) + } + #[allow(clippy::literal_string_with_formatting_args)] pub fn translate(&mut self) { let writer = self.writer; @@ -257,6 +302,39 @@ impl<'env> BoogieTranslator<'env> { // declare the memory variable for this type emitln!(writer, "var {}_$memory: $Memory {};", suffix, param_type); + + // If cmp module is included, emit cmp functions for generic types + if env + .get_modules() + .any(|m| m.get_full_name_str() == "0x1::cmp") + { + self.emit_function( + writer, + &format!( + "$1_cmp_$compare'{}'(v1: {}, v2: {}): $1_cmp_Ordering", + suffix, param_type, param_type + ), + || { + emitln!( + writer, + "if $IsEqual'{}'(v1, v2) then $1_cmp_Ordering_Equal()", + suffix + ); + emitln!(writer, "else $Arbitrary_value_of'$1_cmp_Ordering'()"); + }, + ); + + self.emit_procedure( + writer, + &format!( + "$1_cmp_compare'{}'(v1: {}, v2: {}) returns ($ret0: $1_cmp_Ordering)", + suffix, param_type, param_type + ), + || { + emitln!(writer, "$ret0 := $1_cmp_$compare'{}'(v1, v2);", suffix); + }, + ); + } } emitln!(writer); @@ -511,7 +589,8 @@ impl StructTranslator<'_> { } // Emit $IsValid function for `variant`. - self.emit_function_with_attr( + self.parent.emit_function_with_attr( + writer, "", // not inlined! &format!("$IsValid'{}'(s: {}): bool", suffix_variant, struct_name), || { @@ -538,7 +617,8 @@ impl StructTranslator<'_> { // Emit $IsValid function for struct. fn emit_is_valid_struct(&self, struct_env: &StructEnv, struct_name: &str, emit_fn: impl Fn()) { let writer = self.parent.writer; - self.emit_function_with_attr( + self.parent.emit_function_with_attr( + writer, "", // not inlined! &format!("$IsValid'{}'(s: {}): bool", struct_name, struct_name), || { @@ -642,6 +722,121 @@ impl StructTranslator<'_> { emitln!(writer, "else false"); } + /// Emit the function cmp::compare for enum + fn emit_cmp_for_enum(&self, struct_env: &StructEnv, struct_name: &str) { + let writer = self.parent.writer; + let suffix: String = boogie_type_suffix_for_struct(struct_env, self.type_inst, false); + self.emit_function( + &format!( + "$1_cmp_$compare'{}'(v1: {}, v2: {}): $1_cmp_Ordering", + suffix, struct_name, struct_name + ), + || { + let mut else_symbol = ""; + for (pos_1, v1) in struct_env.get_variants().collect_vec().iter().enumerate() { + for (pos_2, v2) in struct_env.get_variants().collect_vec().iter().enumerate() { + if pos_2 <= pos_1 { + continue; + } + let struct_variant_name_1 = + boogie_struct_variant_name(struct_env, self.type_inst, *v1); + let struct_variant_name_2 = + boogie_struct_variant_name(struct_env, self.type_inst, *v2); + let cmp_order_less = format!( + "{} if v1 is {} && v2 is {} then $1_cmp_Ordering_Less()", + else_symbol, struct_variant_name_1, struct_variant_name_2 + ); + let cmp_order_greater = format!( + "else if v1 is {} && v2 is {} then $1_cmp_Ordering_Greater()", + struct_variant_name_2, struct_variant_name_1 + ); + if else_symbol.is_empty() { + else_symbol = "else"; + } + emitln!(writer, "{}", cmp_order_less); + emitln!(writer, "{}", cmp_order_greater); + } + } + for variant in struct_env.get_variants().collect_vec().iter() { + let struct_variant_name_1 = + boogie_struct_variant_name(struct_env, self.type_inst, *variant); + let suffix_variant = + boogie_type_suffix_for_struct_variant(struct_env, self.type_inst, variant); + let cmp_order = format!( + "{} if v1 is {} && v2 is {} then $1_cmp_$compare'{}'(v1, v2)", + else_symbol, struct_variant_name_1, struct_variant_name_1, suffix_variant + ); + emitln!(writer, "{}", cmp_order); + } + emitln!(writer, "else $Arbitrary_value_of'$1_cmp_Ordering'()"); + }, + ); + for variant in struct_env.get_variants().collect_vec().iter() { + self.emit_cmp_for_enum_variant(struct_env, *variant, struct_name); + } + } + + /// Emit the function cmp::compare for each enum variant + fn emit_cmp_for_enum_variant( + &self, + struct_env: &StructEnv, + variant: Symbol, + struct_name: &str, + ) { + let writer = self.parent.writer; + let suffix_variant = + boogie_type_suffix_for_struct_variant(struct_env, self.type_inst, &variant); + self.emit_function( + &format!( + "$1_cmp_$compare'{}'(v1: {}, v2: {}): $1_cmp_Ordering", + suffix_variant, struct_name, struct_name + ), + || { + if struct_env + .get_fields_of_variant(variant) + .collect_vec() + .is_empty() + { + emitln!(writer, "$1_cmp_Ordering_Equal()"); + } else { + for (pos, field) in struct_env.get_fields_of_variant(variant).enumerate() { + let bv_flag = self.field_bv_flag(&field); + let field_type_name = boogie_type_suffix_bv( + self.parent.env, + &self.inst(&field.get_type()), + bv_flag, + ); + let cmp_field_call = format!( + "$1_cmp_$compare'{}'(v1->{}, v2->{})", + field_type_name, + boogie_field_sel(&field), + boogie_field_sel(&field) + ); + let cmp_field_call_less = + format!("{} == $1_cmp_Ordering_Less()", cmp_field_call); + let cmp_field_call_greater = + format!("{} == $1_cmp_Ordering_Greater()", cmp_field_call); + emitln!(writer, "if {}", cmp_field_call_less); + emitln!(writer, "then $1_cmp_Ordering_Less()"); + emitln!(writer, "else if {}", cmp_field_call_greater); + emitln!(writer, "then $1_cmp_Ordering_Greater()"); + if pos + < struct_env + .get_fields_of_variant(variant) + .collect_vec() + .len() + - 1 + { + emitln!(writer, "else"); + } else { + emitln!(writer, "else $1_cmp_Ordering_Equal()"); + } + } + } + }, + ); + } + /// Return whether a field involves bitwise operations pub fn field_bv_flag(&self, field_env: &FieldEnv) -> bool { let global_state = &self @@ -805,21 +1000,90 @@ impl StructTranslator<'_> { emitln!(writer, "var {}: $Memory {};", memory_name, struct_name); } + // Emit compare function and procedure + let cmp_struct_types = self.parent.env.cmp_types.borrow(); + for cmp_struct_type in cmp_struct_types.iter() { + if let Some((cur_struct, inst)) = cmp_struct_type.get_struct(env) { + if cur_struct.get_id() == struct_env.get_id() && inst == self.type_inst { + if !struct_env.has_variants() { + let suffix = + boogie_type_suffix_for_struct(struct_env, self.type_inst, false); + self.emit_function( + &format!( + "$1_cmp_$compare'{}'(v1: {}, v2: {}): $1_cmp_Ordering", + suffix, struct_name, struct_name + ), + || { + for (pos, field) in struct_env.get_fields().enumerate() { + let bv_flag = self.field_bv_flag(&field); + let suffix_ty = boogie_type_suffix_bv( + self.parent.env, + &self.inst(&field.get_type()), + bv_flag, + ); + let cmp_field_call = format!( + "$1_cmp_$compare'{}'(v1->{}, v2->{})", + suffix_ty, + boogie_field_sel(&field), + boogie_field_sel(&field) + ); + let cmp_field_call_less = + format!("{} == $1_cmp_Ordering_Less()", cmp_field_call); + let cmp_field_call_greater = + format!("{} == $1_cmp_Ordering_Greater()", cmp_field_call); + emitln!(writer, "if {}", cmp_field_call_less); + emitln!(writer, "then $1_cmp_Ordering_Less()"); + emitln!(writer, "else if {}", cmp_field_call_greater); + emitln!(writer, "then $1_cmp_Ordering_Greater()"); + if pos < struct_env.get_field_count() - 1 { + emitln!(writer, "else"); + } else { + emitln!(writer, "else $1_cmp_Ordering_Equal()"); + } + } + }, + ); + self.emit_procedure( + &format!( + "$1_cmp_compare'{}'(v1: {}, v2: {}) returns ($ret0: $1_cmp_Ordering)", + suffix, struct_name, struct_name + ), + || { + emitln!(writer, "$ret0 := $1_cmp_$compare'{}'(v1, v2);", suffix); + }, + ); + } else { + self.emit_cmp_for_enum(struct_env, &struct_name); + let suffix: String = + boogie_type_suffix_for_struct(struct_env, self.type_inst, false); + self.emit_procedure( + &format!( + "$1_cmp_compare'{}'(v1: {}, v2: {}) returns ($ret0: $1_cmp_Ordering)", + suffix, struct_name, struct_name + ), + || { + emitln!(writer, "$ret0 := $1_cmp_$compare'{}'(v1, v2);", suffix); + }, + ); + } + break; + } + } + } + emitln!(writer); } #[allow(clippy::literal_string_with_formatting_args)] fn emit_function(&self, signature: &str, body_fn: impl Fn()) { - self.emit_function_with_attr("{:inline} ", signature, body_fn) + self.parent + .emit_function(self.parent.writer, signature, body_fn); } - fn emit_function_with_attr(&self, attr: &str, signature: &str, body_fn: impl Fn()) { - let writer = self.parent.writer; - emitln!(writer, "function {}{} {{", attr, signature); - writer.indent(); - body_fn(); - writer.unindent(); - emitln!(writer, "}"); + #[allow(clippy::literal_string_with_formatting_args)] + fn emit_procedure(&self, signature: &str, body_fn: impl Fn()) { + self.parent + .emit_procedure(self.parent.writer, signature, body_fn); } } @@ -1622,6 +1886,11 @@ impl FunctionTranslator<'_> { } else { let dest_bv_flag = !dests.is_empty() && compute_flag(dests[0]); let bv_flag = !srcs.is_empty() && compute_flag(srcs[0]); + if module_env.is_cmp() { + fun_name = boogie_function_bv_name(&callee_env, inst, &[ + bv_flag || dest_bv_flag, + ]); + } // Handle the case where the return value of length is assigned to a bv int because // length always returns a non-bv result if module_env.is_std_vector() { diff --git a/third_party/move/move-prover/boogie-backend/src/lib.rs b/third_party/move/move-prover/boogie-backend/src/lib.rs index 906bc6f7b6a..137a3ab5b16 100644 --- a/third_party/move/move-prover/boogie-backend/src/lib.rs +++ b/third_party/move/move-prover/boogie-backend/src/lib.rs @@ -55,6 +55,7 @@ const TABLE_ARRAY_THEORY: &[u8] = include_bytes!("prelude/table-array-theory.bpl // TODO use named addresses const BCS_MODULE: &str = "0x1::bcs"; const EVENT_MODULE: &str = "0x1::event"; +const CMP_MODULE: &str = "0x1::cmp"; mod boogie_helpers; pub mod boogie_wrapper; @@ -208,7 +209,6 @@ pub fn add_prelude( .into_iter() .collect_vec(); all_types.append(&mut bv_all_types); - context.insert("uninterpreted_instances", &all_types); // obtain bv number types appearing in the program, which is currently used to generate cast functions for bv types let number_types = mono_info @@ -321,6 +321,68 @@ pub fn add_prelude( let event_instances = filter_native_ensure_one_inst(EVENT_MODULE); context.insert("event_instances", &event_instances); + // handle cmp module + let filter_native_with_contained_types_with_bv_flag = |module: &str, bv_flag: bool| { + mono_info + .native_inst + .iter() + .filter(|(id, _)| env.get_module(**id).get_full_name_str() == module) + .flat_map(|(_, insts)| { + insts.iter().map(|inst| { + inst.iter() + .flat_map(|i| i.get_all_contained_types_with_skip_reference(env)) + .map(|i| (i.clone(), TypeInfo::new(env, options, &i, bv_flag))) + .collect::>() + }) + }) + .sorted() + .collect_vec() + }; + let filter_native_with_contained_types = |module: &str| { + let mut filtered = filter_native_with_contained_types_with_bv_flag(module, false); + let mut filtered_bv = filter_native_with_contained_types_with_bv_flag(module, true); + filtered.append(&mut filtered_bv); + filtered.into_iter().flatten().collect_vec() + }; + let mut cmp_instances = filter_native_with_contained_types(CMP_MODULE); + cmp_instances.sort(); + cmp_instances.dedup(); + let mut cmp_struct_types = vec![]; + let mut cmp_int_types = all_types + .clone() + .into_iter() + .filter(|ty| ty.name == "int") + .collect_vec(); + for (ty, ty_info) in &cmp_instances { + if ty.is_struct() { + cmp_struct_types.push(ty.clone()); + } + if ty.is_number() && !ty_info.suffix.contains("bv") && !cmp_int_types.contains(ty_info) { + cmp_int_types.push(ty_info.clone()); + } + } + cmp_int_types.sort(); + cmp_int_types.dedup(); + cmp_struct_types.sort(); + cmp_struct_types.dedup(); + context.insert("cmp_int_instances", &cmp_int_types); + env.cmp_types.borrow_mut().extend(cmp_struct_types); + + let filter_cmp_instances_with_name_prefix = |name_prefix: &str| { + cmp_instances + .clone() + .into_iter() + .filter(|ty| ty.1.name.starts_with(name_prefix)) + .map(|ty| ty.1) + .collect_vec() + }; + let cmp_vector_instances = filter_cmp_instances_with_name_prefix("Vec"); + context.insert("cmp_vector_instances", &cmp_vector_instances); + let cmp_table_instances = filter_cmp_instances_with_name_prefix("Table"); + context.insert("cmp_table_instances", &cmp_table_instances); + + context.insert("uninterpreted_instances", &all_types); + // TODO: we have defined {{std}} for adaptable resolution of stdlib addresses but // not used it yet in the templates. let std_addr = format!("${}", env.get_stdlib_address().expect_numerical()); diff --git a/third_party/move/move-prover/boogie-backend/src/prelude/prelude.bpl b/third_party/move/move-prover/boogie-backend/src/prelude/prelude.bpl index 7b279ac9887..cc0e0a031f2 100644 --- a/third_party/move/move-prover/boogie-backend/src/prelude/prelude.bpl +++ b/third_party/move/move-prover/boogie-backend/src/prelude/prelude.bpl @@ -32,7 +32,9 @@ options provided to the prover. {%- set S = "'" ~ instance.suffix ~ "'" -%} {%- set T = instance.name -%} +{%-if S != "'$1_cmp_Ordering'" %} function $Arbitrary_value_of{{S}}(): {{T}}; +{% endif %} {% endfor %} diff --git a/third_party/move/move-prover/boogie-backend/src/spec_translator.rs b/third_party/move/move-prover/boogie-backend/src/spec_translator.rs index 6ca78128163..b2002cf79a5 100644 --- a/third_party/move/move-prover/boogie-backend/src/spec_translator.rs +++ b/third_party/move/move-prover/boogie-backend/src/spec_translator.rs @@ -1251,8 +1251,9 @@ impl SpecTranslator<'_> { .env .get_extension::() .expect("global number operation state"); - let is_vector_table_module = module_env.is_std_vector() || module_env.is_table(); - let bv_flag = if is_vector_table_module && !args.is_empty() { + let is_vector_table_cmp_module = + module_env.is_std_vector() || module_env.is_table() || module_env.is_cmp(); + let bv_flag = if is_vector_table_cmp_module && !args.is_empty() { global_state.get_node_num_oper(args[0].node_id()) == Bitwise } else { global_state.get_node_num_oper(node_id) == Bitwise @@ -1441,12 +1442,6 @@ impl SpecTranslator<'_> { args: &[Exp], ) { let struct_env = self.env.get_module(module_id).into_struct(struct_id); - if struct_env.is_intrinsic() { - self.env.error( - &self.env.get_node_loc(node_id), - "cannot test variants of intrinsic struct", - ); - } let struct_type = &self.get_node_type(args[0].node_id()); let (_, _, _) = struct_type.skip_reference().require_struct(); let inst = self.env.get_node_instantiation(node_id); From cc507bf0c35230455416902361db1a52bf61eaee Mon Sep 17 00:00:00 2001 From: George Mitenkov Date: Wed, 25 Jun 2025 15:13:29 +0100 Subject: [PATCH 012/260] [vm] Fix function value tags (#16932) Downstreamed-from: b2bd65b8a556f2d7ff912a2adc7b40be3ea0c73c --- api/types/src/move_types.rs | 34 +++++- aptos-move/script-composer/src/helpers.rs | 52 ++++++--- .../fuzz_targets/move/type_tag_to_string.rs | 11 +- testsuite/generate-format/src/api.rs | 1 + testsuite/generate-format/src/aptos.rs | 1 + testsuite/generate-format/src/consensus.rs | 1 + testsuite/generate-format/src/move_abi.rs | 1 + .../generate-format/tests/staged/api.yaml | 27 ++++- .../generate-format/tests/staged/aptos.yaml | 27 ++++- .../tests/staged/consensus.yaml | 27 ++++- .../tests/staged/move_abi.yaml | 18 +++- .../closures/funs_as_storage_key.exp | 9 +- .../closures/funs_as_storage_key.move | 102 ++++++++++++++++++ .../move-core/types/src/language_storage.rs | 83 +++++++++++--- third_party/move/move-model/src/ty.rs | 20 +++- .../runtime/src/storage/ty_tag_converter.rs | 23 +++- .../types/src/loaded_data/runtime_types.rs | 20 +++- .../types/src/values/serialization_tests.rs | 18 ++-- .../move-resource-viewer/src/fat_type.rs | 31 +++++- 19 files changed, 437 insertions(+), 69 deletions(-) diff --git a/api/types/src/move_types.rs b/api/types/src/move_types.rs index 325d2b9a10a..21d65bde1e2 100644 --- a/api/types/src/move_types.rs +++ b/api/types/src/move_types.rs @@ -16,7 +16,7 @@ use move_core_types::{ ability::{Ability, AbilitySet}, account_address::AccountAddress, identifier::Identifier, - language_storage::{FunctionTag, ModuleId, StructTag, TypeTag}, + language_storage::{FunctionParamOrReturnTag, FunctionTag, ModuleId, StructTag, TypeTag}, parser::{parse_struct_tag, parse_type_tag}, transaction_argument::TransactionArgument, }; @@ -807,7 +807,21 @@ fn from_function_tag(f: &FunctionTag) -> MoveType { results, abilities, } = f; - let from_vec = |tys: &[TypeTag]| tys.iter().map(MoveType::from).collect::>(); + let from_vec = |ts: &[FunctionParamOrReturnTag]| { + ts.iter() + .map(|t| match t { + FunctionParamOrReturnTag::Reference(t) => MoveType::Reference { + mutable: false, + to: Box::new(MoveType::from(t)), + }, + FunctionParamOrReturnTag::MutableReference(t) => MoveType::Reference { + mutable: true, + to: Box::new(MoveType::from(t)), + }, + FunctionParamOrReturnTag::Value(t) => MoveType::from(t), + }) + .collect::>() + }; MoveType::Function { args: from_vec(args), results: from_vec(results), @@ -838,7 +852,19 @@ impl TryFrom<&MoveType> for TypeTag { } => { let try_vec = |tys: &[MoveType]| { tys.iter() - .map(Self::try_from) + .map(|t| { + Ok(match t { + MoveType::Reference { mutable, to } => { + let tag = to.as_ref().try_into()?; + if *mutable { + FunctionParamOrReturnTag::MutableReference(tag) + } else { + FunctionParamOrReturnTag::Reference(tag) + } + }, + t => FunctionParamOrReturnTag::Value(t.try_into()?), + }) + }) .collect::>() }; TypeTag::Function(Box::new(FunctionTag { @@ -848,7 +874,7 @@ impl TryFrom<&MoveType> for TypeTag { })) }, MoveType::GenericTypeParam { index: _ } => TypeTag::Address, // Dummy type, allows for Object - _ => { + MoveType::Reference { .. } | MoveType::Unparsable(_) => { return Err(anyhow::anyhow!( "Invalid move type for converting into `TypeTag`: {:?}", &tag diff --git a/aptos-move/script-composer/src/helpers.rs b/aptos-move/script-composer/src/helpers.rs index adb27fe8bea..b40c8d0a274 100644 --- a/aptos-move/script-composer/src/helpers.rs +++ b/aptos-move/script-composer/src/helpers.rs @@ -9,7 +9,7 @@ use move_binary_format::{ }; use move_core_types::{ identifier::IdentStr, - language_storage::{ModuleId, TypeTag}, + language_storage::{FunctionParamOrReturnTag, ModuleId, TypeTag}, transaction_argument::TransactionArgument, vm_status::StatusCode, }; @@ -29,11 +29,6 @@ pub(crate) fn import_type_tag( type_tag: &TypeTag, module_resolver: &BTreeMap, ) -> PartialVMResult { - let to_list = |script_builder: &mut CompiledScriptBuilder, ts: &[TypeTag]| { - ts.iter() - .map(|t| import_type_tag(script_builder, t, module_resolver)) - .collect::>>() - }; Ok(match type_tag { TypeTag::Address => SignatureToken::Address, TypeTag::U8 => SignatureToken::U8, @@ -56,17 +51,44 @@ pub(crate) fn import_type_tag( if s.type_args.is_empty() { SignatureToken::Struct(struct_idx) } else { - SignatureToken::StructInstantiation( - struct_idx, - to_list(script_builder, &s.type_args)?, - ) + let type_args = s + .type_args + .iter() + .map(|t| import_type_tag(script_builder, t, module_resolver)) + .collect::>>()?; + SignatureToken::StructInstantiation(struct_idx, type_args) } }, - TypeTag::Function(f) => SignatureToken::Function( - to_list(script_builder, &f.args)?, - to_list(script_builder, &f.results)?, - f.abilities, - ), + TypeTag::Function(f) => { + let to_list = |script_builder: &mut CompiledScriptBuilder, + ts: &[FunctionParamOrReturnTag]| { + ts.iter() + .map(|t| { + Ok(match t { + FunctionParamOrReturnTag::Reference(t) => SignatureToken::Reference( + Box::new(import_type_tag(script_builder, t, module_resolver)?), + ), + FunctionParamOrReturnTag::MutableReference(t) => { + SignatureToken::MutableReference(Box::new(import_type_tag( + script_builder, + t, + module_resolver, + )?)) + }, + FunctionParamOrReturnTag::Value(t) => { + import_type_tag(script_builder, t, module_resolver)? + }, + }) + }) + .collect::>>() + }; + + SignatureToken::Function( + to_list(script_builder, &f.args)?, + to_list(script_builder, &f.results)?, + f.abilities, + ) + }, }) } diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/type_tag_to_string.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/type_tag_to_string.rs index bb873b59db7..6e3a4a1929a 100644 --- a/testsuite/fuzzer/fuzz/fuzz_targets/move/type_tag_to_string.rs +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/type_tag_to_string.rs @@ -5,6 +5,7 @@ use arbitrary::Arbitrary; use libfuzzer_sys::{fuzz_target, Corpus}; use move_core_types::{ability::AbilitySet, identifier::Identifier, language_storage::TypeTag}; + mod utils; #[derive(Arbitrary, Debug)] @@ -24,8 +25,14 @@ fn is_valid_type_tag(type_tag: &TypeTag) -> bool { TypeTag::Vector(inner_type_tag) => is_valid_type_tag(inner_type_tag), TypeTag::Function(function_tag) => { function_tag.abilities.into_u8() <= AbilitySet::ALL.into_u8() - && function_tag.args.iter().all(is_valid_type_tag) - && function_tag.results.iter().all(is_valid_type_tag) + && function_tag + .args + .iter() + .all(|t| is_valid_type_tag(t.inner_tag())) + && function_tag + .results + .iter() + .all(|t| is_valid_type_tag(t.inner_tag())) }, _ => true, // Primitive types are always valid } diff --git a/testsuite/generate-format/src/api.rs b/testsuite/generate-format/src/api.rs index d519dfda1f1..2d09009e37d 100644 --- a/testsuite/generate-format/src/api.rs +++ b/testsuite/generate-format/src/api.rs @@ -97,6 +97,7 @@ pub fn get_registry() -> Result { // 2. Trace the main entry point(s) + every enum separately. // stdlib types tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; diff --git a/testsuite/generate-format/src/aptos.rs b/testsuite/generate-format/src/aptos.rs index 9760854c559..8abeebf52b4 100644 --- a/testsuite/generate-format/src/aptos.rs +++ b/testsuite/generate-format/src/aptos.rs @@ -91,6 +91,7 @@ pub fn get_registry() -> Result { // 2. Trace the main entry point(s) + every enum separately. tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; diff --git a/testsuite/generate-format/src/consensus.rs b/testsuite/generate-format/src/consensus.rs index f79142cca93..ebcb5f2da86 100644 --- a/testsuite/generate-format/src/consensus.rs +++ b/testsuite/generate-format/src/consensus.rs @@ -90,6 +90,7 @@ pub fn get_registry() -> Result { // 2. Trace the main entry point(s) + every enum separately. tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; diff --git a/testsuite/generate-format/src/move_abi.rs b/testsuite/generate-format/src/move_abi.rs index f07d8b27fb4..26dffb6ea0a 100644 --- a/testsuite/generate-format/src/move_abi.rs +++ b/testsuite/generate-format/src/move_abi.rs @@ -19,6 +19,7 @@ pub fn get_registry() -> Result { // 2. Trace the main entry point(s) + every enum separately. tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; // aliases within StructTag diff --git a/testsuite/generate-format/tests/staged/api.yaml b/testsuite/generate-format/tests/staged/api.yaml index bfcaceda30d..06dd42f536c 100644 --- a/testsuite/generate-format/tests/staged/api.yaml +++ b/testsuite/generate-format/tests/staged/api.yaml @@ -343,6 +343,29 @@ FederatedKeylessPublicKey: TYPENAME: AccountAddress - pk: TYPENAME: KeylessPublicKey +FeeDistribution: + ENUM: + 0: + V0: + STRUCT: + - amount: + MAP: + KEY: U64 + VALUE: U64 +FunctionParamOrReturnTag: + ENUM: + 0: + Reference: + NEWTYPE: + TYPENAME: TypeTag + 1: + MutableReference: + NEWTYPE: + TYPENAME: TypeTag + 2: + Value: + NEWTYPE: + TYPENAME: TypeTag FunctionInfo: STRUCT: - module_address: @@ -353,10 +376,10 @@ FunctionTag: STRUCT: - args: SEQ: - TYPENAME: TypeTag + TYPENAME: FunctionParamOrReturnTag - results: SEQ: - TYPENAME: TypeTag + TYPENAME: FunctionParamOrReturnTag - abilities: TYPENAME: AbilitySet G1Bytes: diff --git a/testsuite/generate-format/tests/staged/aptos.yaml b/testsuite/generate-format/tests/staged/aptos.yaml index 731db6591d8..32f3cb03d9e 100644 --- a/testsuite/generate-format/tests/staged/aptos.yaml +++ b/testsuite/generate-format/tests/staged/aptos.yaml @@ -289,6 +289,29 @@ FederatedKeylessPublicKey: TYPENAME: AccountAddress - pk: TYPENAME: KeylessPublicKey +FeeDistribution: + ENUM: + 0: + V0: + STRUCT: + - amount: + MAP: + KEY: U64 + VALUE: U64 +FunctionParamOrReturnTag: + ENUM: + 0: + Reference: + NEWTYPE: + TYPENAME: TypeTag + 1: + MutableReference: + NEWTYPE: + TYPENAME: TypeTag + 2: + Value: + NEWTYPE: + TYPENAME: TypeTag FunctionInfo: STRUCT: - module_address: @@ -299,10 +322,10 @@ FunctionTag: STRUCT: - args: SEQ: - TYPENAME: TypeTag + TYPENAME: FunctionParamOrReturnTag - results: SEQ: - TYPENAME: TypeTag + TYPENAME: FunctionParamOrReturnTag - abilities: TYPENAME: AbilitySet G1Bytes: diff --git a/testsuite/generate-format/tests/staged/consensus.yaml b/testsuite/generate-format/tests/staged/consensus.yaml index 69ddf732872..c79bbd46b40 100644 --- a/testsuite/generate-format/tests/staged/consensus.yaml +++ b/testsuite/generate-format/tests/staged/consensus.yaml @@ -582,6 +582,29 @@ FederatedKeylessPublicKey: TYPENAME: AccountAddress - pk: TYPENAME: KeylessPublicKey +FeeDistribution: + ENUM: + 0: + V0: + STRUCT: + - amount: + MAP: + KEY: U64 + VALUE: U64 +FunctionParamOrReturnTag: + ENUM: + 0: + Reference: + NEWTYPE: + TYPENAME: TypeTag + 1: + MutableReference: + NEWTYPE: + TYPENAME: TypeTag + 2: + Value: + NEWTYPE: + TYPENAME: TypeTag FunctionInfo: STRUCT: - module_address: @@ -592,10 +615,10 @@ FunctionTag: STRUCT: - args: SEQ: - TYPENAME: TypeTag + TYPENAME: FunctionParamOrReturnTag - results: SEQ: - TYPENAME: TypeTag + TYPENAME: FunctionParamOrReturnTag - abilities: TYPENAME: AbilitySet G1Bytes: diff --git a/testsuite/generate-format/tests/staged/move_abi.yaml b/testsuite/generate-format/tests/staged/move_abi.yaml index 9919ebb6a1f..bb27b2a0cd5 100644 --- a/testsuite/generate-format/tests/staged/move_abi.yaml +++ b/testsuite/generate-format/tests/staged/move_abi.yaml @@ -21,14 +21,28 @@ EntryABI: EntryFunction: NEWTYPE: TYPENAME: ScriptFunctionABI +FunctionParamOrReturnTag: + ENUM: + 0: + Reference: + NEWTYPE: + TYPENAME: TypeTag + 1: + MutableReference: + NEWTYPE: + TYPENAME: TypeTag + 2: + Value: + NEWTYPE: + TYPENAME: TypeTag FunctionTag: STRUCT: - args: SEQ: - TYPENAME: TypeTag + TYPENAME: FunctionParamOrReturnTag - results: SEQ: - TYPENAME: TypeTag + TYPENAME: FunctionParamOrReturnTag - abilities: TYPENAME: AbilitySet Identifier: diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/funs_as_storage_key.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/funs_as_storage_key.exp index 4cc272d947b..9656b72fafa 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/funs_as_storage_key.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/funs_as_storage_key.exp @@ -1,7 +1,10 @@ -processed 4 tasks +processed 13 tasks -task 2 'run'. lines 72-72: +task 5 'run'. lines 162-162: return values: true -task 3 'run'. lines 74-74: +task 6 'run'. lines 164-164: return values: true + +task 12 'run'. lines 176-176: +return values: 6 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/funs_as_storage_key.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/funs_as_storage_key.move index b44d4f20e4c..2cb93dc37e8 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/funs_as_storage_key.move +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/funs_as_storage_key.move @@ -69,6 +69,108 @@ module 0x42::mod3 { } } +//# publish +module 0x42::mod4 { + struct Wrapper has key { + fv: T + } + + #[persistent] + fun test(ref: &u64, _mut_ref: &mut u8): &u64 { + ref + } + + fun initialize(acc: &signer) { + move_to>(acc, Wrapper { fv: 0x42::mod4::test}); + } + + fun check_exists(_acc: &signer) { + let exists = exists>(@0x42); + assert!(exists, 404); + } +} + +//# publish +module 0x42::mod5 { + struct VecWrapper has key { + fvs: vector + } + + #[persistent] + fun test(ref: &u64, _mut_ref: &mut u8): &u64 { + ref + } + + fun initialize(acc: &signer) { + move_to>(acc, VecWrapper { fvs: vector[0x42::mod5::test]}); + } + + fun check_exists(_acc: &signer) { + let exists = exists>(@0x42); + assert!(exists, 404); + } +} + +//# publish +module 0x42::mod6 { + struct VecWrapper has key { + fvs: vector + } + + #[persistent] + fun test1(x: &mut u8) { + *x = *x + 1; + } + + #[persistent] + fun test2(x: &mut u8) { + *x = *x + 2; + } + + #[persistent] + fun test3(x: &mut u8) { + *x = *x + 3; + } + + fun initialize(acc: &signer) { + let fvs = vector[ + 0x42::mod6::test1, + 0x42::mod6::test2, + 0x42::mod6::test3, + ]; + move_to>(acc, VecWrapper { fvs }); + } + + fun compute(_acc: &signer): u8 { + let do_not_exist = !exists>(@0x42) + && !exists>(@0x42); + assert!(do_not_exist, 404); + + let wrapper = &borrow_global>(@0x42).fvs; + let x = 0; + + let i = 0; + while (i < 3) { + let f = std::vector::borrow(wrapper, i); + (*f)(&mut x); + i = i + 1; + }; + x + } +} + //# run 0x42::mod3::test_items --signers 0x42 --args true //# run 0x42::mod3::test_items --signers 0x42 --args false + +//# run 0x42::mod4::initialize --signers 0x42 + +//# run 0x42::mod4::check_exists --signers 0x42 + +//# run 0x42::mod5::initialize --signers 0x42 + +//# run 0x42::mod5::check_exists --signers 0x42 + +//# run 0x42::mod6::initialize --signers 0x42 + +//# run 0x42::mod6::compute --signers 0x42 diff --git a/third_party/move/move-core/types/src/language_storage.rs b/third_party/move/move-core/types/src/language_storage.rs index a14edfc6c4e..497bb398c28 100644 --- a/third_party/move/move-core/types/src/language_storage.rs +++ b/third_party/move/move-core/types/src/language_storage.rs @@ -6,6 +6,7 @@ use crate::{ ability::AbilitySet, account_address::AccountAddress, identifier::{IdentStr, Identifier}, + language_storage::FunctionParamOrReturnTag::{MutableReference, Reference, Value}, parser::{parse_module_id, parse_struct_tag, parse_type_tag}, safe_serialize, }; @@ -137,8 +138,13 @@ impl<'a> Iterator for TypeTagPreorderTraversalIter<'a> { Struct(struct_tag) => self.stack.extend(struct_tag.type_args.iter().rev()), Function(fun_tag) => { let FunctionTag { args, results, .. } = fun_tag.as_ref(); - self.stack - .extend(results.iter().rev().chain(args.iter().rev())) + self.stack.extend( + results + .iter() + .map(|t| t.inner_tag()) + .rev() + .chain(args.iter().map(|t| t.inner_tag()).rev()), + ) }, } Some(ty) @@ -257,8 +263,8 @@ impl FromStr for StructTag { #[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))] #[cfg_attr(any(test, feature = "fuzzing"), proptest(no_params))] pub struct FunctionTag { - pub args: Vec, - pub results: Vec, + pub args: Vec, + pub results: Vec, pub abilities: AbilitySet, } @@ -267,7 +273,7 @@ impl FunctionTag { /// /// INVARIANT: If two function tags are different, they must have different canonical strings. pub fn to_canonical_string(&self) -> String { - let fmt_list = |l: &[TypeTag]| -> String { + let fmt_list = |l: &[FunctionParamOrReturnTag]| -> String { l.iter() .map(|t| t.to_canonical_string()) .collect::>() @@ -290,6 +296,42 @@ impl FunctionTag { } } +/// Represents an argument or return tag for [FunctionTag]. This is needed because function tags +/// carry information about return and argument types which can be references. So direct return +/// or paramter tags can be references, but not the inner tags. +#[derive(Serialize, Deserialize, Debug, PartialEq, Hash, Eq, Clone, PartialOrd, Ord)] +#[cfg_attr( + any(test, feature = "fuzzing"), + derive(arbitrary::Arbitrary, dearbitrary::Dearbitrary) +)] +#[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))] +#[cfg_attr(any(test, feature = "fuzzing"), proptest(no_params))] +pub enum FunctionParamOrReturnTag { + Reference(TypeTag), + MutableReference(TypeTag), + Value(TypeTag), +} + +impl FunctionParamOrReturnTag { + /// Returns a canonical string representation of function tag's argument or return tag. If any + /// two tags are different, their canonical representation must be also different. + pub fn to_canonical_string(&self) -> String { + use FunctionParamOrReturnTag::*; + match self { + Reference(tag) => format!("&{}", tag.to_canonical_string()), + MutableReference(tag) => format!("&mut {}", tag.to_canonical_string()), + Value(tag) => tag.to_canonical_string(), + } + } + + /// Returns the inner tag for this argument or return tag. + pub fn inner_tag(&self) -> &TypeTag { + match self { + Reference(tag) | MutableReference(tag) | Value(tag) => tag, + } + } +} + /// Represents the initial key into global storage where we first index by the address, and then /// the struct tag. The struct fields are public to support pattern matching. #[derive(Serialize, Deserialize, Debug, PartialEq, Hash, Eq, Clone, PartialOrd, Ord)] @@ -423,8 +465,8 @@ mod tests { } fn make_function_tag( - args: Vec, - results: Vec, + args: Vec, + results: Vec, abilities: AbilitySet, ) -> TypeTag { TypeTag::Function(Box::new(FunctionTag { @@ -436,6 +478,7 @@ mod tests { #[test] fn test_to_canonical_string() { + use FunctionParamOrReturnTag::*; use TypeTag::*; let data = [ @@ -467,25 +510,33 @@ mod tests { ), (make_function_tag(vec![], vec![], AbilitySet::EMPTY), "||()"), ( - make_function_tag(vec![], vec![U8, U64], AbilitySet::EMPTY), - "||(u8, u64)", + make_function_tag( + vec![], + vec![MutableReference(U8), Value(U64)], + AbilitySet::EMPTY, + ), + "||(&mut u8, u64)", ), ( - make_function_tag(vec![U8, U64], vec![], AbilitySet::EMPTY), - "|u8, u64|()", + make_function_tag(vec![Reference(U8), Value(U64)], vec![], AbilitySet::EMPTY), + "|&u8, u64|()", ), ( make_struct_tag(AccountAddress::ONE, "a", "A", vec![make_function_tag( - vec![make_function_tag( - vec![make_function_tag( + vec![Value(make_function_tag( + vec![Value(make_function_tag( vec![], vec![], AbilitySet::singleton(Ability::Copy), - )], + ))], vec![], AbilitySet::EMPTY, - )], - vec![make_function_tag(vec![], vec![], AbilitySet::ALL)], + ))], + vec![FunctionParamOrReturnTag::Value(make_function_tag( + vec![], + vec![], + AbilitySet::ALL, + ))], AbilitySet::EMPTY, )]), "0x1::a::A<||||() has copy|()|(||() has copy + drop + store + key)>", diff --git a/third_party/move/move-model/src/ty.rs b/third_party/move/move-model/src/ty.rs index c32c3ca06d5..ba2f78d53ce 100644 --- a/third_party/move/move-model/src/ty.rs +++ b/third_party/move/move-model/src/ty.rs @@ -21,7 +21,7 @@ use move_binary_format::{ }; use move_core_types::{ ability::{Ability, AbilitySet}, - language_storage::{FunctionTag, StructTag, TypeTag}, + language_storage::{FunctionParamOrReturnTag, FunctionTag, StructTag, TypeTag}, u256::U256, }; use num::BigInt; @@ -1579,8 +1579,22 @@ impl Type { results, abilities, } = fun.as_ref(); - let from_vec = |ts: &[TypeTag]| { - Type::tuple(ts.iter().map(|t| Type::from_type_tag(t, env)).collect_vec()) + let from_vec = |ts: &[FunctionParamOrReturnTag]| { + Type::tuple( + ts.iter() + .map(|t| match t { + FunctionParamOrReturnTag::Reference(t) => Reference( + ReferenceKind::Immutable, + Box::new(Type::from_type_tag(t, env)), + ), + FunctionParamOrReturnTag::MutableReference(t) => Reference( + ReferenceKind::Mutable, + Box::new(Type::from_type_tag(t, env)), + ), + FunctionParamOrReturnTag::Value(t) => Type::from_type_tag(t, env), + }) + .collect_vec(), + ) }; Fun( Box::new(from_vec(args)), diff --git a/third_party/move/move-vm/runtime/src/storage/ty_tag_converter.rs b/third_party/move/move-vm/runtime/src/storage/ty_tag_converter.rs index 3b33a56ac9d..9d6d3e7d734 100644 --- a/third_party/move/move-vm/runtime/src/storage/ty_tag_converter.rs +++ b/third_party/move/move-vm/runtime/src/storage/ty_tag_converter.rs @@ -5,7 +5,7 @@ use crate::{config::VMConfig, RuntimeEnvironment}; use hashbrown::{hash_map::Entry, HashMap}; use move_binary_format::errors::{PartialVMError, PartialVMResult}; use move_core_types::{ - language_storage::{FunctionTag, StructTag, TypeTag}, + language_storage::{FunctionParamOrReturnTag, FunctionTag, StructTag, TypeTag}, vm_status::StatusCode, }; use move_vm_types::loaded_data::{runtime_types::Type, struct_name_indexing::StructNameIndex}; @@ -278,7 +278,8 @@ impl<'a> TypeTagConverter<'a> { TypeTag::Struct(Box::new(struct_tag)) }, - // Functions: recurse + // Functions: recursively construct tags for argument and return types. Note that these + // can be references, unlike regular tags. Type::Function { args, results, @@ -286,9 +287,23 @@ impl<'a> TypeTagConverter<'a> { } => { let to_vec = |ts: &[Type], gas_ctx: &mut PseudoGasContext| - -> PartialVMResult> { + -> PartialVMResult> { ts.iter() - .map(|t| self.ty_to_ty_tag_impl(t, gas_ctx)) + .map(|t| { + Ok(match t { + Type::Reference(t) => FunctionParamOrReturnTag::Reference( + self.ty_to_ty_tag_impl(t, gas_ctx)?, + ), + Type::MutableReference(t) => { + FunctionParamOrReturnTag::MutableReference( + self.ty_to_ty_tag_impl(t, gas_ctx)?, + ) + }, + t => FunctionParamOrReturnTag::Value( + self.ty_to_ty_tag_impl(t, gas_ctx)?, + ), + }) + }) .collect() }; TypeTag::Function(Box::new(FunctionTag { diff --git a/third_party/move/move-vm/types/src/loaded_data/runtime_types.rs b/third_party/move/move-vm/types/src/loaded_data/runtime_types.rs index a46eabd5ec8..b2ae927b85b 100644 --- a/third_party/move/move-vm/types/src/loaded_data/runtime_types.rs +++ b/third_party/move/move-vm/types/src/loaded_data/runtime_types.rs @@ -16,7 +16,7 @@ use move_binary_format::{ use move_core_types::{ ability::{Ability, AbilitySet}, identifier::Identifier, - language_storage::{FunctionTag, ModuleId, StructTag, TypeTag}, + language_storage::{FunctionParamOrReturnTag, FunctionTag, ModuleId, StructTag, TypeTag}, vm_status::{sub_status::unknown_invariant_violation::EPARANOID_FAILURE, StatusCode}, }; use serde::Serialize; @@ -1322,9 +1322,23 @@ impl TypeBuilder { results, abilities, } = fun.as_ref(); - let mut to_list = |ts: &[TypeTag]| { + let mut to_list = |ts: &[FunctionParamOrReturnTag]| { ts.iter() - .map(|t| self.create_ty_impl(t, resolver, count, depth + 1)) + .map(|t| { + // Note: for reference or mutable reference tags, we add 1 more level + // of depth, hence adding 2 to the counter. + Ok(match t { + FunctionParamOrReturnTag::Reference(t) => Reference(Box::new( + self.create_ty_impl(t, resolver, count, depth + 2)?, + )), + FunctionParamOrReturnTag::MutableReference(t) => MutableReference( + Box::new(self.create_ty_impl(t, resolver, count, depth + 2)?), + ), + FunctionParamOrReturnTag::Value(t) => { + self.create_ty_impl(t, resolver, count, depth + 1)? + }, + }) + }) .collect::>>() }; Function { diff --git a/third_party/move/move-vm/types/src/values/serialization_tests.rs b/third_party/move/move-vm/types/src/values/serialization_tests.rs index f6a04e963ad..1024331016a 100644 --- a/third_party/move/move-vm/types/src/values/serialization_tests.rs +++ b/third_party/move/move-vm/types/src/values/serialization_tests.rs @@ -18,7 +18,7 @@ mod tests { account_address::AccountAddress, function::{ClosureMask, MoveClosure, FUNCTION_DATA_SERIALIZATION_FORMAT_V1}, identifier::Identifier, - language_storage::{FunctionTag, ModuleId, StructTag, TypeTag}, + language_storage::{FunctionParamOrReturnTag, FunctionTag, ModuleId, StructTag, TypeTag}, u256, value::{IdentifierMappingKind, MoveStruct, MoveStructLayout, MoveTypeLayout, MoveValue}, }; @@ -214,13 +214,15 @@ mod tests { vec![ TypeTag::Address, TypeTag::Function(Box::new(FunctionTag { - args: vec![TypeTag::Struct(Box::new(StructTag { - address: AccountAddress::TEN, - module: Identifier::new("mod").unwrap(), - name: Identifier::new("st").unwrap(), - type_args: vec![TypeTag::Signer], - }))], - results: vec![TypeTag::Address], + args: vec![FunctionParamOrReturnTag::Value(TypeTag::Struct(Box::new( + StructTag { + address: AccountAddress::TEN, + module: Identifier::new("mod").unwrap(), + name: Identifier::new("st").unwrap(), + type_args: vec![TypeTag::Signer], + }, + )))], + results: vec![FunctionParamOrReturnTag::Value(TypeTag::Address)], abilities: AbilitySet::PUBLIC_FUNCTIONS, })), ] diff --git a/third_party/move/tools/move-resource-viewer/src/fat_type.rs b/third_party/move/tools/move-resource-viewer/src/fat_type.rs index 4e5577e7e97..0de1e174ed5 100644 --- a/third_party/move/tools/move-resource-viewer/src/fat_type.rs +++ b/third_party/move/tools/move-resource-viewer/src/fat_type.rs @@ -9,7 +9,7 @@ use move_core_types::{ ability::AbilitySet, account_address::AccountAddress, identifier::Identifier, - language_storage::{FunctionTag, StructTag, TypeTag}, + language_storage::{FunctionParamOrReturnTag, FunctionTag, StructTag, TypeTag}, value::{MoveStructLayout, MoveTypeLayout}, vm_status::StatusCode, }; @@ -218,7 +218,17 @@ impl FatFunctionType { pub fn fun_tag(&self, limiter: &mut Limiter) -> PartialVMResult { let tag_slice = |limiter: &mut Limiter, tys: &[FatType]| { tys.iter() - .map(|ty| ty.type_tag(limiter)) + .map(|ty| { + Ok(match ty { + FatType::Reference(ty) => { + FunctionParamOrReturnTag::Reference(ty.type_tag(limiter)?) + }, + FatType::MutableReference(ty) => { + FunctionParamOrReturnTag::MutableReference(ty.type_tag(limiter)?) + }, + ty => FunctionParamOrReturnTag::Value(ty.type_tag(limiter)?), + }) + }) .collect::>>() }; Ok(FunctionTag { @@ -424,9 +434,24 @@ impl From<&StructTag> for FatStructType { } } +impl From<&FunctionParamOrReturnTag> for FatType { + fn from(tag: &FunctionParamOrReturnTag) -> FatType { + use FatType::*; + match tag { + FunctionParamOrReturnTag::Reference(tag) => Reference(Box::new(tag.into())), + FunctionParamOrReturnTag::MutableReference(tag) => { + MutableReference(Box::new(tag.into())) + }, + FunctionParamOrReturnTag::Value(tag) => tag.into(), + } + } +} + impl From<&FunctionTag> for FatFunctionType { fn from(fun_tag: &FunctionTag) -> FatFunctionType { - let into_slice = |tys: &[TypeTag]| tys.iter().map(|ty| ty.into()).collect::>(); + let into_slice = |tys: &[FunctionParamOrReturnTag]| { + tys.iter().map(|ty| ty.into()).collect::>() + }; FatFunctionType { args: into_slice(&fun_tag.args), results: into_slice(&fun_tag.results), From 20ecaedee13deabbfebd05abc233516e63f68e47 Mon Sep 17 00:00:00 2001 From: Jun Xu <5827713+junxzm1990@users.noreply.github.com> Date: Wed, 25 Jun 2025 15:43:12 -0600 Subject: [PATCH 013/260] fixing a bug in decompiling nested loops (#16908) Downstreamed-from: 9dcd46aa3be082979e9cb3b6a45e8cc46cef0e41 --- .../move/move-model/bytecode/src/astifier.rs | 15 +- .../move-decompiler/tests/nested_loops.exp | 235 ++++++++++++++++++ .../move-decompiler/tests/nested_loops.move | 163 ++++++++++++ 3 files changed, 409 insertions(+), 4 deletions(-) create mode 100644 third_party/move/tools/move-decompiler/tests/nested_loops.exp create mode 100644 third_party/move/tools/move-decompiler/tests/nested_loops.move diff --git a/third_party/move/move-model/bytecode/src/astifier.rs b/third_party/move/move-model/bytecode/src/astifier.rs index 4293e836c9a..c2306f95bcd 100644 --- a/third_party/move/move-model/bytecode/src/astifier.rs +++ b/third_party/move/move-model/bytecode/src/astifier.rs @@ -525,11 +525,18 @@ impl Generator { // any blocks after that loop. This is a requirement for the algorithm to work. for header in &ctx.loop_headers { for after_loop_label in &ctx.after_loop_labels[header] { + let dest_block = ctx.block_of_label(*after_loop_label); + let edge_filter = |_: BlockId, _: BlockId| true; + let reachable_from_dest = ctx.forward_cfg.reachable_blocks(dest_block, edge_filter); for loop_block_label in &ctx.loop_labels[header] { - top_sort.add_dependency( - ctx.block_of_label(*loop_block_label), - ctx.block_of_label(*after_loop_label), - ) + // Only when the new virtual edge does not introduce a cycle, we add it! + let source_block = ctx.block_of_label(*loop_block_label); + if !reachable_from_dest.contains(&source_block) { + top_sort.add_dependency( + ctx.block_of_label(*loop_block_label), + ctx.block_of_label(*after_loop_label), + ) + } } } } diff --git a/third_party/move/tools/move-decompiler/tests/nested_loops.exp b/third_party/move/tools/move-decompiler/tests/nested_loops.exp new file mode 100644 index 00000000000..cdff3026033 --- /dev/null +++ b/third_party/move/tools/move-decompiler/tests/nested_loops.exp @@ -0,0 +1,235 @@ + +module 0x99::m { + fun nested_for_loops() { + let _t4; + let _t3; + let _t2; + let _t1; + let _t0; + _t0 = 0; + _t1 = 0; + _t2 = false; + 'l0: loop { + if (_t2) _t1 = _t1 + 1 else _t2 = true; + if (!(_t1 < 10)) break; + _t0 = _t0 + 1; + _t3 = _t1; + _t4 = false; + loop { + if (_t4) _t3 = _t3 + 1 else _t4 = true; + if (!(_t3 < 10)) continue 'l0; + _t0 = _t0 + 1 + }; + break + }; + } + fun nested_for_while_loop_loops() { + let _t4; + let _t3; + let _t2; + let _t1; + let _t0; + _t0 = 0; + _t1 = 0; + _t2 = false; + 'l0: loop { + if (_t2) _t1 = _t1 + 1 else _t2 = true; + if (!(_t1 < 5)) break; + _t0 = _t0 + 1; + _t3 = _t1; + 'l1: loop { + if (!(_t3 < 10)) continue 'l0; + _t0 = _t0 + 1; + _t4 = _t3; + _t3 = _t3 + 1; + loop { + _t0 = _t0 + 1; + if (_t4 > 10) continue 'l1; + _t4 = _t4 + 1 + }; + break + }; + break + }; + } + fun nested_for_while_loops() { + let _t2; + let _t1; + let _t0; + _t0 = 0; + _t1 = 0; + _t2 = false; + 'l0: loop { + if (_t2) _t1 = _t1 + 1 else _t2 = true; + if (!(_t1 < 5)) break; + _t0 = _t0 + 1; + loop { + if (!(_t0 < 5)) continue 'l0; + _t0 = _t0 + 10 + }; + break + }; + } + fun nested_loop_for_loops() { + let _t4; + let _t3; + let _t2; + let _t1; + let _t0; + _t0 = 0; + _t1 = 0; + 'l0: loop { + _t0 = _t0 + 1; + _t2 = 0; + if (_t0 > 3) break; + _t3 = 0; + _t4 = false; + loop { + if (_t4) _t3 = _t3 + 1 else _t4 = true; + if (!(_t3 < 5)) continue 'l0; + _t2 = _t2 + 1; + _t1 = _t1 + 1 + }; + break + }; + } + fun nested_loop_loops() { + let _t2; + let _t1; + let _t0; + _t0 = 0; + _t1 = 0; + 'l0: loop { + _t0 = _t0 + 1; + _t2 = 0; + if (_t0 > 3) break; + loop { + _t2 = _t2 + 1; + _t1 = _t1 + 1; + if (_t2 > 7) continue 'l0 + }; + break + }; + } + fun nested_loop_while_loops() { + let _t2; + let _t1; + let _t0; + _t0 = 0; + _t1 = 0; + 'l0: loop { + _t0 = _t0 + 1; + _t2 = 0; + if (_t0 > 3) break; + loop { + if (!(_t2 < 7)) continue 'l0; + _t2 = _t2 + 1; + _t1 = _t1 + 1 + }; + break + }; + } + fun nested_while_loops() { + let _t2; + let _t1; + let _t0; + _t0 = 0; + _t1 = 0; + 'l0: while (_t0 < 3) { + _t0 = _t0 + 1; + _t2 = 0; + loop { + if (!(_t2 < 7)) continue 'l0; + _t2 = _t2 + 1; + _t1 = _t1 + 1 + }; + break + }; + } + fun three_layer_for_loops() { + let _t6; + let _t5; + let _t4; + let _t3; + let _t2; + let _t1; + let _t0; + _t0 = 0; + _t1 = 0; + _t2 = false; + 'l0: loop { + if (_t2) _t1 = _t1 + 1 else _t2 = true; + if (!(_t1 < 10)) break; + _t0 = _t0 + 1; + _t3 = _t1; + _t4 = false; + 'l1: loop { + if (_t4) _t3 = _t3 + 1 else _t4 = true; + if (!(_t3 < 10)) continue 'l0; + _t0 = _t0 + 1; + _t5 = _t3; + _t6 = false; + loop { + if (_t6) _t5 = _t5 + 1 else _t6 = true; + if (!(_t5 < 10)) continue 'l1; + _t0 = _t0 + 1 + }; + break + }; + break + }; + } + fun three_layer_loop_loops() { + let _t3; + let _t2; + let _t1; + let _t0; + _t0 = 0; + _t1 = 0; + 'l0: loop { + _t0 = _t0 + 1; + _t2 = _t1; + if (_t1 > 10) break; + _t1 = _t1 + 1; + 'l1: loop { + _t0 = _t0 + 1; + _t3 = _t2; + if (_t2 > 10) continue 'l0; + _t2 = _t2 + 1; + loop { + _t0 = _t0 + 1; + if (_t3 > 10) continue 'l1; + _t3 = _t3 + 1 + }; + break + }; + break + }; + } + fun three_layer_while_loops() { + let _t3; + let _t2; + let _t1; + let _t0; + _t0 = 0; + _t1 = 0; + 'l0: while (_t1 < 10) { + _t0 = _t0 + 1; + _t2 = _t1; + _t1 = _t1 + 1; + 'l1: loop { + if (!(_t2 < 10)) continue 'l0; + _t0 = _t0 + 1; + _t3 = _t2; + _t2 = _t2 + 1; + loop { + if (!(_t3 < 10)) continue 'l1; + _t0 = _t0 + 1; + _t3 = _t3 + 1 + }; + break + }; + break + }; + } +} diff --git a/third_party/move/tools/move-decompiler/tests/nested_loops.move b/third_party/move/tools/move-decompiler/tests/nested_loops.move new file mode 100644 index 00000000000..b298bab4c01 --- /dev/null +++ b/third_party/move/tools/move-decompiler/tests/nested_loops.move @@ -0,0 +1,163 @@ +//* Test cases with nested loops +module 0x99::m { + fun nested_for_loops() { + let y = 0; + for (i in 0..10) { + y = y + 1; + for (j in i..10) { + y = y + 1; + }; + }; + } + + fun nested_while_loops() { + let x = 0; + let z = 0; + let y; + while (x < 3) { + x = x + 1; + y = 0; + while (y < 7) { + y = y + 1; + z = z + 1; + } + }; + } + + fun nested_loop_loops () { + let x = 0; + let z = 0; + let y; + loop { + x = x + 1; + y = 0; + if (x > 3) + break; + loop { + y = y + 1; + z = z + 1; + if (y > 7) + break; + }; + }; + } + + fun nested_for_while_loops() { + let y = 0; + for (i in 0..5) { + y = y + 1; + while (y < 5) { + y = y + 10; + }; + }; + } + + fun nested_loop_while_loops() { + let x = 0; + let z = 0; + let y; + loop { + x = x + 1; + y = 0; + if (x > 3) + break; + while (y < 7) { + y = y + 1; + z = z + 1; + } + }; + } + + fun nested_loop_for_loops() { + let x = 0; + let z = 0; + let y; + loop { + x = x + 1; + y = 0; + if (x > 3) + break; + for (i in 0..5) { + y = y + 1; + z = z + 1; + } + }; + } + + fun three_layer_for_loops(){ + let y = 0; + for (i in 0..10) { + y = y + 1; + for (j in i..10) { + y = y + 1; + for (k in j..10) { + y = y + 1; + }; + }; + }; + } + + fun three_layer_while_loops(){ + let y = 0; + let i = 0; + while(i < 10) { + y = y + 1; + let j = i; + i = i + 1; + while(j < 10) { + y = y + 1; + let k = j; + j = j + 1; + while(k < 10) { + y = y + 1; + k = k + 1; + }; + }; + }; + } + + fun three_layer_loop_loops(){ + let y = 0; + let i = 0; + loop { + y = y + 1; + let j = i; + if (i > 10) + break; + i = i + 1; + loop { + y = y + 1; + let k = j; + if (j > 10) + break; + j = j + 1; + loop { + y = y + 1; + if (k > 10) + break; + k = k + 1; + }; + }; + }; + } + + fun nested_for_while_loop_loops(){ + let y = 0; + let i = 0; + for(i in 0..5) { + y = y + 1; + let j = i; + while(j < 10) { + y = y + 1; + let k = j; + j = j + 1; + loop { + y = y + 1; + if (k > 10) + break; + k = k + 1; + }; + }; + }; + } +} From d2eef7144a79f94c5748ea9e1fccf5328d11b3e1 Mon Sep 17 00:00:00 2001 From: Vineeth Kashyap Date: Thu, 26 Jun 2025 15:37:24 -0400 Subject: [PATCH 014/260] [compiler-v2] More tests (#16818) Downstreamed-from: bf9bfa88901a4814a624778ba50406d825049e2a --- .../no-access-check/pack_private_function.exp | 10 ++++++++ .../pack_private_function.move | 14 +++++++++++ .../closures/cross_module_unwrap.exp | 4 +++ .../closures/cross_module_unwrap.move | 25 +++++++++++++++++++ .../transactional-tests/tests/tests.rs | 23 ++++++++++++++--- 5 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-access-check/pack_private_function.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-access-check/pack_private_function.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/cross_module_unwrap.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/cross_module_unwrap.move diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-access-check/pack_private_function.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-access-check/pack_private_function.exp new file mode 100644 index 00000000000..b32f7014095 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-access-check/pack_private_function.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'publish'. lines 8-14: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000c0ffee::n'. Got VMError: { + major_status: LOOKUP_FAILED, + sub_status: None, + location: 0xc0ffee::n, + indices: [(FunctionHandle, 1)], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-access-check/pack_private_function.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-access-check/pack_private_function.move new file mode 100644 index 00000000000..f6289e48b14 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-access-check/pack_private_function.move @@ -0,0 +1,14 @@ +//# publish +module 0xc0ffee::m { + struct S(u64); + + fun inaccessible() {} +} + +//# publish +module 0xc0ffee::n { + public fun test() { + let f = || 0xc0ffee::m::inaccessible(); + f(); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/cross_module_unwrap.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/cross_module_unwrap.exp new file mode 100644 index 00000000000..f4150d6cf7a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/cross_module_unwrap.exp @@ -0,0 +1,4 @@ +processed 3 tasks + +task 2 'run'. lines 25-25: +return values: 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/cross_module_unwrap.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/cross_module_unwrap.move new file mode 100644 index 00000000000..68333b91105 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/cross_module_unwrap.move @@ -0,0 +1,25 @@ +//# publish +module 0xc0ffee::m { + struct Wrapper(u64); + + public fun apply(f: |Wrapper|u64): u64 { + let w = Wrapper(42); + f(w) + } + + public fun unwrap_maker(): |Wrapper|u64 { + |Wrapper(x)| x + } +} + +//# publish +module 0xc0ffee::n { + use 0xc0ffee::m::apply; + + public fun test(): u64 { + let unwrap = 0xc0ffee::m::unwrap_maker(); + apply(unwrap) + } +} + +//# run 0xc0ffee::n::test diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs b/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs index fa0db422342..534c63dd1b8 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs @@ -29,6 +29,13 @@ struct TestConfig { exclude: &'static [&'static str], } +/// Set of exclusions that apply when using `include: &[]` in TestConfig. +const COMMON_EXCLUSIONS: &[&str] = &[ + "/operator_eval/", + "/no-recursive-check/", + "/no-access-check/", +]; + /// Note that any config which has different output for a test directory /// *must* be added to the `SEPARATE_BASELINE` array below, so that a /// special output file `test.foo.exp` will be generated for the output @@ -40,8 +47,8 @@ const TEST_CONFIGS: &[TestConfig] = &[ runner: |p| run(p, get_config_by_name("baseline")), experiments: &[], language_version: LanguageVersion::latest(), - include: &[], - exclude: &["/operator_eval/", "/no-recursive-check/"], + include: &[], // all tests except those excluded below + exclude: COMMON_EXCLUSIONS, }, // Test optimize/no-optimize/etc., except for `/access_control/` TestConfig { @@ -53,7 +60,7 @@ const TEST_CONFIGS: &[TestConfig] = &[ ], language_version: LanguageVersion::latest(), include: &[], // all tests except those excluded below - exclude: &["/operator_eval/", "/no-recursive-check/"], + exclude: COMMON_EXCLUSIONS, }, TestConfig { name: "no-optimize", @@ -61,7 +68,7 @@ const TEST_CONFIGS: &[TestConfig] = &[ experiments: &[(Experiment::OPTIMIZE, false)], language_version: LanguageVersion::latest(), include: &[], // all tests except those excluded below - exclude: &["/operator_eval/", "/no-recursive-check/"], + exclude: COMMON_EXCLUSIONS, }, // Test `/operator_eval/` with language version 1 and 2 TestConfig { @@ -88,6 +95,14 @@ const TEST_CONFIGS: &[TestConfig] = &[ include: &["/no-recursive-check/"], exclude: &[], }, + TestConfig { + name: "no-access-check", + runner: |p| run(p, get_config_by_name("no-access-check")), + experiments: &[(Experiment::ACCESS_CHECK, false)], + language_version: LanguageVersion::latest(), + include: &["/no-access-check/"], + exclude: &[], + }, ]; /// Test files which must use separate baselines because their result From 969a37923ad5c2bd6d7af731b69873d31168e054 Mon Sep 17 00:00:00 2001 From: Vineeth Kashyap Date: Mon, 30 Jun 2025 13:11:19 -0400 Subject: [PATCH 015/260] [vm][bytecode-verifier][trivial] Use captured count (#16940) Downstreamed-from: d6df1d832666649ff5d6f23e29b1365d059b67ae --- .../move-binary-format/src/check_bounds.rs | 9 ++++-- .../move-binary-format/src/file_format.rs | 2 +- .../src/check_duplication.rs | 1 + .../src/stack_usage_verifier.rs | 31 +++++-------------- 4 files changed, 16 insertions(+), 27 deletions(-) diff --git a/third_party/move/move-binary-format/src/check_bounds.rs b/third_party/move/move-binary-format/src/check_bounds.rs index 6f259d57b72..85a74a1bff9 100644 --- a/third_party/move/move-binary-format/src/check_bounds.rs +++ b/third_party/move/move-binary-format/src/check_bounds.rs @@ -144,8 +144,8 @@ impl<'a> BoundsChecker<'a> { } fn check_module_handles(&self) -> PartialVMResult<()> { - for script_handle in self.view.module_handles() { - self.check_module_handle(script_handle)? + for module_handle in self.view.module_handles() { + self.check_module_handle(module_handle)? } Ok(()) } @@ -240,7 +240,7 @@ impl<'a> BoundsChecker<'a> { check_bounds_impl(self.view.identifiers(), function_handle.name)?; check_bounds_impl(self.view.signatures(), function_handle.parameters)?; check_bounds_impl(self.view.signatures(), function_handle.return_)?; - // function signature type paramters must be in bounds to the function type parameters + // function signature type parameters must be in bounds to the function type parameters let type_param_count = function_handle.type_parameters.len(); self.check_type_parameters_in_signature(function_handle.parameters, type_param_count)?; self.check_type_parameters_in_signature(function_handle.return_, type_param_count)?; @@ -678,6 +678,9 @@ impl<'a> BoundsChecker<'a> { Ok(()) } + /// Check `ty` for: + /// - struct handle bounds + /// - struct instantiations have the correct number of type parameters fn check_type(&self, ty: &SignatureToken) -> PartialVMResult<()> { use self::SignatureToken::*; diff --git a/third_party/move/move-binary-format/src/file_format.rs b/third_party/move/move-binary-format/src/file_format.rs index 07b272c12be..93b7d53afcc 100644 --- a/third_party/move/move-binary-format/src/file_format.rs +++ b/third_party/move/move-binary-format/src/file_format.rs @@ -2698,7 +2698,7 @@ pub enum Bytecode { #[group = "closure"] #[description = r#" - `CallClosure(|t1..tn|r has a)` evalutes a closure of the given function type, + `CallClosure(|t1..tn|r has a)` evaluates a closure of the given function type, taking the captured arguments and mixing in the provided ones on the stack. On top of the stack is the closure being evaluated, underneath the arguments: diff --git a/third_party/move/move-bytecode-verifier/src/check_duplication.rs b/third_party/move/move-bytecode-verifier/src/check_duplication.rs index a42008a92ca..4e13e887695 100644 --- a/third_party/move/move-bytecode-verifier/src/check_duplication.rs +++ b/third_party/move/move-bytecode-verifier/src/check_duplication.rs @@ -271,6 +271,7 @@ impl<'a> DuplicationChecker<'a> { }, StructFieldInformation::DeclaredVariants(variants) => { Self::check_duplicate_variants(variants.iter())?; + // Note: unlike structs, number of fields within a variant can be zero. for variant in variants { Self::check_duplicate_fields(variant.fields.iter())? } diff --git a/third_party/move/move-bytecode-verifier/src/stack_usage_verifier.rs b/third_party/move/move-bytecode-verifier/src/stack_usage_verifier.rs index 4a40ecb3e52..c2735f91bc6 100644 --- a/third_party/move/move-bytecode-verifier/src/stack_usage_verifier.rs +++ b/third_party/move/move-bytecode-verifier/src/stack_usage_verifier.rs @@ -228,42 +228,27 @@ impl<'a> StackUsageVerifier<'a> { (arg_count, return_count) }, - // ClosEval pops the number of arguments and pushes the results of the given function - // type + // `CallClosure` pops the closure and then the number of arguments and + // pushes the results of the given function type Bytecode::CallClosure(idx) => { if let Some(SignatureToken::Function(args, result, _)) = self.resolver.signature_at(*idx).0.first() { ((1 + args.len()) as u64, result.len() as u64) } else { - // We don't know what it will pop/push, but the signature checker + // We don't know what it will pop/push, but the signature checker v2 // ensures we never reach this (0, 0) } }, - // ClosPack pops the captured arguments and returns 1 value - Bytecode::PackClosure(idx, mask) => { - let function_handle = self.resolver.function_handle_at(*idx); - // TODO(#15664): use `captured_count` for efficiency - let arg_count = mask - .extract( - &self.resolver.signature_at(function_handle.parameters).0, - true, - ) - .len() as u64; + // `PackClosure` pops the captured arguments and returns 1 value + Bytecode::PackClosure(_, mask) => { + let arg_count = mask.captured_count() as u64; (arg_count, 1) }, - Bytecode::PackClosureGeneric(idx, mask) => { - let func_inst = self.resolver.function_instantiation_at(*idx); - let function_handle = self.resolver.function_handle_at(func_inst.handle); - // TODO(#15664): use `captured_count` for efficiency - let arg_count = mask - .extract( - &self.resolver.signature_at(function_handle.parameters).0, - true, - ) - .len() as u64; + Bytecode::PackClosureGeneric(_, mask) => { + let arg_count = mask.captured_count() as u64; (arg_count, 1) }, From 3a10e9e871a3d48c99397d08af020cbd6e67ca01 Mon Sep 17 00:00:00 2001 From: Vineeth Kashyap Date: Tue, 1 Jul 2025 11:56:47 -0400 Subject: [PATCH 016/260] [vm] [bytecode-verifier] Fix instantiation loop verifier (#16968) Downstreamed-from: bbc7757e8069dd62f7f9f4419e6a5825434607ef --- .../src/instantiation_loops.rs | 109 ++++++++++++++++-- .../no-recursive-type-check/bug_16939_a.exp | 20 ++++ .../no-recursive-type-check/bug_16939_a.move | 9 ++ .../no-recursive-type-check/bug_16939_b.exp | 20 ++++ .../no-recursive-type-check/bug_16939_b.move | 15 +++ .../transactional-tests/tests/tests.rs | 9 ++ 6 files changed, 173 insertions(+), 9 deletions(-) create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_a.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_a.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_b.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_b.move diff --git a/third_party/move/move-bytecode-verifier/src/instantiation_loops.rs b/third_party/move/move-bytecode-verifier/src/instantiation_loops.rs index 53896c212ee..f621d273ac9 100644 --- a/third_party/move/move-bytecode-verifier/src/instantiation_loops.rs +++ b/third_party/move/move-bytecode-verifier/src/instantiation_loops.rs @@ -217,15 +217,106 @@ impl<'a> InstantiationLoopChecker<'a> { ) { if let Some(code) = &caller_def.code { for instr in &code.code { - if let Bytecode::CallGeneric(callee_inst_idx) = instr { - // Get the id of the definition of the function being called. - // Skip if the function is not defined in the current module, as we do not - // have mutual recursions across module boundaries. - let callee_si = self.module.function_instantiation_at(*callee_inst_idx); - if let Some(callee_idx) = self.func_handle_def_map.get(&callee_si.handle) { - let callee_idx = *callee_idx; - self.build_graph_call(caller_idx, callee_idx, callee_si.type_parameters) - } + match instr { + Bytecode::CallGeneric(callee_inst_idx) + | Bytecode::PackClosureGeneric(callee_inst_idx, _) => { + // Get the id of the definition of the function being called/packed into a closure. + // Skip if the function is not defined in the current module, as we do not + // have mutual recursions across module boundaries. + let callee_si = self.module.function_instantiation_at(*callee_inst_idx); + if let Some(callee_idx) = self.func_handle_def_map.get(&callee_si.handle) { + let callee_idx = *callee_idx; + self.build_graph_call(caller_idx, callee_idx, callee_si.type_parameters) + } + }, + Bytecode::Pop + | Bytecode::Ret + | Bytecode::BrTrue(_) + | Bytecode::BrFalse(_) + | Bytecode::Branch(_) + | Bytecode::LdU8(_) + | Bytecode::LdU16(_) + | Bytecode::LdU32(_) + | Bytecode::LdU64(_) + | Bytecode::LdU128(_) + | Bytecode::LdU256(_) + | Bytecode::LdConst(_) + | Bytecode::LdTrue + | Bytecode::LdFalse + | Bytecode::CopyLoc(_) + | Bytecode::MoveLoc(_) + | Bytecode::StLoc(_) + | Bytecode::FreezeRef + | Bytecode::MutBorrowLoc(_) + | Bytecode::ImmBorrowLoc(_) + | Bytecode::MutBorrowField(_) + | Bytecode::ImmBorrowField(_) + | Bytecode::MutBorrowFieldGeneric(_) + | Bytecode::ImmBorrowFieldGeneric(_) + | Bytecode::Call(_) + | Bytecode::Pack(_) + | Bytecode::Unpack(_) + | Bytecode::ReadRef + | Bytecode::WriteRef + | Bytecode::CastU8 + | Bytecode::CastU16 + | Bytecode::CastU32 + | Bytecode::CastU64 + | Bytecode::CastU128 + | Bytecode::CastU256 + | Bytecode::Add + | Bytecode::Sub + | Bytecode::Mul + | Bytecode::Mod + | Bytecode::Div + | Bytecode::BitOr + | Bytecode::BitAnd + | Bytecode::Xor + | Bytecode::Shl + | Bytecode::Shr + | Bytecode::Or + | Bytecode::And + | Bytecode::Not + | Bytecode::Eq + | Bytecode::Neq + | Bytecode::Lt + | Bytecode::Gt + | Bytecode::Le + | Bytecode::Ge + | Bytecode::Abort + | Bytecode::Nop + | Bytecode::Exists(_) + | Bytecode::ExistsGeneric(_) + | Bytecode::MoveFrom(_) + | Bytecode::MoveFromGeneric(_) + | Bytecode::MoveTo(_) + | Bytecode::MoveToGeneric(_) + | Bytecode::VecPack(_, _) + | Bytecode::VecLen(_) + | Bytecode::VecImmBorrow(_) + | Bytecode::VecMutBorrow(_) + | Bytecode::VecPushBack(_) + | Bytecode::VecPopBack(_) + | Bytecode::VecUnpack(_, _) + | Bytecode::VecSwap(_) + | Bytecode::UnpackGeneric(_) + | Bytecode::PackGeneric(_) + | Bytecode::PackVariant(_) + | Bytecode::UnpackVariant(_) + | Bytecode::PackVariantGeneric(_) + | Bytecode::UnpackVariantGeneric(_) + | Bytecode::TestVariant(_) + | Bytecode::TestVariantGeneric(_) + | Bytecode::MutBorrowVariantField(_) + | Bytecode::MutBorrowVariantFieldGeneric(_) + | Bytecode::ImmBorrowVariantField(_) + | Bytecode::ImmBorrowVariantFieldGeneric(_) + | Bytecode::MutBorrowGlobal(_) + | Bytecode::ImmBorrowGlobal(_) + | Bytecode::MutBorrowGlobalGeneric(_) + | Bytecode::ImmBorrowGlobalGeneric(_) + | Bytecode::PackClosure(_, _) + | Bytecode::CallClosure(_) => {}, } } } diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_a.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_a.exp new file mode 100644 index 00000000000..89cbfba31ef --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_a.exp @@ -0,0 +1,20 @@ +processed 1 task + +task 0 'publish'. lines 1-9: +Error: compilation errors: + bug: bytecode verification failed with unexpected status code `LOOP_IN_INSTANTIATION_GRAPH`: +Error message: edges with constructors: [f0#0 --StructInstantiation(StructHandleIndex(0), [TypeParameter(0)])--> f0#0], nodes: [f0#0] + ┌─ TEMPFILE:2:1 + │ +2 │ ╭ module 0x8675309::M { +3 │ │ struct S { f: T } +4 │ │ fun f() { +5 │ │ let ff = || f>(); +6 │ │ ff(); +7 │ │ } +8 │ │ } + │ ╰─^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) + + diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_a.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_a.move new file mode 100644 index 00000000000..80ffd3c5d2a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_a.move @@ -0,0 +1,9 @@ +//# publish +module 0x8675309::M { + struct S { f: T } + + fun f() { + let ff = || f>(); + ff(); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_b.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_b.exp new file mode 100644 index 00000000000..240e7cb6d87 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_b.exp @@ -0,0 +1,20 @@ +processed 1 task + +task 0 'publish'. lines 1-15: +Error: compilation errors: + bug: bytecode verification failed with unexpected status code `LOOP_IN_INSTANTIATION_GRAPH`: +Error message: edges with constructors: [f1#0 --Function([Reference(TypeParameter(0))], [], )--> f0#0], nodes: [f1#0, f0#0] + ┌─ TEMPFILE:2:1 + │ + 2 │ ╭ module 0xc0ffee::m { + 3 │ │ public fun foo(): || { + 4 │ │ bar<|&T|> + 5 │ │ } + · │ +12 │ │ } +13 │ │ } + │ ╰─^ + │ + = please consider reporting this issue (see https://aptos.dev/en/build/smart-contracts/compiler_v2#reporting-an-issue) + + diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_b.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_b.move new file mode 100644 index 00000000000..923ee795fcc --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-recursive-type-check/bug_16939_b.move @@ -0,0 +1,15 @@ +//# publish +module 0xc0ffee::m { + public fun foo(): || { + bar<|&T|> + } + + fun bar() { + (foo())(); + } + + fun test() { + let f = foo<||>(); + f(); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs b/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs index 534c63dd1b8..d0d05c65d1a 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs @@ -34,6 +34,7 @@ const COMMON_EXCLUSIONS: &[&str] = &[ "/operator_eval/", "/no-recursive-check/", "/no-access-check/", + "/no-recursive-type-check/", ]; /// Note that any config which has different output for a test directory @@ -103,6 +104,14 @@ const TEST_CONFIGS: &[TestConfig] = &[ include: &["/no-access-check/"], exclude: &[], }, + TestConfig { + name: "no-recursive-type-check", + runner: |p| run(p, get_config_by_name("no-recursive-type-check")), + experiments: &[(Experiment::RECURSIVE_TYPE_CHECK, false)], + language_version: LanguageVersion::latest(), + include: &["/no-recursive-type-check/"], + exclude: &[], + }, ]; /// Test files which must use separate baselines because their result From fe924c793ce32bdd31e4e8a39635ef41d3fbfd35 Mon Sep 17 00:00:00 2001 From: Wolfgang Grieskamp Date: Tue, 1 Jul 2025 11:24:30 -0700 Subject: [PATCH 017/260] [vm] Gas charge for PackClosure instructions (#16969) * [vm] Gas charge for PackClosure instructions Logic for charging gas when packing closures, as well as new gas parameters. * Addressing reviewer comments * Addressing reviewer comments. * Fixing AbstractValueSizeGasParams key dup error Downstreamed-from: 8ea5ffe6004c94b94561f7cd266989cd58093a87 --- aptos-move/aptos-gas-meter/src/meter.rs | 18 +++++++++++++ .../aptos-gas-profiling/src/profiler.rs | 7 +++++ .../src/gas_schedule/instr.rs | 9 ++++++- .../src/gas_schedule/misc.rs | 26 ++++++++----------- .../aptos-memory-usage-tracker/src/lib.rs | 17 ++++++++++++ .../move/move-vm/runtime/src/interpreter.rs | 16 ++++++++++++ .../move-vm/test-utils/src/gas_schedule.rs | 18 +++++++++++++ third_party/move/move-vm/types/src/gas.rs | 14 ++++++++++ 8 files changed, 109 insertions(+), 16 deletions(-) diff --git a/aptos-move/aptos-gas-meter/src/meter.rs b/aptos-move/aptos-gas-meter/src/meter.rs index 379a2d39108..8ed5e366415 100644 --- a/aptos-move/aptos-gas-meter/src/meter.rs +++ b/aptos-move/aptos-gas-meter/src/meter.rs @@ -339,6 +339,24 @@ where } } + #[inline] + fn charge_pack_closure( + &mut self, + is_generic: bool, + args: impl ExactSizeIterator, + ) -> PartialVMResult<()> { + let num_args = NumArgs::new(args.len() as u64); + + match is_generic { + false => self + .algebra + .charge_execution(PACK_CLOSURE_BASE + PACK_CLOSURE_PER_ARG * num_args), + true => self.algebra.charge_execution( + PACK_CLOSURE_GENERIC_BASE + PACK_CLOSURE_GENERIC_PER_ARG * num_args, + ), + } + } + #[inline] fn charge_read_ref(&mut self, val: impl ValueView) -> PartialVMResult<()> { let (stack_size, heap_size) = self diff --git a/aptos-move/aptos-gas-profiling/src/profiler.rs b/aptos-move/aptos-gas-profiling/src/profiler.rs index 87433532c79..3ee2b7ac684 100644 --- a/aptos-move/aptos-gas-profiling/src/profiler.rs +++ b/aptos-move/aptos-gas-profiling/src/profiler.rs @@ -267,6 +267,13 @@ where args: impl ExactSizeIterator + Clone, ) -> PartialVMResult<()>; + [PACK_CLOSURE] + fn charge_pack_closure( + &mut self, + is_generic: bool, + args: impl ExactSizeIterator + Clone, + ) -> PartialVMResult<()>; + [READ_REF] fn charge_read_ref(&mut self, val: impl ValueView) -> PartialVMResult<()>; diff --git a/aptos-move/aptos-gas-schedule/src/gas_schedule/instr.rs b/aptos-move/aptos-gas-schedule/src/gas_schedule/instr.rs index 1e7f1a48601..204015314c0 100644 --- a/aptos-move/aptos-gas-schedule/src/gas_schedule/instr.rs +++ b/aptos-move/aptos-gas-schedule/src/gas_schedule/instr.rs @@ -3,7 +3,10 @@ //! This module defines the gas parameters for all Move instructions. -use crate::{gas_feature_versions::RELEASE_V1_18, gas_schedule::VMGasParameters}; +use crate::{ + gas_feature_versions::{RELEASE_V1_18, RELEASE_V1_33}, + gas_schedule::VMGasParameters, +}; use aptos_gas_algebra::{ InternalGas, InternalGasPerAbstractValueUnit, InternalGasPerArg, InternalGasPerByte, InternalGasPerTypeNode, @@ -82,6 +85,10 @@ crate::gas_schedule::macros::define_gas_parameters!( [unpack_per_field: InternalGasPerArg, "unpack.per_field", 147], [unpack_generic_base: InternalGas, "unpack_generic.base", 808], [unpack_generic_per_field: InternalGasPerArg, "unpack_generic.per_field", 147], + [pack_closure_base: InternalGas, { RELEASE_V1_33.. => "pack_closure.base" }, 908], + [pack_closure_per_arg: InternalGasPerArg, { RELEASE_V1_33.. => "pack.closure.per_arg" }, 147], + [pack_closure_generic_base: InternalGas, { RELEASE_V1_33.. => "pack_closure_generic.base" }, 908], + [pack_closure_generic_per_arg: InternalGasPerArg, { RELEASE_V1_33.. => "pack_closure_generic.per_arg" }, 147], // ref [read_ref_base: InternalGas, "read_ref.base", 735], [read_ref_per_abs_val_unit: InternalGasPerAbstractValueUnit, "read_ref.per_abs_val_unit", 14], diff --git a/aptos-move/aptos-gas-schedule/src/gas_schedule/misc.rs b/aptos-move/aptos-gas-schedule/src/gas_schedule/misc.rs index 85ca134042b..8ac72a247fb 100644 --- a/aptos-move/aptos-gas-schedule/src/gas_schedule/misc.rs +++ b/aptos-move/aptos-gas-schedule/src/gas_schedule/misc.rs @@ -7,6 +7,7 @@ use crate::{ gas_schedule::VMGasParameters, traits::{FromOnChainGasSchedule, InitialGasSchedule, ToOnChainGasSchedule}, + ver::gas_feature_versions::RELEASE_V1_33, }; use aptos_gas_algebra::{AbstractValueSize, AbstractValueSizePerArg}; use move_core_types::{ @@ -35,6 +36,7 @@ crate::gas_schedule::macros::define_gas_parameters!( [bool: AbstractValueSize, "bool", 40], [address: AbstractValueSize, "address", 40], [struct_: AbstractValueSize, "struct", 40], + [closure: AbstractValueSize, { RELEASE_V1_33.. => "closure" }, 40], [vector: AbstractValueSize, "vector", 40], [reference: AbstractValueSize, "reference", 40], [per_u8_packed: AbstractValueSizePerArg, "per_u8_packed", 1], @@ -249,11 +251,9 @@ impl ValueVisitor for AbstractValueSizeVisitor<'_> { } #[inline] - fn visit_closure(&mut self, depth: u64, _len: usize) -> PartialVMResult { - self.check_depth(depth)?; - // TODO(#15664): introduce a dedicated gas parameter? - self.size += self.params.struct_; - Ok(true) + fn visit_closure(&mut self, _depth: usize, _len: usize) -> bool { + self.size += self.params.closure; + true } #[inline] @@ -464,11 +464,9 @@ impl AbstractValueSizeGasParameters { } #[inline] - fn visit_closure(&mut self, depth: u64, _len: usize) -> PartialVMResult { - self.check_depth(depth)?; - // TODO(#15664): introduce a dedicated gas parameter? - self.res = Some(self.params.struct_); - Ok(false) + fn visit_closure(&mut self, _depth: usize, _len: usize) -> bool { + self.res = Some(self.params.closure); + false } #[inline] @@ -655,11 +653,9 @@ impl AbstractValueSizeGasParameters { } #[inline] - fn visit_closure(&mut self, depth: u64, _len: usize) -> PartialVMResult { - self.check_depth(depth)?; - // TODO(#15664): introduce a dedicated gas parameter? - self.res = Some(self.params.struct_); - Ok(false) + fn visit_closure(&mut self, _depth: usize, _len: usize) -> bool { + self.res = Some(self.params.closure); + false } #[inline] diff --git a/aptos-move/aptos-memory-usage-tracker/src/lib.rs b/aptos-move/aptos-memory-usage-tracker/src/lib.rs index d8e4adb74b4..9981f1167ab 100644 --- a/aptos-move/aptos-memory-usage-tracker/src/lib.rs +++ b/aptos-move/aptos-memory-usage-tracker/src/lib.rs @@ -368,6 +368,23 @@ where self.base.charge_unpack(is_generic, args) } + #[inline] + fn charge_pack_closure( + &mut self, + is_generic: bool, + args: impl ExactSizeIterator + Clone, + ) -> PartialVMResult<()> { + self.use_heap_memory(args.clone().fold(AbstractValueSize::zero(), |acc, val| { + acc + self + .vm_gas_params() + .misc + .abs_val + .abstract_stack_size(val, self.feature_version()) + }))?; + + self.base.charge_pack_closure(is_generic, args) + } + #[inline] fn charge_read_ref(&mut self, val: impl ValueView) -> PartialVMResult<()> { let heap_size = self diff --git a/third_party/move/move-vm/runtime/src/interpreter.rs b/third_party/move/move-vm/runtime/src/interpreter.rs index 30c5c857944..ea88f4f0548 100644 --- a/third_party/move/move-vm/runtime/src/interpreter.rs +++ b/third_party/move/move-vm/runtime/src/interpreter.rs @@ -2245,6 +2245,13 @@ impl Frame { .push(reference.test_variant(info.variant)?)?; }, Bytecode::PackClosure(fh_idx, mask) => { + gas_meter.charge_pack_closure( + false, + interpreter + .operand_stack + .last_n(mask.captured_count() as usize)?, + )?; + let function = self .build_loaded_function_from_handle_and_ty_args( module_storage, @@ -2252,6 +2259,7 @@ impl Frame { vec![], ) .map(Rc::new)?; + let captured = interpreter.operand_stack.popn(mask.captured_count())?; let lazy_function = LazyLoadedFunction::new_resolved( module_storage.runtime_environment(), @@ -2272,6 +2280,13 @@ impl Frame { } }, Bytecode::PackClosureGeneric(fi_idx, mask) => { + gas_meter.charge_pack_closure( + true, + interpreter + .operand_stack + .last_n(mask.captured_count() as usize)?, + )?; + let ty_args = self.instantiate_generic_function(Some(gas_meter), *fi_idx)?; let function = self @@ -2281,6 +2296,7 @@ impl Frame { ty_args, ) .map(Rc::new)?; + let captured = interpreter.operand_stack.popn(mask.captured_count())?; let lazy_function = LazyLoadedFunction::new_resolved( module_storage.runtime_environment(), diff --git a/third_party/move/move-vm/test-utils/src/gas_schedule.rs b/third_party/move/move-vm/test-utils/src/gas_schedule.rs index f841ce6fbec..3cdc79c7dc0 100644 --- a/third_party/move/move-vm/test-utils/src/gas_schedule.rs +++ b/third_party/move/move-vm/test-utils/src/gas_schedule.rs @@ -346,6 +346,24 @@ impl GasMeter for GasStatus { ) } + fn charge_pack_closure( + &mut self, + is_generic: bool, + args: impl ExactSizeIterator, + ) -> PartialVMResult<()> { + let field_count = AbstractMemorySize::new(args.len() as u64); + self.charge_instr_with_size( + if is_generic { + Opcodes::PACK_CLOSURE_GENERIC + } else { + Opcodes::PACK_CLOSURE + }, + args.fold(field_count, |acc, val| { + acc + val.legacy_abstract_memory_size() + }), + ) + } + fn charge_read_ref(&mut self, ref_val: impl ValueView) -> PartialVMResult<()> { self.charge_instr_with_size(Opcodes::READ_REF, ref_val.legacy_abstract_memory_size()) } diff --git a/third_party/move/move-vm/types/src/gas.rs b/third_party/move/move-vm/types/src/gas.rs index 48789f7123c..a22044defa8 100644 --- a/third_party/move/move-vm/types/src/gas.rs +++ b/third_party/move/move-vm/types/src/gas.rs @@ -240,6 +240,12 @@ pub trait GasMeter: NativeGasMeter { self.charge_unpack(is_generic, args) } + fn charge_pack_closure( + &mut self, + is_generic: bool, + args: impl ExactSizeIterator + Clone, + ) -> PartialVMResult<()>; + fn charge_read_ref(&mut self, val: impl ValueView) -> PartialVMResult<()>; fn charge_write_ref( @@ -475,6 +481,14 @@ impl GasMeter for UnmeteredGasMeter { Ok(()) } + fn charge_pack_closure( + &mut self, + _is_generic: bool, + _args: impl ExactSizeIterator, + ) -> PartialVMResult<()> { + Ok(()) + } + fn charge_read_ref(&mut self, _val: impl ValueView) -> PartialVMResult<()> { Ok(()) } From ea00c7f0e447bc6e278fdda780b39fb21273c441 Mon Sep 17 00:00:00 2001 From: Vineeth Kashyap Date: Tue, 1 Jul 2025 17:23:02 -0400 Subject: [PATCH 018/260] [compiler-v2] Script functions cannot be called from Move code (#16953) Downstreamed-from: 165809fbc93899ae51edd1ee6558b024b570d1f6 --- .../src/env_pipeline/function_checker.rs | 19 +++++++++++++++++++ .../lambda/script_uses_itself.exp | 15 +++++++++++++++ .../lambda/script_uses_itself.move | 8 ++++++++ 3 files changed, 42 insertions(+) create mode 100644 third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/script_uses_itself.exp create mode 100644 third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/script_uses_itself.move diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/function_checker.rs b/third_party/move/move-compiler-v2/src/env_pipeline/function_checker.rs index 66655238318..1d99fc2bc5d 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/function_checker.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/function_checker.rs @@ -482,6 +482,12 @@ pub fn check_access_and_use(env: &mut GlobalEnv, before_inlining: bool) { let callees_with_sites = def.used_funs_with_uses(); for (callee, sites) in &callees_with_sites { let callee_func = env.get_function(*callee); + + // Script functions cannot be called. + if callee_func.module_env.is_script_module() { + calling_script_function_error(env, sites, &callee_func); + } + // Check visibility. // Same module is always visible @@ -837,3 +843,16 @@ fn call_package_fun_from_diff_addr_error( let why = "they are from different addresses"; cannot_call_error(env, why, sites, caller, callee); } + +fn calling_script_function_error(env: &GlobalEnv, sites: &BTreeSet, callee: &FunctionEnv) { + let call_details: Vec<_> = sites + .iter() + .map(|node_id| (env.get_node_loc(*node_id), "used here".to_owned())) + .collect(); + let callee_name = callee.get_name_str(); + let msg = format!( + "script function `{}` cannot be used in Move code", + callee_name + ); + env.diag_with_labels(Severity::Error, &callee.get_id_loc(), &msg, call_details); +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/script_uses_itself.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/script_uses_itself.exp new file mode 100644 index 00000000000..67a2a4ef1fe --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/script_uses_itself.exp @@ -0,0 +1,15 @@ + +Diagnostics: +error: script function `main` cannot be used in Move code + ┌─ tests/checking-lang-v2.2/lambda/script_uses_itself.move:2:9 + │ +2 │ fun main() { + │ ^^^^ +3 │ let _f: || has drop = main; + │ ---- used here +4 │ let _g: || has drop = || main(); + │ ------ used here +5 │ (main)(); + │ ---- used here +6 │ main(); + │ ------ used here diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/script_uses_itself.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/script_uses_itself.move new file mode 100644 index 00000000000..4b1ae54904b --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/script_uses_itself.move @@ -0,0 +1,8 @@ +script { + fun main() { + let _f: || has drop = main; + let _g: || has drop = || main(); + (main)(); + main(); + } +} From 83039856f108efbd2319f3d587362cb4749c4d8e Mon Sep 17 00:00:00 2001 From: Vineeth Kashyap Date: Tue, 1 Jul 2025 17:23:12 -0400 Subject: [PATCH 019/260] [compiler-v2] Fix scoping issues with lambda lifting (#16965) Downstreamed-from: 4464bcdecac802badbd385ce333c684d5f2213a0 --- .../src/bytecode_generator.rs | 11 +- .../src/env_pipeline/lambda_lifter.rs | 66 +++++++-- .../no-v1-comparison/closures/bug_16954.exp | 34 +++++ .../no-v1-comparison/closures/bug_16954.move | 135 ++++++++++++++++++ 4 files changed, 231 insertions(+), 15 deletions(-) create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16954.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16954.move diff --git a/third_party/move/move-compiler-v2/src/bytecode_generator.rs b/third_party/move/move-compiler-v2/src/bytecode_generator.rs index 3e3982fdfbd..f1379c34038 100644 --- a/third_party/move/move-compiler-v2/src/bytecode_generator.rs +++ b/third_party/move/move-compiler-v2/src/bytecode_generator.rs @@ -2,7 +2,7 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use crate::Options; +use crate::{Options, COMPILER_BUG_REPORT_MSG}; use codespan_reporting::diagnostic::Severity; use ethnum::U256; use itertools::Itertools; @@ -317,7 +317,14 @@ impl<'env> Generator<'env> { /// Report an (internal) error at the location associated with the node. fn internal_error(&self, id: NodeId, msg: impl AsRef) { - self.diag(id, Severity::Bug, msg) + let env = self.env(); + let loc = env.get_node_loc(id); + env.diag_with_notes( + Severity::Bug, + loc.as_ref(), + &format!("compiler internal error: {}", msg.as_ref()), + vec![COMPILER_BUG_REPORT_MSG.to_string()], + ); } fn diag(&self, id: NodeId, severity: Severity, msg: impl AsRef) { diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/lambda_lifter.rs b/third_party/move/move-compiler-v2/src/env_pipeline/lambda_lifter.rs index 58333b037ac..d55c782ce96 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/lambda_lifter.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/lambda_lifter.rs @@ -174,7 +174,7 @@ pub struct LambdaLifter<'a> { } struct VarInfo { - /// The node were this variable was found. + /// The node where this variable was found. node_id: NodeId, /// Whether the variable is modified modified: bool, @@ -462,6 +462,53 @@ impl<'a> LambdaLifter<'a> { | Loop(..) | LoopCont(..) | Assign(..) | Mutate(..) | SpecBlock(..) => false, } } + + fn is_symbol_in_scope(&self, sym: &Symbol) -> bool { + self.scopes.iter().any(|scope| scope.contains(sym)) + } + + /// Insert `sym` as a free local variable, if it is not already in scope. + fn try_insert_free_local(&mut self, sym: Symbol, var_info: VarInfo) { + if !self.is_symbol_in_scope(&sym) { + if var_info.modified { + // Make sure we mark the variable as modified. + self.free_locals.insert(sym, var_info); + } else { + self.free_locals.entry(sym).or_insert(var_info); + } + } + } + + /// Perform a rewrite action in an isolated context. + /// To do so, we save the current context (free parameters, free locals, and scopes), + /// perform the rewrite action, and then restore the context. + fn rewrite_with_isolated_context(&mut self, rewrite: F, exp: Exp) -> Exp + where + F: FnOnce(&mut Self, Exp) -> Exp, + { + // Save the current context. + let mut curr_free_params = mem::take(&mut self.free_params); + let mut curr_free_locals = mem::take(&mut self.free_locals); + let curr_scopes = mem::take(&mut self.scopes); + // Perform the rewrite action. + let result = rewrite(self, exp); + // Restore the context. + self.scopes = curr_scopes; + // Remove free vars present in the re-instated scope. + let to_remove = self + .free_locals + .keys() + .filter(|sym| self.is_symbol_in_scope(sym)) + .copied() + .collect::>(); + for sym in to_remove { + self.free_locals.remove(&sym); + } + self.free_locals.append(&mut curr_free_locals); + self.free_params.append(&mut curr_free_params); + // Return the result of the rewrite. + result + } } impl ExpRewriterFunctions for LambdaLifter<'_> { @@ -483,12 +530,7 @@ impl ExpRewriterFunctions for LambdaLifter<'_> { // Also if this is a lambda, before descent, clear any usages from siblings in the // context, so we get the isolated usage information for the lambda's body. if matches!(exp.as_ref(), ExpData::Lambda(..)) { - let mut curr_free_params = mem::take(&mut self.free_params); - let mut curr_free_locals = mem::take(&mut self.free_locals); - let result = self.rewrite_exp_descent(exp); - self.free_params.append(&mut curr_free_params); - self.free_locals.append(&mut curr_free_locals); - result + self.rewrite_with_isolated_context(ExpRewriterFunctions::rewrite_exp_descent, exp) } else { self.rewrite_exp_descent(exp) } @@ -504,14 +546,12 @@ impl ExpRewriterFunctions for LambdaLifter<'_> { } fn rewrite_exit_scope(&mut self, _id: NodeId) { - let exiting = self.scopes.pop().expect("stack balanced"); - // Remove all locals which are bound in the scope we are exiting. - self.free_locals.retain(|name, _| !exiting.contains(name)); + self.scopes.pop().expect("stack balanced"); } fn rewrite_local_var(&mut self, node_id: NodeId, sym: Symbol) -> Option { // duplicates are OK -- they are all the same local at different locations - self.free_locals.entry(sym).or_insert(VarInfo { + self.try_insert_free_local(sym, VarInfo { node_id, modified: false, }); @@ -529,7 +569,7 @@ impl ExpRewriterFunctions for LambdaLifter<'_> { fn rewrite_assign(&mut self, _node_id: NodeId, lhs: &Pattern, _rhs: &Exp) -> Option { for (node_id, name) in lhs.vars() { - self.free_locals.insert(name, VarInfo { + self.try_insert_free_local(name, VarInfo { node_id, modified: true, }); @@ -541,7 +581,7 @@ impl ExpRewriterFunctions for LambdaLifter<'_> { if matches!(oper, Operation::Borrow(ReferenceKind::Mutable)) { match args[0].as_ref() { ExpData::LocalVar(node_id, name) => { - self.free_locals.insert(*name, VarInfo { + self.try_insert_free_local(*name, VarInfo { node_id: *node_id, modified: true, }); diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16954.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16954.exp new file mode 100644 index 00000000000..5e4f6bdcd04 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16954.exp @@ -0,0 +1,34 @@ +processed 12 tasks + +task 1 'run'. lines 115-115: +return values: 44 + +task 2 'run'. lines 117-117: +return values: 1 + +task 3 'run'. lines 119-119: +return values: 1 + +task 4 'run'. lines 121-121: +return values: 43 + +task 5 'run'. lines 123-123: +return values: 10 + +task 6 'run'. lines 125-125: +return values: 17 + +task 7 'run'. lines 127-127: +return values: 9 + +task 8 'run'. lines 129-129: +return values: 6 + +task 9 'run'. lines 131-131: +return values: 4 + +task 10 'run'. lines 133-133: +return values: 5 + +task 11 'run'. lines 135-135: +return values: 4 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16954.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16954.move new file mode 100644 index 00000000000..33e281801dc --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16954.move @@ -0,0 +1,135 @@ +//# publish +module 0xc0ffee::m { + public fun test1(): u8 { + let x = 1; + let f = |y: u8| { + let x = x + y; // x: 8 + let f = |y: u8| { + let x = y + x; // x: 11 + x + }; + f(3) * { + let f = |y: u8| { + let x = x - y; // x: 4 + x + }; + f(4) + } + }; + f(7) + } + + public fun test2(): u64 { + let x = 1; + let f = || || x; + f()() + } + + public fun test3(): u64 { + let x = 1; + let f = |x| { + (|x| x - 1)(x + 1) + }; + f(x) + } + + public fun test4(x: u64): u64 { + let f = || || { + let x = x + 1; + x + }; + f()() + } + + public fun test5(): u8 { + let x: u8 = 2; + let f = |x: u8| { // shadows outer `x` + let g = || { x + 1 }; // captures the *parameter* `x` + g() + }; + f(7) + x + } + + public fun test6(): u64 { + let x: u64 = 5; + let f = |y: u64| { + let x = y + 1; + let g = || { + let y = x + 1; + y + }; + g() + }; + f(10) + x + } + + public fun test7(): u8 { + let x: u8 = 3; + let f = |x: u8| { // shadows outer `x` + let x = x + 2; // shadows parameter `x` + let g = |y: u8| x + y; // captures second‑shadow `x` + g(4) // (3 + 2) + 4 + }; + f(x) + } + + public fun test8(): u64 { + let x: u64 = 1; + let f = || { + let x = 2; // shadows outermost + let g = || { + let x = 3; // shadows again + x // 3 + }; + g() + x // 3 + 2 + }; + f() + x // 5 + 1 + } + + public fun test9(): u8 { + let x: u8 = 10; + let f = |x: u8| { + let h = |x: u8| x; // yet another shadow + h(x) // returns the parameter `x` + }; + f(4) + (x - 10) // (4) + 0 + } + + public fun test10(): u8 { + let x: u8 = 2; + let f = |y: u8| y + x; // captures the first `x` + let x: u8 = 5; // new shadow of `x` + f(3) + (x - 5) // (3 + 2) + 0 + } + + fun call(f: ||u64): u64 { + f() + } + + public fun test11(): u64 { + let x = 1; + x + call(|| x + 2) + call(|| x - 1) + } +} + +//# run 0xc0ffee::m::test1 + +//# run 0xc0ffee::m::test2 + +//# run 0xc0ffee::m::test3 + +//# run 0xc0ffee::m::test4 --args 42 + +//# run 0xc0ffee::m::test5 + +//# run 0xc0ffee::m::test6 + +//# run 0xc0ffee::m::test7 + +//# run 0xc0ffee::m::test8 + +//# run 0xc0ffee::m::test9 + +//# run 0xc0ffee::m::test10 + +//# run 0xc0ffee::m::test11 From 04121535c7e76fac9143333f8be385fcd9729906 Mon Sep 17 00:00:00 2001 From: Vineeth Kashyap Date: Tue, 1 Jul 2025 18:23:45 -0400 Subject: [PATCH 020/260] [tests] Vector assignability tests (#16828) Downstreamed-from: c5d897cf67fb86cc70f02bd36f5d77f75cd8989d --- aptos-move/e2e-move-tests/src/tests/mod.rs | 1 + .../src/tests/swap_function_values.rs | 57 +++++++++++++ .../lambda/vector_assignability.exp | 31 +++++++ .../lambda/vector_assignability.move | 82 +++++++++++++++++++ 4 files changed, 171 insertions(+) create mode 100644 aptos-move/e2e-move-tests/src/tests/swap_function_values.rs create mode 100644 third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/vector_assignability.exp create mode 100644 third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/vector_assignability.move diff --git a/aptos-move/e2e-move-tests/src/tests/mod.rs b/aptos-move/e2e-move-tests/src/tests/mod.rs index fa60de62e35..be0b06ec3b9 100644 --- a/aptos-move/e2e-move-tests/src/tests/mod.rs +++ b/aptos-move/e2e-move-tests/src/tests/mod.rs @@ -59,6 +59,7 @@ mod stake; mod state_metadata; mod storage_refund; mod string_args; +mod swap_function_values; mod test_self; mod token_event_store; mod token_objects; diff --git a/aptos-move/e2e-move-tests/src/tests/swap_function_values.rs b/aptos-move/e2e-move-tests/src/tests/swap_function_values.rs new file mode 100644 index 00000000000..9bab1e2174e --- /dev/null +++ b/aptos-move/e2e-move-tests/src/tests/swap_function_values.rs @@ -0,0 +1,57 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Test swapping of function values via vector::replace. + +use crate::{assert_success, tests::common, MoveHarness}; +use aptos_framework::BuildOptions; +use aptos_package_builder::PackageBuilder; +use aptos_types::account_address::AccountAddress; + +#[test] +fn swap_function_values() { + let mut builder = PackageBuilder::new("swap_function_values"); + let source = r#" + module 0xc0ffee::m { + + struct NoCopy; + + entry fun test() { + let nc = NoCopy; + + let f1 = || { + let NoCopy = nc; + 42 + }; + let f2 = || 44; + let v = vector[f2]; + let f3 = v.replace(0, f1); + assert!(f3() == 44, 0); + let f4 = v.pop_back(); + assert!(f4() == 42, 1); + v.destroy_empty(); + } + } + "#; + builder.add_source("swap_function_values.move", source); + builder.add_local_dep( + "AptosStdlib", + &common::framework_dir_path("aptos-stdlib").to_string_lossy(), + ); + let path = builder.write_to_temp().unwrap(); + + let mut h = MoveHarness::new(); + let acc = h.new_account_at(AccountAddress::from_hex_literal("0xc0ffee").unwrap()); + assert_success!(h.publish_package_with_options( + &acc, + path.path(), + BuildOptions::move_2().set_latest_language() + )); + + assert_success!(h.run_entry_function( + &acc, + str::parse("0xc0ffee::m::test").unwrap(), + vec![], + vec![], + )); +} diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/vector_assignability.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/vector_assignability.exp new file mode 100644 index 00000000000..7aa9b6bd102 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/vector_assignability.exp @@ -0,0 +1,31 @@ + +Diagnostics: +error: type `||u64 has drop` is missing required ability `copy` + ┌─ tests/checking-lang-v2.2/lambda/vector_assignability.move:12:55 + │ +12 │ let b: vector<||u64 has drop + copy> = vector[a]; + │ ^ + +error: expected `vector<||u64 has drop>` but found a value of type `vector<||u64 has copy + drop>` + ┌─ tests/checking-lang-v2.2/lambda/vector_assignability.move:33:9 + │ +33 │ v[0] = a; + │ ^ + +error: type `||u64 has drop` is missing required ability `copy` + ┌─ tests/checking-lang-v2.2/lambda/vector_assignability.move:55:28 + │ +55 │ replace(&mut v[0], a); + │ ^ + +error: expected `vector<||u64 has copy + drop>` but found a value of type `vector<||u64 has drop>` + ┌─ tests/checking-lang-v2.2/lambda/vector_assignability.move:66:9 + │ +66 │ v[0] = a; + │ ^ + +error: cannot pass `&mut ||u64 has drop` to a function which expects argument of type `&mut ||u64 has copy + drop` + ┌─ tests/checking-lang-v2.2/lambda/vector_assignability.move:80:22 + │ +80 │ swap(&mut a, &mut b); + │ ^^^^^^ diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/vector_assignability.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/vector_assignability.move new file mode 100644 index 00000000000..424c6c2baf1 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/vector_assignability.move @@ -0,0 +1,82 @@ +module 0xc0ffee::m { + struct NoCopy has drop; + + public fun foo() { + let x = NoCopy; + + let a: ||u64 has drop = ||{ + let NoCopy = x; + 1 + }; + + let b: vector<||u64 has drop + copy> = vector[a]; + (b[0])(); + (b[0])(); + } +} + +module 0xc0ffee::n { + struct NoCopy has drop; + + public fun foo() { + let x = NoCopy; + + let a: ||u64 has drop = ||{ + let NoCopy = x; + 1 + }; + + let b: ||u64 has copy + drop = || 42; + + let v = vector[b]; + (v[0])(); + v[0] = a; + } +} + +module 0xc0ffee::o { + struct NoCopy has drop; + + fun replace(ref: &mut T, new: T): T { + abort 0 + } + + public fun foo() { + let x = NoCopy; + + let a: ||u64 has drop = ||{ + let NoCopy = x; + 1 + }; + + let b: ||u64 has copy + drop = || 42; + + let v = vector[b]; + replace(&mut v[0], a); + } +} + +module 0xc0ffee::p { + public fun foo() { + let a: ||u64 has copy + drop = || 1; + + let b: ||u64 has drop = || 42; + + let v = vector[b]; + v[0] = a; + v[0](); + } +} + +module 0xc0ffee::q { + fun swap(left: &mut T, right: &mut T) { + abort 0 + } + + public fun foo() { + let a: ||u64 has copy + drop = || 1; + let b: ||u64 has drop = || 42; + + swap(&mut a, &mut b); + } +} From 42007ccdd89097e8d966d6329ba916deb4ff3676 Mon Sep 17 00:00:00 2001 From: George Mitenkov Date: Wed, 2 Jul 2025 01:41:30 +0100 Subject: [PATCH 021/260] [vm] Function values always have module ID (#16978) Downstreamed-from: 4f2c240295851f0d826e705319b81382217f1611 --- third_party/move/move-vm/runtime/src/interpreter.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/third_party/move/move-vm/runtime/src/interpreter.rs b/third_party/move/move-vm/runtime/src/interpreter.rs index ea88f4f0548..ee56d8e7c07 100644 --- a/third_party/move/move-vm/runtime/src/interpreter.rs +++ b/third_party/move/move-vm/runtime/src/interpreter.rs @@ -576,9 +576,12 @@ where let module_id = lazy_function.with_name_and_ty_args( |module_opt, _func_name, ty_arg_tags| { let Some(module_id) = module_opt else { - // TODO(#15664): currently we need the module id for gas charging - // of calls, so we can't proceed here without one. But we want - // to be able to let scripts use closures. + // Note: + // Module ID of a function should always exist because functions + // are defined in modules. The only way to have `None` here is + // when function is a script entrypoint. Note that in this case, + // entrypoint function cannot be packed as a closure, nor there + // can be any lambda-lifting in the script. let err = PartialVMError::new_invariant_violation(format!( "module id required to charge gas for function `{}`", lazy_function.to_canonical_string() From 33c7951ef7303e91d79ed9f4109b6b22561dbf34 Mon Sep 17 00:00:00 2001 From: George Mitenkov Date: Wed, 2 Jul 2025 01:57:33 +0100 Subject: [PATCH 022/260] [lazy-loading] Propagate context to check at serialization time (#16576) - Function values cannot capture aggregators: added a special error code - Layouts for storable closures constructed at pack time Downstreamed-from: 52f1a926e30706bf7a86acac00688e0ecba1e2a4 --- aptos-move/aptos-vm/src/aptos_vm.rs | 87 +++++++- .../function_values/sources/capturing.move | 11 +- .../tests/aggregator_v2_function_values.rs | 48 +---- .../tests/bcs.data/function-values/Move.toml | 6 + .../sources/bcs_function_values_test.move | 81 +++++++ aptos-move/e2e-move-tests/src/tests/bcs.rs | 70 ++++++ aptos-move/e2e-move-tests/src/tests/mod.rs | 2 + .../tests/string_utils.data/pack/Move.toml | 6 + .../string_utils.data/pack/scripts/main.move | 11 + .../pack/sources/string_utils_test.move | 88 ++++++++ .../e2e-move-tests/src/tests/string_utils.rs | 54 +++++ aptos-move/e2e-tests/src/executor.rs | 13 +- .../framework/src/natives/string_utils.rs | 84 ++++++-- aptos-move/vm-genesis/src/lib.rs | 202 ++++++++++++++---- .../no-v1-comparison/closures/misc_1.exp | 14 +- .../no-v1-comparison/closures/misc_1.move | 29 ++- .../move/move-core/types/src/vm_status.rs | 13 +- .../move/move-vm/runtime/src/interpreter.rs | 73 +++++-- .../move-vm/runtime/src/loader/function.rs | 114 ++++++++-- .../move-vm/runtime/src/module_traversal.rs | 47 +++- .../move-vm/runtime/src/native_functions.rs | 85 +++++++- .../runtime/src/storage/loader/lazy.rs | 9 +- .../runtime/src/storage/module_storage.rs | 51 ++--- .../tests/display/print_values.exp | 50 +++-- .../tests/display/print_values.move | 5 +- third_party/move/move-vm/types/src/gas.rs | 2 + .../move/move-vm/types/src/value_serde.rs | 26 +-- 27 files changed, 1021 insertions(+), 260 deletions(-) create mode 100644 aptos-move/e2e-move-tests/src/tests/bcs.data/function-values/Move.toml create mode 100644 aptos-move/e2e-move-tests/src/tests/bcs.data/function-values/sources/bcs_function_values_test.move create mode 100644 aptos-move/e2e-move-tests/src/tests/bcs.rs create mode 100644 aptos-move/e2e-move-tests/src/tests/string_utils.data/pack/Move.toml create mode 100644 aptos-move/e2e-move-tests/src/tests/string_utils.data/pack/scripts/main.move create mode 100644 aptos-move/e2e-move-tests/src/tests/string_utils.data/pack/sources/string_utils_test.move create mode 100644 aptos-move/e2e-move-tests/src/tests/string_utils.rs diff --git a/aptos-move/aptos-vm/src/aptos_vm.rs b/aptos-move/aptos-vm/src/aptos_vm.rs index 209c2914956..ade2b4b2ba7 100644 --- a/aptos-move/aptos-vm/src/aptos_vm.rs +++ b/aptos-move/aptos-vm/src/aptos_vm.rs @@ -2210,7 +2210,9 @@ impl AptosVM { &block_metadata.get_prologue_move_args(account_config::reserved_vm_address()), ); - let storage = TraversalStorage::new(); + let traversal_storage = TraversalStorage::new(); + let mut traversal_context = TraversalContext::new(&traversal_storage); + session .execute_function_bypass_visibility( &BLOCK_MODULE, @@ -2218,7 +2220,7 @@ impl AptosVM { vec![], args, &mut gas_meter, - &mut TraversalContext::new(&storage), + &mut traversal_context, module_storage, ) .map(|_return_vals| ()) @@ -2291,7 +2293,8 @@ impl AptosVM { .as_move_value(), ]; - let storage = TraversalStorage::new(); + let traversal_storage = TraversalStorage::new(); + let mut traversal_context = TraversalContext::new(&traversal_storage); session .execute_function_bypass_visibility( @@ -2300,7 +2303,7 @@ impl AptosVM { vec![], serialize_values(&args), &mut gas_meter, - &mut TraversalContext::new(&storage), + &mut traversal_context, module_storage, ) .map(|_return_vals| ()) @@ -2317,6 +2320,82 @@ impl AptosVM { Ok((VMStatus::Executed, output)) } + fn process_block_epilogue( + &self, + resolver: &impl AptosMoveResolver, + module_storage: &impl AptosModuleStorage, + block_epilogue: BlockEpiloguePayload, + log_context: &AdapterLogSchema, + ) -> Result<(VMStatus, VMOutput), VMStatus> { + let (block_id, fee_distribution) = match block_epilogue { + BlockEpiloguePayload::V0 { .. } => { + let status = TransactionStatus::Keep(ExecutionStatus::Success); + let output = VMOutput::empty_with_status(status); + return Ok((VMStatus::Executed, output)); + }, + BlockEpiloguePayload::V1 { + block_id, + fee_distribution, + .. + } => (block_id, fee_distribution), + }; + + let mut gas_meter = UnmeteredGasMeter; + let mut session = self.new_session(resolver, SessionId::block_epilogue(block_id), None); + + let (validator_indices, amounts) = match fee_distribution { + FeeDistribution::V0 { amount } => amount + .into_iter() + .map(|(validator_index, amount)| { + (MoveValue::U64(validator_index), MoveValue::U64(amount)) + }) + .unzip(), + }; + + let args = vec![ + MoveValue::Signer(AccountAddress::ZERO), // Run as 0x0 + MoveValue::Vector(validator_indices), + MoveValue::Vector(amounts), + ]; + + let traversal_storage = TraversalStorage::new(); + let mut traversal_context = TraversalContext::new(&traversal_storage); + + let output = match session + .execute_function_bypass_visibility( + &BLOCK_MODULE, + BLOCK_EPILOGUE, + vec![], + serialize_values(&args), + &mut gas_meter, + &mut traversal_context, + module_storage, + ) + .map(|_return_vals| ()) + .or_else(|e| expect_only_successful_execution(e, BLOCK_EPILOGUE.as_str(), log_context)) + { + Ok(_) => get_system_transaction_output( + session, + module_storage, + &self.storage_gas_params(log_context)?.change_set_configs, + )?, + Err(e) => { + error!( + "Unexpected error from BlockEpilogue txn: {e:?}, fallback to return success." + ); + let status = TransactionStatus::Keep(ExecutionStatus::Success); + VMOutput::empty_with_status(status) + }, + }; + + SYSTEM_TRANSACTIONS_EXECUTED.inc(); + + // TODO(HotState): generate an output according to the block end info in the + // transaction. (maybe resort to the move resolver, but for simplicity I would + // just include the full slot in both the transaction and the output). + Ok((VMStatus::Executed, output)) + } + pub fn execute_view_function( state_view: &impl StateView, module_id: ModuleId, diff --git a/aptos-move/e2e-move-tests/src/tests/aggregator_v2.data/function_values/sources/capturing.move b/aptos-move/e2e-move-tests/src/tests/aggregator_v2.data/function_values/sources/capturing.move index 31ef1be7059..5155df845d9 100644 --- a/aptos-move/e2e-move-tests/src/tests/aggregator_v2.data/function_values/sources/capturing.move +++ b/aptos-move/e2e-move-tests/src/tests/aggregator_v2.data/function_values/sources/capturing.move @@ -1,12 +1,13 @@ module 0x1::capturing { use aptos_framework::aggregator_v2::create_unbounded_aggregator; - use 0x1::proxy::destroy; - public entry fun capture_aggregator(account: &signer, value: u64, expected: u64) { - let aggregator = destroy(account); + public entry fun capture_aggregator() { + let aggregator = create_unbounded_aggregator(); + aggregator.add(1000); + let apply = |x| 0x1::function_store::fetch_and_add(aggregator, x); - let result = apply(value); - assert!(result == expected, 1); + let result = apply(100); + assert!(result == 1100, 1); } public entry fun to_bytes_with_captured_aggregator() { diff --git a/aptos-move/e2e-move-tests/src/tests/aggregator_v2_function_values.rs b/aptos-move/e2e-move-tests/src/tests/aggregator_v2_function_values.rs index a9c52d8ba8d..353793b5474 100644 --- a/aptos-move/e2e-move-tests/src/tests/aggregator_v2_function_values.rs +++ b/aptos-move/e2e-move-tests/src/tests/aggregator_v2_function_values.rs @@ -5,8 +5,7 @@ use crate::{assert_success, assert_vm_status, tests::common, MoveHarness}; use aptos_framework::BuildOptions; use aptos_language_e2e_tests::executor::FakeExecutor; use aptos_transaction_simulation::Account; -use aptos_types::{move_utils::MemberId, transaction::ExecutionStatus}; -use claims::assert_ok; +use aptos_types::move_utils::MemberId; use move_core_types::{ account_address::AccountAddress, parser::parse_struct_tag, vm_status::StatusCode, }; @@ -92,7 +91,7 @@ fn test_function_value_captures_aggregator_is_not_storable() { vec![], vec![bcs::to_bytes(&100_u64).unwrap()], ); - assert_vm_status!(status, StatusCode::VALUE_SERIALIZATION_ERROR); + assert_vm_status!(status, StatusCode::UNABLE_TO_CAPTURE_DELAYED_FIELDS); let status = h.run_entry_function( &acc, @@ -137,37 +136,16 @@ fn test_function_value_uses_aggregator_is_storable() { #[test] fn test_function_value_captures_aggregator() { - let mut h = MoveHarness::new_with_executor(FakeExecutor::from_head_genesis().set_parallel()); + let mut h = MoveHarness::new_with_executor(FakeExecutor::from_head_genesis()); let acc = h.new_account_at(AccountAddress::from_hex_literal("0x123").unwrap()); initialize(&mut h); - let mut value = 100; - let status = h.run_entry_function( - &acc, - MemberId::from_str("0x1::proxy::initialize").unwrap(), - vec![], - vec![bcs::to_bytes(&value).unwrap()], - ); - assert_success!(status); - assert_counter_value_eq(&h, &acc, value); - - let increment = 100; - value += increment; - let status = h.run_entry_function( - &acc, - MemberId::from_str("0x1::capturing::capture_aggregator").unwrap(), - vec![], - vec![ - bcs::to_bytes(&increment).unwrap(), - bcs::to_bytes(&value).unwrap(), - ], - ); - assert_success!(status); - for name in [ + "capture_aggregator", "to_bytes_with_captured_aggregator", "to_string_with_captured_aggregator", "emit_event_with_captured_aggregator", + "serialized_size_with_captured_aggregator", ] { let status = h.run_entry_function( &acc, @@ -175,20 +153,6 @@ fn test_function_value_captures_aggregator() { vec![], vec![], ); - assert_vm_status!(status, StatusCode::VALUE_SERIALIZATION_ERROR); + assert_vm_status!(status, StatusCode::UNABLE_TO_CAPTURE_DELAYED_FIELDS); } - - let status = h.run_entry_function( - &acc, - MemberId::from_str("0x1::capturing::serialized_size_with_captured_aggregator").unwrap(), - vec![], - vec![], - ); - - // Note: the native function remaps the error and aborts with this code. - let status = assert_ok!(status.as_kept_status()); - assert!(matches!(status, ExecutionStatus::MoveAbort { - code: 453, - .. - })); } diff --git a/aptos-move/e2e-move-tests/src/tests/bcs.data/function-values/Move.toml b/aptos-move/e2e-move-tests/src/tests/bcs.data/function-values/Move.toml new file mode 100644 index 00000000000..f477487f740 --- /dev/null +++ b/aptos-move/e2e-move-tests/src/tests/bcs.data/function-values/Move.toml @@ -0,0 +1,6 @@ +[package] +name = "function_values" +version = "0.0.0" + +[dependencies] +AptosStdlib = { local = "../../../../../framework/aptos-stdlib" } diff --git a/aptos-move/e2e-move-tests/src/tests/bcs.data/function-values/sources/bcs_function_values_test.move b/aptos-move/e2e-move-tests/src/tests/bcs.data/function-values/sources/bcs_function_values_test.move new file mode 100644 index 00000000000..f7bda695c49 --- /dev/null +++ b/aptos-move/e2e-move-tests/src/tests/bcs.data/function-values/sources/bcs_function_values_test.move @@ -0,0 +1,81 @@ +module 0x1::bcs_function_values_test { + use std::bcs; + + public fun public_function(x: u64): u64 { + x + } + + #[persistent] + public fun public_persistent_function(x: u64): u64 { + x + } + + public(friend) fun friend_function(x: u64): u64 { + x + } + + #[persistent] + public(friend) fun friend_persistent_function(x: u64): u64 { + x + } + + fun private_function(x: u64): u64 { + x + } + + #[persistent] + fun private_persistent_function(x: u64): u64 { + x + } + + fun check_bcs(x: &T, abort_code: u64) { + let bytes = bcs::to_bytes(x); + let size = bcs::serialized_size(x); + assert!(bytes.length() == size, abort_code); + } + + public entry fun successful_bcs_tests() { + let f1: |u64|u64 has drop = public_function; + check_bcs(&f1, 1); + + let f2: |u64|u64 has drop = public_persistent_function; + check_bcs(&f2, 2); + + let f3: |u64|u64 has drop = friend_persistent_function; + check_bcs(&f3, 3); + + let f4: |u64|u64 has drop = private_persistent_function; + check_bcs(&f4, 4); + } + + public entry fun failure_bcs_test_friend_function() { + let f: |u64|u64 has drop = friend_function; + check_bcs(&f, 404); + } + + public entry fun failure_bcs_test_friend_function_with_capturing() { + let f: ||u64 has drop = || friend_function(3); + check_bcs(&f, 404); + } + + public entry fun failure_bcs_test_private_function() { + let f: |u64|u64 has drop = private_function; + check_bcs(&f, 404); + } + + public entry fun failure_bcs_test_private_function_with_capturing() { + let f: ||u64 has drop = || private_function(4); + check_bcs(&f, 404); + } + + public entry fun failure_bcs_test_anonymous() { + let f: |u64|u64 has drop = |x| { x }; + check_bcs(&f, 404); + } + + public entry fun failure_bcs_test_anonymous_with_capturing() { + let y: u64 = 2; + let f: |u64|u64 has drop = |x| { x + y }; + check_bcs(&f, 404); + } +} diff --git a/aptos-move/e2e-move-tests/src/tests/bcs.rs b/aptos-move/e2e-move-tests/src/tests/bcs.rs new file mode 100644 index 00000000000..30b3e5abb51 --- /dev/null +++ b/aptos-move/e2e-move-tests/src/tests/bcs.rs @@ -0,0 +1,70 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{assert_success, tests::common, MoveHarness}; +use aptos_framework::BuildOptions; +use aptos_language_e2e_tests::executor::FakeExecutor; +use aptos_types::{move_utils::MemberId, transaction::ExecutionStatus}; +use claims::assert_ok; +use move_core_types::{ + account_address::AccountAddress, + ident_str, + language_storage::ModuleId, + vm_status::{sub_status::NFE_BCS_SERIALIZATION_FAILURE, AbortLocation}, +}; +use std::str::FromStr; + +fn initialize(h: &mut MoveHarness) { + let build_options = BuildOptions::move_2().set_latest_language(); + let path = common::test_dir_path("bcs.data/function-values"); + + let framework_account = h.aptos_framework_account(); + let status = h.publish_package_with_options(&framework_account, path.as_path(), build_options); + assert_success!(status); +} + +#[test] +fn test_function_value_serialization() { + let mut h = MoveHarness::new_with_executor(FakeExecutor::from_head_genesis()); + let acc = h.new_account_at(AccountAddress::from_hex_literal("0x123").unwrap()); + initialize(&mut h); + + let status = h.run_entry_function( + &acc, + MemberId::from_str("0x1::bcs_function_values_test::successful_bcs_tests").unwrap(), + vec![], + vec![], + ); + assert_success!(status); + + let expected_failures = [ + "failure_bcs_test_friend_function", + "failure_bcs_test_friend_function_with_capturing", + "failure_bcs_test_private_function", + "failure_bcs_test_private_function_with_capturing", + "failure_bcs_test_anonymous", + "failure_bcs_test_anonymous_with_capturing", + ]; + + let bcs_location = AbortLocation::Module(ModuleId::new( + AccountAddress::ONE, + ident_str!("bcs").to_owned(), + )); + let expected_status = ExecutionStatus::MoveAbort { + location: bcs_location.clone(), + code: NFE_BCS_SERIALIZATION_FAILURE, + info: None, + }; + + for name in expected_failures { + let status = assert_ok!(h + .run_entry_function( + &acc, + MemberId::from_str(&format!("0x1::bcs_function_values_test::{name}")).unwrap(), + vec![], + vec![], + ) + .as_kept_status()); + assert_eq!(&status, &expected_status); + } +} diff --git a/aptos-move/e2e-move-tests/src/tests/mod.rs b/aptos-move/e2e-move-tests/src/tests/mod.rs index be0b06ec3b9..0c750cdb7a0 100644 --- a/aptos-move/e2e-move-tests/src/tests/mod.rs +++ b/aptos-move/e2e-move-tests/src/tests/mod.rs @@ -11,6 +11,7 @@ mod aggregator_v2_function_values; mod aggregator_v2_runtime_checks; mod any; mod attributes; +mod bcs; mod chain_id; mod code_publishing; mod common; @@ -59,6 +60,7 @@ mod stake; mod state_metadata; mod storage_refund; mod string_args; +mod string_utils; mod swap_function_values; mod test_self; mod token_event_store; diff --git a/aptos-move/e2e-move-tests/src/tests/string_utils.data/pack/Move.toml b/aptos-move/e2e-move-tests/src/tests/string_utils.data/pack/Move.toml new file mode 100644 index 00000000000..3a3493eb887 --- /dev/null +++ b/aptos-move/e2e-move-tests/src/tests/string_utils.data/pack/Move.toml @@ -0,0 +1,6 @@ +[package] +name = "string_utils_test" +version = "0.0.0" + +[dependencies] +AptosStdlib= { local = "../../../../../framework/aptos-stdlib" } diff --git a/aptos-move/e2e-move-tests/src/tests/string_utils.data/pack/scripts/main.move b/aptos-move/e2e-move-tests/src/tests/string_utils.data/pack/scripts/main.move new file mode 100644 index 00000000000..5dda6843b54 --- /dev/null +++ b/aptos-move/e2e-move-tests/src/tests/string_utils.data/pack/scripts/main.move @@ -0,0 +1,11 @@ +script { + use 0x1::string_utils_test::{assert_eq, Test}; + + fun main() { + let f1: || has drop = 0x1::string_utils_test::test1; + assert_eq(&f1, b"0x1::string_utils_test::test1()", 1); + + let f2: |u64, vector| has drop = |a, b| 0x1::string_utils_test::test2(a, 20, @0x123, b); + assert_eq(&f2, b"0x1::string_utils_test::test2(_, 20, @0x123, ..)", 2); + } +} diff --git a/aptos-move/e2e-move-tests/src/tests/string_utils.data/pack/sources/string_utils_test.move b/aptos-move/e2e-move-tests/src/tests/string_utils.data/pack/sources/string_utils_test.move new file mode 100644 index 00000000000..38ea5176223 --- /dev/null +++ b/aptos-move/e2e-move-tests/src/tests/string_utils.data/pack/sources/string_utils_test.move @@ -0,0 +1,88 @@ +module 0x1::string_utils_test { + use std::string; + use aptos_std::string_utils; + + struct Test has copy, drop { + x: u64, + } + + enum TestEnum has copy, drop { + V1 { x: u64, }, + V2 { x: u64, y: Test }, + } + + public fun dummy(_x: &u64, _v: u64) { } + + public fun test1() {} + + public fun test2(_a: u64, _b: u16, _c: address, _d: vector) {} + + public fun test3(f: |&u64|, x: u64) { f(&x) } + + public fun test4(_x: A, _y: B, _z: C) {} + + public entry fun run_all() { + + // === Lambda lifting === // + + let f1: || has drop = || {}; + assert_eq(&f1, b"0x1::string_utils_test::__lambda__1__run_all()", 1); + + let f2: |u8, u8| has drop = |a, b| { + let e = TestEnum::V2 { x: 10, y: Test { x: 20 } }; + test4(a, e, b) + }; + assert_eq(&f2, b"0x1::string_utils_test::__lambda__2__run_all()", 2); + + // === No capturing === // + + let f3: || has drop = test1; + assert_eq(&f3, b"0x1::string_utils_test::test1()", 3); + + let f4: |u64, u16, address, vector| has drop = test2; + assert_eq(&f4, b"0x1::string_utils_test::test2()", 4); + + let f5: |(|&u64|), u64| has drop = test3; + assert_eq(&f5, b"0x1::string_utils_test::test3()", 5); + + // === Capturing simple === // + + let f6: |u64, vector| has drop = |a, b| test2(a, 20, @0x123, b); + assert_eq(&f6, b"0x1::string_utils_test::test2(_, 20, @0x123, ..)", 6); + + let v = vector[Test { x: 1 }, Test { x: 2 }]; + let f7: |u16| has drop = |a| test2(10, a, @0x123, v); + assert_eq(&f7, b"0x1::string_utils_test::test2(10, _, @0x123, [ { 1 }, { 2 } ], ..)", 7); + + // === With type arguments === // + + let f8: |u64, Test, (|u64| has drop)| has drop = test4; + assert_eq( + &f8, + b"0x1::string_utils_test::test4()", + 8, + ); + + let e = TestEnum::V2 { x: 10, y: Test { x: 20 } }; + let f9: |u64, u8| has drop = |a, b| test4(a, e, b); + assert_eq( + &f9, + b"0x1::string_utils_test::test4(_, #1{ 10, { 20 } }, ..)", + 9, + ); + + let h1: |&u64| has drop = |x| dummy(x, 10); + let h2: || has drop = || test3(h1, 30); + assert_eq( + &h2, + b"0x1::string_utils_test::test3(0x1::string_utils_test::dummy(_, 10, ..), 30, ..)", + 10, + ); + } + + public fun assert_eq(x: &T, expected: vector, abort_code: u64) { + let actual = string_utils::to_string(x); + let expected = string::utf8(expected); + assert!(actual == expected, abort_code); + } +} diff --git a/aptos-move/e2e-move-tests/src/tests/string_utils.rs b/aptos-move/e2e-move-tests/src/tests/string_utils.rs new file mode 100644 index 00000000000..c102015fae0 --- /dev/null +++ b/aptos-move/e2e-move-tests/src/tests/string_utils.rs @@ -0,0 +1,54 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{assert_success, tests::common, MoveHarness}; +use aptos_framework::{BuildOptions, BuiltPackage}; +use aptos_language_e2e_tests::executor::FakeExecutor; +use aptos_types::move_utils::MemberId; +use move_core_types::account_address::AccountAddress; +use std::str::FromStr; + +fn initialize(h: &mut MoveHarness) { + let build_options = BuildOptions::move_2().set_latest_language(); + let path = common::test_dir_path("string_utils.data/pack"); + + let framework_account = h.aptos_framework_account(); + let status = h.publish_package_with_options(&framework_account, path.as_path(), build_options); + assert_success!(status); +} + +#[test] +fn test_function_value_formatting_in_modules() { + let mut h = MoveHarness::new_with_executor(FakeExecutor::from_head_genesis()); + let acc = h.new_account_at(AccountAddress::from_hex_literal("0x123").unwrap()); + initialize(&mut h); + + let status = h.run_entry_function( + &acc, + MemberId::from_str("0x1::string_utils_test::run_all").unwrap(), + vec![], + vec![], + ); + assert_success!(status); +} + +#[test] +fn test_function_value_formatting_in_scripts() { + let build_options = BuildOptions::move_2().set_latest_language(); + let path = common::test_dir_path("string_utils.data/pack"); + let package = BuiltPackage::build(path.to_owned(), build_options.clone()) + .expect("Building a package must succeed"); + + let mut scripts = package.extract_script_code(); + assert_eq!(scripts.len(), 1); + let script = scripts.pop().expect("Script exists"); + + let mut h = MoveHarness::new_with_executor(FakeExecutor::from_head_genesis()); + let framework_account = h.aptos_framework_account(); + let txn = h.create_publish_built_package(&framework_account, &package, |_| {}); + assert_success!(h.run(txn)); + + let acc = h.new_account_at(AccountAddress::from_hex_literal("0x123").unwrap()); + let txn = h.create_script(&acc, script, vec![], vec![]); + assert_success!(h.run(txn)); +} diff --git a/aptos-move/e2e-tests/src/executor.rs b/aptos-move/e2e-tests/src/executor.rs index e847ff0c49a..5737da7ca27 100644 --- a/aptos-move/e2e-tests/src/executor.rs +++ b/aptos-move/e2e-tests/src/executor.rs @@ -1245,7 +1245,9 @@ impl FakeExecutor { let fun_name = Self::name(function_name); let should_error = fun_name.clone().into_string().ends_with(POSTFIX); - let storage = TraversalStorage::new(); + let traversal_storage = TraversalStorage::new(); + let mut traversal_context = TraversalContext::new(&traversal_storage); + let result = session.execute_function_bypass_visibility( module, &fun_name, @@ -1262,7 +1264,7 @@ impl FakeExecutor { ), shared_buffer: Arc::clone(&a1), }), - &mut TraversalContext::new(&storage), + &mut traversal_context, &module_storage, ); if let Err(err) = result { @@ -1302,7 +1304,10 @@ impl FakeExecutor { let module_storage = self.state_store.as_aptos_code_storage(&env); let mut session = vm.new_session(&resolver, SessionId::void(), None); - let storage = TraversalStorage::new(); + + let traversal_storage = TraversalStorage::new(); + let mut traversal_context = TraversalContext::new(&traversal_storage); + session .execute_function_bypass_visibility( &module_id, @@ -1311,7 +1316,7 @@ impl FakeExecutor { args, // TODO(Gas): we probably want to switch to metered execution in the future &mut UnmeteredGasMeter, - &mut TraversalContext::new(&storage), + &mut traversal_context, &module_storage, ) .unwrap_or_else(|e| { diff --git a/aptos-move/framework/src/natives/string_utils.rs b/aptos-move/framework/src/natives/string_utils.rs index 407f86e8fac..3475c06fa8e 100644 --- a/aptos-move/framework/src/natives/string_utils.rs +++ b/aptos-move/framework/src/natives/string_utils.rs @@ -9,8 +9,10 @@ use aptos_native_interface::{ }; use aptos_types::on_chain_config::FeatureFlag; use ark_std::iterable::Iterable; +use move_binary_format::errors::PartialVMError; use move_core_types::{ account_address::AccountAddress, + function::ClosureMask, language_storage::TypeTag, u256, value::{MoveFieldLayout, MoveStructLayout, MoveTypeLayout, MASTER_ADDRESS_FIELD_OFFSET}, @@ -18,7 +20,6 @@ use move_core_types::{ use move_vm_runtime::native_functions::NativeFunction; use move_vm_types::{ loaded_data::runtime_types::Type, - value_serde::FunctionValueExtension, values::{Closure, Reference, Struct, Value, Vector, VectorRef}, }; use smallvec::{smallvec, SmallVec}; @@ -126,6 +127,59 @@ fn format_vector<'a>( Ok(()) } +fn format_closure_captured_arguments( + context: &mut FormatContext, + mask: ClosureMask, + mut captured_layouts: impl Iterator, + mut captured_arguments: impl Iterator, + depth: usize, + newline: bool, + out: &mut String, +) -> SafeNativeResult<()> { + if depth >= context.max_depth { + write!(out, " .. ").unwrap(); + return Ok(()); + } + + let mut i = 0; + let mut mask = mask.bits(); + + while mask != 0 { + if i > 0 { + out.push(','); + print_space_or_newline(newline, out, depth + 1); + } + if i >= context.max_len { + write!(out, "..").unwrap(); + break; + } + + if mask & 0x1 != 0 { + let layout = captured_layouts.next().ok_or_else(|| { + PartialVMError::new_invariant_violation("Captured layout must exist") + })?; + layout.write_name(out); + + let value = captured_arguments.next().ok_or_else(|| { + PartialVMError::new_invariant_violation("Captured argument must exist") + })?; + native_format_impl(context, layout.get_layout(), value, depth + 1, out)?; + } else { + write!(out, "_").unwrap(); + } + mask >>= 1; + i += 1; + } + + if i < context.max_len { + out.push(','); + print_space_or_newline(newline, out, depth + 1); + write!(out, "..").unwrap(); + } + + Ok(()) +} + fn native_format_impl( context: &mut FormatContext, layout: &MoveTypeLayout, @@ -363,19 +417,25 @@ fn native_format_impl( // avoiding potential loading of the function to get full // decorated type information. let (fun, args) = val.value_as::()?.unpack(); - let data = context + let captured_layouts = context .context - .function_value_extension() - .get_serialization_data(fun.as_ref())?; + .get_captured_layouts_for_string_utils(fun.as_ref())? + .ok_or_else(|| SafeNativeError::Abort { + abort_code: EUNABLE_TO_FORMAT_DELAYED_FIELD, + })?; out.push_str(&fun.to_canonical_string()); - format_vector( - context, - data.captured_layouts.iter(), - args.collect(), - depth, - !context.single_line, - out, - )?; + out.push('('); + if !captured_layouts.is_empty() { + format_closure_captured_arguments( + context, + fun.closure_mask(), + captured_layouts.into_iter(), + args, + depth, + !context.single_line, + out, + )?; + } out.push(')'); }, diff --git a/aptos-move/vm-genesis/src/lib.rs b/aptos-move/vm-genesis/src/lib.rs index 4cdf1bd7be9..52625ff9336 100644 --- a/aptos-move/vm-genesis/src/lib.rs +++ b/aptos-move/vm-genesis/src/lib.rs @@ -159,6 +159,9 @@ pub fn encode_aptos_mainnet_genesis_transaction( let genesis_change_set_configs = genesis_vm.genesis_change_set_configs(); let mut session = genesis_vm.new_genesis_session(&resolver, HashValue::zero()); + let traversal_storage = TraversalStorage::new(); + let mut traversal_context = TraversalContext::new(&traversal_storage); + // On-chain genesis process. let consensus_config = OnChainConsensusConfig::default_for_genesis(); let execution_config = OnChainExecutionConfig::default_for_genesis(); @@ -166,6 +169,7 @@ pub fn encode_aptos_mainnet_genesis_transaction( initialize( &mut session, &module_storage, + &mut traversal_context, chain_id, genesis_config, &consensus_config, @@ -175,23 +179,45 @@ pub fn encode_aptos_mainnet_genesis_transaction( initialize_features( &mut session, &module_storage, + &mut traversal_context, genesis_config .initial_features_override .clone() .map(Features::into_flag_vec), ); - initialize_aptos_coin(&mut session, &module_storage); - initialize_on_chain_governance(&mut session, &module_storage, genesis_config); - create_accounts(&mut session, &module_storage, accounts); - create_employee_validators(&mut session, &module_storage, employees, genesis_config); - create_and_initialize_validators_with_commission(&mut session, &module_storage, validators); - set_genesis_end(&mut session, &module_storage); + initialize_aptos_coin(&mut session, &module_storage, &mut traversal_context); + initialize_on_chain_governance( + &mut session, + &module_storage, + &mut traversal_context, + genesis_config, + ); + create_accounts( + &mut session, + &module_storage, + &mut traversal_context, + accounts, + ); + create_employee_validators( + &mut session, + &module_storage, + &mut traversal_context, + employees, + genesis_config, + ); + create_and_initialize_validators_with_commission( + &mut session, + &module_storage, + &mut traversal_context, + validators, + ); + set_genesis_end(&mut session, &module_storage, &mut traversal_context); // Reconfiguration should happen after all on-chain invocations. - emit_new_block_and_epoch_event(&mut session, &module_storage); + emit_new_block_and_epoch_event(&mut session, &module_storage, &mut traversal_context); // Create a change set with all initialized resources. - let mut change_set = assert_ok!(session.finish(&genesis_change_set_configs, &module_storage)); + let mut change_set = assert_ok!(session.finish(&genesis_change_set_configs, &module_storage,)); // Publish the framework, using a different session id, in case both sessions create tables. let mut new_id = [0u8; 32]; @@ -261,10 +287,14 @@ pub fn encode_genesis_change_set( let genesis_change_set_configs = genesis_vm.genesis_change_set_configs(); let mut session = genesis_vm.new_genesis_session(&resolver, HashValue::zero()); + let traversal_storage = TraversalStorage::new(); + let mut traversal_context = TraversalContext::new(&traversal_storage); + // On-chain genesis process. initialize( &mut session, &module_storage, + &mut traversal_context, chain_id, genesis_config, consensus_config, @@ -274,62 +304,85 @@ pub fn encode_genesis_change_set( initialize_features( &mut session, &module_storage, + &mut traversal_context, genesis_config .initial_features_override .clone() .map(Features::into_flag_vec), ); if genesis_config.is_test { - initialize_core_resources_and_aptos_coin(&mut session, &module_storage, core_resources_key); + initialize_core_resources_and_aptos_coin( + &mut session, + &module_storage, + &mut traversal_context, + core_resources_key, + ); } else { - initialize_aptos_coin(&mut session, &module_storage); + initialize_aptos_coin(&mut session, &module_storage, &mut traversal_context); } - // Initialize the governed gas pool with a default seed - initialize_governed_gas_pool(&mut session, &module_storage); - initialize_config_buffer(&mut session, &module_storage); - initialize_dkg(&mut session, &module_storage); - initialize_reconfiguration_state(&mut session, &module_storage); + initialize_config_buffer(&mut session, &module_storage, &mut traversal_context); + initialize_dkg(&mut session, &module_storage, &mut traversal_context); + initialize_reconfiguration_state(&mut session, &module_storage, &mut traversal_context); let randomness_config = genesis_config .randomness_config_override .clone() .unwrap_or_else(OnChainRandomnessConfig::default_for_genesis); - initialize_randomness_api_v0_config(&mut session, &module_storage); - initialize_randomness_config_seqnum(&mut session, &module_storage); - initialize_randomness_config(&mut session, &module_storage, randomness_config); - initialize_randomness_resources(&mut session, &module_storage); - initialize_on_chain_governance(&mut session, &module_storage, genesis_config); - let not_skip_aa: bool = if let Some(features) = &genesis_config.initial_features_override { - features.is_enabled(FeatureFlag::ACCOUNT_ABSTRACTION) || features.is_enabled(FeatureFlag::DERIVABLE_ACCOUNT_ABSTRACTION) - } else { - false - }; - if not_skip_aa { - initialize_account_abstraction(&mut session, &module_storage); - } - create_and_initialize_validators(&mut session, &module_storage, validators); + initialize_randomness_api_v0_config(&mut session, &module_storage, &mut traversal_context); + initialize_randomness_config_seqnum(&mut session, &module_storage, &mut traversal_context); + initialize_randomness_config( + &mut session, + &module_storage, + &mut traversal_context, + randomness_config, + ); + initialize_randomness_resources(&mut session, &module_storage, &mut traversal_context); + initialize_on_chain_governance( + &mut session, + &module_storage, + &mut traversal_context, + genesis_config, + ); + initialize_account_abstraction(&mut session, &module_storage, &mut traversal_context); + create_and_initialize_validators( + &mut session, + &module_storage, + &mut traversal_context, + validators, + ); if genesis_config.is_test { - allow_core_resources_to_set_version(&mut session, &module_storage); + allow_core_resources_to_set_version(&mut session, &module_storage, &mut traversal_context); } let jwk_consensus_config = genesis_config .jwk_consensus_config_override .clone() .unwrap_or_else(OnChainJWKConsensusConfig::default_for_genesis); - initialize_jwk_consensus_config(&mut session, &module_storage, &jwk_consensus_config); - initialize_jwks_resources(&mut session, &module_storage); + initialize_jwk_consensus_config( + &mut session, + &module_storage, + &mut traversal_context, + &jwk_consensus_config, + ); + initialize_jwks_resources(&mut session, &module_storage, &mut traversal_context); initialize_keyless_accounts( &mut session, &module_storage, + &mut traversal_context, chain_id, genesis_config.initial_jwks.clone(), genesis_config.keyless_groth16_vk.clone(), ); - initialize_confidential_asset(&mut session, &module_storage, chain_id); - set_genesis_end(&mut session, &module_storage); + initialize_confidential_asset( + &mut session, + &module_storage, + chain_id, + &mut traversal_context, + ); + set_genesis_end(&mut session, &module_storage, &mut traversal_context); // Reconfiguration should happen after all on-chain invocations. - emit_new_block_and_epoch_event(&mut session, &module_storage); + emit_new_block_and_epoch_event(&mut session, &module_storage, &mut traversal_context); - let mut change_set = assert_ok!(session.finish(&genesis_change_set_configs, &module_storage)); + let mut change_set = assert_ok!(session.finish(&genesis_change_set_configs, &module_storage,)); // Publish the framework, using a different id, in case both sessions create tables. let mut new_id = [0u8; 32]; @@ -389,13 +442,13 @@ fn validate_genesis_config(genesis_config: &GenesisConfiguration) { fn exec_function_internal( session: &mut SessionExt, module_storage: &impl ModuleStorage, + traversal_context: &mut TraversalContext, module_name: &str, function_name: &str, ty_args: Vec, args: Vec>, address: AccountAddress, ) { - let storage = TraversalStorage::new(); session .execute_function_bypass_visibility( &ModuleId::new(address, Identifier::new(module_name).unwrap()), @@ -403,7 +456,7 @@ fn exec_function_internal( ty_args, args, &mut UnmeteredGasMeter, - &mut TraversalContext::new(&storage), + traversal_context, module_storage, ) .unwrap_or_else(|e| { @@ -421,6 +474,7 @@ fn exec_function_internal( fn exec_function( session: &mut SessionExt, module_storage: &impl ModuleStorage, + traversal_context: &mut TraversalContext, module_name: &str, function_name: &str, ty_args: Vec, @@ -429,6 +483,7 @@ fn exec_function( exec_function_internal( session, module_storage, + traversal_context, module_name, function_name, ty_args, @@ -440,6 +495,7 @@ fn exec_function( fn exec_experimental_function( session: &mut SessionExt, module_storage: &impl ModuleStorage, + traversal_context: &mut TraversalContext, module_name: &str, function_name: &str, ty_args: Vec, @@ -448,6 +504,7 @@ fn exec_experimental_function( exec_function_internal( session, module_storage, + traversal_context, module_name, function_name, ty_args, @@ -459,6 +516,7 @@ fn exec_experimental_function( fn initialize( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, chain_id: ChainId, genesis_config: &GenesisConfiguration, consensus_config: &OnChainConsensusConfig, @@ -489,6 +547,7 @@ fn initialize( exec_function( session, module_storage, + traversal_context, GENESIS_MODULE_NAME, "initialize", vec![], @@ -513,6 +572,7 @@ fn initialize( fn initialize_features( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, features_override: Option>, ) { let features: Vec = features_override @@ -528,6 +588,7 @@ fn initialize_features( exec_function( session, module_storage, + traversal_context, "features", "change_feature_flags_internal", vec![], @@ -538,10 +599,12 @@ fn initialize_features( fn initialize_aptos_coin( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, GENESIS_MODULE_NAME, "initialize_aptos_coin", vec![], @@ -570,10 +633,12 @@ fn initialize_governed_gas_pool( fn initialize_config_buffer( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, CONFIG_BUFFER_MODULE_NAME, "initialize", vec![], @@ -584,10 +649,12 @@ fn initialize_config_buffer( fn initialize_dkg( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, DKG_MODULE_NAME, "initialize", vec![], @@ -598,10 +665,12 @@ fn initialize_dkg( fn initialize_randomness_config_seqnum( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, RANDOMNESS_CONFIG_SEQNUM_MODULE_NAME, "initialize", vec![], @@ -612,10 +681,12 @@ fn initialize_randomness_config_seqnum( fn initialize_randomness_api_v0_config( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, RANDOMNESS_API_V0_CONFIG_MODULE_NAME, "initialize", vec![], @@ -630,11 +701,13 @@ fn initialize_randomness_api_v0_config( fn initialize_randomness_config( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, randomness_config: OnChainRandomnessConfig, ) { exec_function( session, module_storage, + traversal_context, RANDOMNESS_CONFIG_MODULE_NAME, "initialize", vec![], @@ -648,10 +721,12 @@ fn initialize_randomness_config( fn initialize_randomness_resources( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, RANDOMNESS_MODULE_NAME, "initialize", vec![], @@ -662,10 +737,12 @@ fn initialize_randomness_resources( fn initialize_account_abstraction( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, ACCOUNT_ABSTRACTION_MODULE_NAME, "initialize", vec![], @@ -675,6 +752,7 @@ fn initialize_account_abstraction( exec_function( session, module_storage, + traversal_context, ACCOUNT_ABSTRACTION_MODULE_NAME, "register_derivable_authentication_function", vec![], @@ -691,6 +769,7 @@ fn initialize_account_abstraction( exec_function( session, module_storage, + traversal_context, ACCOUNT_ABSTRACTION_MODULE_NAME, "register_derivable_authentication_function", vec![], @@ -705,6 +784,7 @@ fn initialize_account_abstraction( exec_function( session, module_storage, + traversal_context, ACCOUNT_ABSTRACTION_MODULE_NAME, "register_derivable_authentication_function", vec![], @@ -720,10 +800,12 @@ fn initialize_account_abstraction( fn initialize_reconfiguration_state( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, RECONFIGURATION_STATE_MODULE_NAME, "initialize", vec![], @@ -734,11 +816,13 @@ fn initialize_reconfiguration_state( fn initialize_jwk_consensus_config( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, jwk_consensus_config: &OnChainJWKConsensusConfig, ) { exec_function( session, module_storage, + traversal_context, JWK_CONSENSUS_CONFIG_MODULE_NAME, "initialize", vec![], @@ -752,10 +836,12 @@ fn initialize_jwk_consensus_config( fn initialize_jwks_resources( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, JWKS_MODULE_NAME, "initialize", vec![], @@ -766,10 +852,12 @@ fn initialize_jwks_resources( fn set_genesis_end( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, GENESIS_MODULE_NAME, "set_genesis_end", vec![], @@ -780,12 +868,14 @@ fn set_genesis_end( fn initialize_core_resources_and_aptos_coin( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, core_resources_key: &Ed25519PublicKey, ) { let core_resources_auth_key = AuthenticationKey::ed25519(core_resources_key); exec_function( session, module_storage, + traversal_context, GENESIS_MODULE_NAME, "initialize_core_resources_and_aptos_coin", vec![], @@ -800,11 +890,13 @@ fn initialize_core_resources_and_aptos_coin( fn initialize_on_chain_governance( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, genesis_config: &GenesisConfiguration, ) { exec_function( session, module_storage, + traversal_context, GOVERNANCE_MODULE_NAME, "initialize", vec![], @@ -820,6 +912,7 @@ fn initialize_on_chain_governance( fn initialize_keyless_accounts( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, chain_id: ChainId, mut initial_jwks: Vec, vk: Option, @@ -828,6 +921,7 @@ fn initialize_keyless_accounts( exec_function( session, module_storage, + traversal_context, KEYLESS_ACCOUNT_MODULE_NAME, "update_configuration", vec![], @@ -841,6 +935,7 @@ fn initialize_keyless_accounts( exec_function( session, module_storage, + traversal_context, KEYLESS_ACCOUNT_MODULE_NAME, "update_groth16_verification_key", vec![], @@ -872,6 +967,7 @@ fn initialize_keyless_accounts( exec_function( session, module_storage, + traversal_context, JWKS_MODULE_NAME, "set_patches", vec![], @@ -887,11 +983,13 @@ fn initialize_confidential_asset( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, chain_id: ChainId, + traversal_context: &mut TraversalContext, ) { if !chain_id.is_mainnet() && !chain_id.is_testnet() { exec_experimental_function( session, module_storage, + traversal_context, "confidential_asset", "init_module_for_genesis", vec![], @@ -903,6 +1001,7 @@ fn initialize_confidential_asset( fn create_accounts( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, accounts: &[AccountBalance], ) { let accounts_bytes = bcs::to_bytes(accounts).expect("AccountMaps can be serialized"); @@ -911,6 +1010,7 @@ fn create_accounts( exec_function( session, module_storage, + traversal_context, GENESIS_MODULE_NAME, "create_accounts", vec![], @@ -921,6 +1021,7 @@ fn create_accounts( fn create_employee_validators( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, employees: &[EmployeePool], genesis_config: &GenesisConfiguration, ) { @@ -934,6 +1035,7 @@ fn create_employee_validators( exec_function( session, module_storage, + traversal_context, GENESIS_MODULE_NAME, "create_employee_validators", vec![], @@ -947,6 +1049,7 @@ fn create_employee_validators( fn create_and_initialize_validators( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, validators: &[Validator], ) { let validators_bytes = bcs::to_bytes(validators).expect("Validators can be serialized"); @@ -955,6 +1058,7 @@ fn create_and_initialize_validators( exec_function( session, module_storage, + traversal_context, GENESIS_MODULE_NAME, "create_initialize_validators", vec![], @@ -965,6 +1069,7 @@ fn create_and_initialize_validators( fn create_and_initialize_validators_with_commission( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, validators: &[ValidatorWithCommissionRate], ) { let validators_bytes = bcs::to_bytes(validators).expect("Validators can be serialized"); @@ -976,6 +1081,7 @@ fn create_and_initialize_validators_with_commission( exec_function( session, module_storage, + traversal_context, GENESIS_MODULE_NAME, "create_initialize_validators_with_commission", vec![], @@ -986,10 +1092,12 @@ fn create_and_initialize_validators_with_commission( fn allow_core_resources_to_set_version( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, VERSION_MODULE_NAME, "initialize_for_test", vec![], @@ -1000,12 +1108,14 @@ fn allow_core_resources_to_set_version( fn initialize_package( session: &mut SessionExt, module_storage: &impl ModuleStorage, + traversal_context: &mut TraversalContext, addr: AccountAddress, package: &ReleasePackage, ) { exec_function( session, module_storage, + traversal_context, CODE_MODULE_NAME, "initialize", vec![], @@ -1095,6 +1205,9 @@ fn publish_framework( let resolver = state_view.as_move_resolver(); let mut session = genesis_vm.new_genesis_session(&resolver, hash_value); + let traversal_storage = TraversalStorage::new(); + let mut traversal_context = TraversalContext::new(&traversal_storage); + for pack in &framework.packages { // Unfortunately, package does not contain address information, so we have to access its // modules to extract the destination address. @@ -1105,11 +1218,17 @@ fn publish_framework( .1 .self_id() .address(); - initialize_package(&mut session, &module_storage, addr, pack); + initialize_package( + &mut session, + &module_storage, + &mut traversal_context, + addr, + pack, + ); } let change_set = - assert_ok!(session.finish(&genesis_vm.genesis_change_set_configs(), &module_storage)); + assert_ok!(session.finish(&genesis_vm.genesis_change_set_configs(), &module_storage,)); (change_set, module_write_set) } @@ -1117,10 +1236,12 @@ fn publish_framework( fn emit_new_block_and_epoch_event( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, + traversal_context: &mut TraversalContext, ) { exec_function( session, module_storage, + traversal_context, "block", "emit_genesis_block_event", vec![], @@ -1131,6 +1252,7 @@ fn emit_new_block_and_epoch_event( exec_function( session, module_storage, + traversal_context, "reconfiguration", "emit_genesis_reconfiguration_event", vec![], diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.exp index 1bdb2c78fef..29ffe449a8e 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.exp @@ -1,7 +1,13 @@ -processed 4 tasks +processed 6 tasks -task 1 'run'. lines 14-14: -return values: false +task 1 'run'. lines 31-31: +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(453), + location: 0x1::bcs, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 0)], +} -task 3 'run'. lines 27-27: +task 5 'run'. lines 48-48: return values: 42 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.move index cc7985166b1..92875ee174c 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.move +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.move @@ -2,16 +2,37 @@ module 0xc0ffee::m { use std::bcs; - public fun test(): bool { + public fun test1(): bool { let x = 1; let y = 2; let f: || u64 has drop = || {x + y + 1}; - let g: || u64 has drop = || {x + y + 1}; - bcs::to_bytes(&f) == bcs::to_bytes(&g) + // Serialization fails! + let _ = bcs::to_bytes(&f); + true + } + + public fun foo() {} + + #[persistent] + fun bar() {} + + public fun test2() { + let f: || has drop = foo; + let b: || has drop = bar; + assert!(bcs::to_bytes(&f) != bcs::to_bytes(&b), 1); + } + + public fun test3() { + let f: || has drop = foo; + assert!(bcs::to_bytes(&f) == bcs::to_bytes(&f), 2); } } -//# run 0xc0ffee::m::test +//# run 0xc0ffee::m::test1 + +//# run 0xc0ffee::m::test2 + +//# run 0xc0ffee::m::test3 //# publish module 0xc0ffee::n { diff --git a/third_party/move/move-core/types/src/vm_status.rs b/third_party/move/move-core/types/src/vm_status.rs index 677201cdecb..47388049bc4 100644 --- a/third_party/move/move-core/types/src/vm_status.rs +++ b/third_party/move/move-core/types/src/vm_status.rs @@ -211,7 +211,7 @@ impl VMStatus { | StatusCode::IO_LIMIT_REACHED | StatusCode::STORAGE_LIMIT_REACHED | StatusCode::TOO_MANY_DELAYED_FIELDS - | StatusCode::VM_MAX_VALUE_DEPTH_REACHED, + | StatusCode::UNABLE_TO_CAPTURE_DELAYED_FIELDS, .. } | VMStatus::Error { @@ -220,7 +220,7 @@ impl VMStatus { | StatusCode::IO_LIMIT_REACHED | StatusCode::STORAGE_LIMIT_REACHED | StatusCode::TOO_MANY_DELAYED_FIELDS - | StatusCode::VM_MAX_VALUE_DEPTH_REACHED, + | StatusCode::UNABLE_TO_CAPTURE_DELAYED_FIELDS, .. } => Ok(KeptVMStatus::MiscellaneousError), @@ -889,11 +889,14 @@ pub enum StatusCode { // Modules are cyclic (module A uses module B which uses module A). Detected at runtime in case // module loading is performed lazily. RUNTIME_CYCLIC_MODULE_DEPENDENCY = 4040, + // Returned when a function value is trying to capture a delayed field. This is not allowed + // because layouts for values with delayed fields are not serializable. + UNABLE_TO_CAPTURE_DELAYED_FIELDS = 4041, // Reserved error code for future use. Always keep this buffer of well-defined new codes. - RESERVED_RUNTIME_ERROR_1 = 4041, - RESERVED_RUNTIME_ERROR_2 = 4042, - RESERVED_RUNTIME_ERROR_3 = 4043, + RESERVED_RUNTIME_ERROR_1 = 4042, + RESERVED_RUNTIME_ERROR_2 = 4043, + RESERVED_RUNTIME_ERROR_3 = 4044, // A reserved status to represent an unknown vm status. // this is u64::MAX, but we can't pattern match on that, so put the hardcoded value in diff --git a/third_party/move/move-vm/runtime/src/interpreter.rs b/third_party/move/move-vm/runtime/src/interpreter.rs index ee56d8e7c07..62f3ed09f94 100644 --- a/third_party/move/move-vm/runtime/src/interpreter.rs +++ b/third_party/move/move-vm/runtime/src/interpreter.rs @@ -1080,9 +1080,11 @@ where /// Creates a data cache entry for the specified address-type pair. Charges gas for the number /// of bytes loaded. fn create_and_charge_data_cache_entry( + &self, resource_resolver: &impl ResourceResolver, module_storage: &impl ModuleStorage, gas_meter: &mut impl GasMeter, + _traversal_context: &mut TraversalContext, addr: AccountAddress, ty: &Type, ) -> PartialVMResult { @@ -1106,18 +1108,21 @@ where /// Loads a resource from the data store and return the number of bytes read from the storage. fn load_resource<'c>( + &self, data_cache: &'c mut TransactionDataCache, resource_resolver: &impl ResourceResolver, module_storage: &impl ModuleStorage, gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, addr: AccountAddress, ty: &Type, ) -> PartialVMResult<&'c mut GlobalValue> { if !data_cache.contains_resource(&addr, ty) { - let entry = Self::create_and_charge_data_cache_entry( + let entry = self.create_and_charge_data_cache_entry( resource_resolver, module_storage, gas_meter, + traversal_context, addr, ty, )?; @@ -1135,19 +1140,22 @@ where resource_resolver: &impl ResourceResolver, module_storage: &impl ModuleStorage, gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, addr: AccountAddress, ty: &Type, ) -> PartialVMResult<()> { let runtime_environment = module_storage.runtime_environment(); - let res = Self::load_resource( - data_cache, - resource_resolver, - module_storage, - gas_meter, - addr, - ty, - )? - .borrow_global(); + let res = self + .load_resource( + data_cache, + resource_resolver, + module_storage, + gas_meter, + traversal_context, + addr, + ty, + )? + .borrow_global(); gas_meter.charge_borrow_global( is_mut, is_generic, @@ -1213,15 +1221,17 @@ where resource_resolver: &impl ResourceResolver, module_storage: &impl ModuleStorage, gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, addr: AccountAddress, ty: &Type, ) -> PartialVMResult<()> { let runtime_environment = module_storage.runtime_environment(); - let gv = Self::load_resource( + let gv = self.load_resource( data_cache, resource_resolver, module_storage, gas_meter, + traversal_context, addr, ty, )?; @@ -1247,19 +1257,22 @@ where resource_resolver: &impl ResourceResolver, module_storage: &impl ModuleStorage, gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, addr: AccountAddress, ty: &Type, ) -> PartialVMResult<()> { let runtime_environment = module_storage.runtime_environment(); - let resource = match Self::load_resource( - data_cache, - resource_resolver, - module_storage, - gas_meter, - addr, - ty, - )? - .move_from() + let resource = match self + .load_resource( + data_cache, + resource_resolver, + module_storage, + gas_meter, + traversal_context, + addr, + ty, + )? + .move_from() { Ok(resource) => { gas_meter.charge_move_from( @@ -1298,16 +1311,18 @@ where resource_resolver: &impl ResourceResolver, module_storage: &impl ModuleStorage, gas_meter: &mut impl GasMeter, + traversal_context: &mut TraversalContext, addr: AccountAddress, ty: &Type, resource: Value, ) -> PartialVMResult<()> { let runtime_environment = module_storage.runtime_environment(); - let gv = Self::load_resource( + let gv = self.load_resource( data_cache, resource_resolver, module_storage, gas_meter, + traversal_context, addr, ty, )?; @@ -2265,7 +2280,9 @@ impl Frame { let captured = interpreter.operand_stack.popn(mask.captured_count())?; let lazy_function = LazyLoadedFunction::new_resolved( - module_storage.runtime_environment(), + module_storage, + gas_meter, + traversal_context, function.clone(), *mask, )?; @@ -2302,7 +2319,9 @@ impl Frame { let captured = interpreter.operand_stack.popn(mask.captured_count())?; let lazy_function = LazyLoadedFunction::new_resolved( - module_storage.runtime_environment(), + module_storage, + gas_meter, + traversal_context, function.clone(), *mask, )?; @@ -2485,6 +2504,7 @@ impl Frame { resource_resolver, module_storage, gas_meter, + traversal_context, addr, &ty, )?; @@ -2502,6 +2522,7 @@ impl Frame { resource_resolver, module_storage, gas_meter, + traversal_context, addr, ty, )?; @@ -2515,6 +2536,7 @@ impl Frame { resource_resolver, module_storage, gas_meter, + traversal_context, addr, &ty, )?; @@ -2529,6 +2551,7 @@ impl Frame { resource_resolver, module_storage, gas_meter, + traversal_context, addr, ty, )?; @@ -2542,6 +2565,7 @@ impl Frame { resource_resolver, module_storage, gas_meter, + traversal_context, addr, &ty, )?; @@ -2556,6 +2580,7 @@ impl Frame { resource_resolver, module_storage, gas_meter, + traversal_context, addr, ty, )?; @@ -2575,6 +2600,7 @@ impl Frame { resource_resolver, module_storage, gas_meter, + traversal_context, addr, &ty, resource, @@ -2596,6 +2622,7 @@ impl Frame { resource_resolver, module_storage, gas_meter, + traversal_context, addr, ty, resource, diff --git a/third_party/move/move-vm/runtime/src/loader/function.rs b/third_party/move/move-vm/runtime/src/loader/function.rs index 1b3e1851d14..df72f4565b3 100644 --- a/third_party/move/move-vm/runtime/src/loader/function.rs +++ b/third_party/move/move-vm/runtime/src/loader/function.rs @@ -4,8 +4,10 @@ use crate::{ loader::{access_specifier_loader::load_access_specifier, Module, Script}, + module_traversal::TraversalContext, native_functions::{NativeFunction, NativeFunctions, UnboxedNativeFunction}, - ModuleStorage, RuntimeEnvironment, + storage::ty_layout_converter::{LayoutConverter, StorageLayoutConverter}, + ModuleStorage, }; use better_any::{Tid, TidAble, TidExt}; use move_binary_format::{ @@ -22,16 +24,18 @@ use move_core_types::{ identifier::{IdentStr, Identifier}, language_storage, language_storage::{ModuleId, TypeTag}, + value::MoveTypeLayout, vm_status::StatusCode, }; use move_vm_types::{ + gas::DependencyGasMeter, loaded_data::{ runtime_access_specifier::AccessSpecifier, runtime_types::{StructIdentifier, Type}, }, values::{AbstractFunction, SerializedFunctionData}, }; -use std::{cell::RefCell, cmp::Ordering, fmt::Debug, rc::Rc, sync::Arc}; +use std::{cell::RefCell, cmp::Ordering, fmt::Debug, mem, rc::Rc, sync::Arc}; /// A runtime function definition representation. pub struct Function { @@ -113,11 +117,15 @@ impl LoadedFunction { /// `LoadedFunction`. This is wrapped into a Rc so one can clone the /// function while sharing the loading state. #[derive(Clone, Tid)] -pub(crate) struct LazyLoadedFunction(pub(crate) Rc>); +pub(crate) struct LazyLoadedFunction { + pub(crate) state: Rc>, +} #[derive(Clone)] pub(crate) enum LazyLoadedFunctionState { Unresolved { + // Note: this contains layouts from storage, which may be out-dated (e.g., storing only old + // enum variant layouts even when enum has been upgraded to contain more variants). data: SerializedFunctionData, }, Resolved { @@ -129,29 +137,101 @@ pub(crate) enum LazyLoadedFunctionState { // unresolved case, the type argument tags are stored with the serialized data. ty_args: Vec, mask: ClosureMask, + // Layouts for captured arguments. The invariant is that these are always set for storable + // closures at construction time. Non-storable closures just have None as they will not be + // serialized anyway. + captured_layouts: Option>, }, } impl LazyLoadedFunction { pub(crate) fn new_unresolved(data: SerializedFunctionData) -> Self { - Self(Rc::new(RefCell::new(LazyLoadedFunctionState::Unresolved { - data, - }))) + Self { + state: Rc::new(RefCell::new(LazyLoadedFunctionState::Unresolved { data })), + } } pub(crate) fn new_resolved( - runtime_environment: &RuntimeEnvironment, + module_storage: &impl ModuleStorage, + gas_meter: &mut impl DependencyGasMeter, + traversal_context: &mut TraversalContext, fun: Rc, mask: ClosureMask, ) -> PartialVMResult { + let runtime_environment = module_storage.runtime_environment(); let ty_args = fun .ty_args .iter() .map(|t| runtime_environment.ty_to_ty_tag(t)) .collect::>>()?; - Ok(Self(Rc::new(RefCell::new( - LazyLoadedFunctionState::Resolved { fun, ty_args, mask }, - )))) + + // When building a closure, if it captures arguments, and it is persistent (i.e., it may + // be stored to storage), pre-compute layouts which will be stored alongside the captured + // arguments. This way layouts always exist for storable closures and there is no need to + // construct them at serialization time. This makes loading and metering logic much simpler + // while adding layout construction overhead only for storable closures. + let captured_layouts = fun + .function + .is_persistent() + .then(|| { + // In case there are delayed fields when constructing captured layouts, we need to + // fail early to not allow their capturing altogether. + Self::construct_captured_layouts( + module_storage, + gas_meter, + traversal_context, + &fun, + mask, + )? + .ok_or_else(|| { + PartialVMError::new(StatusCode::UNABLE_TO_CAPTURE_DELAYED_FIELDS) + .with_message("Function values cannot capture delayed fields".to_string()) + }) + }) + .transpose()?; + + Ok(Self { + state: Rc::new(RefCell::new(LazyLoadedFunctionState::Resolved { + fun, + ty_args, + mask, + captured_layouts, + })), + }) + } + + /// For a given function and a mask, constructs a vector of layouts for the captured arguments. + /// Returns [None] if there are any captured delayed fields in the layouts (i.e., the captured + /// values are not serializable not "displayable"). For all other failures, an error is + /// returned. + pub(crate) fn construct_captured_layouts( + module_storage: &impl ModuleStorage, + _gas_meter: &mut impl DependencyGasMeter, + _traversal_context: &mut TraversalContext, + fun: &LoadedFunction, + mask: ClosureMask, + ) -> PartialVMResult>> { + let ty_converter = StorageLayoutConverter::new(module_storage); + let ty_builder = &module_storage.runtime_environment().vm_config().ty_builder; + + mask.extract(fun.param_tys(), true) + .into_iter() + .map(|ty| { + let (layout, contains_delayed_fields) = if fun.ty_args.is_empty() { + ty_converter.type_to_type_layout_with_identifier_mappings(ty)? + } else { + let ty = ty_builder.create_ty_with_subst(ty, &fun.ty_args)?; + ty_converter.type_to_type_layout_with_identifier_mappings(&ty)? + }; + + // Do not allow delayed fields to be serialized. + if contains_delayed_fields { + return Ok(None); + } + + Ok(Some(layout)) + }) + .collect::>>>() } pub(crate) fn expect_this_impl( @@ -171,7 +251,7 @@ impl LazyLoadedFunction { &self, action: impl FnOnce(Option<&ModuleId>, &IdentStr, &[TypeTag]) -> T, ) -> T { - match &*self.0.borrow() { + match &*self.state.borrow() { LazyLoadedFunctionState::Unresolved { data: SerializedFunctionData { @@ -194,7 +274,7 @@ impl LazyLoadedFunction { &self, module_storage: &impl ModuleStorage, ) -> PartialVMResult> { - let mut state = self.0.borrow_mut(); + let mut state = self.state.borrow_mut(); Ok(match &mut *state { LazyLoadedFunctionState::Resolved { fun, .. } => fun.clone(), LazyLoadedFunctionState::Unresolved { @@ -205,17 +285,19 @@ impl LazyLoadedFunction { fun_id, ty_args, mask, - captured_layouts: _, + captured_layouts, }, } => { let fun = module_storage .load_function(module_id, fun_id, ty_args) .map(Rc::new) .map_err(|err| err.to_partial())?; + *state = LazyLoadedFunctionState::Resolved { fun: fun.clone(), - ty_args: ty_args.clone(), + ty_args: mem::take(ty_args), mask: *mask, + captured_layouts: Some(mem::take(captured_layouts)), }; fun }, @@ -225,7 +307,7 @@ impl LazyLoadedFunction { impl AbstractFunction for LazyLoadedFunction { fn closure_mask(&self) -> ClosureMask { - let state = self.0.borrow(); + let state = self.state.borrow(); match &*state { LazyLoadedFunctionState::Resolved { mask, .. } => *mask, LazyLoadedFunctionState::Unresolved { @@ -254,7 +336,7 @@ impl AbstractFunction for LazyLoadedFunction { fn to_canonical_string(&self) -> String { self.with_name_and_ty_args(|module_id, fun_id, ty_args| { let prefix = if let Some(m) = module_id { - format!("0x{}::{}::", m.address(), m.name()) + format!("{}::{}", m.address(), m.name()) } else { "".to_string() }; diff --git a/third_party/move/move-vm/runtime/src/module_traversal.rs b/third_party/move/move-vm/runtime/src/module_traversal.rs index e16758dd9eb..dc2c78d35ed 100644 --- a/third_party/move/move-vm/runtime/src/module_traversal.rs +++ b/third_party/move/move-vm/runtime/src/module_traversal.rs @@ -64,6 +64,26 @@ impl<'a> TraversalContext<'a> { !addr.is_special() && self.visited.insert((addr, name), ()).is_none() } + /// If the address of the specified module id is not special, adds the address-name pair to the + /// visited set and returns true. If the address is special, or if the set already contains the + /// pair, returns false. + pub fn visit_if_not_special_module_id(&mut self, module_id: &ModuleId) -> bool { + let addr = module_id.address(); + if addr.is_special() { + return false; + } + + let name = module_id.name(); + if self.visited.contains_key(&(addr, name)) { + false + } else { + let module_id = self.referenced_module_ids.alloc(module_id.clone()); + self.visited + .insert((module_id.address(), module_id.name()), ()); + true + } + } + /// No-op if address is visited, otherwise returns an invariant violation error. fn check_visited_impl(&self, addr: &AccountAddress, name: &IdentStr) -> PartialVMResult<()> { if self.visited.contains_key(&(addr, name)) { @@ -128,8 +148,9 @@ mod test { let mut traversal_context = TraversalContext::new(&traversal_storage); let special = AccountAddress::ONE; - let non_special = AccountAddress::from_hex_literal("0x123").unwrap(); - assert!(special.is_special() && !non_special.is_special()); + let non_special_1 = AccountAddress::from_hex_literal("0x123").unwrap(); + let non_special_2 = AccountAddress::from_hex_literal("0x234").unwrap(); + assert!(special.is_special() && !non_special_1.is_special() && !non_special_2.is_special()); let allocated_module_id = |addr| { let module_id = ModuleId::new(addr, ident_str!("foo").to_owned()); @@ -145,25 +166,35 @@ mod test { .expect_err("0x1 is special address and should not be visited"); assert!(!traversal_context.visit_if_not_special_address(special.address(), special.name())); + assert!(!traversal_context.visit_if_not_special_module_id(special)); assert!(traversal_context.visited.is_empty()); traversal_context .legacy_check_visited(special.address(), special.name()) .expect_err("0x1 is special address but we don't allow them to be non-visited"); - let non_special = allocated_module_id(non_special); + let non_special_1 = allocated_module_id(non_special_1); + let non_special_2 = ModuleId::new(non_special_2, ident_str!("foo").to_owned()); traversal_context - .check_is_special_or_visited(non_special.address(), non_special.name()) + .check_is_special_or_visited(non_special_1.address(), non_special_1.name()) .expect_err("0x123 is non-special address and have not been visited"); + traversal_context + .check_is_special_or_visited(non_special_2.address(), non_special_2.name()) + .expect_err("0x234 is non-special address and have not been visited"); assert!(traversal_context - .visit_if_not_special_address(non_special.address(), non_special.name())); - assert_eq!(traversal_context.visited.len(), 1); + .visit_if_not_special_address(non_special_1.address(), non_special_1.name())); + assert!(traversal_context.visit_if_not_special_module_id(&non_special_2)); + assert_eq!(traversal_context.visited.len(), 2); traversal_context - .check_is_special_or_visited(non_special.address(), non_special.name()) + .check_is_special_or_visited(non_special_1.address(), non_special_1.name()) .expect("0x123 is non-special address but have been visited"); + traversal_context + .check_is_special_or_visited(non_special_2.address(), non_special_2.name()) + .expect("0x234 is non-special address but have been visited"); // Double insertion: should not be visiting anymore. assert!(!traversal_context - .visit_if_not_special_address(non_special.address(), non_special.name())); + .visit_if_not_special_address(non_special_1.address(), non_special_1.name())); + assert!(!traversal_context.visit_if_not_special_module_id(&non_special_2)); } } diff --git a/third_party/move/move-vm/runtime/src/native_functions.rs b/third_party/move/move-vm/runtime/src/native_functions.rs index ed7f60aa00c..4c9f6e84d28 100644 --- a/third_party/move/move-vm/runtime/src/native_functions.rs +++ b/third_party/move/move-vm/runtime/src/native_functions.rs @@ -3,29 +3,43 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ + ambassador_impl_ModuleStorage, ambassador_impl_WithRuntimeEnvironment, check_dependencies_and_charge_gas, data_cache::TransactionDataCache, interpreter::InterpreterDebugInterface, + loader::{LazyLoadedFunction, LazyLoadedFunctionState}, module_traversal::TraversalContext, native_extensions::NativeContextExtensions, storage::{ module_storage::FunctionValueExtensionAdapter, ty_layout_converter::{LayoutConverter, StorageLayoutConverter}, }, - ModuleStorage, + Function, LoadedFunction, Module, ModuleStorage, RuntimeEnvironment, WithRuntimeEnvironment, +}; +use ambassador::delegate_to_methods; +use bytes::Bytes; +use move_binary_format::{ + errors::{ExecutionState, PartialVMError, PartialVMResult, VMResult}, + CompiledModule, }; -use move_binary_format::errors::{ExecutionState, PartialVMError, PartialVMResult, VMResult}; use move_core_types::{ account_address::AccountAddress, gas_algebra::{InternalGas, NumBytes}, - identifier::Identifier, + identifier::{IdentStr, Identifier}, language_storage::{ModuleId, TypeTag}, + metadata::Metadata, value::MoveTypeLayout, vm_status::StatusCode, }; use move_vm_types::{ - gas::NativeGasMeter, loaded_data::runtime_types::Type, natives::function::NativeResult, - resolver::ResourceResolver, values::Value, + gas::{ambassador_impl_DependencyGasMeter, DependencyGasMeter, NativeGasMeter}, + loaded_data::{ + runtime_types::{StructType, Type}, + struct_name_indexing::StructNameIndex, + }, + natives::function::NativeResult, + resolver::ResourceResolver, + values::{AbstractFunction, Value}, }; use std::{ collections::{HashMap, VecDeque}, @@ -233,4 +247,65 @@ impl<'b, 'c> NativeContext<'_, 'b, 'c> { module_storage: self.module_storage, } } + + /// Returns a vector of layouts for captured arguments. Used to format captured arguments as + /// strings. Returns [Ok(None)] in case layouts contain delayed fields (i.e., the values cannot + /// be formatted as strings). + pub fn get_captured_layouts_for_string_utils( + &mut self, + fun: &dyn AbstractFunction, + ) -> PartialVMResult>> { + Ok( + match &*LazyLoadedFunction::expect_this_impl(fun)?.state.borrow() { + LazyLoadedFunctionState::Unresolved { data, .. } => { + Some(data.captured_layouts.clone()) + }, + LazyLoadedFunctionState::Resolved { + fun, + mask, + captured_layouts, + .. + } => match captured_layouts.as_ref() { + Some(captured_layouts) => Some(captured_layouts.clone()), + None => LazyLoadedFunction::construct_captured_layouts( + &ModuleStorageWrapper { + module_storage: self.module_storage, + }, + &mut DependencyGasMeterWrapper { + gas_meter: self.gas_meter, + }, + self.traversal_context, + fun, + *mask, + )?, + }, + }, + ) + } +} + +// Wrappers to use trait objects where static dispatch is expected. +struct ModuleStorageWrapper<'a> { + module_storage: &'a dyn ModuleStorage, +} + +#[delegate_to_methods] +#[delegate(WithRuntimeEnvironment, target_ref = "inner")] +#[delegate(ModuleStorage, target_ref = "inner")] +impl<'a> ModuleStorageWrapper<'a> { + fn inner(&self) -> &dyn ModuleStorage { + self.module_storage + } +} + +struct DependencyGasMeterWrapper<'a> { + gas_meter: &'a mut dyn DependencyGasMeter, +} + +#[delegate_to_methods] +#[delegate(DependencyGasMeter, target_mut = "inner_mut")] +impl<'a> DependencyGasMeterWrapper<'a> { + fn inner_mut(&mut self) -> &mut dyn DependencyGasMeter { + self.gas_meter + } } diff --git a/third_party/move/move-vm/runtime/src/storage/loader/lazy.rs b/third_party/move/move-vm/runtime/src/storage/loader/lazy.rs index 284e0e78ac2..e15b41f4115 100644 --- a/third_party/move/move-vm/runtime/src/storage/loader/lazy.rs +++ b/third_party/move/move-vm/runtime/src/storage/loader/lazy.rs @@ -40,13 +40,10 @@ where traversal_context: &mut TraversalContext, module_id: &ModuleId, ) -> PartialVMResult<()> { - let module_id = traversal_context - .referenced_module_ids - .alloc(module_id.clone()); - let addr = module_id.address(); - let name = module_id.name(); + if traversal_context.visit_if_not_special_module_id(module_id) { + let addr = module_id.address(); + let name = module_id.name(); - if traversal_context.visit_if_not_special_address(addr, name) { let size = self .module_storage .unmetered_get_module_size(addr, name) diff --git a/third_party/move/move-vm/runtime/src/storage/module_storage.rs b/third_party/move/move-vm/runtime/src/storage/module_storage.rs index 9bd2c5eadf2..64b48543ef7 100644 --- a/third_party/move/move-vm/runtime/src/storage/module_storage.rs +++ b/third_party/move/move-vm/runtime/src/storage/module_storage.rs @@ -4,7 +4,6 @@ use crate::{ loader::{Function, LazyLoadedFunction, LazyLoadedFunctionState, LoadedFunctionOwner, Module}, logging::expect_no_verification_errors, - storage::ty_layout_converter::{LayoutConverter, StorageLayoutConverter}, LoadedFunction, WithRuntimeEnvironment, }; use ambassador::delegatable_trait; @@ -555,6 +554,7 @@ where /// Avoids the orphan rule to implement external [FunctionValueExtension] for any generic type that /// implements [ModuleStorage]. pub struct FunctionValueExtensionAdapter<'a> { + #[allow(dead_code)] pub(crate) module_storage: &'a dyn ModuleStorage, } @@ -582,40 +582,23 @@ impl FunctionValueExtension for FunctionValueExtensionAdapter<'_> { &self, fun: &dyn AbstractFunction, ) -> PartialVMResult { - match &*LazyLoadedFunction::expect_this_impl(fun)?.0.borrow() { + match &*LazyLoadedFunction::expect_this_impl(fun)?.state.borrow() { LazyLoadedFunctionState::Unresolved { data, .. } => Ok(data.clone()), - LazyLoadedFunctionState::Resolved { fun, mask, ty_args } => { - let ty_converter = StorageLayoutConverter::new(self.module_storage); - let ty_builder = &self - .module_storage - .runtime_environment() - .vm_config() - .ty_builder; - - let captured_layouts = mask - .extract(fun.param_tys(), true) - .into_iter() - .map(|ty| { - let (layout, contains_delayed_fields) = if fun.ty_args.is_empty() { - ty_converter.type_to_type_layout_with_identifier_mappings(ty)? - } else { - let ty = ty_builder.create_ty_with_subst(ty, &fun.ty_args)?; - ty_converter.type_to_type_layout_with_identifier_mappings(&ty)? - }; - - // Do not allow delayed fields to be serialized. - if contains_delayed_fields { - let err = PartialVMError::new(StatusCode::VALUE_SERIALIZATION_ERROR) - .with_message( - "Function values that capture delayed fields cannot be serialized" - .to_string(), - ); - return Err(err); - } - - Ok(layout) - }) - .collect::>>()?; + LazyLoadedFunctionState::Resolved { + fun, + mask, + ty_args, + captured_layouts, + } => { + // If there are no captured layouts, then this closure is non-storable, i.e., the + // function is not persistent (not public or not private with #[persistent] + // attribute). This means that anonymous lambda-lifted functions are cannot be + // serialized as well. + let captured_layouts = captured_layouts.as_ref().cloned().ok_or_else(|| { + let msg = "Captured layouts must always be computed for storable closures"; + PartialVMError::new(StatusCode::VALUE_SERIALIZATION_ERROR) + .with_message(msg.to_string()) + })?; Ok(SerializedFunctionData { format_version: FUNCTION_DATA_SERIALIZATION_FORMAT_V1, diff --git a/third_party/move/move-vm/transactional-tests/tests/display/print_values.exp b/third_party/move/move-vm/transactional-tests/tests/display/print_values.exp index 94f8b5b43fa..442f9b501a4 100644 --- a/third_party/move/move-vm/transactional-tests/tests/display/print_values.exp +++ b/third_party/move/move-vm/transactional-tests/tests/display/print_values.exp @@ -1,49 +1,55 @@ processed 17 tasks -task 1 'run'. lines 87-87: +task 1 'run'. lines 88-88: return values: true -task 2 'run'. lines 89-89: +task 2 'run'. lines 90-90: return values: 0 -task 3 'run'. lines 91-91: +task 3 'run'. lines 92-92: return values: 1 -task 4 'run'. lines 93-93: +task 4 'run'. lines 94-94: return values: 2 -task 5 'run'. lines 95-95: +task 5 'run'. lines 96-96: return values: 3 -task 6 'run'. lines 97-97: +task 6 'run'. lines 98-98: return values: 4 -task 7 'run'. lines 99-99: +task 7 'run'. lines 100-100: return values: 0000000000000000000000000000000000000000000000000000000000000006 -task 8 'run'. lines 101-101: +task 8 'run'. lines 102-102: return values: [1, 2] -task 9 'run'. lines 103-103: +task 9 'run'. lines 104-104: return values: { 0, 0000000000000000000000000000000000000000000000000000000000000042 } -task 10 'run'. lines 105-105: +task 10 'run'. lines 106-106: return values: { { 1, 23 }, [1, 2, 3] } -task 11 'run'. lines 107-107: -return values: 0x0x0000000000000000000000000000000000000000000000000000000000000042::print_values::::__lambda__1__return_anonymous(..) +task 11 'run'. lines 108-108: +Error: Function execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} -task 12 'run'. lines 109-109: -return values: 0x0x0000000000000000000000000000000000000000000000000000000000000042::print_values::::sum(..) +task 12 'run'. lines 110-110: +return values: 0x0000000000000000000000000000000000000000000000000000000000000042::print_values::sum(..) -task 13 'run'. lines 111-111: -return values: 0x0x0000000000000000000000000000000000000000000000000000000000000042::print_values::::sum(U64(5), ..) +task 13 'run'. lines 112-112: +return values: 0x0000000000000000000000000000000000000000000000000000000000000042::print_values::sum(U64(5), ..) -task 14 'run'. lines 113-113: -return values: 0x0x0000000000000000000000000000000000000000000000000000000000000042::print_values::::sum(_, U64(10), ..) +task 14 'run'. lines 114-114: +return values: 0x0000000000000000000000000000000000000000000000000000000000000042::print_values::sum(_, U64(10), ..) -task 15 'run'. lines 115-115: -return values: 0x0x0000000000000000000000000000000000000000000000000000000000000042::print_values::::sum(U64(2), U64(1), ..) +task 15 'run'. lines 116-116: +return values: 0x0000000000000000000000000000000000000000000000000000000000000042::print_values::sum(U64(2), U64(1), ..) -task 16 'run'. lines 117-117: -return values: 0x0x0000000000000000000000000000000000000000000000000000000000000042::print_values::::__lambda__1__return_closure_capture_struct((container: [(container: [U16(1), U8(23)]), (container: [1, 2, 3])]), ..) +task 16 'run'. lines 118-118: +return values: 0x0000000000000000000000000000000000000000000000000000000000000042::print_values::return_struct(..) diff --git a/third_party/move/move-vm/transactional-tests/tests/display/print_values.move b/third_party/move/move-vm/transactional-tests/tests/display/print_values.move index 29b25f8f936..5627bfff8ef 100644 --- a/third_party/move/move-vm/transactional-tests/tests/display/print_values.move +++ b/third_party/move/move-vm/transactional-tests/tests/display/print_values.move @@ -58,6 +58,8 @@ module 0x42::print_values { a + b } + // Note: fails with invariant violation because MoveVM serializes the return value, and returned value is not + // serializable because it is an anonymous lambda-lifted function. public fun return_anonymous(): || { || {} } @@ -79,8 +81,7 @@ module 0x42::print_values { } public fun return_closure_capture_struct(): ||B { - let b = B { a: A::V1 { x: 23 }, data: vector[1, 2, 3] }; - || { b } + return_struct } } diff --git a/third_party/move/move-vm/types/src/gas.rs b/third_party/move/move-vm/types/src/gas.rs index a22044defa8..2409ad5496a 100644 --- a/third_party/move/move-vm/types/src/gas.rs +++ b/third_party/move/move-vm/types/src/gas.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::views::{TypeView, ValueView}; +use ambassador::delegatable_trait; use move_binary_format::{ errors::PartialVMResult, file_format::CodeOffset, file_format_common::Opcodes, }; @@ -143,6 +144,7 @@ impl SimpleInstruction { /// /// Note: because native functions are trait objects, it is not possible to make [GasMeter] a trait /// object as well as it has APIs that are generic. +#[delegatable_trait] pub trait DependencyGasMeter { fn charge_dependency( &mut self, diff --git a/third_party/move/move-vm/types/src/value_serde.rs b/third_party/move/move-vm/types/src/value_serde.rs index 25fc6698d9a..2aa2ee51f7c 100644 --- a/third_party/move/move-vm/types/src/value_serde.rs +++ b/third_party/move/move-vm/types/src/value_serde.rs @@ -69,10 +69,6 @@ impl DelayedFieldsExtension<'_> { #[derive(Clone)] pub(crate) struct FunctionValueExtensionWithContext<'a> { extension: &'a dyn FunctionValueExtension, - /// Marker to indicate that function value serialization failed. Used to ensure we propagate - /// error status code correctly, as otherwise any serialization failure is treated as an - /// invariant violation. - function_value_serialization_error: RefCell>, } impl<'a> FunctionValueExtensionWithContext<'a> { @@ -81,11 +77,7 @@ impl<'a> FunctionValueExtensionWithContext<'a> { &self, fun: &dyn AbstractFunction, ) -> PartialVMResult { - self.extension - .get_serialization_data(fun) - .inspect_err(|err| { - *self.function_value_serialization_error.borrow_mut() = Some(err.clone()); - }) + self.extension.get_serialization_data(fun) } /// Creates a function from serialized data. @@ -130,10 +122,7 @@ impl<'a> ValueSerDeContext<'a> { mut self, extension: &'a dyn FunctionValueExtension, ) -> Self { - self.function_extension = Some(FunctionValueExtensionWithContext { - extension, - function_value_serialization_error: RefCell::new(None), - }); + self.function_extension = Some(FunctionValueExtensionWithContext { extension }); self } @@ -223,17 +212,6 @@ impl<'a> ValueSerDeContext<'a> { )); } } - - // Check if the error is because of function value serialization. - if let Some(function_extension) = self.function_extension { - if let Some(err) = function_extension - .function_value_serialization_error - .into_inner() - { - return Err(err); - } - } - Ok(None) }, } From ee0ce8a60ccdff44f09832d33d3e66823b9762d1 Mon Sep 17 00:00:00 2001 From: George Mitenkov Date: Wed, 2 Jul 2025 19:29:51 +0100 Subject: [PATCH 023/260] [API] Removing TODO for fat types (#16984) Downstreamed-from: 5a35113425cd3bb50291022c7c4a843f0acef286 --- .../move/tools/move-resource-viewer/src/lib.rs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/third_party/move/tools/move-resource-viewer/src/lib.rs b/third_party/move/tools/move-resource-viewer/src/lib.rs index 193c1d8cadf..eb61043d821 100644 --- a/third_party/move/tools/move-resource-viewer/src/lib.rs +++ b/third_party/move/tools/move-resource-viewer/src/lib.rs @@ -456,17 +456,9 @@ impl MoveValueAnnotator { TypeTag::U256 => FatType::U256, TypeTag::U128 => FatType::U128, TypeTag::Vector(ty) => FatType::Vector(Box::new(self.resolve_type_impl(ty, limit)?)), - TypeTag::Function(function_tag) => { - let mut convert_tags = |tags: &[TypeTag]| { - tags.iter() - .map(|t| self.resolve_type_impl(t, limit)) - .collect::>>() - }; - FatType::Function(Box::new(FatFunctionType { - args: convert_tags(&function_tag.args)?, - results: convert_tags(&function_tag.results)?, - abilities: function_tag.abilities, - })) + TypeTag::Function(..) => { + // TODO(#15664) implement functions for fat types + bail!("TODO: support functions for fat types") }, }) } From 2ae3bf3bb9e16631b3bef1d57b72fa1ce7f1f2c4 Mon Sep 17 00:00:00 2001 From: Vineeth Kashyap Date: Wed, 2 Jul 2025 16:05:55 -0400 Subject: [PATCH 024/260] [vm] [bytecode-verifier] More limits checking in the bytecode verifier (#16982) Downstreamed-from: ddc0df46fe3d2df519492b0889d85ebe6bacb147 --- .../aptos-vm-environment/src/prod_configs.rs | 17 ++++- .../src/unit_tests/large_type_test.rs | 2 +- .../src/unit_tests/vec_pack_tests.rs | 2 +- .../move/move-bytecode-verifier/src/limits.rs | 73 +++++++++++++++---- .../move-bytecode-verifier/src/type_safety.rs | 2 + .../move-bytecode-verifier/src/verifier.rs | 12 ++- .../tests/misc/too_many_returns.exp | 10 +++ .../tests/misc/too_many_returns.move | 6 ++ .../tests/misc/vector_depth_check.exp | 13 ++++ .../tests/misc/vector_depth_check.move | 17 +++++ .../no-v1-comparison/closures/bug_16492.exp | 10 +++ .../no-v1-comparison/closures/bug_16492.move | 8 ++ .../no-v1-comparison/closures/misc_1.exp | 11 ++- .../no-v1-comparison/closures/misc_1.move | 15 +++- 14 files changed, 175 insertions(+), 23 deletions(-) create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/misc/too_many_returns.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/misc/too_many_returns.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/misc/vector_depth_check.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/misc/vector_depth_check.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16492.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16492.move diff --git a/aptos-move/aptos-vm-environment/src/prod_configs.rs b/aptos-move/aptos-vm-environment/src/prod_configs.rs index 2341dc16806..5131c622f39 100644 --- a/aptos-move/aptos-vm-environment/src/prod_configs.rs +++ b/aptos-move/aptos-vm-environment/src/prod_configs.rs @@ -82,6 +82,7 @@ pub fn aptos_prod_verifier_config(features: &Features) -> VerifierConfig { let enable_resource_access_control = features.is_enabled(FeatureFlag::ENABLE_RESOURCE_ACCESS_CONTROL); let enable_function_values = features.is_enabled(FeatureFlag::ENABLE_FUNCTION_VALUES); + // Note: we reuse the `enable_function_values` flag to set various stricter limits on types. VerifierConfig { max_loop_depth: Some(5), @@ -89,7 +90,11 @@ pub fn aptos_prod_verifier_config(features: &Features) -> VerifierConfig { max_function_parameters: Some(128), max_basic_blocks: Some(1024), max_value_stack_size: 1024, - max_type_nodes: Some(256), + max_type_nodes: if enable_function_values { + Some(128) + } else { + Some(256) + }, max_push_size: Some(10000), max_struct_definitions: None, max_struct_variants: None, @@ -105,6 +110,16 @@ pub fn aptos_prod_verifier_config(features: &Features) -> VerifierConfig { enable_enum_types, enable_resource_access_control, enable_function_values, + max_function_return_values: if enable_function_values { + Some(128) + } else { + None + }, + max_type_depth: if enable_function_values { + Some(20) + } else { + None + }, } } diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/large_type_test.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/large_type_test.rs index 1bb45fd6b9c..4bf8a89ce65 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/large_type_test.rs +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/large_type_test.rs @@ -160,6 +160,6 @@ fn test_large_types() { ); assert_eq!( result.unwrap_err().major_status(), - StatusCode::CONSTRAINT_NOT_SATISFIED, + StatusCode::TOO_MANY_TYPE_NODES, ); } diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/vec_pack_tests.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/vec_pack_tests.rs index 4a119ab4b50..5d215549ed2 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/vec_pack_tests.rs +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/vec_pack_tests.rs @@ -67,5 +67,5 @@ fn test_vec_pack() { &m, ) .unwrap_err(); - assert_eq!(res.major_status(), StatusCode::VALUE_STACK_PUSH_OVERFLOW); + assert_eq!(res.major_status(), StatusCode::TOO_MANY_TYPE_NODES); } diff --git a/third_party/move/move-bytecode-verifier/src/limits.rs b/third_party/move/move-bytecode-verifier/src/limits.rs index 1fcb2436be6..54542e16b18 100644 --- a/third_party/move/move-bytecode-verifier/src/limits.rs +++ b/third_party/move/move-bytecode-verifier/src/limits.rs @@ -81,7 +81,14 @@ impl<'a> LimitsVerifier<'a> { return Err(PartialVMError::new(StatusCode::TOO_MANY_PARAMETERS) .at_index(IndexKind::FunctionHandle, idx as u16)); } + } + if let Some(limit) = config.max_function_return_values { + if self.resolver.signature_at(function_handle.return_).0.len() > limit { + return Err(PartialVMError::new(StatusCode::TOO_MANY_PARAMETERS) + .at_index(IndexKind::FunctionHandle, idx as u16)); + } }; + // Note: the size of `attributes` is limited by the deserializer. } Ok(()) } @@ -122,24 +129,58 @@ impl<'a> LimitsVerifier<'a> { config: &VerifierConfig, ty: &SignatureToken, ) -> PartialVMResult<()> { - if let Some(max) = &config.max_type_nodes { - // Structs and Parameters can expand to an unknown number of nodes, therefore - // we give them a higher size weight here. - const STRUCT_SIZE_WEIGHT: usize = 4; - const PARAM_SIZE_WEIGHT: usize = 4; - let mut size = 0; - for t in ty.preorder_traversal() { - // Notice that the preorder traversal will iterate all type instantiations, so we - // why we can ignore them below. - match t { - SignatureToken::Struct(..) | SignatureToken::StructInstantiation(..) => { - size += STRUCT_SIZE_WEIGHT - }, - SignatureToken::TypeParameter(..) => size += PARAM_SIZE_WEIGHT, - _ => size += 1, + if config.max_type_nodes.is_none() + && config.max_function_parameters.is_none() + && config.max_function_return_values.is_none() + && config.max_type_depth.is_none() + { + // If no type-related limits are set, we do not need to verify the type nodes. + return Ok(()); + } + // Structs and Parameters can expand to an unknown number of nodes, therefore + // we give them a higher size weight here. + const STRUCT_SIZE_WEIGHT: usize = 4; + const PARAM_SIZE_WEIGHT: usize = 4; + let mut type_size = 0; + for (token, depth) in ty.preorder_traversal_with_depth() { + if let Some(limit) = config.max_type_depth { + if depth > limit { + return Err(PartialVMError::new(StatusCode::TOO_MANY_TYPE_NODES)); } } - if size > *max { + match token { + SignatureToken::Struct(..) | SignatureToken::StructInstantiation(..) => { + type_size += STRUCT_SIZE_WEIGHT + }, + SignatureToken::TypeParameter(..) => type_size += PARAM_SIZE_WEIGHT, + SignatureToken::Function(params, ret, _) => { + if let Some(limit) = config.max_function_parameters { + if params.len() > limit { + return Err(PartialVMError::new(StatusCode::TOO_MANY_PARAMETERS)); + } + } + if let Some(limit) = config.max_function_return_values { + if ret.len() > limit { + return Err(PartialVMError::new(StatusCode::TOO_MANY_PARAMETERS)); + } + } + }, + SignatureToken::Bool + | SignatureToken::U8 + | SignatureToken::U16 + | SignatureToken::U32 + | SignatureToken::U64 + | SignatureToken::U128 + | SignatureToken::U256 + | SignatureToken::Address + | SignatureToken::Signer + | SignatureToken::Vector(_) + | SignatureToken::Reference(_) + | SignatureToken::MutableReference(_) => type_size += 1, + } + } + if let Some(limit) = config.max_type_nodes { + if type_size > limit { return Err(PartialVMError::new(StatusCode::TOO_MANY_TYPE_NODES)); } } diff --git a/third_party/move/move-bytecode-verifier/src/type_safety.rs b/third_party/move/move-bytecode-verifier/src/type_safety.rs index 60beb13850d..bef08fed008 100644 --- a/third_party/move/move-bytecode-verifier/src/type_safety.rs +++ b/third_party/move/move-bytecode-verifier/src/type_safety.rs @@ -361,6 +361,8 @@ fn clos_pack( }; // Check the captured arguments on the stack let param_sgn = verifier.resolver.signature_at(func_handle.parameters); + // Instruction consistency check has verified that the number of captured arguments + // is less than or equal to the number of parameters of the function. let captured_param_tys = mask.extract(¶m_sgn.0, true); for ty in captured_param_tys.into_iter().rev() { let arg = safe_unwrap!(verifier.stack.pop()); diff --git a/third_party/move/move-bytecode-verifier/src/verifier.rs b/third_party/move/move-bytecode-verifier/src/verifier.rs index d358a73537a..10d64d4659a 100644 --- a/third_party/move/move-bytecode-verifier/src/verifier.rs +++ b/third_party/move/move-bytecode-verifier/src/verifier.rs @@ -43,6 +43,10 @@ pub struct VerifierConfig { pub enable_enum_types: bool, pub enable_resource_access_control: bool, pub enable_function_values: bool, + /// Maximum number of function return values. + pub max_function_return_values: Option, + /// Maximum depth of a type node. + pub max_type_depth: Option, } /// Helper for a "canonical" verification of a module. @@ -242,6 +246,9 @@ impl Default for VerifierConfig { enable_enum_types: true, enable_resource_access_control: true, enable_function_values: true, + + max_function_return_values: None, + max_type_depth: None, } } } @@ -265,7 +272,7 @@ impl VerifierConfig { max_basic_blocks: Some(1024), max_basic_blocks_in_script: Some(1024), max_value_stack_size: 1024, - max_type_nodes: Some(256), + max_type_nodes: Some(128), max_push_size: Some(10000), max_struct_definitions: Some(200), max_fields_in_struct: Some(30), @@ -287,6 +294,9 @@ impl VerifierConfig { enable_enum_types: true, enable_resource_access_control: true, enable_function_values: true, + + max_function_return_values: Some(128), + max_type_depth: Some(20), } } } diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/too_many_returns.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/too_many_returns.exp new file mode 100644 index 00000000000..b8d226a84aa --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/too_many_returns.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-6: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000c0ffee::m'. Got VMError: { + major_status: TOO_MANY_PARAMETERS, + sub_status: None, + location: 0xc0ffee::m, + indices: [(FunctionHandle, 0)], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/too_many_returns.move b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/too_many_returns.move new file mode 100644 index 00000000000..d9e9d880213 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/too_many_returns.move @@ -0,0 +1,6 @@ +//# publish +module 0xc0ffee::m { + public fun test(): (u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64, u64) { + (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130) + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/vector_depth_check.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/vector_depth_check.exp new file mode 100644 index 00000000000..f5e54cfe925 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/vector_depth_check.exp @@ -0,0 +1,13 @@ +processed 3 tasks + +task 1 'run'. lines 9-9: +return values: 0 + +task 2 'publish'. lines 11-17: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000c0ffee::n'. Got VMError: { + major_status: TOO_MANY_TYPE_NODES, + sub_status: None, + location: 0xc0ffee::n, + indices: [], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/misc/vector_depth_check.move b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/vector_depth_check.move new file mode 100644 index 00000000000..f6d36c77246 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/misc/vector_depth_check.move @@ -0,0 +1,17 @@ +//# publish +module 0xc0ffee::m { + public fun test(): u64 { + let v: vector>>>> = vector[]; + std::vector::length(&v) + } +} + +//# run 0xc0ffee::m::test + +//# publish +module 0xc0ffee::n { + public fun test(): u64 { + let v: vector>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> = vector[]; + std::vector::length(&v) + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16492.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16492.exp new file mode 100644 index 00000000000..8020ce7cb9c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16492.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-8: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000066::work'. Got VMError: { + major_status: TOO_MANY_PARAMETERS, + sub_status: None, + location: 0x66::work, + indices: [], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16492.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16492.move new file mode 100644 index 00000000000..0817077e4e8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16492.move @@ -0,0 +1,8 @@ +//# publish +module 0x66::work { + use 0x1::vector; + + public entry fun foo() { + let _: vector<|u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64,u64| has drop> = vector::empty(); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.exp index 29ffe449a8e..ef598c60183 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.exp +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.exp @@ -1,4 +1,4 @@ -processed 6 tasks +processed 7 tasks task 1 'run'. lines 31-31: Error: Function execution failed with VMError: { @@ -11,3 +11,12 @@ Error: Function execution failed with VMError: { task 5 'run'. lines 48-48: return values: 42 + +task 6 'publish'. lines 50-59: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000c0ffee::o'. Got VMError: { + major_status: TOO_MANY_TYPE_NODES, + sub_status: None, + location: 0xc0ffee::o, + indices: [], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.move index 92875ee174c..97e0b9219a8 100644 --- a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.move +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/misc_1.move @@ -37,8 +37,8 @@ module 0xc0ffee::m { //# publish module 0xc0ffee::n { public fun test(x: u64): u64 { - let f = || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || |x| x; - let f1 = |x| f()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()(x); + let f = || || || || || || || || || || |x| x; + let f1 = |x| f()()()()()()()()()()(x); let f2 = |f| f(x); let f3 = |f1, f2| f1(f2); f3(f2, f1) @@ -46,3 +46,14 @@ module 0xc0ffee::n { } //# run 0xc0ffee::n::test --args 42 + +//# publish +module 0xc0ffee::o { + public fun test(x: u64): u64 { + let f = || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || || |x| x; + let f1 = |x| f()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()(x); + let f2 = |f| f(x); + let f3 = |f1, f2| f1(f2); + f3(f2, f1) + } +} From d84dd9908ffb9ea192893d619196cb2390c95cf8 Mon Sep 17 00:00:00 2001 From: Jake Silverman Date: Wed, 2 Jul 2025 16:00:30 -0700 Subject: [PATCH 025/260] [Compiler] Patch issue where prover doesn't handle package visibility properly during filter mode (#16980) Downstreamed-from: dd326acc00b5bd1d7e2fc45d5e36e90934a76fdc --- aptos-move/framework/src/prover.rs | 9 +++++- .../src/env_pipeline/function_checker.rs | 28 +++++++++++++------ .../move/move-compiler-v2/src/experiments.rs | 7 +++++ .../src/compilation/model_builder.rs | 7 +++++ 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/aptos-move/framework/src/prover.rs b/aptos-move/framework/src/prover.rs index 44e437a5173..5e77792c727 100644 --- a/aptos-move/framework/src/prover.rs +++ b/aptos-move/framework/src/prover.rs @@ -8,6 +8,7 @@ use codespan_reporting::{ term::termcolor::{ColorChoice, StandardStream}, }; use log::{info, LevelFilter}; +use move_compiler_v2::Experiment; use move_core_types::account_address::AccountAddress; use move_model::{ metadata::{CompilerVersion, LanguageVersion}, @@ -148,6 +149,12 @@ impl ProverOptions { let now = Instant::now(); let for_test = self.for_test; let benchmark = self.benchmark; + let mut experiments_vec = experiments.to_vec(); + // If `filter` is `some` then only the files filtered for are primary targets. + // This interferes with the package visibility check in the function checker. + if self.filter.is_some() { + experiments_vec.push(Experiment::UNSAFE_PACKAGE_VISIBILITY.to_string()); + }; let mut model = build_model( dev_mode, package_path, @@ -158,7 +165,7 @@ impl ProverOptions { language_version, skip_attribute_checks, known_attributes.clone(), - experiments.to_vec(), + experiments_vec, )?; let mut options = self.convert_options(package_path)?; options.language_version = language_version; diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/function_checker.rs b/third_party/move/move-compiler-v2/src/env_pipeline/function_checker.rs index 1d99fc2bc5d..9f29a8e6b26 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/function_checker.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/function_checker.rs @@ -3,7 +3,7 @@ //! Do a few checks of functions and function calls. -use crate::Options; +use crate::{experiments::Experiment, Options}; use codespan_reporting::diagnostic::Severity; use move_binary_format::file_format::Visibility; use move_model::{ @@ -533,13 +533,25 @@ pub fn check_access_and_use(env: &mut GlobalEnv, before_inlining: bool) { caller_func.module_env.get_full_name_str() ); } else { - call_package_fun_from_diff_package_error( - env, - sites, - &caller_func, - &callee_func, - ); - false + // With "unsafe package visibility" experiment on, all package functions are made + // visible in all modules with the same address. The prover uses this in filter mode + // to get around the lack of package-based target filtering functionality. + let options = env + .get_extension::() + .expect("Options is available"); + if options.experiment_on( + Experiment::UNSAFE_PACKAGE_VISIBILITY, + ) { + true + } else { + call_package_fun_from_diff_package_error( + env, + sites, + &caller_func, + &callee_func, + ); + false + } } } else { call_package_fun_from_diff_addr_error( diff --git a/third_party/move/move-compiler-v2/src/experiments.rs b/third_party/move/move-compiler-v2/src/experiments.rs index 615dd41c1c7..4379809ece0 100644 --- a/third_party/move/move-compiler-v2/src/experiments.rs +++ b/third_party/move/move-compiler-v2/src/experiments.rs @@ -270,6 +270,12 @@ pub static EXPERIMENTS: Lazy> = Lazy::new(|| { .to_string(), default: Given(false), }, + Experiment { + name: Experiment::UNSAFE_PACKAGE_VISIBILITY.to_string(), + description: "Treat all package functions with same address as visible (currently necessary for prover in filter mode)" + .to_string(), + default: Given(false), + }, ]; experiments .into_iter() @@ -318,6 +324,7 @@ impl Experiment { pub const STOP_BEFORE_FILE_FORMAT: &'static str = "stop-before-file-format"; pub const STOP_BEFORE_STACKLESS_BYTECODE: &'static str = "stop-before-stackless-bytecode"; pub const UNINITIALIZED_CHECK: &'static str = "uninitialized-check"; + pub const UNSAFE_PACKAGE_VISIBILITY: &'static str = "unsafe-package-visibility"; pub const UNUSED_ASSIGNMENT_CHECK: &'static str = "unused-assignment-check"; pub const UNUSED_STRUCT_PARAMS_CHECK: &'static str = "unused-struct-params-check"; pub const USAGE_CHECK: &'static str = "usage-check"; diff --git a/third_party/move/tools/move-package/src/compilation/model_builder.rs b/third_party/move/tools/move-package/src/compilation/model_builder.rs index 6762736742d..c5511f85a50 100644 --- a/third_party/move/tools/move-package/src/compilation/model_builder.rs +++ b/third_party/move/tools/move-package/src/compilation/model_builder.rs @@ -140,6 +140,13 @@ impl ModelBuilder { options.known_attributes.clone_from(known_attributes); options.skip_attribute_checks = skip_attribute_checks; options.compile_verify_code = true; + options.experiments.clone_from( + &self + .resolution_graph + .build_options + .compiler_config + .experiments, + ); let mut error_writer = StandardStream::stderr(ColorChoice::Auto); move_compiler_v2::run_move_compiler_for_analysis(&mut error_writer, options) }, From c601fba5484dc0023a1f070573723358a7f16df3 Mon Sep 17 00:00:00 2001 From: Vineeth Kashyap Date: Thu, 3 Jul 2025 14:44:14 -0400 Subject: [PATCH 026/260] [compiler-v2] Fix bug in total order sorting of error/warnings (#16996) Downstreamed-from: a61a7c1236ce28207d388746a579aa59bcfcf0da --- .../tests/ability-check/ability_violation.exp | 12 +- .../typing/constant_non_base_type.exp | 12 +- .../no-v1-comparison/closures/bug_16919.exp | 545 ++++++++++++++++++ .../no-v1-comparison/closures/bug_16919.move | 179 ++++++ third_party/move/move-model/src/model.rs | 67 +-- 5 files changed, 759 insertions(+), 56 deletions(-) create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16919.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16919.move diff --git a/third_party/move/move-compiler-v2/tests/ability-check/ability_violation.exp b/third_party/move/move-compiler-v2/tests/ability-check/ability_violation.exp index 449755574b0..bb5deed1f94 100644 --- a/third_party/move/move-compiler-v2/tests/ability-check/ability_violation.exp +++ b/third_party/move/move-compiler-v2/tests/ability-check/ability_violation.exp @@ -1,18 +1,18 @@ Diagnostics: -error: local `x` of type `Impotent` does not have the `copy` ability +error: value of type `Impotent` does not have the `drop` ability ┌─ tests/ability-check/ability_violation.move:7:10 │ 7 │ (x, x); - │ ^ - used here - │ │ - │ copy needed here because value is still in use + │ ^ implicitly dropped here since it is no longer used -error: value of type `Impotent` does not have the `drop` ability +error: local `x` of type `Impotent` does not have the `copy` ability ┌─ tests/ability-check/ability_violation.move:7:10 │ 7 │ (x, x); - │ ^ implicitly dropped here since it is no longer used + │ ^ - used here + │ │ + │ copy needed here because value is still in use error: value of type `Impotent` does not have the `drop` ability ┌─ tests/ability-check/ability_violation.move:7:13 diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/constant_non_base_type.exp b/third_party/move/move-compiler-v2/tests/checking/typing/constant_non_base_type.exp index d1e07c3fbf0..2847d147f78 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/constant_non_base_type.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/constant_non_base_type.exp @@ -16,6 +16,12 @@ error: Invalid type for constant │ │ │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. +error: expected `&mut u64` but found a value of type `&u64` (mutability mismatch) + ┌─ tests/checking/typing/constant_non_base_type.move:4:26 + │ +4 │ const C2: &mut u64 = &0; + │ ^^ + error: Not a valid constant expression. ┌─ tests/checking/typing/constant_non_base_type.move:4:26 │ @@ -32,12 +38,6 @@ error: Invalid type for constant │ │ │ Expected one of `u8`, `u16, `u32`, `u64`, `u128`, `u256`, `bool`, `address`, or `vector<_>` with valid element type. -error: expected `&mut u64` but found a value of type `&u64` (mutability mismatch) - ┌─ tests/checking/typing/constant_non_base_type.move:4:26 - │ -4 │ const C2: &mut u64 = &0; - │ ^^ - error: Invalid type for constant ┌─ tests/checking/typing/constant_non_base_type.move:5:20 │ diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16919.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16919.exp new file mode 100644 index 00000000000..2581c43420a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16919.exp @@ -0,0 +1,545 @@ +processed 1 task + +task 0 'publish'. lines 1-179: +Error: compilation errors: + warning: Unused value of parameter `var0`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var0`), or binding to `_` + ┌─ TEMPFILE:30:27 + │ +30 │ public fun function1( var0: &mut Enum1, var1: &mut Enum1, var2: &mut Enum1, var3: &mut Enum1) { /* _block0 */ + │ ^^^^ + +warning: Unused value of parameter `var1`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var1`), or binding to `_` + ┌─ TEMPFILE:30:45 + │ +30 │ public fun function1( var0: &mut Enum1, var1: &mut Enum1, var2: &mut Enum1, var3: &mut Enum1) { /* _block0 */ + │ ^^^^ + +warning: Unused value of parameter `var2`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var2`), or binding to `_` + ┌─ TEMPFILE:30:63 + │ +30 │ public fun function1( var0: &mut Enum1, var1: &mut Enum1, var2: &mut Enum1, var3: &mut Enum1) { /* _block0 */ + │ ^^^^ + +warning: Unused value of parameter `var3`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var3`), or binding to `_` + ┌─ TEMPFILE:30:81 + │ +30 │ public fun function1( var0: &mut Enum1, var1: &mut Enum1, var2: &mut Enum1, var3: &mut Enum1) { /* _block0 */ + │ ^^^^ + +warning: Unused value of parameter `var15`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var15`), or binding to `_` + ┌─ TEMPFILE:32:72 + │ +32 │ public fun function2( var12: &Enum0, var13: Struct0, var14: Enum1, var15: Struct0, var16: | u32 | has copy+drop): u8 { /* _block1 */ + │ ^^^^^ + +warning: Unused value of parameter `var16`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var16`), or binding to `_` + ┌─ TEMPFILE:32:88 + │ +32 │ public fun function2( var12: &Enum0, var13: Struct0, var14: Enum1, var15: Struct0, var16: | u32 | has copy+drop): u8 { /* _block1 */ + │ ^^^^^ + +warning: Unused value of parameter `var17`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var17`), or binding to `_` + ┌─ TEMPFILE:33:43 + │ +33 │ *( &( Enum0::Variant1 { field5: | var17: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var18: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block2 */ + │ ^^^^^ + +warning: Unused value of parameter `var18`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var18`), or binding to `_` + ┌─ TEMPFILE:33:152 + │ +33 │ *( &( Enum0::Variant1 { field5: | var17: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var18: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block2 */ + │ ^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var19` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var19`), or renaming to `_` + ┌─ TEMPFILE:39:25 + │ +39 │ let var19 = *( &( false)); + │ ^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var24` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var24`), or renaming to `_` + ┌─ TEMPFILE:42:17 + │ +42 │ Enum1::Variant4 {field10: var24, ..} => { /* _block6 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var20` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var20`), or renaming to `_` + ┌─ TEMPFILE:45:17 + │ +45 │ Enum1::Variant2 {field6: var20, field7: var21,} => { /* _block13 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var21` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var21`), or renaming to `_` + ┌─ TEMPFILE:45:17 + │ +45 │ Enum1::Variant2 {field6: var20, field7: var21,} => { /* _block13 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var38` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var38`), or renaming to `_` + ┌─ TEMPFILE:47:29 + │ +47 │ Enum1::Variant3 {field8: var38, field9: var39,} => | var42: bool, var43: Struct1, var44: Enum0 | { /* _block18 */ ( 18858u16 ^ 18170u16)}, + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var39` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var39`), or renaming to `_` + ┌─ TEMPFILE:47:29 + │ +47 │ Enum1::Variant3 {field8: var38, field9: var39,} => | var42: bool, var43: Struct1, var44: Enum0 | { /* _block18 */ ( 18858u16 ^ 18170u16)}, + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: Unused value of parameter `var42`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var42`), or binding to `_` + ┌─ TEMPFILE:47:82 + │ +47 │ Enum1::Variant3 {field8: var38, field9: var39,} => | var42: bool, var43: Struct1, var44: Enum0 | { /* _block18 */ ( 18858u16 ^ 18170u16)}, + │ ^^^^^ + +warning: Unused value of parameter `var43`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var43`), or binding to `_` + ┌─ TEMPFILE:47:95 + │ +47 │ Enum1::Variant3 {field8: var38, field9: var39,} => | var42: bool, var43: Struct1, var44: Enum0 | { /* _block18 */ ( 18858u16 ^ 18170u16)}, + │ ^^^^^ + +warning: Unused value of parameter `var44`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var44`), or binding to `_` + ┌─ TEMPFILE:47:111 + │ +47 │ Enum1::Variant3 {field8: var38, field9: var39,} => | var42: bool, var43: Struct1, var44: Enum0 | { /* _block18 */ ( 18858u16 ^ 18170u16)}, + │ ^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var35` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var35`), or renaming to `_` + ┌─ TEMPFILE:47:80 + │ +47 │ Enum1::Variant3 {field8: var38, field9: var39,} => | var42: bool, var43: Struct1, var44: Enum0 | { /* _block18 */ ( 18858u16 ^ 18170u16)}, + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var36` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var36`), or renaming to `_` + ┌─ TEMPFILE:48:29 + │ +48 │ Enum1::Variant2 {field6: var36, ..} => { /* _block19 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: Unused value of parameter `var48`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var48`), or binding to `_` + ┌─ TEMPFILE:49:39 + │ +49 │ | var48: bool, var49: Struct1, var50: Enum0 | { /* _block20 */ 39966u16} + │ ^^^^^ + +warning: Unused value of parameter `var49`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var49`), or binding to `_` + ┌─ TEMPFILE:49:52 + │ +49 │ | var48: bool, var49: Struct1, var50: Enum0 | { /* _block20 */ 39966u16} + │ ^^^^^ + +warning: Unused value of parameter `var50`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var50`), or binding to `_` + ┌─ TEMPFILE:49:68 + │ +49 │ | var48: bool, var49: Struct1, var50: Enum0 | { /* _block20 */ 39966u16} + │ ^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var35` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var35`), or renaming to `_` + ┌─ TEMPFILE:49:37 + │ +49 │ | var48: bool, var49: Struct1, var50: Enum0 | { /* _block20 */ 39966u16} + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: Unused value of parameter `var59`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var59`), or binding to `_` + ┌─ TEMPFILE:52:39 + │ +52 │ | var59: bool, var60: Struct1, var61: Enum0 | { /* _block24 */ 6707u16} + │ ^^^^^ + +warning: Unused value of parameter `var60`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var60`), or binding to `_` + ┌─ TEMPFILE:52:52 + │ +52 │ | var59: bool, var60: Struct1, var61: Enum0 | { /* _block24 */ 6707u16} + │ ^^^^^ + +warning: Unused value of parameter `var61`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var61`), or binding to `_` + ┌─ TEMPFILE:52:68 + │ +52 │ | var59: bool, var60: Struct1, var61: Enum0 | { /* _block24 */ 6707u16} + │ ^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var35` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var35`), or renaming to `_` + ┌─ TEMPFILE:52:37 + │ +52 │ | var59: bool, var60: Struct1, var61: Enum0 | { /* _block24 */ 6707u16} + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var67` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var67`), or renaming to `_` + ┌─ TEMPFILE:56:29 + │ +56 │ Enum1::Variant4 {field11: var67, ..} => { /* _block29 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var22` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var22`), or renaming to `_` + ┌─ TEMPFILE:63:17 + │ +63 │ Enum1::Variant3 {field8: var22, field9: var23,} => match ( *( &( Enum1::Variant3 { field8: 69980731u32, field9: 65010u32}))) { + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var23` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var23`), or renaming to `_` + ┌─ TEMPFILE:63:17 + │ +63 │ Enum1::Variant3 {field8: var22, field9: var23,} => match ( *( &( Enum1::Variant3 { field8: 69980731u32, field9: 65010u32}))) { + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var70` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var70`), or renaming to `_` + ┌─ TEMPFILE:64:25 + │ +64 │ Enum1::Variant3 {field8: var70, ..} => &mut ( var14), + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var69` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var69`), or renaming to `_` + ┌─ TEMPFILE:65:25 + │ +65 │ Enum1::Variant2 {field7: var69, ..} => &mut ( var14), + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: cannot transfer mutable value since it is borrowed + ┌─ TEMPFILE:67:42 + │ + 40 │ let () = ( function1) ( &mut ( var14), + │ ------------- previously mutably borrowed here + │ ╭──────────────────' + 41 │ │ match ( Enum1::Variant4 { field10: ( ( 3226759902u32 + 19457u32) | 653762092u32), field11: *( &( 1822826693u32))}) { + 42 │ │ Enum1::Variant4 {field10: var24, ..} => { /* _block6 */ + 43 │ │ &mut ( Enum1::Variant2 { field6: 710633453u32, field7: 1761791860u32}) + · │ + 67 │ │ let () = ( function1) ( &mut ( var14), &mut ( Enum1::Variant2 { field6: 2733676076u32, field7: 662338862u32}), &mut ( var14), &mut ( var14)); + │ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ transfer attempted here + · │ +174 │ │ &mut ( var14) +175 │ │ ); + │ ╰─────────' conflicting reference used here + +error: cannot transfer mutable value since it is borrowed + ┌─ TEMPFILE:67:42 + │ +67 │ let () = ( function1) ( &mut ( var14), &mut ( Enum1::Variant2 { field6: 2733676076u32, field7: 662338862u32}), &mut ( var14), &mut ( var14)); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ previously mutably borrowed here + │ transfer attempted here + +error: cannot transfer mutable value since it is borrowed + ┌─ TEMPFILE:67:42 + │ +67 │ let () = ( function1) ( &mut ( var14), &mut ( Enum1::Variant2 { field6: 2733676076u32, field7: 662338862u32}), &mut ( var14), &mut ( var14)); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ previously mutably borrowed here + │ transfer attempted here + +warning: This assignment/binding to the left-hand-side variable `var77` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var77`), or renaming to `_` + ┌─ TEMPFILE:68:45 + │ +68 │ let var77 = Enum1::Variant2 { field6: ( 1027423549u32 - 15677u32), field7: ( 1027423549u32 - 15677u32)}; + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var82` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var82`), or renaming to `_` + ┌─ TEMPFILE:74:17 + │ +74 │ Enum1::Variant4 {field10: var82, field11: var83,} => match ( Enum1::Variant4 { field10: ( 2560137368u32 * 6296u32), field11: ( 2560137368u32 * 6296u32)}) { + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var83` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var83`), or renaming to `_` + ┌─ TEMPFILE:74:17 + │ +74 │ Enum1::Variant4 {field10: var82, field11: var83,} => match ( Enum1::Variant4 { field10: ( 2560137368u32 * 6296u32), field11: ( 2560137368u32 * 6296u32)}) { + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var88` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var88`), or renaming to `_` + ┌─ TEMPFILE:75:25 + │ +75 │ Enum1::Variant4 {field10: var88, field11: var89,} => { /* _block42 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var89` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var89`), or renaming to `_` + ┌─ TEMPFILE:75:25 + │ +75 │ Enum1::Variant4 {field10: var88, field11: var89,} => { /* _block42 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var84` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var84`), or renaming to `_` + ┌─ TEMPFILE:78:25 + │ +78 │ Enum1::Variant2 {field6: var84, field7: var85,} => &mut ( Enum1::Variant2 { field6: 537516388u32, field7: 3026101499u32}), + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var85` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var85`), or renaming to `_` + ┌─ TEMPFILE:78:25 + │ +78 │ Enum1::Variant2 {field6: var84, field7: var85,} => &mut ( Enum1::Variant2 { field6: 537516388u32, field7: 3026101499u32}), + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var86` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var86`), or renaming to `_` + ┌─ TEMPFILE:79:25 + │ +79 │ Enum1::Variant3 {field8: var86, field9: var87,} => &mut ( Enum1::Variant2 { field6: 791621423u32, field7: 791621423u32}), + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var87` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var87`), or renaming to `_` + ┌─ TEMPFILE:79:25 + │ +79 │ Enum1::Variant3 {field8: var86, field9: var87,} => &mut ( Enum1::Variant2 { field6: 791621423u32, field7: 791621423u32}), + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var78` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var78`), or renaming to `_` + ┌─ TEMPFILE:81:17 + │ +81 │ Enum1::Variant2 {field6: var78, field7: var79,} => { /* _block44 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var79` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var79`), or renaming to `_` + ┌─ TEMPFILE:81:17 + │ +81 │ Enum1::Variant2 {field6: var78, field7: var79,} => { /* _block44 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var117` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var117`), or renaming to `_` + ┌─ TEMPFILE:82:29 + │ +82 │ let Struct0(var117, ..) = match ( Enum0::Variant1 { field5: | var121: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var122: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block47 */ + │ ^^^^^^^^^^^^^^^^^^^ + +warning: Unused value of parameter `var121`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var121`), or binding to `_` + ┌─ TEMPFILE:82:87 + │ +82 │ let Struct0(var117, ..) = match ( Enum0::Variant1 { field5: | var121: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var122: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block47 */ + │ ^^^^^^ + +warning: Unused value of parameter `var122`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var122`), or binding to `_` + ┌─ TEMPFILE:82:197 + │ +82 │ let Struct0(var117, ..) = match ( Enum0::Variant1 { field5: | var121: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var122: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block47 */ + │ ^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var141` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var141`), or renaming to `_` + ┌─ TEMPFILE:98:38 + │ + 98 │ let var141 = ( *( &( Struct1 {field2: 157u8, field3: Struct0 (true,true,),})) != + │ ╭──────────────────────────────────────^ + 99 │ │ Struct1 { +100 │ │ field2: ( 100u8 & 47u8), +101 │ │ field3: Struct0 ( + · │ +104 │ │ } +105 │ │ ); + │ ╰─────────────────────────^ + +warning: This assignment/binding to the left-hand-side variable `var143` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var143`), or renaming to `_` + ┌─ TEMPFILE:106:29 + │ +106 │ let Struct0(var143, ..) = match ( Enum0::Variant1 { field5: | var147: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var148: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block52 */ + │ ^^^^^^^^^^^^^^^^^^^ + +warning: Unused value of parameter `var147`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var147`), or binding to `_` + ┌─ TEMPFILE:106:87 + │ +106 │ let Struct0(var143, ..) = match ( Enum0::Variant1 { field5: | var147: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var148: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block52 */ + │ ^^^^^^ + +warning: Unused value of parameter `var148`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var148`), or binding to `_` + ┌─ TEMPFILE:106:197 + │ +106 │ let Struct0(var143, ..) = match ( Enum0::Variant1 { field5: | var147: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var148: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block52 */ + │ ^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var150` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var150`), or renaming to `_` + ┌─ TEMPFILE:112:41 + │ +112 │ let Struct0(var150, ..) = Struct0 ( + │ ^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var153` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var153`), or renaming to `_` + ┌─ TEMPFILE:115:41 + │ +115 │ let Struct0(var153, ..) = Struct0 ( + │ ^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var156` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var156`), or renaming to `_` + ┌─ TEMPFILE:118:41 + │ +118 │ let Struct0(var156, ..) = Struct0 ( + │ ^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var159` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var159`), or renaming to `_` + ┌─ TEMPFILE:126:41 + │ +126 │ let Struct0(var159, ..) = Struct0 ( + │ ^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var162` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var162`), or renaming to `_` + ┌─ TEMPFILE:129:41 + │ +129 │ let Struct0(var162, ..) = Struct0 ( + │ ^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var165` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var165`), or renaming to `_` + ┌─ TEMPFILE:132:41 + │ +132 │ let Struct0(var165, ..) = Struct0 ( + │ ^^^^^^^^^^^^^^^^^^^ + +warning: Unused value of parameter `var169`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var169`), or binding to `_` + ┌─ TEMPFILE:140:61 + │ +140 │ match ( Enum0::Variant1 { field5: | var169: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var170: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block57 */ + │ ^^^^^^ + +warning: Unused value of parameter `var170`. Consider removing the parameter, or prefixing with an underscore (e.g., `_var170`), or binding to `_` + ┌─ TEMPFILE:140:171 + │ +140 │ match ( Enum0::Variant1 { field5: | var169: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var170: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block57 */ + │ ^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var172` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var172`), or renaming to `_` + ┌─ TEMPFILE:146:41 + │ +146 │ let Struct0(var172, ..) = Struct0 ( + │ ^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var175` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var175`), or renaming to `_` + ┌─ TEMPFILE:149:41 + │ +149 │ let Struct0(var175, ..) = Struct0 ( + │ ^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var178` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var178`), or renaming to `_` + ┌─ TEMPFILE:152:41 + │ +152 │ let Struct0(var178, ..) = Struct0 ( + │ ^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var80` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var80`), or renaming to `_` + ┌─ TEMPFILE:160:17 + │ +160 │ Enum1::Variant3 {field8: var80, field9: var81,} => { /* _block59 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var81` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var81`), or renaming to `_` + ┌─ TEMPFILE:160:17 + │ +160 │ Enum1::Variant3 {field8: var80, field9: var81,} => { /* _block59 */ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var181` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var181`), or renaming to `_` + ┌─ TEMPFILE:161:29 + │ +161 │ let Struct0(var181, var182) = var13; + │ ^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var182` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var182`), or renaming to `_` + ┌─ TEMPFILE:161:29 + │ +161 │ let Struct0(var181, var182) = var13; + │ ^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var183` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var183`), or renaming to `_` + ┌─ TEMPFILE:162:42 + │ +162 │ let var183 = *( &( Enum0::Variant0 { field4: false})); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var184` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var184`), or renaming to `_` + ┌─ TEMPFILE:163:38 + │ +163 │ let var184 = 1867244186u32; + │ ^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var187` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var187`), or renaming to `_` + ┌─ TEMPFILE:164:29 + │ +164 │ let Struct0(.., var187) = var13; + │ ^^^^^^^^^^^^^^^^^^^ + +warning: This assignment/binding to the left-hand-side variable `var190` is unused. Consider removing this assignment/binding, or prefixing the left-hand-side variable with an underscore (e.g., `_var190`), or renaming to `_` + ┌─ TEMPFILE:167:50 + │ +167 │ let var190 = Enum1::Variant2 { field6: ( 2084683531u32 >> 19u8), field7: 2881938354u32}; + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: cannot transfer mutable value since it is borrowed + ┌─ TEMPFILE:40:18 + │ + 40 │ let () = ( function1) ( &mut ( var14), + │ ------------- previously mutably borrowed here + │ ╭──────────────────^ + 41 │ │ match ( Enum1::Variant4 { field10: ( ( 3226759902u32 + 19457u32) | 653762092u32), field11: *( &( 1822826693u32))}) { + 42 │ │ Enum1::Variant4 {field10: var24, ..} => { /* _block6 */ + 43 │ │ &mut ( Enum1::Variant2 { field6: 710633453u32, field7: 1761791860u32}) + · │ +174 │ │ &mut ( var14) +175 │ │ ); + │ ╰─────────^ transfer attempted here + +error: cannot transfer mutable value since it is borrowed + ┌─ TEMPFILE:40:18 + │ + 40 │ let () = ( function1) ( &mut ( var14), + │ ------------- previously mutably borrowed here + │ ╭──────────────────^ + 41 │ │ match ( Enum1::Variant4 { field10: ( ( 3226759902u32 + 19457u32) | 653762092u32), field11: *( &( 1822826693u32))}) { + 42 │ │ Enum1::Variant4 {field10: var24, ..} => { /* _block6 */ + 43 │ │ &mut ( Enum1::Variant2 { field6: 710633453u32, field7: 1761791860u32}) + · │ + 64 │ │ Enum1::Variant3 {field8: var70, ..} => &mut ( var14), + │ │ ------------- previously mutably borrowed here + · │ +174 │ │ &mut ( var14) +175 │ │ ); + │ ╰─────────^ transfer attempted here + +error: cannot transfer mutable value since it is borrowed + ┌─ TEMPFILE:40:18 + │ + 40 │ let () = ( function1) ( &mut ( var14), + │ ------------- previously mutably borrowed here + │ ╭──────────────────^ + 41 │ │ match ( Enum1::Variant4 { field10: ( ( 3226759902u32 + 19457u32) | 653762092u32), field11: *( &( 1822826693u32))}) { + 42 │ │ Enum1::Variant4 {field10: var24, ..} => { /* _block6 */ + 43 │ │ &mut ( Enum1::Variant2 { field6: 710633453u32, field7: 1761791860u32}) + · │ + 64 │ │ Enum1::Variant3 {field8: var70, ..} => &mut ( var14), + │ │ ------------- previously mutably borrowed here + · │ + 76 │ │ &mut ( var14) + │ │ ------------- previously mutably borrowed here + · │ +174 │ │ &mut ( var14) +175 │ │ ); + │ ╰─────────^ transfer attempted here + +error: cannot transfer mutable value since it is borrowed + ┌─ TEMPFILE:40:18 + │ + 40 │ let () = ( function1) ( &mut ( var14), + │ ------------- previously mutably borrowed here + │ ╭──────────────────^ + 41 │ │ match ( Enum1::Variant4 { field10: ( ( 3226759902u32 + 19457u32) | 653762092u32), field11: *( &( 1822826693u32))}) { + 42 │ │ Enum1::Variant4 {field10: var24, ..} => { /* _block6 */ + 43 │ │ &mut ( Enum1::Variant2 { field6: 710633453u32, field7: 1761791860u32}) + · │ + 76 │ │ &mut ( var14) + │ │ ------------- previously mutably borrowed here + · │ +174 │ │ &mut ( var14) +175 │ │ ); + │ ╰─────────^ transfer attempted here + +error: cannot transfer mutable value since it is borrowed + ┌─ TEMPFILE:40:18 + │ + 40 │ let () = ( function1) ( &mut ( var14), + │ ╭──────────────────^ + 41 │ │ match ( Enum1::Variant4 { field10: ( ( 3226759902u32 + 19457u32) | 653762092u32), field11: *( &( 1822826693u32))}) { + 42 │ │ Enum1::Variant4 {field10: var24, ..} => { /* _block6 */ + 43 │ │ &mut ( Enum1::Variant2 { field6: 710633453u32, field7: 1761791860u32}) + · │ + 76 │ │ &mut ( var14) + │ │ ------------- previously mutably borrowed here + · │ +174 │ │ &mut ( var14) +175 │ │ ); + │ ╰─────────^ transfer attempted here + + diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16919.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16919.move new file mode 100644 index 00000000000..b151c8c5cfa --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/bug_16919.move @@ -0,0 +1,179 @@ +//# publish +module 0x9A2D1C77326B441F3C4D46BA03C92B5DF09D75609AFDF1C491CD4529080A0385::Module0 { + struct Struct0(bool, bool) has copy, drop ; + struct Struct1 has copy, drop { + field2: u8, + field3: Struct0, + } + enum Enum0 has copy, drop { + Variant0 { + field4: bool, + }, + Variant1 { + field5: | (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop), (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop) | ((u16, bool) ) has copy+drop, + }, + } + enum Enum1 has copy, drop { + Variant2 { + field6: u32, + field7: u32, + }, + Variant3 { + field8: u32, + field9: u32, + }, + Variant4 { + field10: u32, + field11: u32, + }, + } + public fun function1( var0: &mut Enum1, var1: &mut Enum1, var2: &mut Enum1, var3: &mut Enum1) { /* _block0 */ + } + public fun function2( var12: &Enum0, var13: Struct0, var14: Enum1, var15: Struct0, var16: | u32 | has copy+drop): u8 { /* _block1 */ + *( &( Enum0::Variant1 { field5: | var17: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var18: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block2 */ + ( 41988u16, false,) + } + } + ) + ); + let var19 = *( &( false)); + let () = ( function1) ( &mut ( var14), + match ( Enum1::Variant4 { field10: ( ( 3226759902u32 + 19457u32) | 653762092u32), field11: *( &( 1822826693u32))}) { + Enum1::Variant4 {field10: var24, ..} => { /* _block6 */ + &mut ( Enum1::Variant2 { field6: 710633453u32, field7: 1761791860u32}) + }, + Enum1::Variant2 {field6: var20, field7: var21,} => { /* _block13 */ + let var35: | bool, Struct1, Enum0 | (u16 ) has copy+drop = match ( Enum1::Variant4 { field10: ( 1560922432u32 | 271770460u32), field11: 1499701105u32}) { + Enum1::Variant3 {field8: var38, field9: var39,} => | var42: bool, var43: Struct1, var44: Enum0 | { /* _block18 */ ( 18858u16 ^ 18170u16)}, + Enum1::Variant2 {field6: var36, ..} => { /* _block19 */ + | var48: bool, var49: Struct1, var50: Enum0 | { /* _block20 */ 39966u16} + }, + _ => { + | var59: bool, var60: Struct1, var61: Enum0 | { /* _block24 */ 6707u16} + } + }; + + match ( Enum1::Variant4 { field10: 1511514864u32, field11: ( 3357996168u32 << 10u8)}) { + Enum1::Variant4 {field11: var67, ..} => { /* _block29 */ + &mut ( Enum1::Variant2 { field6: 1159191745u32, field7: 2226907110u32}) + }, + _ => &mut ( var14) + }; + &mut ( var14) + }, + Enum1::Variant3 {field8: var22, field9: var23,} => match ( *( &( Enum1::Variant3 { field8: 69980731u32, field9: 65010u32}))) { + Enum1::Variant3 {field8: var70, ..} => &mut ( var14), + Enum1::Variant2 {field7: var69, ..} => &mut ( var14), + _ => { /* _block35 */ + let () = ( function1) ( &mut ( var14), &mut ( Enum1::Variant2 { field6: 2733676076u32, field7: 662338862u32}), &mut ( var14), &mut ( var14)); + let var77 = Enum1::Variant2 { field6: ( 1027423549u32 - 15677u32), field7: ( 1027423549u32 - 15677u32)}; + &mut ( Enum1::Variant2 { field6: 2560137368u32, field7: 2560137368u32}) + } + } + }, + match ( Enum1::Variant4 { field10: ( ( 2560137368u32 * 6296u32) * 6296u32), field11: ( ( 2560137368u32 * 6296u32) * 6296u32)}) { + Enum1::Variant4 {field10: var82, field11: var83,} => match ( Enum1::Variant4 { field10: ( 2560137368u32 * 6296u32), field11: ( 2560137368u32 * 6296u32)}) { + Enum1::Variant4 {field10: var88, field11: var89,} => { /* _block42 */ + &mut ( var14) + }, + Enum1::Variant2 {field6: var84, field7: var85,} => &mut ( Enum1::Variant2 { field6: 537516388u32, field7: 3026101499u32}), + Enum1::Variant3 {field8: var86, field9: var87,} => &mut ( Enum1::Variant2 { field6: 791621423u32, field7: 791621423u32}), + }, + Enum1::Variant2 {field6: var78, field7: var79,} => { /* _block44 */ + let Struct0(var117, ..) = match ( Enum0::Variant1 { field5: | var121: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var122: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block47 */ + ( 12079u16, true,) + } + } + ) { + Enum0::Variant1 {..} => { /* _block48 */ + Struct0 ( + true,true, + ) + }, + Enum0::Variant0 {..} => { /* _block49 */ + Struct0 ( + true,true, + ) + } + }; + let var141 = ( *( &( Struct1 {field2: 157u8, field3: Struct0 (true,true,),})) != + Struct1 { + field2: ( 100u8 & 47u8), + field3: Struct0 ( + true,true, + ), + } + ); + let Struct0(var143, ..) = match ( Enum0::Variant1 { field5: | var147: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var148: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block52 */ + ( 12079u16, true,) + } + } + ) { + Enum0::Variant1 {..} => { /* _block53 */ + let Struct0(var150, ..) = Struct0 ( + true,true, + ); + let Struct0(var153, ..) = Struct0 ( + true,true, + ); + let Struct0(var156, ..) = Struct0 ( + true,true, + ); + Struct0 ( + true,true, + ) + }, + Enum0::Variant0 {..} => { /* _block54 */ + let Struct0(var159, ..) = Struct0 ( + true,true, + ); + let Struct0(var162, ..) = Struct0 ( + true,true, + ); + let Struct0(var165, ..) = Struct0 ( + true,true, + ); + Struct0 ( + true,true, + ) + } + }; + match ( Enum0::Variant1 { field5: | var169: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop, var170: | (| | has copy+drop), (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | has copy+drop | { /* _block57 */ + ( 12079u16, true,) + } + } + ) { + Enum0::Variant1 {..} => { /* _block58 */ + let Struct0(var172, ..) = Struct0 ( + true,true, + ); + let Struct0(var175, ..) = Struct0 ( + true,true, + ); + let Struct0(var178, ..) = Struct0 ( + true,true, + ); + &mut ( var14) + }, + Enum0::Variant0 {..} => &mut ( var14) + } + }, + Enum1::Variant3 {field8: var80, field9: var81,} => { /* _block59 */ + let Struct0(var181, var182) = var13; + let var183 = *( &( Enum0::Variant0 { field4: false})); + let var184 = 1867244186u32; + let Struct0(.., var187) = var13; + match ( *( var12)) { + Enum0::Variant1 {..} => { /* _block62 */ + let var190 = Enum1::Variant2 { field6: ( 2084683531u32 >> 19u8), field7: 2881938354u32}; + &mut ( Enum1::Variant2 { field6: 582746179u32, field7: 2065999912u32}) + }, + Enum0::Variant0 {..} => &mut ( var14) + } + } + }, + &mut ( var14) + ); + 0 + } +} diff --git a/third_party/move/move-model/src/model.rs b/third_party/move/move-model/src/model.rs index 094535283e4..fd0214e7afa 100644 --- a/third_party/move/move-model/src/model.rs +++ b/third_party/move/move-model/src/model.rs @@ -1284,25 +1284,18 @@ impl GlobalEnv { // Comparison of Diagnostic values that tries to match program ordering so we // can display them to the user in a more natural order. fn cmp_diagnostic(diag1: &Diagnostic, diag2: &Diagnostic) -> Ordering { - let labels_ordering = GlobalEnv::cmp_labels(&diag1.labels, &diag2.labels); - if Ordering::Equal == labels_ordering { - let sev_ordering = diag1 + GlobalEnv::cmp_labels(&diag1.labels, &diag2.labels).then_with(|| { + diag1 .severity .partial_cmp(&diag2.severity) - .expect("Severity provides a total ordering for valid severity enum values"); - if Ordering::Equal == sev_ordering { - let message_ordering = diag1.message.cmp(&diag2.message); - if Ordering::Equal == message_ordering { - diag1.code.cmp(&diag2.code) - } else { - message_ordering - } - } else { - sev_ordering - } - } else { - labels_ordering - } + .expect("Severity provides a total ordering for valid severity enum values") + .then_with(|| { + diag1 + .message + .cmp(&diag2.message) + .then_with(|| diag1.code.cmp(&diag2.code)) + }) + }) } // Label comparison that tries to match program ordering. `FileId` is already set in visitation @@ -1310,25 +1303,13 @@ impl GlobalEnv { // marking nested regions, we want the innermost region, so we order first by end of labelled // code region, then in reverse by start of region. fn cmp_label(label1: &Label, label2: &Label) -> Ordering { - let file_ordering = label1.file_id.cmp(&label2.file_id); - if Ordering::Equal == file_ordering { - // First order by end of region. - let end1 = label1.range.end; - let end2 = label2.range.end; - let end_ordering = end1.cmp(&end2); - if Ordering::Equal == end_ordering { - let start1 = label1.range.start; - let start2 = label2.range.start; - - // For nested regions with same end, show inner-most region first. - // Swap 1 and 2 in comparing starts. - start2.cmp(&start1) - } else { - end_ordering - } - } else { - file_ordering - } + label1.file_id.cmp(&label2.file_id).then_with(|| { + label1 + .range + .end + .cmp(&label2.range.end) + .then_with(|| label2.range.start.cmp(&label1.range.start)) + }) } // Label comparison within a list of labels for a given diagnostic, which orders by priority @@ -1349,12 +1330,14 @@ impl GlobalEnv { fn cmp_labels(labels1: &[Label], labels2: &[Label]) -> Ordering { let mut sorted_labels1 = labels1.iter().collect_vec(); sorted_labels1.sort_by(|l1, l2| GlobalEnv::cmp_label_priority(l1, l2)); + let sorted_labels1_len = sorted_labels1.len(); let mut sorted_labels2 = labels2.iter().collect_vec(); sorted_labels2.sort_by(|l1, l2| GlobalEnv::cmp_label_priority(l1, l2)); + let sorted_labels2_len = sorted_labels2.len(); std::iter::zip(sorted_labels1, sorted_labels2) .map(|(l1, l2)| GlobalEnv::cmp_label(l1, l2)) - .find(|r| Ordering::Equal != *r) - .unwrap_or(Ordering::Equal) + .fold(Ordering::Equal, Ordering::then) + .then_with(|| sorted_labels1_len.cmp(&sorted_labels2_len)) } /// Writes accumulated diagnostics that pass through `filter` @@ -1365,12 +1348,8 @@ impl GlobalEnv { { let mut shown = BTreeSet::new(); self.diags.borrow_mut().sort_by(|a, b| { - let reported_ordering = a.1.cmp(&b.1); - if Ordering::Equal == reported_ordering { - GlobalEnv::cmp_diagnostic(&a.0, &b.0) - } else { - reported_ordering - } + a.1.cmp(&b.1) + .then_with(|| GlobalEnv::cmp_diagnostic(&a.0, &b.0)) }); for (diag, reported) in self.diags.borrow_mut().iter_mut().filter(|(d, reported)| { !reported From 0b234cd23152c84b3a3d4d383ada3ae52110fab5 Mon Sep 17 00:00:00 2001 From: George Mitenkov Date: Thu, 3 Jul 2025 19:55:36 +0100 Subject: [PATCH 027/260] [vm] VM value depth checks (bounded recursion) (#16983) Downstreamed-from: 5313b07572954de545ccb46cdbc26ae85d292cff --- .../src/gas_schedule/misc.rs | 15 ++-- .../aptos-memory-usage-tracker/src/lib.rs | 18 ++-- aptos-move/framework/table-natives/src/lib.rs | 84 ++++++++----------- .../move/move-core/types/src/vm_status.rs | 6 +- .../runtime/src/storage/ty_depth_checker.rs | 47 ++++------- 5 files changed, 74 insertions(+), 96 deletions(-) diff --git a/aptos-move/aptos-gas-schedule/src/gas_schedule/misc.rs b/aptos-move/aptos-gas-schedule/src/gas_schedule/misc.rs index 8ac72a247fb..79a4653faaf 100644 --- a/aptos-move/aptos-gas-schedule/src/gas_schedule/misc.rs +++ b/aptos-move/aptos-gas-schedule/src/gas_schedule/misc.rs @@ -251,9 +251,10 @@ impl ValueVisitor for AbstractValueSizeVisitor<'_> { } #[inline] - fn visit_closure(&mut self, _depth: usize, _len: usize) -> bool { + fn visit_closure(&mut self, depth: u64, _len: usize) -> PartialVMResult { + self.check_depth(depth)?; self.size += self.params.closure; - true + Ok(true) } #[inline] @@ -464,9 +465,10 @@ impl AbstractValueSizeGasParameters { } #[inline] - fn visit_closure(&mut self, _depth: usize, _len: usize) -> bool { + fn visit_closure(&mut self, depth: u64, _len: usize) -> PartialVMResult { + self.check_depth(depth)?; self.res = Some(self.params.closure); - false + Ok(false) } #[inline] @@ -653,9 +655,10 @@ impl AbstractValueSizeGasParameters { } #[inline] - fn visit_closure(&mut self, _depth: usize, _len: usize) -> bool { + fn visit_closure(&mut self, depth: u64, _len: usize) -> PartialVMResult { + self.check_depth(depth)?; self.res = Some(self.params.closure); - false + Ok(false) } #[inline] diff --git a/aptos-move/aptos-memory-usage-tracker/src/lib.rs b/aptos-move/aptos-memory-usage-tracker/src/lib.rs index 9981f1167ab..7ad4d05e2d2 100644 --- a/aptos-move/aptos-memory-usage-tracker/src/lib.rs +++ b/aptos-move/aptos-memory-usage-tracker/src/lib.rs @@ -374,13 +374,17 @@ where is_generic: bool, args: impl ExactSizeIterator + Clone, ) -> PartialVMResult<()> { - self.use_heap_memory(args.clone().fold(AbstractValueSize::zero(), |acc, val| { - acc + self - .vm_gas_params() - .misc - .abs_val - .abstract_stack_size(val, self.feature_version()) - }))?; + self.use_heap_memory( + args.clone() + .try_fold(AbstractValueSize::zero(), |acc, val| { + let stack_size = self + .vm_gas_params() + .misc + .abs_val + .abstract_stack_size(val, self.feature_version())?; + Ok::<_, PartialVMError>(acc + stack_size) + })?, + )?; self.base.charge_pack_closure(is_generic, args) } diff --git a/aptos-move/framework/table-natives/src/lib.rs b/aptos-move/framework/table-natives/src/lib.rs index bef54e0cdcc..b734ec210c9 100644 --- a/aptos-move/framework/table-natives/src/lib.rs +++ b/aptos-move/framework/table-natives/src/lib.rs @@ -384,18 +384,15 @@ fn native_add_box( let (gv, loaded) = table.get_or_create_global_value(&function_value_extension, table_context, key_bytes)?; - let mem_usage = if !fix_memory_double_counting || loaded.is_some() { - gv.view() - .map(|val| { - context - .abs_val_gas_params() - .abstract_heap_size(&val, context.gas_feature_version()) - .map(u64::from) - }) - .transpose()? - } else { - None - }; + let mem_usage = gv + .view() + .map(|val| { + context + .abs_val_gas_params() + .abstract_heap_size(&val, context.gas_feature_version()) + .map(u64::from) + }) + .transpose()?; let res = match gv.move_to(val) { Ok(_) => Ok(smallvec![]), @@ -441,18 +438,15 @@ fn native_borrow_box( let (gv, loaded) = table.get_or_create_global_value(&function_value_extension, table_context, key_bytes)?; - let mem_usage = if !fix_memory_double_counting || loaded.is_some() { - gv.view() - .map(|val| { - context - .abs_val_gas_params() - .abstract_heap_size(&val, context.gas_feature_version()) - .map(u64::from) - }) - .transpose()? - } else { - None - }; + let mem_usage = gv + .view() + .map(|val| { + context + .abs_val_gas_params() + .abstract_heap_size(&val, context.gas_feature_version()) + .map(u64::from) + }) + .transpose()?; let res = match gv.borrow_global() { Ok(ref_val) => Ok(smallvec![ref_val]), @@ -499,18 +493,15 @@ fn native_contains_box( let (gv, loaded) = table.get_or_create_global_value(&function_value_extension, table_context, key_bytes)?; - let mem_usage = if !fix_memory_double_counting || loaded.is_some() { - gv.view() - .map(|val| { - context - .abs_val_gas_params() - .abstract_heap_size(&val, context.gas_feature_version()) - .map(u64::from) - }) - .transpose()? - } else { - None - }; + let mem_usage = gv + .view() + .map(|val| { + context + .abs_val_gas_params() + .abstract_heap_size(&val, context.gas_feature_version()) + .map(u64::from) + }) + .transpose()?; let exists = Value::bool(gv.exists()?); drop(table_data); @@ -551,18 +542,15 @@ fn native_remove_box( let (gv, loaded) = table.get_or_create_global_value(&function_value_extension, table_context, key_bytes)?; - let mem_usage = if !fix_memory_double_counting || loaded.is_some() { - gv.view() - .map(|val| { - context - .abs_val_gas_params() - .abstract_heap_size(&val, context.gas_feature_version()) - .map(u64::from) - }) - .transpose()? - } else { - None - }; + let mem_usage = gv + .view() + .map(|val| { + context + .abs_val_gas_params() + .abstract_heap_size(&val, context.gas_feature_version()) + .map(u64::from) + }) + .transpose()?; let res = match gv.move_from() { Ok(val) => Ok(smallvec![val]), diff --git a/third_party/move/move-core/types/src/vm_status.rs b/third_party/move/move-core/types/src/vm_status.rs index 47388049bc4..03cb7fb70fa 100644 --- a/third_party/move/move-core/types/src/vm_status.rs +++ b/third_party/move/move-core/types/src/vm_status.rs @@ -211,7 +211,8 @@ impl VMStatus { | StatusCode::IO_LIMIT_REACHED | StatusCode::STORAGE_LIMIT_REACHED | StatusCode::TOO_MANY_DELAYED_FIELDS - | StatusCode::UNABLE_TO_CAPTURE_DELAYED_FIELDS, + | StatusCode::UNABLE_TO_CAPTURE_DELAYED_FIELDS + | StatusCode::VM_MAX_VALUE_DEPTH_REACHED, .. } | VMStatus::Error { @@ -220,7 +221,8 @@ impl VMStatus { | StatusCode::IO_LIMIT_REACHED | StatusCode::STORAGE_LIMIT_REACHED | StatusCode::TOO_MANY_DELAYED_FIELDS - | StatusCode::UNABLE_TO_CAPTURE_DELAYED_FIELDS, + | StatusCode::UNABLE_TO_CAPTURE_DELAYED_FIELDS + | StatusCode::VM_MAX_VALUE_DEPTH_REACHED, .. } => Ok(KeptVMStatus::MiscellaneousError), diff --git a/third_party/move/move-vm/runtime/src/storage/ty_depth_checker.rs b/third_party/move/move-vm/runtime/src/storage/ty_depth_checker.rs index 1ad3c989922..6119fe181cf 100644 --- a/third_party/move/move-vm/runtime/src/storage/ty_depth_checker.rs +++ b/third_party/move/move-vm/runtime/src/storage/ty_depth_checker.rs @@ -21,7 +21,12 @@ use std::{ sync::Arc, }; -/// Checks depths for instantiated types. +/// Checks depths for instantiated types in order to bound value size. The idea is that if the +/// depth of the type is bounded, so is the depth of the corresponding value. Note that this is +/// no longer the case with function values enabled: captured arguments are not visible in the type, +/// but do increase the value depth. As a result, it is possible to have a shallow function type, +/// while the value stores a long chain of nested function values via captured arguments. +/// TODO: consider deprecating since values are also bounded dynamically now. /// /// For structs, stores a cache of formulas. The cache is used for performance (avoid repeated /// formula construction within a single transaction). @@ -139,6 +144,10 @@ where | Type::U256 | Type::Address | Type::Signer => check_depth!(0), + // For function types, we ignore the return/argument types because they do not bound + // value size, and we do not to error on a false positive (function operates on a + // nested value, but does not capture it). + Type::Function { .. } => check_depth!(0), Type::Reference(ty) | Type::MutableReference(ty) => self .recursive_check_depth_of_type( gas_meter, @@ -175,19 +184,6 @@ where let formula = visit_struct!(idx); check_depth!(formula.solve(&ty_arg_depths)) }, - Type::Function { args, results, .. } => { - let mut ty_max_depth = depth; - for ty in args.iter().chain(results) { - ty_max_depth = ty_max_depth.max(self.recursive_check_depth_of_type( - gas_meter, - traversal_context, - ty, - max_depth, - check_depth!(1), - )?); - } - ty_max_depth - }, Type::TyParam(_) => { return Err( PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR) @@ -301,6 +297,10 @@ where | Type::U16 | Type::U32 | Type::U256 => DepthFormula::constant(1), + // For function types, we ignore the return/argument types because they do not bound + // value size, and we do not to error on a false positive (function operates on a + // nested value, but does not capture it). Hence, we simply return a constant here. + Type::Function { .. } => DepthFormula::constant(1), Type::Vector(ty) => self .calculate_type_depth_formula(gas_meter, traversal_context, currently_visiting, ty)? .scale(1), @@ -343,25 +343,6 @@ where )?; struct_formula.subst(ty_arg_map)?.scale(1) }, - Type::Function { - args, - results, - abilities: _, - } => { - let inner_formulas = args - .iter() - .chain(results) - .map(|ty| { - self.calculate_type_depth_formula( - gas_meter, - traversal_context, - currently_visiting, - ty, - ) - }) - .collect::>>()?; - DepthFormula::normalize(inner_formulas).scale(1) - }, }) } From 92836ba1626a489deca4bd345b3a25da3f7abcd9 Mon Sep 17 00:00:00 2001 From: George Mitenkov Date: Fri, 4 Jul 2025 00:16:15 +0100 Subject: [PATCH 028/260] [api] Fix fat type conversion for function values with refs (#17004) Co-authored-by: Wolfgang Grieskamp Downstreamed-from: 4498246107ea3621069c090478655f88c1d46cd4 --- api/src/tests/function_value_test.rs | 29 +++++++++++++ .../tests/move/pack_function_values/Move.toml | 9 ++++ .../pack_function_values/sources/test.move | 15 +++++++ .../tools/move-resource-viewer/src/lib.rs | 43 ++++++++++++++++--- 4 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 api/src/tests/move/pack_function_values/Move.toml create mode 100644 api/src/tests/move/pack_function_values/sources/test.move diff --git a/api/src/tests/function_value_test.rs b/api/src/tests/function_value_test.rs index 9c3659873f9..3f48ab337fa 100644 --- a/api/src/tests/function_value_test.rs +++ b/api/src/tests/function_value_test.rs @@ -82,3 +82,32 @@ async fn test_function_values() { .unwrap()["data"]; assert_eq!(state, &json!({"__variant__": "Value", "_0": "33"})); } + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_function_values_with_references() { + let mut context = new_test_context(current_function_name!()); + let mut account = context.create_account().await; + let addr = account.address(); + + let named_addresses = vec![("account".to_string(), addr)]; + let txn = futures::executor::block_on(async move { + let path = + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src/tests/move/pack_function_values"); + TestContext::build_package_with_latest_language(path, named_addresses) + }); + context.publish_package(&mut account, txn).await; + + let resource = format!("{}::test::FunctionStore", addr); + let response = &context.gen_resource(&addr, &resource).await.unwrap(); + + let expected_name = format!("{}::test::freeze_ref", addr); + assert_eq!( + response["data"], + json!({ + "f": { + "__fun_name__": &expected_name, + "__mask__": "0", + } + }) + ); +} diff --git a/api/src/tests/move/pack_function_values/Move.toml b/api/src/tests/move/pack_function_values/Move.toml new file mode 100644 index 00000000000..bcd2fe040c3 --- /dev/null +++ b/api/src/tests/move/pack_function_values/Move.toml @@ -0,0 +1,9 @@ +[package] +name = "pack_function_values" +version = "0.0.0" + +[dependencies] +AptosFramework = { local = "../../../../../aptos-move/framework/aptos-framework" } + +[addresses] +account = "_" diff --git a/api/src/tests/move/pack_function_values/sources/test.move b/api/src/tests/move/pack_function_values/sources/test.move new file mode 100644 index 00000000000..60eeefa4d4c --- /dev/null +++ b/api/src/tests/move/pack_function_values/sources/test.move @@ -0,0 +1,15 @@ +module account::test { + + struct FunctionStore has key { + f: |&mut u64|&u64 has copy+drop+store, + } + + public fun freeze_ref(x: &mut u64): &u64 { + x + } + + fun init_module(account: &signer) { + let f: |&mut u64|&u64 has copy+drop+store = |s| freeze_ref(s); + move_to(account, FunctionStore { f }); + } +} diff --git a/third_party/move/tools/move-resource-viewer/src/lib.rs b/third_party/move/tools/move-resource-viewer/src/lib.rs index eb61043d821..059574f85f9 100644 --- a/third_party/move/tools/move-resource-viewer/src/lib.rs +++ b/third_party/move/tools/move-resource-viewer/src/lib.rs @@ -372,11 +372,6 @@ impl MoveValueAnnotator { sig: &SignatureToken, limit: &mut Limiter, ) -> anyhow::Result { - let resolve_slice = |toks: &[SignatureToken], limit: &mut Limiter| { - toks.iter() - .map(|tok| self.resolve_signature(module, tok, limit)) - .collect::>>() - }; Ok(match sig { SignatureToken::Bool => FatType::Bool, SignatureToken::U8 => FatType::U8, @@ -391,6 +386,39 @@ impl MoveValueAnnotator { FatType::Vector(Box::new(self.resolve_signature(module, ty, limit)?)) }, SignatureToken::Function(args, results, abilities) => { + let resolve_slice = |toks: &[SignatureToken], limit: &mut Limiter| { + toks.iter() + .map(|tok| { + // Function type can have references as immediate argument or return + // types. + Ok(match tok { + SignatureToken::Reference(t) => FatType::Reference(Box::new( + self.resolve_signature(module, t, limit)?, + )), + SignatureToken::MutableReference(t) => FatType::MutableReference( + Box::new(self.resolve_signature(module, t, limit)?), + ), + SignatureToken::Bool + | SignatureToken::U8 + | SignatureToken::U64 + | SignatureToken::U128 + | SignatureToken::Address + | SignatureToken::Signer + | SignatureToken::Vector(_) + | SignatureToken::Function(_, _, _) + | SignatureToken::Struct(_) + | SignatureToken::StructInstantiation(_, _) + | SignatureToken::TypeParameter(_) + | SignatureToken::U16 + | SignatureToken::U32 + | SignatureToken::U256 => { + self.resolve_signature(module, tok, limit)? + }, + }) + }) + .collect::>>() + }; + FatType::Function(Box::new(FatFunctionType { args: resolve_slice(args, limit)?, results: resolve_slice(results, limit)?, @@ -402,7 +430,10 @@ impl MoveValueAnnotator { }, SignatureToken::StructInstantiation(idx, toks) => { let struct_ty = self.resolve_struct_handle(module, *idx, limit)?; - let args = resolve_slice(toks, limit)?; + let args = toks + .iter() + .map(|tok| self.resolve_signature(module, tok, limit)) + .collect::>>()?; FatType::Struct(Box::new( struct_ty .subst(&args, limit) From 663861b479b7293f3852d55c8ac4e19bdb53111a Mon Sep 17 00:00:00 2001 From: "Andrea Cappa (zi0Black)" <13380579+zi0Black@users.noreply.github.com> Date: Mon, 7 Jul 2025 16:52:24 +0200 Subject: [PATCH 029/260] [proptest/fuzzer] FVs serialize/deserialize (#16859) * - Refactored fuzzing targets to utilize new serialization methods and maintain consistency in error handling. - Enhanced mock implementations for testing and serialization in `function_values_impl.rs` and related test files. - Update dependencies in Cargo.lock * small fix * Update golden outputs after upgrading prop-test * Refactor ClosureMask impl to return Result for error handling. * fmt * Update third_party/move/move-core/types/src/function.rs Co-authored-by: Vineeth Kashyap * Add module replacement functionality and improve fuzzing tests - Updated fuzzing tests to handle deserialization errors more robustly, ensuring that only malformed modules are rejected. - Refactored value property tests to improve variant handling in struct layouts. - Enhanced error reporting in the lambda lifter for better debugging of compiler issues. - Implemented `replace_module` method in `BuiltPackage` to allow replacing a module by name with a new `CompiledModule`. * Fix conversion(?) * Minor fixes --------- Co-authored-by: Vineeth Kashyap Downstreamed-from: 8f74ada933eca81feae93adc5734d8e59cf09eb8 --- Cargo.lock | 146 +- ...tor_test__test_entry_function_payload.json | 7761 ++++++++-------- ...tion_vector_test__test_script_payload.json | 8003 +++++++++-------- aptos-move/framework/src/built_package.rs | 22 + testsuite/fuzzer/fuzz.sh | 3 +- .../move/deserialize_script_module.rs | 41 +- .../src/env_pipeline/lambda_lifter.rs | 16 +- .../move/move-core/types/src/function.rs | 19 +- .../move-model/src/builder/exp_builder.rs | 2 +- third_party/move/move-stdlib/Cargo.toml | 2 +- .../types/src/values/function_values_impl.rs | 105 +- .../types/src/values/serialization_tests.rs | 63 +- .../types/src/values/value_depth_tests.rs | 16 +- .../types/src/values/value_prop_tests.rs | 26 +- .../move-vm/types/src/values/values_impl.rs | 168 +- 15 files changed, 8861 insertions(+), 7532 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7596a7a354e..6b69bc3a03d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5811,7 +5811,7 @@ version = "0.69.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "cexpr", "clang-sys", "itertools 0.12.1", @@ -5831,7 +5831,16 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" dependencies = [ - "bit-vec", + "bit-vec 0.6.3", +] + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec 0.8.0", ] [[package]] @@ -5840,6 +5849,12 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + [[package]] name = "bit_field" version = "0.10.2" @@ -5854,9 +5869,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] name = "bitmaps" @@ -7707,7 +7722,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35b696af9ff4c0d2a507db2c5faafa8aa0205e297e5f11e203a24226d5355e7a" dependencies = [ "bigdecimal", - "bitflags 2.6.0", + "bitflags 2.9.1", "byteorder", "chrono", "diesel_derives", @@ -9292,6 +9307,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", +] + [[package]] name = "ghash" version = "0.5.0" @@ -9527,7 +9554,7 @@ dependencies = [ "ff", "rand 0.8.5", "rand_core 0.6.4", - "rand_xorshift", + "rand_xorshift 0.3.0", "subtle", ] @@ -10935,7 +10962,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a1cbf952127589f2851ab2046af368fd20645491bb4b376f04b7f94d7a9837b" dependencies = [ "ascii-canvas", - "bit-set", + "bit-set 0.5.3", "diff", "ena", "is-terminal", @@ -10957,7 +10984,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" dependencies = [ "ascii-canvas", - "bit-set", + "bit-set 0.5.3", "ena", "itertools 0.11.0", "lalrpop-util 0.20.2", @@ -11160,7 +11187,7 @@ version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "libc", "redox_syscall 0.4.1", ] @@ -12876,7 +12903,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "cfg-if", "libc", ] @@ -12887,7 +12914,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "cfg-if", "cfg_aliases 0.2.1", "libc", @@ -13282,7 +13309,7 @@ version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "cfg-if", "foreign-types 0.3.2", "libc", @@ -13658,7 +13685,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "499cff8432e71c5f8784d9645aac0f9fca604d67f59b68a606170b5e229c6538" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "ciborium", "coset", "data-encoding", @@ -14635,7 +14662,7 @@ dependencies = [ "async-trait", "bcs 0.1.4", "bigdecimal", - "bitflags 2.6.0", + "bitflags 2.9.1", "canonical_json", "chrono", "clap 4.5.21", @@ -14766,18 +14793,18 @@ dependencies = [ [[package]] name = "proptest" -version = "1.4.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +checksum = "6fcdab19deb5195a31cf7726a210015ff1496ba1464fd42cb4f537b8b01b471f" dependencies = [ - "bit-set", - "bit-vec", - "bitflags 2.6.0", + "bit-set 0.8.0", + "bit-vec 0.8.0", + "bitflags 2.9.1", "lazy_static", "num-traits", - "rand 0.8.5", - "rand_chacha 0.3.1", - "rand_xorshift", + "rand 0.9.1", + "rand_chacha 0.9.0", + "rand_xorshift 0.4.0", "regex-syntax 0.8.2", "rusty-fork", "tempfile", @@ -15099,6 +15126,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "r2d2" version = "0.8.10" @@ -15147,6 +15180,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -15167,6 +15210,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + [[package]] name = "rand_core" version = "0.5.1" @@ -15185,6 +15238,15 @@ dependencies = [ "getrandom 0.2.11", ] +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.3", +] + [[package]] name = "rand_hc" version = "0.2.0" @@ -15212,6 +15274,15 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_xorshift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.3", +] + [[package]] name = "rand_xoshiro" version = "0.6.0" @@ -15316,6 +15387,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +dependencies = [ + "bitflags 2.9.1", +] + [[package]] name = "redox_users" version = "0.4.4" @@ -15812,7 +15892,7 @@ version = "0.38.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "errno", "libc", "linux-raw-sys 0.4.12", @@ -18675,7 +18755,7 @@ dependencies = [ "errno", "js-sys", "libc", - "rustix 0.38.28", + "rustix 0.37.27", "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", "winapi 0.3.9", @@ -18896,6 +18976,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasite" version = "0.1.0" @@ -19398,6 +19487,15 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.9.1", +] + [[package]] name = "ws_stream_wasm" version = "0.7.4" diff --git a/api/goldens/aptos_api__tests__transaction_vector_test__test_entry_function_payload.json b/api/goldens/aptos_api__tests__transaction_vector_test__test_entry_function_payload.json index 7e340984449..0a113023990 100644 --- a/api/goldens/aptos_api__tests__transaction_vector_test__test_entry_function_payload.json +++ b/api/goldens/aptos_api__tests__transaction_vector_test__test_entry_function_payload.json @@ -1,211 +1,324 @@ [ { "raw_txn": { - "sender": "3364faedb070fcddabba6af05ac3b1d3e4cf59517df4d296872fe3cc41763c07", - "sequence_number": "18129649627527924708", + "sender": "f781d9248b3965741e9d4d11c0acc44743e773c469796bb070c3914aed7136b3", + "sequence_number": "10142476032578219882", "payload": { "EntryFunction": { "module": { "address": "0496ebd75c07f7cd1499e74ed5c9bb038f1fc97267718c3b850b2002dec8a36c", - "name": "xEWRAnYkugjvJrVhoZLPfQYVMwjXPoR1_Coin" + "name": "lTFMwskIkF_Coin" }, - "function": "bqIEyRbFAc7", + "function": "BJCusjEgchjGrHJHfKmL3", "ty_args": [ { "vector": { - "vector": "u8" - } - }, - { - "vector": { - "vector": { - "struct": { - "address": "4866220c00bb849c354aebf118b7e7675ad8e5592dd144edb23b520b53d4c874", - "module": "awOEaxZmLztVXoKOOcBmjLVTY", - "name": "PwJ", - "type_args": [] - } - } + "vector": "signer" } }, { - "vector": "address" + "vector": "signer" }, { "struct": { - "address": "2bf1cb23b029f9771b9ab78de45b21fabe79496e392fc4129b157f881e646bba", - "module": "xhdHJvZKTGkwoT", - "name": "GWGwAcDTUKLbVapovyiYPFXylxO", + "address": "b7e7675ad8e5592dd144edb23b520b53d4c874d5bb61d8f0bfc357bff99bdbf4", + "module": "FFtlLLaTWpvvErMMQKulDxAeAiGO", + "name": "NDqdiWY", "type_args": [] } }, { "vector": { - "vector": { - "struct": { - "address": "f74c7fef8a72033b03a145edb4cb8fdedf59994753e563394cb1e5fd22b126f4", - "module": "MjrpLAGaTUmrfPelcgAdIjvvzArjNdP", - "name": "SKZdMYrqYdLqHLZdzknLvav", - "type_args": [] - } + "vector": "signer" + } + }, + { + "vector": { + "struct": { + "address": "da1f1740b3274a727934637d853b8642c789c38750f9c221a082a27ae257402f", + "module": "x6", + "name": "eWwgpakKdBqwrLPavM", + "type_args": [] } } }, { "struct": { - "address": "bc788e57184e12a7c21570762a1a0ccf1756448be98bd597c5ed528d3d6da03c", - "module": "xboPoeiE", - "name": "ylHMDIorVYPTwGtdBRuL8", + "address": "da1ab2bf902e45e73c5a590b9e2ae7d8b2c5f3cf10763868052460d19b726f69", + "module": "XBHmJC5", + "name": "nfsdfNnwRIQZZIPFp", "type_args": [] } } ], "args": [ - "1693730cdd1903ac", "01", - "72", - "97e8487e2c8ae82bd8431fde4053c4fc772146b39f97b269e960c3125f062925" + "66708be7833cefb7994ed0a5e277767a034b546a880e71dc189254009abac792", + "9a", + "20", + "00", + "9987f15a96b78be319170febeee4f65618ca29f9f9ed5ef623577d10cbbd8330", + "e954018b387611a72eda24ec9429b14d3c114db76e54b933cf1f8bd039a70fdc" ] } }, - "max_gas_amount": "8512786420152370650", - "gas_unit_price": "14991845072478366484", - "expiration_timestamp_secs": "2619726678109771971", - "chain_id": 67 + "max_gas_amount": "11416506364619761024", + "gas_unit_price": "2407153818005157530", + "expiration_timestamp_secs": "15488783003977911101", + "chain_id": 195 }, - "signed_txn_bcs": "3364faedb070fcddabba6af05ac3b1d3e4cf59517df4d296872fe3cc41763c07e44b18ff477499fb020496ebd75c07f7cd1499e74ed5c9bb038f1fc97267718c3b850b2002dec8a36c2578455752416e596b75676a764a7256686f5a4c50665159564d776a58506f52315f436f696e0b6271494579526246416337060606010606074866220c00bb849c354aebf118b7e7675ad8e5592dd144edb23b520b53d4c8741961774f4561785a6d4c7a7456586f4b4f4f63426d6a4c5654590350774a000604072bf1cb23b029f9771b9ab78de45b21fabe79496e392fc4129b157f881e646bba0e786864484a765a4b54476b776f541b4757477741634454554b4c625661706f76796959504658796c784f00060607f74c7fef8a72033b03a145edb4cb8fdedf59994753e563394cb1e5fd22b126f41f4d6a72704c41476154556d726650656c63674164496a76767a41726a4e645017534b5a644d59727159644c71484c5a647a6b6e4c7661760007bc788e57184e12a7c21570762a1a0ccf1756448be98bd597c5ed528d3d6da03c0878626f506f65694515796c484d44496f7256595054774774644252754c380004081693730cdd1903ac010101722097e8487e2c8ae82bd8431fde4053c4fc772146b39f97b269e960c3125f062925da85f37d257e2376146bc3c8a9bb0dd0c3d858a988235b2443002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444019f9c012c90154ed387cb69f28fcbc683e2bba26924ef8351b6d83baf327dffbfd354b06d4f6ffdad0e551dc80a603398bffbcee2cfb127e496f4c2a4bd13e07", + "signed_txn_bcs": "f781d9248b3965741e9d4d11c0acc44743e773c469796bb070c3914aed7136b36aefbce83650c18c020496ebd75c07f7cd1499e74ed5c9bb038f1fc97267718c3b850b2002dec8a36c0f6c54464d77736b496b465f436f696e15424a4375736a456763686a4772484a48664b6d4c3306060605060507b7e7675ad8e5592dd144edb23b520b53d4c874d5bb61d8f0bfc357bff99bdbf41c4646746c4c4c61545770767645724d4d514b756c447841654169474f074e447164695759000606050607da1f1740b3274a727934637d853b8642c789c38750f9c221a082a27ae257402f027836126557776770616b4b64427177724c5061764d0007da1ab2bf902e45e73c5a590b9e2ae7d8b2c5f3cf10763868052460d19b726f69075842486d4a4335116e667364664e6e775249515a5a49504670000701012066708be7833cefb7994ed0a5e277767a034b546a880e71dc189254009abac792019a01200100209987f15a96b78be319170febeee4f65618ca29f9f9ed5ef623577d10cbbd833020e954018b387611a72eda24ec9429b14d3c114db76e54b933cf1f8bd039a70fdc80a525270d946f9e9a36ecd1a4ed67213d0b363b1436f3d6c3002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400f9740dec82d0bfe6dfd5b6aa874516c2766d1b9dd38ff07d34e694426b1db0c5c181263961e5d15adf58d2a8c12a6a2f04d2276e4a744a3af8d20f95a16bf0b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "c04702271194143d2ec17a83f50213effde95200110c77fe4c2128e09fddec03", - "sequence_number": "11779767485194459705", + "sender": "46bf9ca6cc12d114280cbff0697317c79ca78a2d85015b90f4497fbed3b86ab2", + "sequence_number": "16693192227961553902", "payload": { "EntryFunction": { "module": { - "address": "ae97a3f28d001e3e009cfa88bb5df4ef8b0e489156348f02bfa5972dcbf64198", - "name": "KtazJwvtQGVixUtdmpdTxPgIzRP3_Coin" + "address": "638dca5cf3940cdbe43f91d657f3cf9f058d2b75f4df7763dbd12fc5a2a012ef", + "name": "uCnfPWzPrUL6_Coin" }, - "function": "JnZVFRTxAXwABaXbfFduosWxgRBuEAo3", + "function": "HvdSlCUSpzuzRRRdEzGDrF4", "ty_args": [ { "vector": { - "struct": { - "address": "bb1b18f7e217081e4b924cbf2f7127e4b875e606c3b2785c46f14e4983c16f1b", - "module": "aBdTPBGhsXWBqxgdP", - "name": "jgvLXdLMdqGgEVAXhVtmyEsXaOF", - "type_args": [] - } + "vector": "u64" } }, { - "vector": { - "vector": "u64" + "struct": { + "address": "27533da6db6fd9029cb6b1f6ef776782fd090908c30bfe5d179bfe733d77b4ce", + "module": "WQ", + "name": "jo", + "type_args": [] } - }, + } + ], + "args": [ + "71490b008988c9b516c76697e8487e2c8ae82bd8431fde4053c4fc772146b39f", + "962b5ab587966238", + "f25439c1048494cb6a726903a7027ad5", + "08580580106e1d559623a2647985a2ef", + "a0b6348a6c806f39103cf15787ba8173747a54d40d3355dca58618bc97b6c128", + "7bdfbeace6a575255ce9cbb81b53c3b1" + ] + } + }, + "max_gas_amount": "12103938025441788085", + "gas_unit_price": "11586076299572095280", + "expiration_timestamp_secs": "14104416069887580933", + "chain_id": 167 + }, + "signed_txn_bcs": "46bf9ca6cc12d114280cbff0697317c79ca78a2d85015b90f4497fbed3b86ab2eec3f512e321aae702638dca5cf3940cdbe43f91d657f3cf9f058d2b75f4df7763dbd12fc5a2a012ef1175436e6650577a5072554c365f436f696e17487664536c435553707a757a52525264457a4744724634020606020727533da6db6fd9029cb6b1f6ef776782fd090908c30bfe5d179bfe733d77b4ce025751026a6f00062071490b008988c9b516c76697e8487e2c8ae82bd8431fde4053c4fc772146b39f08962b5ab58796623810f25439c1048494cb6a726903a7027ad51008580580106e1d559623a2647985a2ef20a0b6348a6c806f39103cf15787ba8173747a54d40d3355dca58618bc97b6c128107bdfbeace6a575255ce9cbb81b53c3b1b500cd3581d3f9a7302991400203caa005dbf5e9aff3bcc3a7002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440be73eb79d4a4644b634f913caadc800d3cc683e9ff85df7be60b2d3eb42a3fe57c9d1d8a4c899654f310b9f0007ee0f7a13ba4eb84797d4bae2f3cc508a3bd06", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "a52aa97eaa15eb9cfb37f68332228a5997d2f97490615c1cde6c9523db431797", + "sequence_number": "14766778299961515281", + "payload": { + "EntryFunction": { + "module": { + "address": "2d74b2717e76a37467779bcb5048b6af3e9138f7adc51f496916fed0953525a3", + "name": "aYZO7_Coin" + }, + "function": "jgBFNsDsQsATjJi", + "ty_args": [ { "vector": { "struct": { - "address": "bae650dbb57e7dd0c1c0327c877d1cc683548dbfd1d95dab28d289429eff8ca4", - "module": "FJpsseqAKLIlYRwAxHNWznqY", - "name": "DBQBIX", + "address": "4af73603539a5bf5e9f1e5da8582c1a434fe94a9a61082b57b4f10fbfc6f6d82", + "module": "UhFNxnGwVNrVzO", + "name": "ArKOTvpmcU", "type_args": [] } } + } + ], + "args": [ + "01", + "aeaee3cc10f4911c9c7c735562564b15", + "3a87246a6888a65e", + "683feee7fbb5135a754e9cffb0e76df6bc1d1d4194c06336573360eabd7544c6", + "735292de992099c4fd2674654f8d9ea0", + "01", + "d0d15068c122438dc03f34b53276aa13", + "894f01daa26a267285dacffd35978539f36dad2bc374d82207ef250773db9e70", + "fe11fb6f9a41e371a936639639373cebe660daf1497ae20ff6cc7bc7dfcf3459", + "52a3c4e0d86d5493725544d0647b9fb2" + ] + } + }, + "max_gas_amount": "12426891022180114397", + "gas_unit_price": "13136716047207170025", + "expiration_timestamp_secs": "7735136167759826674", + "chain_id": 213 + }, + "signed_txn_bcs": "a52aa97eaa15eb9cfb37f68332228a5997d2f97490615c1cde6c9523db431797111d2746a022eecc022d74b2717e76a37467779bcb5048b6af3e9138f7adc51f496916fed0953525a30a61595a4f375f436f696e0f6a6742464e734473517341546a4a690106074af73603539a5bf5e9f1e5da8582c1a434fe94a9a61082b57b4f10fbfc6f6d820e5568464e786e4777564e72567a4f0a41724b4f5476706d6355000a010110aeaee3cc10f4911c9c7c735562564b15083a87246a6888a65e20683feee7fbb5135a754e9cffb0e76df6bc1d1d4194c06336573360eabd7544c610735292de992099c4fd2674654f8d9ea0010110d0d15068c122438dc03f34b53276aa1320894f01daa26a267285dacffd35978539f36dad2bc374d82207ef250773db9e7020fe11fb6f9a41e371a936639639373cebe660daf1497ae20ff6cc7bc7dfcf34591052a3c4e0d86d5493725544d0647b9fb2dd5f894f8b2f75ace9fff4c4a4fd4eb6f2ce99b05cb9586bd5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a208a4f0faeb180684c9fbc082f4fdbb6700748e10e291a80682103fbeed5f8fed336c1ca2a157719e9e842e92689e77815ccfd073998720d04d95380e33120c", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "a4530486f7685ce6042bebdac89fd9fce7cd5cb6663129764401e3448d162b00", + "sequence_number": "5941087757108226865", + "payload": { + "EntryFunction": { + "module": { + "address": "cf4e9741567aa421be0114aca3a1a542d3a1fae0ccbd98e11d29e020e5ab1df7", + "name": "qQlFudASTiosQq_Coin" + }, + "function": "ZXFxXytjcuZJqXOzpEiPm2", + "ty_args": [ + { + "vector": { + "vector": { + "struct": { + "address": "b7b9efbcdebbbd4f536e2b525eb6243fc8c04d5e87c6dd52142fe0147839e236", + "module": "VkafuWVJVqmdCzuy", + "name": "oY", + "type_args": [] + } + } + } }, { "vector": { "struct": { - "address": "8332228a5997d2f97490615c1cde6c9523db43179711a0f25cdd8be9a4d5cf4e", - "module": "vaxllIZcpOv6", - "name": "bZcWhxZqsODC5", + "address": "198bdcb25193c74fccc8e57724586f1618e4b35c3a4282057599350497aa5579", + "module": "LbXzGlRKLjz0", + "name": "yfevEAYBBGJM", "type_args": [] } } } ], - "args": [] + "args": [ + "427d07d0f837f5d65f25581f7a9942d87f6ffe221b754f81297719eb78b79318", + "01", + "05a86fe39d45fad4de532f81ead27c83bd2b5186e3d7aed06a2dbfc2a5cb9ed9", + "a6b8f9b12e3a402dcf463164eff5ee26cd60f03b5bd97076a0b54bc61ec2c596", + "6c", + "6417dd58fa94b1cff6b7ee6e935790904cdb53446c4c01a71f3b83f395142fdd", + "01", + "52beb142c7af701e", + "00" + ] } }, - "max_gas_amount": "6557116728673777100", - "gas_unit_price": "460112503178869952", - "expiration_timestamp_secs": "4391489686854670868", - "chain_id": 82 + "max_gas_amount": "4591469829133248893", + "gas_unit_price": "1083417168633788325", + "expiration_timestamp_secs": "665348431662327138", + "chain_id": 39 }, - "signed_txn_bcs": "c04702271194143d2ec17a83f50213effde95200110c77fe4c2128e09fddec03395ab6ab1d247aa302ae97a3f28d001e3e009cfa88bb5df4ef8b0e489156348f02bfa5972dcbf64198214b74617a4a77767451475669785574646d706454785067497a5250335f436f696e204a6e5a56465254784158774142615862664664756f7357786752427545416f33040607bb1b18f7e217081e4b924cbf2f7127e4b875e606c3b2785c46f14e4983c16f1b1161426454504247687358574271786764501b6a67764c58644c4d64714767455641586856746d79457358614f46000606020607bae650dbb57e7dd0c1c0327c877d1cc683548dbfd1d95dab28d289429eff8ca418464a7073736571414b4c496c5952774178484e577a6e7159064442514249580006078332228a5997d2f97490615c1cde6c9523db43179711a0f25cdd8be9a4d5cf4e0c7661786c6c495a63704f76360d625a635768785a71734f4443350000cc355f73ec8eff5ac03cb144e2a56206149ac3639ab4f13c52002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406c076a381282d1aee8ef476c0edab5a49e6e4f880c4b00d7db55a26aba7b8470353fc73b1571d0224ca94086cb0fd840ff7d347a7d70d6b51f8aedc881597301", + "signed_txn_bcs": "a4530486f7685ce6042bebdac89fd9fce7cd5cb6663129764401e3448d162b0031abdb7dd6fb725202cf4e9741567aa421be0114aca3a1a542d3a1fae0ccbd98e11d29e020e5ab1df71371516c467564415354696f7351715f436f696e165a5846785879746a63755a4a71584f7a704569506d3202060607b7b9efbcdebbbd4f536e2b525eb6243fc8c04d5e87c6dd52142fe0147839e23610566b61667557564a56716d64437a7579026f59000607198bdcb25193c74fccc8e57724586f1618e4b35c3a4282057599350497aa55790c4c62587a476c524b4c6a7a300c796665764541594242474a4d000920427d07d0f837f5d65f25581f7a9942d87f6ffe221b754f81297719eb78b7931801012005a86fe39d45fad4de532f81ead27c83bd2b5186e3d7aed06a2dbfc2a5cb9ed920a6b8f9b12e3a402dcf463164eff5ee26cd60f03b5bd97076a0b54bc61ec2c596016c206417dd58fa94b1cff6b7ee6e935790904cdb53446c4c01a71f3b83f395142fdd01010852beb142c7af701e01007d2969a27b2db83fa5f7f9b72c12090f62a51899dfca3b0927002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444062155d3d05b0eae448b5814cb4c4d33b4b66bb94ebffc1dba7b1003650fdc4aea2b6e2abf4e5bf041d6ff0b52ca2ebbe663480236e149bd5e21511e715134c04", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "28505d751c53f896b5b381d2b8b7bd85011e93af9697ce5b5f97caff92a4ff9d", - "sequence_number": "2592604223019102058", + "sender": "8fb6127415d329d85b4114f186b4fbfd3482f5641b32ba64d161358b0f450e5f", + "sequence_number": "10319453198047505295", "payload": { "EntryFunction": { "module": { - "address": "f066aabe3b0aa6d823edc0ca5d69d68f2f5055d98d0c054792a933f6a93b5c00", - "name": "VxPKiXi_Coin" + "address": "fdc1dd356292312fe49b46fb69a61458b8ce40212f91e37023b0034ac7849e6e", + "name": "BPFVXLvHgOJocTPnkZ_Coin" }, - "function": "QvRDkmoVyQTaZHVhXSxcCGuz4", + "function": "fZFvyBucUOHmMtEaNIiuurGqTBwsKR", "ty_args": [ { "vector": { "struct": { - "address": "fa7edab19264823887df4f1a656b3485c2c63922f0a73bb403ac86e4e8dcd857", - "module": "Yyxn", - "name": "xlj5", + "address": "7e18c6976e19930e6ee32d02fe15fddcd3f3c147d21a25d40e36b5f32e332ab3", + "module": "yLsxbSVOwWSVlkxypvn", + "name": "MYutLHVigDmjlxBBoMKLASXQ2", "type_args": [] } } }, { "struct": { - "address": "7d07d0f837f5d65f25581f7a9942d87f6ffe221b754f81297719eb78b79318f2", - "module": "ruQzLNgptFtOIqhbffssFzjHFyeVfb", - "name": "HMIyiYeRORPpNCTkhKzIRXbkzZPmk3", + "address": "70a5bf00e21040b01aad375a6743507253d6cb0bef9bd17b679515ea685ca2e8", + "module": "EIvkDcixVObQxqpNig0", + "name": "BURxeomKcfuVIkkkwChm7", "type_args": [] } }, { "struct": { - "address": "cc91d0aed6f67a840f2fc5cf9c181ca6528f62448c556d79eb193e27633bf317", - "module": "FJHolrUreqxAEZuinoxsYQTuT5", - "name": "COpmCCfVnyTZ", + "address": "1b2e7f03ba4f6e6d627ce14243c60b0cd5992c1d031e6c2d32c516601fac87b7", + "module": "Anvcztgt", + "name": "umiWTSOUWfbQSLYgGIlQARFPNbhsU1", "type_args": [] } }, { - "struct": { - "address": "a6a62405695c22f36587273aa80f1cd68c27c2f4bbf2c79a2f08fd7789dd15b1", - "module": "tcxcMDvjYyQqbcByiyCCl4", - "name": "P", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "5956bb82de8d9a89d59ead68150a87dea4460a5c3760070a38003f78f7ebb012", + "module": "KBUUiHiiDBssmDLQL3", + "name": "AqBozFjNvFKoyhWyV", + "type_args": [] + } + } } }, { "struct": { - "address": "5456d5d711a688d8650ec5d6515e745d35145d2a361541ceb2a298639f3165ca", - "module": "adlfrRILbqMaLRMeWPq", - "name": "aZxtLslCurkLiPrzNeouq4", + "address": "ddc4dcf50f49b80da174e040c27da5ba1b59252879c573c4dffdf752876efd34", + "module": "NKq", + "name": "RYfNTt", "type_args": [] } - }, + } + ], + "args": [ + "392ac5a611f11502fb3d559560b18d75", + "fe34e74525a694e9", + "abe3d63b31866595327aee2bf8ed94bdc32d4ee7bc0a4e369d6e89bcc222c2a9", + "bfaf5abaeb2dc42337953093a37baf58", + "98" + ] + } + }, + "max_gas_amount": "3685048587990418110", + "gas_unit_price": "18224268506418640625", + "expiration_timestamp_secs": "13605692111218686210", + "chain_id": 29 + }, + "signed_txn_bcs": "8fb6127415d329d85b4114f186b4fbfd3482f5641b32ba64d161358b0f450e5f8febe3410210368f02fdc1dd356292312fe49b46fb69a61458b8ce40212f91e37023b0034ac7849e6e1742504656584c7648674f4a6f6354506e6b5a5f436f696e1e665a467679427563554f486d4d7445614e49697575724771544277734b520506077e18c6976e19930e6ee32d02fe15fddcd3f3c147d21a25d40e36b5f32e332ab313794c73786253564f775753566c6b787970766e194d5975744c48566967446d6a6c7842426f4d4b4c4153585132000770a5bf00e21040b01aad375a6743507253d6cb0bef9bd17b679515ea685ca2e8134549766b44636978564f62517871704e6967301542555278656f6d4b63667556496b6b6b7743686d3700071b2e7f03ba4f6e6d627ce14243c60b0cd5992c1d031e6c2d32c516601fac87b708416e76637a7467741e756d695754534f5557666251534c596747496c51415246504e6268735531000606075956bb82de8d9a89d59ead68150a87dea4460a5c3760070a38003f78f7ebb012124b42555569486969444273736d444c514c33114171426f7a466a4e76464b6f79685779560007ddc4dcf50f49b80da174e040c27da5ba1b59252879c573c4dffdf752876efd34034e4b71065259664e5474000510392ac5a611f11502fb3d559560b18d7508fe34e74525a694e920abe3d63b31866595327aee2bf8ed94bdc32d4ee7bc0a4e369d6e89bcc222c2a910bfaf5abaeb2dc42337953093a37baf580198be4239a32aec2333f1f66b78a69be9fc0239869ce320d1bc1d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144403d28a10cdf4f0c549cefa43ec230792fc2658e04f0bd0945ea0e31cd6be3b10a1a28be0e200fcd52d4d70183716ffe111ceca2d336ab7a5e9796d75ab696c305", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "642f28579c0649a3ed597aa502ed2454c3755d153630812625b591cced960fb2", + "sequence_number": "2970420445790869281", + "payload": { + "EntryFunction": { + "module": { + "address": "6f3432c2ad9899f87d7944d89790e263e918c29c5117b0fe3fea83078656fb53", + "name": "taHvsbKyEEtJjHQbbVuOeTKhgTDbJc7_Coin" + }, + "function": "PZxHmTyEhWsrtEKaSfGZvUYIbdnHoVCt", + "ty_args": [ { - "struct": { - "address": "b74ccdc00071baf2c19d210ed4df374485895855605f521f980e65e5c3cdd554", - "module": "HeHALNyVBmnmaBIQPPlsYvQeQbQwjzDF7", - "name": "BPyQTBl7", - "type_args": [] + "vector": { + "struct": { + "address": "8524e1bff3790a9a4cbf2b94051ac76bf86eb3ac285fe4b2e545ffcdad684a04", + "module": "Z7", + "name": "EIjiPRawKeJyKqbJ", + "type_args": [] + } } }, - { - "vector": "u64" - }, { "vector": { "struct": { - "address": "62815895e577a53f9d620891d92b7b295c2239ae3545d2e0368f2a08b2c381f1", - "module": "CKFsMhcNOgZfawHuVAfGngACasda", - "name": "zJUMNNDUOmNIiLSJOInQWN", + "address": "b0d38910a88c19d80463a7cb589605ecfc3048baf2edccacddbfe85b751f5582", + "module": "gLJgzALdZADkbuZn", + "name": "sEflokOb9", "type_args": [] } } @@ -213,898 +326,1300 @@ { "vector": { "struct": { - "address": "73055b8d809efda16239c0fe9a0ebb631e2383c361ba43d4cb8f7ba4b4100047", - "module": "DTDEgUWCYkkotrgG3", - "name": "jslFRVmpyvDtoYZhNFNWqZTcSP", + "address": "4d8368d70bfa74bcfaca9d4f1bf772ea9dbfe24ae6d2897e589292fd77bd360f", + "module": "Rp9", + "name": "JWZfFATAr", "type_args": [] } } }, { - "vector": { - "vector": "bool" + "struct": { + "address": "5397093bbc857502123f53ec878f4a16654783b27af4fd15f3026efeb92e3ead", + "module": "AyHvkIOPm4", + "name": "lytXkw8", + "type_args": [] + } + }, + { + "struct": { + "address": "9e923412ce21c119267695ffb89190d246e4cacacbbd052bfc0760e48a8326f7", + "module": "irrFvwLKiMhbOnhSNUf", + "name": "DgZIFspIOEWHHxLCHdwCViUfsn", + "type_args": [] } } ], "args": [ - "63", - "00", - "4c1644b01c901770", - "d89c665cf8f4fa9167ff536292fe4805280408933be8b5af5ab6e795bdbcc684", - "3554b37b01c5ec47e54b1e2fcbc0e3af", - "ce", - "6e52f30c677f3e9d" + "ef", + "580431c60c33522e7170b1d04fb2a270" ] } }, - "max_gas_amount": "12280717757782111148", - "gas_unit_price": "2816398204727124829", - "expiration_timestamp_secs": "3290632587629072169", - "chain_id": 37 + "max_gas_amount": "4295949611041354107", + "gas_unit_price": "9505809599834404731", + "expiration_timestamp_secs": "8639185162411237087", + "chain_id": 99 }, - "signed_txn_bcs": "28505d751c53f896b5b381d2b8b7bd85011e93af9697ce5b5f97caff92a4ff9d6a2f3bfccdc7fa2302f066aabe3b0aa6d823edc0ca5d69d68f2f5055d98d0c054792a933f6a93b5c000c5678504b6958695f436f696e19517652446b6d6f56795154615a485668585378634347757a340a0607fa7edab19264823887df4f1a656b3485c2c63922f0a73bb403ac86e4e8dcd857045979786e04786c6a3500077d07d0f837f5d65f25581f7a9942d87f6ffe221b754f81297719eb78b79318f21e7275517a4c4e67707446744f4971686266667373467a6a484679655666621e484d4979695965524f5250704e43546b684b7a495258626b7a5a506d6b330007cc91d0aed6f67a840f2fc5cf9c181ca6528f62448c556d79eb193e27633bf3171a464a486f6c72557265717841455a75696e6f78735951547554350c434f706d434366566e79545a0007a6a62405695c22f36587273aa80f1cd68c27c2f4bbf2c79a2f08fd7789dd15b116746378634d44766a5979517162634279697943436c34015000075456d5d711a688d8650ec5d6515e745d35145d2a361541ceb2a298639f3165ca1361646c667252494c62714d614c524d6557507116615a78744c736c4375726b4c6950727a4e656f7571340007b74ccdc00071baf2c19d210ed4df374485895855605f521f980e65e5c3cdd55421486548414c4e7956426d6e6d6142495150506c7359765165516251776a7a444637084250795154426c37000602060762815895e577a53f9d620891d92b7b295c2239ae3545d2e0368f2a08b2c381f11c434b46734d68634e4f675a6661774875564166476e67414361736461167a4a554d4e4e44554f6d4e49694c534a4f496e51574e00060773055b8d809efda16239c0fe9a0ebb631e2383c361ba43d4cb8f7ba4b4100047114454444567555743596b6b6f74726747331a6a736c4652566d70797644746f595a684e464e57715a54635350000606000701630100084c1644b01c90177020d89c665cf8f4fa9167ff536292fe4805280408933be8b5af5ab6e795bdbcc684103554b37b01c5ec47e54b1e2fcbc0e3af01ce086e52f30c677f3e9dac336f13bcdf6daa5de3ceca3edb1527298ff467e7acaa2d25002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440481a1966e7da968b18f85fb44b787b45d29bd85b0a87c105dba0cdac32d9b80671f2cf4a9fca3647e43814ed23be55990c1f44d518a342447f3f36e3041b9302", + "signed_txn_bcs": "642f28579c0649a3ed597aa502ed2454c3755d153630812625b591cced960fb22117ec50a80d3929026f3432c2ad9899f87d7944d89790e263e918c29c5117b0fe3fea83078656fb53247461487673624b794545744a6a4851626256754f65544b68675444624a63375f436f696e20505a78486d5479456857737274454b615366475a7655594962646e486f5643740506078524e1bff3790a9a4cbf2b94051ac76bf86eb3ac285fe4b2e545ffcdad684a04025a371045496a69505261774b654a794b71624a000607b0d38910a88c19d80463a7cb589605ecfc3048baf2edccacddbfe85b751f558210674c4a677a414c645a41446b62755a6e097345666c6f6b4f62390006074d8368d70bfa74bcfaca9d4f1bf772ea9dbfe24ae6d2897e589292fd77bd360f03527039094a575a66464154417200075397093bbc857502123f53ec878f4a16654783b27af4fd15f3026efeb92e3ead0a417948766b494f506d34076c7974586b773800079e923412ce21c119267695ffb89190d246e4cacacbbd052bfc0760e48a8326f7136972724676774c4b694d68624f6e68534e55661a44675a49467370494f45574848784c434864774356695566736e000201ef10580431c60c33522e7170b1d04fb2a2707bf1180b69479e3b7bb7a094776beb83dfde5802228de47763002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406fc084fd834622c26a3d443ae3e7ab419c027d5806daef62f2e4258bf8020335f2272dfd2fdc04ced2f9628676346da41f821c2ec69a209e0728f986ad8ab405", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "704f51770a300c83fe50b15ccd55c033e3a586cceab9cc10fa1d666c7f32db1b", - "sequence_number": "4434821165149788175", + "sender": "d6abf9249bde4e56b4cec4d00f568aa20795a8149a0ba73db571bfb0cd1e6075", + "sequence_number": "13222762460728728129", "payload": { "EntryFunction": { "module": { - "address": "bde8beb96188d747ecb0af757b2577c913940e16e53c26c13c601721b758a65d", - "name": "ZKaRPFOjxMivEpQbtxVRfxW2_Coin" + "address": "2c630a955cba95a21eb61038b56106b8df47c2196b5c4e502299241e2d65c8be", + "name": "LxTTExbO7_Coin" }, - "function": "JY5", + "function": "NcxVvufsoPehPSva2", "ty_args": [ { - "struct": { - "address": "57a14f62ee36bc620168d62da4eb73024a45c42dbd087a0be10535ede468b307", - "module": "SrZWYwEFwVWiTwAAwROlmPTYwDObVs7", - "name": "lwMlDaEdfRgtSmrtkmJvdVpewARsuVkV5", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "00c3a4c06c54f0a31617f12d32baec31dec3d03c66b949dd8e37d8cdd9d1ebcd", + "module": "fuJyeiWMhuesjtdiV2", + "name": "TApgwnnSxXQZxiQRCeWlAROBelSEgo", + "type_args": [] + } + } } }, { "struct": { - "address": "d9d1ebcd76d8e5b13e11a7eaaa3df42e3ea81b61d6b55c245f56b1e0344e5f06", - "module": "MinJJnnfHqvQUnexmWTtMfMxBYRgTa5", - "name": "Daf7", + "address": "4f8641bc3f8e01a399e35f2a9b4151c845f0ca0220a3124fd5c9409e5fd961bb", + "module": "glgx", + "name": "tUwhrSAUntgaWp", "type_args": [] } }, { "vector": { "struct": { - "address": "de2fac53cd494b87683944d14cf0994a93163142d24e60d61d85e76c98db2b7b", - "module": "xzH7", - "name": "yJLKbKYiTHPUNWDfheQHONmhtKbcle", + "address": "4ca95b62c0fc80f43412f7e082c40cd2aa7c408f926d1e7ef8dc4ce199fa5694", + "module": "ukJNMzpHalbPBCsBwbSpaEkFi", + "name": "ngtUCxUeCgcjcNOO9", "type_args": [] } } }, { "struct": { - "address": "913b2a61dcf07f2e9f382ae0abfe0349f368f56421678c2169ec153159dc9150", - "module": "GyAGzKPPvymNiOyPsePMGSdzoXnIc7", - "name": "zWlugnLdyrqnbsEKszBDzbxSdvLUQyZK", + "address": "fe0349f368f56421678c2169ec153159dc9150cb25cbe8447f356053d3ce299e", + "module": "xDJfCWn5", + "name": "kDranhwTsrWcNvqiGKO3", "type_args": [] } }, - { - "vector": { - "vector": { - "struct": { - "address": "b1fed38a7b4d2d8c0299268b3b253b9fbe8f88e038697d8ab6c70cb2bd1b7c6e", - "module": "wshhbiieZcZNf", - "name": "XRFcPMRJTEWiET", - "type_args": [] - } - } - } - }, { "struct": { - "address": "74558aa16f49aeb9b8cc113c018b31479490672bc91a9723623bdec5776b5ae2", - "module": "RLhRpqAghBDVLeDPjm4", - "name": "YfDCifzaoCdBmXPjJHEP1", + "address": "bf373279b0dedf7d6b6afc3b3178a7c50c2db2dccb9084d2040a1e1c3f1c84e4", + "module": "NLZHfRRePhLtpH8", + "name": "InKOUtWKttONPLxDpORUygBjUfAZUzv", "type_args": [] } } ], "args": [ - "75692ee9fefe7a9f77058da16c81e6c16307d59c506402ea361fb4307c39d20a", - "835ace4377243888ca8798edddbdc0dd675432973c495ee30a08eb4e1f3d0f8b" + "652280867781bdb1fed38a7b4d2d8c0299268b3b253b9fbe8f88e038697d8ab6", + "b2", + "dac7c103c53063b5", + "41dc98024cea4802", + "e94edfe097af53bb075f8c06a2859b62", + "a813eadeec031b091c6029872550a277", + "b2af9c477adcae21" ] } }, - "max_gas_amount": "16215824449604551441", - "gas_unit_price": "16193022985363382274", - "expiration_timestamp_secs": "2852043486238873068", - "chain_id": 170 + "max_gas_amount": "7339992893755117158", + "gas_unit_price": "17475894077085177983", + "expiration_timestamp_secs": "8199206587883525069", + "chain_id": 82 }, - "signed_txn_bcs": "704f51770a300c83fe50b15ccd55c033e3a586cceab9cc10fa1d666c7f32db1b0f18235f5aa68b3d02bde8beb96188d747ecb0af757b2577c913940e16e53c26c13c601721b758a65d1d5a4b615250464f6a784d69764570516274785652667857325f436f696e034a5935060757a14f62ee36bc620168d62da4eb73024a45c42dbd087a0be10535ede468b3071f53725a5759774546775657695477414177524f6c6d50545977444f62567337216c774d6c4461456466526774536d72746b6d4a76645670657741527375566b56350007d9d1ebcd76d8e5b13e11a7eaaa3df42e3ea81b61d6b55c245f56b1e0344e5f061f4d696e4a4a6e6e6648717651556e65786d5754744d664d78425952675461350444616637000607de2fac53cd494b87683944d14cf0994a93163142d24e60d61d85e76c98db2b7b04787a48371e794a4c4b624b5969544850554e574466686551484f4e6d68744b62636c650007913b2a61dcf07f2e9f382ae0abfe0349f368f56421678c2169ec153159dc91501e477941477a4b505076796d4e694f79507365504d4753647a6f586e496337207a576c75676e4c647972716e6273454b737a42447a62785364764c5551795a4b00060607b1fed38a7b4d2d8c0299268b3b253b9fbe8f88e038697d8ab6c70cb2bd1b7c6e0d77736868626969655a635a4e660e58524663504d524a544557694554000774558aa16f49aeb9b8cc113c018b31479490672bc91a9723623bdec5776b5ae213524c685270714167684244564c6544506a6d34155966444369667a616f4364426d58506a4a4845503100022075692ee9fefe7a9f77058da16c81e6c16307d59c506402ea361fb4307c39d20a20835ace4377243888ca8798edddbdc0dd675432973c495ee30a08eb4e1f3d0f8b1103c6fa6b2e0ae102e051629c2cb9e0ec153ca1707e9427aa002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444045c90dcd4614d30a285f323327fcd9a18cfb96e8d4b51baf408cb88869c161ee5c27bff1ab8e6f3d02ab83a89b805ecd6354913864f63eccea84193b019e6506", + "signed_txn_bcs": "d6abf9249bde4e56b4cec4d00f568aa20795a8149a0ba73db571bfb0cd1e6075411a1b9d66b080b7022c630a955cba95a21eb61038b56106b8df47c2196b5c4e502299241e2d65c8be0e4c7854544578624f375f436f696e114e637856767566736f50656850537661320506060700c3a4c06c54f0a31617f12d32baec31dec3d03c66b949dd8e37d8cdd9d1ebcd1266754a796569574d687565736a74646956321e54417067776e6e537858515a786951524365576c41524f42656c5345676f00074f8641bc3f8e01a399e35f2a9b4151c845f0ca0220a3124fd5c9409e5fd961bb04676c67780e74557768725341556e74676157700006074ca95b62c0fc80f43412f7e082c40cd2aa7c408f926d1e7ef8dc4ce199fa569419756b4a4e4d7a7048616c6250424373427762537061456b4669116e677455437855654367636a634e4f4f390007fe0349f368f56421678c2169ec153159dc9150cb25cbe8447f356053d3ce299e0878444a6643576e35146b4472616e687754737257634e767169474b4f330007bf373279b0dedf7d6b6afc3b3178a7c50c2db2dccb9084d2040a1e1c3f1c84e40f4e4c5a486652526550684c747048381f496e4b4f5574574b74744f4e504c7844704f52557967426a5566415a557a76000720652280867781bdb1fed38a7b4d2d8c0299268b3b253b9fbe8f88e038697d8ab601b208dac7c103c53063b50841dc98024cea480210e94edfe097af53bb075f8c06a2859b6210a813eadeec031b091c6029872550a27708b2af9c477adcae21664e2adea5e4dc657fd8036512d986f2cd13d74ef36ec97152002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402cd91424e3bd8bed85d9b48a3d89d25357bfeaa626a907e41ed1c30b81a53d94191d06c521cb5177c564fe167869a4b02cfc5b09aaea6cccd102e1423a677901", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "e0300fb2af98c1dbb89453f572246c816d9926c0c170672f88ecf7f31ba0e902", - "sequence_number": "2800249294766190279", + "sender": "5e79d29c30b86f11de5beb4f3bb607714c2a21e0cc4b02346843af75a4863362", + "sequence_number": "15143935663759118013", "payload": { "EntryFunction": { "module": { - "address": "f906305b488331f285d09953fd6ef35cc4d9683003f506b403bbe344eb5519a8", - "name": "AmBdyexJfwAuOKmRm_Coin" + "address": "3de48f82cce202873abe314abc5543556974558aa16f49aeb9b8cc113c018b31", + "name": "kySktHTTpomZIdNCTMhuBDhVGmmDc1_Coin" }, - "function": "rAZTBSYwhW", + "function": "DufPMUmAjkLDgsQQTUAM", "ty_args": [ + { + "vector": { + "vector": "address" + } + }, + { + "vector": { + "vector": "u64" + } + }, { "vector": { "struct": { - "address": "5dc1d15ae81869c4ff273fcfafc03d424d5048d072c54d58090dad85418ae1ca", - "module": "kFEKnJFyHGWqQZyNGBRPQvgnQ", - "name": "XKcSYVvIMHVQ", + "address": "db1b0f5aec70116b029caaf906305b488331f285d09953fd6ef35cc4d9683003", + "module": "TlqHpdRBxKwNyp2", + "name": "qswlZASFrnGLW", "type_args": [] } } }, { - "struct": { - "address": "1772f0c9bb1b59bfda6b1b5c405ef1cd6a3e4454035f57e6296d6092272454fe", - "module": "awrgqyMbDRXub", - "name": "PQpkcTBppS0", - "type_args": [] + "vector": { + "vector": "u128" } }, { - "struct": { - "address": "0b0933907b4ea015643fa122cfac9af2f0584c678da4d25a5ee0158accc51997", - "module": "BNDhjidqQiiWbAjFlvsQW", - "name": "hvQHHfSExiZxe3", - "type_args": [] + "vector": { + "struct": { + "address": "126f2a252d7872294e78ffc2760592e4fa9a35951df075e4d4735b078eb6c63d", + "module": "RHHlkQEwokfGi1", + "name": "GPFZkZQoAtKgd0", + "type_args": [] + } } }, { - "struct": { - "address": "d9d02cbf25f43f1ff402c455ab14e383153bfe88eee765114ffbedc850b7719e", - "module": "peQQbZyd", - "name": "wc", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "e2232ae0791a71cf38efea7bc3705a4d8db86d88bc066331c43d99a26ba93de1", + "module": "WFmFlvJTOIalqUrtmnQjMpX", + "name": "WINuEkKhwftjGRrttBfnHKnJviJXNCFD", + "type_args": [] + } + } } }, { "struct": { - "address": "5b283e633761df652f3ed47396b9f9d94d0d29423b248cb224522d0075d49671", - "module": "TkOJHvpvfBzSsioaMuR", - "name": "aQav5", + "address": "158accc51997b45901533466f6db3ea35a538f87fd286906db6ac1a02d88445d", + "module": "MgBZTfhbMSpiWqpLR0", + "name": "KxSFmIwijQFjkhLWIBWDhayQmgKBoG", "type_args": [] } } ], "args": [ - "49cd22ca28a067a96dab0e11efd4648433b61a7b2121256ab3ee708081f028da", - "0d" + "71e424cbef1f2ac9", + "01", + "01" ] } }, - "max_gas_amount": "18412968427985577241", - "gas_unit_price": "7802961839568221912", - "expiration_timestamp_secs": "15214679683176441959", - "chain_id": 176 + "max_gas_amount": "15795417235777155219", + "gas_unit_price": "9932769222204044383", + "expiration_timestamp_secs": "11099530764670004767", + "chain_id": 162 }, - "signed_txn_bcs": "e0300fb2af98c1dbb89453f572246c816d9926c0c170672f88ecf7f31ba0e902c7ae13b1e57bdc2602f906305b488331f285d09953fd6ef35cc4d9683003f506b403bbe344eb5519a816416d42647965784a667741754f4b6d526d5f436f696e0a72415a544253597768570506075dc1d15ae81869c4ff273fcfafc03d424d5048d072c54d58090dad85418ae1ca196b46454b6e4a467948475771515a794e474252505176676e510c584b6353595676494d48565100071772f0c9bb1b59bfda6b1b5c405ef1cd6a3e4454035f57e6296d6092272454fe0d6177726771794d6244525875620b5051706b6354427070533000070b0933907b4ea015643fa122cfac9af2f0584c678da4d25a5ee0158accc5199715424e44686a6964715169695762416a466c767351570e687651484866534578695a7865330007d9d02cbf25f43f1ff402c455ab14e383153bfe88eee765114ffbedc850b7719e0870655151625a796402776300075b283e633761df652f3ed47396b9f9d94d0d29423b248cb224522d0075d4967113546b4f4a4876707666427a5373696f614d755205615161763500022049cd22ca28a067a96dab0e11efd4648433b61a7b2121256ab3ee708081f028da010d192590aa3a0188ffd876648373b0496c67a8159f8f6625d3b0002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f1e77c1f811d31555b82ed431c20bbbcdd361c9d92902b85f9eded96a4491511d09839f5862436018c3ac2fd0497e715851356ef0eeb8721e3e0bef386fbb701", + "signed_txn_bcs": "5e79d29c30b86f11de5beb4f3bb607714c2a21e0cc4b02346843af75a4863362bd4ebb0b40112ad2023de48f82cce202873abe314abc5543556974558aa16f49aeb9b8cc113c018b31236b79536b74485454706f6d5a49644e43544d687542446856476d6d4463315f436f696e14447566504d556d416a6b4c44677351515455414d070606040606020607db1b0f5aec70116b029caaf906305b488331f285d09953fd6ef35cc4d96830030f546c714870645242784b774e7970320d7173776c5a415346726e474c57000606030607126f2a252d7872294e78ffc2760592e4fa9a35951df075e4d4735b078eb6c63d0e5248486c6b5145776f6b664769310e4750465a6b5a516f41744b67643000060607e2232ae0791a71cf38efea7bc3705a4d8db86d88bc066331c43d99a26ba93de11757466d466c764a544f49616c715572746d6e516a4d70582057494e75456b4b687766746a475272747442666e484b6e4a76694a584e4346440007158accc51997b45901533466f6db3ea35a538f87fd286906db6ac1a02d88445d124d67425a546668624d5370695771704c52301e4b7853466d4977696a51466a6b684c5749425744686179516d674b426f4700030871e424cbef1f2ac901010101937094c9499834db5fb46745fb48d8891feeac316c74099aa2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444068b6dda6e327631130de78cd5c8f7418a200d1e1c17369d78fdfaa1f2d8e584015b6b174bf940ec582be0dd75f57422ca61858ba2762ae1acb8cea21beab000d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "869602f21b32d569f970326578744fbbf91d0ae97405c80e0b4d4e086dccd2ac", - "sequence_number": "8350752623996713121", + "sender": "fe634b80b5a38c625df9af738ed24c5d2e51f014792886b57b4ef9a08763cb13", + "sequence_number": "27535578183918161", "payload": { "EntryFunction": { "module": { - "address": "00a3546eaf81a8f71935070e2c793ca6b787c7feea37696085fe634b80b5a38c", - "name": "HUpTFwMnzORtQRUQTkd_Coin" + "address": "d839b79d2b2ec04bef47c0c3eb146c0d9e2abe5b283e633761df652f3ed47396", + "name": "TKUlPeqjlhAQQOwRKFSQBSrSGkoHrt_Coin" }, - "function": "ZPPFbPSoOQuHEpMi", - "ty_args": [ - { - "vector": "bool" - } - ], + "function": "AtyznraCAsVQBcNxKANz8", + "ty_args": [], "args": [ - "01", - "ab9533566138687cd2ec256d2ae4c8d26b638181c61e938ab4da5b889d476fd7", - "b1", - "71a0238457393917", - "00", - "66c8b519ebfad31f91663851eac37ac4", - "73d66f19a98c3792f8367fdaf79df359f3653cee651aa78d62ea7ad9d1869028", - "df75e81533e5de25bab636d1afa18a9317c782a435b32c7a37db4e321d377329" + "eb87f1f938d141a4", + "678f193ad873b000a3546eaf81a8f71935070e2c793ca6b787c7feea37696085" ] } }, - "max_gas_amount": "9062239492371603291", - "gas_unit_price": "13296775297672042174", - "expiration_timestamp_secs": "14626097145987141461", - "chain_id": 232 + "max_gas_amount": "11764068562823368243", + "gas_unit_price": "5707241498503189844", + "expiration_timestamp_secs": "15668928689916847975", + "chain_id": 182 }, - "signed_txn_bcs": "869602f21b32d569f970326578744fbbf91d0ae97405c80e0b4d4e086dccd2aca1387c7044d5e3730200a3546eaf81a8f71935070e2c793ca6b787c7feea37696085fe634b80b5a38c184855705446774d6e7a4f527451525551546b645f436f696e105a5050466250536f4f51754845704d6901060008010120ab9533566138687cd2ec256d2ae4c8d26b638181c61e938ab4da5b889d476fd701b10871a023845739391701001066c8b519ebfad31f91663851eac37ac42073d66f19a98c3792f8367fdaf79df359f3653cee651aa78d62ea7ad9d186902820df75e81533e5de25bab636d1afa18a9317c782a435b32c7a37db4e321d3773295b5f53f4cd8ac37dbe56ee13afa287b8550feba4dc55facae8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444078a8599f483d6c6c7558e8789fb25c8ccb94720b6b59cede9b98045b429b53611a68de7f8776d44ceee5e0dedb35719a03c2935ed28f3f432778aceae6c7d00d", + "signed_txn_bcs": "fe634b80b5a38c625df9af738ed24c5d2e51f014792886b57b4ef9a08763cb135162566476d3610002d839b79d2b2ec04bef47c0c3eb146c0d9e2abe5b283e633761df652f3ed4739623544b556c5065716a6c684151514f77524b46535142537253476b6f4872745f436f696e154174797a6e7261434173565142634e784b414e7a38000208eb87f1f938d141a420678f193ad873b000a3546eaf81a8f71935070e2c793ca6b787c7feea37696085334e6d78075e42a35495a695e731344f67a76b3da03773d9b6002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406d1e38827468500143680a42a66bb990a266aab9cc068a38bc364caaac7c0a14f38a114fbce3cbc1eb7ce8e2ea3c738b550a3a15121b97582cf427aaf4d75f05", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "f4b516580e09ea7a7533ec76f633cb0fc67095461c81c4afee376affb68b39d1", - "sequence_number": "3101801249685340521", + "sender": "b9df74919d57cb7274d4b7011b69f0b6ba9d6c8a63a321ce1a269a4c190b31f6", + "sequence_number": "9616022168444437854", "payload": { "EntryFunction": { "module": { - "address": "913b28cd8ea64e1bbc713e03234ed8745cdf039e53c4b83c81fef0683dae4335", - "name": "hJghrBITptkgZgSeNDhJXnikQNweC_Coin" + "address": "4300619d934cd884e787074355e028ca8f56a0cd85309acb6db3f7b35db5d3d3", + "name": "LecmGTyHbJWi_Coin" }, - "function": "pVrwwnvVSzShlZHOeHNtdcNKMfAmv", + "function": "pjDk7", "ty_args": [ - { - "struct": { - "address": "8dfa75730167c36a39f323f737f8ec2d5e3b7b92c22ba775cd0ed282425a4114", - "module": "aaoiMOzhTnXZu", - "name": "UdBwkog", - "type_args": [] - } - }, - { - "struct": { - "address": "7a90f44b270ced66c73c961d3799533558d4d6304bb9fa8de1ab6c77ac13b478", - "module": "XKAzVbammgZWESzMxvO", - "name": "zoQSGjCbWIaSMpODr", - "type_args": [] - } - }, { "vector": { - "vector": "u8" + "struct": { + "address": "e8bff30aff52d07a52e23b1f04281f78eafacfd5371908a8b297555c03e3e444", + "module": "VUQFjJGRwWVKMAKiia4", + "name": "GsSXHHWeWFRDTnsCrbLzGPUGKM", + "type_args": [] + } } }, { - "struct": { - "address": "d89ee75cb1113d12b0f10abefe68c669fe561f3e610e0b0bf3ab120bbc793fe4", - "module": "O7", - "name": "nmLhEAddkPMYftzVwZOoFZhcGZhsZWut1", - "type_args": [] + "vector": { + "vector": "bool" } }, { "struct": { - "address": "771475ef01439c5dc2346154796f08328ac34bfa0b2b25f14a76c094729d60e7", - "module": "BWDIdZVJLhOjgknllbqkA1", - "name": "KxjmoKRjVnjxQcZOBZDhKjL6", + "address": "200ff188fc76f05eed82f4d6215934c94871573df05b744f3c8129e219e68e40", + "module": "ltdN", + "name": "ImuPuVYLzQyVLOGi1", "type_args": [] } }, { "vector": { - "vector": "signer" - } - }, - { - "vector": { - "vector": "u128" + "struct": { + "address": "82614bede62d772a15ad3276e1e6330af7471bd683b53b11b156f597a997b9f1", + "module": "jVuxYTorwNFAJkTdrDIeSFJw6", + "name": "KnPPVcGBxXCDFhBBXrJ", + "type_args": [] + } } } ], "args": [ - "cbb8890c6ce701f0", - "ce476d520350064dbf8019737d70589329bfe130eae8e7d350e848da297a063b", - "fcf6c9fd6adfc9fff84055c2d42a86d4856652e338711bfb9d04db013c74ee9e", - "01", - "6d9d404a4555ce7244ff5cc70e483838af6f43d6e0f4518c42ce14e8872f3787", - "c9020388386b41ca", - "00" + "ae4056b643fce7f73556d67c10933f28", + "21", + "aa083b1e189ed680472641a6723f8b75", + "a3f8f3ba9107e79c", + "b3df80b7bfcac661", + "678b40c8f70ec02b722fcb236a90d3a6", + "c7bf8e6029c234f7ac4a36fcb988247dcfec2f200105fd8720fd3c009e865a99" ] } }, - "max_gas_amount": "1867025542719666117", - "gas_unit_price": "14061964006813278264", - "expiration_timestamp_secs": "12115124549471106767", - "chain_id": 209 + "max_gas_amount": "13653972913826495318", + "gas_unit_price": "11631731741450810283", + "expiration_timestamp_secs": "1420956246263986001", + "chain_id": 136 }, - "signed_txn_bcs": "f4b516580e09ea7a7533ec76f633cb0fc67095461c81c4afee376affb68b39d169815b73cdcf0b2b02913b28cd8ea64e1bbc713e03234ed8745cdf039e53c4b83c81fef0683dae433522684a67687242495470746b675a6753654e44684a586e696b514e7765435f436f696e1d70567277776e7656537a53686c5a484f65484e7464634e4b4d66416d7607078dfa75730167c36a39f323f737f8ec2d5e3b7b92c22ba775cd0ed282425a41140d61616f694d4f7a68546e585a7507556442776b6f6700077a90f44b270ced66c73c961d3799533558d4d6304bb9fa8de1ab6c77ac13b47813584b417a5662616d6d675a5745537a4d78764f117a6f5153476a4362574961534d704f44720006060107d89ee75cb1113d12b0f10abefe68c669fe561f3e610e0b0bf3ab120bbc793fe4024f37216e6d4c68454164646b504d5966747a56775a4f6f465a6863475a68735a577574310007771475ef01439c5dc2346154796f08328ac34bfa0b2b25f14a76c094729d60e71642574449645a564a4c684f6a676b6e6c6c62716b4131184b786a6d6f4b526a566e6a7851635a4f425a44684b6a4c36000606050606030708cbb8890c6ce701f020ce476d520350064dbf8019737d70589329bfe130eae8e7d350e848da297a063b20fcf6c9fd6adfc9fff84055c2d42a86d4856652e338711bfb9d04db013c74ee9e0101206d9d404a4555ce7244ff5cc70e483838af6f43d6e0f4518c42ce14e8872f378708c9020388386b41ca0100c5f762d4d601e91938206fbec22126c3cff6d6cc969121a8d1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444052ad9888ba9ece92dedb09df12681630e6fcbea135b4d50f08c0e962f414e69d725cf6b0b8e8b1a53039b829fd1f46f69aa4a8ccef4fda0646421eb5b1bd1907", + "signed_txn_bcs": "b9df74919d57cb7274d4b7011b69f0b6ba9d6c8a63a321ce1a269a4c190b31f65e8569de36f97285024300619d934cd884e787074355e028ca8f56a0cd85309acb6db3f7b35db5d3d3114c65636d47547948624a57695f436f696e05706a446b37040607e8bff30aff52d07a52e23b1f04281f78eafacfd5371908a8b297555c03e3e44413565551466a4a47527757564b4d414b696961341a477353584848576557465244546e734372624c7a475055474b4d0006060007200ff188fc76f05eed82f4d6215934c94871573df05b744f3c8129e219e68e40046c74644e11496d75507556594c7a5179564c4f47693100060782614bede62d772a15ad3276e1e6330af7471bd683b53b11b156f597a997b9f1196a56757859546f72774e46414a6b54647244496553464a7736134b6e505056634742785843444668424258724a000710ae4056b643fce7f73556d67c10933f28012110aa083b1e189ed680472641a6723f8b7508a3f8f3ba9107e79c08b3df80b7bfcac66110678b40c8f70ec02b722fcb236a90d3a620c7bf8e6029c234f7ac4a36fcb988247dcfec2f200105fd8720fd3c009e865a9956fb6ef505a87cbdabb3cf2b64366ca151f7ef6b2d40b81388002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444062eda0fc0c0081f975945675eb553ab5e20f06a4d555255f6e5c4c3d0d8c4565913e7adaaa79056bcb3d8f7825b83960520f8d17c6aff56109c36c40b96aee01", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "60039e095c21c6280afc95d28b441cd480945a7307363a4cfef06efba7774cfa", - "sequence_number": "12440803281185121067", + "sender": "4a995849ef5ef9d1a80c2e9c22816f97cc667f74ad4031f2a81391a1c66bd1d4", + "sequence_number": "15718082279670922044", "payload": { "EntryFunction": { "module": { - "address": "81f7fb5abab5c7567fc9d994cd9e21ba7bf8881025d68fd028648c76196f4142", - "name": "YDcedzcSYyKigPyLLbPAhDZMWlrgC8_Coin" + "address": "b80d093eded486b86cc1e7875f023b19d67332c261296604a38a2f720110aeab", + "name": "RWWlkgaSEOnKhgStfdmVq_Coin" }, - "function": "pjinIUtfwvwEZhrbPZjpHlThRXGlxM", + "function": "TsLmCYabR3", "ty_args": [ { - "struct": { - "address": "adef5785329d5000b459bb4f9f289e1698e24ce1d81977af63a7ba1f38d758b3", - "module": "IiPGdvtAReXjMVJcyQK", - "name": "aXQwpg", - "type_args": [] + "vector": { + "vector": { + "vector": "signer" + } + } + }, + { + "vector": { + "vector": "u64" } }, { "struct": { - "address": "89977a05a56e353f5c49bebd0767eecf42094a2332e57b3ae000fd93046eb930", - "module": "OzGcx2", - "name": "abuUPvEcp", + "address": "4decb8fbefcb92d45325dc39c48042b94abe3b4fe6e945dfc15364f91c34b224", + "module": "uOIOe0", + "name": "bEeedDrIlKjgamT3", "type_args": [] } }, { "struct": { - "address": "4a923956baf8fc637267b8f372472c764b3a4f6073fe7ba332752cd41bcb6237", - "module": "BcrKctQmOuuHPSYvhFoUBQS2", - "name": "zJRQEbVPqn", + "address": "322cbece9183344d09da09b5b33cb60a5981252cc046a369a9cf0abfe0994375", + "module": "ffAwanSurjHHeqTzcPYNQrrOGRJuWEFE", + "name": "dff4", "type_args": [] } }, { "vector": { "vector": { - "vector": "u128" + "struct": { + "address": "b58df2df1704d6f6ab4524eb676406204c1839bfaaf5d0d6819f2ec0e9c731f4", + "module": "ZjXlEltbvwWmFiGssdOy9", + "name": "ubpuihlNulpADSwxUjoVbD7", + "type_args": [] + } } } - } - ], - "args": [ - "56040f81dc0e9932e67bee8d093ff7dc", - "f491c95dc30e94c0" - ] - } - }, - "max_gas_amount": "6410391226991906913", - "gas_unit_price": "14708646698958368515", - "expiration_timestamp_secs": "12012681263968585384", - "chain_id": 121 - }, - "signed_txn_bcs": "60039e095c21c6280afc95d28b441cd480945a7307363a4cfef06efba7774cfa2ba38d87ab9ca6ac0281f7fb5abab5c7567fc9d994cd9e21ba7bf8881025d68fd028648c76196f41422359446365647a635359794b696750794c4c62504168445a4d576c726743385f436f696e1e706a696e49557466777677455a687262505a6a70486c54685258476c784d0407adef5785329d5000b459bb4f9f289e1698e24ce1d81977af63a7ba1f38d758b31349695047647674415265586a4d564a6379514b06615851777067000789977a05a56e353f5c49bebd0767eecf42094a2332e57b3ae000fd93046eb930064f7a476378320961627555507645637000074a923956baf8fc637267b8f372472c764b3a4f6073fe7ba332752cd41bcb6237184263724b6374516d4f7575485053597668466f55425153320a7a4a525145625650716e0006060603021056040f81dc0e9932e67bee8d093ff7dc08f491c95dc30e94c061102274db48f65803af22323e9c1fcca886d6b2f69db5a679002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402a31220115b1dd5456964c19fa097659f84ce1e8cf7d04e79bb7a063f30b68691a3e4c2202957a61d89fdba3f9fdfd8e8e6f2d28c51a73bf714f3deb81a9350e", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "2840b829b1a82bf4a695cc253e384d14048acfe2855afc520f2b57678e25e48e", - "sequence_number": "5518872340837970104", - "payload": { - "EntryFunction": { - "module": { - "address": "ca976ae5dec01bc97765345c590e980d3a862a34f1f12175128807b3885e58e3", - "name": "XnLdNotwOwWDqrgNlqOwEezpE_Coin" - }, - "function": "NUJIkVqRpFXDWlHxPbubCEtDp", - "ty_args": [ + }, { "struct": { - "address": "5d5b79470e757f5224f9c2ff40f91caa1009f930d6736514c58d53153bbc973b", - "module": "RQpSnDenchvDCyZtsKcxZssGNISZbX", - "name": "OlEwdUQysf4", + "address": "6735aa9261726c014632c1efde48963fd944940c234b265572e17940b1657978", + "module": "vOSjEtxJzWtHzBFevVQeZNmG", + "name": "QsouQERjVhLXBvCMchEDdfEIzpM", "type_args": [] } }, { "vector": { - "vector": "u128" - } - }, + "struct": { + "address": "6fe2480820651d18baa6f7733ca8b7b9759b702e8feea75551fd54a5016abd7f", + "module": "RxONPUYsUR9", + "name": "frRfxRlVctBbMmUZEmjzAeaMCIlpErAJ1", + "type_args": [] + } + } + }, + { + "struct": { + "address": "2bc3cf93b7a0cb6cf53368cc9c36aaf31074ed158ace7eca08d3a1e78db109db", + "module": "eFHXEusORmvUSIclJW", + "name": "woItodFBReSjBgTuVwDxpVCo7", + "type_args": [] + } + }, + { + "struct": { + "address": "856652e338711bfb9d04db013c74ee9e5eefbc6a2c8aa056e625f126b7bc5d1a", + "module": "j5", + "name": "MQaSdweM", + "type_args": [] + } + }, { "struct": { - "address": "d8c1617de732983c3d9479394b5b84d9ce9da78a9d400baa332193566ba76dbc", - "module": "SYDhBwdHCtxdPhITtkKOlz8", - "name": "iQMG3", + "address": "400859915c3304c507674801f521efd712ad7dcd54666201a1409b6897e54cef", + "module": "lJuuIKvao", + "name": "qGglBigfJIEqljouDsqIQElwey4", "type_args": [] } } ], "args": [ - "01", - "01", - "c3fef31a3ca1e14970535ada4446d54f" + "1674a6fad1b08e55450decb9019b656fe3d9878ab27eb6511ee0c3d39d72849d", + "de5212c84e586b50934f62135a912066", + "99", + "2febe15981188fd6ca1d04f8305bdb99" ] } }, - "max_gas_amount": "1219951378163840144", - "gas_unit_price": "3798051916844728159", - "expiration_timestamp_secs": "15549149336408166729", - "chain_id": 165 + "max_gas_amount": "10100996247913873977", + "gas_unit_price": "11303796198471544444", + "expiration_timestamp_secs": "10519654434661632759", + "chain_id": 45 }, - "signed_txn_bcs": "2840b829b1a82bf4a695cc253e384d14048acfe2855afc520f2b57678e25e48eb830605c27f9964c02ca976ae5dec01bc97765345c590e980d3a862a34f1f12175128807b3885e58e31e586e4c644e6f74774f7757447172674e6c714f7745657a70455f436f696e194e554a496b56715270465844576c487850627562434574447003075d5b79470e757f5224f9c2ff40f91caa1009f930d6736514c58d53153bbc973b1e525170536e44656e6368764443795a74734b63785a7373474e49535a62580b4f6c4577645551797366340006060307d8c1617de732983c3d9479394b5b84d9ce9da78a9d400baa332193566ba76dbc1753594468427764484374786450684954746b4b4f6c7a380569514d473300030101010110c3fef31a3ca1e14970535ada4446d54f9034b49a5023ee105f7f056e1864b53449111c44f0acc9d7a5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c3c115ea61385c9e63fd6967f8c7c9b4111b479b45ca6ea39911d26f1fad22d2c68d4b51d4409bf900635ab5df3d8046569b22c93a9228c480e66640fec35009", + "signed_txn_bcs": "4a995849ef5ef9d1a80c2e9c22816f97cc667f74ad4031f2a81391a1c66bd1d43cbb252e8ed821da02b80d093eded486b86cc1e7875f023b19d67332c261296604a38a2f720110aeab1a5257576c6b676153454f6e4b6867537466646d56715f436f696e0a54734c6d4359616252330a06060605060602074decb8fbefcb92d45325dc39c48042b94abe3b4fe6e945dfc15364f91c34b22406754f494f65301062456565644472496c4b6a67616d54330007322cbece9183344d09da09b5b33cb60a5981252cc046a369a9cf0abfe09943752066664177616e5375726a48486571547a6350594e5172724f47524a7557454645046466663400060607b58df2df1704d6f6ab4524eb676406204c1839bfaaf5d0d6819f2ec0e9c731f4155a6a586c456c74627677576d4669477373644f7939177562707569686c4e756c704144537778556a6f5662443700076735aa9261726c014632c1efde48963fd944940c234b265572e17940b165797818764f536a4574784a7a5774487a424665765651655a4e6d471b51736f755145526a56684c584276434d63684544646645497a704d0006076fe2480820651d18baa6f7733ca8b7b9759b702e8feea75551fd54a5016abd7f0b52784f4e50555973555239216672526678526c56637442624d6d555a456d6a7a4165614d43496c704572414a3100072bc3cf93b7a0cb6cf53368cc9c36aaf31074ed158ace7eca08d3a1e78db109db12654648584575734f526d76555349636c4a5719776f49746f6446425265536a42675475567744787056436f370007856652e338711bfb9d04db013c74ee9e5eefbc6a2c8aa056e625f126b7bc5d1a026a35084d5161536477654d0007400859915c3304c507674801f521efd712ad7dcd54666201a1409b6897e54cef096c4a7575494b76616f1b7147676c426967664a4945716c6a6f754473714951456c776579340004201674a6fad1b08e55450decb9019b656fe3d9878ab27eb6511ee0c3d39d72849d10de5212c84e586b50934f62135a9120660199102febe15981188fd6ca1d04f8305bdb9939c275f291f22d8c7cae4e9fc026df9cf78ade09f951fd912d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e859e35d5c29a853611492f919bd0b80d54127ca7d882614d74960b5cf3c84f0e7ddd8ced0e512bcf09ba34541370f001eb49b54b9e259d6bf093725953d650f", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "37add42d66e8b62e0b77cad2f9127da9886c6d9a28f21a73f132251fc53c11a5", - "sequence_number": "16403975168816619338", + "sender": "5d5d82a19a55bc6c805e2264584b01a36d42be537d15d1b3ca6cbefc6ac953d6", + "sequence_number": "9177619198438643909", "payload": { "EntryFunction": { "module": { - "address": "d184c931a465098e3666deb2a80104a2e1097b98f9c85c7800d53093cb5f5eaa", - "name": "EDzoghCKNj_Coin" + "address": "345b9925c0f1f779ae7cf564bb4dfca6afdfe7b9f4905117f0b0b154fd03336c", + "name": "exyqp_Coin" }, - "function": "LQgqLzCSetg", + "function": "XXSimzqLTEUkmonKS5", "ty_args": [ + { + "vector": "u128" + }, + { + "vector": { + "vector": { + "struct": { + "address": "38d758b39c63f8e4b79d10b3c41862018b1739867390c1f277db7adf7dda8bf7", + "module": "ZwdjOWFwCZlqwXaStMZD", + "name": "MHZkyJRjHssrEQRwYInXINRsVDRDBod7", + "type_args": [] + } + } + } + }, + { + "struct": { + "address": "fc83510f8489c6ed603e3b28722b6718f14a988456f2484794d29f4e48229f4b", + "module": "du", + "name": "YrYaGdDabPjAZfnQUFbNccpE", + "type_args": [] + } + }, { "struct": { - "address": "b9fb1632081c3996cc6289cfbeaef045f9cb575a49f63c16b35aed2e445d388d", - "module": "iWYUvDjwpOrxsQF", - "name": "rkUyDxChRFfNAXV0", + "address": "3956baf8fc637267b8f372472c764b3a4f6073fe7ba332752cd41bcb623760eb", + "module": "IMZtZrfDTzR", + "name": "wyCuCouHTwNwwzpSwhWZ0", + "type_args": [] + } + }, + { + "struct": { + "address": "c36e662e3004ebf52b8f38afc1e756f4f0b067be87c789681ade14dfc1c4c60b", + "module": "cKhlFCvn", + "name": "AsiZfBehGDsuNy6", + "type_args": [] + } + }, + { + "struct": { + "address": "a01995e7f782a6359ecd5b8c696f046d5475a9f19cf498a1e37b7018df536944", + "module": "EBPb", + "name": "dOuHUjejEpWS", "type_args": [] } } ], "args": [ - "0a9ba1be69471b779dc158aef22778feee6d44acba431b06530c9a23265948f7", - "84f3d49579cd2a55d2de4b4dfb7eda93", - "0744c63a848f4b9c427942efda887555", - "332bd7399041fb9f4a0e1dadbc5b5852", - "14", - "01", - "01", - "01", + "033e79ca976ae5dec01bc97765345c590e980d3a862a34f1f12175128807b388", + "e3", "00", - "8e" + "15", + "00" ] } }, - "max_gas_amount": "3836006231316372569", - "gas_unit_price": "16613171545488070686", - "expiration_timestamp_secs": "1863092544196614113", - "chain_id": 235 + "max_gas_amount": "7282141613084938976", + "gas_unit_price": "16718807614804579272", + "expiration_timestamp_secs": "9403326547462170850", + "chain_id": 129 }, - "signed_txn_bcs": "37add42d66e8b62e0b77cad2f9127da9886c6d9a28f21a73f132251fc53c11a54a9fa40981a0a6e302d184c931a465098e3666deb2a80104a2e1097b98f9c85c7800d53093cb5f5eaa0f45447a6f6768434b4e6a5f436f696e0b4c5167714c7a43536574670107b9fb1632081c3996cc6289cfbeaef045f9cb575a49f63c16b35aed2e445d388d0f6957595576446a77704f727873514610726b5579447843685246664e41585630000a200a9ba1be69471b779dc158aef22778feee6d44acba431b06530c9a23265948f71084f3d49579cd2a55d2de4b4dfb7eda93100744c63a848f4b9c427942efda88755510332bd7399041fb9f4a0e1dadbc5b585201140101010101010100018e591ccce5573b3c351e98711180d78de6e1978440cc08db19eb002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144408ac8cddabedd81aea61bcca7fe1cbd045e4f6ab7aa02c980aab7668eaa618fc473bf2093514c2e46343f0fb600145a22d1375c040edde999545eb1ea2091ba01", + "signed_txn_bcs": "5d5d82a19a55bc6c805e2264584b01a36d42be537d15d1b3ca6cbefc6ac953d6c598bd2e09745d7f02345b9925c0f1f779ae7cf564bb4dfca6afdfe7b9f4905117f0b0b154fd03336c0a65787971705f436f696e12585853696d7a714c5445556b6d6f6e4b533506060306060738d758b39c63f8e4b79d10b3c41862018b1739867390c1f277db7adf7dda8bf7145a77646a4f574677435a6c7177586153744d5a44204d485a6b794a526a487373724551527759496e58494e527356445244426f64370007fc83510f8489c6ed603e3b28722b6718f14a988456f2484794d29f4e48229f4b02647518597259614764446162506a415a666e515546624e6363704500073956baf8fc637267b8f372472c764b3a4f6073fe7ba332752cd41bcb623760eb0b494d5a745a726644547a521577794375436f754854774e77777a70537768575a300007c36e662e3004ebf52b8f38afc1e756f4f0b067be87c789681ade14dfc1c4c60b08634b686c4643766e0f4173695a66426568474473754e79360007a01995e7f782a6359ecd5b8c696f046d5475a9f19cf498a1e37b7018df53694404454250620c644f7548556a656a45705753000520033e79ca976ae5dec01bc97765345c590e980d3a862a34f1f12175128807b38801e3010001150100e09204f4365d0f65c8d38514f22205e8e2a87b88ac537f8281002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444059b81ca3d2cb40eba39363107e5d9ad1fec185d5f41952ca08a3e284657d433b034bb8e43f146d07c02e888b913033c8f10052d984a634e1a32ac646164f1706", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "4e042f633cec6fa02a922b0606809cb8fc089dcc7357f8d96be5f3eed2ef1e9d", - "sequence_number": "13888642121806453276", + "sender": "7d374122ab3c356625126028df8bb1045a4d2170eb35a6d8c1617de732983c3d", + "sequence_number": "9665366335728380308", "payload": { "EntryFunction": { "module": { - "address": "b959010ed51103ab3e3af6b948c01504f6059db5807a8f230a21d419b852ad67", - "name": "HIATvkOl_Coin" + "address": "9474b931316737487845f5a0981172e44d19dc727f79c366219727fd64c5437c", + "name": "QlrnmliBiPjLojmJsTD1_Coin" }, - "function": "ZAbJLZzMd3", + "function": "gDWtGJVESwDIz", + "ty_args": [], + "args": [ + "01", + "b8399fd8c943fcacf93400278999e1b98731e913ccf7e284dd5f81266749e7b9", + "586be7fc9f4a5dea", + "0b332f0f3c31c7272d0be9687ca77173d5107e397c36813dd317e424ea642b2a", + "cb3e4fca3e2603dc", + "2f3a00c06f80f28805ad22dbb762afa88909a27a1213431373f79cf3a60a4093", + "f5", + "01" + ] + } + }, + "max_gas_amount": "13656846481406653787", + "gas_unit_price": "15188488487885098201", + "expiration_timestamp_secs": "8776315331632196665", + "chain_id": 157 + }, + "signed_txn_bcs": "7d374122ab3c356625126028df8bb1045a4d2170eb35a6d8c1617de732983c3d94e91b1979472286029474b931316737487845f5a0981172e44d19dc727f79c366219727fd64c5437c19516c726e6d6c694269506a4c6f6a6d4a735444315f436f696e0d67445774474a5645537744497a0008010120b8399fd8c943fcacf93400278999e1b98731e913ccf7e284dd5f81266749e7b908586be7fc9f4a5dea200b332f0f3c31c7272d0be9687ca77173d5107e397c36813dd317e424ea642b2a08cb3e4fca3e2603dc202f3a00c06f80f28805ad22dbb762afa88909a27a1213431373f79cf3a60a409301f501015b75498c84dd86bdd94c80c3ce59c8d2396cc0924bbccb799d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444091eb7f048cd20315353670b168b6648939e5acf5bcd46a58ad4d565b7bf6aae52004e53a51d7f26df0ac4210eaffc6db59f311ceb9b6d86a1339f0ffa6f3990c", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "df595622dd8d67b873861c9498e65de471532a93c1427547a01aa93fd22c1c27", + "sequence_number": "15846156409455883481", + "payload": { + "EntryFunction": { + "module": { + "address": "a78a9d400baa332193566ba76dbc98dbc785c0a954ea1d28ae984848e10fa396", + "name": "OHRsHGxfRBFEtZB8_Coin" + }, + "function": "HVNFowSPViKSglyXtxVVeIyAGNqdBhF", "ty_args": [ { - "vector": { - "vector": { - "struct": { - "address": "f3a48b884c70a3617f971e6ee5a62933d2d126827ae05d4a2c9f42247c299fc6", - "module": "cUXKTnQMzasUJpeL7", - "name": "ZSQVCefFAoidhIBuwu", - "type_args": [] - } - } + "struct": { + "address": "3a561de2660667163e04f038775fc85d6a1274fdc0c229113b335c3b4acf8b27", + "module": "jVdZYJWOTfkamKghOK0", + "name": "TvNBXJnSonWtpYbxBBpLtMqqvsSKUG8", + "type_args": [] + } + }, + { + "struct": { + "address": "d1ecf71b987fafc930c171342467fcac30f6f8a0029983f8953b9ba84b334bba", + "module": "pvwyBVc", + "name": "xWJfzDakIxNWknoroUaJDQWL6", + "type_args": [] } }, { "struct": { - "address": "356213c0b09a655f85baae5533eeda9fa95355a395e688f4254d4bbb632949d7", - "module": "ZOsBnuoqrNHcyNbefUVLDlQDFqXMn2", - "name": "RXxZNhEbPie1", + "address": "86416947d913f696336de7d5348f47f478831fe111f845e69e212175ba4a873c", + "module": "RwDHVbCZ", + "name": "zKViyFyt3", + "type_args": [] + } + }, + { + "struct": { + "address": "a2025bf9ef7e001ce88ff652eedc5425b5a0032b62cd0fed195a0fac3bd1c814", + "module": "b", + "name": "Vdhv", "type_args": [] } }, + { + "vector": { + "vector": "u64" + } + }, { "vector": { "vector": { - "vector": "u64" + "struct": { + "address": "e52827d6c91d12c05ac75ef744f9c433a5aee1ae0477c9871e7d172df1f852f5", + "module": "Iif", + "name": "ABaFaqr5", + "type_args": [] + } } } }, { - "struct": { - "address": "713148b29ac930d83904e8ca9d5ed470578f4c1657e05a276515be46e6407959", - "module": "WYMlRyqOk2", - "name": "ysouotCjNYtCL", - "type_args": [] + "vector": { + "vector": "u128" } }, { "vector": { "struct": { - "address": "a914a1193d054f3c4d9cebf60f9d5107e954f4efe12bff09a50668369dd8e262", - "module": "uNxlvJKLxZUnw", - "name": "ezblbJXDbtvHVWUydqUamAVzpHIpCa2", + "address": "028b692f6d3819887e2e5ed14a597fd66222b8de65ebb416494c177c088a751c", + "module": "lcWdYRziqAbhXgwj6", + "name": "TSlCqBRZrSywovkOiKGmy0", "type_args": [] } } }, + { + "struct": { + "address": "91c005c79ba972a62dd39d3f44af0471551fb40dd3e1767d6dcfb19329ed9dfb", + "module": "VCtGROxPxJISxxWba", + "name": "iLdLxEueMFJ7", + "type_args": [] + } + }, { "vector": { "vector": { "struct": { - "address": "f7da95a6e1f113e5cf8d3734762969dbc4c869ff304d6b318cfa1d7b5e608d14", - "module": "mHOhNnhOGlZZoDwTO4", - "name": "eX", + "address": "99411c621754db098e1885aa7351916fc8e9ed69a523e84e354f020caab34f0b", + "module": "SWsZkbZYO", + "name": "AT4", "type_args": [] } } } } ], - "args": [] + "args": [ + "2b07aa83d3d7aa5c4a14a225ec7ff3eaa23382882d356213c0b09a655f85baae", + "ee", + "a9", + "01", + "a1aedd2078cddabd282e96226f4eeff4d22d3dc0e288a627fca776ba1b3b0962", + "01" + ] } }, - "max_gas_amount": "11292402725231183603", - "gas_unit_price": "16212609470190026335", - "expiration_timestamp_secs": "11819332509964959198", - "chain_id": 38 + "max_gas_amount": "6168383091833147914", + "gas_unit_price": "13429683339798672774", + "expiration_timestamp_secs": "4201528277634298732", + "chain_id": 241 }, - "signed_txn_bcs": "4e042f633cec6fa02a922b0606809cb8fc089dcc7357f8d96be5f3eed2ef1e9d1c1acdb26c5ebec002b959010ed51103ab3e3af6b948c01504f6059db5807a8f230a21d419b852ad670d48494154766b4f6c5f436f696e0a5a41624a4c5a7a4d643306060607f3a48b884c70a3617f971e6ee5a62933d2d126827ae05d4a2c9f42247c299fc6116355584b546e514d7a6173554a70654c37125a53515643656646416f69646849427577750007356213c0b09a655f85baae5533eeda9fa95355a395e688f4254d4bbb632949d71e5a4f73426e756f71724e4863794e62656655564c446c51444671584d6e320c5258785a4e68456250696531000606060207713148b29ac930d83904e8ca9d5ed470578f4c1657e05a276515be46e64079590a57594d6c5279714f6b320d79736f756f74436a4e5974434c000607a914a1193d054f3c4d9cebf60f9d5107e954f4efe12bff09a50668369dd8e2620d754e786c764a4b4c785a556e771f657a626c624a58446274764856575579647155616d41567a7048497043613200060607f7da95a6e1f113e5cf8d3734762969dbc4c869ff304d6b318cfa1d7b5e608d14126d484f684e6e684f476c5a5a6f4477544f340265580000f3c60eea72acb69c5f7ecf406ac2fee0defdafda4bb406a426002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444067e5d8b8d1b11febd84172aba1ae9d29cc86a1abe91031b89c01d3997eeaf68e7ca47db8e58d22fa3922af2cacb3febd6e25f3a0e9b4678e866b64f15e998a06", + "signed_txn_bcs": "df595622dd8d67b873861c9498e65de471532a93c1427547a01aa93fd22c1c27d9b4e5404cdbe8db02a78a9d400baa332193566ba76dbc98dbc785c0a954ea1d28ae984848e10fa396154f4852734847786652424645745a42385f436f696e1f48564e466f77535056694b53676c79587478565665497941474e71644268460a073a561de2660667163e04f038775fc85d6a1274fdc0c229113b335c3b4acf8b27136a56645a594a574f54666b616d4b67684f4b301f54764e42584a6e536f6e5774705962784242704c744d71717673534b5547380007d1ecf71b987fafc930c171342467fcac30f6f8a0029983f8953b9ba84b334bba07707677794256631978574a667a44616b49784e576b6e6f726f55614a4451574c36000786416947d913f696336de7d5348f47f478831fe111f845e69e212175ba4a873c08527744485662435a097a4b566979467974330007a2025bf9ef7e001ce88ff652eedc5425b5a0032b62cd0fed195a0fac3bd1c8140162045664687600060602060607e52827d6c91d12c05ac75ef744f9c433a5aee1ae0477c9871e7d172df1f852f503496966084142614661717235000606030607028b692f6d3819887e2e5ed14a597fd66222b8de65ebb416494c177c088a751c116c63576459527a69714162685867776a361654536c437142525a725379776f766b4f694b476d7930000791c005c79ba972a62dd39d3f44af0471551fb40dd3e1767d6dcfb19329ed9dfb1156437447524f7850784a495378785762610c694c644c784575654d464a370006060799411c621754db098e1885aa7351916fc8e9ed69a523e84e354f020caab34f0b095357735a6b625a594f034154340006202b07aa83d3d7aa5c4a14a225ec7ff3eaa23382882d356213c0b09a655f85baae01ee01a9010120a1aedd2078cddabd282e96226f4eeff4d22d3dc0e288a627fca776ba1b3b096201010a923d93bd7f9a558675ae12d8d15fba6cb32636b5d34e3af1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440786fc819f99727aeb242659344c088af30239750c70a71ef31a9fcc568b0e07991ea59a5c2ce32468e1cc607eb87d697e73bb3b150bbc4c76f2e97239664ac03", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "da52d5ef29dcca1e8c29d754309118e9ef12f45c936abb97977b9e657372825e", - "sequence_number": "11124694569744965819", + "sender": "5d9717fdbfc27de79db2fad16ab2f3761aecfc8144bd64ad62983269ee87a696", + "sequence_number": "2218608088557949180", "payload": { "EntryFunction": { "module": { - "address": "5c4abdf5c0e0656437bca27808d69f83e56453506a29d8984ced66fb71b69d28", - "name": "SFrkc0_Coin" + "address": "f0bd53c8c3afa9aa842138ded8a060956e846d88a0030a61f91483ceb26635a7", + "name": "i7_Coin" }, - "function": "zsZChjIFj", + "function": "QASEbRGdwsPvoCp8", "ty_args": [ { "vector": { "struct": { - "address": "e69a12e79bb0f49f7e4809c262dc3300473143dfea3599347772b85acc5c8e36", - "module": "RrCskeBWWUapT7", - "name": "ymDoaXIIcSSUJpyeibZmBemcdGPR0", + "address": "fd2f959279f5d5dafa186c4021c9876b93bf1ca98dd50f80ea233ffb6038bf6b", + "module": "tsTOpsCCGZLlrsbZiur", + "name": "mKwnDaUHCfymCanaThfUyJCNnzlSnF7", "type_args": [] } } }, { - "struct": { - "address": "6c25ee246bd6c6f1ae8858102a61719fff5586209319e9fe4ce8f0a5a5aebc05", - "module": "WZGhPzADKBHhzRAgyh1", - "name": "VhbVeKVOH", - "type_args": [] + "vector": { + "vector": "bool" } }, { - "vector": "address" + "vector": { + "vector": "signer" + } + }, + { + "struct": { + "address": "7d3a9af931d93a4931bcd0f5e2c594bca07d7159e0add80f09c6caff0a3aac7b", + "module": "mmd7", + "name": "ovGjOWRjhyoqiXHYJmhIGsEg6", + "type_args": [] + } }, { "struct": { - "address": "fbe869392bbc47ccc39856cb4eb89a389d108405d1f020719f118a0f643c214e", - "module": "KBKQPneDvJIYMNiiAnztyFGdShY5", - "name": "Gfi2", + "address": "dc750532f3b61399b2121858a54e26a2887082647f6247303afb3e104b4e6656", + "module": "zUjQDYQXMHaPDhvmWH3", + "name": "TFRdHzlVSZwqqHDMQmxvJaVfvlKCZgZ", "type_args": [] } }, + { + "vector": { + "vector": { + "struct": { + "address": "08d69f83e56453506a29d8984ced66fb71b69d2854033d19ebe0ec9d927ac00f", + "module": "WPIemSTiNWsfwzc", + "name": "V6", + "type_args": [] + } + } + } + }, { "vector": { "struct": { - "address": "11cf7430d23d4cd73d43f4200b125e0ebfb4dfb275f4729e032ed9c20eb52a47", - "module": "bK8", - "name": "URVIBnreILgUQjlFEYM8", + "address": "659899a40213ad955dc377e5b453760169934f37168a705582f68345f1701545", + "module": "O", + "name": "LYwfxDOsRmDJHsZXh", "type_args": [] } } + }, + { + "struct": { + "address": "f05be73565984d7f31158764fc3e6f176ea654c2cc773e49b4a1d0bb514d01aa", + "module": "SYXuoRRtfnIlKuFfGTpDeaWzorqZn9", + "name": "izePLRZTtZREHqkrxTCJmkYu9", + "type_args": [] + } + }, + { + "struct": { + "address": "62875f98b53f70b637470cabe3fc15026422d7e216f504f03a08cdf8d8d238a1", + "module": "otpdzPdCmgMJySyTZHQNSuZXmfqTYw2", + "name": "GIpbumwyKFmUAH", + "type_args": [] + } + }, + { + "vector": "address" } ], "args": [ - "f628b98cb2a52017", - "f93d7c51ab39f174" + "01", + "4e", + "74680f966e138c58804e0dd9758ec250646ac6dadd4540f7a78481b1cf2e0441", + "1215309177624810137c844a1baba3ae2df40fb0a0c56e02baf0b9b13792ea72", + "9480538d19a5c529a01cc9ea4ac6551a2661efae08c64b54b4f97af67157ea64" ] } }, - "max_gas_amount": "14346483141261471112", - "gas_unit_price": "16772306631261316586", - "expiration_timestamp_secs": "744287654133592165", - "chain_id": 244 + "max_gas_amount": "12306627183377365997", + "gas_unit_price": "13239226504445224793", + "expiration_timestamp_secs": "749228628132620752", + "chain_id": 226 }, - "signed_txn_bcs": "da52d5ef29dcca1e8c29d754309118e9ef12f45c936abb97977b9e657372825ebba05d20c5da629a025c4abdf5c0e0656437bca27808d69f83e56453506a29d8984ced66fb71b69d280b5346726b63305f436f696e097a735a43686a49466a050607e69a12e79bb0f49f7e4809c262dc3300473143dfea3599347772b85acc5c8e360e527243736b6542575755617054371d796d446f61584949635353554a70796569625a6d42656d63644750523000076c25ee246bd6c6f1ae8858102a61719fff5586209319e9fe4ce8f0a5a5aebc0513575a4768507a41444b4248687a5241677968310956686256654b564f4800060407fbe869392bbc47ccc39856cb4eb89a389d108405d1f020719f118a0f643c214e1c4b424b51506e6544764a49594d4e6969416e7a747946476453685935044766693200060711cf7430d23d4cd73d43f4200b125e0ebfb4dfb275f4729e032ed9c20eb52a4703624b381455525649426e7265494c6755516a6c4645594d38000208f628b98cb2a5201708f93d7c51ab39f174882d05f367f218c7ea6542840434c3e865705793ad3d540af4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405cdb956fe7a658a1054354bc882caded3d3c2f1be881e44a11d2b4a4b3ab2199642500e4ac997380b6258737d47837425c85fdf81c523f94677aa76fea140108", + "signed_txn_bcs": "5d9717fdbfc27de79db2fad16ab2f3761aecfc8144bd64ad62983269ee87a696fc104e464d14ca1e02f0bd53c8c3afa9aa842138ded8a060956e846d88a0030a61f91483ceb26635a70769375f436f696e105141534562524764777350766f4370380a0607fd2f959279f5d5dafa186c4021c9876b93bf1ca98dd50f80ea233ffb6038bf6b137473544f70734343475a4c6c7273625a6975721f6d4b776e446155484366796d43616e6154686655794a434e6e7a6c536e463700060600060605077d3a9af931d93a4931bcd0f5e2c594bca07d7159e0add80f09c6caff0a3aac7b046d6d6437196f76476a4f57526a68796f71695848594a6d684947734567360007dc750532f3b61399b2121858a54e26a2887082647f6247303afb3e104b4e6656137a556a51445951584d4861504468766d5748331f54465264487a6c56535a77717148444d516d78764a615666766c4b435a675a0006060708d69f83e56453506a29d8984ced66fb71b69d2854033d19ebe0ec9d927ac00f0f575049656d5354694e577366777a63025636000607659899a40213ad955dc377e5b453760169934f37168a705582f68345f1701545014f114c59776678444f73526d444a48735a58680007f05be73565984d7f31158764fc3e6f176ea654c2cc773e49b4a1d0bb514d01aa1e535958756f525274666e496c4b754666475470446561577a6f72715a6e3919697a65504c525a54745a524548716b727854434a6d6b597539000762875f98b53f70b637470cabe3fc15026422d7e216f504f03a08cdf8d8d238a11f6f7470647a5064436d674d4a795379545a48514e53755a586d6671545977320e47497062756d77794b466d554148000604050101014e2074680f966e138c58804e0dd9758ec250646ac6dadd4540f7a78481b1cf2e0441201215309177624810137c844a1baba3ae2df40fb0a0c56e02baf0b9b13792ea72209480538d19a5c529a01cc9ea4ac6551a2661efae08c64b54b4f97af67157ea64edbb5f5038ecc9aa59e764825c2ebbb7d0e965bb77cb650ae2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440cd3ff1233df4016bc45e61622cc0625f40c887ef8e013fed407efa3e0702ec3681195d3b15eba4bf575b837396135b982bdf1610b9b849ddebe6edd6db08190e", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "ae735f802186bc4bdb6a2152ab03f84c113a040c8fa43b1681caa3d012bbf624", - "sequence_number": "10357555565551221430", + "sender": "b91a2a1ea12e0f4265fa3e99cdba576848fa3a539d1d958c2f357472c3403beb", + "sequence_number": "7101046367776588778", "payload": { "EntryFunction": { "module": { - "address": "b469114139a21cc0e8eb88d856f820834a7593163e1e213b3fcb1dfd9005d23e", - "name": "qmbcTtzayHmxluNRUMW_Coin" + "address": "7c872dca6aa04b42c91402b56d9543fbef99bda622a59e28661fbcdce25c5b30", + "name": "hR1_Coin" }, - "function": "JccbHQfmvLwxICZRPhjBi", + "function": "pWZjDnSHoHqqGoHdZgjnaYCwl", "ty_args": [ { "struct": { - "address": "8818f3ce6416a2a75725199c3e6260836a0bedff92a850734e97e851395f98e0", - "module": "ErEEQKEQvCYQAoifLBCXs1", - "name": "YhCwunVVGdpXnxXQXzUQBBenhQm6", + "address": "39a21cc0e8eb88d856f820834a7593163e1e213b3fcb1dfd9005d23ef1796d30", + "module": "dPNOsXIFVqazzuljRJyLKYEh", + "name": "lvowRCftUbYmehZWLAwRCM4", "type_args": [] } + }, + { + "vector": { + "vector": "u128" + } + }, + { + "vector": { + "struct": { + "address": "82a1142edfb1002830b0f54245ea06f2376880b076e2a8939378a37d6db8e0f8", + "module": "uCCpkDEoigwdhzBUFlcsSiArv7", + "name": "BVZpCwEKwQ", + "type_args": [] + } + } + }, + { + "vector": { + "struct": { + "address": "329a3c36e3dadb0eb2c2a3dd6a230016df4fc18265c37fda909fafa19b627807", + "module": "fqfOycTNIvuZ4", + "name": "TOrgHQVXHHOXhcEj", + "type_args": [] + } + } } ], "args": [ - "dd", - "1f066d1487c2bdda" + "69be79cd01c4b5c4ac46e9b2d20b4752" ] } }, - "max_gas_amount": "11045730974253775244", - "gas_unit_price": "15767577093260820063", - "expiration_timestamp_secs": "1023574694421096523", - "chain_id": 129 + "max_gas_amount": "10548839001685872019", + "gas_unit_price": "2910013646378867616", + "expiration_timestamp_secs": "7052182352659501442", + "chain_id": 142 }, - "signed_txn_bcs": "ae735f802186bc4bdb6a2152ab03f84c113a040c8fa43b1681caa3d012bbf624b6fa0c02e96dbd8f02b469114139a21cc0e8eb88d856f820834a7593163e1e213b3fcb1dfd9005d23e18716d626354747a6179486d786c754e52554d575f436f696e154a6363624851666d764c777849435a5250686a426901078818f3ce6416a2a75725199c3e6260836a0bedff92a850734e97e851395f98e01645724545514b455176435951416f69664c42435873311c59684377756e5656476470586e785851587a55514242656e68516d36000201dd081f066d1487c2bdda8cf9ec5ccc514a995fbe657cd3afd1da4b680ceec277340e81002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f3b245ebab878a6b2590d8af49dc4516a186edff3e7fcf2f4d9955839c1f65d830ce47e8c7852b356d5db36f29c13b992a771443d015688e1990c2c978b0ec07", + "signed_txn_bcs": "b91a2a1ea12e0f4265fa3e99cdba576848fa3a539d1d958c2f357472c3403bebeac3e66c0cfc8b62027c872dca6aa04b42c91402b56d9543fbef99bda622a59e28661fbcdce25c5b30086852315f436f696e1970575a6a446e53486f487171476f48645a676a6e615943776c040739a21cc0e8eb88d856f820834a7593163e1e213b3fcb1dfd9005d23ef1796d301864504e4f735849465671617a7a756c6a524a794c4b594568176c766f77524366745562596d65685a574c417752434d3400060603060782a1142edfb1002830b0f54245ea06f2376880b076e2a8939378a37d6db8e0f81a754343706b44456f69677764687a4255466c63735369417276370a42565a704377454b7751000607329a3c36e3dadb0eb2c2a3dd6a230016df4fc18265c37fda909fafa19b6278070d6671664f7963544e4976755a3410544f72674851565848484f586863456a00011069be79cd01c4b5c4ac46e9b2d20b475293cd45902e016592a09bf353fe71622882518c557c62de618e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144408c6220c4bd8baee97ae9e4e1d4c2e900c56d7abda07ab5986dfccd558cc5a89e417c4db3dabd76b15dce0d2c038657964c9c5829c1160fafec45656b70b2ea0e", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "449dcf23a3a88c081dee408676039e001179d4df57db37c1cc592ae7c1e2e49e", - "sequence_number": "11505292297128598057", + "sender": "5eab6dd048d24b07066005e274a13f630e77305eb120c6257ed9fd7512ec11e3", + "sequence_number": "13526641379719566225", "payload": { "EntryFunction": { "module": { - "address": "d8c35420c5943434ff6a8296473d2603438c4fea603a80be93bc290c0243bd8f", - "name": "qWyHiahMLgkqpdVwQooWGjRIVOuzZ8_Coin" + "address": "056c40a62b04dd01086d31e11cb68be029414710b533264aa95f0a009035e5c4", + "name": "zafQazlFxlaJVkwc_Coin" }, - "function": "NXNjfPcYrhtrj8", + "function": "HOafeuL", "ty_args": [ { "struct": { - "address": "112d5944bd109c210f029edeb8b846d740342668d593dee6ee0bf1bc6de6988a", - "module": "KsVTNDfMJDrVrDUg", - "name": "hfRptevFcnGuVbCjrhy", + "address": "8396fcbd65276789a8d33d46f1d7290f8fef1fb1c79f1cf9b819094a71d94f63", + "module": "zQFnY8", + "name": "gbyKLQZWOPiOGzdq0", "type_args": [] } }, { - "vector": { - "struct": { - "address": "9157ee23a4f0d6136d63639d5a787f28ec23c1d7141982b1b229e23a513922dc", - "module": "biZhdW3", - "name": "swQta4", - "type_args": [] - } + "struct": { + "address": "aaf19149132b339d45624e164cf2a3b7216ffb44dc22ba112d5944bd109c210f", + "module": "xviiBSmLx6", + "name": "KWgmHxCgi", + "type_args": [] + } + }, + { + "struct": { + "address": "ef7cb7904c1f5fcb23487e81caeb0262714f222f364719bf86ecc28e2d9d82ae", + "module": "OfnPxYYBIZGnUdVgy", + "name": "SffnwCWOrhfMeffuPtMsH6", + "type_args": [] } }, { "struct": { - "address": "be99e94d5a5eda54b8ece68db6c629f4cd63db19ff641929539b3a7f69cafb65", - "module": "tnojhCssrMwdvvVL1", - "name": "dtkF", + "address": "28ec23c1d7141982b1b229e23a513922dce3547aa90107a22a6199e11c27a0d2", + "module": "GZzjKPgfcebOzDhztqIXsjxMqBjb9", + "name": "nTvRgLnsQdgDcwnbmfATuwIUTJlxS7", "type_args": [] } }, { "vector": { - "vector": "u128" + "vector": { + "struct": { + "address": "fa9ea71ed1abb77033d69fedcd49118ef9f6c2f29aa1a709f1b04c2e3527d329", + "module": "FjnGbABbsOM", + "name": "cuJgIQXVybiVqf", + "type_args": [] + } + } } }, { "vector": { - "vector": "u64" + "vector": { + "struct": { + "address": "34c7607fe2cd3d0552c84dc0abb39e4b7698c60c8a3dbcd36a2003c764a1fb83", + "module": "JaTfYxmVyMhNizGwp9", + "name": "vHsSYzynEo", + "type_args": [] + } + } } }, { "struct": { - "address": "7876e52e16f77d32ed355c7332b29bd9ec08be42d92b715ecf0568cfa3815ddd", - "module": "MxVbAvxhInqGZvzKxcYUNuda8", - "name": "ZLGoXdtZVQPhg", + "address": "9211a473afb21b2fcd80931e8fff2028557c7de59ac6516882c00e8f415b5f28", + "module": "LPmmTRtRrvxpy", + "name": "dDhIJxsMVzqzfZoXX", "type_args": [] } }, { "struct": { - "address": "2463613ba905097bdcce7c32df8ccc73ac2077861d3ce8b02b065facdcedd037", - "module": "JmsHecoY3", - "name": "etLqCOT", + "address": "6988ecd44682d63426a7c101b29d809cd99cc5f1e698d2b648881410586472fe", + "module": "VlgTxRgLzgNjRgHJumm", + "name": "RMSHTuRdCBXgt", "type_args": [] } + }, + { + "vector": "bool" } ], "args": [ - "524d1baa6a91f5711f37a0f419cba6f7eadd0ba0d2f5e3e174e8bc8e318f6ad2", - "ed", - "8b52e908844e2cdd", - "4c", - "fb78cbbaac37ab33fe18b8ac64f2a32d", - "82ea7808b7b187e2eac8c3de8270dca1", - "00", - "cb0fa9c16181d087" + "a069f29d27d4e37088a25e6e13a1fdff", + "4297fe91ea65c861", + "570d34a2059698d1cadf5e5ce8a5e78a11143641848660fffa1ff8f7fab7fe9c", + "a2", + "e01a6a477ebb3f08", + "7a", + "60", + "6cc8131a5dd3e1bd7419f11442efdaff", + "db37c1cc592ae7c1e2e49e29628511976124646b0731f44eee292a0f3c0ef6c5" ] } }, - "max_gas_amount": "5806192569497141911", - "gas_unit_price": "3168304758433508900", - "expiration_timestamp_secs": "18379822374843973765", - "chain_id": 107 + "max_gas_amount": "13943765375296266576", + "gas_unit_price": "4260045256900789382", + "expiration_timestamp_secs": "8994813284850017941", + "chain_id": 194 }, - "signed_txn_bcs": "449dcf23a3a88c081dee408676039e001179d4df57db37c1cc592ae7c1e2e49e295a63f76202ab9f02d8c35420c5943434ff6a8296473d2603438c4fea603a80be93bc290c0243bd8f23715779486961684d4c676b7170645677516f6f57476a5249564f757a5a385f436f696e0e4e584e6a66506359726874726a380707112d5944bd109c210f029edeb8b846d740342668d593dee6ee0bf1bc6de6988a104b7356544e44664d4a44725672445567136866527074657646636e47755662436a7268790006079157ee23a4f0d6136d63639d5a787f28ec23c1d7141982b1b229e23a513922dc0762695a68645733067377517461340007be99e94d5a5eda54b8ece68db6c629f4cd63db19ff641929539b3a7f69cafb6511746e6f6a68437373724d77647676564c310464746b4600060603060602077876e52e16f77d32ed355c7332b29bd9ec08be42d92b715ecf0568cfa3815ddd194d78566241767868496e71475a767a4b786359554e756461380d5a4c476f5864745a565150686700072463613ba905097bdcce7c32df8ccc73ac2077861d3ce8b02b065facdcedd037094a6d734865636f59330765744c71434f54000820524d1baa6a91f5711f37a0f419cba6f7eadd0ba0d2f5e3e174e8bc8e318f6ad201ed088b52e908844e2cdd014c10fb78cbbaac37ab33fe18b8ac64f2a32d1082ea7808b7b187e2eac8c3de8270dca1010008cb0fa9c16181d08797c2632261bd935024ee9b326414f82b85005ac7113f12ff6b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c5366ce74e88c5d10daecc446a935c085eba437d80064bbfa6dc952a2661180ddd3dd674963a885002248a3c2011c33f5bce2ef59f80e34361a38eefa64efd06", + "signed_txn_bcs": "5eab6dd048d24b07066005e274a13f630e77305eb120c6257ed9fd7512ec11e391d348eaaa48b8bb02056c40a62b04dd01086d31e11cb68be029414710b533264aa95f0a009035e5c4157a616651617a6c46786c614a566b77635f436f696e07484f616665754c09078396fcbd65276789a8d33d46f1d7290f8fef1fb1c79f1cf9b819094a71d94f63067a51466e5938116762794b4c515a574f50694f477a6471300007aaf19149132b339d45624e164cf2a3b7216ffb44dc22ba112d5944bd109c210f0a7876696942536d4c7836094b57676d48784367690007ef7cb7904c1f5fcb23487e81caeb0262714f222f364719bf86ecc28e2d9d82ae114f666e5078595942495a476e5564566779165366666e7743574f7268664d6566667550744d734836000728ec23c1d7141982b1b229e23a513922dce3547aa90107a22a6199e11c27a0d21d475a7a6a4b5067666365624f7a44687a74714958736a784d71426a62391e6e547652674c6e735164674463776e626d66415475774955544a6c78533700060607fa9ea71ed1abb77033d69fedcd49118ef9f6c2f29aa1a709f1b04c2e3527d3290b466a6e4762414262734f4d0e63754a67495158567962695671660006060734c7607fe2cd3d0552c84dc0abb39e4b7698c60c8a3dbcd36a2003c764a1fb83124a61546659786d56794d684e697a477770390a76487353597a796e456f00079211a473afb21b2fcd80931e8fff2028557c7de59ac6516882c00e8f415b5f280d4c506d6d54527452727678707911644468494a78734d567a717a665a6f585800076988ecd44682d63426a7c101b29d809cd99cc5f1e698d2b648881410586472fe13566c67547852674c7a674e6a5267484a756d6d0d524d53485475526443425867740006000910a069f29d27d4e37088a25e6e13a1fdff084297fe91ea65c86120570d34a2059698d1cadf5e5ce8a5e78a11143641848660fffa1ff8f7fab7fe9c01a208e01a6a477ebb3f08017a0160106cc8131a5dd3e1bd7419f11442efdaff20db37c1cc592ae7c1e2e49e29628511976124646b0731f44eee292a0f3c0ef6c550e1ec49bb3482c186c4a82897b81e3b952673a806ffd37cc2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406ac1d72d60b3f2fda3320ed03008d418a0bca9146335ab2cd46f7e07583e106c83f68781a2d4be0569b70c692dcd3b78a1ab138b7c800b98a01b3311e0643a05", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "880cdd61301a9936f83efb9e66b4e5742cef37ef6710ed8cfb2b1ff9501c2795", - "sequence_number": "1381338177129607191", + "sender": "93ceb5453a39c221ef6a5afa8815e522038c1aec1ca61b5056f42db035f42079", + "sequence_number": "15579649052219066323", "payload": { "EntryFunction": { "module": { - "address": "0731f44eee292a0f3c0ef6c55eab6dd048d24b07066005e274a13f630e77305e", - "name": "CzRBhknwhUT_Coin" + "address": "055b04fc3d74bd35bc3bce2b2a1d8d69f23d9ea8a15fe86c21e062bc23683948", + "name": "OREdnXCgmLAZ2_Coin" }, - "function": "gaNbHAyp6", + "function": "MCzlrszXqPuIleAql7", "ty_args": [ + { + "struct": { + "address": "e31cfdeb35a1d4e4c9654384abbb81a2d3a322b336aa4061a8fd4dfbe3b5130f", + "module": "GxqHexHGkdUjx", + "name": "PXcAslEqhPEWdTyIO", + "type_args": [] + } + }, { "vector": { - "vector": { - "vector": "bool" - } + "vector": "u128" } }, { "vector": { "struct": { - "address": "985425bbbefea6b1bef17371474e9800ae2956d18f4745809f623d97d6aa1d00", - "module": "CLVgCaEeiGDFlrfVlZYTKYSOfJxLwkvm", - "name": "bopmuIeoLyKkcy", + "address": "09369e71b0586793f98ca19f748578c3f4f4530cf6cc6cd340a4dd6948a42fda", + "module": "VZVhMubYejRySNyONUkuxgGYWlO9", + "name": "sMIPyFWEbaBa4", "type_args": [] } } }, + { + "vector": { + "vector": "u128" + } + }, { "struct": { - "address": "82fd8da12bd8c5e3eb281236266eedea4156a4538283caa5307e18998c382cd7", - "module": "AFomyTGWUJkvScaznvYZYhMa", - "name": "ITCLhAYZAKywmnI4", + "address": "4afdfe5fcafb92a3938655ad4af060e09c58d5a58ca2ab15ec7482aaef47b8b2", + "module": "LznaikVZwCAK", + "name": "nNTXwWDEwAVtDQfcgtEjXL", "type_args": [] } }, { "vector": { "struct": { - "address": "d8e17b88548000dd63b2ca8e550dc69cf5ac5c2a9f136472e38994d66e37e309", - "module": "WPVh", - "name": "gKzDkGV", + "address": "a25ecb9d2ced8e3e99a9ff43aebe120f9e36ea15041111fbcc504abe4dcc3a52", + "module": "SyEJ4", + "name": "NwwZQNG", "type_args": [] } } }, + { + "struct": { + "address": "92279124e797f1599258e99c38d02cf8b5bc99e133fea353fd14070621eefead", + "module": "mqkQzmwvzqxkSnDCyrkTHPFmH", + "name": "YTce2", + "type_args": [] + } + }, { "vector": { - "struct": { - "address": "0b8c33e2b754278857c606fbce3542bd8fdb55dea9c5fe0bbf43027458e11261", - "module": "pxOaCwOapCuBId6", - "name": "KSoPzgZfqgwxnqNgDIIoTiYjJP", - "type_args": [] + "vector": { + "vector": "u8" } } }, + { + "struct": { + "address": "9392b09cc82a3d6503682c179c9bdd09baa0f1f3a1002a1ca9bad45ea54161c6", + "module": "RqTZPrQyDYmSETGzRlfwKxwn", + "name": "EgiYiGOLJcBfcJBoFQtc", + "type_args": [] + } + } + ], + "args": [ + "00", + "02", + "636b7a72c6c12600" + ] + } + }, + "max_gas_amount": "10347459430950769268", + "gas_unit_price": "5821428440788011840", + "expiration_timestamp_secs": "11676970727382150744", + "chain_id": 139 + }, + "signed_txn_bcs": "93ceb5453a39c221ef6a5afa8815e522038c1aec1ca61b5056f42db035f42079d3c7c4ba440836d802055b04fc3d74bd35bc3bce2b2a1d8d69f23d9ea8a15fe86c21e062bc23683948124f5245646e5843676d4c415a325f436f696e124d437a6c72737a58715075496c6541716c370907e31cfdeb35a1d4e4c9654384abbb81a2d3a322b336aa4061a8fd4dfbe3b5130f0d47787148657848476b64556a781150586341736c457168504557645479494f00060603060709369e71b0586793f98ca19f748578c3f4f4530cf6cc6cd340a4dd6948a42fda1c565a56684d756259656a5279534e794f4e556b7578674759576c4f390d734d495079465745626142613400060603074afdfe5fcafb92a3938655ad4af060e09c58d5a58ca2ab15ec7482aaef47b8b20c4c7a6e61696b565a7743414b166e4e54587757444577415674445166636774456a584c000607a25ecb9d2ced8e3e99a9ff43aebe120f9e36ea15041111fbcc504abe4dcc3a52055379454a34074e77775a514e47000792279124e797f1599258e99c38d02cf8b5bc99e133fea353fd14070621eefead196d716b517a6d77767a71786b536e444379726b544850466d480559546365320006060601079392b09cc82a3d6503682c179c9bdd09baa0f1f3a1002a1ca9bad45ea54161c6185271545a5072517944596d534554477a526c66774b78776e144567695969474f4c4a634266634a426f4651746300030100010208636b7a72c6c126007412967d878f998f408b86da52dec950586e3f6202ef0ca28b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400625f4181a4dae1bac0fe40981e46039e91544a02260dcd428b63b852f5a434d34828d562c1a6aeb8dfc2a5a0db4522d83a5349567dd4e05bd23e7669d22d404", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "046fe90fd575a0b7f069479fa11c47029b89cd14f89fd4512c9b9aa190f120e3", + "sequence_number": "12166345473849194768", + "payload": { + "EntryFunction": { + "module": { + "address": "0f0e82c4b35d3db8994cdaf46085f6dd9c3e0b3fe3f0c68b8f11088d5d0b700a", + "name": "pupgeOiJpLbr_Coin" + }, + "function": "kASWwvEOkKVdUKJdpHCrMXrNmnZJEDdL", + "ty_args": [], + "args": [] + } + }, + "max_gas_amount": "6229610779039224186", + "gas_unit_price": "15048478706417742305", + "expiration_timestamp_secs": "6763500135402354831", + "chain_id": 111 + }, + "signed_txn_bcs": "046fe90fd575a0b7f069479fa11c47029b89cd14f89fd4512c9b9aa190f120e310797697bf8ad7a8020f0e82c4b35d3db8994cdaf46085f6dd9c3e0b3fe3f0c68b8f11088d5d0b700a1170757067654f694a704c62725f436f696e206b4153577776454f6b4b5664554b4a64704843724d58724e6d6e5a4a4544644c00007ad19365ff057456e1310f3aa7efd6d08fb8f6e089c7dc5d6f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440eb7a466d55a1a837d16669d4727af30a7507a20e6d1ab07a66749e2e6cea12283dac63ec2f84978b52dc1d133c7c449aacf190e49f1c8e9b4700fbca3c41fd03", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "cf38db305e36d752adbffa775e0c0d22728aff181ef71f296505b32a566ebfb0", + "sequence_number": "6886332014812307704", + "payload": { + "EntryFunction": { + "module": { + "address": "e7d000b8cffbf433727cbb9af90b854535a90a9e686f27313f2d5b75a85dbc79", + "name": "JBbqWYCRsLawKAWDTi_Coin" + }, + "function": "jeXGkOTTOUwPCUAPkIBJEhBrUooH", + "ty_args": [], + "args": [ + "1349120545449abb862890778ee78cf3", + "4e616e1499bb2e8d2fc92ffaa6de11cf8e837183ab8226a0ab629ccdb621bc2c" + ] + } + }, + "max_gas_amount": "16112721288988679135", + "gas_unit_price": "14147689124333243195", + "expiration_timestamp_secs": "8557782823263658189", + "chain_id": 116 + }, + "signed_txn_bcs": "cf38db305e36d752adbffa775e0c0d22728aff181ef71f296505b32a566ebfb0f8a0496c7b2a915f02e7d000b8cffbf433727cbb9af90b854535a90a9e686f27313f2d5b75a85dbc79174a42627157594352734c61774b41574454695f436f696e1c6a6558476b4f54544f557750435541506b49424a45684272556f6f480002101349120545449abb862890778ee78cf3204e616e1499bb2e8d2fc92ffaa6de11cf8e837183ab8226a0ab629ccdb621bc2cdf5b0bbba4e29bdf3b4b8a084db056c4cde091fd225ac37674002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440516d0e07c842647dd4d2374e66f2cd23bae93889ea092bc2f4e175b5548365d9366b8adcd9e2d6a8b2195b93b5f1cfbb22641c3ca28f26cd8c0651d040c30807", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "89f4844338fee31ec24997c4d09688f1f4525f865c2d1655a844aad8982c50f5", + "sequence_number": "6460905479205342360", + "payload": { + "EntryFunction": { + "module": { + "address": "25e33821ae7072467f96977906b51f2a66bd99386dc32afa0f8b1d19cd5707ef", + "name": "bkYgKqkQQjXEBAmIhKIduDqZahyisjM_Coin" + }, + "function": "dsZbTfMxShxHdprnRD", + "ty_args": [ + { + "struct": { + "address": "f542d67e6355ee49c702cef2490766afca33a7c5dd6b2ad3904e8d2c8eb05960", + "module": "jkoifyRcgU6", + "name": "xYL9", + "type_args": [] + } + }, { "vector": { "struct": { - "address": "15a3b6f442bccb980e3406c8f2a511dc422f209c83ca6d2d1f89588c66c30dc1", - "module": "GhQBvJc", - "name": "fnDXHGyjjpFQvnPgyuXpqoxMZppl3", + "address": "900e8b1b99145c05cf7dc0be9a2770b53e4b2e0f4e3c3bcbec7eeb0e10ac62ec", + "module": "cgzhvouadziQwQsVeReJHJtu", + "name": "sXSYE", "type_args": [] } } }, + { + "vector": { + "vector": "u128" + } + }, { "struct": { - "address": "d08a3151ba345f85c9bd68750699abd24a793d30ec8dba963c76103d3efc0fd7", - "module": "aQXCTlOkdCgGVEAkeooPQ", - "name": "YAavhLxVbGGroOjAJg3", + "address": "f7aa485b5bb10a185e6ed0ea7ec274b80c2284abb9b3830d29bc90f8690a8d44", + "module": "ZdEkdPQxSzID", + "name": "TOyzonhOTNuBUFPQrhYKgJSGmRYd", "type_args": [] } }, { - "vector": { - "vector": "u128" + "struct": { + "address": "bfb6bcffeb750b6b65d5c28bd04d63f6c8beabfc7cc91b28192b4259a1207174", + "module": "VbvLYvHBViWGslLSjYA7", + "name": "PE7", + "type_args": [] + } + }, + { + "struct": { + "address": "d9cecc75d2c1cf7d08cdf21d8ec932d078d80f0ede022371f6ad1973a2b57474", + "module": "nlnrVBnGnObmQxpXHOEWFTdAUFgRJ1", + "name": "JVwpSQBxhlTJKjOGsHsMErqwgP9", + "type_args": [] } }, { "struct": { - "address": "05e58e9b159d4e616e1499bb2e8d2fc92ffaa6de11cf8e837183ab8226a0ab62", - "module": "Ds", - "name": "PvgFiXBnEaQlQitglmDgYznI", + "address": "b3c9602101ba78d04c9f16b5428d671bf9f268b549fc9249a596cc974b0edc70", + "module": "ujRcytrHWQXRHHCvVBvuQeEceWSd5", + "name": "OKZMWwOkrSVtiJYXpje9", "type_args": [] } } ], "args": [ "00", - "00", - "01" + "33d0a30b42903b5f5beab55afd7b4947", + "36f8384afcbb04685a1698f2aeb8f8c6", + "87798bd70a704217b910c0f01e7489bb", + "01", + "afba364e217c47a189c3e31b7d1d14cc" ] } }, - "max_gas_amount": "14234658448162911346", - "gas_unit_price": "5618757543891850476", - "expiration_timestamp_secs": "2259191920989873696", - "chain_id": 93 + "max_gas_amount": "9071601584770487647", + "gas_unit_price": "17936966246252769706", + "expiration_timestamp_secs": "10826884554604528622", + "chain_id": 169 }, - "signed_txn_bcs": "880cdd61301a9936f83efb9e66b4e5742cef37ef6710ed8cfb2b1ff9501c279517f07ee2c07f2b13020731f44eee292a0f3c0ef6c55eab6dd048d24b07066005e274a13f630e77305e10437a5242686b6e776855545f436f696e0967614e62484179703609060606000607985425bbbefea6b1bef17371474e9800ae2956d18f4745809f623d97d6aa1d0020434c566743614565694744466c7266566c5a59544b59534f664a784c776b766d0e626f706d7549656f4c794b6b6379000782fd8da12bd8c5e3eb281236266eedea4156a4538283caa5307e18998c382cd71841466f6d79544757554a6b765363617a6e76595a59684d61104954434c6841595a414b79776d6e4934000607d8e17b88548000dd63b2ca8e550dc69cf5ac5c2a9f136472e38994d66e37e309045750566807674b7a446b47560006070b8c33e2b754278857c606fbce3542bd8fdb55dea9c5fe0bbf43027458e112610f70784f6143774f61704375424964361a4b536f507a675a66716777786e714e674449496f5469596a4a5000060715a3b6f442bccb980e3406c8f2a511dc422f209c83ca6d2d1f89588c66c30dc10747685142764a631d666e44584847796a6a704651766e506779755870716f784d5a70706c330007d08a3151ba345f85c9bd68750699abd24a793d30ec8dba963c76103d3efc0fd71561515843546c4f6b644367475645416b656f6f50511359416176684c7856624747726f4f6a414a6733000606030705e58e9b159d4e616e1499bb2e8d2fc92ffaa6de11cf8e837183ab8226a0ab6202447318507667466958426e4561516c516974676c6d4467597a6e4900030100010001017274c3ad70aa8bc5ec54b87a37d6f94d20a6081a15435a1f5d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b0e262d002e853d0c81378f6d510d6fbc6c4426c744b303d392b8a15a572646ece0a0612998425b33ddb8edb42e100f4272dae2e09a5a896ecb305b226665e08", + "signed_txn_bcs": "89f4844338fee31ec24997c4d09688f1f4525f865c2d1655a844aad8982c50f598cc684f4dbfa9590225e33821ae7072467f96977906b51f2a66bd99386dc32afa0f8b1d19cd5707ef24626b59674b716b51516a584542416d49684b49647544715a61687969736a4d5f436f696e1264735a6254664d78536878486470726e52440707f542d67e6355ee49c702cef2490766afca33a7c5dd6b2ad3904e8d2c8eb059600b6a6b6f69667952636755360478594c39000607900e8b1b99145c05cf7dc0be9a2770b53e4b2e0f4e3c3bcbec7eeb0e10ac62ec1863677a68766f7561647a6951775173566552654a484a74750573585359450006060307f7aa485b5bb10a185e6ed0ea7ec274b80c2284abb9b3830d29bc90f8690a8d440c5a64456b64505178537a49441c544f797a6f6e684f544e7542554650517268594b674a53476d5259640007bfb6bcffeb750b6b65d5c28bd04d63f6c8beabfc7cc91b28192b4259a1207174145662764c5976484256695747736c4c536a594137035045370007d9cecc75d2c1cf7d08cdf21d8ec932d078d80f0ede022371f6ad1973a2b574741e6e6c6e7256426e476e4f626d51787058484f455746546441554667524a311b4a56777053514278686c544a4b6a4f477348734d457271776750390007b3c9602101ba78d04c9f16b5428d671bf9f268b549fc9249a596cc974b0edc701d756a526379747248575158524848437656427675516545636557536435144f4b5a4d57774f6b72535674694a5958706a6539000601001033d0a30b42903b5f5beab55afd7b49471036f8384afcbb04685a1698f2aeb8f8c61087798bd70a704217b910c0f01e7489bb010110afba364e217c47a189c3e31b7d1d14cc5f951df493cde47daa711150c4e7ecf8eec35d9d23d24096a9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b74ef839176390d37ab2b84cf7898af0e3bef671218afcae2c56382fdba7b489f5e873dddd748f4e8f35e45e75622dd561646c9f5095af7cc97f342d86b29a00", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "54d5baf582f9994a667d148324ce2691fcf9b0826fdf26ef35ceb5ddd7269d88", - "sequence_number": "3717353077664826892", + "sender": "134d732e9db31a2ab21326068f1c565beab5c67c5b9882b4a097594cf605527d", + "sequence_number": "2570068892391005937", "payload": { "EntryFunction": { "module": { - "address": "83087427899de51fedbd2125795abb17c06116ebf688e7de92721495825a2fc6", - "name": "e_Coin" + "address": "0081ee5519879b7b6adf3565d5fa922747ea5574df7178f175a23ff20907848b", + "name": "UudEaMn_Coin" }, - "function": "fYxUKZQyHfE", + "function": "ZxsXIuGaThkZ", "ty_args": [ { "struct": { - "address": "c5cde625a0a3c678b770d09b95cbeef50a420bd3699ed62a6a23b7c724b88f02", - "module": "shQVyUqjZpTXASdbLtTErv3", - "name": "RKxUYHHOCse3", + "address": "253ab14b324243f82f93c1ac8e92227c9c75b85cbd18f10b20d915b4f1411bb9", + "module": "UFfZf", + "name": "Vp1", "type_args": [] } }, + { + "vector": { + "struct": { + "address": "e210099838049ce8727613c6cb2834ee620c606f3ff75559fbba622cb087b0f7", + "module": "UjOV", + "name": "wPfxVZQgWigsuwggPnwijwYFTjHDruii", + "type_args": [] + } + } + }, { "vector": { "vector": { - "vector": "u64" + "struct": { + "address": "b90cb79a6aeea497cd32dbddfdfaf3f6442b0a5fd30230b935329beecac88e6b", + "module": "NMBfQRDaQTQNCsjbM8", + "name": "abznvPLKI", + "type_args": [] + } } } }, { "struct": { - "address": "cf0dbd1c73cd107278da141c099f9af01510b6978515babaa55a2325010a27fe", - "module": "GgjLEsnzSdyvyhahyfArBGaW1", - "name": "xTKKapZphRgNptVknSiQ", + "address": "770bfa0e8b2eb302ceb436d67840d791478412af7a6fe0c37a093c6bac0ad901", + "module": "nbxNRKtrymYduJynEsRbCSb", + "name": "TpmpRHhiVholsTFPFjniGFRpaYSu", "type_args": [] } }, + { + "vector": { + "struct": { + "address": "4c908e1026bf4a76833244e8f0303ca805332436b25ba0831139db704e15e769", + "module": "YxEaSNvIomkEIYyRNAzJluXmKGFY", + "name": "xHMQBL", + "type_args": [] + } + } + }, { "struct": { - "address": "8a1e5530eae60819bec6b7e74a23b370a2f7d46774757d28d299016aefe01060", - "module": "UAxHputqpmDrUrxQTBzHundp5", - "name": "txJaCfVcJfTU", + "address": "2ed2febc7594a4173faea83d4df1ffbbb90e00efa875ca5bd145ce3b54c0dd10", + "module": "yggrQUPHxNbVOuqBtjrDlodm", + "name": "sEkwQrwjTxwwppoYQVHfCPvBlIFnml9", "type_args": [] } }, + { + "vector": { + "vector": "u128" + } + }, { "struct": { - "address": "74c3220aaccdc846d8294625181e8ae1ef0c0cff68e5775a0dd5ebbb8f17a4cc", - "module": "JeVLCxAvUzlawpnhTCM6", - "name": "rJjTugMkyCcoikdUOdbaxj6", + "address": "e34d30a0e1b597cb60e5c70462ea74135e7050902810c5b573f66ec2ff1e4f27", + "module": "MhbkpfVqZMNsT", + "name": "BqIxxIbxQMAqAO", + "type_args": [] + } + }, + { + "struct": { + "address": "0657d5eba6e9791c6e437b596a2de2a417cfda28d3beecfeefb48a8f352e3f11", + "module": "szyxIi0", + "name": "ZeJrHJgrdDTMzgS", + "type_args": [] + } + }, + { + "struct": { + "address": "66e59e2d8c4138a6f10c28b04059c7748bfbddc0ecc53c07f9a43fb5e8f1d69c", + "module": "Kw2", + "name": "Mq", + "type_args": [] + } + } + ], + "args": [] + } + }, + "max_gas_amount": "16363801318092544663", + "gas_unit_price": "16369882238411763458", + "expiration_timestamp_secs": "10800036792930028983", + "chain_id": 30 + }, + "signed_txn_bcs": "134d732e9db31a2ab21326068f1c565beab5c67c5b9882b4a097594cf605527df15e3f730ab8aa23020081ee5519879b7b6adf3565d5fa922747ea5574df7178f175a23ff20907848b0c55756445614d6e5f436f696e0c5a7873584975476154686b5a0a07253ab14b324243f82f93c1ac8e92227c9c75b85cbd18f10b20d915b4f1411bb9055546665a6603567031000607e210099838049ce8727613c6cb2834ee620c606f3ff75559fbba622cb087b0f704556a4f562077506678565a51675769677375776767506e77696a775946546a48447275696900060607b90cb79a6aeea497cd32dbddfdfaf3f6442b0a5fd30230b935329beecac88e6b124e4d4266515244615154514e43736a624d380961627a6e76504c4b490007770bfa0e8b2eb302ceb436d67840d791478412af7a6fe0c37a093c6bac0ad901176e62784e524b7472796d5964754a796e457352624353621c54706d705248686956686f6c73544650466a6e6947465270615953750006074c908e1026bf4a76833244e8f0303ca805332436b25ba0831139db704e15e7691c59784561534e76496f6d6b45495979524e417a4a6c75586d4b4746590678484d51424c00072ed2febc7594a4173faea83d4df1ffbbb90e00efa875ca5bd145ce3b54c0dd10187967677251555048784e62564f757142746a72446c6f646d1f73456b775172776a5478777770706f5951564866435076426c49466e6d6c390006060307e34d30a0e1b597cb60e5c70462ea74135e7050902810c5b573f66ec2ff1e4f270d4d68626b706656715a4d4e73540e4271497878496278514d4171414f00070657d5eba6e9791c6e437b596a2de2a417cfda28d3beecfeefb48a8f352e3f1107737a79784969300f5a654a72484a67726444544d7a6753000766e59e2d8c4138a6f10c28b04059c7748bfbddc0ecc53c07f9a43fb5e8f1d69c034b7732024d710000979af98399e617e3026f821b2a812de3b74dbefb3d70e1951e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d81156136cd319a30df481932d79404f51cf3abf88cbb27f294d05d85cd3df50a7f92baf96cd93cf045c96504661abb8b06483700967b84166735bb8106a9001", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "e34c228cb0db32dc07105d569c400e706d7e9d44357e3e54ca8fc6e6a3a67855", + "sequence_number": "888570191171883374", + "payload": { + "EntryFunction": { + "module": { + "address": "244760371f7677296d3ef09b116fce093dea6f10cc4558d5810b6a57f42cfe02", + "name": "PaeYJMCBWximKgPRAxfc7_Coin" + }, + "function": "hiOrLWaLZrCLQJNaUvJNzCYgJ3", + "ty_args": [ + { + "struct": { + "address": "3cc9105c38812512626f90e3ec0c810ab5f197ecb0a8d8712ba2e8d91deaf86e", + "module": "TN", + "name": "acjTOuQF2", "type_args": [] } }, { "vector": { "struct": { - "address": "24faaf65e7cefe05f740b732e5fdf3aa467a2418bea584952347b1ef46d3eedf", - "module": "kkNCRVOSBPwKCfyqDuQxvjKNCVtujP6", - "name": "wEjzhGdLBdYaEDhPSkdKUIBQMT2", + "address": "3f3093b6c3bc411ff7477f73d8f49f5c0449af13cd476b3485c96ae5cb5b59a0", + "module": "TilObrKeXE", + "name": "sPxgFQdM7", "type_args": [] } } }, { "struct": { - "address": "2a128efa8dc655606530bd39b474f868244df262fed29e42f3d652b1dabdcf8b", - "module": "HqYDRhUJ6", - "name": "bowFKgoxlbvqGJgyRgwwWwJe3", + "address": "84c3c8114b4cda43a352b7efd2cffdf58010d3e4abc0245de9e09c8feee4904a", + "module": "ldupuolksWYwEFoodFf", + "name": "TWTgNZERkSwjImJfAwfTMbhaEDrDrUed", "type_args": [] } }, + { + "vector": { + "struct": { + "address": "0bade12be074a0fa61a4ba4a51ae410379d36252a6d8b8ff4ad26877cd27dcc5", + "module": "PmwlvpdhJFbyLGQMa1", + "name": "BjKeImcNaFmUMdWIAW6", + "type_args": [] + } + } + }, { "struct": { - "address": "1994a1bdf29555ce80c36f63f05e216aa1b35d14829eedc4039230f8e700d576", - "module": "lzV4", - "name": "mRXWzELcuVWTYp", + "address": "89a200128cc1f57108b093f6c6ac3ab49b3f7e825439eeab9d2d2986e486fc6b", + "module": "GHrJwPvRDxtbeHlJfDsMtS", + "name": "iYRrXB", "type_args": [] } }, @@ -1112,9 +1627,9 @@ "vector": { "vector": { "struct": { - "address": "e34a464bd706ed3bd619596d791e2ed2febc7594a4173faea83d4df1ffbbb90e", - "module": "JWMroNMVcGcBvVRk", - "name": "QRIMpjbeTKfTFmtyCHvm", + "address": "e84a980c5bf6f1dfcbf2554344b84a42a96b3f38018170b8a141d72aa7f8a3fb", + "module": "NNrWslc6", + "name": "ztdkjUrgIXeMPMU2", "type_args": [] } } @@ -1122,1021 +1637,1085 @@ } ], "args": [ - "12", - "0fcc7132f551402a", - "9e93813082773ed762d7bbcbb7ce1ccc", - "883c87ff252dcdad49c9c12a2bb9a75de53e3ba95d72a89691ebca25874a5987" + "d27bc7877d2cc44d8fdfea57cac8336dea075170129117f0a0e2e3e358be5003", + "5ca2c3f79f855a38ec3b1e13d7d20910", + "01", + "5033aa4e303a3e593dab78acc7909c65b47b89c2a8a9905602d80a47cea4b13d", + "4c11b3c4e857a778", + "57f996bfc6c0365226365ee5fdb57f1a70a89c7bd49732e2ff2d5a9339e45436" ] } }, - "max_gas_amount": "6744637128398603363", - "gas_unit_price": "734413557413829576", - "expiration_timestamp_secs": "11536696249601430455", - "chain_id": 174 + "max_gas_amount": "3666232234570733649", + "gas_unit_price": "30194248730412988", + "expiration_timestamp_secs": "4187513366266677308", + "chain_id": 225 }, - "signed_txn_bcs": "54d5baf582f9994a667d148324ce2691fcf9b0826fdf26ef35ceb5ddd7269d880cc6eac2edb096330283087427899de51fedbd2125795abb17c06116ebf688e7de92721495825a2fc606655f436f696e0b665978554b5a51794866450907c5cde625a0a3c678b770d09b95cbeef50a420bd3699ed62a6a23b7c724b88f0217736851567955716a5a705458415364624c7454457276330c524b78555948484f43736533000606060207cf0dbd1c73cd107278da141c099f9af01510b6978515babaa55a2325010a27fe1947676a4c45736e7a53647976796861687966417242476157311478544b4b61705a706852674e7074566b6e53695100078a1e5530eae60819bec6b7e74a23b370a2f7d46774757d28d299016aefe01060195541784870757471706d44725572785154427a48756e6470350c74784a61436656634a665455000774c3220aaccdc846d8294625181e8ae1ef0c0cff68e5775a0dd5ebbb8f17a4cc144a65564c43784176557a6c6177706e6854434d3617724a6a5475674d6b7943636f696b64554f646261786a3600060724faaf65e7cefe05f740b732e5fdf3aa467a2418bea584952347b1ef46d3eedf1f6b6b4e4352564f534250774b4366797144755178766a4b4e435674756a50361b77456a7a6847644c4264596145446850536b644b554942514d543200072a128efa8dc655606530bd39b474f868244df262fed29e42f3d652b1dabdcf8b09487159445268554a3619626f77464b676f786c627671474a67795267777757774a653300071994a1bdf29555ce80c36f63f05e216aa1b35d14829eedc4039230f8e700d576046c7a56340e6d5258577a454c6375565754597000060607e34a464bd706ed3bd619596d791e2ed2febc7594a4173faea83d4df1ffbbb90e104a574d726f4e4d56634763427656526b145152494d706a6265544b6654466d74794348766d00040112080fcc7132f551402a109e93813082773ed762d7bbcbb7ce1ccc20883c87ff252dcdad49c9c12a2bb9a75de53e3ba95d72a89691ebca25874a598763041cd1bbc3995dc8dbe1473d29310ab713136f1d941aa0ae002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d7ffd92ecb3fb714cb14babb35011457eb73f5c27bcefe028393c780dc35d811d9cdbbe741c93a4b486b8754b57fa89dedaf9f9dc533e556c88fb32e2a03450b", + "signed_txn_bcs": "e34c228cb0db32dc07105d569c400e706d7e9d44357e3e54ca8fc6e6a3a678556e11cd8ae1d5540c02244760371f7677296d3ef09b116fce093dea6f10cc4558d5810b6a57f42cfe021a506165594a4d43425778696d4b67505241786663375f436f696e1a68694f724c57614c5a72434c514a4e6155764a4e7a4359674a3306073cc9105c38812512626f90e3ec0c810ab5f197ecb0a8d8712ba2e8d91deaf86e02544e0961636a544f755146320006073f3093b6c3bc411ff7477f73d8f49f5c0449af13cd476b3485c96ae5cb5b59a00a54696c4f62724b65584509735078674651644d37000784c3c8114b4cda43a352b7efd2cffdf58010d3e4abc0245de9e09c8feee4904a136c647570756f6c6b7357597745466f6f64466620545754674e5a45526b53776a496d4a66417766544d62686145447244725565640006070bade12be074a0fa61a4ba4a51ae410379d36252a6d8b8ff4ad26877cd27dcc512506d776c767064684a4662794c47514d613113426a4b65496d634e61466d554d645749415736000789a200128cc1f57108b093f6c6ac3ab49b3f7e825439eeab9d2d2986e486fc6b164748724a775076524478746265486c4a6644734d74530669595272584200060607e84a980c5bf6f1dfcbf2554344b84a42a96b3f38018170b8a141d72aa7f8a3fb084e4e7257736c6336107a74646b6a5572674958654d504d5532000620d27bc7877d2cc44d8fdfea57cac8336dea075170129117f0a0e2e3e358be5003105ca2c3f79f855a38ec3b1e13d7d209100101205033aa4e303a3e593dab78acc7909c65b47b89c2a8a9905602d80a47cea4b13d084c11b3c4e857a7782057f996bfc6c0365226365ee5fdb57f1a70a89c7bd49732e2ff2d5a9339e4543651d8acf5ca12e132bc07d65d82456b003c88866038091d3ae1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409db7b1e8a85bfa87bf1f6e09843c9a0e73c7717e6d3af86b55cf335d4fab91c8cb167ed424017e5dfa3f5c67f6800efc63fc91567e27177dbe91fe370156ed01", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "24c02074401299864e34d765e7cdc212a9bab6b53d812f05526e048aa7fff7e3", - "sequence_number": "18086002593060308461", + "sender": "7c5677dc6662cf3227da3e6ab18bf03d07c7ab987364c6e2057843c04cf6b1c7", + "sequence_number": "6905325641423493828", "payload": { "EntryFunction": { "module": { - "address": "26903d925bc0127b98e641d6f8c8ee92bf76b148a4c8859334d8b3da032e24c8", - "name": "DOwslDvcwWRCTsRYhyIPwCyOVZGiC7_Coin" + "address": "e6cbfc63ba5d801d1605672602731080adbe4b8e4963328222a7f7081bcb17a1", + "name": "nVfZwVBXSHjw1_Coin" }, - "function": "bicVvAkYbwrpRE", + "function": "UrVhCRMLXNIeUplO", "ty_args": [], "args": [ - "fefeaa587042407ad2dd90db5ba259264ce600a46cd6df9c715dd0975ca2670f", - "7ca7b496313b629f06df291ef6fbfbf9c8295c656d2c6157fbba785d6d43ce57", - "01" + "01", + "01", + "8f481ec5966cf9ee8d10423503ddf299", + "4cf4567222684fe41a556c8f7639d88d", + "00", + "c5" ] } }, - "max_gas_amount": "7716011856904148623", - "gas_unit_price": "1435933835037602044", - "expiration_timestamp_secs": "8271686736635672138", - "chain_id": 162 + "max_gas_amount": "18040656634559581542", + "gas_unit_price": "15754263679587659502", + "expiration_timestamp_secs": "2493882573905329835", + "chain_id": 202 }, - "signed_txn_bcs": "24c02074401299864e34d765e7cdc212a9bab6b53d812f05526e048aa7fff7e3ed4527de8863fefa0226903d925bc0127b98e641d6f8c8ee92bf76b148a4c8859334d8b3da032e24c823444f77736c4476637757524354735259687949507743794f565a476943375f436f696e0e6269635676416b59627772705245000320fefeaa587042407ad2dd90db5ba259264ce600a46cd6df9c715dd0975ca2670f207ca7b496313b629f06df291ef6fbfbf9c8295c656d2c6157fbba785d6d43ce5701018f567915e7c7146bfc70610e3776ed134ab67afe42efca72a2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144403b23375b7256fe02abeec9d286a9b35095bcd82edd768176de864b00b7c4bcaadc1b5fe840d2e3a64cb52be173c6efc877c55ccedf2dc509145125b714dc320e", + "signed_txn_bcs": "7c5677dc6662cf3227da3e6ab18bf03d07c7ab987364c6e2057843c04cf6b1c7c49a71bb15a5d45f02e6cbfc63ba5d801d1605672602731080adbe4b8e4963328222a7f7081bcb17a1126e56665a7756425853486a77315f436f696e105572566843524d4c584e496555706c4f000601010101108f481ec5966cf9ee8d10423503ddf299104cf4567222684fe41a556c8f7639d88d010001c566cdb729a0495dfaee2ea9cf5863a2daabfe29e1fc0c9c22ca002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405ddcb990b73a5d491c6a74c5a6e67c18fbe27602825ed8ebcfdd9bfefaca28b11a87d2bd7d625b1694ffce62878dd69df5fe9c37c32c5e4d171d9dd832cf9006", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "c7196048ae1b6b6badb5051fe55702ddcbcea417cfbb25686481a135adc1f2c2", - "sequence_number": "2609204882976820818", + "sender": "d582d64eb84ea6497edf554bde3c414e7ae7abc9c50c8c667561ea4113ba0a15", + "sequence_number": "9117124696319766204", "payload": { "EntryFunction": { "module": { - "address": "b68426c0b04d890f08ef417086c02634ef08c7758c7158ae1c2f0c33c5a1af43", - "name": "SEFfJoUwaoMHFxCzm_Coin" + "address": "3f8ffd1339aec7961c6552ea354e1b8224dc101155d545211655e7905639dcb3", + "name": "uxTQ_Coin" }, - "function": "pUsPuolfbhfOlpjvESLoQSZTVZCxurR4", + "function": "OilsgLnWUpYBb", "ty_args": [ + { + "struct": { + "address": "b707063fbae528597d01de68ee4ed5d02e2da2a03f8e2c8e6297a4a98833cd45", + "module": "gAtlJEWKciHRuUfijQNuDXUDjpQnWGP", + "name": "asBmWVCKeDHMhWdHZUdfidHmJksQHxM", + "type_args": [] + } + }, { "vector": { "vector": { - "vector": "bool" + "vector": "address" } } }, { - "struct": { - "address": "ae410379d36252a6d8b8ff4ad26877cd27dcc582f47a700b80bb135b9992c32e", - "module": "vphTmGmxdjIXtlhTLLTay", - "name": "AtGOeSQrwuOrmuPhxcMHyUjUKTLJhC", - "type_args": [] + "vector": { + "vector": "address" } }, { "vector": { "struct": { - "address": "cc5a38151852cc97fd7bf9ff603970120a7f77dbe84a980c5bf6f1dfcbf25543", - "module": "oqFQwcN", - "name": "FdWMoDkLfozpEyJYklJJiCqWhYcAVT6", + "address": "c13875b7536c22ed5b4707d1d7dbd73e9280265b91aa713bcf2df7d708588614", + "module": "yeACZwrsxtZpOOAoPhsjtfsHw", + "name": "GfQLKUdTpblUKCfMlyOoVSiyyLJp3", "type_args": [] } } }, { - "vector": { - "struct": { - "address": "b0fc45bef6184a8100a982dfed41d86d7a2c34a4c05a8e70cb5decffb08af6ca", - "module": "uoxUGXeb1", - "name": "mJciLGtTNXAGKPjLoWF4", - "type_args": [] - } + "struct": { + "address": "72b8a8f7acf89b1ffa6043823639964c2c4fb29dde3dcd31978d683c80bd7880", + "module": "ctlMOZMyiW", + "name": "R", + "type_args": [] } }, { "vector": { - "vector": { - "vector": "u128" + "struct": { + "address": "b55a0e54cf8dcee8e9e27437e8f2929c37b94dc20fd72990e37a85821c8a16de", + "module": "alPuBZmtrO1", + "name": "PaSO6", + "type_args": [] } } }, + "u128", { "struct": { - "address": "2bd44b1874a5ad1b79869d76a93e5a0227fb879c042f3c38beb47dc222e9d698", - "module": "pPUsqGagULyIhi3", - "name": "doJUWBmiREclbOsKngzgRudpVmVbJx", + "address": "ada65994413d125ec33dc34f2a62f2f2986ccb62d5e160f2fb25e94d9cd9749c", + "module": "dywNzislXPKZDVNRwVFvVxNtAEakpZCA9", + "name": "ejpKlYOeSaMXxpqZPpllqogpdAJuxGDi7", "type_args": [] } + }, + { + "vector": { + "vector": "u8" + } } ], - "args": [] + "args": [ + "2668a664c7fad55058031e203958245f64db890d4f1513073cb47e0226f52010", + "00", + "20cd5eee30144faa", + "9213c4403e92b659", + "01", + "791cbe62acfb65f2394f99eb97e33417" + ] } }, - "max_gas_amount": "8316483292381286413", - "gas_unit_price": "4755289998184685823", - "expiration_timestamp_secs": "14157415986381130450", - "chain_id": 205 + "max_gas_amount": "6149953208834578549", + "gas_unit_price": "5751162415133397679", + "expiration_timestamp_secs": "16653012668262455914", + "chain_id": 41 }, - "signed_txn_bcs": "c7196048ae1b6b6badb5051fe55702ddcbcea417cfbb25686481a135adc1f2c2524e0c5404c2352402b68426c0b04d890f08ef417086c02634ef08c7758c7158ae1c2f0c33c5a1af4316534546664a6f5577616f4d484678437a6d5f436f696e2070557350756f6c666268664f6c706a7645534c6f51535a54565a437875725234060606060007ae410379d36252a6d8b8ff4ad26877cd27dcc582f47a700b80bb135b9992c32e15767068546d476d78646a4958746c68544c4c5461791e4174474f6553517277754f726d75506878634d4879556a554b544c4a6843000607cc5a38151852cc97fd7bf9ff603970120a7f77dbe84a980c5bf6f1dfcbf25543076f71465177634e1f4664574d6f446b4c666f7a7045794a596b6c4a4a6943715768596341565436000607b0fc45bef6184a8100a982dfed41d86d7a2c34a4c05a8e70cb5decffb08af6ca09756f78554758656231146d4a63694c4774544e5841474b506a4c6f5746340006060603072bd44b1874a5ad1b79869d76a93e5a0227fb879c042f3c38beb47dc222e9d6980f7050557371476167554c79496869331e646f4a5557426d695245636c624f734b6e677a6752756470566d56624a7800000d90dbe67d156a73ff20c4090f2ffe41d20aaf95d43e79c4cd002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c3da784f93d783ed3969ab7fdbac707639308e126b76862dc8d9f634c0467929f9a656a528de578db678c380234c44319bca6049cd4896ddf82d4313d057cc04", + "signed_txn_bcs": "d582d64eb84ea6497edf554bde3c414e7ae7abc9c50c8c667561ea4113ba0a15bcae14519b88867e023f8ffd1339aec7961c6552ea354e1b8224dc101155d545211655e7905639dcb309757854515f436f696e0d4f696c73674c6e5755705942620907b707063fbae528597d01de68ee4ed5d02e2da2a03f8e2c8e6297a4a98833cd451f6741746c4a45574b63694852755566696a514e75445855446a70516e5747501f6173426d5756434b6544484d685764485a5564666964486d4a6b735148784d00060606040606040607c13875b7536c22ed5b4707d1d7dbd73e9280265b91aa713bcf2df7d70858861419796541435a77727378745a704f4f416f5068736a74667348771d4766514c4b55645470626c554b43664d6c794f6f56536979794c4a7033000772b8a8f7acf89b1ffa6043823639964c2c4fb29dde3dcd31978d683c80bd78800a63746c4d4f5a4d7969570152000607b55a0e54cf8dcee8e9e27437e8f2929c37b94dc20fd72990e37a85821c8a16de0b616c5075425a6d74724f31055061534f36000307ada65994413d125ec33dc34f2a62f2f2986ccb62d5e160f2fb25e94d9cd9749c216479774e7a69736c58504b5a44564e527756467656784e744145616b705a43413921656a704b6c594f6553614d587870715a50706c6c716f677064414a7578474469370006060106202668a664c7fad55058031e203958245f64db890d4f1513073cb47e0226f5201001000820cd5eee30144faa089213c4403e92b659010110791cbe62acfb65f2394f99eb97e3341775d8db0ddc055955af929adfbe3bd04f6a1add53ca621be729002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444029dce6d6ca09eddb82934807195e6bf2862a590f649f07b289245c1ce8b6de52ad6225c3a8e86d11b83d3886c0efc936f21bf357ca8b3a2243d8ae62ea4b5909", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "4fa1eaf15b0f81e467b4cbe49cf2c8780d01b499c6da1faa3b6d309fc9a76293", - "sequence_number": "3325178443860027294", + "sender": "354dd7953f0fc33c7ef8204fc900510ed78b156b0a55e88332e92d3f3d95a2f3", + "sequence_number": "2864957607836685553", "payload": { "EntryFunction": { "module": { - "address": "c00471a90ad2ce3021246a88795657b0da59c4b3e623d8c57c5677dc6662cf32", - "name": "qlgdIJEugBiyhKRQ_Coin" + "address": "312a14bf8383fc27d648cd829d91a97a377ccae3f5c30e8dd3813b8a88de5c35", + "name": "IznGG_Coin" }, - "function": "MD", + "function": "RiAQTAkPYIqHIxVG", "ty_args": [ { - "struct": { - "address": "2e2da2a03f8e2c8e6297a4a98833cd4564410accf28d893c63f800b67f3d337e", - "module": "JMTyBajvpQQHbARI7", - "name": "kvUjzWs", - "type_args": [] + "vector": { + "struct": { + "address": "94b6ffe1e96006c214b9d06111caec21c9012f388c592bc33ea91057c4c4e03c", + "module": "XPxSjBQh5", + "name": "RuBoJhQTIlZmXbWbaWlbK", + "type_args": [] + } } } ], "args": [ - "60ccb306bf7c1d9e126032fc76ddb8e097e3a67e0bb9a8b453f269792c9bdca3" + "aca8e198557f904c28232a424c3d439c4eec3ea3011bd28bb915afebbf49920b", + "01", + "ed0d14a2e5d2cd7f9bcfbf483f8b3860e5db9e3f2f281ed86fad3e3d1905d6ce", + "b0a99207e9583e6be46e07ca411ecab3f8ddf6c09a6487e691fbbd6038ec3fea", + "9b1891fd8c6a1a43", + "9c" ] } }, - "max_gas_amount": "10423124090295223446", - "gas_unit_price": "14332818859078417237", - "expiration_timestamp_secs": "12447827346449393986", - "chain_id": 150 + "max_gas_amount": "448815171824525478", + "gas_unit_price": "6840996711809809708", + "expiration_timestamp_secs": "10116137999700805261", + "chain_id": 179 }, - "signed_txn_bcs": "4fa1eaf15b0f81e467b4cbe49cf2c8780d01b499c6da1faa3b6d309fc9a762939e2710592d68252e02c00471a90ad2ce3021246a88795657b0da59c4b3e623d8c57c5677dc6662cf3215716c6764494a457567426979684b52515f436f696e024d4401072e2da2a03f8e2c8e6297a4a98833cd4564410accf28d893c63f800b67f3d337e114a4d547942616a76705151486241524937076b76556a7a577300012060ccb306bf7c1d9e126032fc76ddb8e097e3a67e0bb9a8b453f269792c9bdca39604ddd32260a690557b6355d066e8c64269822a0591bfac96002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144407c2cde35d5c24b5af2630ddde85ce53116def16d99a12e81d119960f2bab0c293b7ab13ec692858eb7df6c3e8badff421701fc797f3ba6ed9de971fd04a4320b", + "signed_txn_bcs": "354dd7953f0fc33c7ef8204fc900510ed78b156b0a55e88332e92d3f3d95a2f3f194a8dfc35fc22702312a14bf8383fc27d648cd829d91a97a377ccae3f5c30e8dd3813b8a88de5c350a497a6e47475f436f696e105269415154416b50594971484978564701060794b6ffe1e96006c214b9d06111caec21c9012f388c592bc33ea91057c4c4e03c09585078536a42516835155275426f4a685154496c5a6d5862576261576c624b000620aca8e198557f904c28232a424c3d439c4eec3ea3011bd28bb915afebbf49920b010120ed0d14a2e5d2cd7f9bcfbf483f8b3860e5db9e3f2f281ed86fad3e3d1905d6ce20b0a99207e9583e6be46e07ca411ecab3f8ddf6c09a6487e691fbbd6038ec3fea089b1891fd8c6a1a43019ca620685605833a062cfd09a5431af05e8d46ffc2e9bd638cb3002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444034137d48f8d42c3ec742c720ad099c99ef05e04c6018c2bca46f0c428769fdd755b9eabc715fcec96846316cff06f63190ea0452f182226b7538fa3730bd9a0b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "d319349dcf971010e7113bda5c031175578b3bbe2eda398c0e18862f020f1fb6", - "sequence_number": "16355829892650573629", + "sender": "60d43edaec47a76c61563172716510ff00712d18fad0fbdbe2e8582ff35305ca", + "sequence_number": "6489623314579479024", "payload": { "EntryFunction": { "module": { - "address": "a718056473adfb04ec9139895bf4f55dad151685acf6174c740ad7f68d7ee85c", - "name": "fyh_Coin" + "address": "0809d65751bd28f265563f72871e06ce1a888171a043a5f8328ecbb460a5d092", + "name": "TtQwbhhfvYfWK_Coin" }, - "function": "lnWZptEMukyevSdrxJy", + "function": "JgnNCt", "ty_args": [ - { - "vector": "signer" - }, { "struct": { - "address": "c1a8e819a8e4aa0dda41456cc7e4d2f4f6545b2e49eb4a3ed0c704d7013202d6", - "module": "TTd0", - "name": "GdqnNNmNjK", + "address": "bf93e0f58fb532efa1e07b525df228136a15933fa00872c1b1619d431d4b3be4", + "module": "Pa2", + "name": "dzDZcOG9", "type_args": [] } }, { "vector": { - "vector": "u128" + "struct": { + "address": "63bb31fa316c4556eadbacef93d38887184e46dbfe9d696030bfe61e87e035d4", + "module": "WuxVyqGjGCCsDqxbuWnEF5", + "name": "sGFnoJI", + "type_args": [] + } } } ], "args": [ - "c1efc268c0a0757d", + "9ce2f43e3a6c246e", + "8364c91fc7fed6c6167e463ea03a1964", + "d0", + "adfc2cdf74966aac", + "6d7885c7382f1d49179f9c14d8e7e192", "01", - "742834f586d97ec4417492bea1c27453", - "9c", - "4f", - "8e", - "40ad278eb9c296b9" + "5a235e716b20f369e49fa939ce1565af", + "1b" ] } }, - "max_gas_amount": "12255823520549005536", - "gas_unit_price": "8935819560039374055", - "expiration_timestamp_secs": "13068481333707491606", - "chain_id": 235 + "max_gas_amount": "1391072344350889424", + "gas_unit_price": "17452982293095219306", + "expiration_timestamp_secs": "12165991714004765251", + "chain_id": 208 }, - "signed_txn_bcs": "d319349dcf971010e7113bda5c031175578b3bbe2eda398c0e18862f020f1fb63d1f2766a194fbe202a718056473adfb04ec9139895bf4f55dad151685acf6174c740ad7f68d7ee85c086679685f436f696e136c6e575a7074454d756b796576536472784a7903060507c1a8e819a8e4aa0dda41456cc7e4d2f4f6545b2e49eb4a3ed0c704d7013202d604545464300a4764716e4e4e6d4e6a4b000606030708c1efc268c0a0757d010110742834f586d97ec4417492bea1c27453019c014f018e0840ad278eb9c296b9e06833cc8e6e15aae75c22bd8b68027c1649758188925cb5eb002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400c7ca504f28cc13f65585043f881daed1109c51c76bd85290a353279da27d30da3885d550e776f1b330126f97aa54758ad83485c2102539d8a27b4dba77fca05", + "signed_txn_bcs": "60d43edaec47a76c61563172716510ff00712d18fad0fbdbe2e8582ff35305caf0599a6705c60f5a020809d65751bd28f265563f72871e06ce1a888171a043a5f8328ecbb460a5d092125474517762686866765966574b5f436f696e064a676e4e43740207bf93e0f58fb532efa1e07b525df228136a15933fa00872c1b1619d431d4b3be40350613208647a445a634f473900060763bb31fa316c4556eadbacef93d38887184e46dbfe9d696030bfe61e87e035d416577578567971476a474343734471786275576e454635077347466e6f4a490008089ce2f43e3a6c246e108364c91fc7fed6c6167e463ea03a196401d008adfc2cdf74966aac106d7885c7382f1d49179f9c14d8e7e1920101105a235e716b20f369e49fa939ce1565af011bd095e74ded144e136a801ffbec7235f2438a99750149d6a8d0002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440dda7f1fb6c7c9bd6177dcbb30c26a892e9e3174d098a469c76cc9d25ab51556344d69efd4e77ee6f3b8f4365ddd9525baf34e9f01b306d529757fdc8dfdb0707", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "14d1709d0a4fdec719078a3f6fa4eb632378999f8d87165de109d2fc8e77910c", - "sequence_number": "11542562776416229157", + "sender": "492567b13ed379b192567070f7c5adbb2957241a917f32abe7142d12aa75d23c", + "sequence_number": "14636393335272218835", "payload": { "EntryFunction": { "module": { - "address": "b5c612ed124cecb353449912b21dc34c2d922dfecc9062319cd6ae301e4985a0", - "name": "mISNsySdaVlNfrolHRMHkZ_Coin" + "address": "6c7f2df2c745ff6f47dde5d68d5dc89970ea4f337b52813b0d42763ab190b9a4", + "name": "ej_Coin" }, - "function": "sRZTCcuoUHpNmpHvaz", + "function": "wsys3", "ty_args": [ { "struct": { - "address": "49a20934f5f6a3f2e77fa30cb7552aa055002455ac7887cd01ee9682367b89ba", - "module": "iegkYKJurYIbuTNCokjqVihVyamUs7", - "name": "wUmrnrMDSqmpetuz", + "address": "3fe267f463455d2e22feee79d2a1a0f76b400e774dce70f577a7dbe12b50e440", + "module": "qnGtoWTmMmrWitlJwHzobdBwLJttlV", + "name": "nDAdBeTZrsIZWVzTzRLMXwPhLFMSxl8", "type_args": [] } - } - ], - "args": [ - "775f24314cd492fa818f5c0ad0dfcf0cc90739acd9f8c83079ac3997d582d64e", - "af929adfbe3bd04f", - "2a", - "0bda45c718f002ab14fd1e73ecf5afba", - "10", - "2dbe444f4bdddbfe", - "63", - "619494b6ffe1e96006c214b9d06111caec21c9012f388c592bc33ea91057c4c4", - "4aab1dc471b6d5028a471eba3270728a1022a1e87da7337d3457dc9188e27385" - ] - } - }, - "max_gas_amount": "5154745630719927855", - "gas_unit_price": "17208755434787040077", - "expiration_timestamp_secs": "10124569666660383901", - "chain_id": 48 - }, - "signed_txn_bcs": "14d1709d0a4fdec719078a3f6fa4eb632378999f8d87165de109d2fc8e77910c2597efa5b06b2fa002b5c612ed124cecb353449912b21dc34c2d922dfecc9062319cd6ae301e4985a01b6d49534e7379536461566c4e66726f6c48524d486b5a5f436f696e1273525a544363756f5548704e6d704876617a010749a20934f5f6a3f2e77fa30cb7552aa055002455ac7887cd01ee9682367b89ba1e6965676b594b4a757259496275544e436f6b6a715669685679616d5573371077556d726e724d4453716d706574757a000920775f24314cd492fa818f5c0ad0dfcf0cc90739acd9f8c83079ac3997d582d64e08af929adfbe3bd04f012a100bda45c718f002ab14fd1e73ecf5afba0110082dbe444f4bdddbfe016320619494b6ffe1e96006c214b9d06111caec21c9012f388c592bc33ea91057c4c4204aab1dc471b6d5028a471eba3270728a1022a1e87da7337d3457dc9188e273852fe68e12d75589474deb0d5de4c7d1ee9dbcfc3478b2818c30002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406d589dfb72349139fbd8b7d11ce7b801d91251afc7591698e88827a3e9a2cc65b916595e3fa920fa6a6d03672f0f4168e9bca926ffdec4bdbae2f45a90666209", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "bfe0032d7fc34b8baf3acb7b4eea1f1565e5e302d5e8c5ce8512fee729815ca6", - "sequence_number": "3684526055655899207", - "payload": { - "EntryFunction": { - "module": { - "address": "dd8efb47376dbe66089602d544872340e34d46c13f7ed03bc7df3513c96a5c50", - "name": "TLFd6_Coin" - }, - "function": "UOePmmGAIHRQGQJqFap", - "ty_args": [ + }, { "struct": { - "address": "e5db9e3f2f281ed86fad3e3d1905d6ce996b7cbb84f33ff4899ff91f69adac42", - "module": "B", - "name": "kXDeRdRbKIADaUgCtpNTAJGapi3", + "address": "1117a28be7ed602d0daf4a1158d458f999eee81d99b632e0679b7092e5488b27", + "module": "VcHQXDuysQgsq5", + "name": "Jpu", "type_args": [] } }, + { + "vector": { + "struct": { + "address": "9038d084aa172347d445783d1de45fa58122a89624730e8a5287798f57896db8", + "module": "GoUQLEsADgwbXwMQAALWePD0", + "name": "wyHwLvIkrpEmxwToVeWH8", + "type_args": [] + } + } + }, { "struct": { - "address": "75a3024e99693a53a050cb08d16bc51bed64f2707c1a9a323097d017f45b5bc2", - "module": "gCifNWMXtfHcfaFdDZjDQosPx8", - "name": "PzvzhxBEPhYTGJ", + "address": "5d12df7dfdf9d8a552a1d1650ccfa429a0722f4f4df371439053bc9c80fb9017", + "module": "UIaQEjLkNqSlhrnerWmjOy", + "name": "cravXgxrTlSQNaRIhcppBY2", "type_args": [] } }, + { + "vector": { + "vector": "signer" + } + }, { "struct": { - "address": "6c3beb3be280e492256bab9767bd1edf64cc9b01b2e256c4f203c4e763bf2b78", - "module": "WxTwlvSBQUbAjtWQzsMppKa0", - "name": "TPbzAtqYFzcwoRmmKCdkyRA", + "address": "421d3d059d947c2cbe789fdeeb4d71acac26107eb686b8b2c791f746b84254d5", + "module": "ObWPfj", + "name": "xVqksRecTlGsCQPtfTGPBr", "type_args": [] } }, { "struct": { - "address": "2f97e4f66013d60144d835e8be906b57a42dd881c1967c7677f72c4ff61e24b1", - "module": "dn1", - "name": "kbsPrTMMAUgJQZyme", + "address": "e19be0aea40f644987357b0ec30c015d20f31cda3d8e162e2346ab4ca121b5f0", + "module": "JUdhlnBTjjiNhYMaYpZM", + "name": "KRXQ7", "type_args": [] } } ], "args": [ - "01", - "6ea0b2bac0c163305ab801bb22084cca", - "c51ce27535f007e05e6fe75df344de4c7a1a32e3ff229d491e46e5fcdfdb7645", - "6814468c56caf5531382bf6e9212d6d5", - "618ed1ea36ab3163", - "00", - "c931e1d04152128975fdd2558957eeeb0c0b0d93cf687a2a80c5e741a9868a0d" + "528bccfa87b00e933770391a8bcc6ac1", + "d369bf1deb4502d9315a1b59c635e2c66fd86490622f1c3fac64b4c3c6aa2c0b", + "c35780147370001c003137ebfa074c2b88c706efc5e50e8c76dc095e197cb999", + "8924290c2bd07b38562b13c2c956e8f4725d55c47949e24542b29757537c4639", + "691742bc128ece0784313e9831e14aa2", + "9b22f9e25de41a99bde0e2c13cffab90", + "55c3e3b69632f652", + "9ddf9d56cec575aeb2ecf11ee80033a1", + "80c97183b15bb9df", + "9dd777f326759cce" ] } }, - "max_gas_amount": "15810533055880728804", - "gas_unit_price": "8160813382947086470", - "expiration_timestamp_secs": "3922053241510363826", - "chain_id": 34 + "max_gas_amount": "6912783674791583668", + "gas_unit_price": "5859368504772063319", + "expiration_timestamp_secs": "6933156099596175073", + "chain_id": 206 }, - "signed_txn_bcs": "bfe0032d7fc34b8baf3acb7b4eea1f1565e5e302d5e8c5ce8512fee729815ca647800a19ed10223302dd8efb47376dbe66089602d544872340e34d46c13f7ed03bc7df3513c96a5c500a544c4664365f436f696e13554f65506d6d47414948525147514a714661700407e5db9e3f2f281ed86fad3e3d1905d6ce996b7cbb84f33ff4899ff91f69adac4201421b6b584465526452624b4941446155674374704e54414a4761706933000775a3024e99693a53a050cb08d16bc51bed64f2707c1a9a323097d017f45b5bc21a674369664e574d587466486366614664445a6a44516f735078380e507a767a6878424550685954474a00076c3beb3be280e492256bab9767bd1edf64cc9b01b2e256c4f203c4e763bf2b7818577854776c765342515562416a7457517a734d70704b6130175450627a41747159467a63776f526d6d4b43646b79524100072f97e4f66013d60144d835e8be906b57a42dd881c1967c7677f72c4ff61e24b103646e31116b62735072544d4d4155674a515a796d6500070101106ea0b2bac0c163305ab801bb22084cca20c51ce27535f007e05e6fe75df344de4c7a1a32e3ff229d491e46e5fcdfdb7645106814468c56caf5531382bf6e9212d6d508618ed1ea36ab3163010020c931e1d04152128975fdd2558957eeeb0c0b0d93cf687a2a80c5e741a9868a0de49057e90b4c6adb86a0d0b088084171b20265aaa4ee6d3622002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444053d263dedb7fffb975d3dd64d32c4288e929bcaa05910b6ed40822e896209cb2b6ab73cc630b329eaf213f0ac4e62e8a5f3e93918633f75025c3f9eabc0f9f0b", + "signed_txn_bcs": "492567b13ed379b192567070f7c5adbb2957241a917f32abe7142d12aa75d23cd3a0cb0531ea1ecb026c7f2df2c745ff6f47dde5d68d5dc89970ea4f337b52813b0d42763ab190b9a407656a5f436f696e05777379733307073fe267f463455d2e22feee79d2a1a0f76b400e774dce70f577a7dbe12b50e4401e716e47746f57546d4d6d725769746c4a77487a6f626442774c4a74746c561f6e4441644265545a7273495a57567a547a524c4d587750684c464d53786c3800071117a28be7ed602d0daf4a1158d458f999eee81d99b632e0679b7092e5488b270e5663485158447579735167737135034a70750006079038d084aa172347d445783d1de45fa58122a89624730e8a5287798f57896db818476f55514c4573414467776258774d5141414c576550443015777948774c76496b7270456d7877546f566557483800075d12df7dfdf9d8a552a1d1650ccfa429a0722f4f4df371439053bc9c80fb90171655496151456a4c6b4e71536c68726e6572576d6a4f79176372617658677872546c53514e615249686370704259320006060507421d3d059d947c2cbe789fdeeb4d71acac26107eb686b8b2c791f746b84254d5064f625750666a167856716b73526563546c4773435150746654475042720007e19be0aea40f644987357b0ec30c015d20f31cda3d8e162e2346ab4ca121b5f0144a5564686c6e42546a6a694e68594d6159705a4d054b52585137000a10528bccfa87b00e933770391a8bcc6ac120d369bf1deb4502d9315a1b59c635e2c66fd86490622f1c3fac64b4c3c6aa2c0b20c35780147370001c003137ebfa074c2b88c706efc5e50e8c76dc095e197cb999208924290c2bd07b38562b13c2c956e8f4725d55c47949e24542b29757537c463910691742bc128ece0784313e9831e14aa2109b22f9e25de41a99bde0e2c13cffab900855c3e3b69632f652109ddf9d56cec575aeb2ecf11ee80033a10880c97183b15bb9df089dd777f326759cceb45f12712024ef5f57f00c5f9ca85051e146c338bd843760ce002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144407da102626f65c2e6a73b7a35c4e39c071b402a1c63c8e9cdd07a0d3f0ec9831d6c446f05d329182bb736d31c88cb8d3f9e0ea1f7423461b5df6322b68ed4a204", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "2fbe7ae7760b38b0a4ccd59f2b07ab56d6138a21ea8de2856bb1becd82d5b321", - "sequence_number": "9471573047067652990", + "sender": "30a66c870e97f22763f0c837598a470d21566b0eff14be6570929b5381631cd9", + "sequence_number": "4817647060128806984", "payload": { "EntryFunction": { "module": { - "address": "7e7bacf6750ee1e3e6dd6a9084153ad37bb65e296503be693439155d12df7dfd", - "name": "WxvQYSdcHrNrVsNrCsfhQakHLomQ9_Coin" + "address": "c2612a1f7a9413f5638132c912abfb41924a9109646168993d46b1d3025d0c0d", + "name": "TavNIFyhawqprRZUTGZNcNr_Coin" }, - "function": "uHxYd2", + "function": "FzNaOeJWTMThcpVBuHSkFDlclTGHlCuy6", "ty_args": [ + { + "vector": { + "vector": "signer" + } + }, + { + "struct": { + "address": "a7c25eefc894af8a6d08aa0414c6ec1ffb0067dbce3042ddde3de8e7f446ef0b", + "module": "vCxqhfDYsNNkaePQxUyxYKnvcSkniIw9", + "name": "HhnMucFftZFCgasJItBRynwiOpNffP3", + "type_args": [] + } + }, + { + "struct": { + "address": "9aeb11623d06469bfa9d4105adb6d5a77f41ea276a0f3718d7e1a49e1cc85eb6", + "module": "duXGEGGcE8", + "name": "NKsxjitSJGAzgc6", + "type_args": [] + } + }, + { + "struct": { + "address": "b2b656d832c731d3fbbf776898a9b533b90bc1d7f8e40d0d302a8199f1636f75", + "module": "SU4", + "name": "nTrRqOfARJyyKruXqEg8", + "type_args": [] + } + }, + { + "struct": { + "address": "1d3b523f593d92fc1ea05c250f866b0d02b054c4c5d35dde5b04e146af6204b4", + "module": "icBSXHIjStq3", + "name": "fjUTTFiPXqHZXGJxDYReIEthNFv1", + "type_args": [] + } + }, { "struct": { - "address": "cafd9ba4993d61b5b2536f750432561fa6dfbb6f09243917aab3313f84af664f", - "module": "ZRpt", - "name": "xAtOWbTKB6", + "address": "b405d488629dc647194ebcf8f06ca89ed4f83c97e4637ebee04ab5591d66bfe8", + "module": "envARKRxGvHylk", + "name": "wbPZlfdtELatVySeJthAK", "type_args": [] } }, { - "vector": { - "struct": { - "address": "6fc27b6af2cc8959cbad7a02df83b8a1d5107714ce8789806c232f3078efc51e", - "module": "XXxdomxpNcXZzOzqUFnLBKhbOKex", - "name": "oFudvyNbzdLRpYblLbZdjKpqQ1", - "type_args": [] - } + "struct": { + "address": "fb0bfeed94b942ed153a736d16ad284fabb0d85ee448a5e2fd3284f656cf85fd", + "module": "CZXltTquuEjgDyYarjjmrgk7", + "name": "JTLywcx9", + "type_args": [] } } ], "args": [ - "001c003137ebfa074c2b88c706efc5e50e8c76dc095e197cb999605b9ea506bd", - "0aaa91074ed2ee54", - "8efc2b679f7322aa7e3e35e868b61f6a", - "00bc42870524aae445d2d35e27ee5cdd02a35a69825dce3122b679f8bac44f82", - "b5eee2ac8b424b18", - "01" + "a1764262e6ce89af", + "00", + "5ce7a217b8389cfd2044f39eba055ee0328567d3a45dccffbc9b7ff8d7fa74e3", + "01c8a787912ac553", + "a45d8408e13e1a521920610294357583157d56b9a237ea1f90dbd7f06c21c2de", + "95c928d7c9b016bd43eac70439d2b15b", + "7922cb9f56f80860", + "a7db9f0d3c934240a9d8cfcc18966e6121a2dd8837adb0e9464ddb015029b627", + "00", + "99378115017b46d22ebb103ebf6ecb441e4f183f7d7a976c817fd32fb6756576" ] } }, - "max_gas_amount": "198408076994411574", - "gas_unit_price": "3960752392244391960", - "expiration_timestamp_secs": "16631222935716715441", - "chain_id": 195 + "max_gas_amount": "13115879407401372479", + "gas_unit_price": "15731584257188240775", + "expiration_timestamp_secs": "12959156708318052505", + "chain_id": 108 }, - "signed_txn_bcs": "2fbe7ae7760b38b0a4ccd59f2b07ab56d6138a21ea8de2856bb1becd82d5b3217eb3a1f680c97183027e7bacf6750ee1e3e6dd6a9084153ad37bb65e296503be693439155d12df7dfd22577876515953646348724e7256734e724373666851616b484c6f6d51395f436f696e067548785964320207cafd9ba4993d61b5b2536f750432561fa6dfbb6f09243917aab3313f84af664f045a5270740a7841744f5762544b42360006076fc27b6af2cc8959cbad7a02df83b8a1d5107714ce8789806c232f3078efc51e1c585878646f6d78704e63585a7a4f7a7155466e4c424b68624f4b65781a6f46756476794e627a644c527059626c4c625a646a4b70715131000620001c003137ebfa074c2b88c706efc5e50e8c76dc095e197cb999605b9ea506bd080aaa91074ed2ee54108efc2b679f7322aa7e3e35e868b61f6a2000bc42870524aae445d2d35e27ee5cdd02a35a69825dce3122b679f8bac44f8208b5eee2ac8b424b18010136fcd14518e3c002187001d7506bf736b15bb9df24f9cde6c3002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406bc88fa984140a2cbe17bf8e81862e6df702c5874614dd941e9865a570fcdb0bead3bb46bf6165bf6ea2434bbef28d1c65cf7258a19706d80e6191f34c82ea0a", + "signed_txn_bcs": "30a66c870e97f22763f0c837598a470d21566b0eff14be6570929b5381631cd948b82ee879b8db4202c2612a1f7a9413f5638132c912abfb41924a9109646168993d46b1d3025d0c0d1c5461764e494679686177717072525a5554475a4e634e725f436f696e21467a4e614f654a57544d5468637056427548536b46446c636c5447486c437579360706060507a7c25eefc894af8a6d08aa0414c6ec1ffb0067dbce3042ddde3de8e7f446ef0b207643787168664459734e4e6b6165505178557978594b6e7663536b6e694977391f48686e4d75634666745a46436761734a49744252796e77694f704e6666503300079aeb11623d06469bfa9d4105adb6d5a77f41ea276a0f3718d7e1a49e1cc85eb60a647558474547476345380f4e4b73786a6974534a47417a6763360007b2b656d832c731d3fbbf776898a9b533b90bc1d7f8e40d0d302a8199f1636f7503535534146e547252714f6641524a79794b7275587145673800071d3b523f593d92fc1ea05c250f866b0d02b054c4c5d35dde5b04e146af6204b40c696342535848496a537471331c666a5554544669505871485a58474a7844595265494574684e4676310007b405d488629dc647194ebcf8f06ca89ed4f83c97e4637ebee04ab5591d66bfe80e656e7641524b5278477648796c6b157762505a6c666474454c6174567953654a7468414b0007fb0bfeed94b942ed153a736d16ad284fabb0d85ee448a5e2fd3284f656cf85fd18435a586c7454717575456a6744795961726a6a6d72676b37084a544c7977637839000a08a1764262e6ce89af0100205ce7a217b8389cfd2044f39eba055ee0328567d3a45dccffbc9b7ff8d7fa74e30801c8a787912ac55320a45d8408e13e1a521920610294357583157d56b9a237ea1f90dbd7f06c21c2de1095c928d7c9b016bd43eac70439d2b15b087922cb9f56f8086020a7db9f0d3c934240a9d8cfcc18966e6121a2dd8837adb0e9464ddb015029b62701002099378115017b46d22ebb103ebf6ecb441e4f183f7d7a976c817fd32fb67565763f0b0583d4f604b6871dd54b88d051da9900eb9b5d2cd8b36c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444088daaf4c40016b31dd0d7180abb5351e809c37883569291a0a2b873823b73969c78793fa20344e79d51ea3a5aa2bf8bfb4880d7ef24054f7b5dd7a772e352e06", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "b1ba3fc401ffc58dd4183968b903ecc59b8821574edb19dd740471da100998c2", - "sequence_number": "7951721077400340342", + "sender": "0a2262bb2f4e032573f2d9ab6de5df370cc48123983feb870212094955c8b5c1", + "sequence_number": "4243155741195374353", "payload": { "EntryFunction": { "module": { - "address": "5cbd1aa3eeba7a5e428a714043a4b13ca82265914e147818030ce0e49d264925", - "name": "XDkgnRjAJCzPqQFH1_Coin" + "address": "34ac0434f14c56a1a0cee12af501b57c72df3440e8a19a194d7bff0b62cf7ee3", + "name": "XrEQiVNhRaOcsUoTqFeDyQV_Coin" }, - "function": "ZPwNcAjWPEADYWJYc", + "function": "XCHUHvfKbmuQXWphJjpplR", "ty_args": [ { - "struct": { - "address": "2b90214d86e51df6cf0a639a709ebe86b0cb9bc15c68add36f2d67becb3caf07", - "module": "qALDMGXIYDVAkWkTbeA", - "name": "FOPUgbAgNZmIkTPvkCTHskKQdpsBgzIn2", - "type_args": [] + "vector": { + "struct": { + "address": "4681de2a3f39b54f3e610f143d7c741fd6f36eb6f1d4fe8d9a69df2c50ec4b8d", + "module": "ACEHnbUHMFXeif", + "name": "EecXlTcyY", + "type_args": [] + } } }, { "struct": { - "address": "3691b97ab24f3fe6a34204155f1d9d4836e4d88e6b9238f0c67b26f8f0283ac5", - "module": "oIqnybC7", - "name": "abYsvnDujPcdXx", + "address": "bfb1ba3fc401ffc58dd4183968b903ecc59b8821574edb19dd740471da100998", + "module": "kgcivZwUhImVFmzoWHsvJa", + "name": "XpfsRRkEiHRpAIayFLyt5", "type_args": [] } }, { "vector": { "struct": { - "address": "cf6bf4769f1b6fb0d6e79aa700fa708dc44ec4d8f828b3f8b0a9a6d5eb330495", - "module": "DKSnx5", - "name": "ckfzGcRFcIuuUZgtAZ9", + "address": "9ab8b8e2cb2dc0f4fd80b95248524b5158282dbde0834115d43dd3f5e36efe4f", + "module": "DpvqYqvvTh", + "name": "ghAhOongPMYY", "type_args": [] } } }, { "struct": { - "address": "d35dde5b04e146af6204b46fea5cf36501aae42ce3e5d809499513236e3bdfe9", - "module": "NRpwKPFwpzS3", - "name": "xKBGeXMNXiYpgnOruFDGpFnIsKsTQW", + "address": "74b2a474485adcc985746579ebbe7e40d49d19f9b7863705bb973fc9b5966400", + "module": "AcDIVHdwdAVPmqYYvAgdhUDty2", + "name": "RxQHHSYmyi", "type_args": [] } }, { - "struct": { - "address": "dd69e6a90ec6bc8e27395ebd7a0110acd93d862347fd90fcc59799616ec8fb41", - "module": "f", - "name": "jyiDTAqeNlwdCJgTGKjeJUwLDgSmu", - "type_args": [] + "vector": { + "struct": { + "address": "d09e9d2e6928acc9e3ce3c48c553b45e21ac70d241900e14734cff89f4a6d19d", + "module": "CSIgifIuXKYhc", + "name": "uhMZIHZnvYLmjfnUNHoxvKYKwXypZmG", + "type_args": [] + } } }, { "vector": { - "struct": { - "address": "5933607ca9b10061e97625fa20257723d0a57b5a3597e350cd3c9b3af6ab21d7", - "module": "vzvLvz2", - "name": "SIDHFKrgyYErC3", - "type_args": [] + "vector": { + "vector": "u8" } } }, { "struct": { - "address": "38c53f54d822e4addbf8b0484444705300fe931b506c5b09d7a50e082d9ce72c", - "module": "QqekmctjfRLLhIdlNQfFqHvMxIU", - "name": "rouyNvoWRKxzjjAu", + "address": "95bd76b70ec10ddb28bcf91af17a6f0ab254970b0f793853e6ccba12f17998ae", + "module": "gwhces8", + "name": "fxCboAZmKvIiSmbVdxTDhmuCBAZZKvu4", "type_args": [] } } ], "args": [ - "3a9baca809c3536d", - "21f4c637e59c71071ab2959eba760800", - "21da719ddf7d658c3de5d2046030ec23e91983a8bbbcf21062e2f4c6e760f864", - "01", - "053883cb99440a99", - "00", - "06", - "01", - "2d126b07b4ab8b3f896efebf190f8e19a7e52277cddc669599be119cd3026ebf" + "3f935df258c0a050", + "01" ] } }, - "max_gas_amount": "12941676234029091198", - "gas_unit_price": "5878499895629654640", - "expiration_timestamp_secs": "17723079372365953068", - "chain_id": 196 + "max_gas_amount": "13394626205725655419", + "gas_unit_price": "10907988120019705214", + "expiration_timestamp_secs": "10076503061810064238", + "chain_id": 191 }, - "signed_txn_bcs": "b1ba3fc401ffc58dd4183968b903ecc59b8821574edb19dd740471da100998c276076f9b30305a6e025cbd1aa3eeba7a5e428a714043a4b13ca82265914e147818030ce0e49d2649251658446b676e526a414a437a5071514648315f436f696e115a50774e63416a575045414459574a596307072b90214d86e51df6cf0a639a709ebe86b0cb9bc15c68add36f2d67becb3caf071371414c444d475849594456416b576b5462654121464f5055676241674e5a6d496b5450766b435448736b4b5164707342677a496e3200073691b97ab24f3fe6a34204155f1d9d4836e4d88e6b9238f0c67b26f8f0283ac5086f49716e796243370e61625973766e44756a5063645878000607cf6bf4769f1b6fb0d6e79aa700fa708dc44ec4d8f828b3f8b0a9a6d5eb33049506444b536e783513636b667a4763524663497575555a6774415a390007d35dde5b04e146af6204b46fea5cf36501aae42ce3e5d809499513236e3bdfe90c4e5270774b504677707a53331e784b424765584d4e58695970676e4f727546444770466e49734b735451570007dd69e6a90ec6bc8e27395ebd7a0110acd93d862347fd90fcc59799616ec8fb4101661d6a796944544171654e6c7764434a6754474b6a654a55774c4467536d750006075933607ca9b10061e97625fa20257723d0a57b5a3597e350cd3c9b3af6ab21d707767a764c767a320e53494448464b7267795945724333000738c53f54d822e4addbf8b0484444705300fe931b506c5b09d7a50e082d9ce72c1b5171656b6d63746a66524c4c6849646c4e5166467148764d78495510726f75794e766f57524b787a6a6a41750009083a9baca809c3536d1021f4c637e59c71071ab2959eba7608002021da719ddf7d658c3de5d2046030ec23e91983a8bbbcf21062e2f4c6e760f864010108053883cb99440a99010001060101202d126b07b4ab8b3f896efebf190f8e19a7e52277cddc669599be119cd3026ebf7e496b87f7119ab3702a2d6b82a094512cf8eccbc906f5f5c4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440721c5a5da9c6b68d302251f06c76f880c275fb4eb31f958a43a28e8d6b38bcf25dfb25355f73236aa6acbd132980594e44cb2154b8c99f20290a59597d9c6908", + "signed_txn_bcs": "0a2262bb2f4e032573f2d9ab6de5df370cc48123983feb870212094955c8b5c1110f9c58aab7e23a0234ac0434f14c56a1a0cee12af501b57c72df3440e8a19a194d7bff0b62cf7ee31c5872455169564e6852614f6373556f54714665447951565f436f696e16584348554876664b626d7551585770684a6a70706c520706074681de2a3f39b54f3e610f143d7c741fd6f36eb6f1d4fe8d9a69df2c50ec4b8d0e414345486e6255484d465865696609456563586c546379590007bfb1ba3fc401ffc58dd4183968b903ecc59b8821574edb19dd740471da100998166b676369765a775568496d56466d7a6f574873764a61155870667352526b456948527041496179464c7974350006079ab8b8e2cb2dc0f4fd80b95248524b5158282dbde0834115d43dd3f5e36efe4f0a447076715971767654680c676841684f6f6e67504d5959000774b2a474485adcc985746579ebbe7e40d49d19f9b7863705bb973fc9b59664001a4163444956486477644156506d715959764167646855447479320a527851484853596d7969000607d09e9d2e6928acc9e3ce3c48c553b45e21ac70d241900e14734cff89f4a6d19d0d4353496769664975584b5968631f75684d5a49485a6e76594c6d6a666e554e486f78764b594b775879705a6d4700060606010795bd76b70ec10ddb28bcf91af17a6f0ab254970b0f793853e6ccba12f17998ae076777686365733820667843626f415a6d4b764969536d625664785444686d754342415a5a4b7675340002083f935df258c0a05001017b816afb9045e3b97e9df4f366f560976e2b53a925eed68bbf002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c3a7068e68bb52765fdf284804f38d324df3af047e9079ea65e1e4d1b68f00eb257bc44b3171900524384c871b21503ec192068355ad72c4671441a0dbba440a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "ce52a21f0196c241499e4666394dc8c488300dafa1bca1e189224d248a910f2b", - "sequence_number": "3610790754903159157", + "sender": "cab0ddff7149501cbdaf45dd941ef01d1c27ccc10575ff8818c24e40fac619e4", + "sequence_number": "4867804281556525266", "payload": { "EntryFunction": { "module": { - "address": "ba73e56fb545809fcc90bb8251eb6c593a0dd6e3ee3c578e4f6b99c7a23a6a3d", - "name": "awmoalaKxS_Coin" + "address": "b00315f1122ae8888d442d657343a629a42ce4a82bf902123295eb46da7b1c5f", + "name": "YNsGhawhzbP_Coin" }, - "function": "JbRmqzmJCfhzBsldQAGGeGbK", + "function": "MZcGtQQbegscGijtRV", "ty_args": [ + { + "vector": "bool" + }, + { + "struct": { + "address": "e4414ae7f90379c21800e6302ff6ed0450adb5b2703afb1fb09ca217960bc092", + "module": "sVRKPGOZqCuBDZOPv2", + "name": "tXglVgbybAAoWQOIbpoJ1", + "type_args": [] + } + }, { "struct": { - "address": "5d7a6f55e1ac23d8ac71647c3e0332b14184efad7fb7581e137b30e52574844e", - "module": "vNlciOEczkoOMvtDqHnBtirPOoguq9", - "name": "SmGfvoXkKclaxHG", + "address": "71ca3d62766f01d128c5c221ca5b839beb5e40e2215e17f8bbd97a24cd1f2974", + "module": "iATszaDeU", + "name": "ODYeHGLNx2", "type_args": [] } }, + { + "vector": { + "vector": "u128" + } + }, { "struct": { - "address": "ffd58e54489ab984756871967307bca9d8ec14ffe7771814b7617631470e5889", - "module": "nYEjwcHxWdYusHtRuDkUMvvIsZ5", - "name": "whSWt", + "address": "665df07edd482ce5585a013e01950a843aa0b3fc086014c479135711be86bdca", + "module": "XxyBVXyoLGcBaXJpBFu1", + "name": "NvzYHbaTudPtMNqETyHM1", "type_args": [] } } ], - "args": [] + "args": [ + "dabcec5834f1262f0505a13900382dc6", + "f6" + ] } }, - "max_gas_amount": "18194581930582188789", - "gas_unit_price": "15052774334202349260", - "expiration_timestamp_secs": "4118627564632064333", - "chain_id": 135 + "max_gas_amount": "14179493893931586993", + "gas_unit_price": "17329011313062081753", + "expiration_timestamp_secs": "9271361166066967534", + "chain_id": 175 }, - "signed_txn_bcs": "ce52a21f0196c241499e4666394dc8c488300dafa1bca1e189224d248a910f2b757144900f1b1c3202ba73e56fb545809fcc90bb8251eb6c593a0dd6e3ee3c578e4f6b99c7a23a6a3d0f61776d6f616c614b78535f436f696e184a62526d717a6d4a4366687a42736c64514147476547624b02075d7a6f55e1ac23d8ac71647c3e0332b14184efad7fb7581e137b30e52574844e1e764e6c63694f45637a6b6f4f4d76744471486e42746972504f6f677571390f536d4766766f586b4b636c617848470007ffd58e54489ab984756871967307bca9d8ec14ffe7771814b7617631470e58891b6e59456a77634878576459757348745275446b554d767649735a350577685357740000f5a217e9dd2380fccc863f028132e6d04dc106d8f24d283987002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444076dfc33f53146440679dac22e2dabfe84e92845c01359b33bcfc851ed28b485bcf901bc1ba57a35108de47421bd1dac5f1c0cf5b749338837973e253cd532d0d", + "signed_txn_bcs": "cab0ddff7149501cbdaf45dd941ef01d1c27ccc10575ff8818c24e40fac619e4d2604d0e34ea8d4302b00315f1122ae8888d442d657343a629a42ce4a82bf902123295eb46da7b1c5f10594e7347686177687a62505f436f696e124d5a6347745151626567736347696a74525605060007e4414ae7f90379c21800e6302ff6ed0450adb5b2703afb1fb09ca217960bc092127356524b50474f5a71437542445a4f507632157458676c566762796241416f57514f4962706f4a31000771ca3d62766f01d128c5c221ca5b839beb5e40e2215e17f8bbd97a24cd1f297409694154737a614465550a4f44596548474c4e78320006060307665df07edd482ce5585a013e01950a843aa0b3fc086014c479135711be86bdca14587879425658796f4c47634261584a7042467531154e767a5948626154756450744d4e71455479484d31000210dabcec5834f1262f0505a13900382dc601f6b1d59c0292aec7c4d974cae7f9037df0eee3c5d7db7daa80af002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144403e2d3d3fd8f65dfdaaeb215e025307afa91956557164571b8a6e25f28e5f355bd2a2602ca0281d4f3b8e03dffe11715bfcc45eaa29b798019aad2d466b732202", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "0e8c46f21816b047fc8966bace7f541eef16a7a6bee6a0fd4a6e829cf0a321e6", - "sequence_number": "4659206246992072591", + "sender": "f74cc696f563eb567d57661870ceca4057ebfe0ff4ab5ccbd5b587bef850464b", + "sequence_number": "12939778027499514379", "payload": { "EntryFunction": { "module": { - "address": "0b24ff24b7d56f4f3e03fc4bca557cbfcc34c4db32463b14e57bd3b5fdb8fbef", - "name": "pDIL7_Coin" + "address": "2697ed4e7559b704bcea855595baefc98a860b8ecd03d0f279f7a04533aa7ff9", + "name": "AIfgtJXvSeXQNw3_Coin" }, - "function": "GwwcpiUSdRI", + "function": "VybeqOJMZMvwCbIWvLpSMjT6", "ty_args": [ - { - "vector": "address" - }, { "struct": { - "address": "a42ce4a82bf902123295eb46da7b1c5fe284e676dbc19864fb6861367625dc5b", - "module": "VaqFOGPiZMbOtpcJWxSfNPR5", - "name": "ollrNoqvRVis", + "address": "634a88493e07d254a007a9d9f82bbe21123b924a1518588841ce72133445f46a", + "module": "zDXHtjXZDoNbmQLBRcQvBgKzaeeVqw", + "name": "ObLtXGSuwLG7", "type_args": [] } }, + { + "vector": "u64" + }, { "struct": { - "address": "64dc905edc981194f03a87d27b9db31d0432ce426f5b50c33603b3bc01a10343", - "module": "KO", - "name": "WeoumtPoVZciPc", + "address": "546d1a4a380bb4bd852df88a79275aa094cef2cfff26679aa148575bd75356c7", + "module": "BiVaYcG", + "name": "PMNoOUUsldPXgN2", "type_args": [] } }, { - "vector": { - "struct": { - "address": "fc68aa66683d1586a08e8aabe01af983e4ae8a9bcbc2d6f79a178f76b386b873", - "module": "AMxqxdoPdjWgFcEbIvR", - "name": "mOhnTQOC", - "type_args": [] - } + "struct": { + "address": "6b4b12c36980549b8b46e3b0f34cd61e439cded59c20d933d00a0a655dbc85e3", + "module": "dMMpDZUILRXxwuqnlUK", + "name": "alseWDgdWooHzbZgJLHPwlnAMeILC", + "type_args": [] } }, { "struct": { - "address": "9fd18aa729dd01080d1c8b6b134b3d8e01391334d348aac8b125cc37cae95df6", - "module": "vhktgw", - "name": "MqHcFslclpfBUkRpKxUA7", + "address": "844341c568eafd1398263835b7e5ed30bca19b446f49c6e20bcd2a300afebcc1", + "module": "uAHwRiB", + "name": "OiqyNBqpZipwBVFTfmIdwLuh0", "type_args": [] } - } - ], - "args": [ - "00", - "c6", - "fc83e0e343c66479f9c4aa88a835d6d032554b375b7c634a88493e07d254a007", - "b8d16bbdfdaf16b5a4ad3da094530b4db3768cdbb120f45d2f0abd71e97401b8" - ] - } - }, - "max_gas_amount": "7118661719599132610", - "gas_unit_price": "16960348661650773191", - "expiration_timestamp_secs": "13928332283136587354", - "chain_id": 104 - }, - "signed_txn_bcs": "0e8c46f21816b047fc8966bace7f541eef16a7a6bee6a0fd4a6e829cf0a321e68f4f3e6765d3a840020b24ff24b7d56f4f3e03fc4bca557cbfcc34c4db32463b14e57bd3b5fdb8fbef0a7044494c375f436f696e0b477777637069555364524905060407a42ce4a82bf902123295eb46da7b1c5fe284e676dbc19864fb6861367625dc5b18566171464f4750695a4d624f7470634a577853664e5052350c6f6c6c724e6f717652566973000764dc905edc981194f03a87d27b9db31d0432ce426f5b50c33603b3bc01a10343024b4f0e57656f756d74506f565a63695063000607fc68aa66683d1586a08e8aabe01af983e4ae8a9bcbc2d6f79a178f76b386b87313414d787178646f50646a576746634562497652086d4f686e54514f4300079fd18aa729dd01080d1c8b6b134b3d8e01391334d348aac8b125cc37cae95df60676686b746777154d71486346736c636c706642556b52704b785541370004010001c620fc83e0e343c66479f9c4aa88a835d6d032554b375b7c634a88493e07d254a00720b8d16bbdfdaf16b5a4ad3da094530b4db3768cdbb120f45d2f0abd71e97401b8c2afe0201e91ca62c754777c3f435feb5a36f6816a604bc168002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440db6178975753b41f5b4dc279c84ab2da3f1105ce8dc8d4d04e480bb0405c85f4e728ed9ab1058ed046575ebefaea73dfb535c8025ae41975aa9f3791ee1b2809", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "fa1ce6f43517981fbd8ce9c94b4f2849b49e93cce01b1fa1c03ebce4708d25fd", - "sequence_number": "4866385425938600464", - "payload": { - "EntryFunction": { - "module": { - "address": "74f1b7cf04ddf45d2bd766981d4c318cd619259627801689ea55719f3b18d883", - "name": "aMFuHUPfAlNbdXOmBBaAoyq8_Coin" - }, - "function": "OhLzBZPpLpqo", - "ty_args": [ + }, { - "vector": { - "struct": { - "address": "df319d7fd6bc20202807cea26b4b12c36980549b8b46e3b0f34cd61e439cded5", - "module": "XkMpomRuBguJiWTpeQXccHge1", - "name": "ORKFDCP3", - "type_args": [] - } + "struct": { + "address": "effd65750ded7861b099f9417bb54921f93bc1688116515269361d8f41eaf246", + "module": "ARhEnTzFOYGVhJNlLvCTFndWbSNcFsp", + "name": "zVkUoniuGWoQjQIPUlRuXazivhqbhl0", + "type_args": [] } }, { "struct": { - "address": "8d213ab978276b6bb46ddc1790add8ba7c625bed6c6732614c246d737814eae8", - "module": "epvBQDHzZXzqhtFQhHJbbnzzCbQHIfZ", - "name": "gdSyqNWeuwLMakZlwfumB1", + "address": "56266aaa086556a9c9163c0e3a88153e94d606033cda298c113c8b275a493df5", + "module": "Gu", + "name": "cqJcMWWlBlytdOdVcJLKgqesI2", "type_args": [] } }, { "vector": { - "vector": "u8" + "vector": { + "struct": { + "address": "8340f78c68620cce098780878ae5d7129c937c0d79946646e4f44d9c91a23bda", + "module": "CqHZGiAEMegPJqDzvupMGPPt1", + "name": "HKDyRGOBqkGlSfGZ", + "type_args": [] + } + } } }, { "vector": { "struct": { - "address": "182116172a257903006b40325b662364e54857d58a3589807d08ed3e5a43fdb7", - "module": "NhAT8", - "name": "DWOsAElC0", + "address": "4874c01bffac1996c0112fb99371b39e8d624fdf767368547f86be4b8b4f9584", + "module": "HAITlHiF5", + "name": "LYqeaYhREWShwRJWRe4", "type_args": [] } } - }, - { - "vector": "u64" - }, - { - "vector": "address" } ], "args": [ - "8cadb4d640137ae1", - "48", - "7c624463c3815b2285d6cc549e1541259ee3b8c62013c48f20d2b19de28e47a3" + "406fcc13aa26d3d682ff9eb9adf9d2810efe49dde92fd5c6461e4c3367328b10", + "01", + "41", + "e0cafc4533a6c19ee9ec1d16898d61dd", + "bca988f3dd4689ab4a4d2ed11e676d1a340404dc24157327a6718c5386958dae", + "922e9354c23a7a4211a2565eeeb8353b", + "8d", + "8a4a6a3f8b937a63", + "ea" ] } }, - "max_gas_amount": "10256266921941942060", - "gas_unit_price": "5359926310300319652", - "expiration_timestamp_secs": "1687112809681852145", - "chain_id": 15 + "max_gas_amount": "1625582528020249607", + "gas_unit_price": "1971200951394293533", + "expiration_timestamp_secs": "2444651526185555232", + "chain_id": 22 }, - "signed_txn_bcs": "fa1ce6f43517981fbd8ce9c94b4f2849b49e93cce01b1fa1c03ebce4708d25fd105235fdc2df88430274f1b7cf04ddf45d2bd766981d4c318cd619259627801689ea55719f3b18d8831d614d467548555066416c4e6264584f6d424261416f7971385f436f696e0c4f684c7a425a50704c70716f060607df319d7fd6bc20202807cea26b4b12c36980549b8b46e3b0f34cd61e439cded519586b4d706f6d52754267754a69575470655158636348676531084f524b464443503300078d213ab978276b6bb46ddc1790add8ba7c625bed6c6732614c246d737814eae81f657076425144487a5a587a716874465168484a62626e7a7a4362514849665a1667645379714e576575774c4d616b5a6c7766756d4231000606010607182116172a257903006b40325b662364e54857d58a3589807d08ed3e5a43fdb7054e684154380944574f7341456c4330000602060403088cadb4d640137ae10148207c624463c3815b2285d6cc549e1541259ee3b8c62013c48f20d2b19de28e47a32c3ff0eb6c94558ea47fb8c39448624af116196529d469170f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444006ba78228b4d5a152834fbfdc5094acd59b7ae431486d49c263c4be4dae95654ee727d6a82ad63097e601af93bdf40df77fd99bd63bcb30288aa00b23a7d640f", + "signed_txn_bcs": "f74cc696f563eb567d57661870ceca4057ebfe0ff4ab5ccbd5b587bef850464b0b6a83e18e5393b3022697ed4e7559b704bcea855595baefc98a860b8ecd03d0f279f7a04533aa7ff91441496667744a5876536558514e77335f436f696e1856796265714f4a4d5a4d767743624957764c70534d6a54360907634a88493e07d254a007a9d9f82bbe21123b924a1518588841ce72133445f46a1e7a445848746a585a446f4e626d514c425263517642674b7a6165655671770c4f624c7458475375774c473700060207546d1a4a380bb4bd852df88a79275aa094cef2cfff26679aa148575bd75356c707426956615963470f504d4e6f4f5555736c645058674e3200076b4b12c36980549b8b46e3b0f34cd61e439cded59c20d933d00a0a655dbc85e313644d4d70445a55494c5258787775716e6c554b1d616c736557446764576f6f487a625a674a4c4850776c6e414d65494c430007844341c568eafd1398263835b7e5ed30bca19b446f49c6e20bcd2a300afebcc10775414877526942194f6971794e4271705a69707742564654666d4964774c7568300007effd65750ded7861b099f9417bb54921f93bc1688116515269361d8f41eaf2461f415268456e547a464f594756684a4e6c4c764354466e645762534e634673701f7a566b556f6e697547576f516a514950556c527558617a6976687162686c30000756266aaa086556a9c9163c0e3a88153e94d606033cda298c113c8b275a493df50247751a63714a634d57576c426c7974644f6456634a4c4b677165734932000606078340f78c68620cce098780878ae5d7129c937c0d79946646e4f44d9c91a23bda194371485a476941454d6567504a71447a7675704d475050743110484b447952474f42716b476c5366475a0006074874c01bffac1996c0112fb99371b39e8d624fdf767368547f86be4b8b4f958409484149546c48694635134c597165615968524557536877524a57526534000920406fcc13aa26d3d682ff9eb9adf9d2810efe49dde92fd5c6461e4c3367328b100101014110e0cafc4533a6c19ee9ec1d16898d61dd20bca988f3dd4689ab4a4d2ed11e676d1a340404dc24157327a6718c5386958dae10922e9354c23a7a4211a2565eeeb8353b018d088a4a6a3f8b937a6301ea077cba4fb23a8f161dd7c448d21c5b1b2015e8599c25ed2116002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440038213996f6ac6d9b8df80a8df590c054cf4498ce843bb3cf61a21c31ba4fa90a079dc2bfe9d2e021373a68ffc5ca4558bcf63d2c629c42f982d14fdbdb3530c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "82f68beed585f3951ed855c81c73a11452a1a5792ffabdfc0455f72e2292b91e", - "sequence_number": "3699824623779724405", + "sender": "71a17a1e5cfadfc3a89d87403d44af89a08304a7c53374b7ade00c31ad66cb31", + "sequence_number": "7875611597046967813", "payload": { "EntryFunction": { "module": { - "address": "43839e347b12334f9daadd9277a59eb1d993e013d64949cfa6130768ec9fb1e5", - "name": "xMRoCnSdGtiqwuAOpA6_Coin" + "address": "09b20c3be19714c3b2f0248aa551ae5b3ce70d9a1d1e34c0e27edbb919a0fadb", + "name": "sofWaXYWFHWoOxI8_Coin" }, - "function": "M1", + "function": "TQErrZJaLEJ", "ty_args": [ { "struct": { - "address": "b4bfae6ee033e9890abef9165941ee5eedfff8dff86c67f2797d022844a34970", - "module": "Fe", - "name": "WOWxMCWADjYQavJtJpAuwYTLfIIKCC", + "address": "58b64596a3800d58c66d9847a240666e7286feba5107e73bd1b89ae68f51aab0", + "module": "FOTQHsnNOBnVwONgAGxaFXDV", + "name": "PyglmsiCHCWiDEK2", "type_args": [] } }, { "vector": { - "vector": "bool" + "vector": "u8" } }, { - "vector": { - "vector": "signer" + "struct": { + "address": "4e265a636b07bdf8a9ba99dde48a8de36ae6b8718b3719dd10e44b77c7d04c33", + "module": "fVyncLOuGBSAQcGkRHdQgTt", + "name": "scjszwLIlsCxPWYGEM", + "type_args": [] + } + }, + { + "struct": { + "address": "c80c8f0130ae87f45404228ba8991d5c376417e21e0e8a59aff5d15a21134008", + "module": "oWWMZsjoFSJCBJgruEuoofalmLVicWix2", + "name": "mmiBbJaTTBqPcOkCf", + "type_args": [] } }, { "struct": { - "address": "789faa8795f6a412399941a62a50108d994f4ab0e91f6e2e39fdc4067c85f628", - "module": "RL", - "name": "AnfJkabAdyDoGoUGlUoeDmnEvN", + "address": "679be46377eabe7953210a122cd5ea4efe7ae87ed30908d872705191629a4a46", + "module": "p8", + "name": "cgPAteXloXjENywDY", "type_args": [] } }, { "vector": { "struct": { - "address": "8ac5c2cf1ef9a18ab095dc6fd51bb9f22d85a7beaad65999a0dcfe064ab99e57", - "module": "nIwTPAZjAqsjtdHSSFoKoeJpnTM6", - "name": "USSUYOWRbONvbDhqTqmLmDshMAH1", + "address": "74062fc5d7a8cc14858d26574079750f5982c234665439d0d5a7a18b5d88fb3c", + "module": "WmgQxbThhJlfEwCx8", + "name": "ExU", "type_args": [] } } }, { - "vector": { - "vector": "signer" + "struct": { + "address": "f956e94f8c8046facd52563dec88a1bcd5d912dba915e7f872a3dead61b1f7d2", + "module": "ZsduSSeXnZPoLeR", + "name": "LKP", + "type_args": [] } }, { "vector": { - "vector": { - "vector": "u128" - } + "vector": "address" } - }, - { - "vector": "u64" } ], "args": [ - "bd57e52673b0595a" + "01", + "01", + "1511671db1768e5eafff115bcb72ecdbcc90cb61682cd771035b8e43c88fcca8", + "69e45e0f0aa236b0642a91745c1f21ea", + "e2", + "ac" ] } }, - "max_gas_amount": "14496145507148609802", - "gas_unit_price": "17594285429741085772", - "expiration_timestamp_secs": "1644132714284548029", - "chain_id": 148 + "max_gas_amount": "14656695364758413523", + "gas_unit_price": "6834853282014549520", + "expiration_timestamp_secs": "11294346160195837226", + "chain_id": 126 }, - "signed_txn_bcs": "82f68beed585f3951ed855c81c73a11452a1a5792ffabdfc0455f72e2292b91e753ca28fe46a58330243839e347b12334f9daadd9277a59eb1d993e013d64949cfa6130768ec9fb1e518784d526f436e5364477469717775414f7041365f436f696e024d310807b4bfae6ee033e9890abef9165941ee5eedfff8dff86c67f2797d022844a349700246651e574f57784d435741446a595161764a744a7041757759544c6649494b43430006060006060507789faa8795f6a412399941a62a50108d994f4ab0e91f6e2e39fdc4067c85f62802524c1a416e664a6b6162416479446f476f55476c556f65446d6e45764e0006078ac5c2cf1ef9a18ab095dc6fd51bb9f22d85a7beaad65999a0dcfe064ab99e571c6e49775450415a6a4171736a7464485353466f4b6f654a706e544d361c55535355594f5752624f4e766244687154716d4c6d4473684d414831000606050606060306020108bd57e52673b0595a0ab9f7ed88a72cc94c648c3c61752bf4bd7f871efe21d11694002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e0a4e39c294f8472afec510aa24006fe7a0fcc7ebb026907c009f0f5a3eb7887b71b8be7a7af4a2915c43d76b10598565f925b5772a756f49d48ea0a5d7a140d", + "signed_txn_bcs": "71a17a1e5cfadfc3a89d87403d44af89a08304a7c53374b7ade00c31ad66cb31056eee4e05cb4b6d0209b20c3be19714c3b2f0248aa551ae5b3ce70d9a1d1e34c0e27edbb919a0fadb15736f6657615859574648576f4f7849385f436f696e0b54514572725a4a614c454a080758b64596a3800d58c66d9847a240666e7286feba5107e73bd1b89ae68f51aab018464f545148736e4e4f426e56774f4e674147786146584456105079676c6d7369434843576944454b3200060601074e265a636b07bdf8a9ba99dde48a8de36ae6b8718b3719dd10e44b77c7d04c33176656796e634c4f75474253415163476b524864516754741273636a737a774c496c73437850575947454d0007c80c8f0130ae87f45404228ba8991d5c376417e21e0e8a59aff5d15a21134008216f57574d5a736a6f46534a43424a67727545756f6f66616c6d4c56696357697832116d6d6942624a615454427150634f6b43660007679be46377eabe7953210a122cd5ea4efe7ae87ed30908d872705191629a4a4602703811636750417465586c6f586a454e7977445900060774062fc5d7a8cc14858d26574079750f5982c234665439d0d5a7a18b5d88fb3c11576d675178625468684a6c664577437838034578550007f956e94f8c8046facd52563dec88a1bcd5d912dba915e7f872a3dead61b1f7d20f5a736475535365586e5a506f4c6552034c4b50000606040601010101201511671db1768e5eafff115bcb72ecdbcc90cb61682cd771035b8e43c88fcca81069e45e0f0aa236b0642a91745c1f21ea01e201acd3208a9dc70a67cb10d663eed846da5e2a1dc520fe93bd9c7e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404c8f93f0a2dc5515a8c2c723229b552bcfeec1c38f103e96b5dc1d30edc010971dccd34d679d265f788967d2f01766901ca79a0af7a4127dd5b6499680915e0e", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "8aec5a01c06bfc2dea3c13a721b245ffe93ecd26683ee4ffa8d05f8555290398", - "sequence_number": "4394393999545566916", + "sender": "5dbe8a37c17ccc12f43ca8cf3bf0551253a2ddbba77a3560a954ab1eefe725e3", + "sequence_number": "2161835325662260676", "payload": { "EntryFunction": { "module": { - "address": "ece5054e435226d5ba459aef72b6eced040b4bd89acdadb03fed46c082c0e421", - "name": "nYrkQDvmZzZLBCYzJyqjnClcb_Coin" + "address": "6256bbdf7fa5e98e6f23453268da47335938d04789e68293b54cad5ec9de5a8f", + "name": "OLVGfncDAnkhf_Coin" }, - "function": "BcCVeTfLyDwBNaMgi6", + "function": "AhuIZAfRISvsUDOOThimucKISkfj2", "ty_args": [ { "struct": { - "address": "bd20690a645c2697e25616ac71a17a1e5cfadfc3a89d87403d44af89a08304a7", - "module": "I", - "name": "rDjINOGCAQWWZafskuzs", + "address": "152e229a5ae16c7207a4443cf0feefddb6ab3c2977254da443e1fefffc06985c", + "module": "VEhrgGoSb9", + "name": "bhWZEsRTqBSdmuCvmQFGcZzNZI6", "type_args": [] } }, { - "struct": { - "address": "c3f9c9ce38783261134b5aeb707342ecad2f6051db7ec8c763163336e75d6e69", - "module": "qSSUGPXd", - "name": "KHSaaImrYsotjdXoYZgudam", - "type_args": [] + "vector": { + "struct": { + "address": "91f4573de57880f8208829f278e24e54e49b156ca43a0b76b9da096cfb718808", + "module": "CNDtsgeWZQbHOOXPATkAMATYnO1", + "name": "UQE", + "type_args": [] + } } }, { "struct": { - "address": "1b938a8b177921148cce0be13e9463920c4168c08509db177b42c20664ba0370", - "module": "LCZOgQYHgAw", - "name": "cOsLlKAywsUKCTohnxk0", + "address": "88a7f9c0ae37118116cf48df5196335480988d155c080721df8bd54b2f19ffb0", + "module": "xKerUNXS", + "name": "RJSnFNClPASxGGfLFW6", "type_args": [] } }, { "vector": { "struct": { - "address": "16263889887c6f2f15fe34fdfa843221458380232428641307bc80e284435edd", - "module": "fWhjNogsC", - "name": "tRgWZIlmO1", + "address": "3ff051e25a75624af99c6fcfdeaaa1e24188d99eb703c0f206d6d30088d8f2f5", + "module": "cDfHj3", + "name": "F", "type_args": [] } } - } - ], - "args": [ - "00", - "e4b1bf90cb4398c77ca669cff392ca4eacff0224e27f7b0b7397abcdc8ec548c", - "d907d1d2acd14592458d742525e7cf807d3cf9613a95116bf374e4a93417c5ae" - ] - } - }, - "max_gas_amount": "15381588969336334073", - "gas_unit_price": "2170233801944397936", - "expiration_timestamp_secs": "9952888537206348761", - "chain_id": 96 - }, - "signed_txn_bcs": "8aec5a01c06bfc2dea3c13a721b245ffe93ecd26683ee4ffa8d05f8555290398c48605620f06fc3c02ece5054e435226d5ba459aef72b6eced040b4bd89acdadb03fed46c082c0e4211e6e59726b5144766d5a7a5a4c4243597a4a79716a6e436c63625f436f696e12426343566554664c794477424e614d6769360407bd20690a645c2697e25616ac71a17a1e5cfadfc3a89d87403d44af89a08304a701491472446a494e4f4743415157575a6166736b757a730007c3f9c9ce38783261134b5aeb707342ecad2f6051db7ec8c763163336e75d6e69087153535547505864174b48536161496d7259736f746a64586f595a677564616d00071b938a8b177921148cce0be13e9463920c4168c08509db177b42c20664ba03700b4c435a4f6751594867417714634f734c6c4b41797773554b43546f686e786b3000060716263889887c6f2f15fe34fdfa843221458380232428641307bc80e284435edd096657686a4e6f6773430a745267575a496c6d4f310003010020e4b1bf90cb4398c77ca669cff392ca4eacff0224e27f7b0b7397abcdc8ec548c20d907d1d2acd14592458d742525e7cf807d3cf9613a95116bf374e4a93417c5aef9e65b26ac6176d570f870fc24381e1ed9db3d5564c31f8a60002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405ce30beea39582eb14457ec8543bf93761249fe1af42f888bf7e34df1a1b1be27ccb6c955b5c6e48e0a957cf2ab3ea72c07488645280bf4e48997d8e59c79909", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "64da90f6c8598dadb27e34e076ccdfe8b2d71f75f3aa347b92b72e7647d50da3", - "sequence_number": "5652109983803950991", - "payload": { - "EntryFunction": { - "module": { - "address": "d4b8f164c25219d4c330ccd9bd151dae451e43182223b2bf150dd9d8b220f611", - "name": "mHqisOEzXnroyYn_Coin" - }, - "function": "PoO", - "ty_args": [ + }, + { + "struct": { + "address": "02d2e5d321f64908cf85dd81ca97642eb87aeb98a0f6a945af56cf3892a3c8f6", + "module": "fdsCJAeVonImP7", + "name": "vOBpvjWdjquEJHErIJMByHyXdS", + "type_args": [] + } + }, + { + "struct": { + "address": "613a95116bf374e4a93417c5ae8aec5a01c06bfc2dea3c13a721b245ffe93ecd", + "module": "TXIVTGDiC3", + "name": "sLXayWTLmkNpLxxYYJ4", + "type_args": [] + } + }, { "struct": { - "address": "b63082ad56568e064f491c00792a1c0efca62e9f5317231c4b8e421988876fd3", - "module": "fHRQOOanOSaqGToGFHdiU8", - "name": "raQdxzyXufAeYOxwUO3", + "address": "bf8d16934b196a585be09e4577508b0f17fe6333b68701fca51672b9c2c6b6f4", + "module": "bDKhgfXyy", + "name": "CvIgPeVlfmWikXoVOi4", "type_args": [] } }, { "struct": { - "address": "c37f648cde3ca9c0c63e60cf217436c4c87e31168baeff89669aadcaf46c2352", - "module": "VvVJQdyGBWQVsaEycenBBOjH1", - "name": "IcceBWMVSttbMQdeUXKYcoVcfyTPuC3", + "address": "831b45445ebee9446778e3b6d6afd89e3af4b4e5f4dd52b65416b41683241d2e", + "module": "BqchvuxOfiyparRfflL", + "name": "uRbkVjGeMgUXMSkbBXCKCWd", "type_args": [] } }, { "vector": { - "struct": { - "address": "6fb5721acbb475a4be0bd807be5d4f53c5a71e6403c714e8c7d502fb7c8a6cdd", - "module": "zieFoaoAFPbffeKeFvltgmlWMum", - "name": "hdlvxlSBmMicBzVDvmLfGyGaprmiewm", - "type_args": [] + "vector": { + "vector": "bool" } } } ], "args": [ - "5f4c02ab3c37be6a4112467350995026900bf36ffb87a8c723895102f6123b25", - "54f0c269c845adb3", - "0c1aadfd46f94aab0ae79d2dcf543ab4" + "01" ] } }, - "max_gas_amount": "5189893107018236590", - "gas_unit_price": "6000570407352201126", - "expiration_timestamp_secs": "480398375468096016", - "chain_id": 119 + "max_gas_amount": "11192853545400697713", + "gas_unit_price": "6518750766354711059", + "expiration_timestamp_secs": "4505624551975296546", + "chain_id": 79 }, - "signed_txn_bcs": "64da90f6c8598dadb27e34e076ccdfe8b2d71f75f3aa347b92b72e7647d50da38fc712881554704e02d4b8f164c25219d4c330ccd9bd151dae451e43182223b2bf150dd9d8b220f611146d487169734f457a586e726f79596e5f436f696e03506f4f0307b63082ad56568e064f491c00792a1c0efca62e9f5317231c4b8e421988876fd316664852514f4f616e4f53617147546f474648646955381372615164787a795875664165594f7877554f330007c37f648cde3ca9c0c63e60cf217436c4c87e31168baeff89669aadcaf46c2352195676564a51647947425751567361457963656e42424f6a48311f4963636542574d56537474624d51646555584b59636f5663667954507543330006076fb5721acbb475a4be0bd807be5d4f53c5a71e6403c714e8c7d502fb7c8a6cdd1b7a6965466f616f414650626666654b6546766c74676d6c574d756d1f68646c76786c53426d4d6963427a5644766d4c664779476170726d6965776d0003205f4c02ab3c37be6a4112467350995026900bf36ffb87a8c723895102f6123b250854f0c269c845adb3100c1aadfd46f94aab0ae79d2dcf543ab4ae02129a48340648a6eff23bfe4e4653105a73f8c6b7aa0677002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444045747c032b586818a7e6bd104770ac63b00d052fce9876b674b18677ae07ba896ccc4b7df20596cd2e3d0062fb718eded96bf46253102ab9e455ba2ee7448402", + "signed_txn_bcs": "5dbe8a37c17ccc12f43ca8cf3bf0551253a2ddbba77a3560a954ab1eefe725e3c46dfd58c661001e026256bbdf7fa5e98e6f23453268da47335938d04789e68293b54cad5ec9de5a8f124f4c5647666e6344416e6b68665f436f696e1d416875495a4166524953767355444f4f5468696d75634b49536b666a320907152e229a5ae16c7207a4443cf0feefddb6ab3c2977254da443e1fefffc06985c0a5645687267476f5362391b6268575a45735254714253646d7543766d514647635a7a4e5a493600060791f4573de57880f8208829f278e24e54e49b156ca43a0b76b9da096cfb7188081b434e4474736765575a5162484f4f585041546b414d4154596e4f3103555145000788a7f9c0ae37118116cf48df5196335480988d155c080721df8bd54b2f19ffb008784b6572554e585313524a536e464e436c504153784747664c4657360006073ff051e25a75624af99c6fcfdeaaa1e24188d99eb703c0f206d6d30088d8f2f506634466486a330146000702d2e5d321f64908cf85dd81ca97642eb87aeb98a0f6a945af56cf3892a3c8f60e666473434a4165566f6e496d50371a764f4270766a57646a7175454a484572494a4d427948795864530007613a95116bf374e4a93417c5ae8aec5a01c06bfc2dea3c13a721b245ffe93ecd0a5458495654474469433313734c58617957544c6d6b4e704c787859594a340007bf8d16934b196a585be09e4577508b0f17fe6333b68701fca51672b9c2c6b6f40962444b68676658797913437649675065566c666d57696b586f564f69340007831b45445ebee9446778e3b6d6afd89e3af4b4e5f4dd52b65416b41683241d2e13427163687675784f6669797061725266666c4c177552626b566a47654d6755584d536b624258434b43576400060606000101017183944cff00559b13c2e0bf4841775a221ec47fa831873e4f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440cc729329281c643b5cbef719335e66e0fd620b07add27ad418a94105e839557ae1765a95c58981587d4cdcb0aaa703181a058d0bc6d9a4b7520728c075300e05", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "e850e0c7ec5e50756af7f0cf20f9e0cc734999fa0fba10540e036903087d53c8", - "sequence_number": "17995524261789320622", + "sender": "dc44f42ff37dfbc017d673a65110c206933e31c7f7ca8e1832275ae24ebc9d69", + "sequence_number": "1568570467573419337", "payload": { "EntryFunction": { "module": { - "address": "813babcf3cb7e5e8be96f3fb7a9006df4d309176fdc49440c1287396ff06f45b", - "name": "hsdxPAtVUctkMWKhaUHaEdxJEf_Coin" + "address": "9a8cc18eb3c6e8b0b571178dcc2387cd5913c6413cc010c4e5d22965f19d9845", + "name": "IvTceBoWMdzDSWXk_Coin" }, - "function": "GyxIUcfIDyKwpPb", + "function": "bYFMobdberuKDHycYAlc", "ty_args": [ { "vector": { - "vector": "u128" + "vector": { + "struct": { + "address": "fadcf792cbce96f3a3af338607450e2fe51c774179fbe5afd97ae22fc610f806", + "module": "EYjAdsNnVSiQxOWlaZ2", + "name": "lCodJaBnofJQPfmKBBvZFgxmtIN9", + "type_args": [] + } + } } }, { "struct": { - "address": "8485de37fe833437cb402099f38fac789155918f0819fd4a685b19a0a0be018b", - "module": "fDi7", - "name": "AfYQUrmYkWLZuFlOAZFSldHQcGmhbwr6", + "address": "2cdf5572e6b1fc494581f79b8267ac8cdfeee3bf7140d577d03e515f900a62bd", + "module": "GXy7", + "name": "wOovJFavsQeLchTDxfVHpHhpj8", "type_args": [] } }, { "vector": { "struct": { - "address": "9f0f514bb2ae3f29833f2398c2d82bfe4c13f5f2ff554ca2a6944539192670e7", - "module": "NN", - "name": "pp4", + "address": "2461bfd3b9250539f5a4aed624919a804dc7c84a389b798659237d436914b698", + "module": "AAOFTJoNefcPJPkMNloF6", + "name": "FkTFareNkjigANYQsTUSOITDeHNPr", "type_args": [] } } }, { "struct": { - "address": "94f7f3198ebd3847f9669158e3f785f9b2f341a12ad486edf94c7e22b13c7697", - "module": "RbyAHfmFJWFPjrFxjCqa4", - "name": "yYBuSTAZRpERwahslPuCi", + "address": "b0450561dfbc2444c4247ea7eafce61705a2fb1b7c12e342e929e4ac6bae35ae", + "module": "FXUyxxyAXGkdwCFEvHmUeMozKjYYhOXR3", + "name": "wCOLxkWIDWYMmm", "type_args": [] } - } - ], - "args": [ - "09ef47e57c9f71030ec4cdf24b169384b54191d82070318da0c085de876ebb39", - "edaabf13bfa35ab3e17c30f22f05ee15", - "00", - "856894ebb2d6cc44e2141d268a7c651b" - ] - } - }, - "max_gas_amount": "10050040562277102782", - "gas_unit_price": "13321142185640067551", - "expiration_timestamp_secs": "8684857236114279010", - "chain_id": 61 - }, - "signed_txn_bcs": "e850e0c7ec5e50756af7f0cf20f9e0cc734999fa0fba10540e036903087d53c8ae45e0c2f8f1bcf902813babcf3cb7e5e8be96f3fb7a9006df4d309176fdc49440c1287396ff06f45b1f68736478504174565563746b4d574b68615548614564784a45665f436f696e0f477978495563664944794b7770506204060603078485de37fe833437cb402099f38fac789155918f0819fd4a685b19a0a0be018b0466446937204166595155726d596b574c5a75466c4f415a46536c64485163476d68627772360006079f0f514bb2ae3f29833f2398c2d82bfe4c13f5f2ff554ca2a6944539192670e7024e4e03707034000794f7f3198ebd3847f9669158e3f785f9b2f341a12ad486edf94c7e22b13c7697155262794148666d464a5746506a7246786a4371613415795942755354415a52704552776168736c5075436900042009ef47e57c9f71030ec4cdf24b169384b54191d82070318da0c085de876ebb3910edaabf13bfa35ab3e17c30f22f05ee15010010856894ebb2d6cc44e2141d268a7c651bbe34cbdca4ea788bdf018c493d34deb8628a9253a4cf86783d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144407e5ae9dbe24991ff6b9be7a55336400a75326fcb29774480fa876ab5ce4788799f3bfd02ed1d805e767d1673546969af42c0537c8267cd3fa8e5f395065edf0a", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "42af3ae1d0f0c5a572dbd55d4f8da36f623aad23306d1ae0ee44d7cc254212f7", - "sequence_number": "2455683739375654353", - "payload": { - "EntryFunction": { - "module": { - "address": "08248baf8e4872c8a32d96c6af4eb6bd5859ab2f152de3afc081cc18ee203d67", - "name": "LmtBuqJj8_Coin" - }, - "function": "OAIxQOhHqfCMcBCIvhClODVKSMuxQ", - "ty_args": [ + }, + { + "struct": { + "address": "a759ff6f19e41aeaa5f8923a4cb89003faca836f2b452ff0521edbf63a2c034b", + "module": "HDOSzNDhbjRwY9", + "name": "eZRgtnzVbMajutyB6", + "type_args": [] + } + }, + { + "struct": { + "address": "34d2ade043b09c8f18639f3570740938962b6e85530c8c9f0d7a75eafa1f91ec", + "module": "wwXcfyFoKGJisZzbPejABRdpb6", + "name": "pXwmVQztiPgtXN", + "type_args": [] + } + }, { "struct": { - "address": "bc946e2d27fa14fdc2a422e075027885b9be806599b0bef97dedc23022df5007", - "module": "QdEWV", - "name": "CekXCkZGOsPZo", + "address": "dd286edab4957f3cbf2d1c6bce48d25bafd03c8ca0d4b83c9a9182607ce089e0", + "module": "UdpLvMonqdASLStwymxMasQeALMwdtyZ9", + "name": "XmmjwATcqVcsDlYfbOfXyHiIGfWF", "type_args": [] } }, + { + "vector": { + "vector": "bool" + } + }, { "struct": { - "address": "d41e960f57ffe1ee3bdabeaf1f74928855d82ac22bddfe1c6710101e79702b4a", - "module": "UmanGyW", - "name": "XGTAZiwPFCweKpX", + "address": "cb06141c3566a09f5130a915c441516f2414d8013814bc781c5b969cce8fa391", + "module": "pevKUyRkLCtvbrXNtp7", + "name": "sDwqkIZfnDGKzd5", "type_args": [] } + }, + { + "vector": { + "struct": { + "address": "84b54191d82070318da0c085de876ebb397d39fe33ac3ddd6c3aa64b61a589f9", + "module": "YUQ8", + "name": "dJyDmydYHqiSVIrMVgZNHr", + "type_args": [] + } + } } ], - "args": [ - "67", - "16152096c4c69876", - "08f8b519c1e5922a768b1f14f0e77e65ab55da07fa245dc2ba71a5f78a02e3fa", - "62902f67ce645fb2458b1f45d5ad2391400659b1b42348b26a24bc2777c3c994", - "00", - "ee", - "0e", - "1e", - "df427704e350b4c555e03e2648bfe96a", - "01" - ] + "args": [] } }, - "max_gas_amount": "6025768940618406886", - "gas_unit_price": "11232156725308974974", - "expiration_timestamp_secs": "3118786794130706781", - "chain_id": 77 + "max_gas_amount": "12680044471583224156", + "gas_unit_price": "6330145959402166020", + "expiration_timestamp_secs": "5966256172242054543", + "chain_id": 64 }, - "signed_txn_bcs": "42af3ae1d0f0c5a572dbd55d4f8da36f623aad23306d1ae0ee44d7cc254212f7d15530a6595714220208248baf8e4872c8a32d96c6af4eb6bd5859ab2f152de3afc081cc18ee203d670e4c6d744275714a6a385f436f696e1d4f414978514f68487166434d634243497668436c4f44564b534d7578510207bc946e2d27fa14fdc2a422e075027885b9be806599b0bef97dedc23022df50070551644557560d43656b58436b5a474f73505a6f0007d41e960f57ffe1ee3bdabeaf1f74928855d82ac22bddfe1c6710101e79702b4a07556d616e4779570f584754415a697750464377654b7058000a01670816152096c4c698762008f8b519c1e5922a768b1f14f0e77e65ab55da07fa245dc2ba71a5f78a02e3fa2062902f67ce645fb2458b1f45d5ad2391400659b1b42348b26a24bc2777c3c994010001ee010e011e10df427704e350b4c555e03e2648bfe96a0101e65b24f4ecd49f537e678ef907a3e09b5d1157b21028482b4d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bbe8b40ba2bb4b1b785105776c9ec49278552da8c85a84db7b20f02e7350f3145d069912f6ffbb4acb1dd8bccd33dbd5803f4e3c93276dd7dfe4cdb1a7dc3b0e", + "signed_txn_bcs": "dc44f42ff37dfbc017d673a65110c206933e31c7f7ca8e1832275ae24ebc9d6949cde19487aec415029a8cc18eb3c6e8b0b571178dcc2387cd5913c6413cc010c4e5d22965f19d9845154976546365426f574d647a445357586b5f436f696e146259464d6f6264626572754b4448796359416c630a060607fadcf792cbce96f3a3af338607450e2fe51c774179fbe5afd97ae22fc610f8061345596a4164734e6e56536951784f576c615a321c6c436f644a61426e6f664a5150666d4b4242765a4667786d74494e3900072cdf5572e6b1fc494581f79b8267ac8cdfeee3bf7140d577d03e515f900a62bd04475879371a774f6f764a4661767351654c6368544478665648704868706a380006072461bfd3b9250539f5a4aed624919a804dc7c84a389b798659237d436914b6981541414f46544a6f4e656663504a506b4d4e6c6f46361d466b54466172654e6b6a6967414e5951735455534f49544465484e50720007b0450561dfbc2444c4247ea7eafce61705a2fb1b7c12e342e929e4ac6bae35ae21465855797878794158476b647743464576486d55654d6f7a4b6a5959684f5852330e77434f4c786b57494457594d6d6d0007a759ff6f19e41aeaa5f8923a4cb89003faca836f2b452ff0521edbf63a2c034b0e48444f537a4e4468626a5277593911655a5267746e7a56624d616a7574794236000734d2ade043b09c8f18639f3570740938962b6e85530c8c9f0d7a75eafa1f91ec1a777758636679466f4b474a69735a7a6250656a414252647062360e7058776d56517a7469506774584e0007dd286edab4957f3cbf2d1c6bce48d25bafd03c8ca0d4b83c9a9182607ce089e0215564704c764d6f6e716441534c537477796d784d61735165414c4d776474795a391c586d6d6a7741546371566373446c5966624f665879486949476657460006060007cb06141c3566a09f5130a915c441516f2414d8013814bc781c5b969cce8fa391137065764b5579526b4c4374766272584e7470370f734477716b495a666e44474b7a643500060784b54191d82070318da0c085de876ebb397d39fe33ac3ddd6c3aa64b61a589f9045955513816644a79446d796459487169535649724d56675a4e487200005cb1dfe04391f8af04578a263632d9578f2d78c96066cc5240002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d94cc6d550f2001a4bdba34903589304cb935145af4fef8ec5cde096c3f5974f308a5c09e693f117f988cf6bb52d7647bd3a0f24cddeea6076c090ebeb7ef70b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "fd71525306985c0c5d8496c874d5a725c58d8931e051124b4d0ad9dcd6c8d490", - "sequence_number": "7354507105233684228", + "sender": "b1abeb725fedba093a9e93e27359b4f261ed80425119b89779832de91be9c4c8", + "sequence_number": "8844391917843465996", "payload": { "EntryFunction": { "module": { - "address": "a69b372f465df051ef898beffcf15052127122960ab3eb7c22046af41ac116aa", - "name": "o_Coin" + "address": "c629ff44b5780e3414a2094e545ed162523c42376004f70d0c3266978c30eea8", + "name": "UgCykPx_Coin" }, - "function": "fdVNfpspjmtsecymyoCEkrdUGcXW", + "function": "TzoxSueBAGO", "ty_args": [ { "struct": { - "address": "67b8ba5bc4f9adc50ba4e90fa1cd769043eb84cce297e4cceb9ebb9d523a6aff", - "module": "jy2", - "name": "uLmiDfntnPLyYhGzqWgAMCpW", + "address": "ed57a7e86d17d37f44962fdfb25047e8da7e04f5cc1d7e30ae9d3317c7ac8cd8", + "module": "f", + "name": "GPgkHRfACefWcIbnaPJI4", + "type_args": [] + } + }, + { + "struct": { + "address": "5b9209eb432da7563934bfa4400a24b876230302c169487fa9e864905af8f9a2", + "module": "WqFPz4", + "name": "RUnEGa7", "type_args": [] } }, { "vector": { - "struct": { - "address": "a19ba06ced1d2b29f125d3dea286693d9d33adcd5d7d52bd15a3090a0080d30e", - "module": "MbbySfJcukGfVFJxqVdS", - "name": "exxigysiUrlIlsrwUdQYZdkFiZyHjze", - "type_args": [] + "vector": "u8" + } + }, + { + "vector": { + "vector": { + "struct": { + "address": "960f57ffe1ee3bdabeaf1f74928855d82ac22bddfe1c6710101e79702b4a24f9", + "module": "jCOfkisDFYGls3", + "name": "RNgDcngIJlYQOL", + "type_args": [] + } } } }, { - "struct": { - "address": "6454333b5ffca7416312e8701aeca7a7c434475e87effa7803de00fec92afd98", - "module": "PdPSwiEKUbjjvdHsxTHbfJm6", - "name": "IULgOEnWvoYyHWLHtvOZkAVwkKHbuBYC", - "type_args": [] + "vector": { + "struct": { + "address": "61b6f097e18f0a62b37f75c1c9b96dc7709f5e5ec3feabc1ee1de1029e03b4ea", + "module": "JQREpcWFleOBGBQYYktDczwTswaFnQ3", + "name": "tEMEGzcmCGREmAELIWbYDdrkgHYI", + "type_args": [] + } } }, { - "struct": { - "address": "7268c644159ed1ba9fd20a53228405d4ee7d28cf9698ebd7e0360d2108362361", - "module": "kiMaFXUxPX1", - "name": "dpBnFAcfyZbWhTbzrt", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "fb2f927ea536d51be87cdfe35548612ae2e52b8e606750eff79ddaa364607917", + "module": "qHnuuGXoJ8", + "name": "ZCHct7", + "type_args": [] + } + } } }, { "vector": { - "vector": "signer" + "struct": { + "address": "8f74cb73a43a927e0d020c5deef599b95c99809bd4c950b42c5b817dd07cf0ad", + "module": "YGFixkKLEgFJwchyffmWYZW", + "name": "iFMdFSwrYrfD", + "type_args": [] + } } } ], "args": [ + "00", + "43cb9adb55c5637472c542a4b6293df6", + "9c6cb733acf034d1", + "a2a34dfc9e1372bb9fd14d87543da8d0", + "7c", "01", - "301c38c9bfafa36d09aece7a498d406b", - "4b6fa5b50b8b8d4db0813b0bc72e8fc1604810ccb12493e3e6bb74b84c86c884", - "7d3363649a7f186a233b21df5acce645e53b1ecb706de84c6b4cf3b2f826a3fd", - "9083a6d838e234ac", - "7f2c22bf836a41552c4dfdff9f0bc7a7b3e55ae4162025192e5e29b75bac4611", - "28", - "222d126313f5bc5e", - "5fdb8ac25668f992b4df0d46b9e7839aea4cf3551bc51e83c38d2ae1179c3473", - "73a9113ec7f58cbb876fef394b5a78ae38b1a7b5f9f9a302c4426bca1b22cb02" + "01" ] } }, - "max_gas_amount": "9191068898117423521", - "gas_unit_price": "10472524769623398718", - "expiration_timestamp_secs": "18240895821559382570", - "chain_id": 138 + "max_gas_amount": "12377412770658682390", + "gas_unit_price": "13855668859741411736", + "expiration_timestamp_secs": "7115958003360343245", + "chain_id": 135 }, - "signed_txn_bcs": "fd71525306985c0c5d8496c874d5a725c58d8931e051124b4d0ad9dcd6c8d49004478a113f75106602a69b372f465df051ef898beffcf15052127122960ab3eb7c22046af41ac116aa066f5f436f696e1c6664564e667073706a6d74736563796d796f43456b72645547635857050767b8ba5bc4f9adc50ba4e90fa1cd769043eb84cce297e4cceb9ebb9d523a6aff036a793218754c6d6944666e746e504c795968477a715767414d437057000607a19ba06ced1d2b29f125d3dea286693d9d33adcd5d7d52bd15a3090a0080d30e144d62627953664a63756b476656464a78715664531f657878696779736955726c496c737277556451595a646b46695a79486a7a6500076454333b5ffca7416312e8701aeca7a7c434475e87effa7803de00fec92afd9818506450537769454b55626a6a7664487378544862664a6d362049554c674f456e57766f597948574c4874764f5a6b4156776b4b48627542594300077268c644159ed1ba9fd20a53228405d4ee7d28cf9698ebd7e0360d21083623610b6b694d6146585578505831126470426e46416366795a62576854627a7274000606050a010110301c38c9bfafa36d09aece7a498d406b204b6fa5b50b8b8d4db0813b0bc72e8fc1604810ccb12493e3e6bb74b84c86c884207d3363649a7f186a233b21df5acce645e53b1ecb706de84c6b4cf3b2f826a3fd089083a6d838e234ac207f2c22bf836a41552c4dfdff9f0bc7a7b3e55ae4162025192e5e29b75bac4611012808222d126313f5bc5e205fdb8ac25668f992b4df0d46b9e7839aea4cf3551bc51e83c38d2ae1179c34732073a9113ec7f58cbb876fef394b5a78ae38b1a7b5f9f9a302c4426bca1b22cb02a1116e6a773c8d7f3ed9e1cacae155912a42f4f41aae24fd8a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440144f6e1e114e7bad87a2f52f09a5d1d8ea1e7e707eef843810f7028f112f1517338fd79595541469b0a73db94d01e208f2caff7b45689ec9ca2e74c329400708", + "signed_txn_bcs": "b1abeb725fedba093a9e93e27359b4f261ed80425119b89779832de91be9c4c80c4765f59697bd7a02c629ff44b5780e3414a2094e545ed162523c42376004f70d0c3266978c30eea80c556743796b50785f436f696e0b547a6f785375654241474f0707ed57a7e86d17d37f44962fdfb25047e8da7e04f5cc1d7e30ae9d3317c7ac8cd80166154750676b48526641436566576349626e61504a493400075b9209eb432da7563934bfa4400a24b876230302c169487fa9e864905af8f9a206577146507a340752556e4547613700060601060607960f57ffe1ee3bdabeaf1f74928855d82ac22bddfe1c6710101e79702b4a24f90e6a434f666b6973444659476c73330e524e6744636e67494a6c59514f4c00060761b6f097e18f0a62b37f75c1c9b96dc7709f5e5ec3feabc1ee1de1029e03b4ea1f4a515245706357466c654f4247425159596b7444637a7754737761466e51331c74454d45477a636d434752456d41454c495762594464726b6748594900060607fb2f927ea536d51be87cdfe35548612ae2e52b8e606750eff79ddaa3646079170a71486e757547586f4a38065a43486374370006078f74cb73a43a927e0d020c5deef599b95c99809bd4c950b42c5b817dd07cf0ad1759474669786b4b4c4567464a7763687966666d57595a570c69464d644653777259726644000701001043cb9adb55c5637472c542a4b6293df6089c6cb733acf034d110a2a34dfc9e1372bb9fd14d87543da8d0017c0101010116867e295667c5ab981954de6a3949c0cd24e4221af6c06287002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440180c8421f7bb7f4e86404feef8461f60c2c318e45ed25875689cb48e28a56249319b57e192b287dc29a82fa70e40df227f388c0ee5a056a3c102751b62b13405", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "7f37cdf924047a7d833f04cc52b5ee0981c16fb49031121133c96730b6830b6d", - "sequence_number": "18029546327269471879", + "sender": "9135eb9b0290386e71bb37f25e188e99ac39f422f2e57baef5a5c4079dc5b103", + "sequence_number": "5025910601440530849", "payload": { "EntryFunction": { "module": { - "address": "aaca7e3c0d796b41b2d0adbe0a2a3345f3d04518b1537b19c66325c7d13edcbc", - "name": "kLhgrDgcfvDjGwYEujBpgLXesRO6_Coin" + "address": "b80e41b764b193bd4646a19ba06ced1d2b29f125d3dea286693d9d33adcd5d7d", + "name": "xplv_Coin" }, - "function": "FnZxUivYyLTckvWSFkReOgbUtcTWjkN", + "function": "UlCrSOy", "ty_args": [ { "struct": { - "address": "22a90a126d58504682bc5c95880a530853d24213f29dbf3fcb2bd597123262ed", - "module": "ABabled", - "name": "SDaKIskFTGrsZleVv1", + "address": "4510c51dbb4b340705b24b170ddf074dd5a2def30b80b88890a5e1a10fdc3ba6", + "module": "QAYoCccSTjHkqIsqkVtaJYbr2", + "name": "gmEiwUJUSKQadMhe3", "type_args": [] } }, @@ -2148,669 +2727,643 @@ } }, { - "struct": { - "address": "1e742aa26e4fc8f10fd9c011c5091991d753ce64f433b61773ff6bd08bb96930", - "module": "AJBvqCPLzgvmvcrRZMOCbvcFqxURxYh", - "name": "oIuwAn9", - "type_args": [] + "vector": { + "vector": "bool" } }, { "vector": { - "vector": "address" + "struct": { + "address": "a458eaa84cc66c179d4023b0fafd28d2be494985d1f694a818c257269086e72e", + "module": "AVVzvZHT", + "name": "YqyszyizbuUSTUBEJFiu", + "type_args": [] + } } }, { "vector": { - "vector": { - "vector": "address" + "struct": { + "address": "6c6209b1fd1ed4c0c0ba5ca6ab8acf84ec8d3f62ad4bbeabd6546d9010f97623", + "module": "CHGzalxcTHSDmoUwIhBDKb", + "name": "orHNwUezGMqzQxvxqmxzXZJssKBVgBFH", + "type_args": [] } } }, + { + "vector": { + "vector": "u64" + } + }, + { + "vector": { + "vector": "u8" + } + }, { "struct": { - "address": "3ee5e172ea0b54f333780d1f96cdca7bb9649a79b5115c24fa00fbfab4246f71", - "module": "HocOtMVjuId", - "name": "e", + "address": "2259e756daf15551e69c5fe80f9cf37c55747bb1c792cb59087b232e191e4057", + "module": "sZqctKbufgZgHtRZlLxMtdGjDmoIibw0", + "name": "MgX", "type_args": [] } } ], - "args": [] + "args": [ + "fc", + "01", + "48f61da910a30dc1", + "24", + "e6", + "00", + "00" + ] } }, - "max_gas_amount": "2807864525545556098", - "gas_unit_price": "8074205226668089558", - "expiration_timestamp_secs": "6474922013705849302", - "chain_id": 203 + "max_gas_amount": "197618437163433449", + "gas_unit_price": "2919865573578330141", + "expiration_timestamp_secs": "10285813321112450341", + "chain_id": 77 }, - "signed_txn_bcs": "7f37cdf924047a7d833f04cc52b5ee0981c16fb49031121133c96730b6830b6d8776582adcd035fa02aaca7e3c0d796b41b2d0adbe0a2a3345f3d04518b1537b19c66325c7d13edcbc216b4c6867724467636676446a47775945756a4270674c586573524f365f436f696e1f466e5a7855697659794c54636b765753466b52654f676255746354576a6b4e060722a90a126d58504682bc5c95880a530853d24213f29dbf3fcb2bd597123262ed07414261626c6564125344614b49736b46544772735a6c655676310006060603071e742aa26e4fc8f10fd9c011c5091991d753ce64f433b61773ff6bd08bb969301f414a42767143504c7a67766d766372525a4d4f436276634671785552785968076f497577416e390006060406060604073ee5e172ea0b54f333780d1f96cdca7bb9649a79b5115c24fa00fbfab4246f710b486f634f744d566a75496401650000824890c6e889f726d66027ebdf560d70d6494b0f448bdb59cb002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440cca6cef1b8bc521eb1741308f37503e143ffbfaca070be9c9f5cdef1c5a369240417c3ffb52063d72e2c1cd053924037850017dbb491299cfe95b19a0539b900", + "signed_txn_bcs": "9135eb9b0290386e71bb37f25e188e99ac39f422f2e57baef5a5c4079dc5b103a191bb47109fbf4502b80e41b764b193bd4646a19ba06ced1d2b29f125d3dea286693d9d33adcd5d7d0978706c765f436f696e07556c4372534f7908074510c51dbb4b340705b24b170ddf074dd5a2def30b80b88890a5e1a10fdc3ba6195141596f43636353546a486b714973716b5674614a5962723211676d456977554a55534b5161644d68653300060606030606000607a458eaa84cc66c179d4023b0fafd28d2be494985d1f694a818c257269086e72e084156567a765a485414597179737a79697a62755553545542454a4669750006076c6209b1fd1ed4c0c0ba5ca6ab8acf84ec8d3f62ad4bbeabd6546d9010f97623164348477a616c7863544853446d6f5577496842444b62206f72484e7755657a474d717a51787678716d787a585a4a73734b42566742464800060602060601072259e756daf15551e69c5fe80f9cf37c55747bb1c792cb59087b232e191e405720735a7163744b627566675a674874525a6c4c784d7464476a446d6f4969627730034d6758000701fc01010848f61da910a30dc1012401e601000100e9bd31eceb14be021d5007e1447285282575e30eb88cbe8e4d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d7c777a5b03789af313b56232829160ed7cf1f0afe4a86cdf79b8c653c13e6ed7c5f47c5b4f1ec1a1a064b100a8a310a16c96227059c8244242f95d5e969c80d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "a12d6e5a1247574e2b4497195d8b3c5c1c5333728455360bd13544e96b84e317", - "sequence_number": "18060385885481239920", + "sender": "34d2b7f24ed8ba6d2a28288f309f612fbdf9cdfd803a7f0da20361f7b25a9409", + "sequence_number": "452007691087670478", "payload": { "EntryFunction": { "module": { - "address": "e6e578e1ee5b39d65a00c660a5cb3cb56ae5c8308297d1fb8da4872f45d4cad5", - "name": "RLDmy4_Coin" + "address": "0361d71267ba41799be42dbc53922711e9c1bdc3e7ed631ccf8bde2c1cc9f01d", + "name": "fjiAZqOCdfwqBZSOGmjdK8_Coin" }, - "function": "XY5", + "function": "kVxRASONwzKdagKCwgdSCOCOnCyaRJ", "ty_args": [ { "struct": { - "address": "773460e5ae3e4237a0f6416665a24a83d515db2d4b5f314dbd43fcdd6c0cc17f", - "module": "JYkMSJBeJaEndfYEyhVkHYyQCKdE9", - "name": "pQCZVtLQPTCjayexHu5", + "address": "8ea8d93569747f1cc7536765e455bb2593568200b7bfc7a67dc84025953225a6", + "module": "zMuAfJbvz2", + "name": "JRQzuagpgZieXBU5", + "type_args": [] + } + }, + { + "struct": { + "address": "7c9f04422184fc2328b04ae974231a183da31986e5a33de97bfcb47a20acf281", + "module": "PivxYXCQwqBDgKpqmBlvR8", + "name": "YWqdcQGOPRCjFzWiBZEDRF", + "type_args": [] + } + }, + { + "struct": { + "address": "64e5b04f59aafd10322c1ee79b3b0ffd9634aaa49fa286b7f5775e918c799890", + "module": "QQMNYPIT", + "name": "dr3", "type_args": [] } } ], "args": [ - "97da81147edba5e9", - "01", - "11", - "2c641e1110d1a78d" + "be154fec13fbcf84", + "aceda067a6873aef", + "7d", + "5fb5a4bd062a83aa", + "0b54cbd3cb89e67a", + "2a7f910af5e4cc315238ada049849000", + "00", + "96", + "fe04afd2e7dc8738f4503202d7bfae3ce1873c6054255144530670b39db104fa", + "01" ] } }, - "max_gas_amount": "6691848954133267560", - "gas_unit_price": "396785085347461217", - "expiration_timestamp_secs": "5217000071570202020", - "chain_id": 218 + "max_gas_amount": "6323064361001264397", + "gas_unit_price": "17526482840008418649", + "expiration_timestamp_secs": "14506135780477091069", + "chain_id": 186 }, - "signed_txn_bcs": "a12d6e5a1247574e2b4497195d8b3c5c1c5333728455360bd13544e96b84e3177085965a4661a3fa02e6e578e1ee5b39d65a00c660a5cb3cb56ae5c8308297d1fb8da4872f45d4cad50b524c446d79345f436f696e035859350107773460e5ae3e4237a0f6416665a24a83d515db2d4b5f314dbd43fcdd6c0cc17f1d4a596b4d534a42654a61456e646659457968566b48597951434b644539137051435a56744c515054436a6179657848753500040897da81147edba5e901010111082c641e1110d1a78d68c4ae392b39de5c61f84ed0eea98105a41d219bec816648da002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440775a1ac1a1aa739bfbbf44ac7a27d643793d7284b7a6bd64282b7ea2bf54f941efd444b7d55f8b872440e7fa14d36040f8ef1cbcf92401b684e300327879f203", + "signed_txn_bcs": "34d2b7f24ed8ba6d2a28288f309f612fbdf9cdfd803a7f0da20361f7b25a9409ce6c06a799da4506020361d71267ba41799be42dbc53922711e9c1bdc3e7ed631ccf8bde2c1cc9f01d1b666a69415a714f4364667771425a534f476d6a644b385f436f696e1e6b56785241534f4e777a4b6461674b4377676453434f434f6e437961524a03078ea8d93569747f1cc7536765e455bb2593568200b7bfc7a67dc84025953225a60a7a4d7541664a62767a32104a52517a75616770675a69655842553500077c9f04422184fc2328b04ae974231a183da31986e5a33de97bfcb47a20acf28116506976785958435177714244674b70716d426c76523816595771646351474f5052436a467a5769425a45445246000764e5b04f59aafd10322c1ee79b3b0ffd9634aaa49fa286b7f5775e918c7998900851514d4e5950495403647233000a08be154fec13fbcf8408aceda067a6873aef017d085fb5a4bd062a83aa080b54cbd3cb89e67a102a7f910af5e4cc315238ada0498490000100019620fe04afd2e7dc8738f4503202d7bfae3ce1873c6054255144530670b39db104fa01010da569098909c0575965aea048933af3fdbcebb2a22550c9ba002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444068bb8b7bc6d611754d0055e5f378cb231d27929ce3348307e4193f44b508fb6847e6ee2a699e4648e8264048104baada67f76b8e28b9aeee8ec49f8f7c8c7705", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "b4fdb4f06ca2de91dc7998ef7d478b65c2cda346d7b336a5ad1ad9d44c953407", - "sequence_number": "13845369706455041372", + "sender": "db784de31c6d46d5a0a8000bd4eb5acd4649fd78f9ca79313175b715f81bd43f", + "sequence_number": "10787838317076000469", "payload": { "EntryFunction": { "module": { - "address": "aff1e81c618372adef86f6daebfd7e581b666b8dc0dcba7b31417f96e1e0a4de", - "name": "wHkqJFCHHwbwfaboIPh6_Coin" + "address": "f64ce531c4aea1c5c88813e338423594083097dae790b8298ff79ebe210c01bd", + "name": "GGezhgZiPSVWRkYzZg2_Coin" }, - "function": "VhohlZdOmTtwu0", + "function": "fbJVEjzgwaZWTrLNsglXVfhxPyaVIK1", "ty_args": [ { - "struct": { - "address": "fda28d5c11349d7cf81d1798869b768a79636751341c5fc07470a6beec92a9cd", - "module": "yHBgGFZKRGJNYyRmQNvaYMlqCVDx4", - "name": "gGMjYSnzdVAhAFEJ", - "type_args": [] + "vector": { + "struct": { + "address": "b5ffadbc3b1e19df450ad2a2187af308b5f9db6df78b28fda655ec1c56c00e59", + "module": "ngTip3", + "name": "p", + "type_args": [] + } } }, { "struct": { - "address": "71feb2bcf6c67a3d53848f80ab39255b51d7fe5a8789333eb8a04bcea4cf2d8d", - "module": "UUabxlk3", - "name": "PhrCyQOMxfWwPceVcRhwgEG0", + "address": "a6cf3edfb97b4b579502fc75232fc92bb41e402ebca9aa27aa1b62c7988550e0", + "module": "ZRteQeY", + "name": "K", "type_args": [] } }, { "vector": { - "vector": { - "vector": { - "vector": "bool" - } + "struct": { + "address": "1b7c570c8eeb64fc94cbf820c83e0ce34d6fb03bb53695e380a72ceb88071cdd", + "module": "Vjapw4", + "name": "sTLXB1", + "type_args": [] } } }, - { - "vector": { - "vector": "signer" - } - }, { "vector": { "vector": { "struct": { - "address": "588cacd4b2fd7610684d3eab881fab1566c624463aaae9ef3356f4b8531235ce", - "module": "hVEKlDWjnEusLoLmCSBEIK7", - "name": "XuYOLNbHiYEDsLzPHSOKNgkn", + "address": "0f5e3e84663ef2eb7b858dfc49405122057e487695be332fc6156618400b9dcc", + "module": "PxevRDzhEDoQxjUPyApvlkTpfdR6", + "name": "oNNKX4", "type_args": [] } } } - }, - { - "vector": { - "vector": { - "vector": "signer" - } - } - }, - { - "vector": { - "vector": "u8" - } - }, - { - "vector": "signer" - }, - { - "vector": { - "struct": { - "address": "f3ca942495cae1376c7316e5aa2097042d60152e31360a19b5485c4aaa03c1f1", - "module": "nwWrAnDJsHyK", - "name": "QfvRfpIQgSo7", - "type_args": [] - } - } } ], "args": [ - "01" + "01", + "00", + "e3", + "b386c401f8f369169c9a6e94f2c90e8eeb6c080fb58ea57ad2e953521820d122", + "bb", + "ef2f9e055146502c", + "3d3bacf0acebc72f09bbeed572cb34b9a2f7888b4b6a5c643d25d97584a886a7" ] } }, - "max_gas_amount": "2946195462293242263", - "gas_unit_price": "14033485629172010867", - "expiration_timestamp_secs": "11693715517818192020", - "chain_id": 48 + "max_gas_amount": "870947171588840137", + "gas_unit_price": "684142261780142419", + "expiration_timestamp_secs": "11171755157904492154", + "chain_id": 84 }, - "signed_txn_bcs": "b4fdb4f06ca2de91dc7998ef7d478b65c2cda346d7b336a5ad1ad9d44c9534075c05356164a224c002aff1e81c618372adef86f6daebfd7e581b666b8dc0dcba7b31417f96e1e0a4de1977486b714a464348487762776661626f495068365f436f696e0e56686f686c5a644f6d54747775300907fda28d5c11349d7cf81d1798869b768a79636751341c5fc07470a6beec92a9cd1d7948426747465a4b52474a4e5979526d514e7661594d6c7143564478341067474d6a59536e7a645641684146454a000771feb2bcf6c67a3d53848f80ab39255b51d7fe5a8789333eb8a04bcea4cf2d8d0855556162786c6b33185068724379514f4d78665777506365566352687767454730000606060600060605060607588cacd4b2fd7610684d3eab881fab1566c624463aaae9ef3356f4b8531235ce176856454b6c44576a6e4575734c6f4c6d43534245494b37185875594f4c4e624869594544734c7a5048534f4b4e676b6e000606060506060106050607f3ca942495cae1376c7316e5aa2097042d60152e31360a19b5485c4aaa03c1f10c6e775772416e444a7348794b0c516676526670495167536f37000101019741dbd029fde22873cf58bfd3f4c0c294c006b84e6c48a230002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c9df879c7601b71658baf02b2e4e3c5de41097b3324eee9d70215b7721f07935c37a2414d554ce0620c48d22e0d4e7e2b43bf57228bb7fe9fdfe0ac6e984fd00", + "signed_txn_bcs": "db784de31c6d46d5a0a8000bd4eb5acd4649fd78f9ca79313175b715f81bd43fd5aea9ffca19b69502f64ce531c4aea1c5c88813e338423594083097dae790b8298ff79ebe210c01bd184747657a68675a6950535657526b597a5a67325f436f696e1f66624a56456a7a6777615a5754724c4e73676c585666687850796156494b31040607b5ffadbc3b1e19df450ad2a2187af308b5f9db6df78b28fda655ec1c56c00e59066e675469703301700007a6cf3edfb97b4b579502fc75232fc92bb41e402ebca9aa27aa1b62c7988550e0075a527465516559014b0006071b7c570c8eeb64fc94cbf820c83e0ce34d6fb03bb53695e380a72ceb88071cdd06566a617077340673544c584231000606070f5e3e84663ef2eb7b858dfc49405122057e487695be332fc6156618400b9dcc1c5078657652447a6845446f51786a5550794170766c6b547066645236066f4e4e4b583400070101010001e320b386c401f8f369169c9a6e94f2c90e8eeb6c080fb58ea57ad2e953521820d12201bb08ef2f9e055146502c203d3bacf0acebc72f09bbeed572cb34b9a2f7888b4b6a5c643d25d97584a886a7c91aaf8cd639160c53d93c29c38f7e097a068928200c0a9b54002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404927d288358b89865b74c67c7e4ec5f4d0d901cff6d15db2e9f45e9553bd42b1df43bd55c6af4272486476729ba8d318eca53a68be4259c053dd9ef0b701e200", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "d5677cf319447c640e437f0f54d09d0052c71230ce042bd9702e0b661f241af4", - "sequence_number": "1878380097931517789", + "sender": "53e191cb1e4dc400716c7edc150a7b5de466cbbf925931a511eb15c66fc6538b", + "sequence_number": "12721589224998138041", "payload": { "EntryFunction": { "module": { - "address": "fdfa1ed33806bdf46693e66456d22062b8f146909d30cffea95047889e382ea5", - "name": "UKXqnFpkGaJETdhuCBcrIAbORX2_Coin" + "address": "6f7182a21fdd86ff4825b2e9a36435379380be9301b25c4ca1e1f4c89fef9106", + "name": "WTSPvtAhVXjyJNMOHCQwIFVexI4_Coin" }, - "function": "YUPGrOeRoxNjwZonFJnIGdQXDcJtcC4", + "function": "KZUZMGMrUyXxNDtMvhlO", "ty_args": [ { - "vector": { - "struct": { - "address": "9e804a293d5e42fada17932cf260c1a1a96dc2be3f4378aff31f706b3aa0d27f", - "module": "OAQOHdJNFYhgBimPFzOPxrAKGWeMmNt", - "name": "RkxHNKaeHUXDcVwttLVsXtyZ8", - "type_args": [] - } - } + "vector": "u128" }, { - "struct": { - "address": "c4ffef8e91871f0d6c0944250b19d4e68a7766f974dc2a2ebd21142479d7fe61", - "module": "lTbKVgILHSSMedNwjubCZkb", - "name": "hukrNkFZgDZuIOSEXp0", - "type_args": [] - } + "vector": "u128" } ], "args": [ - "af86bc1e58cc378ae375ee82ed7a1ce1", - "01", - "92" + "033631b8baa23ffe", + "daffac01929af03a463e08b768a9c509ada402c5e2471e498bfda28d5c11349d", + "1d", + "86", + "00", + "eaecaf79d8bc11b65cf49b0112dd1d83dabfcdee794f96fab4f02118d6210866", + "e4" ] } }, - "max_gas_amount": "9925555158849264896", - "gas_unit_price": "5256543240638435974", - "expiration_timestamp_secs": "6046679605804467685", - "chain_id": 232 + "max_gas_amount": "10085432895586854506", + "gas_unit_price": "11669446904000351920", + "expiration_timestamp_secs": "4620749631408738878", + "chain_id": 40 }, - "signed_txn_bcs": "d5677cf319447c640e437f0f54d09d0052c71230ce042bd9702e0b661f241af45d1f5f3abf58111a02fdfa1ed33806bdf46693e66456d22062b8f146909d30cffea95047889e382ea520554b58716e46706b47614a4554646875434263724941624f5258325f436f696e1f59555047724f65526f784e6a775a6f6e464a6e494764515844634a746343340206079e804a293d5e42fada17932cf260c1a1a96dc2be3f4378aff31f706b3aa0d27f1f4f41514f48644a4e4659686742696d50467a4f507872414b4757654d6d4e7419526b78484e4b61654855584463567774744c56735874795a380007c4ffef8e91871f0d6c0944250b19d4e68a7766f974dc2a2ebd21142479d7fe61176c54624b5667494c4853534d65644e776a7562435a6b621368756b724e6b465a67445a75494f5345587030000310af86bc1e58cc378ae375ee82ed7a1ce101010192009dc141d4a7be898612bc1c3afef248e5059396101fea53e8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ba61083d243418caac6ebcb742dd98f18ceb285a66bbb61b4e7b7dd52300e1716ad48b2fbb835dcbacc4754ec0ef9992d4e83b2184709857b52b1e95d5fe730d", + "signed_txn_bcs": "53e191cb1e4dc400716c7edc150a7b5de466cbbf925931a511eb15c66fc6538bb970738eff298cb0026f7182a21fdd86ff4825b2e9a36435379380be9301b25c4ca1e1f4c89fef910620575453507674416856586a794a4e4d4f48435177494656657849345f436f696e144b5a555a4d474d72557958784e44744d76686c4f02060306030708033631b8baa23ffe20daffac01929af03a463e08b768a9c509ada402c5e2471e498bfda28d5c11349d011d0186010020eaecaf79d8bc11b65cf49b0112dd1d83dabfcdee794f96fab4f02118d621086601e46a667e9bc8a7f68bb00e39be2134f2a13e9222d84e33204028002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e3c1cc43ffd9f8ea752977b78ec66c23639957d207716d8d2b0fdce906b809d5d589654ce68f9960fc55edeb6c2cf7b8cdae59e12d160a0818c296643cc9140e", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "9fb9a26728c82e7080454327b831fde9858e3aecc00ea250fe30fd830fe798ba", - "sequence_number": "8045682877290477653", + "sender": "1a07699f4ea7d7af86cdab18897206016666af834f438219a2621ff340f056c1", + "sequence_number": "6393138401489061514", "payload": { "EntryFunction": { "module": { - "address": "1e54c381ee15c7a6a1e5520ee0dde78ab9c344e1228ecb1c670d25ed351892ca", - "name": "OdJIkDLSvckclMYf5_Coin" + "address": "aadfea71cc1b4063703c2e33d4cadfd457455fdd1ab4e5e20ea579d802da8a0a", + "name": "qbQjxRwJbmKsAkzFP_Coin" }, - "function": "sXibMsGJrjSoaUtsqEhZx8", + "function": "cMmZkO", "ty_args": [ - { - "vector": { - "struct": { - "address": "7ad1724e91e802867f203ef815dcf559da22fefc2f14eb1132b238a4da0f145e", - "module": "IWZsPO0", - "name": "MCugsUYS", - "type_args": [] - } - } - }, - { - "vector": { - "vector": { - "vector": "u128" - } - } - }, { "struct": { - "address": "c6e8953f0ce603131a481c6ffcbdf28cf2d9aa840e09c4714bc9cbcde9044689", - "module": "IBwdFVrcElyDZsBhYxFDUjRXrhJh9", - "name": "jxGKyFNzqSkRSFwpXExFZIkyAEfhwJ", + "address": "3eb8a04bcea4cf2d8d72b21b2065418f6eee9ec1e948f563faf2c49ef0f5a2bd", + "module": "bGRpmIrgAZiXioMvJyJeoHBzi1", + "name": "FFEeWDrVwphaRpDqZKKnpq2", "type_args": [] } }, - { - "vector": "address" - }, { "struct": { - "address": "8cdfe9abb4e512e3648dfb0f655df12aee185dc9c20baa0d5f4614ed8f0d380e", - "module": "zLlGhIvRDiXFQhStQtXgGZTiLQZqUrh", - "name": "fkyvdhbvzmViya", + "address": "cb3d4f285f5fa8c90b68ae6f9939eb87f9462d44a548bb0c221df8574d7d257f", + "module": "ExtdSlpTyAFadJFXEyUPLnLMo8", + "name": "cuxZyVjV2", "type_args": [] } }, { "struct": { - "address": "b6c59c0db6c71f334a00c773923404f8ddbe78f122cc15769da8c9395ad4d2cd", - "module": "EmhFBbpDLUAVYP", - "name": "CdeiBVLwoPGOHyiZgLd6", + "address": "7b68664941e0c3c1fdf9cef8dea90af892b163f24898a29cea25f27ac33efa65", + "module": "bGRjeUWpGjwANqCt1", + "name": "RiwbtFDSnTSLdhtQegRVREmWRsdHRmWi", "type_args": [] } }, { - "vector": { - "vector": "u128" - } - }, - { - "vector": { - "struct": { - "address": "03fe0a4626d5dae3f59b4ee365f33ae99910e2df86c188d06128b79fafd44ff4", - "module": "lxXhYPOTswiFyOpaXnOXRSmnaXH7", - "name": "CqZBTtlTFrIfOTjvWclXNsTUPFkP7", - "type_args": [] - } + "struct": { + "address": "1fd1a8678a67c15992037118a7c3ad9fc978d79b74a8881964fe10011f85202b", + "module": "xiMYEMHVboBDYzSyODtLakoHcQDptV", + "name": "mbnbqyJsPgElBQWzkkdGIQBn", + "type_args": [] } }, { "vector": { "struct": { - "address": "b57f7a31472000ae71c148c2418cf2857fbd6bc09f5a33c8819c67b5d8044b9e", - "module": "yLSYHrDjrLh3", - "name": "bMBKLNdcmYmmpOOwbJ", + "address": "565b89ff84add8b5519799a73d27813479588b664f6d212db2e241f2a973330f", + "module": "tvylczukQQKCaBlvXNGSiDzMWSavRN", + "name": "pgkJHXVmoTmChKd8", "type_args": [] } } } ], - "args": [ - "00", - "f2", - "01", - "01", - "c59f60b8d0ecfaadc6c2ac46e430b6d27ecbcd45da5b90f303877872747152b3", - "01", - "00" - ] + "args": [] } }, - "max_gas_amount": "873638699538835602", - "gas_unit_price": "5168442970645378220", - "expiration_timestamp_secs": "8649648247714166998", - "chain_id": 49 + "max_gas_amount": "4635852432370655208", + "gas_unit_price": "12592904291567948249", + "expiration_timestamp_secs": "1601151355790774827", + "chain_id": 200 }, - "signed_txn_bcs": "9fb9a26728c82e7080454327b831fde9858e3aecc00ea250fe30fd830fe798ba557857f4f201a86f021e54c381ee15c7a6a1e5520ee0dde78ab9c344e1228ecb1c670d25ed351892ca164f644a496b444c5376636b636c4d5966355f436f696e16735869624d73474a726a536f615574737145685a78380906077ad1724e91e802867f203ef815dcf559da22fefc2f14eb1132b238a4da0f145e0749575a73504f30084d43756773555953000606060307c6e8953f0ce603131a481c6ffcbdf28cf2d9aa840e09c4714bc9cbcde90446891d4942776446567263456c79445a73426859784644556a525872684a68391e6a78474b79464e7a71536b5253467770584578465a496b7941456668774a000604078cdfe9abb4e512e3648dfb0f655df12aee185dc9c20baa0d5f4614ed8f0d380e1f7a4c6c4768497652446958465168537451745867475a54694c515a715572680e666b7976646862767a6d566979610007b6c59c0db6c71f334a00c773923404f8ddbe78f122cc15769da8c9395ad4d2cd0e456d6846426270444c5541565950144364656942564c776f50474f4879695a674c643600060603060703fe0a4626d5dae3f59b4ee365f33ae99910e2df86c188d06128b79fafd44ff41c6c78586859504f5473776946794f7061586e4f5852536d6e615848371d43715a4254746c54467249664f546a7657636c584e73545550466b5037000607b57f7a31472000ae71c148c2418cf2857fbd6bc09f5a33c8819c67b5d8044b9e0c794c53594872446a724c683312624d424b4c4e64636d596d6d704f4f77624a0007010001f20101010120c59f60b8d0ecfaadc6c2ac46e430b6d27ecbcd45da5b90f303877872747152b30101010092e80bbcc4c91f0cacb42e8b7fffb947d63815e540b9097831002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444023de5862b3e1cd2ddcf2d417900d175c07da2e35ce26487eea3c546940d553fcaf7274159573c72ae6761fab0d44025500b6769da501e6db95a775100b1a3a0a", + "signed_txn_bcs": "1a07699f4ea7d7af86cdab18897206016666af834f438219a2621ff340f056c18a06aafc80fdb85802aadfea71cc1b4063703c2e33d4cadfd457455fdd1ab4e5e20ea579d802da8a0a167162516a7852774a626d4b73416b7a46505f436f696e06634d6d5a6b4f05073eb8a04bcea4cf2d8d72b21b2065418f6eee9ec1e948f563faf2c49ef0f5a2bd1a624752706d497267415a6958696f4d764a794a656f48427a693117464645655744725677706861527044715a4b4b6e7071320007cb3d4f285f5fa8c90b68ae6f9939eb87f9462d44a548bb0c221df8574d7d257f1a45787464536c705479414661644a4658457955504c6e4c4d6f38096375785a79566a563200077b68664941e0c3c1fdf9cef8dea90af892b163f24898a29cea25f27ac33efa65116247526a65555770476a77414e714374312052697762744644536e54534c646874516567525652456d5752736448526d576900071fd1a8678a67c15992037118a7c3ad9fc978d79b74a8881964fe10011f85202b1e78694d59454d4856626f4244597a53794f44744c616b6f48635144707456186d626e6271794a735067456c4251577a6b6b64474951426e000607565b89ff84add8b5519799a73d27813479588b664f6d212db2e241f2a973330f1e7476796c637a756b51514b4361426c76584e475369447a4d57536176524e1070676b4a4858566d6f546d43684b64380000e85f95b639db5540d95166adbbfbc2ae2b528bc1ac6e3816c8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fdde5bf26ff5c498d4fcfd5ae1d5bcf5e5731f537dc7041336454bc1374787ec3b7ffc8110442577723e9fb6aadb796e91970b99fe67b505668135699c4f7b04", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "222cad8a4430c6e8065be9890108095ab704067f751e18c9a1e1eb3cde5d4938", - "sequence_number": "2421426922280710295", + "sender": "f1ed7a8dbc812d61ba115d220ad5acaf2df58ac113879ffa3f8318c0df401213", + "sequence_number": "11055023505453793912", "payload": { "EntryFunction": { "module": { - "address": "28cacab96ef2658950e4e5dbc0205f65aa14b1103b6120eb72bac66ca3ee40f6", - "name": "qErYhkLnTKLjEWni_Coin" + "address": "b45bed166e357b68de8eec6f51721a04f29037411f3d2657500d2f12a986c08a", + "name": "XSYgndDLIFNxVdWXJkxxk_Coin" }, - "function": "MINTwKlJJYlEqdAaOaG", + "function": "obVJhccwsDzpLiCKZxMETLupZRVgifV", "ty_args": [ { - "struct": { - "address": "b9b99b9e2e42a907e1d574c156a3be3a1460fa5690416835c7c2ed71ff96a4e2", - "module": "aAKaN", - "name": "OMyLadmqHHDLDnQaggwdDEoSWvQdL3", - "type_args": [] + "vector": { + "struct": { + "address": "c10dab40d056304a33b372bfbeb565f31f0434bff5dead9327460f7949f536c2", + "module": "wHOrERUJKq5", + "name": "EvpeRpG1", + "type_args": [] + } } - } - ], - "args": [ - "aeaf001dc9491105", - "c29a89ee6b7b78ce", - "98e89bda07a8aae83b87ecc03aef3192f8d4f51fde10a429151be9e071ff09e9", - "01", - "7c" - ] - } - }, - "max_gas_amount": "11657047152064288007", - "gas_unit_price": "10327563732900448828", - "expiration_timestamp_secs": "2449168127409132211", - "chain_id": 18 - }, - "signed_txn_bcs": "222cad8a4430c6e8065be9890108095ab704067f751e18c9a1e1eb3cde5d493897f01be0f4a29a210228cacab96ef2658950e4e5dbc0205f65aa14b1103b6120eb72bac66ca3ee40f61571457259686b4c6e544b4c6a45576e695f436f696e134d494e54774b6c4a4a596c45716441614f61470107b9b99b9e2e42a907e1d574c156a3be3a1460fa5690416835c7c2ed71ff96a4e20561414b614e1e4f4d794c61646d714848444c446e51616767776444456f53577651644c33000508aeaf001dc949110508c29a89ee6b7b78ce2098e89bda07a8aae83b87ecc03aef3192f8d4f51fde10a429151be9e071ff09e90101017c0755c5849f26c6a13c0abd4e7fe0528fb3126e856f31fd2112002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405c5d20568e97960724303220a0e16f4314d81ea77c32f8ec42158920b8c81e22430b7c581a328ff5f18ff5352d55204b8efacfe7cc11fc631cd01cf88870e40e", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "cd024813caccae2287438ebcbcf54ec918a76cfd87928c20ea3f3eb92942b456", - "sequence_number": "10191793175056855089", - "payload": { - "EntryFunction": { - "module": { - "address": "9c86e21299a794ee4dfcc53361de26450819f9ba7c7fb556c34103dd29f63679", - "name": "I0_Coin" - }, - "function": "EERtWBRGMkhVQUBvnaj", - "ty_args": [ + }, { "vector": { "struct": { - "address": "13612872dd98003a98fda8f975ee111c975ffced1e7dd63f89bbe53def9834e6", - "module": "WBLt2", - "name": "kugkSzFdpZRPqubxBJxqV4", + "address": "53aef66fb374ba6975a2648c87963991919a9886e7d6c2410ee5015c55266ab0", + "module": "VzGbptcNRsthDJBdkGGeUtOfq3", + "name": "nQSPLMCQIefjyciuDCQTrqUGNCZ4", "type_args": [] } } }, { "struct": { - "address": "5a288b7d1d0fff57580ec960a94e5ebec1bdaf00c722ffa7bcd7077e4c38ff09", - "module": "SrqMzJjGxxeEtRpw8", - "name": "xCVGvweqcDesqSnFIC", + "address": "70fadd37a9973ad9d5cd5207a212f8bf67545c4d2831beed6edbdd99d616e28b", + "module": "swnaiRhEf7", + "name": "wxxFfRiPIHWtzYhnTiCPtShN1", "type_args": [] } }, { "vector": { "struct": { - "address": "96db37481beb44b255a60351155d914f98806fd3c8ca1a9b0318d505448519f2", - "module": "jSZbvdGFp", - "name": "srsXvqCgCGg7", + "address": "32aac68ed3b2afc8542ceb8ef7cb974ab9defa9e804a293d5e42fada17932cf2", + "module": "ZFAMLHTawcoGQnn", + "name": "BIIQkTGyk", "type_args": [] } } }, { "struct": { - "address": "b07d010654bb8f2720c4da6327d05ea3cdd6579889e5659e58ac23bed6af8448", - "module": "RDRHEHhcOQirKYHORNRAsDyVrXuyE0", - "name": "jPtSTJwtIUkIPPnZlmfspfBai1", + "address": "2afa221144806096fbebd407be51454879119b0bb50d0b743d905e08f385d81b", + "module": "EOdIxAljFrYoJNTShH", + "name": "aGnMsfpFXdKoxfzfH8", "type_args": [] } }, { "vector": { "struct": { - "address": "c34fa23c046e05df2fdcf64b251ee2d3d43004b3205b7b11888e607acdd9aecd", - "module": "Y8", - "name": "hpMrlk", + "address": "a46efe2a843dce11afb2e441798c5f015362923c0ff8bd4141b595bc65201222", + "module": "qQtLtCqQg5", + "name": "EzeqEJsgtCpSCpqxULm2", "type_args": [] } } - }, - { - "struct": { - "address": "8d6610644f6b1e4bec9278f5a651cffde44ea863d73c15a1d343b17190c7f905", - "module": "nnyTO7", - "name": "eFydRU3", - "type_args": [] - } } ], "args": [ - "9fcffe4504ce4a33738eddf122897d32" + "01", + "a4", + "d7", + "5b800c550a0c0075", + "8c095edaa1374b44f15d56e4db4ccdbd", + "2be9f664caae2735fa712271d482ece0" ] } }, - "max_gas_amount": "14870805680598235862", - "gas_unit_price": "1406228066669832324", - "expiration_timestamp_secs": "14548874060634569088", - "chain_id": 27 + "max_gas_amount": "40061172565702091", + "gas_unit_price": "12806960680012040838", + "expiration_timestamp_secs": "12949656614228081273", + "chain_id": 70 }, - "signed_txn_bcs": "cd024813caccae2287438ebcbcf54ec918a76cfd87928c20ea3f3eb92942b45631b083efe485708d029c86e21299a794ee4dfcc53361de26450819f9ba7c7fb556c34103dd29f636790749305f436f696e1345455274574252474d6b6856515542766e616a06060713612872dd98003a98fda8f975ee111c975ffced1e7dd63f89bbe53def9834e60557424c7432166b75676b537a4664705a525071756278424a7871563400075a288b7d1d0fff57580ec960a94e5ebec1bdaf00c722ffa7bcd7077e4c38ff09115372714d7a4a6a477878654574527077381278435647767765716344657371536e46494300060796db37481beb44b255a60351155d914f98806fd3c8ca1a9b0318d505448519f2096a535a6276644746700c7372735876714367434767370007b07d010654bb8f2720c4da6327d05ea3cdd6579889e5659e58ac23bed6af84481e52445248454868634f5169724b59484f524e5241734479567258757945301a6a507453544a777449556b4950506e5a6c6d6673706642616931000607c34fa23c046e05df2fdcf64b251ee2d3d43004b3205b7b11888e607acdd9aecd0259380668704d726c6b00078d6610644f6b1e4bec9278f5a651cffde44ea863d73c15a1d343b17190c7f905066e6e79544f3707654679645255330001109fcffe4504ce4a33738eddf122897d32d63aeb43fab65fce84280ae3f9ec831380b904fadffbe7c91b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440add9f80745a5512865611ec445f737ce96369380e3c886809f6c8ee108fc71b6c3227d5439eb00669cf8ddde74cc2ea64452cfbfecf5a6c77a0496d7b3d79b05", + "signed_txn_bcs": "f1ed7a8dbc812d61ba115d220ad5acaf2df58ac113879ffa3f8318c0df40121378c22a624e556b9902b45bed166e357b68de8eec6f51721a04f29037411f3d2657500d2f12a986c08a1a585359676e64444c49464e78566457584a6b78786b5f436f696e1f6f62564a6863637773447a704c69434b5a784d45544c75705a525667696656060607c10dab40d056304a33b372bfbeb565f31f0434bff5dead9327460f7949f536c20b77484f724552554a4b713508457670655270473100060753aef66fb374ba6975a2648c87963991919a9886e7d6c2410ee5015c55266ab01a567a47627074634e52737468444a42646b47476555744f6671331c6e5153504c4d43514965666a7963697544435154727155474e435a34000770fadd37a9973ad9d5cd5207a212f8bf67545c4d2831beed6edbdd99d616e28b0a73776e61695268456637197778784666526950494857747a59686e546943507453684e3100060732aac68ed3b2afc8542ceb8ef7cb974ab9defa9e804a293d5e42fada17932cf20f5a46414d4c48546177636f47516e6e09424949516b5447796b00072afa221144806096fbebd407be51454879119b0bb50d0b743d905e08f385d81b12454f644978416c6a4672596f4a4e545368481261476e4d7366704658644b6f78667a664838000607a46efe2a843dce11afb2e441798c5f015362923c0ff8bd4141b595bc652012220a7151744c74437151673514457a6571454a73677443705343707178554c6d320006010101a401d7085b800c550a0c0075108c095edaa1374b44f15d56e4db4ccdbd102be9f664caae2735fa712271d482ece0cb7510986c538e00864a8360e276bbb1793a5a96146cb6b346002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d448ec2ef87e9c087022b0d5769dc07cb22e0eb4455690a8b0eb4c47ed076d73a7f68e6a83faa07a8d05e687237f89989c759f2c5171f62d3c769bf6165de603", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "6ecc516d0bd5bd1871bcf74ef6bdcf9db0d21ee625a8732c6ff04d47ba02e852", - "sequence_number": "4229499932157335504", + "sender": "8097c870da2894624f8560bc2691a083eb8e22a4e75179f37bebb076cf9fcd7f", + "sequence_number": "4668949557064069391", "payload": { "EntryFunction": { "module": { - "address": "bbf5fc7f48ba522a374b42f200f359c29aaa50dcfc64d29d3459b067f75ba0aa", - "name": "uSH3_Coin" + "address": "281b875357192ffc6cde7f10c65e051d6f20687792bbdd32bbc79946118e4b4b", + "name": "NDdiBabPDZqHDaduKLVTXnMbOkG2_Coin" }, - "function": "ulHLTgDcfotYMGrLNZTqfHKChEmGchH4", + "function": "MCARjOk3", "ty_args": [ { "struct": { - "address": "b80d183c84c7331d362bae436292fd19fa4e91c9b5bd3e5981a93f4ef087d08e", - "module": "GZWJuLssawyjywqaaty", - "name": "gbYuTvedHuCtEMn", + "address": "17a2b2303887eb88e2fce4c16af0e3fba550c6defbbcafb3b1928a1dcbd01b28", + "module": "UmsVPpfajsSKjgAfjh", + "name": "SdBLSnhcvxgDHnBhpypaktksIP", "type_args": [] } }, { "vector": { - "vector": "address" + "struct": { + "address": "fd2f54f85938e2c116197c1686d17eea76f21a5657fe9e4d582b12259eb3b3ce", + "module": "wuXBybToiddrzTswMFHgOWxeCgvWzUCM", + "name": "bmhtscePASPqvEHny", + "type_args": [] + } } } ], "args": [ - "beefd7c42645fab1", - "c6cc77a7ff214cd7", - "c1d1c4fdea09d029ad38c71daea6b76e" + "25" ] } }, - "max_gas_amount": "5449064544583208634", - "gas_unit_price": "6343790711398206942", - "expiration_timestamp_secs": "6489472502238722924", - "chain_id": 103 + "max_gas_amount": "7232575745544214858", + "gas_unit_price": "11508038239771854729", + "expiration_timestamp_secs": "16404010806166839774", + "chain_id": 198 }, - "signed_txn_bcs": "6ecc516d0bd5bd1871bcf74ef6bdcf9db0d21ee625a8732c6ff04d47ba02e852d0d7c689c733b23a02bbf5fc7f48ba522a374b42f200f359c29aaa50dcfc64d29d3459b067f75ba0aa09755348335f436f696e20756c484c54674463666f74594d47724c4e5a547166484b4368456d47636848340207b80d183c84c7331d362bae436292fd19fa4e91c9b5bd3e5981a93f4ef087d08e13475a574a754c73736177796a797771616174790f676259755476656448754374454d6e000606040308beefd7c42645fab108c6cc77a7ff214cd710c1d1c4fdea09d029ad38c71daea6b76ebace0e3a55f79e4bde0d508a0aac09586cbb9aabdb3c0f5a67002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404cc9dec8cf4253702d7efe01f1f54672ff5605827c091a8c76db65310a9023a699113d6e2eaa20f0ac63e7d38bb13061a02cf878c2d9735cd21d33de3c72330c", + "signed_txn_bcs": "8097c870da2894624f8560bc2691a083eb8e22a4e75179f37bebb076cf9fcd7f0f71058fe270cb4002281b875357192ffc6cde7f10c65e051d6f20687792bbdd32bbc79946118e4b4b214e44646942616250445a7148446164754b4c5654586e4d624f6b47325f436f696e084d4341526a4f6b33020717a2b2303887eb88e2fce4c16af0e3fba550c6defbbcafb3b1928a1dcbd01b2812556d7356507066616a73534b6a6741666a681a5364424c536e686376786744486e4268707970616b746b734950000607fd2f54f85938e2c116197c1686d17eea76f21a5657fe9e4d582b12259eb3b3ce20777558427962546f696464727a5473774d4648674f577865436776577a55434d11626d687473636550415350717645486e79000101254ad9441c52455f648987368fcec3b49fde613e81eac0a6e3c6002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bca159617075e88ad5fb7bead896fb12c489a50c6f00ebc5fd2e900a85f68de28e785a60e899c16119764c27ac010b9705e942c40090786c73c41cfc0d9b8f08", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "8aaeb25091303219507ad3951038a391a0d637ea7a366433e13e8e0f76e08e8a", - "sequence_number": "3650245720722201929", + "sender": "ae7f91083c96a59d9a2ab6a503ca6322e3aed1ce94f1aeb337ffcf5fe3baa3d2", + "sequence_number": "3232771898260856413", "payload": { "EntryFunction": { "module": { - "address": "b760fcb18efb1a1ea0ecf53e096ffdaf43e382d080d5a0233703e2e9ff99d1fc", - "name": "agCTHqS_Coin" + "address": "73786bc8508aebd92ad8bca5a8eea17fd86d9d10ad4fb4d9e74cdf6b55a646c9", + "name": "jVoUPKhQ_Coin" }, - "function": "twXCumwvRKkyHkLFNlcrjKdubKzmQ", + "function": "PiPU", "ty_args": [ { - "vector": "u8" - }, - { - "struct": { - "address": "84f60c65ede80f771a673d8dc71d2f20ff783feb5de2b1ef9133964eaeb8fd4e", - "module": "jxHDjoD1", - "name": "uwlsZwYQqHXYvcc", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "46895e850147098c1fb148be67e13448ac08ddcfbd81539e992fb02ada5301bd", + "module": "HLHRVRNamWoacpyL9", + "name": "ZWDKMwPeFpuvWPZldsOEiYgK", + "type_args": [] + } + } } }, { "vector": { "struct": { - "address": "4b0fae6efd27837e0911fc411d670201c0d351450191a259c2456696d850d2b5", - "module": "KTtJRhP1", - "name": "J", + "address": "1b829bb1297140a1b4f8acc0f5c04223a057915f03dadee3a8c4d86272701f22", + "module": "hJE9", + "name": "XDuewAgdedrqgoA", "type_args": [] } } }, { "vector": { - "struct": { - "address": "35963ddb8630e82e269215daa84595e17fc20f278b2005db88eae012fb19bb16", - "module": "gtDohRkIdLaXQPgwUgUt2", - "name": "ZqCWUoDxryp7", - "type_args": [] - } + "vector": "u64" } }, { "vector": { - "struct": { - "address": "407c122e80ea037e8db87f3d7797caefee068aa5241d168d5f921acd8198895b", - "module": "EPmsLEyncIsEajqPsZTKjajLyMMLB4", - "name": "VsbWUfYnYJ9", - "type_args": [] + "vector": { + "struct": { + "address": "26aa6b8e7fb4504d68f53f9ec39ce166e8ea3d8cdfe9abb4e512e3648dfb0f65", + "module": "RootYezUhUkI", + "name": "uwRwfrbbIQu", + "type_args": [] + } } } }, { "struct": { - "address": "e8a27f639c43d9bced74b85f787b64c1deebbfa2bf4ccd715dbc885b5a4ede31", - "module": "hfFszWkzZwMtJymBphlmPptmJfFjA", - "name": "HXxdnXNOoZtLSJwVcs", + "address": "f67d62313b4007e58ebd60c8ca62404c53558d1e3ad0303bba00b16019859bb2", + "module": "MDZezTUffhlmnqHshVpjYrUM7", + "name": "CgLVHVkz", + "type_args": [] + } + }, + { + "struct": { + "address": "0d512eb6c59c0db6c71f334a00c773923404f8ddbe78f122cc15769da8c9395a", + "module": "QgndOt", + "name": "usKARDxYdDDITqrXZIlbYjlCu", "type_args": [] } }, { "vector": { - "vector": "u64" + "vector": { + "struct": { + "address": "fafdcc2dc3eef830849524b0501a691e3257e8ba6b0691fc33b3d9ae834d615e", + "module": "SoGZtBPAtgUHiQBrohjf", + "name": "VFcjwqbNJROEcQZAfqJ5", + "type_args": [] + } + } } }, { "struct": { - "address": "edcdf1e1f14d239968c5ce2398b83ad8ed5a38986dd98ce3ed86ea05c192b84c", - "module": "CTvQEXSZyPtmYTMFxsegWnbNgQhKApwF9", - "name": "vkgLzdoBWrNvzF", + "address": "86c188d06128b79fafd44ff4e6f5e8b723061153365615ff82318bfb73ba9589", + "module": "qnrhHywhEkTceeHMGfnWOEYiicEhnp", + "name": "rOvAfEMEdPs", "type_args": [] } } ], - "args": [ - "46eef7c7e0a4aa3c818cc6e7db82ac8e", - "169ebac73b5d1e39", - "20", - "25" - ] + "args": [] } }, - "max_gas_amount": "5884333008804670626", - "gas_unit_price": "4248460506912669358", - "expiration_timestamp_secs": "11382274384853212882", - "chain_id": 216 + "max_gas_amount": "7115867385316374095", + "gas_unit_price": "2498960324979615472", + "expiration_timestamp_secs": "7488013861149748261", + "chain_id": 144 }, - "signed_txn_bcs": "8aaeb25091303219507ad3951038a391a0d637ea7a366433e13e8e0f76e08e8a495d89a62447a83202b760fcb18efb1a1ea0ecf53e096ffdaf43e382d080d5a0233703e2e9ff99d1fc0c616743544871535f436f696e1d74775843756d7776524b6b79486b4c464e6c63726a4b6475624b7a6d510806010784f60c65ede80f771a673d8dc71d2f20ff783feb5de2b1ef9133964eaeb8fd4e086a7848446a6f44310f75776c735a775951714858597663630006074b0fae6efd27837e0911fc411d670201c0d351450191a259c2456696d850d2b5084b54744a52685031014a00060735963ddb8630e82e269215daa84595e17fc20f278b2005db88eae012fb19bb16156774446f68526b49644c61585150677755675574320c5a714357556f447872797037000607407c122e80ea037e8db87f3d7797caefee068aa5241d168d5f921acd8198895b1e45506d734c45796e63497345616a7150735a544b6a616a4c794d4d4c42340b567362575566596e594a390007e8a27f639c43d9bced74b85f787b64c1deebbfa2bf4ccd715dbc885b5a4ede311d686646737a576b7a5a774d744a796d4270686c6d5070746d4a66466a4112485878646e584e4f6f5a744c534a775663730006060207edcdf1e1f14d239968c5ce2398b83ad8ed5a38986dd98ce3ed86ea05c192b84c21435476514558535a7950746d59544d4678736567576e624e6751684b41707746390e766b674c7a646f4257724e767a4600041046eef7c7e0a4aa3c818cc6e7db82ac8e08169ebac73b5d1e3901200125a26ce8e9b159a951ae3ece5c5290f53ad21e34453ff6f59dd8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bf9e2816707d750833ad7cdafb9575e1ae28fe9ec7d05f540eed23e1a2bd8533ad861fedc872214c4ed0af5375de72615923623a6f6e795a2168da2045a4a904", + "signed_txn_bcs": "ae7f91083c96a59d9a2ab6a503ca6322e3aed1ce94f1aeb337ffcf5fe3baa3d25d1eb4dbe91cdd2c0273786bc8508aebd92ad8bca5a8eea17fd86d9d10ad4fb4d9e74cdf6b55a646c90d6a566f55504b68515f436f696e04506950550806060746895e850147098c1fb148be67e13448ac08ddcfbd81539e992fb02ada5301bd11484c485256524e616d576f616370794c39185a57444b4d7750654670757657505a6c64734f456959674b0006071b829bb1297140a1b4f8acc0f5c04223a057915f03dadee3a8c4d86272701f2204684a45390f584475657741676465647271676f410006060206060726aa6b8e7fb4504d68f53f9ec39ce166e8ea3d8cdfe9abb4e512e3648dfb0f650c526f6f7459657a5568556b490b75775277667262624951750007f67d62313b4007e58ebd60c8ca62404c53558d1e3ad0303bba00b16019859bb2194d445a657a54556666686c6d6e7148736856706a5972554d370843674c5648566b7a00070d512eb6c59c0db6c71f334a00c773923404f8ddbe78f122cc15769da8c9395a0651676e644f741975734b415244785964444449547172585a496c62596a6c437500060607fafdcc2dc3eef830849524b0501a691e3257e8ba6b0691fc33b3d9ae834d615e14536f475a7442504174675548695142726f686a66145646636a7771624e4a524f4563515a4166714a35000786c188d06128b79fafd44ff4e6f5e8b723061153365615ff82318bfb73ba95891e716e726848797768456b54636565484d47666e574f455969696345686e700b724f764166454d4564507300004ff6917aafa3c062f06634ee2c17ae22252c08fbeec4ea6790002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444099c4f579e65e9105e449c52c87517a8afe6e42dc0930127c0d5dcef3ee89bc4dc6d9862134c94b9ea2a8d37c89d4034070d29a952dec0371e67a3ec358ab8c07", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "6e68e0ad33e9f661b98c5b96845453e9f99228db8f07a738992cb0304c1e7af8", - "sequence_number": "1181733586840230246", + "sender": "73e80cbe2a7518d6909c900f7b8aa28e1a5f7c92b2fe2b5b6361910b1ee8b347", + "sequence_number": "15423139578077517809", "payload": { "EntryFunction": { "module": { - "address": "e578695a8e0b244f796c0c16a647722d01f4bc6aec78641da5eaa8b80bd0867e", - "name": "Paa6_Coin" + "address": "550f12209576637decf60eef4724cd4aad06d5c3eb5e0b4fecdfc04ac8bec02a", + "name": "rWTEUsZIQSWOoIrglrcns_Coin" }, - "function": "KfoiqU5", + "function": "vRgskcbuPRVnUSVqsmefNoMQE", "ty_args": [ { "struct": { - "address": "c01aaec64f3cddd52f73eba0eddcc881a7f108477f261fec6164cd0f1f677737", - "module": "JuLzUFZDlaeEAUXXcktsmKxlBbLkbi", - "name": "h", + "address": "ae71c148c2418cf2857fbd6bc09f5a33c8819c67b5d8044b9ea2537f7d883265", + "module": "QzKaAxyCoolrKfuo5", + "name": "crHuBiIbMXJDdKSKinmFWqxy", "type_args": [] } }, { - "struct": { - "address": "3bc73f2bbebc764dc695ee79269016358487ada21e8df73f0060784e93ed4d57", - "module": "ArLgWuMyyfBobXSqtBkBIFsV", - "name": "kr1", - "type_args": [] + "vector": { + "vector": { + "vector": "address" + } } }, { - "vector": "bool" - }, - "bool", - { - "struct": { - "address": "b237f4af9061e1c882774c1bb050ed57d2eeff4a728782312d246b24c8ec98e0", - "module": "QYNbEBaWjqeoXDLYiQPWcYdFHrqxt", - "name": "ovVFJv", - "type_args": [] - } - }, + "vector": "u8" + } + ], + "args": [] + } + }, + "max_gas_amount": "5665905787442427844", + "gas_unit_price": "2003020702888368619", + "expiration_timestamp_secs": "1755321824711168510", + "chain_id": 94 + }, + "signed_txn_bcs": "73e80cbe2a7518d6909c900f7b8aa28e1a5f7c92b2fe2b5b6361910b1ee8b347f1179420bbff09d602550f12209576637decf60eef4724cd4aad06d5c3eb5e0b4fecdfc04ac8bec02a1a7257544555735a495153574f6f4972676c72636e735f436f696e19765267736b6362755052566e55535671736d65664e6f4d51450307ae71c148c2418cf2857fbd6bc09f5a33c8819c67b5d8044b9ea2537f7d88326511517a4b61417879436f6f6c724b66756f351863724875426949624d584a44644b534b696e6d46577178790006060604060100c4f7555f4b57a14eeb196a81b728cc1bfe516644e6275c185e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144408e8d5a929965598c1c0a03936195a06f2dcfc6589ce7689ed24be315e47f4d6f531320998f20bf1099aa71cc5d235c6b854e57e0c352a3f0e90092889851770d", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "e8e8d6d9bec0f7e38f646fb48bffaa8cffaec917695855b70e76e575b0b6846e", + "sequence_number": "4947151182958275233", + "payload": { + "EntryFunction": { + "module": { + "address": "dafe9577c79423fcf91bb0ea8c0ab2001b1f7687d7a91b183becc248400061e9", + "name": "cdnjaXeohdyH_Coin" + }, + "function": "sgVOHUVurbHbUkmraNYYOhT", + "ty_args": [ { - "struct": { - "address": "5be8c524a4be5a8dd5fbcd9ab4976161591109d7390658bd0bb2670f01f377a8", - "module": "idvTEzFyQWfqeUEInUJ", - "name": "RyQcMvCLtYkzYdNeQIdSiDFzUwPkun9", - "type_args": [] - } + "vector": "u8" }, { - "struct": { - "address": "96125ef1cc0232eae11f227a6a451644705947fb42465af5aac885cc6fde9712", - "module": "q0", - "name": "gwGzAI1", - "type_args": [] + "vector": { + "vector": "bool" } }, { "struct": { - "address": "22f6247faf0b55e979ef3b055d0acadc8d334add4e6cba205642d27c92d23e91", - "module": "MQrgNAOtlavkInbDZOzXylRDH", - "name": "fxyfPeLOSUZAZqy", + "address": "afb5954807f598aabb0a0aceb9e400368717115e8571e223d7c137b148850123", + "module": "YfksWinaKGxGjHpMKW1", + "name": "XTpcoFnh", "type_args": [] } } ], "args": [ - "1aee8e8be8ea6a12ff47aecebdbb9908413c789e54f90230798a4dabd0ad9b50", - "01" + "5c", + "9f04aa7cace870708c215ca397aa21bb", + "00", + "41016c23687433de", + "31f51bf513eb3a88", + "00", + "ce283dc2d678c910e40215ab91e95e13601bed4cd25247d59a14f2215f011143", + "39fc570a86f18f3d", + "d7c6cbdf962ccc95" ] } }, - "max_gas_amount": "12299265788543233336", - "gas_unit_price": "2447077526551110119", - "expiration_timestamp_secs": "12689068831543315256", - "chain_id": 127 + "max_gas_amount": "7574570237970311197", + "gas_unit_price": "75889477014785962", + "expiration_timestamp_secs": "5097396785493781993", + "chain_id": 181 }, - "signed_txn_bcs": "6e68e0ad33e9f661b98c5b96845453e9f99228db8f07a738992cb0304c1e7af86699c2a66f5c661002e578695a8e0b244f796c0c16a647722d01f4bc6aec78641da5eaa8b80bd0867e09506161365f436f696e074b666f697155350807c01aaec64f3cddd52f73eba0eddcc881a7f108477f261fec6164cd0f1f6777371e4a754c7a55465a446c61654541555858636b74736d4b786c42624c6b6269016800073bc73f2bbebc764dc695ee79269016358487ada21e8df73f0060784e93ed4d571841724c6757754d797966426f6258537174426b4249467356036b72310006000007b237f4af9061e1c882774c1bb050ed57d2eeff4a728782312d246b24c8ec98e01d51594e62454261576a71656f58444c5969515057635964464872717874066f7656464a7600075be8c524a4be5a8dd5fbcd9ab4976161591109d7390658bd0bb2670f01f377a81369647654457a467951576671655545496e554a1f527951634d76434c74596b7a59644e65514964536944467a5577506b756e39000796125ef1cc0232eae11f227a6a451644705947fb42465af5aac885cc6fde9712027130076777477a414931000722f6247faf0b55e979ef3b055d0acadc8d334add4e6cba205642d27c92d23e91194d5172674e414f746c61766b496e62445a4f7a58796c5244480f6678796650654c4f53555a415a71790002201aee8e8be8ea6a12ff47aecebdbb9908413c789e54f90230798a4dabd0ad9b50010138ed3b0412c5afaae7a1eb930bc4f52138cb9e6adfa018b07f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444067352af2794582fc7998a7819d3fcd14db0838015c0cb79230ddabcef1bc22d0c3a47340b692ca6b73765c96acee4c8de811acfb4d483ef883f1b21fd9298901", + "signed_txn_bcs": "e8e8d6d9bec0f7e38f646fb48bffaa8cffaec917695855b70e76e575b0b6846ea1aa612ecacfa74402dafe9577c79423fcf91bb0ea8c0ab2001b1f7687d7a91b183becc248400061e91163646e6a6158656f686479485f436f696e177367564f4855567572624862556b6d72614e59594f685403060106060007afb5954807f598aabb0a0aceb9e400368717115e8571e223d7c137b1488501231359666b7357696e614b4778476a48704d4b573108585470636f466e680009015c109f04aa7cace870708c215ca397aa21bb01000841016c23687433de0831f51bf513eb3a88010020ce283dc2d678c910e40215ab91e95e13601bed4cd25247d59a14f2215f0111430839fc570a86f18f3d08d7c6cbdf962ccc951d6877e87f471e69aa0fa8c7139d0d01e92d93865e97bd46b5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bfd19cdd774f90dc96cca3f9a54372c908f4567da0abb27ec8a160bb1abd79ed881517d7f8a15db7608588227872a47c3df8b0eb7da672204ced5956cd9e9907", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "c5060b74d8c2b77634d479babf1116ec5e19873da563694e5370446e8d184014", - "sequence_number": "2661518262186350512", + "sender": "257527d9b8f0e72f0dda5c1b8a310b223b79d7db732047478ee6f11222f91731", + "sequence_number": "12893816990267342013", "payload": { "EntryFunction": { "module": { - "address": "4d9affd320e94695392db9df76b911933a79d9d593574fbd69db7b799334ebd0", - "name": "E_Coin" + "address": "6ae8e083bd57f456c2c58450c26b97edf60b8ab6badb48aacded72a841dd5b52", + "name": "VwRYoFmHKXJxSA7_Coin" }, - "function": "aDLohvvIvQKtcyACxQmaX9", + "function": "GRVInjXGYtR4", "ty_args": [ { "vector": { "struct": { - "address": "90d2615696547fdb8393b2a8b6946a5298cdaaa72dde97371f1950b94243dc8c", - "module": "KvQtgzJAWNRrRDS7", - "name": "GcYUHfqbwVhdAPlFtsuhyfn", + "address": "2cad8a4430c6e8065be9890108095ab704067f751e18c9a1e1eb3cde5d493897", + "module": "pkSEw", + "name": "dEiWd", "type_args": [] } } @@ -2818,2172 +3371,2058 @@ { "vector": { "struct": { - "address": "ea5dee94e3230121db18557fe26185a802d7e6a05211865b69df4006a130327f", - "module": "MHG2", - "name": "VycyNfpy", + "address": "de01266242e66fd40bfe5a784f5909bd3e1bf76670789295207afe2a063e3ed8", + "module": "zbPNRneLC", + "name": "nCxQqwGECxcXnjTxrqKVHzjpZwJBK", "type_args": [] } } }, - { - "struct": { - "address": "f3ce42c13d3881af5aac0dae2119d6dff76f745ecc3c78bd29f501d64789b6f3", - "module": "gWVWeNVMWETXsuijxERtfeC5", - "name": "oAfHUUoYORtVvROilnUEfhvuqh4", - "type_args": [] - } - }, - { - "vector": { - "vector": "u64" - } - }, { "vector": { - "vector": { - "struct": { - "address": "bcb067e6b1499c3e6204ea45da1ce0b210b77991d7edbeb1fe9298b472df0df8", - "module": "ywTYIBLkosJCVfv", - "name": "KrDwpqv6", - "type_args": [] - } + "struct": { + "address": "85779fc9877a0dcb4f7a1d0291e46f612354927bb537c37e66b1b85b20a85455", + "module": "YKWjbun3", + "name": "CCzbZvhfcbBXKbbsl2", + "type_args": [] } } }, { - "struct": { - "address": "f11988aab4ee79dfc570b7437e0c0bd4def6cb891a7347ae094e4b3c258cd516", - "module": "yytLeOaasOOrvqxDsvvYUlqoGhvjga8", - "name": "xEaHOQWHipXMV", - "type_args": [] - } - }, - { - "struct": { - "address": "0333cd96931f1bad3d82db0262ea607436d542029de57e8e3c5121dedae396c5", - "module": "oKVncYwEFIaBLSqgoHfKUaSsNQpYtlT9", - "name": "ycWBzuriCQnGXowcgaHkXIpUoGSNQA3", - "type_args": [] - } + "vector": "u128" }, { "vector": { "struct": { - "address": "372d7507a38d095e855bb72e331c47441797854e3aa0a265525ca001682ad302", - "module": "DQqqBhm", - "name": "ibjNBXuDkjpSjEk", + "address": "688f07e88dfa2f7d890e34ea9e63cba557678f69ec1653a27a14157184fe4c06", + "module": "FefTzMxCWpSZ", + "name": "rnmSHCOcwfoQtN1", "type_args": [] } } }, { "struct": { - "address": "47f21e96adfe45ba131ef7a125501ccae1261fc78089ba5308ae84a356f2bb51", - "module": "LwpWvqKug", - "name": "NRKYXugJOpy2", - "type_args": [] - } - }, - { - "struct": { - "address": "4edba3a64aabefd88bb8d4277524a8d8ce1d54b6b731147a310ea667265fe6b1", - "module": "RdhfMBNnukrjIqhVVkCEzszGhwolWx", - "name": "wcBQHYeXXnTQo", + "address": "55a60351155d914f98806fd3c8ca1a9b0318d505448519f2b13fd16038c18acb", + "module": "qouZKJaxddeI", + "name": "FZWWqWBvPhXMQIqNHBgCgvp", "type_args": [] } } ], "args": [ + "23bed6af8448e4428a2d6af7eb957bdae932d161de1efd530a65c68044300b4a", "01", - "965cc75f7e165519", - "88d5d9f1f9d09da3", - "a5b44163a83bcd8f", - "00", - "b86cd934672cabddb3938959beb85848", - "4435e13ddd24862fdeb93f44ab31a10e62d978f6d5952fc09234ad8dfde914c8", - "3d", - "ea4df748ffe7484c5ddb343806f0d27353aca094eb30a37bf5e1d59babda026f", - "01aa605e59aceebc380d4a5b19f1ab1504f50f340a07c3555500e2004f77c6dc" + "39b06f23c05a0cf1", + "829db1554e59fb0b", + "26", + "ce", + "9433c1c7bd507716b06cb72368f51153", + "f495573280c9bacb6d036a34a12342cd", + "146deaa34d074241" ] } }, - "max_gas_amount": "5728441886086910062", - "gas_unit_price": "1056590787584835226", - "expiration_timestamp_secs": "7238184894938488041", - "chain_id": 60 + "max_gas_amount": "1019463178458680298", + "gas_unit_price": "10482196570888853610", + "expiration_timestamp_secs": "14142035163590226473", + "chain_id": 99 }, - "signed_txn_bcs": "c5060b74d8c2b77634d479babf1116ec5e19873da563694e5370446e8d184014b017d514c29cef24024d9affd320e94695392db9df76b911933a79d9d593574fbd69db7b799334ebd006455f436f696e1661444c6f6876764976514b746379414378516d6158390a060790d2615696547fdb8393b2a8b6946a5298cdaaa72dde97371f1950b94243dc8c104b765174677a4a41574e5272524453371747635955486671627756686441506c467473756879666e000607ea5dee94e3230121db18557fe26185a802d7e6a05211865b69df4006a130327f044d48473208567963794e6670790007f3ce42c13d3881af5aac0dae2119d6dff76f745ecc3c78bd29f501d64789b6f31867575657654e564d574554587375696a78455274666543351b6f41664855556f594f52745676524f696c6e55456668767571683400060602060607bcb067e6b1499c3e6204ea45da1ce0b210b77991d7edbeb1fe9298b472df0df80f7977545949424c6b6f734a43566676084b724477707176360007f11988aab4ee79dfc570b7437e0c0bd4def6cb891a7347ae094e4b3c258cd5161f7979744c654f6161734f4f727671784473767659556c716f4768766a6761380d784561484f5157486970584d5600070333cd96931f1bad3d82db0262ea607436d542029de57e8e3c5121dedae396c5206f4b566e63597745464961424c5371676f48664b556153734e517059746c54391f796357427a75726943516e47586f77636761486b584970556f47534e514133000607372d7507a38d095e855bb72e331c47441797854e3aa0a265525ca001682ad302074451717142686d0f69626a4e425875446b6a70536a456b000747f21e96adfe45ba131ef7a125501ccae1261fc78089ba5308ae84a356f2bb51094c77705776714b75670c4e524b595875674a4f70793200074edba3a64aabefd88bb8d4277524a8d8ce1d54b6b731147a310ea667265fe6b11e526468664d424e6e756b726a49716856566b43457a737a4768776f6c57780d7763425148596558586e54516f000a010108965cc75f7e1655190888d5d9f1f9d09da308a5b44163a83bcd8f010010b86cd934672cabddb3938959beb85848204435e13ddd24862fdeb93f44ab31a10e62d978f6d5952fc09234ad8dfde914c8013d20ea4df748ffe7484c5ddb343806f0d27353aca094eb30a37bf5e1d59babda026f2001aa605e59aceebc380d4a5b19f1ab1504f50f340a07c3555500e2004f77c6dc6ed0ad788b837f4f9abef126b9c3a90ee91c68f9cf3273643c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ccbd41f5b7ee3024137768cb15898712ce2c7d5e988113c979777b67f9578919a479050c398953e55c7c96ecf78bd019f822e044d6250e3e4bca79c40f3fb709", + "signed_txn_bcs": "257527d9b8f0e72f0dda5c1b8a310b223b79d7db732047478ee6f11222f91731bdfcc7ff3c0af0b2026ae8e083bd57f456c2c58450c26b97edf60b8ab6badb48aacded72a841dd5b5214567752596f466d484b584a785341375f436f696e0c475256496e6a5847597452340606072cad8a4430c6e8065be9890108095ab704067f751e18c9a1e1eb3cde5d49389705706b534577056445695764000607de01266242e66fd40bfe5a784f5909bd3e1bf76670789295207afe2a063e3ed8097a62504e526e654c431d6e43785171774745437863586e6a547872714b56487a6a705a774a424b00060785779fc9877a0dcb4f7a1d0291e46f612354927bb537c37e66b1b85b20a8545508594b576a62756e331243437a625a766866636242584b6262736c320006030607688f07e88dfa2f7d890e34ea9e63cba557678f69ec1653a27a14157184fe4c060c466566547a4d78435770535a0f726e6d5348434f6377666f51744e31000755a60351155d914f98806fd3c8ca1a9b0318d505448519f2b13fd16038c18acb0c716f755a4b4a61786464654917465a5757715742765068584d5149714e4842674367767000092023bed6af8448e4428a2d6af7eb957bdae932d161de1efd530a65c68044300b4a01010839b06f23c05a0cf108829db1554e59fb0b012601ce109433c1c7bd507716b06cb72368f5115310f495573280c9bacb6d036a34a12342cd08146deaa34d074241eacb9e055cdc250e6ad8a5813e3e789129f2e0b60d9a42c463002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b19904e5c0c372eebad399a9861ef92d01d725d42fb4342f0e6d404cc36e127b9683dd838d09d83a7e0a2cf1e3f78bff811d3e7edf6ce0f755d0fc7aa068dd01", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "7254d81e6cd63469d0aeed8fbb476479b948af8eeffeb15f34be6842fbf0bac6", - "sequence_number": "18425695080377418547", + "sender": "296a4cee8bb28c535f0ea3679d099e007e89b193a1e1af9e79ef63b5d8c95972", + "sequence_number": "16948937482465331656", "payload": { "EntryFunction": { "module": { - "address": "9f822008cc50b496e5f92555c8a3bc642d8368339732c5d997e75bc0845aa6b9", - "name": "ksNwXIpN_Coin" + "address": "2cbe99b112f03e272e4dd5764dd67664caaccd3894253b2817b29a4a27a60a14", + "name": "uyrzFEEzOYvZZrQepa_Coin" }, - "function": "eKDZhMPLwuQJfLMbrch6", + "function": "hkGOVee", "ty_args": [ { "struct": { - "address": "532465ba437df458f0cbda3a6ac9b2d6cd8e5ba486d85c0b4dbee8fdee4888e5", - "module": "HalCmreIzHWOKDpvQ", - "name": "q", + "address": "5e44c552952ad191a75f2d853cd0f99b7c62d641e7b82c8343ba8e40711aed2f", + "module": "xuTtkrHaTINNqpyQsHkEkCUiDupa5", + "name": "bnOnHIgAPtUvAOukYvYRw", "type_args": [] } }, + { + "vector": { + "struct": { + "address": "6cfd87928c20ea3f3eb92942b45631e480dfd6fa84f91bbbf5fc7f48ba522a37", + "module": "VyoVVKJSsWKyWDm2", + "name": "fCmDqktVEohvhartHPcxrmgQ7", + "type_args": [] + } + } + }, { "struct": { - "address": "831b1513110f2916e1bf4949f3b62752be3f2ecbc4cc27a057bcfb06cab444c0", - "module": "VjrOY5", - "name": "CiqYXOVFdTvTnLi4", + "address": "4f7ada52a7b0ec0af67885272fea779a93ae4ace8074e87180fb9f72590bccfe", + "module": "EgGyel9", + "name": "WbWjwCMsFpiajz5", "type_args": [] } }, { "struct": { - "address": "f2d60796d768bbcc9533f401ac3312411bbbdea3dfb6cd40ae4155ee0e993239", - "module": "YyNGJBwVlcUiSFrTdnVdczfOUarN9", - "name": "LOmUQtaOGNXykCYvbPrbLBX1", + "address": "c6315465f3b9e3e6d6b7a5b0274486d4b7ebbc1710eb70fc35b24647850515ab", + "module": "LisCD", + "name": "AO2", "type_args": [] } }, { - "vector": { - "vector": "u64" + "struct": { + "address": "33cae74acbdf24b28438727a1dae624275f72b362c670af08b0e298f78760fb6", + "module": "CTBnonPFtjavGlAjqpRFsAxgrcjcF8", + "name": "wHdhTehrftcWRszZIpnZF", + "type_args": [] } }, { "struct": { - "address": "b00f8e4b6864958e29cb8e72b8af508a8a452f8f5bff57d1238f1d98d53e83b1", - "module": "cgCrNjRVEWSmvvZNSs", - "name": "sPXzCwMydK", + "address": "a847955df25f5a8252001d36886356be2617b44125825e635ce66861c87aa081", + "module": "SoWoQgDAUzuHgNOwQoLHGrEu", + "name": "OAPWesKZZlycdEjPJL3", "type_args": [] } }, { "vector": { "struct": { - "address": "c78ebe83eb4973283459cb133f10db368fa77296571a37f819d92c0886536fc5", - "module": "XeAomAYZkgpVWTJUdjmRTExa", - "name": "SEClvMeXzuSYUhFJwdMth5", + "address": "14c58ccf9bfa629f45fe36c4491f175f7ee16df237bd450d348c216ec06ccf63", + "module": "HbLcefVu4", + "name": "SCsrRGEyfQ", "type_args": [] } } - }, - { - "vector": "u64" } ], "args": [ - "10258ac91238ec19", - "15", - "718a1ff0133c0ff998d730d55fc8921a", - "8a" + "6933cfd988544e4d1116a53cbd50bb8c98b91aed5b59723b6584f60c65ede80f", + "b4456c26a607b4b952d03f781b28c311f0056c231b355cf92e1730ab083ebb00" ] } }, - "max_gas_amount": "9642444206990112737", - "gas_unit_price": "8269609754187846819", - "expiration_timestamp_secs": "7138260881688368457", - "chain_id": 74 + "max_gas_amount": "18433573115159890309", + "gas_unit_price": "2706418751625183888", + "expiration_timestamp_secs": "9888836989083813752", + "chain_id": 150 }, - "signed_txn_bcs": "7254d81e6cd63469d0aeed8fbb476479b948af8eeffeb15f34be6842fbf0bac633038f550d38b5ff029f822008cc50b496e5f92555c8a3bc642d8368339732c5d997e75bc0845aa6b90d6b734e775849704e5f436f696e14654b445a684d504c7775514a664c4d62726368360707532465ba437df458f0cbda3a6ac9b2d6cd8e5ba486d85c0b4dbee8fdee4888e51148616c436d7265497a48574f4b4470765101710007831b1513110f2916e1bf4949f3b62752be3f2ecbc4cc27a057bcfb06cab444c006566a724f59351043697159584f5646645476546e4c69340007f2d60796d768bbcc9533f401ac3312411bbbdea3dfb6cd40ae4155ee0e9932391d59794e474a4277566c63556953467254646e5664637a664f5561724e39184c4f6d555174614f474e58796b435976625072624c4258310006060207b00f8e4b6864958e29cb8e72b8af508a8a452f8f5bff57d1238f1d98d53e83b112636743724e6a52564557536d76765a4e53730a7350587a43774d79644b000607c78ebe83eb4973283459cb133f10db368fa77296571a37f819d92c0886536fc5185865416f6d41595a6b67705657544a55646a6d5254457861165345436c764d65587a7553595568464a77644d746835000602040810258ac91238ec19011510718a1ff0133c0ff998d730d55fc8921a018ae1372b1cebd7d085a3d478d5418ec37249151aa7733210634a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401ff24fde13a4f79dbfb36c0f68a36f18dd2823dfb3082014575b091558faf697e195a3cd1c242c71db30d2ad976830c9233d8b50d5079f29730b1dbf6b78e304", + "signed_txn_bcs": "296a4cee8bb28c535f0ea3679d099e007e89b193a1e1af9e79ef63b5d8c95972c849a64ad7b836eb022cbe99b112f03e272e4dd5764dd67664caaccd3894253b2817b29a4a27a60a14177579727a4645457a4f59765a5a72516570615f436f696e07686b474f56656507075e44c552952ad191a75f2d853cd0f99b7c62d641e7b82c8343ba8e40711aed2f1d787554746b72486154494e4e7170795173486b456b435569447570613515626e4f6e4849674150745576414f756b59765952770006076cfd87928c20ea3f3eb92942b45631e480dfd6fa84f91bbbf5fc7f48ba522a371056796f56564b4a5373574b7957446d321966436d44716b7456456f68766861727448506378726d67513700074f7ada52a7b0ec0af67885272fea779a93ae4ace8074e87180fb9f72590bccfe0745674779656c390f5762576a77434d73467069616a7a350007c6315465f3b9e3e6d6b7a5b0274486d4b7ebbc1710eb70fc35b24647850515ab054c6973434403414f32000733cae74acbdf24b28438727a1dae624275f72b362c670af08b0e298f78760fb61e4354426e6f6e5046746a6176476c416a717052467341786772636a6346381577486468546568726674635752737a5a49706e5a460007a847955df25f5a8252001d36886356be2617b44125825e635ce66861c87aa08118536f576f51674441557a7548674e4f77516f4c4847724575134f41505765734b5a5a6c796364456a504a4c3300060714c58ccf9bfa629f45fe36c4491f175f7ee16df237bd450d348c216ec06ccf630948624c6365665675340a534373725247457966510002206933cfd988544e4d1116a53cbd50bb8c98b91aed5b59723b6584f60c65ede80f20b4456c26a607b4b952d03f781b28c311f0056c231b355cf92e1730ab083ebb0085c94b3e1535d1ff904213f083218f2578871528d9343c8996002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f85854c6c6ebbc2208a99ad9682ed99fec7f22fb7873166077cd7a566f061560ab9a9d81cf7bc0e72e42ffeecef6d70bd1e96a00edcb1067cde2cde396691207", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "9fa37e9249deb0745364a55ab954875a52f3e4fc267d468295017ee89ef2eda4", - "sequence_number": "5440367760114619002", + "sender": "07011ab22a2d46a7a5bace8bbe0fecd63e8a43c99a0161d7c605a5bd7796391d", + "sequence_number": "14383908686984374315", "payload": { "EntryFunction": { "module": { - "address": "e3213dcf59716f356786e68ed618ac575632846940c9351bc855deb6f95aae61", - "name": "XgIGrNQCfFHTrranyEgidjAuRG6_Coin" + "address": "0221c4ab6cc3cdec859c22fc2efc42149cfedae37180ce2f8a1a13a55dc18f27", + "name": "LZIkICdTZnEeURuTVpTgvAxuXitK7_Coin" }, - "function": "SKwNWePYJyTHAeRpZKvwevtH6", + "function": "AeLqou4", "ty_args": [ { "struct": { - "address": "8d6a4364b105765c8be7684c5b00afe6117a71569c40694bc075f4f910ca97e5", - "module": "MusMwIshTNPkUvCn", - "name": "JXLluQSKqqlU6", + "address": "1f64d13cf3fa7bf0312b7f80a4b586a9515970e72f40b8b3fd3aa43fcc7a48ce", + "module": "nTxWKsxkZhbHyaNSUJIUQi", + "name": "kiPddEDtfZavbNbryVVbTAuATStogaky0", "type_args": [] } }, { "struct": { - "address": "1fc5245eefc2e42b7a8f5355ae03990c3c92ce07a096d21168873bb3adbbc79a", - "module": "AjtfUWbNmQvCcyrOFBSKz", - "name": "beTkiyfsqioWvqAl6", + "address": "adc085e5049cd811f6779e0d679725301d92c976bbeaee4e53c1235ce91e54bd", + "module": "XcvjgMfsasHczWYNZHJiGoeeYAmt", + "name": "lzAaaBQqfQnlkhYNovCASjehLSotSUq", "type_args": [] } }, + { + "vector": { + "vector": "address" + } + }, { "struct": { - "address": "80e5a4d6d14747a40e611cad85d89bf849340b41df21d1d19231500d5b4453f2", - "module": "whACmG5", - "name": "QECjYfzRnOewSnZwugrbMKNupSaIWZa2", + "address": "9c43d9bced74b85f787b64c1deebbfa2bf4ccd715dbc885b5a4ede31e93b09bb", + "module": "KRXioruWBjTzbrWzzLcwscGvA0", + "name": "vcGdQLsfL4", "type_args": [] } + }, + { + "vector": { + "vector": "bool" + } + }, + { + "vector": { + "struct": { + "address": "178780bad8ea54ffa6652d9f23fd71c3ab59fcb4f1dfde7f20231b953616ec30", + "module": "zcushBPHoFHpMGpaGSvZ8", + "name": "IOzPYJqfCFuzeaNxbsblOTEHcmfUHQ", + "type_args": [] + } + } } ], "args": [ - "7f", + "92", + "63", + "074f5f2b5112e5ce2f0b70201d3191ed5c7caa9462cf866cd9840e397905f0fe", + "dcfbe536fc66b72ecdb77743cd9427fe", "00" ] } }, - "max_gas_amount": "11639940403674919501", - "gas_unit_price": "6877393875617437492", - "expiration_timestamp_secs": "9119006124175631920", - "chain_id": 49 + "max_gas_amount": "14770297084228111933", + "gas_unit_price": "17612041824152283443", + "expiration_timestamp_secs": "13591195005148563315", + "chain_id": 184 }, - "signed_txn_bcs": "9fa37e9249deb0745364a55ab954875a52f3e4fc267d468295017ee89ef2eda47a921e4da711804b02e3213dcf59716f356786e68ed618ac575632846940c9351bc855deb6f95aae612058674947724e5143664648547272616e79456769646a41755247365f436f696e19534b774e576550594a795448416552705a4b7677657674483603078d6a4364b105765c8be7684c5b00afe6117a71569c40694bc075f4f910ca97e5104d75734d77497368544e506b5576436e0d4a584c6c7551534b71716c553600071fc5245eefc2e42b7a8f5355ae03990c3c92ce07a096d21168873bb3adbbc79a15416a74665557624e6d5176436379724f4642534b7a116265546b6979667371696f577671416c36000780e5a4d6d14747a40e611cad85d89bf849340b41df21d1d19231500d5b4453f207776841436d4735205145436a59667a526e4f6577536e5a77756772624d4b4e7570536149575a61320002017f01004db2c247206089a134d79fb84a69715f30a61960c1378d7e31002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444044838a0133a927c315eb420d6a7fc4cb06373f549025c80c44d8ec0bb51aaa0e2f43c65ef338cd7c4f0aff26226b3e99ff4eeeeec19224fe274fa6615fdac70c", + "signed_txn_bcs": "07011ab22a2d46a7a5bace8bbe0fecd63e8a43c99a0161d7c605a5bd7796391d2be85bd9bde89dc7020221c4ab6cc3cdec859c22fc2efc42149cfedae37180ce2f8a1a13a55dc18f27224c5a496b494364545a6e45655552755456705467764178755869744b375f436f696e0741654c716f753406071f64d13cf3fa7bf0312b7f80a4b586a9515970e72f40b8b3fd3aa43fcc7a48ce166e5478574b73786b5a68624879614e53554a49555169216b69506464454474665a6176624e627279565662544175415453746f67616b79300007adc085e5049cd811f6779e0d679725301d92c976bbeaee4e53c1235ce91e54bd1c5863766a674d6673617348637a57594e5a484a69476f656559416d741f6c7a41616142517166516e6c6b68594e6f764341536a65684c536f7453557100060604079c43d9bced74b85f787b64c1deebbfa2bf4ccd715dbc885b5a4ede31e93b09bb1a4b5258696f727557426a547a6272577a7a4c63777363477641300a76634764514c73664c34000606000607178780bad8ea54ffa6652d9f23fd71c3ab59fcb4f1dfde7f20231b953616ec30157a637573684250486f4648704d4770614753765a381e494f7a50594a71664346757a65614e786273626c4f544548636d6655485100050192016320074f5f2b5112e5ce2f0b70201d3191ed5c7caa9462cf866cd9840e397905f0fe10dcfbe536fc66b72ecdb77743cd9427fe01003d8e6714f1a2facc3369ebf9b98a6af47387f112d99f9dbcb8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440918e9cfc1402a9f003a716ba53c29b20eef9a487673f0384130dce6f5172b773046f8eba37d15c52640a8cd8267045b0d9386812f28030a7ed1b5a14788a6804", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "211b76aa0eb38de432a867e89b7653078289fb149c2c7f27f4bccd1de358fedb", - "sequence_number": "16672653382472951230", + "sender": "5db903504d1e56d51ed9c486dc34233eec2bd24ba8e4299eda7689f94715b973", + "sequence_number": "9237185929491568159", "payload": { "EntryFunction": { "module": { - "address": "aaae3c1c17e7b00c1638166e720c137b161d8d34d6c89ad36285cadbb66948c5", - "name": "pKbyGHIVTrpp3_Coin" + "address": "a4601d808a04bb26814df344840a3531e8406b3d8dbc1a25b4782644e7c98e12", + "name": "bqrUzbFADSRPYUKOpuClpNgxbiHhPm_Coin" }, - "function": "FecKCcpIOCuUkNkWkLHXrmoEqJpJg", - "ty_args": [ - { - "struct": { - "address": "56fe145a0cbecc2ddcce76c624c283d1a252b6d95919f8f7cdf3bd0a09ccc165", - "module": "eiZfrhMZjgk6", - "name": "GyNuKiaTJgOkgVxgFYYeJBeS", - "type_args": [] - } - } - ], - "args": [ - "2a447964c7a6e460141710c7d872103d", - "65f23d7d081ee4f6", - "b4c16d8fab7bd558" - ] + "function": "qhxNYjEuRpbaHIGOt", + "ty_args": [], + "args": [] } }, - "max_gas_amount": "9274521249931839578", - "gas_unit_price": "4427760382647208866", - "expiration_timestamp_secs": "10084278143191037357", - "chain_id": 173 + "max_gas_amount": "10607121249944982121", + "gas_unit_price": "5968632341615920307", + "expiration_timestamp_secs": "15415890371698324302", + "chain_id": 234 }, - "signed_txn_bcs": "211b76aa0eb38de432a867e89b7653078289fb149c2c7f27f4bccd1de358fedbbee58375ea2961e702aaae3c1c17e7b00c1638166e720c137b161d8d34d6c89ad36285cadbb66948c512704b62794748495654727070335f436f696e1d4665634b436370494f4375556b4e6b576b4c4858726d6f45714a704a67010756fe145a0cbecc2ddcce76c624c283d1a252b6d95919f8f7cdf3bd0a09ccc1650c65695a6672684d5a6a676b361847794e754b6961544a674f6b67567867465959654a4265530003102a447964c7a6e460141710c7d872103d0865f23d7d081ee4f608b4c16d8fab7bd5585ac8ff33f0b7b580a20b3cd69b90723dad3523dd8a8df28bad002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f286b2088dc127928a1ba9c6bad0eb18e7b2561ccf58916f64f442fc73aacabf88b7be6d086244ce01fa9274f1d6fe96ca1fd31cee578a11d01c7e8f184dd90f", + "signed_txn_bcs": "5db903504d1e56d51ed9c486dc34233eec2bd24ba8e4299eda7689f94715b9731fd69483a913318002a4601d808a04bb26814df344840a3531e8406b3d8dbc1a25b4782644e7c98e1223627172557a6246414453525059554b4f7075436c704e677862694868506d5f436f696e117168784e596a4575527062614849474f74000069d277f093103493b3c4ecd47dd7d4524e7371bd9d3ef0d5ea002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409096f12867efdb7ec0da7c0e68ceee58ea52eed2d50f24d45ac7e006775caa14a6b02e3c222bb17c3bb289f76286e44f06b291c4b341d0329a59310d17d77009", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "d8bb3d6f84e4207faf1b0050be34fbf697514d5fb5cce2b1adb116be4ab544c4", - "sequence_number": "9030378947015319143", + "sender": "a7a6ad8a57493204fc0ec8202b5abb3d80352876bbd3bc7c96a55a6d3ad00941", + "sequence_number": "4426527547749008489", "payload": { "EntryFunction": { "module": { - "address": "53d9c1c3bd39399c2880c9c4db594ef9a2929a960c42172a3882abd441300635", - "name": "YtKWLdtzeteFnGz_Coin" + "address": "2206a247c832960eca621d9397e5c7885e470eaa0fcecab886c2abd359fb9e56", + "name": "AnOF_Coin" }, - "function": "FcvPsiSiGvVdi2", + "function": "KcYxjMmZecfbEXtChdWIFFjn", "ty_args": [ - { - "struct": { - "address": "b309acfd6f30dd9e90ee56bd6027e8ce820e6c3c486bc3438ccb73ee72bdde7c", - "module": "zdlSGksImmemhqC1", - "name": "eVKEQI", - "type_args": [] - } - }, - { - "struct": { - "address": "6a4d9253e80a240fd8bb181bd8002f7a60a02ccc6a7264c3eee7fb23e5bb46d4", - "module": "zZelUVPXLgFvDqvbywGfRkW", - "name": "QESHCZYYOiWOL5", - "type_args": [] - } - }, { "vector": { "struct": { - "address": "1cefe1495ae10e87c22a854ca0ec5cff098354ab139b9e78916118acf25aef93", - "module": "JtBSwNNpw2", - "name": "CeSFYF7", + "address": "abc8bb008c7b88c195b10ba4632a29247660ef666366c76f1eda2338a69c6777", + "module": "v4", + "name": "bvrYRZJfLHhbBzpsBxT6", "type_args": [] } } }, { "vector": { - "vector": "address" + "struct": { + "address": "d3b094ee726c415f5099ba66e3e66f1d308c1d5a70ecbdff5c875b592fc4f571", + "module": "ezrWjbCrWqDmSSsrGMLHrM", + "name": "NAsijOnBsMEQ", + "type_args": [] + } } }, { - "struct": { - "address": "285c936601557a454a251cabd8d89c22e56d56b814d8667fdb6e5568d7f58503", - "module": "GpACBGy", - "name": "HaKtYZGVlQRmnnvIZQyoZqFucKXsYsHI9", - "type_args": [] - } - } - ], - "args": [] - } - }, - "max_gas_amount": "11474648439998629906", - "gas_unit_price": "4680695588779612505", - "expiration_timestamp_secs": "4211073660057338776", - "chain_id": 122 - }, - "signed_txn_bcs": "d8bb3d6f84e4207faf1b0050be34fbf697514d5fb5cce2b1adb116be4ab544c4679e03acce59527d0253d9c1c3bd39399c2880c9c4db594ef9a2929a960c42172a3882abd4413006351459744b574c64747a657465466e477a5f436f696e0e46637650736953694776566469320507b309acfd6f30dd9e90ee56bd6027e8ce820e6c3c486bc3438ccb73ee72bdde7c107a646c53476b73496d6d656d687143310665564b45514900076a4d9253e80a240fd8bb181bd8002f7a60a02ccc6a7264c3eee7fb23e5bb46d4177a5a656c555650584c6746764471766279774766526b570e51455348435a59594f69574f4c350006071cefe1495ae10e87c22a854ca0ec5cff098354ab139b9e78916118acf25aef930a4a744253774e4e70773207436553465946370006060407285c936601557a454a251cabd8d89c22e56d56b814d8667fdb6e5568d7f5850307477041434247792148614b74595a47566c51526d6e6e76495a51796f5a714675634b58735973484939000012c89bfcf5233e9f5959f2aed62bf54098c3b8be2ebd703a7a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440552b282d9e112043faab32bb0117e2fabc79276e622a4a92a909c72ac4ecdfdca10c243ac39213c5e54611b5f4abf908e54d970ea658caacbc9054346e64d003", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "ae5a6ea9573592de5a687ae72f045956eae0f8d1674bd96205ea57798ab67afe", - "sequence_number": "3723571107033368582", - "payload": { - "EntryFunction": { - "module": { - "address": "778c04d799ac2e3f2c516342eaa2cc263cea5f42852a913eb2d8d219fe8f0231", - "name": "acYiCEtRXfySFczuf_Coin" - }, - "function": "CaMqrMdiABKkEHwBJYX8", - "ty_args": [ - { - "struct": { - "address": "b6279c32bfaf0e363bed44be780f8e50ece07c0cefcbe2e71abed3dbca645ef3", - "module": "cOhCV", - "name": "HYNZVQtBEDYZcSFvLGKO", - "type_args": [] - } + "vector": "u64" }, { - "struct": { - "address": "88f44a05333eb8370e7d3988fc5efd0db27e7cdb9d6511ddd384aef7617e06dc", - "module": "CnczVFITRrrougDOB0", - "name": "WJyGLcjneHqAijNVCSTGxMvmHCPn9", - "type_args": [] - } + "vector": "signer" }, { "vector": { "vector": { "struct": { - "address": "580e2d9bbd479b135588f20586f7bfa606b7c146b2ae92ea1e71301454f14c9f", - "module": "IxyhST8", - "name": "G", + "address": "9afbb4afea3a7cc811ab9bdcecfbaa72d6517a19139443b6162d4d9a52f6ba5c", + "module": "mxQZxltDpFwlWIDzRTxLnkCQ9", + "name": "CyUOjWAOHxlIgSBfUKENW", "type_args": [] } } } }, { - "struct": { - "address": "25e82505ca23e1687b8afae8c6b55beac01bd51dec15f284e56c0688e302254b", - "module": "wcfsJzgRAuzZKsTYAoUvc", - "name": "KEaXMnOaimkQwDiLTzBcsvKOWV3", - "type_args": [] - } - } - ], - "args": [ - "1d", - "0d6ecf8e024b5025", - "bcbf840e268c3f4b", - "d7", - "d34045cecdf93b4931eff5a81969d450", - "ad", - "6dd066ea13c357f8f70e1bac1cc45420", - "0af75f1f5b10ddc8", - "05cd278e74bdc88c34623ef352e9696f" - ] - } - }, - "max_gas_amount": "5555942518196952427", - "gas_unit_price": "6134359657424957727", - "expiration_timestamp_secs": "8244092837585326127", - "chain_id": 4 - }, - "signed_txn_bcs": "ae5a6ea9573592de5a687ae72f045956eae0f8d1674bd96205ea57798ab67afe06c8a18a31c8ac3302778c04d799ac2e3f2c516342eaa2cc263cea5f42852a913eb2d8d219fe8f02311661635969434574525866795346637a75665f436f696e1443614d71724d646941424b6b454877424a5958380407b6279c32bfaf0e363bed44be780f8e50ece07c0cefcbe2e71abed3dbca645ef305634f6843561448594e5a565174424544595a635346764c474b4f000788f44a05333eb8370e7d3988fc5efd0db27e7cdb9d6511ddd384aef7617e06dc12436e637a564649545272726f7567444f42301d574a79474c636a6e65487141696a4e5643535447784d766d4843506e3900060607580e2d9bbd479b135588f20586f7bfa606b7c146b2ae92ea1e71301454f14c9f07497879685354380147000725e82505ca23e1687b8afae8c6b55beac01bd51dec15f284e56c0688e302254b15776366734a7a675241757a5a4b735459416f5576631b4b4561584d6e4f61696d6b517744694c547a426373764b4f5756330009011d080d6ecf8e024b502508bcbf840e268c3f4b01d710d34045cecdf93b4931eff5a81969d45001ad106dd066ea13c357f8f70e1bac1cc45420080af75f1f5b10ddc81005cd278e74bdc88c34623ef352e9696f6b5d9e9d48ac1a4d1f314d719b9f21552f909db7c1e6687204002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f52addf527f68b66f70ea85b69d1c85626d8552f1de9a719c1d3bb7cf9c66e7252c88277327da30bace4f415309553bc96fd1eac3722ff603384842333de5c09", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "d32f8616dc870f85b92f0feccc75869549166ecd4856f553a71a4dcb7e65dea8", - "sequence_number": "8115358981140172803", - "payload": { - "EntryFunction": { - "module": { - "address": "468bc8e2d64c563f4129822d87ec101e1f3c292584e6deab588cb19ad6a90090", - "name": "cEma_Coin" - }, - "function": "aDCXeVQFzjEfvptgVv3", - "ty_args": [], - "args": [ - "aa8ff2be0632eddf55289cb5fe0a74f58e5316c38b7de87760d60045ba107d3b", - "00", - "01" - ] - } - }, - "max_gas_amount": "9075634731442254814", - "gas_unit_price": "4439356434626085384", - "expiration_timestamp_secs": "15935088546365993895", - "chain_id": 175 - }, - "signed_txn_bcs": "d32f8616dc870f85b92f0feccc75869549166ecd4856f553a71a4dcb7e65dea803d0a20fff8b9f7002468bc8e2d64c563f4129822d87ec101e1f3c292584e6deab588cb19ad6a900900963456d615f436f696e1361444358655651467a6a456676707467567633000320aa8ff2be0632eddf55289cb5fe0a74f58e5316c38b7de87760d60045ba107d3b01000101de33d016b421f37d08823b1528c39b3da7738aee9ace24ddaf002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444033dbc7ebc6061c52d872762524c397b529a0008d5383f7a9a0eab6638badad218b004fa5e2f6fd76f7dc5071c13a437a273b6d257c546c7cb1c0f5fd0726c200", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "70a73ea0d9e144d1f237abd5b1ce268f4ee63d3e8ff89c742740cf1892c8902c", - "sequence_number": "13602672635404385948", - "payload": { - "EntryFunction": { - "module": { - "address": "2ea69f001cb160a518f7d709a4ec8a3d83c66d7de1308ab2f14cb7d3e5619d13", - "name": "JwrKuEXMG_Coin" - }, - "function": "HLaLWUBGXZyaHzokKvzMiuSoEVSJXn3", - "ty_args": [ - { - "struct": { - "address": "2b0df83edb2dd02e23796438b5eeb5175dc27d61bc74924bb6b2c2af58dc8625", - "module": "dtFZED3", - "name": "vZDPytSMirIKMYHwB", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "d81266cda990d02b55b83ecc2deecdb360763675c35500ba7d0dc0b3e256a69b", + "module": "klQPKmWlHpoEWvgp8", + "name": "X", + "type_args": [] + } + } } }, { "struct": { - "address": "c3eaa3e33815d8355f591f8520f012cc5f55ff4563974bc8a9337671755e1481", - "module": "MZjppCXMDwmt", - "name": "VbY3", + "address": "4e5b399096c08f4dca96125ef1cc0232eae11f227a6a451644705947fb42465a", + "module": "lMaLjeCKItSmhSSAFCQFqi", + "name": "hplWJMcfnjJmoFQeREkgkePIAaJjlTRb", "type_args": [] } }, { "struct": { - "address": "3bd3b01df1f25c4bc2feeadde76db0d07e5cf3b61212af98508b44dc283cac0c", - "module": "ntaUfLhckil3", - "name": "nHtbTydXWOERHtVdJNKbgTlAkHbe5", + "address": "99869884b45e171032cfff1d5d628df869e817fb67bdf0b8998920ded60c7a69", + "module": "EhHIiaNxUuUGnVnTlIzJYm2", + "name": "mURgeNRixq", "type_args": [] } }, - { - "vector": { - "struct": { - "address": "7b65df9a3b1ce6464bd16abb69187d9bb808fd37acb7cfcabf6437414c425e65", - "module": "tNkvpMYUfIurrM", - "name": "IHOJnnghJaeGvmSqbudCc4", - "type_args": [] - } - } - }, { "struct": { - "address": "b66ec15047a8a2d14ed31537d3ed415e1e3239de9c9678b602baaed3533bb588", - "module": "HCjE2", - "name": "yjdeSZtxlK", + "address": "884f52f96c3e0286e5b75a4bfca39e9d466831ed1eeccf75c5c2845320bd4081", + "module": "bLYyVKMhbBVdAdMqmcd", + "name": "pbsPKCVplFSpryLaysO", "type_args": [] } }, { "struct": { - "address": "1cfc21d718cb8573a2fd671ea3ce103f8ae748f8d91ad71e6ea4b27d5da46e6b", - "module": "Nsw", - "name": "jEkEXUzu8", + "address": "7c45d8aab3d95b44dafde63a9dbdc54d9dd74bc10a37edca459140baa2a1d99b", + "module": "XTjHmvPHa", + "name": "QzBgKThLlmEca", "type_args": [] } } ], "args": [ - "e8941ec5b325b829bdb9db0e022cf89d2bd0c6dade5ffea765fe0bf0579196f3", - "7b7ab9299216c42b719a72fc6f77fe76" + "01", + "00", + "2bf13a5a72b8f627b99e922faea172ba" ] } }, - "max_gas_amount": "4297974395487375707", - "gas_unit_price": "5195197727577819216", - "expiration_timestamp_secs": "7310655633586021697", - "chain_id": 7 + "max_gas_amount": "2552599493318923495", + "gas_unit_price": "2517986953649707132", + "expiration_timestamp_secs": "5538611344957471463", + "chain_id": 240 }, - "signed_txn_bcs": "70a73ea0d9e144d1f237abd5b1ce268f4ee63d3e8ff89c742740cf1892c8902c9c7e341db166c6bc022ea69f001cb160a518f7d709a4ec8a3d83c66d7de1308ab2f14cb7d3e5619d130e4a77724b7545584d475f436f696e1f484c614c57554247585a7961487a6f6b4b767a4d6975536f4556534a586e3306072b0df83edb2dd02e23796438b5eeb5175dc27d61bc74924bb6b2c2af58dc8625076474465a45443311765a44507974534d6972494b4d594877420007c3eaa3e33815d8355f591f8520f012cc5f55ff4563974bc8a9337671755e14810c4d5a6a707043584d44776d74045662593300073bd3b01df1f25c4bc2feeadde76db0d07e5cf3b61212af98508b44dc283cac0c0c6e746155664c68636b696c331d6e48746254796458574f4552487456644a4e4b6267546c416b486265350006077b65df9a3b1ce6464bd16abb69187d9bb808fd37acb7cfcabf6437414c425e650e744e6b76704d595566497572724d1649484f4a6e6e67684a616547766d53716275644363340007b66ec15047a8a2d14ed31537d3ed415e1e3239de9c9678b602baaed3533bb5880548436a45320a796a6465535a74786c4b00071cfc21d718cb8573a2fd671ea3ce103f8ae748f8d91ad71e6ea4b27d5da46e6b034e7377096a456b4558557a7538000220e8941ec5b325b829bdb9db0e022cf89d2bd0c6dade5ffea765fe0bf0579196f3107b7ab9299216c42b719a72fc6f77fe765bd1bfe8f078a53b504831d2ce0c194841651ab390aa746507002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444074ae208bf0a9697cccd0e383d1b0ed58e93b407eaa03083243c34cb836bc1f4da542e9661d97dcd80c6abd1976e5485c242b99a0eaff7cb368d235d8b817a708", + "signed_txn_bcs": "a7a6ad8a57493204fc0ec8202b5abb3d80352876bbd3bc7c96a55a6d3ad0094169840f185a2f6e3d022206a247c832960eca621d9397e5c7885e470eaa0fcecab886c2abd359fb9e5609416e4f465f436f696e184b6359786a4d6d5a65636662455874436864574946466a6e0a0607abc8bb008c7b88c195b10ba4632a29247660ef666366c76f1eda2338a69c67770276341462767259525a4a664c486862427a707342785436000607d3b094ee726c415f5099ba66e3e66f1d308c1d5a70ecbdff5c875b592fc4f57116657a72576a6243725771446d53537372474d4c48724d0c4e4173696a4f6e42734d455100060206050606079afbb4afea3a7cc811ab9bdcecfbaa72d6517a19139443b6162d4d9a52f6ba5c196d78515a786c74447046776c5749447a5254784c6e6b435139154379554f6a57414f48786c4967534266554b454e5700060607d81266cda990d02b55b83ecc2deecdb360763675c35500ba7d0dc0b3e256a69b116b6c51504b6d576c48706f455776677038015800074e5b399096c08f4dca96125ef1cc0232eae11f227a6a451644705947fb42465a166c4d614c6a65434b4974536d685353414643514671692068706c574a4d63666e6a4a6d6f46516552456b676b65504941614a6a6c545262000799869884b45e171032cfff1d5d628df869e817fb67bdf0b8998920ded60c7a69174568484969614e78557555476e566e546c497a4a596d320a6d555267654e526978710007884f52f96c3e0286e5b75a4bfca39e9d466831ed1eeccf75c5c2845320bd408113624c5979564b4d686242566441644d716d636413706273504b4356706c46537072794c6179734f00077c45d8aab3d95b44dafde63a9dbdc54d9dd74bc10a37edca459140baa2a1d99b0958546a486d765048610d517a42674b54684c6c6d456361000301010100102bf13a5a72b8f627b99e922faea172bae7d41d05b7a76c237cd85b21cbaff122e77a2365ac19dd4cf0002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409d3f687dc57d4f7887d474b488c9cf13570329bc18689919c507cac1f7758a754ec298f2dd629f4aec8077079144178691f9670558f5bd473970c49d6ae1590b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "efaf905d9cbd28d3429c0568d9d50c6ad2e8ce866d924a7a0056ffdc52667522", - "sequence_number": "5410169994901629604", + "sender": "6bb033020106518e8791fadaf2f07f2896fa3ae619882c589f231cd7c966214c", + "sequence_number": "1758092874778925521", "payload": { "EntryFunction": { "module": { - "address": "2ed7ab95be2d704a725e79559bb1398cccc1749c36e5c9f7e0a8a859c2df5ee5", - "name": "JnAjeHRSAUYHApNZRC3_Coin" + "address": "02ba90a6526a64186c5db32b54d6b959850e6ca1c571e572549a3143c2cea975", + "name": "xHYCLBHVNyedIS_Coin" }, - "function": "SuvcBNZaqLzJcEpOJcldGQCHSHQviNvk0", + "function": "r9", "ty_args": [ { - "struct": { - "address": "cad8421bc2831956e2a689183fb7887743662bea748f03ba3f2b0a7f5802f260", - "module": "VsRqXcHzmgRqxEOeCRMRFgUbvLuHwr", - "name": "EGoNDcmZYW0", - "type_args": [] + "vector": { + "struct": { + "address": "f8ed1eb9dcfb4514423b4cb19e3589ca6689ce4d19f080a255c3ccbdea81d352", + "module": "tXdMUDlxwNJBSrhy", + "name": "xzQHlQuQKRsqMFaTWturr9", + "type_args": [] + } } }, { - "struct": { - "address": "a68e684afed1c64cc30f76b6fe12ad5542dcc58539e6859a7ffd9929d33710fe", - "module": "sEpQncZWVLBuOHUgFBsaZcrqdB8", - "name": "MbfUqumYoMKuKrPKIGtsWrkcvKwLk2", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "0c24c10a73457c72a6ddc935d95cdf20dc08b2dbe562dee4425c4e0ce24d3092", + "module": "vZmwrpkOMJtYQRCNF", + "name": "jLijxBWFqwrJTpKewPcS", + "type_args": [] + } + } } }, { "struct": { - "address": "d7e3fe63ae985a31c221390159a166d65ebb5048fa7f53ef9e010102386ad3d7", - "module": "KLSHfHnHsvFRSaknh", - "name": "YhIbxVeETPuEVhdY", + "address": "3ff8f9dbd319d8364aa10b55cf07844c8dc3eb9b4bdc415f637ee0f6d14d6ee0", + "module": "afSDIUgAPiOHPPrrpfBltiLGWF", + "name": "SVPglAqctajtACZhyokXLYEo", "type_args": [] } }, - { - "vector": { - "struct": { - "address": "ca7c99725f58cbc5b05c9f0e21c4ad90806c219464610e552c1ddcc266e2e61a", - "module": "xwdQESCtvfPgOg", - "name": "NsLIqwIjji", - "type_args": [] - } - } - }, { "struct": { - "address": "dc60cb3b28f0309f5aba62d3eaf82a3a2b8f39810f0afad8c9827471bed1d431", - "module": "cgU9", - "name": "AdCVYgYORXI4", + "address": "c2a9ccfedc3625dda71a3d7ade7665a7c7348ed3a2793d629a4a29aaf9717bf8", + "module": "lBKOlgeqGcVlQOY7", + "name": "xAm", "type_args": [] } } ], "args": [ - "c417741308b8aede", - "2c69d4b906524a23b725dc02c1d8c9cc", - "ec34ed88f290127adbab049e174656864db9a403dece49af62c06496ec9d4de0", - "00", - "0f", - "57", - "fc2d028aae80096b738a7ef927eeb1cb", - "cc8bd732701cb1d040e92b9df1376955b9d0da539e05159f32d100facc55bab7", - "ce83c4f04c67d73501fd07d862bdf9feb74dd7e2e1dcfb3cc301e45d8202f801", - "01fa876405a4639dc855ad7183be588d7cdb226b7d7096b2a7119bce0db0838e" + "01", + "2941dc907428c7c0", + "bdb1654b742755fc", + "32" ] } }, - "max_gas_amount": "11368655333997618484", - "gas_unit_price": "14055158318522351311", - "expiration_timestamp_secs": "296318824705683393", - "chain_id": 221 + "max_gas_amount": "3159814478235305041", + "gas_unit_price": "15465352455365793319", + "expiration_timestamp_secs": "5849613825024107381", + "chain_id": 21 }, - "signed_txn_bcs": "efaf905d9cbd28d3429c0568d9d50c6ad2e8ce866d924a7a0056ffdc52667522a4aa9630f2c8144b022ed7ab95be2d704a725e79559bb1398cccc1749c36e5c9f7e0a8a859c2df5ee5184a6e416a654852534155594841704e5a5243335f436f696e2153757663424e5a61714c7a4a6345704f4a636c644751434853485176694e766b300507cad8421bc2831956e2a689183fb7887743662bea748f03ba3f2b0a7f5802f2601e567352715863487a6d67527178454f6543524d5246675562764c754877720b45476f4e44636d5a5957300007a68e684afed1c64cc30f76b6fe12ad5542dcc58539e6859a7ffd9929d33710fe1b734570516e635a57564c42754f485567464273615a6372716442381e4d62665571756d596f4d4b754b72504b4947747357726b63764b774c6b320007d7e3fe63ae985a31c221390159a166d65ebb5048fa7f53ef9e010102386ad3d7114b4c534866486e487376465253616b6e681059684962785665455450754556686459000607ca7c99725f58cbc5b05c9f0e21c4ad90806c219464610e552c1ddcc266e2e61a0e7877645145534374766650674f670a4e734c497177496a6a690007dc60cb3b28f0309f5aba62d3eaf82a3a2b8f39810f0afad8c9827471bed1d43104636755390c416443565967594f52584934000a08c417741308b8aede102c69d4b906524a23b725dc02c1d8c9cc20ec34ed88f290127adbab049e174656864db9a403dece49af62c06496ec9d4de00100010f015710fc2d028aae80096b738a7ef927eeb1cb20cc8bd732701cb1d040e92b9df1376955b9d0da539e05159f32d100facc55bab720ce83c4f04c67d73501fd07d862bdf9feb74dd7e2e1dcfb3cc301e45d8202f8012001fa876405a4639dc855ad7183be588d7cdb226b7d7096b2a7119bce0db0838e3425c7e4ca93c59dcfbe66f505f40dc3c1efd7ae66bc1c04dd002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b21e49a64155bd8fcf71b194fe4f5e33b04dc7b040fe5a51acef87c29f33d5390adee86202f6d302cf9db0060ccd4573955966846e0f0476cdd6edd732d4590e", + "signed_txn_bcs": "6bb033020106518e8791fadaf2f07f2896fa3ae619882c589f231cd7c966214cd1d957a3270066180202ba90a6526a64186c5db32b54d6b959850e6ca1c571e572549a3143c2cea97513784859434c4248564e79656449535f436f696e027239040607f8ed1eb9dcfb4514423b4cb19e3589ca6689ce4d19f080a255c3ccbdea81d352107458644d55446c78774e4a425372687916787a51486c5175514b5273714d466154577475727239000606070c24c10a73457c72a6ddc935d95cdf20dc08b2dbe562dee4425c4e0ce24d309211765a6d7772706b4f4d4a74595152434e46146a4c696a784257467177724a54704b657750635300073ff8f9dbd319d8364aa10b55cf07844c8dc3eb9b4bdc415f637ee0f6d14d6ee01a616653444955674150694f48505072727066426c74694c47574618535650676c41716374616a7441435a68796f6b584c59456f0007c2a9ccfedc3625dda71a3d7ade7665a7c7348ed3a2793d629a4a29aaf9717bf8106c424b4f6c6765714763566c514f59370378416d00040101082941dc907428c7c008bdb1654b742755fc013251045acb86ead92b27164b841ef89fd675a3c601c8002e5115002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e57190b3dc8566d1cc99b64e2b7a6d8a874ce97fa45edc594626d10aee79f929014a6d7fd67cc4e30cbe7d5f434021cb60fdd7978197ac4f62f47c93a803da0d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "c97c6ad1f365bcee0233c9ffcd8faa4a241661925660ab55f440412278288d52", - "sequence_number": "12123035773214832494", + "sender": "bafd4e0c2bbaec46393c66af927e328bf45d5bb11231cc079679423bc49322a2", + "sequence_number": "17544160367041894174", "payload": { "EntryFunction": { "module": { - "address": "820b0a2353f9702a42fc9bfd1f13587369a56c4aab2e4d67e33e3053ddebbf08", - "name": "WujXdeIIjVjmRsKxkleYY0_Coin" + "address": "0dbad0b1127180af1225938e88727dfccdddedb35237f7cb3b77539fbd397ba9", + "name": "CQdgZ2_Coin" }, - "function": "YIisHeQn5", + "function": "fYjCcFUjBloyKeDQbUiXEBIoNR6", "ty_args": [ - { - "vector": { - "vector": "u8" - } - }, - { - "struct": { - "address": "ff2b8a261483eff3c6bac6a51a4b837704807f4ac74edb431cab2ecdf24bed2c", - "module": "vsyzrrg", - "name": "ncFsHSoLYCBEsGvZGklcLf9", - "type_args": [] - } - }, { "struct": { - "address": "a50408a8c8b9cefdba2c428f5ea87c50618da0ce06282deba37c5040b1ebaa26", - "module": "JPjxjZQOWferqAfmMCG", - "name": "yqsVCxrRvuXG", + "address": "628f95e338200e1ca3287e010c175892733f73ec51d4c24d597de448a2f786c6", + "module": "FNXbDIcYwCEzpEWbenGHfHQUwQUE1", + "name": "GjTfLIlYWcELGPwsLhoWD", "type_args": [] } }, { "struct": { - "address": "a01040059c7a80c08957e1ed3d57d283ab1980ff8bd77438af3328043fa96fef", - "module": "CfEJuZMIOIyCy", - "name": "gpMMBTwAwfXdy", + "address": "1d4874b1eb6e48635261e70f3f23c8a359b47dc8bff14efe2f9969d6db261488", + "module": "tecKfKSaIPoxaS", + "name": "BwkydKDoSfPobNjAgbRWLrsQQzzykOUq4", "type_args": [] } }, { "vector": { "struct": { - "address": "916f0897855fae032d0738d67eb38711c77b827e62528cd356e7f686deffd41d", - "module": "oQKLXUkfYISlzUGE1", - "name": "RXGmRakSQZvbtFxPaFhGrQ3", + "address": "bd8b5eeddab04cde77003afd557bb4352e594166c631177c5a7d9be82f1b6e3e", + "module": "mqtLdSvZUXanQKCbLpTeRvOWVkNj2", + "name": "qJAFwJLMMXqTjMHhsCS", "type_args": [] } } }, { "struct": { - "address": "57f3ec98be03abbfbfa0905e8281f6b0274c0c64702dfd53bb75eab8ba74607c", - "module": "FToLsdNJXAQqWKm9", - "name": "PNJSoEXVIFzQ9", + "address": "571e64acf55c43cae2e6b7de0a529c6c9d1431d364fec8b9535b96cbf3537e5b", + "module": "UcMPIMLAtyXKVrtlQKlJpW", + "name": "Sp", "type_args": [] } }, { "struct": { - "address": "87d18f490eeee1727d3b7f6c1d1e75f036000a89ab7450f3d6f3941e708f8698", - "module": "HmreSwBZdmUJztlpNLToECbeVOB8", - "name": "H9", + "address": "288381f9391d5205ca56bd96504f179bb06f7cde296daa96d399926047f21e96", + "module": "RVDPVmupnJCiXWtTdYgnYOg5", + "name": "IsaCvmrREHdeUmqUxFDjrVWSp0", "type_args": [] } }, { "vector": { - "struct": { - "address": "3f0da91e22e9b93d00e38d0520a508ba44cd7296a0cb3e32e6e94af61458c954", - "module": "YpvZxFCYVqGHoFKbvtlfjSWVygvt4", - "name": "KiVReT", - "type_args": [] + "vector": { + "struct": { + "address": "12f0fa7d6c8a6657f7993b3d1c58d99613689810fc08d6bd76e4f123de97cf7d", + "module": "qJFvTuugvGSIuGjFGg", + "name": "FhYH8", + "type_args": [] + } } } }, { - "struct": { - "address": "b4b3339aac701607ea2d7937d6ae55e568ef581674a4a76e39985fdfbf998242", - "module": "AJYJYGIzGrRUgulKoPRzctvZOKznex0", - "name": "IlrSBHXOXJmTaSyFbVxfI2", - "type_args": [] + "vector": { + "struct": { + "address": "a7a4f7a5d5e8a29060762230f10f26a0433b0f4401b9acf76a87e7e2724da949", + "module": "oUXHaIoqexLOksCIPsbNPmABgZbWR", + "name": "EjNlfHyGtjYibRWUvIhsDahTO", + "type_args": [] + } } }, { - "struct": { - "address": "f7d0b635843482b5610852e35f9995228da20880d6d1add2491d176ec28c940d", - "module": "hbWax", - "name": "GaCEIONXYfcNzsXBdOrTaPQPA8", - "type_args": [] - } - } - ], - "args": [ - "b69d8849dfa1d6c6", - "00", - "b1" - ] - } - }, - "max_gas_amount": "12490997299298066625", - "gas_unit_price": "6903517920949035232", - "expiration_timestamp_secs": "4313428367871423487", - "chain_id": 101 - }, - "signed_txn_bcs": "c97c6ad1f365bcee0233c9ffcd8faa4a241661925660ab55f440412278288d526eb7d21dceac3da802820b0a2353f9702a42fc9bfd1f13587369a56c4aab2e4d67e33e3053ddebbf081b57756a58646549496a566a6d52734b786b6c655959305f436f696e09594969734865516e350a06060107ff2b8a261483eff3c6bac6a51a4b837704807f4ac74edb431cab2ecdf24bed2c077673797a727267176e63467348536f4c594342457347765a476b6c634c66390007a50408a8c8b9cefdba2c428f5ea87c50618da0ce06282deba37c5040b1ebaa26134a506a786a5a514f576665727141666d4d43470c7971735643787252767558470007a01040059c7a80c08957e1ed3d57d283ab1980ff8bd77438af3328043fa96fef0d4366454a755a4d494f497943790d67704d4d425477417766586479000607916f0897855fae032d0738d67eb38711c77b827e62528cd356e7f686deffd41d116f514b4c58556b665949536c7a55474531175258476d52616b53515a76627446785061466847725133000757f3ec98be03abbfbfa0905e8281f6b0274c0c64702dfd53bb75eab8ba74607c1046546f4c73644e4a58415171574b6d390d504e4a536f45585649467a5139000787d18f490eeee1727d3b7f6c1d1e75f036000a89ab7450f3d6f3941e708f86981c486d72655377425a646d554a7a746c704e4c546f45436265564f42380248390006073f0da91e22e9b93d00e38d0520a508ba44cd7296a0cb3e32e6e94af61458c9541d5970765a78464359567147486f464b6276746c666a5357567967767434064b69565265540007b4b3339aac701607ea2d7937d6ae55e568ef581674a4a76e39985fdfbf9982421f414a594a5947497a4772525567756c4b6f50527a6374765a4f4b7a6e65783016496c72534248584f584a6d54615379466256786649320007f7d0b635843482b5610852e35f9995228da20880d6d1add2491d176ec28c940d0568625761781a47614345494f4e585966634e7a735842644f7254615051504138000308b69d8849dfa1d6c6010001b1c1600613ddef58ade0e0b502f938ce5fffb3113f3f60dc3b65002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444099395f75e09a2a983e6ff71dc38c70e688b695e7868a130e92d77e6ce26e677a118278ccc50c05786762d25eb91e8b0f9b07141b8d7de8325f532ef0d92ec307", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "d2e697d81794f91bc99d4bfc8a6b9988fae75c175907b42a927336bee67398ff", - "sequence_number": "2137401416069863360", - "payload": { - "EntryFunction": { - "module": { - "address": "0495923c6adaaa80fc24bf8d54e116d2f8cbf1a98c3cca117d9f54a7cf56f5fc", - "name": "mTGrqQAJtcgMwsKXPOscMr_Coin" - }, - "function": "EVMLkgiqlzdbydoiruEGS7", - "ty_args": [ - { - "struct": { - "address": "3b4c8a715a3966538624869b527d928282d0a13e4b3e28f34acfc6f2c5092f43", - "module": "auqj", - "name": "auljdUCBvZIWpajsdJCEFjguem7", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "4d5167b867b3be746092265da8baaa0e8825455cab1952f59a6edf241657ff09", + "module": "wTZ8", + "name": "B2", + "type_args": [] + } + } } }, { "struct": { - "address": "5c95967af8a288f4ba4c5aa1a608fbf26ee4e36b58edafac7d0b48af72d867b9", - "module": "meSQZQjkPVTiXKegADGZTSeLBHmc", - "name": "loECdVuqGryQWAArhiCdGRdLtEHBe", + "address": "35e13ddd24862fdeb93f44ab31a10e62d978f6d5952fc09234ad8dfde914c8a7", + "module": "Q0", + "name": "LIgIFFCNxTuPyQmoRLU", "type_args": [] } } ], "args": [ - "939836c2e640ecb454a479410a7ed965" + "3870312306af8153", + "00", + "96e5f92555c8a3bc642d8368339732c5d997e75bc0845aa6b956184f35e218d2", + "efcbfa5d63650daa", + "99fb66844ba677fdafcb8e0a3c8ed15f777761f98f914ec630038130f9eb81f8", + "cb0aa68c518c288f958d68e7f21bc1da13f0db0a65897d4ed2791dcc532465ba", + "00", + "d2036309d39f8bfc5d1e001946e76eaa02d6d560e067f5c3e9f7eccf178968ac", + "217c00087b59c8f102ea1e22dd0361dbca75cfbbff7b6c6ba17d717e2964ab69", + "00" ] } }, - "max_gas_amount": "533426335464637558", - "gas_unit_price": "17324896568071707149", - "expiration_timestamp_secs": "11640582366230838350", - "chain_id": 127 + "max_gas_amount": "6474672790465785428", + "gas_unit_price": "18269917365123453405", + "expiration_timestamp_secs": "4411469518669170188", + "chain_id": 123 }, - "signed_txn_bcs": "d2e697d81794f91bc99d4bfc8a6b9988fae75c175907b42a927336bee67398ffc0d742734393a91d020495923c6adaaa80fc24bf8d54e116d2f8cbf1a98c3cca117d9f54a7cf56f5fc1b6d5447727151414a7463674d77734b58504f73634d725f436f696e1645564d4c6b6769716c7a646279646f6972754547533702073b4c8a715a3966538624869b527d928282d0a13e4b3e28f34acfc6f2c5092f43046175716a1b61756c6a64554342765a495770616a73644a4345466a6775656d3700075c95967af8a288f4ba4c5aa1a608fbf26ee4e36b58edafac7d0b48af72d867b91c6d6553515a516a6b50565469584b65674144475a5453654c42486d631d6c6f4543645675714772795157414172686943644752644c7445484265000110939836c2e640ecb454a479410a7ed965764435076d1c67070d5a4c2ea3656ef04e7cddd5fca78ba17f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f3f3e7634861b1625c1d5b81265a7693ed672268227d050d54fa670e34ac04c16a2ab0460170a570411635549dd469793d39232989bd79db3db13a4ca82de801", + "signed_txn_bcs": "bafd4e0c2bbaec46393c66af927e328bf45d5bb11231cc079679423bc49322a21ed704a0e66079f3020dbad0b1127180af1225938e88727dfccdddedb35237f7cb3b77539fbd397ba90b435164675a325f436f696e1b66596a436346556a426c6f794b654451625569584542496f4e52360907628f95e338200e1ca3287e010c175892733f73ec51d4c24d597de448a2f786c61d464e5862444963597743457a70455762656e474866485155775155453115476a54664c496c595763454c475077734c686f574400071d4874b1eb6e48635261e70f3f23c8a359b47dc8bff14efe2f9969d6db2614880e7465634b664b536149506f7861532142776b79644b446f5366506f624e6a41676252574c727351517a7a796b4f557134000607bd8b5eeddab04cde77003afd557bb4352e594166c631177c5a7d9be82f1b6e3e1d6d71744c6453765a5558616e514b43624c70546552764f57566b4e6a3213714a4146774a4c4d4d5871546a4d48687343530007571e64acf55c43cae2e6b7de0a529c6c9d1431d364fec8b9535b96cbf3537e5b1655634d50494d4c417479584b5672746c514b6c4a70570253700007288381f9391d5205ca56bd96504f179bb06f7cde296daa96d399926047f21e961852564450566d75706e4a4369585774546459676e594f67351a49736143766d725245486465556d71557846446a7256575370300006060712f0fa7d6c8a6657f7993b3d1c58d99613689810fc08d6bd76e4f123de97cf7d12714a4676547575677647534975476a464767054668594838000607a7a4f7a5d5e8a29060762230f10f26a0433b0f4401b9acf76a87e7e2724da9491d6f55584861496f7165784c4f6b7343495073624e506d4142675a62575219456a4e6c66487947746a59696252575576496873446168544f000606074d5167b867b3be746092265da8baaa0e8825455cab1952f59a6edf241657ff090477545a38024232000735e13ddd24862fdeb93f44ab31a10e62d978f6d5952fc09234ad8dfde914c8a7025130134c4967494646434e7854755079516d6f524c55000a083870312306af815301002096e5f92555c8a3bc642d8368339732c5d997e75bc0845aa6b956184f35e218d208efcbfa5d63650daa2099fb66844ba677fdafcb8e0a3c8ed15f777761f98f914ec630038130f9eb81f820cb0aa68c518c288f958d68e7f21bc1da13f0db0a65897d4ed2791dcc532465ba010020d2036309d39f8bfc5d1e001946e76eaa02d6d560e067f5c3e9f7eccf178968ac20217c00087b59c8f102ea1e22dd0361dbca75cfbbff7b6c6ba17d717e2964ab69010054ae994099a8da59dd91ec9f0bc98bfd0c46bd7d27b0383d7b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444040994bab3db59ac76ea6052c6c61ac18314200f09ff1bd58736c9bf99a723f1a42dee94a5ddaa2bf88a5c790d2ad50692d3da8f03abe238b5b36522bac7f3504", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "5894d59791ce104ccc08e862a40f9abe6762819079d607d11f6088ddd4a9b339", - "sequence_number": "18170734757694866675", + "sender": "c7595666f07a0907e14efbd2214993d971ec5d5a7867bdb4f8f2b6cc316a409e", + "sequence_number": "5947902502497048432", "payload": { "EntryFunction": { "module": { - "address": "0e2d8ba2b1f96b1bfef5acf29d94981beda302dad649c7e40732a1c8b857c11c", - "name": "XSzZvXhGikuxnSZhEWwRPSz_Coin" + "address": "c50e47674680a109402988bbf0afdbdb34f87acbad31bdd1f0e07c60eb4c0537", + "name": "GBMFhqCTtOJrvpLmeRbuOKCUXtO_Coin" }, - "function": "DnOCbGlZxPsmRIGvfFA", + "function": "KXwdWNV", "ty_args": [ { "vector": { "struct": { - "address": "fda4e425fad55dd73e53b04390a3543f4655c043d2231ab893ad05bea5acbc10", - "module": "HbZSHxlqkKHbmLpsOovfrTFelokuTRPD8", - "name": "lNVAqXtpVBTsYElif8", + "address": "7c55145424fafd135562b02f53db1867954c79336b0b423ac16b1daf5d8fe43a", + "module": "ycFlhvHLvQVkxfExuyISCf", + "name": "cpAORkNgvMNWiEwdMQrX", "type_args": [] } } }, { - "struct": { - "address": "6fbc0a16bd40c7fa5c0fcdc6b952d20e90ad7ff537b0c2b1ae3bac5b7e13ddfa", - "module": "JTltrUqQQFaElGIDQOQhIAXWoz6", - "name": "yQ", - "type_args": [] + "vector": { + "vector": "address" } }, { "struct": { - "address": "af035dad551d3d80abf570b59610e85038aa431d7d7d83b32310a30188c90808", - "module": "CdArWHnslKnL1", - "name": "UlEl5", + "address": "c00ca5f249c12bfd4f9f294428c11a06c04aed44f93249f1ad0ad603b8a0e0dd", + "module": "DWZSZCW", + "name": "tPmIwvPyaNEaSDbvdm", "type_args": [] } }, { "struct": { - "address": "0a6399a598724c89dc6648495e4a19a77b0c80d573e8aaf1dc342efdd86d4cd4", - "module": "AzcoSwLxeBjRiHPDkJXr8", - "name": "PKleUxhEnZMYLdklagD8", + "address": "386802ce917a6ef7a29b0e9e215c91b22748082311b7ce060bb573bc67881733", + "module": "SXfQABHzCNMp", + "name": "bLSLCwBOHuavKWfXeGaJj", "type_args": [] } }, { "struct": { - "address": "b638e6ce59ec969593bd3eead33e853e5a0e10a86549f6f7cddf0980f02babfe", - "module": "aPIR1", - "name": "UnyAtlhLEyQWspthropxxYXeaVqxHn", + "address": "3532a8dd9d9b0a7c7f4995ea225cb1c904284cbab4d02f4f876c28b283d13b62", + "module": "YRZCnsIaQxkyKQSJgEBOiZUixng", + "name": "EzJmcRyfoCiqiYmyMtch", "type_args": [] } + }, + { + "vector": { + "struct": { + "address": "8a945242b918865557d991bf889ac19b4ec492db48c2a88b4beb5b780a1a7b61", + "module": "uEHlROVZPCExXAuhccmzQkBJNuRWD", + "name": "LwlFXSaxKuPMTIjhE5", + "type_args": [] + } + } + }, + { + "vector": { + "struct": { + "address": "c466a0c6283d90ed207b5fd8f85fd6b05ebfd870eea2d57f10eed7ac766df01a", + "module": "mFisEgIqnfKUCwDItDBc0", + "name": "CGoMlsUJUGmlWrvOkMBgerefnwnpJJj", + "type_args": [] + } + } } ], - "args": [ - "b5e11d0fab07b93bca0b431076b1b962" - ] + "args": [] } }, - "max_gas_amount": "15690994166080608262", - "gas_unit_price": "1019922765953207371", - "expiration_timestamp_secs": "12322986801690557708", - "chain_id": 196 + "max_gas_amount": "18132661458080473926", + "gas_unit_price": "15286620286439603657", + "expiration_timestamp_secs": "11740717763513176354", + "chain_id": 51 }, - "signed_txn_bcs": "5894d59791ce104ccc08e862a40f9abe6762819079d607d11f6088ddd4a9b339f3043f4cfd6a2bfc020e2d8ba2b1f96b1bfef5acf29d94981beda302dad649c7e40732a1c8b857c11c1c58537a5a76586847696b75786e535a684557775250537a5f436f696e13446e4f4362476c5a7850736d52494776664641050607fda4e425fad55dd73e53b04390a3543f4655c043d2231ab893ad05bea5acbc102148625a5348786c716b4b48626d4c70734f6f7666725446656c6f6b755452504438126c4e5641715874705642547359456c69663800076fbc0a16bd40c7fa5c0fcdc6b952d20e90ad7ff537b0c2b1ae3bac5b7e13ddfa1b4a546c7472557151514661456c474944514f5168494158576f7a360279510007af035dad551d3d80abf570b59610e85038aa431d7d7d83b32310a30188c908080d4364417257486e736c4b6e4c3105556c456c3500070a6399a598724c89dc6648495e4a19a77b0c80d573e8aaf1dc342efdd86d4cd415417a636f53774c7865426a52694850446b4a58723814504b6c65557868456e5a4d594c646b6c616744380007b638e6ce59ec969593bd3eead33e853e5a0e10a86549f6f7cddf0980f02babfe0561504952311e556e7941746c684c4579515773707468726f70787859586561567178486e000110b5e11d0fab07b93bca0b431076b1b9620618f6410f9cc1d94b8cf9125a7e270e0cbd97c6340b04abc4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440146c88586af1a18a4d4fb43d6013984e5d117a7a94b3a17a83bbf26edd7f546a9182b3a977c14518686db2a750abe8812bfd26ee0aec5de1f5ebb755af1bc40d", + "signed_txn_bcs": "c7595666f07a0907e14efbd2214993d971ec5d5a7867bdb4f8f2b6cc316a409e7057fe0bd0318b5202c50e47674680a109402988bbf0afdbdb34f87acbad31bdd1f0e07c60eb4c05372047424d4668714354744f4a7276704c6d655262754f4b435558744f5f436f696e074b587764574e560706077c55145424fafd135562b02f53db1867954c79336b0b423ac16b1daf5d8fe43a167963466c6876484c7651566b78664578757949534366146370414f526b4e67764d4e57694577644d5172580006060407c00ca5f249c12bfd4f9f294428c11a06c04aed44f93249f1ad0ad603b8a0e0dd0744575a535a43571274506d4977765079614e456153446276646d0007386802ce917a6ef7a29b0e9e215c91b22748082311b7ce060bb573bc678817330c535866514142487a434e4d7015624c534c4377424f487561764b5766586547614a6a00073532a8dd9d9b0a7c7f4995ea225cb1c904284cbab4d02f4f876c28b283d13b621b59525a436e73496151786b794b51534a6745424f695a5569786e6714457a4a6d635279666f43697169596d794d7463680006078a945242b918865557d991bf889ac19b4ec492db48c2a88b4beb5b780a1a7b611d7545486c524f565a504345785841756863636d7a516b424a4e75525744124c776c46585361784b75504d54496a684535000607c466a0c6283d90ed207b5fd8f85fd6b05ebfd870eea2d57f10eed7ac766df01a156d466973456749716e664b554377444974444263301f43476f4d6c73554a55476d6c5772764f6b4d4267657265666e776e704a4a6a000046a34d718627a4fbc93d839528fc24d4225152d69968efa233002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440088ea14d2822add45bbfc4a42f0559307e61fcce418fd2e973ba639e23de573ec8ce57f56421e76b8a17517abfe3b3a8f4a69a474f4c0ee596a2fc91a88e640c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "8c7ef4d27c16f347b878e61339ec075933e756ae50f2ed30b48d29c06913c6ec", - "sequence_number": "934095557084397604", + "sender": "8340971c80b76164b38f4e13748211d13a97ec3eaebb9da342954d365bb4d95c", + "sequence_number": "1093245616517658282", "payload": { "EntryFunction": { "module": { - "address": "3e454d70174c62f1d026e72882b185085dc726cf3699b9e805ec28839231e73b", - "name": "SIBJISTztyKbanATqymrFWLmoIHU3_Coin" + "address": "7b018235a34a982334dfc1abbc223f027f01c56b1a76d5f31561cf178d6a4364", + "name": "wI2_Coin" }, - "function": "EwLZGAojawYq8", + "function": "DoatyUOyTFGscluKnNXnhktuhYnPU2", "ty_args": [ - { - "struct": { - "address": "6c1ac7b61a4b272c9aca8a48bbae63148204cb058015db82a869c1ff7ca47f3e", - "module": "ryAbyAZEAcaxyi", - "name": "DaiGGDAoGzcdGOmiLJuGulektKiS6", - "type_args": [] - } - }, { "vector": { "vector": { "struct": { - "address": "5860fd94a3e7b173098e592544dda997336ce801074e187b41a1cfeb2692e0c8", - "module": "PPzPuGEICJcHuMGiEOSJAsq", - "name": "C", + "address": "04516d2e134d40a0dd3fb2a2e079f548bd33d67bfda7e462fe3cd167bbfe394b", + "module": "KoyrpCCjckYqANPrwaVPnn9", + "name": "eMQFVIzZFirbxdDJCtXbGqpCaDvX7", "type_args": [] } } } }, { - "struct": { - "address": "af09eeeda0efa61824743c1fea95c5b8dc8823b073092467cf18cde8e74425ed", - "module": "QXrl2", - "name": "ucPmcNOpAAfdKUvwqaIDC1", - "type_args": [] - } - }, - { - "vector": "u64" - }, - { - "struct": { - "address": "d17554224e80a6c3f7cad84f2cce8709e3d2df0592e526243aca41876befd6e5", - "module": "KfXwhHbpOvZCCuMMVlJNyRHe8", - "name": "EcHbrQPJepFhiWzFPuDPg", - "type_args": [] - } - }, - { - "struct": { - "address": "66379cf2947b9050bbfde5e3f06210fc09634740497a7f6755df330e9822abb0", - "module": "O8", - "name": "oTXyArcNRIX3", - "type_args": [] + "vector": { + "struct": { + "address": "f01f096d047608f1ce4d1febba891aae32f2540d0738f9e615293f9937e31c51", + "module": "NFZhthIdUqxFqyCJNEmSmnAmiOobb", + "name": "vnnWykBUC", + "type_args": [] + } } }, { - "struct": { - "address": "24ecf01fb221bc367980b8e5c81541d657cf66d2737b2e41a48a3cf0544f96af", - "module": "banF4", - "name": "bRHGTfxBMKEeH", - "type_args": [] + "vector": { + "vector": "signer" } }, { "vector": { "vector": { "struct": { - "address": "27d56b0676caa1050bb1821e28263ee656c2881dc3dc7903a4b74821ff5a488a", - "module": "aYOpgirdvMLJErXZUgiVnYXfeMUyIpq", - "name": "niZDPjVUSlZQIvPgAqWNlrOHgtB8", + "address": "54875a52f3e4fc267d468295017ee89ef2eda47aa730c14d20344a31aaae3c1c", + "module": "xUYAjDbqTvkhVn9", + "name": "bcVpZZqAtOSxlwhEdFW2", "type_args": [] } } } + }, + { + "vector": { + "struct": { + "address": "39375bd649c98f788e9505439bd12821b63cbf360fb3a6ec72a34a1134cd1306", + "module": "qQICZTNWEwqfwSglXPDGfkXHjD", + "name": "aLvAcNetIaUWqNSxnfqfqS", + "type_args": [] + } + } } ], "args": [ - "2fae7f946c2a4c76980f536bd4187bed", - "00", - "02d37a1024d03794d8d28017097a5c809321908b73a8a7e01827210ea33744d8", - "8267b4c8d469c5520249870517aec7dd", - "b2e75aa6a53f28c2393e2f1243717cce7bac40375c6f2ce46f6c3e5c74625343", - "00", - "44ab4c34ec26105469b0e6b3b0dcfde1", - "f5", - "00" + "305b4bcc64703bc374d9cce7d61dfc2a", + "86bf81f3b00e64bd" ] } }, - "max_gas_amount": "12858810095607501848", - "gas_unit_price": "2164941838794790151", - "expiration_timestamp_secs": "6323315818208380198", - "chain_id": 65 + "max_gas_amount": "14419184308878584498", + "gas_unit_price": "12641339608471202686", + "expiration_timestamp_secs": "8339370291029987680", + "chain_id": 170 }, - "signed_txn_bcs": "8c7ef4d27c16f347b878e61339ec075933e756ae50f2ed30b48d29c06913c6ec244049caf592f60c023e454d70174c62f1d026e72882b185085dc726cf3699b9e805ec28839231e73b225349424a4953547a74794b62616e415471796d7246574c6d6f494855335f436f696e0d45774c5a47416f6a617759713808076c1ac7b61a4b272c9aca8a48bbae63148204cb058015db82a869c1ff7ca47f3e0e7279416279415a454163617879691d446169474744416f477a6364474f6d694c4a7547756c656b744b695336000606075860fd94a3e7b173098e592544dda997336ce801074e187b41a1cfeb2692e0c81750507a5075474549434a6348754d4769454f534a41737101430007af09eeeda0efa61824743c1fea95c5b8dc8823b073092467cf18cde8e74425ed055158726c32167563506d634e4f70414166644b55767771614944433100060207d17554224e80a6c3f7cad84f2cce8709e3d2df0592e526243aca41876befd6e5194b665877684862704f765a4343754d4d566c4a4e795248653815456348627251504a6570466869577a465075445067000766379cf2947b9050bbfde5e3f06210fc09634740497a7f6755df330e9822abb0024f380c6f5458794172634e52495833000724ecf01fb221bc367980b8e5c81541d657cf66d2737b2e41a48a3cf0544f96af0562616e46340d62524847546678424d4b4565480006060727d56b0676caa1050bb1821e28263ee656c2881dc3dc7903a4b74821ff5a488a1f61594f7067697264764d4c4a4572585a556769566e595866654d55794970711c6e695a44506a5655536c5a51497650674171574e6c724f48677442380009102fae7f946c2a4c76980f536bd4187bed01002002d37a1024d03794d8d28017097a5c809321908b73a8a7e01827210ea33744d8108267b4c8d469c5520249870517aec7dd20b2e75aa6a53f28c2393e2f1243717cce7bac40375c6f2ce46f6c3e5c7462534301001044ab4c34ec26105469b0e6b3b0dcfde101f501001854e42ea7ab73b20795becc216b0b1e2645ebfa3beec05741002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fac786081029253460169c02c8531260a3e60f0f79037318a646734a2cc46120e949f4b3f7fa333de7d6e1d7ca089d97def0044ec8c127299b4fc8a9f8510608", + "signed_txn_bcs": "8340971c80b76164b38f4e13748211d13a97ec3eaebb9da342954d365bb4d95caab6c99018fd2b0f027b018235a34a982334dfc1abbc223f027f01c56b1a76d5f31561cf178d6a4364087749325f436f696e1e446f617479554f7954464773636c754b6e4e586e686b747568596e5055320506060704516d2e134d40a0dd3fb2a2e079f548bd33d67bfda7e462fe3cd167bbfe394b174b6f79727043436a636b5971414e5072776156506e6e391d654d514656497a5a466972627864444a43745862477170436144765837000607f01f096d047608f1ce4d1febba891aae32f2540d0738f9e615293f9937e31c511d4e465a6874684964557178467179434a4e456d536d6e416d694f6f626209766e6e57796b4255430006060506060754875a52f3e4fc267d468295017ee89ef2eda47aa730c14d20344a31aaae3c1c0f785559416a44627154766b68566e3914626356705a5a7141744f53786c7768456446573200060739375bd649c98f788e9505439bd12821b63cbf360fb3a6ec72a34a1134cd13061a715149435a544e57457771667753676c58504447666b58486a4416614c7641634e657449615557714e53786e6671667153000210305b4bcc64703bc374d9cce7d61dfc2a0886bf81f3b00e64bdb22a9899bb3b1bc87e6b00b0650f6faf60d149871865bb73aa002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402da05bcaddf533c9b5278cc04233ad266887d635b7d28f5191e53df1e03166522d9e72d92e67ee391b53f65b1677bbde0b9f66720516b6682df1c1a6dc9c6002", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "fce38649ab69c65bf3efc88305087a2ad64381dd6b013ff073435dab2b95fdef", - "sequence_number": "9210329543072062798", + "sender": "6ce4807617a2bdd7521237eaf7648064623f967dba38800d59148bae631dc59f", + "sequence_number": "10024027587874959934", "payload": { "EntryFunction": { "module": { - "address": "325a3f73a6737af32ebb80b2e2602b991bab54b6ab80ff200f781908fed603ba", - "name": "WAkZGLEEaa0_Coin" + "address": "cefcac9eb3c903dbfe0c0f03f552a106e60f127d430627e4756164ffe5b55a6c", + "name": "RWtqQVgSP3_Coin" }, - "function": "XdB5", - "ty_args": [], + "function": "YgiINjEGmCxKsiSheUKEagywjiIUgj", + "ty_args": [ + { + "vector": "u8" + }, + { + "struct": { + "address": "e33ef8f86169d3503809dd5d37570042eb8c5d129607937bc473e70c4be1eba3", + "module": "iJJnirYztpqtVfsPqIvzJAsAxu2", + "name": "wmzZBTiLKZHRcMbGmkwbXWSaI3", + "type_args": [] + } + }, + { + "vector": { + "struct": { + "address": "73ee72bdde7c78269b5c64b7c7ede605da94bd1a67c228bebc312eb6f89dad1c", + "module": "dbzVkkTiqTOmswfCHPmJt", + "name": "HXl", + "type_args": [] + } + } + }, + { + "struct": { + "address": "0401657da28fc559fbf997e6901ac7c7ae35ce1621dda8e26e88e6833d0eeb3b", + "module": "DCpbNHfaasbmhIEIGBekVpuIHQ", + "name": "bljQknyTyVWutFGzdUtqyBNRKxDGd4", + "type_args": [] + } + }, + { + "struct": { + "address": "d190e257610dca30a4a911ece34ab51c54ef34c4bb204acc478021c98778b259", + "module": "EQMGdWzsX1", + "name": "YqjHjheHvV4", + "type_args": [] + } + }, + { + "struct": { + "address": "92f6830eda0fe407881b63699a963e5b19b4de87fc10fb1eab4b30a00c96f968", + "module": "vdGTCEkgwRglvA", + "name": "pjmzREx0", + "type_args": [] + } + } + ], "args": [ - "86", - "aba525b40b6181a6ca9e94349302ece56fa7b35dfde391740190882fa19034eb" + "5d911df6dfdbe0c3ecaeb32280fa08e1" ] } }, - "max_gas_amount": "3308815829877714599", - "gas_unit_price": "14112012253935530488", - "expiration_timestamp_secs": "5948639000346966189", - "chain_id": 196 + "max_gas_amount": "3872677047018042768", + "gas_unit_price": "10861652966118473630", + "expiration_timestamp_secs": "7528687943350007434", + "chain_id": 39 }, - "signed_txn_bcs": "fce38649ab69c65bf3efc88305087a2ad64381dd6b013ff073435dab2b95fdef4e9d18c7eba9d17f02325a3f73a6737af32ebb80b2e2602b991bab54b6ab80ff200f781908fed603ba1057416b5a474c45456161305f436f696e04586442350002018620aba525b40b6181a6ca9e94349302ece56fa7b35dfde391740190882fa19034eba7ee0c677746eb2df871c95560f0d7c3ad38b750a7cf8d52c4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401fd6e2910bf6e22d80eb0810036cedb2afd497a21a9b418dbffdb5ddbc5d71a49bda199133458bb2978bcb0fee0a7893278b292f6459cc4558a9ce3877cb2600", + "signed_txn_bcs": "6ce4807617a2bdd7521237eaf7648064623f967dba38800d59148bae631dc59f3eb2004afb7f1c8b02cefcac9eb3c903dbfe0c0f03f552a106e60f127d430627e4756164ffe5b55a6c0f525774715156675350335f436f696e1e596769494e6a45476d43784b7369536865554b45616779776a694955676a06060107e33ef8f86169d3503809dd5d37570042eb8c5d129607937bc473e70c4be1eba31b694a4a6e6972597a74707174566673507149767a4a4173417875321a776d7a5a4254694c4b5a4852634d62476d6b776258575361493300060773ee72bdde7c78269b5c64b7c7ede605da94bd1a67c228bebc312eb6f89dad1c1564627a566b6b546971544f6d7377664348506d4a740348586c00070401657da28fc559fbf997e6901ac7c7ae35ce1621dda8e26e88e6833d0eeb3b1a444370624e4866616173626d684945494742656b5670754948511e626c6a516b6e7954795657757446477a6455747179424e524b78444764340007d190e257610dca30a4a911ece34ab51c54ef34c4bb204acc478021c98778b2590a45514d4764577a7358310b59716a486a686548765634000792f6830eda0fe407881b63699a963e5b19b4de87fc10fb1eab4b30a00c96f9680e7664475443456b677752676c764108706a6d7a524578300001105d911df6dfdbe0c3ecaeb32280fa08e190b551854183be359e3f0f3fd357bc968ab624b8cb457b6827002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444052dcb21f82ceddae1d610cd40d266dc3d855fc028d619f7e50713d772e0707c54c9c38b54c8973bdf122a59775671f535d2995123111ee59010de8df4cea0d08", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "8867be519974482d85749ec7e447e30d32e7ed9887c72537d540788c5062cf29", - "sequence_number": "14028212931138068049", + "sender": "a6caa7b50cff5188f44a05333eb8370e7d3988fc5efd0db27e7cdb9d6511ddd3", + "sequence_number": "10497445081074617988", "payload": { "EntryFunction": { "module": { - "address": "322b2866b67ed7e4805ce02cf4789c936dd80d6b7067744987cc07d7539d3b09", - "name": "FEWPYalbTOdKuqlTfrHt9_Coin" + "address": "394062af170c721804ab2a1db0451c53e34e9e1ea62af30ef16609bdd1d0aaba", + "name": "TLAFRnUgSKfDLCeEFvLrwmbnztOizP_Coin" }, - "function": "ZRYSddigNRsqpuwiCEQzfn", + "function": "qsfXSG9", "ty_args": [ { "vector": { - "vector": "bool" + "vector": { + "struct": { + "address": "786d76a6ddd39a30dfacb874256c2d2f28c337f75d90e783e30a82d7843f578a", + "module": "CydYJCLjGXFxHWtK9", + "name": "TIeqVRfI1", + "type_args": [] + } + } } }, + "bool", { - "vector": { - "vector": "u64" + "struct": { + "address": "50be34fbf697514d5fb5cce2b1adb116be4ab544c467ce982e12f559d67a778c", + "module": "ApIkZcQpuSYooJTJBJnjfgqApLntVx", + "name": "rSPuZVCWjHMqrkSdZAwLaZxFHzEBDUXZ1", + "type_args": [] + } + }, + { + "struct": { + "address": "b7e5efd1d521e0770b3160266053074ce7b0693f395a0a2c8cf1256fc7d2ab40", + "module": "SNEDejlObHjOrslLAKbiaxgkZhl9", + "name": "CYUq0", + "type_args": [] } } ], "args": [ - "9fefab3896102103" + "80606055b93c6fa9d125a534c1a00139a515606519688084cc9216decb27dfea" ] } }, - "max_gas_amount": "14351007517483828191", - "gas_unit_price": "16513633505218907534", - "expiration_timestamp_secs": "4509086126613255848", - "chain_id": 126 + "max_gas_amount": "13709806115342765438", + "gas_unit_price": "13497204900084317404", + "expiration_timestamp_secs": "150081558987513591", + "chain_id": 170 }, - "signed_txn_bcs": "8867be519974482d85749ec7e447e30d32e7ed9887c72537d540788c5062cf29519e06125639aec202322b2866b67ed7e4805ce02cf4789c936dd80d6b7067744987cc07d7539d3b091a4645575059616c62544f644b75716c5466724874395f436f696e165a525953646469674e527371707577694345517a666e0206060006060201089fefab3896102103df8395604d0529c78ecd8f152e362ce5a8d66c26f17d933e7e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144403e1d492edb3f45f704a2eba22135561e5951b4125eab641a11294546f1280a2537ccb51602ffdec07d3eda67408a46c789adf105edbcabc9492c46ef8bc6f305", + "signed_txn_bcs": "a6caa7b50cff5188f44a05333eb8370e7d3988fc5efd0db27e7cdb9d6511ddd384ce9ff2ae6aae9102394062af170c721804ab2a1db0451c53e34e9e1ea62af30ef16609bdd1d0aaba23544c4146526e5567534b66444c43654546764c72776d626e7a744f697a505f436f696e077173665853473904060607786d76a6ddd39a30dfacb874256c2d2f28c337f75d90e783e30a82d7843f578a11437964594a434c6a475846784857744b390954496571565266493100000750be34fbf697514d5fb5cce2b1adb116be4ab544c467ce982e12f559d67a778c1e4170496b5a6351707553596f6f4a544a424a6e6a66677141704c6e74567821725350755a5643576a484d71726b53645a41774c615a7846487a45424455585a310007b7e5efd1d521e0770b3160266053074ce7b0693f395a0a2c8cf1256fc7d2ab401c534e4544656a6c4f62486a4f72736c4c414b62696178676b5a686c3905435955713000012080606055b93c6fa9d125a534c1a00139a515606519688084cc9216decb27dfea7ecd7b34060443bedcfc2f6a58b44fbbf79ec9fa61321502aa002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440613f446ddd36105c86ce4bd9e69acfa667c714280d3f6d959f970a521015abe2fe92562bd51959423e04f85d5b5ff08a6b3904e8902b66c6276b7d88e68f2e0a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "1e69a8d43901bd3e6937ab56b4cbfce83c0c851f34036d52bfadb1a085753a6d", - "sequence_number": "16293253121409703180", + "sender": "575811eaabab700fa0447ba9673b362a7561130af49da337f301d32f8616dc87", + "sequence_number": "1997651572116658959", "payload": { "EntryFunction": { "module": { - "address": "2b86b5fbfebc4d6b438debaf176b48447e9c95f3cc850e28394b5f7fd6ca1975", - "name": "khZMGRFKszBVgXvecpZv_Coin" + "address": "f68d5d1021b79beef496e3bc86cd7377b3670895bedf052db39128457932c828", + "name": "mjbJkgpP4_Coin" }, - "function": "kEZAp", + "function": "rXnDociJqPcrUawA0", "ty_args": [ - { - "struct": { - "address": "6e5b72ea2206a14646b7e5f71aebac78ed203d7cb2c265ed80fb86547b7e3cde", - "module": "ZHy4", - "name": "ycBuWrtJLFtFCkVDsNTWfVNKxEUZM", - "type_args": [] - } - }, { "vector": { "struct": { - "address": "3061470749f650bc5649906b2b38dae2458a4ebb10ec26fce1f37e2ead0ac9cb", - "module": "mWqDJUdbVULuRQtlz5", - "name": "riUBDEKAwqyjOLtDLMfGOSLngD", + "address": "b7168337dd0c3549e41757f92b07b1e8f554a03bfe834f6a6fef3bfc6cd1df22", + "module": "YlskG", + "name": "TKuKIu0", "type_args": [] } } }, { "struct": { - "address": "ba4f5bc47e0419b31eeebd3a26df1eb28d47227864fd71e3fbf877bba1af7ff1", - "module": "VTVpxiEouCIAgMkmDca", - "name": "lhQNUKfZjXVDTtMnATBkM", + "address": "98409d26594da9a75287f72417d3267adc9d41438ce6d7b5f2514bfe062159ef", + "module": "XBfWUU", + "name": "HxzQtLecEyc", "type_args": [] } }, { "struct": { - "address": "026383b44979155157731849d88b9e86babf112a5534dba204dec17bbcf1fe66", - "module": "YAiRCKwlZZbdbqysVpGuTHCfz", - "name": "sNNmskcF6", + "address": "45708425d1d31e64482023751a813cc091659f550da3d8e5fca1bf2f7600828e", + "module": "lVNGtkpyu8", + "name": "GckVDAFrhTtdDQzycsanzVcaRI5", "type_args": [] } }, { "struct": { - "address": "9ef7fb0988ed299836783964b6d37576402efab170e239c43d04b90a260a16ed", - "module": "LFfRdrJFhGpeS", - "name": "WUDwObKbweeOdPxFSPesDZdTpB", + "address": "982374303505fd8bf6bbd8c9ee78eef7156f5c14281593be44fa7545199eaff3", + "module": "jvBiKEWTuhFSnAkxrHTpeLDiCCR", + "name": "bRdEdXqh5", "type_args": [] } }, { "vector": { - "vector": { - "struct": { - "address": "974418edfc477bd97ec12cef59f54dfbc860a552bd15db3783dd15106c10a018", - "module": "BqDVNrhBFpAdxjoaRpbweFlW", - "name": "coQS8", - "type_args": [] - } + "struct": { + "address": "07fb7cdeb37f4f81fb573f5bee8b0d0200ab3265d274356df7feb702f0e945d3", + "module": "vWaGMIJK5", + "name": "IGmaVKLFubPIImoSjxFZaUpC", + "type_args": [] } } }, - { - "struct": { - "address": "5db98d0627ee32093b77491ff85b9d054da6f96a8ea877ddab008e9ff1584999", - "module": "m", - "name": "yySZGfZCu", - "type_args": [] - } - }, { "vector": { - "vector": "address" + "vector": { + "struct": { + "address": "481f9b04468bc8e2d64c563f4129822d87ec101e1f3c292584e6deab588cb19a", + "module": "VRJ", + "name": "nkLxC9", + "type_args": [] + } + } } } ], "args": [ - "50dca3ae56446b5ef52204daeaaa449b", - "08", - "9e9f7fe547e6971e", + "f6", + "d3329b14c3d94a25f2e528e412193c246793ad26f356960d120b1bc08659a52e", + "bf9e50828e9b924da2e9b65864a6f070", + "b6", "01", - "47", - "01", - "4b" + "01" ] } }, - "max_gas_amount": "1867269909061192501", - "gas_unit_price": "12996127631785832905", - "expiration_timestamp_secs": "8049646627435807187", - "chain_id": 198 + "max_gas_amount": "9112191536816973839", + "gas_unit_price": "689809912111241676", + "expiration_timestamp_secs": "16724924462822336185", + "chain_id": 134 }, - "signed_txn_bcs": "1e69a8d43901bd3e6937ab56b4cbfce83c0c851f34036d52bfadb1a085753a6d0c5d267963431de2022b86b5fbfebc4d6b438debaf176b48447e9c95f3cc850e28394b5f7fd6ca1975196b685a4d4752464b737a42566758766563705a765f436f696e056b455a417008076e5b72ea2206a14646b7e5f71aebac78ed203d7cb2c265ed80fb86547b7e3cde045a4879341d796342755772744a4c467446436b5644734e545766564e4b7845555a4d0006073061470749f650bc5649906b2b38dae2458a4ebb10ec26fce1f37e2ead0ac9cb126d5771444a55646256554c755251746c7a351a7269554244454b417771796a4f4c74444c4d66474f534c6e67440007ba4f5bc47e0419b31eeebd3a26df1eb28d47227864fd71e3fbf877bba1af7ff113565456707869456f75434941674d6b6d446361156c68514e554b665a6a58564454744d6e4154426b4d0007026383b44979155157731849d88b9e86babf112a5534dba204dec17bbcf1fe661959416952434b776c5a5a62646271797356704775544843667a09734e4e6d736b63463600079ef7fb0988ed299836783964b6d37576402efab170e239c43d04b90a260a16ed0d4c46665264724a4668477065531a575544774f624b627765654f6450784653506573445a6454704200060607974418edfc477bd97ec12cef59f54dfbc860a552bd15db3783dd15106c10a01818427144564e72684246704164786a6f615270627765466c5705636f51533800075db98d0627ee32093b77491ff85b9d054da6f96a8ea877ddab008e9ff1584999016d097979535a47665a437500060604071050dca3ae56446b5ef52204daeaaa449b0108089e9f7fe547e6971e010101470101014b354b5ecd16e0e919c9b13b8439855bb4d381bb73f516b66fc6002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444020052c05b93b082576e2061cd79f51fbf9491d559848e14eadff6361c1c6c2d60726f6684e7e978efee8b5c7df5e4c0609d77472ea69ad15cb9ad45f7a290b0d", + "signed_txn_bcs": "575811eaabab700fa0447ba9673b362a7561130af49da337f301d32f8616dc870f9b03558515b91b02f68d5d1021b79beef496e3bc86cd7377b3670895bedf052db39128457932c8280e6d6a624a6b677050345f436f696e1172586e446f63694a715063725561774130060607b7168337dd0c3549e41757f92b07b1e8f554a03bfe834f6a6fef3bfc6cd1df2205596c736b4707544b754b497530000798409d26594da9a75287f72417d3267adc9d41438ce6d7b5f2514bfe062159ef065842665755550b48787a51744c6563457963000745708425d1d31e64482023751a813cc091659f550da3d8e5fca1bf2f7600828e0a6c564e47746b707975381b47636b56444146726854746444517a796373616e7a5663615249350007982374303505fd8bf6bbd8c9ee78eef7156f5c14281593be44fa7545199eaff31b6a7642694b455754756846536e416b7872485470654c44694343520962526445645871683500060707fb7cdeb37f4f81fb573f5bee8b0d0200ab3265d274356df7feb702f0e945d309765761474d494a4b351849476d61564b4c4675625049496d6f536a78465a6155704300060607481f9b04468bc8e2d64c563f4129822d87ec101e1f3c292584e6deab588cb19a0356524a066e6b4c784339000601f620d3329b14c3d94a25f2e528e412193c246793ad26f356960d120b1bc08659a52e10bf9e50828e9b924da2e9b65864a6f07001b6010101010fe84b9dec01757ecc19efd575b29209b926c4bd2fde1ae886002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401f67e7678ac237d7a5781236581cc05e5ae495c40ae2a082bc79cac4bdb3bad82a24023f88ea77817d9cf3c53e2f36348462a31f0e75cb9970aee9f22deac804", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "02886dccdadff8e15d5f1925e0c8119f0d78bc36ab9384d36a8293387155dfb6", - "sequence_number": "14115098276434168496", + "sender": "db21e20f06cac0a7c5cac21311c387deff22296df93e7602d255b41cfbe7b724", + "sequence_number": "6142073736242761049", "payload": { "EntryFunction": { "module": { - "address": "2e17158708fc259583be086d060e2307863c1b6fd17a229327ece03b4189ba9d", - "name": "BvIVuGDLOaOQDWeIWzeECWV_Coin" + "address": "9549166ecd4856f553a71a4dcb7e65dea803ffa79adeb40828af2ea69f001cb1", + "name": "Gr_Coin" }, - "function": "jBRrOHxkBeRPlBPZf", + "function": "KAclDIFEEQVkFLBtUjVS", "ty_args": [ { "vector": { - "vector": "u64" + "struct": { + "address": "294f0d417eab6c82a5e234b3dbfb1cc01a9dd0a58048eec3c0a6e1564e8eb4c6", + "module": "licVGZVxtYsuQeLwIFyP6", + "name": "qnepjyTOzwAtUiMnYRRBomQ3", + "type_args": [] + } } - } - ], - "args": [ - "df7c30f0df076cf4f01a77469534bb4e", - "01", - "60", - "dd3e1e3607a73e9a82108ea8d183b909", - "4d", - "c9", - "39f676f277ab210a1a7ef67651e09306cb6efafc41eac87ef5247c1bacb7c74f", - "1802f968def58330", - "ae06b0d3930dd34549bc019b44f89e73e4263f5d444360f1b2fa4286b8a94e78", - "78b21b3a04bf65321aa776334ddd75acc16fb9f3a8545bcf0813f7d387b5c0f8" - ] - } - }, - "max_gas_amount": "1372575531059564028", - "gas_unit_price": "8145372623935955716", - "expiration_timestamp_secs": "12059370263054168483", - "chain_id": 51 - }, - "signed_txn_bcs": "02886dccdadff8e15d5f1925e0c8119f0d78bc36ab9384d36a8293387155dfb6b04a96f018e7e2c3022e17158708fc259583be086d060e2307863c1b6fd17a229327ece03b4189ba9d1c427649567547444c4f614f5144576549577a65454357565f436f696e116a4252724f48786b426552506c42505a66010606020a10df7c30f0df076cf4f01a77469534bb4e0101016010dd3e1e3607a73e9a82108ea8d183b909014d01c92039f676f277ab210a1a7ef67651e09306cb6efafc41eac87ef5247c1bacb7c74f081802f968def5833020ae06b0d3930dd34549bc019b44f89e73e4263f5d444360f1b2fa4286b8a94e782078b21b3a04bf65321aa776334ddd75acc16fb9f3a8545bcf0813f7d387b5c0f8fccd325c2c5e0c1304e3e4d43e2d0a71a3b140685c7d5ba733002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406c0d633725c4b5d18f0b9a6143803f9101b81420e9177500bfe65534a43256b05564908fcc038b2cd94bf4f538090ce3bf95bbb4f997ae49c520d63894320b0b", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "f508aee9e8be65a1ff3f88210946013475d8c883c5789296126b22d781248811", - "sequence_number": "7411065962129702027", - "payload": { - "EntryFunction": { - "module": { - "address": "91d47d3a4e99dbe306e8e35101ac56b6b1377168b06a9303a552c29a3684c1e7", - "name": "rYcXGngSehrhNLM6_Coin" - }, - "function": "XmUGfvQPQYLjovIFb1", - "ty_args": [ + }, { "vector": { - "vector": { - "vector": "u8" - } + "vector": "u8" } }, { "struct": { - "address": "7126b68c7e144a5556b281a4bfeb4893e755a1c4aedf3562eaa3c4b23d051d4c", - "module": "aNhIFhmkpQndZzwdGVDOjpNSNKos0", - "name": "FpCcUgpzIEkFmZgHXESTeyjwaPtyUD0", + "address": "f867803cc5828dddc90181dbec6a1a82f7a81f7403185d88c0b7e6278a262f32", + "module": "cmlELvGSrXV2", + "name": "xYFUESIVyjskjzzMpmrXWgfyjsDkqVVt0", "type_args": [] } }, { "vector": { - "vector": "u128" - } - }, - { - "struct": { - "address": "0f3767e8f3418727b349469f6caa379975e738ba0565d806dc5fe630ac9beeee", - "module": "oXTgYBycWWv9", - "name": "NYeqyobnKIjhR4", - "type_args": [] + "struct": { + "address": "588085a949dc743119e7ce3bd3b01df1f25c4bc2feeadde76db0d07e5cf3b612", + "module": "FYmRkXkaCzMfptMiMP", + "name": "CmF", + "type_args": [] + } } }, { - "struct": { - "address": "e352dc78be93047b539cd60678c99ff025da2ab58d82300b8513a1fd4b3ef82d", - "module": "GNZshkDfoyimPEHayJad", - "name": "GWHovCZpq", - "type_args": [] + "vector": { + "vector": "signer" } }, { "struct": { - "address": "189f78f12ec09d40dfcab3ff56b174ae89d0306cafea87d1b57da68e500009c5", - "module": "UsC0", - "name": "MXofsFBbOmOLFsEkhqKyFRiVZoWTygq3", + "address": "a05f9b1fb59f6f508084622f923124a5c5af0979ab9dc1fc26185529d0b5325b", + "module": "MiaTZmWiwxcpWVvujJVV6", + "name": "iGPJkLBnPGBEFKpAJaSjIUAO", "type_args": [] } }, { "vector": { "struct": { - "address": "72913d4c8c65161b174d33f965f0f580a61b1ec2e12a6a476e29794cd765fdae", - "module": "EbIzWaRLFoXkBxZn5", - "name": "KdVifueRYagVYwakirM", + "address": "ef65043b74a0aea0ac3ae913b345f77dbf5b2733b2d076e41e708e9c9dad387a", + "module": "dUSVEneGjYJgBmODPErJagHWJM1", + "name": "KCxXflQCEOknXUBml1", "type_args": [] } } } ], "args": [ - "00", - "bf9723de9ca9bf5f706a72460ee037ac", - "59ac0e2cf75f823cf7fdaccd052593ca", - "30", - "714674d1f28e74b8060194c43de7e608", - "534b326cacf75f4c8c80aec1d5f8d883", - "b833ff9e1d300a25e634e4c71dcc7755", - "7b905bd8f0eb7b39c797f1812c70fe55b5201ed9d2b0e38154f4c0085e026303", - "b6ce0c225e3dd003cbad4d0ee9731876713be06ac396798292a0ed118b86ba54" + "4dc9722bd67b687a", + "b55bea562d9db3a5" ] } }, - "max_gas_amount": "13956917626014664570", - "gas_unit_price": "12414917268344739473", - "expiration_timestamp_secs": "9222137133471424349", - "chain_id": 134 + "max_gas_amount": "7087822654672157468", + "gas_unit_price": "5386696312750303881", + "expiration_timestamp_secs": "16097047032009723918", + "chain_id": 101 }, - "signed_txn_bcs": "f508aee9e8be65a1ff3f88210946013475d8c883c5789296126b22d7812488118bbcba1f3a65d9660291d47d3a4e99dbe306e8e35101ac56b6b1377168b06a9303a552c29a3684c1e71572596358476e6753656872684e4c4d365f436f696e12586d55476676515051594c6a6f76494662310706060601077126b68c7e144a5556b281a4bfeb4893e755a1c4aedf3562eaa3c4b23d051d4c1d614e684946686d6b70516e645a7a77644756444f6a704e534e4b6f73301f467043635567707a49456b466d5a67485845535465796a776150747955443000060603070f3767e8f3418727b349469f6caa379975e738ba0565d806dc5fe630ac9beeee0c6f58546759427963575776390e4e596571796f626e4b496a6852340007e352dc78be93047b539cd60678c99ff025da2ab58d82300b8513a1fd4b3ef82d14474e5a73686b44666f79696d50454861794a6164094757486f76435a70710007189f78f12ec09d40dfcab3ff56b174ae89d0306cafea87d1b57da68e500009c50455734330204d586f66734642624f6d4f4c4673456b68714b79465269565a6f57547967713300060772913d4c8c65161b174d33f965f0f580a61b1ec2e12a6a476e29794cd765fdae114562497a5761524c466f586b42785a6e35134b64566966756552596167565977616b69724d0009010010bf9723de9ca9bf5f706a72460ee037ac1059ac0e2cf75f823cf7fdaccd052593ca013010714674d1f28e74b8060194c43de7e60810534b326cacf75f4c8c80aec1d5f8d88310b833ff9e1d300a25e634e4c71dcc7755207b905bd8f0eb7b39c797f1812c70fe55b5201ed9d2b0e38154f4c0085e02630320b6ce0c225e3dd003cbad4d0ee9731876713be06ac396798292a0ed118b86ba547a07fe49a2eeb0c191168d7f7aa54aac5ddf80a6dc9cfb7f86002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a115c7bd22d4d1d00339c41e087c5284554cdafed1c7ea53dd6768da638ae7d320bcb2382a17c982bb7d5c3026b2ce651646bf15523dd539ea069fa79a764404", + "signed_txn_bcs": "db21e20f06cac0a7c5cac21311c387deff22296df93e7602d255b41cfbe7b724598d016185073d55029549166ecd4856f553a71a4dcb7e65dea803ffa79adeb40828af2ea69f001cb10747725f436f696e144b41636c444946454551566b464c4274556a5653070607294f0d417eab6c82a5e234b3dbfb1cc01a9dd0a58048eec3c0a6e1564e8eb4c6156c696356475a56787459737551654c77494679503618716e65706a79544f7a77417455694d6e595252426f6d51330006060107f867803cc5828dddc90181dbec6a1a82f7a81f7403185d88c0b7e6278a262f320c636d6c454c76475372585632217859465545534956796a736b6a7a7a4d706d7258576766796a73446b7156567430000607588085a949dc743119e7ce3bd3b01df1f25c4bc2feeadde76db0d07e5cf3b6121246596d526b586b61437a4d6670744d694d5003436d460006060507a05f9b1fb59f6f508084622f923124a5c5af0979ab9dc1fc26185529d0b5325b154d6961545a6d576977786370575676756a4a565636186947504a6b4c426e50474245464b70414a61536a4955414f000607ef65043b74a0aea0ac3ae913b345f77dbf5b2733b2d076e41e708e9c9dad387a1b64555356456e65476a594a67426d4f445045724a616748574a4d31124b437858666c5143454f6b6e5855426d6c310002084dc9722bd67b687a08b55bea562d9db3a51c3bb3ca26015d62896a63aac163c14a0e10b263fd3264df65002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440540577ce6acbe7934e97c5f9075b7348686af56b0e2249d35e7fc3ecee264680a4aaac0f0ce4c17581791bb7ee92c619374d8144ada75a7b994e20b12133b80d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "1a5b4722ee4fc8d0d8a169fa7cbb775781198b2144b8b4f543c26cbc0756968a", - "sequence_number": "9909356483017387857", + "sender": "ef76e208bd7aad105f1bcad7af1d9dca8c529cbe6e8eeaa5ce95a40ffcf87c11", + "sequence_number": "3568203870469089742", "payload": { "EntryFunction": { "module": { - "address": "f78eaaf80e695ad24d1df6d6d73cf1cac39b8044fa202a3ec5fbd70354235a88", - "name": "FZnpisFL0_Coin" + "address": "f61cfc21d718cb8573a2fd671ea3ce103f8ae748f8d91ad71e6ea4b27d5da46e", + "name": "icwgSfIjcSOPjqjtjURHjGZ4_Coin" }, - "function": "YvLBXOSOuzozUbOUbk", + "function": "ZoRRoSBDENFMdWKzzZnyiwhaWjWVKam8", "ty_args": [ + { + "struct": { + "address": "abd5b1ce268f4ee63d3e8ff89c742740cf1892c8902c9cb141905bf050ce072e", + "module": "pKJJGTShQcWXNAJ7", + "name": "AjkwQuUFSfVOZGpZuwYfjZooME9", + "type_args": [] + } + }, + { + "struct": { + "address": "e098e6a947216c0abbf21a765e280633e754710707eb1ee41fa64c0d023e930e", + "module": "BKLnOoCmOnUPnnIHFxrWDoYyGjAuMvi", + "name": "VWNMrnhmVmVUGZFHqc", + "type_args": [] + } + }, + { + "struct": { + "address": "19d4d59dd306f229a29a6e0cc0a43bf0115452580f9a7a2a5e2a6250b96ef4ca", + "module": "agQFsDMnZryBotEvoLTQxEUQegR1", + "name": "IEAx", + "type_args": [] + } + }, { "vector": { - "vector": "u8" + "vector": "u64" + } + }, + { + "vector": { + "vector": { + "vector": "u64" + } } }, { "vector": { "struct": { - "address": "b5ea179dace4702cfbfcc9e950a54cb6037a0a443b0ed99f1580528e351fe5f4", - "module": "MiymArhMA1", - "name": "cMbSLYPHhBTu", + "address": "89d9338477d513f9b2f313c5d9a93c115b5b2d2b85310963c031b9f65b6df4ff", + "module": "nhbuNHdObMaPXBtAjdiXVw", + "name": "YkAXAKpD", "type_args": [] } } }, { "struct": { - "address": "aa88ae6b4ab92ea1eb8c3d27b29f68f25279614c47b6478f4ad2cbb35bcb6bfb", - "module": "WHhTPyTC7", - "name": "xyqdIYdzNQDKqBzsCIv6", + "address": "9cd67396e922e6b449ebaf30d1a0b3c5bf0c6f26e8e90efbdb5cdb49fda9e652", + "module": "twBe8", + "name": "FLykkphBxCXhWkv", "type_args": [] } }, { - "struct": { - "address": "8a31b3fe89546607c6c71ce54a3fd88273db518854b62b2642b40fe36fa906e5", - "module": "JjgpQzUMMdIMf6", - "name": "DxUMSfKDMLkSWXUwXkgJHPY3", - "type_args": [] + "vector": { + "struct": { + "address": "ae15ca5aba5b60cc6e0041bca651792c41088c48d7e92dc0cfd3b33be459be7a", + "module": "lPuhBMJYnhFovDwawm", + "name": "PbgmQxLpChftyOLwEFGJuXkFhV", + "type_args": [] + } } } ], "args": [ - "2e6e16fd001e1cca65e04274689782949bf1c25b196a5d7ff1ba7e8796b61770" + "0035f384be186f26", + "e61accf7c33617585ab220a264535f3fd1c0d6fa2299d7e4a9e9966cb2addd80", + "dab449b40c45f534" + ] + } + }, + "max_gas_amount": "5978384933565601556", + "gas_unit_price": "12697481204468443067", + "expiration_timestamp_secs": "4085833426773117905", + "chain_id": 196 + }, + "signed_txn_bcs": "ef76e208bd7aad105f1bcad7af1d9dca8c529cbe6e8eeaa5ce95a40ffcf87c11cee97bd983ce843102f61cfc21d718cb8573a2fd671ea3ce103f8ae748f8d91ad71e6ea4b27d5da46e1d696377675366496a63534f506a716a746a5552486a475a345f436f696e205a6f52526f534244454e464d64574b7a7a5a6e7969776861576a57564b616d380807abd5b1ce268f4ee63d3e8ff89c742740cf1892c8902c9cb141905bf050ce072e10704b4a4a47545368516357584e414a371b416a6b77517555465366564f5a47705a757759666a5a6f6f4d45390007e098e6a947216c0abbf21a765e280633e754710707eb1ee41fa64c0d023e930e1f424b4c6e4f6f436d4f6e55506e6e494846787257446f5979476a41754d76691256574e4d726e686d566d5655475a46487163000719d4d59dd306f229a29a6e0cc0a43bf0115452580f9a7a2a5e2a6250b96ef4ca1c6167514673444d6e5a7279426f7445766f4c5451784555516567523104494541780006060206060602060789d9338477d513f9b2f313c5d9a93c115b5b2d2b85310963c031b9f65b6df4ff166e6862754e48644f624d6150584274416a646958567708596b4158414b704400079cd67396e922e6b449ebaf30d1a0b3c5bf0c6f26e8e90efbdb5cdb49fda9e6520574774265380f464c796b6b70684278435868576b76000607ae15ca5aba5b60cc6e0041bca651792c41088c48d7e92dc0cfd3b33be459be7a126c507568424d4a596e68466f76447761776d1a5062676d51784c7043686674794f4c774546474a75586b4668560003080035f384be186f2620e61accf7c33617585ab220a264535f3fd1c0d6fa2299d7e4a9e9966cb2addd8008dab449b40c45f5341497b9176c7df752bb678a9ee18336b0d18b3a9edacbb338c4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440db2bc9ad0a6aba3a6e157b4407c87a076657d16391cd0d5ca19500aa58ba4340210ca948eb959f15b8258ded50fb5eeef88181c85adaafa72894c272bec78500", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "19ffbaadb1307587f637b9ee84cf6590f8398bfb1ddf90d55637ee36a4dde8da", + "sequence_number": "10760634243356899393", + "payload": { + "EntryFunction": { + "module": { + "address": "786103b9609086e6a1873e1f5ff5bc03bc12cc378d8459a51f76edeb17c91115", + "name": "j_Coin" + }, + "function": "dRFQVjTjsJsiwuYSxuOGaMebGVhLBViH2", + "ty_args": [], + "args": [ + "cbcdcf695bccfd32efb5141ca30dd4a04abd1aec5804ac0e9cba84967efc76d2", + "7d3a8cc9495b5d2de87f0006c47f7c67", + "67d1e8023cbc871abf79ec37929b7eaa7f9ed39adfbe96e57ac34d72739dbce4", + "d0", + "754f7cca9b0faeb75731fd6778e5475fbd9127c6c9d3606cc2afa04b4d1d1bb9", + "00", + "90" ] } }, - "max_gas_amount": "12141343625491720070", - "gas_unit_price": "5233756779710902830", - "expiration_timestamp_secs": "9649027066944241969", - "chain_id": 61 + "max_gas_amount": "17198227190739173324", + "gas_unit_price": "9584021427452052761", + "expiration_timestamp_secs": "14195817529465238459", + "chain_id": 31 }, - "signed_txn_bcs": "1a5b4722ee4fc8d0d8a169fa7cbb775781198b2144b8b4f543c26cbc0756968a512ff722381b858902f78eaaf80e695ad24d1df6d6d73cf1cac39b8044fa202a3ec5fbd70354235a880e465a6e706973464c305f436f696e1259764c42584f534f757a6f7a55624f55626b040606010607b5ea179dace4702cfbfcc9e950a54cb6037a0a443b0ed99f1580528e351fe5f40a4d69796d4172684d41310c634d62534c595048684254750007aa88ae6b4ab92ea1eb8c3d27b29f68f25279614c47b6478f4ad2cbb35bcb6bfb0957486854507954433714787971644959647a4e51444b71427a734349763600078a31b3fe89546607c6c71ce54a3fd88273db518854b62b2642b40fe36fa906e50e4a6a6770517a554d4d64494d6636184478554d53664b444d4c6b5357585577586b674a485059330001202e6e16fd001e1cca65e04274689782949bf1c25b196a5d7ff1ba7e8796b6177086276325b3b77ea82ef275bf0f0aa248314157a1fe3ae8853d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440928106fd159c95a655e578cca3628d4591e7590421c9511eebd155c794bd912f019c7f5c658138dcefe15e6e163d2647815a7a9713eab031078cea61d016d80d", + "signed_txn_bcs": "19ffbaadb1307587f637b9ee84cf6590f8398bfb1ddf90d55637ee36a4dde8da41383101d573559502786103b9609086e6a1873e1f5ff5bc03bc12cc378d8459a51f76edeb17c91115066a5f436f696e2164524651566a546a734a73697775595378754f47614d65624756684c4256694832000720cbcdcf695bccfd32efb5141ca30dd4a04abd1aec5804ac0e9cba84967efc76d2107d3a8cc9495b5d2de87f0006c47f7c672067d1e8023cbc871abf79ec37929b7eaa7f9ed39adfbe96e57ac34d72739dbce401d020754f7cca9b0faeb75731fd6778e5475fbd9127c6c9d3606cc2afa04b4d1d1bb901000190ccff78868260acee190503bfb5480185bbf30994d4ac01c51f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ba85c68b9a25526e840d0a53ddf423f084274fbe628c0d0152dd8e163546ae188eca3e917f70301197b6dc562b05c56a81a5537c365ceaafe69fc7d54ba2760a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "0e5f3a9a117cee5cba2c122690ba630c6bcfa60b0e3627cb66497a80ab434c6f", - "sequence_number": "14731477467461079559", + "sender": "3c68ec584027dc36ca3f6f63d2f233b63c59b3c151fe026b76333d0f5b9bfb60", + "sequence_number": "17390244856979794740", "payload": { "EntryFunction": { "module": { - "address": "efb4268809c1b90b4c6739dd67711a24ae26bf45c046fcc3081ecaeeb62953c4", - "name": "jhpD_Coin" + "address": "4ddea3eec776f30f4847204d540158b849e207beebef55ecc7f7a835e71a56e8", + "name": "LDqfapClUMsQwmonNiF3_Coin" }, - "function": "RZaOerKznxYsGoGgGHBxT", + "function": "zOnmGAQqPoXhEpRhctDxYg5", "ty_args": [ { "struct": { - "address": "c9c48aeca6fdaf4fd50ef4c54a3e057334108412c9b2dcee22dbd26b4e2c700d", - "module": "yTcZcGyFrTRsSYyJrBVGRgXtD", - "name": "mEAmolnkomZxs", + "address": "701350223e3cdab45446e5108013d95bbb074b7b7d5023ccfda3e5ae212b173a", + "module": "kjCpRYHoUcCOdtfIlhj6", + "name": "zCOagnmXTELFDOLzYTXv", "type_args": [] } }, { "vector": { - "vector": "u64" + "struct": { + "address": "e658419e417115d1c60b01163f1012fad905cd42f2108c68d3cf3010fdc13b70", + "module": "IcLSmgnLHKplZNsUvibbtaJ", + "name": "Soy", + "type_args": [] + } + } + }, + { + "struct": { + "address": "2edf45ce26ed750f48ac6572bf6b4fa931927c09aaedbbb07c9eb9bb65de21df", + "module": "aUXzCyjkJar8", + "name": "vRWrYNLyMUfmopPjfHdICeMzcAmELxP6", + "type_args": [] } }, { "vector": { "vector": { - "vector": "u8" + "struct": { + "address": "e1d6b084c1f753b1d0304bc83ab20d5fc44aa8a50408a8c8b9cefdba2c428f5e", + "module": "VxFsDPVOrxplZLY", + "name": "dWWrQui", + "type_args": [] + } } } }, { "struct": { - "address": "60d5d253f4c8d5cf74549332ddf0addee4e8e63094c3e8b2691248fc4abd4e6b", - "module": "LB2", - "name": "D8", + "address": "c30d2d828fb656cffd85d38bf06d8e06d93fae8441a9b9adfde74c3ae1692990", + "module": "vZD1", + "name": "tbREAMmIQhlhgeF8", + "type_args": [] + } + }, + { + "struct": { + "address": "2f7f0ec5ac3242a8cfa8bf75fcdd3c30bdcb7cf9e6efbe6baee92133cad1d719", + "module": "ETihgVFQeJytPCFc", + "name": "ebd2", "type_args": [] } } ], "args": [ - "794212eaeaf922fb", - "04584748faac8e37", - "88b372ff2aa3fd15" + "01", + "bc28daeefa1d0c87", + "1d1c6fe79f590043549431784146a402", + "01", + "00", + "00", + "2ff2d2197ccfcb4b656de0bc6f41a4f1" ] } }, - "max_gas_amount": "2906846268964641390", - "gas_unit_price": "18273790671293480295", - "expiration_timestamp_secs": "1892230298483870303", - "chain_id": 182 + "max_gas_amount": "2153991594174387025", + "gas_unit_price": "2953682040473812213", + "expiration_timestamp_secs": "8717308078034732449", + "chain_id": 17 }, - "signed_txn_bcs": "0e5f3a9a117cee5cba2c122690ba630c6bcfa60b0e3627cb66497a80ab434c6f0752b0b8b4b870cc02efb4268809c1b90b4c6739dd67711a24ae26bf45c046fcc3081ecaeeb62953c4096a6870445f436f696e15525a614f65724b7a6e785973476f476747484278540407c9c48aeca6fdaf4fd50ef4c54a3e057334108412c9b2dcee22dbd26b4e2c700d197954635a63477946725452735359794a7242564752675874440d6d45416d6f6c6e6b6f6d5a787300060602060606010760d5d253f4c8d5cf74549332ddf0addee4e8e63094c3e8b2691248fc4abd4e6b034c4232024438000308794212eaeaf922fb0804584748faac8e370888b372ff2aa3fd156e9a4ece47315728677d4bfecb8b99fd5fca5c566e8d421ab6002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440cb973207e191ae2c4a0e467ea114e7c684ebe42d7b1953c3f91036a2c78963da599d371621831e1cf6c943070bb8fb086948c3641533982aac15b06369d5820c", + "signed_txn_bcs": "3c68ec584027dc36ca3f6f63d2f233b63c59b3c151fe026b76333d0f5b9bfb60342b58598f8f56f1024ddea3eec776f30f4847204d540158b849e207beebef55ecc7f7a835e71a56e8194c4471666170436c554d7351776d6f6e4e6946335f436f696e177a4f6e6d47415171506f586845705268637444785967350607701350223e3cdab45446e5108013d95bbb074b7b7d5023ccfda3e5ae212b173a146b6a43705259486f5563434f647466496c686a36147a434f61676e6d5854454c46444f4c7a59545876000607e658419e417115d1c60b01163f1012fad905cd42f2108c68d3cf3010fdc13b701749634c536d676e4c484b706c5a4e73557669626274614a03536f7900072edf45ce26ed750f48ac6572bf6b4fa931927c09aaedbbb07c9eb9bb65de21df0c6155587a43796a6b4a6172382076525772594e4c794d55666d6f70506a6648644943654d7a63416d454c78503600060607e1d6b084c1f753b1d0304bc83ab20d5fc44aa8a50408a8c8b9cefdba2c428f5e0f567846734450564f7278706c5a4c5907645757725175690007c30d2d828fb656cffd85d38bf06d8e06d93fae8441a9b9adfde74c3ae169299004765a44311074625245414d6d4951686c686765463800072f7f0ec5ac3242a8cfa8bf75fcdd3c30bdcb7cf9e6efbe6baee92133cad1d719104554696867564651654a79745043466304656264320007010108bc28daeefa1d0c87101d1c6fe79f590043549431784146a402010101000100102ff2d2197ccfcb4b656de0bc6f41a4f15113f14bf183e41df57ce4a12a96fd28a145e7bc8219fa7811002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f19228b6eb7129addc430ff23c7f00af9e07c6fb9b4b9b0dca8e4174fbdb5990ebd55bf8a9d0c0f778b448ebd65d1767d0174b556449cc46fc92ab5fc82d3a0d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "a385c204a88000efcb5cdd922adc043ab5a3332d5c15302548036ace686ad9da", - "sequence_number": "13704468344051268201", + "sender": "2e20d7c37b1e02e358b7c7363035a46ee62c1027a8fe6053f90741cd5116ce2c", + "sequence_number": "13292118493125151970", "payload": { "EntryFunction": { "module": { - "address": "d528e4c4d77ad4096fbc1822320f9d049768996e8362eac97be042f0fb46b480", - "name": "VrPjDswDgxEfRUACgw6_Coin" + "address": "3bf9191e78251d273a4ee049a35d1b898bbca0c2929727d437773e3d4dd578b2", + "name": "IwprzCDLkcuLMCTgG0_Coin" }, - "function": "IwOvKLAavjblSoPumHYOKVcWOYoVh4", + "function": "IXiYFIWxyMXEOMzwavLt", "ty_args": [ { "struct": { - "address": "2993dfef5ec0db4af60cc49cafe4e44dc6da010e5c8eee92f79b17d92c9e788b", - "module": "GSiLplAdjYfyRYzFVVwonSZdNG", - "name": "FkThBfdLNXiUKwlEVJtugYcv8", + "address": "d550b52aee82be61055a519fdc29bd702f115aef5e7f2a133dae52ebc63bef3a", + "module": "MMedQDmbxNuBSCGLnUMlfXhDX4", + "name": "GxmPrUh6", "type_args": [] } }, { "vector": { - "vector": "address" + "struct": { + "address": "c07fbde8d27ec9b72033b8a87327342a13712c729b8a8f418c458c00d48108bc", + "module": "mECBjERfYUmkSUBlbPeBen", + "name": "wUkDtUmzs", + "type_args": [] + } + } + }, + { + "struct": { + "address": "1e22e9b93d00e38d0520a508ba44cd7296a0cb3e32e6e94af61458c9548307a8", + "module": "bCNxiIhtFUYjADitqhBqkyCso", + "name": "KqvEVeOHgpvtKsepKeohaGnTtoM", + "type_args": [] } }, { "vector": { - "struct": { - "address": "ee9771fa6d7d2f28eee2496fdf188ed03805b7d063201c3ef910880a48571197", - "module": "r5", - "name": "ROqhyzBBVwEZEaNYZRZZc", - "type_args": [] - } + "vector": "u8" } }, { "vector": { "struct": { - "address": "aade919e95a1ce2ce75142d67f3eb0dd609c51fd1e1ac8407c41a2f0e04048c7", - "module": "ypnBOodtpw4", - "name": "gSECCCEEVrdccGTonWm6", + "address": "920b5d3ae685e437fb87e4daac09255d065df57daf1a34925dd58125b9831b6b", + "module": "xmgyqKrKaVeRfk", + "name": "ZRVyD", "type_args": [] } } }, { "vector": { - "vector": { - "struct": { - "address": "1e7165c9654c9e8833f4e16b553850e7a255a60192749edd67babb81a35c2955", - "module": "oQIlpRfGXMcnQNFKKCSJCDGYoSlSbevM", - "name": "FhKsnhrcVWiVViQU1", - "type_args": [] - } + "struct": { + "address": "4f11a194ff87b5c60978cea042e77c6693b6bd2f49301c4be3037364f3151418", + "module": "UMcnfeMJJsdYsRaASkFghSDuSc", + "name": "EUbSRCDtlNF0", + "type_args": [] } } }, { "struct": { - "address": "386210bdeaa52f74c499e9c087222aae35ee37821d62d664ec223f2f5aa57af0", - "module": "mjAUijmoS0", - "name": "VLeckVxCSLMdHiuavNfQhRfmOllFOVBm6", - "type_args": [] - } - }, - { - "struct": { - "address": "fef7f4a99485b4352df04e1a5e4a217ec080f3bce538b445a14cd86e4541d90b", - "module": "qbaRY", - "name": "GxsP3", + "address": "a0db485ce70b7a86ad3c7f0fbe157498533d9779e084cda141195d6357447778", + "module": "TaeQeYOfCxoJoGfVYcU", + "name": "suGbejDqIjpZrwfKjP9", "type_args": [] } }, - { - "vector": { - "vector": "bool" - } - }, { "struct": { - "address": "d7fcb3662122cba4982d03793481d0bddce4320ab977b083281cf2027e775683", - "module": "FtfmbEcsIf8", - "name": "kEqCUKXzn", + "address": "dec1bd013459b6dfd50447217498858823e8e94425b6857979424a4103a09f59", + "module": "xqkzc", + "name": "lEcTTiev", "type_args": [] } }, { "vector": { - "vector": "bool" + "vector": { + "vector": { + "vector": "u128" + } + } } } ], - "args": [] + "args": [ + "f2c6d4904ab08c86afa601e5659cea8e97bcce58bb4e6accece1844e784cf521", + "ce", + "00", + "3777e4aa82b3177c", + "1f", + "01" + ] } }, - "max_gas_amount": "787700363516691461", - "gas_unit_price": "2253623552836068268", - "expiration_timestamp_secs": "12924879428485727890", - "chain_id": 253 + "max_gas_amount": "12812229658802979376", + "gas_unit_price": "10387984302647450081", + "expiration_timestamp_secs": "16871334350373130331", + "chain_id": 183 }, - "signed_txn_bcs": "a385c204a88000efcb5cdd922adc043ab5a3332d5c15302548036ace686ad9da69fac27a590d30be02d528e4c4d77ad4096fbc1822320f9d049768996e8362eac97be042f0fb46b480185672506a4473774467784566525541436777365f436f696e1e49774f764b4c4161766a626c536f50756d48594f4b5663574f596f5668340a072993dfef5ec0db4af60cc49cafe4e44dc6da010e5c8eee92f79b17d92c9e788b1a4753694c706c41646a59667952597a465656776f6e535a644e4719466b54684266644c4e5869554b776c45564a74756759637638000606040607ee9771fa6d7d2f28eee2496fdf188ed03805b7d063201c3ef910880a4857119702723515524f7168797a42425677455a45614e595a525a5a63000607aade919e95a1ce2ce75142d67f3eb0dd609c51fd1e1ac8407c41a2f0e04048c70b79706e424f6f6474707734146753454343434545567264636347546f6e576d36000606071e7165c9654c9e8833f4e16b553850e7a255a60192749edd67babb81a35c2955206f51496c70526647584d636e514e464b4b43534a434447596f536c536265764d1146684b736e6872635657695656695155310007386210bdeaa52f74c499e9c087222aae35ee37821d62d664ec223f2f5aa57af00a6d6a4155696a6d6f533021564c65636b567843534c4d6448697561764e66516852666d4f6c6c464f56426d360007fef7f4a99485b4352df04e1a5e4a217ec080f3bce538b445a14cd86e4541d90b0571626152590547787350330006060007d7fcb3662122cba4982d03793481d0bddce4320ab977b083281cf2027e7756830b4674666d62456373496638096b457143554b587a6e000606000005c4dba44e79ee0aac633f5cae7a461f9246a57b5c655eb3fd002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409bac87e879f6815dc4aa01e3618d5bd1df6418a68536bab89d090b0310172cefbdf079f501a1801531e36cf731e5d15c23ac8928795c4896aaf4a0ff40d5440a", + "signed_txn_bcs": "2e20d7c37b1e02e358b7c7363035a46ee62c1027a8fe6053f90741cd5116ce2ce20c2047581777b8023bf9191e78251d273a4ee049a35d1b898bbca0c2929727d437773e3d4dd578b217497770727a43444c6b63754c4d43546747305f436f696e144958695946495778794d58454f4d7a7761764c740907d550b52aee82be61055a519fdc29bd702f115aef5e7f2a133dae52ebc63bef3a1a4d4d656451446d62784e75425343474c6e554d6c6658684458340847786d5072556836000607c07fbde8d27ec9b72033b8a87327342a13712c729b8a8f418c458c00d48108bc166d4543426a45526659556d6b5355426c62506542656e0977556b4474556d7a7300071e22e9b93d00e38d0520a508ba44cd7296a0cb3e32e6e94af61458c9548307a81962434e78694968744655596a41446974716842716b7943736f1b4b71764556654f48677076744b7365704b656f6861476e54746f4d000606010607920b5d3ae685e437fb87e4daac09255d065df57daf1a34925dd58125b9831b6b0e786d6779714b724b61566552666b055a525679440006074f11a194ff87b5c60978cea042e77c6693b6bd2f49301c4be3037364f31514181a554d636e66654d4a4a73645973526141536b46676853447553630c45556253524344746c4e46300007a0db485ce70b7a86ad3c7f0fbe157498533d9779e084cda141195d6357447778135461655165594f6643786f4a6f4766565963551373754762656a4471496a705a7277664b6a50390007dec1bd013459b6dfd50447217498858823e8e94425b6857979424a4103a09f590578716b7a63086c456354546965760006060606030620f2c6d4904ab08c86afa601e5659cea8e97bcce58bb4e6accece1844e784cf52101ce0100083777e4aa82b3177c011f01013002ad19fe2eceb1e199a273af8829905b10d618340523eab7002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400928d9e0cb72569fe718fbdcd5bc786cef60922ee4d2fdd4839ee8b4676250122ce5a12499070d698541d5aef03eea23d50fd3c452ba7f0d4eb3d8074ab8060d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "41e4f51efd906a78b101ec45005dc1b1e7e3bdb5106067d04aee032f9e950bd7", - "sequence_number": "18052590803928200838", + "sender": "f56da85068d328ca9f4f000f7f158bac3791d2f4e77fcc9942edba3d288e8661", + "sequence_number": "2381091883749179909", "payload": { "EntryFunction": { "module": { - "address": "b00b3bc4630f54aa5eba8e03e250c329900ce4e13797cf4d66deba8082273031", - "name": "sitibnobnSpx4_Coin" + "address": "49ce1e2ebf1166b97ec7d8ae199548a7ac968d45b584e00d948f4895147595c1", + "name": "TCkM_Coin" }, - "function": "BejSHvtcNAZXEzbPYbwFRy", + "function": "WqvmNFxwIJUWEvCgNbeMKJOQEnVMD3", "ty_args": [ { - "struct": { - "address": "6cb86465135097d01663f9934cc9e06a94e3c2f7f50e5c1093c324c63ef7419d", - "module": "bJQB8", - "name": "nlZYOjIWeQNiVoUw1", - "type_args": [] - } - }, - { - "struct": { - "address": "6d049dc804ad0be6b456670ffe578ec64b1430ce1a79340018dd973309d6f37a", - "module": "kfjhLPRvbuJZxYFzzohBqeROhAhM", - "name": "dSlTIAyoPtInGFMQwHZNWrgEt", - "type_args": [] + "vector": { + "struct": { + "address": "89e5575c81bf859caef143b0adfdb331e2b9267209b41073f9c24eb4386e3ec1", + "module": "KknxyVOPBXCQSNUAk3", + "name": "QpxrMdokDLxUiFGFszSXoglsv", + "type_args": [] + } } } ], "args": [ - "e0862d486cfbc3ce", - "89", - "f9a300544be778ae9f8364130827f6d8a48df09a21d63deb71daf90590f69ca5", - "00" + "f73d46165c8fc9567ad697b9f7c27863", + "cf2964467eef594f", + "01", + "01", + "987ca20f1b0bd902edc891a6a3093a3d", + "c3ea89772df7ce25aba1b9c236575da2e234bf66c2ae244c3b67cbb3ad6407fb", + "1be094ef12ebba7ac96777ffcdff8394" + ] + } + }, + "max_gas_amount": "6873527945612096672", + "gas_unit_price": "13091222159671541088", + "expiration_timestamp_secs": "3260526299180740587", + "chain_id": 216 + }, + "signed_txn_bcs": "f56da85068d328ca9f4f000f7f158bac3791d2f4e77fcc9942edba3d288e866105826fe473560b210249ce1e2ebf1166b97ec7d8ae199548a7ac968d45b584e00d948f4895147595c10954436b4d5f436f696e1e5771766d4e467877494a5557457643674e62654d4b4a4f51456e564d443301060789e5575c81bf859caef143b0adfdb331e2b9267209b41073f9c24eb4386e3ec1124b6b6e7879564f5042584351534e55416b3319517078724d646f6b444c785569464746737a53586f676c7376000710f73d46165c8fc9567ad697b9f7c2786308cf2964467eef594f0101010110987ca20f1b0bd902edc891a6a3093a3d20c3ea89772df7ce25aba1b9c236575da2e234bf66c2ae244c3b67cbb3ad6407fb101be094ef12ebba7ac96777ffcdff8394a0f4edbf3fad635f60bdf1a6315dadb5ebaf7ce364b73f2dd8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440adce82e43ae44894afd9532e24a361edb41690779e604f630f7e2d54c932212ebc94a7d4deddd05da776a9ebfb427059bcaa62bdf43b3b39252e36a97efcaa0c", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "89096e1bbacac0bf73e8f01a5ad8859444e743e7c09357d7f520ed420c0f618f", + "sequence_number": "16646303590430540292", + "payload": { + "EntryFunction": { + "module": { + "address": "38cda35d66d698be8342b209283e25540fb019e071b10bddb44857b73c08af49", + "name": "aIqWIcx_Coin" + }, + "function": "fucjiQdpkxGHDvvSCzeIE", + "ty_args": [], + "args": [ + "32080be3deec3678", + "2cb863c3a69c3d11e0cd07469d96bb6e", + "c1d426523e43dc23913b883df9ed1e20", + "2943fe529dbf949a2b9fae4f06ccf864" ] } }, - "max_gas_amount": "17484836495617486891", - "gas_unit_price": "14301740504977152099", - "expiration_timestamp_secs": "2474958349761980257", - "chain_id": 245 + "max_gas_amount": "13720985037169515524", + "gas_unit_price": "1549985750013368675", + "expiration_timestamp_secs": "8310368323352221542", + "chain_id": 196 }, - "signed_txn_bcs": "41e4f51efd906a78b101ec45005dc1b1e7e3bdb5106067d04aee032f9e950bd786b69f7fb0af87fa02b00b3bc4630f54aa5eba8e03e250c329900ce4e13797cf4d66deba80822730311273697469626e6f626e537078345f436f696e1642656a53487674634e415a58457a625059627746527902076cb86465135097d01663f9934cc9e06a94e3c2f7f50e5c1093c324c63ef7419d05624a514238116e6c5a594f6a495765514e69566f55773100076d049dc804ad0be6b456670ffe578ec64b1430ce1a79340018dd973309d6f37a1c6b666a684c50527662754a5a7859467a7a6f68427165524f6841684d1964536c544941796f5074496e47464d5177485a4e5772674574000408e0862d486cfbc3ce018920f9a300544be778ae9f8364130827f6d8a48df09a21d63deb71daf90590f69ca501002bf01075279ea6f26398fa2437fd79c66127739781d15822f5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400d2e55900a2dfd226b61d2404243e22619e6db6052e0ace1cdc67af00185aaeadb0426efe76396f051c0726487c070c3e5610a1800c43e2ab52c79d3ad86e30f", + "signed_txn_bcs": "89096e1bbacac0bf73e8f01a5ad8859444e743e7c09357d7f520ed420c0f618f0402ec6aeb8c03e70238cda35d66d698be8342b209283e25540fb019e071b10bddb44857b73c08af490c614971574963785f436f696e156675636a695164706b78474844767653437a65494500040832080be3deec3678102cb863c3a69c3d11e0cd07469d96bb6e10c1d426523e43dc23913b883df9ed1e20102943fe529dbf949a2b9fae4f06ccf864045cf0c431bb6abe63d976d4d3a78215665711baf55b5473c4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405277a23229093ff77dec95ea68b34af6d799f52c002ededd18964bee1acf63000aba560dbb061a832bf59b8f44c1237a57c0c9c8e5c9646bbb9bad03b5679a05", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "860786a2e72ff6bfb4269ab8925f514e02849da1d55da5c5686731b641ad7bd4", - "sequence_number": "4238815789794674729", + "sender": "f147491bfcad57b97d5c2d174711e0693e22976fa790f081b0aae4b4d27593c9", + "sequence_number": "2295976120420002857", "payload": { "EntryFunction": { "module": { - "address": "3c22488bafcb15495a5d163c7c108f356e187e9db9b6f7b563c2fd0dbca7141b", - "name": "BrZhiRCBkj9_Coin" + "address": "60165d39eeea8c26a1e8f558a3a353770364495fefe980593bf213ad4ff43436", + "name": "WiOMlEo8_Coin" }, - "function": "EYYdTuVugsTbfykfvoGmDQ9", + "function": "huXGQCTdzXFxlojzvVaRAvoFve4", "ty_args": [ { "vector": { "struct": { - "address": "0f6c49258197632e2e7607039ef09e5014701644697e82d57e74980dda7fd350", - "module": "cgcHEASgyNWFstPRtgDFoEjPdTEVSYKK", - "name": "C4", + "address": "34d6045ed94c34b6692020ac9be1d65e0f682ca28a6ed5d0b5362cfcd1d59aac", + "module": "fMoREh", + "name": "WNDmulBOlTpntiM", "type_args": [] } } }, { "struct": { - "address": "d17adc7b66ca5c45cd9d7d40b45c6398ef416bddb84a3909d17c33b61b60dac0", - "module": "J", - "name": "scVDUiVzlbjojltjtPWcGyYBOfWY2", + "address": "df7b06a43804e9849cda19520de4fe6b2423470f765354df246c714d34a6bcb5", + "module": "bpJxrHIOZtkEqwAJciSIoienZqs", + "name": "lQDxxqxabCzJwICprxmfVACXrgMsWkM9", "type_args": [] } }, { "struct": { - "address": "9a169316ddbdb6b5bac240aacf75bcc7345a010b11d84296fd19650faedb72a8", - "module": "BoYsHeJkePGMrCuNcJjBHgAHkdXew1", - "name": "hrQztUKbtAQPmNwj", - "type_args": [] - } - }, - { - "struct": { - "address": "975efb5db65d1004bf46294f302442a7aa2c01fd1527a93cc3d5f8fde315079b", - "module": "ebLZCPtViTQ", - "name": "AXqxrY", + "address": "816da3c80107b83f5358b779f363a2d91204a2444b37da9591adde2d000b7de6", + "module": "LFoOytcjGY0", + "name": "cNZoAjYflPhgOxYWcDzUYoFSNK9", "type_args": [] } }, { "vector": { - "vector": { - "struct": { - "address": "ab4e989cad803d8125ab3879879d65127551510a7821030b99b5e35e7327d316", - "module": "DdKOQNtWBXAHtHqnNmPvMrHIAbYlUyNZ", - "name": "hcbRkETOzdHUOTqaKpJpfcvgXD", - "type_args": [] - } + "struct": { + "address": "552324dba74b8af97fdf022428888a887bc8ef8569bf1ad65c40941d273d6856", + "module": "agdVMJhH8", + "name": "gnRFQYHYHJmV5", + "type_args": [] } } }, { - "vector": "u128" - }, - { - "struct": { - "address": "ed3895aa0898bbd5c47991ec3b128156b7db80678b65591edd9e2fa161c0fba8", - "module": "qVnKKxBJJYXmuUnQxJLuKF", - "name": "hTCM", - "type_args": [] + "vector": { + "struct": { + "address": "9d94389021547140b638e6ce59ec969593bd3eead33e853e5a0e10a86549f6f7", + "module": "xQHMaISKmJyiBLBZoIkVKAej", + "name": "spcypVzZxOoyBrhN6", + "type_args": [] + } } } ], - "args": [] + "args": [ + "ad77195f31bc8614a27c706c6e89c86a02016401780261df8a98ce8d9e0cd026", + "86", + "c6", + "01", + "d8b5ab8c3fb04f44da60b3af065400dafda15f3274e2493a7a993059a9d1d8a7", + "ca0afe31a8fcdcfa1a480da29d83584f" + ] } }, - "max_gas_amount": "16567008626372739107", - "gas_unit_price": "3683144946775359419", - "expiration_timestamp_secs": "4904256669355706873", - "chain_id": 122 + "max_gas_amount": "11272266645211468354", + "gas_unit_price": "7103600372080276284", + "expiration_timestamp_secs": "17538683650486161090", + "chain_id": 85 }, - "signed_txn_bcs": "860786a2e72ff6bfb4269ab8925f514e02849da1d55da5c5686731b641ad7bd4294807ab804cd33a023c22488bafcb15495a5d163c7c108f356e187e9db9b6f7b563c2fd0dbca7141b1042725a68695243426b6a395f436f696e1745595964547556756773546266796b66766f476d4451390706070f6c49258197632e2e7607039ef09e5014701644697e82d57e74980dda7fd350206367634845415367794e574673745052746744466f456a506454455653594b4b0243340007d17adc7b66ca5c45cd9d7d40b45c6398ef416bddb84a3909d17c33b61b60dac0014a1d736356445569567a6c626a6f6a6c746a74505763477959424f6657593200079a169316ddbdb6b5bac240aacf75bcc7345a010b11d84296fd19650faedb72a81e426f597348654a6b6550474d7243754e634a6a42486741486b6458657731106872517a74554b62744151506d4e776a0007975efb5db65d1004bf46294f302442a7aa2c01fd1527a93cc3d5f8fde315079b0b65624c5a435074566954510641587178725900060607ab4e989cad803d8125ab3879879d65127551510a7821030b99b5e35e7327d3162044644b4f514e7457425841487448716e4e6d50764d7248494162596c55794e5a1a686362526b45544f7a6448554f5471614b704a7066637667584400060307ed3895aa0898bbd5c47991ec3b128156b7db80678b65591edd9e2fa161c0fba81671566e4b4b78424a4a59586d75556e51784a4c754b46046854434d00002380c7e591d6e9e5bbffd1a0d0281d33f98949f8746b0f447a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144403119557d7e3d18a28b0df24b5efa8f3e3474b290bfe05aeda457bfb409843738a5ec0e0c612b7d0cd40a4898e544faae37d2fa77d97ff44d4f833f1347363505", + "signed_txn_bcs": "f147491bfcad57b97d5c2d174711e0693e22976fa790f081b0aae4b4d27593c929ec69ee1df2dc1f0260165d39eeea8c26a1e8f558a3a353770364495fefe980593bf213ad4ff434360d57694f4d6c456f385f436f696e1b68755847514354647a5846786c6f6a7a7656615241766f4676653405060734d6045ed94c34b6692020ac9be1d65e0f682ca28a6ed5d0b5362cfcd1d59aac06664d6f5245680f574e446d756c424f6c54706e74694d0007df7b06a43804e9849cda19520de4fe6b2423470f765354df246c714d34a6bcb51b62704a787248494f5a746b457177414a636953496f69656e5a7173206c5144787871786162437a4a7749437072786d665641435872674d73576b4d390007816da3c80107b83f5358b779f363a2d91204a2444b37da9591adde2d000b7de60b4c466f4f7974636a4759301b634e5a6f416a59666c5068674f78595763447a55596f46534e4b39000607552324dba74b8af97fdf022428888a887bc8ef8569bf1ad65c40941d273d685609616764564d4a6848380d676e524651594859484a6d56350006079d94389021547140b638e6ce59ec969593bd3eead33e853e5a0e10a86549f6f7187851484d6149534b6d4a7969424c425a6f496b564b41656a117370637970567a5a784f6f794272684e36000620ad77195f31bc8614a27c706c6e89c86a02016401780261df8a98ce8d9e0cd026018601c6010120d8b5ab8c3fb04f44da60b3af065400dafda15f3274e2493a7a993059a9d1d8a710ca0afe31a8fcdcfa1a480da29d83584f42525071ca226f9c3c732de4e60e9562c2ce2d2fdbeb65f355002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144408605ff4d2706892a22914e3a6414de317c0d0a92acdacd2a2abd2f3032097d05813571f213f3e3e518cc1d7a0964b9d8a3cb0b7fc523bef882e537f576294201", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "4a2965ea422d11818be607577cedbe8f41849cd0957dfcc290fb07322e803c12", - "sequence_number": "14472827820061072350", + "sender": "b070c8fa03321ace0f289c3a9da57a48c598422994f9333d730bd8c0ef769ad7", + "sequence_number": "6177125906860738368", "payload": { "EntryFunction": { "module": { - "address": "b3f18de0af2ab3f4af1afaabfa0b6c9d5737979d1430e5bba461f82b83d733f2", - "name": "B4_Coin" + "address": "9edb2d8553a262b1020039f593f28bd713469a8d57b28e62d6943c281096ccbf", + "name": "hZkoT6_Coin" }, - "function": "EBwwXnTxEeW6", + "function": "WjAozPRLmAXgBQkbhTROvRfU8", "ty_args": [ { - "struct": { - "address": "605e4624f631ea88c07742715dfb8f450d0877c81c0fd68df92024604521c1ce", - "module": "ipHksqmtEIwoEjF9", - "name": "jlBKO7", - "type_args": [] - } - }, - { - "struct": { - "address": "1a131db6b3c50cff210289ed8b3319b7112089da42a4b3486e0c2b8e9b6ce507", - "module": "MxOIolAFQODFSekDZF6", - "name": "XNCcsygyKicPcQQbPunaQKhJMEz5", - "type_args": [] + "vector": { + "struct": { + "address": "7810c3d438a37068359ebdcb9e0e1e0e7330122b078211c4a5dee4d8c86e73bf", + "module": "jqfDtSEUsobUtAayQDQpKhlZDggKCKi", + "name": "IGBzfGWXNlSO2", + "type_args": [] + } } }, { "vector": { "vector": { - "struct": { - "address": "b4307919ddfa7e916aa5d0b6282c7531478a90001de4d6057ee6a3c787412a60", - "module": "cywFVWalxsfynoMtbaIQJQ8", - "name": "h9", - "type_args": [] - } + "vector": "u8" } } - } - ], - "args": [ - "80", - "00", - "f8cc9b1b7791758f", - "00", - "13", - "df8ecc3c5f0374e9e2f6be3af3e46c0ed1ec0f614d3903b0ce42b03dbc1eec6f", - "8b03c8202ae75de7", - "ebe58764f802bdcb622bee5fb91d1bf2" - ] - } - }, - "max_gas_amount": "7612315422534578784", - "gas_unit_price": "7126107356915110626", - "expiration_timestamp_secs": "3765643732774742854", - "chain_id": 144 - }, - "signed_txn_bcs": "4a2965ea422d11818be607577cedbe8f41849cd0957dfcc290fb07322e803c12de9b21d638d0d9c802b3f18de0af2ab3f4af1afaabfa0b6c9d5737979d1430e5bba461f82b83d733f20742345f436f696e0c45427777586e5478456557360307605e4624f631ea88c07742715dfb8f450d0877c81c0fd68df92024604521c1ce106970486b73716d744549776f456a4639066a6c424b4f3700071a131db6b3c50cff210289ed8b3319b7112089da42a4b3486e0c2b8e9b6ce507134d784f496f6c4146514f444653656b445a46361c584e4363737967794b6963506351516250756e61514b684a4d457a3500060607b4307919ddfa7e916aa5d0b6282c7531478a90001de4d6057ee6a3c787412a6017637977465657616c787366796e6f4d74626149514a513802683900080180010008f8cc9b1b7791758f0100011320df8ecc3c5f0374e9e2f6be3af3e46c0ed1ec0f614d3903b0ce42b03dbc1eec6f088b03c8202ae75de710ebe58764f802bdcb622bee5fb91d1bf260b266868b60a469e21239a8e204e56246ebb6120641423490002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405044c02d7ff12713b61ec66ba82c1fd33a3552c5bbc591e779aab95c443fa45d444bea31f262eed464a0dc91b27a7bc8e360ab26e8fa55b6e931ad09d3ecea03", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "8506ecaa580e10ddaf549c95bed2709d4890f8f1362637fae4c867c9d758d76b", - "sequence_number": "16877266771338628753", - "payload": { - "EntryFunction": { - "module": { - "address": "0a3a6beb54c9ab707b21dc407a3da42954a3f9e82c9f40f6e4bb868beb92438b", - "name": "NVfSb1_Coin" - }, - "function": "GwCzqwFNmNmhunYMIm", - "ty_args": [ + }, { "struct": { - "address": "0cd69cbc33932eeaf457c011f63a3b78feecd9abba11f01d0e25026c5b94d619", - "module": "GM", - "name": "yKNbTAtXrLbaLeDryqFNsGNFQTJTrbgy2", + "address": "bd90884985a0f75c3ac76eab9debcf33b3ab3bd6f8f10937f7b1704340a53911", + "module": "PfCFEwt2", + "name": "uHmS1", "type_args": [] } } ], "args": [ - "501e417bd8ad99c1764c4a9a913fb6453bab6e03ac373fd96c9b0332e9e95fa8", - "d6422734f9842be9", - "f8742a4cb2d4ae0b4ff2af62fc66a612053653909ae67f34c0f3220b2cf3261d", - "2df19b9d1d6f168d38553ab95059e82a", - "8c3fcf4f75140f69f019e29c5e256df847505437915834afc3fc037f5e65f02f", - "48507c47db215d7fd066ff188a74b993f4bd5bf250bc448c99333e57e1cc71c7" + "9e333853075c6771a21ca87cc088433e" ] } }, - "max_gas_amount": "11438595287817743361", - "gas_unit_price": "16967601714845867504", - "expiration_timestamp_secs": "12991137736850721006", - "chain_id": 173 + "max_gas_amount": "16505778574009280432", + "gas_unit_price": "17406207243672207826", + "expiration_timestamp_secs": "1113148162930406650", + "chain_id": 250 }, - "signed_txn_bcs": "8506ecaa580e10ddaf549c95bed2709d4890f8f1362637fae4c867c9d758d76b918e247db51838ea020a3a6beb54c9ab707b21dc407a3da42954a3f9e82c9f40f6e4bb868beb92438b0b4e56665362315f436f696e124777437a7177464e6d4e6d68756e594d496d01070cd69cbc33932eeaf457c011f63a3b78feecd9abba11f01d0e25026c5b94d61902474d21794b4e6254417458724c62614c6544727971464e73474e4651544a547262677932000620501e417bd8ad99c1764c4a9a913fb6453bab6e03ac373fd96c9b0332e9e95fa808d6422734f9842be920f8742a4cb2d4ae0b4ff2af62fc66a612053653909ae67f34c0f3220b2cf3261d102df19b9d1d6f168d38553ab95059e82a208c3fcf4f75140f69f019e29c5e256df847505437915834afc3fc037f5e65f02f2048507c47db215d7fd066ff188a74b993f4bd5bf250bc448c99333e57e1cc71c7016cd55bcf0dbe9ef05db287dc0779ebeec82811f1ca49b4ad002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444099ca6939ff52a83aaf81ab2917ac2afc4623ad9ac8644dc44ed75d08d1d7913e2c9184d767b23a140a5247f30e7bebf0b48b7f0edf6cd3b02ce2da3f381eef01", + "signed_txn_bcs": "b070c8fa03321ace0f289c3a9da57a48c598422994f9333d730bd8c0ef769ad740074cd3488fb955029edb2d8553a262b1020039f593f28bd713469a8d57b28e62d6943c281096ccbf0b685a6b6f54365f436f696e19576a416f7a50524c6d41586742516b626854524f76526655380306077810c3d438a37068359ebdcb9e0e1e0e7330122b078211c4a5dee4d8c86e73bf1f6a71664474534555736f625574416179514451704b686c5a4467674b434b690d4947427a664757584e6c534f32000606060107bd90884985a0f75c3ac76eab9debcf33b3ab3bd6f8f10937f7b1704340a539110850664346457774320575486d53310001109e333853075c6771a21ca87cc088433eb0a71365294e10e5d2c1e91d44458ff1fa74d8415bb2720ffa002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d029aa60189666152f8263e0756a89b305b6d78e0992da765438969e2a42daeeb10eb0f6e458c886babcf404a2744804c33707a60c694ecf326020c792dd7b0b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "6c4fbc1b3da1dcc6fecf0762d1b4d5c92e0f4aa35a7137aa18b5bd0cdafbeb88", - "sequence_number": "2102221068478695521", + "sender": "e9482f794ee5a19e8dabbe1835c8fdd0b63b7569ff446e7f9cee01309567c04b", + "sequence_number": "16538324045974198284", "payload": { "EntryFunction": { "module": { - "address": "834ec1e45eea6ff41eed5665fd11f309f0ce9f8c238804f2c85cfee8822937ff", - "name": "ZlKDxOQ1_Coin" + "address": "4c982db19274a428fdbee82c43709eb3b8852dfbfef51b246709c1676f478200", + "name": "n8_Coin" }, - "function": "cbIsL6", + "function": "xrdNNgAxMOxHNJSSEGomiG", "ty_args": [ { "struct": { - "address": "a8f47aa530993d2a18cdadcd308c7cf9281b6af44068c1c0e65d215f2ea4b1df", - "module": "jJtxkPaWmngdifTrA", - "name": "qsXCConWUoHRCqsWFQMurLhjggbe8", + "address": "2d22b28c3edbcfbc3ec4998fd7f45fce72d7afa8b756544ca80644f26fcf50ee", + "module": "ioLpxRgluJNVsfCiUFbaTRkyg", + "name": "bahcEKQFdAS4", + "type_args": [] + } + }, + { + "struct": { + "address": "243aca41876befd6e5bd163e5f4ecfa7c32003f8a25d5be63a3119056de66f05", + "module": "QHcQLTatpeGnUctL", + "name": "onNDjD", "type_args": [] } }, { "vector": { "vector": { - "vector": { - "vector": "address" + "struct": { + "address": "c5032f880e9e9906dbd9e476f7c9e994190e69d225149cfef23a408ec549392d", + "module": "Xra", + "name": "OpRTKAwFGvWSjjWS", + "type_args": [] } } } }, { "struct": { - "address": "12b76fef2bc2510ac6f2392243a581ad1f777511b44224e5c759090d9fdb4159", - "module": "fOjTySPBIFzHOFFaPagNTDuZaM", - "name": "HOwaW", - "type_args": [] - } - }, - { - "struct": { - "address": "66f4f2943450fdbda3086482fdd32ed151d994e5c9166424e69ff945aa011afb", - "module": "sButNDrdOtUtKMQOdYZJFTxtLxtMll", - "name": "MKWHNV", + "address": "c6ba3969486df5ea4ca9ee53d48cbd45c00a72ff00f0089a65a41660bfaf014c", + "module": "LaWEdIFFlGTmdy3", + "name": "ySXBJyBJWrtkNzRf", "type_args": [] } } ], "args": [ - "b3a74ab81ec292c5", - "50", - "c8743e72da832594", - "f3" + "00", + "23f2b221a414203e6559274f9e542a889bb5fde471da04e8b0334f87b78c7aa0", + "a6" ] } }, - "max_gas_amount": "2162485022171231861", - "gas_unit_price": "3033277309195572849", - "expiration_timestamp_secs": "7167970984150080068", - "chain_id": 226 + "max_gas_amount": "4470031051066226875", + "gas_unit_price": "13286768312151856452", + "expiration_timestamp_secs": "16078901869778707216", + "chain_id": 134 }, - "signed_txn_bcs": "6c4fbc1b3da1dcc6fecf0762d1b4d5c92e0f4aa35a7137aa18b5bd0cdafbeb8861c8037aec962c1d02834ec1e45eea6ff41eed5665fd11f309f0ce9f8c238804f2c85cfee8822937ff0d5a6c4b44784f51315f436f696e06636249734c360407a8f47aa530993d2a18cdadcd308c7cf9281b6af44068c1c0e65d215f2ea4b1df116a4a74786b5061576d6e676469665472411d71735843436f6e57556f48524371735746514d75724c686a67676265380006060606040712b76fef2bc2510ac6f2392243a581ad1f777511b44224e5c759090d9fdb41591a664f6a547953504249467a484f4646615061674e5444755a614d05484f776157000766f4f2943450fdbda3086482fdd32ed151d994e5c9166424e69ff945aa011afb1e734275744e4472644f7455744b4d514f64595a4a465478744c78744d6c6c064d4b57484e56000408b3a74ab81ec292c5015008c8743e72da83259401f375769e9aabb0021e71d6da47a45d182a449a92eea1bf7963e2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bbfa845aefb2e69d1a481c62a6a89fcba8b0adf7d8999bcd45ae2fe375c44247fa1e4718b4b0c388c07a63eb5b5a7e6c77e2e563645a05d533ef53305d128e02", + "signed_txn_bcs": "e9482f794ee5a19e8dabbe1835c8fdd0b63b7569ff446e7f9cee01309567c04b0cd8979418ee83e5024c982db19274a428fdbee82c43709eb3b8852dfbfef51b246709c1676f478200076e385f436f696e167872644e4e6741784d4f78484e4a535345476f6d694704072d22b28c3edbcfbc3ec4998fd7f45fce72d7afa8b756544ca80644f26fcf50ee19696f4c707852676c754a4e56736643695546626154526b79670c62616863454b5146644153340007243aca41876befd6e5bd163e5f4ecfa7c32003f8a25d5be63a3119056de66f0510514863514c5461747065476e5563744c066f6e4e446a4400060607c5032f880e9e9906dbd9e476f7c9e994190e69d225149cfef23a408ec549392d03587261104f7052544b417746477657536a6a57530007c6ba3969486df5ea4ca9ee53d48cbd45c00a72ff00f0089a65a41660bfaf014c0f4c615745644946466c47546d64793310795358424a79424a5772746b4e7a5266000301002023f2b221a414203e6559274f9e542a889bb5fde471da04e8b0334f87b78c7aa001a6bbb8c4c58ebd083e4455ba32621564b8102386960fbc23df86002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c60b890f9cbd5dc35042092e546028bbd55ec07bbee814d0a552121f8a08a69ccb8b469a1a2c69b4d08cc909d9cab085441afd12a25a64b6fb055b17a127e600", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "c173dd48e9f2ae09bd68bb4b0d46022d610e13d2ad8d703adb6c96d404865934", - "sequence_number": "13985455694557908219", + "sender": "b85711e1213ac8fe40b9427fb2af6b085da8fcb70a74714f1d63e47298b01b86", + "sequence_number": "4956597925115649980", "payload": { "EntryFunction": { "module": { - "address": "e5f26a79de77b33b3c8ecf733383dcfa56f6d27000c3cc33a79ec804fd847170", - "name": "CHKLPVOmZqgW_Coin" + "address": "ee2cba765b7702bdeef83f4a6afdcd4c6d7674987a201d144d0e2fa3eb2853ba", + "name": "pOFwzUyiAalXbxsSMFOFMU_Coin" }, - "function": "eW4", + "function": "dOcPYCTfgLY", "ty_args": [ { "vector": { - "struct": { - "address": "a663385db20dd34fe57b6c1eb841ec2c6b10435b7bd986ce8f36cec6759aee49", - "module": "oiXhHPVkvIjiMPWMgq", - "name": "U", - "type_args": [] + "vector": "u128" + } + }, + { + "struct": { + "address": "8c5f1682743700b660426b943490d132eb11d3c492c27c710a4d4a1b0db5127d", + "module": "IkFinBjunFrzVIBUc9", + "name": "FjZBGaL3", + "type_args": [] + } + }, + { + "vector": { + "vector": { + "struct": { + "address": "d39cca3d33506b8cc1221bbf54b3edd7443c1bcc5abbe5511506179ff006038f", + "module": "YvGhRicYgvGXbucsrSODZf", + "name": "KmkPJdQmXSxZU0", + "type_args": [] + } } } }, { "struct": { - "address": "1eb940db2f3cd6b1424666fea07f1d3dae707982e5679a7e54168b3375dac71c", - "module": "WpePAi6", - "name": "VlOnkettbXAath", + "address": "e01827210ea33744d8de768fc9a717520763b272711112eaae09abf56595e363", + "module": "SygwyhrIiydwGZqUKLsmqDKhJT2", + "name": "CfCnzBGDIk", "type_args": [] } }, { "struct": { - "address": "4b4935517f18690a5794280e78652a20b8a4b60f87656e6a685e048942eb8cba", - "module": "VfsQLrFRrymXxCRqSeRmAEVuF7", - "name": "mJPVRBKblkxlk", + "address": "1bc8e3935aa010725a41f4fa105379f6045df944ad1149167917251287626c84", + "module": "lyuwVjLEhQyFVJVLZ", + "name": "xwetNgogPPlpnsjOjKqActTZIgfEOC", "type_args": [] } + }, + { + "vector": { + "vector": { + "vector": { + "vector": "address" + } + } + } + }, + { + "vector": { + "vector": "bool" + } } ], "args": [ - "7180113a716403c7", - "4baf11cf52927097", - "e8" + "a795eb563695723446af4f3bb75df514", + "00", + "d4c80dbb9d6a756a269aea819864c89241db96b0de8a7f7a9973b0c434d401f7", + "9f7646c98c5295d5e7c36f4699e30360", + "85", + "62a0a7a293bc3d2f97c8d51d4b5259e2ac853931e17f5006fcf6cb26c7375e26", + "3c424b72d1a01047bef0c8c74dacccd0ca2817dd17e1be19cedffb5b949f9688", + "51", + "3a24213abe8695979eb3c628be7dbb7b2ced8a6727b9677b0b163b797a7aac78" ] } }, - "max_gas_amount": "9656599366441229911", - "gas_unit_price": "3246663498399746146", - "expiration_timestamp_secs": "6365248133953928743", - "chain_id": 81 + "max_gas_amount": "16404006694186810573", + "gas_unit_price": "13172268199097888748", + "expiration_timestamp_secs": "8841549655154613548", + "chain_id": 92 }, - "signed_txn_bcs": "c173dd48e9f2ae09bd68bb4b0d46022d610e13d2ad8d703adb6c96d404865934fb8c1628db5116c202e5f26a79de77b33b3c8ecf733383dcfa56f6d27000c3cc33a79ec804fd8471701143484b4c50564f6d5a7167575f436f696e03655734030607a663385db20dd34fe57b6c1eb841ec2c6b10435b7bd986ce8f36cec6759aee49126f6958684850566b76496a694d50574d6771015500071eb940db2f3cd6b1424666fea07f1d3dae707982e5679a7e54168b3375dac71c07577065504169360e566c4f6e6b65747462584161746800074b4935517f18690a5794280e78652a20b8a4b60f87656e6a685e048942eb8cba1a566673514c72465272796d58784352715365526d4145567546370d6d4a505652424b626c6b786c6b0003087180113a716403c7084baf11cf5292709701e857defdfef52103866208580f40770e2d27be8a0b74e7555851002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f91c7f155886ebbcb761238a666aba6a7ea7cb76856abd8f35fa5c04ab47299648e50ea9fcb8f373e3c960d61b71514b632765687ed24e314b6817e69c10a80f", + "signed_txn_bcs": "b85711e1213ac8fe40b9427fb2af6b085da8fcb70a74714f1d63e47298b01b86bcdff43c8d5fc94402ee2cba765b7702bdeef83f4a6afdcd4c6d7674987a201d144d0e2fa3eb2853ba1b704f46777a55796941616c58627873534d464f464d555f436f696e0b644f635059435466674c5907060603078c5f1682743700b660426b943490d132eb11d3c492c27c710a4d4a1b0db5127d12496b46696e426a756e46727a56494255633908466a5a4247614c3300060607d39cca3d33506b8cc1221bbf54b3edd7443c1bcc5abbe5511506179ff006038f165976476852696359677647586275637372534f445a660e4b6d6b504a64516d5853785a55300007e01827210ea33744d8de768fc9a717520763b272711112eaae09abf56595e3631b537967777968724969796477475a71554b4c736d71444b684a54320a4366436e7a424744496b00071bc8e3935aa010725a41f4fa105379f6045df944ad1149167917251287626c84116c797577566a4c4568517946564a564c5a1e787765744e676f6750506c706e736a4f6a4b71416374545a496766454f430006060606040606000910a795eb563695723446af4f3bb75df514010020d4c80dbb9d6a756a269aea819864c89241db96b0de8a7f7a9973b0c434d401f7109f7646c98c5295d5e7c36f4699e3036001852062a0a7a293bc3d2f97c8d51d4b5259e2ac853931e17f5006fcf6cb26c7375e26203c424b72d1a01047bef0c8c74dacccd0ca2817dd17e1be19cedffb5b949f96880151203a24213abe8695979eb3c628be7dbb7b2ced8a6727b9677b0b163b797a7aac78cd7c221c2dbda6e3ec6f672d234ccdb62cdd771b917eb37a5c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b2f6208ea7db2b172f8cb58f96699a07bb8bed200e50c2cf0b543bcb4786d56a9f45a81bd7a3609f970077ebce8940fcf2c05f3ae1f705cc8301219b63e89509", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "7aa115aa69dcb6277ad3cf843e50dea69f536ebe4de13e206e141ae390ff869f", - "sequence_number": "9067414561635691199", + "sender": "ccf524d78d3bba4f5bc47e0419b31eeebd3a26df1eb28d47227864fd71e3fbf8", + "sequence_number": "11799231719437850743", "payload": { "EntryFunction": { "module": { - "address": "9ca2ee85e9bb9bb000ced8b239f53b90594c88f9e807dd4e1f81da7bd68324e1", - "name": "kxKctZAuEML3_Coin" + "address": "b18ee30a1ba60617d5c49b646a14f3646a694aa87a087803df1b761d125356fc", + "name": "OUpdOpZmKvZ_Coin" }, - "function": "BpwHgjTDHneUCG3", + "function": "AqzEReSpdxakrGdruwrh5", "ty_args": [ { - "vector": { - "vector": "u64" + "struct": { + "address": "32b45d3839c25c64ce0285b71c579cd24a624b8354dbe9b850a2a424029fad2c", + "module": "iOZh4", + "name": "XDtLKCJVZjswnIyvcdkBfO8", + "type_args": [] } }, { "vector": { - "vector": "u8" + "vector": "signer" } }, { "vector": { - "vector": "u64" - } - }, - { - "struct": { - "address": "6bacda7b4018500e44f72c7535b43adfe4d18b65f9e82e66e65262b20e0edcce", - "module": "WEeYkmQXzfdLeEbLOGSRNnVBThRV4", - "name": "UkgYeEJb8", - "type_args": [] + "struct": { + "address": "022199ea4571ff4db56b0c46b14521c1c43083051456a5c2713baf0ec3d2be55", + "module": "vHt", + "name": "etbjGBTE", + "type_args": [] + } } } ], "args": [ - "b4", - "00", - "d1", - "99", - "f0", - "0b50a699cb67466ad825a55216ba50ba5f41b71de797f893930d2b7b871295dc", - "01", - "97f70e43540259d75858ad063b0bf155" + "87555392c0343597446aa172ffd0850d", + "3d9a302ce75670d8eaa475ebb56cd2a189596b47e12386e42b45a4c8d99ca696" ] } }, - "max_gas_amount": "16583592488852503128", - "gas_unit_price": "12778924948966926060", - "expiration_timestamp_secs": "12171629856011959008", - "chain_id": 162 + "max_gas_amount": "1143267728454726271", + "gas_unit_price": "10396682778159846291", + "expiration_timestamp_secs": "8016354214383991969", + "chain_id": 108 }, - "signed_txn_bcs": "7aa115aa69dcb6277ad3cf843e50dea69f536ebe4de13e206e141ae390ff869fbfea7fa980edd57d029ca2ee85e9bb9bb000ced8b239f53b90594c88f9e807dd4e1f81da7bd68324e1116b784b63745a4175454d4c335f436f696e0f42707748676a5444486e655543473304060602060601060602076bacda7b4018500e44f72c7535b43adfe4d18b65f9e82e66e65262b20e0edcce1d574565596b6d51587a66644c6545624c4f4753524e6e5642546852563409556b675965454a6238000801b4010001d1019901f0200b50a699cb67466ad825a55216ba50ba5f41b71de797f893930d2b7b871295dc01011097f70e43540259d75858ad063b0bf15558bae34581c124e6ece68c1289dc57b1e0ba21b1dd50eaa8a2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440235b541a406ea18a3e6850d08624d448f1e57da90825c4770b4671db1a614139530723a26a2fb195996dd13253af57f50bf64beccd8f641442ac1af408686603", + "signed_txn_bcs": "ccf524d78d3bba4f5bc47e0419b31eeebd3a26df1eb28d47227864fd71e3fbf877589ddbbb4abfa302b18ee30a1ba60617d5c49b646a14f3646a694aa87a087803df1b761d125356fc104f5570644f705a6d4b765a5f436f696e1541717a45526553706478616b724764727577726835030732b45d3839c25c64ce0285b71c579cd24a624b8354dbe9b850a2a424029fad2c05694f5a6834175844744c4b434a565a6a73776e49797663646b42664f38000606050607022199ea4571ff4db56b0c46b14521c1c43083051456a5c2713baf0ec3d2be5503764874086574626a4742544500021087555392c0343597446aa172ffd0850d203d9a302ce75670d8eaa475ebb56cd2a189596b47e12386e42b45a4c8d99ca6967f32b615f1b3dd0f9393a31ae76f4890a13c107eafcf3f6f6c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401c0d7f4085aeaf3c23a23221eb9977672c69cb30b73125b884215f10f1de9a08cfc0f71b3b11e2dfd9efebb4601c68121f8ab046efe69c1618ae7f3e52cad109", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "263abebe0754ea910db90c2e648a641dac56dc04da79911b6ca6134befa202f4", - "sequence_number": "7017105405210085067", + "sender": "94ea8b1a03dd9934414a6151d97802e4fb0f48dd9d03555df1d57d3fce35ba80", + "sequence_number": "5724768557541440751", "payload": { "EntryFunction": { "module": { - "address": "d1da4cc74a36ca0bff67e7ead53b962035103df55b886fcc61e4e2391824e42c", - "name": "FTdPWFwpUYApolhymdhmYrmUGQ1_Coin" + "address": "02e733b1df658a21fe60272acd6d52d54b5ef050f8d67113895a895cf24ff957", + "name": "XxFLDT_Coin" }, - "function": "gaHrPAubtNasp8", + "function": "p6", "ty_args": [ + { + "struct": { + "address": "74f3c427591f6dd5a4ae6aa6ada5dbb5091ef2332c4206a83062408e08a6c770", + "module": "hTlaDxMWfaMbbZklpUmTWlJw4", + "name": "gUg7", + "type_args": [] + } + }, { "vector": { - "struct": { - "address": "2f3569966f98a1ab8ca218e62d464714e41c7ed7bfae541cce3ee838e35439b4", - "module": "XUdHVdOtpZmZ8", - "name": "WlWF0", - "type_args": [] + "vector": { + "vector": "u128" } } }, { "struct": { - "address": "3016eca4e0b80ae5832b79a25541f5a550919723b880b6d5dd667193a73a9082", - "module": "WJzSXQSqELWa6", - "name": "gniSkpquyJWAzZYuEpoG", + "address": "4564b311f2e3c0efc3791b5b1387cff1bdd9ec686ed8d9cdaa500b7de5dcee94", + "module": "icjmhTKUwmRBJkxVrTrKepUjuflNe", + "name": "bWqwlwgrCKcgLhFvZmYzSSZEYThwCp", "type_args": [] } } ], "args": [ + "40ef16737968618bffbf97aa7bc5b9b8d2b216120a8d6a5ed7c1b2bb348adc2c", + "1393e67584cc468b98cd9933555e63a1edeba3b11e8d5640815c35a63da15676", "00", - "52ba97f21f079ef7", "00", - "b4044794a4e44a4e", - "00" + "f1392af899faf0705459388c6584750ae8d1a891b721a8d98a300fbb694ad6fc", + "00", + "8e", + "01" ] } }, - "max_gas_amount": "2470189135079308135", - "gas_unit_price": "14676404892966061827", - "expiration_timestamp_secs": "7946542680997397790", - "chain_id": 230 + "max_gas_amount": "7942297055904599991", + "gas_unit_price": "15221829944515414785", + "expiration_timestamp_secs": "7048737163643094817", + "chain_id": 238 }, - "signed_txn_bcs": "263abebe0754ea910db90c2e648a641dac56dc04da79911b6ca6134befa202f4cb46051530c4616102d1da4cc74a36ca0bff67e7ead53b962035103df55b886fcc61e4e2391824e42c204654645057467770555941706f6c68796d64686d59726d554751315f436f696e0e6761487250417562744e617370380206072f3569966f98a1ab8ca218e62d464714e41c7ed7bfae541cce3ee838e35439b40d5855644856644f74705a6d5a3805576c57463000073016eca4e0b80ae5832b79a25541f5a550919723b880b6d5dd667193a73a90820d574a7a5358515371454c57613614676e69536b707175794a57417a5a597545706f47000501000852ba97f21f079ef7010008b4044794a4e44a4e0100677b6e44eedf472203070cc17d10adcb1e85543d77ca476ee6002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444058c291b5f10623e98d3cdd97138226529ef80646766a4061c5cd6d7d7e7b7f2c456a5682c7b529296e7fb9d7d7348cbdf52dd60dcd9c9ca4c81f89884dfe4807", + "signed_txn_bcs": "94ea8b1a03dd9934414a6151d97802e4fb0f48dd9d03555df1d57d3fce35ba80ef3c9505ac76724f0202e733b1df658a21fe60272acd6d52d54b5ef050f8d67113895a895cf24ff9570b5878464c44545f436f696e027036030774f3c427591f6dd5a4ae6aa6ada5dbb5091ef2332c4206a83062408e08a6c7701968546c6144784d5766614d62625a6b6c70556d54576c4a773404675567370006060603074564b311f2e3c0efc3791b5b1387cff1bdd9ec686ed8d9cdaa500b7de5dcee941d69636a6d68544b55776d52424a6b78567254724b6570556a75666c4e651e625771776c776772434b63674c6846765a6d597a53535a4559546877437000082040ef16737968618bffbf97aa7bc5b9b8d2b216120a8d6a5ed7c1b2bb348adc2c201393e67584cc468b98cd9933555e63a1edeba3b11e8d5640815c35a63da156760100010020f1392af899faf0705459388c6584750ae8d1a891b721a8d98a300fbb694ad6fc0100018e0101b70fd39d17b5386e01cb3e92afcd3ed321870ac21a25d261ee002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440af84219e85b772223c6c6c485108994b40e3db4e45e33dab66806e626d4f9a9036df32e61d47c23301588d1158dc481c4b7592dd2ef8aa6ef54f759c6229d803", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "4340105451eb392d3cc037dc812416941c1dc10b913665144b1d6b9d90043379", - "sequence_number": "14768792697688847021", + "sender": "f32477ffca61486c2c8ae41b00c4b4791577bb28508f131860045cc1904af61b", + "sequence_number": "10369884036316857967", "payload": { "EntryFunction": { "module": { - "address": "ee1ad60948498ddbe6a6ebd91d38db29b610fd72d271803a8fdb019fdb35aff4", - "name": "gFleWbQuBMsXQbKVNrKauVck2_Coin" + "address": "880fdc0115def3c6785b55cf5e39c6da4e70beab2abe6dfe94bace886855ed0a", + "name": "utZ9_Coin" }, - "function": "xUdYxDEXf6", + "function": "tsDtdS", "ty_args": [ { "vector": { - "struct": { - "address": "eb6441ab97fe6403d6ca6c7855b9eceeb5a0ac8753a69b35e9c0d0e94ef1eedb", - "module": "KVjskjiVbBURtdZYBaC", - "name": "AXnnAwGtBcO9", - "type_args": [] + "vector": { + "vector": "u8" } } }, { - "struct": { - "address": "711b00ca198eafd77767390bd4aacc6fe37795c2a43b6631279cc8acd7698eff", - "module": "FSzFbQlCwopeDadro", - "name": "UjEumVPTZPH", - "type_args": [] - } - }, - { - "struct": { - "address": "547216f5ee079c833f055708215caffaca3ebb94bfc9389d84cdac060c5ca199", - "module": "DPjhIDeroUavOW7", - "name": "NLRUAduxVgCQWDyrIDY", - "type_args": [] - } - }, - { - "struct": { - "address": "7e4163ae4a75cafe476002169655ccb2b6a995acabc256bf47381b276545cee5", - "module": "CyHwBpFwYlUXLWyScng5", - "name": "NUbyivi6", - "type_args": [] - } - }, - { - "vector": { - "vector": "signer" - } - }, - { - "vector": { - "vector": "address" - } + "vector": "bool" } ], "args": [ - "84876fd4b8c346d95e94449ba66b52672f963b3b2a286580d451afef11d5f56e" + "01", + "00", + "1bcfc3f7458eae4821db1ac1f8b3965f320ac0785dcb78f88956192aacb45110", + "9d", + "8ba70d3a8204c80f", + "30089ce4a20d4649b75af20256369145" ] } }, - "max_gas_amount": "5014881067796366166", - "gas_unit_price": "10284107719020051992", - "expiration_timestamp_secs": "16343549532649488808", - "chain_id": 162 + "max_gas_amount": "5243357817996892892", + "gas_unit_price": "9444438872369638487", + "expiration_timestamp_secs": "10545651318676919993", + "chain_id": 177 }, - "signed_txn_bcs": "4340105451eb392d3cc037dc812416941c1dc10b913665144b1d6b9d90043379ad7220cbb54af5cc02ee1ad60948498ddbe6a6ebd91d38db29b610fd72d271803a8fdb019fdb35aff41e67466c6557625175424d735851624b564e724b617556636b325f436f696e0a78556459784445586636060607eb6441ab97fe6403d6ca6c7855b9eceeb5a0ac8753a69b35e9c0d0e94ef1eedb134b566a736b6a69566242555274645a594261430c41586e6e4177477442634f390007711b00ca198eafd77767390bd4aacc6fe37795c2a43b6631279cc8acd7698eff1146537a4662516c43776f7065446164726f0b556a45756d5650545a50480007547216f5ee079c833f055708215caffaca3ebb94bfc9389d84cdac060c5ca1990f44506a68494465726f5561764f5737134e4c525541647578566743515744797249445900077e4163ae4a75cafe476002169655ccb2b6a995acabc256bf47381b276545cee5144379487742704677596c55584c577953636e6735084e5562796976693600060605060604012084876fd4b8c346d95e94449ba66b52672f963b3b2a286580d451afef11d5f56e5683d5dcc26f984518fe0aa07b7db88ea8019346b5f3cfe2a2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144408b81403e240a10c7a9af9716c43ae7264dd723d366c5ed2d076c25be20fe86307f2db7eac3e1a54eb97acd027948738384c4bd55f5eb9bfb24b383fbe5000c01", + "signed_txn_bcs": "f32477ffca61486c2c8ae41b00c4b4791577bb28508f131860045cc1904af61b6f06a9ca963ae98f02880fdc0115def3c6785b55cf5e39c6da4e70beab2abe6dfe94bace886855ed0a0975745a395f436f696e06747344746453020606060106000601010100201bcfc3f7458eae4821db1ac1f8b3965f320ac0785dcb78f88956192aacb45110019d088ba70d3a8204c80f1030089ce4a20d4649b75af20256369145dcdaf8ab2726c44857ac7b9a1d631183b916de4600ae5992b1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a8e5a8b44d347b35a63e17598a5c468ea17647b726ff322efaa63a101588e7825b095ee5ec6c48f511e7b402ce70104609d499ae39ef7db7a8f766da2ed38f05", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "ae3c899d46331f2f945c62e521a934ced10d2e695c132bd648bdf672ffe66387", - "sequence_number": "9710929933222611683", + "sender": "de431e12633493917b2f39b6911d9dd19a9f8d6f9ada58a13f3613366b06c133", + "sequence_number": "15601851185367795655", "payload": { "EntryFunction": { "module": { - "address": "bc11cfe1bc7c2ce85c3356e392c517e526b36a12c247390bac6df8286b09f865", - "name": "Wrfn8_Coin" + "address": "0b8dadb06febf55b7e7d2ca48c0b8db5eb02538059daf541fd5737d47c950040", + "name": "bAsHTWWsEhPweqGW_Coin" }, - "function": "o1", + "function": "jY6", "ty_args": [ { - "vector": "u64" + "struct": { + "address": "0fda0e682eb4b9e09474614c5548ca79cb57dbcbc50f1fa6bb96094299de677b", + "module": "SGuMFhbudpFsNkbRBB", + "name": "tZz", + "type_args": [] + } }, { "struct": { - "address": "a46a09f87ed9a67ccbd7bb65e3f7860893a411c712feaac50b0d13be8f4b749f", - "module": "jFixKtTUYhAqzzMJUiu3", - "name": "LlwLALHLPoTNfdRuIPqPVreJGv1", + "address": "7228fad5d1a95d36f10dadf82fe38e6fb7a458a2f9741509f7ee579f0196aee9", + "module": "rIrFTrHvBYEZf1", + "name": "rLCrBz3", "type_args": [] } }, { "vector": { - "vector": "signer" + "vector": "u8" } } ], "args": [ - "ffc4ab76d50b8322", - "1f7fb8a4deb6ec3a41d3701e455581f4752f77cbe78b98ba07e114a6506e1ec7", - "01", - "01", - "00", - "9af65988d58af4bfd53386d9dc6f29de", - "ed44525fc5125f6470190016e287b1b3", - "02", - "01" + "63036ae1f1800c1e4684b4a41802f968" ] } }, - "max_gas_amount": "10206929233670852440", - "gas_unit_price": "2604431443004056849", - "expiration_timestamp_secs": "16774726504011982482", - "chain_id": 210 + "max_gas_amount": "3335893672433147462", + "gas_unit_price": "4999270595337222181", + "expiration_timestamp_secs": "12225224986382944946", + "chain_id": 233 }, - "signed_txn_bcs": "ae3c899d46331f2f945c62e521a934ced10d2e695c132bd648bdf672ffe66387e30a71d45227c48602bc11cfe1bc7c2ce85c3356e392c517e526b36a12c247390bac6df8286b09f8650a5772666e385f436f696e026f3103060207a46a09f87ed9a67ccbd7bb65e3f7860893a411c712feaac50b0d13be8f4b749f146a4669784b745455596841717a7a4d4a556975331b4c6c774c414c484c506f544e66645275495071505672654a477631000606050908ffc4ab76d50b8322201f7fb8a4deb6ec3a41d3701e455581f4752f77cbe78b98ba07e114a6506e1ec7010101010100109af65988d58af4bfd53386d9dc6f29de10ed44525fc5125f6470190016e287b1b301020101584f80340f4ca68d11651d3a99cc242492e6f60be1cccbe8d2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bb3ada5f9f177b835075fca485b8b01bac3ebae02ee38c10a9084f16b511f13b4ce7e0db3aaeb52a56a5412977bbd203d645705f6f15572f22f16cba9af7340f", + "signed_txn_bcs": "de431e12633493917b2f39b6911d9dd19a9f8d6f9ada58a13f3613366b06c133c7c75aaefde884d8020b8dadb06febf55b7e7d2ca48c0b8db5eb02538059daf541fd5737d47c95004015624173485457577345685077657147575f436f696e036a593603070fda0e682eb4b9e09474614c5548ca79cb57dbcbc50f1fa6bb96094299de677b125347754d46686275647046734e6b6252424203745a7a00077228fad5d1a95d36f10dadf82fe38e6fb7a458a2f9741509f7ee579f0196aee90e72497246547248764259455a663107724c4372427a3300060601011063036ae1f1800c1e4684b4a41802f96846ded9e99e794b2e257821831efa6045b2ca95645ab9a8a9e9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d44e09c5411281e7051beba0f3c7dd78b0a9a19182ccd5160de3834218f7944a6e3cd178c4a48807435d28e9fb1c16e15a5c6d2fdd84cc80911f0f97dda76308", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "6024b1bbf11a1aa03b522c3232296af3de35cf4ed6b2922f80081e1c0f86b7de", - "sequence_number": "14934495808590520968", + "sender": "3d95d1c9457ec5dd49d918eefb2b81f7ced6350934f9d492639e4f5ffa4ae1c1", + "sequence_number": "6503306600740168691", "payload": { "EntryFunction": { "module": { - "address": "fd45db7eb37db82a5b48a8411c768ece9346fe0278bd9c6b7403dad7e302aec3", - "name": "xFhyyyaztxczgZGX3_Coin" + "address": "307e1217113f316d147c938f383f3f1073e42fefc7868e33e7d4186ee97574b2", + "name": "PWdkwmpfyeLOIX_Coin" }, - "function": "GzqlWkUKayCzAiwrqSLKz", + "function": "JvJMOXzC7", "ty_args": [ { "vector": { - "vector": { - "struct": { - "address": "0a57ab396cc0de20d68c9f913706e04fbe787681e725b7d9b231171f39cf7126", - "module": "fNMd5", - "name": "zn2", - "type_args": [] - } + "struct": { + "address": "a776334ddd75acc16fb9f3a8545bcf0813f7d387b5c0f802886dccdadff8e15d", + "module": "UTqQtlITP2", + "name": "TINGysgSGOnSSlk", + "type_args": [] + } + } + }, + { + "vector": { + "struct": { + "address": "94ebccc34202e857027ce8240ed8a69d3264ec0c2a50cf25cbe7ae74fd07174a", + "module": "hufBYCynMMaHGnXA", + "name": "xQLnWFrSreFBpbjFVBrQpWuWvn", + "type_args": [] } } + }, + { + "struct": { + "address": "35cd526d45d904c862dd607ad8932ef6d0a41def94c9df7f9b4512080d35d056", + "module": "WwkjcZLlEqwRPswaLFtymstIkebiV", + "name": "QUhTOkofhCgPADwjUumOTGlND", + "type_args": [] + } } ], "args": [ - "034224b2e471b0c95d2becaba7dd6ea351e89708e32f0a7832cd0a20270a7c10", - "a7668d0e759010762243bd98a9ff46b1", - "6aaa7289962fe321", - "0853ac94b5fb81387554455e9fc7aae0d9ec923e6f86961c6b3c59f5d13aed6b", - "7b5787d37c6305468fffbb14b328ff19e2817a73c960dd236f164facb8e9d04a", - "646ed345efe4d9daca0d2cfececcb6539d3a176376f7aff3a8f2fa8313898d5b", - "06" + "01", + "baaed5bc2a0606d7a10ec329a4ac82ee", + "4c893f5493828b38a248f1e13ce8c058", + "bf9844ef6244f5ab7dd4877d2b406857", + "0f10dab615fa2e416fdb5cd332b94ede2bf660d1f77440d6e6674fdfdb31ff6d", + "41", + "0d7bd2b7c44053ba" ] } }, - "max_gas_amount": "16466216651595651702", - "gas_unit_price": "9183487826657206494", - "expiration_timestamp_secs": "7924879799203201130", - "chain_id": 84 + "max_gas_amount": "16160087449451456012", + "gas_unit_price": "1997283851603316910", + "expiration_timestamp_secs": "1355921652732278076", + "chain_id": 119 }, - "signed_txn_bcs": "6024b1bbf11a1aa03b522c3232296af3de35cf4ed6b2922f80081e1c0f86b7de882299c2cffc41cf02fd45db7eb37db82a5b48a8411c768ece9346fe0278bd9c6b7403dad7e302aec316784668797979617a7478637a675a4758335f436f696e15477a716c576b554b6179437a4169777271534c4b7a010606070a57ab396cc0de20d68c9f913706e04fbe787681e725b7d9b231171f39cf712605664e4d6435037a6e32000720034224b2e471b0c95d2becaba7dd6ea351e89708e32f0a7832cd0a20270a7c1010a7668d0e759010762243bd98a9ff46b1086aaa7289962fe321200853ac94b5fb81387554455e9fc7aae0d9ec923e6f86961c6b3c59f5d13aed6b207b5787d37c6305468fffbb14b328ff19e2817a73c960dd236f164facb8e9d04a20646ed345efe4d9daca0d2cfececcb6539d3a176376f7aff3a8f2fa8313898d5b0106761afb88cdc083e4dee006ab854d727f6a002d8730d4fa6d54002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144407b7a5d2173d7f6daec50ec9212fbbf19d2aeb8c7f6c81fbf4a3a29a3f66874df98711d9e3e16f7400b90c7d3539b2de2a2c9c6801840aed3ad691d45fa29200a", + "signed_txn_bcs": "3d95d1c9457ec5dd49d918eefb2b81f7ced6350934f9d492639e4f5ffa4ae1c1f32392bae562405a02307e1217113f316d147c938f383f3f1073e42fefc7868e33e7d4186ee97574b2135057646b776d706679654c4f49585f436f696e094a764a4d4f587a4337030607a776334ddd75acc16fb9f3a8545bcf0813f7d387b5c0f802886dccdadff8e15d0a55547151746c495450320f54494e4779736753474f6e53536c6b00060794ebccc34202e857027ce8240ed8a69d3264ec0c2a50cf25cbe7ae74fd07174a10687566425943796e4d4d6148476e58411a78514c6e574672537265464270626a465642725170577557766e000735cd526d45d904c862dd607ad8932ef6d0a41def94c9df7f9b4512080d35d0561d57776b6a635a4c6c45717752507377614c4674796d7374496b6562695619515568544f6b6f66684367504144776a55756d4f54476c4e440007010110baaed5bc2a0606d7a10ec329a4ac82ee104c893f5493828b38a248f1e13ce8c05810bf9844ef6244f5ab7dd4877d2b406857200f10dab615fa2e416fdb5cd332b94ede2bf660d1f77440d6e6674fdfdb31ff6d0141080d7bd2b7c44053ba0c66cd5bea2944e0ae9070ba14c7b71b3c355e268f33d11277002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400a9fc69f56b40cc2379f58f198c798614cceac9cb552bd114baa8a7dc0b59f257e0a2ad19a79f58f2a6cca1f88bab0a4eb0ca8e924dbd778a69ec0a6ceb27606", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "24743c19992aca92785d0ff92a29bee359fcdc6681238d17788656cbe2525e80", - "sequence_number": "9360365806149000792", + "sender": "cef634d8bd1e06c2aca36e50b05052d97f9a3be27991b231a83040fe4d257c67", + "sequence_number": "14499498641130194886", "payload": { "EntryFunction": { "module": { - "address": "44cfa04f8dac2eb538dc22684ec91f93a89feeeede8e975b8997c5a1acc71a28", - "name": "wPLW_Coin" + "address": "8cdbf1de27df1b9c9eeb80bc3ae40b0478f6686fe1f19d86f52e3965e7e8c3da", + "name": "Bso6_Coin" }, - "function": "txuiIBGAoddfaeavAnuZnkNHUhBp", + "function": "DFqKFqiMaQhcB", "ty_args": [ - { - "vector": { - "vector": { - "vector": "signer" - } - } - }, { "vector": { "struct": { - "address": "5686e1de3bd319633487163a695ab27ea9b0750a3516805cee8cc02cfdfc73a9", - "module": "drwNdFEGxwvNoFtPSvnYbOToKN", - "name": "QrJMmswgUqQRSDdeIUEPsQZ1", + "address": "e5473d49de5ec077531f7a1baa6987e00d776f435008b30ba541f3a763235694", + "module": "lpWYFnMZWKBFeKBpC", + "name": "urjuGkZiGEJXrnqNbvlZSoL", "type_args": [] } } }, - { - "struct": { - "address": "645402a096ae0ea0e67d62f26373cc95a844ecd26a73cd57650d5482460b47bf", - "module": "RKvBCkkcQZofbNpmNVHYseTVITieYEpk5", - "name": "PnffaXRsrmDjmApWf3", - "type_args": [] - } - }, - { - "struct": { - "address": "2df40ad7bedc8c3ea427b8a590e7ec09a773517d0c57d3ebf885d4d11ad803b7", - "module": "Zjv", - "name": "uODsVk7", - "type_args": [] - } - }, { "vector": { - "vector": "u8" - } - }, - { - "struct": { - "address": "2e3fdcd9164f4dc3da50077107930ebbce55ec691db8d9ac7c8ba1a215ee5be6", - "module": "kyXPsybswKFvutvEcHjEoAhJFk8", - "name": "aOJJTmYDMHyHodowoYtFIdYeIw4", - "type_args": [] + "vector": { + "struct": { + "address": "8620965f6b3f186879a8c041bfaa097cc9f4dfacfdf9942490193f85f5f9f1e2", + "module": "KMnGsDzeDkbmEawefHIOoOFmJJQXb2", + "name": "btUTmWnPQhMJtZgigHVGDTWRmZmpC", + "type_args": [] + } + } } }, { "struct": { - "address": "dcb4823adc5740a858266b2134d8254bc405ccaa6ca9cfdea59a0331985b4c51", - "module": "LSoYhJKgrqGJHscAhBdnsjzcbs", - "name": "PqemYDcPerSycmAynPrMZ9", + "address": "8d116727cb3f9c65f7c62857e9ce1a3887af299ac3659154bdd5e1a1d2a5ad6c", + "module": "RoYytyEy", + "name": "gknVbpT3", "type_args": [] } }, - { - "vector": { - "vector": "u8" - } - }, { "vector": { "struct": { - "address": "c07e6d846e9b6e79b74af6f0d56077f28df2b1dbb237d78be7ee19b92c4e1972", - "module": "txhZgmRHhYQTZC3", - "name": "ePUZCnCT", + "address": "80a61b1ec2e12a6a476e29794cd765fdae2a2f0ca7d0e9fd9bb09dd054ab7c3e", + "module": "YoNiux", + "name": "HfxSLaBbmtddXIDDCvxyq", "type_args": [] } } }, { "struct": { - "address": "327be36249db72966d3c7799376d55a4d1f7b182f1686e4bfcbe5880d2831f8c", - "module": "KZWDPAiPWDdGl", - "name": "YdOPoyTNckqUKowpeAX7", + "address": "54f53e444cab1a11b09b67d1060abdf0367dbef422c4be37980e5e992dc1acdf", + "module": "HdSG", + "name": "XvVqKRPjnohJfjQyYRXoKqftrRBxNqF", "type_args": [] } } ], "args": [ - "01", - "7dff31bc1e6e8ccb96a2ca92fb6b9d5d02596e7cfd57daf5645bcd100502f2f8", - "b6584c3350f088cc", - "66e3b4ae1160618b", - "2823d7947633bb76c3707cbddf55b25abbfd891a9da2781c7e6f0d1ecaa0344d", "00", - "64", - "29" + "57d3eeaf5649bac478fc990c6c12134e", + "ebe2b76c356c88fe", + "6734a0855b4b0c7d", + "efa79b34a21ad17ecc3fc14228f3aa3e", + "00", + "d66dc7a28f25db0e", + "bb" ] } }, - "max_gas_amount": "10812350595248184786", - "gas_unit_price": "206499380024714730", - "expiration_timestamp_secs": "13130731864468102950", - "chain_id": 178 + "max_gas_amount": "11050409494143445722", + "gas_unit_price": "1934110844654878075", + "expiration_timestamp_secs": "14344789952289861980", + "chain_id": 91 }, - "signed_txn_bcs": "24743c19992aca92785d0ff92a29bee359fcdc6681238d17788656cbe2525e80585e397b1bb3e6810244cfa04f8dac2eb538dc22684ec91f93a89feeeede8e975b8997c5a1acc71a280977504c575f436f696e1c74787569494247416f64646661656176416e755a6e6b4e48556842700a0606060506075686e1de3bd319633487163a695ab27ea9b0750a3516805cee8cc02cfdfc73a91a6472774e644645477877764e6f46745053766e59624f546f4b4e1851724a4d6d73776755715152534464654955455073515a310007645402a096ae0ea0e67d62f26373cc95a844ecd26a73cd57650d5482460b47bf21524b7642436b6b63515a6f66624e706d4e56485973655456495469655945706b3512506e666661585273726d446a6d417057663300072df40ad7bedc8c3ea427b8a590e7ec09a773517d0c57d3ebf885d4d11ad803b7035a6a7607754f4473566b3700060601072e3fdcd9164f4dc3da50077107930ebbce55ec691db8d9ac7c8ba1a215ee5be61b6b79585073796273774b46767574764563486a456f41684a466b381b614f4a4a546d59444d4879486f646f776f597446496459654977340007dcb4823adc5740a858266b2134d8254bc405ccaa6ca9cfdea59a0331985b4c511a4c536f59684a4b677271474a487363416842646e736a7a636273165071656d5944635065725379636d41796e50724d5a39000606010607c07e6d846e9b6e79b74af6f0d56077f28df2b1dbb237d78be7ee19b92c4e19720f7478685a676d5248685951545a4333086550555a436e43540007327be36249db72966d3c7799376d55a4d1f7b182f1686e4bfcbe5880d2831f8c0d4b5a574450416950574464476c1459644f506f79544e636b71554b6f77706541583700080101207dff31bc1e6e8ccb96a2ca92fb6b9d5d02596e7cfd57daf5645bcd100502f2f808b6584c3350f088cc0866e3b4ae1160618b202823d7947633bb76c3707cbddf55b25abbfd891a9da2781c7e6f0d1ecaa0344d010001640129d25dc080942f0d96ea25b69017a2dd02261f86a60fbb39b6b2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440afb0da13fc35b1d0b359d10f4caa95c7a823363e0347099a8e258972c54018536da7d9efc03388e60426feb07edc257caba7b4563d30eae1042fdf3c4ae59409", + "signed_txn_bcs": "cef634d8bd1e06c2aca36e50b05052d97f9a3be27991b231a83040fe4d257c67c607d345319138c9028cdbf1de27df1b9c9eeb80bc3ae40b0478f6686fe1f19d86f52e3965e7e8c3da0942736f365f436f696e0d4446714b4671694d6151686342050607e5473d49de5ec077531f7a1baa6987e00d776f435008b30ba541f3a763235694116c705759466e4d5a574b4246654b4270431775726a75476b5a6947454a58726e714e62766c5a536f4c000606078620965f6b3f186879a8c041bfaa097cc9f4dfacfdf9942490193f85f5f9f1e21e4b4d6e4773447a65446b626d456177656648494f6f4f466d4a4a515862321d627455546d576e5051684d4a745a676967485647445457526d5a6d704300078d116727cb3f9c65f7c62857e9ce1a3887af299ac3659154bdd5e1a1d2a5ad6c08526f59797479457908676b6e566270543300060780a61b1ec2e12a6a476e29794cd765fdae2a2f0ca7d0e9fd9bb09dd054ab7c3e06596f4e69757815486678534c6142626d746464584944444376787971000754f53e444cab1a11b09b67d1060abdf0367dbef422c4be37980e5e992dc1acdf04486453471f587656714b52506a6e6f684a666a51795952586f4b716674725242784e7146000801001057d3eeaf5649bac478fc990c6c12134e08ebe2b76c356c88fe086734a0855b4b0c7d10efa79b34a21ad17ecc3fc14228f3aa3e010008d66dc7a28f25db0e01bbda2a0629e3f05a997b7de2db9057d71a5c71d4ab75ee12c75b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405cf91ddc872090437c48eba52402cbd8e0c265d9fb5193abbf1a81915ae3213ee195ed2aba525b111a6714c905be3778ab5ea10ea981e4ae3acabdb5c319d90b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "6778a62240e734349b4e553713c79b75a7fe097abdc52a574ea152209e817d5b", - "sequence_number": "5990529320530598198", + "sender": "3b0707ca80892ecb201a6ec391eb1c567f235fea982fc67d9381c8419717a212", + "sequence_number": "12584222423719844830", "payload": { "EntryFunction": { "module": { - "address": "71d3b2e5fb84df92f2864e0fe41235808d92102bd29d69fbd7b84364e8b37ef9", - "name": "QiayZGoDmVyBAfsQXlsJlGnBlpcCuX7_Coin" + "address": "d8f0eb7b39c797f1812c70fe55b5201ed9d2b0e38154f4c0085e02630348002e", + "name": "jGpIQCYIholgELmXIDxTkmUOk9_Coin" }, - "function": "dyPncMAZUOWgwSSaqtr4", + "function": "EPFOMTkEUmdmLTWDCavDLRWxXvf0", "ty_args": [ + { + "struct": { + "address": "ed842ad4239ddf6a327985076574c398462d47dc5bf0418d1d81db7ad015299e", + "module": "Tz", + "name": "bQ9", + "type_args": [] + } + }, { "vector": { - "vector": { - "struct": { - "address": "ca04240048b0d74b4c947470d954fbeb3b0c94dc3031bc9bdc668be78e37ac81", - "module": "tmIcXsQ3", - "name": "XloOTg", - "type_args": [] - } + "struct": { + "address": "4ed3dda2b6d709be6c3724087aa17dbd791616ac8d5f6736f47082efcf87d1fe", + "module": "KufuBm2", + "name": "OfkzFvCyxEuDYaUebmmVCzws", + "type_args": [] } } }, { "vector": { "vector": { - "vector": "u128" + "struct": { + "address": "8b71b0c22ef7b0ad0bdd4fe1ab6703821868d7977353916f47983fe1a8e24dd8", + "module": "zcYcctLSkwuNELUC", + "name": "wvsZAzldOSzYWxFzBVjzQA8", + "type_args": [] + } } } }, { "struct": { - "address": "fb2f37d44afd9f37fd5db9dbf9c88e460d3587a30102e6486ebc48a96c067278", - "module": "PvIrPMT", - "name": "TlVnsUGbfNtxq1", + "address": "5c45fd57b0f7d2f709525feef4e0e68b8c5403bf2ff805135bbad93169044809", + "module": "JYLYZLdwFuJpFKklVTMXfmU9", + "name": "QykXZcNOjWyjdk0", "type_args": [] } }, { "struct": { - "address": "a55af3438e90514f5f0a5b56625f96ce658b1a762711a96325a3cf288a4d2755", - "module": "apNSsfnEbjL", - "name": "wzNgbHKIoYEBWiTWwoQTXAjYuwOkf2", + "address": "82fb517f5914a9841a0ab1f71a5511293263d4a292dfd005cbb716107ac31b95", + "module": "mDdlfLTFCQiQleP", + "name": "hDbJLNkN", "type_args": [] } } @@ -4991,155 +5430,245 @@ "args": [] } }, - "max_gas_amount": "12149949148592631079", - "gas_unit_price": "5755966100836256336", - "expiration_timestamp_secs": "489257404244072347", - "chain_id": 62 + "max_gas_amount": "18120236537945030104", + "gas_unit_price": "8924417157808123988", + "expiration_timestamp_secs": "8391785183681096261", + "chain_id": 143 }, - "signed_txn_bcs": "6778a62240e734349b4e553713c79b75a7fe097abdc52a574ea152209e817d5b36d9c986ada222530271d3b2e5fb84df92f2864e0fe41235808d92102bd29d69fbd7b84364e8b37ef924516961795a476f446d56794241667351586c734a6c476e426c7063437558375f436f696e146479506e634d415a554f5767775353617174723404060607ca04240048b0d74b4c947470d954fbeb3b0c94dc3031bc9bdc668be78e37ac8108746d49635873513306586c6f4f5467000606060307fb2f37d44afd9f37fd5db9dbf9c88e460d3587a30102e6486ebc48a96c0672780750764972504d540e546c566e73554762664e747871310007a55af3438e90514f5f0a5b56625f96ce658b1a762711a96325a3cf288a4d27550b61704e5373666e45626a4c1e777a4e6762484b496f59454257695457776f515458416a5975774f6b66320000276deca0604a9da8500a891bac4ce14f9b97b2570431ca063e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401836988b035c5a0f5e0d553257c96d91bfbf3f8e8279e80619b79ff2a254bda51f51b630f91f9f929ed24f836900661542eed10da07416c154dc14ae91dc400a", + "signed_txn_bcs": "3b0707ca80892ecb201a6ec391eb1c567f235fea982fc67d9381c8419717a212de9b53cc9e23a4ae02d8f0eb7b39c797f1812c70fe55b5201ed9d2b0e38154f4c0085e02630348002e1f6a47704951435949686f6c67454c6d58494478546b6d554f6b395f436f696e1c4550464f4d546b45556d646d4c545744436176444c525778587666300507ed842ad4239ddf6a327985076574c398462d47dc5bf0418d1d81db7ad015299e02547a036251390006074ed3dda2b6d709be6c3724087aa17dbd791616ac8d5f6736f47082efcf87d1fe074b756675426d32184f666b7a467643797845754459615565626d6d56437a7773000606078b71b0c22ef7b0ad0bdd4fe1ab6703821868d7977353916f47983fe1a8e24dd8107a63596363744c536b77754e454c5543177776735a417a6c644f537a595778467a42566a7a51413800075c45fd57b0f7d2f709525feef4e0e68b8c5403bf2ff805135bbad93169044809184a594c595a4c647746754a70464b6b6c56544d58666d55390f51796b585a634e4f6a57796a646b30000782fb517f5914a9841a0ab1f71a5511293263d4a292dfd005cbb716107ac31b950f6d44646c664c5446435169516c6550086844624a4c4e6b4e0000d87d444a200378fb54f08d161fe6d97b45aab2b8299c75748f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ea13391e30fb64fcf698552550e9987f2084ff492f10db42a6b9780fc15fa58c7dbfebcc4cd42fbc4624ae0bb4fe2da8e39a0ba32108a626e2a4a915094d7701", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "6ef0b35a4bdfd6843e769dd46227a1b7525ad29ef25fafb791c9353ecc7afc3c", - "sequence_number": "5144150898799306293", + "sender": "f9598a71c5b29379f88c9cad2ba7f6e9fb423b3fccca79ca3ea731f7db22db43", + "sequence_number": "3935367627153526151", "payload": { "EntryFunction": { "module": { - "address": "967286f392e6fceaefc0e5eca020da2208b9f962f60c60fd3d3a42b1b2da699c", - "name": "LTJRLSuXzvseOa_Coin" + "address": "7e124120250c327fed390fe57dc099302e20f167ece61dc55e20570aaf91ae56", + "name": "wEeNVBnGEeVSefxrUqjG0_Coin" }, - "function": "pYirLsUNfLPHVZJILBPBFNtpYvB", + "function": "uFfmokhkdAp3", "ty_args": [ { "struct": { - "address": "2bf8302396a5e774266888be954168eb3e8b7dcd8a99308e303a004097ebb3f4", - "module": "wDCfnzBNjQtQRZCJStNjti9", - "name": "DehRZLIukWTNK2", + "address": "ee4fc8d0d8a169fa7cbb775781198b2144b8b4f543c26cbc0756968a513831fe", + "module": "eIwpP", + "name": "sdQBsprLlIDimrtaWTphO", "type_args": [] } }, { "struct": { - "address": "52bf6e8aad73229c54c5a713878078fc08245339e1b821d85f96c1f8de051967", - "module": "PxYUPOLmVkwd1", - "name": "c", + "address": "c857cfdcbe402808c8bc8a452f380995a16e06fc6d61aae212855065de8740a1", + "module": "PVJxpA7", + "name": "xk", + "type_args": [] + } + }, + { + "struct": { + "address": "7334108412c9b2dcee22dbd26b4e2c700d04f45828fc600ee6dbb41a954ccb03", + "module": "TxY", + "name": "OfGuxCKNKAWjdIsYivzyXVJxjPgKHA", "type_args": [] } }, { "vector": { "struct": { - "address": "6196ad6c46a0bcb427c9748d6ac8fd097d39ec98ae4f0251c9cd6281310917ae", - "module": "bccohAy", - "name": "iNxeXSsjJhexdElxrhdRFdajgl", + "address": "6ed1188441ba150d67b88aca185ccdbdd07dc90556ea7abde1c251b0452939d4", + "module": "QCSHrcRIFVXsb7", + "name": "mJhukJwThvDC", "type_args": [] } } }, { "struct": { - "address": "5591e026da98df7662a1fe2c23efebfaadea9ced59e6b19afb097c22bc63bea5", - "module": "zGSyAvkYBgfWjcBuOvDuLPJs", - "name": "sovELQLMXrqqjFsnbzISALalMtTJc", + "address": "8def064d6b4f036357028625bd4339d4dc5c960d27487fcfa166bc09223764e5", + "module": "XhFkuPVSTDEaFcYSysmDCDwGhaZRKr8", + "name": "HTBKctkabKxrqhYfMZDhJGln7", "type_args": [] } }, + { + "vector": { + "vector": "bool" + } + } + ], + "args": [ + "d32f70786e7312f81094731ecd0e10077954afcec2c62866e6a80b79bbded1af", + "5dccae51abb6b799bcd0f53cf43161e1", + "01", + "f8d347f9b7793342", + "9bd7cc3eaa3e9e596be5a4d39bb01f6c5d3960646ed1515d4f3cffabb7b536c3", + "29ae391a93a97d7ddf9e3c0eef40a740", + "6b08330994f2701bce4a7d8b5a65b8ccc98fd71b05d264191e376d29a83d3e34", + "2c25b34c392dc2426c79960364f5b3d499a1e7fc2259e7044f85edf521f817e5", + "7e" + ] + } + }, + "max_gas_amount": "8637265394567282464", + "gas_unit_price": "16343533545087809091", + "expiration_timestamp_secs": "9587767908266062746", + "chain_id": 137 + }, + "signed_txn_bcs": "f9598a71c5b29379f88c9cad2ba7f6e9fb423b3fccca79ca3ea731f7db22db4387cd0ea5013c9d36027e124120250c327fed390fe57dc099302e20f167ece61dc55e20570aaf91ae561a7745654e56426e47456556536566787255716a47305f436f696e0c7546666d6f6b686b644170330607ee4fc8d0d8a169fa7cbb775781198b2144b8b4f543c26cbc0756968a513831fe05654977705015736451427370724c6c4944696d727461575470684f0007c857cfdcbe402808c8bc8a452f380995a16e06fc6d61aae212855065de8740a10750564a7870413702786b00077334108412c9b2dcee22dbd26b4e2c700d04f45828fc600ee6dbb41a954ccb03035478591e4f66477578434b4e4b41576a6449735969767a7958564a786a50674b48410006076ed1188441ba150d67b88aca185ccdbdd07dc90556ea7abde1c251b0452939d40e51435348726352494656587362370c6d4a68756b4a77546876444300078def064d6b4f036357028625bd4339d4dc5c960d27487fcfa166bc09223764e51f5868466b75505653544445614663595379736d444344774768615a524b7238194854424b63746b61624b7872716859664d5a44684a476c6e37000606000920d32f70786e7312f81094731ecd0e10077954afcec2c62866e6a80b79bbded1af105dccae51abb6b799bcd0f53cf43161e1010108f8d347f9b7793342209bd7cc3eaa3e9e596be5a4d39bb01f6c5d3960646ed1515d4f3cffabb7b536c31029ae391a93a97d7ddf9e3c0eef40a740206b08330994f2701bce4a7d8b5a65b8ccc98fd71b05d264191e376d29a83d3e34202c25b34c392dc2426c79960364f5b3d499a1e7fc2259e7044f85edf521f817e5017e20fff4391dbbdd7743b6a3e12ae5cfe29ab316491d980e8589002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400f86cdb111b01ca37b8da66bd29f76d9a97cb0e14d38ace83b645971fcf21f28b207dec127c6a11340eb8e01e9aa4a4230b194ae92afc12b2110dd638faa7104", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "190edabe73df3005278ea9d2afb38ea6f8f480ab441ee7b1146c07e6c90010b3", + "sequence_number": "4394165734779209286", + "payload": { + "EntryFunction": { + "module": { + "address": "7e9d3c319876a7a4165c8e9ec3dadaa07c0df5be44021a3d72c8ca83e15a4056", + "name": "ByUtvtRIhFMrf9_Coin" + }, + "function": "zfgWDGYtoxrOCDHd", + "ty_args": [ { "vector": { "struct": { - "address": "67e66bacd1bd6498a3640c66d591d099fb550be4a7694239c006c1f57e1b7956", - "module": "yBJHVC", - "name": "OXmVBQxs", + "address": "d41fbaa554fc07ebf675e1bf8e1a56933e70dfcc7107b47b9d1a2046dffe6c4b", + "module": "FkfDxyedQ5", + "name": "Ry1", "type_args": [] } } }, { - "struct": { - "address": "560e5a1a747c100e30f3da7d8260be526096245fa6a3c08f5a2a32198cadff27", - "module": "qThrKuSIcfiIUtYjlET3", - "name": "geQZscETkgc", - "type_args": [] + "vector": { + "vector": "u8" } - }, + } + ], + "args": [ + "7914dd70f88fd869", + "43", + "bd347dccd29caed01d1e6a78f72d0228f5a4efa16c9aa70a5de59b34dd355025", + "cc80110b79c06206891105e83c2b5ca0a3ffe2b1a38b892174b279f6f4ea8715", + "b8b98e038ff73f0f41f7941606eaa869" + ] + } + }, + "max_gas_amount": "8885486341595182023", + "gas_unit_price": "17317823854610856875", + "expiration_timestamp_secs": "15866080410689049502", + "chain_id": 102 + }, + "signed_txn_bcs": "190edabe73df3005278ea9d2afb38ea6f8f480ab441ee7b1146c07e6c90010b34646b5597436fb3c027e9d3c319876a7a4165c8e9ec3dadaa07c0df5be44021a3d72c8ca83e15a405613427955747674524968464d7266395f436f696e107a666757444759746f78724f43444864020607d41fbaa554fc07ebf675e1bf8e1a56933e70dfcc7107b47b9d1a2046dffe6c4b0a466b6644787965645135035279310006060105087914dd70f88fd869014320bd347dccd29caed01d1e6a78f72d0228f5a4efa16c9aa70a5de59b34dd35502520cc80110b79c06206891105e83c2b5ca0a3ffe2b1a38b892174b279f6f4ea871510b8b98e038ff73f0f41f7941606eaa869c7b35d17c0964f7babbbddc00a4555f09e93e74812a42fdc66002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fb60e53c46d4fdef69eaa39ad4730ebb4792a2f60caa1e6e207b7e8401e7bddc4e22605258055c46466690fb53a97903d45cf9eb8d5a15c53e7c6b9511142900", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "99fd3eb88be8fef7f4a99485b4352df04e1a5e4a217ec080f3bce538b445a14c", + "sequence_number": "14521371487918958808", + "payload": { + "EntryFunction": { + "module": { + "address": "d3f612afca6b25f7a214c4f1c25754d3d33c70d1266efbdd0b1fb9f2a0af6d56", + "name": "qLRHHyJ_Coin" + }, + "function": "rQwdsiitpswxOXdxNrTKLuYhNOPxbjZU", + "ty_args": [ { "struct": { - "address": "a1c8bf180cfd5eda9d45806efb7c108ed0f2a9ce7d78c1445f3ae45c6b5d995f", - "module": "fnpdoUltgONF0", - "name": "yluFjYemtXLNRtJQXspzQHYsGiqC6", + "address": "c9654c9e8833f4e16b553850e7a255a60192749edd67babb81a35c295582964c", + "module": "onUqtAo8", + "name": "aRPRGDqagTlcuhQsP", "type_args": [] } }, { "struct": { - "address": "dfdd1f365f49185f446f017679842e14e38f70be2694f9666671533fb24162dd", - "module": "ZcWEgwOHQCuBlTCMxFkEeo0", - "name": "zg", + "address": "7e3e7e5293ce77ee5bfec3d67634a12a2a9dbe2ff039e2ddea9689a8f5f5e545", + "module": "bRXhTvyCjyvt", + "name": "LlusnjFjr0", "type_args": [] } }, - { - "vector": { - "struct": { - "address": "59925cc9bedfd6077defcc6503199de5c99138e50323617ee32743f3fc2bf1a9", - "module": "EWDTjmugQGpZtVNMHQrofYJV1", - "name": "YDyVexWNYBF", - "type_args": [] - } - } - } + "u128" ], "args": [ - "58105313d008f0bb", - "01", - "25", - "01", - "4c60eb34df833da4", - "10d48b9d2339a629fbc52ae094a1ff96" + "00", + "8275e5b86d2fa243362f92bb0250eedd", + "3cf4012c73964da5706ecb42ac8a02bd4b94e0a4fb4eaace9c8ef4452767326f", + "4f", + "7b3855b49100e57b", + "99", + "e52fad792b449d873af69db58ba86f7e", + "02a2095f56f0f16463569b50161b1010" + ] + } + }, + "max_gas_amount": "17879258683857870553", + "gas_unit_price": "2605423656524117849", + "expiration_timestamp_secs": "8802723359040033093", + "chain_id": 213 + }, + "signed_txn_bcs": "99fd3eb88be8fef7f4a99485b4352df04e1a5e4a217ec080f3bce538b445a14cd828e5446e4686c902d3f612afca6b25f7a214c4f1c25754d3d33c70d1266efbdd0b1fb9f2a0af6d560c714c524848794a5f436f696e207251776473696974707377784f5864784e72544b4c7559684e4f5078626a5a550307c9654c9e8833f4e16b553850e7a255a60192749edd67babb81a35c295582964c086f6e557174416f3811615250524744716167546c63756851735000077e3e7e5293ce77ee5bfec3d67634a12a2a9dbe2ff039e2ddea9689a8f5f5e5450c62525868547679436a7976740a4c6c75736e6a466a72300003080100108275e5b86d2fa243362f92bb0250eedd203cf4012c73964da5706ecb42ac8a02bd4b94e0a4fb4eaace9c8ef4452767326f014f087b3855b49100e57b019910e52fad792b449d873af69db58ba86f7e1002a2095f56f0f16463569b50161b1010d99eaa6a0be31ff859f784f00253282445519d97418e297ad5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144408e21be47d80617f1b917c4e052971934923ca06c6c8822d38d580f3c3ba800a9017083360de9c90beb96d20235924fe5e2254b5a38ac212c0db5866fe2afea09", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "68d337a0f6277f5d0349d789790d016e79de516c8e4ae6ff9c4cd36950e70a0f", + "sequence_number": "2157332272851327941", + "payload": { + "EntryFunction": { + "module": { + "address": "864a21ae60811a18560aca58de0e829a9ad8fe71be9d2abd8d0330e21c5e5142", + "name": "wMduaLNplNzhrVP2_Coin" + }, + "function": "eWGbDqGiTvfbCoUKHrulmfYJdgZGUyB9", + "ty_args": [], + "args": [ + "00", + "2fda54c850a6a8e4" ] } }, - "max_gas_amount": "7906394760520268964", - "gas_unit_price": "8327544633798890850", - "expiration_timestamp_secs": "2479669273317751503", - "chain_id": 220 + "max_gas_amount": "10380498159669693669", + "gas_unit_price": "8746182619075811418", + "expiration_timestamp_secs": "7313961327173535914", + "chain_id": 22 }, - "signed_txn_bcs": "6ef0b35a4bdfd6843e769dd46227a1b7525ad29ef25fafb791c9353ecc7afc3c3566f0d1fcb1634702967286f392e6fceaefc0e5eca020da2208b9f962f60c60fd3d3a42b1b2da699c134c544a524c5375587a7673654f615f436f696e1b705969724c73554e664c5048565a4a494c425042464e747059764209072bf8302396a5e774266888be954168eb3e8b7dcd8a99308e303a004097ebb3f417774443666e7a424e6a517451525a434a53744e6a7469390e446568525a4c49756b57544e4b32000752bf6e8aad73229c54c5a713878078fc08245339e1b821d85f96c1f8de0519670d50785955504f4c6d566b77643101630006076196ad6c46a0bcb427c9748d6ac8fd097d39ec98ae4f0251c9cd6281310917ae076263636f6841791a694e78655853736a4a68657864456c78726864524664616a676c00075591e026da98df7662a1fe2c23efebfaadea9ced59e6b19afb097c22bc63bea5187a47537941766b59426766576a6342754f7644754c504a731d736f76454c514c4d587271716a46736e627a4953414c616c4d74544a6300060767e66bacd1bd6498a3640c66d591d099fb550be4a7694239c006c1f57e1b79560679424a485643084f586d56425178730007560e5a1a747c100e30f3da7d8260be526096245fa6a3c08f5a2a32198cadff2714715468724b755349636669495574596a6c4554330b6765515a736345546b67630007a1c8bf180cfd5eda9d45806efb7c108ed0f2a9ce7d78c1445f3ae45c6b5d995f0d666e70646f556c74674f4e46301d796c75466a59656d74584c4e52744a515873707a5148597347697143360007dfdd1f365f49185f446f017679842e14e38f70be2694f9666671533fb24162dd175a63574567774f48514375426c54434d78466b45656f30027a6700060759925cc9bedfd6077defcc6503199de5c99138e50323617ee32743f3fc2bf1a919455744546a6d75675147705a74564e4d4851726f66594a56310b594479566578574e59424600060858105313d008f0bb010101250101084c60eb34df833da41010d48b9d2339a629fbc52ae094a1ff96a4fcd1122528b96d6215cb24b9619173cf3a8ef4108e6922dc002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444025cf42ad15ed3ea6ac061ffbd383bed69b1372958f40627d269b9910eb99c0acf84d8adb9e8cd9a0aed6c527da3e176c74150fc103024488668fc580df7ac30c", + "signed_txn_bcs": "68d337a0f6277f5d0349d789790d016e79de516c8e4ae6ff9c4cd36950e70a0fc51bcaa94562f01d02864a21ae60811a18560aca58de0e829a9ad8fe71be9d2abd8d0330e21c5e514215774d6475614c4e706c4e7a68725650325f436f696e20655747624471476954766662436f554b4872756c6d66594a64675a475579423900020100082fda54c850a6a8e4e54cb5f613f00e905a98b5b6c0ae6079aa881f771369806516002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405eba09c2006fef19fe8237783bb554a632103205ba6b61e7eafaf06da76e83b7ab42dadfa3c4755d8571c6894a5a0aa12709179dd826d160248b8f644ec0350b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "cdae5d36e8b3894d69347f9fb627730171a09ef20fd14bb95d6929e6ebe3558e", - "sequence_number": "4103580044930880649", + "sender": "523f859b49472b872257e9d8692ceb1c361d580936c31632160d2f66ede09bfb", + "sequence_number": "12453521025643580607", "payload": { "EntryFunction": { "module": { - "address": "1a24efa5b9f435261b31a7a0a3f99762d77c77cf1d4361320aec1c86294532f1", - "name": "QiyTVBnAZyPNy9_Coin" + "address": "639707b7e9ca960d81877d36176b04645685d35722e63fec67e772557883a044", + "name": "JppbPUyNONIZSpMDInFHBjp_Coin" }, - "function": "CqEN", + "function": "QsGTuUqCIOZVR", "ty_args": [ { "vector": { - "vector": "address" - } - }, - { - "vector": "address" - }, - { - "struct": { - "address": "d15c26076dc690c0973cb96048d23946eac7a6891005d0582efb6d94a3c0f0e4", - "module": "W3", - "name": "CxlqrcBBzGtObmnsFZPYtkD2", - "type_args": [] + "struct": { + "address": "eda0461881555e0ee747b7fc4cb1dedbef42d037b85e8cdc39371f03dd296e3a", + "module": "XTVsFxmIbksDBj", + "name": "gofjIqlnbDn2", + "type_args": [] + } } }, { "vector": { - "vector": { - "vector": "signer" + "struct": { + "address": "70c9a1458c9e888d88b98f4ccc613296fbfd71f452ed36dcf08dae37da8616f4", + "module": "NcbV", + "name": "wgnfvkxvwNvikwtSVeFuQeYcIY", + "type_args": [] } } }, @@ -5147,957 +5676,910 @@ "vector": { "vector": { "struct": { - "address": "382874ffd0e010e11be2b5107d5c0ecaf17817cf5c64a804482ecd2b23945346", - "module": "Ffe2", - "name": "vybGeTPfG", + "address": "2b11e1dd1060724f7c51a22d4a828ae42f101d7cfb769516324357a8a1a6fd91", + "module": "WZcGNKaorwrwJSWW8", + "name": "JNORCelHPWTi6", "type_args": [] } } } }, { - "struct": { - "address": "c52b8f728e668849c4b3d73d1bbf3b51f05f19bf3f8d927bdda3c93d91ed2b64", - "module": "yofMT", - "name": "pNjcxnwcUiALPZecswUULcK3", - "type_args": [] - } - }, - { - "struct": { - "address": "39e3db494d86811a4a2f5bc3492a993dbe3482ce749f5fd651ac030c65e739b5", - "module": "df", - "name": "kIziLA0", - "type_args": [] - } + "vector": "u64" }, { "vector": { "struct": { - "address": "7d7b59b2ab1604b73d4872432010a7d91e2b62e96328ad825995225ea0ed988e", - "module": "xAGsMso", - "name": "hjxISgSIFlWLGglEZhGKPaFRQ", + "address": "b9f386ebe06c0a6189db406ea60f7dc969aeed476a39ffe66e3ddb06adff7451", + "module": "abpaSVxoEbYyYGEmEaSiveidFfLcPuW4", + "name": "xHiVgmvfEXqplIXjHxIYsmZHBCy1", "type_args": [] } } - }, - "u64" + } ], + "args": [] + } + }, + "max_gas_amount": "2121712084599913483", + "gas_unit_price": "4205030645980683583", + "expiration_timestamp_secs": "2915328730634002746", + "chain_id": 146 + }, + "signed_txn_bcs": "523f859b49472b872257e9d8692ceb1c361d580936c31632160d2f66ede09bfbbf0c582864cbd3ac02639707b7e9ca960d81877d36176b04645685d35722e63fec67e772557883a0441c4a7070625055794e4f4e495a53704d44496e4648426a705f436f696e0d5173475475557143494f5a5652050607eda0461881555e0ee747b7fc4cb1dedbef42d037b85e8cdc39371f03dd296e3a0e5854567346786d49626b7344426a0c676f666a49716c6e62446e3200060770c9a1458c9e888d88b98f4ccc613296fbfd71f452ed36dcf08dae37da8616f4044e6362561a77676e66766b7876774e76696b77745356654675516559634959000606072b11e1dd1060724f7c51a22d4a828ae42f101d7cfb769516324357a8a1a6fd9111575a63474e4b616f727772774a535757380d4a4e4f5243656c4850575469360006020607b9f386ebe06c0a6189db406ea60f7dc969aeed476a39ffe66e3ddb06adff745120616270615356786f456259795947456d456153697665696446664c63507557341c78486956676d7666455871706c49586a48784959736d5a484243793100000b3c3b4ee6d5711d3f5d4fe317455b3a3a21eed00854752892002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ee0ef6d18b3faf513e10327f38a4fc377b6486772cd713771179d81171708c6ba76519ca7e6d9515dcd5a0c53a3e1763ed52402aad800ed081a350ce93b6d206", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "ccd1576d8e206739f9e65c823e0f6c49258197632e2e7607039ef09e50147016", + "sequence_number": "10249967804133273924", + "payload": { + "EntryFunction": { + "module": { + "address": "b42e07d4c6750f4296cad0b23f77cd8299b90b1f8c486b3a9c80ace1fa5f902b", + "name": "bBTrPib_Coin" + }, + "function": "CDqOuaaQOEHDAExBukPIvon5", + "ty_args": [], "args": [ - "a1a5437fc6432ffcf074db13006241a2b397f9a25818305cdb53047d7634d1de" + "ba226df75bef7e1eb76461f5f52e730a", + "0691a777c14996a8a2482de376a2b072" ] } }, - "max_gas_amount": "17830332572551937389", - "gas_unit_price": "6240710093775976093", - "expiration_timestamp_secs": "9935782003335331201", - "chain_id": 201 + "max_gas_amount": "8019537092035902677", + "gas_unit_price": "8538650725598733428", + "expiration_timestamp_secs": "13284623303320135806", + "chain_id": 13 }, - "signed_txn_bcs": "cdae5d36e8b3894d69347f9fb627730171a09ef20fd14bb95d6929e6ebe3558e89947c254fd8f238021a24efa5b9f435261b31a7a0a3f99762d77c77cf1d4361320aec1c86294532f1135169795456426e415a79504e79395f436f696e044371454e09060604060407d15c26076dc690c0973cb96048d23946eac7a6891005d0582efb6d94a3c0f0e40257331843786c71726342427a47744f626d6e73465a5059746b44320006060605060607382874ffd0e010e11be2b5107d5c0ecaf17817cf5c64a804482ecd2b239453460446666532097679624765545066470007c52b8f728e668849c4b3d73d1bbf3b51f05f19bf3f8d927bdda3c93d91ed2b6405796f664d5418704e6a63786e77635569414c505a6563737755554c634b33000739e3db494d86811a4a2f5bc3492a993dbe3482ce749f5fd651ac030c65e739b5026466076b497a694c41300006077d7b59b2ab1604b73d4872432010a7d91e2b62e96328ad825995225ea0ed988e07784147734d736f19686a784953675349466c574c47676c455a68474b506146525100020120a1a5437fc6432ffcf074db13006241a2b397f9a25818305cdb53047d7634d1de6dfd086e011172f79d36b6fdc3749b56817d850a17fde289c9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409bf27d31d188ae544c8b5291b760befe79320e4544f1f91017a8714684c128b8f075bb2384b57831aff2f40a464abb5373d5cbf4ddbe8fd5ca5dd79c856a670f", + "signed_txn_bcs": "ccd1576d8e206739f9e65c823e0f6c49258197632e2e7607039ef09e5014701644f18d4469333f8e02b42e07d4c6750f4296cad0b23f77cd8299b90b1f8c486b3a9c80ace1fa5f902b0c624254725069625f436f696e184344714f756161514f45484441457842756b5049766f6e35000210ba226df75bef7e1eb76461f5f52e730a100691a777c14996a8a2482de376a2b072d57cdef17e1e4b6f74a4716098617f767ee8456982765cb80d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c5ee4e4056ad2fe552cc7da0daf4fb8beac344ba70e5ec07a0c2003f044d20402a82ac6e7045c2e28a5dfc0b5087693803d4903dc635d0996d7dbbfa88993502", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "f1f16bd196c3d4aeb23debc5ce93100b7b07b2f2fe726c7de6d1741b122f0a74", - "sequence_number": "9663237585012466233", + "sender": "1db6b3c50cff210289ed8b3319b7112089da42a4b3486e0c2b8e9b6ce50791e7", + "sequence_number": "5274975001615907895", "payload": { "EntryFunction": { "module": { - "address": "5aa8e1999aa92f0daafbafe7b760749df76265152de201e7863205b1058573a4", - "name": "OCXVISMHODJGaurrHlaEYqK_Coin" + "address": "da7fd350e5d1c6b8640c3713d88c0813fbf84fe750f9b4296b6bdcfbce554a40", + "name": "R0_Coin" }, - "function": "UAPQocoVQxMqWvAa4", + "function": "uvSMN", "ty_args": [ { "struct": { - "address": "68e85884c392b1985372b02b975ec9f68e266c8c4ce0339e085c64247ddad54f", - "module": "wnausFhpytSqD5", - "name": "XeYQTqdrZMXWgHDixhNVsuGUL", + "address": "966ab4d4086ea16f0d19f33e0629741e4095a06103ab799ec7a9074dd3e48c42", + "module": "tCPZgjUUCVvHdIzTxBEgCdkG9", + "name": "gNEudbDqfrI4", "type_args": [] } }, { - "vector": { - "struct": { - "address": "3c7facf06bcbf163e4e976aa45296da691e65a770f6cf6510b681fb38f9104ec", - "module": "mfXGN", - "name": "LFktQYHMnOxZTNeitJdla2", - "type_args": [] - } + "struct": { + "address": "e568407cd551802b3069a1424bae127ad752125a5e9e950b365c812c7815aef0", + "module": "tJZwRIYD0", + "name": "HexMkytjYWP", + "type_args": [] } }, { "vector": { - "vector": "u64" + "vector": { + "vector": "signer" + } } }, { "struct": { - "address": "0aae102420453e9d84b40b523b8349ac5df8875f9df918b7d3d6fa60857809bb", - "module": "QGtSoXwdVZsfsVvzy4", - "name": "LgKbSBtCAquMOGyVpmlkMC", + "address": "589cf2731da9ad868d676432a540730a4497afeb17089cf8eb3fcdff92a00de9", + "module": "HLieJDdcrzhDXYmg9", + "name": "PxhbVcQvkwfUowKKSnjv0", "type_args": [] } }, { "struct": { - "address": "769039133e7a971456e0cf7fe30a19164a227fc288043f794feb10b5bb814235", - "module": "aaGWZcPYzBZwVaGC", - "name": "NvmnspnzvrYXBPsRimTHdSAlg", + "address": "371a3930753b26845e87f35acf14539875ef36a40cd9442f827fbbb404cb76ca", + "module": "CLyhVERWalfymVP", + "name": "GfKETzLLuzXcSu2", "type_args": [] } }, { - "struct": { - "address": "130ded7057c932665326f4846bb01477df2a77e1f7ab44ccd684ec1c536f2012", - "module": "bEDjYwhmBdUmLoMXbQER", - "name": "WIHEAbVzehZNqGuwsNLHWDZ", - "type_args": [] + "vector": { + "struct": { + "address": "063c705df504166eb6abe266adba197a436e53fed056a31882ef45a10a3c999b", + "module": "nfHhxMoSqwf5", + "name": "ZurphlzORmvtxYMqKbwmlyJhcdhsSNCx6", + "type_args": [] + } } }, { - "struct": { - "address": "734184284a19ca6af3385961fb8db21142cf5c1e60f4dc67bbe62ba2dfaf56ce", - "module": "BbWcCIVynjK", - "name": "cgDwS", - "type_args": [] + "vector": { + "struct": { + "address": "06c9eff13c2c32fed87bcc60c96d5bd2abff49be533f79b7a7d1dd123131ced1", + "module": "bKUOmRPPiijLjybgEzulhiKtF", + "name": "rqwWFesjS7", + "type_args": [] + } } }, - { - "vector": "u64" - }, { "struct": { - "address": "01fd4e12ec18f511528f7ea2cf6c350e881c0b813587d908c0bdb0d425b2cca0", - "module": "rLCckGCKwCthAAgQhiNjNSHedS", - "name": "NjXqEzwmuxFJdkQesRA", + "address": "ab2f10d4d977010445578648d2e7e30c7e9f7cc58a7be1a1ddd849cd3e1a7aed", + "module": "JlVSdcjzlPNHzaCtpL", + "name": "bYtWNHaN3", "type_args": [] } }, { - "vector": "u8" + "vector": { + "vector": { + "struct": { + "address": "62f72cab10b9e58626ee5228ed3895aa0898bbd5c47991ec3b128156b7db8067", + "module": "OxyOVgbnKPLEaKBJerHqn", + "name": "MTgcaXalnzrCrRXaRzEO", + "type_args": [] + } + } + } + }, + { + "vector": { + "vector": { + "struct": { + "address": "f7c19a15f67a9f70d70795464355a0300ab5989db4ff7995e529a74e24cc3308", + "module": "tZDoyjBbjDeNFzYpeAg2", + "name": "ffNfp", + "type_args": [] + } + } + } } ], "args": [ - "00", - "ad07d50f6c5fab0b70b22c6875a20a97febff6a58faeaad71c5117479e7d2870", - "a5", - "db33adbae3d160ba13681f37667dad0f" + "15", + "c05047be77dc5113", + "9f320a5481395fc1", + "b2bc27176085da2abe23db5129ad8d5a", + "c417a510363a2614", + "e3cfd3817ae33db03bf0593acaa201ea20cf37a81950dbb3c6e4365a2b7a1a13" ] } }, - "max_gas_amount": "16972055748975707876", - "gas_unit_price": "1412612105432416277", - "expiration_timestamp_secs": "9001456888302104920", - "chain_id": 122 + "max_gas_amount": "2426038067790815985", + "gas_unit_price": "261788517794558074", + "expiration_timestamp_secs": "1129844286756052873", + "chain_id": 231 }, - "signed_txn_bcs": "f1f16bd196c3d4aeb23debc5ce93100b7b07b2f2fe726c7de6d1741b122f0a743922dfb262b71a86025aa8e1999aa92f0daafbafe7b760749df76265152de201e7863205b1058573a41c4f43585649534d484f444a4761757272486c614559714b5f436f696e11554150516f636f5651784d7157764161340a0768e85884c392b1985372b02b975ec9f68e266c8c4ce0339e085c64247ddad54f0e776e6175734668707974537144351958655951547164725a4d58576748446978684e56737547554c0006073c7facf06bcbf163e4e976aa45296da691e65a770f6cf6510b681fb38f9104ec056d6658474e164c466b745159484d6e4f785a544e6569744a646c613200060602070aae102420453e9d84b40b523b8349ac5df8875f9df918b7d3d6fa60857809bb12514774536f587764565a73667356767a7934164c674b62534274434171754d4f477956706d6c6b4d430007769039133e7a971456e0cf7fe30a19164a227fc288043f794feb10b5bb81423510616147575a6350597a425a7756614743194e766d6e73706e7a7672595842507352696d54486453416c670007130ded7057c932665326f4846bb01477df2a77e1f7ab44ccd684ec1c536f2012146245446a5977686d4264556d4c6f4d586251455217574948454162567a65685a4e71477577734e4c4857445a0007734184284a19ca6af3385961fb8db21142cf5c1e60f4dc67bbe62ba2dfaf56ce0b42625763434956796e6a4b0563674477530006020701fd4e12ec18f511528f7ea2cf6c350e881c0b813587d908c0bdb0d425b2cca01a724c43636b47434b774374684141675168694e6a4e5348656453134e6a5871457a776d7578464a646b516573524100060104010020ad07d50f6c5fab0b70b22c6875a20a97febff6a58faeaad71c5117479e7d287001a510db33adbae3d160ba13681f37667dad0fe4c6d229c8da88eb1540b7bd399b9a1358713d205999eb7c7a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bb28ce9b104c5027f66b3a21dd94a001aa05c5abdc798c7bb036ad5a3acc5028e8da70fe55c176ab45fed1e9cccf3fccec4d610abb27408fdf0b7e99055e2b02", + "signed_txn_bcs": "1db6b3c50cff210289ed8b3319b7112089da42a4b3486e0c2b8e9b6ce50791e737bc61e2d079344902da7fd350e5d1c6b8640c3713d88c0813fbf84fe750f9b4296b6bdcfbce554a400752305f436f696e057576534d4e0a07966ab4d4086ea16f0d19f33e0629741e4095a06103ab799ec7a9074dd3e48c42197443505a676a55554356764864497a547842456743646b47390c674e457564624471667249340007e568407cd551802b3069a1424bae127ad752125a5e9e950b365c812c7815aef009744a5a7752495944300b4865784d6b79746a595750000606060507589cf2731da9ad868d676432a540730a4497afeb17089cf8eb3fcdff92a00de911484c69654a446463727a684458596d67391550786862566351766b7766556f774b4b536e6a76300007371a3930753b26845e87f35acf14539875ef36a40cd9442f827fbbb404cb76ca0f434c796856455257616c66796d56500f47664b45547a4c4c757a5863537532000607063c705df504166eb6abe266adba197a436e53fed056a31882ef45a10a3c999b0c6e664868784d6f5371776635215a757270686c7a4f526d767478594d714b62776d6c794a6863646873534e43783600060706c9eff13c2c32fed87bcc60c96d5bd2abff49be533f79b7a7d1dd123131ced119624b554f6d52505069696a4c6a796267457a756c68694b74460a727177574665736a53370007ab2f10d4d977010445578648d2e7e30c7e9f7cc58a7be1a1ddd849cd3e1a7aed124a6c565364636a7a6c504e487a614374704c09625974574e48614e330006060762f72cab10b9e58626ee5228ed3895aa0898bbd5c47991ec3b128156b7db8067154f78794f5667626e4b504c45614b424a657248716e144d5467636158616c6e7a724372525861527a454f00060607f7c19a15f67a9f70d70795464355a0300ab5989db4ff7995e529a74e24cc330814745a446f796a42626a44654e467a5970654167320566664e66700006011508c05047be77dc5113089f320a5481395fc110b2bc27176085da2abe23db5129ad8d5a08c417a510363a261420e3cfd3817ae33db03bf0593acaa201ea20cf37a81950dbb3c6e4365a2b7a1a13f1223fdac404ab217ab06b19450fa203895f99836403ae0fe7002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444008ed8ea53aa1c62d1dfebe61ff5a3d5325968dc267eb3f33c503286a1b83cce6d4900672cfda63d099a4107f001a83daf9ffae010d521e706390225232176803", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "519f286dc93603c580cfe6b065886fc2e3a299b0caef2e3fce04c9456d291b83", - "sequence_number": "13732536632205293064", + "sender": "2262a0894340b635fbd202d48474bffa8fec61e805115640ff5652bda5048392", + "sequence_number": "14174148195835009751", "payload": { "EntryFunction": { "module": { - "address": "ec0f4c6a05a495f803ba31015d46fc6691fc03025c0c87e44c073b300a7833cd", - "name": "EZgUWKPEGoDMHYkzcFpqBuqoMZgzU_Coin" + "address": "f4c550dabc219964c4090d65a0dac9475fb265082bbf007504c4dea4ff1ec8e6", + "name": "XirtbNWnSNWrCEDdHelzzd_Coin" }, - "function": "fVjaxadhHWImGvjTUUpndIkSZEMz", + "function": "iZaFj9", "ty_args": [ { "vector": { - "struct": { - "address": "d62d804f7dd2851925d1b83e05651506b9500df7c0837d4bc694bdf86955da7b", - "module": "HhSAHzDztDSno7", - "name": "jJNUSDSYLPSNvvDnUNdyDHyiGjNz", - "type_args": [] - } - } - }, - { - "struct": { - "address": "a53c2132dab3df013b11b6300d3d17eb7b18555a7871db21a99322bb78de2e6e", - "module": "vkKYZVmFYNTQvMbDhMLLa3", - "name": "HgZgaEaKwTySSCwMiztGhXSkPvopZ3", - "type_args": [] - } - }, - { - "struct": { - "address": "a791cc0423b493ae9b175532fd8a4d87bd178fdafa52c3a49e98ec67ac051c25", - "module": "riEglWV3", - "name": "eqpd", - "type_args": [] - } - }, - { - "vector": { - "vector": { - "struct": { - "address": "2e0fbf7a20fbf7701a7632973da39bd900c3be72c92cf1d5b9a1d00e9ad15bbc", - "module": "tLeOHkxYrr", - "name": "UUNUNUfhfhLdQUVUtnhb", - "type_args": [] - } - } - } - }, - { - "vector": { - "vector": { - "struct": { - "address": "5a68269ba685df6563e15f06cb1875f733bf4008f1a09c6081248ea9886a27fc", - "module": "doeXYSPdEpWkXanDJk9", - "name": "NyTRXl1", - "type_args": [] - } + "struct": { + "address": "47b25f6e6460f7e1aab0a624677ca1fb9676439295395ca823274a90d2725eaf", + "module": "cRyalecyPo", + "name": "ekknxOKVVlQxePzEnfMrEOoFlljJ", + "type_args": [] } } }, { "struct": { - "address": "6246020d735c6ba2eb319a7019daf9b2e48b96e34f33aa796895f39fded5eaba", - "module": "GevtFrTbRgIUEFKILinHmBpGLMoYer3", - "name": "JnTZdjeOnUzhEUbhhTavuVgt", + "address": "38262cb1e4a3bd0005bbf76adc702b6cb9bd9f015bb4307919ddfa7e916aa5d0", + "module": "g4", + "name": "jNr", "type_args": [] } }, { - "vector": { - "struct": { - "address": "fdf4630955c58b054dd099e42316d4d31ad17001b16d28d582a8b7305802989b", - "module": "IpvjRXlCxW", - "name": "LBOSJsiVYu8", - "type_args": [] - } + "struct": { + "address": "1e1cf8d985f461444ac39c6d522649c4dcbca8928665990ddc1b3d3e852e5efa", + "module": "NkjNMINEbaHPPCyaWZiLqvrRuZnYjk6", + "name": "EpwDMcVwSoSuDtIRorxNgfpjcZDXfk", + "type_args": [] } }, { - "struct": { - "address": "b92014919382d8b2676ad41bd7ff43f6ef1af3b5534920a6d35314b0adbc2930", - "module": "rGxcW", - "name": "zfCEoKsVCugKqbJoXhLlWunQmmLiAu1", - "type_args": [] + "vector": { + "vector": "address" } }, { "vector": { "struct": { - "address": "20ddb1daa827ae01f7f7eaf973e98b3c10e6ab3ff28f5a1f8059f96da8e6f489", - "module": "mJEozCRMHAjHjcbfnAaOSMV", - "name": "NRl4", + "address": "029159e7ebf862b94a2965ea422d11818be607577cedbe8f41849cd0957dfcc2", + "module": "sokH", + "name": "dCHbyUfHnsbbAPGzEYGinQKT5", "type_args": [] } } + }, + { + "struct": { + "address": "dc5c6ecbbe5798959c7ccbb327500fa10500a1e7801a62663b6376004c4838dc", + "module": "XcsECDmxndHVrGFkHkKBeATMzcI6", + "name": "yINMBzYSOMVQKlE", + "type_args": [] + } } ], "args": [ - "d8e534c43c1f5acb", - "15", - "00", - "17", - "289047bb0072d88ddde4674eaf7342ec", - "808170f0208f7175", - "82dcf6677f44c368e9563aa63f1d5ff883e7acdbd83dad196ec9b678613830ba", - "67704465b910d0c0125588a27afb58f86ed8e88ec2ec9c3d618fe8e6642ba4df", - "9df68b441485ba3f", - "f267340695a22919" + "18", + "8e17569f378fb87c1305a1f012857023be686b274de2c410ad12be50b5121dca", + "01", + "4d", + "110723d978bb25b4" ] } }, - "max_gas_amount": "4667834604792196443", - "gas_unit_price": "1859594188800543022", - "expiration_timestamp_secs": "12609327417526666413", - "chain_id": 164 + "max_gas_amount": "11654879041958255661", + "gas_unit_price": "10906307489344411750", + "expiration_timestamp_secs": "6526634952143335589", + "chain_id": 243 }, - "signed_txn_bcs": "519f286dc93603c580cfe6b065886fc2e3a299b0caef2e3fce04c9456d291b8308b6a2134fc593be02ec0f4c6a05a495f803ba31015d46fc6691fc03025c0c87e44c073b300a7833cd22455a6755574b5045476f444d48596b7a634670714275716f4d5a677a555f436f696e1c66566a61786164684857496d47766a545555706e64496b535a454d7a090607d62d804f7dd2851925d1b83e05651506b9500df7c0837d4bc694bdf86955da7b0e48685341487a447a7444536e6f371c6a4a4e55534453594c50534e7676446e554e647944487969476a4e7a0007a53c2132dab3df013b11b6300d3d17eb7b18555a7871db21a99322bb78de2e6e16766b4b595a566d46594e5451764d6244684d4c4c61331e48675a676145614b775479535343774d697a74476858536b50766f705a330007a791cc0423b493ae9b175532fd8a4d87bd178fdafa52c3a49e98ec67ac051c2508726945676c5756330465717064000606072e0fbf7a20fbf7701a7632973da39bd900c3be72c92cf1d5b9a1d00e9ad15bbc0a744c654f486b785972721455554e554e55666866684c6451555655746e6862000606075a68269ba685df6563e15f06cb1875f733bf4008f1a09c6081248ea9886a27fc13646f6558595350644570576b58616e444a6b39074e795452586c3100076246020d735c6ba2eb319a7019daf9b2e48b96e34f33aa796895f39fded5eaba1f47657674467254625267495545464b494c696e486d4270474c4d6f59657233184a6e545a646a654f6e557a68455562686854617675566774000607fdf4630955c58b054dd099e42316d4d31ad17001b16d28d582a8b7305802989b0a4970766a52586c4378570b4c424f534a7369565975380007b92014919382d8b2676ad41bd7ff43f6ef1af3b5534920a6d35314b0adbc29300572477863571f7a6643456f4b73564375674b71624a6f58684c6c57756e516d6d4c6941753100060720ddb1daa827ae01f7f7eaf973e98b3c10e6ab3ff28f5a1f8059f96da8e6f489176d4a456f7a43524d48416a486a6362666e41614f534d56044e526c34000a08d8e534c43c1f5acb01150100011710289047bb0072d88ddde4674eaf7342ec08808170f0208f71752082dcf6677f44c368e9563aa63f1d5ff883e7acdbd83dad196ec9b678613830ba2067704465b910d0c0125588a27afb58f86ed8e88ec2ec9c3d618fe8e6642ba4df089df68b441485ba3f08f267340695a229195b2dea80d77ac7402e49d6e90f9bce19ad4445aa7a54fdaea4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ee2f66f9660f6efef622b211dc518149bc2a1efc684f9f81ae896124563b6f29f28096255b7ebdc86be14334e8314c662426b14552ebb05616d698ce33790e0c", + "signed_txn_bcs": "2262a0894340b635fbd202d48474bffa8fec61e805115640ff5652bda5048392d75a7daeafb0b4c402f4c550dabc219964c4090d65a0dac9475fb265082bbf007504c4dea4ff1ec8e61b58697274624e576e534e57724345446448656c7a7a645f436f696e06695a61466a3906060747b25f6e6460f7e1aab0a624677ca1fb9676439295395ca823274a90d2725eaf0a635279616c656379506f1c656b6b6e784f4b56566c517865507a456e664d72454f6f466c6c6a4a000738262cb1e4a3bd0005bbf76adc702b6cb9bd9f015bb4307919ddfa7e916aa5d0026734036a4e7200071e1cf8d985f461444ac39c6d522649c4dcbca8928665990ddc1b3d3e852e5efa1f4e6b6a4e4d494e456261485050437961575a694c71767252755a6e596a6b361e457077444d635677536f5375447449526f72784e6766706a635a4458666b000606040607029159e7ebf862b94a2965ea422d11818be607577cedbe8f41849cd0957dfcc204736f6b481964434862795566486e7362624150477a455947696e514b54350007dc5c6ecbbe5798959c7ccbb327500fa10500a1e7801a62663b6376004c4838dc1c5863734543446d786e6448567247466b486b4b426541544d7a6349360f79494e4d427a59534f4d56514b6c4500050118208e17569f378fb87c1305a1f012857023be686b274de2c410ad12be50b5121dca0101014d08110723d978bb25b42d1c110cbd72bea166588ea1e0fc5a97a5f026cde843935af3002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400f122d0a4fcd3f72e331d693e8ae913f46f8db682add4bcbaa2ac474f37b72f0b810a39c2866f0e97c77b50bb70d693b1ca63796effa3d81bc83859b7ec78f04", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "d5a49d30d9133f3e16b724f055f042096c569e1d6d30e16d8c5e677ee68f3fa2", - "sequence_number": "15438830636111827449", + "sender": "c9166424e69ff945aa011afbaf8712db99a0e54ec2717afcfe69fb2933e97035", + "sequence_number": "17269409797658351941", "payload": { "EntryFunction": { "module": { - "address": "4e8a0bfc982e4a54a3d64d3757f2d58cca12129ec4b4cb359e860abceac1b013", - "name": "rCbIbtxdlAJZfSUuUNkNC_Coin" + "address": "85b6a3fcf3501e417bd8ad99c1764c4a9a913fb6453bab6e03ac373fd96c9b03", + "name": "coMsCjZRvHHuFLHSbNBmqQmRivSJpIVA3_Coin" }, - "function": "NGaVDk5", + "function": "WJiZuFIjlrJdwDulop4", "ty_args": [ { "struct": { - "address": "bcf6b3d454b77337cff4db962c20a23f3691a28a7e45888d44b254ed63bc28b8", - "module": "HCUIN4", - "name": "GcKp", + "address": "23d56d1b65fd2f9a61b254e03e116ea56ab97e2ae4779d35a7a416c9296bc162", + "module": "oUTpHIXmaBTvBrjZZjEMePnwNzHmy", + "name": "QM6", "type_args": [] } }, - { - "vector": { - "struct": { - "address": "0cfa637d3c772a93a2df9d3557dbbb85bb26c8efe2d15b13b6ba85e1f22f41e2", - "module": "OAgPPRXuwNaVWMrnQp7", - "name": "xISNyKvTaWbbLsmiKdhIahNcHyC2", - "type_args": [] - } - } - }, - { - "vector": { - "vector": "bool" - } - }, { "struct": { - "address": "e0df5fb8210ef562af7b0438329efab0b8ef1bd5c39014f0f7d1698584901fbd", - "module": "S", - "name": "XYdoIrEzKruCYzHeIApmsRiR", + "address": "cc71c78506ecaa580e10ddaf549c95bed2709d4890f8f1362637fae4c867c9d7", + "module": "bwyDigskjtAiJfkHW7", + "name": "hFOxFMMgKvXdYivpenOS", "type_args": [] } }, { "struct": { - "address": "42ae20cfdc98ebf5291e30c25b1ca4d87c2e9c8b19583bd80e0e68b57f169962", - "module": "WmXMUyCVhnjgsQypwPjdipPpbGXQlWNa8", - "name": "KKwFhIheFyaZuFwGuoInvydyBep", + "address": "30993d2a18cdadcd308c7cf9281b6af44068c1c0e65d215f2ea4b1dfd3dcfa8e", + "module": "IgAAMxlUAZMGKO", + "name": "ypPnDkonZdXLsMjtpeNS2", "type_args": [] } }, { - "struct": { - "address": "2730376d1b27bad9dee8fb8932fd82ead9ed293e7714f464e1f763268105b367", - "module": "XkEkZlQNrKeWG", - "name": "vFKdZbPYzDovaylercjnCiE", - "type_args": [] + "vector": { + "struct": { + "address": "f9b0441b7b6347cee0f0657ed796b1fe948b76a9cf7071c2cf5c4f5df0101164", + "module": "ezLYgMFXapmOMraM", + "name": "eqI2", + "type_args": [] + } } } ], "args": [ - "cfdc9ada7e53a1891ffdb8f9bda58260", - "906c0539783bd1d300a0d7cc88331488", - "3c8c1dca210cebcc04ba2b53eb08aca793238119a69959201803541061d90ae9", + "d0c60d8c1aa3097d936f40350f5a027010bb387992b0f3db859899f0fa3800af", + "01", + "57a3cd584cc4d551", + "15b80faaa193e1e33c17d7ffe94b64ea", + "9f6a4699db01c1e341077cf659af341d", + "5ddc9c4e8e0df85cfa67d99d384547059d05343e3dbffc355298d778a16e3b66", + "01", "01" ] } }, - "max_gas_amount": "9206564620883451925", - "gas_unit_price": "3700298311803824370", - "expiration_timestamp_secs": "7911132546571793726", - "chain_id": 1 + "max_gas_amount": "12163981542360528951", + "gas_unit_price": "14765093712408029964", + "expiration_timestamp_secs": "11114357721146404348", + "chain_id": 157 + }, + "signed_txn_bcs": "c9166424e69ff945aa011afbaf8712db99a0e54ec2717afcfe69fb2933e97035459913b6b644a9ef0285b6a3fcf3501e417bd8ad99c1764c4a9a913fb6453bab6e03ac373fd96c9b0326636f4d73436a5a5276484875464c4853624e426d71516d526976534a70495641335f436f696e13574a695a7546496a6c724a647744756c6f7034040723d56d1b65fd2f9a61b254e03e116ea56ab97e2ae4779d35a7a416c9296bc1621d6f5554704849586d6142547642726a5a5a6a454d65506e774e7a486d7903514d360007cc71c78506ecaa580e10ddaf549c95bed2709d4890f8f1362637fae4c867c9d712627779446967736b6a7441694a666b4857371468464f78464d4d674b76586459697670656e4f53000730993d2a18cdadcd308c7cf9281b6af44068c1c0e65d215f2ea4b1dfd3dcfa8e0e496741414d786c55415a4d474b4f157970506e446b6f6e5a64584c734d6a7470654e5332000607f9b0441b7b6347cee0f0657ed796b1fe948b76a9cf7071c2cf5c4f5df010116410657a4c59674d465861706d4f4d72614d0465714932000820d0c60d8c1aa3097d936f40350f5a027010bb387992b0f3db859899f0fa3800af01010857a3cd584cc4d5511015b80faaa193e1e33c17d7ffe94b64ea109f6a4699db01c1e341077cf659af341d205ddc9c4e8e0df85cfa67d99d384547059d05343e3dbffc355298d778a16e3b660101010137b8cee6c324cfa80c2b6fab8026e8ccfc2d8d0376213e9a9d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444027785b74f5ccba50ebf891f365c2f1335d50bd5db158c72ea097751c07aa6fe3f94692383b70ed5d32ee8b853df6300a2d55c036a757659a184afb85c998b207", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "bb4c0f670be7aa9717e8547036b31e489950632ff2043a7696b92aea3fe5610c", + "sequence_number": "6453282049904902343", + "payload": { + "EntryFunction": { + "module": { + "address": "72850c2d70ec6454e91948351689ca952f0c46fc6739f6adf6cea918b938d5cb", + "name": "obngthmKtrYvT2_Coin" + }, + "function": "hFwbgQpvkYCqC6", + "ty_args": [], + "args": [ + "01", + "01", + "82" + ] + } + }, + "max_gas_amount": "10181911510354079584", + "gas_unit_price": "833200967485478358", + "expiration_timestamp_secs": "10175748302787041689", + "chain_id": 111 }, - "signed_txn_bcs": "d5a49d30d9133f3e16b724f055f042096c569e1d6d30e16d8c5e677ee68f3fa2f911dd44aabe41d6024e8a0bfc982e4a54a3d64d3757f2d58cca12129ec4b4cb359e860abceac1b0131a72436249627478646c414a5a66535575554e6b4e435f436f696e074e476156446b350607bcf6b3d454b77337cff4db962c20a23f3691a28a7e45888d44b254ed63bc28b806484355494e340447634b700006070cfa637d3c772a93a2df9d3557dbbb85bb26c8efe2d15b13b6ba85e1f22f41e2134f41675050525875774e6156574d726e5170371c7849534e794b7654615762624c736d694b64684961684e63487943320006060007e0df5fb8210ef562af7b0438329efab0b8ef1bd5c39014f0f7d1698584901fbd0153185859646f4972457a4b727543597a48654941706d73526952000742ae20cfdc98ebf5291e30c25b1ca4d87c2e9c8b19583bd80e0e68b57f16996221576d584d55794356686e6a677351797077506a6469705070624758516c574e61381b4b4b7746684968654679615a75467747756f496e7679647942657000072730376d1b27bad9dee8fb8932fd82ead9ed293e7714f464e1f763268105b3670d586b456b5a6c514e724b6557471776464b645a6250597a446f7661796c6572636a6e436945000410cfdc9ada7e53a1891ffdb8f9bda5826010906c0539783bd1d300a0d7cc88331488203c8c1dca210cebcc04ba2b53eb08aca793238119a69959201803541061d90ae9010115e06f85be49c47ff2680ba6b5195a333e7571d922fdc96d01002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400c4088eb433e4e0ad75126a9161f6878c51c9e367c9fcb64543c10d227318e1aba5e338a66d6ef4c123476d014a9caca1bd3a9527267e1021440717f769b2802", + "signed_txn_bcs": "bb4c0f670be7aa9717e8547036b31e489950632ff2043a7696b92aea3fe5610cc780fc5bd5a98e590272850c2d70ec6454e91948351689ca952f0c46fc6739f6adf6cea918b938d5cb136f626e6774686d4b7472597654325f436f696e0e68467762675170766b5943714336000301010101018260af1d95926a4d8dd6d57b8ddd1f900b99d967ff2a85378d6f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c26261e0146341b5b7ba198cee21d3ea928f28ab5f83b06d59090ea0e506b679465e2155fd99ef5753181b21693d562368042bcd3e86021e6aaa5e56d1a0e601", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "bd4c462ed728b02c397d164233843798c5642043aa172a22e767b5be9e6653fd", - "sequence_number": "11845293532130120585", + "sender": "118d4a6c93414571f691198f0d12db5beabc20033850dadf25524a1e56c932ef", + "sequence_number": "11566724955845481078", "payload": { "EntryFunction": { "module": { - "address": "6176ed9dcfb921a3216cf549ac74529efdbd7c1b8099c1fd115772b85d0beed4", - "name": "JFImCdAwzEuiw8_Coin" + "address": "8cefec8c2965bf886c57b4c8da4940f36c4fbc1b3da1dcc6fecf0762d1b4d5c9", + "name": "vgSkXRCfmzihhjpiaHmgyspYwObo2_Coin" }, - "function": "VBVjevXdaELQaSSU", + "function": "KrUdcAPssHEWqRTBja2", "ty_args": [ { "vector": { - "vector": "address" - } - }, - { - "vector": { - "vector": "u8" - } - }, - { - "struct": { - "address": "4cf37dd5915368719924f2fee04f0539db16fd30992e6b200dde8be52621e382", - "module": "SUqpXvVKyvkKTt2", - "name": "MOAKQjzPvhWsgWG", - "type_args": [] + "struct": { + "address": "a3b25c3d1173d9e338537d2fcffb131ac9c7d01eadb657cd4fc84f489248d879", + "module": "UrgLXAsRxjhBZDnfhmYabMJt3", + "name": "Ujj", + "type_args": [] + } } }, { "vector": { "struct": { - "address": "5ba469c77457646b0646105582c80c1ca908afd8bf45597300fd2975ca17aa80", - "module": "ZInMTnhpVJQclqYqtkte5", - "name": "agMfiaqrcYrFNa", + "address": "01fa5e8bda469e1e1b5459bcd7af60c03aedac73929857cdd2e843f10245a619", + "module": "NnrbHbVXMt", + "name": "JgPNnVW6", "type_args": [] } } }, { "struct": { - "address": "2b3914d54f345bec8bb0ba0f841778d46d46bad3c7dfa5e4788ff8b19aac3e43", - "module": "bcXDbitZAsEpIgxzCRzuGV", - "name": "rVsQtBdUEDeXHYWVsKfIvPknQBmY4", - "type_args": [] - } - }, - { - "struct": { - "address": "f7965365269b4fad14d50d707e74a101dde1ec7310ec2e6d96ca4ede2b87e19d", - "module": "olZJI0", - "name": "cSkMdVpyohjR0", + "address": "eab93ef6a3f3ef9113c746506966f342e97b3b4eda6e8eefbdfa3ee1c11073c7", + "module": "nrwfnRftigR5", + "name": "AFsAEbCuODmNbQScczArET", "type_args": [] } } ], "args": [ - "64d13c8d2327ae6d8cce0f34a3778bf665a9627f3a3c6a753960e3b5e870fd52", - "7acfe5726e00dd78", - "6c", - "00", - "fb97ed3d15b3168a38db3119dcf2562b", - "b5ce551b4a3d09f629aa1b76fb0cfc4cc3126d18cf91b201e9fd45825d7b3801", - "0f18bb333f2864e5c2fb98ba0c52dfb7", - "9dc7a5291da914adf78a6f24596a6278", - "36c0815c0db1db6d0677bfcff2a430a2", - "e47eb96fb16954100ab67094988214eb" + "6d8fa83b826231b2a44173b7cdf0c57f", + "00" ] } }, - "max_gas_amount": "4985178632606946101", - "gas_unit_price": "13246191027765076139", - "expiration_timestamp_secs": "7949440090373165906", - "chain_id": 76 + "max_gas_amount": "7303608381061446115", + "gas_unit_price": "13274416015632612760", + "expiration_timestamp_secs": "12986023075089194371", + "chain_id": 204 }, - "signed_txn_bcs": "bd4c462ed728b02c397d164233843798c5642043aa172a22e767b5be9e6653fd8913d95ab5ef62a4026176ed9dcfb921a3216cf549ac74529efdbd7c1b8099c1fd115772b85d0beed4134a46496d436441777a45756977385f436f696e105642566a6576586461454c516153535506060604060601074cf37dd5915368719924f2fee04f0539db16fd30992e6b200dde8be52621e3820f535571705876564b79766b4b5474320f4d4f414b516a7a50766857736757470006075ba469c77457646b0646105582c80c1ca908afd8bf45597300fd2975ca17aa80155a496e4d546e6870564a51636c715971746b7465350e61674d6669617172635972464e6100072b3914d54f345bec8bb0ba0f841778d46d46bad3c7dfa5e4788ff8b19aac3e4316626358446269745a417345704967787a43527a7547561d72567351744264554544655848595756734b664976506b6e51426d59340007f7965365269b4fad14d50d707e74a101dde1ec7310ec2e6d96ca4ede2b87e19d066f6c5a4a49300d63536b4d645670796f686a5230000a2064d13c8d2327ae6d8cce0f34a3778bf665a9627f3a3c6a753960e3b5e870fd52087acfe5726e00dd78016c010010fb97ed3d15b3168a38db3119dcf2562b20b5ce551b4a3d09f629aa1b76fb0cfc4cc3126d18cf91b201e9fd45825d7b3801100f18bb333f2864e5c2fb98ba0c52dfb7109dc7a5291da914adf78a6f24596a62781036c0815c0db1db6d0677bfcff2a430a210e47eb96fb16954100ab67094988214eb359367c28de92e45ab60e7f48eecd3b75213f1eda415526e4c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409dc65aff0ed00d8a868f8662ca4f63edbafc359c1586d5b4341db2de96ff181939d96fabb1ec46d21f0abcbd4aff7bc25ebc3d49ab6c185643d6c80f06e0cc02", + "signed_txn_bcs": "118d4a6c93414571f691198f0d12db5beabc20033850dadf25524a1e56c932ef76d2d06f104385a0028cefec8c2965bf886c57b4c8da4940f36c4fbc1b3da1dcc6fecf0762d1b4d5c9227667536b585243666d7a6968686a706961486d6779737059774f626f325f436f696e134b7255646341507373484557715254426a6132030607a3b25c3d1173d9e338537d2fcffb131ac9c7d01eadb657cd4fc84f489248d879195572674c58417352786a68425a446e66686d5961624d4a743303556a6a00060701fa5e8bda469e1e1b5459bcd7af60c03aedac73929857cdd2e843f10245a6190a4e6e7262486256584d74084a67504e6e5657360007eab93ef6a3f3ef9113c746506966f342e97b3b4eda6e8eefbdfa3ee1c11073c70c6e7277666e526674696752351641467341456243754f446d4e62515363637a417245540002106d8fa83b826231b2a44173b7cdf0c57f0100e3b9bb5b20a15b6598bd890c093338b8839db7132f9f37b4cc002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404a3718994880432cb46bdaba6310d5f7d866da4757c7920d746bc3a92c4909817be06f4d92594034cbd8b2d4ea24f21cfe4dcec7a0d5a67c1deac1fefd1b5d0c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "24555927c73a0a938a8f4cec3996dceaf37924383bb237e7184a05386b07d352", - "sequence_number": "1376807367105215343", + "sender": "08cca3e6831835945878db45288c595dc9a6b6f3be8ffd071e51bb85a47c6a68", + "sequence_number": "9127392870752029956", "payload": { "EntryFunction": { "module": { - "address": "b41b6572b3350c3b8a007d657090ea490d82026ff2203fb44a373fc11f6d13e6", - "name": "j_Coin" + "address": "d9ae66ab3cc8cf42aa872dc62b468e730bc0a881bf1953a0c0e9fe62e96f5761", + "name": "WZy2_Coin" }, - "function": "yo", + "function": "QzHWIyoJkf6", "ty_args": [ { "vector": { - "struct": { - "address": "cfebdf04927aecd6ecd33041d251a5f132dbc37be6877dff1e9c23df19ad314f", - "module": "AhyhZiERYDyuTXLrKEHnyoBSdAMLfb9", - "name": "KzNUmtiPgsCm", - "type_args": [] + "vector": { + "vector": "u64" } } }, { "struct": { - "address": "432b868bac0617b6687558fe781309beb91e47fe9e8ef7ab455451744d5919d5", - "module": "FWqENxaVECJkHyMaSgdeMkvZhTVDZ9", - "name": "dewqdKBElMfygZsLmMlyM", + "address": "05508a1b2b055007b8046d9c26ab1622d6c2262a75a90d2573a9f43bda3673b5", + "module": "oUgDQmERiuYejDQsaW", + "name": "xS6", "type_args": [] } }, { "struct": { - "address": "f4e988cb1f5d16974f7989dd4e45882d5c2146aed762fe6d9eb590bd6cbb3e9b", - "module": "FSjOBmHJTLmiJynMPKMIE8", - "name": "NuIZ", + "address": "24930ae8450ca8947271623ba78ae9a1c6a5172e91763c8f8b498c9db9d0c6d4", + "module": "rIYjlbcBdAdzV", + "name": "CwCHeCHLhaCGdVctjqXtNdG6", "type_args": [] } }, { "struct": { - "address": "f1f90c0a41d4291c897f3deb0e033ec5e0e1b51a5f1cf7ac53cd96a88182f71b", - "module": "KMfjNsHrNQFRUdBzPuYQciByQ", - "name": "WYFdAJRmkfRcxnCieudysCVXPYr", + "address": "089756c2fce6c14214bd45a1baabf27a37371b581b9d9ddce2f507a18d763823", + "module": "FkEgkuuPOmqvyfdtBKOABsM8", + "name": "SqtTWYZxkA2", "type_args": [] } }, - { - "vector": { - "struct": { - "address": "608a4f1c81926883c2d7dd63ef54523c6ef8f491199180306283bee9138b15bf", - "module": "EXhY", - "name": "ApAnxKdDrmRWnyoHB8", - "type_args": [] - } - } - }, { "struct": { - "address": "8dec53d3fee8411cb86e4a0b348237fad194cae841b78fcba8e607bfe6302641", - "module": "GNydsmDLb", - "name": "yBJIGqgfYqIvmEKBbA4", + "address": "b0c1f657727e59851c46de3479d91297f0da683bb92dc04103a8b83618ac5fd7", + "module": "NdgBVfiRbuvXgqZSaqilhGGKGbkQVDa", + "name": "I", "type_args": [] } }, { "struct": { - "address": "8123b47f7ab0af9d7dac568c3795b89a8bd567893e348bb79e46e89e8edad85c", - "module": "WbqKDdsBalNeRIGGYYYOsBMARZMNNR", - "name": "eT", + "address": "ec9ce14166e2417c771c2911a39ef6e47be80590a4fcdab20635abfb1aff87eb", + "module": "PVritKDrnrrmrVuygh9", + "name": "ytwNfh5", "type_args": [] } }, { "struct": { - "address": "7a62255139eb85adf10f17099ed3d490a69afd188f8b28acfd50c60e67621fde", - "module": "WNynIJlQicFxIgTvJrrsi3", - "name": "XTRArdOhwYSnHDQhQjdnSFEjxS", + "address": "05c1a925c96b8713b4dbe84fac37c2c2b4b6370c8ee701a7f78a505b342c272f", + "module": "OesyQmFPSJTXETJLQpmIHZQg4", + "name": "nonfafRDa2", "type_args": [] } }, { "vector": { - "struct": { - "address": "dd6601a51a6b4e8fbe283d28947d2614031b4ca46494fc7f7992dfbae28141d5", - "module": "egUPEuIRGIMVTKRHLwOFiss1", - "name": "JDWwPpIyFdSonZ", - "type_args": [] + "vector": { + "struct": { + "address": "74a7c8c96a1fe405fbffd17cbaef897889b1d8b1fffffbe7cc001c3f3963ca8a", + "module": "JeSFmhGRudQNvXxdXuKnRmZsa", + "name": "oBQ6", + "type_args": [] + } } } }, { "vector": { - "vector": "u128" + "struct": { + "address": "e2b4fe5eff9cb2ddcd11a49e71d4f43b769bad87e095d855fb8f5911bd3786c7", + "module": "musMSLeICJVjEWEMNiYTeascZZm", + "name": "BsXSYdxDtShyVxOwp7", + "type_args": [] + } } } ], "args": [ - "b4b3b2c77e005ea95e85b0e7556aa132947b1cca6fee05596ee19f218b00cb32", - "89", - "a7f9495a34070bd3d48cb3047d45a357", "00", - "28e7baf5519e67472880af3d61ef8bf05dc568ae47eacd72198aa744555e3d1b", - "f9490db31b8e6f8d3590d8e97fad1466e798b1286e2ce3d0833def2c920a4c61", - "474c050ecf230611deec92b5a5201574", - "7e", - "01" + "f8d9cf68fa0f4875" ] } }, - "max_gas_amount": "1343955921040667317", - "gas_unit_price": "1554507090856542603", - "expiration_timestamp_secs": "1938967014672769545", - "chain_id": 65 + "max_gas_amount": "1496721602515314109", + "gas_unit_price": "5861327224961934685", + "expiration_timestamp_secs": "8536129913379145190", + "chain_id": 198 }, - "signed_txn_bcs": "24555927c73a0a938a8f4cec3996dceaf37924383bb237e7184a05386b07d3526f7b727801671b1302b41b6572b3350c3b8a007d657090ea490d82026ff2203fb44a373fc11f6d13e6066a5f436f696e02796f0a0607cfebdf04927aecd6ecd33041d251a5f132dbc37be6877dff1e9c23df19ad314f1f416879685a6945525944797554584c724b45486e796f425364414d4c6662390c4b7a4e556d7469506773436d0007432b868bac0617b6687558fe781309beb91e47fe9e8ef7ab455451744d5919d51e465771454e78615645434a6b48794d61536764654d6b765a685456445a391564657771644b42456c4d6679675a734c6d4d6c794d0007f4e988cb1f5d16974f7989dd4e45882d5c2146aed762fe6d9eb590bd6cbb3e9b1646536a4f426d484a544c6d694a796e4d504b4d494538044e75495a0007f1f90c0a41d4291c897f3deb0e033ec5e0e1b51a5f1cf7ac53cd96a88182f71b194b4d666a4e7348724e5146525564427a5075595163694279511b57594664414a526d6b665263786e43696575647973435658505972000607608a4f1c81926883c2d7dd63ef54523c6ef8f491199180306283bee9138b15bf0445586859124170416e784b6444726d52576e796f48423800078dec53d3fee8411cb86e4a0b348237fad194cae841b78fcba8e607bfe630264109474e7964736d444c621379424a4947716766597149766d454b4262413400078123b47f7ab0af9d7dac568c3795b89a8bd567893e348bb79e46e89e8edad85c1e5762714b44647342616c4e65524947475959594f73424d41525a4d4e4e5202655400077a62255139eb85adf10f17099ed3d490a69afd188f8b28acfd50c60e67621fde16574e796e494a6c5169634678496754764a72727369331a5854524172644f687759536e48445168516a646e5346456a7853000607dd6601a51a6b4e8fbe283d28947d2614031b4ca46494fc7f7992dfbae28141d518656755504575495247494d56544b52484c774f46697373310e4a445777507049794664536f6e5a000606030920b4b3b2c77e005ea95e85b0e7556aa132947b1cca6fee05596ee19f218b00cb32018910a7f9495a34070bd3d48cb3047d45a35701002028e7baf5519e67472880af3d61ef8bf05dc568ae47eacd72198aa744555e3d1b20f9490db31b8e6f8d3590d8e97fad1466e798b1286e2ce3d0833def2c920a4c6110474c050ecf230611deec92b5a5201574017e0101b5726923cab0a6128b815487f6b792150922c50c3a98e81a41002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404f86d71f451392ef54e1f9e316394695d16fb75c855ff6d77047fcee070fe95b723900bfab8b3494a9d609e917afdd4efa01f2a769a10bee834ce25eaad1c308", + "signed_txn_bcs": "08cca3e6831835945878db45288c595dc9a6b6f3be8ffd071e51bb85a47c6a68048d9bfa7403ab7e02d9ae66ab3cc8cf42aa872dc62b468e730bc0a881bf1953a0c0e9fe62e96f576109575a79325f436f696e0b517a485749796f4a6b663609060606020705508a1b2b055007b8046d9c26ab1622d6c2262a75a90d2573a9f43bda3673b5126f556744516d4552697559656a445173615703785336000724930ae8450ca8947271623ba78ae9a1c6a5172e91763c8f8b498c9db9d0c6d40d7249596a6c6263426441647a5618437743486543484c68614347645663746a7158744e6447360007089756c2fce6c14214bd45a1baabf27a37371b581b9d9ddce2f507a18d76382318466b45676b7575504f6d717679666474424b4f4142734d380b5371745457595a786b41320007b0c1f657727e59851c46de3479d91297f0da683bb92dc04103a8b83618ac5fd71f4e646742566669526275765867715a536171696c6847474b47626b5156446101490007ec9ce14166e2417c771c2911a39ef6e47be80590a4fcdab20635abfb1aff87eb1350567269744b44726e72726d72567579676839077974774e666835000705c1a925c96b8713b4dbe84fac37c2c2b4b6370c8ee701a7f78a505b342c272f194f657379516d4650534a545845544a4c51706d49485a5167340a6e6f6e666166524461320006060774a7c8c96a1fe405fbffd17cbaef897889b1d8b1fffffbe7cc001c3f3963ca8a194a6553466d6847527564514e7658786458754b6e526d5a7361046f425136000607e2b4fe5eff9cb2ddcd11a49e71d4f43b769bad87e095d855fb8f5911bd3786c71b6d75734d534c6549434a566a4557454d4e695954656173635a5a6d1242735853596478447453687956784f7770370002010008f8d9cf68fa0f4875bd2594155e6cc5145da52e740e9e5751e6c58c0bee6c7676c6002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a301a5fb7ec09136dd3479ad039cbacfa810c59c8582dda28bd3d2464d9ffaf9dde2b5226d5b15f2e17b2990de8f291bdecbf0c07d56db6497459c2afe86020b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "42ed563cf7d8de375ab586013640e5ec0c556d2d901a703ad2dc84f6ef4306a9", - "sequence_number": "13308712221981273264", + "sender": "40d15ef04d926a127deb574aef4fa645c3a72f6f3b81c1fc987b1b70f90fa656", + "sequence_number": "17577631904513889653", "payload": { "EntryFunction": { "module": { - "address": "f548740496df955a20f1d7e1a216a858db24737175b0f1b966a6b23840e97044", - "name": "DAqaGyIZkLwONvVhcdWUodLYAmLRKGZf5_Coin" + "address": "7d1e1a28e905fe4c3f616c013016eca4e0b80ae5832b79a25541f5a550919723", + "name": "MLCuaCwZLQqi_Coin" }, - "function": "unAjqbqse", + "function": "DLbAKcFApENdmqBvfxzdYpsvznl5", "ty_args": [ { "vector": { - "vector": "u128" + "vector": "address" + } + }, + { + "struct": { + "address": "882dadcf627059770fe01bad69a122506a3c77de79dc8480b7c4d4d5711d4730", + "module": "FIrBucmzVUJrosyyTmc", + "name": "CCNRndPJwwKiPJnStENMjMtPLuHf", + "type_args": [] + } + }, + { + "vector": { + "vector": { + "struct": { + "address": "0b810face7fd3b08bcf9128fe96dbd30486ccc2090d7c60ce089c7ce712ef91a", + "module": "WxxzPKQrBqtqKJ2", + "name": "EQlyLdxtm", + "type_args": [] + } + } + } + }, + { + "struct": { + "address": "538036f6e2871d6cb2619c25994129a0506cd6ca11b28753879c0835f6000458", + "module": "tXbybiJRaMcugptutiGFlc", + "name": "tCgblAn3", + "type_args": [] + } + }, + { + "vector": { + "vector": { + "struct": { + "address": "80dfb5ae095d2c2801cc39b0a3b6ad344b3307aa227be2756076d698e9264ee5", + "module": "akrpvghtwbvNchgTjblwaROBT4", + "name": "eRiaUSNBwPRCYZ3", + "type_args": [] + } + } } }, { "vector": { "struct": { - "address": "4f848a5c37546b64a16d2b31e2ea80c206c941aeea0d35275c91bbc8e65933b4", - "module": "iTejDUHpj3", - "name": "nFyszxxawlGFJSBjGHrtjnXwvxqmHg0", + "address": "654dbd4d23f6e407159b3a6d9115d32f95215621c51ee2528ee9293624743db1", + "module": "jJ", + "name": "vsEHXeYqAQUolBOEkdVYngOomETyNji", "type_args": [] } } } ], "args": [ - "26cfa2bc3482e92dffbe03fb0ea18f03", - "0fc86437a60e433358b084c97fedaf8a", - "00" + "01", + "3062ec6e489bbbc2054964af945497ac" ] } }, - "max_gas_amount": "12695207949733120140", - "gas_unit_price": "15749846802159546298", - "expiration_timestamp_secs": "8716299144477001698", - "chain_id": 70 + "max_gas_amount": "5897866893466189851", + "gas_unit_price": "10500791076102577215", + "expiration_timestamp_secs": "11816105298633330157", + "chain_id": 8 }, - "signed_txn_bcs": "42ed563cf7d8de375ab586013640e5ec0c556d2d901a703ad2dc84f6ef4306a9b0ec17d9400bb2b802f548740496df955a20f1d7e1a216a858db24737175b0f1b966a6b23840e9704426444171614779495a6b4c774f4e765668636457556f644c59416d4c524b475a66355f436f696e09756e416a71627173650206060306074f848a5c37546b64a16d2b31e2ea80c206c941aeea0d35275c91bbc8e65933b40a6954656a445548706a331f6e4679737a787861776c47464a53426a474872746a6e58777678716d48673000031026cfa2bc3482e92dffbe03fb0ea18f03100fc86437a60e433358b084c97fedaf8a01008cc88e415e702eb0baaf8a6538b292dae2c79716e483f67846002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f5fef41fabcdbd9e0d91eba828f3730a43fb3d44e037d24c24d23fdac49472247ddadd2e6c74550adf19f81cc3853d587cd702f70352ac0ca47387e37314880b", + "signed_txn_bcs": "40d15ef04d926a127deb574aef4fa645c3a72f6f3b81c1fc987b1b70f90fa65675951f3d164bf0f3027d1e1a28e905fe4c3f616c013016eca4e0b80ae5832b79a25541f5a550919723114d4c43756143775a4c5171695f436f696e1c444c62414b63464170454e646d71427666787a64597073767a6e6c350606060407882dadcf627059770fe01bad69a122506a3c77de79dc8480b7c4d4d5711d4730134649724275636d7a56554a726f737979546d631c43434e526e64504a77774b69504a6e5374454e4d6a4d74504c754866000606070b810face7fd3b08bcf9128fe96dbd30486ccc2090d7c60ce089c7ce712ef91a0f5778787a504b5172427174714b4a320945516c794c6478746d0007538036f6e2871d6cb2619c25994129a0506cd6ca11b28753879c0835f6000458167458627962694a52614d637567707475746947466c6308744367626c416e330006060780dfb5ae095d2c2801cc39b0a3b6ad344b3307aa227be2756076d698e9264ee51a616b7270766768747762764e636867546a626c7761524f4254340f6552696155534e4277505243595a33000607654dbd4d23f6e407159b3a6d9115d32f95215621c51ee2528ee9293624743db1026a4a1f76734548586559714151556f6c424f456b6456596e674f6f6d4554794e6a6900020101103062ec6e489bbbc2054964af945497ac1bc096fdb06ed9513f9caf1fd94dba91ed8da6292a3dfba308002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440385c5e212c8ad6c9bd3d1e4311b8d31222904e95d133e6e7f7fd68d12c0fdc991e31b83f085ae82b73a5776ea717894424a21b31da329f4018c947f6cab6e406", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "d2bc24b0f019b2b82ebb1f9fb92617526626952d1ac2472ba1aaa4491b323cb3", - "sequence_number": "4211736428245228250", + "sender": "b13d2e3db8e0541f8b85e84d797ae2c18d09a04af48835393ac2bd78c12290c2", + "sequence_number": "10873594142851988359", "payload": { "EntryFunction": { "module": { - "address": "2b3e987c6c6a4c9674d36208082c1cd1c0b056a2a2a6b9ee9c2737895cd3a895", - "name": "MNmbLHAVwlbneu3_Coin" + "address": "ac4f98ac27f32a1df3ae0ee731311ef97a6e3c9f4deedbb24a7d46240705d2b9", + "name": "pAfneD3_Coin" }, - "function": "LZZhGMzzFoSrxftt8", - "ty_args": [ - { - "vector": { - "struct": { - "address": "9eb96b3824bcce2dab78f474c257cf886f128025433a702d6950f21325483c82", - "module": "XpADI", - "name": "gOlzjUtqJc", - "type_args": [] - } - } - } - ], + "function": "BkKTlZIHsXlwcpfuFQ", + "ty_args": [], "args": [ - "27df94f48ef84a958734d707dac0b875", - "e2690de2bb8285a5", - "55", - "00", - "c3a9edea62dedd56e1e9b2aa7fc3b25bc96e4b7e3af938e19ae9740aa4366705", - "00", - "01", - "30" + "0a", + "d01bc3d91d958a0b130fd14d32ff300e95d8bf535000de174f1dcc6dc183f781", + "89be9a9d1d81d486", + "e0c3ab969e0d6306d26edbe527a704f4ef29f2dbb0300dd805f5d2bbb1705f6a", + "6e12d5d340f2c7c20fa14df2c8fc04f4", + "09" ] } }, - "max_gas_amount": "15188451962748323527", - "gas_unit_price": "1643726718602092844", - "expiration_timestamp_secs": "331084826812339556", - "chain_id": 94 + "max_gas_amount": "14741512601017041932", + "gas_unit_price": "16679536404755377091", + "expiration_timestamp_secs": "7373462436341996817", + "chain_id": 67 }, - "signed_txn_bcs": "d2bc24b0f019b2b82ebb1f9fb92617526626952d1ac2472ba1aaa4491b323cb3da1a217df717733a022b3e987c6c6a4c9674d36208082c1cd1c0b056a2a2a6b9ee9c2737895cd3a895144d4e6d624c484156776c626e6575335f436f696e114c5a5a68474d7a7a466f537278667474380106079eb96b3824bcce2dab78f474c257cf886f128025433a702d6950f21325483c820558704144490a674f6c7a6a5574714a6300081027df94f48ef84a958734d707dac0b87508e2690de2bb8285a50155010020c3a9edea62dedd56e1e9b2aa7fc3b25bc96e4b7e3af938e19ae9740aa4366705010001010130c7c6b2979638c8d22ca118e2bdb0cf1664d5ab54e53f98045e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444091e51e51711745361a083c22d6c3b4e23ada0481cf711b9a4471a14ed70af742d7a0478a05a14078118a9a137b2e72d18f817f7ad476c164880b5f970e226506", + "signed_txn_bcs": "b13d2e3db8e0541f8b85e84d797ae2c18d09a04af48835393ac2bd78c12290c287fb751c43c4e69602ac4f98ac27f32a1df3ae0ee731311ef97a6e3c9f4deedbb24a7d46240705d2b90c7041666e6544335f436f696e12426b4b546c5a494873586c776370667546510006010a20d01bc3d91d958a0b130fd14d32ff300e95d8bf535000de174f1dcc6dc183f7810889be9a9d1d81d48620e0c3ab969e0d6306d26edbe527a704f4ef29f2dbb0300dd805f5d2bbb1705f6a106e12d5d340f2c7c20fa14df2c8fc04f401090cc490539b5f94ccc3eba3f7fc9d79e711ddd90205cd536643002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444093368d2f3217473f6261ffa7cd6d61d9b1d7529429d6034e6a88e625f0bea4832f1ee4bacc947f51126b3de090dc0cfef0ee01f15d177e14683ee6b90e33a806", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "f529681e812425ef7ff1181614127bfd0d44cbc2c9de3c97379ba3cab58e69c6", - "sequence_number": "6188140359364258365", + "sender": "d1e56e7fc34202535a6d7532b21c4689470dd961fcfc5c637c2a61e6cbb8ca96", + "sequence_number": "2046370809621826751", "payload": { "EntryFunction": { "module": { - "address": "6f0c3212072e8b9101f423b113c9a5fec394316b9b9e38c85b9520da8d5982b9", - "name": "oS_Coin" + "address": "286df04220939f8a5433a337fd38912f5024022ed1e8f2bc1862f4dad2ba0fd3", + "name": "FaM7_Coin" }, - "function": "UIyiNLs", + "function": "nUVrtSuXitzoCjgduuKR9", "ty_args": [ { - "vector": "bool" + "struct": { + "address": "71dcccd79e40cdf048e8e19181e4209f836a4b9b104ccc9e01aef2c568bcde26", + "module": "MvCrodIJmaKenjTqDtkvzrXQDefZYcd", + "name": "ceJwqQyKGiJFYwpZQytbpjhHLfX1", + "type_args": [] + } }, { "struct": { - "address": "faa6772651e726fd538aa2ec247b1abe00eabe5bd2204e4306fe55c60ffe365e", - "module": "JESk", - "name": "CYiMhFlLuryMezloEGbYIJYuLkmkbHUO7", + "address": "f810435df41b418fda3ea6d4dd5aa1a3326be052568379696abcde21b3e72d29", + "module": "suCyyzQbtzKDXWmsqhhq8", + "name": "BzGlwFtX6", "type_args": [] } }, { "struct": { - "address": "2ecb72480ba3bdc2eccd3d7995e4fd9c72aa5e6aa0fed2ce251a2c4efe91dfb0", - "module": "TumAyURkVdU", - "name": "PrWvwxiFgOVxniIqDGvaMgIQKYmp", + "address": "079615fbb04d03bb19b47c19ff6cc868fdea83d3682acbb8ed399180a6ce0188", + "module": "xILabrjsvvaU", + "name": "eznGxSCLzHQJDxlpgSwMbYWfViTa5", "type_args": [] } }, { "struct": { - "address": "73581947cd9aae0edf44a748124136c5a4ba496fae367516508014c599c6187e", - "module": "upKIsrqPOGNgMBqgvFjTaXUxaYTRZzd", - "name": "UddbjIiyxzrkCoGfcFMrDzWPWb", + "address": "7807297e8d7d93dcb5edfe984276d32daf79dc5df11e56b9a309f1478aa5f656", + "module": "KKSHxBNrDvUZwqxic9", + "name": "sxafwjwZJFbNjYTgAtiIVqoMTpCCFi9", "type_args": [] } }, { "struct": { - "address": "8eb6b83d5e43cf46b004d04bb6f0e6f58bbcd236644b6e3abe642d5dc7ce1352", - "module": "wjbGDsSnvCNbKqr6", - "name": "qRH", + "address": "680d6b94d6e4db59c4429af17d2b26cdf3ef6ded4ff2c84e2bb6bb318dc9e957", + "module": "kxFiOvTSfNXTfvjI", + "name": "DnwDogNepHkazEMxjJSxvYIQi", "type_args": [] } + }, + { + "vector": { + "struct": { + "address": "bee3bb090a1f09f43aa41f6e7084eca4559f540fcb5ef4ee01994f79739a8303", + "module": "P2", + "name": "vFzYNbRNJX", + "type_args": [] + } + } + }, + { + "vector": { + "vector": { + "vector": "u8" + } + } + }, + { + "vector": { + "vector": "u128" + } } ], "args": [ - "d49b480b39c513752ed949578a45cb04be4ce3a2f32e741e5dce2f74413b26b9", - "c65e6a7b03bcd4559c9fa58be4884d9417004126cb47b7b7e4c05e7977b45b29", - "c04022a5d3dc9f6d", - "01", - "601718e49ea508216e847725786b115d37ae941924e7148e943d2c83b0c0d395" + "88", + "b472e11751d58735cb5d87fa65283eb03a6b9780286fe47730cdf24381f83183", + "61cdac66654a209fe3de09768fd0d64e", + "9ecd0ea060dc1456", + "170fdd29538d50f53e1653948e746d8060e246a7ad68411364d3141f2a8206d0", + "4a1ae182ace4bff95b201f7d2de27b03c06fb5f32e370a10ccd29ebf459cd7c8", + "16ef156773b75c4f" ] } }, - "max_gas_amount": "7323667094198240433", - "gas_unit_price": "9466671185694131136", - "expiration_timestamp_secs": "13224356982163801046", - "chain_id": 70 + "max_gas_amount": "17653232582407812613", + "gas_unit_price": "16759295553845889652", + "expiration_timestamp_secs": "6075588763469599562", + "chain_id": 7 }, - "signed_txn_bcs": "f529681e812425ef7ff1181614127bfd0d44cbc2c9de3c97379ba3cab58e69c63d2a2ae4deb0e055026f0c3212072e8b9101f423b113c9a5fec394316b9b9e38c85b9520da8d5982b9076f535f436f696e07554979694e4c7305060007faa6772651e726fd538aa2ec247b1abe00eabe5bd2204e4306fe55c60ffe365e044a45536b214359694d68466c4c7572794d657a6c6f45476259494a59754c6b6d6b6248554f3700072ecb72480ba3bdc2eccd3d7995e4fd9c72aa5e6aa0fed2ce251a2c4efe91dfb00b54756d417955526b5664551c5072577677786946674f56786e694971444776614d6749514b596d70000773581947cd9aae0edf44a748124136c5a4ba496fae367516508014c599c6187e1f75704b49737271504f474e674d42716776466a5461585578615954525a7a641a556464626a496979787a726b436f476663464d72447a5750576200078eb6b83d5e43cf46b004d04bb6f0e6f58bbcd236644b6e3abe642d5dc7ce135210776a62474473536e76434e624b71723603715248000520d49b480b39c513752ed949578a45cb04be4ce3a2f32e741e5dce2f74413b26b920c65e6a7b03bcd4559c9fa58be4884d9417004126cb47b7b7e4c05e7977b45b2908c04022a5d3dc9f6d010120601718e49ea508216e847725786b115d37ae941924e7148e943d2c83b0c0d395b144e7726be4a265c083b96c495f6083d683d4109c5a86b746002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440adacf592d3eead46a54c131908c1d3a63827e0428930054025377de4517c72ddc6ea6b7111ffa314dbb9e90fa075aee49595ee0a5eae3434ee61fe90c56ec20b", + "signed_txn_bcs": "d1e56e7fc34202535a6d7532b21c4689470dd961fcfc5c637c2a61e6cbb8ca96bfcc3cc2682b661c02286df04220939f8a5433a337fd38912f5024022ed1e8f2bc1862f4dad2ba0fd30946614d375f436f696e156e5556727453755869747a6f436a676475754b5239080771dcccd79e40cdf048e8e19181e4209f836a4b9b104ccc9e01aef2c568bcde261f4d7643726f64494a6d614b656e6a547144746b767a7258514465665a5963641c63654a777151794b47694a465977705a51797462706a68484c6658310007f810435df41b418fda3ea6d4dd5aa1a3326be052568379696abcde21b3e72d291573754379797a5162747a4b4458576d73716868713809427a476c77467458360007079615fbb04d03bb19b47c19ff6cc868fdea83d3682acbb8ed399180a6ce01880c78494c6162726a73767661551d657a6e477853434c7a48514a44786c706753774d62595766566954613500077807297e8d7d93dcb5edfe984276d32daf79dc5df11e56b9a309f1478aa5f656124b4b534878424e724476555a7771786963391f73786166776a775a4a46624e6a5954674174694956716f4d547043434669390007680d6b94d6e4db59c4429af17d2b26cdf3ef6ded4ff2c84e2bb6bb318dc9e957106b7846694f765453664e585466766a4919446e77446f674e6570486b617a454d786a4a53787659495169000607bee3bb090a1f09f43aa41f6e7084eca4559f540fcb5ef4ee01994f79739a83030250320a76467a594e62524e4a58000606060106060307018820b472e11751d58735cb5d87fa65283eb03a6b9780286fe47730cdf24381f831831061cdac66654a209fe3de09768fd0d64e089ecd0ea060dc145620170fdd29538d50f53e1653948e746d8060e246a7ad68411364d3141f2a8206d0204a1ae182ace4bff95b201f7d2de27b03c06fb5f32e370a10ccd29ebf459cd7c80816ef156773b75c4f05f6c4bb80e1fcf4748ac4fc82fa94e84ad3f55fcad3505407002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406142e3e09dbc0cb612cb50a0356766dad6d8ccd0ce6135aecea873398064df335a29acd84c7ca90e46dfd6499b228b1a9fb6060c54cab21354afb3a90ebd760a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "96c11e9d896f174f0315513049d4822767df0f1616142d7eca104b1d78ceceff", - "sequence_number": "11559191383198427281", + "sender": "81133450ae78d10f2a992fde2c7f36ef4dec9add7a3b1fc7bb89f7ce9cdb9220", + "sequence_number": "15029474211003710184", "payload": { "EntryFunction": { "module": { - "address": "53469100bcfc213d42f24288e08b6a5143e43d1f228566ce671e90e1a4df17b0", - "name": "Lbb_Coin" + "address": "cb76a7fe304272b711c7f43bdef8f9a6cc7e11ae0c3671abaf17e3bee73bdd27", + "name": "TflmkLMbgiLqKaLDWqHLVb8_Coin" }, - "function": "gGgayA", + "function": "VHVl6", "ty_args": [ { "struct": { - "address": "e274060106cd8f4c8f6b9437861f8b9c8a646bd6692cad99806ce67a24afda5c", - "module": "LXl", - "name": "wuzxvWYAKcvQMGgXTQfilGXhcDtJwtWN", + "address": "8d5251fdfe6f20707fcadd12cd4ad7f999a682bb019f4af86cbb6fb871dc4d2c", + "module": "fPAgZdUzyFEATRuELCeIjXlUrls5", + "name": "UmSavkxxSaoDedKdIGaYQqIqgcshb", "type_args": [] } }, { - "vector": { - "struct": { - "address": "4b9c754aa38ba008606b7c2e8691de46093190cb4dfea7043db3ac8d831262cd", - "module": "awZkBLMlL3", - "name": "jFoEIAjizmlMgTPfusXNkqeA8", - "type_args": [] - } + "struct": { + "address": "b68e4fc5c2268337918aefa57c60e14a09156444aca0ca0b441ae1ca8447ed76", + "module": "KsTnWq", + "name": "PmQvd", + "type_args": [] } }, { - "struct": { - "address": "d40f8cd435359da4b6356d530fe7121f7e6fea952f62ce697cc879c04b6ec1ad", - "module": "iElxmcNxvMokvHOXLWrbEULmE", - "name": "tRzASqosndJldXnQThJr", - "type_args": [] + "vector": { + "vector": "signer" } }, { "vector": { "vector": { "struct": { - "address": "cdaa73f986e43d409b5e25cb9ad570d0895cc91ca72a83a474f526cff4aca2f1", - "module": "cpsXwMkWpdaVIaZWDzaTDUiTwcToI4", - "name": "SpCJfgswkSgpdXkfDGysE7", + "address": "bed2635e0cb1f7e72bf40a722b9d992ffb892c943d466fef820eb029849cbdd9", + "module": "oegjW", + "name": "vSMcnTpgDDmUvUuDIPCtYrEczeV7", "type_args": [] } } } }, - { - "struct": { - "address": "b36c9fa416b3ee2602f6c9e214e1477bc1e441a5cab39fdb3f7f10e2c0f8e21b", - "module": "bmrEipOOvzVAcsWTWVUEOfflUUqaFtU", - "name": "wSoRmAwMbjmG5", - "type_args": [] - } - }, { "vector": { "struct": { - "address": "5bb0698e9f5594ddd3be77eebeea8c150d4ab7bf40c663ffaf1e744ab90bd232", - "module": "NQsLVvAXCKNgWx", - "name": "LFOv", + "address": "0a5686e1de3bd319633487163a695ab27ea9b0750a3516805cee8cc02cfdfc73", + "module": "FAhOANFOTjpR", + "name": "H", "type_args": [] } } }, { "struct": { - "address": "3a0b88e0b8dc41ebc4d74f1b2349c950a4b091fbae0eb09f62624f22ef8a4e65", - "module": "npwEw3", - "name": "bojLBrdEyFicYdsyMBZB", + "address": "22dcb28cac70885a6dcc9bfd591eca32255931eb60bcee4b3ef13807e2060d8c", + "module": "lHAkawXUQaNWTIovCKxwNrqzrV", + "name": "LZEmkKROvwJaoqSkliLmSDNVJJPHcjP", "type_args": [] } }, - { - "vector": "signer" - }, { "struct": { - "address": "2a0415a7406192d0a4124bcdb027342d758f81173b97b8515ebbb39ffaacf8c8", - "module": "VTauwkxVeCvWQUROeFJCIRmle", - "name": "LwfbHiQqTwqhzNIptlJslmmBfZdzkG5", + "address": "fffe5b7b904e5605b9d1f2b548b592ce54093516645402a096ae0ea0e67d62f2", + "module": "pVsvVQfbPvx1", + "name": "IJykNT", "type_args": [] } }, { - "vector": { - "struct": { - "address": "9c9bb9958b26b970cb5fdafb149933d724371883b05d302e8a78fc7ac50232eb", - "module": "JjSfrYcEUNNHQzKGLHXD3", - "name": "GKWfza4", - "type_args": [] - } + "struct": { + "address": "93714ab13acd25d571718710336ea3dadb04494a2f56118744fe72241ba1de97", + "module": "HLtKraXORTK1", + "name": "GTiSSKaApmlRPlrjTrnuOL7", + "type_args": [] } } ], "args": [ - "982af3edb8e57732", - "9d474766ccd6da84" + "8a404d169212231eba50dab75619d447", + "26756851b2eb6d70", + "ac1359453b5c89b7e227b099103c7e01", + "3458ef907851a500db640fca47db8b963dab06348ddfa4ce5110b55bbc01eb26", + "bd663ff14fd60185467e653e3801741d73daf8698047d969936603b3ff88cd49", + "00" ] } }, - "max_gas_amount": "2024503265829179028", - "gas_unit_price": "13048994257953207127", - "expiration_timestamp_secs": "14340796864842073462", - "chain_id": 108 + "max_gas_amount": "42646023232644863", + "gas_unit_price": "11010247173556066819", + "expiration_timestamp_secs": "5430664830276812460", + "chain_id": 70 }, - "signed_txn_bcs": "96c11e9d896f174f0315513049d4822767df0f1616142d7eca104b1d78ceceff91684cde517f6aa00253469100bcfc213d42f24288e08b6a5143e43d1f228566ce671e90e1a4df17b0084c62625f436f696e066747676179410a07e274060106cd8f4c8f6b9437861f8b9c8a646bd6692cad99806ce67a24afda5c034c586c2077757a78765759414b6376514d476758545166696c4758686344744a7774574e0006074b9c754aa38ba008606b7c2e8691de46093190cb4dfea7043db3ac8d831262cd0a61775a6b424c4d6c4c33196a466f4549416a697a6d6c4d675450667573584e6b716541380007d40f8cd435359da4b6356d530fe7121f7e6fea952f62ce697cc879c04b6ec1ad1969456c786d634e78764d6f6b76484f584c57726245554c6d451474527a4153716f736e644a6c64586e5154684a7200060607cdaa73f986e43d409b5e25cb9ad570d0895cc91ca72a83a474f526cff4aca2f11e63707358774d6b577064615649615a57447a6154445569547763546f4934165370434a666773776b53677064586b664447797345370007b36c9fa416b3ee2602f6c9e214e1477bc1e441a5cab39fdb3f7f10e2c0f8e21b1f626d724569704f4f767a564163735754575655454f66666c555571614674550d77536f526d41774d626a6d47350006075bb0698e9f5594ddd3be77eebeea8c150d4ab7bf40c663ffaf1e744ab90bd2320e4e51734c56764158434b4e675778044c464f7600073a0b88e0b8dc41ebc4d74f1b2349c950a4b091fbae0eb09f62624f22ef8a4e65066e707745773314626f6a4c4272644579466963596473794d425a42000605072a0415a7406192d0a4124bcdb027342d758f81173b97b8515ebbb39ffaacf8c81956546175776b7856654376575155524f65464a4349526d6c651f4c77666248695171547771687a4e4970746c4a736c6d6d42665a647a6b47350006079c9bb9958b26b970cb5fdafb149933d724371883b05d302e8a78fc7ac50232eb154a6a536672596345554e4e48517a4b474c4858443307474b57667a6134000208982af3edb8e57732089d474766ccd6da8494ce5d76fe7a181c57b3691d245717b57685f28cc4be04c76c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f3bdfe0a07fb0d252271c80f05c27240ebe0da78d4814b780ff2e9029d8c3b12dc669feb497979bce0bd4bd1feec5315dfcb038dba4544542df513d00c59530c", + "signed_txn_bcs": "81133450ae78d10f2a992fde2c7f36ef4dec9add7a3b1fc7bb89f7ce9cdb9220e83ac5532a6b93d002cb76a7fe304272b711c7f43bdef8f9a6cc7e11ae0c3671abaf17e3bee73bdd271c54666c6d6b4c4d6267694c714b614c445771484c5662385f436f696e055648566c3608078d5251fdfe6f20707fcadd12cd4ad7f999a682bb019f4af86cbb6fb871dc4d2c1c665041675a64557a79464541545275454c4365496a586c55726c73351d556d5361766b787853616f4465644b64494761595171497167637368620007b68e4fc5c2268337918aefa57c60e14a09156444aca0ca0b441ae1ca8447ed76064b73546e577105506d51766400060605060607bed2635e0cb1f7e72bf40a722b9d992ffb892c943d466fef820eb029849cbdd9056f65676a571c76534d636e54706744446d557655754449504374597245637a6556370006070a5686e1de3bd319633487163a695ab27ea9b0750a3516805cee8cc02cfdfc730c4641684f414e464f546a70520148000722dcb28cac70885a6dcc9bfd591eca32255931eb60bcee4b3ef13807e2060d8c1a6c48416b6177585551614e5754496f76434b78774e72717a72561f4c5a456d6b4b524f76774a616f71536b6c694c6d53444e564a4a5048636a500007fffe5b7b904e5605b9d1f2b548b592ce54093516645402a096ae0ea0e67d62f20c70567376565166625076783106494a796b4e54000793714ab13acd25d571718710336ea3dadb04494a2f56118744fe72241ba1de970c484c744b7261584f52544b311747546953534b6141706d6c52506c726a54726e754f4c370006108a404d169212231eba50dab75619d4470826756851b2eb6d7010ac1359453b5c89b7e227b099103c7e01203458ef907851a500db640fca47db8b963dab06348ddfa4ce5110b55bbc01eb2620bd663ff14fd60185467e653e3801741d73daf8698047d969936603b3ff88cd490100ff66dd095582970003da0e357841cc98ac3edbe6e3985d4b46002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444087475046b185276fd453a0d5e3ff21704d676045e12a938404a0b8631d97a8f72096c25a4daae2c2c06b852639e55180ad150279d6dbf193ab390cb4523bd00b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "fbc5a206f7fae90fcf70eea1cda0355e4c9efe0fbe4dc8c9ce4af00514b9b0e3", - "sequence_number": "745648003805177336", + "sender": "e0247736e22af10e5c0d51c6315ad0531a58cbc9fae45362122007426aea0da9", + "sequence_number": "10029122952531535429", "payload": { "EntryFunction": { "module": { - "address": "837bad2a269644dd81a55ccefcd1a980033f5e49f7d0bf4bee868827d76114b2", - "name": "tlGsWMMAFr_Coin" + "address": "84ece6d4652d666f0aa272b9f63dd985c8d172791328d799fb0783862c1555e4", + "name": "AmhcGBkABcVhICJTiEvpTUNecA2_Coin" }, - "function": "gQkhxR", + "function": "EFMBgyWKMuMSEOSodWW1", "ty_args": [ - { - "struct": { - "address": "ac6d1c1d76b444ad094755c6c2d1e2751f5db2a40a2b80736a10a5601afd57db", - "module": "FJYiAqRJvBdnByLnCforvRnAtZJ", - "name": "XLflVtRSndErPr", - "type_args": [] - } - }, - { - "vector": { - "struct": { - "address": "e954e1e55c4a5a81416ea56c225f09850a1c53250d9fec509201014961077839", - "module": "hiWrNQihET", - "name": "QFcCkiXkuMEBTOLcbdLRdDEYtXNINUo5", - "type_args": [] - } - } - }, { "vector": { "struct": { - "address": "6e66f3a95bb8fb2eb6d33c6f1c6bb840267ca2e200daafed30ff5cbaee37adfd", - "module": "htnIYGlqfBlQgotrnLpGm", - "name": "cddsdHoRhYLoNNVONPLub3", + "address": "6b2ca45f532d03ce487367fceb74144c5b796a2ce67357f251e593f9d2ab1bb3", + "module": "WeAImICitwSAv8", + "name": "vtQxQrVpGxUv", "type_args": [] } } }, { "struct": { - "address": "f10b1ca3465fceeaa1fbe244939a56ce0490dd28e6e3492a6cf458394aaeff45", - "module": "tmcLFbxwzmPLrtjpBmeB", - "name": "WtIrDKOHQGJwZSspwQZygYRWCMF", + "address": "b01c45ed5248881e3efd7b91f5c2381ab2c52d09667660ed09ee1d81f80e2744", + "module": "AbAE0", + "name": "djwgORARgPhR", "type_args": [] } - }, - { - "vector": { - "vector": { - "struct": { - "address": "48aa03a7c032eb572c7fed2179a35bf6d309c3e604bd3e6511ad882cb689edc3", - "module": "V0", - "name": "rkw", - "type_args": [] - } - } - } - }, - { - "vector": { - "struct": { - "address": "b16a91b9667bf06025ce699c79470fe70a72376316b70c51f7ce9f89dbdf38c8", - "module": "ncwAaJPcwEmIXiaycHLruAVuWMx", - "name": "GukvNyrZwF", - "type_args": [] - } - } - }, - { - "vector": { - "vector": "address" - } } ], "args": [ - "6a555e0c18e81dd3bb582715f1c0d099" - ] - } - }, - "max_gas_amount": "898980706617675217", - "gas_unit_price": "7210551618278762929", - "expiration_timestamp_secs": "5688830681978596580", - "chain_id": 90 - }, - "signed_txn_bcs": "fbc5a206f7fae90fcf70eea1cda0355e4c9efe0fbe4dc8c9ce4af00514b9b0e3f86549aae812590a02837bad2a269644dd81a55ccefcd1a980033f5e49f7d0bf4bee868827d76114b20f746c4773574d4d4146725f436f696e0667516b6878520707ac6d1c1d76b444ad094755c6c2d1e2751f5db2a40a2b80736a10a5601afd57db1b464a59694171524a7642646e42794c6e43666f7276526e41745a4a0e584c666c567452536e6445725072000607e954e1e55c4a5a81416ea56c225f09850a1c53250d9fec5092010149610778390a686957724e516968455420514663436b69586b754d4542544f4c6362644c526444455974584e494e556f350006076e66f3a95bb8fb2eb6d33c6f1c6bb840267ca2e200daafed30ff5cbaee37adfd1568746e4959476c7166426c51676f74726e4c70476d166364647364486f5268594c6f4e4e564f4e504c7562330007f10b1ca3465fceeaa1fbe244939a56ce0490dd28e6e3492a6cf458394aaeff4514746d634c466278777a6d504c72746a70426d65421b57744972444b4f4851474a775a53737077515a7967595257434d460006060748aa03a7c032eb572c7fed2179a35bf6d309c3e604bd3e6511ad882cb689edc302563003726b77000607b16a91b9667bf06025ce699c79470fe70a72376316b70c51f7ce9f89dbdf38c81b6e637741614a506377456d495869617963484c7275415675574d780a47756b764e79725a77460006060401106a555e0c18e81dd3bb582715f1c0d099d14de08d30d2790cb1a91f627e061164e46cad525dc9f24e5a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440cb0761e15eba801cc3e1ff3b542e2801b8b8e92bbaa2ac5836cf2af34de88d4a6ce3b16a702ba30e031520a7ce1c90525198d6e0cb56de41edcf5a1e15261401", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "30a1daef4d811cd587cf300147af34da5d0b89b1666dfd2eab2e402b63ac805b", - "sequence_number": "2714727452880618199", - "payload": { - "EntryFunction": { - "module": { - "address": "19f437c3b9441a5661367cf398973528c6e8c4eb4b098a91a18587ad76a447da", - "name": "gOBIYGhMdORWvgnY7_Coin" - }, - "function": "FOKmOgYpEBDuGDYw", - "ty_args": [], - "args": [ - "7e5d89badcbb467da497c49c625304d3", - "c5ec47f373dbaec556205a8a2ca4f27318e917a40e6d486f366636f5e38cd326", - "1cf2b84d921e706a", - "9198f94dccb74835" + "7e012218621dbe5e", + "9b", + "5bc9718fe91157d5ad5f835a338a47c8", + "f4", + "ae44011a553e4d89", + "4ca8b119e464fad51fe9cfef3781d50737e78a82c31b32b62047bfcd6cde7411", + "00", + "5f10c514213e7079bd1873f2f5595e65bb6c81f671d2d94924ea9c43d518753e" ] } }, - "max_gas_amount": "1953091393739247917", - "gas_unit_price": "17223638430308449281", - "expiration_timestamp_secs": "10767712634746963016", - "chain_id": 117 + "max_gas_amount": "9051309887105204035", + "gas_unit_price": "13933671736710381225", + "expiration_timestamp_secs": "5244721609848198792", + "chain_id": 4 }, - "signed_txn_bcs": "30a1daef4d811cd587cf300147af34da5d0b89b1666dfd2eab2e402b63ac805bd742f3323ca6ac250219f437c3b9441a5661367cf398973528c6e8c4eb4b098a91a18587ad76a447da16674f42495947684d644f525776676e59375f436f696e10464f4b6d4f67597045424475474459770004107e5d89badcbb467da497c49c625304d320c5ec47f373dbaec556205a8a2ca4f27318e917a40e6d486f366636f5e38cd326081cf2b84d921e706a089198f94dccb748352d51b35146c61a1b013c4dcae5a706ef4804946d97996e9575002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409ead5895864296bf22c805683a4890813f6b35260e12bc4aa26cb8631c595c990576861cf676cbc02d2adf117630666bb5faa1470583962ec77d0f1759a9030c", + "signed_txn_bcs": "e0247736e22af10e5c0d51c6315ad0531a58cbc9fae45362122007426aea0da945e65b52309a2e8b0284ece6d4652d666f0aa272b9f63dd985c8d172791328d799fb0783862c1555e420416d686347426b414263566849434a546945767054554e656341325f436f696e1445464d426779574b4d754d53454f536f645757310206076b2ca45f532d03ce487367fceb74144c5b796a2ce67357f251e593f9d2ab1bb30e576541496d4943697477534176380c7674517851725670477855760007b01c45ed5248881e3efd7b91f5c2381ab2c52d09667660ed09ee1d81f80e27440541624145300c646a77674f524152675068520008087e012218621dbe5e019b105bc9718fe91157d5ad5f835a338a47c801f408ae44011a553e4d89204ca8b119e464fad51fe9cfef3781d50737e78a82c31b32b62047bfcd6cde74110100205f10c514213e7079bd1873f2f5595e65bb6c81f671d2d94924ea9c43d518753e43ffe2ec62b69c7da9be85eb9e585ec18816d13484fec84804002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440343eccb1956e74a49e1663a37ed66c314a1b97c6504929020fc7e924169b3c63e561da4894d6b85a633222a64551c7bfeb7c9411d8007b284106512787e9850a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "e746c64d6b9a393b7ccdbc0008a9fcc468c20cbd46ffb0b21892d4300d6a3395", - "sequence_number": "2060520937195848607", + "sender": "00c0d0991ac6a0eebb9649eb505f2e62ec4b8d0c9e3a734a9075bde1668f0f23", + "sequence_number": "17725476240111942094", "payload": { "EntryFunction": { "module": { - "address": "cd32ff0caf4a263d388bc32234fa832a9c3c0352022d03fddc02cfa8e4f2813f", - "name": "FdqMjNhyssQXKxFJMwy_Coin" + "address": "260ccf1cdb626e4ab219dff04438da2bf025c2ef104c5568cac9fc437760ace5", + "name": "KlDTQvtvp_Coin" }, - "function": "GNrKBKIFWiEhRO6", + "function": "BNarIzEowihuLPQowCjPkD", "ty_args": [ { "struct": { - "address": "c2fc60f46b344fc52f0f5d331b1cd8f78c04e6f41f5a09e456b473bcb50ee5f6", - "module": "HYntURLGRXmhHItBY4", - "name": "xSCHkOmthlWTiaWCzaGIJXEVCIUN4", + "address": "42ef1d27b329b29e9010a1c4674f2a130dfa039b22da6679c61643f9fdb03aa4", + "module": "gnQQRcWgcQfVTTnkSgoVNedJ1", + "name": "BmOaEGtBYdqchFnrfrjFmoX", "type_args": [] } }, { "vector": { - "vector": "address" + "struct": { + "address": "09cb81be1b4706872dd7d8cca0feafa94a4c4d14ff386f69e4b52f2b3da43c3b", + "module": "nlAe", + "name": "SRtfqxNwNFKTFpLHdFYORtNkFrhoOOiS4", + "type_args": [] + } } }, { "vector": { "struct": { - "address": "5240457eeaf994a111bf36c9ee93d7733c1e8e492cd4bb8b662dec3a3170e390", - "module": "pxmHxgotFcWY9", - "name": "SnsHdwg", + "address": "9da2781c7e6f0d1ecaa0344d92712ab077ce1b9b4e5f958cdb1cd65e468e218e", + "module": "sTcxImSQiLOXChkjwGvNrWZc8", + "name": "YjpAOWYUzqPRPAx", "type_args": [] } } @@ -6105,446 +6587,404 @@ { "vector": { "struct": { - "address": "5988be909a38db33f5d28e2fc432bdd2b48e5f2864e6b30e299e0be22cdaf802", - "module": "RfEfqGNCrBJTbGhNkZL3", - "name": "oZwEDSTAhzxhvOYuJpYzM9", + "address": "37e1ede5f083b5f384f567dafb8b426da2105763d1419b62b4b9284e66a3e787", + "module": "dGMGHGeUvnWQlWCVtX7", + "name": "sVbznwxXoNAINJOd0", "type_args": [] } } }, - { - "struct": { - "address": "445a538bd20313c97323bfc650b38be10d94ac58cd2e7b35989ba7e3348f67d2", - "module": "imBjyYyMKbgVrxGRi", - "name": "WBASBjRUS7", - "type_args": [] - } - }, { "vector": { "vector": { - "vector": "u8" + "struct": { + "address": "a55cc024484783de4cf6b10edea3d73d24aee1c1f592d5e3f45a2f0df3517c61", + "module": "pnxdQsKqqjwZUuDLVbqCrguuGHePPhlm", + "name": "greNkayEDVH", + "type_args": [] + } } } }, { "vector": { "struct": { - "address": "b0bfd5186d35afc9ff7629caaef8fb1a3db89947786f222f4ade5dfc6e9483d2", - "module": "UGGxGxHRIDkFHduxAufbl", - "name": "EnjrnqRrgUIrGCTjphKbkLjfzaHelrR", + "address": "adc57b5e2b25c5b91ddf9b4a04e9a7ce75a766ddbf691f122617a6a8f63df9b9", + "module": "BnIowWFrNBxsCzWwenrBtXuqX", + "name": "zJ0", "type_args": [] } } }, { - "struct": { - "address": "3b9c72ac28702f1b3db64b8d6105ac251abda21be31b67000cae580a5d7bfaaa", - "module": "OtP9", - "name": "bdYuk6", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "9b905a70f34bf982ff4cd7630fbb0e00d81a78988e0a89baefb7184f70ed6d92", + "module": "EInLkSbNAiTfAEeeqB7", + "name": "qYYhreozURBlUrZZmosY2", + "type_args": [] + } + } } }, { "struct": { - "address": "340fd5395a7aef450e7f25a1ca1ad5cfea7cd80638592b1136007798baa27af0", - "module": "sEBsqci", - "name": "znFlq", + "address": "f1cc55af2ba266a08f5dbb2bc8f3f06b63f2ac01d909212f99160b9e16554875", + "module": "a6", + "name": "HFQRTElPNhmmTiMOjKDIgGT", "type_args": [] } }, { "vector": { - "struct": { - "address": "4bd666c517292a353c780a78da2880740b32162044eb600a2f5edad8dfc5fbb5", - "module": "ezOU3", - "name": "Zs8", - "type_args": [] - } + "vector": "u128" + } + }, + { + "vector": { + "vector": "address" } } ], "args": [ - "f1968abd440f875613be09016f62f445", - "b45a3ae40c1d13f8", - "6e2bd1b0a9e1a917b0d243adc2e519d4", - "be", - "521cdc2e4281babdd5c24c5a19dd359b" + "4fa87f3704166bd0a3e02ca8c6389743", + "0e12493a5b5ba9e2", + "953111b4b5fcf27c", + "b4dbda68dee18302a0f7893e9dbdd5b2", + "01", + "64424066472402bea9c9bcab6c45621e", + "4b71e09d170a748abae5aeb94c984c3fd4faa8fe25509ee4e5407cf77a468790", + "70e8f976aa0b98ced857a5d4562cd2bb" ] } }, - "max_gas_amount": "11416902272062105797", - "gas_unit_price": "4683073065799001555", - "expiration_timestamp_secs": "13509958379741968100", - "chain_id": 133 + "max_gas_amount": "159525429769349151", + "gas_unit_price": "13415899599566842889", + "expiration_timestamp_secs": "15680871419898424020", + "chain_id": 16 }, - "signed_txn_bcs": "e746c64d6b9a393b7ccdbc0008a9fcc468c20cbd46ffb0b21892d4300d6a33959f43d011e070981c02cd32ff0caf4a263d388bc32234fa832a9c3c0352022d03fddc02cfa8e4f2813f184664714d6a4e6879737351584b78464a4d77795f436f696e0f474e724b424b494657694568524f360a07c2fc60f46b344fc52f0f5d331b1cd8f78c04e6f41f5a09e456b473bcb50ee5f61248596e7455524c4752586d684849744259341d785343486b4f6d74686c5754696157437a6147494a5845564349554e340006060406075240457eeaf994a111bf36c9ee93d7733c1e8e492cd4bb8b662dec3a3170e3900d70786d4878676f74466357593907536e73486477670006075988be909a38db33f5d28e2fc432bdd2b48e5f2864e6b30e299e0be22cdaf802145266456671474e4372424a546247684e6b5a4c33166f5a774544535441687a7868764f59754a70597a4d390007445a538bd20313c97323bfc650b38be10d94ac58cd2e7b35989ba7e3348f67d211696d426a7959794d4b62675672784752690a57424153426a5255533700060606010607b0bfd5186d35afc9ff7629caaef8fb1a3db89947786f222f4ade5dfc6e9483d215554747784778485249446b4648647578417566626c1f456e6a726e715272675549724743546a70684b626b4c6a667a6148656c725200073b9c72ac28702f1b3db64b8d6105ac251abda21be31b67000cae580a5d7bfaaa044f74503906626459756b360007340fd5395a7aef450e7f25a1ca1ad5cfea7cd80638592b1136007798baa27af00773454273716369057a6e466c710006074bd666c517292a353c780a78da2880740b32162044eb600a2f5edad8dfc5fbb505657a4f5533035a7338000510f1968abd440f875613be09016f62f44508b45a3ae40c1d13f8106e2bd1b0a9e1a917b0d243adc2e519d401be10521cdc2e4281babdd5c24c5a19dd359bc5a89c8920fc709ed3252630249efd40e4f6d44a91037dbb85002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409929430724e53ce4e0215b679f754bef185016c2b0d175d22657d4cb376bee5c372c5f93c89c6a1b6584b18c52d7d31f1da946dd0e08c7a987b2fd262e8bec06", + "signed_txn_bcs": "00c0d0991ac6a0eebb9649eb505f2e62ec4b8d0c9e3a734a9075bde1668f0f23ceb97f0eba8afdf502260ccf1cdb626e4ab219dff04438da2bf025c2ef104c5568cac9fc437760ace50e4b6c445451767476705f436f696e16424e6172497a456f776968754c50516f77436a506b440a0742ef1d27b329b29e9010a1c4674f2a130dfa039b22da6679c61643f9fdb03aa419676e5151526357676351665654546e6b53676f564e65644a3117426d4f61454774425964716368466e7266726a466d6f5800060709cb81be1b4706872dd7d8cca0feafa94a4c4d14ff386f69e4b52f2b3da43c3b046e6c4165215352746671784e774e464b5446704c486446594f52744e6b4672686f4f4f6953340006079da2781c7e6f0d1ecaa0344d92712ab077ce1b9b4e5f958cdb1cd65e468e218e1973546378496d5351694c4f5843686b6a7747764e72575a63380f596a70414f5759557a71505250417800060737e1ede5f083b5f384f567dafb8b426da2105763d1419b62b4b9284e66a3e7871364474d4748476555766e57516c574356745837117356627a6e7778586f4e41494e4a4f643000060607a55cc024484783de4cf6b10edea3d73d24aee1c1f592d5e3f45a2f0df3517c6120706e786451734b71716a775a5575444c56627143726775754748655050686c6d0b6772654e6b617945445648000607adc57b5e2b25c5b91ddf9b4a04e9a7ce75a766ddbf691f122617a6a8f63df9b919426e496f775746724e427873437a5777656e72427458757158037a4a30000606079b905a70f34bf982ff4cd7630fbb0e00d81a78988e0a89baefb7184f70ed6d921345496e4c6b53624e4169546641456565714237157159596872656f7a5552426c55725a5a6d6f7359320007f1cc55af2ba266a08f5dbb2bc8f3f06b63f2ac01d909212f99160b9e16554875026136174846515254456c504e686d6d54694d4f6a4b44496747540006060306060408104fa87f3704166bd0a3e02ca8c6389743080e12493a5b5ba9e208953111b4b5fcf27c10b4dbda68dee18302a0f7893e9dbdd5b201011064424066472402bea9c9bcab6c45621e204b71e09d170a748abae5aeb94c984c3fd4faa8fe25509ee4e5407cf77a4687901070e8f976aa0b98ced857a5d4562cd2bb1f280b7e88bf360209ac7cf69ad92ebad4ea9ebf79a59dd910002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d754f43fab3c4e8fc7501eaa11178df1113dc447709fc167807435ddb9845b6076e56121563f75af41ee6e4aac6d22aa500f675da8198f9a5cca4d9fbb633d0d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "522ba9a0c868f2410ce9fba8ecec6e5b3085e67956412f24de3ccfc93b67a400", - "sequence_number": "9708135129554253710", + "sender": "b17ed44f5106ef2206751bc41b34553c3a21dc2414f0ebe34aae3ee3693d5a90", + "sequence_number": "11053536302808657764", "payload": { "EntryFunction": { "module": { - "address": "2c193cbf81e90dbe7d4f5ed11c7951fdbf314fecb4294b223626cce67cb4fa3a", - "name": "VTYQKSg0_Coin" + "address": "db75d0ab4e371025348defd7b76a38e1d623859fff01583bbde1acd0ebfb3770", + "name": "fTVixSeMAdgSEMBozEBPYBy_Coin" }, - "function": "qzpiDhuugNENjqpTQSMJPirfHYEfbVk8", + "function": "lTkvCqPU1", "ty_args": [ + { + "vector": { + "vector": "bool" + } + }, + { + "struct": { + "address": "8ecec98dda4cace103facbbf02db26e27168a96196ad6c46a0bcb427c9748d6a", + "module": "HCdfgbyexhoSgY", + "name": "RIuhGkNPXfXobrtpqoRWsvRxAsbyDw7", + "type_args": [] + } + }, { "struct": { - "address": "193cd22d8bfc41ee65cdd696018fcc21e80e5a813f2959d36219ec1a318230c4", - "module": "jGXWzQ", - "name": "pCKS8", + "address": "ecd3668476cb556c93a02f72437567bc61989620167886f2d637183b3adf1342", + "module": "NCQyIkmUpBWdmi8", + "name": "qSM3", "type_args": [] } }, { "vector": { - "struct": { - "address": "0c7d43a2d74772a19735af32201c253aa8f92b8176648084c6de90488d970ea1", - "module": "AhrYtqrvVQCrpltFkQCZTAlsHdG9", - "name": "ZhkWjDiDprRshBXqLWOEDNCjHLyDtcHH", - "type_args": [] - } + "vector": "bool" + } + }, + { + "struct": { + "address": "2ae1f9a4d0ecd43db83555207c59399b142a74aff83f8d431f93ecb01e48b014", + "module": "qPJhjUdmTYCCmAJOTFuNllrTUWTqcIWF3", + "name": "O5", + "type_args": [] + } + }, + { + "struct": { + "address": "0808357741d50041ab6132d24986c84bda2bb520d3a315307589a2a270b3959e", + "module": "pVcM", + "name": "sVTGidCrUVRauvDeC3", + "type_args": [] } + }, + { + "vector": "u8" } ], "args": [ - "3139765f1a3e9d51", - "00", + "2a3ed44f0ed53e19", + "a6a3c08f5a2a32198cadff2758351ffa8a8dbe2f84eefc5843d3e46fe5502bc2", + "269694b61fd8c70e", + "ceaab856e69c0a6e51c30531be9186f4", + "7a", + "8d", "00", - "a2f1f6c0388f7388" - ] - } - }, - "max_gas_amount": "1364424639455611421", - "gas_unit_price": "13608074874311660985", - "expiration_timestamp_secs": "5558338812362258986", - "chain_id": 91 - }, - "signed_txn_bcs": "522ba9a0c868f2410ce9fba8ecec6e5b3085e67956412f24de3ccfc93b67a4008e7792e47639ba86022c193cbf81e90dbe7d4f5ed11c7951fdbf314fecb4294b223626cce67cb4fa3a0d565459514b5367305f436f696e20717a706944687575674e454e6a71705451534d4a506972664859456662566b380207193cd22d8bfc41ee65cdd696018fcc21e80e5a813f2959d36219ec1a318230c4066a4758577a510570434b53380006070c7d43a2d74772a19735af32201c253aa8f92b8176648084c6de90488d970ea11c416872597471727656514372706c74466b51435a54416c7348644739205a686b576a44694470725273684258714c574f45444e436a484c7944746348480004083139765f1a3e9d510100010008a2f1f6c0388f73881dca8a05fb68ef12b9d543e0ff97d9bc2a7a1e54b32f234d5b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444018d5e087013367f0c3d4d0a140ffc66c56cf19a056ce9f521bc8f85023b81e41040513850c569219817e1a37dd6fc5f70909c0ab8122c1a33a943af08e73890b", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "98f4a2068c66b5dcb53f732bbf4142bc1d31dbf6b15fdedd7a1384ff33f6bb94", - "sequence_number": "11266348269592408159", - "payload": { - "EntryFunction": { - "module": { - "address": "ece1b40c8d9fb086da7ba30cfd428b8aa3c737690e5f974fb7e61e5fb862d5ba", - "name": "WT0_Coin" - }, - "function": "EQdTcyB", - "ty_args": [], - "args": [ - "25bb266e0a80c57b", - "afebdf3932c59c18ae5d635ab973977b02adbb015c7ef091a156d437c16e0159", - "f6" - ] - } - }, - "max_gas_amount": "13553455173283714370", - "gas_unit_price": "14686835722051792292", - "expiration_timestamp_secs": "17601619364688645269", - "chain_id": 14 - }, - "signed_txn_bcs": "98f4a2068c66b5dcb53f732bbf4142bc1d31dbf6b15fdedd7a1384ff33f6bb945f70e43c0f1c5a9c02ece1b40c8d9fb086da7ba30cfd428b8aa3c737690e5f974fb7e61e5fb862d5ba085754305f436f696e074551645463794200030825bb266e0a80c57b20afebdf3932c59c18ae5d635ab973977b02adbb015c7ef091a156d437c16e015901f64295c1baab8b17bca42d6a67461fd2cb954ce7078e8345f40e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401178e5516aacf67e552828d29f85186d0abf850b4ca7b9b0df03aefde166377d2064de2763d6971ca02c21934031b9e6049b8814d5a74d97088416efdd48be05", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "c3cdd2f19bf9e41edaf6827c622b6643657873fe148f2d3a04a5db77eb959964", - "sequence_number": "11625350026605985555", - "payload": { - "EntryFunction": { - "module": { - "address": "8487765f9600a41ad93889a0167178dacabfe2103b67e979a876bf231ddc8664", - "name": "gtQeOQNXROecwHXqnlmDvvxFtbkqxFt3_Coin" - }, - "function": "pdHHUTSPXYzqifqxSrLImwwtahmu", - "ty_args": [], - "args": [ - "6c", - "2a" - ] - } - }, - "max_gas_amount": "8613143236029441603", - "gas_unit_price": "12871874025297730325", - "expiration_timestamp_secs": "5202525924052740702", - "chain_id": 117 - }, - "signed_txn_bcs": "c3cdd2f19bf9e41edaf6827c622b6643657873fe148f2d3a04a5db77eb959964137f6d65418a55a1028487765f9600a41ad93889a0167178dacabfe2103b67e979a876bf231ddc866425677451654f514e58524f6563774858716e6c6d447676784674626b71784674335f436f696e1c706448485554535058597a716966717853724c496d77777461686d750002016c012a43e617872308887715db72573a15a2b25eaaec85c315334875002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401edfc5b6fce1388bab75d963cb1833e146dea2653c2a7ece18921fd8a2f8f3eb511fad19deb1f30a4ed90a2c8b730ba76cfcf64df55a09982530cf554abafc0c", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "52f462e609ddd4f47fa654a0e08ca0b3c58791e7079a8a8b8ed2665813cdb381", - "sequence_number": "402780560270399056", - "payload": { - "EntryFunction": { - "module": { - "address": "47b29ea2377514149ce05bbc213a484544b8f86a106d83b5650558c3662c3d1d", - "name": "Rjy9_Coin" - }, - "function": "IrweXnyEhWcyRR", - "ty_args": [], - "args": [ - "d88931abed1680d2", - "d1e59e5d85ba1dcfe661aef0f8a80b4e", - "4119514cd9614af165aa991ea5b782cc", - "01" + "88fa8d8b122bb23f", + "8f", + "e0" ] } }, - "max_gas_amount": "12491913433583050434", - "gas_unit_price": "1117778264511740331", - "expiration_timestamp_secs": "4676265782475935942", - "chain_id": 227 + "max_gas_amount": "15596187450180252967", + "gas_unit_price": "12669226718746987033", + "expiration_timestamp_secs": "7775379903985497020", + "chain_id": 28 }, - "signed_txn_bcs": "52f462e609ddd4f47fa654a0e08ca0b3c58791e7079a8a8b8ed2665813cdb38150965919c9f696050247b29ea2377514149ce05bbc213a484544b8f86a106d83b5650558c3662c3d1d09526a79395f436f696e0e49727765586e7945685763795252000408d88931abed1680d210d1e59e5d85ba1dcfe661aef0f8a80b4e104119514cd9614af165aa991ea5b782cc0101c2dea53515315cadabf9dfc96825830fc6d0ca07f46ee540e3002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401c6f9a3bfa5f6b6150d7b530229b127e94c5628a7036c9c5672374c0d6ce7645f0ee0a3b9be8b853b789f132ee8ce3ce4317f80e8a8c6674b275613b2be1690e", + "signed_txn_bcs": "b17ed44f5106ef2206751bc41b34553c3a21dc2414f0ebe34aae3ee3693d5a90646fcb08b40c669902db75d0ab4e371025348defd7b76a38e1d623859fff01583bbde1acd0ebfb37701c665456697853654d41646753454d426f7a4542505942795f436f696e096c546b76437150553107060600078ecec98dda4cace103facbbf02db26e27168a96196ad6c46a0bcb427c9748d6a0e484364666762796578686f5367591f52497568476b4e505866586f62727470716f525773765278417362794477370007ecd3668476cb556c93a02f72437567bc61989620167886f2d637183b3adf13420f4e435179496b6d55704257646d69380471534d3300060600072ae1f9a4d0ecd43db83555207c59399b142a74aff83f8d431f93ecb01e48b0142171504a686a55646d545943436d414a4f5446754e6c6c7254555754716349574633024f3500070808357741d50041ab6132d24986c84bda2bb520d3a315307589a2a270b3959e047056634d127356544769644372555652617576446543330006010a082a3ed44f0ed53e1920a6a3c08f5a2a32198cadff2758351ffa8a8dbe2f84eefc5843d3e46fe5502bc208269694b61fd8c70e10ceaab856e69c0a6e51c30531be9186f4017a018d01000888fa8d8b122bb23f018f01e027356692dac970d8194acd859322d2afbc33c4b2d3b2e76b1c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401534e7c8d384eac66d310a1e788f1bc17bd3a25b2decace27a2a13fff063bc16eec9d0262c2efa579734697bd52d765b12f2833a7e73ebb97a8f2aaf0122fb01", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "ecee76b8cf2d77c185945bdb3f8c32f20e2e6e51084ca7d79ddc1b12b9dac418", - "sequence_number": "16506098280255848226", + "sender": "91c9353ecc7afc3c35fccf10a42562b9dc1a24efa5b9f435261b31a7a0a3f997", + "sequence_number": "3570480216679393122", "payload": { "EntryFunction": { "module": { - "address": "80639879a4aa60afe7ebcea5626b84238c6d25c797d8b4218d0f4e63a6cf9f7a", - "name": "KEPPiKOWgjHRJXJ_Coin" + "address": "dd7e4de93632810988d3d9eec4869ce7abcd263404f0d15d515ddfc473e56102", + "name": "PxRojjYUTrHhj7_Coin" }, - "function": "KYFbHRaSvkxkFuhZPKTfAztCDwq3", + "function": "ilohmlnXXJk9", "ty_args": [ { "struct": { - "address": "1fe0bc9eecc1490323030851e866e956b6186c4169a6f84a70103f855919c59c", - "module": "CLlFVsWebuLdNZgHiBUkyGF", - "name": "dFjHn", + "address": "41ed44f7f5c335f9caf860b435ceef171fb32debd6f6b873f6c52b96fd4b08fa", + "module": "RxQbHjJKRoehQQBJjhTcwymCLGDyKn", + "name": "oivYMCnQtNKtbe", "type_args": [] } }, { "struct": { - "address": "d6bd4e12c5238d7f8c7e2bd9113195b5e39481b7190b9bfdf81256cf83fe6758", - "module": "DjQivUCNShhLmHbpQGX7", - "name": "hGeUFZgEIoCCdPua8", + "address": "c6ee3f80e6f1cd0d7c63f7804eda5d6361c4efaa44fc7a52ee7997f5748f5f3d", + "module": "fqGPTqYObWIxDpLijspfiCaKX2", + "name": "FknPFQJjJAeTzqg3", "type_args": [] } }, { "vector": { "struct": { - "address": "c0ae510496151ad2c10c8e500bdf6ff7ed0ece968c09a0784d8d40d746c00f63", - "module": "sqYBZPIkJWZFMnqlU5", - "name": "aTrsRPBVNFkLqUXnsSyppkWXgoUIuBPe", + "address": "bedfd6077defcc6503199de5c99138e50323617ee32743f3fc2bf1a993032181", + "module": "queUHHSTdNZPKeFEAwpsXxQxjguN", + "name": "dR9", "type_args": [] } } }, { - "struct": { - "address": "2cc21154adc669e52cc4f69942a058d58d74ecab6e1fb4cf2b15bd5be7709ae6", - "module": "TbbIKZwVsghRJETUEt5", - "name": "ofjfrPdqzhziMyZzGhtYiTACNG5", - "type_args": [] - } - }, - { - "struct": { - "address": "9b423b60dd801b9311ca07e15b6869a234a40a633874d7fee73914f6807352a6", - "module": "IqMffgGGckskecZyJans4", - "name": "vxH8", - "type_args": [] - } - }, - { - "struct": { - "address": "93121002189a050e6a6f4789ebc48c6bab3b74b41e768957adf03e486628c638", - "module": "Psp3", - "name": "ejzVpoXHFfNzTAPxA2", - "type_args": [] + "vector": { + "struct": { + "address": "6a5b43b11ff2cbede42398400daffce4e16a16167bdf8028118f0732a0526ef6", + "module": "XhstxajLKPC7", + "name": "DbyTlbfocp8", + "type_args": [] + } } }, { "struct": { - "address": "4474e5068451307c9891b87fec7ff7492130e629add5aa5b0f410ec6c483828e", - "module": "fPROplAQR3", - "name": "BdJcspIEAxrSpNxNHkXSUeqdKvO0", + "address": "83c73337e0dcae1b9f257cb0ee37846525821441734c2d05466dcc7973bb8f50", + "module": "zOaRDJfSg", + "name": "gKTNONeHsilUQyaRzpRSPTapcNfRtXD", "type_args": [] } - }, + } + ], + "args": [] + } + }, + "max_gas_amount": "14858205428171983055", + "gas_unit_price": "18083285532585807171", + "expiration_timestamp_secs": "10609333344275075708", + "chain_id": 50 + }, + "signed_txn_bcs": "91c9353ecc7afc3c35fccf10a42562b9dc1a24efa5b9f435261b31a7a0a3f9976227bc00d7e48c3102dd7e4de93632810988d3d9eec4869ce7abcd263404f0d15d515ddfc473e56102135078526f6a6a5955547248686a375f436f696e0c696c6f686d6c6e58584a6b39050741ed44f7f5c335f9caf860b435ceef171fb32debd6f6b873f6c52b96fd4b08fa1e52785162486a4a4b526f65685151424a6a68546377796d434c4744794b6e0e6f6976594d436e51744e4b7462650007c6ee3f80e6f1cd0d7c63f7804eda5d6361c4efaa44fc7a52ee7997f5748f5f3d1a667147505471594f6257497844704c696a7370666943614b583210466b6e5046514a6a4a4165547a716733000607bedfd6077defcc6503199de5c99138e50323617ee32743f3fc2bf1a9930321811c7175655548485354644e5a504b65464541777073587851786a67754e036452390006076a5b43b11ff2cbede42398400daffce4e16a16167bdf8028118f0732a0526ef60c5868737478616a4c4b5043370b446279546c62666f637038000783c73337e0dcae1b9f257cb0ee37846525821441734c2d05466dcc7973bb8f50097a4f6152444a6653671f674b544e4f4e654873696c55517961527a70525350546170634e66527458440000cfc8f8611df332ce43cdbced61bcf4fa7c12394977ec3b9332002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444023a819af297f01a5d24e2db211e6560d38c009a3e41f716f7c355f32475f0724d6414143674b622ee6cd3313df1ba44faf5590ac51538a720ddea90314d0750e", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "8f885f2e8d64307eb2ebabcdcbb0da33e92bad819945e0fda3e539ba2b406c2a", + "sequence_number": "15482645997933708300", + "payload": { + "EntryFunction": { + "module": { + "address": "0aec1c86294532f1140bc6ad5576554b66034ae2db8e1271e9efac47d975a8ae", + "name": "xuukDAenpMFZoivxJhHhWPnshxXsYYFq_Coin" + }, + "function": "DLVXhCgFcrgLrgRUDyWoLFVeZabHu9", + "ty_args": [ { "vector": { - "vector": "address" - } - }, - { - "struct": { - "address": "5a3b671a34e61cc36683e95350d2a1ad51ec8bc5d29dda898abc1eccc651864b", - "module": "epPFGCJFNr", - "name": "JFcjqMaInQD6", - "type_args": [] + "vector": { + "vector": "address" + } } } ], "args": [ - "eb" + "623e4a74acd9afc69ef1040bb4ec7f0e", + "a67b34625a56dfb807512dfd7e54a36691b6028ea2dc93242f2bc0f331e55447", + "12a7700f7736688320934b79dd9e109a", + "b2ed3d11ed8197b6091ef86db76255abbe7b8ade23bfd73a7514ebe799c198d4", + "01", + "82", + "93" ] } }, - "max_gas_amount": "13402343559833689883", - "gas_unit_price": "1667303761792637328", - "expiration_timestamp_secs": "10618678220240828538", - "chain_id": 178 + "max_gas_amount": "5565563150619258041", + "gas_unit_price": "5161692174764465018", + "expiration_timestamp_secs": "15892331458200183756", + "chain_id": 195 }, - "signed_txn_bcs": "ecee76b8cf2d77c185945bdb3f8c32f20e2e6e51084ca7d79ddc1b12b9dac41822ff55ceee7011e50280639879a4aa60afe7ebcea5626b84238c6d25c797d8b4218d0f4e63a6cf9f7a144b455050694b4f57676a48524a584a5f436f696e1c4b59466248526153766b786b4675685a504b5466417a74434477713309071fe0bc9eecc1490323030851e866e956b6186c4169a6f84a70103f855919c59c17434c6c465673576562754c644e5a67486942556b7947460564466a486e0007d6bd4e12c5238d7f8c7e2bd9113195b5e39481b7190b9bfdf81256cf83fe675814446a51697655434e5368684c6d486270514758371168476555465a6745496f43436450756138000607c0ae510496151ad2c10c8e500bdf6ff7ed0ece968c09a0784d8d40d746c00f6312737159425a50496b4a575a464d6e716c55352061547273525042564e466b4c7155586e73537970706b5758676f55497542506500072cc21154adc669e52cc4f69942a058d58d74ecab6e1fb4cf2b15bd5be7709ae613546262494b5a7756736768524a4554554574351b6f666a66725064717a687a694d795a7a47687459695441434e473500079b423b60dd801b9311ca07e15b6869a234a40a633874d7fee73914f6807352a61549714d6666674747636b736b65635a794a616e73340476784838000793121002189a050e6a6f4789ebc48c6bab3b74b41e768957adf03e486628c638045073703312656a7a56706f584846664e7a54415078413200074474e5068451307c9891b87fec7ff7492130e629add5aa5b0f410ec6c483828e0a6650524f706c415152331c42644a637370494541787253704e784e486b5853556571644b764f3000060604075a3b671a34e61cc36683e95350d2a1ad51ec8bc5d29dda898abc1eccc651864b0a6570504647434a464e720c4a46636a714d61496e514436000101eb1b9fa18175b0feb990995206f07323177ab8a1c5941f5d93b2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400f4d6f3e098a9c7c89f85311bc0a3e01e8587d8d1f58abbfa77cc999fb19675594b5bb7b3453014f1218bd04beae64f21f2f1040f0afbe5369b8693cfc368705", + "signed_txn_bcs": "8f885f2e8d64307eb2ebabcdcbb0da33e92bad819945e0fda3e539ba2b406c2a0c44f6298168ddd6020aec1c86294532f1140bc6ad5576554b66034ae2db8e1271e9efac47d975a8ae257875756b4441656e704d465a6f6976784a68486857506e7368785873595946715f436f696e1e444c5658684367466372674c726752554479576f4c4656655a616248753901060606040710623e4a74acd9afc69ef1040bb4ec7f0e20a67b34625a56dfb807512dfd7e54a36691b6028ea2dc93242f2bc0f331e554471012a7700f7736688320934b79dd9e109a20b2ed3d11ed8197b6091ef86db76255abbe7b8ade23bfd73a7514ebe799c198d4010101820193b92caaa732da3c4d7adbbf64af03a247cca3c99242e78cdcc3002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a6617f9650a1b95f7537c50380d4b376b04047cc850383a3accd770fb1fa600b64b29c952d690c2d8da24b530db93dcf2782acbe67cc31cdc03a0db3249b5d0a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "4cf9da65612636650a5fa18e3d0a7dc5a81632468f15d56bcf1fdbf53f004e14", - "sequence_number": "1175884268994291843", + "sender": "ea975cb1b94b93f25b6735fb6db40f6eee62bd372bf462550a40536f191d5f3a", + "sequence_number": "9507448392380117424", "payload": { "EntryFunction": { "module": { - "address": "2c1df553bbaa84028a3904a9e3ae2791cd12f7aaff8c88aef3577d4ab4abf096", - "name": "MsnpLtaAEkpBh_Coin" + "address": "36b8d7a64c0aecea9634f5d5acf177524f5ff4b5a5e1629ab6b0b201215bfbdd", + "name": "VhzyasqWjMT_Coin" }, - "function": "DTazIxHhpuVRkrDnkrFvGeaKaiC", + "function": "TkNMRmFkaStYTe4", "ty_args": [ { "struct": { - "address": "1cd778bdb941dbd4316b921c14eb5461feaaedd550801f0ff0ff7a5cfb5831fd", - "module": "J", - "name": "zbDxA3", + "address": "1119d5b664aefac81ef6d7d1e1f68417091acf18de18c39d605593fce9a150fb", + "module": "nt", + "name": "ZsesfgqsRkELXAd", "type_args": [] } }, { "vector": { "vector": { - "vector": "signer" + "vector": "u64" } } }, + { + "struct": { + "address": "83778a69666982c4721925306403014d3c8caaeb42d85d0b5d78e261b7c56014", + "module": "hbsLcCUjSLtjtCNKkTBhnIXcyD", + "name": "WpgYBaBzb8", + "type_args": [] + } + }, { "vector": { - "struct": { - "address": "df7dca80c2f7474ab751ef3f0bdf5f78aac239dc4a1b8e2691f2fa5f03dafec8", - "module": "ZgHOoODnZiSlelWQzjPmOGdqa", - "name": "OmBEpbfvvNSKVsMejuTcvBpGoAHSif", - "type_args": [] - } + "vector": "bool" } }, + { + "vector": "u128" + }, { "vector": { "vector": { "struct": { - "address": "d1b11c1e5ddb8424ea8106dbacb96388f92d58543b51228d6920cd7468d3bc8e", - "module": "wuvluoOrSPRblIwfdENDFPBBKWqwDx", - "name": "OfgfnadWQXtMtacjViL3", + "address": "3129a3140ffd4bf20dbc54e54e0f14835700e4b9a9863d843bc410a98e5fd131", + "module": "jJ", + "name": "iTylTQJbpNBVJDCPWVB1", "type_args": [] } } } }, + { + "struct": { + "address": "b6ab077aa0027da458cd171b0db51d7002fcd08f1278355b7f26b4f75a609936", + "module": "PJiZeUVwmJzHjzHh", + "name": "kYfBeIN", + "type_args": [] + } + }, { "vector": { "struct": { - "address": "2e46b573e37510ffe1748fb7dc44777b1392467a740980c13e1af83d0b9fcc42", - "module": "IQm8", - "name": "izzhEMfacEYP9", + "address": "c12ce1dff77bdc3fda9e82306f2ba3200e7cd8dadc63fa0247f2c1d736a4a5a9", + "module": "jmnSHNChOxj", + "name": "ER", "type_args": [] } } }, - { - "struct": { - "address": "0d061744da1c099ba010362cb3d7901d1368fccfb04c7ea18924c4e6205c4211", - "module": "zEFFoTCuAqvmm0", - "name": "M", - "type_args": [] - } - }, { "vector": { "struct": { - "address": "99e385c490a595c127c422caa407fe03f6a2beab5998e6819a6e628e90f07793", - "module": "tgyjqslSuILJsGwNyhbIR", - "name": "dgvkqhY", + "address": "733db0e8db073486139e003357792b07ebbf5b216a14a20eae53b70c5ef3bffe", + "module": "corCYwheAClMqKqAWZheEWtmKgLw7", + "name": "MYTdyPBn", "type_args": [] } } }, { "struct": { - "address": "4d42d063185143901d05c3701c8a0d53ec9b56ce5d525f4c1f75c9a46b10e5cc", - "module": "zUUYPvyOrQuqElnOY", - "name": "TPiTEQNJQrGYEadpBaZ", + "address": "df6301c0d7b8cfdaae0a5051ef8aeeb42d74e10964e4772564059b774af57296", + "module": "p9", + "name": "oZajNdnRvNfuqYjZSFlxV", "type_args": [] } } ], "args": [ - "d0", - "7de4c159275a2a4288fcc9f3c2a6c912", - "128670234bdadfe3", - "0c98e4ba31c067ca", - "a235b1a3d42b30cca52639dc7c21c856", - "c7" + "01", + "52", + "00", + "00", + "39531951e0cfce6d3706b6a1edaa28a1", + "258c183b63a905bd3e3451813e3190cc", + "d28cd8c1516c4f17", + "08ec26244edc64e7b3e43347e5b2eee86ba0c35c736eba9e2581773865023bc6" ] } }, - "max_gas_amount": "14641276958299992272", - "gas_unit_price": "11816269869188365754", - "expiration_timestamp_secs": "15779597964659532366", - "chain_id": 144 + "max_gas_amount": "17780926253518102796", + "gas_unit_price": "8481489915609985387", + "expiration_timestamp_secs": "13790857081150253923", + "chain_id": 75 }, - "signed_txn_bcs": "4cf9da65612636650a5fa18e3d0a7dc5a81632468f15d56bcf1fdbf53f004e1483e85f3683945110022c1df553bbaa84028a3904a9e3ae2791cd12f7aaff8c88aef3577d4ab4abf096124d736e704c746141456b7042685f436f696e1b4454617a49784868707556526b72446e6b7246764765614b61694308071cd778bdb941dbd4316b921c14eb5461feaaedd550801f0ff0ff7a5cfb5831fd014a067a624478413300060606050607df7dca80c2f7474ab751ef3f0bdf5f78aac239dc4a1b8e2691f2fa5f03dafec8195a67484f6f4f446e5a69536c656c57517a6a506d4f476471611e4f6d424570626676764e534b56734d656a755463764270476f414853696600060607d1b11c1e5ddb8424ea8106dbacb96388f92d58543b51228d6920cd7468d3bc8e1e7775766c756f4f72535052626c49776664454e44465042424b5771774478144f6667666e6164575158744d7461636a56694c330006072e46b573e37510ffe1748fb7dc44777b1392467a740980c13e1af83d0b9fcc420449516d380d697a7a68454d6661634559503900070d061744da1c099ba010362cb3d7901d1368fccfb04c7ea18924c4e6205c42110e7a4546466f5443754171766d6d30014d00060799e385c490a595c127c422caa407fe03f6a2beab5998e6819a6e628e90f07793157467796a71736c5375494c4a7347774e7968624952076467766b71685900074d42d063185143901d05c3701c8a0d53ec9b56ce5d525f4c1f75c9a46b10e5cc117a5555595076794f72517571456c6e4f59135450695445514e4a517247594561647042615a000601d0107de4c159275a2a4288fcc9f3c2a6c91208128670234bdadfe3080c98e4ba31c067ca10a235b1a3d42b30cca52639dc7c21c85601c7d030951dd24330cbbabd1f3bd7d2fba34e2202b6be64fcda90002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bcab78f1ebc73e950a640b879931bef90f44be07ec4678029838efc81bd7648345f18ca7b14437c7bea6e2de39f1ede9fac6fb66da9cde7355efc20425516c0f", + "signed_txn_bcs": "ea975cb1b94b93f25b6735fb6db40f6eee62bd372bf462550a40536f191d5f3ab0f12cb4f03df1830236b8d7a64c0aecea9634f5d5acf177524f5ff4b5a5e1629ab6b0b201215bfbdd1056687a79617371576a4d545f436f696e0f546b4e4d526d466b615374595465340a071119d5b664aefac81ef6d7d1e1f68417091acf18de18c39d605593fce9a150fb026e740f5a73657366677173526b454c58416400060606020783778a69666982c4721925306403014d3c8caaeb42d85d0b5d78e261b7c560141a6862734c6343556a534c746a74434e4b6b5442686e49586379440a577067594261427a62380006060006030606073129a3140ffd4bf20dbc54e54e0f14835700e4b9a9863d843bc410a98e5fd131026a4a146954796c54514a62704e42564a444350575642310007b6ab077aa0027da458cd171b0db51d7002fcd08f1278355b7f26b4f75a60993610504a695a655556776d4a7a486a7a4868076b59664265494e000607c12ce1dff77bdc3fda9e82306f2ba3200e7cd8dadc63fa0247f2c1d736a4a5a90b6a6d6e53484e43684f786a024552000607733db0e8db073486139e003357792b07ebbf5b216a14a20eae53b70c5ef3bffe1d636f72435977686541436c4d714b7141575a68654557746d4b674c7737084d5954647950426e0007df6301c0d7b8cfdaae0a5051ef8aeeb42d74e10964e4772564059b774af57296027039156f5a616a4e646e52764e667571596a5a53466c7856000801010152010001001039531951e0cfce6d3706b6a1edaa28a110258c183b63a905bd3e3451813e3190cc08d28cd8c1516c4f172008ec26244edc64e7b3e43347e5b2eee86ba0c35c736eba9e2581773865023bc60c215d5e388ac2f66bb1fd31244eb475632b24be72f762bf4b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a4316e282a65cd7b3182a26f55b8115e70457001daffc2bc6f55f86953c80c48237f9f7db7a8649bba58ff875d52e51a8d84ad4a1f4c21c1f7e0331c34456006", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "555157eef5c2a66918739038d7a73237b7e55bfee7a429a82b83fd3a501a7c80", - "sequence_number": "17550559087365898062", + "sender": "ed25163dbc552d6996903246d7a3207b2aa2f824b20ddd28a53c2132dab3df01", + "sequence_number": "13265645245838293307", "payload": { "EntryFunction": { "module": { - "address": "4261a4b87cf1e2b26eb4775d8ed8a713ad6189f0710a855bb3d02c6bb2f2107c", - "name": "vRYfducDeDnSwmdQ_Coin" + "address": "61ad29837b7abce25de582660f9b366d3a62782b98ba0d9948f893bb748b4f9b", + "name": "SiNAVCzHsCJmIXeFyTPZbhXFooK3_Coin" }, - "function": "FUBgeyxeAnCAdbJhJWpykdKykSZ2", + "function": "tOdurPVhuw", "ty_args": [ - { - "struct": { - "address": "a05758ed3b49170daedc052780995acd674b95f2b7a800d346a6256dd54f4288", - "module": "sTJQIEZbsSAQaJMHPzHcLWbq", - "name": "KKRQwulvCc6", - "type_args": [] - } - }, - { - "struct": { - "address": "2203fbd6085761f1d25c9b8c0785c77c337d5301cd22301c2cffd03a22688f8c", - "module": "JqcPjWpLdrmJiHr", - "name": "rApyYWhwHhdxChSXFtLI", - "type_args": [] - } - }, { "vector": { "vector": { "struct": { - "address": "8d97cb5cf34b4554880e9c30a6759e947e00a408e61bbcb6a4d9101b13b23e72", - "module": "XivxzomTWtFBu", - "name": "NfiWhMiPrZNEQPjgG6", + "address": "775249248fd67146bd015e9ba8f4e5b85b713a6ed7e06d521e12b7340015236d", + "module": "TMltUiIrJKVTjmhkWrRaGVGM", + "name": "dQMhsxfKHnUWvuRLMWZ", "type_args": [] } } @@ -6552,196 +6992,143 @@ }, { "struct": { - "address": "5d89a6aa63ef6ae338dfafd83332c1598b361b2f9a298a12ef8935f655b35e98", - "module": "m", - "name": "RPUC", - "type_args": [] - } - }, - { - "struct": { - "address": "1a56e1a6f20701ed54f1046fae8ec454c941bd584a438fa62119d1944b723b56", - "module": "lFzUidMBlIjvdsVlIh", - "name": "zXb", + "address": "add6ee76d7116858b00ed5da2ebad5b8263e76a15969a5a1e7dd5339a5ed26a6", + "module": "nCCANAWTCUSNVIk2", + "name": "eJHUrfzEtyZfpPhcPxCDrbDGxdlzPy1", "type_args": [] } }, { "struct": { - "address": "02786e6ae3354703196c1a1e64dda26e67562c6d3faf2d7b42161d4240bcceb1", - "module": "PWjENfDcR0", - "name": "FBpIZcwMspYCfFPqZg", + "address": "b2f14cc33b042cdaa6634447da83cc8e8af0d19c678f7ad9bffab1086d5f99e7", + "module": "WsjmNckoOkEVY5", + "name": "AQUjUhXDA2", "type_args": [] } }, { "struct": { - "address": "6b19b3b8bf936a8b2a278adebf4c3caa4c7e5ff2cc8961b62c3d89a52fc798d3", - "module": "UseRWKEOPXZggAOCgXGeMhRhOfNqPZFs9", - "name": "VwiWBKkPkBPBLUUJOaE9", + "address": "c1f015afdff9e9ef96014fad5557eab5b66b7f3d1e23850459cac859019a70a4", + "module": "mt", + "name": "RqISDRona", "type_args": [] } }, - { - "vector": { - "struct": { - "address": "56709589a2ea4228622ae1a42b7c5d9c95ccf04bf0d13057e2ed3e422595ef35", - "module": "mwPcqDYJIhdiAcikMBwRZlnh", - "name": "YJFBPQpMwmREBraxyxb", - "type_args": [] - } - } - } - ], - "args": [ - "05", - "95", - "be", - "b3", - "7762099c1411efb8", - "ab9f6f1e1754dd0b", - "0b3df99d75741908f3c7a2de4555f75d" - ] - } - }, - "max_gas_amount": "5152191004395986010", - "gas_unit_price": "16501995279232981224", - "expiration_timestamp_secs": "8188060161470793311", - "chain_id": 65 - }, - "signed_txn_bcs": "555157eef5c2a66918739038d7a73237b7e55bfee7a429a82b83fd3a501a7c804ebff2cb801c90f3024261a4b87cf1e2b26eb4775d8ed8a713ad6189f0710a855bb3d02c6bb2f2107c15765259666475634465446e53776d64515f436f696e1c4655426765797865416e434164624a684a5770796b644b796b535a320807a05758ed3b49170daedc052780995acd674b95f2b7a800d346a6256dd54f42881873544a5149455a6273534151614a4d48507a48634c5762710b4b4b525177756c7643633600072203fbd6085761f1d25c9b8c0785c77c337d5301cd22301c2cffd03a22688f8c0f4a7163506a57704c64726d4a694872147241707959576877486864784368535846744c49000606078d97cb5cf34b4554880e9c30a6759e947e00a408e61bbcb6a4d9101b13b23e720d586976787a6f6d545774464275124e666957684d6950725a4e4551506a67473600075d89a6aa63ef6ae338dfafd83332c1598b361b2f9a298a12ef8935f655b35e98016d045250554300071a56e1a6f20701ed54f1046fae8ec454c941bd584a438fa62119d1944b723b56126c467a5569644d426c496a766473566c4968037a5862000702786e6ae3354703196c1a1e64dda26e67562c6d3faf2d7b42161d4240bcceb10a50576a454e664463523012464270495a63774d73705943664650715a6700076b19b3b8bf936a8b2a278adebf4c3caa4c7e5ff2cc8961b62c3d89a52fc798d32155736552574b454f50585a6767414f43675847654d6852684f664e71505a4673391456776957424b6b506b4250424c55554a4f61453900060756709589a2ea4228622ae1a42b7c5d9c95ccf04bf0d13057e2ed3e422595ef35186d7750637144594a496864694163696b4d4277525a6c6e6813594a46425051704d776d52454272617879786200070105019501be01b3087762099c1411efb808ab9f6f1e1754dd0b100b3df99d75741908f3c7a2de4555f75d5a5cfcc76b428047e8d8da6f46dd02e55f86feab55d5a17141002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444036caf64fe036bdeac5f9826d8b57868dd0ffff2594aa133e3e6108c4b3286f169302909efb7b04cc4d28dc565494c5f00fc07c5eb74f8b97da6e8e4cf4bb1c0f", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "6b46acabc7c6ea6665d51a84a0b29fee090f40be5a588be4b740dee7e07341a4", - "sequence_number": "9796473743182989945", - "payload": { - "EntryFunction": { - "module": { - "address": "5f363cf6eefc06531ba344935f74745932e3d7d3f801df7347ca06a0faadbade", - "name": "XrmxWf9_Coin" - }, - "function": "HTncePbwJopzCMbygHV2", - "ty_args": [ { "vector": { "vector": { "struct": { - "address": "009572fcb80cca479f33ac5b36ac79f886487be9ea35cb5321b1f9cc32b0e96c", - "module": "olUQdxqygJGZXazFVcYH9", - "name": "wDLjWQgDJKjCNSTrEvDlccf4", + "address": "7c2104690336e006c862dde29270e3e598247185c4d1fa811a6eb18aba0c1788", + "module": "lAZjWllpJUOuOMOnBTvxRYwVrqLf", + "name": "NPjLGh9", "type_args": [] } } } }, { - "vector": { - "vector": { - "vector": { - "struct": { - "address": "ddb66ca4bc7058c2a06ca055d2d9cbf6025090a86c73b1494a89cc891400e98b", - "module": "MTKuSGIeFqIfHctedJ", - "name": "xlcWTPDMCJRTwBmzCl9", - "type_args": [] - } - } - } + "struct": { + "address": "977d2230a609d14c265d78d8fab839ea5bae5f4a000b639417f7d9e42f4ded86", + "module": "TeHwSyMATOTaTKrNiIYrRRiEd6", + "name": "QpKFkKxEnzr", + "type_args": [] } }, { "struct": { - "address": "787a181a21eacde79fce2af097fddf0616c98c211cc4c4c64f1db53a5412d9e6", - "module": "ZWrkuJhATGyAGneoFANNR", - "name": "hNfjhBOJcUJMJEzc8", + "address": "ec4d1807b5967831e69de5c0f5553dcb1ffef85d2f8bfb8a1f0129546e094f42", + "module": "Nwth1", + "name": "dGWdVGezJezKAgqwLAcL3", "type_args": [] } }, { - "vector": { - "struct": { - "address": "b4309529bdce0037abe4ccaa289dfe917d410c5c2b4ccdd9f4f41d16261c7e37", - "module": "usUjuN", - "name": "bkalkyOYGIfUKhTMrDeMxYSWZWu0", - "type_args": [] - } + "struct": { + "address": "c4e21773084d52cd25e68f1f24b4d3d814a600a52b1290a73a1f75ea161f7b9d", + "module": "WSoOUhKpypLMjIlZjbbIFDq1", + "name": "NODRBTChKIKLQLcURMxc4", + "type_args": [] + } + }, + { + "struct": { + "address": "f5c831952a512a1bd23f1e53d078341dd791dcf6ed40542ced7c78017176bfa7", + "module": "wnxutxfOpuSgcIzEcxWBKQfWtXiz", + "name": "QBmjhMuLmqXTqChBpyfKWSRfYIEI", + "type_args": [] + } + }, + { + "struct": { + "address": "add5a2dfbde0da7202c4843177bb1700f11e4c5215205c20a7e203e67dbdac1d", + "module": "iKvUdrarqgnSPsMMAicdHRRwFUsMZbJb0", + "name": "KxPTMIGhtrisCqcdgjGWbSPoiv5", + "type_args": [] } } ], "args": [ - "01", - "8670b6c923b144b6", - "97dbaa52a5a74d6d2d2333de62c81a216bddffb54ae0048842725f069a54dd6a", - "d0e9700e061be3d7e54be431e37ed6e7", - "cceb4a5bd3a72f83", - "d5b445bfd2013b5e795118a54cc922f76554c8b4df4f9704476bbc5070ddd3cd", - "6fab1d57bb6ab5a2a099b0972246d34a3d0a268b00cfaeaf7a399671e22d9c97" + "61c590b05ab0bc3b8caa40aa2ddf5bc23bd14cbe0b5dbdac699162e6e039204a", + "dd5e76d8b6ae636786bc5bc9d61a2777c838c72f701a38cb961307c351145ae3", + "cea665f861d76cf9", + "ac", + "e882985920444ec205b93e6a30e6d4b5adeb8e0b53a317d1307aa3b7d494051c", + "275a97c225b3b237e8798414411602946592b8d545772a9ecabdfb2e258a4d7e", + "551699eb38ad6d33", + "eb197aa234e255ce", + "f135b94b8aa0a209", + "c1" ] } }, - "max_gas_amount": "5809823051666828294", - "gas_unit_price": "1424962271267863624", - "expiration_timestamp_secs": "8336870702502479669", - "chain_id": 74 + "max_gas_amount": "6958953391503829005", + "gas_unit_price": "17028215654876135447", + "expiration_timestamp_secs": "17144117674252706486", + "chain_id": 123 }, - "signed_txn_bcs": "6b46acabc7c6ea6665d51a84a0b29fee090f40be5a588be4b740dee7e07341a4790add29f710f487025f363cf6eefc06531ba344935f74745932e3d7d3f801df7347ca06a0faadbade0c58726d785766395f436f696e1448546e63655062774a6f707a434d62796748563204060607009572fcb80cca479f33ac5b36ac79f886487be9ea35cb5321b1f9cc32b0e96c156f6c555164787179674a475a58617a4656635948391877444c6a575167444a4b6a434e5354724576446c636366340006060607ddb66ca4bc7058c2a06ca055d2d9cbf6025090a86c73b1494a89cc891400e98b124d544b75534749654671496648637465644a13786c63575450444d434a525477426d7a436c390007787a181a21eacde79fce2af097fddf0616c98c211cc4c4c64f1db53a5412d9e6155a57726b754a684154477941476e656f46414e4e5211684e666a68424f4a63554a4d4a457a6338000607b4309529bdce0037abe4ccaa289dfe917d410c5c2b4ccdd9f4f41d16261c7e37067573556a754e1c626b616c6b794f59474966554b68544d7244654d785953575a57753000070101088670b6c923b144b62097dbaa52a5a74d6d2d2333de62c81a216bddffb54ae0048842725f069a54dd6a10d0e9700e061be3d7e54be431e37ed6e708cceb4a5bd3a72f8320d5b445bfd2013b5e795118a54cc922f76554c8b4df4f9704476bbc5070ddd3cd206fab1d57bb6ab5a2a099b0972246d34a3d0a268b00cfaeaf7a399671e22d9c97062c7aa248a3a050483c41cda27bc613358705b9bb83b2734a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444059aed456ade6e5680ed5cf6bf24828ec6a46e12e2939997ba81290dd1a2fcd8e0f043c28d4e4b59da4a8f55209308b5836baa93c29b0bd013657b81c197c0b09", + "signed_txn_bcs": "ed25163dbc552d6996903246d7a3207b2aa2f824b20ddd28a53c2132dab3df013b798a12110a19b80261ad29837b7abce25de582660f9b366d3a62782b98ba0d9948f893bb748b4f9b2153694e4156437a4873434a6d495865467954505a626858466f6f4b335f436f696e0a744f64757250566875770a060607775249248fd67146bd015e9ba8f4e5b85b713a6ed7e06d521e12b7340015236d18544d6c74556949724a4b56546a6d686b577252614756474d1364514d687378664b486e55577675524c4d575a0007add6ee76d7116858b00ed5da2ebad5b8263e76a15969a5a1e7dd5339a5ed26a6106e4343414e4157544355534e56496b321f654a485572667a4574795a6670506863507843447262444778646c7a5079310007b2f14cc33b042cdaa6634447da83cc8e8af0d19c678f7ad9bffab1086d5f99e70e57736a6d4e636b6f4f6b455659350a4151556a5568584441320007c1f015afdff9e9ef96014fad5557eab5b66b7f3d1e23850459cac859019a70a4026d74095271495344526f6e61000606077c2104690336e006c862dde29270e3e598247185c4d1fa811a6eb18aba0c17881c6c415a6a576c6c704a554f754f4d4f6e425476785259775672714c66074e506a4c4768390007977d2230a609d14c265d78d8fab839ea5bae5f4a000b639417f7d9e42f4ded861a5465487753794d41544f5461544b724e694959725252694564360b51704b466b4b78456e7a720007ec4d1807b5967831e69de5c0f5553dcb1ffef85d2f8bfb8a1f0129546e094f42054e7774683115644757645647657a4a657a4b416771774c41634c330007c4e21773084d52cd25e68f1f24b4d3d814a600a52b1290a73a1f75ea161f7b9d1857536f4f55684b7079704c4d6a496c5a6a62624946447131154e4f4452425443684b494b4c514c6355524d7863340007f5c831952a512a1bd23f1e53d078341dd791dcf6ed40542ced7c78017176bfa71c776e78757478664f7075536763497a45637857424b5166577458697a1c51426d6a684d754c6d715854714368427079664b57535266594945490007add5a2dfbde0da7202c4843177bb1700f11e4c5215205c20a7e203e67dbdac1d21694b76556472617271676e5350734d4d41696364485252774655734d5a624a62301b4b7850544d4947687472697343716364676a47576253506f697635000a2061c590b05ab0bc3b8caa40aa2ddf5bc23bd14cbe0b5dbdac699162e6e039204a20dd5e76d8b6ae636786bc5bc9d61a2777c838c72f701a38cb961307c351145ae308cea665f861d76cf901ac20e882985920444ec205b93e6a30e6d4b5adeb8e0b53a317d1307aa3b7d494051c20275a97c225b3b237e8798414411602946592b8d545772a9ecabdfb2e258a4d7e08551699eb38ad6d3308eb197aa234e255ce08f135b94b8aa0a20901c10de8154d3d2b93601740a333eb5f50ecb62254f93024eced7b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d1073cd64b85de881312847f0856b9c9c170c2a5f34887fa95c587f7dd42ed1632d048f60072a79cba426b8db12d04f17519490c1b12632fa4a8e34c05e8140a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "e50cf2f58c8f60f51778ded644606ec4c51179114d9837196addc43f1d924407", - "sequence_number": "5969652622676644968", + "sender": "a42daed21bdedd449e3c50a9c59393c7c0837a733ca640360d6aa41c19a2bb82", + "sequence_number": "962110457275232569", "payload": { "EntryFunction": { "module": { - "address": "1315b5634efb86a795e4749502a4ff68ae21be5eacafdd0918a62ae30b2cee16", - "name": "QEwKmxRbKqGf_Coin" + "address": "18555a7871db21a99322bb78de2e6ee32a9177e3adc1b3cf4a95daa28d99620e", + "name": "jKxRkeyEwloYVNYHsOU_Coin" }, - "function": "wNJssxWYothgPcCvzFSShzGow4", + "function": "bvbStM8", "ty_args": [ - { - "vector": { - "vector": "u64" - } - }, - { - "struct": { - "address": "b6a9ffe42c37328236ded3541f53c4dfcafc1ed2b98e8ae60d88a924d4358770", - "module": "KJgeafEmPj9", - "name": "VcHIpsG2", - "type_args": [] - } - }, - { - "struct": { - "address": "1dcc7e87dd156b95fcde81923c41229cb6597fe4a02adf40edb8447cdc4a3ca3", - "module": "EjtGgJAiABYrDtiTwU4", - "name": "rBhRXVdUsUDUkMFeBxjaErKaJGZa", - "type_args": [] - } - }, { "struct": { - "address": "63214b2b7d07b27bcf2046f258649a57f340bb0e0ab053cb715bcc17a1315514", - "module": "tFiU2", - "name": "MeAVZYYLSIfQoayzcG", + "address": "949f538bf19fd0d70ec0510b59cb529074f9a2fff15baa89958bec15aa733701", + "module": "ijUWsk9", + "name": "CtPsMrSIcpHNItzJbOOHgnVooHF", "type_args": [] } } ], "args": [ - "9536a1911eda0576", - "5aa2fd34b33a6339" + "00", + "7f75155ae7c9efcaafe38ca5c356d10e", + "a7c4b617e463e05e", + "05c0a1bded20a406484b9a11764c6c06", + "ecfb00e9235da9cd7864b76f6e61fed7", + "4b7688f02fddeddd", + "01", + "33", + "4bf362b461c53493" ] } }, - "max_gas_amount": "1529263278239304793", - "gas_unit_price": "12665888032592171223", - "expiration_timestamp_secs": "16745816932938102590", - "chain_id": 57 + "max_gas_amount": "6693488240307777576", + "gas_unit_price": "14234577073664709025", + "expiration_timestamp_secs": "488493618113310900", + "chain_id": 188 }, - "signed_txn_bcs": "e50cf2f58c8f60f51778ded644606ec4c51179114d9837196addc43f1d92440768d41e876e77d852021315b5634efb86a795e4749502a4ff68ae21be5eacafdd0918a62ae30b2cee16115145774b6d7852624b7147665f436f696e1a774e4a73737857596f746867506343767a465353687a476f77340406060207b6a9ffe42c37328236ded3541f53c4dfcafc1ed2b98e8ae60d88a924d43587700b4b4a67656166456d506a3908566348497073473200071dcc7e87dd156b95fcde81923c41229cb6597fe4a02adf40edb8447cdc4a3ca313456a7447674a416941425972447469547755341c7242685258566455735544556b4d466542786a6145724b614a475a61000763214b2b7d07b27bcf2046f258649a57f340bb0e0ab053cb715bcc17a1315514057446695532124d6541565a59594c534966516f61797a63470002089536a1911eda0576085aa2fd34b33a633959cc8063d9083915d71087130f46c6af3e377f01c71765e839002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ceda275cafb02f650b06e82765eaf41a7c98eb20dc9efb5f376b5a1ce46415d91d8209bf7cad2ff7a1b9650f46a16cc4f0f021013d6e0dcd0ae89424c833fa09", + "signed_txn_bcs": "a42daed21bdedd449e3c50a9c59393c7c0837a733ca640360d6aa41c19a2bb82393194085d1a5a0d0218555a7871db21a99322bb78de2e6ee32a9177e3adc1b3cf4a95daa28d99620e186a4b78526b657945776c6f59564e5948734f555f436f696e0762766253744d380107949f538bf19fd0d70ec0510b59cb529074f9a2fff15baa89958bec15aa73370107696a5557736b391b437450734d7253496370484e49747a4a624f4f48676e566f6f484600090100107f75155ae7c9efcaafe38ca5c356d10e08a7c4b617e463e05e1005c0a1bded20a406484b9a11764c6c0610ecfb00e9235da9cd7864b76f6e61fed7084b7688f02fddeddd01010133084bf362b461c5349328b0cc47170ce45ca151b4336e608bc5b470b0865b7ac706bc002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144407a9335924968b0732f5a080b358a1c9a23d01e23338a8a0812bfd0891682f40d718e8868e6a703c308398ba948a792f8b0b0e4c862dc324217170bade0fa6207", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" } ] diff --git a/api/goldens/aptos_api__tests__transaction_vector_test__test_script_payload.json b/api/goldens/aptos_api__tests__transaction_vector_test__test_script_payload.json index 12d27c6ad06..e471267bfa6 100644 --- a/api/goldens/aptos_api__tests__transaction_vector_test__test_script_payload.json +++ b/api/goldens/aptos_api__tests__transaction_vector_test__test_script_payload.json @@ -1,346 +1,371 @@ [ { "raw_txn": { - "sender": "3677c13bc493651612ace666edf6df7d5487b8c879190e076e9ad821df7b10c1", - "sequence_number": "7368908614509515972", + "sender": "2729dccd25b898c50a4817ac2e2da58483cc8ce1a5fa27c38e49ad5467c2f62c", + "sequence_number": "5705042828739947510", "payload": { "Script": { - "code": "d14669faf5d7bcc3e0ef6f2b5fbf4e", + "code": "140f8872", "ty_args": [], "args": [ { - "Bool": true - }, + "U128": "261704167350626216139117546641434913030" + } + ] + } + }, + "max_gas_amount": "13830445450937936658", + "gas_unit_price": "12586797386046485072", + "expiration_timestamp_secs": "717113376446464636", + "chain_id": 71 + }, + "signed_txn_bcs": "2729dccd25b898c50a4817ac2e2da58483cc8ce1a5fa27c38e49ad5467c2f62cf62b6fe339622c4f0004140f887200010206a9908b8499aa41290f83b3a563e2c412ab925cdc9cefbf50b21def8849adae7cc2c502d1b2f30947002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444019e332a536e7a5319ff7935050262a5782743122074ea1dec72e396f9c332b77cb7e570751e2bf7fc6f151c347c6522c4b3571f587f90ee7f8d8d3d26ab2450c", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "2a1a0ccf1756448be98bd597c5ed528d3d6da03cfb63e9a2ea40507a83593ac5", + "sequence_number": "16614609060284234275", + "payload": { + "Script": { + "code": "b3c2b6a493a64a", + "ty_args": [ { - "U8Vector": "1ada43" + "vector": { + "struct": { + "address": "8713ef270a2c14cca1e2887d73a54b32671c2708971cf076d40326aac136fce4", + "module": "S3", + "name": "YvJFrYPdeKTvW", + "type_args": [] + } + } }, { - "Address": "cc8b2b138d80f546f8acf863d0485e58082290a8e418e93c0c79784c0a98ccbc" + "struct": { + "address": "4a2d581f1f10299989d0a73bf6665aa46e3242c19ef02cee8612c5e189318f61", + "module": "RWhyXlQlZOrxTtogqfPa", + "name": "zHyS", + "type_args": [] + } }, { - "Bool": false + "struct": { + "address": "cb9d5c0e6a5ed6f8860e0e27660a2b712e0254b1b86ee1dc2d20e98ee41c088a", + "module": "WpvvErMMQKulDxAeAi5", + "name": "cMD3", + "type_args": [] + } }, { - "U128": "315385698958223888496209828405063395858" + "struct": { + "address": "ea12520a6c2df57589429329b35154a30cc8a24eaa7fec9fd8dba1fbf6615d4b", + "module": "DBWEotdUgxeFGOmSgXVanZgmmjNIq6", + "name": "UepisP", + "type_args": [] + } }, { - "Bool": false + "struct": { + "address": "6bba16f836d6fd28be7403e6da1f1740b3274a727934637d853b8642c789c387", + "module": "ZlORXKfXpwkK", + "name": "Bqwr", + "type_args": [] + } }, { - "U8": 62 + "vector": { + "vector": { + "vector": "signer" + } + } }, { - "U8": 160 + "vector": { + "struct": { + "address": "37b4cf18e28c88a631cbee996ed7236addecc4327a1f889caf5480810049fba8", + "module": "YyKMOivPyELeAeLbWOnQEneOXF", + "name": "aUMdXCqRF", + "type_args": [] + } + } }, { - "U8": 216 + "struct": { + "address": "4e36310b49e197b6ba356f28da0af750165c98a4090e831de802db5b9f658be3", + "module": "obpiLuLpynLeiySvAoGdddUZRvIY", + "name": "JgbqmslEqliXE4", + "type_args": [] + } + } + ], + "args": [ + { + "Address": "3bcb2090dc01c4e2f6c6601047e5df19d2395188bc788e57184e12a7c2157076" } ] } }, - "max_gas_amount": "3632834521076475754", - "gas_unit_price": "12742885074082071529", - "expiration_timestamp_secs": "12222167853736003849", - "chain_id": 232 + "max_gas_amount": "7870293755328302448", + "gas_unit_price": "10031130616132128983", + "expiration_timestamp_secs": "1873221992609571222", + "chain_id": 14 }, - "signed_txn_bcs": "3677c13bc493651612ace666edf6df7d5487b8c879190e076e9ad821df7b10c1c4d427be579f4366000fd14669faf5d7bcc3e0ef6f2b5fbf4e0009050104031ada4303cc8b2b138d80f546f8acf863d0485e58082290a8e418e93c0c79784c0a98ccbc050002122a57179bf2e9d4156b48957f1345ed0500003e00a000d86a278ad4bf6b6a32e9034ace75d2d7b00909223be8dc9da9e8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fae8669b12f59ff55096893b9f6a30df5e11f81fb00d3477ef94bfa5aa7d6975e6f719132e4ba950c87c2d84467aa6d37b1b210f910709d37cd0d99c594f5a0d", + "signed_txn_bcs": "2a1a0ccf1756448be98bd597c5ed528d3d6da03cfb63e9a2ea40507a83593ac5237a3a90e9f292e60007b3c2b6a493a64a0806078713ef270a2c14cca1e2887d73a54b32671c2708971cf076d40326aac136fce40253330d59764a4672595064654b54765700074a2d581f1f10299989d0a73bf6665aa46e3242c19ef02cee8612c5e189318f611452576879586c516c5a4f727854746f6771665061047a4879530007cb9d5c0e6a5ed6f8860e0e27660a2b712e0254b1b86ee1dc2d20e98ee41c088a135770767645724d4d514b756c4478416541693504634d44330007ea12520a6c2df57589429329b35154a30cc8a24eaa7fec9fd8dba1fbf6615d4b1e444257456f74645567786546474f6d53675856616e5a676d6d6a4e4971360655657069735000076bba16f836d6fd28be7403e6da1f1740b3274a727934637d853b8642c789c3870c5a6c4f52584b665870776b4b04427177720006060605060737b4cf18e28c88a631cbee996ed7236addecc4327a1f889caf5480810049fba81a59794b4d4f69765079454c6541654c62574f6e51456e654f58460961554d64584371524600074e36310b49e197b6ba356f28da0af750165c98a4090e831de802db5b9f658be31c6f6270694c754c70796e4c6569795376416f47646464555a527649590e4a6762716d736c45716c695845340001033bcb2090dc01c4e2f6c6601047e5df19d2395188bc788e57184e12a7c2157076708d51cc78e6386dd7d019ee25bc358b9661f13e7a05ff190e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444017f34220abb3d7c7af5f2a94316b97ebf086d12d25fbb896361473d957ed5f87481df0568a8f7caf0c5596aa99d51a0ced192d1a568ac18652636c82331bb603", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "7ac465126a334a70eee1b07d1a1989771e1518edc598e263e24150e59c4f0f6f", - "sequence_number": "13441949339655375926", + "sender": "a7cca0278bb399cfa9ee82a0eea6c90cfa20a7bcbfd9b60b4c87d65cf28bbb51", + "sequence_number": "5310585696735356372", "payload": { "Script": { - "code": "d873cf24d7ad9a749d9aa5cd29f5e8cb", + "code": "d0", "ty_args": [ { - "vector": { - "vector": "bool" + "struct": { + "address": "9a6f279399cf5d6e585e9a87fde31cdb49362e8835569bcba367f3709feecc2a", + "module": "OXwfUsxKF2", + "name": "vOxvMzbkmUpVGIiSUMNBvXqDDL", + "type_args": [] } - } - ], - "args": [ - { - "Bool": true - }, - { - "U8Vector": "01d042c4" }, { - "U8": 192 + "vector": "bool" }, { - "U64": "617923059089471977" + "vector": { + "struct": { + "address": "dee55c3b1b7a1616f3661ba2d5d8ee931999c75881fa59bc3d06da50a289c9c1", + "module": "nZklZhKAwcx", + "name": "ZaqGZLXqbVIez", + "type_args": [] + } + } }, { - "U64": "1598632091548018378" + "struct": { + "address": "89e8154e9f0ab0f0edd4ca6a08109679c84989d6f0d4dac289826566d76ed712", + "module": "x0", + "name": "tMeP8", + "type_args": [] + } }, { - "U64": "16796681836754028853" + "struct": { + "address": "2a4340fabbdda0b6348a6c806f39103cf15787ba8173747a54d40d3355dca586", + "module": "BaPmNIaQwnaOzxFlw", + "name": "xClSXgXEGfJOFYZOtnjgBFNsDsQsAT1", + "type_args": [] + } }, { - "Address": "5eac1204eded4d878683d24ea4b48d8f606e6e4ac01c5100865ba04dc798226c" + "vector": { + "struct": { + "address": "4f765754fcd331bca469603a4af73603539a5bf5e9f1e5da8582c1a434fe94a9", + "module": "VSKgoNxnGwVNrVzOqAjIU5", + "name": "SdmcUYZrd", + "type_args": [] + } + } }, { - "Address": "bc53656662b19e30a91463bd658e7dad8cd266507a8991812cc5f4530268d3c0" + "vector": { + "struct": { + "address": "c5dd214165b0115f0e0fb21e6e23f29321c5cfc5665b527e9facbe093f5902af", + "module": "AuZMhKSHnVBdEaxjBh4", + "name": "qVKuEsAhMWQSUOImiDvIwPUKkw9", + "type_args": [] + } + } } - ] - } - }, - "max_gas_amount": "2379161332701705344", - "gas_unit_price": "15831352416342365390", - "expiration_timestamp_secs": "12632939087256464513", - "chain_id": 222 - }, - "signed_txn_bcs": "7ac465126a334a70eee1b07d1a1989771e1518edc598e263e24150e59c4f0f6f368cf4b6b4658bba0010d873cf24d7ad9a749d9aa5cd29f5e8cb01060600080501040401d042c400c001e9f98c93bf4d930801ca6642d76a7b2f160135c9fa4c23cd19e9035eac1204eded4d878683d24ea4b48d8f606e6e4ac01c5100865ba04dc798226c03bc53656662b19e30a91463bd658e7dad8cd266507a8991812cc5f4530268d3c080b40773a07a0421ced41b022543b4db81ac11ed2a3751afde002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440818825720e7bd76df57e1ff092bf82f5275b7fdc9c30d0747989b4eb0a52be706c27775bdac614a433b098ca52be51d4fe7f96dc7b78a46ddc32a2eb6fe04004", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "c1ba58be8f01dae46304ef12e16f5ef0edcf7e41e745a4e2449a061797a804dc", - "sequence_number": "9388239715593337979", - "payload": { - "Script": { - "code": "4d2a7adaf0540f0f2b85e0acc2cd", - "ty_args": [], + ], "args": [ { - "Address": "30571cb038bae02be546e861058a5c326108632029a7ab397ad2c581df4e8fde" + "U128": "25680354967437262440103972820965337728" }, { - "Bool": true + "U8Vector": "a26bde0ea1eaae47120ad576faa9" }, { - "U128": "315909425913736247369136596642703600253" + "U8": 162 }, { - "U8Vector": "132c7da6" + "U64": "1305168316212991399" }, { - "U128": "2920741250566672498145397932276312518" + "Address": "046214b96f7e55a6ed579b630f38a740bc6f8ec0b7cbaccdd8150c2f0ee72ece" }, { "Bool": false }, { - "U128": "195793708823119404329594645648077531660" - } - ] - } - }, - "max_gas_amount": "15156470291225489005", - "gas_unit_price": "12860663242782441493", - "expiration_timestamp_secs": "9814150118819918291", - "chain_id": 173 - }, - "signed_txn_bcs": "c1ba58be8f01dae46304ef12e16f5ef0edcf7e41e745a4e2449a061797a804dc7bbc27c247ba4982000e4d2a7adaf0540f0f2b85e0acc2cd00070330571cb038bae02be546e861058a5c326108632029a7ab397ad2c581df4e8fde0501027dea5fd946c645eee0a9471b3bf1a9ed0404132c7da602c6e9eff28181510de1a2b063a98332020500020caae81f7d51aeb1540c810f267f4c936dae416d6d9956d21580f8a114417ab2d3719e1489dd3288ad002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bf81c2ababc8192cf17a91ceefaee539c3004906d1391c1d78a34b1e218b6fcc2668bb06f88c200f7213b7e72b5a9d733313513046bbadedc66628cf82c18e0d", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "c48a7e4388eeb87b4911d0d7e06d71bde41140470e89185e2c2c427d07d0f837", - "sequence_number": "11109762177366031093", - "payload": { - "Script": { - "code": "a122d96f968ebca5", - "ty_args": [], - "args": [ + "Bool": false + }, { - "U128": "45077997921317895071198074102829683367" + "Bool": false }, { - "U8": 167 + "U128": "194090749148390769775460304387217641849" }, { - "U128": "94599078468267412910149511684199585296" + "Bool": false } ] } }, - "max_gas_amount": "3220965574846946392", - "gas_unit_price": "3980648369345363322", - "expiration_timestamp_secs": "10188780789372192095", - "chain_id": 66 + "max_gas_amount": "4879103659518400818", + "gas_unit_price": "10044714951574220916", + "expiration_timestamp_secs": "18004133680754939116", + "chain_id": 192 }, - "signed_txn_bcs": "c48a7e4388eeb87b4911d0d7e06d71bde41140470e89185e2c2c427d07d0f837f5faf898d6cd2d9a0008a122d96f968ebca5000302a7127add6dec2f483cd8a3eee3b4e92100a70210967484f95d1b2b9e5eddc6aa1e2b47589c83fa1f2bb32c7a7d91fe991a3e375f85da3c25d2658d42002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440803c5c4b9aafe22535c018121013a577d3d6120a0cd78120552d7ee67045f23c0fa1b8c15e1d1862b8d09f47d023beb84cc230f10b458872324f263292d6000f", + "signed_txn_bcs": "a7cca0278bb399cfa9ee82a0eea6c90cfa20a7bcbfd9b60b4c87d65cf28bbb51d4652ef38dfdb2490001d007079a6f279399cf5d6e585e9a87fde31cdb49362e8835569bcba367f3709feecc2a0a4f5877665573784b46321a764f78764d7a626b6d55705647496953554d4e4276587144444c0006000607dee55c3b1b7a1616f3661ba2d5d8ee931999c75881fa59bc3d06da50a289c9c10b6e5a6b6c5a684b417763780d5a6171475a4c5871625649657a000789e8154e9f0ab0f0edd4ca6a08109679c84989d6f0d4dac289826566d76ed71202783005744d65503800072a4340fabbdda0b6348a6c806f39103cf15787ba8173747a54d40d3355dca586114261506d4e496151776e614f7a78466c771f78436c535867584547664a4f46595a4f746e6a6742464e73447351734154310006074f765754fcd331bca469603a4af73603539a5bf5e9f1e5da8582c1a434fe94a91656534b676f4e786e4777564e72567a4f71416a4955350953646d6355595a7264000607c5dd214165b0115f0e0fb21e6e23f29321c5cfc5665b527e9facbe093f5902af1341755a4d684b53486e5642644561786a4268341b71564b75457341684d575153554f496d694476497750554b6b7739000a02802a8f0cc5d058be1af15f0e41db5113040ea26bde0ea1eaae47120ad576faa900a201a755f823abe31c1203046214b96f7e55a6ed579b630f38a740bc6f8ec0b7cbaccdd8150c2f0ee72ece05000500050002795105e5e2647a5556e97117c184049205003219e77fed0eb64374f0a27e07ff658bec540b523188dbf9c0002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e07ef3e5c7f5363ac19b49de4e2c74daa7e0dc4d0a5a72fa551393dc7b4b193a6ac3d162504df0afdac73429cfb7c8ea2192f8f89cb5316171b592e487650005", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "bb0ba357d91acbb2f5f0a7b988f5ae9a5bea8c18a9a5ce5c5a2513cc57314cba", - "sequence_number": "6093216383570124492", + "sender": "0486f7685ce6042bebdac89fd9fce7cd5cb6663129764401e3448d162b0031d6", + "sequence_number": "665348431662327138", "payload": { "Script": { - "code": "9f3ee6a2df1da127bee0e32fdd5ff4", + "code": "cf8cf3", "ty_args": [], "args": [ { - "U8": 126 + "U64": "11707063606211854951" + }, + { + "U128": "139620163540106684070863785733306811456" + }, + { + "U128": "111931529506956067538841559824815852142" + }, + { + "Bool": false + }, + { + "U8Vector": "04bdeebfdc35eb" + }, + { + "Address": "c9db5e6e2c0079a6d255f07b997471c4cfc36417dd58fa94b1cff6b7ee6e9357" }, { - "U8": 252 + "U8Vector": "a8cdc5dcdc" } ] } }, - "max_gas_amount": "1625956033161485284", - "gas_unit_price": "13144010732074727349", - "expiration_timestamp_secs": "197079322304101729", - "chain_id": 38 + "max_gas_amount": "1083417168633788325", + "gas_unit_price": "1923148079119374375", + "expiration_timestamp_secs": "4591469829133248893", + "chain_id": 193 }, - "signed_txn_bcs": "bb0ba357d91acbb2f5f0a7b988f5ae9a5bea8c18a9a5ce5c5a2513cc57314cbacc9e498204748f54000f9f3ee6a2df1da127bee0e32fdd5ff40002007e00fce45bfec0658e9016b5773cf11ee868b661bd8276992abc0226002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a06b4362aac78a7d1c35aee2d2c9dad50c933ff2fafd3c38b555d17020df09e417fce322ca008244a91e8b8ab0bd3703a537f9d65442f224a0675cb214fddd0a", + "signed_txn_bcs": "0486f7685ce6042bebdac89fd9fce7cd5cb6663129764401e3448d162b0031d662a51899dfca3b090003cf8cf3000701674229bb52d877a2024084a5a647bb85d80e59c38e89dd0969026e8a6bc7aeb0b0c03236b9087b3a35540500040704bdeebfdc35eb03c9db5e6e2c0079a6d255f07b997471c4cfc36417dd58fa94b1cff6b7ee6e93570405a8cdc5dcdca5f7f9b72c12090f2798621afd64b01a7d2969a27b2db83fc1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440cbaed7a0fdfe7bce9ef37dce398c8effaf69b4e55401f893defd89263f98312a6d1f6fad2b1c3e1e4deaa5a383e83ef2f6a592b62ea1ab4438d53fda06804a0b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "e07128e285ac3faa0dd2dfee7664b266b296ad121a58ce14affd267e6e82f0cb", - "sequence_number": "17784040071166682866", + "sender": "1a58ce14affd267e6e82f0cbf23810e5949a23a8ae74b6ed1c56ab183db9c3fd", + "sequence_number": "2456727406725119419", "payload": { "Script": { - "code": "2ec0711303", + "code": "f3e7b6e3a6b2b53da76dc9", "ty_args": [ { "vector": { "vector": "u8" } }, - { - "vector": { - "struct": { - "address": "f7685ce6042bebdac89fd9fce7cd5cb6663129764401e3448d162b0031d662df", - "module": "oYezCOpm", - "name": "CCfVnyTZRPIQiIshitFGtfMxcMDvjY", - "type_args": [] - } - } - }, { "struct": { - "address": "817f8b397e18c6976e19930e6ee32d02fe15fddcd3f3c147d21a25d40e36b5f3", - "module": "yNNPhfaMRtNQMgW6", - "name": "lfrRILbqMaLRMeWPqwDoQxtLslCurkL1", + "address": "e9ba2bc7dfe32acfe41ab6d433b327feb8ecaa9493803032f9de6d852ae78c4e", + "module": "pCQBcWjHieaAvLGpMAtbSVO8", + "name": "xMVlkxypvn", "type_args": [] } }, { - "vector": { - "vector": "u64" - } - }, - { - "vector": { - "vector": "bool" + "struct": { + "address": "faad1bf563f2deacb647cd571ffec31d31e460d7c16f1c19afd2a1432027935c", + "module": "Jc", + "name": "QGQwaKDOjRsbZWQbwdYcVQHoaEokDcix", + "type_args": [] } }, { "struct": { - "address": "45317b4503af22c72ceafc748c84a2ab6c83c75fc9a070cbf0f91067028380b2", - "module": "QQevQeQbQw0", - "name": "WzDFa4", + "address": "a13e92589ba3e02a71e2a29e20c3747b7ef84cdbd971eb1e97c0199215c685ec", + "module": "WqjVIkkkwChmIqtTsvTB", + "name": "ZzEwAuItNuyahCbzv", "type_args": [] } }, { "struct": { - "address": "68150a87dea4460a5c3760070a38003f78f7ebb012661fd8a762f284dbff22db", - "module": "Ss0", - "name": "sExASogoTWc", + "address": "decde1f145317b4503af22c72ceafc748c84a2ab6c83c75fc9a070cbf0f91067", + "module": "GIlQARFPNbhsUeQGmuxd8", + "name": "jhQUDqUqYoRH7", "type_args": [] } } ], "args": [ { - "U8": 179 + "Address": "964d43a10e68dc5948292613116170513e9ba4afa713c0f545a0f11d8b2ca978" }, { - "U128": "41913946970560315782656879538600815227" + "U8Vector": "cce80534" }, { - "U128": "30241266543890506402994956609964705390" + "U8": 18 } ] } }, - "max_gas_amount": "13609061798892567444", - "gas_unit_price": "4445232778290510883", - "expiration_timestamp_secs": "8402715135250614288", - "chain_id": 174 + "max_gas_amount": "3664686011449254850", + "gas_unit_price": "15579694643738237657", + "expiration_timestamp_secs": "13256897693341282297", + "chain_id": 38 }, - "signed_txn_bcs": "e07128e285ac3faa0dd2dfee7664b266b296ad121a58ce14affd267e6e82f0cbf2e63389389acdf600052ec0711303070606010607f7685ce6042bebdac89fd9fce7cd5cb6663129764401e3448d162b0031d662df086f59657a434f706d1e434366566e79545a52504951694973686974464774664d78634d44766a590007817f8b397e18c6976e19930e6ee32d02fe15fddcd3f3c147d21a25d40e36b5f310794e4e506866614d52744e514d675736206c667252494c62714d614c524d6557507177446f5178744c736c4375726b4c31000606020606000745317b4503af22c72ceafc748c84a2ab6c83c75fc9a070cbf0f91067028380b20b515165765165516251773006577a44466134000768150a87dea4460a5c3760070a38003f78f7ebb012661fd8a762f284dbff22db035373300b73457841536f676f545763000300b3027b2adec82922e4795c3397602255881f026e86271dfd2be67734bbda698e41c016947b54299a19ddbc23bcedf5a8a3b03d10486961e5709c74ae002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401cb34c68fa5060af7f805c5a86cd6363f64b0bc25b291a5ac0a60e6165856b67dd16209cd97a85853f00a57e95f7d0b1ee8ae4c874e6edf821d339367b546d09", + "signed_txn_bcs": "1a58ce14affd267e6e82f0cbf23810e5949a23a8ae74b6ed1c56ab183db9c3fdbb3dd1638f0c1822000bf3e7b6e3a6b2b53da76dc90506060107e9ba2bc7dfe32acfe41ab6d433b327feb8ecaa9493803032f9de6d852ae78c4e187043514263576a4869656141764c47704d41746253564f380a784d566c6b787970766e0007faad1bf563f2deacb647cd571ffec31d31e460d7c16f1c19afd2a1432027935c024a632051475177614b444f6a5273625a575162776459635651486f61456f6b446369780007a13e92589ba3e02a71e2a29e20c3747b7ef84cdbd971eb1e97c0199215c685ec1457716a56496b6b6b7743686d4971745473765442115a7a4577417549744e7579616843627a760007decde1f145317b4503af22c72ceafc748c84a2ab6c83c75fc9a070cbf0f910671547496c51415246504e626873556551476d757864380d6a68515544715571596f524837000303964d43a10e68dc5948292613116170513e9ba4afa713c0f545a0f11d8b2ca9780404cce805340012c2a3c6d58294db32d9da12d5bb3136d8f96f4dcb36f6f9b726002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f25ff5407d7efd132feac98e712957c7ad2bd5b13cbd63a0c62f0c511cc775b34530a44c9915c40d59fda7a6cc5c0c1976ff6c947b24d2ab2e9c37eef1559d0e", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "1f8e6a9fa279601985378ee664f2348d551ab93a96e6f70bcf771b234c23bfe0", - "sequence_number": "16950474678649250918", + "sender": "2aabddb611f372855b53d7e160c266cda6010b855e2a4f8641bc3f8e01a399e3", + "sequence_number": "4608167762538335583", "payload": { "Script": { - "code": "d29d157c4fd8bc", + "code": "42f91d7c2bfeec4dfdb0fefb", "ty_args": [ { "vector": { - "struct": { - "address": "05ecfc3048baf2edccacddbfe85b751f5582795cd472e392337cd245b6f2aada", - "module": "YNCGGjPIwQgLPmwrEL7", - "name": "YzQEdhxbqWsWZZFpTzRqCaZKaRPFOjxM2", - "type_args": [] + "vector": { + "vector": "u8" } } }, { - "vector": { - "vector": "u8" + "struct": { + "address": "7ba4b4100047139fc611ff753fe48861986324b6dbbf242675a18d06a36f4960", + "module": "OtCchPZxHm", + "name": "SqGMsrtEKaSfGZvUYIbdnHoVCtKGrykp5", + "type_args": [] } }, { "struct": { - "address": "277f1829044362989e4b910e041d097b57a14f62ee36bc620168d62da4eb7302", - "module": "iwzUkFwVWiTwAAwROlmPTYwDObVsSUP", - "name": "MlDaEdfRgtSmrtkmJvdVpewARsuVkV5", + "address": "48f0cb8524e1bff3790a9a4cbf2b94051ac76bf86eb3ac285fe4b2e545ffcdad", + "module": "TpTEasGAPRawKeJyKqb3", + "name": "NTektcsw", "type_args": [] } - } - ], - "args": [ - { - "Bool": true - }, - { - "U128": "228895819552789049808880313259319031790" - }, - { - "U64": "6732905901992753485" }, - { - "U64": "5422052687078449972" - } - ] - } - }, - "max_gas_amount": "9178518397033043993", - "gas_unit_price": "3848803411630323426", - "expiration_timestamp_secs": "11840717114376118439", - "chain_id": 78 - }, - "signed_txn_bcs": "1f8e6a9fa279601985378ee664f2348d551ab93a96e6f70bcf771b234c23bfe0666424abe92e3ceb0007d29d157c4fd8bc03060705ecfc3048baf2edccacddbfe85b751f5582795cd472e392337cd245b6f2aada13594e4347476a50497751674c506d7772454c3721597a514564687862715773575a5a4670547a527143615a4b615250464f6a784d320006060107277f1829044362989e4b910e041d097b57a14f62ee36bc620168d62da4eb73021f69777a556b46775657695477414177524f6c6d50545977444f6256735355501f4d6c4461456466526774536d72746b6d4a76645670657741527375566b56350004050102eef706ee7c9c70f6dc55979e36bb33ac014db968d23e16705d013463c30e31003f4b19d88a2bdaa5607fe27689a04fb26935a7e046107bad52a44e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f15c8c4e596a491ce24b9b92a71e33a9a8b159742ea12d52df4e231b9909bc2dbc71a2eb4e9ba810f94c4afa14ed8f81f92debd980d866565eed5ee19296bc0f", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "bc7990945a2e63ff6356cad8e00e3701531221a2e6d0c620c0b3b396fb53ba7d", - "sequence_number": "17545374257061755347", - "payload": { - "Script": { - "code": "7ad1abad", - "ty_args": [ { "vector": { "struct": { - "address": "d14cf0994a93163142d24e60d61d85e76c98db2b7bf6fdca6c8f5bd53f1266d3", - "module": "VGPAbSWbKYiTHPUNWD", - "name": "BwWeQHONmhtKbclefwRf5", + "address": "7cd245b6f2aadaf5b5b889bbe6685d273d2ac50fb8cbdb6f8fa053ef9a4c1c2a", + "module": "AADkbuZnnMItlokObZwQXRlwYVqRQJwy7", + "name": "oFsvYqa6", "type_args": [] } } @@ -348,116 +373,122 @@ { "vector": { "struct": { - "address": "cefb54736f58b4f5f109191849af0f45ad159806219e55ee2dd528e6170bb50c", - "module": "mNiOyPs", - "name": "PMGSdzoXnIcTQ", + "address": "b0af757b2577c913940e16e53c26c13c601721b758a65d98992b395e5011dd3f", + "module": "kSXbuyBKc", + "name": "y0", "type_args": [] } } }, - { - "struct": { - "address": "66c5f841dc5f5f16127f4c980ada4799163f76377a87451288edbbef7d312b87", - "module": "sEKszBDzbxSdv2", - "name": "fUU6", - "type_args": [] - } - }, { "vector": { "struct": { - "address": "1303d5aaca229ec93e9b9e50cb0e84a11633686d652280867781bdb1fed38a7b", - "module": "mBAxmhhbiieZcZNfX0", - "name": "FcPMRJTEWiEThOYfdtzDLW", + "address": "34083de9a25920bfbc71b98948a6b9a227dd6fe970c015892abe8d3f7227979a", + "module": "rpwixScZ6", + "name": "Fv", "type_args": [] } } }, { "vector": { - "struct": { - "address": "3fad006d5433de2340b293361e7d83ca1d957a1ec59320443082812d784ee6e3", - "module": "cpKYfDCif", - "name": "zaoCdBmXPjJ", - "type_args": [] + "vector": { + "vector": "u128" } } }, { "struct": { - "address": "e6d5cae8d1d1a24d30ac0a8398bcea3c3f867f2aa7f17350be0241c0367b68ff", - "module": "NeTfOUZbDKnh", - "name": "EhPAuKoRlHgDqGCPCsLyP5", - "type_args": [] - } - }, - { - "struct": { - "address": "125f4a403ddf3a0eeff1eb8120c79e1457ae324bd06ca5b90b8e158fa1b628c0", - "module": "m", - "name": "iPRSZTBSYwhW", + "address": "08bd580c714f642f28579c0649a3ed597aa502ed2454c3755d153630812625b5", + "module": "AMnzFbFlfLxTTExbOvMn", + "name": "WtkcPjvjehPSvaNVEXwPCH8", "type_args": [] } - }, - { - "vector": { - "struct": { - "address": "96fd5dc1d15ae81869c4ff273fcfafc03d424d5048d072c54d58090dad85418a", - "module": "kFEKnJFyH", - "name": "GWqQZyNGBRPQ", - "type_args": [] - } - } } ], "args": [ { - "U8": 87 + "U8": 55 + }, + { + "Bool": true + }, + { + "U64": "9742342893388317998" }, { - "U128": "28392322025090209641960477563633994233" + "Bool": true }, { - "U128": "233132878765093455377962454144140377008" + "U128": "66131818607320732354043527631890030391" }, { - "U64": "12971809279381426289" + "U64": "8536089777481325465" }, { - "U8Vector": "db80dcc7997c5fcee3774ed345" + "U64": "6368203391322889181" }, { - "U64": "13300572078824693014" + "U64": "279191632959094547" } ] } }, - "max_gas_amount": "16008713040735597115", - "gas_unit_price": "6125932074628081907", - "expiration_timestamp_secs": "4040826562623066682", - "chain_id": 84 + "max_gas_amount": "9253418150885725265", + "gas_unit_price": "12828784947872612421", + "expiration_timestamp_secs": "750545610171665819", + "chain_id": 202 }, - "signed_txn_bcs": "bc7990945a2e63ff6356cad8e00e3701531221a2e6d0c620c0b3b396fb53ba7dd3f9726bedb07df300047ad1abad080607d14cf0994a93163142d24e60d61d85e76c98db2b7bf6fdca6c8f5bd53f1266d31256475041625357624b5969544850554e5744154277576551484f4e6d68744b62636c656677526635000607cefb54736f58b4f5f109191849af0f45ad159806219e55ee2dd528e6170bb50c076d4e694f7950730d504d4753647a6f586e49635451000766c5f841dc5f5f16127f4c980ada4799163f76377a87451288edbbef7d312b870e73454b737a42447a62785364763204665555360006071303d5aaca229ec93e9b9e50cb0e84a11633686d652280867781bdb1fed38a7b126d4241786d6868626969655a635a4e665830164663504d524a544557694554684f596664747a444c570006073fad006d5433de2340b293361e7d83ca1d957a1ec59320443082812d784ee6e30963704b5966444369660b7a616f4364426d58506a4a0007e6d5cae8d1d1a24d30ac0a8398bcea3c3f867f2aa7f17350be0241c0367b68ff0c4e6554664f555a62444b6e681645685041754b6f526c4867447147435043734c7950350007125f4a403ddf3a0eeff1eb8120c79e1457ae324bd06ca5b90b8e158fa1b628c0016d0c695052535a5442535977685700060796fd5dc1d15ae81869c4ff273fcfafc03d424d5048d072c54d58090dad85418a096b46454b6e4a4679480c475771515a794e47425250510006005702f90927ffd342213c55f024aa8d295c1502b0fbba53a6947adb16be78785cc263af017150a5dfcf1f05b4040ddb80dcc7997c5fcee3774ed34501161dd313d61f95b83b723558b15f2adef3e860eac3ae03553a521c7859e6133854002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402ef7f01ba5b5f6d5c9d04910ec6080fdbd3514e613e530b5f1b95ad7de96f9450d78e373ab4c62905116892697e155a70b952f2d6ad04123111940923d86c10e", + "signed_txn_bcs": "2aabddb611f372855b53d7e160c266cda6010b855e2a4f8641bc3f8e01a399e35f0d81372a80f33f000c42f91d7c2bfeec4dfdb0fefb0806060601077ba4b4100047139fc611ff753fe48861986324b6dbbf242675a18d06a36f49600a4f74436368505a78486d215371474d737274454b615366475a7655594962646e486f5643744b4772796b7035000748f0cb8524e1bff3790a9a4cbf2b94051ac76bf86eb3ac285fe4b2e545ffcdad145470544561734741505261774b654a794b716233084e54656b746373770006077cd245b6f2aadaf5b5b889bbe6685d273d2ac50fb8cbdb6f8fa053ef9a4c1c2a214141446b62755a6e6e4d49746c6f6b4f625a775158526c7759567152514a777937086f46737659716136000607b0af757b2577c913940e16e53c26c13c601721b758a65d98992b395e5011dd3f096b5358627579424b6302793000060734083de9a25920bfbc71b98948a6b9a227dd6fe970c015892abe8d3f7227979a09727077697853635a3602467600060606030708bd580c714f642f28579c0649a3ed597aa502ed2454c3755d153630812625b514414d6e7a4662466c664c7854544578624f764d6e1757746b63506a766a6568505376614e5645587750434838000800370501012e4576903ec13387050102371f806e8e32f515e646d1a56486c03101991b9e2d6d48767601dd1b3d853e6760580113bfc99a4fe3df035114b211c8be6a804540d3b5f0ff08b29bcd028241796a0aca002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e5cc017a8eeb9856fe456a261ed17b648d7165d3199aacee59e491f53911c8f20bb7cb59e2a30f1dd9c090bc96b47988c7f5d1868f3f5c413de902784ec4bc0c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "f95347eeeb2494465bcf9a46d602100d2dee62332f4047bab8674a7c8249d75a", - "sequence_number": "3431580643192205041", + "sender": "eb8b6d459630be1a6054d5a38a4e219b1badba23a6b46efdb6547069b8a00bb2", + "sequence_number": "5198429413034048659", "payload": { "Script": { - "code": "5097ee675259c000bbe0e3bf6aad", + "code": "ed1c227bbe66", "ty_args": [ + { + "struct": { + "address": "f6fdca6c8f5bd53f1266d392d55b7fbe7bb39bd3ee82e8db543c0a1cb5ffd90f", + "module": "onmsIS", + "name": "sFYBDSYrjOJNMzp", + "type_args": [] + } + }, { "vector": { - "struct": { - "address": "589b69209f3bd3dda63d4f42514b5e79d29c30b86f11de5beb4f3bb607714c2a", - "module": "y6", - "name": "QYUCYzlVjhHOhvfBzSsioaMuREnH", - "type_args": [] + "vector": { + "struct": { + "address": "c125da5d2951c5105a10836d39b82749289487eebe73ad4a3aa87cf295863fea", + "module": "fcHwQuNBdqHZmXeFTqDeoDJfCWn5", + "name": "kDranhwTsrWcNvqiGKO3", + "type_args": [] + } } } }, + { + "struct": { + "address": "bf373279b0dedf7d6b6afc3b3178a7c50c2db2dccb9084d2040a1e1c3f1c84e4", + "module": "NLZHfRRePhLtpH8", + "name": "InKOUtWKttONPLxDpORUygBjUfAZUzv", + "type_args": [] + } + }, + { + "vector": "signer" + }, + { + "struct": { + "address": "8106e32c84f676629587416c467d4dd4aaccd223935177e99707a26597b5cd4d", + "module": "byresAEiGssZaUMVcTjrGlK", + "name": "vEqdWldQuAInqJLolzaaipom5", + "type_args": [] + } + }, { "vector": { "vector": "u128" @@ -465,58 +496,117 @@ }, { "struct": { - "address": "b5a38c625df9af738ed24c5d2e51f014792886b57b4ef9a08763cb13517667a0", - "module": "cEngMnzORtQRUQTkdJPPF5", - "name": "vOQuHEpMiqMbA", + "address": "0d113e9954d341f1c484d49ef783a376d4d17aae43af877dd0a0ef64edf301e3", + "module": "BEXhJcWHDnWiSQdPxNoO", + "name": "uSfvTxRUlW", + "type_args": [] + } + }, + { + "struct": { + "address": "c4a214697e460da917612558b12269ea8fd5dd6fe4271c8f262dfdc4e1417297", + "module": "vNGnrqrLlzmrxDRPCQ", + "name": "dPcebKrUpTlqHp", "type_args": [] } }, { "struct": { - "address": "a05e67668c21a36654c24b1441d11f53e1a28142507a75f42cf0f7ee4f3b26ce", - "module": "P", - "name": "hTFOZVSRwiKeWDtPKLGXDtAaLXrAtfMQ1", + "address": "0eeff1eb8120c79e1457ae324bd06ca5b90b8e158fa1b628c0463984ff594e62", + "module": "GWVTMOJrCHgTknHbCcXZKhfxTzk0", + "name": "FW3", "type_args": [] } }, { "struct": { - "address": "f38a66eb91ea85caef654165a4ec5277e6e75b9744bf59affae477a73c569f1b", - "module": "ZVzVIHmQVcS8", - "name": "oARTMIaJqbyFrbVDBxJZYJugtDhJg", + "address": "273fcfafc03d424d5048d072c54d58090dad85418ae1cadefc37d0dca737df4a", + "module": "xEsHQiJxRJjsrPGRHHlkQEwokfG3", + "name": "dBGFZkZQoAtKgdIQYbr5", "type_args": [] } + } + ], + "args": [ + { + "U8Vector": "dc0b835efd8bffec9a9e" + } + ] + } + }, + "max_gas_amount": "16020561696894556420", + "gas_unit_price": "4902116123370541945", + "expiration_timestamp_secs": "9719021368655792451", + "chain_id": 107 + }, + "signed_txn_bcs": "eb8b6d459630be1a6054d5a38a4e219b1badba23a6b46efdb6547069b8a00bb2933cd639028824480006ed1c227bbe660a07f6fdca6c8f5bd53f1266d392d55b7fbe7bb39bd3ee82e8db543c0a1cb5ffd90f066f6e6d7349530f73465942445359726a4f4a4e4d7a7000060607c125da5d2951c5105a10836d39b82749289487eebe73ad4a3aa87cf295863fea1c6663487751754e426471485a6d586546547144656f444a6643576e35146b4472616e687754737257634e767169474b4f330007bf373279b0dedf7d6b6afc3b3178a7c50c2db2dccb9084d2040a1e1c3f1c84e40f4e4c5a486652526550684c747048381f496e4b4f5574574b74744f4e504c7844704f52557967426a5566415a557a76000605078106e32c84f676629587416c467d4dd4aaccd223935177e99707a26597b5cd4d1762797265734145694773735a61554d5663546a72476c4b1976457164576c64517541496e714a4c6f6c7a616169706f6d3500060603070d113e9954d341f1c484d49ef783a376d4d17aae43af877dd0a0ef64edf301e314424558684a635748446e576953516450784e6f4f0a75536676547852556c570007c4a214697e460da917612558b12269ea8fd5dd6fe4271c8f262dfdc4e141729712764e476e7271724c6c7a6d727844525043510e64506365624b725570546c71487000070eeff1eb8120c79e1457ae324bd06ca5b90b8e158fa1b628c0463984ff594e621c475756544d4f4a72434867546b6e48624363585a4b686678547a6b30034657330007273fcfafc03d424d5048d072c54d58090dad85418ae1cadefc37d0dca737df4a1c7845734851694a78524a6a737250475248486c6b5145776f6b66473314644247465a6b5a516f41744b67644951596272350001040adc0b835efd8bffec9a9e0419a195fb7754de79533745a4d0074443c928f370e6e0866b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b65b4c4ec89d6b38c40e8a65f8c78e1c884f798eaffe39e5e3f1065e7aabb6f4ea69a3ba3a14c1fad3af3c6ccdf20d66078a48662b6bc00c3c7d02874c38a009", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "8d62ea7ad9d18690287e70e487a895d9ba2be639596704331e6d83707b5a6f68", + "sequence_number": "2572310825440540822", + "payload": { + "Script": { + "code": "ea2cfad47af4f76f", + "ty_args": [ + { + "vector": { + "vector": "u8" + } }, { "struct": { - "address": "7c548d772ec75da3918fa6c00fe1434ed304cb015522ea4bd35a40bb7cd8daff", - "module": "ymQVnikQNweC", - "name": "pVrwwnvVSzShlZHOeHNtdcNKMfAmv", + "address": "12531fbe37a26d3ffc41e39af8a1f50194906aa1aee74d999f64e6640182e21f", + "module": "pxp1", + "name": "TuShpodIQolkNBBEZwhPdaciVjyaYv2", "type_args": [] } }, { "vector": { - "vector": "signer" + "vector": "u128" } }, { "vector": { "struct": { - "address": "2ca7d5d82c407a90f44b270ced66c73c961d3799533558d4d6304bb9fa8de1ab", - "module": "dG", - "name": "hmHbammgZWESzMxvOjfPQSGjCbWIaSM8", + "address": "ee5d0374459724681daeffc9ba14e4293bb9a775867fcb2a9f6cffe8ae505f0e", + "module": "yUswDZXESjdusBciUy4", + "name": "mnnZqpLvLwZaeBi8", "type_args": [] } } }, + { + "vector": { + "struct": { + "address": "e96e83a5a47429ff4693c7f0cd3500b586f00007b39a493bc98552af4e0835f3", + "module": "Gq7", + "name": "qNLDPkTBbVvkBvJ9", + "type_args": [] + } + } + }, + { + "vector": { + "vector": { + "struct": { + "address": "5069fb47d5620a2b8cb9a064ced887cc065c59ea5720eba6f9b890a36ecbe6d2", + "module": "DaeWFRDTnsCrbLzGPUGKMKZDn6", + "name": "pwYlNFMyEZbyIRyZ8", + "type_args": [] + } + } + } + }, { "vector": { "vector": { "struct": { - "address": "2cbece9183344d09da09b5b33cb60a5981252cc046a369a9cf0abfe0994375ee", - "module": "WBwRridqLYwuxLhEAdd0", - "name": "C", + "address": "686e7d23c57bb4c3108deb5661c2244cd43096b42297892ada78962f7b817047", + "module": "dIXhxrrmpbCzMVLqfnaOXBaw2", + "name": "u4", "type_args": [] } } @@ -525,829 +615,755 @@ ], "args": [ { - "U64": "11890275679649734087" - }, - { - "Bool": true - }, - { - "U128": "211326598592605503961921466601160637814" - }, - { - "U8": 29 - }, - { - "Bool": true - }, - { - "U8Vector": "cfe4fcb46cff68b8fb" - }, - { - "U8": 58 + "U128": "45963502836960241715715009736023054062" } ] } }, - "max_gas_amount": "6333199691283183015", - "gas_unit_price": "6979750436888388414", - "expiration_timestamp_secs": "13766757096412574883", - "chain_id": 248 + "max_gas_amount": "5978513436980869405", + "gas_unit_price": "8517019043616324231", + "expiration_timestamp_secs": "6051718683617614515", + "chain_id": 159 }, - "signed_txn_bcs": "f95347eeeb2494465bcf9a46d602100d2dee62332f4047bab8674a7c8249d75af1ee93e7696c9f2f000e5097ee675259c000bbe0e3bf6aad090607589b69209f3bd3dda63d4f42514b5e79d29c30b86f11de5beb4f3bb607714c2a0279361c51595543597a6c566a68484f687666427a5373696f614d7552456e480006060307b5a38c625df9af738ed24c5d2e51f014792886b57b4ef9a08763cb13517667a01663456e674d6e7a4f527451525551546b644a505046350d764f51754845704d69714d62410007a05e67668c21a36654c24b1441d11f53e1a28142507a75f42cf0f7ee4f3b26ce0150216854464f5a56535277694b65574474504b4c4758447441614c58724174664d51310007f38a66eb91ea85caef654165a4ec5277e6e75b9744bf59affae477a73c569f1b0c5a567a5649486d51566353381d6f4152544d49614a716279467262564442784a5a594a75677444684a6700077c548d772ec75da3918fa6c00fe1434ed304cb015522ea4bd35a40bb7cd8daff0c796d51566e696b514e7765431d70567277776e7656537a53686c5a484f65484e7464634e4b4d66416d760006060506072ca7d5d82c407a90f44b270ced66c73c961d3799533558d4d6304bb9fa8de1ab02644720686d4862616d6d675a5745537a4d78764f6a66505153476a4362574961534d38000606072cbece9183344d09da09b5b33cb60a5981252cc046a369a9cf0abfe0994375ee1457427752726964714c597775784c6845416464300143000701c71dfdb6bbbe02a505010276fd5422b9a130c1863703cfbd05fc9e001d05010409cfe4fcb46cff68b8fb003aa7358c82900be4573e239cc30a0edd60a374c2c8a3580dbff8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c18771e47eafa03cba45a57f8c911b5178e27976632c3918d6e4ca85c62218057fb6f15204c32839050d7dc95a2afc8a4050d19b06d60584a0f40d7372853003", + "signed_txn_bcs": "8d62ea7ad9d18690287e70e487a895d9ba2be639596704331e6d83707b5a6f689678462a11afb2230008ea2cfad47af4f76f070606010712531fbe37a26d3ffc41e39af8a1f50194906aa1aee74d999f64e6640182e21f04707870311f54755368706f6449516f6c6b4e4242455a77685064616369566a7961597632000606030607ee5d0374459724681daeffc9ba14e4293bb9a775867fcb2a9f6cffe8ae505f0e1379557377445a5845536a647573426369557934106d6e6e5a71704c764c775a6165426938000607e96e83a5a47429ff4693c7f0cd3500b586f00007b39a493bc98552af4e0835f30347713710714e4c44506b54426256766b42764a39000606075069fb47d5620a2b8cb9a064ced887cc065c59ea5720eba6f9b890a36ecbe6d21a44616557465244546e734372624c7a475055474b4d4b5a446e36117077596c4e464d79455a62794952795a3800060607686e7d23c57bb4c3108deb5661c2244cd43096b42297892ada78962f7b81704719644958687872726d7062437a4d564c71666e614f5842617732027534000102ee9685076550b9c81a990f48a73f94221df924a04bf2f75287fafcefb1873276b35a9f511406fc539f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ba22eee7cfbe28a429a35e78478b49b0981efe022752aff290301cfac703fab87da113f43fe7d8e21731f1f141c452b4f1c46cd845a4177b53b46c7139f9140d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "4cc4e4ab1728c8abc6cbae7698ed55b11e7c941911c88e002a3df4d2dac06253", - "sequence_number": "5166986925766650006", + "sender": "e0f192ac663f415b70f2858642d4c477a9129e3db242d3cb115143f7b4c67bd0", + "sequence_number": "2646633000989045210", "payload": { "Script": { - "code": "5d9017fc", + "code": "623f685ddab2eb1dc2280aa939a9", "ty_args": [ - { - "struct": { - "address": "a5e888fc1a702231948093ced0c3c81a7e27874cf74ef80e716267b294f0c501", - "module": "KQCdzpUWYjrAUaklu", - "name": "vXCdojUBdwrdDYIaL1", - "type_args": [] - } - }, { "vector": { - "vector": "u128" + "struct": { + "address": "15833a6017a76152f3630fe01825339daa1847726cf8c046d561471803b333fa", + "module": "VZClZKpGuBydbdUBLPucvhPF", + "name": "ewDngaWpghVVruExayEtmAt", + "type_args": [] + } } }, { "vector": { - "vector": "address" + "struct": { + "address": "e7875f023b19d67332c261296604a38a2f720110aeab1ee46c45b9c72b1b7b12", + "module": "WlkgaSEOnKhgStfdmVqsgsLmCYab", + "name": "vzZmGFRalUmJM", + "type_args": [] + } } }, { - "struct": { - "address": "33cb0fc67095461c81c4afee376affb68b39d169cdcf96c5d638c2d181f7fb5a", - "module": "HRXYdzedz", - "name": "WdYyKig5", - "type_args": [] + "vector": { + "struct": { + "address": "0edcbcfbf1185399cf35af0b8467d40dddc0771ac492ef75c98f175cfeec0997", + "module": "CQi5", + "name": "EjqJu", + "type_args": [] + } } } ], "args": [ { - "Address": "c8a6a8a636d50aa7ef72757839db19c3cf12359c04409451ac00f16403fbdf25" + "U8": 43 }, { - "U128": "157331703291025202463992733642664352818" + "U128": "5967268949439651005934301882302361787" } ] } }, - "max_gas_amount": "4716318631450662867", - "gas_unit_price": "8648061684764613470", - "expiration_timestamp_secs": "3476223040702190383", - "chain_id": 100 + "max_gas_amount": "6399467889325266872", + "gas_unit_price": "6665082992972751287", + "expiration_timestamp_secs": "193767705983652603", + "chain_id": 5 }, - "signed_txn_bcs": "4cc4e4ab1728c8abc6cbae7698ed55b11e7c941911c88e002a3df4d2dac0625396a868ad3bd3b44700045d9017fc0407a5e888fc1a702231948093ced0c3c81a7e27874cf74ef80e716267b294f0c501114b5143647a705557596a724155616b6c7512765843646f6a554264777264445949614c31000606030606040733cb0fc67095461c81c4afee376affb68b39d169cdcf96c5d638c2d181f7fb5a0948525859647a65647a08576459794b696735000203c8a6a8a636d50aa7ef72757839db19c3cf12359c04409451ac00f16403fbdf2502329cb2987ed402cc586dc90cdefb5c76d3572ca3ceba73415e9b0f6c481604782f13150d70063e3064002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444057b9114c752bb201f08c59c9393a6a3778635e2d2e73df6216ec5d369b2716ccce6cbbb6ec209d07322543c61de96096ad9d3648007241a61c7bacf62cd55109", + "signed_txn_bcs": "e0f192ac663f415b70f2858642d4c477a9129e3db242d3cb115143f7b4c67bd0da31c722b1baba24000e623f685ddab2eb1dc2280aa939a903060715833a6017a76152f3630fe01825339daa1847726cf8c046d561471803b333fa18565a436c5a4b704775427964626455424c50756376685046176577446e676157706768565672754578617945746d4174000607e7875f023b19d67332c261296604a38a2f720110aeab1ee46c45b9c72b1b7b121c576c6b676153454f6e4b6867537466646d56717367734c6d435961620d767a5a6d474652616c556d4a4d0006070edcbcfbf1185399cf35af0b8467d40dddc0771ac492ef75c98f175cfeec0997044351693505456a714a750002002b02bb707024e4a206df062762f612417d04b857c0b6237acf58b761a342ab217f5cfb1219b4b366b00205002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440673a5a8c867e438310fe8f39544c4d2feda4f736b01d1dec25a37d9b6694a61bd4b6a8d42159c3168290b766697bb3f0328c09594e9f79d17024d5430500890c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "7e0a9a15e0ad717f235636ad80275fe49715cd8d364a00d3dcbaf5b39ade76c8", - "sequence_number": "7227984514519167296", + "sender": "f7dcde955e9874518dcd915eeea994fb4b9fe152919e9606661d1dd7543ba2f2", + "sequence_number": "14709205516768297372", "payload": { "Script": { - "code": "b0aabb", - "ty_args": [], - "args": [ - { - "Address": "b3c41862018b1739867390c1f277db7adf7dda8bf74e777b08eecb08c15a5caf" - }, - { - "U8Vector": "9dfaec44" - }, - { - "U8Vector": "8ad7f7ccb7ca33fe0ce4ae" - }, - { - "U128": "114397681220791908685918816472162765191" - }, - { - "U8Vector": "3f9a878b854eeb6cacefd2" - }, + "code": "814a2a1fc5af9fcf4bebfad44daace", + "ty_args": [ { - "U8Vector": "d4d728b9b5" + "vector": { + "struct": { + "address": "4b6357156afce2e7993ea6613f27dda8d6d21de9e1f11a9cdff76d2919ead7a1", + "module": "RWipnFAtwce", + "name": "qImZFqzNNrAwan", + "type_args": [] + } + } }, { - "U8": 100 + "struct": { + "address": "f901dd0841d725ac6588a44c25f47850a956f9f810269caf3eb101eb5756c978", + "module": "JuWEFEZNGKAmCr", + "name": "zghDEJZisOI", + "type_args": [] + } } - ] + ], + "args": [] } }, - "max_gas_amount": "2419250657686819403", - "gas_unit_price": "10664924541046458205", - "expiration_timestamp_secs": "8777437622354548390", - "chain_id": 130 + "max_gas_amount": "10121544640024291411", + "gas_unit_price": "693523612328745626", + "expiration_timestamp_secs": "450304319726693670", + "chain_id": 215 }, - "signed_txn_bcs": "7e0a9a15e0ad717f235636ad80275fe49715cd8d364a00d3dcbaf5b39ade76c84071f0d59ef54e640003b0aabb000703b3c41862018b1739867390c1f277db7adf7dda8bf74e777b08eecb08c15a5caf04049dfaec44040b8ad7f7ccb7ca33fe0ce4ae0287091e3a99d11a824da4ecce25311056040b3f9a878b854eeb6cacefd20405d4d728b9b500644b920dcaa7e792215d876b695d6c0194a696973e03b9cf7982002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440891a26cd99df89775855bedabb754c922a757c6970fe822b719a852a2e265460fb5f4684379c741c137338e7b7df37a72b73aa619952031145e3107fafaabf06", + "signed_txn_bcs": "f7dcde955e9874518dcd915eeea994fb4b9fe152919e9606661d1dd7543ba2f29cc1301b7c9821cc000f814a2a1fc5af9fcf4bebfad44daace0206074b6357156afce2e7993ea6613f27dda8d6d21de9e1f11a9cdff76d2919ead7a10b525769706e4641747763650e71496d5a46717a4e4e724177616e0007f901dd0841d725ac6588a44c25f47850a956f9f810269caf3eb101eb5756c9780e4a75574546455a4e474b416d43720b7a676844454a5a69734f4900005328e84e39f3768c9a5a330c0de49f09262d229a64cd3f06d7002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440da09569cc62f634fe0348b9f89809759e215b01c262c6fe60c17a2bf81fefd9be0880a78182968b7b64b5d52c5e4332ebc0b7e5dff1645a9cc17f4b70c1da106", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "e84d4fc3f1d14df2fa279a8656b23c32c59c1d8186ea2393b37091bee2ac5b06", - "sequence_number": "350987295300083611", + "sender": "c01c51c7f1a215858722a7288fcb285b1353eb24e25ee1e9b397bf701803d617", + "sequence_number": "9125347005557893276", "payload": { "Script": { - "code": "1efd32f9e9c8", + "code": "d17a9ebee9c9ceeaef8c2cc1", "ty_args": [ { "struct": { - "address": "018d89e73a42f25146ebb0343257befb955f5d7a423669ef968e07b96d2a23e4", - "module": "PtAk6", - "name": "EtDpmzBNJbnnG8", + "address": "2130c6d10d6cee52eaf92cf212b3974eaa044bf9ec7fb4f8a070d49af1ccace9", + "module": "xUjoVbDUGORjsMsPXkKtcW", + "name": "xIbkCGdv", "type_args": [] } }, { - "vector": "u128" - } - ], - "args": [ - { - "Address": "7c36813dd317e424ea642b2a656b74212f6ce9f26eb960c3a36c77890546c92b" + "vector": { + "vector": { + "struct": { + "address": "fdaf8e4593a18d7b234b5d09a3139f0acfe0b57e1238a97f3af95347eeeb2494", + "module": "BvCMchEDd3", + "name": "fzpM", + "type_args": [] + } + } + } }, { - "U128": "275771500081230549234015361492539735011" + "vector": { + "struct": { + "address": "6fe2480820651d18baa6f7733ca8b7b9759b702e8feea75551fd54a5016abd7f", + "module": "RxONPUYsUR9", + "name": "frRfxRlVctBbMmUZEmjzAeaMCIlpErAJ1", + "type_args": [] + } + } }, { - "Bool": false + "struct": { + "address": "2bc3cf93b7a0cb6cf53368cc9c36aaf31074ed158ace7eca08d3a1e78db109db", + "module": "eFHXEusORmvUSIclJW", + "name": "woItodFBReSjBgTuVwDxpVCo7", + "type_args": [] + } }, { - "U64": "17977028123766152978" + "struct": { + "address": "856652e338711bfb9d04db013c74ee9e5eefbc6a2c8aa056e625f126b7bc5d1a", + "module": "j5", + "name": "MQaSdweM", + "type_args": [] + } }, { - "U128": "151526128532424140838094688808140732364" + "struct": { + "address": "400859915c3304c507674801f521efd712ad7dcd54666201a1409b6897e54cef", + "module": "lJuuIKvao", + "name": "qGglBigfJIEqljouDsqIQElwey4", + "type_args": [] + } }, { - "Address": "4d372edb8e5f5a45b4db39d97af8a280ce427f869b4da7aa29cdd97cf5e483ec" + "struct": { + "address": "b68b39d169cdcf96c5d638c2d181f7fb5abab5c7567fc9d994cd9e21ba7bf888", + "module": "R3", + "name": "lYyDDBoxxlTfUZsPvdHyOBm4", + "type_args": [] + } + } + ], + "args": [ + { + "U8": 114 } ] } }, - "max_gas_amount": "6793051906045157290", - "gas_unit_price": "13633036682382135220", - "expiration_timestamp_secs": "7745521548611890597", - "chain_id": 253 + "max_gas_amount": "9951943570233611203", + "gas_unit_price": "5943447743841487415", + "expiration_timestamp_secs": "15423464442069995182", + "chain_id": 224 }, - "signed_txn_bcs": "e84d4fc3f1d14df2fa279a8656b23c32c59c1d8186ea2393b37091bee2ac5b069b5f09e115f5de0400061efd32f9e9c80207018d89e73a42f25146ebb0343257befb955f5d7a423669ef968e07b96d2a23e4055074416b360e457444706d7a424e4a626e6e473800060306037c36813dd317e424ea642b2a656b74212f6ce9f26eb960c3a36c77890546c92b02e3fb94ae56a8d5ba5e9b0303b3a877cf05000112df490ad53b7bf902ccf7469e843d5a9ebb6717b3eedefe71034d372edb8e5f5a45b4db39d97af8a280ce427f869b4da7aa29cdd97cf5e483ecaa9f9ca8b7c4455eb4cf41b7a14632bda52d2599cf9e7d6bfd002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444032a7db01f62235db4fee8b95872a4da02617a1ee4e899adfcbeebc0d97ce7b608f93a57440fa8cfed39c5a4207ca57b2ac07a4f3dd6f693c41b1c2f956b2680d", + "signed_txn_bcs": "c01c51c7f1a215858722a7288fcb285b1353eb24e25ee1e9b397bf701803d6179ce873dec0bea37e000cd17a9ebee9c9ceeaef8c2cc107072130c6d10d6cee52eaf92cf212b3974eaa044bf9ec7fb4f8a070d49af1ccace91678556a6f56624455474f526a734d7350586b4b746357087849626b4347647600060607fdaf8e4593a18d7b234b5d09a3139f0acfe0b57e1238a97f3af95347eeeb24940a4276434d63684544643304667a704d0006076fe2480820651d18baa6f7733ca8b7b9759b702e8feea75551fd54a5016abd7f0b52784f4e50555973555239216672526678526c56637442624d6d555a456d6a7a4165614d43496c704572414a3100072bc3cf93b7a0cb6cf53368cc9c36aaf31074ed158ace7eca08d3a1e78db109db12654648584575734f526d76555349636c4a5719776f49746f6446425265536a42675475567744787056436f370007856652e338711bfb9d04db013c74ee9e5eefbc6a2c8aa056e625f126b7bc5d1a026a35084d5161536477654d0007400859915c3304c507674801f521efd712ad7dcd54666201a1409b6897e54cef096c4a7575494b76616f1b7147676c426967664a4945716c6a6f754473714951456c776579340007b68b39d169cdcf96c5d638c2d181f7fb5abab5c7567fc9d994cd9e21ba7bf888025233186c59794444426f78786c5466555a7350766448794f426d3400010072c3d38110f3671c8a37cac4b83b5e7b52ae4e736b31270bd6e0002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440978cf0997597bce11383d42df0a261e009a9e8bd4afd49018282f807b4c7e861a1ccb99411e141304f5b9bcd15be0d9e4287c612f2a675203d570a9c2aa54502", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "9ba972a62dd39d3f44af0471551fb40dd3e1767d6dcfb19329ed9dfb707e8702", - "sequence_number": "14992661250520904036", + "sender": "befb955f5d7a423669ef968e07b96d2a23e4a12f8695b523a2128c8b05718970", + "sequence_number": "16374847433563205325", "payload": { "Script": { - "code": "3537e3b9d4b5a03723ffe54df4cf5e", + "code": "8efcbc3689076eb5a4", "ty_args": [ { - "struct": { - "address": "7a30a956a42fc89e306c95adadccd6697a0546e028438fd792aa3435f9c43fc6", - "module": "mghCKNjLQgqLzCSetgWhlW", - "name": "CRhDpIVieEyvD", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "4c7c8c5aecba884bd982a7e78dc6b61a609274a3d82aa57c2a718f4c216666c5", + "module": "YRuMK2", + "name": "utHAZkNFdriHmhpt3", + "type_args": [] + } + } } }, { "struct": { - "address": "33427a3a031fac11fa17dffb1700e66d0daf5dbbec9a865bfd14ee6d3eb67cff", - "module": "VChRFfNA", - "name": "T", + "address": "6e169abfde9cd9677b866ecaf088b414cf1c53b79fcaf65d2a02f4132001ed7e", + "module": "XaStMZDwJFOyJRjHssrEQRwYI", + "name": "pCKIsVD", "type_args": [] } }, { "vector": { - "struct": { - "address": "db41eaaa9446a7b9aa9dd3c467413654a23a8c94b7bec39dfb9dc2c16d004345", - "module": "MOSeM3", - "name": "YSJHDaOmcRvEJyyHMQQ0", - "type_args": [] + "vector": { + "vector": { + "vector": "address" + } } } }, { "struct": { - "address": "ba2acfbf55d9a965f0cfbd44923526526e39412dba879722e1f0d5368dfb0882", - "module": "hIDaJUSdxgqeCUtPHSvszZUm", - "name": "KOFtyMVQguTTXxsfG", + "address": "d41bcb623760eb0809eca630f2141804da67c31c88815a15cbce68782ad3bb13", + "module": "ZrfDTzRmpMyuCouHTwNw", + "name": "FpS", + "type_args": [] + } + }, + { + "struct": { + "address": "3e9ea560d38262d6b2613f3e883507e0ddbba82f19cf8cafc36e662e3004ebf5", + "module": "lzSfnYvNbRFCvn", + "name": "AsiZfBehGDsuNy6", + "type_args": [] + } + }, + { + "struct": { + "address": "a01995e7f782a6359ecd5b8c696f046d5475a9f19cf498a1e37b7018df536944", + "module": "EBPb", + "name": "dOuHUjejEpWS", "type_args": [] } } ], "args": [ { - "Address": "ccb8872a8b69546647fcf64a12f4ccc1d4546f1bc9c8e3c11863a99dde74b091" + "U8Vector": "bd2b584ab2d0b88e602acfceb1ca8b69" }, { - "U8": 199 - } - ] - } - }, - "max_gas_amount": "6898781826993812256", - "gas_unit_price": "15421261541659152626", - "expiration_timestamp_secs": "15551876510667012352", - "chain_id": 45 - }, - "signed_txn_bcs": "9ba972a62dd39d3f44af0471551fb40dd3e1767d6dcfb19329ed9dfb707e870264f10f0bf9a110d0000f3537e3b9d4b5a03723ffe54df4cf5e04077a30a956a42fc89e306c95adadccd6697a0546e028438fd792aa3435f9c43fc6166d6768434b4e6a4c5167714c7a435365746757686c570d43526844704956696545797644000733427a3a031fac11fa17dffb1700e66d0daf5dbbec9a865bfd14ee6d3eb67cff085643685246664e410154000607db41eaaa9446a7b9aa9dd3c467413654a23a8c94b7bec39dfb9dc2c16d004345064d4f53654d331459534a4844614f6d635276454a7979484d5151300007ba2acfbf55d9a965f0cfbd44923526526e39412dba879722e1f0d5368dfb088218684944614a5553647867716543557450485376737a5a556d114b4f4674794d5651677554545878736647000203ccb8872a8b69546647fcf64a12f4ccc1d4546f1bc9c8e3c11863a99dde74b09100c720f3e2348565bd5ff290fcb2aa5303d600790c014a5dd3d72d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400b886edd30fed09d08bb867f01832c9c5c29090aea4018ce5c061defbe7bd767beb6c3b51193d8f0df09fbe6038fe768729ef2e547cdbf887f28c196a783d003", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "cf7c638f0041cb968497e22d091a304415052fb15679c0f253a2a6f7bc716798", - "sequence_number": "11745274922679138599", - "payload": { - "Script": { - "code": "0f9a78ea8cbce8c7164cb4a4", - "ty_args": [], - "args": [ + "Bool": true + }, { - "Address": "4589457a00474b1b5e00971bb4ba7b970581287d244bb0ee7911bea1aedd2078" + "U8": 31 }, { - "U128": "247733931560227065529341776975280050698" + "U8": 205 }, { - "U64": "9293165213621309782" + "Bool": true } ] } }, - "max_gas_amount": "13100034624844546052", - "gas_unit_price": "4838957551341363502", - "expiration_timestamp_secs": "6246074009986970437", - "chain_id": 204 + "max_gas_amount": "12017997239567011546", + "gas_unit_price": "7070718548572320482", + "expiration_timestamp_secs": "16765325951114236141", + "chain_id": 133 }, - "signed_txn_bcs": "cf7c638f0041cb968497e22d091a304415052fb15679c0f253a2a6f7bc71679827f997235099ffa2000c0f9a78ea8cbce8c7164cb4a40003034589457a00474b1b5e00971bb4ba7b970581287d244bb0ee7911bea1aedd2078020a923d93bd7f9a558675ae12d8d15fba015651ea4486f4f78004402d9715acccb52e61e54a416e274345b3120e3883ae56cc002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a4e89a211a6bcd3dcea6de5b59af68307e92397546e2c99b1e2c76549eef914da70dc05d7d65d2b7985bf3a2efd1811ff040be61eaedb0d18b8ce667428d2b0a", + "signed_txn_bcs": "befb955f5d7a423669ef968e07b96d2a23e4a12f8695b523a2128c8b05718970cd6ec0b0fb243fe300098efcbc3689076eb5a4060606074c7c8c5aecba884bd982a7e78dc6b61a609274a3d82aa57c2a718f4c216666c5065952754d4b3211757448415a6b4e46647269486d6870743300076e169abfde9cd9677b866ecaf088b414cf1c53b79fcaf65d2a02f4132001ed7e19586153744d5a44774a464f794a526a487373724551527759490770434b4973564400060606060407d41bcb623760eb0809eca630f2141804da67c31c88815a15cbce68782ad3bb13145a726644547a526d704d7975436f754854774e770346705300073e9ea560d38262d6b2613f3e883507e0ddbba82f19cf8cafc36e662e3004ebf50e6c7a53666e59764e62524643766e0f4173695a66426568474473754e79360007a01995e7f782a6359ecd5b8c696f046d5475a9f19cf498a1e37b7018df53694404454250620c644f7548556a656a4570575300050410bd2b584ab2d0b88e602acfceb1ca8b690501001f00cd0501da4e04b8d080c8a6e2326bc20e3d2062ed50cd432067aae885002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b1221b0a07548315d27c0345266c928454e8054a94c17970e6cc36bde203ac7b7b59be8a11058dc4ae8e3e32e00de3a6a6f96959736ef261bbe3f9e1e213910c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "006e9b6597e1f0c0763dd93c72d5d960dbf44b3a7f2339cf9d3858d23b04b2ca", - "sequence_number": "15439727154301880735", + "sender": "8cfa3a212f3a00c06f80f28805ad22dbb762afa88909a27a1213431373f79cf3", + "sequence_number": "3806457624865730470", "payload": { "Script": { - "code": "1d1fe961bbb74f5bdddfa968b05edff1", + "code": "eb7412b1", "ty_args": [ { - "struct": { - "address": "a141088f1b39dcf294c0348ad152d1201d67e5da64145e4b7063d8f2eb4f105c", - "module": "uotCjNYtCLwiegHCoE0", - "name": "VlGWcNlFQaldVWzKLxZUnwueZl8", - "type_args": [] - } - }, - { - "struct": { - "address": "0ecd2b97014daf86edf7d7c31303a2ee28db4428739a309c63d3094de44b823b", - "module": "ydqUamAVzpHIpCaGrVcUbfSXfH", - "name": "Rv0", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "2d8f661ac79c985f708e8b4a45536361c2d40ee6230ab8399fd8c943fcacf934", + "module": "YuGsKhve2", + "name": "JZJbUPqhKszdJZI", + "type_args": [] + } + } } } ], "args": [ { - "U64": "3513174488313567450" - }, - { - "U8Vector": "d3f4c20fde2a442df2ba3ce8c1240191" - }, - { - "U8Vector": "ce05d9aa1fada93da3c6be5c" + "Address": "486ca2cb3e30b13ef742d09758af966ec0db3396ba6f86e5d90db038d0892508" }, { - "U128": "137955332674727377407097834001997876746" + "Bool": true } ] } }, - "max_gas_amount": "7453951127712946889", - "gas_unit_price": "5417133610917930122", - "expiration_timestamp_secs": "17682353803604118289", - "chain_id": 146 + "max_gas_amount": "1864029782666557290", + "gas_unit_price": "11678867262183273717", + "expiration_timestamp_secs": "17698605108931169088", + "chain_id": 213 }, - "signed_txn_bcs": "006e9b6597e1f0c0763dd93c72d5d960dbf44b3a7f2339cf9d3858d23b04b2ca9fc91d2d0bee44d600101d1fe961bbb74f5bdddfa968b05edff10207a141088f1b39dcf294c0348ad152d1201d67e5da64145e4b7063d8f2eb4f105c13756f74436a4e5974434c7769656748436f45301b566c4757634e6c4651616c6456577a4b4c785a556e7775655a6c3800070ecd2b97014daf86edf7d7c31303a2ee28db4428739a309c63d3094de44b823b1a79647155616d41567a704849704361477256635562665358664803527630000401da18e561954dc1300410d3f4c20fde2a442df2ba3ce8c1240191040cce05d9aa1fada93da3c6be5c020acea5a85dd4430fb2b455d2093bc967c9da73d40ec171678aa4976351862d4b11cb9968195764f592002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444081871c49cfae78a1c6728ae5f3d530e6e4768d23e09dd9172c9b0b7b54cc3244031cba0099decf0e0fe8b03751d07e3bf2eb1b2dbb0b6beee9e22031c0333308", + "signed_txn_bcs": "8cfa3a212f3a00c06f80f28805ad22dbb762afa88909a27a1213431373f79cf3a6efb2d60a41d3340004eb7412b1010606072d8f661ac79c985f708e8b4a45536361c2d40ee6230ab8399fd8c943fcacf93409597547734b687665320f4a5a4a62555071684b737a644a5a49000203486ca2cb3e30b13ef742d09758af966ec0db3396ba6f86e5d90db038d089250805016ab79616365dde19f5745fcde5ab13a2408bc14993139ef5d5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440edc1f57308b8257fe0a5eea1f61aa38ccd56d26ef6e118033fab118389d34e58e88fae959f2aa7cbf0cdca8078891f144d39952638040fa75a464a4e675ba106", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "e06988ecd44682d63426a7c101b29d809cd99cc5f1e698d2b648881410586472", - "sequence_number": "10487547084945647102", + "sender": "54f1ae389bc9393ba00c63352477be125da2c202096c5417d0865caf552318a3", + "sequence_number": "14261575651282797772", "payload": { "Script": { - "code": "1f", + "code": "e32fe121e1da05", "ty_args": [ { "struct": { - "address": "22d7e216f504f03a08cdf8d8d238a160e5bf90510672557e8251010b9a93994a", - "module": "zADKBHhzRAgyhxVhbVe", - "name": "VOHDvDLukcGEpfdgVDpsvbwFPioW6", - "type_args": [] - } - }, - { - "struct": { - "address": "15afeb103aafe8464d8a397f38171534efa0f45f66062483b1714cf37ae387e1", - "module": "ozDvJIYMNiiAnztyFGdShYJJ", - "name": "eSRZxuTTxDKYkfrwHThwi5", - "type_args": [] - } - }, - { - "struct": { - "address": "482f792c98dc519de41c075b38f6a300d3ed680ae5b034dcbc0f052cef15c8b5", - "module": "iFEYMoGqCGIIKzYJWOTiz7", - "name": "rHtjjDlTt", - "type_args": [] - } - }, - { - "struct": { - "address": "e228ddca62dc8cd3bee675f154e74d552ac59350b64de99eb9bfb829b12afb68", - "module": "UMWolnEbHQfmvLwxICZRPh5", - "name": "lNlRmsvVARxvGBDQKEQvCYQAoifLB", + "address": "5b5b40036a07cac4db75adfea1ba44b76e070bd0ba23b4c9123bddefea958383", + "module": "yAGNqdBhFgIklw", + "name": "tYVYfpzFAbuldgHTOgffZYJWOTfka0", "type_args": [] } }, { "vector": { "struct": { - "address": "053e5142a288b9330bc4f4609fde4b645c65131e2b186f9ef9047cd0b33df27e", - "module": "dpXnxXQXzUQBBenhQmHVLBokniUXt9", - "name": "wWyHiahMLgkqpdVwQooW", + "address": "855afc520f2b57678e25e48eb82749f090505f18a5d184c931a465098e3666de", + "module": "fqvsSKUGw7", + "name": "ilecgwKGsGMRJF", "type_args": [] } } }, { - "struct": { - "address": "33ef70199aaae2758e5e8396fcbd65276789a8d33d46f1d7290f8fef1fb1c79f", - "module": "NXNjfPcYrhtrj8", - "name": "KQUOEdbyzGmswQHCigYDrVr", - "type_args": [] + "vector": { + "struct": { + "address": "0a8e8cf46dcac3ddea29d211c7568ba1c9d300c7956287505f6f5b2afa0e11c9", + "module": "i0", + "name": "eyOgkdLXfxWvzO", + "type_args": [] + } } }, - { - "vector": "signer" - }, { "struct": { - "address": "bb214259146ba93af7320b9157ee23a4f0d6136d63639d5a787f28ec23c1d714", - "module": "KiZhdWJht8", - "name": "HMwd", + "address": "4d351dcd391e4b2da2ef6085f125e87ea46db8baa976d3853413aa84e4973b2e", + "module": "hPUeAyFytldrK", + "name": "qEL", "type_args": [] } } ], "args": [ { - "U8Vector": "eccba25eada6fcfc0e6bb53cdcee" + "Address": "151d7da2c83f4338e78d8799776b597828d1db41eaaa9446a7b9aa9dd3c46741" }, { - "U128": "76255342504606188957239480992778324548" + "U8": 162 }, { - "U64": "13942247285528114878" + "U8": 148 }, { - "U128": "207017947391519220235190917041964167342" + "U8Vector": "a136f674a2d61c25012a" }, { - "U8": 57 + "U8": 158 }, { - "U8Vector": "2aa3eb" + "U64": "1940488923066780474" }, { - "Bool": true + "Address": "8ef9ed852d439d96fe2a806eba363e3b64e0683594f24b1a3d883880fcaf1eee" } ] } }, - "max_gas_amount": "10676289091798208454", - "gas_unit_price": "10963576889334364574", - "expiration_timestamp_secs": "16522257710845683887", - "chain_id": 152 - }, - "signed_txn_bcs": "e06988ecd44682d63426a7c101b29d809cd99cc5f1e698d2b648881410586472fe655e2382408b9100011f080722d7e216f504f03a08cdf8d8d238a160e5bf90510672557e8251010b9a93994a137a41444b4248687a52416779687856686256651d564f484476444c756b63474570666467564470737662774650696f5736000715afeb103aafe8464d8a397f38171534efa0f45f66062483b1714cf37ae387e1186f7a44764a49594d4e6969416e7a74794647645368594a4a166553525a7875545478444b596b6672774854687769350007482f792c98dc519de41c075b38f6a300d3ed680ae5b034dcbc0f052cef15c8b516694645594d6f4771434749494b7a594a574f54697a37097248746a6a446c54740007e228ddca62dc8cd3bee675f154e74d552ac59350b64de99eb9bfb829b12afb6817554d576f6c6e45624851666d764c777849435a525068351d6c4e6c526d73765641527876474244514b455176435951416f69664c42000607053e5142a288b9330bc4f4609fde4b645c65131e2b186f9ef9047cd0b33df27e1e6470586e785851587a55514242656e68516d48564c426f6b6e695558743914775779486961684d4c676b7170645677516f6f57000733ef70199aaae2758e5e8396fcbd65276789a8d33d46f1d7290f8fef1fb1c79f0e4e584e6a66506359726874726a38174b51554f456462797a476d73775148436967594472567200060507bb214259146ba93af7320b9157ee23a4f0d6136d63639d5a787f28ec23c1d7140a4b695a6864574a68743804484d77640007040eeccba25eada6fcfc0e6bb53cdcee02448a564dadbac1bd30130942a83e5e3901beb68e7809d07cc102aeb0233dec687dd288533305d634be9b003904032aa3eb0501c68f02145dcc29949ef974e417732698af686a6ed9d94ae598002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444041155b99eb1746bbdf1475b86a750eb6cf306f002344b25c7eedb58feeb4f0ecf77bff523587c3e03d47d6d99c5d9f02113e763a07aaa15e95ada9b5c5353b0d", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "9f7baa4483e94dd48afaad2be117d0c3eb09dc70a8cc459c716e0681ba79a0d8", - "sequence_number": "17977606044187181875", - "payload": { - "Script": { - "code": "85b61c23e0bf6c", - "ty_args": [], - "args": [] - } - }, - "max_gas_amount": "12635767792378714", - "gas_unit_price": "11925796493406539536", - "expiration_timestamp_secs": "16088173215446108219", - "chain_id": 29 + "max_gas_amount": "7559132535607383342", + "gas_unit_price": "6865154531655048702", + "expiration_timestamp_secs": "9923173966526464563", + "chain_id": 164 }, - "signed_txn_bcs": "9f7baa4483e94dd48afaad2be117d0c3eb09dc70a8cc459c716e0681ba79a0d83343b19f72497df9000785b61c23e0bf6c00005aa3baf229e42c00108f18a5b9f080a53b889ef74cac44df1d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e2eb0ada3c48d88678df63bd55f259ec816adbe8211407aa3f7fe2cbaaca07b0f832559a44e07f800604533bcbc37401b04eac9c5b0fb6694d57778aaaa8890e", + "signed_txn_bcs": "54f1ae389bc9393ba00c63352477be125da2c202096c5417d0865caf552318a3cc4412687e4bebc50007e32fe121e1da0504075b5b40036a07cac4db75adfea1ba44b76e070bd0ba23b4c9123bddefea9583830e7941474e716442684667496b6c771e7459565966707a464162756c646748544f6766665a594a574f54666b6130000607855afc520f2b57678e25e48eb82749f090505f18a5d184c931a465098e3666de0a66717673534b554777370e696c656367774b4773474d524a460006070a8e8cf46dcac3ddea29d211c7568ba1c9d300c7956287505f6f5b2afa0e11c90269300e65794f676b644c58667857767a4f00074d351dcd391e4b2da2ef6085f125e87ea46db8baa976d3853413aa84e4973b2e0d6850556541794679746c64724b0371454c000703151d7da2c83f4338e78d8799776b597828d1db41eaaa9446a7b9aa9dd3c4674100a20094040aa136f674a2d61c25012a009e013acbf9f56400ee1a038ef9ed852d439d96fe2a806eba363e3b64e0683594f24b1a3d883880fcaf1eee2ed5f9bafd6ee768fe5d7663aced455f33c236b72532b689a4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444012b56f1e4daa6afd17a4e4ee0b9d9682fb322550d85a66cbb4229c17b07cc3ebb275d5ac1f1c81bc34ab3f52545671fdc457ccd892c6e595ebe0ece87717e001", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "a9ff43aebe120f9e36ea15041111fbcc504abe4dcc3a52654d03810da21540fa", - "sequence_number": "9927057380151577608", + "sender": "f253a2a6f7bc7167982750453804152e41cc5fdf8d4ce7dcd81793440b0e67fa", + "sequence_number": "15016318171376071630", "payload": { "Script": { - "code": "aaf84c", + "code": "d03857d2e2bdd49c0fed358cca8a", "ty_args": [ { - "struct": { - "address": "9f26d7a8f66aa573f0f1f15ab869564b1dca4756ea0d5a4df68ca3f230e688e3", - "module": "xVrzROMZiiZBWcEO8", - "name": "nGJcZCsbLcSpGzL8", - "type_args": [] + "vector": { + "vector": "u8" } }, { "struct": { - "address": "001179d4df57db37c1cc592ae7c1e2e49e29628511976124646b0731f44eee29", - "module": "ewJCzRBhknwhUToVraNbHAyp6", - "name": "OrvkBCfdhrXJrBgkyASnLOHoWFlvg", + "address": "df86fce9a11f32295d6eff475d804ea1cc76f706b89658ee0eccb8872a8b6954", + "module": "nBTdQuBuBQBCtGROxPxJISxxWbaXDJ2", + "name": "WFCYzPU", "type_args": [] } }, { "struct": { - "address": "a73234c1689920010d6699d3b767ea4de84b327e0cf3a73c0b6ea054c8c46cf4", - "module": "MwciKYSOfJxLwkvmbopmuIeoLyKkcy", - "name": "gPKwMfPpcp", + "address": "c1105095f8a507e2bdd783d42fa6cdf60680af811c1e8f379cf7ebe751697684", + "module": "OW7", + "name": "hBpKPTnzgyiYuSWsZkbZ", "type_args": [] } }, - { - "struct": { - "address": "9b74138cfefd9027529f7e7e55167dab06d1b850751b1da8de9f9c4815713cd5", - "module": "jk", - "name": "xwSaznvYZYhMaMlYNMzYZ0", - "type_args": [] - } - } + "bool" ], "args": [ { - "U8": 217 + "U64": "15863227158632817352" + }, + { + "U64": "8543237655741033780" }, { - "U8": 97 + "Bool": false }, { - "U8": 127 + "U8": 169 }, { - "U64": "1425792806691718700" + "Address": "4766bbc297565258d667b88188219b4e0367ffebb45914bab4c6f4c9fa8c397e" }, { - "Address": "a54491ddded79b80fd012fd8e17b88548000dd63b2ca8e550dc69cf5ac5c2a9f" + "Bool": true }, { - "U64": "9677263550203145772" + "U8": 1 }, { - "U8": 153 + "Bool": false } ] } }, - "max_gas_amount": "16910529628569530931", - "gas_unit_price": "8070652017398338964", - "expiration_timestamp_secs": "4387869792080252212", - "chain_id": 61 + "max_gas_amount": "4136412553771309001", + "gas_unit_price": "12859340020265596516", + "expiration_timestamp_secs": "9777326043190247490", + "chain_id": 186 }, - "signed_txn_bcs": "a9ff43aebe120f9e36ea15041111fbcc504abe4dcc3a52654d03810da21540fa08ccda6817fec3890003aaf84c04079f26d7a8f66aa573f0f1f15ab869564b1dca4756ea0d5a4df68ca3f230e688e3117856727a524f4d5a69695a425763454f38106e474a635a4373624c635370477a4c380007001179d4df57db37c1cc592ae7c1e2e49e29628511976124646b0731f44eee291965774a437a5242686b6e776855546f5672614e6248417970361d4f72766b424366646872584a7242676b7941536e4c4f486f57466c76670007a73234c1689920010d6699d3b767ea4de84b327e0cf3a73c0b6ea054c8c46cf41e4d7763694b59534f664a784c776b766d626f706d7549656f4c794b6b63790a67504b774d665070637000079b74138cfefd9027529f7e7e55167dab06d1b850751b1da8de9f9c4815713cd5026a6b16787753617a6e76595a59684d614d6c594e4d7a595a30000700d90061007f012cc62ae6006fc91303a54491ddded79b80fd012fd8e17b88548000dd63b2ca8e550dc69cf5ac5c2a9f012caeb133ed8b4c86009933f29af21945aeea9455d1ea3fb70070344d9cf553d8e43c3d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444019a42d9e347c376f1f7b6e3a07593c0ba1b7506c27396a773d3c814da4830fc5501111349da303495d6829d5b8f583f19b5f8f3cf126842510dc8cce054a000a", + "signed_txn_bcs": "f253a2a6f7bc7167982750453804152e41cc5fdf8d4ce7dcd81793440b0e67face331d27d1ad64d0000ed03857d2e2bdd49c0fed358cca8a0406060107df86fce9a11f32295d6eff475d804ea1cc76f706b89658ee0eccb8872a8b69541f6e42546451754275425142437447524f7850784a4953787857626158444a3207574643597a50550007c1105095f8a507e2bdd783d42fa6cdf60680af811c1e8f379cf7ebe751697684034f5737146842704b50546e7a67796959755357735a6b625a00000801c862a3c50d8125dc01346d2f4662ad8f76050000a9034766bbc297565258d667b88188219b4e0367ffebb45914bab4c6f4c9fa8c397e050100010500c95701504d7d67396436e5e19d8d75b242c087d93b0ab087ba002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444077e1d6577e9d4d1172fdc854b3b8ef1446858035e6d0adabc42485fe78fd2921a439d513c2baab592496244b2413525a29ba03c64aabaaa35003716cc5090402", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "7613c6cb2834ee620c606f3ff75559fbba622cb087b0f79e7c8b45ae139bafec", - "sequence_number": "1706399116719379400", + "sender": "f81044b9e702312389c44f5a6442a4a4e4ff80f028de5fb6470e5dd8cb6819df", + "sequence_number": "14951616327499698008", "payload": { "Script": { - "code": "a8cfab8cccd3f447d2", + "code": "6d1dfac9bee8f7a54b7178e6", "ty_args": [ - { - "vector": { - "vector": "address" - } - }, - { - "struct": { - "address": "ac51b0c7f894a2789147d527ad2609d7459064457dc43115a3b6f442bccb980e", - "module": "FggGhQBvJcWnDXHGy3", - "name": "pFQvnPgyuXpqoxMZpplpiydMmAwli", - "type_args": [] - } - }, { "struct": { - "address": "43a51a415d8e7bae6e318b7e7f65117212544ed9d26c38c69fef987ce01763a3", - "module": "pdCgGVEAkeooPQnppavhLxV", - "name": "ewGroOjAJgs", + "address": "82095c4803d69ae9afb52e62b98c7b9a5d62f400d09497c5a1aef2b79450c21e", + "module": "sbZiurKoOnDaUHCfymCana6", + "name": "ofUyJCNnzlSnFnRdZtUn1", "type_args": [] } }, { "struct": { - "address": "9724f10eb8bdaf7b4bd77216733ec6642dd3c1321b2572d94ba931fa5771c086", - "module": "AapOJRhoCPr9", - "name": "JAwhoxMjfZZwc9", + "address": "87841872552c8a3bd9a5f20d49d5ce719a39e3484ec292b81b2510009aac4b9d", + "module": "zDVaksvAyFmN4", + "name": "sAaHZhDlmVnHbMmjHuKEk", "type_args": [] } }, - { - "vector": { - "struct": { - "address": "f5b6f4a8943425690294db075c5b86b224f5a3b3214647e6a756513b1744ddd4", - "module": "YznIlVwk4", - "name": "YVQBPUS", - "type_args": [] - } - } - }, - { - "vector": "bool" - }, { "struct": { - "address": "7501e345cad7aa857579675eee39204409de72d4b214933c62092627d4e4a805", - "module": "OeAYzteDTWxuiosjkSXVZvBqZVHq", - "name": "yksJvLrXIAmy7", + "address": "3712950223900d9e854b650934c18ae9d9d26418f98c5e899085d2cfc57d3a9a", + "module": "mfYDkeVyxtovGjO", + "name": "ijAhyoqiX", "type_args": [] } - }, - { - "vector": { - "vector": { - "struct": { - "address": "0ef15ebcabc045328c4e014ebdced27da5ed61f76eba3777275123b67c9b57aa", - "module": "xHpRKxU6", - "name": "HOCsekUWmo", - "type_args": [] - } - } - } } ], "args": [ { - "U128": "283468200632207921301017618007671628120" - }, - { - "Bool": true + "U64": "13227480147978568088" }, { - "U64": "7204411996546967455" + "Address": "f7e6a86617d5b5646ac5bc77335cb9945140de4b2d5fcaebd4291ee6cd85b64e" }, { - "Address": "24e517350e14e596481d62a8ef7d4b1bc0fe04ff3188919690d076dfdbdd36dd" - }, - { - "U8Vector": "f254bbb83ef0afebfd50" - }, - { - "U8": 22 - }, - { - "U8Vector": "cb6aafcab7384f43f1" - }, + "U8": 189 + } + ] + } + }, + "max_gas_amount": "14295657202696819219", + "gas_unit_price": "934966119282591900", + "expiration_timestamp_secs": "743999501008191489", + "chain_id": 25 + }, + "signed_txn_bcs": "f81044b9e702312389c44f5a6442a4a4e4ff80f028de5fb6470e5dd8cb6819df58cf8c32d5cf7ecf000c6d1dfac9bee8f7a54b7178e6030782095c4803d69ae9afb52e62b98c7b9a5d62f400d09497c5a1aef2b79450c21e1773625a6975724b6f4f6e446155484366796d43616e6136156f6655794a434e6e7a6c536e466e52645a74556e31000787841872552c8a3bd9a5f20d49d5ce719a39e3484ec292b81b2510009aac4b9d0d7a4456616b73764179466d4e3415734161485a68446c6d566e48624d6d6a48754b456b00073712950223900d9e854b650934c18ae9d9d26418f98c5e899085d2cfc57d3a9a0f6d6659446b65567978746f76476a4f09696a4168796f7169580003019841cbc51c7391b703f7e6a86617d5b5646ac5bc77335cb9945140de4b2d5fcaebd4291ee6cd85b64e00bd13927ff57b6064c69c48dd58bbaaf90c0140a9b29a37530a19002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440076d3eea1538615252eb60c5dc267cc3ee2c7319e7a1b9bb5d4ee998b51a90197e3081877fd41dab6c05546226db473b813bc95b40d8517bf0242f11eaadfa04", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "919e83780a53a34ac5f0d9c830f9659899a40213ad955dc377e5b45376016993", + "sequence_number": "3713091688849788495", + "payload": { + "Script": { + "code": "8c0dc657a8b5c414ab4e21", + "ty_args": [ { - "U128": "51177119647560543826431264473193611276" + "vector": { + "vector": "signer" + } }, { - "Bool": false + "vector": "u8" } - ] + ], + "args": [] } }, - "max_gas_amount": "2602951867719947708", - "gas_unit_price": "3223517900651077899", - "expiration_timestamp_secs": "6542621566755311154", - "chain_id": 206 + "max_gas_amount": "13042946056958781552", + "gas_unit_price": "3150143652295273602", + "expiration_timestamp_secs": "10390206255665303062", + "chain_id": 131 }, - "signed_txn_bcs": "7613c6cb2834ee620c606f3ff75559fbba622cb087b0f79e7c8b45ae139bafecc85319adf458ae170009a8cfab8cccd3f447d20806060407ac51b0c7f894a2789147d527ad2609d7459064457dc43115a3b6f442bccb980e1246676747685142764a63576e4458484779331d704651766e506779755870716f784d5a70706c706979644d6d41776c69000743a51a415d8e7bae6e318b7e7f65117212544ed9d26c38c69fef987ce01763a31770644367475645416b656f6f50516e70706176684c78560b657747726f4f6a414a677300079724f10eb8bdaf7b4bd77216733ec6642dd3c1321b2572d94ba931fa5771c0860c4161704f4a52686f435072390e4a4177686f784d6a665a5a776339000607f5b6f4a8943425690294db075c5b86b224f5a3b3214647e6a756513b1744ddd409597a6e496c56776b340759565142505553000600077501e345cad7aa857579675eee39204409de72d4b214933c62092627d4e4a8051c4f6541597a74654454577875696f736a6b5358565a7642715a5648710d796b734a764c725849416d7937000606070ef15ebcabc045328c4e014ebdced27da5ed61f76eba3777275123b67c9b57aa08784870524b7855360a484f4373656b55576d6f00090258e11ebe110469dc8e4b2ea255fd41d50501019fa7be4d8a36fb630324e517350e14e596481d62a8ef7d4b1bc0fe04ff3188919690d076dfdbdd36dd040af254bbb83ef0afebfd5000160409cb6aafcab7384f43f1020c80fb76dada4056ebb790e8ce5a80260500bc15e3c2ee8a1f240ba16ba3733cbc2c328e4292a60fcc5ace002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444013395756f744fdfdc2eac8cb81d5c07e5046ca34550a15111d4df10cd4e19ce89b13b1c27b0ebe60068b6a384c8d7bf0ca87be7bd92e929f6967a5e2ea60c405", + "signed_txn_bcs": "919e83780a53a34ac5f0d9c830f9659899a40213ad955dc377e5b453760169934fce58dc378d8733000b8c0dc657a8b5c414ab4e210206060506010070289c9555da01b582ec822af68eb72b16cef8338a6d319083002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400ad1916b089d378a3d1784f4e42fe7a84bd52de1ced648b0a6706ff8d1a3ba03baf25da39469edcf92ee8a3285cd462333853ee10f4160a30a217b02998ca10a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "032e24c8cd56b9fa0834c2dac90f73a2aae14e4e0b16f652b72bb23d112c00af", - "sequence_number": "7574377721982990589", + "sender": "799480538d19a5c529a01cc9ea4ac6551a2661efae08c64b54b4f97af67157ea", + "sequence_number": "6428080728338718564", "payload": { "Script": { - "code": "fbdadeec8fca2beb9a", + "code": "f52cfda36f6d132e99bcd2", "ty_args": [ { "vector": { "vector": { "struct": { - "address": "5fd30230b935329beecac88e6bdd7bf6321e99c42910b66931bbd956f70b841b", - "module": "dUQlhinDKsyoyIHqYDRhUJeo6", - "name": "EgoxlbvqGJg", + "address": "6b2a98fd068e552c28b4b86be5e6d41ecd1b673e4f76357c01bf72e3253ab436", + "module": "pDe", + "name": "cXfLydOWjGZHLRZTt", "type_args": [] } } } }, { - "struct": { - "address": "810c21fdd35e8730962c6d8b95d0ba5c03b96f9004132d780c11d756022102b3", - "module": "LOWnJuSfgFvVfnEoFALcuVWTYpLljwkP9", - "name": "MJVVUpOykVkbNerfmroNMVcGcBvVR", - "type_args": [] + "vector": { + "struct": { + "address": "dd6c25ee246bd6c6f1ae8858102a61719fff5586209319e9fe4ce8f0a5a5aebc", + "module": "PvVfxEvbioot", + "name": "dzPdCmgMJySyTZHQNSuZXmfqTYwfHGIp0", + "type_args": [] + } } }, { - "vector": { - "vector": { - "struct": { - "address": "d25df829b39ff74ef444128b7b3e6f558aee6ec123454f628ef55929e5365f48", - "module": "MbvmWWDjPIIFqdPy8", - "name": "HKDjfnSEcvuwetjPXaarWQdhwZ2", - "type_args": [] - } - } + "struct": { + "address": "f219f64678ca6cf8291acef055020c8727a7bdc3349832e64897e37a3bfa22bc", + "module": "zURlPOSJWcdOqRBZAWZIpYsOXs7", + "name": "USXUVmqqTbWpsZCYHxnGHwPHUhid", + "type_args": [] } } ], - "args": [] + "args": [ + { + "Bool": true + }, + { + "U64": "4991296121917984485" + }, + { + "U8Vector": "1c81a0fda08b" + }, + { + "U64": "780270738634991358" + }, + { + "U8": 186 + } + ] } }, - "max_gas_amount": "2075620853176563889", - "gas_unit_price": "16277998168108031144", - "expiration_timestamp_secs": "10390203313178923156", - "chain_id": 155 + "max_gas_amount": "10680423677853326845", + "gas_unit_price": "13506371687864439490", + "expiration_timestamp_secs": "14235487095123703959", + "chain_id": 231 }, - "signed_txn_bcs": "032e24c8cd56b9fa0834c2dac90f73a2aae14e4e0b16f652b72bb23d112c00affdb86d4968981d690009fbdadeec8fca2beb9a030606075fd30230b935329beecac88e6bdd7bf6321e99c42910b66931bbd956f70b841b196455516c68696e444b73796f7949487159445268554a656f360b45676f786c627671474a670007810c21fdd35e8730962c6d8b95d0ba5c03b96f9004132d780c11d756022102b3214c4f576e4a75536667467656666e456f46414c637556575459704c6c6a776b50391d4d4a565655704f796b566b624e6572666d726f4e4d566347634276565200060607d25df829b39ff74ef444128b7b3e6f558aee6ec123454f628ef55929e5365f48114d62766d5757446a5049494671645079381b484b446a666e53456376757765746a505861617257516468775a320000b178fb392b16ce1ca8dc89e01611e7e194d01d1add6a31909b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ac83471283dfbf85f5d46cb11996d4c9744c6975f16d9d51011e555628e9b351dcc332ca09069b403659843bcc71bda62451d6cab1c69627f1f26928347e9204", + "signed_txn_bcs": "799480538d19a5c529a01cc9ea4ac6551a2661efae08c64b54b4f97af67157ea64df29705d213559000bf52cfda36f6d132e99bcd2030606076b2a98fd068e552c28b4b86be5e6d41ecd1b673e4f76357c01bf72e3253ab43603704465116358664c79644f576a475a484c525a5474000607dd6c25ee246bd6c6f1ae8858102a61719fff5586209319e9fe4ce8f0a5a5aebc0c5076566678457662696f6f7421647a5064436d674d4a795379545a48514e53755a586d66715459776648474970300007f219f64678ca6cf8291acef055020c8727a7bdc3349832e64897e37a3bfa22bc1b7a55526c504f534a5763644f7152425a41575a497059734f5873371c55535855566d717154625770735a435948786e4748775048556869640005050101e5ceb4bb60a5444504061c81a0fda08b01fe66f84c1a14d40a00bafd5d1e69bf7c3894c2928d837d4570bb97788115179c8ec5e7002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409337a380a5f706396db12c02bf2dfb5db5263f2d42f72b6166532bd71650dd8d1e500fc6586e0c7d2f45e5fb78dfa67b596e2f9118f830871038edddfbb8150c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "9b45e8f59e9d6ac60a4ebd256775ae022e19625b2eb79ee88557f996bfc6c036", - "sequence_number": "14205352846149403986", + "sender": "1fad49a667854e48a305d969c3dae702db79b0d19e1215751491f2f5ab2ec782", + "sequence_number": "3555661566543083544", "payload": { "Script": { - "code": "ece1f5a7e69bf3feebe679aac8ac", + "code": "d1d07dd79331a51b0ace4613d52d", "ty_args": [ { - "struct": { - "address": "f10ab73d9799022a1e244760371f7677296d3ef09b116fce093dea6f10cc4558", - "module": "PdsFhy", - "name": "pbzQzumOrWLBwhMm", - "type_args": [] - } - }, - { - "struct": { - "address": "295c656d2c6157fbba785d6d43ce573e80c8f4c804452d3312b61e8c5db52bfe", - "module": "ut2", - "name": "ijEXcPXHGalxtSojKDrJoU0", - "type_args": [] - } - }, - { - "struct": { - "address": "03f391db9aec24f47fceb36df7bd7df5433e751125968e576776b5be5f4c8668", - "module": "PrUXpolfbhfOlpjvESLoQSZT", - "name": "wPZCxurRmQbUSXfSWreTmqQOFluBcNy", - "type_args": [] - } + "vector": "signer" }, { "vector": { - "vector": "u64" + "vector": "u8" } }, { "vector": { "struct": { - "address": "6709402959a757bbb4731ea1f45a3c417a89a200128cc1f57108b093f6c6ac3a", - "module": "NrmuPhxcMHyUjUKTL0", - "name": "aCZKmluTDhojJwrPMe3", + "address": "ab2fdcc69ea495e33ff51f33ae10344c0f901fb1c34011bd9ea0692a9a9b37f7", + "module": "KqyZqQWPlSRcfdgmVYrxsVTEJYkoV4", + "name": "CvEgLcjsZ", "type_args": [] } } }, { - "struct": { - "address": "14b489255eb39ecea08b58411e12949f4593d4937083b52a8d106d00c4b460cb", - "module": "LfozpEyJYklJJ5", - "name": "QYWhYcAVTUxVXudWULLPhLrQHlguoxUG", - "type_args": [] + "vector": { + "vector": { + "vector": "u128" + } } } ], "args": [ { - "Bool": true + "U8": 30 }, { - "Address": "93e4754c81bdf320bc7ca4d38d55985ddaf5044e9c4dc6de285f33f76665aa73" + "U128": "129276751065345552951432700655578992622" } ] } }, - "max_gas_amount": "13481784958246247653", - "gas_unit_price": "123245906274907829", - "expiration_timestamp_secs": "13141077505956651830", - "chain_id": 26 + "max_gas_amount": "2145903621860984851", + "gas_unit_price": "13430175339104821123", + "expiration_timestamp_secs": "16181208580549465986", + "chain_id": 121 }, - "signed_txn_bcs": "9b45e8f59e9d6ac60a4ebd256775ae022e19625b2eb79ee88557f996bfc6c03652c5d17f268d23c5000eece1f5a7e69bf3feebe679aac8ac0607f10ab73d9799022a1e244760371f7677296d3ef09b116fce093dea6f10cc4558065064734668791070627a517a756d4f72574c4277684d6d0007295c656d2c6157fbba785d6d43ce573e80c8f4c804452d3312b61e8c5db52bfe0375743217696a45586350584847616c7874536f6a4b44724a6f5530000703f391db9aec24f47fceb36df7bd7df5433e751125968e576776b5be5f4c86681850725558706f6c666268664f6c706a7645534c6f51535a541f77505a43787572526d51625553586653577265546d71514f466c7542634e790006060206076709402959a757bbb4731ea1f45a3c417a89a200128cc1f57108b093f6c6ac3a124e726d75506878634d4879556a554b544c301361435a4b6d6c755444686f6a4a7772504d6533000714b489255eb39ecea08b58411e12949f4593d4937083b52a8d106d00c4b460cb0e4c666f7a7045794a596b6c4a4a352051595768596341565455785658756457554c4c50684c7251486c67756f785547000205010393e4754c81bdf320bc7ca4d38d55985ddaf5044e9c4dc6de285f33f76665aa73e5dc786efdeb18bbb57689af7fdbb50136236c045e7c5eb61a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a3d2668cbd3538229d984ff0d359841473e46c655e8663083c59462cef340a544221ea1982d092e03a8dba7964295f1b4decd70ddb9d6e3fb941d4b22ed5a604", + "signed_txn_bcs": "1fad49a667854e48a305d969c3dae702db79b0d19e1215751491f2f5ab2ec78218384f275b3f5831000ed1d07dd79331a51b0ace4613d52d0406050606010607ab2fdcc69ea495e33ff51f33ae10344c0f901fb1c34011bd9ea0692a9a9b37f71e4b71795a715157506c5352636664676d56597278735654454a596b6f563409437645674c636a735a000606060302001e02ee4f59a4bda6e0d6bace39e9edcb416113883f7ff9c7c71d83df8d96509161ba825727e878338fe079002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402b43eba0289837d5eff8353cbd1cae8070fe90f82595b3df329325d15592944174f5afbf80f296e9744ac2f470d4e67355f50123a6ffdd61af87510f96b0440c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "7edf554bde3c414e7ae7abc9c50c8c667561ea4113ba0a15bc9b6aca75dcafbe", - "sequence_number": "3368735613719441705", + "sender": "fdf9645a5604f72e8b5a5bd1ce147df19c32649409e6cbc843ee52e1ed9e3351", + "sequence_number": "13891525780570891155", "payload": { "Script": { - "code": "5df50201ec", + "code": "ec1e993d", "ty_args": [ { - "vector": { - "struct": { - "address": "6b95c62aabf2db9f7acbe87b8d5ddf719ec399785e2172fdaf7529bca905588b", - "module": "qLyIhirreoJUWBmi4", - "name": "EclbOsKngzgRudpVmVbJxDCciNgL0", - "type_args": [] - } + "struct": { + "address": "a44d9dc0f7c5bbf75b97481bd05e3ad0bceba9b4a3313429faad53b9ddf35a95", + "module": "HHOXhcEjkvFaDymCJuYXMhwjljylLO6", + "name": "pcxTCbyOJQazlFxlaJVkwcKYVafe", + "type_args": [] } }, { "struct": { - "address": "cd30d430f2ee2c18fc7176bef8f84c5f5cd941da18921c631e1c92baa784148f", - "module": "vRQMDCKLTAwcgrjZKzHycLluVkQ", - "name": "WPxxkqwPfhjcHDWlkjXdrDkhmSYGW", + "address": "2533ef70199aaae2758e5e8396fcbd65276789a8d33d46f1d7290f8fef1fb1c7", + "module": "NAzQFnYwjbYKLQZWOPiOGzdqCSCQ", + "name": "ljgIogYfAbvO3", "type_args": [] } }, { "struct": { - "address": "cbe49cf2c8780d01b499c6da1faa3b6d309fc9a762939e2d4205962255d096a7", - "module": "TeVLyhgRWZptEMukyevSdrx4", - "name": "yTKOBHZJtmGCQn", + "address": "4d54d77d298154b9a6eac50251833b69ba3aa3b49fae10abf3f102b62dcdc040", + "module": "Qx5", + "name": "kikXgJg5", "type_args": [] } }, { "struct": { - "address": "a4d43cc6f08278714e3f2d3587ddbb493698da04327d643d9fc13875b7536c22", - "module": "gppwbpCsFThj", - "name": "BejsTdhGdqnNNmNjKpYSmtJTHowRDU", + "address": "2d9d82ae002a8b20ef3a7d8edd9c6e13b14323f605169567019a76309b9b0c78", + "module": "YBIZGnUdVgyzpqnwCWOrhfMeffuPtM0", + "name": "QOLcXhzMt", "type_args": [] } }, { "vector": { - "vector": "bool" + "vector": { + "struct": { + "address": "53d9ca124767f92cb2429093a2ecb40701a41f37697c2109da4f071e4593112c", + "module": "XBPZyGwvfrvRgLnsQdgDcwnbmfATu8", + "name": "Zl", + "type_args": [] + } + } } }, { - "vector": { - "vector": { - "vector": "address" - } + "struct": { + "address": "42d1cfe3093052308f73734690e1cda8579cf179d06e5e242ca76b53a517ab0c", + "module": "zihd", + "name": "PZJn8", + "type_args": [] } }, { "vector": { - "struct": { - "address": "4516bd2851ac1d9364aee2a51e87dfcb8a37dc99a622ada65994413d125ec33d", - "module": "daVlNf1", - "name": "IHRMHkZnb4", - "type_args": [] - } + "vector": "u128" } }, { - "struct": { - "address": "102f3a7d3aaf3f20e270fffef0b4118ba731f932ce1970e09ba187cd34edf069", - "module": "FnzPbxLxhYtCb8", - "name": "bDqVJgkYKJurYIbuTNCokjq", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "34c7607fe2cd3d0552c84dc0abb39e4b7698c60c8a3dbcd36a2003c764a1fb83", + "module": "JaTfYxmVyMhNizGwp9", + "name": "vHsSYzynEo", + "type_args": [] + } + } } }, { "struct": { - "address": "2010184befd59e3ebc4bf661557bd028f7aef798cb72cd83ccb97d1651ebf258", - "module": "aDgRMDSqmpetuzlJMvFSNmyUF", - "name": "XvZyPUhN", + "address": "9211a473afb21b2fcd80931e8fff2028557c7de59ac6516882c00e8f415b5f28", + "module": "LPmmTRtRrvxpy", + "name": "dDhIJxsMVzqzfZoXX", "type_args": [] } } @@ -1355,43 +1371,28 @@ "args": [] } }, - "max_gas_amount": "15980864413258155199", - "gas_unit_price": "1555563745445757059", - "expiration_timestamp_secs": "17243099985585191978", - "chain_id": 39 + "max_gas_amount": "13053965050136016325", + "gas_unit_price": "8579807345382899004", + "expiration_timestamp_secs": "1529158086750067956", + "chain_id": 145 }, - "signed_txn_bcs": "7edf554bde3c414e7ae7abc9c50c8c667561ea4113ba0a15bc9b6aca75dcafbe2971f43d3127c02e00055df50201ec0906076b95c62aabf2db9f7acbe87b8d5ddf719ec399785e2172fdaf7529bca905588b11714c794968697272656f4a5557426d69341d45636c624f734b6e677a6752756470566d56624a78444363694e674c300007cd30d430f2ee2c18fc7176bef8f84c5f5cd941da18921c631e1c92baa784148f1b7652514d44434b4c5441776367726a5a4b7a4879634c6c75566b511d575078786b71775066686a634844576c6b6a586472446b686d535947570007cbe49cf2c8780d01b499c6da1faa3b6d309fc9a762939e2d4205962255d096a7185465564c79686752575a7074454d756b79657653647278340e79544b4f42485a4a746d4743516e0007a4d43cc6f08278714e3f2d3587ddbb493698da04327d643d9fc13875b7536c220c67707077627043734654686a1e42656a735464684764716e4e4e6d4e6a4b7059536d744a54486f77524455000606000606060406074516bd2851ac1d9364aee2a51e87dfcb8a37dc99a622ada65994413d125ec33d076461566c4e66310a4948524d486b5a6e62340007102f3a7d3aaf3f20e270fffef0b4118ba731f932ce1970e09ba187cd34edf0690e466e7a5062784c7868597443623817624471564a676b594b4a757259496275544e436f6b6a7100072010184befd59e3ebc4bf661557bd028f7aef798cb72cd83ccb97d1651ebf25819614467524d4453716d706574757a6c4a4d7646534e6d7955460858765a795055684e0000bf04ef7b836fc7dd8340c518fc7896152a3c593b14cc4bef27002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144403b41631678d5a31d3e2b7df1a94a3d62f252a69a5bda7cdc4b0c50ff878e149cef1a1fcf1503c9c2a733117ddf8e2d27eb689e6a1183a5693ebc7e75527e1907", + "signed_txn_bcs": "fdf9645a5604f72e8b5a5bd1ce147df19c32649409e6cbc843ee52e1ed9e335193e31bd3189dc8c00004ec1e993d0907a44d9dc0f7c5bbf75b97481bd05e3ad0bceba9b4a3313429faad53b9ddf35a951f48484f586863456a6b76466144796d434a7559584d68776a6c6a796c4c4f361c706378544362794f4a51617a6c46786c614a566b77634b595661666500072533ef70199aaae2758e5e8396fcbd65276789a8d33d46f1d7290f8fef1fb1c71c4e417a51466e59776a62594b4c515a574f50694f477a6471435343510d6c6a67496f6759664162764f3300074d54d77d298154b9a6eac50251833b69ba3aa3b49fae10abf3f102b62dcdc04003517835086b696b58674a673500072d9d82ae002a8b20ef3a7d8edd9c6e13b14323f605169567019a76309b9b0c781f5942495a476e55645667797a70716e7743574f7268664d6566667550744d3009514f4c6358687a4d740006060753d9ca124767f92cb2429093a2ecb40701a41f37697c2109da4f071e4593112c1e5842505a7947777666727652674c6e735164674463776e626d6641547538025a6c000742d1cfe3093052308f73734690e1cda8579cf179d06e5e242ca76b53a517ab0c047a69686405505a4a6e380006060306060734c7607fe2cd3d0552c84dc0abb39e4b7698c60c8a3dbcd36a2003c764a1fb83124a61546659786d56794d684e697a477770390a76487353597a796e456f00079211a473afb21b2fcd80931e8fff2028557c7de59ac6516882c00e8f415b5f280d4c506d6d54527452727678707911644468494a78734d567a717a665a6f58580000c5b5b8db0c0029b53cbdd5a652991177f45c27962da9381591002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440661db9ac9af5877000ae301c1a914109e8b75ebba36798ac82bfc3070ef6a5e97d0f4e8740fcbe37879ae85a8897ba3d791e604677a49f8ba90f9ecbd985ee00", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "789fdeeb4d71acac26107eb686b8b2c791f746b84254d56a89549de4c2855f06", - "sequence_number": "3131219673398083535", + "sender": "e274a13f630e77305eb120c6257ed9fd7512ec11e391aa950650bb8697c2055b", + "sequence_number": "1707861502839437572", "payload": { "Script": { - "code": "cbc773eefbb245aff9f03b7a738b78", + "code": "afdf22fad5d9b2b584", "ty_args": [ { "vector": { "struct": { - "address": "4eec3ea3011bd28bb915afebbf49920baf7c4b315e3020497c730ab22f18dc01", - "module": "dGAIHRQGQJ1", - "name": "DqzbeldUoiovQxFex3", - "type_args": [] - } - } - }, - { - "vector": { - "vector": "address" - } - }, - { - "vector": { - "struct": { - "address": "d017f45b5bc2f8bcbfd95226ada46b101ce62556ba52b11fb687677b90de4139", - "module": "fNWMXtfHc3", - "name": "FdDZjDQosPxHPzvzh", + "address": "b99f7baa4483e94dd48afaad2be117d0c3eb09dc70a8cc459c716e0681ba79a0", + "module": "QNsmHtbHyyfOLJvVRudF", + "name": "KlArCLkREkpVsrUXquVxLpseCCsyQJL9", "type_args": [] } } @@ -1399,879 +1400,861 @@ { "vector": { "vector": { - "vector": { - "struct": { - "address": "c4e763bf2b786463771808a34f73f15f20a1218ec8762775237ce8b809768fc7", - "module": "XlvSBQUbAjtWQzsMppKasbnPbzAtqY", - "name": "FzcwoRmmKCd", - "type_args": [] - } - } - } - } - }, - { - "vector": { - "struct": { - "address": "bb881b1ceb810136155dcec32f97e4f66013d60144d835e8be906b57a42dd881", - "module": "bdnuPNkbsPrTMMAUgJQZymejJcL1", - "name": "GYzKhmNUMAlyfkelxPnsxmS5", - "type_args": [] + "vector": "u64" } } - }, - { - "struct": { - "address": "bcfd93d296c4d90573605fef28c012ead61ad84b713b95ffe8327f8b2e107877", - "module": "M5", - "name": "cYNzvxanGAGdfg7", - "type_args": [] - } } ], "args": [ { - "U8Vector": "42fc253d7f5619b1ea5b" - }, - { - "U64": "1473128561786810381" - }, - { - "Address": "c054c088beed0f3e116692fb98c71fe07cfff6daf3307a3e08242902669b0f29" - }, - { - "U8Vector": "b5796b7e" + "Address": "29628511976124646b0731f44eee292a0f3c0ef6c55eab6dd048d24b07066005" } ] } }, - "max_gas_amount": "16830529844262677456", - "gas_unit_price": "6640323194831559980", - "expiration_timestamp_secs": "1082914194734019568", - "chain_id": 162 + "max_gas_amount": "9736704560257072061", + "gas_unit_price": "6373179767395044284", + "expiration_timestamp_secs": "4910113764382074429", + "chain_id": 206 }, - "signed_txn_bcs": "789fdeeb4d71acac26107eb686b8b2c791f746b84254d56a89549de4c2855f06cf7f9bfab353742b000fcbc773eefbb245aff9f03b7a738b780606074eec3ea3011bd28bb915afebbf49920baf7c4b315e3020497c730ab22f18dc010b6447414948525147514a311244717a62656c64556f696f76517846657833000606040607d017f45b5bc2f8bcbfd95226ada46b101ce62556ba52b11fb687677b90de41390a664e574d587466486333114664445a6a44516f73507848507a767a680006060607c4e763bf2b786463771808a34f73f15f20a1218ec8762775237ce8b809768fc71e586c765342515562416a7457517a734d70704b6173626e50627a417471590b467a63776f526d6d4b4364000607bb881b1ceb810136155dcec32f97e4f66013d60144d835e8be906b57a42dd8811c62646e75504e6b62735072544d4d4155674a515a796d656a4a634c311847597a4b686d4e554d416c79666b656c78506e73786d53350007bcfd93d296c4d90573605fef28c012ead61ad84b713b95ffe8327f8b2e107877024d350f63594e7a7678616e474147646667370004040a42fc253d7f5619b1ea5b010df0c8399f9a711403c054c088beed0f3e116692fb98c71fe07cfff6daf3307a3e08242902669b0f290404b5796b7ed02be3acb80d92e92cddb885c32a275cf07359fbb848070fa2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406855c411e32a53a309df3f2567df522585045a7a1ba4fc025a918df76b4711f2fbd6f71e9ef31927572938725f190e3a4fb4291f7e7462071d0b10d3a6564e08", + "signed_txn_bcs": "e274a13f630e77305eb120c6257ed9fd7512ec11e391aa950650bb8697c2055b04394ffafc8ab3170009afdf22fad5d9b2b584020607b99f7baa4483e94dd48afaad2be117d0c3eb09dc70a8cc459c716e0681ba79a014514e736d487462487979664f4c4a765652756446204b6c4172434c6b52456b705673725558717556784c70736543437379514a4c390006060602010329628511976124646b0731f44eee292a0f3c0ef6c55eab6dd048d24b07066005bd7b0cd535b91f87bccb495d3b1572583de6bf2c743a2444ce002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144408aad6954cb3795ed4438fcb1e0d9f10a20c7608ac5a602335af116bea982b74f8bfe24c29a2880c61df4f43a94530453f8df328fddcf756656937f707966ec0f", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "b005f82c41c8735370ce3e476f72abadf43b14bd9ccdda2eaf7d9afe2adce49c", - "sequence_number": "11371359119202989976", + "sender": "7dc83737f22bb99f1a13d0de5915a1130dc0a924ac662bca83b1696b85afdbaa", + "sequence_number": "2895946074836110500", "payload": { "Script": { - "code": "ab91dd", + "code": "12e5acad90bc49", "ty_args": [ { "vector": { - "vector": "signer" + "vector": { + "vector": "u8" + } + } + }, + { + "struct": { + "address": "702b9794ea87fd2a6247455fbf2c75292ff0a1ca1f801ab28e3872e2e459b91a", + "module": "pVmydAslEqhPEWd", + "name": "OIOmCbpMF3", + "type_args": [] } }, { "struct": { - "address": "51988913ad90eacadc9c6768529b5dbd3c28349768b0ecb58bdf115e4192457c", - "module": "gFRXDPzTQU", - "name": "WbkpzJMhCZo8", + "address": "1ef6d4c80149bc94a9c53959d91321fed8292ef895909621a73234c168992001", + "module": "qAZzkpXBtIwjpacRkUBpcShuLsBFXQFd8", + "name": "ASbVZVhMubYejRySNyONUkuxgGYWlOy", "type_args": [] } }, { "struct": { - "address": "44d14eeb4058b91b58dbed7aa7071194598a85c2ad0609122ead759b921a003e", - "module": "pjhUHSwzPwNcAjW", - "name": "WEADYWJYcDluQDn4", + "address": "29235f5ceb7400bf3a0add4dfe1459834f52b20caa37100de3e05493f6cc04f7", + "module": "YTRTCfXaiYEJDuqHsSbXnaYkpInbxjx", + "name": "dpsfqqDRIIYoCVFh", "type_args": [] } }, { "vector": { - "struct": { - "address": "0ce5d870613c1c5605d20787ac0e00697dbaa960b0186d2c43e7a97a184bd297", - "module": "FUeAibcKfKKgNZmIkTPv8", - "name": "ljhskKQdpsBgzInFVGmMgkKJ", - "type_args": [] - } + "vector": "signer" } }, { "vector": { "struct": { - "address": "495d17d49349c4a35a0c0a7782c06f57e14955cf0a8a6b6ec160ec797ae67b5b", - "module": "ujPcdXxMSKfsGtwVYX", - "name": "jhBZWSnxtnzBcvqavkcIu9", + "address": "1dfbb5c2e365e5e8a44743eed8f4716800e6e40748a549fdef4bf9d99c7e4df3", + "module": "dOedQitGizMFtJrCEvKSzieqF4", + "name": "Wzqxk", "type_args": [] } } }, { - "vector": { - "vector": "u8" + "struct": { + "address": "d8324b2b02c8033418b1f8f2269b436a1dcbb27f45336178ef8e8a1848821b4e", + "module": "iAkDDXBSYDFHugKpGaJ6", + "name": "mBdfBjjTgATNzBq", + "type_args": [] } }, { "vector": { "struct": { - "address": "b1577560b93c98ee664ae48663845fa2a6915faf56991ab10db8afa26d7269c7", - "module": "UxKBGeXMNX5", - "name": "gnOruFDGpFnIsKsTQWxT3", + "address": "23daa2e0d824eb288b18861e1a81dcac662277d737fb9d3f33f2a480cc6fa540", + "module": "TG", + "name": "gflfwKxwnHWX", "type_args": [] } } }, { "vector": { - "vector": { - "vector": "address" + "struct": { + "address": "89316687675a6ad7c98163dd93f08906bcc961e4bf8d58060777cbf092ee45c3", + "module": "L", + "name": "jVrJARfUJ", + "type_args": [] } } }, { - "struct": { - "address": "8ce74ceba02dfed5629171a2999c0b33e2778036c9ce04cb9a013655056511e5", - "module": "SmutLKxHbukdKBFBzZzb9", - "name": "PziRESIDHFKrgyYErCGMDWixMO", - "type_args": [] - } - }, - { - "struct": { - "address": "d7f06c21c2de3b0b0aed06bea393bbca0665b2113a2da3fbddeeb55ca5d75aa7", - "module": "ospjfRLLhIdlNQfFqHvMxIUr2", - "name": "fdioncSOUNUjhRMxnyD5", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "07cf4105afd69a6ffa08eb3ff79ed88bb2b2cdc6d2d417f3bb52ded295a23d1a", + "module": "lWASWwvEOkKVdUKJdpHCrM", + "name": "VNmnZJEDdLJvlZPXrFbOrRFe3", + "type_args": [] + } + } } } ], - "args": [ - { - "Bool": true - }, - { - "Bool": false - } - ] + "args": [] } }, - "max_gas_amount": "9601868369686518606", - "gas_unit_price": "13290345674121224896", - "expiration_timestamp_secs": "16510887524430014979", - "chain_id": 151 + "max_gas_amount": "10998293935718974367", + "gas_unit_price": "3543300086054847203", + "expiration_timestamp_secs": "17292235556376811790", + "chain_id": 165 }, - "signed_txn_bcs": "b005f82c41c8735370ce3e476f72abadf43b14bd9ccdda2eaf7d9afe2adce49c98377ef1de2ecf9d0003ab91dd0a0606050751988913ad90eacadc9c6768529b5dbd3c28349768b0ecb58bdf115e4192457c0a6746525844507a5451550c57626b707a4a4d68435a6f38000744d14eeb4058b91b58dbed7aa7071194598a85c2ad0609122ead759b921a003e0f706a68554853777a50774e63416a57105745414459574a5963446c7551446e340006070ce5d870613c1c5605d20787ac0e00697dbaa960b0186d2c43e7a97a184bd29715465565416962634b664b4b674e5a6d496b54507638186c6a68736b4b5164707342677a496e4656476d4d676b4b4a000607495d17d49349c4a35a0c0a7782c06f57e14955cf0a8a6b6ec160ec797ae67b5b12756a50636458784d534b6673477477565958166a68425a57536e78746e7a4263767161766b63497539000606010607b1577560b93c98ee664ae48663845fa2a6915faf56991ab10db8afa26d7269c70b55784b424765584d4e583515676e4f727546444770466e49734b735451577854330006060604078ce74ceba02dfed5629171a2999c0b33e2778036c9ce04cb9a013655056511e515536d75744c4b784862756b644b4246427a5a7a62391a507a69524553494448464b72677959457243474d445769784d4f0007d7f06c21c2de3b0b0aed06bea393bbca0665b2113a2da3fbddeeb55ca5d75aa7196f73706a66524c4c6849646c4e5166467148764d7849557232146664696f6e63534f554e556a68524d786e7944350002050105004e5b39cb68b04085c02225b0f9ca70b8036a149cb97422e597002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404919f7468bfdd2e3226798275f81e2dea5baac6bf98b20621a90f5b443e3c85af780176083f45bd54c65288bfb396c9ba56393faa6a9bc75b6e96e27bc289001", + "signed_txn_bcs": "7dc83737f22bb99f1a13d0de5915a1130dc0a924ac662bca83b1696b85afdbaaa40c4b979c773028000712e5acad90bc490a0606060107702b9794ea87fd2a6247455fbf2c75292ff0a1ca1f801ab28e3872e2e459b91a0f70566d796441736c457168504557640a4f494f6d4362704d463300071ef6d4c80149bc94a9c53959d91321fed8292ef895909621a73234c1689920012171415a7a6b7058427449776a706163526b554270635368754c73424658514664381f415362565a56684d756259656a5279534e794f4e556b7578674759576c4f79000729235f5ceb7400bf3a0add4dfe1459834f52b20caa37100de3e05493f6cc04f71f59545254436658616959454a44757148735362586e61596b70496e62786a781064707366717144524949596f435646680006060506071dfbb5c2e365e5e8a44743eed8f4716800e6e40748a549fdef4bf9d99c7e4df31a644f656451697447697a4d46744a724345764b537a696571463405577a71786b0007d8324b2b02c8033418b1f8f2269b436a1dcbb27f45336178ef8e8a1848821b4e1469416b44445842535944464875674b7047614a360f6d426466426a6a546741544e7a427100060723daa2e0d824eb288b18861e1a81dcac662277d737fb9d3f33f2a480cc6fa5400254470c67666c66774b78776e48575800060789316687675a6ad7c98163dd93f08906bcc961e4bf8d58060777cbf092ee45c3014c096a56724a415266554a0006060707cf4105afd69a6ffa08eb3ff79ed88bb2b2cdc6d2d417f3bb52ded295a23d1a166c574153577776454f6b4b5664554b4a64704843724d19564e6d6e5a4a4544644c4a766c5a50587246624f725246653300009fc3dc2510caa198e302e9b1a7542c310e1938ce9e5cfaefa5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ea7f6bebb7f91fa9f08a88c0de9def3902b73ece097334c73fcd7f12e90950b52eb6c8d645254bcd3ba2209235de685cca0aa03b91f473c01faeb7e9ba1c0102", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "8b37e28b5c9bb57483162ccb5e1a4a713f19bd8ef06348dcc7de07e0c15652b5", - "sequence_number": "9717115411162054424", + "sender": "56a8c963a752a82d87ee5b4593253ab14b324243f82f93c1ac8e92227c9c75b8", + "sequence_number": "3947346515594680668", "payload": { "Script": { - "code": "2dcc63", + "code": "39408f7b7a92c574bf7c1705c3", "ty_args": [ { - "vector": { - "struct": { - "address": "c40a3c773ec8605a6290c99e2a2fb7eb349a6f472a9258d982435b5ea263bfb2", - "module": "waemqzmJCfhzBsldQAGGeGb1", - "name": "BlecvqTChOVtbtciOEczko", - "type_args": [] - } + "vector": "u8" + }, + { + "struct": { + "address": "7328d0be15ab151b4cefd447f8fde5180ff23d27eb3f5e73ed0478a9ca7c1592", + "module": "Oh", + "name": "hgoNkJxaLEOboekTWyMe", + "type_args": [] } }, { "struct": { - "address": "cd2d58a88c338de7dcc426502f0ef4e5bfb0a4ae268dd41372820d304243834e", - "module": "rPOoguqydLD9", - "name": "B8", + "address": "385d289a1449125597f52fc0d50ce55f16bb93dcf77d9ffd1d133a3fcbd5be8e", + "module": "xQBAmIhKIduDqZahyisjMVtKQx", + "name": "fMxShxHdprnRD", "type_args": [] } }, { "vector": { - "vector": { - "vector": "u64" - } + "vector": "address" } }, { "struct": { - "address": "f35bb05c1d0288cf714b5918f75f4f5bd910bda38af1de193221acf6a22ab87e", - "module": "dYusHtRuDkUM6", - "name": "vIsZcGhSWtCEtEOWzOZCpDILrne9", + "address": "1285ed7f900e8b1b99145c05cf7dc0be9a2770b53e4b2e0f4e3c3bcbec7eeb0e", + "module": "ecgzhvouadziQwQsVe", + "name": "gGHJtuhEBvYEwknYXKDaPKtUzsQK", "type_args": [] } }, { - "struct": { - "address": "e8b8865be5f7aeafe09e8417f3e1727855f970ab1d7364bb1217f0c2403a4641", - "module": "BUbcqFFnPdBJNRqJneixcwot", - "name": "ekYbvcVaqFOGPiZMbOtpcJWxSf5", - "type_args": [] + "vector": { + "struct": { + "address": "887467fe6af9ada54daec830abe9415e48e02b5c6599b871db100ef15ebcabc0", + "module": "GeY", + "name": "QiIQroQIAozcEUk3", + "type_args": [] + } } }, { - "struct": { - "address": "50adb5b2703afb1fb09ca217960bc0921e34ece9b8a97ee6dc5b3c2a617c3749", - "module": "nxBeRjRZTmxzALviKOAXVu", - "name": "wFBoVZc1", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "1728e1ce1184ba469aa8977e417707292ed0530a9d7b4a5ba56158118e55af30", + "module": "RYdIXZTITPLbAhtK", + "name": "iFHDWLALPiLYvHBViWGslLSjYASiDQfn", + "type_args": [] + } + } } }, { - "struct": { - "address": "2c78afd9270fca61cc039d13193147c5cba85f43b4fea76c5c8a4f5238324f51", - "module": "UxBVfEoXdHDVEd5", - "name": "vTygFcEbIv4", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "635abd03be654c6a2450fd042cace6effe0d52b62af09531313f33689132213a", + "module": "vHOEWFTdAUFgRJgbt", + "name": "pSQBxhlTJKjOG9", + "type_args": [] + } + } + } + }, + { + "vector": { + "vector": "address" } }, { "struct": { - "address": "9327244e60d4b818748cabd00597daa5bc9c0f66f74ecc171b34b2e0c3fae99e", - "module": "mXrMxUhuvhktgwpmvHcFs", - "name": "blclpfBUkRpKxUATvWNPd4", + "address": "1b28f4156bf300a23fdc85e0acf5f241d79259862e24dbf930b65ab7addf785c", + "module": "MWwOk", + "name": "sAutiJYXpjeupmUA7", "type_args": [] } } ], "args": [ { - "U64": "1456176404328498001" + "U8": 68 + }, + { + "U8": 156 + }, + { + "U8": 124 + }, + { + "U64": "7589469449094887828" + }, + { + "U8Vector": "9c6e9dff087e9af36cc5bf188e" + }, + { + "U8": 177 + }, + { + "U64": "8488512686883627308" + }, + { + "U64": "496840316488219765" }, { - "U8": 198 + "Address": "5990c4dda091b1bec74e3a3e5c89fa43233a15898a28b7291a3589ca2cb4a39b" } ] } }, - "max_gas_amount": "15667356745103459526", - "gas_unit_price": "16930683256175926446", - "expiration_timestamp_secs": "382443118719448317", - "chain_id": 214 + "max_gas_amount": "5397305908186692363", + "gas_unit_price": "7835174926084901593", + "expiration_timestamp_secs": "15040051270553271576", + "chain_id": 180 }, - "signed_txn_bcs": "8b37e28b5c9bb57483162ccb5e1a4a713f19bd8ef06348dcc7de07e0c15652b518bfc9a3fb20da8600032dcc63080607c40a3c773ec8605a6290c99e2a2fb7eb349a6f472a9258d982435b5ea263bfb2187761656d717a6d4a4366687a42736c64514147476547623116426c656376715443684f5674627463694f45637a6b6f0007cd2d58a88c338de7dcc426502f0ef4e5bfb0a4ae268dd41372820d304243834e0c72504f6f67757179644c4439024238000606060207f35bb05c1d0288cf714b5918f75f4f5bd910bda38af1de193221acf6a22ab87e0d6459757348745275446b554d361c7649735a634768535774434574454f577a4f5a437044494c726e65390007e8b8865be5f7aeafe09e8417f3e1727855f970ab1d7364bb1217f0c2403a464118425562637146466e5064424a4e52714a6e65697863776f741b656b59627663566171464f4750695a4d624f7470634a5778536635000750adb5b2703afb1fb09ca217960bc0921e34ece9b8a97ee6dc5b3c2a617c3749166e784265526a525a546d787a414c76694b4f41585675087746426f565a633100072c78afd9270fca61cc039d13193147c5cba85f43b4fea76c5c8a4f5238324f510f5578425666456f58644844564564350b765479674663456249763400079327244e60d4b818748cabd00597daa5bc9c0f66f74ecc171b34b2e0c3fae99e156d58724d7855687576686b746777706d764863467316626c636c706642556b52704b7855415476574e50643400020151434e7eb960351400c6c6443651f3a16dd9ae1c0509b8def5eafdb4107efdb54e05d6002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406c95d84684f4576a1c9315bd3733a87686b78dfedd3d3eeab25357bed37d847d5c336f78c32d80c24675dd6be27231c4ddf593e06ca15d24acf93dea190adf03", + "signed_txn_bcs": "56a8c963a752a82d87ee5b4593253ab14b324243f82f93c1ac8e92227c9c75b85c9965f3bdcac736000d39408f7b7a92c574bf7c1705c30a0601077328d0be15ab151b4cefd447f8fde5180ff23d27eb3f5e73ed0478a9ca7c1592024f681468676f4e6b4a78614c454f626f656b5457794d650007385d289a1449125597f52fc0d50ce55f16bb93dcf77d9ffd1d133a3fcbd5be8e1a785142416d49684b49647544715a61687969736a4d56744b51780d664d78536878486470726e524400060604071285ed7f900e8b1b99145c05cf7dc0be9a2770b53e4b2e0f4e3c3bcbec7eeb0e126563677a68766f7561647a695177517356651c6747484a7475684542765945776b6e59584b4461504b74557a73514b000607887467fe6af9ada54daec830abe9415e48e02b5c6599b871db100ef15ebcabc0034765591051694951726f5149416f7a6345556b33000606071728e1ce1184ba469aa8977e417707292ed0530a9d7b4a5ba56158118e55af301052596449585a544954504c624168744b2069464844574c414c50694c5976484256695747736c4c536a594153694451666e00060607635abd03be654c6a2450fd042cace6effe0d52b62af09531313f33689132213a1176484f455746546441554667524a6762740e7053514278686c544a4b6a4f473900060604071b28f4156bf300a23fdc85e0acf5f241d79259862e24dbf930b65ab7addf785c054d57774f6b1173417574694a5958706a6575706d55413700090044009c007c0194f9fad240365369040d9c6e9dff087e9af36cc5bf188e00b1012c61188d5041cd7501757c5faea221e506035990c4dda091b1bec74e3a3e5c89fa43233a15898a28b7291a3589ca2cb4a39b0bbb95992015e74ad98a562e1522bc6c187dfde8f1feb8d0b4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444038f59e7592509bb1278c290f85738ede90fee3479fb6c34eaa68ad2cb2049078e4e67eaca0afe3fabaf804e1c87774f730517fbbbb332f9a2c8b0c8211faa405", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "918f46da4daa83f267fa898ac5c2cf1ef9a18ab095dc6fd51bb9f22d85a7beaa", - "sequence_number": "3198344470995509974", + "sender": "0ff5086c7e84e0ce82c3a640457c56b5764e89dc04d0631b4146688ec3cf8199", + "sequence_number": "11764089532947933679", "payload": { "Script": { - "code": "f94f18", + "code": "8b0f", "ty_args": [ { "struct": { - "address": "a804dcd896c931199f1a0ddf5a0905fc88a2c81848324d223a6e24ab16e6fa61", - "module": "DSOn", - "name": "zRKFDCPjuPOjuQFiEQaOuBQD8", + "address": "97c78c169e51c9a46daa5a64de281b2c08713721b0e77bd5003128a3e2c13954", + "module": "uwggPnwijwYFTjHDruiigtAQnRULV", + "name": "IpQzLHvDhsh8", "type_args": [] } }, { "vector": { - "vector": "address" + "vector": "u8" } }, { "vector": { "struct": { - "address": "8c56c6471c9b2ecf387e787994df1a093761a74293701dbeb2a240f75d83bcdf", - "module": "ecjZiumBUfCaoLXOJNEjIenVaJ", - "name": "u4", - "type_args": [] - } - } - }, - { - "vector": { - "struct": { - "address": "ffd3804df3e7a13d4447897be31928f0bb715b5f22311b7df46f791a3f899759", - "module": "WOsAElCitHqbCKESiPlqcOP", - "name": "wfKmBNUbxeJFhcNpvur", + "address": "44b5dd4b5d7becb69d9ac8262a2dcddd3a11df3e0f90f724e1d8fb88877c3d81", + "module": "BvUhBNKCel", + "name": "SonwkRKtrymYduJynEsRb", "type_args": [] } } + } + ], + "args": [ + { + "U64": "8246150575885019277" }, { - "vector": { - "vector": { - "vector": "u128" - } - } + "U128": "107641842610249000958099304350184303966" }, { - "vector": { - "vector": { - "vector": "address" - } - } + "U64": "14763856152715430698" }, { - "vector": { - "struct": { - "address": "7d022844a349705741fb7082cf6f281f4a670fc8d2b0b73b6b54242ce4b866b0", - "module": "WOWxMCWADjYQavJ2", - "name": "JpAuwYTLfIIKCCnUGYQXxcAnc", - "type_args": [] - } - } - } - ], - "args": [ + "U128": "183034631719426385601700413881596384161" + }, { - "U8Vector": "0db3a45a0c" + "U64": "789606558540120552" }, { - "U64": "7024259777566843714" + "Address": "dab93344eed8ae5bef61bc8a2c289dda0444d095b9d923c40e80dc80205b3291" }, { - "Bool": true + "Address": "94a4173faea83d4df1ffbbb90e00efa875ca5bd145ce3b54c0dd101e3d7d0a85" }, { - "Bool": true + "U8Vector": "e5d696" + }, + { + "Address": "971afe6f386f14a121716a795d4a3f06c1175438254794bba8a7360b4fcba9c6" } ] } }, - "max_gas_amount": "17500826518180333788", - "gas_unit_price": "1599457683868736262", - "expiration_timestamp_secs": "13446065823184727193", - "chain_id": 185 + "max_gas_amount": "10025263189613158168", + "gas_unit_price": "15350321695262339503", + "expiration_timestamp_secs": "18414410145325957257", + "chain_id": 220 }, - "signed_txn_bcs": "918f46da4daa83f267fa898ac5c2cf1ef9a18ab095dc6fd51bb9f22d85a7beaad6a205cf59cd622c0003f94f180707a804dcd896c931199f1a0ddf5a0905fc88a2c81848324d223a6e24ab16e6fa610444534f6e197a524b464443506a75504f6a755146694551614f75425144380006060406078c56c6471c9b2ecf387e787994df1a093761a74293701dbeb2a240f75d83bcdf1a65636a5a69756d42556643616f4c584f4a4e456a49656e56614a027534000607ffd3804df3e7a13d4447897be31928f0bb715b5f22311b7df46f791a3f89975917574f7341456c436974487162434b455369506c71634f501377664b6d424e556278654a4668634e7076757200060606030606060406077d022844a349705741fb7082cf6f281f4a670fc8d2b0b73b6b54242ce4b866b010574f57784d435741446a595161764a32194a7041757759544c6649494b43436e55475951587863416e63000404050db3a45a0c0142a3ef330d2f7b6105010501dc08e0b3fe6cdff206db43084a6a3216992c7239a0059abab9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ccfb27e5f61595612b1913ba6fe917c4d9402c76ad506c8312d6b9bb523e2410c5c56a5b288548821ad4c5592bda912a0de96d2e37969814125a6be4b4fda007", + "signed_txn_bcs": "0ff5086c7e84e0ce82c3a640457c56b5764e89dc04d0631b4146688ec3cf8199efa940f5197142a300028b0f030797c78c169e51c9a46daa5a64de281b2c08713721b0e77bd5003128a3e2c139541d75776767506e77696a775946546a484472756969677441516e52554c560c4970517a4c4876446873683800060601060744b5dd4b5d7becb69d9ac8262a2dcddd3a11df3e0f90f724e1d8fb88877c3d810a42765568424e4b43656c15536f6e776b524b7472796d5964754a796e457352620009018d68024042367072025eed9a1687599a94305d3a6b9610fb50012a8b91d9f2c0e3cc02a113b2eab30740025df25c3d1430b38901e8411a42fb3ef50a03dab93344eed8ae5bef61bc8a2c289dda0444d095b9d923c40e80dc80205b32910394a4173faea83d4df1ffbbb90e00efa875ca5bd145ce3b54c0dd101e3d7d0a850403e5d69603971afe6f386f14a121716a795d4a3f06c1175438254794bba8a7360b4fcba9c6181fb13cc1e3208baf71159a404c07d589c080a476208dffdc002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d024a81f4b016552add88c4d2001daf8bcb357f19d82c94368fe60d87d17c2e7fa8a40e43c28815e6e129835f9c1e68b6c069cec82e31c7455e2f0fab0b9c602", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "5416bfb39dab0593f4711f5e0b56d31481dea50bb672641f816eb024d9790d58", - "sequence_number": "10706683213577597782", + "sender": "1818ba4fa3a8d2523b0bade12be074a0fa61a4ba4a51ae410379d36252a6d8b8", + "sequence_number": "14286251766004153855", "payload": { "Script": { - "code": "984db38fb88c66899f80075c", + "code": "0af6d15baa", "ty_args": [ { - "vector": { - "struct": { - "address": "d5ea4efe7ae87ed30908d872705191629a4a4688c4d2d6c60e623565770fa5ac", - "module": "hWjKHXvQWnQVuOUrNJfZUWMItl", - "name": "GLsFYZavJtTMBFfh", - "type_args": [] - } - } - }, - { - "vector": { - "struct": { - "address": "41ddbc7b6aa7a550f964e9ec8f32591335e52772846e118d05ce814c6d964a64", - "module": "XPBkRWOKIogTuzD4", - "name": "nqCnYrkQDvmZzZLBCYzJyqj5", - "type_args": [] - } + "struct": { + "address": "e34d30a0e1b597cb60e5c70462ea74135e7050902810c5b573f66ec2ff1e4f27", + "module": "MhbkpfVqZMNsT", + "name": "BqIxxIbxQMAqAO", + "type_args": [] } }, { "struct": { - "address": "d81c9988b6a7762286f63e767b84c0dbfd72a9056bb0c6f0ab30602318a7cc65", - "module": "fLyDw8", - "name": "aMgiqpIENImSxAGeIuKDjINOGC9", + "address": "0657d5eba6e9791c6e437b596a2de2a417cfda28d3beecfeefb48a8f352e3f11", + "module": "szyxIi0", + "name": "ZeJrHJgrdDTMzgS", "type_args": [] } }, { - "vector": { - "vector": { - "vector": "u128" - } + "struct": { + "address": "66e59e2d8c4138a6f10c28b04059c7748bfbddc0ecc53c07f9a43fb5e8f1d69c", + "module": "Kw2", + "name": "Mq", + "type_args": [] } }, { - "vector": { - "struct": { - "address": "5d35b198b8edef2fbd936b2b541dfec66c8c5771f7378bec10d22e363e01857f", - "module": "otjdXo", - "name": "NGqcOUbNLSeZFUDNCZOgQYH9", - "type_args": [] - } + "struct": { + "address": "57f42cfe025501bcb4b594253c8e6ae13d29b1ad42fac1bc3bfafd49571ee4ca", + "module": "KFKVxBmKgPR0", + "name": "ZfcSNohorLWaLZrCLQJNa", + "type_args": [] } }, { - "vector": { - "vector": "signer" + "struct": { + "address": "295c656d2c6157fbba785d6d43ce573e80c8f4c804452d3312b61e8c5db52bfe", + "module": "QPpQ4", + "name": "nGYirfikySjTOuQFVmBaVlvrQTQobREo", + "type_args": [] } }, { "vector": { "struct": { - "address": "e89c61f81be7b1144085acc70c36ea1c27f012581bcb98adec99b571105ec423", - "module": "sCyRgWZIlmOIoZHSiTHcWtxRCpqGEF2", - "name": "kDChY", + "address": "dbb7a0cda2a7ea70ab90ae4940a481021b5785780efe98dcda03f391db9aec24", + "module": "JSnQzBPt7", + "name": "dXkpXq5", "type_args": [] } } - }, - { - "struct": { - "address": "13dbf86569a691c550f75e135114479119146ecf735153147c02c0ff40afa345", - "module": "mG0", - "name": "SxHHpRveETRgcSdJmHq4", - "type_args": [] - } } ], "args": [ { - "Address": "934b196a585be09e4577508b0f17fe6333b68701fca51672b9c2c6b6f4e0a0a9" + "U128": "205742330523462318325428180869851245042" }, { - "Address": "d8b9e255f0fcad5e4278bda7414eea1dfac5286592cd10667f895977c1479a6c" + "U64": "2465559581404745137" }, { - "Address": "53c1a30f734be93b2162b5f799144b65059e294275ee33a3c16b70d87ab92dc1" + "U8Vector": "e1710aa4dc97861aff" }, { - "U64": "11199803512888179599" + "U8": 142 }, { - "Bool": false + "U8": 152 }, { - "U8Vector": "da08f8248ad8cbebed4adacd6a" - }, + "U64": "1924808419949941931" + } + ] + } + }, + "max_gas_amount": "14144151447906987127", + "gas_unit_price": "8417117598073422119", + "expiration_timestamp_secs": "6101300421118953170", + "chain_id": 197 + }, + "signed_txn_bcs": "1818ba4fa3a8d2523b0bade12be074a0fa61a4ba4a51ae410379d36252a6d8b8ff7d79144af642c600050af6d15baa0607e34d30a0e1b597cb60e5c70462ea74135e7050902810c5b573f66ec2ff1e4f270d4d68626b706656715a4d4e73540e4271497878496278514d4171414f00070657d5eba6e9791c6e437b596a2de2a417cfda28d3beecfeefb48a8f352e3f1107737a79784969300f5a654a72484a67726444544d7a6753000766e59e2d8c4138a6f10c28b04059c7748bfbddc0ecc53c07f9a43fb5e8f1d69c034b7732024d71000757f42cfe025501bcb4b594253c8e6ae13d29b1ad42fac1bc3bfafd49571ee4ca0c4b464b5678426d4b67505230155a6663534e6f686f724c57614c5a72434c514a4e610007295c656d2c6157fbba785d6d43ce573e80c8f4c804452d3312b61e8c5db52bfe055150705134206e4759697266696b79536a544f755146566d4261566c76725154516f6252456f000607dbb7a0cda2a7ea70ab90ae4940a481021b5785780efe98dcda03f391db9aec24094a536e517a425074370764586b70587135000602f2e9cd9922c2a109230b95951188c89a01b1cd304e606d37220409e1710aa4dc97861aff008e009801ab14cc530f4bb61a77acd28dcd1e4ac42701db11dc9bcf74d286bc2c682cac54c5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444035a9e3b84f182ffbc7663c8ddf7048414cea68e93b357571fc576e526ea8462a31bb29ae48787a03b4c9e66301f2d369935a5d9c00a7c1e44545d8331f5ed501", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "6e16d309245435e9e910cac58b2ed9ac71750c58818297cf6709402959a757bb", + "sequence_number": "9164924021602996", + "payload": { + "Script": { + "code": "1cbfb5d032ba4a3f3f2ba1fa", + "ty_args": [], + "args": [] + } + }, + "max_gas_amount": "18122307170286939380", + "gas_unit_price": "15184117320809213500", + "expiration_timestamp_secs": "5652925324185931294", + "chain_id": 122 + }, + "signed_txn_bcs": "6e16d309245435e9e910cac58b2ed9ac71750c58818297cf6709402959a757bbb47ab328738f2000000c1cbfb5d032ba4a3f3f2ba1fa0000f4ac77f35a5e7ffb3c6eb01e41d2b8d21e8ee9c1a139734e7a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440785425ea2bcc8c078560e3efca0a50f210b6b7e3dc64c3751c23431aa49e7fd925f44516ac7213c517bcf2f2475fe3cf6c74f7f46bf384c4e4af4d72adcefb09", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "05463318a70d83d99a7a2a53c6182909415f93baf8b4bfd25c6a3acd0643ec7b", + "sequence_number": "6356444125711872204", + "payload": { + "Script": { + "code": "c4b6de22", + "ty_args": [ { - "U64": "16189395170145667347" + "vector": { + "vector": "address" + } }, { - "U8Vector": "ec4de6384bfddb7245d5febbc636ab" + "vector": { + "vector": { + "vector": "signer" + } + } }, { - "U64": "2694903550936475086" + "struct": { + "address": "8bd27bc7877d2cc44d8fdfea57cac8336dea075170129117f0a0e2e3e358be50", + "module": "cchMxTZJNdqgjUtWKBWRhmJib9", + "name": "OLoYkQmasGuIj4", + "type_args": [] + } } - ] + ], + "args": [] } }, - "max_gas_amount": "6771618820553153754", - "gas_unit_price": "1234495723078004851", - "expiration_timestamp_secs": "4944881089605332966", - "chain_id": 8 + "max_gas_amount": "15713964331740974573", + "gas_unit_price": "4394958025515581644", + "expiration_timestamp_secs": "2336158501503025776", + "chain_id": 49 }, - "signed_txn_bcs": "5416bfb39dab0593f4711f5e0b56d31481dea50bb672641f816eb024d9790d585633ee03a8c79594000c984db38fb88c66899f80075c080607d5ea4efe7ae87ed30908d872705191629a4a4688c4d2d6c60e623565770fa5ac1a68576a4b48587651576e5156754f55724e4a665a55574d49746c10474c7346595a61764a74544d4246666800060741ddbc7b6aa7a550f964e9ec8f32591335e52772846e118d05ce814c6d964a64105850426b52574f4b496f6754757a4434186e71436e59726b5144766d5a7a5a4c4243597a4a79716a350007d81c9988b6a7762286f63e767b84c0dbfd72a9056bb0c6f0ab30602318a7cc6506664c794477381b614d6769717049454e496d537841476549754b446a494e4f474339000606060306075d35b198b8edef2fbd936b2b541dfec66c8c5771f7378bec10d22e363e01857f066f746a64586f184e4771634f55624e4c53655a4655444e435a4f6751594839000606050607e89c61f81be7b1144085acc70c36ea1c27f012581bcb98adec99b571105ec4231f7343795267575a496c6d4f496f5a4853695448635774785243707147454632056b44436859000713dbf86569a691c550f75e135114479119146ecf735153147c02c0ff40afa345036d4730145378484870527665455452676353644a6d487134000903934b196a585be09e4577508b0f17fe6333b68701fca51672b9c2c6b6f4e0a0a903d8b9e255f0fcad5e4278bda7414eea1dfac5286592cd10667f895977c1479a6c0353c1a30f734be93b2162b5f799144b65059e294275ee33a3c16b70d87ab92dc1018f3bdfb3f4b16d9b0500040dda08f8248ad8cbebed4adacd6a011309f5d42149ace0040fec4de6384bfddb7245d5febbc636ab01cee5815980386625da9c6b91709ff95d73b0cdca51cf2111e6ef78e226bf9f4408002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c6d9ab40998fc30e14a0e93b5a69f09cb4edc782fc4f0db89a04957ab26ef095fea39ff27ad32ba391ad95559019430a5632f22501224ea1c6a9d9f463bd3a03", + "signed_txn_bcs": "05463318a70d83d99a7a2a53c6182909415f93baf8b4bfd25c6a3acd0643ec7bccb0ac2341a036580004c4b6de220306060406060605078bd27bc7877d2cc44d8fdfea57cac8336dea075170129117f0a0e2e3e358be501a6363684d78545a4a4e6471676a5574574b425752686d4a6962390e4f4c6f596b516d61734775496a340000ed4d94b64d3713daccc09be90907fe3c70c21895c7b36b2031002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144403518e11709becfab5cb2601a67327d846f82d514ebd2c6be1167c27cf3ad48141b95808c75b31a8c59f99028c6301bf5aa8e0c6c6f0f1c95e6ef4787fa989504", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "5dec35ac246fbbfc7fa047e2d6b9c6044fc85d9df620647d2032b8084afaf191", - "sequence_number": "1930686019399630607", + "sender": "ab0aedf476aeb6bf7ea272d6485194d00f821031f7e2dbd9a997692203aaa713", + "sequence_number": "16648589168966582675", "payload": { "Script": { - "code": "e79fe34bfacd46b59cb511", + "code": "347cd1bec8b068bc8d", "ty_args": [ { "struct": { - "address": "93de7b3850971d5bc8dc0b7316b574d351a06cc77637afcefb51ad629010d2d7", - "module": "hMVbJtBJRZujhaRQVoSVjex5", - "name": "wwtDijeAfYQUrmY5", + "address": "961fde6a054b7130a2128e06b5f0302ba71da76cd0659c86c80dcfb65f789bc5", + "module": "IxGtlugwiTfIMeNkrurbsddJoFLsNtp", + "name": "HAbVfZwVBXSHjw1", "type_args": [] } }, { "struct": { - "address": "e332c3bb30c6a5620c60509d682b337c2624211133f22acc6d09447325ed5a95", - "module": "iqcGmhbwrYgFIQLxqPYskMupHjhI", - "name": "ppLdsxnkwRfaQVobyAHfmFJWFPjrF", + "address": "7d104d64052c5902a403f819a421ff6b95c62aabf2db9f7acbe87b8d5ddf719e", + "module": "OpuPpNEyoSrVrnZEneeGQTIiuh", + "name": "G6", "type_args": [] } }, { "struct": { - "address": "a559f100e2e908a77ee61fc90b80f79658cff531827386ac9bcb06141c3566a0", - "module": "STAZRpERwahslPuCiDQwdPlE2", - "name": "fgeCd0", + "address": "43613aa925e701542ec58dc03b76c1550d245d482fe3713505b41c02c7e70b18", + "module": "zwllKxGDaPaW", + "name": "lPcfoLCiDALrcsiuJAOzl", "type_args": [] } }, { - "vector": { - "struct": { - "address": "30a3cb3dc051c8a40a78bec7275518f5bc7f59cbeb3448875ed50e28b22347ff", - "module": "dCdwNcZVZAHMBFnhyBGLmtBuqJjvGuv", - "name": "QOhHqfCMcB", - "type_args": [] - } + "struct": { + "address": "905639dcb3dc90726c5846bb1e61bb696ecd30d430f2ee2c18fc7176bef8f84c", + "module": "ty7", + "name": "LnWUpYBbLidXrKYCObnsMBWT", + "type_args": [] } }, { - "vector": { - "struct": { - "address": "bfa4400a24b876230302c169487fa9e864905af8f9a22edcff2e16adce187a73", - "module": "OlZwwkzEOZGSpQ7", - "name": "EW", - "type_args": [] - } + "struct": { + "address": "1d6780916986761313329d4b3be9469a17b6041eca0ee2c9b6d683a4bed839aa", + "module": "HcNuDXUDjpQnWGPRk", + "name": "DmWVCKeDHMhWdHZUdfidHmJ", + "type_args": [] } }, { - "vector": "u8" - }, - { - "vector": { - "struct": { - "address": "c22bddfe1c6710101e79702b4a24f909605be7f44fe5bf618ddc10915377f6d7", - "module": "nGyWJXG5", - "name": "AZiwPFCweKpXVPemWpkofymnF4", - "type_args": [] - } + "struct": { + "address": "e85552888bee5e278c22d011ee321a2960ccb306bf7c1d9e126032fc76ddb8e0", + "module": "WxEbUqJflRsyojBVYXwHCg6", + "name": "TisDWaYVBZqkEvCjIus", + "type_args": [] } }, { "struct": { - "address": "d290263bdbf28c68181ad4003d8eb2ff6bd4b797f2e30a984d959bbbf1fce73b", - "module": "hQTXAzOmXiqHGDPdygTcIOA", - "name": "YcCmOQZydrpABhwFgtfOsrui", + "address": "0f95ae2dce1cd67574bf60d5bf9d390217dad59330c805abe02f57ad26da97fb", + "module": "kBgE", + "name": "FueiETkGoQVJIotpdYqJWtbr9", "type_args": [] } }, { "struct": { - "address": "b3eb7c22046af41ac116aa75a5a85aafa5dbe9ecea7f255715eee00bf5f70cb8", - "module": "rhHVNfpspjmtsecymyoCEkrdUGc", - "name": "JeEvpQdOsiTPpfwFuLmiDfn", + "address": "db6e48834c7d7b8fc1a3d4935978dc45041291525656a72467dd25eb5526d4eb", + "module": "xFZpOOAoPhsjtfsHwGfQLKUdTpblUKCf", + "name": "lyOoVSiyyLJpjufKdLdT9", "type_args": [] } }, { "struct": { - "address": "853e693d1feac1b5d660b1d7f54b69b3174c14b9916a8a2fe734fb60747018be", - "module": "AMCpWUQPumHjkYcwREToNZvrFhuxOJcu4", - "name": "fVFJxq", + "address": "2bfbe6e1138767061f90ca38f06b05291d0aedfbe075e364492c58569f79ce07", + "module": "FQRCrbQkPBhhLnYWgd", + "name": "cBiaklye1", "type_args": [] } } ], "args": [ { - "Bool": false + "Address": "c32d0de8fa28ffbb40b9d319349dcf971010e7113bda5c031175578b3bbe2eda" }, { - "U128": "262930563587521952415156244747956297955" + "Bool": true }, { - "U8Vector": "03df98" + "U128": "254211244599074843831887360934135788922" }, { - "Bool": true + "U8": 66 }, { - "Address": "cf86491320ac54250a299e2e579bb435005d260f64bbe419e37268c644159ed1" + "U128": "97833133182255706541339503665876263457" }, { - "U64": "9001975557501623229" + "Address": "102f3a7d3aaf3f20e270fffef0b4118ba731f932ce1970e09ba187cd34edf069" }, { - "Bool": false + "U128": "104090777741055779958582672288738339321" }, { - "Address": "946d9f4afb113a5a6ec3bba1076b399e476ab96483f415d4a287fd0328075418" + "U8": 225 + }, + { + "U128": "15439701480389844381054627003488522079" } ] } }, - "max_gas_amount": "2586144858769439642", - "gas_unit_price": "9435749238933968853", - "expiration_timestamp_secs": "1472101799157070050", - "chain_id": 73 + "max_gas_amount": "10021860953213164887", + "gas_unit_price": "14185700538305981397", + "expiration_timestamp_secs": "961076190049227493", + "chain_id": 144 }, - "signed_txn_bcs": "5dec35ac246fbbfc7fa047e2d6b9c6044fc85d9df620647d2032b8084afaf1910fbf2097b42ccb1a000be79fe34bfacd46b59cb5110a0793de7b3850971d5bc8dc0b7316b574d351a06cc77637afcefb51ad629010d2d718684d56624a74424a525a756a68615251566f53566a6578351077777444696a654166595155726d59350007e332c3bb30c6a5620c60509d682b337c2624211133f22acc6d09447325ed5a951c697163476d6862777259674649514c78715059736b4d7570486a68491d70704c6473786e6b7752666151566f62794148666d464a5746506a72460007a559f100e2e908a77ee61fc90b80f79658cff531827386ac9bcb06141c3566a0195354415a52704552776168736c5075436944517764506c45320666676543643000060730a3cb3dc051c8a40a78bec7275518f5bc7f59cbeb3448875ed50e28b22347ff1f644364774e635a565a41484d42466e687942474c6d744275714a6a764775760a514f68487166434d6342000607bfa4400a24b876230302c169487fa9e864905af8f9a22edcff2e16adce187a730f4f6c5a77776b7a454f5a47537051370245570006010607c22bddfe1c6710101e79702b4a24f909605be7f44fe5bf618ddc10915377f6d7086e4779574a5847351a415a697750464377654b70585650656d57706b6f66796d6e46340007d290263bdbf28c68181ad4003d8eb2ff6bd4b797f2e30a984d959bbbf1fce73b1768515458417a4f6d586971484744506479675463494f41185963436d4f515a7964727041426877466774664f737275690007b3eb7c22046af41ac116aa75a5a85aafa5dbe9ecea7f255715eee00bf5f70cb81b726848564e667073706a6d74736563796d796f43456b7264554763174a6545767051644f7369545070667746754c6d6944666e0007853e693d1feac1b5d660b1d7f54b69b3174c14b9916a8a2fe734fb60747018be21414d437057555150756d486a6b5963775245546f4e5a7672466875784f4a637534066656464a78710008050002e3a010dbf8565f33d033476ea695cec5040303df98050103cf86491320ac54250a299e2e579bb435005d260f64bbe419e37268c644159ed101bd1ba2351371ed7c050003946d9f4afb113a5a6ec3bba1076b399e476ab96483f415d4a287fd03280754189abba70c0cd5e323d55752a8f083f282e278f86bc9f46d1449002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440aca53cc6946bce8f739f637c696a4102be4d36a728982969dc0c450c8b039bc128e1f3adb816b3b21631e29ab3a37e7c7777331f50aeec0db0fee996e80af90c", + "signed_txn_bcs": "ab0aedf476aeb6bf7ea272d6485194d00f821031f7e2dbd9a997692203aaa7139341ab23a4ab0be70009347cd1bec8b068bc8d0907961fde6a054b7130a2128e06b5f0302ba71da76cd0659c86c80dcfb65f789bc51f497847746c756777695466494d654e6b727572627364644a6f464c734e74700f48416256665a7756425853486a773100077d104d64052c5902a403f819a421ff6b95c62aabf2db9f7acbe87b8d5ddf719e1a4f707550704e45796f537256726e5a456e656547515449697568024736000743613aa925e701542ec58dc03b76c1550d245d482fe3713505b41c02c7e70b180c7a776c6c4b78474461506157156c5063666f4c436944414c72637369754a414f7a6c0007905639dcb3dc90726c5846bb1e61bb696ecd30d430f2ee2c18fc7176bef8f84c03747937184c6e5755705942624c696458724b59434f626e734d42575400071d6780916986761313329d4b3be9469a17b6041eca0ee2c9b6d683a4bed839aa1148634e75445855446a70516e574750526b17446d5756434b6544484d685764485a5564666964486d4a0007e85552888bee5e278c22d011ee321a2960ccb306bf7c1d9e126032fc76ddb8e0175778456255714a666c5273796f6a425659587748436736135469734457615956425a716b4576436a49757300070f95ae2dce1cd67574bf60d5bf9d390217dad59330c805abe02f57ad26da97fb046b426745194675656945546b476f51564a496f74706459714a57746272390007db6e48834c7d7b8fc1a3d4935978dc45041291525656a72467dd25eb5526d4eb2078465a704f4f416f5068736a74667348774766514c4b55645470626c554b4366156c794f6f56536979794c4a706a75664b644c64543900072bfbe6e1138767061f90ca38f06b05291d0aedfbe075e364492c58569f79ce0712465152437262516b504268684c6e5957676409634269616b6c796531000903c32d0de8fa28ffbb40b9d319349dcf971010e7113bda5c031175578b3bbe2eda0501027af5344b68bf5c0609473282084e3fbf0042022162134f6fe592378a36500be0f9994903102f3a7d3aaf3f20e270fffef0b4118ba731f932ce1970e09ba187cd34edf06902f969ce3e1e823fd71094a77692274f4e00e1025fcf675e82a679a87ac2b82d0e949d0b57dda05870cd148bd5abcb037bbbddc4e552f8edb36d560d90002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144408ed7f832ffdf404f68c756b4e99878f680e2d3726cae430596ecff520c469f6b956e43ac79dcc8f38ef7f367d4c6a20641b4c3b50f4697c3362d055e051efe0c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "4213f29dbf3fcb2bd597123262ed8f6f20de99f92384f0d44d75da9da2a606f7", - "sequence_number": "11849599448090427893", + "sender": "5366daa23bce1a85ea3967a94bc0ebf84914433cb1d78fc1f0f2c85a6e1ff032", + "sequence_number": "10838811419951474794", "payload": { "Script": { - "code": "0d3d6ac6", + "code": "0daf3f5bd99a2bcaac", "ty_args": [ { - "struct": { - "address": "0d46b9e7839aea4cf3551bc51e83c38d2ae1179c34732ca467a610762399faf1", - "module": "MnIeqGyAjyTLR9", - "name": "PgaqXRXGEwNEaPduZGrDgcfvDjGwYEu", - "type_args": [] + "vector": { + "struct": { + "address": "ccb97d1651ebf2585133b5fafe2810970bf845d78e605b5d33ab925319defa1e", + "module": "KFHjKiChSJyxumWYymoenjrQu", + "name": "IDqlDLouzSGzotKxUdGaPG", + "type_args": [] + } } }, { - "struct": { - "address": "11a1497c9852eeee81e4220b509feadb31945a37284a945a3372d8f946de3aeb", - "module": "FPjnZxUivYyLTckvWSFk", - "name": "xOgbUt", - "type_args": [] + "vector": { + "struct": { + "address": "83fc27d648cd829d91a97a377ccae3f5c30e8dd3813b8a88de5c353cf3dc16dd", + "module": "ieJIMRiA", + "name": "QTAkPYIqHIxVGKpFLGzwK0", + "type_args": [] + } } + }, + { + "vector": "address" } ], "args": [ + { + "U64": "6321595345605947245" + }, + { + "Bool": true + }, + { + "U8Vector": "626fe00b6a3d514bd5c5a84adb7763" + }, + { + "Bool": true + }, + { + "U128": "63457244369885773050148059375950775617" + }, + { + "U64": "8603327848767259057" + }, { "Bool": false }, { - "U64": "17608128222000313866" + "U8Vector": "c57cbdcd3c" }, { - "U8": 210 + "U8Vector": "4df3278074ed1eed6d87" } ] } }, - "max_gas_amount": "13704429922159957780", - "gas_unit_price": "6109142244499550406", - "expiration_timestamp_secs": "1028314999427100147", - "chain_id": 36 + "max_gas_amount": "3834650048000301839", + "gas_unit_price": "14676635422596059984", + "expiration_timestamp_secs": "11818640550382943081", + "chain_id": 184 }, - "signed_txn_bcs": "4213f29dbf3fcb2bd597123262ed8f6f20de99f92384f0d44d75da9da2a606f7f541188aea3b72a400040d3d6ac602070d46b9e7839aea4cf3551bc51e83c38d2ae1179c34732ca467a610762399faf10e4d6e4965714779416a79544c52391f506761715852584745774e45615064755a47724467636676446a4777594575000711a1497c9852eeee81e4220b509feadb31945a37284a945a3372d8f946de3aeb1446506a6e5a7855697659794c54636b765753466b06784f6762557400030500010af6db7753a35cf400d2141794af67ea2fbec670baf58008c854f3ed0e320b4f450e24002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440dcd12cc075add40a3e72357a2db45fe481accd5fee0c3e5dcf2d441f9118d99c053d52e6cb2e4d6ccd7412c52bf6beeafbb46a1139a6c792358cba66d978bb08", + "signed_txn_bcs": "5366daa23bce1a85ea3967a94bc0ebf84914433cb1d78fc1f0f2c85a6e1ff0326aa8a7598f316b9600090daf3f5bd99a2bcaac030607ccb97d1651ebf2585133b5fafe2810970bf845d78e605b5d33ab925319defa1e194b46486a4b694368534a7978756d5759796d6f656e6a725175164944716c444c6f757a53477a6f744b7855644761504700060783fc27d648cd829d91a97a377ccae3f5c30e8dd3813b8a88de5c353cf3dc16dd0869654a494d526941165154416b5059497148497856474b70464c477a774b3000060409016def9a3c79d1ba570501040f626fe00b6a3d514bd5c5a84adb77630501024145deb41e1f9937ca4789c8b36bbd2f01b181ff971829657705000405c57cbdcd3c040a4df3278074ed1eed6d870f1bfedce669373550d3c01d28e2adcb693b9a75f63e04a4b8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c6fa69ba3853ee6dd52f8a05422505518095669e3d823dff2ba5ecaa0295a9316eba20efba5a24e98a504e9adb2f4b12b98acafe8d87aa4f7c9bae387a65ce0e", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "da8a0a6ea1495e03b51718c9a91051b01cf94dd16c23c538432037e743fc96d6", - "sequence_number": "2044898358789552004", + "sender": "ac0760a704c449a03193fa060e1b8c41c6b2037f2acf2b2fd7f8e60e9efc9e45", + "sequence_number": "11360494150803451654", "payload": { "Script": { - "code": "5db6d1fa", + "code": "b27fc9f0d818b154cd4da0bca6", "ty_args": [ { "struct": { - "address": "28288f309f612fbdf9cdfd803a7f0da20361f7b25a9409ce99fda20d895948ba", - "module": "igaxdIgYWbGVAJBvqCPLzgvmvcrR", - "name": "C", + "address": "a0dfe99d522efe5d53309b4a72675b7628b9147b659480a91687dfe2f1707d15", + "module": "tWihgevNG", + "name": "EHdQnQRyhahLRBkXrSQysJ5", "type_args": [] } - }, + } + ], + "args": [ { - "vector": { - "struct": { - "address": "21b2895144b5ffadbc3b1e19df450ad2a2187af308b5f9db6df78b28fda655ec", - "module": "WIH", - "name": "aPtEtOYpGPNO", - "type_args": [] - } - } + "U64": "1040913975628432616" }, { - "vector": "signer" + "Address": "7e7b7b30dd7969baedb3dbe1e111031fec82b05225d9a46c7f6f4a8d5559b1aa" }, { - "struct": { - "address": "efe01408d1c42013f0c2f9d9f9fcf2720fd56f20b02202c459be5ddab13bed1e", - "module": "LYwOlALhkmY", - "name": "LnjkVKDRkTtMVjuIdRbs8", - "type_args": [] - } + "U128": "311376526564884573071967890926569318512" }, { - "struct": { - "address": "532f7a818988e8a96eb80d78f032ada2665a39104bbfda7921ba2dceaa45cfac", - "module": "XgefMiwMUBqkQqoJYkMSJBeJaEndf8", - "name": "ayhVkHY", - "type_args": [] - } + "U8": 240 }, { - "struct": { - "address": "72ffbf25284f16f40c21dd3d3bacf0acebc72f09bbeed572cb34b9a2f7888b4b", - "module": "eoJPTCjayex", - "name": "JVjxyGuEGHZkCGRhXhosCSbi3", - "type_args": [] - } + "U128": "181478793818321106459908050269555341146" }, - { - "vector": { - "vector": "signer" - } - } - ], - "args": [ { "Bool": false - }, - { - "U8Vector": "8b3f45c9" } ] } }, - "max_gas_amount": "18121609316144400377", - "gas_unit_price": "16900354104346654057", - "expiration_timestamp_secs": "12434008238370568224", - "chain_id": 47 + "max_gas_amount": "15229539943640243686", + "gas_unit_price": "14978038977400147217", + "expiration_timestamp_secs": "9333885236940749081", + "chain_id": 162 }, - "signed_txn_bcs": "da8a0a6ea1495e03b51718c9a91051b01cf94dd16c23c538432037e743fc96d684376e1539f0601c00045db6d1fa070728288f309f612fbdf9cdfd803a7f0da20361f7b25a9409ce99fda20d895948ba1c696761786449675957624756414a42767143504c7a67766d76637252014300060721b2895144b5ffadbc3b1e19df450ad2a2187af308b5f9db6df78b28fda655ec035749480c61507445744f597047504e4f00060507efe01408d1c42013f0c2f9d9f9fcf2720fd56f20b02202c459be5ddab13bed1e0b4c59774f6c414c686b6d59154c6e6a6b564b44526b54744d566a754964526273380007532f7a818988e8a96eb80d78f032ada2665a39104bbfda7921ba2dceaa45cfac1e586765664d69774d5542716b51716f4a596b4d534a42654a61456e64663807617968566b4859000772ffbf25284f16f40c21dd3d3bacf0acebc72f09bbeed572cb34b9a2f7888b4b0b656f4a5054436a61796578194a566a787947754547485a6b4347526858686f7343536269330006060502050004048b3f45c9f947321fa9e37cfb69b5e517841e8aea20b85b569d788eac2f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444029299aedac4ae9cab227efbe905d044addd7344cb59e3c5cb8dd66ad433aacf064027b8d349c4f0cd0fb83bce42f446f4b4dfbde031d4d86bce8aa7e4413c704", + "signed_txn_bcs": "ac0760a704c449a03193fa060e1b8c41c6b2037f2acf2b2fd7f8e60e9efc9e4506ef8a5b3d95a89d000db27fc9f0d818b154cd4da0bca60107a0dfe99d522efe5d53309b4a72675b7628b9147b659480a91687dfe2f1707d1509745769686765764e4717454864516e5152796861684c52426b5872535179734a35000601e88412efbe11720e037e7b7b30dd7969baedb3dbe1e111031fec82b05225d9a46c7f6f4a8d5559b1aa0270e858b89038be59bb50cfc409f040ea00f0025a37977a24b940b80c77771e598b87880500e69d4ca1e3315ad3110de4c717afdccf19b91d822b9f8881a2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d27067bdcfd1e10f019b961e59cb53b2a6a2081cdea76c4059e103c3ea42fb731a6f4e5a9426abd68022bd585e48b9a209de32618748855eefd04fa4b7994505", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "3016f570cbfcd2384527c0c1a1172c8aa89cd9fe7ccc03289c7b22b3c27c5e9f", - "sequence_number": "17882037105359852191", + "sender": "492cbdc0622fbbbdae0c779cc88932cac59a74250638f00cc56524a06674b843", + "sequence_number": "10014795794658293170", "payload": { "Script": { - "code": "0ae2961ee366d82abf636ef642", + "code": "53de70fc2b4aedbbea", "ty_args": [ { - "struct": { - "address": "b14d57f6cc49a80ee9617d3614870f0c9fb54d05c24255b3de4f43a5fbb183ac", - "module": "ZfHhLJcVhufPtdQoHUapcAPKKBYAeVhC", - "name": "nCuGT", - "type_args": [] + "vector": { + "struct": { + "address": "308d39e97e85043e640921a5d884a0b284fbfe204fdc07cfef91b7ac0fb037e7", + "module": "AALWePDanyHwLvIkrpEmxwToVeWHlYXV6", + "name": "ioROBFZeATokWuBx9", + "type_args": [] + } } }, { "vector": { "struct": { - "address": "a32ae9d0aa5a2baec6cc74b5279b74252492835eb806196a7ce0d1fb3ad1ca0a", - "module": "iwNdQtv", - "name": "vS9", + "address": "b87066910ae8cf70633a76a8628085092b0d9f4885b1d1be2ef09fe88e09d809", + "module": "xrTlSQNaRIhcppBYFVuRqYr6", + "name": "aXCCkU3", "type_args": [] } } }, { "struct": { - "address": "23a98e4a854808eba299f43065bbf17fbe544fba6a043c2b16d40e2fbe67c00e", - "module": "W9", - "name": "psLoLmCSBEIKSkXuYOLNbHiYE4", + "address": "eafa512f87158bd7d28a80cafd9ba4993d61b5b2536f750432561fa6dfbb6f09", + "module": "CPHAGNEYyCFjKrGMtNUzsCE", + "name": "kIQJfWmcyIuObWPfjedqksRecTl6", "type_args": [] } }, { "struct": { - "address": "4ced9376224399222b31b9ad09996b7bbae480f1981ab26aba48df4ffef18efe", - "module": "nLMIvubaWjcVm", - "name": "UlVmctQS7", + "address": "3ef067b3f1831d6990217d886ed493804db54297edf52e90e5165cc07f4fa97b", + "module": "dIXzgF4", + "name": "xgQfItdhlnBTjjiNhYMaYpZMNK0", "type_args": [] } }, + { + "vector": { + "vector": { + "vector": "u64" + } + } + }, + { + "vector": { + "vector": { + "vector": "u8" + } + } + }, { "struct": { - "address": "09a12be6b13bedc3960b828a344c47d6521459acb7feab2af46a23ee5fa838ab", - "module": "FDemogDVBRIpzHlkw", - "name": "pv", + "address": "b999605b9ea506bd1eec7cfed0ff3a33814f3cb34a419b1ab3428498ec5cdae9", + "module": "YMyMMpGtyGfGnk4", + "name": "kiPoicVsCIOuzotgVV", "type_args": [] } } ], "args": [ { - "U8": 181 - }, - { - "U64": "5944416058970951721" - }, - { - "U8": 203 - }, - { - "U8Vector": "cfe10511ac6a92d8eff15abd0a56" - }, - { - "U128": "234889453750481879312164067104052621660" + "Address": "42057e7339ccb5559628c0ebbf0cdd54708fe98cb0f1309315b87dc7aae9e97f" }, { - "U8": 110 + "Bool": false }, { - "U8": 153 + "U8Vector": "ba" }, { - "U128": "276034989414573574914673590497258359296" + "U64": "9304155991702506264" }, { - "Address": "c995645fb4eac2dff08090ec8aef92dccabee582b067dd8af3392393c52ae51c" + "U8Vector": "66f7ffe79a28dc5d9dc59b4e" }, { - "U8": 13 + "U8Vector": "e393c5eaa4d18118ca20af" } ] } }, - "max_gas_amount": "10476342948306686394", - "gas_unit_price": "8990236584983068033", - "expiration_timestamp_secs": "17891741780155462635", - "chain_id": 77 + "max_gas_amount": "10486369804270171442", + "gas_unit_price": "6258567329192714545", + "expiration_timestamp_secs": "773546943721589078", + "chain_id": 251 }, - "signed_txn_bcs": "3016f570cbfcd2384527c0c1a1172c8aa89cd9fe7ccc03289c7b22b3c27c5e9f9f12541501c229f8000d0ae2961ee366d82abf636ef6420507b14d57f6cc49a80ee9617d3614870f0c9fb54d05c24255b3de4f43a5fbb183ac205a6648684c4a6356687566507464516f485561706341504b4b42594165566843056e43754754000607a32ae9d0aa5a2baec6cc74b5279b74252492835eb806196a7ce0d1fb3ad1ca0a0769774e6451747603765339000723a98e4a854808eba299f43065bbf17fbe544fba6a043c2b16d40e2fbe67c00e0257391a70734c6f4c6d43534245494b536b5875594f4c4e62486959453400074ced9376224399222b31b9ad09996b7bbae480f1981ab26aba48df4ffef18efe0d6e4c4d4976756261576a63566d09556c566d6374515337000709a12be6b13bedc3960b828a344c47d6521459acb7feab2af46a23ee5fa838ab114644656d6f674456425249707a486c6b77027076000a00b50129501728e9ce7e5200cb040ecfe10511ac6a92d8eff15abd0a56025c31a24a4d7e85b728aab1cc3110b6b0006e00990200caf1a3ffcad9e9d37abff4b967aacf03c995645fb4eac2dff08090ec8aef92dccabee582b067dd8af3392393c52ae51c000dba11fdca6772639181fda2ae8abcc37ceb732ec35a3c4cf84d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402b5df9a65c6106d692a0b16aa7673605fafaa6e1b4bcaf5056135fbec6367e98ffdce5195d428f51326e4d9643cf3423615c735c2b9f0fbb54b6d8ba31e53b03", + "signed_txn_bcs": "492cbdc0622fbbbdae0c779cc88932cac59a74250638f00cc56524a06674b843b2f5aeeeb6b3fb8a000953de70fc2b4aedbbea070607308d39e97e85043e640921a5d884a0b284fbfe204fdc07cfef91b7ac0fb037e72141414c57655044616e7948774c76496b7270456d7877546f566557486c5958563611696f524f42465a6541546f6b5775427839000607b87066910ae8cf70633a76a8628085092b0d9f4885b1d1be2ef09fe88e09d809187872546c53514e615249686370704259465675527159723607615843436b55330007eafa512f87158bd7d28a80cafd9ba4993d61b5b2536f750432561fa6dfbb6f091743504841474e45597943466a4b72474d744e557a7343451c6b49514a66576d637949754f625750666a6564716b73526563546c3600073ef067b3f1831d6990217d886ed493804db54297edf52e90e5165cc07f4fa97b076449587a6746341b78675166497464686c6e42546a6a694e68594d6159705a4d4e4b3000060606020606060107b999605b9ea506bd1eec7cfed0ff3a33814f3cb34a419b1ab3428498ec5cdae90f594d794d4d704774794766476e6b34126b69506f6963567343494f757a6f7467565600060342057e7339ccb5559628c0ebbf0cdd54708fe98cb0f1309315b87dc7aae9e97f05000401ba01180b403494001f81040c66f7ffe79a28dc5d9dc59b4e040be393c5eaa4d18118ca20af32f5e71ec711879131a1659bd3e5da5656499dcdd830bc0afb002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ec4de47a91fcf4da2568f9d83bc522e280d32e7661dc6d9eaac59227195f0ca4afc63c938de75c833c6cb9819ca09e435789be8363fe90a6dc831057aa7d090f", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "37562f9f09435725bb60c5fc8aad160924dcdf241de04f56bc1f33deaffd18d3", - "sequence_number": "8540763488405155213", + "sender": "f61270099d80975c9ab8b8e2cb2dc0f4fd80b95248524b5158282dbde0834115", + "sequence_number": "7074675893320599764", "payload": { "Script": { - "code": "620aef", + "code": "bf207cc4a4b7", "ty_args": [ { "struct": { - "address": "d5b5ed068f578c9c446443068a93c18a1473d9e3b783c6a9574ef8eeb983cb9a", - "module": "VxHNKaeHUXDcVwttLVsX", - "name": "tyZhoRQpRCpwpeTvZslTbKVgILHSS", + "address": "034f29cfc8a1805dc9c3ca90f59cbf7c20b96cdfebdb009b0ae131470ad0700a", + "module": "dojKcVWGsfurhtMGX", + "name": "ZKHIjStq3", "type_args": [] } }, { - "vector": { - "struct": { - "address": "0f7e9088febd61cd3b2122e83f4ddd9fa8074fe497fc587d91ea1d179e0d58a0", - "module": "kFZgDZuIOSEXphJCiQRFbbLUnEaq", - "name": "vtumtuhmJzjf", - "type_args": [] - } + "struct": { + "address": "ac5363ea81f1d93514ed956337c5fb2a3b608f70704f215032db0ff7d572a018", + "module": "GWEthN0", + "name": "AEppHXvANtMzOLMGCGoU", + "type_args": [] } }, { "vector": { - "vector": "signer" + "struct": { + "address": "2a0a48152b4205bd1d68e4f4a440839cbb89e20f2eeaf7e41333f3ea533aca59", + "module": "hcNlScUKpawSYlfSJPuodUbl", + "name": "XasTocCZXltTquuEjgDyYarj3", + "type_args": [] + } } }, { "struct": { - "address": "7d30ac1a0579160256d64ae086f9dcd6ba0a0ec762e438e7b78fb5eb4381b5dd", - "module": "yotVjLdlYTWXHNEstCIWZ", - "name": "MOxRZCugsUYShMWCbUVHEluwNowIX3", - "type_args": [] - } - } - ], - "args": [] - } - }, - "max_gas_amount": "12082630409813889442", - "gas_unit_price": "12221669662445329259", - "expiration_timestamp_secs": "9290029090669801926", - "chain_id": 84 - }, - "signed_txn_bcs": "37562f9f09435725bb60c5fc8aad160924dcdf241de04f56bc1f33deaffd18d38ded034d24e386760003620aef0407d5b5ed068f578c9c446443068a93c18a1473d9e3b783c6a9574ef8eeb983cb9a145678484e4b61654855584463567774744c5673581d74795a686f52517052437077706554765a736c54624b5667494c4853530006070f7e9088febd61cd3b2122e83f4ddd9fa8074fe497fc587d91ea1d179e0d58a01c6b465a67445a75494f53455870684a436951524662624c556e4561710c7674756d7475686d4a7a6a6600060605077d30ac1a0579160256d64ae086f9dcd6ba0a0ec762e438e7b78fb5eb4381b5dd15796f74566a4c646c59545758484e4573744349575a1e4d4f78525a43756773555953684d574362555648456c75774e6f774958330000a2114a595720aea76bdb3808ce179ca9c6316bbe3cd0ec8054002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b7bbab116642202052b91c70d800a81049a25b427d95eacc6815b9c90e4110161ebd917bb003a81a5187e9b9ba8dba7bf3a158c55f0649acd90ba7e74dad8001", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "592f71d24a86160aee3f518a0bb78a315fe07ea9d8ca279b64f6bcb4b56e2de4", - "sequence_number": "9169727676310944314", - "payload": { - "Script": { - "code": "e86a527decf2fa6fa8", - "ty_args": [ - { - "struct": { - "address": "f251e2fdd6d84499cd3a9d6dcce72bcdd34d18e750e5f1840d1b78ca0e9ed7be", - "module": "nsrXrhJhnwnGKyFNzqSkRSFwpXExFZIk0", - "name": "EfhwJTJGLCY", + "address": "36c9ce04cb9a013655056511e54aed4e175fa45abba38f845939b45475adef62", + "module": "kTtVKvXpfZyb", + "name": "AuSKKUzSvFFlDKaTbxXAvjMPuY0", "type_args": [] } }, { "vector": { "struct": { - "address": "f4623e60e7bc825d5b97dbff3f932845c7f1fbe7d2444bf744dbc72ba6001357", - "module": "iRDvokUkJXqPOZoiIvRDiXF6", - "name": "uZlQtXgGZTiL", + "address": "039da6eae422b6e1305ea9f24ce331ced87f7731d96825978bc59de99037e457", + "module": "aZkRcWwMaYYxVCqhHWJg0", + "name": "ruLAeaINeFtStvjeUZdAEkZVWThINw9", "type_args": [] } } @@ -2279,81 +2262,89 @@ { "vector": { "vector": { - "struct": { - "address": "b00bd60e71d379119c7059c0c504e7cf98885fdddd55b775acf0a48d136355d4", - "module": "vXIlyyakEdwjPjoDLUAVYPm", - "name": "uViBV1", - "type_args": [] - } + "vector": "u8" } } - } - ], - "args": [ - { - "U128": "112155803909479183986279334731816694555" - }, - { - "U8": 247 }, { - "U64": "12310332194893902679" + "struct": { + "address": "f757bae2081bd62367a4a600e5110979c1481fe529e35fc8e0a49c411332255f", + "module": "h6", + "name": "vHMokBUhCWqQIOWQvueTXGbMO", + "type_args": [] + } }, { - "Address": "4c9b4baf5c32dabdc0ee15edf6c16a9a1e1e2aabe01d86e0f7ddfc8218cb2ba2" + "struct": { + "address": "af727b20ee9e09dfe80ca68e960a62b40b21da719ddf7d658c3de5d2046030ec", + "module": "RaOcsUoTq2", + "name": "eDyQVDCHUHvfKbmuQXWphJj5", + "type_args": [] + } }, { - "U8": 142 + "struct": { + "address": "4827703b68750a1a2bc398ce0658a6f7c995aec0d12c07877ce2b5e90c01827a", + "module": "oIQSJiMsnGzB", + "name": "EHn", + "type_args": [] + } }, { - "U8Vector": "d4f157f64b8ddad59160a98ffc8fdd" - }, + "vector": { + "vector": "u64" + } + } + ], + "args": [ { - "U8": 136 + "Bool": false }, { - "U64": "4686224094570393612" + "Address": "a1a4790ed0f2211955b6749750559945c5e6a2aab55d4b3e1fa61feebb89198b" }, { - "U64": "7233804134355271388" + "U8": 212 }, { - "Bool": false + "Bool": true } ] } }, - "max_gas_amount": "7092256970346917398", - "gas_unit_price": "16895287754651257858", - "expiration_timestamp_secs": "5754006700794787217", - "chain_id": 37 + "max_gas_amount": "4651959406551131875", + "gas_unit_price": "27169274433095166", + "expiration_timestamp_secs": "3016496912331981779", + "chain_id": 146 }, - "signed_txn_bcs": "592f71d24a86160aee3f518a0bb78a315fe07ea9d8ca279b64f6bcb4b56e2de43afa9401bd6a417f0009e86a527decf2fa6fa80307f251e2fdd6d84499cd3a9d6dcce72bcdd34d18e750e5f1840d1b78ca0e9ed7be216e73725872684a686e776e474b79464e7a71536b5253467770584578465a496b300b456668774a544a474c4359000607f4623e60e7bc825d5b97dbff3f932845c7f1fbe7d2444bf744dbc72ba600135718695244766f6b556b4a5871504f5a6f6949765244695846360c755a6c51745867475a54694c00060607b00bd60e71d379119c7059c0c504e7cf98885fdddd55b775acf0a48d136355d4177658496c7979616b4564776a506a6f444c55415659506d06755669425631000a021bf3e4099312c2385a3f14f70f6c605400f70157b3b487e815d7aa034c9b4baf5c32dabdc0ee15edf6c16a9a1e1e2aabe01d86e0f7ddfc8218cb2ba2008e040fd4f157f64b8ddad59160a98ffc8fdd0088010cb0be3efccf084101dc7effaa88a26364050016ee505d23c26c6202ccfea1b21e78ea913517bc9b56da4f25002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402db1959c1b49019975172122b4108e56f676351bdff074afef544e8fcf1a222a4c0e0cffc43287085e71070c4aba1acb95680ddc14083d599ba875148c59d00e", + "signed_txn_bcs": "f61270099d80975c9ab8b8e2cb2dc0f4fd80b95248524b5158282dbde0834115d4c864e23d4c2e620006bf207cc4a4b70a07034f29cfc8a1805dc9c3ca90f59cbf7c20b96cdfebdb009b0ae131470ad0700a11646f6a4b635657477366757268744d4758095a4b48496a537471330007ac5363ea81f1d93514ed956337c5fb2a3b608f70704f215032db0ff7d572a0180747574574684e301441457070485876414e744d7a4f4c4d4743476f550006072a0a48152b4205bd1d68e4f4a440839cbb89e20f2eeaf7e41333f3ea533aca591868634e6c5363554b70617753596c66534a50756f6455626c19586173546f63435a586c7454717575456a6744795961726a33000736c9ce04cb9a013655056511e54aed4e175fa45abba38f845939b45475adef620c6b5474564b765870665a79621b4175534b4b557a537646466c444b615462785841766a4d50755930000607039da6eae422b6e1305ea9f24ce331ced87f7731d96825978bc59de99037e45715615a6b526357774d615959785643716848574a67301f72754c416561494e6546745374766a65555a6441456b5a56575468494e7739000606060107f757bae2081bd62367a4a600e5110979c1481fe529e35fc8e0a49c411332255f0268361976484d6f6b42556843577151494f5751767565545847624d4f0007af727b20ee9e09dfe80ca68e960a62b40b21da719ddf7d658c3de5d2046030ec0a52614f6373556f547132186544795156444348554876664b626d7551585770684a6a3500074827703b68750a1a2bc398ce0658a6f7c995aec0d12c07877ce2b5e90c01827a0c6f4951534a694d736e477a420345486e0006060204050003a1a4790ed0f2211955b6749750559945c5e6a2aab55d4b3e1fa61feebb89198b00d40501e36604e16e148f40fec563a74f866000d3439cadf5bfdc2992002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444023f24f7b1010f824301f9f6f08587efc073c65649b5efee44552cd1db5f856004baf3fbf3bc66494b889697a88abebc2d31c275329d1ef01aad3196cfee8e600", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "5d8feb86ca256f52bdc48766ceccb284bee92b5c4cc459d337e62cb6de8ccabd", - "sequence_number": "14743781543221447808", + "sender": "86b87357d3c522af0e3ccc8de8da15385a2b209761b56b7dfa6a1bb6e010abec", + "sequence_number": "404549278413470988", "payload": { "Script": { - "code": "b9", + "code": "f6087227", "ty_args": [ { - "struct": { - "address": "5f2e7892df226d49f7b201f477bfcdc01ecfb6244a2090ad0db8af19218b4239", - "module": "iUlMBKLNdcmYmmpOOwbJmPsclEFJkcjO", - "name": "nmwugjFFiLCNeOc0", - "type_args": [] + "vector": { + "struct": { + "address": "7920ee815072911b30d570541344c4d8d197549a05f5d09e9d2e6928acc9e3ce", + "module": "NmiUWbRcYyFIuXKYhcRnMZI", + "name": "uixyc", + "type_args": [] + } } }, { "vector": { "vector": { "struct": { - "address": "40ebb1f6f66eb2d922aa9b7ea162720a2254aefa55aaf280c96565c59f60b8d0", - "module": "iasDiaSBqbsTiFYvdEtstmPCIG", - "name": "LzKNSuaiErYhk", + "address": "86b83a64f34db202eef270075540736f6d3fea21d6c399a3d4f2ce82532556b2", + "module": "egnOnGVhCVaFPBdawKUbvBtZHKJu1", + "name": "KoEWKkwqtwhc", "type_args": [] } } @@ -2361,271 +2352,313 @@ }, { "vector": { - "struct": { - "address": "f54249adaf59fa534d3dceb851077c0562d76c53034d1103c3c75c976e5f5192", - "module": "auYBereqdAa", - "name": "ysLPhowohXxVBgBXaAKaNatyLadmqH6", - "type_args": [] - } + "vector": "u128" } + } + ], + "args": [ + { + "U128": "227256863336655445251818701500700937500" }, { - "vector": "u8" + "Address": "76dbc19864fb6861367625dc5b763c941d62b316af3765176bf6206bddee65ff" }, { - "vector": { - "struct": { - "address": "1e7e91835587b43fd796e8e8d6d9bec0f7e38f646fb48bffaa8cffaec9176958", - "module": "EClydrVhoHyFbye7", - "name": "sChPfFPsAsfIByJlDmWbJ7", - "type_args": [] - } - } - } - ], - "args": [ + "U8Vector": "29" + }, + { + "U64": "6759228007510437688" + }, { - "U8Vector": "d9cadcacedea27224ada47aa4f688e87" + "U128": "22373333087657506833071305838259824444" }, { - "U64": "9013362639669053" + "Bool": false }, { - "U64": "7568998237139347555" + "Address": "34552c5f076d3a760c32b6ab87e412e23c083728c8290eb9fdf471ca3d62766f" }, { - "Address": "b710806365d3f8ec1f744abd9bc5ebbe50921c9bea037151e18bcea8bcd3c337" + "Address": "5698bbfc68aa66683d1586a08e8aabe01af983e4ae8a9bcbc2d6f79a178f76b3" } ] } }, - "max_gas_amount": "1692258841077112611", - "gas_unit_price": "4274255541197264352", - "expiration_timestamp_secs": "985506230859005061", - "chain_id": 175 + "max_gas_amount": "2822368108429471272", + "gas_unit_price": "11575837400634404389", + "expiration_timestamp_secs": "5613918175603189730", + "chain_id": 201 }, - "signed_txn_bcs": "5d8feb86ca256f52bdc48766ceccb284bee92b5c4cc459d337e62cb6de8ccabd80ccac99326f9ccc0001b905075f2e7892df226d49f7b201f477bfcdc01ecfb6244a2090ad0db8af19218b42392069556c4d424b4c4e64636d596d6d704f4f77624a6d5073636c45464a6b636a4f106e6d7775676a4646694c434e654f63300006060740ebb1f6f66eb2d922aa9b7ea162720a2254aefa55aaf280c96565c59f60b8d01a6961734469615342716273546946597664457473746d504349470d4c7a4b4e53756169457259686b000607f54249adaf59fa534d3dceb851077c0562d76c53034d1103c3c75c976e5f51920b61755942657265716441611f79734c50686f776f685878564267425861414b614e6174794c61646d71483600060106071e7e91835587b43fd796e8e8d6d9bec0f7e38f646fb48bffaa8cffaec91769581045436c79647256686f487946627965371673436850664650734173664942794a6c446d57624a3700040410d9cadcacedea27224ada47aa4f688e87013d875e069b0520000163a83f5ecb7b0a6903b710806365d3f8ec1f744abd9bc5ebbe50921c9bea037151e18bcea8bcd3c337235f6a32731c7c17e0d54eccc434513b85fc480eb238ad0daf002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404683eb031e047ce742ed3de8a4fb9bcac09169db72f3626367293cbc9813854996e1667cda9158de4004f098154c5af06b2db60e7fbb4cb2dbdbe2fdd16be903", + "signed_txn_bcs": "86b87357d3c522af0e3ccc8de8da15385a2b209761b56b7dfa6a1bb6e010abec0cbdf9e16c3f9d050004f60872270306077920ee815072911b30d570541344c4d8d197549a05f5d09e9d2e6928acc9e3ce174e6d6955576252635979464975584b596863526e4d5a490575697879630006060786b83a64f34db202eef270075540736f6d3fea21d6c399a3d4f2ce82532556b21d65676e4f6e4756684356614650426461774b55627642745a484b4a75310c4b6f45574b6b7771747768630006060308021ccd87a89391a04f1459fede6e14f8aa0376dbc19864fb6861367625dc5b763c941d62b316af3765176bf6206bddee65ff0401290138ef87970f9acd5d023c6787352a99bbe761756dad7cf2d41005000334552c5f076d3a760c32b6ab87e412e23c083728c8290eb9fdf471ca3d62766f035698bbfc68aa66683d1586a08e8aabe01af983e4ae8a9bcbc2d6f79a178f76b3286e5450d7102b2725ae7ed2c8a2a5a0e2e7ef3ed6a4e84dc9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444054b487d7d4ad507c14102938f224836dfb5690b01f57034775f3bcf42e9e6fdf115951ef72ba73d682524f40f1425ec5bc68a65eb66ac527932038f10ea9e00d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "f7c4446bd445b75ee341cfe0381b0fa1f1740e8d6610644f6b1e4bec9278f5a6", - "sequence_number": "9494789570812305745", + "sender": "fd1398263835b7e5ed30bca19b446f49c6e20bcd2a300afebcc1ef10ca336626", + "sequence_number": "8012530865797725776", "payload": { "Script": { - "code": "d2c17dd8722d88a46d45f2bd950ad7", - "ty_args": [], + "code": "12ce8fd26a5d2b940e", + "ty_args": [ + { + "vector": { + "vector": "u64" + } + }, + { + "vector": { + "struct": { + "address": "4434e41c71e37f4f985ec3ad0ad900ec8ebd23274a70416623d5becb5ea806dd", + "module": "kwq", + "name": "NBSODdkbGuAUQQThEhUotHmRdR9", + "type_args": [] + } + } + }, + { + "vector": { + "struct": { + "address": "e577cc78e9646592aa595e2863321a631695d64c5da1efedb7b4774c39f5d3a0", + "module": "OJMZMvwCbIWvLpSMjTrcnjrNlUt7", + "name": "REQAphMJXkzDXHtjXZD", + "type_args": [] + } + } + }, + { + "struct": { + "address": "bdfdaf16b5a4ad3da094530b4db3768cdbb120f45d2f0abd71e97401b80e8c46", + "module": "uOIbLtXGSuwLGLEKSDqbL", + "name": "CtfKZNkbSHHeFRwCSasVZTlqs", + "type_args": [] + } + } + ], "args": [ { - "Bool": true + "Bool": false }, { - "U8Vector": "2e9816cdff0afac22812babce8" + "U128": "87365757594906072518882772707606604623" }, { - "U8": 35 + "U64": "9321582198391004080" }, { - "U64": "2215184528335456973" + "U128": "206177304539752532775225512981783533406" }, { - "Address": "fdc85a6e02066f9a6ac6a95ec53a318ec26922d2b4b47c5cebd5cb3b0a5af493" - } - ] - } - }, - "max_gas_amount": "15272936314777272654", - "gas_unit_price": "14775369019845558883", - "expiration_timestamp_secs": "2550760206131445245", - "chain_id": 60 - }, - "signed_txn_bcs": "f7c4446bd445b75ee341cfe0381b0fa1f1740e8d6610644f6b1e4bec9278f5a651e15921cf44c483000fd2c17dd8722d88a46d45f2bd950ad700050501040d2e9816cdff0afac22812babce8002301cd4a608b97eabd1e03fdc85a6e02066f9a6ac6a95ec53a318ec26922d2b4b47c5cebd5cb3b0a5af4934e8176a7a85ef4d363c2341dd7a70ccdfdbdaa99e41e66233c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c4675a2d9486b6227a9fa85b2fb68d7e24ff10e7ff1e683fc136c33e0438516f1820aecd180d197eebe595260bcbb8880e312ca385b755b5099098e82c77fd04", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "1ea0ecf53e096ffdaf43e382d080d5a0233703e2e9ff99d1fc7151819b163058", - "sequence_number": "93087573714700565", - "payload": { - "Script": { - "code": "65c3bf2be2d2aca1a840", - "ty_args": [], - "args": [ + "U64": "15049080533632696097" + }, { - "U8Vector": "48" + "Address": "6ec643c9b9101cd89c539c33ea9111fe77139e97e073205cc722d26e68dd1123" }, { - "U8": 10 + "U128": "151415075041809247393355773762258533856" }, { - "U8Vector": "8decf0ebcb87ba8a55a0af5cd4cd32" + "U64": "7219431739781086568" } ] } }, - "max_gas_amount": "12510455267995156094", - "gas_unit_price": "9919112838882768429", - "expiration_timestamp_secs": "17452032925716965600", - "chain_id": 105 + "max_gas_amount": "11706266843780901541", + "gas_unit_price": "4594881765337666540", + "expiration_timestamp_secs": "5069264976216212089", + "chain_id": 132 }, - "signed_txn_bcs": "1ea0ecf53e096ffdaf43e382d080d5a0233703e2e9ff99d1fc7151819b163058158944b4a7b64a01000a65c3bf2be2d2aca1a8400003040148000a040f8decf0ebcb87ba8a55a0af5cd4cd327efe4373c8109ead2db69fc092c4a789e0e8c7297b1332f269002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405467c77caa3417c717a88857f2b00327d18a430b86a1b4dc49b47a441e3e95288217b42fa7aa022069dfba46bd51b3e5b70ffd216893796c851ea96286862400", + "signed_txn_bcs": "fd1398263835b7e5ed30bca19b446f49c6e20bcd2a300afebcc1ef10ca33662650feb9c75e3a326f000912ce8fd26a5d2b940e0406060206074434e41c71e37f4f985ec3ad0ad900ec8ebd23274a70416623d5becb5ea806dd036b77711b4e42534f44646b6247754155515154684568556f74486d52645239000607e577cc78e9646592aa595e2863321a631695d64c5da1efedb7b4774c39f5d3a01c4f4a4d5a4d767743624957764c70534d6a5472636e6a724e6c557437135245514170684d4a586b7a445848746a585a440007bdfdaf16b5a4ad3da094530b4db3768cdbb120f45d2f0abd71e97401b80e8c4615754f49624c7458475375774c474c454b534471624c194374664b5a4e6b625348486546527743536173565a546c717300080500024f2ba561f4fb7aaf24bc39f26908ba4101b05bb31f9fe95c81025e57ae7f2ad963283ca22c86f14d1c9b01213f6c0b0313d9d0036ec643c9b9101cd89c539c33ea9111fe77139e97e073205cc722d26e68dd112302e0fdb685095ab818fd6cde95927be9710168fdd4c9ea923064a56a7e05ac0375a2ec13dfef9e4cc43f7942b243a3a5594684002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ea00dc6c2c4bc99746763e6c9a50325e8b580ccd824c731b7532d053fad068a7fdb8f91b7f9c3bf893357d9bf56efb1b0d725cbb2b12a4674de46d56d0371203", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "e4c685f4517b068bb0c727af20429c95b788e21e4463b98443b55f0aedc781d3", - "sequence_number": "7844837829379685075", + "sender": "17f683a8f2b73390fc4ef83c67728a684c0cebd4d5887f03dac7ac33d178ef0e", + "sequence_number": "7878198917564551839", "payload": { "Script": { - "code": "4adffed56d1d9f5fea", + "code": "713fa6d13f", "ty_args": [ { - "struct": { - "address": "0b98a633bf8c25236689d8bac4ba19d24673b2db6fa869c78fec53ce0ddd0220", - "module": "PoYMCAC", - "name": "RCnUZjidUtcLlvHDjoDDPPGu9", - "type_args": [] + "vector": { + "struct": { + "address": "3b5babe04d7115442a1d96eeb09928cf9780f94bc5a376a23274043030de58eb", + "module": "wfWCEEhbcbSntARhEnTzFO", + "name": "dOChJNlLvC7", + "type_args": [] + } + } + }, + { + "vector": { + "struct": { + "address": "64a1ae397fe1da7d2381a546cb32298322e79b972aa8ee6158bae854287dd7ec", + "module": "wQjuwazivhqbhlCZEIPqgSevZoIXIm3", + "name": "nKnnTuYbJcMWWlBlytdOdVcJLKgqe1", + "type_args": [] + } } }, { "vector": { "vector": { "struct": { - "address": "aad1c4b6bdd1bb80b29f2f0a1d62388a708085ba69c3df98410a503eb3835a75", - "module": "NmJgZNXKdCv3", - "name": "ZvptIZjlgUrKfRTHLZg8", + "address": "e0fe10dcd5150f8d70201ba14a43f74d8340f78c68620cce098780878ae5d712", + "module": "CqSaKCKCQnCNOwgP", + "name": "UITzYPMGPPtMHKDyR", "type_args": [] } } } }, { - "struct": { - "address": "bb60f5ffcd1486062023a7bab4dceb68142dc014fb7c980950afbc2c88262c17", - "module": "rgwUgU9", - "name": "rhGdwoDx2", - "type_args": [] - } - }, - { - "struct": { - "address": "9f0ca7a4d79b8281da6b81e0fc580c1fac222d716ff3305dab889fff6e826262", - "module": "qizHbJCKOyALBPkh3", - "name": "DNoajqPsZTKja0", - "type_args": [] + "vector": { + "struct": { + "address": "e6528ac0f1a1a0b3d353190c02b41869bada812e7bfa7ac45939ba6bd69735de", + "module": "OZDZmXxRfZvAITlH", + "name": "lalGqeaYhREWShwRJWReMKKrPr", + "type_args": [] + } } }, { - "struct": { - "address": "1b4f0d3518b99c3df3d7b34b59bdbaefeeea7fbfb4b63404dce6c484be0141fc", - "module": "WUf8", - "name": "mYJsdBGxUQhbXBoR", - "type_args": [] + "vector": { + "struct": { + "address": "cc13aa26d3d682ff9eb9adf9d2810efe49dde92fd5c6461e4c3367328b106a28", + "module": "HXBaYGKANXggcIhAXRluQBvT6", + "name": "BIpCFHqFRxhNuDxiIbDEsJzdE2", + "type_args": [] + } } }, { "vector": { "struct": { - "address": "948892b7a161383440ad9ccdf23d3d4b9f394723d847c9ef9975c1078c869c63", - "module": "HqmPptmJfFjAzHXxdnXN", - "name": "uZtLSJwVcsvYZc0", + "address": "c3816a886b59014f83fb54e3058e8a84c68bc092c211ee44d88d4f9e7b07fc8a", + "module": "NHwrtZFcwOPcIyIBHEckP4", + "name": "tZo", "type_args": [] } } }, { "struct": { - "address": "1a8714fe28079b02eccb6cd9af073997566ccd8ce570cf50a3b3fa59ce0d3a6c", - "module": "OloswIDSjMbEgvQEXSZyPtmYTMFx", - "name": "wWnbNgQhKApwFKkgLz2", + "address": "e60c7b5003bc138a0879bbb3a509c3e47beb8eef59b2ecb2a0bf654fe0312e5c", + "module": "rlHEJ", + "name": "YNJFOxOkkbepagKlPtUgFOTQ", "type_args": [] } }, { "vector": { - "vector": "u64" + "vector": "u8" } - } - ], - "args": [ - { - "U128": "209965902554127036893218997229937319241" }, { - "U64": "12461468443567440336" + "vector": { + "vector": { + "struct": { + "address": "320df2d9228e6a4bc27946c9ea21193fa1e24b2654fa888b3b048a420db2221a", + "module": "UDHnSrjeYDpKQ2", + "name": "XmejfVyncLOuGBSAQcGkRHdQgTtSUVs9", + "type_args": [] + } + } + } }, { - "U8Vector": "dd192c06d00dd46b79" - }, + "struct": { + "address": "4e191f57cef49d470c80d5b997d3e26f08d888e454fc9eb1fed6a4954e1fa9e0", + "module": "ursvTshSeoiGpJWMZsjoFSJCBJg", + "name": "MsFMnzCcvmLVicWixNmmiBb0", + "type_args": [] + } + } + ], + "args": [ { - "U8": 179 + "Address": "53210a122cd5ea4efe7ae87ed30908d872705191629a4a4688c4d2d6c60e6235" }, { - "Bool": false + "U8": 15 }, { - "U128": "122818813095141469507882228666766558408" + "U8": 84 }, { - "U8": 83 + "U8": 247 } ] } }, - "max_gas_amount": "9185705063188198709", - "gas_unit_price": "5480641370307763048", - "expiration_timestamp_secs": "15236713497716522836", - "chain_id": 155 + "max_gas_amount": "788092704077831629", + "gas_unit_price": "3006259600154363039", + "expiration_timestamp_secs": "12909114088754588574", + "chain_id": 73 }, - "signed_txn_bcs": "e4c685f4517b068bb0c727af20429c95b788e21e4463b98443b55f0aedc781d3d3fab82c7176de6c00094adffed56d1d9f5fea08070b98a633bf8c25236689d8bac4ba19d24673b2db6fa869c78fec53ce0ddd022007506f594d4341431952436e555a6a69645574634c6c7648446a6f4444505047753900060607aad1c4b6bdd1bb80b29f2f0a1d62388a708085ba69c3df98410a503eb3835a750c4e6d4a675a4e584b64437633145a767074495a6a6c6755724b665254484c5a67380007bb60f5ffcd1486062023a7bab4dceb68142dc014fb7c980950afbc2c88262c1707726777556755390972684764776f44783200079f0ca7a4d79b8281da6b81e0fc580c1fac222d716ff3305dab889fff6e8262621171697a48624a434b4f79414c42506b68330e444e6f616a7150735a544b6a613000071b4f0d3518b99c3df3d7b34b59bdbaefeeea7fbfb4b63404dce6c484be0141fc0457556638106d594a73644247785551686258426f52000607948892b7a161383440ad9ccdf23d3d4b9f394723d847c9ef9975c1078c869c631448716d5070746d4a66466a417a485878646e584e0f755a744c534a7756637376595a633000071a8714fe28079b02eccb6cd9af073997566ccd8ce570cf50a3b3fa59ce0d3a6c1c4f6c6f73774944536a4d62456776514558535a7950746d59544d46781377576e624e6751684b417077464b6b674c7a32000606020702495d89a62447a832d21e34453ff6f59d01d0c193968607f0ac0409dd192c06d00dd46b7900b3050002c88475b89639403f07f0f238010b665c005335f5d646162e7a7f681b81e249260f4c54ffcad732ae73d39b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ce5d5126a1848c619b8de127d7fdc62e2fc0aee66d1edf5a9aa9f66189b1796f566dd9fe56aa08e31d0e7f32fc65a94d39c1fdfb9fcaf21f4bf5c6e4239ed40a", + "signed_txn_bcs": "17f683a8f2b73390fc4ef83c67728a684c0cebd4d5887f03dac7ac33d178ef0e9f524dcf2cfc546d0005713fa6d13f0a06073b5babe04d7115442a1d96eeb09928cf9780f94bc5a376a23274043030de58eb1677665743454568626362536e74415268456e547a464f0b644f43684a4e6c4c76433700060764a1ae397fe1da7d2381a546cb32298322e79b972aa8ee6158bae854287dd7ec1f77516a7577617a6976687162686c435a45495071675365765a6f4958496d331e6e4b6e6e547559624a634d57576c426c7974644f6456634a4c4b6771653100060607e0fe10dcd5150f8d70201ba14a43f74d8340f78c68620cce098780878ae5d71210437153614b434b43516e434e4f776750115549547a59504d475050744d484b447952000607e6528ac0f1a1a0b3d353190c02b41869bada812e7bfa7ac45939ba6bd69735de104f5a445a6d587852665a764149546c481a6c616c477165615968524557536877524a5752654d4b4b725072000607cc13aa26d3d682ff9eb9adf9d2810efe49dde92fd5c6461e4c3367328b106a28194858426159474b414e5867676349684158526c7551427654361a42497043464871465278684e7544786949624445734a7a644532000607c3816a886b59014f83fb54e3058e8a84c68bc092c211ee44d88d4f9e7b07fc8a164e487772745a4663774f5063497949424845636b503403745a6f0007e60c7b5003bc138a0879bbb3a509c3e47beb8eef59b2ecb2a0bf654fe0312e5c05726c48454a18594e4a464f784f6b6b62657061674b6c50745567464f545100060601060607320df2d9228e6a4bc27946c9ea21193fa1e24b2654fa888b3b048a420db2221a0e5544486e53726a655944704b513220586d656a6656796e634c4f75474253415163476b52486451675474535556733900074e191f57cef49d470c80d5b997d3e26f08d888e454fc9eb1fed6a4954e1fa9e01b7572737654736853656f6947704a574d5a736a6f46534a43424a67184d73464d6e7a4363766d4c5669635769784e6d6d6942623000040353210a122cd5ea4efe7ae87ed30908d872705191629a4a4688c4d2d6c60e6235000f005400f7cddda28c23deef0a9f04cfb12d61b8299e2b3549de6226b349002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402e6edc0a17495a9f0307d0ea62ab97b81e5d3145857eb497c313ac2211e97a0dbb4223bf13b4e2fb977e2cb06f95647a25430f65ba615bab138392413f4fe306", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "e5b1dbf8f47d0d746ca556103e540d955b9f77fb243cbdcc4976e1c005e26b5e", - "sequence_number": "11445035797593009101", + "sender": "77c26b26a45eb63082ad56568e064f491c00792a1c0efca62e9f5317231c4b8e", + "sequence_number": "18070014116409769794", "payload": { "Script": { - "code": "b41ada", + "code": "db963f6dd5", "ty_args": [ + { + "vector": { + "struct": { + "address": "c6d8bcff80fe95d4598249a7b4cda38b291d39704b309f81f8782c42a149bc07", + "module": "WCtjoAgEtweUYLRwZZWYFQtQvhGdN", + "name": "DjtjxYbNSbzInjbVbYzqrZqllnwqTKIX", + "type_args": [] + } + } + }, { "struct": { - "address": "26c275b9edd04fa1b643d4c5fe3c81ce8ece3654a430dfa3ec03e8c6ffc7019e", - "module": "sdZRKquotEBnvsnyz2", - "name": "dryQWfqeUEInUJezyQcMv2", + "address": "2318a7cc65c5b148d5d9bf6dd92525c7635805d83278f6219123bed6d9858477", + "module": "JWsOjapVI8", + "name": "iLiCNpIJHEawxFMKTwCv1", "type_args": [] } }, { "struct": { - "address": "58ad9e4700ae1d1246d81266cda990d02b55b83ecc2deecdb360763675c35500", - "module": "DFzUwPkunv", - "name": "KRITJmSzWJgjxCwGzAIYMAZUhw", + "address": "de5a8fdafff71f72cc13162b377920fbe3fab86c74a2b414fcdc1a733e1befe8", + "module": "roAnkhfxAhuIZAfRISv0", + "name": "J", "type_args": [] } }, { "struct": { - "address": "d8d4c60bbbce09c96038ec505c3b01efb49ee8f6ec7f5b8d85b18bc2743152b7", - "module": "OtlavkInbDZOzXylRDHD", - "name": "xyfPeLO", + "address": "25c3f9c9ce38783261134b5aeb707342ecad2f6051db7ec8c763163336e75d6e", + "module": "Mvt8", + "name": "bFBEgxwspL", "type_args": [] } }, + { + "vector": { + "vector": "u64" + } + }, { "struct": { - "address": "d797e5319c6256a38c71c85bf283ec4fdce4f70861815556200afbb412defda9", - "module": "LeUrKOJ8", - "name": "POWRNMoSol7", + "address": "90abb4da2b4fcac66af3ffda02d0bce568e99a865c1b938a8b177921148cce0b", + "module": "xkNSG", + "name": "dowdwwUCNDtsgeW5", "type_args": [] } }, { "vector": { "struct": { - "address": "4d9affd320e94695392db9df76b911933a79d9d593574fbd69db7b799334ebd0", - "module": "E", - "name": "aDLohvvIvQKtcyACxQmaX9", + "address": "3df93d42f95f8dade6f85eddb795f7d3a74a4b3bd5e7a2f18ada43ca0ffb2c56", + "module": "nORklbjiFkxgZGBlqUNXSRJ", + "name": "HhMoC", "type_args": [] } } @@ -2633,285 +2666,343 @@ { "vector": { "struct": { - "address": "38c490d2615696547fdb8393b2a8b6946a5298cdaaa72dde97371f1950b94243", - "module": "hKvQtgz4", - "name": "CNRrRDSOfGcY", + "address": "994ec3ce986fbfb646b3fcdee5d970646f49b6582a923c19d4f4a824b5ead932", + "module": "YQFmDlxqQvuIGMifHjfuGgxcaWniSkVh2", + "name": "cpZZEEHqzaFCAeVonImPS8", "type_args": [] } } - }, - { - "struct": { - "address": "db44e39dd735c3e0016017e667b2a7eee24656984cdeac42d63256a122590c98", - "module": "ZMldDyfn", - "name": "sOtxuzQgDgpTzGVRHGOGcyNfpypSBdq", - "type_args": [] - } - }, - { - "struct": { - "address": "24c10a73457c72a6ddc935d95cdf20dc08b2dbe562dee4425c4e0ce24d30926f", - "module": "VMWETXs5", - "name": "JijxERtfeCkoAfHUUoYORtVvR", - "type_args": [] - } } ], "args": [ { - "U128": "124542641658449678121282165522415514875" + "U128": "87529034153559330264885154409336100689" + }, + { + "U8Vector": "3ac47fa2e99af9f4cc5d006934bee0" }, { - "Address": "26189e93d8bd4c7945a23536368539d041f788e069a14999c775e500d6c4194c" + "Bool": false } ] } }, - "max_gas_amount": "1926523178893065734", - "gas_unit_price": "9422914524794285288", - "expiration_timestamp_secs": "4276564168168062919", - "chain_id": 220 + "max_gas_amount": "6916975781500037231", + "gas_unit_price": "11832574915920991358", + "expiration_timestamp_secs": "15481718037493599112", + "chain_id": 151 }, - "signed_txn_bcs": "e5b1dbf8f47d0d746ca556103e540d955b9f77fb243cbdcc4976e1c005e26b5ecd2b29656befd49e0003b41ada080726c275b9edd04fa1b643d4c5fe3c81ce8ece3654a430dfa3ec03e8c6ffc7019e1273645a524b71756f7445426e76736e797a321664727951576671655545496e554a657a7951634d7632000758ad9e4700ae1d1246d81266cda990d02b55b83ecc2deecdb360763675c355000a44467a5577506b756e761a4b5249544a6d537a574a676a784377477a4149594d415a5568770007d8d4c60bbbce09c96038ec505c3b01efb49ee8f6ec7f5b8d85b18bc2743152b7144f746c61766b496e62445a4f7a58796c524448440778796650654c4f0007d797e5319c6256a38c71c85bf283ec4fdce4f70861815556200afbb412defda9084c6555724b4f4a380b504f57524e4d6f536f6c370006074d9affd320e94695392db9df76b911933a79d9d593574fbd69db7b799334ebd001451661444c6f6876764976514b746379414378516d61583900060738c490d2615696547fdb8393b2a8b6946a5298cdaaa72dde97371f1950b9424308684b765174677a340c434e52725244534f664763590007db44e39dd735c3e0016017e667b2a7eee24656984cdeac42d63256a122590c98085a4d6c644479666e1f734f7478757a5167446770547a47565248474f4763794e6670797053426471000724c10a73457c72a6ddc935d95cdf20dc08b2dbe562dee4425c4e0ce24d30926f08564d574554587335194a696a784552746665436b6f41664855556f594f5274567652000202fb7474decb94a9ff93a0c898500ab25d0326189e93d8bd4c7945a23536368539d041f788e069a14999c775e500d6c4194c063e7ac19f62bc1ae86c3be7d5eac482c73fd2e67368593bdc002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444098870a3a832e6f60e1a491a640bef7f54a80240dea3d0cc1d85f7e5582087e0e151fd32759e7b5efe956f3de1cfb47f607ac2d53c9d238fbc8af0c7c232ee006", + "signed_txn_bcs": "77c26b26a45eb63082ad56568e064f491c00792a1c0efca62e9f5317231c4b8e42ffe58e1996c5fa0005db963f6dd5080607c6d8bcff80fe95d4598249a7b4cda38b291d39704b309f81f8782c42a149bc071d5743746a6f41674574776555594c52775a5a575946517451766847644e20446a746a7859624e53627a496e6a625662597a71725a716c6c6e7771544b495800072318a7cc65c5b148d5d9bf6dd92525c7635805d83278f6219123bed6d98584770a4a57734f6a617056493815694c69434e70494a4845617778464d4b54774376310007de5a8fdafff71f72cc13162b377920fbe3fab86c74a2b414fcdc1a733e1befe814726f416e6b686678416875495a41665249537630014a000725c3f9c9ce38783261134b5aeb707342ecad2f6051db7ec8c763163336e75d6e044d7674380a6246424567787773704c000606020790abb4da2b4fcac66af3ffda02d0bce568e99a865c1b938a8b177921148cce0b05786b4e534710646f7764777755434e447473676557350006073df93d42f95f8dade6f85eddb795f7d3a74a4b3bd5e7a2f18ada43ca0ffb2c56176e4f526b6c626a69466b78675a47426c71554e5853524a0548684d6f43000607994ec3ce986fbfb646b3fcdee5d970646f49b6582a923c19d4f4a824b5ead932215951466d446c787151767549474d6966486a66754767786361576e69536b5668321663705a5a454548717a6146434165566f6e496d5053380003025157392c1404f57f471614d9917ad941040f3ac47fa2e99af9f4cc5d006934bee005006f284a58d308fe5f7e14abc131c035a4884b9089871cdad697002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440567c3d9dbcb418740d5beffd07d36c4176ebf0baf6cd383022e6ce767f4b4ef834ab8d3e5a959fa8fa0cd8d13ba55676ce6cad2021ff39623342f842c46fc007", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "3ab5d68b68ed89bf848d18b846c9d77f937b1eceeea9d58269fdb64058f2f7dd", - "sequence_number": "2320556455284762657", + "sender": "55d48685b2e28ae850e0c7ec5e50756af7f0cf20f9e0cc734999fa0fba10540e", + "sequence_number": "14034884849846446851", "payload": { "Script": { - "code": "a2d327", + "code": "3b4681e86cd00c7c4b7bb37abf", "ty_args": [ { "struct": { - "address": "91d7edbeb1fe9298b472df0df8925715ec4f5c41f41f5739506d184be3731d29", - "module": "ncbIylsJCVfvITrDwpqvmrUGjzOJ", - "name": "TxsUMfNKOaasOOrvqxDs", + "address": "a77112200b7a7e70d46bdb71cdfa8f3582335d53c1a30f734be93b2162b5f799", + "module": "yparRfflLltVjAbgvSBAZKwNuJLFM7", + "name": "ydVAqhcLEvNrarkYFVYzd7", "type_args": [] } }, { "struct": { - "address": "ae67cb655eeecad53b5b8098a960de679231146ecf2b1f0a7a25baaa521ea972", - "module": "KpAHOQWHipXMVpcBrjjlWJUUvKVnc", - "name": "SYEFIaBLSqgoHfKUaSsNQp1", + "address": "6cc792b9697bcd56e1532e160f61121700ad716eb3880d25407467cffed2a52a", + "module": "VaHIwevIlJNG", + "name": "aQkWTGSjLlJceBoWMdzD", "type_args": [] } }, + { + "vector": { + "vector": "u64" + } + }, + { + "vector": { + "struct": { + "address": "690011fadcf792cbce96f3a3af338607450e2fe51c774179fbe5afd97ae22fc6", + "module": "EYjAdsNnVSiQxOWla", + "name": "vhlCodJaBnofJQPfmKBBvZFgxmtINzee3", + "type_args": [] + } + } + }, + { + "vector": "address" + }, { "vector": { "struct": { - "address": "7861be3b3dc94521f69aa59f604bd909645d5918ef65f4bd8b5eeddab04cde77", - "module": "IWzcWcgaHkXIpUoGSNQAYJC", - "name": "XgjwwCMeCjZOIAjzBhmR", + "address": "a0d383ad939f339ee5e8ebccfcc36750907e6a78cf5a2701fb1cd5b5e4fdeb97", + "module": "jpHKlaMIiSZycTAOFTJoNefcP", + "name": "ewkMNloFNfWkTFareNkjigAN", "type_args": [] } } }, { "struct": { - "address": "e5f0c4ba30c9f3b202f89df6f219e04e1ed679c88c0c0340402fd2abf1b43b9f", - "module": "EkfgCbLpGvRBhLwpWvqKugzORKYX", - "name": "kdrpy2", + "address": "a50bb672641f816eb024d9790d5856a8e626da7073510806ba70dff951929db4", + "module": "adLcUxXc7", + "name": "HJMFXKPUyxxyAXGkd0", + "type_args": [] + } + }, + { + "struct": { + "address": "ac1141d7d4fe13222145d87b1e65d2afcc3e5ac172a8423a1378559228fc1050", + "module": "GrZxMzRMtt", + "name": "WYMmmEylFDJMQ7", "type_args": [] } } ], "args": [ { - "U8Vector": "b7cdcafaf1e34289954f97d0" + "U128": "98434209940513369142324584340025652319" + }, + { + "U128": "321894956682793891505064759699072864634" + }, + { + "U8Vector": "d8fc2d0dd6c050" + }, + { + "U64": "7051346425801042965" + }, + { + "U8Vector": "10cb07ad8ce6dbba052b19b82b3e" + }, + { + "U64": "10338548140756552756" + }, + { + "U8Vector": "11f627bee202b811a1" + }, + { + "U64": "18319272913683637683" }, { - "U64": "3339465231986042915" + "U64": "1580206222738488545" }, { - "U128": "91959944195168597389071294253267069517" + "Address": "14a2094e545ed162523c42376004f70d0c3266978c30eea8d42292ab15740b12" } ] } }, - "max_gas_amount": "3792915403161698018", - "gas_unit_price": "18055594279998178409", - "expiration_timestamp_secs": "7340711166730222471", - "chain_id": 19 + "max_gas_amount": "9620912920125864317", + "gas_unit_price": "14042300254469599944", + "expiration_timestamp_secs": "17916949931666593283", + "chain_id": 248 }, - "signed_txn_bcs": "3ab5d68b68ed89bf848d18b846c9d77f937b1eceeea9d58269fdb64058f2f7dd21e87c1ecd4534200003a2d327040791d7edbeb1fe9298b472df0df8925715ec4f5c41f41f5739506d184be3731d291c6e636249796c734a4356667649547244777071766d7255476a7a4f4a14547873554d664e4b4f6161734f4f7276717844730007ae67cb655eeecad53b5b8098a960de679231146ecf2b1f0a7a25baaa521ea9721d4b7041484f5157486970584d56706342726a6a6c574a5555764b566e6317535945464961424c5371676f48664b556153734e5170310006077861be3b3dc94521f69aa59f604bd909645d5918ef65f4bd8b5eeddab04cde771749577a6357636761486b584970556f47534e5141594a431458676a7777434d65436a5a4f49416a7a42686d520007e5f0c4ba30c9f3b202f89df6f219e04e1ed679c88c0c0340402fd2abf1b43b9f1c456b666743624c7047765242684c77705776714b75677a4f524b5958066b64727079320003040cb7cdcafaf1e34289954f97d00123a84b6cef29582e024daa96c67436b0a94ccd65264dd72e45e27e8fa47624a33469c4ddc3555b92fa87bbb2d3e971df6513002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444039fc5505d8b250e77b8873ccb2c18f011c2d5601612c5b3e488edeb31881b67b3ba0d262b827012bfe386dfab53ac02fb2ea197a4070e7f20dd5f3ecfacbbc05", + "signed_txn_bcs": "55d48685b2e28ae850e0c7ec5e50756af7f0cf20f9e0cc734999fa0fba10540e03eb9b3269edc5c2000d3b4681e86cd00c7c4b7bb37abf0807a77112200b7a7e70d46bdb71cdfa8f3582335d53c1a30f734be93b2162b5f7991e797061725266666c4c6c74566a416267765342415a4b774e754a4c464d3716796456417168634c45764e7261726b594656597a643700076cc792b9697bcd56e1532e160f61121700ad716eb3880d25407467cffed2a52a0c56614849776576496c4a4e471461516b575447536a4c6c4a6365426f574d647a44000606020607690011fadcf792cbce96f3a3af338607450e2fe51c774179fbe5afd97ae22fc61145596a4164734e6e56536951784f576c612176686c436f644a61426e6f664a5150666d4b4242765a4667786d74494e7a6565330006040607a0d383ad939f339ee5e8ebccfcc36750907e6a78cf5a2701fb1cd5b5e4fdeb97196a70484b6c614d4969535a796354414f46544a6f4e656663501865776b4d4e6c6f464e66576b54466172654e6b6a6967414e0007a50bb672641f816eb024d9790d5856a8e626da7073510806ba70dff951929db40961644c63557858633712484a4d46584b5055797878794158476b64300007ac1141d7d4fe13222145d87b1e65d2afcc3e5ac172a8423a1378559228fc10500a47725a784d7a524d74740e57594d6d6d45796c46444a4d5137000a025f34fa4dbff80e2aae2c8f553fbd0d4a027ad1233fca8fe39cafc24ba3aeb62af20407d8fc2d0dd6c05001156c17f2366adb61040e10cb07ad8ce6dbba052b19b82b3e0134cc110fc2e6798f040911f627bee202b811a101b3658cc3a7213bfe01e17c30f22f05ee150314a2094e545ed162523c42376004f70d0c3266978c30eea8d42292ab15740b127d7911bb53598485c8b209a1ae45e0c2035672e708cba5f8f8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444077668cf5a746e704526dcdfa6677fa891dc634a22a87c788560d4c38cafa8cde39a294570dbab42ad3a42f67bee5625c5134d1cd7eec688a35c7b7a5933bd802", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "7356f4b0079984a3e1194582e8bffdacd5a164c5d77ef09abcc4f1fd5af99b60", - "sequence_number": "5825701095339355035", + "sender": "102cd984b63283aaf4e39ae449ba3dc83fece8fba3f83da5778ea0a3810843e3", + "sequence_number": "6989147576989387327", "payload": { "Script": { - "code": "649a", + "code": "cfa8309dbbb2bb91", "ty_args": [ - { - "vector": { - "struct": { - "address": "60eb5719c967063d38367d3ee3c38e4435e13ddd24862fdeb93f44ab31a10e62", - "module": "kGRTOIkFlJuGesgMiY6", - "name": "dGyjsgZzYdTnKxMMpfflRlhHZBRIga2", - "type_args": [] - } - } - }, { "struct": { - "address": "5de474aa4008092f002e28521c3efff6448d6887c07d0198c3382e17bf1fe70c", - "module": "MgfVFLXwuQJfLMbrchhUZrjUHV", - "name": "ytcmdICmreIzHWOKDpvQGas", + "address": "2409a98e42ff9b359d6bac28a56c0d738d81cc27e8357c0c65f582877ad269d5", + "module": "DYwVIlpghJXkOk5", + "name": "WqFPz4", "type_args": [] } }, { - "vector": { - "struct": { - "address": "ba824a6d89ef327ba374de0b1d50ee19a828042e4141d15929a8f351417178fe", - "module": "hzdlfHqYXOVFdTvTnLis", - "name": "LzJOGGrlXgXSrGyNGJBwVlcUiSFrTdnV9", - "type_args": [] - } + "struct": { + "address": "027885b9be806599b0bef97dedc23022df50077e22741c578f2a9d6dbd328d1f", + "module": "SoDEckgcxhnGYRYnZWOQrmPOV1", + "name": "bwlvltwI", + "type_args": [] } }, { - "vector": { - "struct": { - "address": "e76ead5c5c0d44a1b1abe493b3e3502bd74d03fa50891661e099ad4fd0bf034a", - "module": "HXykC", - "name": "YvbPrbLBXTGRHyPAWtEkrFi9", - "type_args": [] - } + "struct": { + "address": "618ddc10915377f6d7cf87e08645e2be5594bcb94e4845da3d4ca5a8624bcf0a", + "module": "KnjpUsiGqik", + "name": "nngIJlYQOLgZZrYtPFOXSyhcMW", + "type_args": [] } }, { - "vector": { - "vector": { - "vector": { - "struct": { - "address": "03b8a0e0dde1db9d42a874a367381effa55cdf94abec15c19baec5fcea039946", - "module": "iNKaBNSss7", - "name": "yzCwMydKUOUQJzRxKeBPFcsg1", - "type_args": [] - } - } - } + "struct": { + "address": "44e167ba4ba8e4f494cc083f7d4832ad57ac9cf0bc578ceb1262044cf376ffa5", + "module": "leOBGBQY6", + "name": "eXDczwTswaFnQiLtEMEGzcm0", + "type_args": [] } } ], "args": [ { - "U64": "11197693848083373671" - }, - { - "U8": 228 - }, - { - "U8Vector": "37bdcbb4aebfd3dac0ed5fbf9eddda05" - }, - { - "U128": "255703811106046701869778741362779795070" - }, - { - "U8Vector": "bfcdd9bcf8923ea154b5610e76febb9d" + "U128": "243664118736732188932597356670613141623" } ] } }, - "max_gas_amount": "1627589315093971743", - "gas_unit_price": "14878407516917835187", - "expiration_timestamp_secs": "849845923837689512", - "chain_id": 225 + "max_gas_amount": "3085025885905844913", + "gas_unit_price": "2386665543726565458", + "expiration_timestamp_secs": "5818427994280985010", + "chain_id": 65 }, - "signed_txn_bcs": "7356f4b0079984a3e1194582e8bffdacd5a164c5d77ef09abcc4f1fd5af99b609b6b4ec3470cd9500002649a05060760eb5719c967063d38367d3ee3c38e4435e13ddd24862fdeb93f44ab31a10e62136b4752544f496b466c4a75476573674d6959361f6447796a73675a7a5964546e4b784d4d7066666c526c68485a42524967613200075de474aa4008092f002e28521c3efff6448d6887c07d0198c3382e17bf1fe70c1a4d676656464c587775514a664c4d6272636868555a726a554856177974636d6449436d7265497a48574f4b44707651476173000607ba824a6d89ef327ba374de0b1d50ee19a828042e4141d15929a8f351417178fe14687a646c66487159584f5646645476546e4c6973214c7a4a4f4747726c586758537247794e474a4277566c63556953467254646e5639000607e76ead5c5c0d44a1b1abe493b3e3502bd74d03fa50891661e099ad4fd0bf034a054858796b43185976625072624c4258544752487950415774456b72466939000606060703b8a0e0dde1db9d42a874a367381effa55cdf94abec15c19baec5fcea0399460a694e4b61424e5373733719797a43774d79644b554f55514a7a52784b6542504663736731000501671e96163a33669b00e4041037bdcbb4aebfd3dac0ed5fbf9eddda05027eaef84c38be134351647b5c3ec35ec00410bfcdd9bcf8923ea154b5610e76febb9d1fc365d6db5b9616b3a563b5ceb87acea8be28745d42cb0be1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409271b625cb4f49d2f8f3df871138d4740266ff8d1d10d480db2bd0890d80d9b20f947268bf9ca7fea70824ed9e2bbc4bc58ee0fbac2954d538e85e7bdf904500", + "signed_txn_bcs": "102cd984b63283aaf4e39ae449ba3dc83fece8fba3f83da5778ea0a3810843e33f0a3cf1b070fe600008cfa8309dbbb2bb9104072409a98e42ff9b359d6bac28a56c0d738d81cc27e8357c0c65f582877ad269d50f44597756496c7067684a586b4f6b3506577146507a340007027885b9be806599b0bef97dedc23022df50077e22741c578f2a9d6dbd328d1f1a536f4445636b676378686e475952596e5a574f51726d504f56310862776c766c7477490007618ddc10915377f6d7cf87e08645e2be5594bcb94e4845da3d4ca5a8624bcf0a0b4b6e6a705573694771696b1a6e6e67494a6c59514f4c675a5a72597450464f58537968634d57000744e167ba4ba8e4f494cc083f7d4832ad57ac9cf0bc578ceb1262044cf376ffa5096c654f42474251593618655844637a7754737761466e51694c74454d45477a636d300001027738abddc36e73e9c9ccb36c940050b7b17a4db4b236d02a52887cbbaa231f21b2814ef66e35bf5041002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444064017db6a013179c1864a9fc1f240b4625ca7b609195de38a27348217ecd1378648d614eea403e43f7df31ba76a11a83b434c67456b429aed29caf7cfb1a2b0a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "6f4d44b6b0364d5280348a056e2f613f6f5a5f8d80500ea3955f6b8528213c8e", - "sequence_number": "4844760987894299668", + "sender": "f04944a59d7219321ee03823407c03e4a378b0e32dbb6a9f91eed4c69d424ab4", + "sequence_number": "17678564563898859448", "payload": { "Script": { - "code": "8af4d7a74f6f100f4f73aef7", + "code": "14fb14", "ty_args": [ { "vector": { "struct": { - "address": "6f968802b0807dc58df080ed68118e9eb1aba512d47f3ca4cb806138ca83c3b0", - "module": "cttxYpFecKCcpI5", - "name": "vuUkNkWkLHXrmoE8", + "address": "5548612ae2e52b8e606750eff79ddaa364607917639aeb216515c72464362ac4", + "module": "nuuGXoJlvZCHctUzhxQbacxhEEBwz8", + "name": "irzsOebDyNcfGFixkKLEgFJwchyffmWY3", "type_args": [] } } }, { - "vector": { + "struct": { + "address": "c131e320d8b96857e4dd2187bb4358b4ccd7db4e9ad8e472b8de3dc286899d6f", + "module": "vWc", + "name": "nchvFt", + "type_args": [] + } + }, + { + "vector": { + "struct": { + "address": "54ba2751dfc8f8bbd6ce1dcc5abf40f2199cace04460b5a9f5e899a20f4df6a8", + "module": "wyZTdnOZs5", + "name": "YYmgQtzRsaXfvNrBt8", + "type_args": [] + } + } + }, + { + "struct": { + "address": "d35815011368a2e142bc4427ae3239440c2d534a6f15193c68354f2e967e1de1", + "module": "BsTimRbxCmRQuToEMTjxN6", + "name": "hd4", + "type_args": [] + } + }, + { + "vector": { "struct": { - "address": "145a0cbecc2ddcce76c624c283d1a252b6d95919f8f7cdf3bd0a09ccc165efe9", - "module": "PUdGh8", - "name": "ljgkFE", + "address": "170ddf074dd5a2def30b80b88890a5e1a10fdc3ba6a74735082d28b14a9ed23b", + "module": "myPlcSTjHkqIsqkVtaJYbrHIdEiw5", + "name": "YUSKQadMheiDFGDwKdHtykBJFXKW", "type_args": [] } } }, { "struct": { - "address": "b3c903dbfe0c0f03f552a106e60f127d430627e4756164ffe5b55a6c09a12f66", - "module": "OkgVxgFYYeJBeSPKaBojVI", - "name": "GrumAkFtkIRmoneMFaJCXTWiktteFnGz", + "address": "34475e87effa7803de00fec92afd9893cb50f91e263df58084a4f2b1811f6cc4", + "module": "HrQuRQZtHSdqhdTGzBBaGwosgGFY", + "name": "Naf", + "type_args": [] + } + }, + { + "struct": { + "address": "18c257269086e72ed05eef67e76903ce78c388f50a66c91f968209e7139bf930", + "module": "ZHTpmyszyizbuUSTUBEJFiuUJElW", + "name": "czDhpk6", "type_args": [] } } ], "args": [ { - "Address": "6050cd12df115d42f559590784243cfd6d24b2987617c278e967842f650751e5" + "U64": "3553575050996659418" + }, + { + "U64": "4975158244011507856" + }, + { + "U8": 35 }, { - "U128": "102656740297815742676618895381284238036" + "Bool": false }, { "Bool": false }, { - "U128": "175842861174649112373128126531069423702" + "Address": "946d9f4afb113a5a6ec3bba1076b399e476ab96483f415d4a287fd0328075418" + }, + { + "U64": "1472101799157070050" + }, + { + "U8": 213 } ] } }, - "max_gas_amount": "2403789431177497853", - "gas_unit_price": "14949880805531151743", - "expiration_timestamp_secs": "7114375590957426350", - "chain_id": 32 + "max_gas_amount": "10680405262183461876", + "gas_unit_price": "9452163127402016207", + "expiration_timestamp_secs": "2356159463261813315", + "chain_id": 2 }, - "signed_txn_bcs": "6f4d44b6b0364d5280348a056e2f613f6f5a5f8d80500ea3955f6b8528213c8e143c1c29730c3c43000c8af4d7a74f6f100f4f73aef70306076f968802b0807dc58df080ed68118e9eb1aba512d47f3ca4cb806138ca83c3b00f6374747859704665634b4363704935107675556b4e6b576b4c4858726d6f4538000607145a0cbecc2ddcce76c624c283d1a252b6d95919f8f7cdf3bd0a09ccc165efe906505564476838066c6a676b46450007b3c903dbfe0c0f03f552a106e60f127d430627e4756164ffe5b55a6c09a12f66164f6b67567867465959654a426553504b61426f6a5649204772756d416b46746b49526d6f6e654d46614a43585457696b747465466e477a0004036050cd12df115d42f559590784243cfd6d24b2987617c278e967842f650751e502d4b263f94872640e834e044111f83a4d050002563066163b745515a44243496a1a4a84fd4c2c78c0f95b217f6d1d8062a578cfae26ba09e856bb6220002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444002f546f4eecbe607f697c87bd8ed96d690b0fe9221d5edb2501a6d761a2712d462103a5ecccbea9cb3c9e7fe0894eac1f7b503cff42c26a704c81a9da726a105", + "signed_txn_bcs": "f04944a59d7219321ee03823407c03e4a378b0e32dbb6a9f91eed4c69d424ab4b8ffff49cee056f5000314fb140706075548612ae2e52b8e606750eff79ddaa364607917639aeb216515c72464362ac41e6e757547586f4a6c765a43486374557a6878516261637868454542777a382169727a734f656244794e6366474669786b4b4c4567464a7763687966666d5759330007c131e320d8b96857e4dd2187bb4358b4ccd7db4e9ad8e472b8de3dc286899d6f03765763066e636876467400060754ba2751dfc8f8bbd6ce1dcc5abf40f2199cace04460b5a9f5e899a20f4df6a80a77795a54646e4f5a73351259596d6751747a5273615866764e724274380007d35815011368a2e142bc4427ae3239440c2d534a6f15193c68354f2e967e1de116427354696d526278436d525175546f454d546a784e3603686434000607170ddf074dd5a2def30b80b88890a5e1a10fdc3ba6a74735082d28b14a9ed23b1d6d79506c6353546a486b714973716b5674614a596272484964456977351c5955534b5161644d68656944464744774b644874796b424a46584b57000734475e87effa7803de00fec92afd9893cb50f91e263df58084a4f2b1811f6cc41c4872517552515a7448536471686454477a42426147776f7367474659034e6166000718c257269086e72ed05eef67e76903ce78c388f50a66c91f968209e7139bf9301c5a4854706d79737a79697a62755553545542454a466975554a456c5707637a4468706b36000801dab45865aed55031019080a93b10500b4500230500050003946d9f4afb113a5a6ec3bba1076b399e476ab96483f415d4a287fd032807541801e278f86bc9f46d1400d5f473a8adff6b3894cfadd7df48d42c83433ae5618cc2b22002002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fd58c08d34a8794a1f6e9023355517c14e65faf4899429b7d5aa37af0dbf2990ccc164992e27ffaf978bd60966ab4256b0837eacc0cb09e8fb5fd3efbab8f303", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "ac9d11d59e90d32cfa6a6cf2f3296aaabab1f1460834e7543f417938c32f0bba", - "sequence_number": "17045144598194283172", + "sender": "8813e338423594083097dae790b8298ff79ebe210c01bdf753851ad07f4a73da", + "sequence_number": "883909938445623171", "payload": { "Script": { - "code": "002f24e6f598be8ec1d90b80efaf2b", + "code": "47bf5924b313acea3c1b", "ty_args": [ { "struct": { - "address": "e6d3c74816d2075d551f68ed79b573f92f67003aa966964dd4b2eaefb967d2bb", - "module": "uvwrsmSEyCpez1", - "name": "nVfggJtBSwNN2", + "address": "0f9cf37c55747bb1c792cb59087b232e191e4057ce2a0e60219fd76aa2727b12", + "module": "ctKbufgZg", + "name": "MJ9", "type_args": [] } }, + { + "vector": { + "struct": { + "address": "4e7dd6d327e593895a471c9a7eaee5ac9caa420475a5e804a08325f4597526b9", + "module": "hI7", + "name": "mjRhNjEdGsCdWSIptjkizcWsRiLS", + "type_args": [] + } + } + }, { "vector": { "vector": { "vector": { "struct": { - "address": "cb9dae4e5ddfec806ce4807617a2bdd7521237eaf7648064623f967dba38800d", - "module": "nvkAUZBgBleALwFImFTRF6", - "name": "EX", + "address": "f5a5c4079dc5b103a11025b8e9eb1d444d0361d71267ba41799be42dbc539227", + "module": "Nby8", + "name": "SkQZqOCdfwqBZSOGmjd", "type_args": [] } } @@ -2920,162 +3011,212 @@ }, { "struct": { - "address": "5f205230891ca4e458ac9d67b74002fcb384a28371430f9a3e9cbbe06eeb70d1", - "module": "tYZGVlQRmnnvIZQyoZqFucKXsYsHI9", - "name": "wTD", + "address": "b35e1ff57ac16e8fb143bd40d36edf20fcfeeaef07571c776056c958bca8e107", + "module": "COCOnC5", + "name": "aRJlZqhgtcnpjpCZsAILebBkMuAfJbv", "type_args": [] } }, { "vector": { "struct": { - "address": "d8738bad7a1883e430352f1589a5a990b2bd2ca6bdfdbf5ca023205cf3926f15", - "module": "SFczufzEUMqrMdiABKkEHwBJYXjk2", - "name": "vKZSSDaxXccOhCVmYNZV9", + "address": "0a2a3345f3d04518b1537b19c66325c7d13edcbcacbab89fdd940b9ee4fe85c0", + "module": "qVvBPmsFWyCfjfGdDDOfcrBDgKpqmBlv", + "name": "WOVieUcQG", "type_args": [] } } }, { - "vector": { - "struct": { - "address": "711a5d37396334320fbe57df9fcbf5809fcb8b6999385207483dd9ced15eba67", - "module": "JHRjTCpxFienQUITRrrou", - "name": "sGjbRrwWJyGL", - "type_args": [] - } + "struct": { + "address": "2e610e8a0c1b5f2726282d661375e0918869067ef14b105f81c90e37f810e6ec", + "module": "jNdnBRwzwkvYGBEQMNY6", + "name": "BtNAxI", + "type_args": [] } + } + ], + "args": [ + { + "Address": "108ec586862e0bcbf21fee198922a90a126d58504682bc5c95880a530853d242" + }, + { + "Address": "7984fe4e8f8ae0aafd11107466d9a4fd419610697b5f6b71e7a928c8346159fe" + }, + { + "Bool": true + }, + { + "U64": "4545657304924097671" }, + { + "Address": "cdfd803a7f0da20361f7b25a9409ce99fda20d895948baf64ce531c4aea1c5c8" + } + ] + } + }, + "max_gas_amount": "7264225699521684428", + "gas_unit_price": "13411789687573686515", + "expiration_timestamp_secs": "6762716022413094369", + "chain_id": 241 + }, + "signed_txn_bcs": "8813e338423594083097dae790b8298ff79ebe210c01bdf753851ad07f4a73da831f7de66747440c000a47bf5924b313acea3c1b06070f9cf37c55747bb1c792cb59087b232e191e4057ce2a0e60219fd76aa2727b120963744b627566675a67034d4a390006074e7dd6d327e593895a471c9a7eaee5ac9caa420475a5e804a08325f4597526b9036849371c6d6a52684e6a45644773436457534970746a6b697a63577352694c530006060607f5a5c4079dc5b103a11025b8e9eb1d444d0361d71267ba41799be42dbc539227044e62793813536b515a714f4364667771425a534f476d6a640007b35e1ff57ac16e8fb143bd40d36edf20fcfeeaef07571c776056c958bca8e10707434f434f6e43351f61524a6c5a71686774636e706a70435a7341494c6562426b4d7541664a62760006070a2a3345f3d04518b1537b19c66325c7d13edcbcacbab89fdd940b9ee4fe85c02071567642506d7346577943666a66476444444f6663724244674b70716d426c7609574f5669655563514700072e610e8a0c1b5f2726282d661375e0918869067ef14b105f81c90e37f810e6ec146a4e646e4252777a776b7659474245514d4e59360642744e417849000503108ec586862e0bcbf21fee198922a90a126d58504682bc5c95880a530853d242037984fe4e8f8ae0aafd11107466d9a4fd419610697b5f6b71e7a928c8346159fe050101870ca9223c6b153f03cdfd803a7f0da20361f7b25a9409ce99fda20d895948baf64ce531c4aea1c5c8cce34044c9b6cf64f3a81382a93f20bae16dc65864fed95df1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a96fa35cbd5c9196a7e834f8f865c95fec3498ca284fe072db24f1f442e99d3b74cbc99e41b1391aa40adf68261ad862ba9cedcdfde9c0c202a35faf5628fa0a", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "606b67953fd5bcd590635954afc21b25200f72ffbf25284f16f40c21dd3d3bac", + "sequence_number": "635684488432411632", + "payload": { + "Script": { + "code": "66b9fd2abe3e9bcdba382fbfa987e0", + "ty_args": [ { "struct": { - "address": "0c3549e41757f92b07b1e8f554a03bfe834f6a6fef3bfc6cd1df2297f3e7ec86", - "module": "STGxMvmHCPnTQDfArZEUJIRHYeIyx1", - "name": "kGnAxyhSTgaGXpi7", + "address": "581a6fdb0efccd6d339b784c11275bd202869957ad6352440d9df40787eb433d", + "module": "bu", + "name": "aJ", "type_args": [] } }, { "vector": { - "vector": "signer" + "vector": { + "vector": { + "vector": "u8" + } + } } }, { - "struct": { - "address": "e845393a1b337f39dab3afc43de85c91ca35bcd2263c039dd3d438828eb1f98b", - "module": "AALTzBcsvKOWVbrp", - "name": "vsTcBBJcG2", - "type_args": [] + "vector": { + "struct": { + "address": "5d25089c677dae1abe0f4505f94e94c9e7de897efe9d9c7dc05bdf4b2a3a3f33", + "module": "NFjrjNiKoxasebpjq", + "name": "Vjapwn3", + "type_args": [] + } } }, { "vector": { "vector": { - "struct": { - "address": "f89325957cdda0d8080687e8074d3a480231f532c36baa3eb077c1a5787ce5dc", - "module": "CJOiux", - "name": "feXRrc", - "type_args": [] - } + "vector": "u64" + } + } + }, + { + "vector": { + "struct": { + "address": "e365a7c5904ad705c3a0f2d0d609af7cb5d60885becc7655715acd6f32d93297", + "module": "ScPAyaoNNKXjFyPJdCJPqCYycku", + "name": "UGuDwoWdXhthdJKNDVJXhl", + "type_args": [] } } } ], "args": [ { - "U128": "284647226096586039146447832453055478128" + "U64": "11338045746867582339" }, { - "U8": 42 + "U64": "10295715561298037260" }, { - "Address": "77773fab98855cf984b9f100ab2af513935cad2e59e03edca28fbea32bc1f9d7" + "U8": 168 }, { - "U8Vector": "fbb46a85632c2a448e16" + "U128": "221940221782822424795979897138330631780" + }, + { + "U128": "308553076537417435682747259167237353455" + }, + { + "Bool": true } ] } }, - "max_gas_amount": "8475223550754311714", - "gas_unit_price": "4050192680872727420", - "expiration_timestamp_secs": "7896248004655782942", - "chain_id": 183 + "max_gas_amount": "17928996185255220527", + "gas_unit_price": "5225265107742083515", + "expiration_timestamp_secs": "8444797716586235371", + "chain_id": 213 }, - "signed_txn_bcs": "ac9d11d59e90d32cfa6a6cf2f3296aaabab1f1460834e7543f417938c32f0bbaa4e289f8b3848cec000f002f24e6f598be8ec1d90b80efaf2b0907e6d3c74816d2075d551f68ed79b573f92f67003aa966964dd4b2eaefb967d2bb0e75767772736d5345794370657a310d6e566667674a744253774e4e320006060607cb9dae4e5ddfec806ce4807617a2bdd7521237eaf7648064623f967dba38800d166e766b41555a4267426c65414c7746496d465452463602455800075f205230891ca4e458ac9d67b74002fcb384a28371430f9a3e9cbbe06eeb70d11e74595a47566c51526d6e6e76495a51796f5a714675634b5873597348493903775444000607d8738bad7a1883e430352f1589a5a990b2bd2ca6bdfdbf5ca023205cf3926f151d5346637a75667a45554d71724d646941424b6b454877424a59586a6b3215764b5a53534461785863634f6843566d594e5a5639000607711a5d37396334320fbe57df9fcbf5809fcb8b6999385207483dd9ced15eba67154a48526a544370784669656e515549545272726f750c73476a62527277574a79474c00070c3549e41757f92b07b1e8f554a03bfe834f6a6fef3bfc6cd1df2297f3e7ec861e535447784d766d4843506e5451446641725a45554a495248596549797831106b476e417879685354676147587069370006060507e845393a1b337f39dab3afc43de85c91ca35bcd2263c039dd3d438828eb1f98b1041414c547a426373764b4f57566272700a7673546342424a63473200060607f89325957cdda0d8080687e8074d3a480231f532c36baa3eb077c1a5787ce5dc06434a4f697578066665585272630004027079abb6747475435f34be27c70f25d6002a0377773fab98855cf984b9f100ab2af513935cad2e59e03edca28fbea32bc1f9d7040afbb46a85632c2a448e16224ebc6eea0a9e757c534ecfc82c35381e1ce55fb91b956db7002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440aa60a79ba27eaf939538d2afbc13b877c40789d4d93e564827f7dad43ce635d3ff78392055e39eb811667d4db73ff6307b79bb376a22d33d40548dce0f955705", + "signed_txn_bcs": "606b67953fd5bcd590635954afc21b25200f72ffbf25284f16f40c21dd3d3bacf0633d9aac67d208000f66b9fd2abe3e9bcdba382fbfa987e00507581a6fdb0efccd6d339b784c11275bd202869957ad6352440d9df40787eb433d02627502614a00060606060106075d25089c677dae1abe0f4505f94e94c9e7de897efe9d9c7dc05bdf4b2a3a3f33114e466a726a4e694b6f7861736562706a7107566a6170776e3300060606020607e365a7c5904ad705c3a0f2d0d609af7cb5d60885becc7655715acd6f32d932971b5363504179616f4e4e4b586a4679504a64434a5071435979636b751655477544776f576458687468644a4b4e44564a58686c00060183b52b0589d4589d010c8aa103c1bae18e00a802647e2ae1b3349ab686de352bc421f8a602ef2f9e055146502c932fae41342921e805012f9578e10997d0f8bbc9354ceede8348eb0527e1c7f23175d5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b0c53825ee0c782f397a2a4a3d6a2853ad245307418f7cdcd2ded0033f46f09cdb297050dcd07c0e41dd9f5c399405f42235083b320c0efcd584996a3f7b4d03", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "25cefe006c9ca9bd117dd7f5a077e292edbd27c1b4ad87fd29d7552008c090c6", - "sequence_number": "785122008010187244", + "sender": "c67d986d9ed7b80ae86f530c10cc588a8415ce913b734ee17c9600e227f71d99", + "sequence_number": "12734893865027769132", "payload": { "Script": { - "code": "24202989b6ec491eed87639e", - "ty_args": [ + "code": "add7d1368f074746bddbfdee0b89c7ae", + "ty_args": [], + "args": [ { - "struct": { - "address": "dd9f9dcf6d644ace56538e6a43d02b0df83edb2dd02e23796438b5eeb5175dc2", - "module": "NPsFZEDmmDPytSMirI1", - "name": "HwBDpWDw2", - "type_args": [] - } + "U64": "3993307104017215887" }, { - "struct": { - "address": "abc4c28533297f50800f801c4c3454230bc1f869c3d7d145b0fca6ff15a68844", - "module": "oZVwmtVbYjriLjXyjPCuvLSqmntaUf3", - "name": "CkilJFHtbTydXWOERH6", - "type_args": [] - } + "Address": "10a12d6e5a1247574e2b4497195d8b3c5c1c5333728455360bd13544e96b84e3" }, { - "struct": { - "address": "4019770c56b353b2804f8cafd71203409a5d43754a2bebb9f4ac2208d19e3d54", - "module": "meYNtGwIZIiopiVXv3", - "name": "VsnkvpMYUfIu3", - "type_args": [] - } + "U128": "153769828724711268800887548148281294368" }, { - "vector": { - "vector": "u64" - } + "U64": "9501229679438455053" }, + { + "U64": "13382853789626215589" + } + ] + } + }, + "max_gas_amount": "8365807898758044472", + "gas_unit_price": "10594160532785386233", + "expiration_timestamp_secs": "16173895361808194721", + "chain_id": 90 + }, + "signed_txn_bcs": "c67d986d9ed7b80ae86f530c10cc588a8415ce913b734ee17c9600e227f71d992c1348757f6ebbb00010add7d1368f074746bddbfdee0b89c7ae0005018f71fd55a7136b370310a12d6e5a1247574e2b4497195d8b3c5c1c5333728455360bd13544e96b84e30220be5c1262f0e97554d10889e4fdae73010de153c40d26db8301a52ca9c39d72b9b9385ba1c0f5511974f9d222d2df040693a15cea7a233875e05a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e8b1b2fe0c18f7de9cfeab8eded2384a6fb995d0909fb9aa703412abdc1f14ce50b9f4f7dcff0f84c47e8b7cfee611d29708381b0df306ccbd48d1ec3b80c500", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "8de3d2fe69f9040114f0eddc73809b7581ea3d959407d2792afcbe98bab628c3", + "sequence_number": "3828648834406245551", + "payload": { + "Script": { + "code": "57f5", + "ty_args": [ { "vector": { - "struct": { - "address": "165942394b3c9dc32cdd8f4c65e17f1368d8b66ec15047a8a2d14ed31537d3ed", - "module": "tBkNENjdeSZtxlKu", - "name": "XWbKlhUtSbTOswWZfmqaApuglbiyKcw1", - "type_args": [] - } + "vector": "signer" } }, { "struct": { - "address": "9d2bd0c6dade5ffea765fe0bf0579196f3e6bf1a96eb5b572e0edbc5c65379a4", - "module": "FwesGYZCbTliAUw", - "name": "pjeHRSAUYHApNZR5", + "address": "63703c2e33d4cadfd457455fdd1ab4e5e20ea579d802da8a0a6ea1495e03b517", + "module": "fVpCXJbmKsAkzFPxZMmZkOozszfFIMI8", + "name": "jE4", "type_args": [] } }, { - "vector": { - "struct": { - "address": "33e754710707eb1ee41fa64c0d023e930e2198e3da5e297c979cff522678c90b", - "module": "OJcldGQCHS0", - "name": "AY8", - "type_args": [] - } + "struct": { + "address": "824c7e1321aca36efa9fba391ea26ea528165784a2199bfb50e4003a6e86d650", + "module": "uWJPJeoHBziRFFEeWDrVw8", + "name": "haRpDqZKKnpqhMBJQoSg", + "type_args": [] } }, { "vector": { "vector": { "struct": { - "address": "06f229a29a6e0cc0a43bf0115452580f9a7a2a5e2a6250b96ef4caa647dcefa4", - "module": "XcHzmgRqxEOeCRMRFgUbvLu7", - "name": "JPMDcmZYW0", + "address": "93456813ba68b80a7820875fdf6a5f2a9545db09460259fa80f41bf5e3307b7e", + "module": "VMogcuxZyVjVPjOhJpI7", + "name": "bekDGQcqWHF6", "type_args": [] } } @@ -3083,280 +3224,224 @@ }, { "struct": { - "address": "a68e684afed1c64cc30f76b6fe12ad5542dcc58539e6859a7ffd9929d33710fe", - "module": "sEpQncZWVLBuOHUgFBsaZcrqdB8", - "name": "MbfUqumYoMKuKrPKIGtsWrkcvKwLk2", - "type_args": [] - } - }, - { - "struct": { - "address": "d7e3fe63ae985a31c221390159a166d65ebb5048fa7f53ef9e010102386ad3d7", - "module": "KLSHfHnHsvFRSaknh", - "name": "YhIbxVeETPuEVhdY", + "address": "4722bc99a0a02f3ae3d09eb8db371a9abd8ec5f334528d51f60704484a73786e", + "module": "wbtFDSnTSLd0", + "name": "cegRVREmWRsdHRmWiBvCzw9", "type_args": [] } } ], "args": [ { - "U128": "310313545942415089976197901925240488815" + "U8": 200 }, { - "Bool": false + "U64": "8105345358869507537" }, { - "U8": 22 + "Address": "709de7e77078e3ecaecdb23abe1148f35976ea3d4378b9aca4da1413fc167f30" }, { - "U128": "110281736843605731954589936240845032401" + "U8Vector": "27b1d4f7ce5f1720fe" }, { - "Address": "5b21e40515a52e64b51768b646fb8824c6c46ee6c0676f800eb960edfbc95e2d" + "Bool": false }, { - "Bool": true + "Address": "3fdda215dcd84b12ae3b39d38cb23c20e8e3d58a4c2d1dec6c0210f962816f5e" } ] } }, - "max_gas_amount": "715937801192525421", - "gas_unit_price": "8582137578423854300", - "expiration_timestamp_secs": "15275376885070959758", - "chain_id": 18 + "max_gas_amount": "11653455633830677408", + "gas_unit_price": "1884770236608181706", + "expiration_timestamp_secs": "5018182781233168552", + "chain_id": 157 }, - "signed_txn_bcs": "25cefe006c9ca9bd117dd7f5a077e292edbd27c1b4ad87fd29d7552008c090c6ece1c9784e50e50a000c24202989b6ec491eed87639e0a07dd9f9dcf6d644ace56538e6a43d02b0df83edb2dd02e23796438b5eeb5175dc2134e5073465a45446d6d44507974534d69724931094877424470574477320007abc4c28533297f50800f801c4c3454230bc1f869c3d7d145b0fca6ff15a688441f6f5a56776d745662596a72694c6a58796a504375764c53716d6e746155663313436b696c4a4648746254796458574f4552483600074019770c56b353b2804f8cafd71203409a5d43754a2bebb9f4ac2208d19e3d54126d65594e744777495a49696f7069565876330d56736e6b76704d595566497533000606020607165942394b3c9dc32cdd8f4c65e17f1368d8b66ec15047a8a2d14ed31537d3ed1074426b4e454e6a6465535a74786c4b75205857624b6c6855745362544f7377575a666d7161417075676c6269794b63773100079d2bd0c6dade5ffea765fe0bf0579196f3e6bf1a96eb5b572e0edbc5c65379a40f4677657347595a4362546c6941557710706a654852534155594841704e5a523500060733e754710707eb1ee41fa64c0d023e930e2198e3da5e297c979cff522678c90b0b4f4a636c64475143485330034159380006060706f229a29a6e0cc0a43bf0115452580f9a7a2a5e2a6250b96ef4caa647dcefa4185863487a6d67527178454f6543524d5246675562764c75370a4a504d44636d5a5957300007a68e684afed1c64cc30f76b6fe12ad5542dcc58539e6859a7ffd9929d33710fe1b734570516e635a57564c42754f485567464273615a6372716442381e4d62665571756d596f4d4b754b72504b4947747357726b63764b774c6b320007d7e3fe63ae985a31c221390159a166d65ebb5048fa7f53ef9e010102386ad3d7114b4c534866486e487376465253616b6e6810596849627856654554507545566864590006026f4333241b8ff4447a0255120c3774e90500001602d18b3a9edacbb3381497b9176c7df752035b21e40515a52e64b51768b646fb8824c6c46ee6c0676f800eb960edfbc95e2d05016dce5a11a385ef09dc247c4fa8e019778e14de34580afdd312002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409e9e88676c5ba1093cb10cd9332f60cf6f7cd3a99a08fb0dda1765ed0821a739d2b41f23f4ee24c62a992a32c8896a1175a82ffc51d37db474aa1e4e84410209", + "signed_txn_bcs": "8de3d2fe69f9040114f0eddc73809b7581ea3d959407d2792afcbe98bab628c3af647f70d4172235000257f5050606050763703c2e33d4cadfd457455fdd1ab4e5e20ea579d802da8a0a6ea1495e03b5172066567043584a626d4b73416b7a4650785a4d6d5a6b4f6f7a737a6646494d4938036a45340007824c7e1321aca36efa9fba391ea26ea528165784a2199bfb50e4003a6e86d6501675574a504a656f48427a695246464565574472567738146861527044715a4b4b6e7071684d424a516f53670006060793456813ba68b80a7820875fdf6a5f2a9545db09460259fa80f41bf5e3307b7e14564d6f676375785a79566a56506a4f684a7049370c62656b44475163715748463600074722bc99a0a02f3ae3d09eb8db371a9abd8ec5f334528d51f60704484a73786e0c7762744644536e54534c643017636567525652456d5752736448526d57694276437a7739000600c801d12d47f1a8f87b7003709de7e77078e3ecaecdb23abe1148f35976ea3d4378b9aca4da1413fc167f30040927b1d4f7ce5f1720fe0500033fdda215dcd84b12ae3b39d38cb23c20e8e3d58a4c2d1dec6c0210f962816f5ea08b40042864b9a1ca7542548b0c281aa88062eda62aa4459d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444059be01c9a11afad4448736ffa9caa6ec855b1dd11f7d89e9ccf4b064ad5bbb9f25e7a81f72eda1389369dcafef6f7ff0b51a7531e8a276a8f529c58f314b5608", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "8e1ebc9679e32f24bf90850c31f83d681ad1138e7ad91961c4bc15ddc584efb5", - "sequence_number": "1531774979442275390", + "sender": "c381ee15c7a6a1e5520ee0dde78ab9c344e1228ecb1c670d25ed351892caf395", + "sequence_number": "15924010228039490380", "payload": { "Script": { - "code": "6647c660dfe07df5", + "code": "39f4174e0ac563", "ty_args": [ - { - "struct": { - "address": "e85db5cc8bd732701cb1d040e92b9df1376955b9d0da539e05159f32d100facc", - "module": "MSuNqwhNEfGvb1", - "name": "yrCDYUlDqeQwcxiGDlU", - "type_args": [] - } - }, - { - "vector": { - "vector": { - "struct": { - "address": "cb8cbf9c51e07a54be472f2639b172a6a91347b1621fd2547add7bd01a77964a", - "module": "cRsKxkleYYGYIisHe", - "name": "gvKMPUxXqFaAEGdFWmaleJi", - "type_args": [] - } - } - } - }, { "vector": { "struct": { - "address": "08d8987cee18bc8dbf51fca7ff09d60c29fc3a62b0658da52ebed8e794f67a58", - "module": "msHSoLYCBEsGvZGklcLfZdzFk", - "name": "QPaKwoJP", + "address": "1880c10dab40d056304a33b372bfbeb565f31f0434bff5dead9327460f7949f5", + "module": "sED", + "name": "rERUJKqfEvpeRpGWKGo0", "type_args": [] } } }, { "struct": { - "address": "28cc7d7defb0995a4a090dea42606751838e9d0d38071243b39e29c7e1f89a96", - "module": "hM", - "name": "qCGyqsVCxrRvuXGoup", + "address": "c47a106ea9f4bb0e6de0e5260779cbb5ca0d53aef66fb374ba6975a2648c8796", + "module": "hdN8", + "name": "zGbptcNRsthDJBdkGGeUtOfqdZN", "type_args": [] } }, { - "struct": { - "address": "af3328043fa96fef86dede6fc3c1ff4827638c8d85a408facc72c86c87d7ed27", - "module": "QxZMIOIyCytpMMBTw", - "name": "wfXdyMbiDCXjzRZVwtEqntfyGwoCP", - "type_args": [] - } + "vector": "signer" }, { "vector": { - "vector": "bool" + "vector": "u8" } }, { "struct": { - "address": "dfb50f6666fa7249fb853ad6286362bdb79cabefe60d16756275deabcaa2f8bd", - "module": "mbtFxPaFhGrQomAPnKYtNewWqyFToL7", - "name": "LXAQqWK7", + "address": "30738ea0c6caee779663874e581bfabcd474b26b1475ebcf0ec995645fb4eac2", + "module": "ROpQpcZNdyryWoRuAqIbYxMo", + "name": "JDRVAMdWxU2", "type_args": [] } }, { "struct": { - "address": "51802da9a7b1d550b52aee82be61055a519fdc29bd702f115aef5e7f2a133dae", - "module": "hiYjzzDVIGGLJfGfreSwBZ", - "name": "EmUJztlpNLToECb3", + "address": "fb48e4c94ebbabd71c188bd193302764cc0228159d16a1430c1b03f830137c33", + "module": "sYzGzBJOn", + "name": "ziIAzfBYeWezEvYoJNTShHFMz", "type_args": [] } }, { - "struct": { - "address": "272d0814aacf69e4748d140c8b4a2a339192246afe8a0cfb1fb57e6c6bd7efc8", - "module": "sbQzUs", - "name": "sdKfYtgxFC", - "type_args": [] + "vector": { + "vector": { + "vector": "signer" + } } + }, + { + "vector": "bool" + }, + { + "vector": "signer" } ], "args": [ { - "U64": "14152186213602291517" + "U128": "67228802430822539503780027228672268104" }, { - "U128": "194960027815502236621641780540778789210" - } - ] - } - }, - "max_gas_amount": "11270702748945352126", - "gas_unit_price": "16393096032874889482", - "expiration_timestamp_secs": "15583782261484208381", - "chain_id": 147 - }, - "signed_txn_bcs": "8e1ebc9679e32f24bf90850c31f83d681ad1138e7ad91961c4bc15ddc584efb53ef47c653af5411500086647c660dfe07df50907e85db5cc8bd732701cb1d040e92b9df1376955b9d0da539e05159f32d100facc0e4d53754e7177684e456647766231137972434459556c447165517763786947446c5500060607cb8cbf9c51e07a54be472f2639b172a6a91347b1621fd2547add7bd01a77964a116352734b786b6c655959475949697348651767764b4d505578587146614145476446576d616c654a6900060708d8987cee18bc8dbf51fca7ff09d60c29fc3a62b0658da52ebed8e794f67a58196d7348536f4c594342457347765a476b6c634c665a647a466b085150614b776f4a50000728cc7d7defb0995a4a090dea42606751838e9d0d38071243b39e29c7e1f89a9602684d127143477971735643787252767558476f75700007af3328043fa96fef86dede6fc3c1ff4827638c8d85a408facc72c86c87d7ed271151785a4d494f4979437974704d4d4254771d77665864794d62694443586a7a525a56777445716e74667947776f43500006060007dfb50f6666fa7249fb853ad6286362bdb79cabefe60d16756275deabcaa2f8bd1f6d62744678506146684772516f6d41506e4b59744e657757717946546f4c37084c58415171574b37000751802da9a7b1d550b52aee82be61055a519fdc29bd702f115aef5e7f2a133dae166869596a7a7a44564947474c4a66476672655377425a10456d554a7a746c704e4c546f454362330007272d0814aacf69e4748d140c8b4a2a339192246afe8a0cfb1fb57e6c6bd7efc8067362517a55730a73644b665974677846430002013deff13861aa66c4025ab9f4bb6b97f6bb3c74266480efab92be05e8776f94699c0a815fd0fcf97fe3fdc0cc8066b744d893002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402df284e8a7025ab59f860da3779572d9bf63fa86e0d839823d2f6ce47e21ecb0f8910a1f96c25c1689f1c587fbb124cdbe1ad93c3e23ef8ade4ed2140ada620f", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "fcd3a9fb8963cb187eed9d8581333546177e293deed637ef97802236473fa440", - "sequence_number": "13958774376282326110", - "payload": { - "Script": { - "code": "f80aaf8624857dc2f9fa8a3e863b", - "ty_args": [ - { - "vector": { - "vector": { - "vector": "u64" - } - } + "U8": 51 }, { - "vector": { - "vector": { - "vector": "u128" - } - } + "U8Vector": "37dcce" }, { - "vector": { - "struct": { - "address": "843482b5610852e35f9995228da20880d6d1add2491d176ec28c940d59dbb74a", - "module": "XtghGaCEIONXYfcNzsXBdOrTaPQ3", - "name": "toJTykVmQtBiQGThlPSCQVJPuA", - "type_args": [] - } - } + "Bool": false }, { - "struct": { - "address": "15242f488fd3aafea900f66c6ff7239c648cd5f1fa3052d503c529b787b862a6", - "module": "wsKXPOscMrkDZhLk", - "name": "Sqlzdbydoir3", - "type_args": [] - } - } - ], - "args": [ + "U8": 58 + }, { - "U8Vector": "8aeccdd8bdc1fced28" + "U8": 84 } ] } }, - "max_gas_amount": "2987791653114619784", - "gas_unit_price": "2432473712390999682", - "expiration_timestamp_secs": "4367410872703778418", - "chain_id": 116 + "max_gas_amount": "1017335802261363768", + "gas_unit_price": "4706034258846139448", + "expiration_timestamp_secs": "1664197215799409446", + "chain_id": 5 }, - "signed_txn_bcs": "fcd3a9fb8963cb187eed9d8581333546177e293deed637ef97802236473fa4405e0422a65687b7c1000ef80aaf8624857dc2f9fa8a3e863b0406060602060606030607843482b5610852e35f9995228da20880d6d1add2491d176ec28c940d59dbb74a1c5874676847614345494f4e585966634e7a735842644f7254615051331a746f4a54796b566d51744269514754686c50534351564a507541000715242f488fd3aafea900f66c6ff7239c648cd5f1fa3052d503c529b787b862a61077734b58504f73634d726b445a684c6b0c53716c7a646279646f697233000104098aeccdd8bdc1fced288827c6b2adc47629828e8a20f4e1c12172feaf970c299c3c74002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bed079a278c90b2d87d7c3e491aeb2bde5b466d07a3677ae1c684e0e72ce62838ae7d10c74d71da91a4040288bf377d86037a3f9c2104086d0954fa724f1230d", + "signed_txn_bcs": "c381ee15c7a6a1e5520ee0dde78ab9c344e1228ecb1c670d25ed351892caf3954c1bfbf1ee72fddc000739f4174e0ac5630906071880c10dab40d056304a33b372bfbeb565f31f0434bff5dead9327460f7949f50373454414724552554a4b716645767065527047574b476f300007c47a106ea9f4bb0e6de0e5260779cbb5ca0d53aef66fb374ba6975a2648c87960468644e381b7a47627074634e52737468444a42646b47476555744f6671645a4e0006050606010730738ea0c6caee779663874e581bfabcd474b26b1475ebcf0ec995645fb4eac218524f705170635a4e64797279576f52754171496259784d6f0b4a445256414d64577855320007fb48e4c94ebbabd71c188bd193302764cc0228159d16a1430c1b03f830137c330973597a477a424a4f6e197a6949417a6642596557657a4576596f4a4e54536848464d7a00060606050600060506024897807e8088897ca1437e14dfcb93320033040337dcce0500003a0054385c13a7854d1e0e38c4578b39314f4126fbeaeb8c6a181705002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fbb546e7dcf26ad5f04cf8ab5f2526f14f760209473c8550095686c1e0b1052f2d4c82f677f295091847f060d244b11f5dedc4acb732df1944160ab747fec10d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "8c5db5d33a1df20826b289a2ca85ece7419a15e58af4d382ab492d6aa625c4eb", - "sequence_number": "1090973585839028943", + "sender": "4d50f4c12e01baae7f91083c96a59d9a2ab6a503ca6322e3aed1ce94f1aeb337", + "sequence_number": "9471017033331266559", "payload": { "Script": { - "code": "bf1c59cf0baa493976bff76331b9", + "code": "debef9b128", "ty_args": [ { - "vector": { - "struct": { - "address": "963c5883f1e7a92e44fc732ab84a5c03bd99ff6d6105b7ce018898328e75f3be", - "module": "aryQWAArhiCdGRdLtEHB9", - "name": "uGJfWKnwjVKGAXSzZvXhGi0", - "type_args": [] - } + "struct": { + "address": "b5dd8f205c57d6832740124dba5338ec4def3e5f0c05ce66b3dc92edd72ee42a", + "module": "rneDZZQYrTYjPHAkOt6", + "name": "NXBybToidd2", + "type_args": [] } }, { "struct": { - "address": "2c4457c7c3879fcc0df5466d0213af9bb79083d70b78cd9d2edcae3ef32077d6", - "module": "vknOCbGlZxPsmRIGvfFAvWC1", - "name": "FaJVsEHUlhZ4", + "address": "2a005fccec34d22363828f2537eb23a5189db6fd7537541685a7ebbff0b74a51", + "module": "UOtsc", + "name": "TzTqPqvEHnyCuipYajoUclzsX", "type_args": [] } }, { - "vector": { - "vector": "u64" + "struct": { + "address": "ee37562f9f09435725bb60c5fc8aad160924dcdf241de04f56bc1f33deaffd18", + "module": "ntqyAKjQcuG", + "name": "iqkSFFEWleqvKkDYjwHLHRVRNamWoac9", + "type_args": [] + } + }, + { + "struct": { + "address": "6dcce72bcdd34d18e750e5f1840d1b78ca0e9ed7beaa600b1e94d2bc2b3ac719", + "module": "sOEiY4", + "name": "KpiNlsDnhnwgKsxpmDKDUfxw3", + "type_args": [] } }, { "struct": { - "address": "dad07b8742e46016a90d64418e3d2b6d9f48d18b4a80589994575f02bf93b4bc", - "module": "RUeCPDuj", - "name": "QBqXtpVBTsYElifqUgDImkWeRCuiQJT2", + "address": "3641bbff5cd093affb7e3e6424b01cc8bfd8a01f5553afd58ec6c0ec8032e1d0", + "module": "zIzGC6", + "name": "jZMFuMJblJKwLZRNC3", "type_args": [] } }, { "vector": { - "vector": "bool" + "vector": { + "vector": "u128" + } } }, { "vector": { - "vector": "signer" + "struct": { + "address": "579c8b019621fed5a2a5659a45b9f705c783c8d8ee3ce294726c3e8ec64c0ba7", + "module": "qfOsq3", + "name": "zGcbzTYEdIlMDZezTUffhlmnq", + "type_args": [] + } } } ], "args": [ { - "U128": "11498965134222276024643446538925200043" + "U128": "192491556015919642584328801971437344312" }, { - "U128": "40220626748274954768399808851027050712" + "Address": "769da8c9395ad4d2cd3ffc7d3b5c506864ed0d9265bc3354270465acae2babfb" }, { - "U8": 129 + "U8Vector": "0efc8c81acf01d06e4a9" }, { - "U8": 200 + "U8": 179 }, { - "U8": 184 + "U128": "315077671688090229400148984499658756826" }, { - "U64": "6380118867066596080" + "Bool": false }, { - "Bool": false + "U128": "65705937973926824295544856324934735466" }, { "Bool": false @@ -3364,513 +3449,687 @@ ] } }, - "max_gas_amount": "5957574110157586789", - "gas_unit_price": "18235895432617489712", - "expiration_timestamp_secs": "14750702199615523789", - "chain_id": 136 + "max_gas_amount": "16439330115351780794", + "gas_unit_price": "15831311977517755346", + "expiration_timestamp_secs": "8542313520942612831", + "chain_id": 233 }, - "signed_txn_bcs": "8c5db5d33a1df20826b289a2ca85ece7419a15e58af4d382ab492d6aa625c4ebcffa4433b2ea230f000ebf1c59cf0baa493976bff76331b9060607963c5883f1e7a92e44fc732ab84a5c03bd99ff6d6105b7ce018898328e75f3be156172795157414172686943644752644c74454842391775474a66574b6e776a564b474158537a5a76586847693000072c4457c7c3879fcc0df5466d0213af9bb79083d70b78cd9d2edcae3ef32077d618766b6e4f4362476c5a7850736d52494776664641765743310c46614a56734548556c685a340006060207dad07b8742e46016a90d64418e3d2b6d9f48d18b4a80589994575f02bf93b4bc08525565435044756a205142715874705642547359456c696671556744496d6b576552437569514a5432000606000606050802ab5277d47d0e0fcbefe3dbb7c09ea60802d840c69d92fcb8e547c438670036421e008100c800b801f0aa45684ebc8a580500050065c101af168ead523075552e47ea12fdcd0ba87b7f05b5cc88002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ecbb63562fff2f90d3b0f1ce3e0a101ac87734e51075ca24c8d498567c2710e6ce53bb7e9866f454f9115c49204f8f22ea063dd992f797bce4a7caef9c32d008", + "signed_txn_bcs": "4d50f4c12e01baae7f91083c96a59d9a2ab6a503ca6322e3aed1ce94f1aeb337ff5362edcfcf6f830005debef9b1280707b5dd8f205c57d6832740124dba5338ec4def3e5f0c05ce66b3dc92edd72ee42a13726e65445a5a51597254596a5048416b4f74360b4e58427962546f6964643200072a005fccec34d22363828f2537eb23a5189db6fd7537541685a7ebbff0b74a5105554f74736319547a547150717645486e794375697059616a6f55636c7a73580007ee37562f9f09435725bb60c5fc8aad160924dcdf241de04f56bc1f33deaffd180b6e747179414b6a516375472069716b53464645576c6571764b6b44596a77484c485256524e616d576f61633900076dcce72bcdd34d18e750e5f1840d1b78ca0e9ed7beaa600b1e94d2bc2b3ac71906734f45695934194b70694e6c73446e686e77674b7378706d444b44556678773300073641bbff5cd093affb7e3e6424b01cc8bfd8a01f5553afd58ec6c0ec8032e1d0067a497a474336126a5a4d46754d4a626c4a4b774c5a524e433300060606030607579c8b019621fed5a2a5659a45b9f705c783c8d8ee3ce294726c3e8ec64c0ba70671664f737133197a4763627a54594564496c4d445a657a54556666686c6d6e710008023896585d4485151b6fd995047286d09003769da8c9395ad4d2cd3ffc7d3b5c506864ed0d9265bc3354270465acae2babfb040a0efc8c81acf01d06e4a900b302da12937e3c9a5472a33840d894c009ed0500026a1698b2e328d4dc5c080c56db806e310500ba9decfea33b24e4d22b559c5d1eb4db5f01cd5fe3648c76e9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ab366fc4627c973f47f14ee9fe4bab7ecc195a8920571c172c7cc3a8a6ed8cd068cd7ee8e6e4b33adc761614424766a33f804adc8513586d3e1a576c22e2ad0c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "26cf3699b9e805ec28839231e73bff9390bcc8599f279ca5ad5f0fdde2713662", - "sequence_number": "3837411713125595783", + "sender": "79d9b4031d6fee835f5eeba9add0cb2eafac14b75b4270c9882bc0331cf4f6f8", + "sequence_number": "11221441559277894029", "payload": { "Script": { - "code": "7a2aabaeefb8294ac2", - "ty_args": [], - "args": [ + "code": "91ba8fdf0e1593677ad3ebedee51beca", + "ty_args": [ { - "Bool": true + "vector": { + "struct": { + "address": "e02c89f2d2aa2d29a646236c2c4b738570480d25967526c2c60445d39f6700d0", + "module": "UVwLK", + "name": "avrVUjQmQzKaAxyCoo", + "type_args": [] + } + } }, { - "U64": "3474333142161611273" + "struct": { + "address": "6082686acaf755abab06205587b9651ef61f66d2feaf6927043d969aecc8a79f", + "module": "lSKi", + "name": "nmFWqxyirLUgCAGvEqAq3", + "type_args": [] + } }, { - "Bool": false + "vector": { + "struct": { + "address": "f2270ea8dda05f6be736502ba28eab40726ad1e4e433b7461b31dfc6d8633713", + "module": "hIOTcNPREIFOILDIe", + "name": "PVjaNsEEIiA", + "type_args": [] + } + } }, { - "U128": "210275219742270604359323107769974579373" + "struct": { + "address": "0e133c46a1444f425dba67536b4d6a3d8dd7a92d3b99dcf014625c2129c69194", + "module": "ZyHXbuOHUVurbH0", + "name": "UkmraNY", + "type_args": [] + } }, { - "U64": "17806591079525347967" + "struct": { + "address": "5cad39a475562104801796a215cbefb9cc3ee4132485146129299ef7bef46732", + "module": "YtnHgwNGdDrZsdHqLYeWVdVcy7", + "name": "NSYboeSAJDtfsYtICRDvKGx2", + "type_args": [] + } }, { - "Bool": false + "struct": { + "address": "077c0562d76c53034d1103c3c75c976e5f5192e361ee493b789aa49bd0e0d5ad", + "module": "J", + "name": "zByxsMCNCFbuSxMWYhlNxI2", + "type_args": [] + } }, { - "Bool": false + "vector": { + "vector": { + "vector": "address" + } + } + }, + { + "struct": { + "address": "6556c5a22712d8050a89ce283dc2d678c910e40215ab91e95e13601bed4cd252", + "module": "SjrPGbQvGRJFjWipQPsOlbevcw8", + "name": "bChjkDgoFmHK", + "type_args": [] + } + }, + { + "vector": { + "vector": "u8" + } }, { - "U64": "179749017677351005" + "struct": { + "address": "20536a0be579aa23b615ab7c222cad8a4430c6e8065be9890108095ab704067f", + "module": "RBdpkSE8", + "name": "z5", + "type_args": [] + } } - ] + ], + "args": [] } }, - "max_gas_amount": "17551628816525803969", - "gas_unit_price": "976402986023287607", - "expiration_timestamp_secs": "1412463201473963225", - "chain_id": 74 + "max_gas_amount": "415783401751606302", + "gas_unit_price": "14633880235777633592", + "expiration_timestamp_secs": "7303237492838149505", + "chain_id": 248 }, - "signed_txn_bcs": "26cf3699b9e805ec28839231e73bff9390bcc8599f279ca5ad5f0fdde2713662873ac6219f39413500097a2aabaeefb8294ac2000805010109dae8c1954f3730050002ade03c0a02bfa63e8ae51d10c388319e017f72bf533eb81df705000500015d48627bc7987e02c1c187866ae993f3377b8cb357e18c0dd9a42a56cc139a134a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fb7713dde0084ceb521da5fad43a0cb8b9985a8cc797d3335fc7a6faeeecf6a532645dbc81168b9526ecedf08e1ccebeeec5dbfccd8729b7e1759cc20e354302", + "signed_txn_bcs": "79d9b4031d6fee835f5eeba9add0cb2eafac14b75b4270c9882bc0331cf4f6f88d7990f8a491ba9b001091ba8fdf0e1593677ad3ebedee51beca0a0607e02c89f2d2aa2d29a646236c2c4b738570480d25967526c2c60445d39f6700d0055556774c4b1261767256556a516d517a4b61417879436f6f00076082686acaf755abab06205587b9651ef61f66d2feaf6927043d969aecc8a79f046c534b69156e6d465771787969724c5567434147764571417133000607f2270ea8dda05f6be736502ba28eab40726ad1e4e433b7461b31dfc6d86337131168494f54634e50524549464f494c4449650b50566a614e73454549694100070e133c46a1444f425dba67536b4d6a3d8dd7a92d3b99dcf014625c2129c691940f5a79485862754f485556757262483007556b6d72614e5900075cad39a475562104801796a215cbefb9cc3ee4132485146129299ef7bef467321a59746e4867774e476444725a736448714c596557566456637937184e5359626f6553414a44746673597449435244764b4778320007077c0562d76c53034d1103c3c75c976e5f5192e361ee493b789aa49bd0e0d5ad014a177a427978734d434e4346627553784d5759686c4e7849320006060604076556c5a22712d8050a89ce283dc2d678c910e40215ab91e95e13601bed4cd2521b536a72504762517647524a466a5769705150734f6c6265766377380c6243686a6b44676f466d484b000606010720536a0be579aa23b615ab7c222cad8a4430c6e8065be9890108095ab704067f08524264706b534538027a3500001e74e80ccd28c50538ad22738afc15cb81adee36ce4f5a65f8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ebfaff60548c97e767560610e21ee3db6dfd4ed33068f40f5df2ba5317814cf375785e21351d28327325291d823e1ffa6234b3702517e233d6786b18343b2506", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "486df5ea4ca9ee53d48cbd45c00a72ff00f0089a65a41660bfaf014ccf4d4d11", - "sequence_number": "952304163986397957", + "sender": "fd91737f1f2564120a47f2654ab4fe40d1ab066d3c2cc3c35eb6d641cfeb5f45", + "sequence_number": "2650617817229611596", "payload": { "Script": { - "code": "2273eef7aadb2feb28d7bb8b9c", + "code": "48", "ty_args": [ + "address", { "vector": { "struct": { - "address": "c902c19db898215966dcbbf40418bb60eccade43af61131fc6ac54d958a1ffd2", - "module": "J5", - "name": "aQPIryAbyAZE", + "address": "5ffced1e7dd63f89bbe53def9834e6f1c114ec1a191739dd3030f648212cf854", + "module": "QcBearFRJCibyU2", + "name": "dI8", "type_args": [] } } }, { "struct": { - "address": "1ecb60f2e987df96f74549169b7e447ea48608c2b6bb641e62e55c02e26fe57f", - "module": "eRIOnKdGOmiLJuGulektKiSpNUTGq", - "name": "lOqPMftEbXuvoZ8", + "address": "cd0f33c5c4bf7352239bb0547a2833d7f14eab2f2366e8aad462b07c682fead3", + "module": "GzbZvhfcbBXKbbslaiJ6", + "name": "PqjcKNg", "type_args": [] } - } - ], - "args": [ - { - "U128": "232387967613288644351367840724258676038" }, { - "U8": 77 + "vector": { + "vector": { + "struct": { + "address": "c081b92e0652063e7e3d1e92631daa2e4fff507a91ce173fbdeac451bf8b4510", + "module": "qGzT", + "name": "TrzFMzCJFefTzMxCWpSZ", + "type_args": [] + } + } + } }, { - "U8": 45 - }, + "struct": { + "address": "1c9bea037151e18bcea8bcd3c3375d8feb86ca256f52bdc48766ceccb284bee9", + "module": "XApCxzfxiMgPbjDAqouZKJaxddeIFZWW", + "name": "sBvPhXMQIqNHBgCgvpaBHiQCuXY8", + "type_args": [] + } + } + ], + "args": [ { - "Address": "b029d244fa4c982db19274a428fdbee82c43709eb3b8852dfbfef51b246709c1" + "U128": "327594961058430596899094752992007146957" }, { - "Bool": false + "Bool": true }, { - "Address": "4ca80644f26fcf50ee912d11d8c10608f4dc9f6873fcbb7ab3000f8aac023a99" + "Bool": true }, { - "U8": 158 + "Bool": true }, { - "U8Vector": "978c05f9caba352ccbd8de8ddeab6b" + "Address": "ea5c6a3e632cbe99b112f03e272e4dd5764dd67664caaccd3894253b2817b29a" }, { - "U64": "9930114374004042041" + "Bool": true } ] } }, - "max_gas_amount": "2160534189671687279", - "gas_unit_price": "11793001753851515959", - "expiration_timestamp_secs": "13217010274385529707", - "chain_id": 242 + "max_gas_amount": "14517550843959167445", + "gas_unit_price": "11705723287556020675", + "expiration_timestamp_secs": "3608535604572905763", + "chain_id": 162 }, - "signed_txn_bcs": "486df5ea4ca9ee53d48cbd45c00a72ff00f0089a65a41660bfaf014ccf4d4d1105db88749743370d000d2273eef7aadb2feb28d7bb8b9c020607c902c19db898215966dcbbf40418bb60eccade43af61131fc6ac54d958a1ffd2024a350c615150497279416279415a4500071ecb60f2e987df96f74549169b7e447ea48608c2b6bb641e62e55c02e26fe57f1d6552494f6e4b64474f6d694c4a7547756c656b744b6953704e555447710f6c4f71504d667445625875766f5a38000902465df88be98efbbeef41f9e6674bd4ae004d002d03b029d244fa4c982db19274a428fdbee82c43709eb3b8852dfbfef51b246709c10500034ca80644f26fcf50ee912d11d8c10608f4dc9f6873fcbb7ab3000f8aac023a99009e040f978c05f9caba352ccbd8de8ddeab6b0139e9824169dace896fa4770466c2fb1d37d4e0f59c28a9a36b0b705dd1406cb7f2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c8113d2cc236097cbe532fb4fcf17a630bf62dd9d97fbeaa185ff271e1f99a4ad55b1bf57b77515d7f0ed3a0b344d52a3a03c3ddf3f0a9cdd044b5ef75cf0200", + "signed_txn_bcs": "fd91737f1f2564120a47f2654ab4fe40d1ab066d3c2cc3c35eb6d641cfeb5f454cd24a77dce2c824000148050406075ffced1e7dd63f89bbe53def9834e6f1c114ec1a191739dd3030f648212cf8540f51634265617246524a436962795532036449380007cd0f33c5c4bf7352239bb0547a2833d7f14eab2f2366e8aad462b07c682fead314477a625a766866636242584b6262736c61694a360750716a634b4e6700060607c081b92e0652063e7e3d1e92631daa2e4fff507a91ce173fbdeac451bf8b45100471477a541454727a464d7a434a466566547a4d78435770535a00071c9bea037151e18bcea8bcd3c3375d8feb86ca256f52bdc48766ceccb284bee92058417043787a6678694d6750626a4441716f755a4b4a617864646549465a57571c7342765068584d5149714e4842674367767061424869514375585938000602cdcda97cd696c21457de1d6c987e74f605010501050103ea5c6a3e632cbe99b112f03e272e4dd5764dd67664caaccd3894253b2817b29a0501d5c9db4693b378c9c359cb794f1573a223e1ea7503181432a2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444049cb88b2dc313df7808025a5a2747661dcf4f4cb61ab3dc80fd9c85faae9552472cf0f06bcf031d6415cd3dd4430a48755496afc07a3074662173195e2279706", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "69a703bc29521209bc81a7a30a8910ddc0403728f624968cd7df9c3aa85c1778", - "sequence_number": "11014360300890509205", + "sender": "b496b45da267963eb32879cf4e6242c4bac5e42638e8a27f639c43d9bced74b8", + "sequence_number": "9116319703090776671", "payload": { "Script": { - "code": "cff2ff50feb339023490fb16afadad", + "code": "65ac1043baf8", "ty_args": [ + { + "vector": { + "vector": "address" + } + }, { "struct": { - "address": "258f9943eaa590e8e17023f2b221a414203e6559274f9e542a889bb5fde471da", - "module": "eeHEIukXLGamvkyKwsduSAsAM", - "name": "ozObeLbirdvMLJErXZUg8", + "address": "191d254641229a20ed1c926f587c1bef78c6366d2c2aa8ed90e8cad026ab16b3", + "module": "lLDAonOfGfJdIzsSylpNVyoVVKJ7", + "name": "AJMDmcfCmDqktVEohvhartHPcx6", "type_args": [] } - } - ], - "args": [ - { - "U128": "117050558650263471822715105162506020147" }, { - "U64": "6781022535632576491" + "struct": { + "address": "0a65ab615f5414a69ff8976c8d3cc27ac858786d4f7ada52a7b0ec0af6788527", + "module": "tdjxwS0", + "name": "QJIArbWjwCMsFpiajzPFsvjcIHVNuUP9", + "type_args": [] + } }, - { - "Bool": false - } - ] - } - }, - "max_gas_amount": "4879753392121320192", - "gas_unit_price": "13407482513661342686", - "expiration_timestamp_secs": "5942918218619123171", - "chain_id": 118 - }, - "signed_txn_bcs": "69a703bc29521209bc81a7a30a8910ddc0403728f624968cd7df9c3aa85c1778954fbe4a56deda98000fcff2ff50feb339023490fb16afadad0107258f9943eaa590e8e17023f2b221a414203e6559274f9e542a889bb5fde471da196565484549756b584c47616d766b794b77736475534173414d156f7a4f62654c62697264764d4c4a4572585a5567380003023325b04ee41d9282e7079f741a1e0f5801eb5f4c9a11081b5e05000013e628db5db843deb30b6f4ff210bae375fd05a27c795276002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a098dd6df76c938183b6a653723e5b13b797f687c60e7d25755f26983836c6908c7365227e576c69a2e6198c5f6b29491270abe5ae0fc415e5ddb7dc1532cd05", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "cb8e1ede05c66b884d7ef63335bf26c5a09226e573550f9ec44e56531fb2cf40", - "sequence_number": "969269243045527319", - "payload": { - "Script": { - "code": "1b7100", - "ty_args": [ { "struct": { - "address": "295304bf743f1814c6b997191454a279d7e41bc8e3935aa010725a41f4fa1053", - "module": "xv", - "name": "WcoTQGHpLYIZbLlCvWBTpNqxtSYUtJ0", + "address": "595cee5c556ce602d702dd878a1bd2bfe2efcd59c1ee2a88af95b1033682f134", + "module": "jSINWBqmLgEVUBCnXQNuPnPFtjavGl", + "name": "njqpRFsAxgrcjcFqwHdhTehrftcWR", "type_args": [] } }, + { + "vector": { + "struct": { + "address": "8e971631daed54a847955df25f5a8252001d36886356be2617b44125825e635c", + "module": "CGoWoQgDAUzuHgNOwQoLHG", + "name": "pHGfOAPWesKZZlycdEjPJLp8", + "type_args": [] + } + } + }, { "vector": { "vector": { - "vector": "address" + "struct": { + "address": "5907e32695a4ea0dbb4d770c4dfc1cf41a0cd811d6e8bcbbc96881dfecc8150d", + "module": "ucpjUkgJhEyfQwdEXUWiZ", + "name": "trA", + "type_args": [] + } } } }, { "vector": { - "vector": "bool" + "struct": { + "address": "0c65ede80f771a673d8dc71d2f20ff783feb5de2b1ef9133964eaeb8fd4e8d81", + "module": "w3", + "name": "AZACBTQVhjjrzoCdpJwaNdZiqE", + "type_args": [] + } + } + }, + { + "struct": { + "address": "d51c524062b2c07f8c08d8d4332a9bcfe3e4ef286858c1cba97cc5923e3eef17", + "module": "TZnEeU6", + "name": "gTVpTgvAxuXitKkXAeL", + "type_args": [] } } ], "args": [ { - "U8Vector": "7b7b16c11bba" + "U8Vector": "ba2fa7d8330e" }, { - "U8": 218 + "U8Vector": "cb501d5cdc" }, { - "U8Vector": "46c9" + "U128": "89570550819865856735458984007533375076" }, { - "U8Vector": "e8c62a152bd2e1" + "Bool": false }, { "Bool": false }, { - "Address": "084fe2fced7a6b69c27292e167499b1dd350d456f65e0b517f53ab7ee75301f6" + "U128": "19565242277200864594553890093588396337" }, { - "U64": "11393535352084719867" + "U8": 43 }, { - "U8Vector": "399bd44d667a58c26c6e0fc6c7" + "Address": "efeeea7fbfb4b63404dce6c484be0141fc60cde3c8ca570cf9ef4df33220caa5" }, { - "Bool": false + "U128": "238033984331132102971666449500149121802" }, { - "U8": 76 + "U64": "14292111081056986895" } ] } }, - "max_gas_amount": "14082883475045409068", - "gas_unit_price": "10635544574547446870", - "expiration_timestamp_secs": "12054556410856265370", - "chain_id": 216 + "max_gas_amount": "12863496450124996033", + "gas_unit_price": "2494701448280716011", + "expiration_timestamp_secs": "4720182960744506747", + "chain_id": 162 }, - "signed_txn_bcs": "cb8e1ede05c66b884d7ef63335bf26c5a09226e573550f9ec44e56531fb2cf4017bf70bb3d89730d00031b71000307295304bf743f1814c6b997191454a279d7e41bc8e3935aa010725a41f4fa10530278761f57636f54514748704c59495a624c6c4376574254704e717874535955744a3000060606040606000a04067b7b16c11bba00da040246c90407e8c62a152bd2e1050003084fe2fced7a6b69c27292e167499b1dd350d456f65e0b517f53ab7ee75301f601fb68dd8409f81d9e040d399bd44d667a58c26c6e0fc6c70500004c2ce14cffe77370c356ccbbe6700b99939ad6fe1930634aa7d8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405a5502d8c0b752d558fbd3b0c4d1653a08786645d584a799c9cc10b64dc0466311bd9dd655abe495f23395209913cf45fc8a8abec99e31527ed4ae1411227905", + "signed_txn_bcs": "b496b45da267963eb32879cf4e6242c4bac5e42638e8a27f639c43d9bced74b85fca9e3978ac837e000665ac1043baf80806060407191d254641229a20ed1c926f587c1bef78c6366d2c2aa8ed90e8cad026ab16b31c6c4c44416f6e4f6647664a64497a7353796c704e56796f56564b4a371b414a4d446d6366436d44716b7456456f687668617274485063783600070a65ab615f5414a69ff8976c8d3cc27ac858786d4f7ada52a7b0ec0af67885270774646a7877533020514a49417262576a77434d73467069616a7a504673766a634948564e755550390007595cee5c556ce602d702dd878a1bd2bfe2efcd59c1ee2a88af95b1033682f1341e6a53494e5742716d4c6745565542436e58514e75506e5046746a6176476c1d6e6a717052467341786772636a634671774864685465687266746357520006078e971631daed54a847955df25f5a8252001d36886356be2617b44125825e635c1643476f576f51674441557a7548674e4f77516f4c484718704847664f41505765734b5a5a6c796364456a504a4c7038000606075907e32695a4ea0dbb4d770c4dfc1cf41a0cd811d6e8bcbbc96881dfecc8150d157563706a556b674a6845796651776445585557695a037472410006070c65ede80f771a673d8dc71d2f20ff783feb5de2b1ef9133964eaeb8fd4e8d810277331a415a414342545156686a6a727a6f4364704a77614e645a6971450007d51c524062b2c07f8c08d8d4332a9bcfe3e4ef286858c1cba97cc5923e3eef1707545a6e4565553613675456705467764178755869744b6b5841654c000a0406ba2fa7d8330e0405cb501d5cdc0264aeb89ed416bb090ebc80d01ca96243050005000231b9f91204b7d095bf6713bdeb20b80e002b03efeeea7fbfb4b63404dce6c484be0141fc60cde3c8ca570cf9ef4df33220caa5020a032cad637fd4e6fca427a585ad13b3010f67d32c4ec757c6c1dd321fde5184b2ebb26cedbff59e227b2507ea64758141a2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406aa6c4e66e633208cb1d16e63f71a6d0bbc42bffa525914709b17e0268dc641d42f06c05093bb70c40753d60c829cc3c839738a35dc426dff0163a4707588b02", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "6c4d06761ddf84c64496cfd4e90bb6dfa21f6d8edfb3dac808ea82fd6f4af666", - "sequence_number": "13469864845076407220", + "sender": "1817204690db3824f9f05d4ec6f43557a1c5882654df1ad325885b8c294b349a", + "sequence_number": "4029562605877010109", "payload": { "Script": { - "code": "d881b00aff4131", - "ty_args": [], - "args": [ + "code": "afb458bee86c", + "ty_args": [ { - "U64": "4718097164583779556" + "vector": { + "struct": { + "address": "aa88062e8f3b136b417d538421f5e3f4ca896584b68afdfe5a59f514a9f642fa", + "module": "QSgKXtFOJQJlLnlxuONxMluoyj", + "name": "ttbSKjBIxeVQPHoWmushBPHoF", + "type_args": [] + } + } }, { - "Address": "eeaed7fc702189e3d378e03411df26e29d5921214ae0129b39984f9dbf64cf8e" + "struct": { + "address": "091f829b206cd6c9fdb5ab2f465e36648f1a8714fe28079b02eccb6cd9af0739", + "module": "CFuzeaNxb", + "name": "blOTEHc", + "type_args": [] + } }, { - "U128": "256345448976444894725098292547615511212" + "struct": { + "address": "be687ea156deebf0cf880924fb04d51c01d6062b96d5f9f1e58d5560e3f8052e", + "module": "frvnhwBafhO", + "name": "QMCsRIbWoqDXVDp", + "type_args": [] + } }, { - "Bool": true + "struct": { + "address": "8ee875c54848f73b1809b94f9ab84f4d703b93909defdbd9a76f51c611e01136", + "module": "GZoOPEgq5", + "name": "WUW8", + "type_args": [] + } }, { - "U128": "330487666557371312528993012441621356572" + "struct": { + "address": "e05d59c85624c04ed7d9a21f17303f4539fb44fd6eaf9abea168182057b6f189", + "module": "U2", + "name": "puCl6", + "type_args": [] + } }, { - "U64": "423311800870371780" + "struct": { + "address": "78695a8e0b244f796c0c16a647722d01f4bc6aec78641da5eaa8b80bd0867e26", + "module": "aHI2", + "name": "xAhcdPQRvPXvFso0", + "type_args": [] + } }, { - "Bool": false + "struct": { + "address": "f50c5960c01aaec64f3cddd52f73eba0eddcc881a7f108477f261fec6164cd0f", + "module": "dWIFFjnLDauAkdNYleDhEABlX2", + "name": "H4", + "type_args": [] + } }, { - "U8Vector": "3ff737252b62b3" - } - ] - } - }, - "max_gas_amount": "14310406112985531978", - "gas_unit_price": "503010067782432092", - "expiration_timestamp_secs": "5290525690940886077", - "chain_id": 188 - }, - "signed_txn_bcs": "6c4d06761ddf84c64496cfd4e90bb6dfa21f6d8edfb3dac808ea82fd6f4af666b4234dcfb592eeba0007d881b00aff4131000801e43ccba65f0c7a4103eeaed7fc702189e3d378e03411df26e29d5921214ae0129b39984f9dbf64cf8e02acd2a45d17e776bfd6968cdc6e56dac00501021c60a21c34aee8a3452993e0fc9ba1f801c4011c10d7e7df05050004073ff737252b62b34ac6143c8ac698c65cf59dd8fd0cfb063d0c9ce315b96b49bc002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404f473d1aa408bef577f6b9d74ba18581d126ba6a347293f88911d478ed8bee135d9eefa38776de4a7ec95fcc4180a0134e2b728ba3eba5b28877d9c7ee949205", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "37ab56b4cbfce83c0c851f34036d52bfadb1a085753a6d0c63d3f53516c939c6", - "sequence_number": "5365422232441453102", - "payload": { - "Script": { - "code": "21", - "ty_args": [ + "struct": { + "address": "6925a8ba7189706479aae9b165ca82f1cef225ff753ebcc69c69a637257cc55e", + "module": "nMXsBxTlZDYoPXGHTJGcKBwrJTbp", + "name": "JBgYeFnMcKrWjbCrWqDmS6", + "type_args": [] + } + }, { "vector": { "struct": { - "address": "16120a8d6a5ed7c1b2bb348adc2cf33b2fc5a99aa3b13f7ada39157e1f777040", - "module": "DZdTpBexKFDEgGLwgSUWjaaWcBqDV", - "name": "QQBFp0", + "address": "dd72f39e2b279d53ba8de746e3c6c466d9b87e5b8ffa6c52d6ec4ba7dd0bc896", + "module": "JuEAiOLX", + "name": "GBwZSMZ7", "type_args": [] } } + }, + { + "struct": { + "address": "1d30f9180d8555cd4ef355a6c54cf93a982866b52730062f54999f929ff3ee35", + "module": "jeUJQqQoaSuVyRLfpfncRfTCNvTC", + "name": "SEJySte9", + "type_args": [] + } } ], "args": [ { - "U64": "13902666144100980934" - }, - { - "U128": "19767269901051689400272223097837913919" - }, - { - "U8": 175 + "Bool": true }, { - "U64": "7212250821232717834" + "U8Vector": "fc3b709b93" }, { - "Bool": false + "U64": "539015909240454383" }, { - "U8Vector": "3cb19dab5014dd6bea" + "U8Vector": "663c8c64e1ebde9f933db973c3" }, { - "Address": "898b34e3ed5a1017e7a170092b363d89e400898dae2c89f96b259fd616a26ebd" + "U128": "295100329759719467903817925573479009762" }, { - "U64": "4264585990717292329" + "U8": 85 }, { "Bool": false }, { - "U8": 105 + "Bool": false } ] } }, - "max_gas_amount": "4506247237582036488", - "gas_unit_price": "4160030373782694693", - "expiration_timestamp_secs": "2642486563502286357", - "chain_id": 131 + "max_gas_amount": "3737336546645264515", + "gas_unit_price": "12905892364096598225", + "expiration_timestamp_secs": "12729379616073566242", + "chain_id": 254 }, - "signed_txn_bcs": "37ab56b4cbfce83c0c851f34036d52bfadb1a085753a6d0c63d3f53516c939c62efaa7da17cf754a00012101060716120a8d6a5ed7c1b2bb348adc2cf33b2fc5a99aa3b13f7ada39157e1f7770401d445a6454704265784b46444567474c77675355576a616157634271445606515142467030000a01c618fdd53231f0c0023f0729aab70582dc93f6a4d8a609df0e00af010a7098e6e80f1764050004093cb19dab5014dd6bea03898b34e3ed5a1017e7a170092b363d89e400898dae2c89f96b259fd616a26ebd0129bfcf225dda2e3b05000069089e29cafc67893e252b278c9565bb3915e64b6d87ffab2483002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fd48d2401e93cdbd3a339bf7c78daeb7ea6ba21e7617c2a1fe0c2a0c1300c159dc8b5544d142c7caaed2102fafbf6585be5fd20bbd991c8b98c26ab80b47f10b", + "signed_txn_bcs": "1817204690db3824f9f05d4ec6f43557a1c5882654df1ad325885b8c294b349abd1e7f2bd7e1eb370006afb458bee86c0a0607aa88062e8f3b136b417d538421f5e3f4ca896584b68afdfe5a59f514a9f642fa1a5153674b5874464f4a514a6c4c6e6c78754f4e784d6c756f796a19747462534b6a42497865565150486f576d7573684250486f460007091f829b206cd6c9fdb5ab2f465e36648f1a8714fe28079b02eccb6cd9af0739094346757a65614e786207626c4f544548630007be687ea156deebf0cf880924fb04d51c01d6062b96d5f9f1e58d5560e3f8052e0b6672766e6877426166684f0f514d4373524962576f71445856447000078ee875c54848f73b1809b94f9ab84f4d703b93909defdbd9a76f51c611e0113609475a6f4f504567713504575557380007e05d59c85624c04ed7d9a21f17303f4539fb44fd6eaf9abea168182057b6f189025532057075436c36000778695a8e0b244f796c0c16a647722d01f4bc6aec78641da5eaa8b80bd0867e2604614849321078416863645051527650587646736f300007f50c5960c01aaec64f3cddd52f73eba0eddcc881a7f108477f261fec6164cd0f1a64574946466a6e4c446175416b644e596c6544684541426c583202483400076925a8ba7189706479aae9b165ca82f1cef225ff753ebcc69c69a637257cc55e1c6e4d58734278546c5a44596f50584748544a47634b4277724a546270164a42675965466e4d634b72576a6243725771446d5336000607dd72f39e2b279d53ba8de746e3c6c466d9b87e5b8ffa6c52d6ec4ba7dd0bc896084a754541694f4c58084742775a534d5a3700071d30f9180d8555cd4ef355a6c54cf93a982866b52730062f54999f929ff3ee351c6a65554a5171516f6153755679524c6670666e63526654434e7654430853454a7953746539000805010405fc3b709b9301efbc8f161df87a07040d663c8c64e1ebde9f933db973c302e28d889201b0d55e2d368d3e944102de0055050005008348e0b4c9afdd33d170670fbaf01ab322c8295351d7a7b0fe002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c65b3a17592d876127ffcc3551362e9b3641fa749628f71120e43517bcb46c9477f2d9dcc03c10ec07770431854804ab0f9847ebe02b124ab5fdbe15db296d03", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "b615fa2e416fdb5cd332b94ede2bf660d1f77440d6e6674fdfdb31ff6dd40d41", - "sequence_number": "5837377380404227635", + "sender": "c85186271e150dbad0b1127180af1225938e88727dfccdddedb35237f7cb3b77", + "sequence_number": "9007599062242443603", "payload": { "Script": { - "code": "3c0d88a48ec0e1bfc0dc0936", + "code": "f61d5deb3d3a4cee24", "ty_args": [ { - "vector": { - "vector": { - "struct": { - "address": "5676ad8838a31b2c93550d3b9e34484843ed652a5be2a36dae7629cfae4da90c", - "module": "EKfsRy", - "name": "TCriPDrcumkPSfdpqmrRKdXVZMNwE4", - "type_args": [] - } - } + "struct": { + "address": "5b743ad3a9a964703db5bcd8923f1a9680fc7285f7eaa0670980bb3a6095d0c0", + "module": "hhRxURnzlKiTvVsHFvU4", + "name": "EyVKMhbBV", + "type_args": [] } }, { - "vector": { - "vector": { - "vector": "bool" - } + "struct": { + "address": "610b0d3fd1f4066c47cb2b2de32e0884ec455e6f4785bce0a7897a06f2ae3935", + "module": "yvbEsysOeqLGubWjqAYaiGL5", + "name": "DsxooJiNeouvPHavarBgKThLlmEca", + "type_args": [] + } + }, + { + "struct": { + "address": "1d61afa6a3d12d1aaf8edc78fc906572c28849c38914332a9946d6a5d1c9fca4", + "module": "kzqmVgnoPohcTuyMNFZTH7", + "name": "tQzRExmvgYOSnhmFIQKDca", + "type_args": [] } }, { "vector": { "struct": { - "address": "ae06b0d3930dd34549bc019b44f89e73e4263f5d444360f1b2fa4286b8a94e78", - "module": "wzkpUTOnbJbeDbwPNiaHyqxVjTfrR2", - "name": "GngSehrhNLMtXmUGfvQ", + "address": "6fd2f83b882f8719db44e39dd735c3e0016017e667b2a7eee24656984cdeac42", + "module": "PDzMdzglNjXVMlfCSuGYPqXdMUD8", + "name": "wNJB", "type_args": [] } } - } - ], - "args": [ - { - "Address": "49d7daf6cf3f60defb822cdb3ebcaaedc3e703ddcffd0240482e68c2b809738f" }, { - "U64": "15184151781367649819" + "struct": { + "address": "4859c5c2661b58eff7ea25cd488075c5a1ee7c205be0ae24ca26eb0c9993a69d", + "module": "vturrZDOSQxSKc4", + "name": "HFoqbhQcTOLHUosyPtBkeAAnv8", + "type_args": [] + } }, { - "U64": "15632735920676928943" + "struct": { + "address": "e96478e91826d1417d9eed694b479585d15e7509a2a20f352e99423d84022a16", + "module": "lGtwrJ0", + "name": "fUewPcSOLbpHrzEHg", + "type_args": [] + } }, { - "U64": "11991635335206315829" + "vector": { + "vector": "u128" + } + } + ], + "args": [ + { + "U128": "118372847108559400719492021265429286852" }, { - "U8Vector": "61e071b895c703af3a9e" + "U8Vector": "6e" }, { - "Address": "cb93021d3aa8be2e3df32bc0fea68994d29ec5ce15059fddc9b7daec204561ff" + "U128": "21458443027750733995186292840990338962" }, { - "U64": "17286979860819331334" + "U64": "13026082275583392372" }, { - "Bool": false + "U64": "14174837382319505091" }, { - "U64": "6308942936716947076" + "U128": "68442354932695970041146911119044597488" }, { - "U64": "7475543113224185616" + "U128": "2360618083786172535065555526279216460" } ] } }, - "max_gas_amount": "12571397295076794938", - "gas_unit_price": "7557422626387433805", - "expiration_timestamp_secs": "1864149713697490987", - "chain_id": 210 + "max_gas_amount": "15783062434960069755", + "gas_unit_price": "3231898998924662970", + "expiration_timestamp_secs": "4365332986977757373", + "chain_id": 32 }, - "signed_txn_bcs": "b615fa2e416fdb5cd332b94ede2bf660d1f77440d6e6674fdfdb31ff6dd40d4133eee4bacc870251000c3c0d88a48ec0e1bfc0dc0936030606075676ad8838a31b2c93550d3b9e34484843ed652a5be2a36dae7629cfae4da90c06454b667352791e5443726950447263756d6b5053666470716d72524b6458565a4d4e77453400060606000607ae06b0d3930dd34549bc019b44f89e73e4263f5d444360f1b2fa4286b8a94e781e777a6b7055544f6e624a6265446277504e696148797178566a546672523213476e6753656872684e4c4d74586d5547667651000a0349d7daf6cf3f60defb822cdb3ebcaaedc3e703ddcffd0240482e68c2b809738f011b96089898f1b8d201affd6f7b7ea2f2d80135a7fe8ecdd86aa6040a61e071b895c703af3a9e03cb93021d3aa8be2e3df32bc0fea68994d29ec5ce15059fddc9b7daec204561ff0106c977d397b0e7ef050001842e39bb2cde8d57011067d8b6da76be673ae25bd73b9376ae4d995277d65be1682bc815b549cade19d2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404a0fef4d1deaf6461b86d0deab6655f9c1f445c4c453198ecca99d3068287dd82ad90963c9789c205727873b7d32826852b5ffeb019f66b5f8b869cdbb911900", + "signed_txn_bcs": "c85186271e150dbad0b1127180af1225938e88727dfccdddedb35237f7cb3b7753411a709f6b017d0009f61d5deb3d3a4cee2407075b743ad3a9a964703db5bcd8923f1a9680fc7285f7eaa0670980bb3a6095d0c0146868527855526e7a6c4b69547656734846765534094579564b4d686242560007610b0d3fd1f4066c47cb2b2de32e0884ec455e6f4785bce0a7897a06f2ae393518797662457379734f65714c477562576a7141596169474c351d4473786f6f4a694e656f757650486176617242674b54684c6c6d45636100071d61afa6a3d12d1aaf8edc78fc906572c28849c38914332a9946d6a5d1c9fca4166b7a716d56676e6f506f68635475794d4e465a5448371674517a5245786d7667594f536e686d4649514b4463610006076fd2f83b882f8719db44e39dd735c3e0016017e667b2a7eee24656984cdeac421c50447a4d647a676c4e6a58564d6c664353754759507158644d55443804774e4a4200074859c5c2661b58eff7ea25cd488075c5a1ee7c205be0ae24ca26eb0c9993a69d0f76747572725a444f535178534b63341a48466f7162685163544f4c48556f73795074426b6541416e76380007e96478e91826d1417d9eed694b479585d15e7509a2a20f352e99423d84022a16076c477477724a3011665565775063534f4c627048727a454867000606030702c4cfb51601054f6b510ea82df5c70d5904016e02926f3903570bc573151901aaecbe24100174fa2883d0f0c5b401c3fe146a7f23b7c402f05679f8b24553660e302715a1847d33024cbd6bd0d1d957a32700661875a3c6017b549b8fa9b308dbba58d8240403da2cbda81a1f39c7943c20002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144403dd689902d1abc96ac1a205a9157f441013f170424473607e984f96a6cefa29cb16aef8d85a040d8738f6078ccb2479921292b24385d228aba2e42da80fa4d01", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "d20716d9d7f808c6088d116727cb3f9c65f7c62857e9ce1a3887af299ac36591", - "sequence_number": "15405229642529301844", + "sender": "0147bb288381f9391d5205ca56bd96504f179bb06f7cde296daa96d399926047", + "sequence_number": "15252492502399378930", "payload": { "Script": { - "code": "d7bbdfc1783cc3da", + "code": "f3aedf9d4df710ebf259b13cb8c4c3", "ty_args": [ { - "vector": { - "vector": { - "vector": "u8" - } + "struct": { + "address": "7eae77bcc63d8168d3a0ca378f687baa3c3cd7bd11f9c3b01d921f99d8497875", + "module": "lYWcELGPwsLhoWDHWtAydc0", + "name": "gHwsxrgVfpqakecKfKSaIPo", + "type_args": [] } }, { - "vector": { - "struct": { - "address": "ed53b46d636eaa6003f2387e5547550a7752ed853a13eae91c1f66e393b4a7a1", - "module": "EHayJadNGZBmyvnpqmUKKOmDEliX2", - "name": "JXMXofsFBbOmOLFs9", - "type_args": [] - } + "struct": { + "address": "5801c7ff9ed37b121259c09a6a133ba4570ea06d763639bb481440da7f0e80da", + "module": "qRWLrsQQzzykOUqVnvkdyXlQmsYvWT", + "name": "NrxpAOtQAvKioLl", + "type_args": [] + } + }, + { + "struct": { + "address": "f4b49a2684d4acf72151905715970573db51b2bf33f59eaaba5bc0aa8f394119", + "module": "SvOWVkNjGqJAFwJLMMXqTjMHhsCSwW1", + "name": "CnVSY5", + "type_args": [] } } ], "args": [ { - "U8": 0 + "Bool": true + }, + { + "U128": "121528544243717186204597139324948943328" }, { - "U64": "7464551970126444647" + "U64": "5305951097543336481" + }, + { + "U8": 54 + }, + { + "U64": "13184475694240485098" + }, + { + "U8": 42 } ] } }, - "max_gas_amount": "15911564735358519201", - "gas_unit_price": "5059319936941745829", - "expiration_timestamp_secs": "15501906556986466005", - "chain_id": 108 + "max_gas_amount": "17934905217570785534", + "gas_unit_price": "10417178966175803834", + "expiration_timestamp_secs": "12882391350330850198", + "chain_id": 30 }, - "signed_txn_bcs": "d20716d9d7f808c6088d116727cb3f9c65f7c62857e9ce1a3887af299ac3659154e5464ebd5ecad50008d7bbdfc1783cc3da02060606010607ed53b46d636eaa6003f2387e5547550a7752ed853a13eae91c1f66e393b4a7a11d454861794a61644e475a426d79766e70716d554b4b4f6d44456c695832114a584d586f66734642624f6d4f4c46733900020000016738d4ca776a9767a147addfd23bd1dca5e6765ead503646d51e7a86e1d521d76c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400150e63d43fe69f4bbd534460cbf5390843c4ecdf0cd9e9a62ab5ed5ec14329a735270fec3c026da87d60d0b5fc538be81f154b91fa23049c281ec195a23430e", + "signed_txn_bcs": "0147bb288381f9391d5205ca56bd96504f179bb06f7cde296daa96d399926047f2e5d2a81ebdabd3000ff3aedf9d4df710ebf259b13cb8c4c303077eae77bcc63d8168d3a0ca378f687baa3c3cd7bd11f9c3b01d921f99d8497875176c595763454c475077734c686f57444857744179646330176748777378726756667071616b65634b664b536149506f00075801c7ff9ed37b121259c09a6a133ba4570ea06d763639bb481440da7f0e80da1e7152574c727351517a7a796b4f5571566e766b6479586c516d73597657540f4e727870414f745141764b696f4c6c0007f4b49a2684d4acf72151905715970573db51b2bf33f59eaaba5bc0aa8f3941191f53764f57566b4e6a47714a4146774a4c4d4d5871546a4d486873435377573106436e565359350006050102e091efa94e8404471eb5b3c1d68b6d5b012122aa3c6986a249003601eacef920caaaf8b6002afe489bad4595e5f8ba6994c01341919096fb08e6ad72c7b21e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444075bd8966ddc98a0f6c75f583b2a9d1f99a2e2f196f1ba82810751d6be38452d242a1409280ec3bb045b2c409561a04d979ae8109f0303665153f14ee3e72cc0d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "18e7979c691c519b4a74ce0d3bd524299c382182c23d00ec3f6a19e1d370d85e", - "sequence_number": "4362907959864234135", + "sender": "45cceac62a473dcab06238ac17c2557d46faea4df748ffe7484c5ddb343806f0", + "sequence_number": "6118075719813831122", "payload": { "Script": { - "code": "d8a6cad3", + "code": "11eb", "ty_args": [ { - "struct": { - "address": "610cd183e2c4d54352ffc06f614b48f372913d4c8c65161b174d33f965f0f580", - "module": "E2", - "name": "EbIzWaRLFoXkBxZ5", - "type_args": [] + "vector": { + "vector": "bool" } }, { "vector": { - "vector": "address" + "vector": { + "struct": { + "address": "c5294e55ae70a7e6221772d0cce62e803a24ba844f070cba8c3a643adf9ff16e", + "module": "qVuGjFGgFEij", + "name": "cuMS6", + "type_args": [] + } + } } }, { "struct": { - "address": "69f03134932c7a20173b356f8cae864dd5a648c1c5ee64db10e006f6cb4ad11c", - "module": "qxTTkNHkxKSIBk8", - "name": "dtcUmN3", + "address": "70d15cf5bc798916d754b3dfac986d023ea7a4f7a5d5e8a29060762230f10f26", + "module": "kbqoUXH6", + "name": "oqexLOksCIPsbNPmAB2", "type_args": [] } }, { "struct": { - "address": "d282c1fb69662432e03b6db45fb6bc7062e181874468c0f173fc51e22e0450a1", - "module": "FinNXBvkRFrWwZvEiwAH6", - "name": "oodrwDjAuogpknElOhILIQ0", + "address": "3b6f554cd81b5aeaeb871f8cdad1b1ebd1ea5574ea88f9db6f0a1783eec05cab", + "module": "vIhsDahTOiJhjHbRorweZZuTHa3", + "name": "DfkURGhxXUZYrZYErowTZVrm3", "type_args": [] } + } + ], + "args": [ + { + "U128": "214108435312937267759021862276698029454" }, { - "struct": { - "address": "53832e11a4c1d922c3febf5cf4a6412bb7ee90844aa35287448fdb798350fc4b", - "module": "iJBXOSOuzozUbOUbkVDn6", - "name": "zBWHOwH", - "type_args": [] - } + "U8": 36 }, + { + "U64": "7110860009704152941" + }, + { + "U8": 230 + }, + { + "U8": 203 + }, + { + "Bool": true + } + ] + } + }, + "max_gas_amount": "6076078913143743136", + "gas_unit_price": "2197487445196182763", + "expiration_timestamp_secs": "9166162987362567251", + "chain_id": 163 + }, + "signed_txn_bcs": "45cceac62a473dcab06238ac17c2557d46faea4df748ffe7484c5ddb343806f0d21972c473c5e754000211eb04060600060607c5294e55ae70a7e6221772d0cce62e803a24ba844f070cba8c3a643adf9ff16e0c715675476a4647674645696a0563754d5336000770d15cf5bc798916d754b3dfac986d023ea7a4f7a5d5e8a29060762230f10f26086b62716f55584836136f7165784c4f6b7343495073624e506d41423200073b6f554cd81b5aeaeb871f8cdad1b1ebd1ea5574ea88f9db6f0a1783eec05cab1b76496873446168544f694a686a4862526f7277655a5a75544861331944666b555247687858555a59725a5945726f77545a56726d330006028e3ded374498655835c0ed8ae1c813a10024016d5ff2fd80d9ae6200e600cb0501a0a22c3d94915254eb944c49300b7f1e5344142facc0347fa3002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444030b018088eaec9f825b17253fda532a880137d691d87d63ce59a6884541a0b9f717657b0ed1833f61e677b302d513c3ecd19a12e648fa5bf68858f737b962b0b", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "024612fed776ac4b9b3d1183e42bcaeb6e142b0e8a9c18cf3e74b7c644d007f2", + "sequence_number": "11058167725027665747", + "payload": { + "Script": { + "code": "9b63", + "ty_args": [ { "vector": { "struct": { - "address": "566544163696f3543a02d49bb4da0c47a1b32ea7fb982cebaeb5ea179dace470", - "module": "YlhuymArhMAZWDRAbSLYPHhBTux5", - "name": "IRQDayvBDSoPyTCbXyqdIY", + "address": "f4b4f567dfcc3affcec015e52b4cda2ff7762d29c6ed0545a2a808d166f37276", + "module": "PyzwxznUXXygmMOL5", + "name": "NbswNdhwNhRSWrbOPfNJSeQQnRo2", "type_args": [] } } @@ -3878,9 +4137,9 @@ { "vector": { "struct": { - "address": "b54465f5cbaefbae3117df4f9edbb2f99039c919af9bdd8e5c621b2fb1292ed3", - "module": "litO", - "name": "uJEiNvLgpQzUMMdIMfz", + "address": "811dcb065a2be9eee32bc911b254a53ca4bcb55cefda940e6629a37662f1db36", + "module": "SecjHWcpfdqadohTsJabASiGsglm", + "name": "powFnYaWLVtkdGxzqhMUYpiADqUP", "type_args": [] } } @@ -3888,205 +4147,299 @@ { "vector": { "struct": { - "address": "d820541f8f7e124120250c327fed390fe57dc099302e20f167ece61dc55e2057", - "module": "cmPHPYwWKscx", - "name": "qUAypgGvIkdYWczqwM", + "address": "31cc079679423bc49322a21ee60c275499dd0b7bc50e47674680a109402988bb", + "module": "PnuuADrxcQqCTtOJ3", + "name": "bLmeRbuOKCUXtOdEXwdWNVXJTfDqxoun", "type_args": [] } } }, { - "struct": { - "address": "8904f71b7567e980d6d944dde4339b639399a487243b17821e2bcf1300c76dbc", - "module": "Kznx1", - "name": "zJBJmGHBxTYwjXSfbAvXipjHTcZ5", - "type_args": [] + "vector": { + "struct": { + "address": "718ee7b87ba8f334ee9d96ef9aa7b0e76ead5c5c0d44a1b1abe493b3e3502bd7", + "module": "ATmJCQvOISCfO", + "name": "zyoWNgvMNWiEwdMQrXYBAYiReCcKzst9", + "type_args": [] + } } } ], "args": [ { - "U64": "3687411726281348093" + "U8": 68 }, { - "Bool": false + "U64": "13676000934817443644" + }, + { + "U128": "40310899289190009276175955026044235859" + }, + { + "U128": "148899498661687295357316993543427667006" + }, + { + "Bool": true } ] } }, - "max_gas_amount": "14120676573151442337", - "gas_unit_price": "8947925908516791181", - "expiration_timestamp_secs": "1773433781802022082", - "chain_id": 35 + "max_gas_amount": "11312876955957371312", + "gas_unit_price": "8418976261203799233", + "expiration_timestamp_secs": "12144148242640435391", + "chain_id": 167 }, - "signed_txn_bcs": "18e7979c691c519b4a74ce0d3bd524299c382182c23d00ec3f6a19e1d370d85e97906e7fac298c3c0004d8a6cad30907610cd183e2c4d54352ffc06f614b48f372913d4c8c65161b174d33f965f0f580024532104562497a5761524c466f586b42785a35000606040769f03134932c7a20173b356f8cae864dd5a648c1c5ee64db10e006f6cb4ad11c0f717854546b4e486b784b5349426b3807647463556d4e330007d282c1fb69662432e03b6db45fb6bc7062e181874468c0f173fc51e22e0450a11546696e4e5842766b52467257775a76456977414836176f6f647277446a41756f67706b6e456c4f68494c495130000753832e11a4c1d922c3febf5cf4a6412bb7ee90844aa35287448fdb798350fc4b15694a42584f534f757a6f7a55624f55626b56446e36077a4257484f7748000607566544163696f3543a02d49bb4da0c47a1b32ea7fb982cebaeb5ea179dace4701c596c6875796d4172684d415a5744524162534c59504868425475783516495251446179764244536f5079544362587971644959000607b54465f5cbaefbae3117df4f9edbb2f99039c919af9bdd8e5c621b2fb1292ed3046c69744f13754a45694e764c6770517a554d4d64494d667a000607d820541f8f7e124120250c327fed390fe57dc099302e20f167ece61dc55e20570c636d5048505977574b736378127155417970674776496b645957637a71774d00078904f71b7567e980d6d944dde4339b639399a487243b17821e2bcf1300c76dbc054b7a6e78311c7a4a424a6d474842785459776a5853666241765869706a4854635a35000201fd139ca56d512c330500a135df5a87b8f6c38d63a8a5346b2d7cc2b4fce4a0809c1823002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444081e9ddd7000c9d02ca6551e249a4993c29042094570172db55d339277a5ac4eca931f163d5ba2d8381200263310acf6ee484c394cb1ecb5b78dfe43ad4f1880c", + "signed_txn_bcs": "024612fed776ac4b9b3d1183e42bcaeb6e142b0e8a9c18cf3e74b7c644d007f253a7f60cf580769900029b63040607f4b4f567dfcc3affcec015e52b4cda2ff7762d29c6ed0545a2a808d166f372761150797a77787a6e55585879676d4d4f4c351c4e6273774e6468774e6852535772624f50664e4a536551516e526f32000607811dcb065a2be9eee32bc911b254a53ca4bcb55cefda940e6629a37662f1db361c5365636a4857637066647161646f6854734a61624153694773676c6d1c706f77466e5961574c56746b6447787a71684d55597069414471555000060731cc079679423bc49322a21ee60c275499dd0b7bc50e47674680a109402988bb11506e7575414472786351714354744f4a3320624c6d655262754f4b435558744f6445587764574e56584a54664471786f756e000607718ee7b87ba8f334ee9d96ef9aa7b0e76ead5c5c0d44a1b1abe493b3e3502bd70d41546d4a4351764f495343664f207a796f574e67764d4e57694577644d5172585942415969526543634b7a73743900050044013c2fb44364eacabd0253b03f6929a73e158a99830ec898531e023e34ed4f83c1b0a5b138c5d1140005700501b0a18a3ba769ff9cc1ac7fcd4d36d674bf7844f67bae88a8a7002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444087d61aa31f282534aaf498aacd2b0bf8704c7495a6b041e7d62a9c9947f9e4585557cb2a8f8e0bfaf9ffbe6076a8f63b92140747fe803f91c30712022f74d70d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "44222ec7f7261c9c56c6920afc3484484a291c2b9e122adc0bc5e637ca578824", - "sequence_number": "283426149573850337", + "sender": "3a5950e423a8f6e4e1753ae07ffe7d5dfcddfe3ad965ef6c055d4f32f9961bcb", + "sequence_number": "7532924430507795912", "payload": { "Script": { - "code": "c887e314cb5ad003e5d67bdbcc", + "code": "a5de", + "ty_args": [], + "args": [] + } + }, + "max_gas_amount": "9595889026010961157", + "gas_unit_price": "9852539364742002166", + "expiration_timestamp_secs": "5507062235127362974", + "chain_id": 232 + }, + "signed_txn_bcs": "3a5950e423a8f6e4e1753ae07ffe7d5dfcddfe3ad965ef6c055d4f32f9961bcbc86547c0db528a680002a5de000005d5735b3a722b85f6f5ffea5940bb889e35bcd8ec036d4ce8002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144403d0c20d30fbd1eba5b6361de23f20bdb776932e967c1193092b65e8b35bcf7025cbcf14c25b03b3b41ef569e4e4dec8a6e54d329c15c2412de1a63561ac98d08", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "4579ae923262e0410b6f3f8a271d8ac1905230c2050059cc25a3cc1790476616", + "sequence_number": "16976452507296608360", + "payload": { + "Script": { + "code": "450c4bfdb21fa26f", "ty_args": [ { - "struct": { - "address": "753f59cb62a5880149377fd49f45ee1a1f8d96af8575463f014b6b312d505dad", - "module": "AadcbPaPFtQItBmKdOrJDgcXWu0", - "name": "lQrsJfVrPjDsw", - "type_args": [] + "vector": { + "struct": { + "address": "0a052634bce17b953273ec15475397ba9428ed61d3473708fa2f282d88d157bd", + "module": "YRTl", + "name": "AnZoihoJapjFKZPCExXAu7", + "type_args": [] + } } }, { "struct": { - "address": "613528f7ffc05353db4b055b0a0d23c38f5dabbcf49b9d4aab209027dd38de64", - "module": "wOvKLAavjblSoPumHYOKVcWOYoVhSDU", - "name": "MUUApEJUGSiLplAdjYfyRYzFVVw", + "address": "356786e68ed618ac575632846940c9351bc855deb6f95aae6166aaec08f3b925", + "module": "KuPMTIjhElVBQZJiAQPqmnNysEkPfz", + "name": "JaafSY1", "type_args": [] } + } + ], + "args": [ + { + "U128": "104046641615441813557234973536285860546" }, { - "struct": { - "address": "c30e93df9d6ca3211e4da05b1229a39d7cf4a507bf37172c25b34c392dc2426c", - "module": "JLEcUKwlE", - "name": "VJtugYcvxvvAp", - "type_args": [] - } + "Bool": true }, + { + "U64": "14382015018320333836" + } + ] + } + }, + "max_gas_amount": "10997993042044025262", + "gas_unit_price": "13574570577267536110", + "expiration_timestamp_secs": "6019553334104423048", + "chain_id": 87 + }, + "signed_txn_bcs": "4579ae923262e0410b6f3f8a271d8ac1905230c2050059cc25a3cc17904766166830b43b9c7998eb0008450c4bfdb21fa26f0206070a052634bce17b953273ec15475397ba9428ed61d3473708fa2f282d88d157bd045952546c16416e5a6f69686f4a61706a464b5a50434578584175370007356786e68ed618ac575632846940c9351bc855deb6f95aae6166aaec08f3b9251e4b75504d54496a68456c5642515a4a69415150716d6e4e7973456b50667a074a616166535931000302c2a2a3d9f8f60e5012804a3d7ea7464e0501010c0c51c1752e97c7ae7940e166b8a098ee3080d4049062bc88facf49ddbf895357002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ca6bdcab9bbbbee044627b5a3a768b3e844e6b8e0c42674471b82e97575653bd72b1e3f4f7061822ecb3fd46d5b1457a96de8d4bdf097fe1de98aead9a85b404", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "81cfc7eaa52fd59eda217417cf11c5a504e069186fd12e90619f5a913e96b250", + "sequence_number": "711278242712846207", + "payload": { + "Script": { + "code": "169e4cf20dc137d90f32ec7e", + "ty_args": [ { "vector": { - "vector": { - "struct": { - "address": "88dd8a250268408cfc4472167d91d41fbaa554fc07ebf675e1bf8e1a56933e70", - "module": "sHaRy8", - "name": "PymterSuABYUrVvROqhyzBBVwEZE1", - "type_args": [] - } - } + "vector": "u64" } }, { "vector": { "struct": { - "address": "8067864a2daa34ee5aeb0ee8c4a0d404990ebe852ca863d2816f121e126355d9", - "module": "lUMWgYpnBOodt", - "name": "YMVwKeinECCCEEVrdccGTon9", + "address": "25bf0d45b18a42d3243c94c090fbac661ffa2e5e04516d2e134d40a0dd3fb2a2", + "module": "hqgRtTyrpCCjc4", + "name": "kqANPrwaVPnnzMpXeyAdpF9", "type_args": [] } } }, { "struct": { - "address": "228d8ff01f52a2206ba80489952945a3d00a1ba0cc39bb57918fab2b21b0cb5f", - "module": "VvdiuNifYOroQIlpRfGXMcnQN0", - "name": "kCSJ7", + "address": "198306e869e0fcc10918627b9018694da21fe2194d0a45150a40516543b73270", + "module": "fSbrMgMcBU", + "name": "jKgooCsmxAxYf6", "type_args": [] } }, { "struct": { - "address": "44ed43b73682171092fa2b9a5e5a2fd79bf1a7461735ece8e5fe752460b09955", - "module": "VmKsnhrcVWiVViQUFSxDui", - "name": "v0", + "address": "47a40e611cad85d89bf849340b41df21d1d19231500d5b4453f205b531e03c2b", + "module": "KmnAmiOobbnDvnWykBUCkG6", + "name": "TzRKKrZipVeA", "type_args": [] } }, { "struct": { - "address": "a73fa612e44b298bd5c5231a8db9927f47d259361c4b3480bc9b8ec5f8a990af", - "module": "SryFIckVxCSLMd6", - "name": "MRNfQhRfmOllFOVBmHWxG", + "address": "f103cb3f53b7b978ea5c88d526be57be593721f1a63b5841db5a87bd9de9a77d", + "module": "ajRpCVa", + "name": "tSTbwqOTNNHWZfdeHZmy", "type_args": [] } }, { "struct": { - "address": "a14cd86e4541d90b5902d5864a21ae60811a18560aca58de0e829a9ad8fe71be", - "module": "RYGxsPEWkmwZkobOUvgTxinccoGKstf3", - "name": "BE8", + "address": "64a55ab954875a52f3e4fc267d468295017ee89ef2eda47aa730c14d20344a31", + "module": "FxUYAjDbqTvkhVnYbcV1", + "name": "ZqAtOSxlwhEdFWTCIFBc", "type_args": [] } + }, + { + "vector": "address" } ], + "args": [ + { + "Address": "de4fd609ed3ed41cab3d3d32701685781b7eff676a958414a9ed7b73e1a18f33" + }, + { + "U8Vector": "26faefccc6daf30e0ffdfed1" + }, + { + "Bool": true + }, + { + "Address": "c7ede605da94bd1a67c228bebc312eb6f89dad1cf74afab545df2802b034bdfd" + }, + { + "U8": 165 + } + ] + } + }, + "max_gas_amount": "7606180589862811393", + "gas_unit_price": "10059064723437699714", + "expiration_timestamp_secs": "14776157625751617020", + "chain_id": 154 + }, + "signed_txn_bcs": "81cfc7eaa52fd59eda217417cf11c5a504e069186fd12e90619f5a913e96b2507fff5c11cbf7de09000c169e4cf20dc137d90f32ec7e07060602060725bf0d45b18a42d3243c94c090fbac661ffa2e5e04516d2e134d40a0dd3fb2a20e68716752745479727043436a6334176b71414e5072776156506e6e7a4d7058657941647046390007198306e869e0fcc10918627b9018694da21fe2194d0a45150a40516543b732700a665362724d674d6342550e6a4b676f6f43736d784178596636000747a40e611cad85d89bf849340b41df21d1d19231500d5b4453f205b531e03c2b174b6d6e416d694f6f62626e44766e57796b4255436b47360c547a524b4b725a69705665410007f103cb3f53b7b978ea5c88d526be57be593721f1a63b5841db5a87bd9de9a77d07616a5270435661147453546277714f544e4e48575a666465485a6d79000764a55ab954875a52f3e4fc267d468295017ee89ef2eda47aa730c14d20344a311446785559416a44627154766b68566e5962635631145a7141744f53786c7768456446575443494642630006040503de4fd609ed3ed41cab3d3d32701685781b7eff676a958414a9ed7b73e1a18f33040c26faefccc6daf30e0ffdfed1050103c7ede605da94bd1a67c228bebc312eb6f89dad1cf74afab545df2802b034bdfd00a501773e7cf2948e6982c22a1d12fa988bfcbd1abc12750fcd9a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440989a3f3f41e5f454d3e123ebd45a2c9c135973e00915c32d465f122bdc23ad289a3153d03c06f98badfa3cb57eb46ba324345236474d4325cfdd0c3df0dd9004", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "a46a6f4d44b6b0364d5280348a056e2f613f6f5a5f8d80500ea3955f6b852821", + "sequence_number": "13425116749930332988", + "payload": { + "Script": { + "code": "64", + "ty_args": [], "args": [] } }, - "max_gas_amount": "14430727083845081031", - "gas_unit_price": "7556689492896447026", - "expiration_timestamp_secs": "6142095777508616633", - "chain_id": 242 + "max_gas_amount": "7114375590957426350", + "gas_unit_price": "2403789431177497853", + "expiration_timestamp_secs": "4844760987894299668", + "chain_id": 127 }, - "signed_txn_bcs": "44222ec7f7261c9c56c6920afc3484484a291c2b9e122adc0bc5e637ca578824e1f467d594eeee03000dc887e314cb5ad003e5d67bdbcc0907753f59cb62a5880149377fd49f45ee1a1f8d96af8575463f014b6b312d505dad1b41616463625061504674514974426d4b644f724a446763585775300d6c5172734a665672506a4473770007613528f7ffc05353db4b055b0a0d23c38f5dabbcf49b9d4aab209027dd38de641f774f764b4c4161766a626c536f50756d48594f4b5663574f596f56685344551b4d55554170454a554753694c706c41646a59667952597a465656770007c30e93df9d6ca3211e4da05b1229a39d7cf4a507bf37172c25b34c392dc2426c094a4c4563554b776c450d564a74756759637678767641700006060788dd8a250268408cfc4472167d91d41fbaa554fc07ebf675e1bf8e1a56933e70067348615279381d50796d746572537541425955725676524f7168797a42425677455a45310006078067864a2daa34ee5aeb0ee8c4a0d404990ebe852ca863d2816f121e126355d90d6c554d576759706e424f6f647418594d56774b65696e454343434545567264636347546f6e390007228d8ff01f52a2206ba80489952945a3d00a1ba0cc39bb57918fab2b21b0cb5f1a56766469754e6966594f726f51496c70526647584d636e514e30056b43534a37000744ed43b73682171092fa2b9a5e5a2fd79bf1a7461735ece8e5fe752460b0995516566d4b736e68726356576956566951554653784475690276300007a73fa612e44b298bd5c5231a8db9927f47d259361c4b3480bc9b8ec5f8a990af0f5372794649636b567843534c4d6436154d524e66516852666d4f6c6c464f56426d485778470007a14cd86e4541d90b5902d5864a21ae60811a18560aca58de0e829a9ad8fe71be2052594778735045576b6d775a6b6f624f5576675478696e63636f474b73746633034245380000c7d73153d33d44c832fa04860ec1de68b9e9d342911b3d55f2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b147ea5773d5ee90ccb09ca0715adf07bc67a646b90477bf17bfdf410de8c90ef04e60f3d2ba91598e9964d20d1aff3d6125f0c11d01102dc661b6c77f182f0b", + "signed_txn_bcs": "a46a6f4d44b6b0364d5280348a056e2f613f6f5a5f8d80500ea3955f6b8528213c83be038e984fba0001640000ae26ba09e856bb62fd4c2c78c0f95b21143c1c29730c3c437f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ea788ab0fb659cdda200cdce311c228ae10baa46909ff1e89d9378faeb05e3c407a64f37a83f72e6cde646f8c0afff951c9fa9bd6d33fccbefe184601a36ee06", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "4aa7b8854e9e9c510f0586aade10554ebaf87fec1f5d3a1b28b96b89cb829355", - "sequence_number": "1450217912299015648", + "sender": "3d805897cbbf59173aeb2d936e00728a72c441b3c879ba2387cd0a42d23bcb85", + "sequence_number": "3746467104349212564", "payload": { "Script": { - "code": "b4", + "code": "b7aa029e34ee0e6d49f8c7ec8c", "ty_args": [ { "struct": { - "address": "87262487e5b93d502885c2cf3a9b5592b1941ce8c6a8aa14bfe312daa2512e66", - "module": "RyXIbYDcfhp8", - "name": "bJQBOYlZYOjIWeQNi8", + "address": "4132ac9dc2980dc332e2fe1b331739aebb04e99c6fd8172ae043c0b36db51c55", + "module": "pyVWutFGzdUtqyBNRKxDGdYWmcRh", + "name": "zdflNrWd9", "type_args": [] } }, { - "struct": { - "address": "45e6de8b55b4a9fef01ab392a015a73edf0fc211ccac66e996f6f52d286d049d", - "module": "gMkfjhLPRvbuJZxYFzzohBqe1", - "name": "OhAhMvolTIAyoPtInGFMQw", - "type_args": [] + "vector": "signer" + }, + { + "vector": { + "struct": { + "address": "3457e80850406e524ceb354d1dfa8595139bec8a4739de232706528c13a53387", + "module": "hQunQI8", + "name": "aPhmC", + "type_args": [] + } } }, { "struct": { - "address": "d18a5e0d803170b7738b064796ef10f7d745b86b6f9c230fd4b9f386ebe06c0a", - "module": "AehCzDfyCKk", - "name": "UpZMGf6", + "address": "0ef16609bdd1d0aaba7ee85708fd62aceeed466825f2034070d74954b93f8777", + "module": "rUgSK", + "name": "LKFsXYBaRvvVVztOizPRRtykcGYeVZJA", "type_args": [] } }, { "struct": { - "address": "38758fe0d002df8f457a41e4f51efd906a78b101ec45005dc1b1e7e3bdb51060", - "module": "kdsdHgOFrH3", - "name": "mGXnTbEYYdTuVugsTbfykfvoGmDQb", + "address": "1826f9e1574059792e75c6f40be4357802412309240c3107eebb42010e521729", + "module": "oIECFWJfmJydYJCLjGXFxHWtKcCI", + "name": "qVRfIuAVtZcnmEsH6", "type_args": [] } }, { - "struct": { - "address": "9bb23cb0683f1f0b36b3d3322906c1a276ccd1576d8e206739f9e65c823e0f6c", - "module": "DmHc", - "name": "cHEASgyNWFstPRtgDFoEjPdTEVSYKKZ", - "type_args": [] + "vector": { + "struct": { + "address": "d532214513d5ff89e969539127d42beb9a8aa4e389f75ed5b41dc628c2892dac", + "module": "JBJn3", + "name": "hoqApLntVxQv", + "type_args": [] + } } }, { "struct": { - "address": "2ee2064f1e615717bed69460b84349d17adc7b66ca5c45cd9d7d40b45c6398ef", - "module": "vnjep", - "name": "ZxfVzlbjojltjt", + "address": "42cf66bc7ecca3f98bc85d2a75a81fd14dbe96db07a5a57f53b781a94ec0906d", + "module": "AeMxQWFyz", + "name": "nwmByQRzyJlIRJKQOWdxi", "type_args": [] } }, + { + "vector": { + "vector": "bool" + } + }, { "vector": "u128" }, { "vector": { "vector": { - "struct": { - "address": "24ec15a2053fef507c969595d47a62fa5244f2a3c4723f331544f0700bde1f95", - "module": "duNcJjBHgAHkdXewauVAYtUKbtA7", - "name": "IrLfksNXACbOWzPVXSLZCPtViTQljsMy", - "type_args": [] + "vector": { + "vector": "u8" } } } @@ -4094,600 +4447,678 @@ ], "args": [ { - "U8Vector": "7992cd65e825e9ea24263b" - }, - { - "U8Vector": "5dcdbaf47dfa2bae0bad894b" - }, - { - "Bool": true - }, - { - "U8": 170 - }, - { - "U8Vector": "c05e" + "U64": "14643706405178757101" }, { - "U8Vector": "ae4a9317afda4ece3eddd8fcaf3e4e9d" - }, - { - "U64": "8242106911441398398" - }, - { - "U64": "9229237050746261132" - }, - { - "Bool": true - }, - { - "U64": "1017682496720226605" + "Bool": false } ] } }, - "max_gas_amount": "16967000839206206196", - "gas_unit_price": "8760237806306588359", - "expiration_timestamp_secs": "6671490437646032492", - "chain_id": 239 + "max_gas_amount": "5912313607436414234", + "gas_unit_price": "11783603220958470423", + "expiration_timestamp_secs": "6999602012720126811", + "chain_id": 235 }, - "signed_txn_bcs": "4aa7b8854e9e9c510f0586aade10554ebaf87fec1f5d3a1b28b96b89cb829355e0cd7df5813520140001b4080787262487e5b93d502885c2cf3a9b5592b1941ce8c6a8aa14bfe312daa2512e660c52795849625944636668703812624a51424f596c5a594f6a495765514e6938000745e6de8b55b4a9fef01ab392a015a73edf0fc211ccac66e996f6f52d286d049d19674d6b666a684c50527662754a5a7859467a7a6f6842716531164f6841684d766f6c544941796f5074496e47464d51770007d18a5e0d803170b7738b064796ef10f7d745b86b6f9c230fd4b9f386ebe06c0a0b416568437a446679434b6b0755705a4d476636000738758fe0d002df8f457a41e4f51efd906a78b101ec45005dc1b1e7e3bdb510600b6b64736448674f467248331d6d47586e546245595964547556756773546266796b66766f476d44516200079bb23cb0683f1f0b36b3d3322906c1a276ccd1576d8e206739f9e65c823e0f6c04446d48631f634845415367794e574673745052746744466f456a506454455653594b4b5a00072ee2064f1e615717bed69460b84349d17adc7b66ca5c45cd9d7d40b45c6398ef05766e6a65700e5a7866567a6c626a6f6a6c746a7400060306060724ec15a2053fef507c969595d47a62fa5244f2a3c4723f331544f0700bde1f951c64754e634a6a42486741486b64586577617556415974554b627441372049724c666b734e584143624f577a505658534c5a435074566954516c6a734d79000a040b7992cd65e825e9ea24263b040c5dcdbaf47dfa2bae0bad894b050100aa0402c05e0410ae4a9317afda4ece3eddd8fcaf3e4e9d017eaa414191d86172018cce9af532d614800501012d4924bfd6881f0ef4faa3445ee576ebc7f6d900df9d92796c9e4eba34e5955cef002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144401bf16e1c51eb6d3b4dae71dec29eeb511fb2826fbec9569fa605ff77e6e733658e829a035a3d1b719947d39e768e8d42b17fdaa7277aeda9f7bf53bf11d1560a", + "signed_txn_bcs": "3d805897cbbf59173aeb2d936e00728a72c441b3c879ba2387cd0a42d23bcb8594cf6b55fb1ffe33000db7aa029e34ee0e6d49f8c7ec8c0a074132ac9dc2980dc332e2fe1b331739aebb04e99c6fd8172ae043c0b36db51c551c70795657757446477a6455747179424e524b7844476459576d635268097a64666c4e7257643900060506073457e80850406e524ceb354d1dfa8595139bec8a4739de232706528c13a53387076851756e514938056150686d4300070ef16609bdd1d0aaba7ee85708fd62aceeed466825f2034070d74954b93f877705725567534b204c4b46735859426152767656567a744f697a50525274796b63475965565a4a4100071826f9e1574059792e75c6f40be4357802412309240c3107eebb42010e5217291c6f49454346574a666d4a7964594a434c6a475846784857744b634349117156526649754156745a636e6d45734836000607d532214513d5ff89e969539127d42beb9a8aa4e389f75ed5b41dc628c2892dac054a424a6e330c686f7141704c6e7456785176000742cf66bc7ecca3f98bc85d2a75a81fd14dbe96db07a5a57f53b781a94ec0906d0941654d78515746797a156e776d427951527a794a6c49524a4b514f5764786900060600060306060606010201edcfcacb63e538cb05001aadf4b3e6c10c5217e1607fb2c487a35bdb4af1f1942361eb002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f7b2f5ecd3d484ad0c718dd8841312b4da92e7ec70c4996efd060b303bdab9847c90aa867a93a7d324a6620d26a810a14294248c80e06fa8c91082a771ea7c0a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "441b7b6347cee0f0657ed796b1fe948b76a9cf7071c2cf5c4f5df01011641a3f", - "sequence_number": "9541883071816858300", + "sender": "ab4b5acae40a5b6613e3b6ff3850f424b28842f89325957cdda0d8080687e807", + "sequence_number": "12164948521843264589", "payload": { "Script": { - "code": "685f28ddeefd596aa279e67188ef", + "code": "f55a57", "ty_args": [ { "vector": { - "struct": { - "address": "3903b0ce42b03dbc1eec6f6e36a4d179be2081d124857fa907702f3e2be9feb4", - "module": "asEUHDWhRxmSSUpQjeqTSbMrZnlzqwF6", - "name": "y", - "type_args": [] - } + "vector": "signer" } }, { "vector": { "vector": { - "struct": { - "address": "0cd69cbc33932eeaf457c011f63a3b78feecd9abba11f01d0e25026c5b94d619", - "module": "GM", - "name": "yKNbTAtXrLbaLeDryqFNsGNFQTJTrbgy2", - "type_args": [] - } + "vector": "bool" } } + }, + { + "struct": { + "address": "2db6932dfd073b2d6036ecea1d3e86ab301d976bb8e8d880cd91e407cf9f3a3e", + "module": "N6", + "name": "OrhTtdDQzycsanzVcaRIoJCEBjZ4", + "type_args": [] + } } ], "args": [ { - "U8Vector": "21adb535cfb0" + "Bool": false + }, + { + "Address": "de8d9be3bfcb042cd7796af690798d16012fd7ccc7dbae2037a7a6c34d9b2d7e" }, { - "U64": "2780841581946207986" + "U64": "15023193589304839973" }, { - "Address": "f30cad00aa2b1a0ad18f524b598a8523d56d1b65fd2f9a61b254e03e116ea56a" + "Bool": true }, { - "U8Vector": "beca63e9cfa8dc5c8efc6a0cf2ccb1f0" + "U8": 38 }, { - "U128": "192227257179974796427444501406979264718" + "U8": 215 }, { - "U64": "4433355884256655353" + "U128": "107441138282805897602104491545465274579" + }, + { + "U8": 173 + }, + { + "Bool": true } ] } }, - "max_gas_amount": "12959706881503430118", - "gas_unit_price": "9336195391619533489", - "expiration_timestamp_secs": "13582988879818119321", - "chain_id": 254 + "max_gas_amount": "2745873013984181297", + "gas_unit_price": "11444160966442979378", + "expiration_timestamp_secs": "17341343472857252680", + "chain_id": 107 }, - "signed_txn_bcs": "441b7b6347cee0f0657ed796b1fe948b76a9cf7071c2cf5c4f5df01011641a3fbcfaf44719946b84000e685f28ddeefd596aa279e67188ef0206073903b0ce42b03dbc1eec6f6e36a4d179be2081d124857fa907702f3e2be9feb420617345554844576852786d53535570516a65715453624d725a6e6c7a717746360179000606070cd69cbc33932eeaf457c011f63a3b78feecd9abba11f01d0e25026c5b94d61902474d21794b4e6254417458724c62614c6544727971464e73474e4651544a5472626779320006040621adb535cfb001f2fe896caf88972603f30cad00aa2b1a0ad18f524b598a8523d56d1b65fd2f9a61b254e03e116ea56a0410beca63e9cfa8dc5c8efc6a0cf2ccb1f002ce1075244e793b7e78f0dfb6819f9d9001f9770114b071863de68532c9be20dab3b10a1f4f3ed4908199d8a3a16b7880bcfe002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b817870bb734e3f9fc045bc4eafdd8ee4ce93d04950dbbab1af24eddae1761cfa1d3ab8f4cae41f2f944e34ecd01a6ed02bc266b062dc30c2356727edf3fdd0b", + "signed_txn_bcs": "ab4b5acae40a5b6613e3b6ff3850f424b28842f89325957cdda0d8080687e8074d8c615b3a94d2a80003f55a570306060506060600072db6932dfd073b2d6036ecea1d3e86ab301d976bb8e8d880cd91e407cf9f3a3e024e361c4f726854746444517a796373616e7a56636152496f4a4345426a5a340009050003de8d9be3bfcb042cd7796af690798d16012fd7ccc7dbae2037a7a6c34d9b2d7e0125cf7022f91a7dd00501002600d702d34045cecdf93b4931eff5a81969d45000ad050131bcdb3cf54c1b26329039e5c3d3d19e4803b29b02d4a8f06b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444086e6dbc320ca4daf14941d30b8c31655479c77b22586da9a17e611d9885061d8117e73788f2bbd49a17be0829c1047e302a5928640c741c40c6c305d93228202", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "61b8ddf45ddc9c4e8e0df85cfa67d99d384547059d05343e3dbffc355298d778", - "sequence_number": "3212491976351734433", + "sender": "989410a1c746118cbac9fa3715d2e55db51a306afaf629430c6c521429c8e461", + "sequence_number": "12558573004730147143", "payload": { "Script": { - "code": "ba0d", + "code": "7ddef6a0", "ty_args": [ + { + "struct": { + "address": "0046e75f00dd6f8d91e169399bae6ec0c7f636673b6bac61306b19a8434af339", + "module": "AJqcbVzMtnreJUPu7", + "name": "JEps", + "type_args": [] + } + }, { "vector": { - "struct": { - "address": "92b0f3db859899f0fa3800af6025e9302a6304699daf9991a909500300d6d5d0", - "module": "omAypCVPvaQA", - "name": "qqYIBBeHvTrUyyvkqfOjTySPBIF0", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "85ba76b985c0e8d7136d50b9d6379dc181cbfd04ab55d6aa8faa8ff2be0632ed", + "module": "aLwPmX", + "name": "cwSlZRWWvKZICfFFytwIVgtCgwG", + "type_args": [] + } + } } } + }, + { + "vector": "u128" + }, + { + "struct": { + "address": "0fa5510d3969294f0d417eab6c82a5e234b3dbfb1cc01a9dd0a58048eec3c0a6", + "module": "tGicVGZVxtYsuQeLwIFyPRswnepjy", + "name": "AismbdviMnYRRBomQYjH", + "type_args": [] + } + }, + { + "struct": { + "address": "5b7edd8739ec790d7f4b19280e8e73298a20dc5ecabdcc3453990fc576159a45", + "module": "GrlYvXWpbFmqmEuXOcLXkSfxSWlELvG1", + "name": "GVlvYFUESIVyjskjzzMpmrXWgfy2", + "type_args": [] + } } ], "args": [ { - "U64": "142094399836878917" + "Address": "9f6c5d6d22e03d1ade727299588085a949dc743119e7ce3bd3b01df1f25c4bc2" + }, + { + "Bool": false + }, + { + "U8": 58 + }, + { + "U8": 233 + }, + { + "U128": "144238845553776560038062209844056854386" }, { - "U8": 80 + "Bool": true + }, + { + "Bool": true + }, + { + "Bool": false + }, + { + "Address": "598b457a8e064b814a78e43727c31df86c58f53337e2ad25492cb9b4f1f07c08" } ] } }, - "max_gas_amount": "13152095560504917519", - "gas_unit_price": "8194314105725481846", - "expiration_timestamp_secs": "3020176361718574651", - "chain_id": 169 + "max_gas_amount": "1297830983944135860", + "gas_unit_price": "6906583924764589407", + "expiration_timestamp_secs": "12970449795987964072", + "chain_id": 3 }, - "signed_txn_bcs": "61b8ddf45ddc9c4e8e0df85cfa67d99d384547059d05343e3dbffc355298d778a1da3c966e10952c0002ba0d01060792b0f3db859899f0fa3800af6025e9302a6304699daf9991a909500300d6d5d00c6f6d417970435650766151411c7171594942426548765472557979766b71664f6a54795350424946300002014578d9921ad2f80100500f3ee3bf3aa185b67673bd89430db8713b6e443f66d2e929a9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406fd25f678cb44b8197fd9754c99316493f058612329f5d26d0f2da570517f6b70c009952ffd23f63d1fa8718e1b59a181c51dbfe982b9fb416d76d26ef61710d", + "signed_txn_bcs": "989410a1c746118cbac9fa3715d2e55db51a306afaf629430c6c521429c8e4614721c0109c0349ae00047ddef6a005070046e75f00dd6f8d91e169399bae6ec0c7f636673b6bac61306b19a8434af33911414a716362567a4d746e72654a55507537044a457073000606060785ba76b985c0e8d7136d50b9d6379dc181cbfd04ab55d6aa8faa8ff2be0632ed06614c77506d581b6377536c5a525757764b5a49436646467974774956677443677747000603070fa5510d3969294f0d417eab6c82a5e234b3dbfb1cc01a9dd0a58048eec3c0a61d7447696356475a56787459737551654c77494679505273776e65706a79144169736d626476694d6e595252426f6d51596a4800075b7edd8739ec790d7f4b19280e8e73298a20dc5ecabdcc3453990fc576159a452047726c597658577062466d716d4575584f634c586b53667853576c454c7647311c47566c7659465545534956796a736b6a7a7a4d706d725857676679320009039f6c5d6d22e03d1ade727299588085a949dc743119e7ce3bd3b01df1f25c4bc20500003a00e902728f624f6ae1e76b7d726a582464836c05010501050003598b457a8e064b814a78e43727c31df86c58f53337e2ad25492cb9b4f1f07c08b4647c5867d202125f3d04a77c1dd95fa880e67a5e4b00b403002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c66569f93b7599bc078b82c0579a08ce4aa300469b750b9d566ebe601e3dd2d295b2eea05a68bd87ac54feaf7372890bb6e4de528ea6e236b7b1dc6563d0e80f", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "4eda6e8eefbdfa3ee1c11073c7f94a97f91da12097685d0f5f1ffe54175acee0", - "sequence_number": "18175735931542196744", + "sender": "e1543e28c5da0cef76e208bd7aad105f1bcad7af1d9dca8c529cbe6e8eeaa5ce", + "sequence_number": "8294062215890220949", "payload": { "Script": { - "code": "89d7e8db1fb98aceff4f429eaf66", + "code": "5a", "ty_args": [ { "vector": { - "vector": { - "vector": "u128" + "struct": { + "address": "97d185c3a8c46c71f0246b10165942394b3c9dc32cdd8f4c65e17f1368d8b66e", + "module": "XFPJMCKCxXflQCEOknXUBmluCZCf3", + "name": "wlHJQAEtlIrOStKAlKhHpnzE3", + "type_args": [] } } }, + { + "vector": { + "vector": "u64" + } + }, + { + "struct": { + "address": "f67fa62940c3472220abe9e18619a54656d9cf5ad985adce71a87fe8941ec5b3", + "module": "mMVKamxMzFkOATNBU", + "name": "EKiQrmEXEnWpPFVWaYLcWXNAJjhAjkw", + "type_args": [] + } + }, { "vector": { "struct": { - "address": "5a0f659986dba9af858d3208d945eee00f9d039ab1f24eecc30dfc6eb6f595c7", - "module": "SyQ5", - "name": "PTqriMpePAiJqgwnPrkettbXAath", + "address": "0db31a172a0f0f5a827cbd692d4cd110385f8f87c50433e7a2aba59cfd4ac829", + "module": "msvJgUcz", + "name": "LmiKtoHYBKLnOoCm5", "type_args": [] } } - } - ], - "args": [] - } - }, - "max_gas_amount": "11041327343616192605", - "gas_unit_price": "5916981571310921152", - "expiration_timestamp_secs": "15095098698483063373", - "chain_id": 79 - }, - "signed_txn_bcs": "4eda6e8eefbdfa3ee1c11073c7f94a97f91da12097685d0f5f1ffe54175acee00852e0d2872f3dfc000e89d7e8db1fb98aceff4f429eaf66020606060306075a0f659986dba9af858d3208d945eee00f9d039ab1f24eecc30dfc6eb6f595c704537951351c50547172694d70655041694a7167776e50726b65747462584161746800005df00c35b8ac3a99c02585bc63571d524d5a8bfc49907cd14f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400cbf2e5832ab699c8c58f662b1f1d60b62b9f4f00d763206285a0ee25f06dba0dc17d4620adacff71342d2b25b52c206afec913f5a8062696831779b40455b09", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "62730bf48724ca92aa775838ed73b3faaf5309fe52faa1eb74bce6868db33aef", - "sequence_number": "10556944518786229831", - "payload": { - "Script": { - "code": "e2ad17ad1ba64f3fcf116cf3b2274e", - "ty_args": [ + }, { "struct": { - "address": "209809ccd9ae66ab3cc8cf42aa872dc62b468e730bc0a881bf1953a0c0e9fe62", - "module": "rrlkbypSCBJdpVvyBEeu", - "name": "IxcEwKuzKuEMLurnFBpwHgj", + "address": "044a4de5e29038d6d1ce953b8849d496d5da2ffa08c8f03467c6f04aa76cc71c", + "module": "iYDcMrnhmVmVUGZFHqcFgcDanEs1", + "name": "VzqmTvXUyRoagQFsDMnZ1", "type_args": [] } - } - ], - "args": [] - } - }, - "max_gas_amount": "14395772647879255167", - "gas_unit_price": "13398674410878513211", - "expiration_timestamp_secs": "7479244747097403500", - "chain_id": 103 - }, - "signed_txn_bcs": "62730bf48724ca92aa775838ed73b3faaf5309fe52faa1eb74bce6868db33aef47a6c2531bcd8192000fe2ad17ad1ba64f3fcf116cf3b2274e0107209809ccd9ae66ab3cc8cf42aa872dc62b468e730bc0a881bf1953a0c0e9fe621472726c6b6279705343424a6470567679424565751749786345774b757a4b75454d4c75726e4642707748676a00007fa42080f30ec8c73bb0873163a7f1b96c70f282789dcb6767002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402c57f607bb7ec4fee2c4f5808147aaee2164e0687477e57d9db079e6f303c864665b5aba8036a3f547464fb480ee1e889630d4523d1a454ab1529a74011f2904", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "07360613a42e0911c55556a6b95d7d75f3b2ac275ef04513a0be712d3fc96075", - "sequence_number": "3115872219421417690", - "payload": { - "Script": { - "code": "dbe9a4a939fae7a14ca1024eeaef", - "ty_args": [ + }, + { + "struct": { + "address": "0d4b2a9a78836bf90c02df0257af021948205aa6c83228d4177e912e82a1f4eb", + "module": "CxJ5", + "name": "qaHjzynVtZucakHLiCcKiKWy4", + "type_args": [] + } + }, + { + "struct": { + "address": "0926fd406fe0370168a89b3b6fcd17ba4b40009ca29fb9d3ffc754ddc758050e", + "module": "uM", + "name": "xsHdASItWuk", + "type_args": [] + } + }, { "vector": { "vector": { - "struct": { - "address": "178a131a43a79b9c16f68d9613c79225756237814d6777d36e8ff2bee66e71f1", - "module": "RiLnzOGSRNnVBThRVCMUkgYe", - "name": "THUDxy3", - "type_args": [] - } + "vector": "address" + } + } + }, + { + "vector": { + "struct": { + "address": "41c3a34677bb78bdb5b57c46644421812f59696241a7d9b52acb2c5950571782", + "module": "ZydPHgZCtwBevFLyk3", + "name": "hBxCXhWkvxDmYFPBIfvMYPgmEe2", + "type_args": [] } } }, { "struct": { - "address": "aac8d1201799209af0b18541b91cce7ed006a09e61a4b0520d42310a872744fd", - "module": "JcWexNKqniTVaMBTQmySnWgQAjbE5", - "name": "IChGIFrmunOTbFTdPWFwpUYApolh4", + "address": "cfe9818db1d2bbf167fa473e5c4bec8ad0347bd774f262db245a585b3a906e53", + "module": "HRvDwawmtvtmQxLpChftyOLwEFGJuX8", + "name": "JPlLFZ4", "type_args": [] } } ], "args": [ { - "U128": "297717619728410700700382732537971135833" - }, - { - "U128": "125999204074353536081384399435688995445" - }, - { - "U8": 116 + "U64": "10112216091735588454" }, { - "U64": "8167598841516669270" + "Bool": false }, { - "Bool": true + "U128": "317989941949335886294221571572048072363" } ] } }, - "max_gas_amount": "6313298336391918973", - "gas_unit_price": "14925550415676924965", - "expiration_timestamp_secs": "6678369736510502456", - "chain_id": 32 + "max_gas_amount": "17080536540619536888", + "gas_unit_price": "15671376401493888273", + "expiration_timestamp_secs": "8193437490374087183", + "chain_id": 131 }, - "signed_txn_bcs": "07360613a42e0911c55556a6b95d7d75f3b2ac275ef04513a0be712d3fc96075da201f6446cd3d2b000edbe9a4a939fae7a14ca1024eeaef02060607178a131a43a79b9c16f68d9613c79225756237814d6777d36e8ff2bee66e71f11852694c6e7a4f4753524e6e564254685256434d556b67596507544855447879330007aac8d1201799209af0b18541b91cce7ed006a09e61a4b0520d42310a872744fd1d4a635765784e4b716e695456614d4254516d79536e576751416a6245351d494368474946726d756e4f54624654645057467770555941706f6c683400050259d5b0f643255e62c51eb8fcef53fadf02756abe2e2979c5bdc6b279ee6290ca5e00740156397e60df23597105017d75b43d63579d5725649b2b063522cf38766d4fe455ae5c20002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ec8670c530958c5944d35e509bac04e2f531382a0e42efac7aa134cf16a1a15157b54a1230fb868d69d571ff755f64c6d27274fb563cb621d78ca447bbf2a408", + "signed_txn_bcs": "e1543e28c5da0cef76e208bd7aad105f1bcad7af1d9dca8c529cbe6e8eeaa5ce9537203ba46d1a7300015a0a060797d185c3a8c46c71f0246b10165942394b3c9dc32cdd8f4c65e17f1368d8b66e1d5846504a4d434b437858666c5143454f6b6e5855426d6c75435a43663319776c484a514145746c49724f53744b416c4b6848706e7a45330006060207f67fa62940c3472220abe9e18619a54656d9cf5ad985adce71a87fe8941ec5b3116d4d564b616d784d7a466b4f41544e42551f454b6951726d4558456e57705046565761594c6357584e414a6a68416a6b770006070db31a172a0f0f5a827cbd692d4cd110385f8f87c50433e7a2aba59cfd4ac829086d73764a6755637a114c6d694b746f4859424b4c6e4f6f436d350007044a4de5e29038d6d1ce953b8849d496d5da2ffa08c8f03467c6f04aa76cc71c1c695944634d726e686d566d5655475a4648716346676344616e45733115567a716d5476585579526f6167514673444d6e5a3100070d4b2a9a78836bf90c02df0257af021948205aa6c83228d4177e912e82a1f4eb0443784a35197161486a7a796e56745a7563616b484c6943634b694b57793400070926fd406fe0370168a89b3b6fcd17ba4b40009ca29fb9d3ffc754ddc758050e02754d0b787348644153497457756b0006060604060741c3a34677bb78bdb5b57c46644421812f59696241a7d9b52acb2c5950571782125a79645048675a437477426576464c796b331b684278435868576b7678446d594650424966764d5950676d4565320007cfe9818db1d2bbf167fa473e5c4bec8ad0347bd774f262db245a585b3a906e531f485276447761776d7476746d51784c7043686674794f4c774546474a755838074a506c4c465a34000301667ee367f5ce558c050002ab0ed86d8b2a1d32a15e395197a23aeff8f9b4b47c410aed118d7b80cee97bd90f921d9ffcefb47183002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444097af3f8677a46a8a17ca6571c0dda30a37a2333a6a155eefaf868c7393aaaf4e3b71bdd73a43687204ca8b3f6a2f6bf1c53d2795c87f5bed2ade19b4bac09107", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "0456d5e204ce08283c3e11193387ec351956074c843228aa64ebc4a5ccd83637", - "sequence_number": "9952221749218452634", + "sender": "41b9f50a50ea506e61fdccb02526967426e115814d1a27810498e70744810e44", + "sequence_number": "3169051079518170606", "payload": { "Script": { - "code": "0d51", + "code": "635a94be9a626aace3b7", "ty_args": [ + { + "vector": { + "struct": { + "address": "2d9afe46b41d01211e589c5ba29c1bbc46211454e74e791581d50c9f6c373f3d", + "module": "tyPbaDVOoFMzJGMSnmJPEluy7", + "name": "jbgudGQYml", + "type_args": [] + } + } + }, { "struct": { - "address": "f55d7856b8bed9212aa359eea9ff7949fd9f46141a066b4f34727574ac497214", - "module": "SomZbWlWFzWyOlhKLHnQn", - "name": "nky2", + "address": "56fe9573b96d45001142200ef7c09efdf2c81aa8f979533db6f41c9d46130b02", + "module": "MWzoyYLMYzOvnyvEa", + "name": "PQwa", "type_args": [] } }, { "vector": { "struct": { - "address": "6830905b96a08c3cabb7d977ec793088d1e7b1fc5c0604e307413167e56229ed", - "module": "SkpquyJWAzZYuEpoGlSPzui4", - "name": "hDJJmIOBOyhdvbPVqi", + "address": "5fbd9127c6c9d3606cc2afa04b4d1d1bb905ad4682df24e11ae2e56af8876836", + "module": "QhACo", + "name": "nZQrdgcPsXBpGAoqNMipNsnrwESgfapC", "type_args": [] } } }, { "struct": { - "address": "caf185f139725d867896546f628376edd832c7bd751e90b04630263abebe0754", - "module": "uTDTxouigFleWbQuB", - "name": "GdybKVNrKauVckJ", + "address": "ac117a15b4e6846d8c509bb821c9752cc6370a74fcdb4c39211148e02dbbf97c", + "module": "QqPoXhEpRhctDxYgnoQDNBUehyO8", + "name": "vQPbUselGHQUgNyoYHo8", "type_args": [] } }, { "struct": { - "address": "117d8b4d6819ae3a247f82dcde9d2076c087ef97250a3c5d51d6e95528ab8e27", - "module": "cFOtdRxsHcIZouhbKVjskjiVbBU", - "name": "zdZYBaCrPAwGtBc", + "address": "e08e6ebb7ea489e6bf0a920cb245916271a8dd4d7b041dc5b09406cea1400fc4", + "module": "ELFDO", + "name": "AvNXvetGPpTpIUptOIYdHyhWCrEAS", "type_args": [] } }, { "vector": "signer" }, - { - "vector": "bool" - }, { "struct": { - "address": "159b3a6d9115d32f95215621c51ee2528ee9293624743db144e8ad3519501914", - "module": "vzAHzulEjkdZfLciMYEWTROWenubMlUA9", - "name": "rVgCQWDyrIDYcCUjTBhEplm5", + "address": "c6a51a4b837704807f4ac74edb431cab2ecdf24bed2c6db23b8ec4058f1df7c7", + "module": "xnWrYNLyMUfmopPjfHdICeMzcAmE8", + "name": "wRrGocQyEVi", "type_args": [] } + } + ], + "args": [ + { + "Address": "7c50618da0ce06282deba37c5040b1ebaa26979a3b602c6c3e6a969190584e19" }, { - "vector": { - "vector": "bool" - } + "U64": "278800393134973744" }, { - "struct": { - "address": "bf535000de174f1dcc6dc183f7815b0a2e9b112224bfde9232b82d51a04ca046", - "module": "eZoaiviMlDNQysTOEUeKeMtn", - "name": "iUqhrKwJKTLzTK5", - "type_args": [] - } + "Bool": true }, { - "struct": { - "address": "a17e352a212c178aa3c77f3c29926f9b162d542ee1476e1bb27a359533f71726", - "module": "hvSKvkSpzijIaI5", - "name": "rPhQzdaNIwMwSPT", - "type_args": [] - } - } - ], - "args": [ + "U8": 250 + }, + { + "U64": "15335735909415376237" + }, + { + "U128": "79816927670890525972803969110632030421" + }, + { + "U64": "17930027732171610781" + }, + { + "Address": "3cb9bdb07f2f8daa5aac91c4505edf29331cad8ca1a428b4146cf9d690a22383" + }, { - "U128": "83212402971793114539665000330304910125" + "U8": 166 }, { - "U64": "1621105024004393239" + "U128": "312305964016387277572647613022444348585" } ] } }, - "max_gas_amount": "14344898315039182053", - "gas_unit_price": "10754005830704235827", - "expiration_timestamp_secs": "6867936405135539567", - "chain_id": 28 + "max_gas_amount": "15715777892768735142", + "gas_unit_price": "8113771906591471746", + "expiration_timestamp_secs": "4423052659580801412", + "chain_id": 242 }, - "signed_txn_bcs": "0456d5e204ce08283c3e11193387ec351956074c843228aa64ebc4a5ccd836379a2415a8f3641d8a00020d510a07f55d7856b8bed9212aa359eea9ff7949fd9f46141a066b4f34727574ac49721415536f6d5a62576c57467a57794f6c684b4c486e516e046e6b79320006076830905b96a08c3cabb7d977ec793088d1e7b1fc5c0604e307413167e56229ed18536b707175794a57417a5a597545706f476c53507a7569341268444a4a6d494f424f7968647662505671690007caf185f139725d867896546f628376edd832c7bd751e90b04630263abebe07541175544454786f756967466c6557625175420f476479624b564e724b617556636b4a0007117d8b4d6819ae3a247f82dcde9d2076c087ef97250a3c5d51d6e95528ab8e271b63464f74645278734863495a6f7568624b566a736b6a69566242550f7a645a594261437250417747744263000605060007159b3a6d9115d32f95215621c51ee2528ee9293624743db144e8ad351950191421767a41487a756c456a6b645a664c63694d59455754524f57656e75624d6c554139187256674351574479724944596343556a54426845706c6d350006060007bf535000de174f1dcc6dc183f7815b0a2e9b112224bfde9232b82d51a04ca04618655a6f616976694d6c444e517973544f4555654b654d746e0f69557168724b774a4b544c7a544b350007a17e352a212c178aa3c77f3c29926f9b162d542ee1476e1bb27a359533f717260f6876534b766b53707a696a496149350f725068517a64614e49774d775350540002022d7323b31160db497e35098b38209a3e011709622b6e527f16e58c02d7035113c733059b6b53e73d956fbd13c8c5cf4f5f1c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440dd147d7ba3fbbcfd9ff9f77ad0973594652a2f2fb418946f245bc4084372ca1dd5341b5c6327fcea7ca1f66160258d38985296ebe900e4efed0a2f1806e34506", + "signed_txn_bcs": "41b9f50a50ea506e61fdccb02526967426e115814d1a27810498e70744810e44eeadbf9d2abbfa2b000a635a94be9a626aace3b70706072d9afe46b41d01211e589c5ba29c1bbc46211454e74e791581d50c9f6c373f3d19747950626144564f6f464d7a4a474d536e6d4a50456c7579370a6a626775644751596d6c000756fe9573b96d45001142200ef7c09efdf2c81aa8f979533db6f41c9d46130b02114d577a6f79594c4d597a4f766e7976456104505177610006075fbd9127c6c9d3606cc2afa04b4d1d1bb905ad4682df24e11ae2e56af887683605516841436f206e5a5172646763507358427047416f714e4d69704e736e7277455367666170430007ac117a15b4e6846d8c509bb821c9752cc6370a74fcdb4c39211148e02dbbf97c1c5171506f5868457052686374447859676e6f51444e42556568794f3814765150625573656c47485155674e796f59486f380007e08e6ebb7ea489e6bf0a920cb245916271a8dd4d7b041dc5b09406cea1400fc405454c46444f1d41764e587665744750705470495570744f49596448796857437245415300060507c6a51a4b837704807f4ac74edb431cab2ecdf24bed2c6db23b8ec4058f1df7c71d786e5772594e4c794d55666d6f70506a6648644943654d7a63416d45380b775272476f635179455669000a037c50618da0ce06282deba37c5040b1ebaa26979a3b602c6c3e6a969190584e190130a30cfc7a7fde03050100fa016dd5e7b18e7ad3d402d5e06b492531ad5906eedb075d2e0c3c019ddafd9c3941d4f8033cb9bdb07f2f8daa5aac91c4505edf29331cad8ca1a428b4146cf9d690a2238300a602a96446a4ac10cdb7230c9fadd7f0f3eaa6df6a4bbaa819da82b8ed788fe89970841129a5f5d6613df2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f7aab8724aff5c2b39130d1e5315cdc09f3dfd10abae2e2270fca0b51a4b424b36437b93891f89465fc1cada655cfdd059d34ccc2c5b8bffbf2cace5fcaa5b09", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "9f8ae0665c221eab106be5608d96146cbd7f5825a07586606e1ceea473e3b7b2", - "sequence_number": "16067698781839025786", + "sender": "7cd7b709714bbd423e8ef860629574fe317196d63125a625e329a4284f5b1951", + "sequence_number": "5946583572668348617", "payload": { "Script": { - "code": "c5ffd5fd130ee2f74f80b0fffb9a4b38", + "code": "188c101d4f5f2efb4b5bba", "ty_args": [ { "vector": { - "struct": { - "address": "ad42e70ec430100b014220bdb7f48149fe8f480f3565573f023ff55964d72acf", - "module": "zoqPVreJGvJIYDBRVdjWudwROvby", - "name": "zGAmHoUhLbutrLAfYwGJYFLb4", - "type_args": [] + "vector": { + "struct": { + "address": "58d44a7a65c18fad7154d96e289ad1e99289491a42f14b9bb0fe57dfb50f6666", + "module": "jBPAbjmfmaOLx", + "name": "SrYpsJgF", + "type_args": [] + } } } + } + ], + "args": [ + { + "Address": "905e8281f6b0274c0c64702dfd53bb75eab8ba74607ca205cb8fba10f19b3d21" }, { - "struct": { - "address": "455581f4752f77cbe78b98ba07e114a6506e1ec72f1a3e9829785b253a0def36", - "module": "RaKkCdSvlQmslhcXRnyohXJEZIoJ3", - "name": "pltkiDKwiVwGsthlcvME", - "type_args": [] - } + "U64": "7780955474889081499" + }, + { + "U8Vector": "74" + }, + { + "U128": "248693895592419659934728610523660644337" + }, + { + "Bool": false + }, + { + "U8Vector": "30f5fbd8cd50cad5ab36f6ab417f" + }, + { + "U8Vector": "fa25ce11ecaaec88017efc3335" + }, + { + "Address": "a659920b5d3ae685e437fb87e4daac09255d065df57daf1a34925dd58125b983" + }, + { + "U8Vector": "dbb43eef" + }, + { + "Bool": true } - ], - "args": [] + ] } }, - "max_gas_amount": "15535092722645356811", - "gas_unit_price": "8173556935965178537", - "expiration_timestamp_secs": "15109467814014306650", - "chain_id": 104 + "max_gas_amount": "69315318454741073", + "gas_unit_price": "3933576690278203516", + "expiration_timestamp_secs": "4439421401642006109", + "chain_id": 99 }, - "signed_txn_bcs": "9f8ae0665c221eab106be5608d96146cbd7f5825a07586606e1ceea473e3b7b27ae67d69e9eefbde0010c5ffd5fd130ee2f74f80b0fffb9a4b38020607ad42e70ec430100b014220bdb7f48149fe8f480f3565573f023ff55964d72acf1c7a6f71505672654a47764a495944425256646a57756477524f766279197a47416d486f55684c627574724c41665977474a59464c62340007455581f4752f77cbe78b98ba07e114a6506e1ec72f1a3e9829785b253a0def361d52614b6b436453766c516d736c686358526e796f68584a455a496f4a3314706c746b69444b77695677477374686c63764d4500000b5108d685bc97d7a97aa257ba4e6e715a498567ec9cafd168002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444043a2a9970c3415fae326f2c380f546b83b54b59c8942ac24506529970fa4158f8c33b06c04eede32de9332e8b628a5f29e989d8168a225b1b1a119e209958c05", + "signed_txn_bcs": "7cd7b709714bbd423e8ef860629574fe317196d63125a625e329a4284f5b1951c9f811c440828652000b188c101d4f5f2efb4b5bba0106060758d44a7a65c18fad7154d96e289ad1e99289491a42f14b9bb0fe57dfb50f66660d6a425041626a6d666d614f4c780853725970734a6746000a03905e8281f6b0274c0c64702dfd53bb75eab8ba74607ca205cb8fba10f19b3d21019b02e575c781fb6b04017402f16f1fc288b83cdf58678099b9b318bb0500040e30f5fbd8cd50cad5ab36f6ab417f040dfa25ce11ecaaec88017efc333503a659920b5d3ae685e437fb87e4daac09255d065df57daf1a34925dd58125b9830404dbb43eef050151e8fc35ea41f6007c00caa828df96365d7623653efe9b3d63002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405cf137c10147f9dedc72bd4cb1d71f76de4bad23af3254e8a0f7560647a1c897555df72ca6f617a5f389bcbe7be2b1fbf7c0329db3e36bea403897ea6c954505", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "b029849cbdd9f2172b6ab1aba3a573e3cb37c3f615af7a427f2358ce3dbcefb1", - "sequence_number": "17505806273866944451", + "sender": "4390a3543f4655c043d2231ab893ad05bea5acbc1006795d6a167ba02ca6e09d", + "sequence_number": "9114109835453485267", "payload": { "Script": { - "code": "f77719", + "code": "bc45ef1715", "ty_args": [ { "struct": { - "address": "c6162d0be80674dc1f413a5ac35ee88bb7770e1a61ce15d61cd49e35f3316093", - "module": "yaztxczgZGXsgazqlWkUKayCzAiwrq", - "name": "SLKzurZuFZJCQHoAjgytPHDSzfNM", + "address": "9c4554d4e22a7cb9d3b277814ea6cf81f12a25f0c4aa55484d05f9d666e36259", + "module": "sZMgSdkVmbLAqkzcYDGtfTievihby", + "name": "VmtRRuBLUoXFOFKcyIipjZcsAs5", "type_args": [] } }, { "struct": { - "address": "55e715a9ca321673d1e56e7fc34202535a6d7532b21c4689470dd961fcfc5c63", - "module": "bziZXOFOXTXwNLOwTYnHPe7", - "name": "WPWCN", + "address": "e58079576ce1ec2004331d76ff0ed4c93ece96dd9c6c8deebe8ba316ef238178", + "module": "DknaFLEtuOMQhTYRdcJZJvRKwTlr", + "name": "vSwnSqhPuEfzicFCqVzyMFsiUlEi5", "type_args": [] } }, - { - "vector": "u8" - }, { "vector": { "struct": { - "address": "b89879c47f13fe4803c4f521427649b676597afec86f406d88bf46f70be034ff", - "module": "Q", - "name": "VSSQFQkVNDgnQNhLwtHAKpminLfCX", + "address": "82fb31f25b072e20d7c37b1e02e358b7c7363035a46ee62c1027a8fe6053f907", + "module": "bvUkUPXVtmohPUEWqvmNFxwIJUWEvCgN", + "name": "gCj2", "type_args": [] } } + }, + { + "struct": { + "address": "dc799013edeadc8de7b9e5a04dd2354a0d26d04df81300225c95967af8a288f4", + "module": "CHiL", + "name": "oKynBQeAYSnKknx", + "type_args": [] + } + }, + { + "vector": { + "vector": "u128" + } } ], "args": [ { - "U64": "17577370735988215262" + "U64": "1108539902270911603" + }, + { + "Address": "5bb5c35e19e69a93924c12a0b9f9dc35f2e1d66c858af101ee5467d8b69370b5" }, { - "U64": "8346918520968356006" + "Bool": true }, { - "U8Vector": "3f00f0373f" + "U64": "9417897524974853842" }, { - "U64": "15051991286521375549" + "U64": "533426335464637558" }, { - "U8": 160 + "U8Vector": "b0ba8cfb4f1395ffaf" }, { - "U64": "10086890048705212034" + "Address": "752d772cedfd6485311d264c764ea9783b61d9877ffda4e425fad55dd73e53b0" } ] } }, - "max_gas_amount": "13487501960493552671", - "gas_unit_price": "457913481097952844", - "expiration_timestamp_secs": "4772752131770310249", - "chain_id": 71 + "max_gas_amount": "12089713127047329427", + "gas_unit_price": "2067815035718419322", + "expiration_timestamp_secs": "660625096132194620", + "chain_id": 5 }, - "signed_txn_bcs": "b029849cbdd9f2172b6ab1aba3a573e3cb37c3f615af7a427f2358ce3dbcefb1c3cfa46c0e1ef1f20003f777190407c6162d0be80674dc1f413a5ac35ee88bb7770e1a61ce15d61cd49e35f33160931e79617a7478637a675a47587367617a716c576b554b6179437a41697772711c534c4b7a75725a75465a4a4351486f416a677974504844537a664e4d000755e715a9ca321673d1e56e7fc34202535a6d7532b21c4689470dd961fcfc5c6317627a695a584f464f585458774e4c4f7754596e4850653705575057434e0006010607b89879c47f13fe4803c4f521427649b676597afec86f406d88bf46f70be034ff01511d5653535146516b564e44676e514e684c777448414b706d696e4c664358000601de8dec338e5deff301a6a072c32b36d67304053f00f0373f013dab6183536ae3d000a001822e7f810ed5fb8b1f549abe923b2dbb4cbeb48ae2d55a06695e28d7c6383c4247002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fb18467eabd8fe6d7b2e0bb0d160f8346352a363bdf0b3ef82a2ad8a5df88b1562f624a4274d5a69ec44a541c64e0699b3f98d35f79989d7135ed1e504e02a01", + "signed_txn_bcs": "4390a3543f4655c043d2231ab893ad05bea5acbc1006795d6a167ba02ca6e09dd35019529bd27b7e0005bc45ef171505079c4554d4e22a7cb9d3b277814ea6cf81f12a25f0c4aa55484d05f9d666e362591d735a4d6753646b566d624c41716b7a63594447746654696576696862791b566d74525275424c556f58464f464b63794969706a5a63734173350007e58079576ce1ec2004331d76ff0ed4c93ece96dd9c6c8deebe8ba316ef2381781c446b6e61464c4574754f4d516854595264634a5a4a76524b77546c721d7653776e537168507545667a6963464371567a794d467369556c45693500060782fb31f25b072e20d7c37b1e02e358b7c7363035a46ee62c1027a8fe6053f907206276556b55505856746d6f685055455771766d4e467877494a5557457643674e0467436a320007dc799013edeadc8de7b9e5a04dd2354a0d26d04df81300225c95967af8a288f4044348694c0f6f4b796e4251654159536e4b6b6e78000606030701733434f62a53620f035bb5c35e19e69a93924c12a0b9f9dc35f2e1d66c858af101ee5467d8b69370b5050101d21e289be617b38201764435076d1c67070409b0ba8cfb4f1395ffaf03752d772cedfd6485311d264c764ea9783b61d9877ffda4e425fad55dd73e53b0937608f6084ac7a77a4335b9d15ab21c3cf1aa5806032b0905002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444001ca631a7ca6776f139ae6638e8c6045ca829501394810c451c5925702c98f6b8c041840452ec1115cfce483ed84e3e9535c63e9bf23ec4af75ffa8e13fd270a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "39762179f2ea0ef705922c9303e55911914918748fa7a7ac7e20d9f55ae53124", - "sequence_number": "16835706463422638052", + "sender": "6d4cd4e592a6e58c33bdc372dfbfc910c010b4381daf241f0bd373a372881505", + "sequence_number": "16465024613591909859", "payload": { "Script": { - "code": "84f30c4a5e93d1", + "code": "0ec4c1ddebe82603bac8678e8a609b", "ty_args": [ { "struct": { - "address": "8f49903978a240df50e659f9523c3ac6acbca3753b92a1fe978ecaf2eba5eb80", - "module": "rmNoFtPSvnYbOToKNdawenwgUqQRS", - "name": "iSVIL3", + "address": "e7b692911a6ede107887fc48be8eaa54f8336fe59e82f852cd9ad8b21a2fcb0d", + "module": "PFrvkYFRHexdr2", + "name": "DEhxqNDmulBOlTpntiMCQwyEBaaberkB", "type_args": [] } + }, + { + "vector": { + "vector": { + "vector": "u128" + } + } } ], "args": [ { - "Bool": false - }, - { - "Bool": false - }, - { - "U128": "323385331272803013858506194106500612350" - }, - { - "U8": 43 + "U128": "181708444721642633521082875558100582905" }, { - "U8Vector": "621efbef335af268d5a2378633" + "Bool": true }, { - "U64": "8782399549394235126" + "U128": "8929027186322074994452394208945006336" }, { - "U8": 20 + "Bool": true } ] } }, - "max_gas_amount": "538368058380050410", - "gas_unit_price": "2285502343222694818", - "expiration_timestamp_secs": "11082384882239754792", - "chain_id": 185 + "max_gas_amount": "11294129881830650036", + "gas_unit_price": "17293583353315745254", + "expiration_timestamp_secs": "12222469843586822661", + "chain_id": 145 }, - "signed_txn_bcs": "39762179f2ea0ef705922c9303e55911914918748fa7a7ac7e20d9f55ae53124e4e70d3fd471a4e9000784f30c4a5e93d101078f49903978a240df50e659f9523c3ac6acbca3753b92a1fe978ecaf2eba5eb801d726d4e6f46745053766e59624f546f4b4e646177656e7767557151525306695356494c3300070500050002fe80a53738cd00f94af9e49bd2bf49f3002b040d621efbef335af268d5a237863301f6ae31e9db59e1790014eadf288ee5aa7807a2931ca545bcb71f28520f5a558acc99b9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144407035db7fbec3367c1ccf6d71dcc18340c75da5587b03f603659fffc44ae07a71aa412f9b092476460819e0687b52c67f594991d622c1736e1596baa6d02f020f", + "signed_txn_bcs": "6d4cd4e592a6e58c33bdc372dfbfc910c010b4381daf241f0bd373a372881505e385358fa6847fe4000f0ec4c1ddebe82603bac8678e8a609b0207e7b692911a6ede107887fc48be8eaa54f8336fe59e82f852cd9ad8b21a2fcb0d0e504672766b5946524865786472322044456878714e446d756c424f6c54706e74694d43517779454261616265726b4200060606030402f9c149d77ae803046a52da0703c6b388050102006724f98839118bfa87cc8007abb7060501b4f0a3e549cfbc9ce65dfe3b6f26ffef05b2eab890ef9ea991002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444099c025f9dbff18db512ef118df319c65ead913bf53f74624ef0b5119f61c5db6a62e6b49411b635f1f2d8ff3f2e8cbcbc7a19f1a0d6df7c5e9bcd59201fd3600", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "6778a62240e734349b4e553713c79b75a7fe097abdc52a574ea152209e817d5b", - "sequence_number": "5990529320530598198", + "sender": "cf686fd4b7f9f13c5455fc499c1efc8ba7c3db97af5930745d14770cbd2b769b", + "sequence_number": "3931114927032381043", "payload": { "Script": { - "code": "6ee7a41943ce", + "code": "0fbb", "ty_args": [ { "vector": { - "struct": { - "address": "33fe6f903ef85d3d0ed04c30d52e42e38d95fe71811dc1bccc0238593da714e8", - "module": "XiRJKgrqGJHscAhBdnsj", - "name": "zcbscyemYDcPerSycmAynPrMZwyHKrDF2", - "type_args": [] + "vector": { + "struct": { + "address": "9e274e72df7c2db25965e524d59286473ded7b164337f8e6b38fcaee99286cc6", + "module": "iuFiCYHJmVaHmjgjDCmblmIEYif1", + "name": "ZnzQrVfWdiVQHMaISKmJy", + "type_args": [] + } } } }, { - "struct": { - "address": "0649f4e161ed646973ef3a05fe74843342bbcd264a861a73595a143e65f69ec4", - "module": "zoQmiZnKVkt6", - "name": "ToDhpYxgJeDyICnCTkKQYWenmQsXTk", - "type_args": [] + "vector": { + "vector": { + "vector": { + "vector": "u128" + } + } } }, { "vector": { "vector": { - "vector": "address" + "struct": { + "address": "454d70174c62f1d026e72882b185085dc726cf3699b9e805ec28839231e73bff", + "module": "KoVBUfJJiblnZgIymrGblSibHjTu", + "name": "adGktSLCFwtMJpvuIGHbfJxElI", + "type_args": [] + } } } }, { "struct": { - "address": "c7ef0f7142bef199cb92dde852e452e03f31d77d32d3f9b9448c3bd8f0f267a9", - "module": "gApJWbMzzxuXRHfnOUMCZsfVavKgFTl", - "name": "iRObtGcQALNrXTpv2", + "address": "17cbf70b2e2565ce120f2513d9d89a35f5b2207aa9b7521b2e1cb0134e775d73", + "module": "GeQBQkbhTROvRfUVzreGvUSaeEI5", + "name": "FlEAPlKEUKaraCyj7", "type_args": [] } }, { "vector": { - "vector": { - "struct": { - "address": "2a29bee359fcdc6681238d17788656cbe2525e80581b260fd294ea17b271d3b2", - "module": "OunRsQyGoDmVyBAf", - "name": "XIWhjJlGnBlpcCu9", - "type_args": [] - } + "struct": { + "address": "88a831634ecf8cc8f42452a7781526b014482fd9d461f808c984fefd47041f49", + "module": "KibK", + "name": "BzfGWXNl", + "type_args": [] } } }, { - "vector": { - "vector": { - "struct": { - "address": "397c400442707ccefcf2e5b57f4223777de07a221a7c1ed8e1e5059b73ed711e", - "module": "trxJgLmytBzzkyjCMVZrzvSCpZeE0", - "name": "QCy8", - "type_args": [] - } - } + "struct": { + "address": "8c0a77f45c479a6c680d739058fa97a0e1fad612c80b44390fdffe25f86d1a1e", + "module": "yFqWvSUY", + "name": "LhSlSWKfc", + "type_args": [] } }, { "vector": { - "vector": "u128" + "vector": "u64" } }, { - "struct": { - "address": "686a17d57183a4c54bc99f9b5add4536738ba67e698eb939809f3aa9b3adbe81", - "module": "ZXYV7", - "name": "vIrPMTSbsAsUGbfNtxq1", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "efa61824743c1fea95c5b8dc8823b073092467cf18cde8e74425ed8961a6b550", + "module": "nFRHqyrLNJSS", + "name": "LyF4", + "type_args": [] + } + } } }, { "struct": { - "address": "a55af3438e90514f5f0a5b56625f96ce658b1a762711a96325a3cf288a4d2755", - "module": "apNSsfnEbjL", - "name": "wzNgbHKIoYEBWiTWwoQTXAjYuwOkf2", + "address": "daf64b6b07a5d8a4711b742d22b28c3edbcfbc3ec4998fd7f45fce72d7afa8b7", + "module": "TTioLpxRgl4", + "name": "JNVsfCiUFbaTRkygNhfhcEKQFd1", "type_args": [] } } @@ -4695,1212 +5126,1178 @@ "args": [] } }, - "max_gas_amount": "12149949148592631079", - "gas_unit_price": "5755966100836256336", - "expiration_timestamp_secs": "489257404244072347", - "chain_id": 62 + "max_gas_amount": "13482906663579605794", + "gas_unit_price": "10124702418907107086", + "expiration_timestamp_secs": "9093570556160162731", + "chain_id": 249 }, - "signed_txn_bcs": "6778a62240e734349b4e553713c79b75a7fe097abdc52a574ea152209e817d5b36d9c986ada2225300066ee7a41943ce09060733fe6f903ef85d3d0ed04c30d52e42e38d95fe71811dc1bccc0238593da714e8145869524a4b677271474a487363416842646e736a217a6362736379656d5944635065725379636d41796e50724d5a7779484b7244463200070649f4e161ed646973ef3a05fe74843342bbcd264a861a73595a143e65f69ec40c7a6f516d695a6e4b566b74361e546f4468705978674a65447949436e43546b4b515957656e6d517358546b000606060407c7ef0f7142bef199cb92dde852e452e03f31d77d32d3f9b9448c3bd8f0f267a91f6741704a57624d7a7a7875585248666e4f554d435a73665661764b6746546c1169524f6274476351414c4e725854707632000606072a29bee359fcdc6681238d17788656cbe2525e80581b260fd294ea17b271d3b2104f756e52735179476f446d567942416610584957686a4a6c476e426c706343753900060607397c400442707ccefcf2e5b57f4223777de07a221a7c1ed8e1e5059b73ed711e1d7472784a674c6d7974427a7a6b796a434d565a727a765343705a65453004514379380006060307686a17d57183a4c54bc99f9b5add4536738ba67e698eb939809f3aa9b3adbe81055a5859563714764972504d545362734173554762664e747871310007a55af3438e90514f5f0a5b56625f96ce658b1a762711a96325a3cf288a4d27550b61704e5373666e45626a4c1e777a4e6762484b496f59454257695457776f515458416a5975774f6b66320000276deca0604a9da8500a891bac4ce14f9b97b2570431ca063e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e2ee665b20d025446be4ed9b9b59294c4a0869d2361b920e23ac0b96c9d4b0fef1228c914035f7dd3610a5af098127c3a6dc4aecf9551d424e14f8e36226cf0b", + "signed_txn_bcs": "cf686fd4b7f9f13c5455fc499c1efc8ba7c3db97af5930745d14770cbd2b769b732e00bd32208e3600020fbb090606079e274e72df7c2db25965e524d59286473ded7b164337f8e6b38fcaee99286cc61c697546694359484a6d5661486d6a676a44436d626c6d494559696631155a6e7a517256665764695651484d6149534b6d4a79000606060603060607454d70174c62f1d026e72882b185085dc726cf3699b9e805ec28839231e73bff1c4b6f564255664a4a69626c6e5a6749796d7247626c536962486a54751a6164476b74534c434677744d4a70767549474862664a78456c49000717cbf70b2e2565ce120f2513d9d89a35f5b2207aa9b7521b2e1cb0134e775d731c47655142516b626854524f76526655567a726547765553616545493511466c4541506c4b45554b61726143796a3700060788a831634ecf8cc8f42452a7781526b014482fd9d461f808c984fefd47041f49044b69624b08427a664757584e6c00078c0a77f45c479a6c680d739058fa97a0e1fad612c80b44390fdffe25f86d1a1e087946715776535559094c68536c53574b666300060602060607efa61824743c1fea95c5b8dc8823b073092467cf18cde8e74425ed8961a6b5500c6e4652487179724c4e4a5353044c7946340007daf64b6b07a5d8a4711b742d22b28c3edbcfbc3ec4998fd7f45fce72d7afa8b70b5454696f4c707852676c341b4a4e56736643695546626154526b79674e68666863454b51466431000022db68ce2ce81cbb0e0f7fff342b828cabbbe0b33dda327ef9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402d5a1a49ee5b31a5c61f8ccf184333924d785285a072c02ac0147e2d71c19589b1c12908887c13318871c5e81149dd24a63b4e5c1415ef39f47553dc61040903", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "fa8e31c5fe4b9ebe189fe617925d057aa9ecbabba3a74f9f3323dd2211e69c58", - "sequence_number": "12443942011090498040", + "sender": "d3112a35dab263116706c212783a531bda65e83bdb8e0bb5644faa0af1c892ae", + "sequence_number": "11317395760043438969", "payload": { "Script": { - "code": "cab45ece", + "code": "6f3f91075131651beb3bb2cf28ae5d", "ty_args": [ { "vector": { "struct": { - "address": "196ee7b2979364764cd99d4c5051c3e6b4dea09d915119f7fe92210e73fd1725", - "module": "QtsGcLjaFwDCfnzBNjQtQRZCJStN0", - "name": "iqYIehRZLIukWTNKdEceclSLddGGG4", + "address": "b662609f3e7e3d908909c2dd19465dc380d572a2c7429436962ab403440f4dbd", + "module": "d", + "name": "mMcXpJSqWKPIFFlGTmdy3", "type_args": [] } } }, { "struct": { - "address": "8b357f77f3954a80cf32ee4ec074a8b07b3cf1da3d20ae73d03411add1b07332", - "module": "JdOgRHgwAPJrhuRf9", - "name": "sGSccohAyxFuaeeXSsjJh", + "address": "9ac158f8861d80ef42b68278386f9d0691dccdfde790351c6a66a62997a7bd8b", + "module": "OKFecgHTVpZHzLsXtOqvsyxrQP0", + "name": "dctktPLuJIaMgfPMDF", "type_args": [] } }, { "vector": { "struct": { - "address": "3c377c7057729ed56b5b17ceb4b0df142c247aecd3668476cb556c93a02f7243", - "module": "tVGIyvbGmMZss", - "name": "LTzGSyAvkYBgfWjc0", + "address": "5ddafdfbc369023736bcc2e4434220899ac43087040388c482ffac70ff3a4b1f", + "module": "FjSbsSeefLlFMUPyouYCTfgLYEiiY", + "name": "DpsokrMSRWNQPjhQFvjypNOtSm5", "type_args": [] } } }, - { - "struct": { - "address": "f1f669f0a7e7e572a103e5f7b0abca0ab8240a29b81c62d6474900d61a512fd5", - "module": "HSLQLMXrqqjFsn", - "name": "zISALalM9", - "type_args": [] - } - }, { "vector": { - "vector": { - "vector": "u128" - } + "vector": "u128" } }, { "vector": { - "vector": "address" + "struct": { + "address": "f05ed751f2647fbfb6b4f329aee3ef998d1fe1cbd54fcfc2b408991c67fc2ef7", + "module": "VLbPDZgrpNnEafDrCyAcrnwtQC3", + "name": "c", + "type_args": [] + } } } ], "args": [ - { - "U8": 63 - }, - { - "Bool": false - } - ] - } - }, - "max_gas_amount": "7789358680916156578", - "gas_unit_price": "14274096670257788678", - "expiration_timestamp_secs": "3686056827652387823", - "chain_id": 110 - }, - "signed_txn_bcs": "fa8e31c5fe4b9ebe189fe617925d057aa9ecbabba3a74f9f3323dd2211e69c58f8f19b0854c3b1ac0004cab45ece060607196ee7b2979364764cd99d4c5051c3e6b4dea09d915119f7fe92210e73fd17251d51747347634c6a6146774443666e7a424e6a517451525a434a53744e301e697159496568525a4c49756b57544e4b64456365636c534c64644747473400078b357f77f3954a80cf32ee4ec074a8b07b3cf1da3d20ae73d03411add1b07332114a644f675248677741504a7268755266391573475363636f6841797846756165655853736a4a680006073c377c7057729ed56b5b17ceb4b0df142c247aecd3668476cb556c93a02f72430d74564749797662476d4d5a7373114c547a47537941766b59426766576a63300007f1f669f0a7e7e572a103e5f7b0abca0ab8240a29b81c62d6474900d61a512fd50e48534c514c4d587271716a46736e097a4953414c616c4d39000606060306060402003f0500a2e01c54735c196c06374d504bc717c6efb31fba278127336e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b9b1b8ed215afa9b9b329627eb192c83674cad8d83cdca0d1ee5040a89e843971acc5f07e254c259f10dc63c38920d391ed8f0f6952217de11793a5b0cac7f0b", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "5803037f4d99acc1c20e7a4a46716a09a2b183500884e068f6cf18a94e333b38", - "sequence_number": "7558017470450256172", - "payload": { - "Script": { - "code": "9a9a8f70c8f0af2fe64ee5", - "ty_args": [], - "args": [ - { - "Address": "2a10c8e530150ee166811213522efc2d67435cbdbd5941ed44f7f5c335f9caf8" - }, - { - "U128": "211467621562724105686418323837114622526" - }, { "Bool": true }, { - "U64": "10684441934317049199" + "U64": "16592985250054899238" }, { - "U64": "17788765030610950021" + "U8Vector": "7a20" }, { - "Bool": false + "U64": "8184392632415910142" }, { - "Address": "af8068cdae12d46daf749cd1bd70cc466bfb7a7bec59907d5c9f278bc498f306" + "U8": 6 }, { - "U128": "197001163778025359920518866930209026593" + "U8": 221 }, { - "U8Vector": "2c33cacb18516edbf353948bee" - } - ] - } - }, - "max_gas_amount": "3943902040477750761", - "gas_unit_price": "7909560873518593690", - "expiration_timestamp_secs": "5948534100489374172", - "chain_id": 139 - }, - "signed_txn_bcs": "5803037f4d99acc1c20e7a4a46716a09a2b183500884e068f6cf18a94e333b382c496264d878e368000b9a9a8f70c8f0af2fe64ee50009032a10c8e530150ee166811213522efc2d67435cbdbd5941ed44f7f5c335f9caf8023ea2e3014f6ff7fb1cf839efb52e179f0501016f5541a654c346940185d774e28b63def6050003af8068cdae12d46daf749cd1bd70cc466bfb7a7bec59907d5c9f278bc498f3060221728e9fa4a3d4c94c584e33460b3594040d2c33cacb18516edbf353948beee9559d97028ebb369a766733b567c46ddc89f7693f708d528b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440609437722e4eafac62c23ac65794f47f5c4d3d26b35045c334407529c4fb711b82556da3241c4de18a8113262799d33e62a516f1f12143b40c1e6a7099f05305", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "582efb6d94a3c0f0e4c72d738aea1476cdbc8ed122218332333d204e9587c18a", - "sequence_number": "18269217945718730999", - "payload": { - "Script": { - "code": "9a7c3231d3cf0aeca85b", - "ty_args": [ - { - "vector": { - "struct": { - "address": "608013bb952138be454b9556d31d508b4fc714e5751023fb946ef0b35a4bdfd6", - "module": "GbVHriaO3", - "name": "iyTVBnAZyPNyUZEFsKkH3", - "type_args": [] - } - } + "Bool": true }, { - "struct": { - "address": "46dfb20b08affd8c5307766a11af9afb214cef9f7a08a232e47d7208ff3dec92", - "module": "XyYRdGQsQhkzfMjmSRheW0", - "name": "EzkPAMNfkn", - "type_args": [] - } - } - ], - "args": [ - { - "Bool": false - } - ] - } - }, - "max_gas_amount": "8768983532547004881", - "gas_unit_price": "11116067293793949526", - "expiration_timestamp_secs": "2092107220378183561", - "chain_id": 231 - }, - "signed_txn_bcs": "582efb6d94a3c0f0e4c72d738aea1476cdbc8ed122218332333d204e9587c18af7b0c15aed4c89fd000a9a7c3231d3cf0aeca85b020607608013bb952138be454b9556d31d508b4fc714e5751023fb946ef0b35a4bdfd609476256487269614f331569795456426e415a79504e79555a4546734b6b4833000746dfb20b08affd8c5307766a11af9afb214cef9f7a08a232e47d7208ff3dec9216587959526447517351686b7a664d6a6d5352686557300a457a6b50414d4e666b6e00010500d1d9b61210b0b1795617ede94e34449a89e7abb66ea8081de7002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ff4b1dbb62a8001533becb19e46d8cd736e510e483a35206e191e53c53f1a19e8e7805a43e53abcc486965f278103f078eb657573a7fd02b9631368796702902", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "2a0ca74777f44e535ce53f25a06a9a3b846e6a782064daeb565ec88a7463574e", - "sequence_number": "14449257996875173549", - "payload": { - "Script": { - "code": "ba8c2e94d5d09ecc726e", - "ty_args": [ - { - "struct": { - "address": "89be520ddcd6c2f58b8840fe5ae0468de0ac318ce8ece1f223515da6b62ff329", - "module": "ciBfgqnAcSKMkoxBVwLJKhmEHgAK6", - "name": "UOGFiTeGvybGeTPf2", - "type_args": [] - } - } - ], - "args": [ - { - "Bool": true + "U8Vector": "b5584deae793bb152fdb03a8bf" }, { - "U128": "266447769348689817799891676368920039257" + "Address": "dd13e9400371db0a7153a0f778dd4d53f647fdcb72cc31094c2f76e2d8ce5575" }, { - "Address": "14c466c68c3cc1311b2db031ae62398584ceb79de51bb1b3cad6da679a136724" + "U64": "4632402690727099796" } ] } }, - "max_gas_amount": "16376512804615235462", - "gas_unit_price": "4534528246782129563", - "expiration_timestamp_secs": "13164474123173948316", - "chain_id": 85 + "max_gas_amount": "18144409603821775609", + "gas_unit_price": "13916502754957037740", + "expiration_timestamp_secs": "6472631485891458202", + "chain_id": 238 }, - "signed_txn_bcs": "2a0ca74777f44e535ce53f25a06a9a3b846e6a782064daeb565ec88a7463574ead8eb7bb971386c8000aba8c2e94d5d09ecc726e010789be520ddcd6c2f58b8840fe5ae0468de0ac318ce8ece1f223515da6b62ff3291d6369426667716e4163534b4d6b6f784256774c4a4b686d454867414b3611554f474669546547767962476554506632000305010259cfd2c63b76d1274313455c48f973c80314c466c68c3cc1311b2db031ae62398584ceb79de51bb1b3cad6da679a1367248627ba1aa10f45e39b756c5d6ae1ed3e9ceb9a76779bb1b655002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444014f918e6fd43d357b0b30743c71b99b765c2c73f266ea0eecf6a4edd8d37223f97f0bdf13422bbbe4a4e2d3c1db3b1b4af5cc284142a44d49e48015cf9444407", + "signed_txn_bcs": "d3112a35dab263116706c212783a531bda65e83bdb8e0bb5644faa0af1c892ae79b3e64b7b770f9d000f6f3f91075131651beb3bb2cf28ae5d050607b662609f3e7e3d908909c2dd19465dc380d572a2c7429436962ab403440f4dbd0164156d4d6358704a5371574b504946466c47546d64793300079ac158f8861d80ef42b68278386f9d0691dccdfde790351c6a66a62997a7bd8b1b4f4b46656367485456705a487a4c7358744f717673797872515030126463746b74504c754a49614d6766504d44460006075ddafdfbc369023736bcc2e4434220899ac43087040388c482ffac70ff3a4b1f1d466a536273536565664c6c464d5550796f7559435466674c59456969591b4470736f6b724d5352574e51506a685146766a79704e4f74536d35000606030607f05ed751f2647fbfb6b4f329aee3ef998d1fe1cbd54fcfc2b408991c67fc2ef71b564c6250445a6772704e6e456166447243794163726e77745143330163000a0501012686d1e82b2046e604027a2001fe787985bccd9471000600dd0501040db5584deae793bb152fdb03a8bf03dd13e9400371db0a7153a0f778dd4d53f647fdcb72cc31094c2f76e2d8ce557501943d5a25b4994940f9aafbc666e4cdfbac90f5d8855921c19ab491fe0a68d359ee002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a74153d68f54fc3459921e2f8c567f81d48d814c77a45672298ea22359fb83c266e7068bbdbb2b4767c9a53b108bb54cae33939f9e1c14508827e6ab3fec400a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "d6af5a859c66d291a4f0248576fae16302f2c17034027b8ee7e650747d9afb32", - "sequence_number": "14431430428798177451", + "sender": "5c308848ee650e3ef92696f3a4df69ac86010f6a8adcdd09e1c0eae525a6a736", + "sequence_number": "7343474801930024784", "payload": { "Script": { - "code": "bae08fe4098a75ad5f1320c4332e", - "ty_args": [ - { - "vector": { - "struct": { - "address": "e9803129a3140ffd4bf20dbc54e54e0f14835700e4b9a9863d843bc410a98e5f", - "module": "UJmFlEZhGK", - "name": "qJRQ", - "type_args": [] - } - } - }, - "u64", - { - "vector": "signer" - }, + "code": "ab9a97ae66ddbd8c1fced2eb", + "ty_args": [ { "vector": { - "vector": { - "vector": "signer" + "struct": { + "address": "920ab33fee5ccbe23e98e07154736f78ed9b329bcd5b9a17dfeaf5c8955c7c97", + "module": "FTKofRBQcPe4", + "name": "XZCptBtfmshlbVGOFVrKOH", + "type_args": [] } } }, - { - "vector": "bool" - }, { "struct": { - "address": "617ca08c0a1bb611d19d08c2636f58e58a0ed65e09222065c879c25fbc0aaa2a", - "module": "SmYjorLSnDsFhpytSqDTuGeYQTqdrZM0", - "name": "WgHDixhNVsuGUL", + "address": "5e98c3d263e427045a00b5899aa0134ef55aaf7c5359db754fb767f52c7df470", + "module": "nRrumqLDo1", + "name": "ALOZZwfLCbsSuEimzDUD", "type_args": [] } }, { - "vector": { - "struct": { - "address": "3c7facf06bcbf163e4e976aa45296da691e65a770f6cf6510b681fb38f9104ec", - "module": "mfXGN", - "name": "LFktQYHMnOxZTNeitJdla2", - "type_args": [] - } + "struct": { + "address": "c5562d915f2779c7627cc96db73c424b72d1a01047bef0c8c74dacccd0ca2817", + "module": "CEKLAnoThdclgBMPotYEi", + "name": "wEsGZxTuHRzFeRsNBtJomRGCo8", + "type_args": [] } } ], - "args": [] + "args": [ + { + "U8Vector": "deb31e3bb573" + }, + { + "U64": "7854546456176212918" + }, + { + "U8": 242 + }, + { + "U8": 26 + } + ] } }, - "max_gas_amount": "13282057214705936327", - "gas_unit_price": "12993000192595888241", - "expiration_timestamp_secs": "59644643332691307", - "chain_id": 78 + "max_gas_amount": "17509046379295504281", + "gas_unit_price": "15361126804883023941", + "expiration_timestamp_secs": "14472674886141213698", + "chain_id": 255 }, - "signed_txn_bcs": "d6af5a859c66d291a4f0248576fae16302f2c17034027b8ee7e650747d9afb32ab50479583bd46c8000ebae08fe4098a75ad5f1320c4332e070607e9803129a3140ffd4bf20dbc54e54e0f14835700e4b9a9863d843bc410a98e5f0a554a6d466c455a68474b04714a52510002060506060605060007617ca08c0a1bb611d19d08c2636f58e58a0ed65e09222065c879c25fbc0aaa2a20536d596a6f724c536e44734668707974537144547547655951547164725a4d300e576748446978684e56737547554c0006073c7facf06bcbf163e4e976aa45296da691e65a770f6cf6510b681fb38f9104ec056d6658474e164c466b745159484d6e4f785a544e6569744a646c61320000c727f658aa5853b8718842d6d56850b46b9599b27ce6d3004e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444015ed6c93b34960e1215c2e1edceb29cf1d9ff967c0fa31863ec456e05ce48a6ddd8a44bb24ed88ffae24d43f981e4c1513065488999219203c12c45d2598880c", + "signed_txn_bcs": "5c308848ee650e3ef92696f3a4df69ac86010f6a8adcdd09e1c0eae525a6a736503712ca6c43e965000cab9a97ae66ddbd8c1fced2eb030607920ab33fee5ccbe23e98e07154736f78ed9b329bcd5b9a17dfeaf5c8955c7c970c46544b6f665242516350653416585a4370744274666d73686c6256474f4656724b4f4800075e98c3d263e427045a00b5899aa0134ef55aaf7c5359db754fb767f52c7df4700a6e5272756d714c446f3114414c4f5a5a77664c436273537545696d7a4455440007c5562d915f2779c7627cc96db73c424b72d1a01047bef0c8c74dacccd0ca28171543454b4c416e6f546864636c67424d506f745945691a774573475a78547548527a466552734e42744a6f6d5247436f3800040406deb31e3bb57301b6bb2f0063f4006d00f2001a9977bf41eaa0fcf245a8c83a71af2dd502fc29222145d9c8ff002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d73a75e46a89668e480b5236553372c0c2923149acdfe289273991f652166fc6d1d0d91866045fdc020d60cb4194eda00e5591efd09b4601c81fca543ba7430b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "9330fe8690527058ffc0eed628605af78468ebb885217ae2c8f2ba9e98ae49a7", - "sequence_number": "1167799286041149258", + "sender": "4360f1b2fa4286b8a94e7807e04445980f7776fa49fe10e5f5101f1e8eb82877", + "sequence_number": "1088039576809455787", "payload": { "Script": { - "code": "f2ac01aeb917e5e833", + "code": "fc22b6b3bdd9", "ty_args": [ + { + "vector": "u128" + }, { "vector": { "struct": { - "address": "116858b00ed5da2ebad5b8263e76a15969a5a1e7dd5339a5ed26a64347a17280", - "module": "QJAW0", - "name": "mDH2", + "address": "4b704080af3509d6aae5e899498f06577a400f305af4c367d8800b7d702b7c57", + "module": "AgbBlNyCcoGSnoQN3", + "name": "TlaDxMWfaMb7", "type_args": [] } } }, { - "struct": { - "address": "17a720727f2a9fa3b579a9aa5b0e542c0dd602fa608005cf4045aed3191b5fe8", - "module": "bHsRimTHdSAlgXw", - "name": "HebEFGt8", - "type_args": [] - } - }, - { - "struct": { - "address": "dc39ee55c23d19d622ecfa20f044bf93981dec863aff79d7a1d90dced00c259e", - "module": "UmLoM6", - "name": "wClPdHE4", - "type_args": [] + "vector": { + "struct": { + "address": "6fd201c30b3d5d902bf4666aa53521f25a2358387900e6269e56232d3906b494", + "module": "FdhDKDOrcYeweEgwjFVOKwRHcNQRBxZ6", + "name": "QuFAjXVosgOFnMKBWyy", + "type_args": [] + } } }, { - "struct": { - "address": "5a92439ccfbae326662a5a1df94f20312f8412daf282e1f464c085324b87657d", - "module": "pwsNLHWDZqh", - "name": "O7", - "type_args": [] + "vector": { + "struct": { + "address": "0db290cbf49a27766d762c3a0d1fc3694ab36793c455ddada3629f10b6cf6b5c", + "module": "caWqwlwgrCKcgLhFvZmYzSSZEYThwCpt", + "name": "GUXWleFY1", + "type_args": [] + } } }, { "struct": { - "address": "7929a3b61682743a07de91840f74db88dbbe7fdc8a500c481b086beaac77fce9", - "module": "IVy", - "name": "iLcgDwSKqDCiWQhKRGc9", + "address": "c707bb40ef16737968618bffbf97aa7bc5b9b8d2b216120a8d6a5ed7c1b2bb34", + "module": "qytqbYJTHdxGms", + "name": "dWxiKGKFEyPipaVfgfBPIbt9", "type_args": [] } }, { "vector": { "vector": { - "struct": { - "address": "1f0129546e094f42bf8ce5f9b2c9ef0f82c46e0d6bda61a1b919d33732cc7da8", - "module": "CthAAgQhiNjNSHedSkKrVqxqEzwmuxF", - "name": "t6", - "type_args": [] - } + "vector": "bool" } } }, - { - "vector": { - "vector": "u8" - } - }, { "struct": { - "address": "d791dcf6ed40542ced7c78017176bfa79e6e3c4c8a94cdb4ac964ee672626956", - "module": "VfPMgIb3", - "name": "nWlWhgZXhuRobh0", + "address": "8fc63289be2dcfc0df5913f3e8571708375d8670086e053a1f9d8aa69340dc4c", + "module": "QRrguqRKDRcMoNkwQfIqICbDCvaWKzf8", + "name": "aqtYUWHjrZUdsRESzfMgfEHFZjVfeTV5", "type_args": [] } }, { "struct": { - "address": "726c7de6d1741b122f0a7439625859e4c815397aec0f4c6a05a495f803ba3101", - "module": "aE7", - "name": "WKPEGoDMHYkzcFpqBu3", + "address": "efebc6f0e878e0e364fe466fbb8c7913b8ae0b516e8e426eafeeb6f8dc2a690e", + "module": "JnDBificMJxcAfHyYoSQioHYmwGyT0", + "name": "tDpRBV", "type_args": [] } } ], "args": [ { - "U8Vector": "3fbe4c971a6dddf6eb12e7a9e893" + "U8Vector": "f86abdaf3fc16e21cba1ca" }, { - "Address": "472ed38d548432cb9b538c7b6d208702a4de9f8c898eed4e890e76f80b8eaf63" + "U128": "166535325407266626037271017678494386296" }, { - "Bool": false + "U128": "244945400911735842573953173064461037442" }, { - "U64": "10538815536394318937" + "U8Vector": "1b5fbd2879f646fe0dc6bc6df7440f" }, { - "U8Vector": "5a4a" + "U8Vector": "9cdc683ddc" + }, + { + "Address": "5773408336f6d8cd0e7a574cb2b8eb6e9dc05fb9a9b20dff4dbc6fb81668d179" }, { "Bool": true }, { - "U8": 105 + "U128": "218806341931895708613213624837905906964" + }, + { + "Bool": false } ] } }, - "max_gas_amount": "17060233067279520784", - "gas_unit_price": "8945305671794026200", - "expiration_timestamp_secs": "15716723434029534256", - "chain_id": 14 + "max_gas_amount": "14644889091342839495", + "gas_unit_price": "12449067845467013138", + "expiration_timestamp_secs": "9006737639653211879", + "chain_id": 44 }, - "signed_txn_bcs": "9330fe8690527058ffc0eed628605af78468ebb885217ae2c8f2ba9e98ae49a74aff6f6d43db34100009f2ac01aeb917e5e833090607116858b00ed5da2ebad5b8263e76a15969a5a1e7dd5339a5ed26a64347a1728005514a415730046d444832000717a720727f2a9fa3b579a9aa5b0e542c0dd602fa608005cf4045aed3191b5fe80f62487352696d54486453416c6758770848656245464774380007dc39ee55c23d19d622ecfa20f044bf93981dec863aff79d7a1d90dced00c259e06556d4c6f4d360877436c506448453400075a92439ccfbae326662a5a1df94f20312f8412daf282e1f464c085324b87657d0b7077734e4c4857445a7168024f3700077929a3b61682743a07de91840f74db88dbbe7fdc8a500c481b086beaac77fce90349567914694c63674477534b714443695751684b52476339000606071f0129546e094f42bf8ce5f9b2c9ef0f82c46e0d6bda61a1b919d33732cc7da81f4374684141675168694e6a4e53486564536b4b7256717871457a776d7578460274360006060107d791dcf6ed40542ced7c78017176bfa79e6e3c4c8a94cdb4ac964ee672626956085666504d674962330f6e576c5768675a586875526f6268300007726c7de6d1741b122f0a7439625859e4c815397aec0f4c6a05a495f803ba31010361453713574b5045476f444d48596b7a634670714275330007040e3fbe4c971a6dddf6eb12e7a9e89303472ed38d548432cb9b538c7b6d208702a4de9f8c898eed4e890e76f80b8eaf6305000159b426b0e464419204025a4a05010069109491f0951fc2ecd8e6913e1d1c247c304c6346b1041dda0e002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444049c46de007e358258ce3f407e96d33537bb85136c7db95ae0cd0f69d1a12ae7a3530fb01ce0d5d44594f9956553b5915a828bb30fc6a150300b1fd0eb6f3f707", + "signed_txn_bcs": "4360f1b2fa4286b8a94e7807e04445980f7776fa49fe10e5f5101f1e8eb82877ab404bfd3a7e190f0006fc22b6b3bdd908060306074b704080af3509d6aae5e899498f06577a400f305af4c367d8800b7d702b7c5711416762426c4e7943636f47536e6f514e330c546c6144784d5766614d62370006076fd201c30b3d5d902bf4666aa53521f25a2358387900e6269e56232d3906b49420466468444b444f7263596577654567776a46564f4b775248634e515242785a3613517546416a58566f73674f466e4d4b425779790006070db290cbf49a27766d762c3a0d1fc3694ab36793c455ddada3629f10b6cf6b5c2063615771776c776772434b63674c6846765a6d597a53535a455954687743707409475558576c654659310007c707bb40ef16737968618bffbf97aa7bc5b9b8d2b216120a8d6a5ed7c1b2bb340e7179747162594a54486478476d7318645778694b474b46457950697061566667664250496274390006060600078fc63289be2dcfc0df5913f3e8571708375d8670086e053a1f9d8aa69340dc4c20515272677571524b4452634d6f4e6b775166497149436244437661574b7a663820617174595557486a725a5564735245537a664d67664548465a6a5666655456350007efebc6f0e878e0e364fe466fbb8c7913b8ae0b516e8e426eafeeb6f8dc2a690e1e4a6e4442696669634d4a786341664879596f5351696f48596d7747795430067444705242560009040bf86abdaf3fc16e21cba1ca027848367d5d6f55d7cb9934d57889497d0282afbfd8f2f6c71008995816abc446b8040f1b5fbd2879f646fe0dc6bc6df7440f04059cdc683ddc035773408336f6d8cd0e7a574cb2b8eb6e9dc05fb9a9b20dff4dbc6fb81668d17905010214fd88de7cd4fca393b7906e8f919ca40500c7ae7b6009193dcb1280cc593ff9c3ace77eabdc295cfe7c2c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402f6ffa823b4caebdfdbda3189dd4a716041a33e849d6ac9925e3ddbb20b6efb9a6c0194864ebe50a1a274a5eb9b8272437fc2031af6a4b8a0d33a89762e7dd0c", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "cf7dc51873af9d146d59be68a0f281f88a7f7066744b4c917f94aa78c2b5fce3", - "sequence_number": "10098718141568347637", + "sender": "b57db763e8e4e9ae06f23700c6e00b3c7cc3dccccc2bec8188b9f2b7bb340e39", + "sequence_number": "7909989780314925760", "payload": { "Script": { - "code": "55226e87077519ac06db851e79", + "code": "de1a9ec1486c", "ty_args": [ - { - "vector": { - "vector": { - "vector": "bool" - } - } - }, - { - "struct": { - "address": "92ab41f3ad9d77bd8edf551b1d983e45ecfa323b0e3f1840fb6e2836f08da41c", - "module": "BsbkkQvXFOPRcYjoeXYS5", - "name": "dEpWkXanDJkxRGHkLqsBRMGok1", - "type_args": [] - } - }, { "struct": { - "address": "f42aef540899e3ae26d251798abf0cf103869d63d40ce97c194277de0c550102", - "module": "xbRgIUE", - "name": "HCfinHmBpGL", + "address": "ccdadff8e15d5f1925e0c8119f0d78bc36ab9384d36a8293387155dfb6b018a3", + "module": "lITPUDfINGysgSGOnSSlk", + "name": "yYVwjOaFH4", "type_args": [] } }, { "struct": { - "address": "482e553d04de7c836dacb358985076283bcd28af41120f2f9cbec5e70c5f776c", - "module": "IQPAKhEUbhhTavuVgtRu7", - "name": "LgJmzaancmyHpv", + "address": "ec0c2a50cf25cbe7ae74fd07174af6868efb6fddc3f3dd8637217960d72a61d8", + "module": "QzCknM9", + "name": "tHGnXAlrlLnWFrSreFBpbjFVBr", "type_args": [] } }, { - "struct": { - "address": "7827ed21f961c7173316264d8190f78f77f8c4e3ab583d14bf7b862a1b740e2f", - "module": "OxdiVYuqQXBSEWGeqYLzqIMcWZ", - "name": "fCEoKsVCugKqbJoXhLlWunQmmLiAuhh1", - "type_args": [] + "vector": { + "vector": "u128" } } ], "args": [ { - "U128": "6347413909970404825473117070013011153" + "U64": "15830664374836198020" + }, + { + "U8Vector": "d2c513d4ac" }, { - "U8Vector": "d048ea9a0b" + "U8Vector": "b864bb5e87" }, { - "U8": 223 + "U8": 249 }, { - "Address": "776299c891e0d2fd61e58f0f922c4ad5c9a046fcd57deb9858d19111ad571b31" + "U8Vector": "86b3cb40aa6286dc8232d59f" }, { - "U64": "10723821603705179403" + "Bool": true }, { - "U8Vector": "ae" + "Bool": false }, { - "U64": "9669193803797871633" + "U128": "169178792675421688294448796037298234339" }, { - "Address": "f0d14908960656b4d2ed844731e232818a1e718f7b578e10771bd1b0ea9b0f41" + "Address": "7377813d25ed53b46d636eaa6003f2387e5547550a7752ed853a13eae91c1f66" }, { - "U128": "195755553405654857702698412326685789095" + "U8Vector": "d2ed9f7036dcd3e3d5" } ] } }, - "max_gas_amount": "11833728329949603988", - "gas_unit_price": "6579074447514022924", - "expiration_timestamp_secs": "11901977016832333977", + "max_gas_amount": "17311090139685803557", + "gas_unit_price": "14494414453570357900", + "expiration_timestamp_secs": "12242362978143905725", "chain_id": 250 }, - "signed_txn_bcs": "cf7dc51873af9d146d59be68a0f281f88a7f7066744b4c917f94aa78c2b5fce3f56df9faa4da258c000d55226e87077519ac06db851e7905060606000792ab41f3ad9d77bd8edf551b1d983e45ecfa323b0e3f1840fb6e2836f08da41c154273626b6b517658464f505263596a6f65585953351a644570576b58616e444a6b785247486b4c717342524d476f6b310007f42aef540899e3ae26d251798abf0cf103869d63d40ce97c194277de0c55010207786252674955450b484366696e486d4270474c0007482e553d04de7c836dacb358985076283bcd28af41120f2f9cbec5e70c5f776c15495150414b684555626868546176755667745275370e4c674a6d7a61616e636d7948707600077827ed21f961c7173316264d8190f78f77f8c4e3ab583d14bf7b862a1b740e2f1a4f78646956597571515842534557476571594c7a71494d63575a206643456f4b73564375674b71624a6f58684c6c57756e516d6d4c694175686831000902d19410c730a76f438cede0ecaa77c6040405d048ea9a0b00df03776299c891e0d2fd61e58f0f922c4ad5c9a046fcd57deb9858d19111ad571b31010bcd816beeaad2940401ae0111bcc7f388e02f8603f0d14908960656b4d2ed844731e232818a1e718f7b578e10771bd1b0ea9b0f4102a74bb46e79fca62e0c826afcf025459394681fe337d939a40c34ec425a914d5b9998279509512ca5fa002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405cf1fdb6a6cc0c4ce131b633236432d546a266c061f4cfedacb39472303fb46ff7be104e42c2f99b5e88a5c9659a2277603e9a2002d7d2faba1f9519b400ab0c", + "signed_txn_bcs": "b57db763e8e4e9ae06f23700c6e00b3c7cc3dccccc2bec8188b9f2b7bb340e39c02aa4d8cbedc56d0006de1a9ec1486c0307ccdadff8e15d5f1925e0c8119f0d78bc36ab9384d36a8293387155dfb6b018a3156c495450554466494e4779736753474f6e53536c6b0a795956776a4f614648340007ec0c2a50cf25cbe7ae74fd07174af6868efb6fddc3f3dd8637217960d72a61d807517a436b6e4d391a7448476e58416c726c4c6e574672537265464270626a46564272000606030a0184fa8adc5fd1b1db0405d2c513d4ac0405b864bb5e8700f9040c86b3cb40aa6286dc8232d59f0501050002e3a39b4352c6456fdcfbcc8b78a6467f037377813d25ed53b46d636eaa6003f2387e5547550a7752ed853a13eae91c1f660409d2ed9f7036dcd3e3d52556bd92c3583df08c4a599c268126c9bd27a90b449ce5a9fa002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440a013bd69fac7ac3acca794bbab5018098b9ce30a0251d4a6b784680170bbf8960753fee6e22e1f84b26c95df750bccfc006b6b3ec3dfa92605e156170da10b00", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "3ba7eaedd50974b567f5d25f0f03bbba5174dc3e23cbd0c7c06e973b0efd226a", - "sequence_number": "6614832036659731813", + "sender": "48098623eb0a1f4ae6d44bcd3f3cb69ae46826bedc5c607edb8d5cbbb2f2205c", + "sequence_number": "10418745558998481016", "payload": { "Script": { - "code": "eaeabe", + "code": "8dd18fcd01c7c292219dfcefb9b1", "ty_args": [ { "vector": { - "vector": { - "struct": { - "address": "ce4b4dde706c46ceb664cd29f42b0ce7e04b5e328b2bc2efb43cbb9296715c26", - "module": "UNkNCNGaVDkq", - "name": "dIDMSdocGhOLHHCUIN4", - "type_args": [] - } + "struct": { + "address": "3666fc9ea3df4dd4c4c7622a0df2d99fced4574d483b89f1a361563b71e018f5", + "module": "RCiivXSevKFBFGXvVqKR6", + "name": "jnohJfjQyYRXoKqftrR6", + "type_args": [] } } }, { "vector": { - "vector": { - "struct": { - "address": "dd6bf3cde98f8669d8e5538f0cfa637d3c772a93a2df9d3557dbbb85bb26c8ef", - "module": "jKO", - "name": "AgPPRXuwNaV8", - "type_args": [] - } + "struct": { + "address": "0ce40354edc1db6139450796fbe0cc57224b82de0595cf754067118037b4c0f7", + "module": "kuVh8", + "name": "XWTebBdGosOlqmpSfkOtitgKak", + "type_args": [] } } }, { "struct": { - "address": "9d0cda26de396227b133d51a95ae68f7c507922abdeb6aca025cf90459d36160", - "module": "zKvTaWbbLsmiKdhIahNc0", - "name": "yCESQRAJZ9", + "address": "e181874468c0f173fc51e22e0450a158b81de61d7a374d9340404eb88b50b29b", + "module": "liGRw8", + "name": "QggKthqnQhZoEpiRiTv", "type_args": [] } }, { "struct": { - "address": "b518d81436af19eb7940e96ce76a36c572e74af455e0df5fb8210ef562af7b04", - "module": "kOAzXYdoIrEzKruCYzHeIA", - "name": "GNRiRYIXNkbbSMbEmzgIxUyCVhnjgsQ5", + "address": "f299bf450a3623d1c69ce82bacb8d7af24a907f727cfb39649e3658471aaa5ea", + "module": "vXInCkmUOkVEPFOMTkEUmdmLTWDCav5", + "name": "CexxXvfapiiGw4", "type_args": [] } }, { "struct": { - "address": "e08286c79ee58bbe707b6143006bbf113fbe015cff13657e960a210ab8ade34e", - "module": "XQlWNadYy", - "name": "FLz", + "address": "7ad015299ec3f723818ad8a8154f4d8d050cd46edc3d0a59bc90c8d77fac381b", + "module": "FuOGRrFsyxyqNHfIVULxpq", + "name": "tbDpHbE", "type_args": [] } }, { "struct": { - "address": "4667a592abecc33dcfe5edfa72b7cb641cf1de3d911cfcdb1021f0756683ad80", - "module": "pGuoInvydyBep", - "name": "wahdd", + "address": "70406a395cd12cb757f790e79b8aa1544f2f91ccef68d732c2c11773bbb0af9e", + "module": "UebmmV", + "name": "CzwsgteYXIILILgPdMQj", "type_args": [] } }, - { - "vector": { - "struct": { - "address": "5e735494528d4f1b1285c6ff6d287ac1ff05d34bec5ccfa9490c8ea85e3b3c84", - "module": "WRKeWGivFK4", - "name": "dZbPYzDovaylercjnCiEghjUgwapkix6", - "type_args": [] - } - } - }, { "struct": { - "address": "613fad17707e69b934c6103669e27b0123a3daca2382ca0eb21f7b5b712d9a58", - "module": "ZKavrZCqQMsybXt8", - "name": "bVKfdLIQxxxINJFImCdAwzEuiwyja1", + "address": "dd4fe1ab6703821868d7977353916f47983fe1a8e24dd8d920d5772d1b3b4bc4", + "module": "Ycc", + "name": "KHLmcuNELUCwv", "type_args": [] } } ], "args": [ { - "U64": "1764369398606935485" - }, - { - "U8": 100 - }, - { - "U8": 144 - }, - { - "U128": "83140352232770170850150048524016911181" - }, - { - "U8": 22 - }, - { - "U64": "15700772822954277568" - }, - { - "U128": "262273053620126370962401425373527742539" - }, - { - "Address": "4ca6cf5e4e29827a055362eb3f62cf75d454a81b029996480c047d3b9176b2fe" + "Address": "e7e26febdff9143b1a27ce110190d834bd968f2b6a163d62cc8abd43586d4e25" }, { - "Bool": false + "U64": "15376622668004256954" }, { - "Bool": true + "U8": 4 } ] } }, - "max_gas_amount": "8986133668028382376", - "gas_unit_price": "16673083440310656290", - "expiration_timestamp_secs": "2325140547591945145", - "chain_id": 22 + "max_gas_amount": "11807527580054520646", + "gas_unit_price": "11814128229025072429", + "expiration_timestamp_secs": "1845872271018643928", + "chain_id": 162 }, - "signed_txn_bcs": "3ba7eaedd50974b567f5d25f0f03bbba5174dc3e23cbd0c7c06e973b0efd226a651dfac1b09acc5b0003eaeabe08060607ce4b4dde706c46ceb664cd29f42b0ce7e04b5e328b2bc2efb43cbb9296715c260c554e6b4e434e476156446b71136449444d53646f6347684f4c48484355494e3400060607dd6bf3cde98f8669d8e5538f0cfa637d3c772a93a2df9d3557dbbb85bb26c8ef036a4b4f0c41675050525875774e61563800079d0cda26de396227b133d51a95ae68f7c507922abdeb6aca025cf90459d36160157a4b7654615762624c736d694b64684961684e63300a794345535152414a5a390007b518d81436af19eb7940e96ce76a36c572e74af455e0df5fb8210ef562af7b04166b4f417a5859646f4972457a4b727543597a4865494120474e5269525949584e6b6262534d62456d7a67497855794356686e6a677351350007e08286c79ee58bbe707b6143006bbf113fbe015cff13657e960a210ab8ade34e0958516c574e6164597903464c7a00074667a592abecc33dcfe5edfa72b7cb641cf1de3d911cfcdb1021f0756683ad800d7047756f496e767964794265700577616864640006075e735494528d4f1b1285c6ff6d287ac1ff05d34bec5ccfa9490c8ea85e3b3c840b57524b6557476976464b3420645a6250597a446f7661796c6572636a6e43694567686a55677761706b6978360007613fad17707e69b934c6103669e27b0123a3daca2382ca0eb21f7b5b712d9a58105a4b6176725a4371514d7379625874381e62564b66644c4951787878494e4a46496d436441777a45756977796a6131000a01bd3589b89e4c7c1800640090024d83618fee312353e34f215dd83f8c3e001601c0fa4b3bb259e4d9024b18fb3f576f09423e34d1e6e7f34fc5034ca6cf5e4e29827a055362eb3f62cf75d454a81b029996480c047d3b9176b2fe05000501a87c02e3f528b57c221d2a1a0db162e7b93b1348028f442016002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440260aea8940dbcdd07ea54edf4175c091dbf3cef446fecd3b5d121f481956c897e8c619060da53904c9dd2030e7c6c895c8d61e009d4d187f816a2cb7be996e0d", + "signed_txn_bcs": "48098623eb0a1f4ae6d44bcd3f3cb69ae46826bedc5c607edb8d5cbbb2f2205c78784891e2d19690000e8dd18fcd01c7c292219dfcefb9b10706073666fc9ea3df4dd4c4c7622a0df2d99fced4574d483b89f1a361563b71e018f5155243696976585365764b46424647587656714b5236146a6e6f684a666a51795952586f4b7166747252360006070ce40354edc1db6139450796fbe0cc57224b82de0595cf754067118037b4c0f7056b755668381a58575465624264476f734f6c716d7053666b4f746974674b616b0007e181874468c0f173fc51e22e0450a158b81de61d7a374d9340404eb88b50b29b066c6947527738135167674b7468716e51685a6f457069526954760007f299bf450a3623d1c69ce82bacb8d7af24a907f727cfb39649e3658471aaa5ea1f7658496e436b6d554f6b564550464f4d546b45556d646d4c545744436176350e436578785876666170696947773400077ad015299ec3f723818ad8a8154f4d8d050cd46edc3d0a59bc90c8d77fac381b1646754f4752724673797879714e48664956554c7870710774624470486245000770406a395cd12cb757f790e79b8aa1544f2f91ccef68d732c2c11773bbb0af9e065565626d6d5614437a7773677465595849494c494c6750644d516a0007dd4fe1ab6703821868d7977353916f47983fe1a8e24dd8d920d5772d1b3b4bc4035963630d4b484c6d63754e454c55437776000303e7e26febdff9143b1a27ce110190d834bd968f2b6a163d62cc8abd43586d4e2501baec9c03d9bc64d500044603c76cc6c3dca32d45f4c50737f4a3d851cff60cdb9d19a2002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144407cfe99aee1592c0e1e8d51911dea1aa619a2f0de42ecef2ab2ea024785095f55273d4ac0e9f166d65d6ef5f0168dc025c0b27711834bb55a4c8e3b299a8f2f00", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "809a13ccf5c7db175f08263d2822058f5df64b16d498993cc3e45ee92ca9e635", - "sequence_number": "2564923877260231936", + "sender": "c7e4533bd6136c67852cca49aea796476f03449f3198093278f04dda01bf7724", + "sequence_number": "13216997792481252917", "payload": { "Script": { - "code": "025aacbdb9b1e3591f5e24", + "code": "b38e9cb1dfda55c8facaafc4", "ty_args": [ { "vector": { - "struct": { - "address": "f909f83e7690072cae1ea1f0111735b313c82ab22ee7fbd2b450b6ec46efc898", - "module": "hWQtBdUEDeXHYWVsKfIvPknQBmY4", - "name": "tiUNWisSDlZJItHKkMdVpyo", - "type_args": [] + "vector": { + "vector": "bool" } } }, { - "vector": { - "struct": { - "address": "fbb4fa525b92792e2e3993473aa57e9b735cc369e262e1fb4da656f864bed28e", - "module": "ShXtoRlmDEBkXFfhoeAUdCUylQ", - "name": "nnkssGoHRTRDAegkkN2", - "type_args": [] - } - } + "vector": "u8" }, { - "vector": { - "vector": "address" + "struct": { + "address": "20570aaf91ae56c4e3f12f41ddd0a128e73d6ff325f0b9309236d0fd6b667979", + "module": "BnGEeVSefxrUqjGIuFf2", + "name": "dhkdApqYyxGvpXIQUegYgWjyaDhSIw4", + "type_args": [] } }, { "vector": { "struct": { - "address": "026ff2203fb44a373fc11f6d13e6222415ec4b3e2aa91aabc5b34bfc01264787", - "module": "TOekZfhdHGmKVljoahyh7", - "name": "yiERYDyuTXLrKEHn", + "address": "72ac0a80b986003ddcf8b147edaddecd41d66ed844b57c069cdb1fed21baf409", + "module": "NervIzGQHNzofHuOI8", + "name": "BxpAjzxdvksq", "type_args": [] } } }, { "struct": { - "address": "1486e8226428dcb7fa634e7a433a535a07a9bc502305a4ebe2d97553931bd6c5", - "module": "nvNUmtiPgsCmQpfEkdH", - "name": "OfjoYQFszqENxaVEC", + "address": "e6dbb41a954ccb031787abdd2e26616bdd13ff5f3b0659d1d5d72329afb50573", + "module": "GuxCKNKAWjdIsYivzyXVJxjP2", + "name": "KHAxwnxBamAhVEJzsSwloSLR3", "type_args": [] } }, { "struct": { - "address": "064212cbee8b80b4ea9a2baf02e749a896ded724309c0797094d82866b47cd18", - "module": "RvZhTVDZQVewqdKBElMfygZsLmM", - "name": "GMgxTFezTQgOLYBhMmRjOBm1", + "address": "2c18f9c34799f7a00132c5a34e868514e03956becafe45a876eef1fc68033331", + "module": "jHXkJwThvDClO", + "name": "vmOqvGKzIETAMPPJXX8", "type_args": [] } - } - ], - "args": [ - { - "U8": 170 }, { - "U8": 62 - }, - { - "U8": 22 - }, - { - "U8": 71 + "vector": { + "struct": { + "address": "fdabae2c150585567e8dfb0c33753f59cb62a5880149377fd49f45ee1a1f8d96", + "module": "rKaJfBKctkabKx9", + "name": "hYfMZDhJGlnjsoNIKGiE", + "type_args": [] + } + } }, { - "Bool": false - }, + "vector": { + "struct": { + "address": "68996e8362eac97be042f0fb46b4802c7b332af0b96ed4234d7b0d7b44663bee", + "module": "g8", + "name": "jJRFnzUOXlnBo0", + "type_args": [] + } + } + } + ], + "args": [ { - "Bool": true + "Address": "05439264af08eddc5394f111e7caa60ca5e2c208a2283fa2c3ec7c7ca6ace331" }, { - "Address": "eb418f0ed9fcb378cc68df855c963b4eb098909725cd1fae6eb4358e0f5b5384" + "U64": "14218076558200407721" }, { - "Address": "59ec18ab4544ff8fa2da89149a620d291b40ec905c072f2eb2ba4b5d076c5482" + "U64": "8331309585300069520" }, { - "Address": "ec2214391259896d012dfc4b3f35ba587baff4a59f85447b7f558b0e8f680268" + "Bool": false }, { - "U128": "214978350937184170951630500255633230472" + "Address": "212b6ef78f1e4f5c9f8858d394b841a7c2603a64d63e9161aa6931fc41c43f3c" } ] } }, - "max_gas_amount": "1264925446907894872", - "gas_unit_price": "12272290939450114635", - "expiration_timestamp_secs": "10850854884466199341", - "chain_id": 13 + "max_gas_amount": "1113308163642896686", + "gas_unit_price": "10833942846498038489", + "expiration_timestamp_secs": "14727499257998517032", + "chain_id": 166 }, - "signed_txn_bcs": "809a13ccf5c7db175f08263d2822058f5df64b16d498993cc3e45ee92ca9e63500850344ad709823000b025aacbdb9b1e3591f5e24060607f909f83e7690072cae1ea1f0111735b313c82ab22ee7fbd2b450b6ec46efc8981c685751744264554544655848595756734b664976506b6e51426d5934177469554e57697353446c5a4a4974484b6b4d645670796f000607fbb4fa525b92792e2e3993473aa57e9b735cc369e262e1fb4da656f864bed28e1a536858746f526c6d4445426b584666686f654155644355796c51136e6e6b7373476f48525452444165676b6b4e32000606040607026ff2203fb44a373fc11f6d13e6222415ec4b3e2aa91aabc5b34bfc0126478715544f656b5a66686448476d4b566c6a6f616879683710796945525944797554584c724b45486e00071486e8226428dcb7fa634e7a433a535a07a9bc502305a4ebe2d97553931bd6c5136e764e556d7469506773436d517066456b6448114f666a6f595146737a71454e78615645430007064212cbee8b80b4ea9a2baf02e749a896ded724309c0797094d82866b47cd181b52765a685456445a5156657771644b42456c4d6679675a734c6d4d18474d67785446657a5451674f4c5942684d6d526a4f426d31000a00aa003e001600470500050103eb418f0ed9fcb378cc68df855c963b4eb098909725cd1fae6eb4358e0f5b53840359ec18ab4544ff8fa2da89149a620d291b40ec905c072f2eb2ba4b5d076c548203ec2214391259896d012dfc4b3f35ba587baff4a59f85447b7f558b0e8f6802680288ca8b62fdcafe44efc0235f0853bba1581c4cfafdea8d114b422b8a96ef4faa2d8bebf106fb95960d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440013475e3e87c41e29aa8f2243017aff662ace872537057ef5409c8c4ec6873e944bc0543a6e6081f2ce7a3d183e4995f2a659393d235bbe1ed8548e8eff23c01", + "signed_txn_bcs": "c7e4533bd6136c67852cca49aea796476f03449f3198093278f04dda01bf77243596f73177356cb7000cb38e9cb1dfda55c8facaafc4080606060006010720570aaf91ae56c4e3f12f41ddd0a128e73d6ff325f0b9309236d0fd6b66797914426e47456556536566787255716a4749754666321f64686b644170715979784776705849515565675967576a796144685349773400060772ac0a80b986003ddcf8b147edaddecd41d66ed844b57c069cdb1fed21baf409124e657276497a4751484e7a6f6648754f49380c427870416a7a7864766b73710007e6dbb41a954ccb031787abdd2e26616bdd13ff5f3b0659d1d5d72329afb5057319477578434b4e4b41576a6449735969767a7958564a786a5032194b484178776e7842616d416856454a7a7353776c6f534c523300072c18f9c34799f7a00132c5a34e868514e03956becafe45a876eef1fc680333310d6a48586b4a7754687644436c4f13766d4f7176474b7a494554414d50504a585838000607fdabae2c150585567e8dfb0c33753f59cb62a5880149377fd49f45ee1a1f8d960f724b614a66424b63746b61624b7839146859664d5a44684a476c6e6a736f4e494b47694500060768996e8362eac97be042f0fb46b4802c7b332af0b96ed4234d7b0d7b44663bee0267380e6a4a52466e7a554f586c6e426f3000050305439264af08eddc5394f111e7caa60ca5e2c208a2283fa2c3ec7c7ca6ace33101a906d8904cc150c501901c9e39edc19e73050003212b6ef78f1e4f5c9f8858d394b841a7c2603a64d63e9161aa6931fc41c43f3c2e317a53e043730fd96266429ee5599628a3d4a68b9662cca6002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402b7172bdb73965602a79dad87974bcfeb6ded4357b8fff583128db4b7eb2ba5bb34610c06a6d6075ec81c2b3b07b224328f654a863bcbe4c3455bef4b7e2870a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "49aa3bc1aecf0874bca007638f1910b483bba9dd8dc74316080bc0f12265b238", - "sequence_number": "943915736789503137", + "sender": "4dd9c00406596e06c5c0324bf340bac59695967d5aec3cfb2f3c48aabca7b6db", + "sequence_number": "14826440523967436776", "payload": { "Script": { - "code": "a9049d096a177780df4b8f", + "code": "9fdee51ee924", "ty_args": [ - { - "vector": "u128" - }, - { - "struct": { - "address": "3cea18934fc97b661f7cd4b9dedbc44088f8c262f4e2b09db952bbf1deca67b1", - "module": "ro", - "name": "aLGqgfYqIvmEKBbAEsSSaOV", - "type_args": [] - } - }, { "vector": { "vector": { - "vector": "address" + "struct": { + "address": "f817e5d4c57ef9598a71c5b29379f88c9cad2ba7f6e9fb423b3fccca79ca3ea7", + "module": "aNxUJlrlgP", + "name": "VyUtvtRIhFMrfMnN", + "type_args": [] + } } } }, { "vector": { - "vector": "u64" + "vector": { + "struct": { + "address": "e32f66b65bb65ccbb243f8a7d832bc34d78e13396288dd8a250268408cfc4472", + "module": "qxELNRDFkfDxyedQaRypNcQMerLvuDQ4", + "name": "HndJ4", + "type_args": [] + } + } } - }, + } + ], + "args": [ { - "struct": { - "address": "e874563f4cd75ac50bc0bcaf9326a0ac6729e04114dd3b8b5894cdd043f70cf6", - "module": "icFxIgTvJrrsinAXT", - "name": "ZAdO", - "type_args": [] - } + "Bool": false }, + { + "U64": "1189101587387096878" + } + ] + } + }, + "max_gas_amount": "10838446097219818562", + "gas_unit_price": "11389042524445608135", + "expiration_timestamp_secs": "8538611105845132942", + "chain_id": 222 + }, + "signed_txn_bcs": "4dd9c00406596e06c5c0324bf340bac59695967d5aec3cfb2f3c48aabca7b6dbe817894a1a19c2cd00069fdee51ee92402060607f817e5d4c57ef9598a71c5b29379f88c9cad2ba7f6e9fb423b3fccca79ca3ea70a614e78554a6c726c675010567955747674524968464d72664d6e4e00060607e32f66b65bb65ccbb243f8a7d832bc34d78e13396288dd8a250268408cfc4472207178454c4e5244466b66447879656451615279704e63514d65724c767544513405486e644a3400020500012e9f0ff697898010429401064de56996c7086691d5010e9e8ebe1aaf8f3d7f76de002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444075cd140f3d48dab431bd68fe7c260d906f9ce085c9ea2988d429c11fa1f4b328b451dc0a913f161aa2777d8f985f4d64311b76751ecde912bb432cc09f120101", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "aa5eba8e03e250c329900ce4e13797cf4d66deba80822730311e0c3110858e67", + "sequence_number": "14649111383586666489", + "payload": { + "Script": { + "code": "b93870f7eaf96afa", + "ty_args": [ { "struct": { - "address": "8a3db5b4a583000436eb8c1396d55cd8a8d544be63a2049de2ca3d965486aff6", - "module": "IQEjxSCQKk3", - "name": "JjH", + "address": "41a2f0e04048c7ede38d6e511d2e4e59a7a9d3965cae8eb0d4e4dd39b6b64247", + "module": "DSWaykVxgdOEsqfQYo", + "name": "vCvtCskSuWyGB2", "type_args": [] } }, { "vector": { - "vector": { - "struct": { - "address": "5a127b0f6a2c2b86548f6698a53a3f846ec7414376d6f698e3a53245e5742051", - "module": "VTKR6", - "name": "abmissDJDWwPpIyFdSonZlXRDWwKa", - "type_args": [] - } + "struct": { + "address": "545e1ca22490451d45991eb0aa18536b282e09b08851afc5b3df538c95ae7e75", + "module": "QqKqfmihNOPxbjZUvaCshgiZ6", + "name": "hNwziIggfMFonUqtAooWaRPRGDqa9", + "type_args": [] } } }, { - "struct": { - "address": "8b216b3e597a2f726b1f6d6d3b8a6bd7c02ccacac3c4e28b9eb2ba77c3aec1a7", - "module": "AjujgnmAOzieMm8", - "name": "wkkAzD9", - "type_args": [] + "vector": { + "struct": { + "address": "7e3e7e5293ce77ee5bfec3d67634a12a2a9dbe2ff039e2ddea9689a8f5f5e545", + "module": "bRXhTvyCjyvt", + "name": "LlusnjFjr0", + "type_args": [] + } } }, + "u128", { "struct": { - "address": "7c29b2ae3bd898ad398efe68e4cafa958b82f81be6b2b6966dafc9ed4f358b99", - "module": "TwWWYxpLsOpfdprAVzQF", - "name": "UlXINCTbFKtvLMUNRKwKSQEIIIWVZ", + "address": "e9c087222aae35ee37821d62d664ec223f2f5aa57af0cb6b29797b492c2bcc3b", + "module": "ICxMUhgIRAKDgxQr", + "name": "xmAekiqsZH", "type_args": [] } } ], "args": [ { - "U128": "184978467638395630235234185117781944136" + "U8Vector": "1d9ece57c28193" }, { - "U64": "2616397024289982492" + "U64": "17272415624117048522" }, { - "U128": "254139950712531940234997650499677123735" + "U8": 84 }, { - "Bool": false + "U128": "222874246534065957883798634403783466686" + }, + { + "U8Vector": "cc" + }, + { + "Address": "2ec7f7261c9c56c6920afc3484484a291c2b9e122adc0bc5e637ca578824e194" }, { - "U64": "7536268907478363538" + "U64": "14435402601205272797" }, { - "U8": 218 + "Bool": true }, { - "U128": "251754068884130696264236728203220304292" + "U128": "107213817717410373703941531578311036100" } ] } }, - "max_gas_amount": "7047151181682270977", - "gas_unit_price": "4142074427579536419", - "expiration_timestamp_secs": "2255642673682054664", - "chain_id": 112 + "max_gas_amount": "12840238355444255864", + "gas_unit_price": "12794017514012234033", + "expiration_timestamp_secs": "11793030871588086569", + "chain_id": 63 }, - "signed_txn_bcs": "49aa3bc1aecf0874bca007638f1910b483bba9dd8dc74316080bc0f12265b238a14c3d8d5c76190d000ba9049d096a177780df4b8f090603073cea18934fc97b661f7cd4b9dedbc44088f8c262f4e2b09db952bbf1deca67b102726f17614c47716766597149766d454b42624145735353614f56000606060406060207e874563f4cd75ac50bc0bcaf9326a0ac6729e04114dd3b8b5894cdd043f70cf61169634678496754764a727273696e415854045a41644f00078a3db5b4a583000436eb8c1396d55cd8a8d544be63a2049de2ca3d965486aff60b4951456a785343514b6b33034a6a48000606075a127b0f6a2c2b86548f6698a53a3f846ec7414376d6f698e3a53245e57420510556544b52361d61626d697373444a445777507049794664536f6e5a6c58524457774b6100078b216b3e597a2f726b1f6d6d3b8a6bd7c02ccacac3c4e28b9eb2ba77c3aec1a70f416a756a676e6d414f7a69654d6d3807776b6b417a443900077c29b2ae3bd898ad398efe68e4cafa958b82f81be6b2b6966dafc9ed4f358b9914547757575978704c734f706664707241567a51461d556c58494e435462464b74764c4d554e524b774b53514549494957565a00070248679f967446e588048188d7968e298b011c8831383b4f4f240297f426237e4e9093b36e8c26f99231bf05000192ad117aa434966800da02a44163b19f0f0736915aa4c4ea1166bd0163a58ea982cc6123941b09bf9a7b3908fe07910fa74d1f70002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440318ea6f4b998cab6005abab3730b2345c0f98e6a6ccadfd30806f162522c175b55d5b4042511f37caaabc54b9e17a85fec885617ac0c224af7dd0b3f85d0670c", + "signed_txn_bcs": "aa5eba8e03e250c329900ce4e13797cf4d66deba80822730311e0c3110858e67f977d06530194ccb0008b93870f7eaf96afa050741a2f0e04048c7ede38d6e511d2e4e59a7a9d3965cae8eb0d4e4dd39b6b642471244535761796b567867644f4573716651596f0e7643767443736b53755779474232000607545e1ca22490451d45991eb0aa18536b282e09b08851afc5b3df538c95ae7e751951714b71666d69684e4f5078626a5a55766143736867695a361d684e777a69496767664d466f6e557174416f6f576152505247447161390006077e3e7e5293ce77ee5bfec3d67634a12a2a9dbe2ff039e2ddea9689a8f5f5e5450c62525868547679436a7976740a4c6c75736e6a466a7230000307e9c087222aae35ee37821d62d664ec223f2f5aa57af0cb6b29797b492c2bcc3b104943784d5568674952414b44677851720a786d41656b6971735a48000904071d9ece57c2819301ca5467387ff2b3ef005402be5ef7319d02995c2a2fe7f0bd04aca70401cc032ec7f7261c9c56c6920afc3484484a291c2b9e122adc0bc5e637ca578824e19401dd10970a2fda54c8050102c4ccc65263c9d3b00f2a84bf54a1a85078cc99f7c0b031b23151d3b4247b8db1292339761843a9a33f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b2c68ef98cd53b7e6ad96dcda0f4bd90eee6e29d43c2bb439c85ef68fdcad357aad16dc38685f15d550d836187866d6152da3cae9051268e30a7cb0b337e3105", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "91526aadbcbb28706a7f1e3fd72a57760b773c613bc0a90c3febda52a28dbf8d", - "sequence_number": "16514684600105100779", + "sender": "c0032ffd5c674b7eac32e0e070bc19e7bc139727294a51893900fbed4e03f8ee", + "sequence_number": "5014040751203557078", "payload": { "Script": { - "code": "5d", + "code": "57", "ty_args": [ { "struct": { - "address": "b1f2e2166e7aeb01393b3d2d1a92fac238d975dd25a76c99004d9ac957359085", - "module": "fqsfycztZoODfSSLWaeStcsS", - "name": "s8", + "address": "cf631a24c27cc5a63772d0438cab36cd15aa027ccb9722a4fd00766cb8adb876", + "module": "eajfhRGYXAjcEPZXcgXTV", + "name": "sFxmIbksDBjuAfjIqlnbDnJauTILTdpp", "type_args": [] } + }, + { + "vector": { + "vector": { + "struct": { + "address": "0b0a47c2ce208201d824ee7e12ff729505b68e4b4b8c603b5d6680353c6b8ec9", + "module": "GSnuszeFuQeY3", + "name": "wPCPwZ", + "type_args": [] + } + } + } + }, + { + "vector": { + "struct": { + "address": "690399796bf911ec455b356d2b11e1dd1060724f7c51a22d4a828ae42f101d7c", + "module": "Kj3", + "name": "ZcGNKaorwrwJSWWDBuPORCelHPWTi6", + "type_args": [] + } + } + }, + { + "vector": "u64" + }, + { + "vector": { + "struct": { + "address": "b9f386ebe06c0a6189db406ea60f7dc969aeed476a39ffe66e3ddb06adff7451", + "module": "abpaSVxoEbYyYGEmEaSiveidFfLcPuW4", + "name": "xHiVgmvfEXqplIXjHxIYsmZHBCy1", + "type_args": [] + } + } + }, + { + "vector": { + "vector": "u8" + } + }, + { + "vector": { + "vector": "address" + } } ], "args": [ { - "U8Vector": "c2340c5af8edf856eb577815" + "U8": 173 + }, + { + "Address": "0b890df4cb58a6c57a48e3ce7b7fd008d2f1e4bc9d7b03af9c6bb76215ab3c6f" + }, + { + "U64": "15901890813245339400" }, { - "U64": "15161469171796677350" + "Address": "0b1016483f692feca9d86c8593456979b400646ed7807d593ae9ea456ed794c0" }, { - "U8": 170 + "U8": 74 + }, + { + "U8": 120 + }, + { + "Bool": false } ] } }, - "max_gas_amount": "15825405578611127592", - "gas_unit_price": "10384103424025831782", - "expiration_timestamp_secs": "11019528035513869122", - "chain_id": 128 + "max_gas_amount": "6067536402263779936", + "gas_unit_price": "14201549918304428720", + "expiration_timestamp_secs": "10540034508853713370", + "chain_id": 161 }, - "signed_txn_bcs": "91526aadbcbb28706a7f1e3fd72a57760b773c613bc0a90c3febda52a28dbf8debe5e02e25f22fe500015d0107b1f2e2166e7aeb01393b3d2d1a92fac238d975dd25a76c99004d9ac957359085186671736679637a745a6f4f446653534c57616553746373530273380003040cc2340c5af8edf856eb57781501e612fa01e25b68d200aa28f599f386229fdb6629fafb0bbf1b90422343455d3aed9880002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440608badf6f83185c0fecdb2b09b8ea5eb42835d267b18bdc20d62af8c74c5e81b3191d7c75c70a560449747f28f741e29047a4ae9df998cc61d34745a27156d0d", + "signed_txn_bcs": "c0032ffd5c674b7eac32e0e070bc19e7bc139727294a51893900fbed4e03f8eed61ed2687f7395450001570707cf631a24c27cc5a63772d0438cab36cd15aa027ccb9722a4fd00766cb8adb8761565616a666852475958416a6345505a586367585456207346786d49626b7344426a7541666a49716c6e62446e4a617554494c54647070000606070b0a47c2ce208201d824ee7e12ff729505b68e4b4b8c603b5d6680353c6b8ec90d47536e75737a654675516559330677504350775a000607690399796bf911ec455b356d2b11e1dd1060724f7c51a22d4a828ae42f101d7c034b6a331e5a63474e4b616f727772774a535757444275504f5243656c4850575469360006020607b9f386ebe06c0a6189db406ea60f7dc969aeed476a39ffe66e3ddb06adff745120616270615356786f456259795947456d456153697665696446664c63507557341c78486956676d7666455871706c49586a48784959736d5a4842437931000606010606040700ad030b890df4cb58a6c57a48e3ce7b7fd008d2f1e4bc9d7b03af9c6bb76215ab3c6f010837895c71ddaedc030b1016483f692feca9d86c8593456979b400646ed7807d593ae9ea456ed794c0004a00780500602aafee35383454b062835c680a16c5da9995d48ab94592a1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440bdffe8554083491fc3902827be34b7575acbdb71e58bcb25d43dfa9b14c7d0a2476a7d93098c71652049937f670c637a57db0dc98a2d56f6e1e5b55e31ed9502", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "a50b4b5b6fffe00d147c375018f4f62380f3de157b20f72e29909f1c994bbcf6", - "sequence_number": "16835229308990646972", + "sender": "07d2d9d47555a2cb6d8f2ebe2ace211be4ac7b427190da9e82d0529d84fa593b", + "sequence_number": "7910615762214382748", "payload": { "Script": { - "code": "f6da83992d", + "code": "f37bf4eff88f4c", "ty_args": [ + { + "struct": { + "address": "bb1bee0d6e6a075ce110bfb62a5719c2b3e1a1148c925aaf40368c081815cac7", + "module": "EcbotWWWoGhiZcrrkUM", + "name": "E1", + "type_args": [] + } + }, { "vector": { - "vector": "u64" + "struct": { + "address": "8724ec15a2053fef507c969595d47a62fa5244f2a3c4723f331544f0700bde1f", + "module": "i9", + "name": "HPINdbCuPHWYieJDdcrzhDXYmgZPxhb", + "type_args": [] + } + } + }, + { + "struct": { + "address": "62aa6f94583893de69e3a7343ba05211552eb60adeeac3b6dbedb3883ec6b2df", + "module": "hTHgQvlgRauAjMclCLyh", + "name": "epgWalfymVPmSMBG", + "type_args": [] + } + }, + { + "struct": { + "address": "17e74ee1a03fffa75cfb38cb97b1cdb6406f2e59db05ebcea7f390bd5dea20a6", + "module": "cjKvAtURRiTovgdgfnfHhxMoSqwflk8", + "name": "rphlzORmvtxYMq3", + "type_args": [] } }, { "struct": { - "address": "2ef68a7e9947f4b43ab42c7d68621939fffb6465176219745f9ee1023ac8614c", - "module": "QGMzzFoSrxfttVaMKmINOLUYXwkxH9", - "name": "EhicIJOlzjUtqJcPOWamXuiP", + "address": "cdc5d7fd0eeef750cc7247b83eb0aa09153455577b5b356facc2d64f3e950846", + "module": "wVccunfXRtmzBPiEWftAfH0", + "name": "KUOmRPPiijLjybgEzulh8", "type_args": [] } }, + { + "vector": { + "struct": { + "address": "ee2862aebcbf7b1516baea15664b888ed3bdd53a140352ef925aa0125a0e0c5e", + "module": "QPbsDoJlVSdcj2", + "name": "nugHzaCtpLwGBapNHaNIXvIEWN", + "type_args": [] + } + } + }, { "struct": { - "address": "58299d2e16f139f19d71939c1142e63426448712aeffbfc8684cf706ff228ccb", - "module": "uKADNMSseOhhqWDIJsbhM3", - "name": "xxbBTedOaGVluJzbizrfJEMP4", + "address": "9f1f637929cf2aa569adc169780e0146da97e6ca7082acb99fd46222f0628898", + "module": "NxKxxhxCxxPyOVgbnK8", + "name": "GxMAkJerHqnD", "type_args": [] } } ], "args": [ { - "U64": "10171033063516062128" + "U128": "306786671993115455744181353170353173379" + }, + { + "U8Vector": "df48d77ea8f0bc" + }, + { + "U8": 156 + }, + { + "U8": 74 + }, + { + "U64": "7429020534841168214" + }, + { + "U8": 225 } ] } }, - "max_gas_amount": "4013181934439521811", - "gas_unit_price": "4593988229141740668", - "expiration_timestamp_secs": "16855507443251563415", - "chain_id": 151 + "max_gas_amount": "17637792777810475238", + "gas_unit_price": "6543983681056533918", + "expiration_timestamp_secs": "13531786298246877595", + "chain_id": 165 }, - "signed_txn_bcs": "a50b4b5b6fffe00d147c375018f4f62380f3de157b20f72e29909f1c994bbcf6bceaa112dcbfa2e90005f6da83992d03060602072ef68a7e9947f4b43ab42c7d68621939fffb6465176219745f9ee1023ac8614c1e51474d7a7a466f53727866747456614d4b6d494e4f4c555958776b7848391845686963494a4f6c7a6a5574714a63504f57616d58756950000758299d2e16f139f19d71939c1142e63426448712aeffbfc8684cf706ff228ccb16754b41444e4d5373654f6868715744494a7362684d3319787862425465644f6147566c754a7a62697a72664a454d5034000101b0c1a0cdaec4268d135e48e5b4afb1377cbc5154f41fc13f974bf61fb7caeae997002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e627ad44cbc5dcc99c95d01dac18dce3e8582d3d47c130088d780c66c36cc79ccedea02cf6bde6f97de1c02a12ea20bff7358920b552310fa112c7d8554dc200", + "signed_txn_bcs": "07d2d9d47555a2cb6d8f2ebe2ace211be4ac7b427190da9e82d0529d84fa593b9cec649d1f27c86d0007f37bf4eff88f4c0707bb1bee0d6e6a075ce110bfb62a5719c2b3e1a1148c925aaf40368c081815cac7134563626f745757576f4768695a6372726b554d0245310006078724ec15a2053fef507c969595d47a62fa5244f2a3c4723f331544f0700bde1f0269391f4850494e646243755048575969654a446463727a684458596d675a50786862000762aa6f94583893de69e3a7343ba05211552eb60adeeac3b6dbedb3883ec6b2df146854486751766c67526175416a4d636c434c79681065706757616c66796d56506d534d4247000717e74ee1a03fffa75cfb38cb97b1cdb6406f2e59db05ebcea7f390bd5dea20a61f636a4b76417455525269546f76676467666e664868784d6f537177666c6b380f7270686c7a4f526d767478594d71330007cdc5d7fd0eeef750cc7247b83eb0aa09153455577b5b356facc2d64f3e9508461777566363756e665852746d7a4250694557667441664830154b554f6d52505069696a4c6a796267457a756c6838000607ee2862aebcbf7b1516baea15664b888ed3bdd53a140352ef925aa0125a0e0c5e0e51506273446f4a6c565364636a321a6e7567487a614374704c77474261704e48614e4958764945574e00079f1f637929cf2aa569adc169780e0146da97e6ca7082acb99fd46222f0628898134e784b7878687843787850794f5667626e4b380c47784d416b4a657248716e4400060283b3ca855dda3b95b905a273bcf6cce60407df48d77ea8f0bc009c004a0156514ad8d02e196700e1e6f857171507c6f49eed53857ce6d05a9bd1809bf18fcabba5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444088ed8381490548b7ae0d3bf6428939b9276da5152b5830ae924283939a3c65a325fef60026d93dd198326803b11c8a4c10af27695a2cd0e378d3a8b3987f090b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "fb420db4689874e7cfe605c6420fafa22035b995b6c4013cfb03cceab95bacb1", - "sequence_number": "5826606718587375740", + "sender": "e197a41f55d5a8f47aa530993d2a18cdadcd308c7cf9281b6af44068c1c0e65d", + "sequence_number": "15985993478924758817", "payload": { "Script": { - "code": "4315c1468b2c490d", + "code": "7cfd68cc42ab84a48311db8fd00e", "ty_args": [ { - "struct": { - "address": "d22bc0c0cdc3889aaacaeabcb68e9c8dd8e84de731d58aeb0572c3100e7d8611", - "module": "EtgbHUO7", - "name": "tBDkxunfwqcxmAyU", - "type_args": [] + "vector": { + "vector": { + "vector": "u8" + } + } + }, + { + "vector": { + "vector": { + "vector": "u64" + } } }, { "struct": { - "address": "f52b94584877600a12b6478c6c035753bc625578cd655055876ff8d5485fd61e", - "module": "wxiFgOVxniIqDGvaMgIQKYmpBXQ2", - "name": "ErVoyupK", + "address": "f1e41beeaa472b049fe85e838b6a9982855b39a0f0a6f2bca90247f732ea7c1f", + "module": "Wtek", + "name": "NRGKVVlQxePzEnfMr3", "type_args": [] } }, { "struct": { - "address": "7a677c2e367633f817a1d81f52b2bd1a26ef9add44d2e32a5e7bdd5b07daf5aa", - "module": "mIiFLyjTaXUxaYTRZzdbfPSj", - "name": "i8", + "address": "496c1afd43e76b5bd9b6aedd0b185fa17c45c700f58bd5ed025b88d8311f0338", + "module": "rBu3", + "name": "fgTpkbjNruHbvHffkXaYozPkfMZYNkj0", "type_args": [] } }, { - "vector": { - "vector": "address" + "struct": { + "address": "cb2f4c5296102b1b5435597480352325e9875f8aa0d9d1363cb71b1a9646c480", + "module": "nYjkPeipwDMcVwS7", + "name": "VVDtIRorxNg2", + "type_args": [] } }, { "vector": { "struct": { - "address": "a9eac72834be97f81bef842fcba58ed64206dcebd8374b0d6db056bc2759a307", - "module": "r6", - "name": "qRH", + "address": "721577b2f653fe725c4f6efd658ff4d2e5a64737a69ff57fb57dff1648bc01d3", + "module": "QMmGIMCgXuJjahiruMNkNPvWIujuLZ", + "name": "msXkGEddwHkRMgGEsLkcoSokHSWCHby", "type_args": [] } } + }, + { + "struct": { + "address": "884dfbeee68f767ee33ff547074f33cfd72a7e148e009581db80436716a4299f", + "module": "friXLwOSCNPtrudcNuKETXcsECDm6", + "name": "dHVrGFkHkKBeATMz", + "type_args": [] + } } ], "args": [ { - "U8Vector": "58ebbe5f792fe99bbdaa2ecda6" + "Address": "0d52581587c27234112a1f90778feda2d8670e88a5250c8d6ea13c782d016ebd" }, { - "U128": "72177508439034498538853631892127474356" + "Bool": false }, { - "U128": "156027757285584213157579780422170453880" + "U128": "118192579823141803869441249422430204340" }, { - "Bool": false + "U8Vector": "f96fabdfdff14c1b2bccddd87d" + }, + { + "U128": "14923363319826848102844136152729516787" + }, + { + "Address": "8a74b993f4bd5bf250bc448c99333e57e1cc71c78506ecaa580e10ddaf549c95" + }, + { + "U128": "136551542986760826840617261584197226574" }, { - "U8Vector": "3c43bb8cc7ec09ca1b95ca30" + "U64": "14291322353618468924" + }, + { + "Bool": true + }, + { + "U128": "40203162341521008532440479979341511068" } ] } }, - "max_gas_amount": "2783700821253608093", - "gas_unit_price": "2335682078354024113", - "expiration_timestamp_secs": "5219432038205066666", - "chain_id": 169 + "max_gas_amount": "1732126496613337009", + "gas_unit_price": "9370383186405701075", + "expiration_timestamp_secs": "9708959958149694766", + "chain_id": 250 }, - "signed_txn_bcs": "fb420db4689874e7cfe605c6420fafa22035b995b6c4013cfb03cceab95bacb17c104e9bf043dc5000084315c1468b2c490d0507d22bc0c0cdc3889aaacaeabcb68e9c8dd8e84de731d58aeb0572c3100e7d8611084574676248554f37107442446b78756e66777163786d4179550007f52b94584877600a12b6478c6c035753bc625578cd655055876ff8d5485fd61e1c77786946674f56786e694971444776614d6749514b596d7042585132084572566f7975704b00077a677c2e367633f817a1d81f52b2bd1a26ef9add44d2e32a5e7bdd5b07daf5aa186d4969464c796a5461585578615954525a7a64626650536a026938000606040607a9eac72834be97f81bef842fcba58ed64206dcebd8374b0d6db056bc2759a307027236037152480005040d58ebbe5f792fe99bbdaa2ecda602b4e29bf869a16c1380e10f4deae14c36027827a6926bbcc83c11ad6ca15dda61750500040c3c43bb8cc7ec09ca1b95ca309dd2c8f325b1a126b1a689ac79026a20aa8d81f6c8256f48a9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144406000f2e2e75b2f7eb368ab2c81d76713c568fb07de1c7ab34f698cf31a84f35d58e833c4e310b9ddba9cfc5ca3a609274202824383f5973e48253ccba7cf100c", + "signed_txn_bcs": "e197a41f55d5a8f47aa530993d2a18cdadcd308c7cf9281b6af44068c1c0e65d216f05255fa8d9dd000e7cfd68cc42ab84a48311db8fd00e07060606010606060207f1e41beeaa472b049fe85e838b6a9982855b39a0f0a6f2bca90247f732ea7c1f045774656b124e52474b56566c517865507a456e664d72330007496c1afd43e76b5bd9b6aedd0b185fa17c45c700f58bd5ed025b88d8311f0338047242753320666754706b626a4e72754862764866666b5861596f7a506b664d5a594e6b6a300007cb2f4c5296102b1b5435597480352325e9875f8aa0d9d1363cb71b1a9646c480106e596a6b5065697077444d63567753370c5656447449526f72784e6732000607721577b2f653fe725c4f6efd658ff4d2e5a64737a69ff57fb57dff1648bc01d31e514d6d47494d436758754a6a61686972754d4e6b4e50765749756a754c5a1f6d73586b4745646477486b524d674745734c6b636f536f6b485357434862790007884dfbeee68f767ee33ff547074f33cfd72a7e148e009581db80436716a4299f1d667269584c774f53434e5074727564634e754b45545863734543446d36106448567247466b486b4b426541544d7a000a030d52581587c27234112a1f90778feda2d8670e88a5250c8d6ea13c782d016ebd050002b471a0d4e1b91082830eb1271810eb58040df96fabdfdff14c1b2bccddd87d02f3fa593b17b273f4c1c1d55b9e223a0b038a74b993f4bd5bf250bc448c99333e57e1cc71c78506ecaa580e10ddaf549c95024e10f28b169788c934e931f5dcdeba66013c400742f6f954c60501029c79221d247c229f88298499f0d83e1eb107ae18dfbf0918d3350193dc490a822e050144a427bd86fa002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440714442e38dd5122dd2392396bdc9392850f1c39a8618b4ba287a23a589e34c33796d3f93280bb9052077c3de9ae92e742ab52d50a96c3d5991b75803323f9b03", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "d5df8f1df59ce813caf86bb7814ce9aedca45b0f6ef792d908f6e0efc6444bab", - "sequence_number": "12821437480896073078", + "sender": "584e27862d6a7a6459c385052e56b16ba7c033bc6f1284c19d06f35befdcce01", + "sequence_number": "3042360372311368557", "payload": { "Script": { - "code": "a1c3e8ec18ffb0bdcb", + "code": "4a0756c70f06", "ty_args": [ { "vector": { "struct": { - "address": "2f97bc3fa65e29780a23c2b40e79c57f4e8f681bfa59068b12608ec3b66bd88b", - "module": "ASqosndJldXnQThJrPwyMSpuspcpkqP", - "name": "XxkLRcpsXwMkWpdaVIaZ", + "address": "8d631ad9e2c07be487b793e5c082707d3a3b8595bf73ee94a7f04655a48f66e1", + "module": "mnMuxgWoKQflOvwrXBMFIQzLYgMFXapm5", + "name": "QaMLRIfXTPzLaErVbmoGaOYGIJRi", "type_args": [] } } }, - { - "struct": { - "address": "82748436ed02a86d3ce308f63fa072ad5daca827b15baa953b119b7259d95626", - "module": "oIftGGK4", - "name": "gswkSgp7", - "type_args": [] - } - }, { "vector": { "vector": { - "struct": { - "address": "9bccb36c9fa416b3ee2602f6c9e214e1477bc1e441a5cab39fdb3f7f10e2c0f8", - "module": "smrEi6", - "name": "OOvzVAcsWTWVUEOfflU", - "type_args": [] - } + "vector": "u8" } } }, { "vector": { - "struct": { - "address": "b206bb8c4b591984976e8e53d2c6d44a0792afe964384ab3410c80f3aa677c8e", - "module": "mGMnzhETHGqQ1", - "name": "bF6", - "type_args": [] - } - } - }, - { - "struct": { - "address": "ce2fd627c60af9089ed5d45173f5327614dd9d579670ae3d986c0e5d5ba86e4b", - "module": "kzgNWxrDn0", - "name": "iGhrXCoRZsAVrrwEwJEojLBrdEy4", - "type_args": [] + "vector": "address" } }, { "vector": { - "struct": { - "address": "191ff413706125dd8a337e91668f2e6a8268066de50d794619904b741481eda8", - "module": "cmNdEaBcS5", - "name": "VmOFYNLaqaRuUkDaTV5", - "type_args": [] + "vector": { + "struct": { + "address": "e712972ac65c88c0c7829585a24aec902fc8a7da5944411c792004d5a51bee07", + "module": "amtZlxtca", + "name": "HJIAe", + "type_args": [] + } } } } ], "args": [ { - "U8": 220 + "Bool": true + }, + { + "U64": "1129289047097439740" + }, + { + "Bool": true }, { - "U8": 138 + "U128": "82499140802586845079355174818694921217" }, { - "Address": "a0dc0e5c0b6a56b24f6db3640348cbf4d437159d46ca53ae0462ebae9580efb9" + "U64": "7102508758265109256" } ] } }, - "max_gas_amount": "5957046504815328649", - "gas_unit_price": "16926931739088385739", - "expiration_timestamp_secs": "13040940422862090611", - "chain_id": 10 + "max_gas_amount": "2622500318438106821", + "gas_unit_price": "15327403766450772212", + "expiration_timestamp_secs": "13907208539078655062", + "chain_id": 225 }, - "signed_txn_bcs": "d5df8f1df59ce813caf86bb7814ce9aedca45b0f6ef792d908f6e0efc6444bab768db03e75e5eeb10009a1c3e8ec18ffb0bdcb0606072f97bc3fa65e29780a23c2b40e79c57f4e8f681bfa59068b12608ec3b66bd88b1f4153716f736e644a6c64586e5154684a725077794d537075737063706b71501458786b4c5263707358774d6b577064615649615a000782748436ed02a86d3ce308f63fa072ad5daca827b15baa953b119b7259d95626086f49667447474b34086773776b53677037000606079bccb36c9fa416b3ee2602f6c9e214e1477bc1e441a5cab39fdb3f7f10e2c0f806736d72456936134f4f767a564163735754575655454f66666c55000607b206bb8c4b591984976e8e53d2c6d44a0792afe964384ab3410c80f3aa677c8e0d6d474d6e7a6845544847715131036246360007ce2fd627c60af9089ed5d45173f5327614dd9d579670ae3d986c0e5d5ba86e4b0a6b7a674e577872446e301c6947687258436f525a73415672727745774a456f6a4c427264457934000607191ff413706125dd8a337e91668f2e6a8268066de50d794619904b741481eda80a636d4e6445614263533513566d4f46594e4c6171615275556b4461545635000300dc008a03a0dc0e5c0b6a56b24f6db3640348cbf4d437159d46ca53ae0462ebae9580efb989fdfffd3baeab52cbf6a5e5bb8ae8ea7331ba8138bafab40a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440911dbb82048e9b7f226e7f44489a9bb6fad609a54418291338d547d2d5d19bf1edb3c0a7b9774f5d27bd1881d4b5634a7cf9806fbc887bd170e964a740fe330d", + "signed_txn_bcs": "584e27862d6a7a6459c385052e56b16ba7c033bc6f1284c19d06f35befdcce016d2358b6a3a2382a00064a0756c70f060406078d631ad9e2c07be487b793e5c082707d3a3b8595bf73ee94a7f04655a48f66e1216d6e4d757867576f4b51666c4f76777258424d4649517a4c59674d465861706d351c51614d4c5249665854507a4c61457256626d6f47614f5947494a52690006060601060604060607e712972ac65c88c0c7829585a24aec902fc8a7da5944411c792004d5a51bee0709616d745a6c7874636105484a4941650005050101fc75fbb4670aac0f050102017c757da8279bc10544b64baec1103e01081b7ebe152e9162c526da1f25fe6424f458487c84e0b5d456fc0f957b5400c1e1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440f26d6db4fdfdc177c5fa316d52d89ab2f0c835943bee34ef504881332b5fbc9db4499886c5603c3107980861ec9934afc71d16cf0a233aad0360fc5078f82102", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "42c53ee250a5ed6f23e98c6c5b170be36d2dbaa0270a5c0135323d26ebf2fd02", - "sequence_number": "9287665328597658750", + "sender": "0b9c2120a042949babc98c0154fec9d0bf28f02730a0fd52149b1ee5467cc0d2", + "sequence_number": "8418523283924709462", "payload": { "Script": { - "code": "cda6c0", + "code": "4076ad2be2c5efef2cd3", "ty_args": [ { - "struct": { - "address": "52d78828abeec6a65c2f1262cdba27244469eb67bf2ad2510806302a4036977c", - "module": "dHCmBfZdzkGfiMieNsmsej", - "name": "x0", - "type_args": [] + "vector": { + "vector": { + "struct": { + "address": "c267be4d1528680991fdc479fdd022e72f925ea43ccc3fa38de0287b1606d843", + "module": "bKrUdcAPssHEWqRTBjaFp7", + "name": "JpACqrtCGlAjGNJxOps", + "type_args": [] + } + } } }, { - "struct": { - "address": "5e492f2dbb9d0651d62955ae8ebfbf40c1c64091542af3778f6199f4bccdbece", - "module": "yDwxyz", - "name": "GLHXDmS4", - "type_args": [] + "vector": { + "vector": "u8" + } + }, + { + "vector": { + "vector": "u128" } }, { "struct": { - "address": "afa47f59857d33e239e653b1ae45f7e93c24fe2bd5dff624c3e0fef498b8afba", - "module": "NlKxMgenzkGsWMMAFrNrkhxRdcnydHCB", - "name": "WtxIBpuiAqRJvBdnByLn", + "address": "d1097175be1dafa0765bc144e174d9be0dc05b6e3a9e247bbb2ea208bd964eea", + "module": "jeHtzDAyRVUjzrzfEjQr8", + "name": "PvRftigRNAFsAEbCuODm5", "type_args": [] } }, { - "vector": { - "struct": { - "address": "247f0956ffb1144123117bea3efe3f286025323565519de336b5bb3ad52f865f", - "module": "MQRSndErPrGiOxfKcJ1", - "name": "rNUCjlDRdrNQihETLWmDCkiXkuMEBTOL0", - "type_args": [] - } + "struct": { + "address": "29d4d7b1214bbcd48383245d0492c4a7e2c90c3992168708cc2096c8b47ab238", + "module": "zSOemu", + "name": "M2", + "type_args": [] } }, { "struct": { - "address": "f2c69f158ceab61223207cca99ff0b731deb2b89782c44a602a10c6f8b2afacf", - "module": "kPvrxfetmfFquJTaLatnIYGlqfBlQgo", - "name": "cNSKGmXPddsdHoRhYLoNNVONPLubeMVq8", + "address": "8b118d4a6c93414571f691198f0d12db5beabc20033850dadf25524a1e56c932", + "module": "bSuBvSGKAvlkDTiGdNoJkf6", + "name": "qCCpzppIZvyVAbQfrskOVIvCcvKp", "type_args": [] } }, { "struct": { - "address": "2fb958330e94313e56938ac293bd0f18fc0687655e17e4e8f6553fdb288f8222", - "module": "LbxwzmPLrtjpBmeBfxrDKO", - "name": "CdJwZSspwQZygYRWC9", + "address": "bb4a8b5383e6a91016a46ec8dfda31ac1198ee6260100974151b2f09220dc2f9", + "module": "hHhSUcUo", + "name": "UgDQmERiuYejDQsaWIsatuoUzG6", "type_args": [] } } ], "args": [ { - "U8Vector": "26ae4fc52b5abc8fefc24db8e2" - }, - { - "Address": "efdeca410a2abd580ddbefa435f4327755d059f60c4ab0efbe479668aa2267dc" - }, - { - "Bool": false + "Address": "cd79d6d0e581e422e4bc11988bbe0bef2dfebbcb45f00ebef181d7c040f735e4" }, { - "U8": 161 + "U128": "68942842412514201517218368923699049517" }, { - "U128": "188265901547279518962912897258701323103" + "U8": 216 } ] } }, - "max_gas_amount": "4333006260350701639", - "gas_unit_price": "17455251202340989571", - "expiration_timestamp_secs": "4321074352408813668", - "chain_id": 145 + "max_gas_amount": "7720715308021314329", + "gas_unit_price": "1563391181758931021", + "expiration_timestamp_secs": "18033160152886928644", + "chain_id": 191 }, - "signed_txn_bcs": "42c53ee250a5ed6f23e98c6c5b170be36d2dbaa0270a5c0135323d26ebf2fd027e6cc67f686ae4800003cda6c0060752d78828abeec6a65c2f1262cdba27244469eb67bf2ad2510806302a4036977c166448436d42665a647a6b4766694d69654e736d73656a02783000075e492f2dbb9d0651d62955ae8ebfbf40c1c64091542af3778f6199f4bccdbece0679447778797a08474c4858446d53340007afa47f59857d33e239e653b1ae45f7e93c24fe2bd5dff624c3e0fef498b8afba204e6c4b784d67656e7a6b4773574d4d4146724e726b68785264636e79644843421457747849427075694171524a7642646e42794c6e000607247f0956ffb1144123117bea3efe3f286025323565519de336b5bb3ad52f865f134d5152536e644572507247694f78664b634a3121724e55436a6c445264724e51696845544c576d44436b69586b754d4542544f4c300007f2c69f158ceab61223207cca99ff0b731deb2b89782c44a602a10c6f8b2afacf1f6b507672786665746d664671754a54614c61746e4959476c7166426c51676f21634e534b476d585064647364486f5268594c6f4e4e564f4e504c7562654d56713800072fb958330e94313e56938ac293bd0f18fc0687655e17e4e8f6553fdb288f8222164c6278777a6d504c72746a70426d6542667872444b4f1243644a775a53737077515a796759525743390005040d26ae4fc52b5abc8fefc24db8e203efdeca410a2abd580ddbefa435f4327755d059f60c4ab0efbe479668aa2267dc050000a1025ffbd9415f304c3758acf64498b1a28d4750bf8d3cee213c83aabe947c823df264e060bf3a8af73b91002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400a571edb19b7f97e05738e44a4b86a5198739e6b066414225a77362a13ef019a0bb4f633d0b425143c638e2d7bee156d4d1e39f40d68441ae96e6624361f1807", + "signed_txn_bcs": "0b9c2120a042949babc98c0154fec9d0bf28f02730a0fd52149b1ee5467cc0d256f0afcf529ad474000a4076ad2be2c5efef2cd307060607c267be4d1528680991fdc479fdd022e72f925ea43ccc3fa38de0287b1606d84316624b7255646341507373484557715254426a61467037134a70414371727443476c416a474e4a784f70730006060106060307d1097175be1dafa0765bc144e174d9be0dc05b6e3a9e247bbb2ea208bd964eea156a6548747a4441795256556a7a727a66456a5172381550765266746967524e41467341456243754f446d35000729d4d7b1214bbcd48383245d0492c4a7e2c90c3992168708cc2096c8b47ab238067a534f656d75024d3200078b118d4a6c93414571f691198f0d12db5beabc20033850dadf25524a1e56c93217625375427653474b41766c6b44546947644e6f4a6b66361c714343707a7070495a7679564162516672736b4f5649764363764b700007bb4a8b5383e6a91016a46ec8dfda31ac1198ee6260100974151b2f09220dc2f908684868535563556f1b556744516d4552697559656a445173615749736174756f557a4736000303cd79d6d0e581e422e4bc11988bbe0bef2dfebbcb45f00ebef181d7c040f735e4022df4a40933d121827f5a4a2f91e8dd3300d819f387a2aa7d256b4d20b821ff47b21504e58d829da742fabf002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444059c6779aa02293415326f155ad1b08d309329f1b8d505a1dde1e65baaaa212e2357d164e5c697f6e78bc96883865e21a36e5e4352bcc2f5b86f9e0032770b703", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "aa332235096dae1896447526be2aaf823cadc4072c85431a568a14721ed44c4e", - "sequence_number": "9809558636918014699", + "sender": "ab6b2b8e1a11486830905b96a08c3cabb7d977ec793088d1e7b1fc5c0604e307", + "sequence_number": "12601294073069459265", "payload": { "Script": { - "code": "adf87b26", + "code": "7e693a91ea669472cf6e70", "ty_args": [ { "vector": { - "struct": { - "address": "2adb820d7f64fda7c4c987cab5b751513c8871d2d22b15f884b4d447a9c67d3b", - "module": "MowDeQUqQciyaPmYdkYwAvIzPxr3", - "name": "KrixLDeQa", - "type_args": [] - } + "vector": "u128" } }, { - "vector": { - "vector": { - "struct": { - "address": "85bd10d584274dd9481f0a1831b85905fd2930b0c5e02cf728f847297d3e99de", - "module": "aMwyLBIBKIFWiEhROqhwktSzRNyqMoAe4", - "name": "URLGRXmhHItBYpUWxSCHkOmt", - "type_args": [] - } - } - } + "vector": "u128" }, { "struct": { - "address": "a006f96390783ee993b522a0421cc0cd3281212aa95f4f429f7e0295c3a23ef3", - "module": "KcabCqVaUeVaVbQmVHDeFTY0", - "name": "vimrlNKMMCAZ", + "address": "e5cffc16cc1cce1ec1cb6cbf2b64200929ab6cda926d0fe8791fafbe5aead50a", + "module": "qzopxs0", + "name": "IOmqEdvJxsgYJ", "type_args": [] } }, { "struct": { - "address": "c3e35240457eeaf994a111bf36c9ee93d7733c1e8e492cd4bb8b662dec3a3170", - "module": "ipxmHxgotFcWYImAsHdwgy", - "name": "qEPzGfeDtijruyXRfEfqGNC", + "address": "0971476864e3cfca7f8b43223ab985e110b60c626849a62cd122a86fe5b90886", + "module": "YQtiOcIpCLaxKhOsVkfexGlesyQm", + "name": "jWSJTXETJLQpmIHZQgkZo", "type_args": [] } }, { - "vector": { - "struct": { - "address": "86213050de96e43aedefe586b233ce77840abd49735ba701e2155530a1f4bb38", - "module": "wEDSTAhzxhvOYu2", - "name": "gwYzMGquaFuIc", - "type_args": [] - } + "struct": { + "address": "391824e42ca3c28efd452ce03bfc0dc79091e29bec7b496f7261cd3f3acb2192", + "module": "DBKsgzfEfRYYnRjh7", + "name": "BB", + "type_args": [] } }, { "vector": { "struct": { - "address": "2dc5670499c357b06313e8569f54635cfd6550d58dd88fe6a6122ae2cabec984", - "module": "gVrxGRiaBIZJS", - "name": "jZU1", + "address": "64b9726e58bc4c5943c5ef8a71b3a2c39b303fe3bd73c0364d248586f007d934", + "module": "saKFWQ6", + "name": "ZEBvhSJQtm", "type_args": [] } } @@ -5908,234 +6305,300 @@ ], "args": [ { - "U128": "288030427202234136605094063789654441825" - }, - { - "U8": 134 - }, - { - "Bool": false - }, - { - "U128": "319501370971646994301660070280920866705" + "Bool": true }, { - "Address": "6bee732c90d85b47facb213a3f80615027ef1a2f9900b40f9e92c02410d475f7" + "U8Vector": "ddf22eeded981b6b14a3a26a25e1" }, { - "Address": "d5be5dc7ce66492758e868df31f58c0eb73718100e8f47aa2dd15203794d1175" + "U64": "4609310245914815820" }, { - "Bool": true + "U8Vector": "e5" } ] } }, - "max_gas_amount": "7840909704778509361", - "gas_unit_price": "2099018007977147000", - "expiration_timestamp_secs": "17693806140635264453", - "chain_id": 22 + "max_gas_amount": "11024527293977263202", + "gas_unit_price": "5729072554979043309", + "expiration_timestamp_secs": "11085322295844090727", + "chain_id": 163 }, - "signed_txn_bcs": "aa332235096dae1896447526be2aaf823cadc4072c85431a568a14721ed44c4eeb02dd649b8d22880004adf87b260606072adb820d7f64fda7c4c987cab5b751513c8871d2d22b15f884b4d447a9c67d3b1c4d6f7744655155715163697961506d59646b59774176497a50787233094b7269784c446551610006060785bd10d584274dd9481f0a1831b85905fd2930b0c5e02cf728f847297d3e99de21614d77794c4249424b494657694568524f7168776b74537a524e79714d6f4165341855524c4752586d684849744259705557785343486b4f6d740007a006f96390783ee993b522a0421cc0cd3281212aa95f4f429f7e0295c3a23ef3184b63616243715661556556615662516d56484465465459300c76696d726c4e4b4d4d43415a0007c3e35240457eeaf994a111bf36c9ee93d7733c1e8e492cd4bb8b662dec3a3170166970786d4878676f7446635759496d41734864776779177145507a4766654474696a727579585266456671474e4300060786213050de96e43aedefe586b233ce77840abd49735ba701e2155530a1f4bb380f774544535441687a7868764f5975320d6777597a4d47717561467549630006072dc5670499c357b06313e8569f54635cfd6550d58dd88fe6a6122ae2cabec9840d675672784752696142495a4a53046a5a5531000702617fe8865e3ad3c640470e8b78a4b0d80086050002919fe854ad58c6dd7f18b395cbb95df0036bee732c90d85b47facb213a3f80615027ef1a2f9900b40f9e92c02410d475f703d5be5dc7ce66492758e868df31f58c0eb73718100e8f47aa2dd15203794d11750501316c3c65d581d06c783aa0d6c135211dc5b53069f0068df516002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409a26537b03484dce60d68f2641df036d165d8eb0b7fb5846a3d5d641ed6a6a15bc4b8785caebce4b088059ed19311e4d76a15d78c6fc8474cf8033f3fdd46a08", + "signed_txn_bcs": "ab6b2b8e1a11486830905b96a08c3cabb7d977ec793088d1e7b1fc5c0604e30741578ae731cae0ae000b7e693a91ea669472cf6e7006060603060307e5cffc16cc1cce1ec1cb6cbf2b64200929ab6cda926d0fe8791fafbe5aead50a07717a6f707873300d494f6d714564764a787367594a00070971476864e3cfca7f8b43223ab985e110b60c626849a62cd122a86fe5b908861c595174694f634970434c61784b684f73566b666578476c657379516d156a57534a545845544a4c51706d49485a51676b5a6f0007391824e42ca3c28efd452ce03bfc0dc79091e29bec7b496f7261cd3f3acb21921144424b73677a6645665259596e526a683702424200060764b9726e58bc4c5943c5ef8a71b3a2c39b303fe3bd73c0364d248586f007d9340773614b465751360a5a45427668534a51746d00040501040eddf22eeded981b6b14a3a26a25e1014c2d525b3f8ff73f0401e562fc1cd629fdfe98ed27f78322c1814f67338140e5f9d699a3002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444096970f338a8c920dd8d4cde4512fb4bfc34a4ce482b57e745073255ed42be8f597b5345148b8b19690362726069404c5b586f0aa2f220d7130a597593d06ab08", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "5c73f1dc1f6bf87873865caed16e3527ae148e3e403cba5b03416aadb48fbc54", - "sequence_number": "1815782951030465357", + "sender": "2c3b9404a0bbfb161c21b5bdd8cfab322dfd3e0d7ec5957716d232de67a1f4e3", + "sequence_number": "8264196253837583744", "payload": { "Script": { - "code": "aca45bb904", + "code": "8a54c2ae8a7a8ff9a741bf5fccb2d675", "ty_args": [ { "struct": { - "address": "e31b67000cae580a5d7bfaaa7bd63fa896d52f848f485ed1db5c07ed072083f7", - "module": "PWXSxukpGaGHmFqId2", - "name": "wuXlqciznFlqdbiBhC", + "address": "e674b9995fafd64ad8486793c63dacd98e3ff5c6d2b795d371097c8a5af47e0f", + "module": "GZMzqFR", + "name": "OSXBkkFIrBucmzVU3", "type_args": [] } }, { "struct": { - "address": "2880740b32162044eb600a2f5edad8dfc5fbb5c3eeccd6bde90fe993acd96675", - "module": "UmulCdRnzJQSt", - "name": "mYQdeCtsVbbRVupDdgjAAepqxxEH4", + "address": "6eb77c9141dea54f4e58a29f4c9b69c688a34474e9a920634d85555d1752f68a", + "module": "LrnStE", + "name": "XNjMtPLuHfweqtuvjLVEGsBfPqCIVNJ", "type_args": [] } + }, + { + "vector": { + "vector": "u8" + } } ], - "args": [] + "args": [ + { + "U8Vector": "6a4597d9d8" + }, + { + "Address": "b1968253ed1254407d38e569f3827fb6a1a8d928ddd5accef0351d562282920e" + }, + { + "U128": "186707421460848458310452463163448828768" + }, + { + "Bool": true + }, + { + "U128": "208868171904263487706822830267964677768" + }, + { + "U128": "64306121334804148670540023868498182337" + } + ] } }, - "max_gas_amount": "17350715829852566773", - "gas_unit_price": "7220038959882769063", - "expiration_timestamp_secs": "11902278560671980246", - "chain_id": 3 + "max_gas_amount": "11556856339225058913", + "gas_unit_price": "10456992466620457051", + "expiration_timestamp_secs": "5205563897016189139", + "chain_id": 29 }, - "signed_txn_bcs": "5c73f1dc1f6bf87873865caed16e3527ae148e3e403cba5b03416aadb48fbc544da36139f9f432190005aca45bb9040207e31b67000cae580a5d7bfaaa7bd63fa896d52f848f485ed1db5c07ed072083f7125057585378756b70476147486d4671496432127775586c7163697a6e466c7164626942684300072880740b32162044eb600a2f5edad8dfc5fbb5c3eeccd6bde90fe993acd966750d556d756c4364526e7a4a5153741d6d59516465437473566262525675704464676a414165707178784548340000f5f41b851e20caf0a7124b3c2ebb3264d6da993a4a632da503002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444002569dba114cc73b5c8de66c19459e8ce43ed4d4a25b589d5d61338db8eab6ee71a2d210b4080c0eaab88a92a0c1aa3fe05af4dcbcc7078073e3c2d7452b710a", + "signed_txn_bcs": "2c3b9404a0bbfb161c21b5bdd8cfab322dfd3e0d7ec5957716d232de67a1f4e380651a10b552b07200108a54c2ae8a7a8ff9a741bf5fccb2d6750307e674b9995fafd64ad8486793c63dacd98e3ff5c6d2b795d371097c8a5af47e0f07475a4d7a714652114f5358426b6b4649724275636d7a56553300076eb77c9141dea54f4e58a29f4c9b69c688a34474e9a920634d85555d1752f68a064c726e5374451f584e6a4d74504c7548667765717475766a4c56454773426650714349564e4a000606010604056a4597d9d803b1968253ed1254407d38e569f3827fb6a1a8d928ddd5accef0351d562282920e026023a900761b1e38d6eed414988a768c050102885ea17337ecaabab2c16790f28b229d02c1004944de2003410b9e186691e86030611ebb139c3362a05b20d9af3eb31e91d3803fb9c8e03d481d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444043f78dcbd3051b9ccca90d631d2c8fd124172e15f544b8e8e51f17eaaed5390eafbbfd2055766575135e142248b0edfd883a90ceec0ae9fa0ae32cc728810002", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "9c18ae5d635ab973977b02adbb015c7ef091a156d437c16e0159001bf698f4a2", - "sequence_number": "4381573132213259014", + "sender": "ab257292d77ad98187cea46d5f8b5600a822ea922519674a85067bb1ad3b9f7d", + "sequence_number": "15646642158652465588", "payload": { "Script": { - "code": "fd9c223f", + "code": "fda70ecc5da7f9eeb59e9d9ec7", "ty_args": [ { "struct": { - "address": "0e9f311a1967ddaf37c8a28e7e315027948274a5fc5798ae54c6433bd7662b5a", - "module": "gnoPpzujudDLsdvzzQQRGGSma0", - "name": "kKbpKuJTTyzXI", + "address": "6b4ebbbdc32e991fb39ab48a65e8196c3cf58e14d685d0e7c4e4721c8c609af5", + "module": "bedZvt7", + "name": "HCpeNWMZmgscWevQEI2", + "type_args": [] + } + }, + { + "struct": { + "address": "7516ed2a1bb03fd908ac4f98ac27f32a1df3ae0ee731311ef97a6e3c9f4deedb", + "module": "AdlDYeDQvBHQTl9", + "name": "IHsXlwcp5", + "type_args": [] + } + }, + { + "vector": { + "vector": "u128" + } + }, + { + "struct": { + "address": "11468b661fe4c358a3135e30ed8f83f72d93aff977defdceaba8ab4ab7ee10bd", + "module": "LJCQY8", + "name": "pnbAhaBhFXdx1", "type_args": [] } } ], "args": [ { - "U128": "84021873993414384437526647783736021062" + "U8": 248 }, { - "U128": "30908192967921401892113355560787711387" + "U64": "3845388220096084976" }, { - "U8Vector": "aeeaf3" + "U128": "159549754998025519505546147122868533032" }, { - "U128": "68568069113358875780695410855098908361" + "U128": "102790906798126818129379643752370009989" }, { - "U8": 63 + "U128": "54365632605266578775850984755293158987" }, { - "U8": 208 - }, - { - "Bool": true + "Address": "da70a211267cb243822295440e5048c064713eaf5decef02e7bea94a1cb5fc18" } ] } }, - "max_gas_amount": "16976842943183761884", - "gas_unit_price": "10405226585714504255", - "expiration_timestamp_secs": "9006712950649754982", - "chain_id": 43 + "max_gas_amount": "1558339676583077653", + "gas_unit_price": "12351108678222572812", + "expiration_timestamp_secs": "8706299470873983090", + "chain_id": 161 }, - "signed_txn_bcs": "9c18ae5d635ab973977b02adbb015c7ef091a156d437c16e0159001bf698f4a2068bf7968c79ce3c0004fd9c223f01070e9f311a1967ddaf37c8a28e7e315027948274a5fc5798ae54c6433bd7662b5a1a676e6f50707a756a7564444c7364767a7a5151524747536d61300d6b4b62704b754a5454797a5849000702461009ab49620808ecd09d3a3906363f029b1521b835296a7d5d68b05591b340170403aeeaf302c9feaebef3c47f233688ce1ed1ba9533003f00d00501dcb110acb5dc99eb3fb2f65073ca669066956381b545fe7c2b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400f69b2a03cc8fe8075f0b57e620174bb460d1ca932bb211e1985443c64bedbf0839f1f08836d4a50a6a1a07f488a6e0f3eb0fa58c94c7dc3e0d219a525bf6f03", + "signed_txn_bcs": "ab257292d77ad98187cea46d5f8b5600a822ea922519674a85067bb1ad3b9f7db4a121d2240a24d9000dfda70ecc5da7f9eeb59e9d9ec704076b4ebbbdc32e991fb39ab48a65e8196c3cf58e14d685d0e7c4e4721c8c609af5076265645a76743713484370654e574d5a6d6773635765765145493200077516ed2a1bb03fd908ac4f98ac27f32a1df3ae0ee731311ef97a6e3c9f4deedb0f41646c445965445176424851546c3909494873586c77637035000606030711468b661fe4c358a3135e30ed8f83f72d93aff977defdceaba8ab4ab7ee10bd064c4a435159380d706e6241686142684658647831000600f801f07b4c6236905d3502283752596db6c6c8f03c107d422a08780285f7d9dbd60149acd2b76b90fcce544d024b7e81478a7460c32f430166a270e62803da70a211267cb243822295440e5048c064713eaf5decef02e7bea94a1cb5fc1815a721eead55a0150c6db363e7f367ab72789da53dfdd278a1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d6fea51eeb72a9cd4ed94660f6ed6542033d2d0f71da0ec00ac2cdfd545ca0806ea1a680515b99059ae737a2205647b33f562bee506c89b9ff13c818aeb6b70b", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "f72d9f3def738b0b374b7a7534021b8a7d6a02c79590b5b9922a41933d1c532b", - "sequence_number": "7747399145951486354", + "sender": "e525149bd1029f4fc46f14aa3ed67109bb66af459a377267494b83f05048cd7f", + "sequence_number": "17142836387107613736", "payload": { "Script": { - "code": "8f2eac", + "code": "c4ffbfa6c3244d9fcadcb20c0612", "ty_args": [ { "vector": { "struct": { - "address": "410ccc541f5f4d9fd25f6b291d95e8afe20dd4eded4dd512866e415733125fbf", - "module": "zs", - "name": "SrLImwwtahmuJRUuSEbPKKHlycyZpn5", + "address": "59ecdd64d239ace94e3979b7c5963c95d4af3612d839e8c4ae601d1c6e72ae0d", + "module": "KBMXWmsqhhqHJtBJE2", + "name": "nrr", "type_args": [] } } + } + ], + "args": [ + { + "Address": "1e3747702f94ebde1778d62e03786317014a753834427c29fb241a67904a2fe5" }, + { + "U128": "320905206663419734484647629456963149928" + } + ] + } + }, + "max_gas_amount": "17715802104690965765", + "gas_unit_price": "17403895568628907430", + "expiration_timestamp_secs": "12646372252762467533", + "chain_id": 79 + }, + "signed_txn_bcs": "e525149bd1029f4fc46f14aa3ed67109bb66af459a377267494b83f05048cd7f28ac3010de96e7ed000ec4ffbfa6c3244d9fcadcb20c061201060759ecdd64d239ace94e3979b7c5963c95d4af3612d839e8c4ae601d1c6e72ae0d124b424d58576d7371686871484a74424a4532036e72720002031e3747702f94ebde1778d62e03786317014a753834427c29fb241a67904a2fe50268202ef31024b55a6a7927193d186cf105fd38e1262cdbf5a6fd1e54cf0e87f1cd6c437f8ff080af4f002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440e02bff099011ee805ba1ed112949bdb15ec9c38a61d3a749b4be2db65450a7e193a3bb7ea6734519d5ebbdd5e4030992b70c80923c19c49f66b24eebacb7fe0d", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "08796761c3dfa0d73a786a96bd5639f57d041ba6adb827255508c7cf7eaa1e4f", + "sequence_number": "2295289120988170088", + "payload": { + "Script": { + "code": "371dd94ea40c8b4f1e79c8", + "ty_args": [ { "struct": { - "address": "9e12edf91b29e016be387b3edd57cea74af8737a6e2ba978e04f75484f43dea9", - "module": "kmiGvcEy", - "name": "TIpzIHqOVLUC2", + "address": "79bc62298b2ec2f2d8100fc7ae97a3b05bd13f928b11a1ab582ec703be173007", + "module": "BniIVqoMTp", + "name": "ocGbYChwQnAkSjMKSJcGAECaFkUxFiOv7", "type_args": [] } }, - { - "vector": "signer" - }, { "struct": { - "address": "0c01770935d275c2038ae020886649761c841d81c183b1901075b292c12c941e", - "module": "lmpIYFbHRaSvkxkFuh", - "name": "v2", + "address": "07e114a6506e1ec72f1a3e9829785b253a0def36be8ed2cf291ab88070ac8537", + "module": "azEMxjJSxvYIQiizNLVmxBzD3", + "name": "MexYMYlstiuVbJwEuHacQYbHnNJ", "type_args": [] } }, { - "vector": { - "vector": "u8" - } + "vector": "u8" }, { - "struct": { - "address": "19c59c35d3754a15ed133f7f0b564789b2ffd369ec71457c1705fd30bee25dab", - "module": "ISgWebuLdNZgHiBUkyGFDQ5", - "name": "QnvjRaJ6", - "type_args": [] + "vector": { + "struct": { + "address": "608d96146cbd7f5825a07586606e1ceea473e3b7b27ae95aec0b85a9ba6868e9", + "module": "OBElTBLFDTdknTpRURynXZdzQP4", + "name": "mnJIxZCIhWfLEVkTVBN", + "type_args": [] + } } }, { "vector": { "struct": { - "address": "4957806cfe9daa528f82ab81e6151f1a487309f6e4df1a3da4b7d9c91711142a", - "module": "hhLmHbpQGXYLrQhRDAKCaFt1", - "name": "CdP5", + "address": "874fb484ea2cc5b62972fd201f57a52978e2cc6165e38f8ce51feb7c9b8fe4f9", + "module": "FKwZipwRsWjY", + "name": "pTlYCkoRcFrXZGupMCkYEzQV", "type_args": [] } } }, + { + "vector": "address" + }, { "struct": { - "address": "cc990406c9acecf0c27fcd5573b92018d2fceab2ed587af7ae44be9df31a349f", - "module": "cJYAeSuwUY4", - "name": "AsYFZxnQnqlUWWswANdhRPBVNFkL5", + "address": "748207cb76a7fe304272b711c7f43bdef8f9a6cc7e11ae0c3671abaf17e3bee7", + "module": "jFzbxnSMbgiLqKaLD8", + "name": "HLVbUkHVlsVtf9", "type_args": [] } } ], "args": [ { - "U128": "10208642586978738564512370034247999400" - }, - { - "U8Vector": "ad" - }, - { - "Address": "7b3fa80afacdb4b7042b0d58ea675073945cd4d3eaac05e7f48e3922632a09a0" - }, - { - "U64": "17312150182304003873" - }, - { - "Address": "81b1c7746db97cfced0723a5fa65d18862eb74e1b7ffc7729c866811df9d38e9" + "U8": 112 } ] } }, - "max_gas_amount": "8974567084832537115", - "gas_unit_price": "12238280730371531235", - "expiration_timestamp_secs": "13505924667837049376", - "chain_id": 255 + "max_gas_amount": "7037993816267440905", + "gas_unit_price": "5634125986179912929", + "expiration_timestamp_secs": "3808962854621067214", + "chain_id": 64 }, - "signed_txn_bcs": "f72d9f3def738b0b374b7a7534021b8a7d6a02c79590b5b9922a41933d1c532b92619acb794a846b00038f2eac080607410ccc541f5f4d9fd25f6b291d95e8afe20dd4eded4dd512866e415733125fbf027a731f53724c496d77777461686d754a525575534562504b4b486c7963795a706e3500079e12edf91b29e016be387b3edd57cea74af8737a6e2ba978e04f75484f43dea9086b6d6947766345790d5449707a4948714f564c554332000605070c01770935d275c2038ae020886649761c841d81c183b1901075b292c12c941e126c6d704959466248526153766b786b467568027632000606010719c59c35d3754a15ed133f7f0b564789b2ffd369ec71457c1705fd30bee25dab17495367576562754c644e5a67486942556b79474644513508516e766a52614a360006074957806cfe9daa528f82ab81e6151f1a487309f6e4df1a3da4b7d9c91711142a1868684c6d486270514758594c7251685244414b436146743104436450350007cc990406c9acecf0c27fcd5573b92018d2fceab2ed587af7ae44be9df31a349f0b634a5941655375775559341d417359465a786e516e716c5557577377414e6468525042564e466b4c35000502a81f78107e09318881ff0f84f01cae070401ad037b3fa80afacdb4b7042b0d58ea675073945cd4d3eaac05e7f48e3922632a09a00121b771fadd1c41f00381b1c7746db97cfced0723a5fa65d18862eb74e1b7ffc7729c866811df9d38e91b3a5be036118c7ce3a14dab7b1bd7a920ea9c8dedae6ebbff002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ebe889e36791a5c05f91e9509e5ef17d314dd8163ea9a201e644696a4b57af5fc1ec571bc3232c780bec24e9f74e78388e5f87f087dd854d589f3c4616fdb80f", + "signed_txn_bcs": "08796761c3dfa0d73a786a96bd5639f57d041ba6adb827255508c7cf7eaa1e4f688751694b81da1f000b371dd94ea40c8b4f1e79c8070779bc62298b2ec2f2d8100fc7ae97a3b05bd13f928b11a1ab582ec703be1730070a426e694956716f4d5470216f63476259436877516e416b536a4d4b534a634741454361466b557846694f7637000707e114a6506e1ec72f1a3e9829785b253a0def36be8ed2cf291ab88070ac853719617a454d786a4a53787659495169697a4e4c566d78427a44331b4d6578594d596c7374697556624a774575486163515962486e4e4a0006010607608d96146cbd7f5825a07586606e1ceea473e3b7b27ae95aec0b85a9ba6868e91b4f42456c54424c464454646b6e5470525552796e585a647a515034136d6e4a49785a43496857664c45566b5456424e000607874fb484ea2cc5b62972fd201f57a52978e2cc6165e38f8ce51feb7c9b8fe4f90c464b775a6970775273576a591870546c59436b6f52634672585a4775704d436b59457a515600060407748207cb76a7fe304272b711c7f43bdef8f9a6cc7e11ae0c3671abaf17e3bee7126a467a62786e534d6267694c714b614c44380e484c5662556b48566c7356746639000100700943044616faab61e1140dcabb6f304eceb758188927dc3440002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440006c8b59051e3a56aa0fe8420cf7d151a121131580650eea0a9ff234b64a5dfb5ec2b7c83bffa74a806ac8e1a94433cb94a04c5578ecbbf08444906ff541840e", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "d1e5dc19f001ae32443bcb34a32c3d8a700c65c09342b3f48ac631fd79f3c417", - "sequence_number": "8739409712431927954", + "sender": "2134d8254bc405ccaa6ca9cfdea59a0331985b4c51fbf458850323d333fe6f90", + "sequence_number": "11273164043936601406", "payload": { "Script": { - "code": "7f506fb9b7b087c3a04c", + "code": "0fb6e140a345efabef8c", "ty_args": [ + { + "struct": { + "address": "6ef66904cd56087b5787d37c6305468fffbb14b328ff19e2817a73c960dd236f", + "module": "Rqgc", + "name": "SQ", + "type_args": [] + } + }, + { + "vector": { + "struct": { + "address": "d122646ed345efe4d9daca0d2cfececcb6539d3a176376f7aff3a8f2fa831389", + "module": "mQvdIVpcRVFaQoa", + "name": "BxWBSJh4", + "type_args": [] + } + } + }, { "vector": { "vector": { "struct": { - "address": "505492d6d3d42002b608d225b5ee33d13ca3f036c36d4d7a84963d823c56d08e", - "module": "nxHCQJnXqWvZAtVrSW", - "name": "WXibNzVpoXHFfNzTAPxA2", + "address": "173582243bcbc79c1b68823512e8dddcf82138c3b5e11252b22decf525f13c0d", + "module": "BcHQNvGWOYGROrG", + "name": "dNKEVnvfZHzZXKotoT", "type_args": [] } } @@ -6143,1088 +6606,1216 @@ }, { "struct": { - "address": "4474e5068451307c9891b87fec7ff7492130e629add5aa5b0f410ec6c483828e", - "module": "fPROplAQR3", - "name": "BdJcspIEAxrSpNxNHkXSUeqdKvO0", + "address": "7854086b46eb5c753037bfbdc3a568cd2ddc23a50a8fde6234cc98eef41c1a8f", + "module": "nMiE", + "name": "hVgr7", "type_args": [] } }, { "vector": { - "vector": "address" + "struct": { + "address": "0a5686e1de3bd319633487163a695ab27ea9b0750a3516805cee8cc02cfdfc73", + "module": "FAhOANFOTjpR", + "name": "H", + "type_args": [] + } } }, { "struct": { - "address": "5a3b671a34e61cc36683e95350d2a1ad51ec8bc5d29dda898abc1eccc651864b", - "module": "epPFGCJFNr", - "name": "JFcjqMaInQD6", + "address": "22dcb28cac70885a6dcc9bfd591eca32255931eb60bcee4b3ef13807e2060d8c", + "module": "lHAkawXUQaNWTIovCKxwNrqzrV", + "name": "LZEmkKROvwJaoqSkliLmSDNVJJPHcjP", "type_args": [] } }, { - "vector": { - "struct": { - "address": "c6207e6170b9e5b9224cfcdb4710f87e24950d711f8e218ad131cf0cefba17c1", - "module": "vaAEkpBhDTazIxHhpuVRk", - "name": "SNvrFvGeaKaiCPdjZ", - "type_args": [] - } + "struct": { + "address": "fffe5b7b904e5605b9d1f2b548b592ce54093516645402a096ae0ea0e67d62f2", + "module": "pVsvVQfbPvx1", + "name": "IJykNT", + "type_args": [] + } + }, + { + "struct": { + "address": "93714ab13acd25d571718710336ea3dadb04494a2f56118744fe72241ba1de97", + "module": "HLtKraXORTK1", + "name": "GTiSSKaApmlRPlrjTrnuOL7", + "type_args": [] } }, { "struct": { - "address": "5831fdeef9a88830947725a17ded113832ed5d6412495fc7a35f2f25843115b0", - "module": "LA3", - "name": "olEEKEEWUaNmVpJAvdWsAS", + "address": "ba567c0f7c361d0fd2ef324b6f1b584ab56a94a27702704a353b36769e412dbe", + "module": "IbhYQgjqUc7", + "name": "AHhzyvJJzWcGL", "type_args": [] } }, { "struct": { - "address": "831184a076a98e25d5fa2a1ae7c0e8ecbc490da7533bc8d2199fb0a33416ab97", - "module": "NMYXQnYaDUZgHO", - "name": "uTDnZiSlelWQz", + "address": "4943c75e5cd666a9003f3ba5e3b1cd624d3458ef907851a500db640fca47db8b", + "module": "GuxRmIlq0", + "name": "JDsfBekBKnXpu1", "type_args": [] } } ], - "args": [] + "args": [ + { + "U64": "18166531275790253375" + }, + { + "Bool": true + }, + { + "U64": "1966265504895757521" + }, + { + "U8": 47 + }, + { + "Bool": false + }, + { + "U128": "339730435431780618589547627944501577736" + }, + { + "Address": "8b86227a5f79904155609c7f6edab6e7d1368bb06fe078e9b62d99b884253a46" + }, + { + "Address": "8496f0a3239bdffe2e82c1c25e1e03e436d0ac7b54dcb4823adc5740a858266b" + } + ] } }, - "max_gas_amount": "399246007634378942", - "gas_unit_price": "4462090929251500417", - "expiration_timestamp_secs": "11258660708475125563", - "chain_id": 124 + "max_gas_amount": "16773073868372672270", + "gas_unit_price": "5453199651213076556", + "expiration_timestamp_secs": "11489967142195648349", + "chain_id": 213 }, - "signed_txn_bcs": "d1e5dc19f001ae32443bcb34a32c3d8a700c65c09342b3f48ac631fd79f3c41792921a80d49e4879000a7f506fb9b7b087c3a04c07060607505492d6d3d42002b608d225b5ee33d13ca3f036c36d4d7a84963d823c56d08e126e784843514a6e587157765a41745672535715575869624e7a56706f584846664e7a54415078413200074474e5068451307c9891b87fec7ff7492130e629add5aa5b0f410ec6c483828e0a6650524f706c415152331c42644a637370494541787253704e784e486b5853556571644b764f3000060604075a3b671a34e61cc36683e95350d2a1ad51ec8bc5d29dda898abc1eccc651864b0a6570504647434a464e720c4a46636a714d61496e514436000607c6207e6170b9e5b9224cfcdb4710f87e24950d711f8e218ad131cf0cefba17c115766141456b7042684454617a49784868707556526b11534e767246764765614b61694350646a5a00075831fdeef9a88830947725a17ded113832ed5d6412495fc7a35f2f25843115b0034c4133166f6c45454b45455755614e6d56704a417664577341530007831184a076a98e25d5fa2a1ae7c0e8ecbc490da7533bc8d2199fb0a33416ab970e4e4d5958516e596144555a67484f0d7554446e5a69536c656c57517a0000be400aef20688a05814187190f88ec3d3bbf4e6f43cc3e9c7c002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404277cb4b2ecb638c7aaa3d07fedb21cd3d1446fe2d4e50822639c1ff4dca497ee1a6beafff673bcb627a900699218e34c726cfc25c7d16a39436b10ead42d20e", + "signed_txn_bcs": "2134d8254bc405ccaa6ca9cfdea59a0331985b4c51fbf458850323d333fe6f903e158c5df852729c000a0fb6e140a345efabef8c0a076ef66904cd56087b5787d37c6305468fffbb14b328ff19e2817a73c960dd236f0452716763025351000607d122646ed345efe4d9daca0d2cfececcb6539d3a176376f7aff3a8f2fa8313890f6d5176644956706352564661516f610842785742534a683400060607173582243bcbc79c1b68823512e8dddcf82138c3b5e11252b22decf525f13c0d0f426348514e7647574f5947524f724712644e4b45566e76665a487a5a584b6f746f5400077854086b46eb5c753037bfbdc3a568cd2ddc23a50a8fde6234cc98eef41c1a8f046e4d69450568566772370006070a5686e1de3bd319633487163a695ab27ea9b0750a3516805cee8cc02cfdfc730c4641684f414e464f546a70520148000722dcb28cac70885a6dcc9bfd591eca32255931eb60bcee4b3ef13807e2060d8c1a6c48416b6177585551614e5754496f76434b78774e72717a72561f4c5a456d6b4b524f76774a616f71536b6c694c6d53444e564a4a5048636a500007fffe5b7b904e5605b9d1f2b548b592ce54093516645402a096ae0ea0e67d62f20c70567376565166625076783106494a796b4e54000793714ab13acd25d571718710336ea3dadb04494a2f56118744fe72241ba1de970c484c744b7261584f52544b311747546953534b6141706d6c52506c726a54726e754f4c370007ba567c0f7c361d0fd2ef324b6f1b584ab56a94a27702704a353b36769e412dbe0b4962685951676a715563370d4148687a79764a4a7a5763474c00074943c75e5cd666a9003f3ba5e3b1cd624d3458ef907851a500db640fca47db8b09477578526d496c71300e4a44736642656b424b6e587075310008013f7d80e6f17b1cfc050101d16c6a190f94491b002f05000208086c400a38cd95ef1ba736adb395ff038b86227a5f79904155609c7f6edab6e7d1368bb06fe078e9b62d99b884253a46038496f0a3239bdffe2e82c1c25e1e03e436d0ac7b54dcb4823adc5740a858266b0e7fbdd3d0edc5e84ce8d6c330a8ad4b5d577b473d90749fd5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d4da2863fb7d0302791812ff14f0b4bdfeef65b3fc36ee7f1b59f15d7bd8164691aa8d87f77995edb17eb7d4984a3252546527bcf5865e3e3b864f3f5ab5d90a", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "bfe4cb128df10e145d28d1b17c93023af18197f7508c755edf2089a4d31832d0", - "sequence_number": "9536922386635308482", + "sender": "0411361366dce3abb32fe8a55af3438e90514f5f0a5b56625f96ce658b1a7627", + "sequence_number": "6973500397045173521", "payload": { "Script": { - "code": "ba0b8fb6f9cf", + "code": "6f", "ty_args": [ { "struct": { - "address": "88d0f332f949254dc9194001db868ffe473ac72580408242aae127e9a9b34055", - "module": "upqHSLcVSifFqNbLF4", - "name": "ZqbTzbDFdYwuvluoOrS", + "address": "be1b1a30034a1689991761f989853f123536267bc6ab24a681191055009a412f", + "module": "QSB", + "name": "ZGbetbzJsmMvpJRAoVQW2", "type_args": [] } }, { - "vector": { - "vector": "bool" + "struct": { + "address": "182f37ced1c4ab08188b55b2f7977c43d83611a18dd07aa577fa44f7bf5784e9", + "module": "FTXKTijikfOinbDWPuynSPat5", + "name": "qJyvCxVEnTUVHPRawFhENOyhyEEtjwY", + "type_args": [] } }, { - "vector": "bool" + "vector": "u64" }, { "struct": { - "address": "0b54d3bb94e052a7185a43c0c575b7d45dffbb236b46f98996a0325984810454", - "module": "adWQXtMtacjViLhug7", - "name": "MbtgicogQgVIXBZHIQmUIRzh4", + "address": "327be36249db72966d3c7799376d55a4d1f7b182f1686e4bfcbe5880d2831f8c", + "module": "QowCjPkDpjgbmkipk3", + "name": "uR2", "type_args": [] } }, { "vector": { - "vector": "u8" + "vector": "address" } }, { - "struct": { - "address": "ca8485b992043dc3da8c82b9f961b520b14b088a48f00da722803212935bc604", - "module": "WSrGGmnMl7", - "name": "pkYlSVUkzcldiewqpgxqslSuILJsGwNy", - "type_args": [] + "vector": { + "struct": { + "address": "569775b184bf4beb0327611aa621b1712c302aa774b4779e15479c681087808c", + "module": "wubCfjkaZACnlAe", + "name": "SRtfqxNwNFKTFpLHdFYORtNkFrhoOOiS4", + "type_args": [] + } } }, { - "vector": "u64" + "vector": { + "struct": { + "address": "9da2781c7e6f0d1ecaa0344d92712ab077ce1b9b4e5f958cdb1cd65e468e218e", + "module": "sTcxImSQiLOXChkjwGvNrWZc8", + "name": "YjpAOWYUzqPRPAx", + "type_args": [] + } + } + }, + { + "vector": { + "struct": { + "address": "37e1ede5f083b5f384f567dafb8b426da2105763d1419b62b4b9284e66a3e787", + "module": "dGMGHGeUvnWQlWCVtX7", + "name": "sVbznwxXoNAINJOd0", + "type_args": [] + } + } } ], "args": [ { - "Bool": false + "U64": "4326550357321837148" }, { "Bool": false }, { - "Bool": false + "Address": "83949bca04240048b0d74b4c947470d954fbeb3b0c94dc3031bc9bdc668be78e" }, { - "Bool": false + "U64": "9196770266735518645" + }, + { + "U128": "184753456356789213655870323073355165438" + }, + { + "U8": 119 + }, + { + "Bool": true + }, + { + "U8Vector": "5a76fab9a295fdd469dfbab43e74" }, { - "U8": 155 + "U8": 0 + }, + { + "Address": "78e619c7511b7132ce6b019bddd2dfc9d9364cc4affa679cfdfc78ea88088782" } ] } }, - "max_gas_amount": "12997735213505085827", - "gas_unit_price": "3433525629701912474", - "expiration_timestamp_secs": "3280625629164775885", - "chain_id": 241 + "max_gas_amount": "2895609843429665187", + "gas_unit_price": "11826031002099742760", + "expiration_timestamp_secs": "13341225763917567843", + "chain_id": 77 }, - "signed_txn_bcs": "bfe4cb128df10e145d28d1b17c93023af18197f7508c755edf2089a4d31832d0c23ddec161f459840006ba0b8fb6f9cf070788d0f332f949254dc9194001db868ffe473ac72580408242aae127e9a9b340551275707148534c635653696646714e624c4634135a7162547a62444664597775766c756f4f7253000606000600070b54d3bb94e052a7185a43c0c575b7d45dffbb236b46f98996a0325984810454126164575158744d7461636a56694c68756737194d62746769636f675167564958425a4849516d5549527a68340006060107ca8485b992043dc3da8c82b9f961b520b14b088a48f00da722803212935bc6040a57537247476d6e4d6c3720706b596c5356556b7a636c646965777170677871736c5375494c4a7347774e79000602050500050005000500009b83818ecd4f3b61b49af7945d5e55a62fcda968d3a01f872df1002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440446e12bce40a7c14eb6658a112c9e74df6ff1b13c3d2d9e2ff1f924d52f626444506a543aa5e9c325c3f67de9cebb98e51eda015fc864a0ee7654abc27f38d02", + "signed_txn_bcs": "0411361366dce3abb32fe8a55af3438e90514f5f0a5b56625f96ce658b1a7627114decf6a9d9c66000016f0807be1b1a30034a1689991761f989853f123536267bc6ab24a681191055009a412f03515342155a47626574627a4a736d4d76704a52416f565157320007182f37ced1c4ab08188b55b2f7977c43d83611a18dd07aa577fa44f7bf5784e9194654584b54696a696b664f696e6244575075796e53506174351f714a7976437856456e54555648505261774668454e4f7968794545746a775900060207327be36249db72966d3c7799376d55a4d1f7b182f1686e4bfcbe5880d2831f8c12516f77436a506b44706a67626d6b69706b3303755232000606040607569775b184bf4beb0327611aa621b1712c302aa774b4779e15479c681087808c0f77756243666a6b615a41436e6c4165215352746671784e774e464b5446704c486446594f52744e6b4672686f4f4f6953340006079da2781c7e6f0d1ecaa0344d92712ab077ce1b9b4e5f958cdb1cd65e468e218e1973546378496d5351694c4f5843686b6a7747764e72575a63380f596a70414f5759557a71505250417800060737e1ede5f083b5f384f567dafb8b426da2105763d1419b62b4b9284e66a3e7871364474d4748476555766e57516c574356745837117356627a6e7778586f4e41494e4a4f6430000a015cea017fa0fe0a3c05000383949bca04240048b0d74b4c947470d954fbeb3b0c94dc3031bc9bdc668be78e01b523a5bdd47da17f02fe2e25b4c4df83906cf77130ad38fe8a00770501040e5a76fab9a295fdd469dfbab43e7400000378e619c7511b7132ce6b019bddd2dfc9d9364cc4affa679cfdfc78ea88088782a3e9bf9dcf452f282878e9168a801ea4639798be258e25b94d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ddc1d9a29325cf44f9320704dc2e71c96fbdd585186821f7e10f513f1ddb131957aea343926fb4e392f2001c235bb6d673b74f3592090f6edcc585956698e206", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "a83b178defbdb6dada0889078f964732cacf7ca9ec7618de05438e93bcdfac48", - "sequence_number": "13732763229123254603", + "sender": "f7b0abca0ab8240a29b81c62d6474900d61a512fd5072a6326d3a1c8d44cfabc", + "sequence_number": "2824333326381802296", "payload": { "Script": { - "code": "efddd2", + "code": "ad9b5be7c5c70ef9bbad0debf2", "ty_args": [ { - "vector": { - "vector": { - "vector": { - "vector": "address" - } - } + "struct": { + "address": "c436baf14dcecc5e1ca161c35a3a5c8a16b3607052914fa51bf713d35bbac9e4", + "module": "qGTdWwVoaGqVYXYNOYOxVSTsdJo0", + "name": "koQwMjeBQtJjAFZHJkHQsJh7", + "type_args": [] } }, { "struct": { - "address": "668932d808b604101a2ba5a4e3372c4483f2311ef9da69bdb16a55b061b84c49", - "module": "l2", - "name": "nCAdbJhJWpykdKykSZlSRBbXYszj2", + "address": "a3251b4cff7348a2a51c9ebc219890800a8938d3946d84df48f6032b88b9c611", + "module": "VqNGPDlBmrwxZbtxhPwWDSM5", + "name": "shjzgoysFMQuFcoSXEFgEW1", "type_args": [] } }, { "vector": { - "struct": { - "address": "39410dc16318fc5a75a123ed54af40f2c41cfde253f2da25b408b1ca0c9ef246", - "module": "o8", - "name": "pEGncqbqrKRQwulvCcQnk5", - "type_args": [] - } + "vector": "u8" } }, { "struct": { - "address": "22688f8ce4ffe443e1859d2c18b9a898feb35ab364dd8244539488f5bc7525af", - "module": "jWpLdrmJiHrqJXapyYWhwHhdxChSXFtL", - "name": "qcj", + "address": "710025aa324fee54bef9a2dda3af9629266447a96c5aba9e960fbe9835d9782b", + "module": "DpUtUADPLsIgqJXQieNyuMyCZkrzv3", + "name": "OEwYFfPbfDGOOeuVY", "type_args": [] } - } - ], - "args": [ + }, { - "U8": 196 + "struct": { + "address": "40d5143bfd1bd052d04f49c8f979699cdd66ccb633d75ab9268273a5e589d4b5", + "module": "dgSEMBozEBPYByYaRUCqPUQSl", + "name": "E2", + "type_args": [] + } }, { - "U64": "13778504220115306745" + "struct": { + "address": "deb10d4a9040182aa948ea0420c690896371806276c54c326b837e85eaab506e", + "module": "ZDJ", + "name": "FThIAWTCaHVeoCdfgbyexhoSgYRIuhG2", + "type_args": [] + } }, { - "Address": "5b79dd8c597e168948c87b6b9c90caba3827cef831c89c861867033cd8269aed" + "vector": { + "struct": { + "address": "59d5464e58793bbb67c19996a5934f58e45946ed5162226efe5c478a4de2d4f8", + "module": "pNQON", + "name": "hAKXFhnxtKxGCQyIkmUpBWdmivXcMMHh9", + "type_args": [] + } + } + } + ], + "args": [ + { + "U64": "16526179801449030834" }, { - "Address": "54a7a285fcf24bc6bd854f703e268769bd160e36d2e0d22c0e537e89cbb3a3b1" + "Address": "ecb01e48b014fae2035255f3999b864001a431b772e49ffdf1f669f0a7e7e572" }, { - "U64": "1106225910981390324" + "U8": 229 } ] } }, - "max_gas_amount": "11345108606844796263", - "gas_unit_price": "16552614547007878935", - "expiration_timestamp_secs": "12172438902837304755", - "chain_id": 214 + "max_gas_amount": "2550987853934352734", + "gas_unit_price": "13158722821141889234", + "expiration_timestamp_secs": "1644979020586007368", + "chain_id": 27 }, - "signed_txn_bcs": "a83b178defbdb6dada0889078f964732cacf7ca9ec7618de05438e93bcdfac484b1970c8659394be0003efddd204060606060407668932d808b604101a2ba5a4e3372c4483f2311ef9da69bdb16a55b061b84c49026c321d6e434164624a684a5770796b644b796b535a6c535242625859737a6a3200060739410dc16318fc5a75a123ed54af40f2c41cfde253f2da25b408b1ca0c9ef246026f38167045476e63716271724b525177756c764363516e6b35000722688f8ce4ffe443e1859d2c18b9a898feb35ab364dd8244539488f5bc7525af206a57704c64726d4a694872714a5861707959576877486864784368535846744c0371636a000500c401f9883128961437bf035b79dd8c597e168948c87b6b9c90caba3827cef831c89c861867033cd8269aed0354a7a285fcf24bc6bd854f703e268769bd160e36d2e0d22c0e537e89cbb3a3b101f4ef60e19a1a5a0f67fd35412bec719d17375e223bb3b6e5b35dc395b030eda8d6002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440663393fb528485f6409924f0538ffd484d013ca13851286b050a7f9e7f5938917e1eaffefd08cab408ac2c805fa5a2555013f9e3d22bfb006655a81a9649240a", + "signed_txn_bcs": "f7b0abca0ab8240a29b81c62d6474900d61a512fd5072a6326d3a1c8d44cfabc38e34846320c3227000dad9b5be7c5c70ef9bbad0debf20707c436baf14dcecc5e1ca161c35a3a5c8a16b3607052914fa51bf713d35bbac9e41c714754645777566f614771565958594e4f594f7856535473644a6f30186b6f51774d6a654251744a6a41465a484a6b4851734a68370007a3251b4cff7348a2a51c9ebc219890800a8938d3946d84df48f6032b88b9c6111856714e4750446c426d7277785a6274786850775744534d351773686a7a676f7973464d517546636f53584546674557310006060107710025aa324fee54bef9a2dda3af9629266447a96c5aba9e960fbe9835d9782b1e44705574554144504c734967714a585169654e79754d79435a6b727a7633114f457759466650626644474f4f65755659000740d5143bfd1bd052d04f49c8f979699cdd66ccb633d75ab9268273a5e589d4b519646753454d426f7a454250594279596152554371505551536c0245320007deb10d4a9040182aa948ea0420c690896371806276c54c326b837e85eaab506e035a444a204654684941575443614856656f4364666762796578686f53675952497568473200060759d5464e58793bbb67c19996a5934f58e45946ed5162226efe5c478a4de2d4f805704e514f4e2168414b5846686e78744b7847435179496b6d55704257646d697658634d4d486839000301b2e49a4ff8c858e503ecb01e48b014fae2035255f3999b864001a431b772e49ffdf1f669f0a7e7e57200e55ed917fcefed6623d200fd1bb02c9db648bbff28b423d4161b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440dcdfb5820c1b30c138bc9968da95cedde5e972dee62cd62f41544a1364589544238bb3b3400d150a5391d5d00fe4928c734b865e0cb4a27179295653da21bc03", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "56cfa34ca1b88841d37f126e6557a40e2881b56b886477aea098021707b5b789", - "sequence_number": "2661617152235426414", + "sender": "2bfcfd9c3016c935ab35627dd38b5eeea514cbb5c0a13748783edcc42f4f4543", + "sequence_number": "17728406288952106544", "payload": { "Script": { - "code": "f68912", + "code": "c291", "ty_args": [ { "vector": { "vector": { - "struct": { - "address": "56e1a6f20701ed54f1046fae8ec454c941bd584a438fa62119d1944b723b56e6", - "module": "RvFzUidMBlIjvdsVlIhN", - "name": "XbbMWCEAgDpglKDPWjEN", - "type_args": [] - } + "vector": "address" } } }, + { + "struct": { + "address": "357bfa8e31c5fe4b9ebe189fe617925d057aa9ecbabba3a74f9f3323dd2211e6", + "module": "sIDMzQlNLpIWaeVkP1", + "name": "AuIsyvsdHgwbBFxPxR5", + "type_args": [] + } + }, { "vector": { "vector": { - "vector": { - "struct": { - "address": "09b85a76927f05df7713216b6297ccf67f215f865caca6dfdbed9692f491ad78", - "module": "WlbDHBmVOZpqUseRWKEOP9", - "name": "tggAOCgXGeMhR3", - "type_args": [] - } - } + "vector": "u64" } } }, { "struct": { - "address": "17db59bfa5590f5ec7e79a64ef418573571d7cf587aba84e1b9f16509e391825", - "module": "uWBKkPkBPBLUUJOaErcrkBqzldumkAqm9", - "name": "OtsOqJIhdiAcikMBwRZlnh", + "address": "5d3af3303e4f1cb584d8866e191cb93d8712947b6248af9973731558c46e4232", + "module": "NLXzJBaymCLGDyKnbdivYMCnQtNKt7", + "name": "PwmdAaJnNKAkKnKkCgyYUYbj", "type_args": [] } }, { "struct": { - "address": "00f0656f48c37c8cccd3e3863cd8d1acb3cb49bb5fc3d1cbe20070842c52a538", - "module": "pagraxyxbvBPODGdZUiydCPiLkXeXJts", - "name": "efBwmxWfsbFtn8", + "address": "cdc9de0778287782d575545f39181b9e9d5a73bf50343a53f50e18baec8edbea", + "module": "vrxGHpGF", + "name": "F9", "type_args": [] } }, + { + "vector": { + "vector": { + "struct": { + "address": "dabeb8f45f4fde087997371f7fdf3f3359925cc9bedfd6077defcc6503199de5", + "module": "uQMgueUHHSTdNZPKeFEAwpsXxQ9", + "name": "wNNRBfFg", + "type_args": [] + } + } + } + }, { "struct": { - "address": "645904bfe308e5c742eafd74823ed8c6ec6f17ec84c35c40fa2cce49bd01887e", - "module": "tl6", - "name": "kNMWnpu", + "address": "300f1e392c363a797dc1becfc4c9c2c25025568e4478174efb226a5b43b11ff2", + "module": "uVfPoqthstxajLKPCVLWqyTlbfocpGF4", + "name": "VOfoDMs4", "type_args": [] } }, { "vector": { - "vector": "u128" + "struct": { + "address": "2cdbce8cca373ea765fa811e67acb46b499514332d51a05e2b800ffb28d12aa7", + "module": "ilUQyaRzpRSPTap7", + "name": "qfRtXDbJzDrAPObzt", + "type_args": [] + } } }, { "struct": { - "address": "e7c6d5328605060187182c7102c18467e94e2682b8ad62fe3a84b0b685099232", - "module": "oWDLjWQgDJKjCNSTrEvD", - "name": "JccfpTHzyjDaownTckKvtHm9", + "address": "5629c2f4a048917feb30482a26b16caf9e8a365f39bc77c3fdcf0d9c80673ae6", + "module": "fWShWPnshxXsYYFq", + "name": "DLVXhCgFcrgLrgRUDyWoLFVeZabHu9", "type_args": [] } } ], "args": [ { - "Address": "f55b231ad5722bb091953b75fe65f4414a87c549bd11b0e0944f6db788d8ac70" - }, - { - "U64": "18131286182979262564" - }, - { - "U64": "16511952788643100658" - }, - { - "Address": "8e24b2d7fa65b3a316c53ff4405438b77ea313f2f952e1b27211a8d4e55d5d3e" - }, - { - "U8": 57 - }, - { - "Bool": true - }, - { - "Address": "97e90fd47cc5733b0f835bc7fb1d80ee6f5fc5e01d3da28d8713d0bc470ba0df" - }, - { - "Bool": true - }, - { - "U128": "302950496867062496659949831159537244545" + "Address": "5e0faf71c1ce1633d8cc0a5625b2fcdf7214f754df6b097ae011802e301b0141" } ] } }, - "max_gas_amount": "4433652520108920145", - "gas_unit_price": "1517921566327502147", - "expiration_timestamp_secs": "17462184974355895389", + "max_gas_amount": "7247968693703850901", + "gas_unit_price": "698183644497723964", + "expiration_timestamp_secs": "2291547024516551779", "chain_id": 70 }, - "signed_txn_bcs": "56cfa34ca1b88841d37f126e6557a40e2881b56b886477aea098021707b5b7896e5214b7b2f6ef240003f689120706060756e1a6f20701ed54f1046fae8ec454c941bd584a438fa62119d1944b723b56e6145276467a5569644d426c496a766473566c49684e145862624d57434541674470676c4b4450576a454e000606060709b85a76927f05df7713216b6297ccf67f215f865caca6dfdbed9692f491ad7816576c624448426d564f5a707155736552574b454f50390e746767414f43675847654d685233000717db59bfa5590f5ec7e79a64ef418573571d7cf587aba84e1b9f16509e391825217557424b6b506b4250424c55554a4f61457263726b42717a6c64756d6b41716d39164f74734f714a496864694163696b4d4277525a6c6e68000700f0656f48c37c8cccd3e3863cd8d1acb3cb49bb5fc3d1cbe20070842c52a538207061677261787978627642504f4447645a556979644350694c6b5865584a74730e656642776d785766736246746e380007645904bfe308e5c742eafd74823ed8c6ec6f17ec84c35c40fa2cce49bd01887e03746c36076b4e4d576e70750006060307e7c6d5328605060187182c7102c18467e94e2682b8ad62fe3a84b0b685099232146f57444c6a575167444a4b6a434e535472457644184a6363667054487a796a44616f776e54636b4b7674486d39000903f55b231ad5722bb091953b75fe65f4414a87c549bd11b0e0944f6db788d8ac700164586d41b8449ffb01f2b717c3933d26e5038e24b2d7fa65b3a316c53ff4405438b77ea313f2f952e1b27211a8d4e55d5d3e003905010397e90fd47cc5733b0f835bc7fb1d80ee6f5fc5e01d3da28d8713d0bc470ba0df05010281993c2feadbe79bf6d89c21b324eae3518d9bfe797f873d43f5da4d9fbd10155d94a52eb72456f246002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440aff566ff82b5142d364486805177f71e286502882478aa702652cf6e6050252dbab491d3ec7d040a818ec9fdd01455ada5cf4fd3c014c6038e6477f152b7b30d", + "signed_txn_bcs": "2bfcfd9c3016c935ab35627dd38b5eeea514cbb5c0a13748783edcc42f4f4543309eca3697f307f60002c291090606060407357bfa8e31c5fe4b9ebe189fe617925d057aa9ecbabba3a74f9f3323dd2211e6127349444d7a516c4e4c7049576165566b503113417549737976736448677762424678507852350006060602075d3af3303e4f1cb584d8866e191cb93d8712947b6248af9973731558c46e42321e4e4c587a4a4261796d434c4744794b6e62646976594d436e51744e4b74371850776d6441614a6e4e4b416b4b6e4b6b436779595559626a0007cdc9de0778287782d575545f39181b9e9d5a73bf50343a53f50e18baec8edbea08767278474870474602463900060607dabeb8f45f4fde087997371f7fdf3f3359925cc9bedfd6077defcc6503199de51b75514d6775655548485354644e5a504b654645417770735878513908774e4e52426646670007300f1e392c363a797dc1becfc4c9c2c25025568e4478174efb226a5b43b11ff220755666506f717468737478616a4c4b5043564c577179546c62666f637047463408564f666f444d73340006072cdbce8cca373ea765fa811e67acb46b499514332d51a05e2b800ffb28d12aa710696c55517961527a705253505461703711716652745844624a7a447241504f627a7400075629c2f4a048917feb30482a26b16caf9e8a365f39bc77c3fdcf0d9c80673ae6106657536857506e7368785873595946711e444c5658684367466372674c726752554479576f4c4656655a61624875390001035e0faf71c1ce1633d8cc0a5625b2fcdf7214f754df6b097ae011802e301b014195bb5e2320f595643c4246565372b009639469aee035cd1f46002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144404233dfdb4234352bd2020519e8a2554f0faaf94b34df0795852d250ffc5f27d8ddc56d20c165d001d8c23fc1f850c9c59dc4b8d1a50a02c41b6272fba840af09", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "95a53b704ee1f8e73e4e246fab1d57bb6ab5a2a099b0972246d34a3d0a268b00", - "sequence_number": "15551757094686444239", + "sender": "ab2cc0e183ecc287a10596c3900a6057f651742884daad6b3e4bdf6c6d782a3d", + "sequence_number": "3872313872576232138", "payload": { "Script": { - "code": "6ae5c30e3ca525acabdf5983f3a17e7c", - "ty_args": [], - "args": [ + "code": "c9cbf5ee14fa", + "ty_args": [ { - "U8": 164 + "vector": "u128" }, { - "Bool": false + "struct": { + "address": "70bb4310288e401dd5d24b1630f9c1c19bccae220b9a177ef2ba0cd922f6ea5d", + "module": "C2", + "name": "lZrYaTwozjWekyb", + "type_args": [] + } }, { - "U8": 171 + "vector": "address" }, { - "U8": 152 + "struct": { + "address": "c0586a30923e198a0bb95df9da43d1b25c5a8fa578037443f9524ddd6da2d42a", + "module": "oogmjeeKjmcUDq8", + "name": "LXNngWBNnoGHBntTZse", + "type_args": [] + } }, { - "U64": "17461360269322427740" + "vector": { + "struct": { + "address": "e9477373e6cc9fc52b8f728e668849c4b3d73d1bbf3b51f05f19bf3f8d927bdd", + "module": "MrTJNooDIQdUbxnbvekJNX1", + "name": "wPJJLvwynzUzsI2", + "type_args": [] + } + } }, { - "U8Vector": "d11d4f1007cbeee4" - } - ] - } - }, - "max_gas_amount": "9394619420418217017", - "gas_unit_price": "4444541433715188081", - "expiration_timestamp_secs": "6573402207503295407", - "chain_id": 45 - }, - "signed_txn_bcs": "95a53b704ee1f8e73e4e246fab1d57bb6ab5a2a099b0972246d34a3d0a268b00cf4af24daef0d2d700106ae5c30e3ca525acabdf5983f3a17e7c000600a4050000ab0098015c1d1594a63653f20408d11d4f1007cbeee43994038a96646082716119c2e22eae3dafa300f87a6a395b2d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440199ab2addd2a03c2f8b69beed26d5a0e9f1311e8e9b245e24140d4d5461f6a8d9778c5c35a87fb232097b6b4d810828c449e8b392a80e5b959f07db679e35506", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "54307a4673ffa5c3e0d43c442c5f4726745fbf423f4fc6d0a99af4a31d001f1d", - "sequence_number": "6856937665810920871", - "payload": { - "Script": { - "code": "fb6cd1c76f4ea8", - "ty_args": [ - { - "struct": { - "address": "c4ab6e294155b17791649b3594f56c69d562fa4dba0f0d2d35ad06a3ee650730", - "module": "Nth", - "name": "gPcCvzFSShzGowhIUk5", - "type_args": [] + "vector": { + "vector": { + "vector": "signer" + } } }, { "struct": { - "address": "6478795882e33e5565d58dd8aa865e9e7eb2987a22616c23cd1901571a424f82", - "module": "xpuvrkKVYSkhNFLALaf1", - "name": "mnCQuVcHIpsGBJfV", + "address": "9b04392eafe7e207d9551ae84ddd28551ac1ff948393e09acf142a6d728c611b", + "module": "CgWtNPUgxZSKGhbWQFbU7", + "name": "ZvPucHYikMqg7", "type_args": [] } } ], "args": [ { - "U128": "98059321511487480325801574385003714109" - }, - { - "U64": "12468083047052168348" + "Address": "20cca3b087189deee3331d5adff745068ef1244bcc3dea1b95b4fadd88d40108" } ] } }, - "max_gas_amount": "12229459776087095658", - "gas_unit_price": "469563520749451787", - "expiration_timestamp_secs": "17094626840501200692", - "chain_id": 102 + "max_gas_amount": "8588131319440127613", + "gas_unit_price": "7322459796803828037", + "expiration_timestamp_secs": "11745573920069745845", + "chain_id": 90 }, - "signed_txn_bcs": "54307a4673ffa5c3e0d43c442c5f4726745fbf423f4fc6d0a99af4a31d001f1da7f5a7397abc285f0007fb6cd1c76f4ea80207c4ab6e294155b17791649b3594f56c69d562fa4dba0f0d2d35ad06a3ee650730034e74681367506343767a465353687a476f776849556b3500076478795882e33e5565d58dd8aa865e9e7eb2987a22616c23cd1901571a424f821478707576726b4b5659536b684e464c414c616631106d6e43517556634849707347424a66560002023dd6268c858c467b617f6620d289c549019c4c9df9788707ad6a799934dfc4b7a90bbac0c58839840634a7ee4b8a503ced66002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440c98e15b4b00a2f36d4224f670ce13559db6b170f2f4457210decc276588dd8fd96df556c6761005e07dbceef39252ab6252f23a07a64f4a7dced45c23f5b870f", + "signed_txn_bcs": "ab2cc0e183ecc287a10596c3900a6057f651742884daad6b3e4bdf6c6d782a3dca3ab961f338bd350006c9cbf5ee14fa0706030770bb4310288e401dd5d24b1630f9c1c19bccae220b9a177ef2ba0cd922f6ea5d0243320f6c5a72596154776f7a6a57656b796200060407c0586a30923e198a0bb95df9da43d1b25c5a8fa578037443f9524ddd6da2d42a0f6f6f676d6a65654b6a6d6355447138134c584e6e6757424e6e6f4748426e74545a7365000607e9477373e6cc9fc52b8f728e668849c4b3d73d1bbf3b51f05f19bf3f8d927bdd174d72544a4e6f6f444951645562786e6276656b4a4e58310f77504a4a4c7677796e7a557a7349320006060605079b04392eafe7e207d9551ae84ddd28551ac1ff948393e09acf142a6d728c611b15436757744e505567785a534b4768625751466255370d5a765075634859696b4d71673700010320cca3b087189deee3331d5adff745068ef1244bcc3dea1b95b4fadd88d401087db6a2e3ee2b2f774539929e639a9e65b57cd9e43fa900a35a002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144409d5538754711d04e9d9b39c6845936b51cfed09de735197868b0ca5885b77737dc239f4dd514d6ac5a17d90273b93bcc1fcb7cd362fa4969e27d3ae3b41bfc0f", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "9609bc85db874a966e97c96a33d7829f1ac9170802b93eecd7d43b561e3891be", - "sequence_number": "17687558104016224339", + "sender": "3729c5e3a74f6ec7a51d1a6774b86ead94d8726a8a08500d8ea476d56e9ca067", + "sequence_number": "12305060499781852653", "payload": { "Script": { - "code": "fb5f50d42e74", + "code": "83", "ty_args": [ - { - "vector": { - "vector": "signer" - } - }, - { - "vector": { - "vector": "u64" - } - }, - "u128", { "struct": { - "address": "4b921ff487969a24d4571b406d031ecf73f0e957b82ef97e5b902403b5e0af82", - "module": "mXJiAqzuxylBINpvkf", - "name": "McognWSTKwAshXNDRxJKDVGLeQR8", + "address": "6ccf83e014a223e796a90cea4f296cbb083f858d2ffaff5f66d6d44c2646700f", + "module": "HhwaXnGeINDGjhDAWCdHOGNLNFZb", + "name": "xTfgiugoHmrnSHNChOxjDmk", "type_args": [] } - }, + } + ], + "args": [ { - "vector": { - "struct": { - "address": "a3b76af16a405fb30fa9320e618171ccb5af821a6e097d61d07225e35b6dad3b", - "module": "SIUjfUEe5", - "name": "VlPzwlqaAsWAmFPxLOLRvhzcHRUjI7", - "type_args": [] - } - } + "Address": "0c5ef3bffebddbde6ea4ad2320eb01871952e9ab20ec28e64ef7571c3d22bbe4" }, { - "vector": { - "struct": { - "address": "507a39ff0c7865e44d50d4dc8f5eb39bee70f939fe7ad049c8f70bd096461b82", - "module": "RzDPRMo", - "name": "evkwoCqZRtgQQbwIJw", - "type_args": [] - } - } + "U8Vector": "dc25facd1897abb0d19ac6d6" }, { - "struct": { - "address": "c80ba36748f4d73b44c8b1f850d484285ab6bdcf840a96b4c97b83b834106a7e", - "module": "mhFAyVxDUDfFgXZL", - "name": "GVPwRYUGCLtpIvtrLsStaZTknkxDgz", - "type_args": [] - } + "U8Vector": "cc9f3a3d2b916eb8" }, { - "struct": { - "address": "c9fde90db3c04efc49815ce426d2e45ef2e466805d82cdf7a61aa6230a8e3f08", - "module": "AnbVOlaNYeLMSNFPdgPZvRJWMCpGLbpQ2", - "name": "lPZwFrPCiZmDT", - "type_args": [] - } + "U64": "14639135242141902991" }, { - "vector": { - "struct": { - "address": "2306889929128220567bb14c474c030215d41e4d2f2357cba4b315c522e0c260", - "module": "IhBgEyJbIisvtGTKYKl1", - "name": "OxcHQyXybjwAwMPsDSInsoghRXjCJ5", - "type_args": [] - } - } - } - ], - "args": [ - { - "Bool": true + "U64": "6842359644889251257" }, { - "U128": "280985065801775361285127062301290532394" + "U64": "7531166228595667584" }, { - "U64": "8144600650747321330" + "Address": "6e158bc58007be6517fc605439d8d6af5a859c66d291a4f0248576fae16302f2" }, { - "U64": "14648556027250784588" + "Address": "7abce25de582660f9b366d3a62782b98ba0d9948f893bb748b4f9b426e1454cf" }, { - "U8Vector": "eaedf01c0242cd0bb7" + "U128": "99101526061378840795639220189646180090" }, { - "U64": "8564468921085257152" - }, + "U128": "251440031276578871427245521626970165109" + } + ] + } + }, + "max_gas_amount": "14794125858309214756", + "gas_unit_price": "17410790857721714324", + "expiration_timestamp_secs": "18199854647864929323", + "chain_id": 214 + }, + "signed_txn_bcs": "3729c5e3a74f6ec7a51d1a6774b86ead94d8726a8a08500d8ea476d56e9ca067ed1d305d545bc4aa00018301076ccf83e014a223e796a90cea4f296cbb083f858d2ffaff5f66d6d44c2646700f1c48687761586e4765494e44476a684441574364484f474e4c4e465a6217785466676975676f486d726e53484e43684f786a446d6b000a030c5ef3bffebddbde6ea4ad2320eb01871952e9ab20ec28e64ef7571c3d22bbe4040cdc25facd1897abb0d19ac6d60408cc9f3a3d2b916eb8018f28c5f6f0a728cb01b97d173bd8f1f45e0180f2dc77c8138468036e158bc58007be6517fc605439d8d6af5a859c66d291a4f0248576fae16302f2037abce25de582660f9b366d3a62782b98ba0d9948f893bb748b4f9b426e1454cf02fa4eaa0360f34942852fc7eb78428e4a02758f6778ec6dbe1fb0f200e8aa9629bd2412f1e2154b4fcd94161fed098e9ff12b2cbb1160df92fcd6002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440151f1016b8fc14e1164b1ed22166820fde5861e9d46562f905e306c44ccf05765fb76ca22440683e59ed3f768b50b8d60452be2c1b8bff29cf3961f6c9b2950d", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "016a3d46ad439f01a5f36d8e7ce11930576f48f4115971495837293e32eb8d16", + "sequence_number": "12046995388962542349", + "payload": { + "Script": { + "code": "808df58a87bdac1eeb", + "ty_args": [ { - "U128": "327396226602606374060509883176823284409" + "vector": { + "struct": { + "address": "b68417f1d65a9c3c373e7bcddd13d07ee1affcf953390c628a19c7ef9069bf99", + "module": "MhkWrRaGVGMYQMhsxfKHnUWv", + "name": "saCDsfEsXvJYbsmWWO2", + "type_args": [] + } + } }, { - "Bool": true - }, + "struct": { + "address": "9a85171dfae9f53f5dafb758db2930e24e227bff5e337c0701b7601de820a82b", + "module": "fYeJHUrf", + "name": "XUnxiyPhcPxCDrbDGxdlzPydExojrihd", + "type_args": [] + } + } + ], + "args": [ { - "Address": "0fadfac3e30fafba196a143987d11147c236868dd968dde0c7e05e4ccbafeb02" + "U8Vector": "e292774bde40fe8638fddce2" } ] } }, - "max_gas_amount": "8839770948383055560", - "gas_unit_price": "18074078266046854559", - "expiration_timestamp_secs": "16903064721136039343", - "chain_id": 6 + "max_gas_amount": "11627145617221000123", + "gas_unit_price": "3585734865993914012", + "expiration_timestamp_secs": "5928218249849684188", + "chain_id": 187 }, - "signed_txn_bcs": "9609bc85db874a966e97c96a33d7829f1ac9170802b93eecd7d43b561e3891be5300f80562d476f50006fb5f50d42e740906060506060203074b921ff487969a24d4571b406d031ecf73f0e957b82ef97e5b902403b5e0af82126d584a6941717a7578796c42494e70766b661c4d636f676e5753544b77417368584e4452784a4b4456474c65515238000607a3b76af16a405fb30fa9320e618171ccb5af821a6e097d61d07225e35b6dad3b095349556a66554565351e566c507a776c7161417357416d4650784c4f4c5276687a634852556a4937000607507a39ff0c7865e44d50d4dc8f5eb39bee70f939fe7ad049c8f70bd096461b8207527a4450524d6f1265766b776f43715a52746751516277494a770007c80ba36748f4d73b44c8b1f850d484285ab6bdcf840a96b4c97b83b834106a7e106d684641795678445544664667585a4c1e4756507752595547434c7470497674724c735374615a546b6e6b7844677a0007c9fde90db3c04efc49815ce426d2e45ef2e466805d82cdf7a61aa6230a8e3f0821416e62564f6c614e59654c4d534e46506467505a76524a574d4370474c627051320d6c505a7746725043695a6d44540006072306889929128220567bb14c474c030215d41e4d2f2357cba4b315c522e0c260144968426745794a62496973767447544b594b6c311e4f78634851795879626a7741774d50734453496e736f676852586a434a3500090501022a0eb83dee2922e7e654a5ca55c163d301f29b35d1236f0771014cb9b06c18204acb0409eaedf01c0242cd0bb701c0e528731b1bdb7602b9e2afe6abdc238495cb55f03a384ef60501030fadfac3e30fafba196a143987d11147c236868dd968dde0c7e05e4ccbafeb02c89e30aad72cad7a9fb554226c06d4faaf35c0becebf93ea06002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405a84979273b97ead3a414fbb416e6f92dec825035ed9b763f9864fe46560c4fb5a0b462f409555bc1f3eb89a0147a91fcc7fe138c176b06f1838445edb61a701", + "signed_txn_bcs": "016a3d46ad439f01a5f36d8e7ce11930576f48f4115971495837293e32eb8d160d93e1817a862fa70009808df58a87bdac1eeb020607b68417f1d65a9c3c373e7bcddd13d07ee1affcf953390c628a19c7ef9069bf99184d686b577252614756474d59514d687378664b486e55577613736143447366457358764a5962736d57574f3200079a85171dfae9f53f5dafb758db2930e24e227bff5e337c0701b7601de820a82b086659654a485572662058556e786979506863507843447262444778646c7a50796445786f6a726968640001040ce292774bde40fe8638fddce2bb9b32ea55eb5ba19cd64cd2dc16c331dc4047d516434552bb002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144402b25bb11fded2d1cb1c65a8d270aae09bc56afe457870985a8c3edaba5fbfd6b992bb27987ea800f4b0063b93c0edea01ea32eb4faa9d013da1c7aaa8737e906", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "e7295426efa93d91b6947909b0c285640e0aaf3692d49609d286d1378d48422d", - "sequence_number": "335287349186502855", + "sender": "0e5fe28a2c7a00c81d6506a682ee2c81e0ec23786e80c3e677ba4c47d1c4e992", + "sequence_number": "2478245332043816803", "payload": { "Script": { - "code": "dbfd85ea7ffca2f94a7fb2dddb22b6", + "code": "a492e90aa3a2add467edb1def57b", "ty_args": [ { "struct": { - "address": "b392e8cce86d06a0f7036bb0879c6bb4ff3b1b4e76be1bf9864b1785eecce1e9", - "module": "xPSeyWQ7", - "name": "TZHTsMJxeSAfslDdvSBeAnRooWZJGABN", + "address": "4e634593ef15a4775e7570f0d7b6ca03be9edf70de759338e1df4086826d9f1d", + "module": "TvxRYw", + "name": "NwLfBPjLGhZo", "type_args": [] } }, { "vector": { - "vector": { - "vector": "bool" + "struct": { + "address": "983554a65374c024e5bbf41052dfe3d4df26ee37febf4953b6bd91d459c4f09a", + "module": "OTaTKrNi", + "name": "M", + "type_args": [] } } }, - { - "vector": { - "vector": "bool" - } - }, { "struct": { - "address": "f4189c4e4a7f7678ab74b3b63a4cfb6c5c13b913ee73dba2012c99ef19459f64", - "module": "GFBqjSNSQfxVUjQSqKjqE", - "name": "xPCB", + "address": "350f06db2a20d3ea38640b44d9cff7844a7a2808177a27dcbd925952edcba8f4", + "module": "YmadSaIvuK", + "name": "UebrniDMdthDWBCdVG", "type_args": [] } }, { "struct": { - "address": "8a4c5b439f547ed413258c6676b2caee11984252b623cfc8e36c43267be90f29", - "module": "GSeAqwLnuoaLdfYgxdBfUOqgKhBDa3", - "name": "TXxflpbnxRBGywbvkpxmRs6", + "address": "5915a4691187100e0b0f629600b337237f6a15db4917904a11d0cafec18598da", + "module": "fnboSHGIUCmOPJRASoOUhKpypLMjIlZj", + "name": "IHCJUcYNODRBT1", "type_args": [] } }, { "vector": { - "struct": { - "address": "6c4d670da786d58cc35ca96b5d6c32656aa1b38ff1a473ae14cefdafdee3202d", - "module": "voBHBByHgRLboxjfUPAqUnNWHXa", - "name": "PdnejAmyhQVSn", - "type_args": [] + "vector": { + "struct": { + "address": "2a512a1bd23f1e53d078341dd791dcf6ed40542ced7c78017176bfa79e6e3c4c", + "module": "exutxfOpuSgcIzEcx9", + "name": "GMPttXizQBmjhMuLmq", + "type_args": [] + } } } }, { "struct": { - "address": "19fccf25a0a35123ea099e6bbbb37da8885423c0b30cb0cbf46a0b193ad94076", - "module": "bq", - "name": "UwyaZU2", + "address": "dbe31366f1f16bd196c3d4aeb23debc5ce93100b7b07b2f2fe726c7de6d1741b", + "module": "bXhRlWZljGYEOVjKiKvUd4", + "name": "aqgnSPsMMAicd6", "type_args": [] } }, { - "struct": { - "address": "883a661c70cf5dc8f05ec874640d7deccac42ae271d6660f433ea295c2d3d0b0", - "module": "p", - "name": "iIoZQQ", - "type_args": [] + "vector": { + "struct": { + "address": "b93c3282275d0a19e02caa5137c85c81e2374543fcee8354b005cb7b529290f7", + "module": "TgjGWbSPo", + "name": "rWQVNBvIFUMmlVdtRkHC", + "type_args": [] + } } }, { - "vector": { - "vector": { - "struct": { - "address": "7ef1a39a0be7c90d3b92ecdeea0a937fa07b221c79db67630bb55261eb54bfc2", - "module": "zYLVapaZUK4", - "name": "RnKLLFNmfWnJvszOFgDl7", - "type_args": [] - } - } + "struct": { + "address": "9162e6e039204a75d7fd99dc47b288557c8e7b0bcbd41dfea24c0e9d678c76ce", + "module": "cwsEkWGyAbPGcmZELeXrtH", + "name": "YDRpMSoEqjnaV1", + "type_args": [] } }, { "vector": { "struct": { - "address": "1ac85bab5127b192e1b8d03eae28fd33343e66e398748d88aa2f4a80ff0c0c11", - "module": "bxIeMwCE8", - "name": "Rorcqlr5", + "address": "af631e085fe882985920444ec205b93e6a30e6d4b5adeb8e0b53a317d1307aa3", + "module": "uaQkyFmO0", + "name": "JNRLoFDOZvBoSkNHYdyj1", "type_args": [] } } + }, + { + "struct": { + "address": "a09dc20fcfeb340aeb349eb3ef10d31428b84b5b60aa2d5b7358782327d440f2", + "module": "rAkAbYcynJQXOqivMp1", + "name": "xRkeyEwloYVNY", + "type_args": [] + } } ], "args": [ { - "U64": "11125017316911219746" + "Bool": true + }, + { + "U64": "3044188842724663537" + }, + { + "Bool": true + }, + { + "Address": "9278e51af271afce316e06f25c2e5505e5603b7e70c2d57e557697d4945406fa" }, { - "U128": "224090288159002228037611019592564033184" + "U128": "287388840358859522288757710645111650039" }, { - "Address": "5ef3a554d37ccd4d78508d9a67b8ca9d68934572fea4ff0028069837097e4cb9" + "U64": "3215015169696812189" }, { - "U64": "9762548323170607058" + "U8": 3 }, { - "U8": 10 + "Address": "346c60d8b1242b4d1f09a86b609ea5816863dc87d7a9d89a58e3d19d83eb7bd8" + } + ] + } + }, + "max_gas_amount": "3210935520263238788", + "gas_unit_price": "16963736859640883248", + "expiration_timestamp_secs": "8859820784511795774", + "chain_id": 113 + }, + "signed_txn_bcs": "0e5fe28a2c7a00c81d6506a682ee2c81e0ec23786e80c3e677ba4c47d1c4e99263dfbdcaff7e6422000ea492e90aa3a2add467edb1def57b0a074e634593ef15a4775e7570f0d7b6ca03be9edf70de759338e1df4086826d9f1d065476785259770c4e774c6642506a4c47685a6f000607983554a65374c024e5bbf41052dfe3d4df26ee37febf4953b6bd91d459c4f09a084f5461544b724e69014d0007350f06db2a20d3ea38640b44d9cff7844a7a2808177a27dcbd925952edcba8f40a596d616453614976754b12556562726e69444d6474684457424364564700075915a4691187100e0b0f629600b337237f6a15db4917904a11d0cafec18598da20666e626f5348474955436d4f504a5241536f4f55684b7079704c4d6a496c5a6a0e4948434a5563594e4f4452425431000606072a512a1bd23f1e53d078341dd791dcf6ed40542ced7c78017176bfa79e6e3c4c126578757478664f7075536763497a4563783912474d50747458697a51426d6a684d754c6d710007dbe31366f1f16bd196c3d4aeb23debc5ce93100b7b07b2f2fe726c7de6d1741b16625868526c575a6c6a4759454f566a4b694b765564340e6171676e5350734d4d4169636436000607b93c3282275d0a19e02caa5137c85c81e2374543fcee8354b005cb7b529290f70954676a47576253506f14725751564e42764946554d6d6c566474526b484300079162e6e039204a75d7fd99dc47b288557c8e7b0bcbd41dfea24c0e9d678c76ce16637773456b57477941625047636d5a454c65587274480e594452704d536f45716a6e615631000607af631e085fe882985920444ec205b93e6a30e6d4b5adeb8e0b53a317d1307aa3097561516b79466d4f30154a4e524c6f46444f5a76426f536b4e485964796a310007a09dc20fcfeb340aeb349eb3ef10d31428b84b5b60aa2d5b7358782327d440f21372416b41625963796e4a51584f7169764d70310d78526b657945776c6f59564e590008050101f1a0cfa79f213f2a0501039278e51af271afce316e06f25c2e5505e5603b7e70c2d57e557697d4945406fa02f7762922a7ba8c5791b33118cc1335d8019d4c455143079e2c000303346c60d8b1242b4d1f09a86b609ea5816863dc87d7a9d89a58e3d19d83eb7bd88474f9e9d7888f2c306818cecb4c6beb3ec272ea0f68f47a71002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144403913563f581df8cd0223c7e8c383005eb5392e1b40ff46a5a73352dba69defdec3924d4f5eafcf0508f8810b72d9957aa99ceba3f107628868cf203e6fd29e0e", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "4196f31db04e5283fac8f4bba9e8eee73d2e69b9f9f1b0849a9e68d1754c0ba2", + "sequence_number": "1577710948971570034", + "payload": { + "Script": { + "code": "9be2786dd5272fdf2f1b32", + "ty_args": [], + "args": [] + } + }, + "max_gas_amount": "2225013669346353923", + "gas_unit_price": "17638595618307636652", + "expiration_timestamp_secs": "13918323580338658277", + "chain_id": 218 + }, + "signed_txn_bcs": "4196f31db04e5283fac8f4bba9e8eee73d2e69b9f9f1b0849a9e68d1754c0ba272e3b1bfbf27e515000b9be2786dd5272fdf2f1b3200000323c7c524d6e01eacfdfcf542e1c8f4e55b07cb8dd127c1da002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444030d24f2f2ead539b0910b27d4745c54f8de52cb3e97fa6d99169c1dc456c46c31ce5639236c622511a266bf7b0b9a89e5f6a852a4951188302568180030ad10d", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "6e346246a63c983c51aa36c6af408d82e135dff579db9531c5faf37a1a3d866c", + "sequence_number": "8171628192841034801", + "payload": { + "Script": { + "code": "c0dac3bfd9dd528eb197d0", + "ty_args": [], + "args": [ + { + "U128": "31156802096962552737543799420199911103" }, { - "U8": 243 + "U128": "299007279878533710233315308632219582057" }, { - "U128": "249722772252919954218220255248461892336" + "Bool": false }, { - "Address": "dbcc9c640567df9c88856c6ff04a5b9c848882ad3a8866b2edaa90a9fbff91de" + "U128": "116748484421061774065981085981354642036" }, { "Bool": true }, { - "Bool": true + "U8Vector": "a3e2" } ] } }, - "max_gas_amount": "3254761518834885712", - "gas_unit_price": "5052221458502361444", - "expiration_timestamp_secs": "3883634640262817181", - "chain_id": 164 + "max_gas_amount": "12341950535458896099", + "gas_unit_price": "11550643287287996765", + "expiration_timestamp_secs": "15575045573907471887", + "chain_id": 45 }, - "signed_txn_bcs": "e7295426efa93d91b6947909b0c285640e0aaf3692d49609d286d1378d48422dc7a0f151112ea704000fdbfd85ea7ffca2f94a7fb2dddb22b60a07b392e8cce86d06a0f7036bb0879c6bb4ff3b1b4e76be1bf9864b1785eecce1e908785053657957513720545a4854734d4a7865534166736c446476534265416e526f6f575a4a4741424e000606060006060007f4189c4e4a7f7678ab74b3b63a4cfb6c5c13b913ee73dba2012c99ef19459f6415474642716a534e5351667856556a5153714b6a7145047850434200078a4c5b439f547ed413258c6676b2caee11984252b623cfc8e36c43267be90f291e4753654171774c6e756f614c6466596778644266554f71674b684244613317545878666c70626e78524247797762766b70786d5273360006076c4d670da786d58cc35ca96b5d6c32656aa1b38ff1a473ae14cefdafdee3202d1b766f42484242794867524c626f786a6655504171556e4e574858610d50646e656a416d79685156536e000719fccf25a0a35123ea099e6bbbb37da8885423c0b30cb0cbf46a0b193ad9407602627107557779615a55320007883a661c70cf5dc8f05ec874640d7deccac42ae271d6660f433ea295c2d3d0b001700669496f5a5151000606077ef1a39a0be7c90d3b92ecdeea0a937fa07b221c79db67630bb55261eb54bfc20b7a594c566170615a554b3415526e4b4c4c464e6d66576e4a76737a4f4667446c370006071ac85bab5127b192e1b8d03eae28fd33343e66e398748d88aa2f4a80ff0c0c1109627849654d7743453808526f7263716c7235000a012204908e4e00649a02a04689d7010a628583f2f317393896a8035ef3a554d37ccd4d78508d9a67b8ca9d68934572fea4ff0028069837097e4cb901d25f2bc9f9897b87000a00f302f08ae4c6857d1959f58ca2c742dbdebb03dbcc9c640567df9c88856c6ff04a5b9c848882ad3a8866b2edaa90a9fbff91de0501050150a4c35e5b3c2b2d64a1a310a6181d469d6544022171e535a4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405538e9a304543ba8240bc8a8810fdbbe2295968a1392a048c7dc1778e2aea84acb16cda8927c18452523892e429c9bafd64302b2de08d289ef985efb0d019f07", + "signed_txn_bcs": "6e346246a63c983c51aa36c6af408d82e135dff579db9531c5faf37a1a3d866c316cdbd68b746771000bc0dac3bfd9dd528eb197d0000602bf3ef87740e5f36908f12eb2f19470170269fed338b87af295d119fc8f17b5f2e0050002744ae6017fe8e4eda17c43a8b1f0d45705010402a3e2e338781d9f6a47ab5d210d32df204ca00f5e46e96dad25d82d002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144400f4b7abe9685100e466565ed8b4079783fa3e279dbd71fe46b7bcc655c81083991ae7b9b2c2e28ca3a0570369764800a4bf15c992c105f21285cf333e280bd00", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "fdc8b629d10795b4982c942cb09046a34a7836ac2eed00f6b5e794ce233be1cd", - "sequence_number": "10067822224099704130", + "sender": "81c1ee891cdec0435f07c5bd5b1c50148cac3940e245a2d1c5ed131587bb44e4", + "sequence_number": "7078771148902522948", "payload": { "Script": { - "code": "77e294db47ca749d2b252fa5a2", + "code": "7afc", "ty_args": [ { - "vector": { - "vector": "signer" + "struct": { + "address": "8b054dd099e42316d4d31ad17001b16d28d582a8b7305802989b8de69c980f59", + "module": "QHiWUvRpqvrXblpRTGqtBhfljjKJdmJn", + "name": "auCfzSrgxRAvHhTRIGlTqo1", + "type_args": [] } }, { - "vector": { - "vector": { - "struct": { - "address": "6b0da0caee4f0ef1aed1fbe5966b3009c0d48597774f05d8591eb70b58092150", - "module": "QBsfyQLxFpkbpRWOlmFGpOMVWwZG", - "name": "LpuP", - "type_args": [] - } - } + "struct": { + "address": "a9d21d0e991d933a94ff9a7b18580ed1b1289e0c22fec86d369ec517f7f31a1e", + "module": "uYEsTLFDsOPc0", + "name": "xZsvQinSQkxozI4", + "type_args": [] } }, { "struct": { - "address": "9b8ec02e07b06be9fb557277b781aeff75239deb922faa2b49fe421889239fc7", - "module": "ljDkjwuUZDRdFzpDHkzfCC", - "name": "jktYqStwMNmglONFpdRbEZlqp2", + "address": "2ac9cc5b70aec0b3d4b40ea533884a8a749f791e527c18e8f2f96de1dad5c1a8", + "module": "tnNwlEqipVeMhmz7", + "name": "nSXSwTWRmnwvhliLbgtZUABzXjUzrzCA3", "type_args": [] } }, { - "vector": { - "struct": { - "address": "e6105010fe0e7b2e67b3e5d2d0197daab7a52bc3e6125ac4168e857cc35db90a", - "module": "cLukHIvDJrp2", - "name": "oWrXYFziWrAvjnfIvglO", - "type_args": [] - } + "struct": { + "address": "9b2dc2dfa48de05743a134fe98aae4be4a3f06f5f35cc142e0b72cceacadbb98", + "module": "zQmichuaGaWUcaFEsIR2", + "name": "FJRPcyclEwuoTcYomGcHr4", + "type_args": [] } }, { "struct": { - "address": "3eaa4c96ab9aad6a6dd8a454e9b88a4eb62cdf8dbb10564465925ab91c252f9b", - "module": "qnruScnogXuERnbWj", - "name": "aSwsxATxCWivmbqGSDoCbQowpWaXhr", + "address": "85470bee2cbf10af3c8b1c36c4e9cd95f8e756fac9b8b84d8f70012aed716ffd", + "module": "KXjshTgScbwt4", + "name": "qLDgcLU2", "type_args": [] } }, { "vector": { "struct": { - "address": "1418d2ba78e3e41c4ecedca0959d1759a1bd5e240984df5c02bffe22d664d48b", - "module": "NVP", - "name": "yfLHCRXnVTYIvSUBk8", + "address": "e7acdbd83dad196ec9b678613830bae2f53421a9500a6c24dfcd1dff74cf9569", + "module": "fzZsTtWcRUcYxRlNFwBHE", + "name": "Qxp", "type_args": [] } } }, + { + "vector": { + "vector": "u8" + } + }, { "struct": { - "address": "aa6dd613a33115476a76190705e2742a570fb6ec3c4ba5091283338e9884a3ab", - "module": "MiFiBEiwDfwKse7", - "name": "XBPbLiFlUJKjBxJMITEDScNv", + "address": "1c3ebbb79823f6462519d34dc6fa162daf29b6c8a35c86a58027b7afaa127032", + "module": "tEvJM", + "name": "iSbAIzbvPaUiriQQWUeqvQSZgmGAGIO", "type_args": [] } } ], "args": [ { - "U8Vector": "26b2e0a8" + "U8": 119 }, { - "Address": "e10319cba37b3ccf0c309d137c95030e703f914353ca830c21d19d39dda78763" + "Bool": false }, { - "Address": "895f6dd4379494615192bf4dcbd0e22e29392c4a038a5c6edfbc230db354c07f" + "U64": "4793160774261931186" }, { - "U8Vector": "a284805c4bf6d3f9" + "U64": "16301314610666142679" }, { - "U128": "79081000444503330652015900608976219124" + "U8": 102 }, { - "U128": "324253899910341760689708112208275606064" + "Address": "ca7fa4b82b9a12f98ddfe6828921f5be6b9258e0db8ade555d2022dd6bf3cde9" }, { - "Bool": false + "Address": "0ab5d98305da5c3a0647008b62f210df7fd336fb0cdb848b9e5059a694ff49d9" }, { - "U8Vector": "fb42ca494a036bd55ef3145fdda1fdf6" + "Address": "fc9eb5df7fd6c91fae44b8324070ebf9d27eaac668b587641b5f9a56609891f8" }, { - "U64": "3507681983389876459" + "U64": "8357029262025990126" } ] } }, - "max_gas_amount": "15520459568698736870", - "gas_unit_price": "6526723669730002879", - "expiration_timestamp_secs": "10335115094460958137", - "chain_id": 180 + "max_gas_amount": "7174009825256145777", + "gas_unit_price": "2106946568972138902", + "expiration_timestamp_secs": "3010894555185195363", + "chain_id": 171 }, - "signed_txn_bcs": "fdc8b629d10795b4982c942cb09046a34a7836ac2eed00f6b5e794ce233be1cd42fd3ea1f816b88b000d77e294db47ca749d2b252fa5a2070606050606076b0da0caee4f0ef1aed1fbe5966b3009c0d48597774f05d8591eb70b580921501c5142736679514c7846706b627052574f6c6d4647704f4d5657775a47044c70755000079b8ec02e07b06be9fb557277b781aeff75239deb922faa2b49fe421889239fc7166c6a446b6a7775555a445264467a7044486b7a6643431a6a6b7459715374774d4e6d676c4f4e4670645262455a6c717032000607e6105010fe0e7b2e67b3e5d2d0197daab7a52bc3e6125ac4168e857cc35db90a0c634c756b484976444a727032146f57725859467a69577241766a6e664976676c4f00073eaa4c96ab9aad6a6dd8a454e9b88a4eb62cdf8dbb10564465925ab91c252f9b11716e727553636e6f67587545526e62576a1e6153777378415478435769766d62714753446f4362516f777057615868720006071418d2ba78e3e41c4ecedca0959d1759a1bd5e240984df5c02bffe22d664d48b034e56501279664c484352586e56545949765355426b380007aa6dd613a33115476a76190705e2742a570fb6ec3c4ba5091283338e9884a3ab0f4d694669424569774466774b73653718584250624c69466c554a4b6a42784a4d4954454453634e760009040426b2e0a803e10319cba37b3ccf0c309d137c95030e703f914353ca830c21d19d39dda7876303895f6dd4379494615192bf4dcbd0e22e29392c4a038a5c6edfbc230db354c07f0408a284805c4bf6d3f902f46bad09c8c4fac8d584fe8a59727e3b02308a868f08ed65a3819f50139007f1f305000410fb42ca494a036bd55ef3145fdda1fdf601ebc0fdec2dcaad30e6c0192fbfbf63d7bf0764f99894935ab9851fae6bb46d8fb4002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fbfcb1b3085b87d880e8c933c63cbfcff407baf068243611931a022f0ec76d10fdba9769bfd2d5439a4d19a8636e039a30dbc006b283058be1ae40ecfe3a9f07", + "signed_txn_bcs": "81c1ee891cdec0435f07c5bd5b1c50148cac3940e245a2d1c5ed131587bb44e444609ee0dad83c6200027afc08078b054dd099e42316d4d31ad17001b16d28d582a8b7305802989b8de69c980f5920514869575576527071767258626c7052544771744268666c6a6a4b4a646d4a6e17617543667a537267785241764868545249476c54716f310007a9d21d0e991d933a94ff9a7b18580ed1b1289e0c22fec86d369ec517f7f31a1e0d75594573544c4644734f5063300f785a737651696e53516b786f7a493400072ac9cc5b70aec0b3d4b40ea533884a8a749f791e527c18e8f2f96de1dad5c1a810746e4e776c4571697056654d686d7a37216e535853775457526d6e7776686c694c6267745a5541427a586a557a727a43413300079b2dc2dfa48de05743a134fe98aae4be4a3f06f5f35cc142e0b72cceacadbb98147a516d696368756147615755636146457349523216464a52506379636c4577756f5463596f6d4763487234000785470bee2cbf10af3c8b1c36c4e9cd95f8e756fac9b8b84d8f70012aed716ffd0d4b586a7368546753636277743408714c4467634c5532000607e7acdbd83dad196ec9b678613830bae2f53421a9500a6c24dfcd1dff74cf956915667a5a73547457635255635978526c4e46774248450351787000060601071c3ebbb79823f6462519d34dc6fa162daf29b6c8a35c86a58027b7afaa127032057445764a4d1f69536241497a62765061556972695151575565717651535a676d474147494f00090077050001b2fc373554ba844201d7fba33445e739e2006603ca7fa4b82b9a12f98ddfe6828921f5be6b9258e0db8ade555d2022dd6bf3cde9030ab5d98305da5c3a0647008b62f210df7fd336fb0cdb848b9e5059a694ff49d903fc9eb5df7fd6c91fae44b8324070ebf9d27eaac668b587641b5f9a56609891f801ee9f9a1cd621fa7371038e31ed338f6396f94fccbd603d1d63a9f841a5d8c829ab002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440fd6ec1e77ba9388e110b1f8a1214e7cf4f3254c4c7d510a125fd8ef05eec3d5ac08570e0d0934b217af65c18ce1e70f1a184f4b91695b5df18f9c8487b5d9508", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "473e9c1307184af1e7405946563fa381ce43377f97abae3d76a167b8cb6b24ae", - "sequence_number": "9782011366124380318", + "sender": "a1255740fc5f70ba70152de7fda251b396088682bee801513a79223a37a51d7d", + "sequence_number": "12660138461313456493", "payload": { "Script": { - "code": "f5d7cbb18b06f039ce85d0be43d81b", + "code": "35039c", "ty_args": [ { "struct": { - "address": "4af91f3a95cc6d2a843d79f2c5386f35d22d11396166993ea6f7d0fe0733b365", - "module": "gbtrtCLXRsxvNwboLlxriivIgqdOZKrR4", - "name": "mWfdrTKGGjjJoRhBIe0", + "address": "c39014f0f7d1698584901fbd0c668f55daf916c48217cf43a2cc475d4eda57cf", + "module": "Y2", + "name": "jmCzwBXCvroVtXLTPOscSjWMsmyXB", "type_args": [] } }, { - "vector": { - "vector": { - "vector": "address" - } + "struct": { + "address": "27fd810e6a53337d18fb3772e1a14a238817174c4a0b1d8d0e64da410234b363", + "module": "YUfnjrYWhL", + "name": "uzyqZVGknbygGvaqkY1", + "type_args": [] } }, { "struct": { - "address": "95bd2723119be8e25a1e1d8b07771d666bacb6987cd4fbb442eb3002afaa4fa1", - "module": "qcaQLvzVkoklmlgCWHlEPXuHDijHnL", - "name": "DRVMoHnPeOOmyHfCIQVGNJO8", + "address": "5c77e525fab7e96403356b7d876bb6a78c77ec7460d992466e5d32c9788b91dc", + "module": "lzBNKGKnXwLilDUrhcQFyLtQc", + "name": "FLqQTPgunrTPWtDgdnsa9", "type_args": [] } }, { - "vector": { - "vector": { - "struct": { - "address": "e2fcf69af1f844228f17f74d34a31bb8941cb752c04ac1beb24720e9caf83f36", - "module": "YeePRvOVJEMxeLYTdrT0", - "name": "fJuYUXbxrNJYZiAZpGrw4", - "type_args": [] - } - } + "struct": { + "address": "7832ecca47a228a2c156343eb95e1c1ec2906c3706762fcdbf95997102dfbbdf", + "module": "OaZlRdaRRJbKVDjkgB2", + "name": "OBmavFC", + "type_args": [] } }, { - "vector": "bool" + "struct": { + "address": "3b3c842346407e1b722150a948e92315a71702c0b9ef1393b9683ebc9d970026", + "module": "H2", + "name": "bTXlGLswKXYpJQkGIbDPuYPxMZZN", + "type_args": [] + } }, { "struct": { - "address": "982e8ccbb5cf02bb8f9160d5c7e1e749e0abcd0e989689d20d216437fcda9f35", - "module": "lThQePlP", - "name": "mQFICDpAAFAAhNjSQnqxmksmEMTaSk", + "address": "10a95c649a12057087b1c10b6444c47fc5b7dd398ff14f233afc92b3e01f15bb", + "module": "fLpDikfIeUdijqk5", + "name": "ZuhDHLQCOCuJLwhthnN0", "type_args": [] } }, { "vector": { - "vector": "u64" + "vector": "u128" } } ], "args": [ { - "Address": "f902a5d08c4d2047391f8e3ad608263a6e93f7c5b5e9f4b3be8a0eaa7aeb8ab6" + "U8Vector": "ad0cf03fce1afd8c5ca2ce" }, { - "U8": 148 + "U64": "17836449646785977896" + }, + { + "Bool": false }, { - "U64": "14276210385800183890" + "Bool": true + }, + { + "Address": "9176b2fedec19bf39bdd629f40267bcb570684ce2643bed66bbfbd8c45371249" }, { - "U128": "291785481323107682230268245528037982596" + "U64": "16974329509336560348" }, { - "U128": "280103279105506602879011102937134709228" + "Address": "41b28c753ba7eaedd50974b567f5d25f0f03bbba5174dc3e23cbd0c7c06e973b" }, { - "U128": "205315309024393168796546883567362855978" + "U8Vector": "ee181a6dfac80a19ea2f1bf2c7157f" }, { - "U8Vector": "e4" + "Address": "65c419d72ca71253efdfa8b72e38f8ebbca06765f26ad51438fe4cbed630a770" }, { - "U64": "13253358204309939585" + "Bool": true } ] } }, - "max_gas_amount": "12332363216131018363", - "gas_unit_price": "17597597511299893800", - "expiration_timestamp_secs": "15434991086228552512", - "chain_id": 201 + "max_gas_amount": "369064747035258644", + "gas_unit_price": "18066323232969855987", + "expiration_timestamp_secs": "2829102044765843053", + "chain_id": 8 }, - "signed_txn_bcs": "473e9c1307184af1e7405946563fa381ce43377f97abae3d76a167b8cb6b24ae9e60ad9a82afc087000ff5d7cbb18b06f039ce85d0be43d81b07074af91f3a95cc6d2a843d79f2c5386f35d22d11396166993ea6f7d0fe0733b365216762747274434c58527378764e77626f4c6c7872696976496771644f5a4b725234136d57666472544b47476a6a4a6f52684249653000060606040795bd2723119be8e25a1e1d8b07771d666bacb6987cd4fbb442eb3002afaa4fa11e716361514c767a566b6f6b6c6d6c674357486c455058754844696a486e4c184452564d6f486e50654f4f6d79486643495156474e4a4f3800060607e2fcf69af1f844228f17f74d34a31bb8941cb752c04ac1beb24720e9caf83f36145965655052764f564a454d78654c59546472543015664a755955586278724e4a595a69415a704772773400060007982e8ccbb5cf02bb8f9160d5c7e1e749e0abcd0e989689d20d216437fcda9f35086c54685165506c501e6d5146494344704141464141684e6a53516e71786d6b736d454d5461536b000606020803f902a5d08c4d2047391f8e3ad608263a6e93f7c5b5e9f4b3be8a0eaa7aeb8ab600940152c05c10b5491fc602848162b09588f843873a90d4eed683db02ecb97c66b6f3336027a1fcf7e4edb9d2022a5419bb8a3b4a9b56b6ff85484a769a0401e4018125e7481163edb77b4e9562015b25ab280a5451b33937f4403bf9659d1a34d6c9002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444022f47b6fa58d8bba9b730aaddfa7d822ad449e91a676354775384b3f8bc34b32a7d268d6ffe25fff719c3e61f0b229347a5d3d94bc0f6050bac75744028e4d01", + "signed_txn_bcs": "a1255740fc5f70ba70152de7fda251b396088682bee801513a79223a37a51d7d6d59d9b1dad8b1af000335039c0707c39014f0f7d1698584901fbd0c668f55daf916c48217cf43a2cc475d4eda57cf0259321d6a6d437a7742584376726f5674584c54504f7363536a574d736d795842000727fd810e6a53337d18fb3772e1a14a238817174c4a0b1d8d0e64da410234b3630a5955666e6a725957684c13757a79715a56476b6e627967477661716b593100075c77e525fab7e96403356b7d876bb6a78c77ec7460d992466e5d32c9788b91dc196c7a424e4b474b6e58774c696c44557268635146794c74516315464c7151545067756e72545057744467646e73613900077832ecca47a228a2c156343eb95e1c1ec2906c3706762fcdbf95997102dfbbdf134f615a6c52646152524a624b56446a6b674232074f426d6176464300073b3c842346407e1b722150a948e92315a71702c0b9ef1393b9683ebc9d9700260248321c6254586c474c73774b5859704a516b4749624450755950784d5a5a4e000710a95c649a12057087b1c10b6444c47fc5b7dd398ff14f233afc92b3e01f15bb10664c7044696b6649655564696a716b35145a756844484c51434f43754a4c776874686e4e30000606030a040bad0cf03fce1afd8c5ca2ce0128ded1c273cc87f705000501039176b2fedec19bf39bdd629f40267bcb570684ce2643bed66bbfbd8c4537124901dcb26f40c1ee90eb0341b28c753ba7eaedd50974b567f5d25f0f03bbba5174dc3e23cbd0c7c06e973b040fee181a6dfac80a19ea2f1bf2c7157f0365c419d72ca71253efdfa8b72e38f8ebbca06765f26ad51438fe4cbed630a770050114ef279a6e2e1f05f3138eca4279b8fa6d6e990b52fd422708002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444048b298ec1336eb62f7774f0932a6f7f3bd9d0288474c51129ec2189909fd5f1c4ce8116c2c2865668f7b9ae230d5ca44fac7abc635c18b755a28acb0b3ada509", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "c3c4d4428c5a4cc64439c28db0bb94cce540cc24bb0e9052eb9b873fd0066e55", - "sequence_number": "8073277356858258859", + "sender": "1545c8b01ee468f662a577e203e28e51349889f3fc1024591024413d35000205", + "sequence_number": "16804998618124462611", "payload": { "Script": { - "code": "65f4ce9d4dbb3dcdb7cc28", - "ty_args": [], - "args": [ + "code": "e55dbf4ec764df175a85ad365d09", + "ty_args": [ { - "U64": "11085638268145166188" + "struct": { + "address": "26866f33fbf98f48dc73d2666c6552cd9ed54496637abc64c873fac9c2bd3d62", + "module": "XuccNuVKyOKwPDPgSH", + "name": "alIPMhafxJ7", + "type_args": [] + } }, { - "U64": "5323767124305874940" + "struct": { + "address": "41df9a9447769d483e58c4e48760c3db9e860db63c55255420da2f7627914d1a", + "module": "QlpfHysJdSvQAlVMXrbQ", + "name": "jxnjhGKOZuhZpMk", + "type_args": [] + } }, { - "U64": "11769484486888837404" + "vector": { + "struct": { + "address": "a77e681efb21d41e65d3e133eaa2ce81340af29b8ad2fcdd27c7d6022f078439", + "module": "XltNQatsemdKmDMKnkDYJHzXZPy", + "name": "uSjWbRBmQMflPBCUQNEXKHaGpZZQeOYG3", + "type_args": [] + } + } }, { - "U8Vector": "782c" + "vector": { + "struct": { + "address": "394821fa139da46a04130bf29863d3e2dbb2cdea4b5d5b92430e529597381e49", + "module": "SoAdW", + "name": "BmeQBCZgiyNHkyAOvnEbRcZusF", + "type_args": [] + } + } }, { - "Bool": false + "vector": { + "struct": { + "address": "825d7b3801d9fd0288557f252752ca3e826d9e79229174269de7e65b874da4f0", + "module": "YBGKoKLFOkhcAYfZ", + "name": "PhXwYLVw8", + "type_args": [] + } + } }, { - "U128": "314204467941148495762212499050548115845" + "struct": { + "address": "242e77a5440292d8f6954b75af180b1d951bb3030e84ec124f7556b9adb8284e", + "module": "KZIPIhLtoKlDJgq", + "name": "VdfMLVhHczCDlOAAIZvzNcLyS", + "type_args": [] + } + } + ], + "args": [ + { + "U64": "11558429351014721328" }, { - "U128": "4584345534997736242174311336492322340" + "Bool": false }, { - "Address": "485cc9f6a698f8ce1e4f0f12a77f1cb8dbe3c87c071ca300cc6f55d135446edf" + "U128": "174821211453018074747865826924333359885" }, { - "U128": "303931106742206111661078089684253045527" + "Address": "8474cc4af4f4c2664642f93e4f3e21048b61a7e719fc3170cc5e5b5f56584cd6" } ] } }, - "max_gas_amount": "2289790510539497089", - "gas_unit_price": "9882869995972678909", - "expiration_timestamp_secs": "15307158103760537138", - "chain_id": 85 + "max_gas_amount": "7370179406592730488", + "gas_unit_price": "5225626897218240416", + "expiration_timestamp_secs": "10680669731652310010", + "chain_id": 197 }, - "signed_txn_bcs": "c3c4d4428c5a4cc64439c28db0bb94cce540cc24bb0e9052eb9b873fd0066e55abb5bd64fb0a0a70000b65f4ce9d4dbb3dcdb7cc280009016ce744494519d89901fc8f2737fed1e149011cd17a8ec89b55a30402782c05000285390f0a4948e383ea5b9912509461ec0224ce7a2931fad5a7322a527fafe9720303485cc9f6a698f8ce1e4f0f12a77f1cb8dbe3c87c071ca300cc6f55d135446edf0217731aaddef89589e2b0e9d47f00a7e4815ec46656f8c61ffd54514fe6012789328663cf31f36dd455002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144408bf598a20fb0532e8b14f9b0458392cae048ad0f3f67fe6b9db570fda965dbdddbf96e612fa4ebd91a248b809c8604af587c0215756f403d3d13fdb2614a820e", + "signed_txn_bcs": "1545c8b01ee468f662a577e203e28e51349889f3fc1024591024413d35000205132a3ddc345937e9000ee55dbf4ec764df175a85ad365d09060726866f33fbf98f48dc73d2666c6552cd9ed54496637abc64c873fac9c2bd3d6212587563634e75564b794f4b775044506753480b616c49504d686166784a37000741df9a9447769d483e58c4e48760c3db9e860db63c55255420da2f7627914d1a14516c70664879734a64537651416c564d587262510f6a786e6a68474b4f5a75685a704d6b000607a77e681efb21d41e65d3e133eaa2ce81340af29b8ad2fcdd27c7d6022f0784391b586c744e51617473656d644b6d444d4b6e6b44594a487a585a50792175536a576252426d514d666c50424355514e45584b486147705a5a51654f594733000607394821fa139da46a04130bf29863d3e2dbb2cdea4b5d5b92430e529597381e4905536f4164571a426d655142435a6769794e486b79414f766e456252635a757346000607825d7b3801d9fd0288557f252752ca3e826d9e79229174269de7e65b874da4f0105942474b6f4b4c464f6b68634159665a0950685877594c5677380007242e77a5440292d8f6954b75af180b1d951bb3030e84ec124f7556b9adb8284e0f4b5a495049684c746f4b6c444a6771195664664d4c566848637a43446c4f4141495a767a4e634c79530004013067ae6c41ca67a00500020de3e77aece261cb4fde09e631578583038474cc4af4f4c2664642f93e4f3e21048b61a7e719fc3170cc5e5b5f56584cd678e5db141f234866a07f6bf9f9278548fa136746885c3994c5002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440b0c5e64fe4e1880fa3f6067726296c8990cb28acca52738d73cfb376c0fa1c74b1f70cfc400b025704d720ec7aeb879989fc6f8a1e3e9396258f9b488a672308", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "66318dca6e1664da5cd9aba49cb53eb045f8867220093ef4de07d43aab02eb60", - "sequence_number": "6861844787957671690", + "sender": "650e1ca68403d34b17a77508c23ea4df5abc5d0e62ee949e3ac5aeb7beac6559", + "sequence_number": "12460075618115661006", "payload": { "Script": { - "code": "fcaacc3a69cf804cacff1babab3fee22", + "code": "0ddcfdba304f25afda", "ty_args": [ { - "vector": { - "vector": { - "struct": { - "address": "442233ffc3bb0531077766bc83c0094e0b87e58660c3165c4dd340b326709c0a", - "module": "gSKXEErUH", - "name": "fZxahSEatYnoShUwxhG8", - "type_args": [] - } - } + "struct": { + "address": "11800983819d279a1e19b51529663c4bce11b26594294f11fa598a574b7bda1c", + "module": "LoDncMdIjVazkcmjEyFERultARs", + "name": "kxrdmiZxIxsMXhruaEZvAlGgN3", + "type_args": [] + } + }, + { + "struct": { + "address": "2e3d1ec8fc2b4ff4e988cb1f5d16974f7989dd4e45882d5c2146aed762fe6d9e", + "module": "BmfcHSVLyGEoad", + "name": "UOpDmRZJPRJjVbmhKJVlSaaDZkibg5", + "type_args": [] } } ], + "args": [] + } + }, + "max_gas_amount": "639181661965572466", + "gas_unit_price": "2075643314198606976", + "expiration_timestamp_secs": "2141029323575591627", + "chain_id": 27 + }, + "signed_txn_bcs": "650e1ca68403d34b17a77508c23ea4df5abc5d0e62ee949e3ac5aeb7beac6559ce2c4a24c214ebac00090ddcfdba304f25afda020711800983819d279a1e19b51529663c4bce11b26594294f11fa598a574b7bda1c1b4c6f446e634d64496a56617a6b636d6a4579464552756c744152731a6b7872646d695a784978734d5868727561455a76416c47674e3300072e3d1ec8fc2b4ff4e988cb1f5d16974f7989dd4e45882d5c2146aed762fe6d9e0e426d66634853564c7947456f61641e554f70446d525a4a50524a6a56626d684b4a566c536161445a6b69626735000072d966c455d4de0880f438d7982ace1ccb026b7dd376b61d1b002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444024e67a2317010b0e7648039b4520f5d3566a285ebef2a4f829daca03ba29feb3e85bbbce4c3d86ead7ba8b62b444162c06dee9b3910faa9a33100b4ea55e330b", + "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" + }, + { + "raw_txn": { + "sender": "43feea62f0fe51f723e4b478193455657f96f4348f1db5b0a4ce5992885227e9", + "sequence_number": "13278693470332108686", + "payload": { + "Script": { + "code": "71ec487db3cccc0fef68ab77f3", + "ty_args": [], "args": [ { - "Bool": false - }, - { - "Bool": false - }, - { - "U64": "14717097353069105624" - }, - { - "Address": "a04cc448418c0733dbc09b52a0a277924f0d473e4e339baf026defdc1241c473" - }, - { - "Bool": false - }, - { - "U128": "272904463939657246664530984336417128996" - }, - { - "Address": "5fda40bf58888cffca9eb89259ffa094ed7d99a1ad0e6978a13d6936cf564230" + "U64": "17212120449677473728" } ] } }, - "max_gas_amount": "6506413227801536550", - "gas_unit_price": "13998435644183772162", - "expiration_timestamp_secs": "2507554841301947435", - "chain_id": 171 + "max_gas_amount": "16107300990561446519", + "gas_unit_price": "6013620086228886065", + "expiration_timestamp_secs": "4502156261695870772", + "chain_id": 19 }, - "signed_txn_bcs": "66318dca6e1664da5cd9aba49cb53eb045f8867220093ef4de07d43aab02eb600a2715a27a2b3a5f0010fcaacc3a69cf804cacff1babab3fee2201060607442233ffc3bb0531077766bc83c0094e0b87e58660c3165c4dd340b326709c0a0967534b58454572554814665a78616853456174596e6f536855777868473800070500050001d891866e11a23dcc03a04cc448418c0733dbc09b52a0a277924f0d473e4e339baf026defdc1241c473050002248290d3c961249e61558d65e77c4fcd035fda40bf58888cffca9eb89259ffa094ed7d99a1ad0e6978a13d6936cf564230266803b55b6c4b5a027cbd2e0d6f44c22b149db2d79fcc22ab002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440ab3238c78d8f89eb324e55bf2080681e6c2182a2eb8a9beff7774d2b2715b77ed389467fe86543628312ba3ee10b7c66a86694cb231e3f42074facfb0508ae06", + "signed_txn_bcs": "43feea62f0fe51f723e4b478193455657f96f4348f1db5b0a4ce5992885227e98ebf71945b6547b8000d71ec487db3cccc0fef68ab77f3000101c03743f25abcddee776ab628e9a088df31a2d35d9bab745334d7ae3d44df7a3e13002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440dee4910512894656b90e6105c05e41bc3ce61d31e11c30f6b16cd8844fd17ed54fe64152fc3e89a3d0f4daac782f5923e08f52d1ce40eb1fb2aafd117084160d", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" }, { "raw_txn": { - "sender": "53c6a20e460e61c02ef6929f19345d7bcb7392f4ec816be5f49a83850f81db1a", - "sequence_number": "15578517666318777960", + "sender": "8f836387d1bcb38c1f228b9ed7d21c4477c624de28111c88e07ae56f1a6589f6", + "sequence_number": "9950409979139359963", "payload": { "Script": { - "code": "7eff72796f", + "code": "67841f8946c50a2fcab7eab03f83", "ty_args": [ { "struct": { - "address": "f708ee98fb4d613c35009d11ebd50b90d6eb65e66ff7659f7b10aa6bd15a18aa", - "module": "uVbeqBfOwhPIUBl1", - "name": "sshZLWTYosfzXMOFqClf", + "address": "e7c50b00e9ffc34885e2482cd79605b372e42ad5e69a1990cd7648ca1325a2ee", + "module": "kEkYdShbkvOQsDjwdAuHghNCO", + "name": "xnTRunsvGTWphTeQZkoBBAsct9", "type_args": [] } }, { "struct": { - "address": "0ec36b27bab4551aa36bfcb677cccb4231d5545d9f394cdb679a863179575b72", - "module": "HlQjcDqETcRAvDQo7", - "name": "WyqgiKBFzKaGHFv", + "address": "cae841b78fcba8e607bfe6302641170123917995db53f518ac40456d369901f1", + "module": "brRRYgoOdvWLrPrmBALThNgqusaIEGuM5", + "name": "vPRLYedoBQbXVAUXlhsgiBNhoSwFPuF9", "type_args": [] } }, { "vector": { - "vector": { - "struct": { - "address": "b67282202df0777ff7616205f0d52d746d9494b6375e2fff527dd64bfb662bbe", - "module": "JWBkcVIFixBeXfAOuEyrO8", - "name": "UCVEKjZrYTXSvlWZhTHlvCAyzQzZb0", - "type_args": [] - } - } + "vector": "address" } }, { "struct": { - "address": "7eb23c3cc8a165ec44b8df598722585a9f52e54b223cf2a9bdc86cf954cd0d66", - "module": "AbrzHCWGTaCLkxjvB", - "name": "iczxuJQFqiLIZVfkBI7", + "address": "eb82b083ba94e320953dd73399a18b9b9d57349f0602090b4bf9179ec38be984", + "module": "XliXLWiYaBF6", + "name": "eNHth0", "type_args": [] } }, { "struct": { - "address": "dac8d8adfe18cf3ecc7e46a159c8152e69472d15933903202392bf83672a7898", - "module": "RWAGafqKOBdbHBdTPKx7", - "name": "iwnfrrQexFwl7", + "address": "f70cf6f34bfac4803a0a17b29bc8ba06b1b04b8bc12511b67ea6dd1a0f2b923e", + "module": "B", + "name": "dXS", "type_args": [] } }, { "struct": { - "address": "4cdd8edfa149dd2fc0c872020704fe3292c0f8df207f6c4c09bbd9f60481691e", - "module": "ktkWSXjgMXBVokjPmLATTtRyXPIH", - "name": "QwqdwYYvXpjSUkiGwi", + "address": "9c4fcb2c59dd6675d8161e0555ebc6d464c7bde04e7bf7b7bb169a0932a98fff", + "module": "CbumHBwfwigajZfWlcWQIjriyF", + "name": "ZkIcWjtzeDWJcbbuEMMGM4", "type_args": [] } } ], - "args": [] - } - }, - "max_gas_amount": "18117267148020982538", - "gas_unit_price": "3586885016193938819", - "expiration_timestamp_secs": "7606986017144337215", - "chain_id": 146 - }, - "signed_txn_bcs": "53c6a20e460e61c02ef6929f19345d7bcb7392f4ec816be5f49a83850f81db1a68fe136c470332d800057eff72796f0607f708ee98fb4d613c35009d11ebd50b90d6eb65e66ff7659f7b10aa6bd15a18aa10755662657142664f7768504955426c31147373685a4c5754596f73667a584d4f4671436c6600070ec36b27bab4551aa36bfcb677cccb4231d5545d9f394cdb679a863179575b7211486c516a63447145546352417644516f370f57797167694b42467a4b614748467600060607b67282202df0777ff7616205f0d52d746d9494b6375e2fff527dd64bfb662bbe164a57426b63564946697842655866414f754579724f381e554356454b6a5a7259545853766c575a6854486c764341797a517a5a623000077eb23c3cc8a165ec44b8df598722585a9f52e54b223cf2a9bdc86cf954cd0d66114162727a484357475461434c6b786a76421369637a78754a514671694c495a56666b4249370007dac8d8adfe18cf3ecc7e46a159c8152e69472d15933903202392bf83672a789814525741476166714b4f42646248426454504b78370d69776e66727251657846776c3700074cdd8edfa149dd2fc0c872020704fe3292c0f8df207f6c4c09bbd9f60481691e1c6b746b5753586a674d5842566f6b6a506d4c4154547452795850494812517771647759597658706a53556b6947776900000a23a5527b766dfb83356908eb2cc7313f7340a37a71916992002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a1444048101cde99588eeaae522c381bc0376fd8fdba10d761a72116a493c8c11b472677844623a4dd447008b5611a551a8bddc42e42353c6e15cbae21afd455c0710c", - "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" - }, - { - "raw_txn": { - "sender": "88afc70e42a0581de2a0f8a2203ba6561119cfcf5c700a5af04a5cc1cd7b1a3a", - "sequence_number": "16120235932136881982", - "payload": { - "Script": { - "code": "2f3f", - "ty_args": [ + "args": [ { - "vector": { - "vector": { - "struct": { - "address": "7e5e718b46fd88b60652c76817cdf54ea65f09df094556296748debd14bf52db", - "module": "zrXpKvIzgXjcRBcEnIKBhQeGlp1", - "name": "bMzmAlVVA3", - "type_args": [] - } - } - } + "U128": "14140931011640362963876395461809917561" }, { - "struct": { - "address": "2169cde70e0da53b3e9b21eaa69d3f8d048b3e81b463e18924d62ba8f682a90f", - "module": "oEDHLzZsAKHHBRLydwSyJN", - "name": "CtNqBi0", - "type_args": [] - } - } - ], - "args": [ + "U64": "1123097944319240555" + }, { - "Address": "cf0b6010934d009f145b18293dc105c91af47d3b0ddd919775f195c9f945ef1a" + "U64": "17864694468739376037" }, { - "Bool": true + "U64": "14494955386954077556" }, { - "Bool": false + "Address": "22dd3ae19101df11c7b57d184a33b7d08cf8fa67a8536f6542f6385aa329c5a8" + }, + { + "U64": "2662883762553180001" }, { - "U128": "265100979247294034163966764865660825792" + "Bool": true }, { - "U64": "2444078154558270811" + "U128": "308535887565064038273400162331148444955" }, { - "Bool": false + "U8Vector": "459e8b0d72cc0e8fde38a1f1bbaeba" }, { - "Address": "9b81e31773c73929717fdc08fa557a72b4a8b61b7a868ee433912a3e24d286a5" + "Bool": false } ] } }, - "max_gas_amount": "14612169717085905559", - "gas_unit_price": "13086807626326515660", - "expiration_timestamp_secs": "10010401325028931018", - "chain_id": 136 + "max_gas_amount": "11216059455577111357", + "gas_unit_price": "14327256314869360691", + "expiration_timestamp_secs": "8884530080395915140", + "chain_id": 172 }, - "signed_txn_bcs": "88afc70e42a0581de2a0f8a2203ba6561119cfcf5c700a5af04a5cc1cd7b1a3a3ebf81ee2b95b6df00022f3f020606077e5e718b46fd88b60652c76817cdf54ea65f09df094556296748debd14bf52db1b7a7258704b76497a67586a63524263456e494b42685165476c70310a624d7a6d416c5656413300072169cde70e0da53b3e9b21eaa69d3f8d048b3e81b463e18924d62ba8f682a90f166f4544484c7a5a73414b484842524c79647753794a4e0743744e71426930000703cf0b6010934d009f145b18293dc105c91af47d3b0ddd919775f195c9f945ef1a0501050002c0b0f692262eec5f1c28886c679770c7015bedbcdd211ceb210500039b81e31773c73929717fdc08fa557a72b4a8b61b7a868ee433912a3e24d286a59722a068f0dac8cacc9f100333ae9db5caf572bdf716ec8a88002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a144405bad7c727f36868e5739db1a31a0fe90cec947703e419df10006be73012a242980db35bce2f4d3ae149cdbc1d13ce77b82c5db6ae49959206abf5ec186c1a30d", + "signed_txn_bcs": "8f836387d1bcb38c1f228b9ed7d21c4477c624de28111c88e07ae56f1a6589f6db841a1028f5168a000e67841f8946c50a2fcab7eab03f830607e7c50b00e9ffc34885e2482cd79605b372e42ad5e69a1990cd7648ca1325a2ee196b456b59645368626b764f5173446a776441754867684e434f1a786e5452756e737647545770685465515a6b6f424241736374390007cae841b78fcba8e607bfe6302641170123917995db53f518ac40456d369901f1216272525259676f4f6476574c7250726d42414c54684e6771757361494547754d35207650524c5965646f42516258564155586c68736769424e686f537746507546390006060407eb82b083ba94e320953dd73399a18b9b9d57349f0602090b4bf9179ec38be9840c586c69584c5769596142463606654e487468300007f70cf6f34bfac4803a0a17b29bc8ba06b1b04b8bc12511b67ea6dd1a0f2b923e01420364585300079c4fcb2c59dd6675d8161e0555ebc6d464c7bde04e7bf7b7bb169a0932a98fff1a4362756d48427766776967616a5a66576c635751496a72697946165a6b4963576a747a6544574a63626275454d4d474d34000a0279ce5d2b9220bcc5dfc75637ba71a30a016ba91e43a10b960f01a5a318d6f724ecf7017455887a206d28c90322dd3ae19101df11c7b57d184a33b7d08cf8fa67a8536f6542f6385aa329c5a801614f2369ac76f4240501021b65fcb5178433ebd9be85ecb8d91de8040f459e8b0d72cc0e8fde38a1f1bbaeba05003dbb554da672a79b33a8c295b5a3d4c6846f452e09314c7bac002020fdbac9b10b7587bba7b5bc163bce69e796d71e4ed44c10fcb4488689f7a14440d559570e40d4e10e3304239f3cf40766299462b8d7809f344d421fe7478700561cdce8f6d057d64203e3d77e2ad593995f7cab632bd1d820c8f175653cbd5e0f", "private_key": "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" } ] diff --git a/aptos-move/framework/src/built_package.rs b/aptos-move/framework/src/built_package.rs index d360cc989f2..178ddd4032b 100644 --- a/aptos-move/framework/src/built_package.rs +++ b/aptos-move/framework/src/built_package.rs @@ -461,6 +461,28 @@ impl BuiltPackage { }) } + /// Replaces a module by name with a new CompiledModule instance + #[cfg(feature = "testing")] + pub fn replace_module( + &mut self, + module_name: &str, + new_module: CompiledModule, + ) -> anyhow::Result<()> { + for unit_with_source in &mut self.package.root_compiled_units { + if let CompiledUnit::Module(named_module) = &mut unit_with_source.unit { + if named_module.name.as_str() == module_name { + named_module.module = new_module; + return Ok(()); + } + } + } + + Err(anyhow::anyhow!( + "Module '{}' not found in package", + module_name + )) + } + /// Returns the number of scripts in the package. pub fn script_count(&self) -> usize { self.package.scripts().count() diff --git a/testsuite/fuzzer/fuzz.sh b/testsuite/fuzzer/fuzz.sh index a31cfb0d165..c36392eee9e 100755 --- a/testsuite/fuzzer/fuzz.sh +++ b/testsuite/fuzzer/fuzz.sh @@ -3,8 +3,7 @@ export RUSTFLAGS="${RUSTFLAGS} --cfg tokio_unstable" export EXTRAFLAGS="-Ztarget-applies-to-host -Zhost-config" # Nightly version control -# Pin nightly-2024-02-12 because of https://github.com/google/oss-fuzz/issues/11626 -NIGHTLY_VERSION="nightly-2024-09-05" +NIGHTLY_VERSION="nightly-2025-04-03" # GDRIVE format https://docs.google.com/uc?export=download&id=DOCID # "https://storage.googleapis.com/aptos-core-corpora/move_aptosvm_publish_seed_corpus.zip" diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/deserialize_script_module.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/deserialize_script_module.rs index bbd6d5a0639..17ad74ccd89 100644 --- a/testsuite/fuzzer/fuzz/fuzz_targets/move/deserialize_script_module.rs +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/deserialize_script_module.rs @@ -6,8 +6,11 @@ use arbitrary::Arbitrary; use libfuzzer_sys::{fuzz_target, Corpus}; // mod utils; use move_binary_format::{ - deserializer::DeserializerConfig, file_format::CompiledScript, CompiledModule, + deserializer::DeserializerConfig, + file_format::{CompiledModule, CompiledScript}, + file_format_common::VERSION_MAX, }; +use move_vm_types::natives::function::StatusCode; #[derive(Arbitrary, Debug)] enum ExecVariant { @@ -28,31 +31,49 @@ fn run_case(data: &ExecVariant) -> Corpus { fn run_case_module(module: &CompiledModule) -> Corpus { let mut module_code = vec![]; - if module.serialize(&mut module_code).is_err() { + if module + .serialize_for_version(Some(VERSION_MAX), &mut module_code) + .is_err() + { return Corpus::Reject; } - match CompiledModule::deserialize_with_config(&module_code, &DeserializerConfig::default()) { + + match CompiledModule::deserialize_no_check_bounds(&module_code) { Ok(mut m) => { m.version = module.version; assert_eq!(*module, m); Corpus::Keep }, - Err(_) => Corpus::Reject, + Err(e) => { + if e.major_status() != StatusCode::MALFORMED { + panic!("Failed to deserialize module after serialization\nCompiledModule:\n{:?}\nSerialized:{:?}", module, module_code); + } + Corpus::Reject + }, } } fn run_case_script(script: &CompiledScript) -> Corpus { let mut script_code = vec![]; - if script.serialize(&mut script_code).is_err() { + if script + .serialize_for_version(Some(VERSION_MAX), &mut script_code) + .is_err() + { return Corpus::Reject; } - match CompiledScript::deserialize_with_config(&script_code, &DeserializerConfig::default()) { + + match CompiledScript::deserialize_no_check_bounds(&script_code) { Ok(mut s) => { s.version = script.version; assert_eq!(*script, s); Corpus::Keep }, - Err(_) => Corpus::Reject, + Err(e) => { + if e.major_status() != StatusCode::MALFORMED { + panic!("Failed to deserialize script after serialization\nCompiledScript:\n{:?}\nSerialized:{:?}", script, script_code); + } + Corpus::Reject + }, } } @@ -60,7 +81,8 @@ fn run_case_raw(raw_data: &Vec) -> Corpus { if let Ok(m) = CompiledModule::deserialize_with_config(raw_data, &DeserializerConfig::default()) { let mut module_code = vec![]; - m.serialize(&mut module_code).unwrap(); + m.serialize_for_version(Some(VERSION_MAX), &mut module_code) + .unwrap(); assert_eq!(*raw_data, module_code); return Corpus::Keep; } @@ -68,7 +90,8 @@ fn run_case_raw(raw_data: &Vec) -> Corpus { if let Ok(s) = CompiledScript::deserialize_with_config(raw_data, &DeserializerConfig::default()) { let mut script_code = vec![]; - s.serialize(&mut script_code).unwrap(); + s.serialize_for_version(Some(VERSION_MAX), &mut script_code) + .unwrap(); assert_eq!(*raw_data, script_code); return Corpus::Keep; } diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/lambda_lifter.rs b/third_party/move/move-compiler-v2/src/env_pipeline/lambda_lifter.rs index d55c782ce96..5515daa5889 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/lambda_lifter.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/lambda_lifter.rs @@ -40,6 +40,8 @@ //! like `|x| f(c, x)` can be represented as `Closure(f, mask(0b01), c)`, whereas //! `|x| f(x, c)` can be represented as `Closure(f, mask(0b10), c)`. +use crate::COMPILER_BUG_REPORT_MSG; +use codespan_reporting::diagnostic::Severity; use itertools::Itertools; use move_binary_format::file_format::Visibility; use move_core_types::function::ClosureMask; @@ -387,12 +389,10 @@ impl<'a> LambdaLifter<'a> { { // We can capture an argument if it can be eagerly evaluated and if // it does not depend on lambda arguments. - if pos >= ClosureMask::MAX_ARGS { - // Exceeded maximal number of arguments which can be captured + if mask.set_captured(pos).is_err() { return None; } captured.push(arg.clone()); - mask.set_captured(pos); } else if lambda_param_pos < lambda_params.len() && matches!(arg.as_ref(), LocalVar(_, name) if name == &lambda_params[lambda_param_pos].0) { @@ -764,7 +764,15 @@ impl ExpRewriterFunctions for LambdaLifter<'_> { Operation::Closure( module_id, fun_id, - ClosureMask::new_for_leading(closure_args.len()), + ClosureMask::new_for_leading(closure_args.len()).unwrap_or_else(|err| { + env.diag_with_notes( + Severity::Bug, + &env.get_node_loc(id), + &format!("compiler internal error: {}", err), + vec![COMPILER_BUG_REPORT_MSG.to_string()], + ); + ClosureMask::empty() + }), ), closure_args, ) diff --git a/third_party/move/move-core/types/src/function.rs b/third_party/move/move-core/types/src/function.rs index 2cbd8c096e0..d780645fca9 100644 --- a/third_party/move/move-core/types/src/function.rs +++ b/third_party/move/move-core/types/src/function.rs @@ -51,12 +51,12 @@ impl ClosureMask { Self(mask) } - pub fn new_for_leading(n: usize) -> Self { + pub fn new_for_leading(n: usize) -> Result { let mut mask = Self::new(0); for i in 0..n { - mask.set_captured(i) + mask.set_captured(i)?; } - mask + Ok(mask) } pub fn bits(&self) -> u64 { @@ -70,9 +70,16 @@ impl ClosureMask { } /// Sets the ith argument to be captured - pub fn set_captured(&mut self, i: usize) { - assert!(i < Self::MAX_ARGS); - self.0 |= 1 << i + pub fn set_captured(&mut self, i: usize) -> Result<(), String> { + if i >= Self::MAX_ARGS { + return Err(format!( + "Captured argument index {} exceeds maximum allowed captured arguments {}", + i, + Self::MAX_ARGS + )); + } + self.0 |= 1 << i; + Ok(()) } /// Apply a closure mask to a list of elements, returning only those diff --git a/third_party/move/move-model/src/builder/exp_builder.rs b/third_party/move/move-model/src/builder/exp_builder.rs index 0b440bbc778..79d28be7719 100644 --- a/third_party/move/move-model/src/builder/exp_builder.rs +++ b/third_party/move/move-model/src/builder/exp_builder.rs @@ -3749,7 +3749,7 @@ impl ExpTranslator<'_, '_, '_> { return ExpData::Call( id, - Operation::Closure(module_id, fun_id, ClosureMask::new_for_leading(0)), + Operation::Closure(module_id, fun_id, ClosureMask::empty()), vec![], ); } diff --git a/third_party/move/move-stdlib/Cargo.toml b/third_party/move/move-stdlib/Cargo.toml index 4b02d534248..3acd27fe902 100644 --- a/third_party/move/move-stdlib/Cargo.toml +++ b/third_party/move/move-stdlib/Cargo.toml @@ -37,4 +37,4 @@ move-unit-test = { workspace = true } tempfile = { workspace = true } [features] -testing = [] +testing = ["move-vm-types/testing"] diff --git a/third_party/move/move-vm/types/src/values/function_values_impl.rs b/third_party/move/move-vm/types/src/values/function_values_impl.rs index 066f2651b3c..8e44b69ef6b 100644 --- a/third_party/move/move-vm/types/src/values/function_values_impl.rs +++ b/third_party/move/move-vm/types/src/values/function_values_impl.rs @@ -84,7 +84,14 @@ impl Closure { impl Debug for Closure { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { let Self(fun, captured) = self; - write!(f, "Closure({}, {:?})", fun.to_canonical_string(), captured) + let mask = fun.closure_mask(); + + f.debug_struct("Closure") + .field("function", &fun.to_canonical_string()) + .field("closure_mask", &mask) + .field("captured_count", &captured.len()) + .field("captured_values", captured) + .finish() } } @@ -211,3 +218,99 @@ where None => Err(A::Error::custom("expected more elements")), } } + +/// Mock AbstractFunction for testing +/// Value:closure(AbstractFunction, [Value]) requires an AbstractFunction, which is agnostic from runtime implementation. +/// This mock is used to test the function values system. +#[cfg(any(test, feature = "fuzzing", feature = "testing"))] +pub(crate) mod mock { + use super::*; + use better_any::{Tid, TidAble, TidExt}; + use move_binary_format::errors::PartialVMResult; + use move_core_types::{ + account_address::AccountAddress, + function::{ClosureMask, FUNCTION_DATA_SERIALIZATION_FORMAT_V1}, + identifier::Identifier, + language_storage::{ModuleId, TypeTag}, + value::MoveTypeLayout, + }; + use std::cmp::Ordering; + + // Since Abstract functions are `Tid`, we cannot auto-mock them, so need to mock manually. + #[derive(Clone, Tid)] + pub(crate) struct MockAbstractFunction { + pub(crate) data: SerializedFunctionData, + } + + impl MockAbstractFunction { + #[allow(dead_code)] + pub(crate) fn new( + fun_name: &str, + ty_args: Vec, + mask: ClosureMask, + captured_layouts: Vec, + ) -> MockAbstractFunction { + Self { + data: SerializedFunctionData { + format_version: FUNCTION_DATA_SERIALIZATION_FORMAT_V1, + module_id: ModuleId::new(AccountAddress::TWO, Identifier::new("m").unwrap()), + fun_id: Identifier::new(fun_name).unwrap(), + ty_args, + mask, + captured_layouts, + }, + } + } + + #[allow(dead_code)] + pub(crate) fn new_from_data(data: SerializedFunctionData) -> Self { + Self { data } + } + } + + impl AbstractFunction for MockAbstractFunction { + fn closure_mask(&self) -> ClosureMask { + self.data.mask + } + + fn cmp_dyn(&self, other: &dyn AbstractFunction) -> PartialVMResult { + // We only need equality for tests + let other_mock = other.downcast_ref::().unwrap(); + Ok(if self.data == other_mock.data { + Ordering::Equal + } else { + Ordering::Less + }) + } + + fn clone_dyn(&self) -> PartialVMResult> { + // Didn't need it in the test + unimplemented!("clone_dyn is not implemented for MockAbstractFunction") + } + + fn to_canonical_string(&self) -> String { + // Needed for assertion failure printing + let ty_args_str = if self.data.ty_args.is_empty() { + String::new() + } else { + format!( + "<{}>", + self.data + .ty_args + .iter() + .map(|t| t.to_canonical_string()) + .collect::>() + .join(", ") + ) + }; + + format!( + "{}::{}::{}{}", + self.data.module_id.address(), + self.data.module_id.name(), + self.data.fun_id, + ty_args_str + ) + } + } +} diff --git a/third_party/move/move-vm/types/src/values/serialization_tests.rs b/third_party/move/move-vm/types/src/values/serialization_tests.rs index 1024331016a..459c5ec2c02 100644 --- a/third_party/move/move-vm/types/src/values/serialization_tests.rs +++ b/third_party/move/move-vm/types/src/values/serialization_tests.rs @@ -8,22 +8,22 @@ mod tests { use crate::{ delayed_values::delayed_field_id::DelayedFieldID, value_serde::{MockFunctionValueExtension, ValueSerDeContext}, - values::{values_impl, AbstractFunction, SerializedFunctionData, Struct, Value}, + values::{function_values_impl::mock::MockAbstractFunction, values_impl, Struct, Value}, }; - use better_any::{Tid, TidAble, TidExt}; + use better_any::TidExt; use claims::{assert_err, assert_ok, assert_some}; use move_binary_format::errors::PartialVMResult; use move_core_types::{ ability::AbilitySet, account_address::AccountAddress, - function::{ClosureMask, MoveClosure, FUNCTION_DATA_SERIALIZATION_FORMAT_V1}, + function::{ClosureMask, MoveClosure}, identifier::Identifier, language_storage::{FunctionParamOrReturnTag, FunctionTag, ModuleId, StructTag, TypeTag}, u256, value::{IdentifierMappingKind, MoveStruct, MoveStructLayout, MoveTypeLayout, MoveValue}, }; use serde::{Deserialize, Serialize}; - use std::{cmp::Ordering, iter}; + use std::iter; // ========================================================================== // Enums @@ -335,61 +335,6 @@ mod tests { // -------------------------------------------------------------------------------------- // VM Values - // Since Abstract functions are `Tid`, we cannot auto-mock them, so need to mock manually. - #[derive(Clone, Tid)] - struct MockAbstractFunction { - data: SerializedFunctionData, - } - - impl MockAbstractFunction { - fn new( - fun_name: &str, - ty_args: Vec, - mask: ClosureMask, - captured_layouts: Vec, - ) -> MockAbstractFunction { - Self { - data: SerializedFunctionData { - format_version: FUNCTION_DATA_SERIALIZATION_FORMAT_V1, - module_id: ModuleId::new(AccountAddress::TWO, Identifier::new("m").unwrap()), - fun_id: Identifier::new(fun_name).unwrap(), - ty_args, - mask, - captured_layouts, - }, - } - } - - fn new_from_data(data: SerializedFunctionData) -> Self { - Self { data } - } - } - - impl AbstractFunction for MockAbstractFunction { - fn closure_mask(&self) -> ClosureMask { - self.data.mask - } - - fn cmp_dyn(&self, other: &dyn AbstractFunction) -> PartialVMResult { - // We only need equality for tests - let other_mock = other.downcast_ref::().unwrap(); - Ok(if self.data == other_mock.data { - Ordering::Equal - } else { - Ordering::Less - }) - } - - fn clone_dyn(&self) -> PartialVMResult> { - unimplemented!() - } - - fn to_canonical_string(&self) -> String { - // Needed for assertion failure printing - "".to_string() - } - } - fn round_trip_vm_closure_value( fun: MockAbstractFunction, captured: Vec, diff --git a/third_party/move/move-vm/types/src/values/value_depth_tests.rs b/third_party/move/move-vm/types/src/values/value_depth_tests.rs index bd62cd4084e..879ae162a31 100644 --- a/third_party/move/move-vm/types/src/values/value_depth_tests.rs +++ b/third_party/move/move-vm/types/src/values/value_depth_tests.rs @@ -197,9 +197,11 @@ where let v = MockFunction::closure(ClosureMask::empty(), vec![], vec![]); assert_ok!(f(&v, &v, 1)); - let v = MockFunction::closure(ClosureMask::new_for_leading(1), vec![Value::u8(0)], vec![ - MoveTypeLayout::U8, - ]); + let v = MockFunction::closure( + ClosureMask::new_for_leading(1).expect("Capturing one argument should not fail"), + vec![Value::u8(0)], + vec![MoveTypeLayout::U8], + ); let err = assert_err!(f(&v, &v, 1)); assert_eq!(err.major_status(), StatusCode::VM_MAX_VALUE_DEPTH_REACHED); @@ -235,9 +237,11 @@ where let v = MockFunction::closure(ClosureMask::empty(), vec![], vec![]); assert_ok!(f(&v, 1)); - let v = MockFunction::closure(ClosureMask::new_for_leading(1), vec![Value::u8(0)], vec![ - MoveTypeLayout::U8, - ]); + let v = MockFunction::closure( + ClosureMask::new_for_leading(1).expect("Capturing one argument should not fail"), + vec![Value::u8(0)], + vec![MoveTypeLayout::U8], + ); let err = assert_err!(f(&v, 1)); assert_eq!(err.major_status(), StatusCode::VM_MAX_VALUE_DEPTH_REACHED); } diff --git a/third_party/move/move-vm/types/src/values/value_prop_tests.rs b/third_party/move/move-vm/types/src/values/value_prop_tests.rs index 979371208bc..84e12e0766f 100644 --- a/third_party/move/move-vm/types/src/values/value_prop_tests.rs +++ b/third_party/move/move-vm/types/src/values/value_prop_tests.rs @@ -2,15 +2,35 @@ // Copyright (c) The Move Contributors // SPDX-License-Identifier: Apache-2.0 -use crate::{value_serde::ValueSerDeContext, values::prop::layout_and_value_strategy}; +use crate::{ + value_serde::{MockFunctionValueExtension, ValueSerDeContext}, + values::{function_values_impl::mock, prop::layout_and_value_strategy}, +}; +use better_any::TidExt; use move_core_types::value::MoveValue; use proptest::prelude::*; proptest! { + #![proptest_config(ProptestConfig::with_cases(10000))] #[test] fn serializer_round_trip((layout, value) in layout_and_value_strategy()) { - let blob = ValueSerDeContext::new(None).serialize(&value, &layout).unwrap().expect("must serialize"); - let value_deserialized = ValueSerDeContext::new(None).deserialize(&blob, &layout).expect("must deserialize"); + // Set up mock function extension for function value serialization + let mut ext_mock = MockFunctionValueExtension::new(); + ext_mock + .expect_get_serialization_data() + .returning(move |af| { + Ok(af + .downcast_ref::() + .expect("Should be a mock abstract function") + .data.clone()) + }); + ext_mock + .expect_create_from_serialization_data() + .returning(move |data| Ok(Box::new(mock::MockAbstractFunction::new_from_data(data)))); + + let ctx = ValueSerDeContext::new(None).with_func_args_deserialization(&ext_mock); + let blob = ctx.serialize(&value, &layout).unwrap().expect("must serialize"); + let value_deserialized = ValueSerDeContext::new(None).with_func_args_deserialization(&ext_mock).deserialize(&blob, &layout).expect("must deserialize"); assert!(value.equals(&value_deserialized).unwrap()); let move_value = value.as_move_value(&layout); diff --git a/third_party/move/move-vm/types/src/values/values_impl.rs b/third_party/move/move-vm/types/src/values/values_impl.rs index 50d40f8e159..fb89a156ce8 100644 --- a/third_party/move/move-vm/types/src/values/values_impl.rs +++ b/third_party/move/move-vm/types/src/values/values_impl.rs @@ -16,14 +16,16 @@ use move_binary_format::{ errors::*, file_format::{Constant, SignatureToken, VariantIndex}, }; +#[cfg(any(test, feature = "fuzzing", feature = "testing"))] +use move_core_types::value::{MoveStruct, MoveValue}; use move_core_types::{ account_address::AccountAddress, effects::Op, gas_algebra::AbstractMemorySize, u256, value::{ - self, MoveStruct, MoveStructLayout, MoveTypeLayout, MoveValue, MASTER_ADDRESS_FIELD_OFFSET, - MASTER_SIGNER_VARIANT, PERMISSIONED_SIGNER_VARIANT, PERMISSION_ADDRESS_FIELD_OFFSET, + self, MoveStructLayout, MoveTypeLayout, MASTER_ADDRESS_FIELD_OFFSET, MASTER_SIGNER_VARIANT, + PERMISSIONED_SIGNER_VARIANT, PERMISSION_ADDRESS_FIELD_OFFSET, }, vm_status::{sub_status::NFE_VECTOR_ERROR_BASE, StatusCode}, }; @@ -4705,10 +4707,52 @@ impl GlobalValue { #[cfg(feature = "fuzzing")] pub mod prop { use super::*; + use crate::values::function_values_impl::mock; #[allow(unused_imports)] - use move_core_types::value::{MoveStruct, MoveValue}; + use move_core_types::{ + ability::AbilitySet, + function::ClosureMask, + language_storage::{FunctionParamOrReturnTag, FunctionTag, TypeTag}, + value::{MoveStruct, MoveValue}, + }; use proptest::{collection::vec, prelude::*}; + fn type_tag_strategy() -> impl Strategy { + use move_core_types::language_storage::{FunctionTag, StructTag}; + use proptest::prelude::any; + + let leaf = prop_oneof![ + 1 => Just(TypeTag::Bool), + 1 => Just(TypeTag::U8), + 1 => Just(TypeTag::U16), + 1 => Just(TypeTag::U32), + 1 => Just(TypeTag::U64), + 1 => Just(TypeTag::U128), + 1 => Just(TypeTag::U256), + 1 => Just(TypeTag::Address), + 1 => Just(TypeTag::Signer), + ]; + + prop_oneof![ + 3 => leaf.clone(), // Direct leaf types at top level + 2 => leaf.clone().prop_recursive(4, 16, 2, |inner| { + prop_oneof![ + 1 => inner.clone().prop_map(|ty| TypeTag::Vector(Box::new(ty))), + 1 => any::().prop_map(|struct_tag| { + TypeTag::Struct(Box::new(struct_tag)) + }), + ] + }), + 1 => (vec(leaf.clone(), 0..=2), vec(leaf, 0..=2), any::()).prop_map(|(args, results, abilities)| { + TypeTag::Function(Box::new(FunctionTag { + args: args.into_iter().map(FunctionParamOrReturnTag::Value).collect(), + results: results.into_iter().map(FunctionParamOrReturnTag::Value).collect(), + abilities, + })) + }), + ] + } + pub fn value_strategy_with_layout(layout: &MoveTypeLayout) -> impl Strategy { use MoveTypeLayout as L; @@ -4790,14 +4834,23 @@ pub mod prop { }) .boxed(), }, - L::Struct(struct_layout @ MoveStructLayout::RuntimeVariants(variants)) => struct_layout - // TODO(#13806): do we need to have a strategy for different variants? - .fields(Some(variants.len().wrapping_sub(1))) // choose last variant - .iter() - .map(value_strategy_with_layout) - .collect::>() - .prop_map(move |vals| Value::struct_(Struct::pack(vals))) - .boxed(), + L::Struct(_struct_layout @ MoveStructLayout::RuntimeVariants(variants)) => { + // Randomly choose a variant index + let variant_count = variants.len(); + let variants = variants.clone(); + (0..variant_count as u16) + .prop_flat_map(move |variant_tag| { + let variant_layouts = variants[variant_tag as usize].clone(); + variant_layouts + .iter() + .map(value_strategy_with_layout) + .collect::>() + .prop_map(move |vals| { + Value::struct_(Struct::pack_variant(variant_tag, vals)) + }) + }) + .boxed() + }, L::Struct(struct_layout) => struct_layout .fields(None) @@ -4808,11 +4861,41 @@ pub mod prop { .boxed(), L::Function => { - // TODO(#15664): not clear how to generate closure values, we'd need - // some test functions for this, and generate `AbstractFunction` impls. - // As we do not generate function layouts in the first place, we can bail - // out here - unreachable!("unexpected function layout") + ( + "[a-z][a-z0-9_]{0,8}", + any::().prop_map(|bits| ClosureMask::new((bits % 16) as u64)), + ) + .prop_flat_map(|(name, mask)| { + let num_captured = mask.captured_count() as usize; + + // Generate random type arguments (0-3 type args) + let ty_args_strategy = vec(type_tag_strategy(), 0..=3); + + // Generate random layouts for each captured value + let captured_layouts_strategy = vec(layout_strategy(), num_captured); + + (ty_args_strategy, captured_layouts_strategy).prop_flat_map( + move |(ty_args, captured_layouts)| { + // Then recursively generate values matching those layouts + let name = name.clone(); + let captured_strategies = captured_layouts + .iter() + .map(value_strategy_with_layout) + .collect::>(); + + captured_strategies.prop_map(move |captured_values| { + let fun = mock::MockAbstractFunction::new( + &name, + ty_args.clone(), + mask, + captured_layouts.clone(), + ); + Value::closure(Box::new(fun), captured_values) + }) + }, + ) + }) + .boxed() }, // TODO[agg_v2](cleanup): double check what we should do here (i.e. if we should @@ -4824,6 +4907,7 @@ pub mod prop { pub fn layout_strategy() -> impl Strategy { use MoveTypeLayout as L; + // Non-recursive leafs let leaf = prop_oneof![ 1 => Just(L::U8), 1 => Just(L::U16), @@ -4835,13 +4919,21 @@ pub mod prop { 1 => Just(L::Address), ]; - leaf.prop_recursive(8, 32, 2, |inner| { - prop_oneof![ - 1 => inner.clone().prop_map(|layout| L::Vector(Box::new(layout))), - 1 => vec(inner, 0..1).prop_map(|f_layouts| { - L::Struct(MoveStructLayout::new(f_layouts))}), - ] - }) + // Return a random layout strategy + prop_oneof![ + 1 => leaf.clone(), + // Recursive leafs are 4x more likely than non-recursive leafs + 4 => leaf.prop_recursive(8, 32, 2, |inner| { + prop_oneof![ + 1 => inner.clone().prop_map(|layout| L::Vector(Box::new(layout))), + 1 => vec(inner.clone(), 0..=5).prop_map(|f_layouts| { + L::Struct(MoveStructLayout::new(f_layouts))}), + 1 => vec(vec(inner, 0..=3), 1..=4).prop_map(|variant_layouts| { + L::Struct(MoveStructLayout::new_variants(variant_layouts))}), + ] + }), + 2 => Just(L::Function), + ] } pub fn layout_and_value_strategy() -> impl Strategy { @@ -4852,8 +4944,10 @@ pub mod prop { } } +#[cfg(any(test, feature = "fuzzing", feature = "testing"))] impl ValueImpl { pub fn as_move_value(&self, layout: &MoveTypeLayout) -> MoveValue { + use crate::values::function_values_impl::mock::MockAbstractFunction; use MoveTypeLayout as L; if let L::Native(kind, layout) = layout { @@ -4930,11 +5024,39 @@ impl ValueImpl { } }, + (L::Function, ValueImpl::ClosureValue(closure)) => { + use better_any::TidExt; + use move_core_types::function::MoveClosure; + + // Downcast to MockAbstractFunction to access data directly + if let Some(mock_fun) = closure.0.downcast_ref::() { + let move_closure = MoveClosure { + module_id: mock_fun.data.module_id.clone(), + fun_id: mock_fun.data.fun_id.clone(), + ty_args: mock_fun.data.ty_args.clone(), + mask: mock_fun.data.mask, + captured: closure + .1 + .iter() + .zip(mock_fun.data.captured_layouts.iter()) + .map(|(captured_val, layout)| { + (layout.clone(), captured_val.as_move_value(layout)) + }) + .collect(), + }; + MoveValue::closure(move_closure) + } else { + // Fallback for unknown function types + panic!("Cannot convert unknown function type to MoveValue") + } + }, + (layout, val) => panic!("Cannot convert value {:?} as {:?}", val, layout), } } } +#[cfg(any(test, feature = "fuzzing", feature = "testing"))] impl Value { // TODO: Consider removing this API, or at least it should return a Result! pub fn as_move_value(&self, layout: &MoveTypeLayout) -> MoveValue { From dfb442b618cd4b748692ff2c7a52f421a240c1c4 Mon Sep 17 00:00:00 2001 From: George Mitenkov Date: Mon, 7 Jul 2025 16:05:06 +0100 Subject: [PATCH 030/260] [vm] Depth checks error feature-gating (#17018) Downstreamed-from: c8f980430a6221e66832329aab07ff9e6846a823 --- aptos-move/aptos-vm/src/aptos_vm.rs | 38 ++++++++++++++++--- .../move/move-core/types/src/vm_status.rs | 22 ++++++++--- types/src/proptest_types.rs | 4 +- types/src/transaction/mod.rs | 38 ++----------------- 4 files changed, 55 insertions(+), 47 deletions(-) diff --git a/aptos-move/aptos-vm/src/aptos_vm.rs b/aptos-move/aptos-vm/src/aptos_vm.rs index ade2b4b2ba7..787b260170e 100644 --- a/aptos-move/aptos-vm/src/aptos_vm.rs +++ b/aptos-move/aptos-vm/src/aptos_vm.rs @@ -497,11 +497,8 @@ impl AptosVM { } } - let txn_status = TransactionStatus::from_vm_status( - error_vm_status.clone(), - self.features() - .is_enabled(FeatureFlag::CHARGE_INVARIANT_VIOLATION), - ); + let txn_status = + TransactionStatus::from_vm_status(error_vm_status.clone(), self.features()); match txn_status { TransactionStatus::Keep(status) => { @@ -2448,7 +2445,36 @@ impl AptosVM { let gas_used = Self::gas_used(max_gas_amount.into(), &gas_meter); match execution_result { Ok(result) => ViewFunctionOutput::new(Ok(result), gas_used), - Err(e) => ViewFunctionOutput::new(Err(e), gas_used), + Err(e) => { + let vm_status = e.clone().into_vm_status(); + match vm_status { + VMStatus::MoveAbort(_, _) => {}, + _ => { + let message = e + .message() + .map(|m| m.to_string()) + .unwrap_or_else(|| e.to_string()); + return ViewFunctionOutput::new_error_message( + message, + Some(vm_status.status_code()), + gas_used, + ); + }, + } + let txn_status = + TransactionStatus::from_vm_status(vm_status.clone(), vm.features()); + let execution_status = match txn_status { + TransactionStatus::Keep(status) => status, + _ => ExecutionStatus::MiscellaneousError(Some(vm_status.status_code())), + }; + let status_with_abort_info = + vm.inject_abort_info_if_available(&module_storage, execution_status); + ViewFunctionOutput::new_move_abort_error( + status_with_abort_info, + Some(vm_status.status_code()), + gas_used, + ) + }, } } diff --git a/third_party/move/move-core/types/src/vm_status.rs b/third_party/move/move-core/types/src/vm_status.rs index 03cb7fb70fa..bfed232ad81 100644 --- a/third_party/move/move-core/types/src/vm_status.rs +++ b/third_party/move/move-core/types/src/vm_status.rs @@ -192,7 +192,10 @@ impl VMStatus { /// Returns `Ok` with a recorded status if it should be kept, `Err` of the error code if it /// should be discarded - pub fn keep_or_discard(self) -> Result { + pub fn keep_or_discard( + self, + function_values_enabled: bool, + ) -> Result { match self { VMStatus::Executed => Ok(KeptVMStatus::Executed), VMStatus::MoveAbort(location, code) => Ok(KeptVMStatus::MoveAbort(location, code)), @@ -205,14 +208,24 @@ impl VMStatus { .. } => Ok(KeptVMStatus::OutOfGas), + // Note: this is feature gated because the status was not propagated out before and was + // mapped to execution error at function ... at offset ..., etc. + VMStatus::ExecutionFailure { + status_code: StatusCode::VM_MAX_VALUE_DEPTH_REACHED, + .. + } + | VMStatus::Error { + status_code: StatusCode::VM_MAX_VALUE_DEPTH_REACHED, + .. + } if function_values_enabled => Ok(KeptVMStatus::MiscellaneousError), + VMStatus::ExecutionFailure { status_code: StatusCode::EXECUTION_LIMIT_REACHED | StatusCode::IO_LIMIT_REACHED | StatusCode::STORAGE_LIMIT_REACHED | StatusCode::TOO_MANY_DELAYED_FIELDS - | StatusCode::UNABLE_TO_CAPTURE_DELAYED_FIELDS - | StatusCode::VM_MAX_VALUE_DEPTH_REACHED, + | StatusCode::UNABLE_TO_CAPTURE_DELAYED_FIELDS, .. } | VMStatus::Error { @@ -221,8 +234,7 @@ impl VMStatus { | StatusCode::IO_LIMIT_REACHED | StatusCode::STORAGE_LIMIT_REACHED | StatusCode::TOO_MANY_DELAYED_FIELDS - | StatusCode::UNABLE_TO_CAPTURE_DELAYED_FIELDS - | StatusCode::VM_MAX_VALUE_DEPTH_REACHED, + | StatusCode::UNABLE_TO_CAPTURE_DELAYED_FIELDS, .. } => Ok(KeptVMStatus::MiscellaneousError), diff --git a/types/src/proptest_types.rs b/types/src/proptest_types.rs index fdc8b00b3cd..156155fbeb0 100644 --- a/types/src/proptest_types.rs +++ b/types/src/proptest_types.rs @@ -19,7 +19,7 @@ use crate::{ epoch_state::EpochState, event::{EventHandle, EventKey}, ledger_info::{generate_ledger_info_with_sig, LedgerInfo, LedgerInfoWithSignatures}, - on_chain_config::ValidatorSet, + on_chain_config::{Features, ValidatorSet}, proof::TransactionInfoListWithProof, state_store::state_key::StateKey, transaction::{ @@ -541,7 +541,7 @@ impl Arbitrary for TransactionExtraConfig { prop_compose! { fn arb_transaction_status()(vm_status in any::()) -> TransactionStatus { - TransactionStatus::from_vm_status(vm_status, true) + TransactionStatus::from_vm_status(vm_status, &Features::default()) } } diff --git a/types/src/transaction/mod.rs b/types/src/transaction/mod.rs index bdf4c011d17..685b62f235e 100644 --- a/types/src/transaction/mod.rs +++ b/types/src/transaction/mod.rs @@ -61,6 +61,7 @@ use crate::{ fee_statement::FeeStatement, function_info::FunctionInfo, keyless::FederatedKeylessPublicKey, + on_chain_config::{FeatureFlag, Features}, proof::accumulator::InMemoryEventAccumulator, state_store::{state_key::StateKey, state_value::StateValue}, validator_txn::ValidatorTransaction, @@ -1492,10 +1493,10 @@ impl TransactionStatus { } } - pub fn from_vm_status(vm_status: VMStatus, charge_invariant_violation: bool) -> Self { + pub fn from_vm_status(vm_status: VMStatus, features: &Features) -> Self { let status_code = vm_status.status_code(); // TODO: keep_or_discard logic should be deprecated from Move repo and refactored into here. - match vm_status.keep_or_discard() { + match vm_status.keep_or_discard(features.is_enabled(FeatureFlag::ENABLE_FUNCTION_VALUES)) { Ok(recorded) => match recorded { // TODO(bowu):status code should be removed from transaction status KeptVMStatus::MiscellaneousError => { @@ -1505,7 +1506,7 @@ impl TransactionStatus { }, Err(code) => { if code.status_type() == StatusType::InvariantViolation - && charge_invariant_violation + && features.is_enabled(FeatureFlag::CHARGE_INVARIANT_VIOLATION) { TransactionStatus::Keep(ExecutionStatus::MiscellaneousError(Some(code))) } else { @@ -1621,37 +1622,6 @@ impl Default for TransactionAuxiliaryData { } impl TransactionAuxiliaryData { - pub fn from_vm_status(vm_status: &VMStatus) -> Self { - let detail_error_message = match vm_status.clone().keep_or_discard() { - Ok(KeptVMStatus::MiscellaneousError) => { - let status_code = vm_status.status_code(); - Some(VMErrorDetail::new(status_code, None)) - }, - Ok(KeptVMStatus::ExecutionFailure { - location: _, - function: _, - code_offset: _, - message, - }) => { - let status_code = vm_status.status_code(); - Some(VMErrorDetail::new(status_code, message)) - }, - Err(status_code) => { - // emulate the behavior of - if status_code.status_type() == StatusType::InvariantViolation { - Some(VMErrorDetail::new(status_code, None)) - } else { - None - } - }, - _ => None, - }; - - Self::V1(TransactionAuxiliaryDataV1 { - detail_error_message, - }) - } - pub fn get_detail_error_message(&self) -> Option<&VMErrorDetail> { match self { Self::V1(data) => data.detail_error_message.as_ref(), From 0e530c9ad6d5633a670e6da34bdb9ae7c609720f Mon Sep 17 00:00:00 2001 From: George Mitenkov Date: Mon, 7 Jul 2025 17:09:34 +0100 Subject: [PATCH 031/260] [vm][tests] Runtime visibility checks for pack closure (#17017) Downstreamed-from: 34c9ecfab56e1f964104acf249b0425ac247dd6e --- .../move/move-vm/runtime/src/interpreter.rs | 2 + .../runtime/src/runtime_type_checks.rs | 12 +++ .../cross_module_pack_closure.exp | 46 +++++++++ .../cross_module_pack_closure.move | 94 +++++++++++++++++++ .../cross_module_pack_closure_generic.exp | 46 +++++++++ .../cross_module_pack_closure_generic.move | 94 +++++++++++++++++++ .../transactional-tests/tests/tests.rs | 2 +- .../src/framework.rs | 36 ++++++- 8 files changed, 327 insertions(+), 5 deletions(-) create mode 100644 third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_pack_closure.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_pack_closure.move create mode 100644 third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_pack_closure_generic.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_pack_closure_generic.move diff --git a/third_party/move/move-vm/runtime/src/interpreter.rs b/third_party/move/move-vm/runtime/src/interpreter.rs index 62f3ed09f94..ce550802cf9 100644 --- a/third_party/move/move-vm/runtime/src/interpreter.rs +++ b/third_party/move/move-vm/runtime/src/interpreter.rs @@ -2277,6 +2277,7 @@ impl Frame { vec![], ) .map(Rc::new)?; + RTTCheck::check_pack_closure_visibility(&self.function, &function)?; let captured = interpreter.operand_stack.popn(mask.captured_count())?; let lazy_function = LazyLoadedFunction::new_resolved( @@ -2316,6 +2317,7 @@ impl Frame { ty_args, ) .map(Rc::new)?; + RTTCheck::check_pack_closure_visibility(&self.function, &function)?; let captured = interpreter.operand_stack.popn(mask.captured_count())?; let lazy_function = LazyLoadedFunction::new_resolved( diff --git a/third_party/move/move-vm/runtime/src/runtime_type_checks.rs b/third_party/move/move-vm/runtime/src/runtime_type_checks.rs index f2ea8378fdc..66670b7b511 100644 --- a/third_party/move/move-vm/runtime/src/runtime_type_checks.rs +++ b/third_party/move/move-vm/runtime/src/runtime_type_checks.rs @@ -79,6 +79,18 @@ pub(crate) trait RuntimeTypeCheck { } } + /// Checks if the caller can pack a function as a closure. + fn check_pack_closure_visibility( + caller: &LoadedFunction, + function: &LoadedFunction, + ) -> PartialVMResult<()> { + if caller.module_id() == function.module_id() { + return Ok(()); + } + // Same visibility rules as for regular cross-contract calls should apply. + Self::check_cross_module_regular_call_visibility(caller, function) + } + /// Performs a runtime check of the caller is allowed to call a cross-module callee. Applies /// only on regular static calls (no dynamic dispatch!), with caller and callee being coming /// from different modules. diff --git a/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_pack_closure.exp b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_pack_closure.exp new file mode 100644 index 00000000000..89c418f55cd --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_pack_closure.exp @@ -0,0 +1,46 @@ +processed 13 tasks + +task 4 'run'. lines 54-54: +Error: Function execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x2::a, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 0)], +} + +task 7 'run'. lines 60-60: +Error: Function execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x2::c, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 0)], +} + +task 8 'run'. lines 62-62: +Error: Function execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x2::c, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 10 'run'. lines 66-74: +Error: Script execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 11 'run'. lines 76-84: +Error: Script execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_pack_closure.move b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_pack_closure.move new file mode 100644 index 00000000000..f9aa730e984 --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_pack_closure.move @@ -0,0 +1,94 @@ +//# publish +module 0x2::a { + // Empty module for 0x2::b to link against when declaring as a friend. +} + +//# publish +module 0x2::b { + friend 0x2::a; + + fun private_function() {} + public(friend) fun friend_function() {} + public fun public_function() {} +} + + +//# publish +module 0x2::a { + use 0x2::b; + + public fun call_private_function() { + let f = || b::private_function(); + f(); + } + public fun call_friend_function() { + let f = || b::friend_function(); + f(); + } + + public fun call_public_function() { + let f = || b::public_function(); + f(); + } +} + +//# publish +module 0x2::c { + use 0x2::b; + + public fun call_private_function() { + let f = || b::private_function(); + f(); + } + public fun call_friend_function() { + let f = || b::friend_function(); + f(); + } + + public fun call_public_function() { + let f = || b::public_function(); + f(); + } +} + +//# run 0x2::a::call_private_function + +//# run 0x2::a::call_friend_function + +//# run 0x2::a::call_public_function + +//# run 0x2::c::call_private_function + +//# run 0x2::c::call_friend_function + +//# run 0x2::c::call_public_function + +//# run --signers 0x1 +script { + use 0x2::b; + + fun main(_account: signer) { + let f = || b::private_function(); + f(); + } +} + +//# run --signers 0x1 +script { + use 0x2::b; + + fun main(_account: signer) { + let f = || b::friend_function(); + f(); + } +} + +//# run --signers 0x1 +script { + use 0x2::b; + + fun main(_account: signer) { + let f = || b::public_function(); + f(); + } +} diff --git a/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_pack_closure_generic.exp b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_pack_closure_generic.exp new file mode 100644 index 00000000000..89c418f55cd --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_pack_closure_generic.exp @@ -0,0 +1,46 @@ +processed 13 tasks + +task 4 'run'. lines 54-54: +Error: Function execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x2::a, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 0)], +} + +task 7 'run'. lines 60-60: +Error: Function execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x2::c, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 0)], +} + +task 8 'run'. lines 62-62: +Error: Function execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x2::c, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 10 'run'. lines 66-74: +Error: Script execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 11 'run'. lines 76-84: +Error: Script execution failed with VMError: { + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: script, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_pack_closure_generic.move b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_pack_closure_generic.move new file mode 100644 index 00000000000..6223b6f9bee --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/paranoid-tests/encapsulation_safety/cross_module_pack_closure_generic.move @@ -0,0 +1,94 @@ +//# publish +module 0x2::a { + // Empty module for 0x2::b to link against when declaring as a friend. +} + +//# publish +module 0x2::b { + friend 0x2::a; + + fun private_function() {} + public(friend) fun friend_function() {} + public fun public_function() {} +} + + +//# publish +module 0x2::a { + use 0x2::b; + + public fun call_private_function() { + let f = || b::private_function(); + f(); + } + public fun call_friend_function() { + let f = || b::friend_function(); + f(); + } + + public fun call_public_function() { + let f = || b::public_function(); + f(); + } +} + +//# publish +module 0x2::c { + use 0x2::b; + + public fun call_private_function() { + let f = || b::private_function(); + f(); + } + public fun call_friend_function() { + let f = || b::friend_function(); + f(); + } + + public fun call_public_function() { + let f = || b::public_function(); + f(); + } +} + +//# run 0x2::a::call_private_function + +//# run 0x2::a::call_friend_function + +//# run 0x2::a::call_public_function + +//# run 0x2::c::call_private_function + +//# run 0x2::c::call_friend_function + +//# run 0x2::c::call_public_function + +//# run --signers 0x1 +script { + use 0x2::b; + + fun main(_account: signer) { + let f = || b::private_function(); + f(); + } +} + +//# run --signers 0x1 +script { + use 0x2::b; + + fun main(_account: signer) { + let f = || b::friend_function(); + f(); + } +} + +//# run --signers 0x1 +script { + use 0x2::b; + + fun main(_account: signer) { + let f = || b::public_function(); + f(); + } +} diff --git a/third_party/move/move-vm/transactional-tests/tests/tests.rs b/third_party/move/move-vm/transactional-tests/tests/tests.rs index 161489003d6..c14381f4509 100644 --- a/third_party/move/move-vm/transactional-tests/tests/tests.rs +++ b/third_party/move/move-vm/transactional-tests/tests/tests.rs @@ -75,7 +75,7 @@ static TEST_CONFIGS: Lazy> = Lazy::new(|| { TestConfig { name: "paranoid-mode-only", runner: Arc::new(SkipBytecodeVerifierRunner), - experiments: &[], + experiments: &[("access-use-function-check", false)], language_version: LanguageVersion::latest(), // Verifier config is irrelevant here, because we disable verifier for these tests. // Importantly, paranoid checks are enabled. diff --git a/third_party/move/testing-infra/transactional-test-runner/src/framework.rs b/third_party/move/testing-infra/transactional-test-runner/src/framework.rs index 496d517bcbc..a44ee5f87e4 100644 --- a/third_party/move/testing-infra/transactional-test-runner/src/framework.rs +++ b/third_party/move/testing-infra/transactional-test-runner/src/framework.rs @@ -38,11 +38,13 @@ use move_model::{metadata::LanguageVersion, model::GlobalEnv}; use move_symbol_pool::Symbol; use move_vm_runtime::move_vm::SerializedReturnValues; use move_vm_types::values::Value; +use regex::Regex; use std::{ collections::{BTreeMap, BTreeSet, VecDeque}, fmt::{Debug, Write as FmtWrite}, io::Write, path::Path, + str::FromStr, }; use tempfile::NamedTempFile; @@ -209,6 +211,28 @@ pub trait MoveTestAdapter<'a>: Sized { let state = self.compiled_state(); let (named_addr_opt, module, opt_model, warnings_opt) = match syntax { SyntaxChoice::Source => { + // It is possible that a module gets republished. In this case, we need to filter + // existing pre-compiled dependencies to remove old module. Because we do not know + // in advance the module we are compiling, we need to see if the module matches the + // one already compiled. This special case is sufficient for testing, and in case + // match is not found, compiler should complain when seeing a duplicate symbol. + let deps = state + .source_files() + .filter_map(|(dep_id, path)| { + let re = + Regex::new(r"module\s+(0x[0-9a-fA-F]+::[A-Za-z]\w*)\s*\{").unwrap(); + let code = std::fs::read_to_string(data_path).unwrap(); + if let Some(id) = re + .captures(code.trim()) + .and_then(|c| ModuleId::from_str(&c[1]).ok()) + { + id.ne(dep_id).then(|| path.to_owned()) + } else { + Some(path.to_owned()) + } + }) + .collect::>(); + let (unit, opt_model, warnings_opt) = match run_config { // Run the V2 compiler if requested TestRunConfig::CompilerV2 { @@ -218,7 +242,7 @@ pub trait MoveTestAdapter<'a>: Sized { } => compile_source_unit_v2( state.pre_compiled_deps_v2, state.named_address_mapping.clone(), - &state.source_files().cloned().collect::>(), + &deps, data_path.to_owned(), self.known_attributes(), language_version, @@ -290,7 +314,11 @@ pub trait MoveTestAdapter<'a>: Sized { } => compile_source_unit_v2( state.pre_compiled_deps_v2, state.named_address_mapping.clone(), - &state.source_files().cloned().collect::>(), + &state + .source_files() + .map(|(_, path)| path) + .cloned() + .collect::>(), data_path.to_owned(), self.known_attributes(), language_version, @@ -621,10 +649,10 @@ impl<'a> CompiledState<'a> { self.modules.values().map(|pmod| &pmod.module) } - pub fn source_files(&self) -> impl Iterator { + pub fn source_files(&self) -> impl Iterator { self.modules .iter() - .filter_map(|(_, pmod)| Some(&pmod.source_file.as_ref()?.0)) + .filter_map(|(id, pmod)| Some((id, &pmod.source_file.as_ref()?.0))) } pub fn add_with_source_file( From ce180a74136c5ffe5465c90744ea7ba5508431b2 Mon Sep 17 00:00:00 2001 From: Jun Xu <5827713+junxzm1990@users.noreply.github.com> Date: Mon, 7 Jul 2025 10:17:49 -0600 Subject: [PATCH 032/260] fix issues; support closure (#16955) Downstreamed-from: 6801d334f9f630187e8ddca37e9c2a81ba71f442 --- .../move/move-model/bytecode/src/astifier.rs | 79 ++++++- .../tools/move-decompiler/tests/closure.exp | 188 +++++++++++++++++ .../tools/move-decompiler/tests/closure.move | 196 ++++++++++++++++++ .../move-decompiler/tests/nested_loops.exp | 2 +- .../move-decompiler/tests/nested_loops.move | 2 +- .../move-decompiler/tests/noexit_loops.exp | 71 +++++++ .../move-decompiler/tests/noexit_loops.move | 132 ++++++++++++ 7 files changed, 657 insertions(+), 13 deletions(-) create mode 100644 third_party/move/tools/move-decompiler/tests/closure.exp create mode 100644 third_party/move/tools/move-decompiler/tests/closure.move create mode 100644 third_party/move/tools/move-decompiler/tests/noexit_loops.exp create mode 100644 third_party/move/tools/move-decompiler/tests/noexit_loops.move diff --git a/third_party/move/move-model/bytecode/src/astifier.rs b/third_party/move/move-model/bytecode/src/astifier.rs index c2306f95bcd..0d0696f15d8 100644 --- a/third_party/move/move-model/bytecode/src/astifier.rs +++ b/third_party/move/move-model/bytecode/src/astifier.rs @@ -247,6 +247,9 @@ impl<'a> Context<'a> { /// here to simplify the viewpoint on the resulting CFG. /// 3. There must not be stub blocks which just forward a jump, as in /// `label L1; goto L2`. In this case, we substitute `L1` by `L2`. + /// Given a dead loop like `loop continue`, the substitutions will + /// form a cycle like L1->L2->L3--->L1. In this case, all labels will be + /// substituted with the last one, L3. fn clean_bytecode(self) -> Vec { // Compute # of incoming edges for each block. let mut incoming_count = BTreeMap::::new(); @@ -257,22 +260,28 @@ impl<'a> Context<'a> { } // Build a label substitution for stubs. let mut label_subst = BTreeMap::new(); + for blk_id in self.forward_cfg.blocks() { let block_code = self.code_for_block(blk_id); if block_code.len() == 2 { if let (Bytecode::Label(_, label1), Bytecode::Jump(_, label2)) = (&block_code[0], &block_code[1]) { - label_subst.insert(*label1, *label2); + // When only a substitution does not create a cycle, we add it. + if !Self::cyclic_label_subst_detected(*label1, *label2, &label_subst) { + label_subst.insert(*label1, *label2); + } } } } let substitute_label = |mut label: Label| { let mut visited = BTreeSet::new(); while let Some(s) = label_subst.get(&label) { + // This assert should always hold as we have prevented cycles + // when building the label_subst map. assert!( visited.insert(label), - "unexpected cyclic label substitution" + "label_subst is acyclic by construction" ); label = *s; } @@ -346,6 +355,28 @@ impl<'a> Context<'a> { result } + /// Helper function to detect if a label substitution creates a cycle. + fn cyclic_label_subst_detected( + label1: Label, + label2: Label, + label_subst: &BTreeMap, + ) -> bool { + if label1 == label2 { + return true; + } + + let mut visited = BTreeSet::new(); + visited.insert(label1); + let mut target = label2; + while let Some(s) = label_subst.get(&target) { + if !visited.insert(target) { + return true; + } + target = *s; + } + false + } + /// Helper to compute information about loops. fn compute_loop_info(&mut self, loop_info: &FatLoopFunctionInfo) { let backward_cfg = StacklessControlFlowGraph::new_backward(self.code(), true); @@ -525,13 +556,17 @@ impl Generator { // any blocks after that loop. This is a requirement for the algorithm to work. for header in &ctx.loop_headers { for after_loop_label in &ctx.after_loop_labels[header] { - let dest_block = ctx.block_of_label(*after_loop_label); - let edge_filter = |_: BlockId, _: BlockId| true; - let reachable_from_dest = ctx.forward_cfg.reachable_blocks(dest_block, edge_filter); for loop_block_label in &ctx.loop_labels[header] { - // Only when the new virtual edge does not introduce a cycle, we add it! + // Only when the new virtual edge does not bring a loop back (without considering the back edges), + // we add it! let source_block = ctx.block_of_label(*loop_block_label); - if !reachable_from_dest.contains(&source_block) { + let dest_block = ctx.block_of_label(*after_loop_label); + let edge_filter = |from: BlockId, to: BlockId| !ctx.is_back_edge(from, to); + if !ctx + .forward_cfg + .reachable_blocks(dest_block, edge_filter) + .contains(&source_block) + { top_sort.add_dependency( ctx.block_of_label(*loop_block_label), ctx.block_of_label(*after_loop_label), @@ -960,10 +995,14 @@ impl Generator { Operation::MoveFunction(*mid, *fid), srcs, ), - Closure(..) | Invoke => { - // TODO(#15664): implement closure opcodes for astifier - panic!("closure operations not supported: {:?}", oper) - }, + Closure(mid, fid, inst, closure_mask) => self.gen_call_stm( + ctx, + Some(inst), + dests, + Operation::Closure(*mid, *fid, *closure_mask), + srcs, + ), + Invoke => self.gen_invoke(ctx, dests, srcs), Pack(mid, sid, inst) => { self.gen_call_stm( ctx, @@ -1144,6 +1183,24 @@ impl Generator { } } + fn gen_invoke(&mut self, ctx: &Context, dests: &[TempIndex], srcs: &[TempIndex]) { + let ty = Type::tuple( + dests + .iter() + .map(|d| ctx.target.get_local_type(*d).clone()) + .collect(), + ); + let invoke_id = self.new_node_id(ctx, ty); + let mut temps = self.make_temps(ctx, srcs.iter().copied()); + let closure = temps.pop().expect("closure must be present for invoke"); + let invoke = ExpData::Invoke(invoke_id, closure, temps); + if !dests.is_empty() { + self.gen_assign(ctx, dests, invoke) + } else { + self.add_stm(invoke) + } + } + fn gen_match( &mut self, ctx: &Context, diff --git a/third_party/move/tools/move-decompiler/tests/closure.exp b/third_party/move/tools/move-decompiler/tests/closure.exp new file mode 100644 index 00000000000..61caec66e5e --- /dev/null +++ b/third_party/move/tools/move-decompiler/tests/closure.exp @@ -0,0 +1,188 @@ + +module 0x99::basic_enum { + enum FV has key { + V1 { + v1: |&mut T|(T) has copy + store, + } + } + fun increment_by_one(x: &mut u64): u64 { + *x = *x + 1; + *x + } + fun test_fun_vec(s: &signer) { + move_to(FV::V1{v1: |arg0| increment_by_one(arg0)}, s); + } +} + +module 0x99::basic_struct { + struct Wrapper has key { + fv: T, + } + fun add_resource_with_struct(acc: &signer, f: |&||(u64)|(u64) has copy + drop + store) { + move_to<|&||(u64)|(u64) has copy + drop + store>(Wrapper<|&||(u64)|(u64) has copy + drop + store>{fv: f}, acc); + } + fun test(f: &||(u64)): u64 { + let _t1; + if (f == f) _t1 = 1 else _t1 = 2; + _t1 + } + public fun test_driver(acc: &signer) { + add_resource_with_struct(acc, |arg0| test(arg0)); + } +} + +module 0x99::lambda_arg { + public fun test(): u64 { + foo(|arg0| __lambda__1__test(arg0), 10) + } + fun __lambda__1__test(param$0: u64): u64 { + 3 + } + fun foo(f: |u64|(u64), x: u64): u64 { + f(x) + } + public fun main() { + if (!(test() == 3)) abort 5; + } +} + +module 0x99::lambda_basic { + fun map(x: u64, f: |u64|(u64) has drop): u64 { + f(x) + } + fun no_name_clash(x: u64, c: u64): u64 { + map(x, |arg0| __lambda__1__no_name_clash(c, arg0)) + } + fun __lambda__1__no_name_clash(c: u64, y: u64): u64 { + y + c + } + fun with_name_clash1(x: u64, c: u64): u64 { + map(x, |arg0| __lambda__1__with_name_clash1(c, arg0)) + } + fun __lambda__1__with_name_clash1(c: u64, x: u64): u64 { + x + c + } + fun with_name_clash2(x: u64, c: u64): u64 { + map(x, |arg0| __lambda__1__with_name_clash2(c, arg0)) + } + fun __lambda__1__with_name_clash2(c: u64, x: u64): u64 { + c + 1 + x + } +} + +module 0x99::lambda_fun_wrapper { + struct Work has drop { + _0: |u64|(u64) has drop, + } + fun t1(): bool { + Work{_0: |arg0| __lambda__1__t1(arg0)} == Work{_0: |arg0| __lambda__2__t1(arg0)} + } + fun __lambda__1__t1(x: u64): u64 { + x + 1 + } + fun __lambda__2__t1(x: u64): u64 { + x + 2 + } + fun t2() { + take_work(Work{_0: |arg0| __lambda__1__t2(arg0)}); + } + fun __lambda__1__t2(x: u64): u64 { + x + 1 + } + fun take_work(_work: Work) { + () + } +} + +module 0x99::lambda_generics { + struct S has drop { + x: T, + } + fun id(self: S): S { + self + } + fun inlined(f: |S|(S), s: S) { + () + } + fun test_receiver_inference(s: S) { + inlined(|arg0| id(arg0), s); + } +} + +module 0x99::lambda_inline { + fun g() { + () + } +} + +module 0x99::lambda_inline1 { + public fun test() { + let _t1; + let _t0; + let _t2; + _t2 = 1 + 1; + _t0 = 1000 + 1; + _t1 = 100 + 1; + _t2 = _t2 + 1; + _t1 = _t1 + 1; + _t2 = _t2 * _t0 + _t1 + 3 * _t2 + 5 * _t1 + 7 * (_t0 + 1); + if (!(_t2 == 9637)) abort _t2; + } +} + +module 0x99::lambda_no_param { + public fun test() { + () + } +} + +module 0x99::lambda_no_param1 { + public fun test() { + if (!(foo(|(arg0,arg1)| __lambda__1__test(arg0, arg1), |(arg0,arg1)| __lambda__2__test(arg0, arg1), 10, 100) == 110)) abort 0; + } + fun __lambda__1__test(x: u64, param$1: u64): u64 { + x + } + fun foo(f: |(u64, u64)|(u64), g: |(u64, u64)|(u64), x: u64, _y: u64): u64 { + f(x, _y) + g(x, _y) + } + fun __lambda__2__test(param$0: u64, y: u64): u64 { + y + } +} + +module 0x99::lambda_pattern { + struct S { + x: T, + } + fun consume(s: S, x: T, f: |(S, T)|(T)): T { + f(s, x) + } + fun pattern(s: S, x: u64): u64 { + consume(s, x, |(arg0,arg1)| __lambda__1__pattern(arg0, arg1)) + } + fun __lambda__1__pattern(param$0: S, _y: u64): u64 { + let _t4; + S{x: _t4} = param$0; + _y = _t4; + _y + _y + } +} + +module 0x99::nested_lambda { + fun map1(x: u64, f: |u64|(u64)): u64 { + f(x) + } + fun map2(x: u8, f: |u8|(u8)): u8 { + f(x) + } + fun nested(x: u64, c: u64): u64 { + map1(x, |arg0| __lambda__2__nested(c, arg0)) + } + fun __lambda__2__nested(c: u64, y: u64): u64 { + map2(y - c as u8, |arg0| __lambda__1__nested(c, arg0)) as u64 + } + fun __lambda__1__nested(c: u64, y: u8): u8 { + y + (c as u8) + } +} diff --git a/third_party/move/tools/move-decompiler/tests/closure.move b/third_party/move/tools/move-decompiler/tests/closure.move new file mode 100644 index 00000000000..2591eef573c --- /dev/null +++ b/third_party/move/tools/move-decompiler/tests/closure.move @@ -0,0 +1,196 @@ +module 0x99::basic_enum { + #[persistent] + fun increment_by_one(x: &mut u64): u64 { *x = *x + 1; *x } + + enum FV has key { + V1 { v1: |&mut T|T has copy+store}, + } + + fun test_fun_vec(s: &signer) { + // ok case + let f1: |&mut u64|u64 has copy+store = increment_by_one; + let v1 = FV::V1{v1: f1}; + move_to(s, v1); + } +} + +module 0x99::basic_struct { + struct Wrapper has key { + fv: T + } + + #[persistent] + fun test(f: &||u64): u64 { + if (f == f) + 1 + else + 2 + } + + // all abilities satisfied + fun add_resource_with_struct(acc: &signer, f: | &||u64 |u64 has copy+store+drop) { + move_to>(acc, Wrapper { fv: f}); + } + + public fun test_driver(acc: &signer){ + // ok case + let f: | &||u64 |u64 has copy+store+drop = test; + add_resource_with_struct(acc, f); + } +} + +module 0x99::nested_lambda { + + /// A higher order function on ints + fun map1(x: u64, f: |u64|u64): u64 { + f(x) + } + + /// Another higher order function on ints + fun map2(x: u8, f: |u8|u8): u8 { + f(x) + } + + /// A tests which nests things + fun nested(x: u64, c: u64): u64 { + map1(x, |y| (map2((y - c as u8), |y| y + (c as u8)) as u64)) + } +} + + +module 0x99::lambda_basic { + /// A higher order function on ints + fun map(x: u64, f: |u64|u64 has drop): u64 { + f(x) + } + + /// Tests basic usage, without name overlap + fun no_name_clash(x: u64, c: u64): u64 { + map(x, |y| y + c) + } + + /// Basic usage in the presence of name clask + fun with_name_clash1(x: u64, c: u64): u64 { + map(x, |x| x + c) + } + + /// More clashes + fun with_name_clash2(x: u64, c: u64): u64 { + map(x, |x| { + let x = c + 1; + x + } + x) + } +} + +module 0x99::lambda_pattern { + + /// Test struct + struct S { + x: T + } + + /// A higher order function on `S` + fun consume(s: S, x: T, f: |S, T|T): T { + f(s, x) + } + + /// Lambda with pattern + fun pattern(s: S, x: u64): u64 { + consume(s, x, |S{x}, _y| { let y = x; x + y}) + } +} + +module 0x99::lambda_fun_wrapper { + struct Work(|u64|u64) has drop; + + fun take_work(_work: Work) {} + + fun t1():bool { + let work = Work(|x| x + 1); + work == (|x| x + 2) + } + + fun t2() { + take_work(|x| x + 1) + } +} + +module 0x99::lambda_no_param { + inline fun foo(f:|u64, u64| u64, g: |u64, u64| u64, x: u64, _y: u64): u64 { + f(x, _y) + g(x, _y) + } + + public fun test() { + assert!(foo(|_, _| 3, |_, _| 10, 10, 100) == 13, 0); + } +} + +module 0x99::lambda_no_param1 { + fun foo(f:|u64, u64| u64, g: |u64, u64| u64, x: u64, _y: u64): u64 { + f(x, _y) + g(x, _y) + } + + public fun test() { + assert!(foo(|x, _| x, |_, y| y, 10, 100) == 110, 0); + } +} + +module 0x99::lambda_inline { + inline fun foo(f: |&u64|) { + } + + fun g() { + foo(|v| { + v == &1; + }); + } +} + +module 0x99::lambda_inline1 { + inline fun foo(f:|u64, u64, u64| u64, g: |u64, u64, u64| u64, x: u64, _: u64, y: u64, z: u64): u64 { + let r1 = f({x = x + 1; x}, {y = y + 1; y}, {z = z + 1; z}); + let r2 = g({x = x + 1; x}, {y = y + 1; y}, {z = z + 1 ; z}); + r1 + r2 + 3*x + 5*y + 7*z + } + + public fun test() { + let r = foo(|x, _, z| x*z, |_, y, _| y, 1, 10, 100, 1000); + assert!(r == 9637, r); + } +} + +module 0x99::lambda_arg { + fun foo(f:|u64| u64, x: u64): u64 { + f(x) + } + + public fun test(): u64 { + foo(|_| 3, 10) + } + + public fun main() { + assert!(test() == 3, 5); + } +} + +module 0x99::lambda_generics { + + struct S has drop { x: T } + + + fun inlined(f: |S|S, s: S) { + f(s); + } + + fun id(self: S): S { + self + } + + fun test_receiver_inference(s: S) { + // In the lambda the type of `s` is not known when the expression is checked, + // and the receiver function `id` is resolved later when the parameter type is unified + // with the lambda expression + inlined(|s| s.id(), s) + } +} diff --git a/third_party/move/tools/move-decompiler/tests/nested_loops.exp b/third_party/move/tools/move-decompiler/tests/nested_loops.exp index cdff3026033..d659349feb1 100644 --- a/third_party/move/tools/move-decompiler/tests/nested_loops.exp +++ b/third_party/move/tools/move-decompiler/tests/nested_loops.exp @@ -1,5 +1,5 @@ -module 0x99::m { +module 0x99::nested_loops { fun nested_for_loops() { let _t4; let _t3; diff --git a/third_party/move/tools/move-decompiler/tests/nested_loops.move b/third_party/move/tools/move-decompiler/tests/nested_loops.move index b298bab4c01..a3ce5d75a05 100644 --- a/third_party/move/tools/move-decompiler/tests/nested_loops.move +++ b/third_party/move/tools/move-decompiler/tests/nested_loops.move @@ -1,5 +1,5 @@ //* Test cases with nested loops -module 0x99::m { +module 0x99::nested_loops { fun nested_for_loops() { let y = 0; for (i in 0..10) { diff --git a/third_party/move/tools/move-decompiler/tests/noexit_loops.exp b/third_party/move/tools/move-decompiler/tests/noexit_loops.exp new file mode 100644 index 00000000000..4da7cbeff9a --- /dev/null +++ b/third_party/move/tools/move-decompiler/tests/noexit_loops.exp @@ -0,0 +1,71 @@ + +module 0x99::noexit_loops { + struct R { + } + fun bar(_x: u64) { + () + } + fun baz(_: &u64) { + () + } + fun f1() { + let _t0; + _t0 = 0; + loop _t0 = _t0 + 1 + } + fun f10() { + loop continue + } + fun f11() { + loop continue + } + fun f12() { + () + } + fun f13(cond: bool) { + let _t2; + if (cond) _t2 = 0 else _t2 = 1; + loop continue + } + fun f14(p: bool, q: bool) { + if (p && q) loop continue; + } + fun f15() { + let _t0; + _t0 = 0; + } + fun f16() { + loop continue + } + fun f2(): u64 { + let _t0; + _t0 = 1 + 1; + loop _t0 = _t0 + 1 + } + fun f3(): u64 { + let _t0; + _t0 = 1; + loop _t0 = _t0 + foo(_t0) + } + fun foo(x: u64): u64 { + x + 1 + } + fun f4(): R { + loop continue + } + fun f5(): u64 { + loop continue + } + fun f6() { + loop continue + } + fun f7(): R { + loop continue + } + fun f8() { + loop continue + } + fun f9() { + loop continue + } +} diff --git a/third_party/move/tools/move-decompiler/tests/noexit_loops.move b/third_party/move/tools/move-decompiler/tests/noexit_loops.move new file mode 100644 index 00000000000..e4bc3613af2 --- /dev/null +++ b/third_party/move/tools/move-decompiler/tests/noexit_loops.move @@ -0,0 +1,132 @@ +//* Test cases with no-exit loops +module 0x99::noexit_loops { + fun f1() { + let x = 0; + 'outer: loop { + // inner loop; can never go out + loop { + x = x + 1; + 'inner: loop if (true) loop { + if (false) continue 'outer else break 'inner; + break + } else continue 'outer + }; + break + } + } + + fun f2(): u64 { + let x = 1; + loop { x = x + 1; break }; + loop { x = x + 1 }; + x + } + + fun foo(x: u64): u64 { + x = x + 1; + x + } + fun f3(): u64 { + let x = 1; + while (true) { + x = x + foo(x) + }; + x + } + + struct R {} + + fun f4(): R { + loop {} + } + + fun f5(): u64 { + loop { let x = 0; x; } + } + + fun bar(_x: u64) {} + fun f6() { + bar(loop {}) + } + + fun f7(): R { + let x: R = loop { 0; }; + x + } + + fun f8() { + let () = loop { break }; + let () = loop { if (false) break }; + } + + fun f9() { + while (true) (); + while (false) () + } + + fun f10() { + while ({ let foo = true; foo }) (); + while ({ let bar = false; bar }) () + } + + fun f11() { + loop { + continue; + break + }; + } + + fun f12() { + loop { + if (return) break; + } + } + + fun baz(_: &u64) {} + fun f13(cond: bool) { + 1 + if (cond) 0 else { 1 } + 2; + 1 + loop {} + 2; + 1 + return + 0; + + baz(&if (cond) 0 else 1); + baz(&loop {}); + baz(&return); + baz(&abort 0); + } + + fun f14(p: bool, q: bool) { + while (p) { + if (q) { + loop {}; + let i = 0; + i = i + 1; + } else { + break; + }; + let i = 0; + i = i + 1; + } + } + + fun f15(){ + let x = 0; + 'outer: loop { + // inner loop; just run once + 'inner: loop { + x = x + 1; + 'innermost: loop { + if (true) loop { + if (false) continue 'outer else break 'inner; + break + } else continue 'outer + } + }; + break + } + + } + + fun f16() { + loop { loop { loop {}; }; }; + } +} From d00510bc0fc1ba1b82d7826f57a8b0255282639d Mon Sep 17 00:00:00 2001 From: Vineeth Kashyap Date: Mon, 7 Jul 2025 17:10:15 -0400 Subject: [PATCH 033/260] [compiler-v2] Fix cyclic instantiation checker to consider function types (#16993) Downstreamed-from: 1291b25e155592cb5c16c450e1c796c8131093af --- .../cyclic_instantiation_checker.rs | 33 ++++-- .../tests/checking-lang-v2.2/bug_16938.exp | 75 ++++++++++++ .../tests/checking-lang-v2.2/bug_16938.move | 56 +++++++++ .../recursive_type_instantiation.exp | 48 ++++---- .../v1-tests/complex_1.exp | 20 ++-- ...ree_args_type_con_non_generic_types_ok.exp | 24 ++-- ...recursive_three_args_type_con_shifting.exp | 24 ++-- ...y_recursive_two_args_swapping_type_con.exp | 12 +- .../v1-tests/mutually_recursive_type_con.exp | 12 +- .../v1-tests/nested_types_1.exp | 4 +- .../v1-tests/nested_types_2.exp | 4 +- .../recursive_infinite_type_terminates.exp | 4 +- .../v1-tests/recursive_one_arg_type_con.exp | 4 +- .../recursive_two_args_swapping_type_con.exp | 4 +- .../v1-tests/two_loops.exp | 8 +- .../infinite_instantiations_invalid.exp | 108 +++++++++--------- 16 files changed, 293 insertions(+), 147 deletions(-) create mode 100644 third_party/move/move-compiler-v2/tests/checking-lang-v2.2/bug_16938.exp create mode 100644 third_party/move/move-compiler-v2/tests/checking-lang-v2.2/bug_16938.move diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/cyclic_instantiation_checker.rs b/third_party/move/move-compiler-v2/src/env_pipeline/cyclic_instantiation_checker.rs index 1293ee754b3..b35bed77f5e 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/cyclic_instantiation_checker.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/cyclic_instantiation_checker.rs @@ -88,7 +88,8 @@ impl<'a> CyclicInstantiationChecker<'a> { insts: &[Type], callers_chain: &mut Vec<(Loc, QualifiedInstId)>, ) -> bool { - if let Operation::MoveFunction(mod_id, fun_id) = op { + if let Operation::MoveFunction(mod_id, fun_id) | Operation::Closure(mod_id, fun_id, _) = op + { let callee_uninst = mod_id.qualified_inst(*fun_id, self.get_inst(*nid)); let callee = callee_uninst.instantiate(insts); if *mod_id != self.mod_env.get_id() || self.def_not_recursive(callee.to_qualified_id()) @@ -97,8 +98,8 @@ impl<'a> CyclicInstantiationChecker<'a> { // or if the callee is not recursive true } else { - for (_, ancester_caller) in callers_chain.iter() { - if ancester_caller.to_qualified_id() == callee.to_qualified_id() { + for (_, ancestor_caller) in callers_chain.iter() { + if ancestor_caller.to_qualified_id() == callee.to_qualified_id() { // we are checking for the root caller let (_, checking_for) = &callers_chain[0]; if checking_for.to_qualified_id() != callee.to_qualified_id() { @@ -164,7 +165,7 @@ impl<'a> CyclicInstantiationChecker<'a> { .mod_env .env .get_function(id) - .get_transitive_closure_of_called_functions() + .get_transitive_closure_of_used_functions() .contains(&id) } @@ -184,7 +185,7 @@ impl<'a> CyclicInstantiationChecker<'a> { // callee of `caller` let (callee_loc, callee) = &callers_chain[i + 1]; format!( - "`{}` calls `{}` {}", + "`{}` uses `{}` {}", self.display_call(caller, root), self.display_call(callee, root), callee_loc.display_file_name_and_line(self.mod_env.env) @@ -194,7 +195,7 @@ impl<'a> CyclicInstantiationChecker<'a> { let (_caller_loc, caller) = &callers_chain.last().expect("parent"); let callee_loc = self.mod_env.env.get_node_loc(nid); labels.push(format!( - "`{}` calls `{}` {}", + "`{}` uses `{}` {}", self.display_call(caller, root), self.display_call(&callee, root), callee_loc.display_file_name_and_line(self.mod_env.env) @@ -207,7 +208,7 @@ impl<'a> CyclicInstantiationChecker<'a> { .env .error_with_notes( &root_loc, - "cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound", + "cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound", labels ) } @@ -236,7 +237,14 @@ fn ty_contains_ty_parameter(ty: &Type) -> Option { Type::Vector(ty) => ty_contains_ty_parameter(ty), Type::Struct(_, _, insts) => insts.iter().filter_map(ty_contains_ty_parameter).next(), Type::Primitive(_) => None, - _ => panic!("ICE: {:?} used as a type parameter", ty), + Type::Fun(args, result, _) => { + ty_contains_ty_parameter(args).or_else(|| ty_contains_ty_parameter(result)) + }, + Type::Reference(_, ty) => ty_contains_ty_parameter(ty), + Type::Tuple(ty) => ty.iter().filter_map(ty_contains_ty_parameter).next(), + Type::TypeDomain(_) | Type::ResourceDomain(..) | Type::Error | Type::Var(_) => { + panic!("ICE: {:?} used as a type parameter", ty) + }, } } @@ -246,6 +254,13 @@ fn ty_properly_contains_ty_parameter(ty: &Type) -> Option { Type::Vector(ty) => ty_contains_ty_parameter(ty), Type::Struct(_, _, insts) => insts.iter().filter_map(ty_contains_ty_parameter).next(), Type::Primitive(_) | Type::TypeParameter(_) => None, - _ => panic!("ICE: {:?} used as a type parameter", ty), + Type::Fun(args, result, _) => { + ty_contains_ty_parameter(args).or_else(|| ty_contains_ty_parameter(result)) + }, + Type::Reference(_, ty) => ty_contains_ty_parameter(ty), + Type::Tuple(ty) => ty.iter().filter_map(ty_contains_ty_parameter).next(), + Type::TypeDomain(_) | Type::ResourceDomain(..) | Type::Error | Type::Var(_) => { + panic!("ICE: {:?} used as a type parameter", ty) + }, } } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/bug_16938.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/bug_16938.exp new file mode 100644 index 00000000000..0cb42e6274c --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/bug_16938.exp @@ -0,0 +1,75 @@ + +Diagnostics: +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound + ┌─ tests/checking-lang-v2.2/bug_16938.move:4:9 + │ +4 │ fun f() { + │ ^ + │ + = `f` uses `f<|T|>` at tests/checking-lang-v2.2/bug_16938.move:5 + +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound + ┌─ tests/checking-lang-v2.2/bug_16938.move:10:16 + │ +10 │ public fun foo(): || { + │ ^^^ + │ + = `foo` uses `bar<|&T|>` at tests/checking-lang-v2.2/bug_16938.move:11 + = `bar<|&T|>` uses `foo<|&T|>` at tests/checking-lang-v2.2/bug_16938.move:15 + +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound + ┌─ tests/checking-lang-v2.2/bug_16938.move:14:9 + │ +14 │ fun bar() { + │ ^^^ + │ + = `bar` uses `foo` at tests/checking-lang-v2.2/bug_16938.move:15 + = `foo` uses `bar<|&T|>` at tests/checking-lang-v2.2/bug_16938.move:11 + +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound + ┌─ tests/checking-lang-v2.2/bug_16938.move:25:16 + │ +25 │ public fun foo(): ||(||) { + │ ^^^ + │ + = `foo` uses `bar<|&T|>` at tests/checking-lang-v2.2/bug_16938.move:26 + = `bar<|&T|>` uses `maker<|&T|>` at tests/checking-lang-v2.2/bug_16938.move:30 + = `maker<|&T|>` uses `foo<|&T|>` at tests/checking-lang-v2.2/bug_16938.move:34 + +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound + ┌─ tests/checking-lang-v2.2/bug_16938.move:29:9 + │ +29 │ fun bar(): || { + │ ^^^ + │ + = `bar` uses `maker` at tests/checking-lang-v2.2/bug_16938.move:30 + = `maker` uses `foo` at tests/checking-lang-v2.2/bug_16938.move:34 + = `foo` uses `bar<|&T|>` at tests/checking-lang-v2.2/bug_16938.move:26 + +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound + ┌─ tests/checking-lang-v2.2/bug_16938.move:33:9 + │ +33 │ fun maker(): ||(||(||)) { + │ ^^^^^ + │ + = `maker` uses `foo` at tests/checking-lang-v2.2/bug_16938.move:34 + = `foo` uses `bar<|&T|>` at tests/checking-lang-v2.2/bug_16938.move:26 + = `bar<|&T|>` uses `maker<|&T|>` at tests/checking-lang-v2.2/bug_16938.move:30 + +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound + ┌─ tests/checking-lang-v2.2/bug_16938.move:44:16 + │ +44 │ public fun foo(): || { + │ ^^^ + │ + = `foo` uses `bar<||(T, T)>` at tests/checking-lang-v2.2/bug_16938.move:45 + = `bar<||(T, T)>` uses `foo<||(||(T, T))>` at tests/checking-lang-v2.2/bug_16938.move:49 + +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound + ┌─ tests/checking-lang-v2.2/bug_16938.move:48:9 + │ +48 │ fun bar() { + │ ^^^ + │ + = `bar` uses `foo<||T>` at tests/checking-lang-v2.2/bug_16938.move:49 + = `foo<||T>` uses `bar<||(||T, ||T)>` at tests/checking-lang-v2.2/bug_16938.move:45 diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/bug_16938.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/bug_16938.move new file mode 100644 index 00000000000..c6a65e05d12 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/bug_16938.move @@ -0,0 +1,56 @@ +module 0xc0ffee::m { + struct S { f: T } + + fun f() { + f<|T|>(); + } +} + +module 0xc0ffee::n { + public fun foo(): || { + bar<|&T|> + } + + fun bar() { + (foo())(); + } + + fun test() { + let f = foo<||>(); + f(); + } +} + +module 0xc0ffee::o { + public fun foo(): ||(||) { + bar<|&T|> + } + + fun bar(): || { + maker()()() + } + + fun maker(): ||(||(||)) { + foo + } + + fun test() { + let f = foo<||>(); + f()(); + } +} + +module 0xc0ffee::p { + public fun foo(): || { + bar<||(T, T)> + } + + fun bar() { + (foo<||T>())(); + } + + fun test() { + let f = foo<||>(); + f(); + } +} diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/recursive_type_instantiation.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/recursive_type_instantiation.exp index fc66bb2fb5e..9212e7f41a1 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/recursive_type_instantiation.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/recursive_type_instantiation.exp @@ -1,73 +1,73 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/recursive_type_instantiation.move:6:16 │ 6 │ public fun simple_recursion() { │ ^^^^^^^^^^^^^^^^ │ - = `simple_recursion` calls `simple_recursion>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:7 + = `simple_recursion` uses `simple_recursion>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:7 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/recursive_type_instantiation.move:10:9 │ 10 │ fun two_level_recursion_0() { │ ^^^^^^^^^^^^^^^^^^^^^ │ - = `two_level_recursion_0` calls `two_level_recursion_1` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:11 - = `two_level_recursion_1` calls `two_level_recursion_0>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:15 + = `two_level_recursion_0` uses `two_level_recursion_1` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:11 + = `two_level_recursion_1` uses `two_level_recursion_0>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:15 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/recursive_type_instantiation.move:14:9 │ 14 │ fun two_level_recursion_1() { │ ^^^^^^^^^^^^^^^^^^^^^ │ - = `two_level_recursion_1` calls `two_level_recursion_0>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:15 - = `two_level_recursion_0>` calls `two_level_recursion_1>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:11 + = `two_level_recursion_1` uses `two_level_recursion_0>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:15 + = `two_level_recursion_0>` uses `two_level_recursion_1>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:11 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/recursive_type_instantiation.move:18:9 │ 18 │ fun three_level_recursion_0() { │ ^^^^^^^^^^^^^^^^^^^^^^^ │ - = `three_level_recursion_0` calls `three_level_recursion_1` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:19 - = `three_level_recursion_1` calls `three_level_recursion_2` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:23 - = `three_level_recursion_2` calls `three_level_recursion_0>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:27 + = `three_level_recursion_0` uses `three_level_recursion_1` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:19 + = `three_level_recursion_1` uses `three_level_recursion_2` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:23 + = `three_level_recursion_2` uses `three_level_recursion_0>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:27 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/recursive_type_instantiation.move:22:9 │ 22 │ fun three_level_recursion_1() { │ ^^^^^^^^^^^^^^^^^^^^^^^ │ - = `three_level_recursion_1` calls `three_level_recursion_2` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:23 - = `three_level_recursion_2` calls `three_level_recursion_0>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:27 - = `three_level_recursion_0>` calls `three_level_recursion_1>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:19 + = `three_level_recursion_1` uses `three_level_recursion_2` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:23 + = `three_level_recursion_2` uses `three_level_recursion_0>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:27 + = `three_level_recursion_0>` uses `three_level_recursion_1>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:19 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/recursive_type_instantiation.move:26:9 │ 26 │ fun three_level_recursion_2() { │ ^^^^^^^^^^^^^^^^^^^^^^^ │ - = `three_level_recursion_2` calls `three_level_recursion_0>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:27 - = `three_level_recursion_0>` calls `three_level_recursion_1>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:19 - = `three_level_recursion_1>` calls `three_level_recursion_2>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:23 + = `three_level_recursion_2` uses `three_level_recursion_0>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:27 + = `three_level_recursion_0>` uses `three_level_recursion_1>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:19 + = `three_level_recursion_1>` uses `three_level_recursion_2>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:23 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/recursive_type_instantiation.move:30:9 │ 30 │ fun recurse_at_different_position() { │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ │ - = `recurse_at_different_position` calls `recurse_at_different_position>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:31 + = `recurse_at_different_position` uses `recurse_at_different_position>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:31 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/recursive_type_instantiation.move:44:9 │ 44 │ fun test_vec() { │ ^^^^^^^^ │ - = `test_vec` calls `test_vec>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:45 + = `test_vec` uses `test_vec>` at tests/cyclic-instantiation-checker/recursive_type_instantiation.move:45 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/complex_1.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/complex_1.exp index 1bb77ca0c24..bdcefbc06a5 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/complex_1.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/complex_1.exp @@ -1,29 +1,29 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/complex_1.move:13:9 │ 13 │ fun c() { │ ^ │ - = `c` calls `d` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:15 - = `d` calls `b` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:20 - = `b` calls `c, bool>` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:10 + = `c` uses `d` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:15 + = `d` uses `b` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:20 + = `b` uses `c, bool>` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:10 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/complex_1.move:26:9 │ 26 │ fun f() { │ ^ │ - = `f` calls `g` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:27 - = `g` calls `f>` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:31 + = `f` uses `g` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:27 + = `g` uses `f>` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:31 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/complex_1.move:30:9 │ 30 │ fun g() { │ ^ │ - = `g` calls `f>` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:31 - = `f>` calls `g>` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:27 + = `g` uses `f>` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:31 + = `f>` uses `g>` at tests/cyclic-instantiation-checker/v1-tests/complex_1.move:27 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.exp index a4cbf1c179a..05c0c6f6181 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.exp @@ -1,31 +1,31 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:4:9 │ 4 │ fun f() { │ ^ │ - = `f` calls `g` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:5 - = `g` calls `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:9 - = `h>` calls `f>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:14 + = `f` uses `g` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:5 + = `g` uses `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:9 + = `h>` uses `f>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:14 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:8:9 │ 8 │ fun g() { │ ^ │ - = `g` calls `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:9 - = `h>` calls `f>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:14 - = `f>` calls `g, T1>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:5 + = `g` uses `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:9 + = `h>` uses `f>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:14 + = `f>` uses `g, T1>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:5 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:12:9 │ 12 │ fun h() { │ ^ │ - = `h` calls `f` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:14 - = `f` calls `g` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:5 - = `g` calls `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:9 + = `h` uses `f` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:14 + = `f` uses `g` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:5 + = `g` uses `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_non_generic_types_ok.move:9 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.exp index db55cc263c7..0e648a2662f 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.exp @@ -1,31 +1,31 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:4:9 │ 4 │ fun f() { │ ^ │ - = `f` calls `g` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:5 - = `g` calls `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:9 - = `h>` calls `f>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:13 + = `f` uses `g` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:5 + = `g` uses `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:9 + = `h>` uses `f>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:13 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:8:9 │ 8 │ fun g() { │ ^ │ - = `g` calls `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:9 - = `h>` calls `f>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:13 - = `f>` calls `g, T1>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:5 + = `g` uses `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:9 + = `h>` uses `f>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:13 + = `f>` uses `g, T1>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:5 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:12:9 │ 12 │ fun h() { │ ^ │ - = `h` calls `f` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:13 - = `f` calls `g` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:5 - = `g` calls `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:9 + = `h` uses `f` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:13 + = `f` uses `g` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:5 + = `g` uses `h>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_three_args_type_con_shifting.move:9 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.exp index 1066db9abfa..60e6e631e75 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.exp @@ -1,19 +1,19 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.move:4:9 │ 4 │ fun f() { │ ^ │ - = `f` calls `g` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.move:5 - = `g` calls `f, u64>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.move:9 + = `f` uses `g` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.move:5 + = `g` uses `f, u64>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.move:9 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.move:8:9 │ 8 │ fun g() { │ ^ │ - = `g` calls `f, u64>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.move:9 - = `f, u64>` calls `g, T1>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.move:5 + = `g` uses `f, u64>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.move:9 + = `f, u64>` uses `g, T1>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_two_args_swapping_type_con.move:5 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.exp index 13dda3ae7a1..54bbcd1fc45 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.exp @@ -1,19 +1,19 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.move:7:9 │ 7 │ fun f() { │ ^ │ - = `f` calls `g>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.move:8 - = `g>` calls `f>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.move:12 + = `f` uses `g>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.move:8 + = `g>` uses `f>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.move:12 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.move:11:9 │ 11 │ fun g() { │ ^ │ - = `g` calls `f` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.move:12 - = `f` calls `g>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.move:8 + = `g` uses `f` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.move:12 + = `f` uses `g>` at tests/cyclic-instantiation-checker/v1-tests/mutually_recursive_type_con.move:8 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/nested_types_1.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/nested_types_1.exp index 4c7b9af8fd5..619423018bb 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/nested_types_1.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/nested_types_1.exp @@ -1,9 +1,9 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/nested_types_1.move:4:9 │ 4 │ fun foo() { │ ^^^ │ - = `foo` calls `foo>>` at tests/cyclic-instantiation-checker/v1-tests/nested_types_1.move:5 + = `foo` uses `foo>>` at tests/cyclic-instantiation-checker/v1-tests/nested_types_1.move:5 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/nested_types_2.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/nested_types_2.exp index 4b510f95aa1..61579012c93 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/nested_types_2.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/nested_types_2.exp @@ -1,9 +1,9 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/nested_types_2.move:5:9 │ 5 │ fun foo() { │ ^^^ │ - = `foo` calls `foo>>>` at tests/cyclic-instantiation-checker/v1-tests/nested_types_2.move:6 + = `foo` uses `foo>>>` at tests/cyclic-instantiation-checker/v1-tests/nested_types_2.move:6 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_infinite_type_terminates.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_infinite_type_terminates.exp index aa91ac66ecc..cfa8904c56c 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_infinite_type_terminates.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_infinite_type_terminates.exp @@ -1,9 +1,9 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/recursive_infinite_type_terminates.move:9:9 │ 9 │ fun f(n: u64, x: T): T { │ ^ │ - = `f` calls `f>` at tests/cyclic-instantiation-checker/v1-tests/recursive_infinite_type_terminates.move:11 + = `f` uses `f>` at tests/cyclic-instantiation-checker/v1-tests/recursive_infinite_type_terminates.move:11 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_one_arg_type_con.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_one_arg_type_con.exp index e9041a1b054..cabf5fe3277 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_one_arg_type_con.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_one_arg_type_con.exp @@ -1,9 +1,9 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/recursive_one_arg_type_con.move:6:9 │ 6 │ fun f(x: T) { │ ^ │ - = `f` calls `f>` at tests/cyclic-instantiation-checker/v1-tests/recursive_one_arg_type_con.move:7 + = `f` uses `f>` at tests/cyclic-instantiation-checker/v1-tests/recursive_one_arg_type_con.move:7 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_two_args_swapping_type_con.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_two_args_swapping_type_con.exp index 4892af9de9b..4c485cb8f74 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_two_args_swapping_type_con.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/recursive_two_args_swapping_type_con.exp @@ -1,9 +1,9 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/recursive_two_args_swapping_type_con.move:7:9 │ 7 │ fun f(a: T1, x: T2) { │ ^ │ - = `f` calls `f, T1>` at tests/cyclic-instantiation-checker/v1-tests/recursive_two_args_swapping_type_con.move:8 + = `f` uses `f, T1>` at tests/cyclic-instantiation-checker/v1-tests/recursive_two_args_swapping_type_con.move:8 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/two_loops.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/two_loops.exp index ca960a47c8c..4c8de7b9532 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/two_loops.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-tests/two_loops.exp @@ -1,17 +1,17 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/two_loops.move:7:9 │ 7 │ fun f() { │ ^ │ - = `f` calls `f>` at tests/cyclic-instantiation-checker/v1-tests/two_loops.move:8 + = `f` uses `f>` at tests/cyclic-instantiation-checker/v1-tests/two_loops.move:8 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-tests/two_loops.move:11:9 │ 11 │ fun g() { │ ^ │ - = `g` calls `g>` at tests/cyclic-instantiation-checker/v1-tests/two_loops.move:12 + = `g` uses `g>` at tests/cyclic-instantiation-checker/v1-tests/two_loops.move:12 diff --git a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.exp b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.exp index b5a0ebd9a7c..2d97f6c2360 100644 --- a/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.exp +++ b/third_party/move/move-compiler-v2/tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.exp @@ -1,139 +1,139 @@ Diagnostics: -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:6:16 │ 6 │ public fun t() { │ ^ │ - = `t` calls `t>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:7 + = `t` uses `t>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:7 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:10:16 │ 10 │ public fun x() { │ ^ │ - = `x` calls `y>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:11 - = `y>` calls `x>>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:14 + = `x` uses `y>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:11 + = `y>` uses `x>>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:14 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:13:16 │ 13 │ public fun y() { │ ^ │ - = `y` calls `x>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:14 - = `x>` calls `y>>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:11 + = `y` uses `x>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:14 + = `x>` uses `y>>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:11 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:17:16 │ 17 │ public fun a() { │ ^ │ - = `a` calls `b` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:18 - = `b` calls `c` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:21 - = `c` calls `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:24 + = `a` uses `b` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:18 + = `b` uses `c` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:21 + = `c` uses `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:24 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:20:16 │ 20 │ public fun b() { │ ^ │ - = `b` calls `c` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:21 - = `c` calls `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:24 - = `a>` calls `b>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:18 + = `b` uses `c` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:21 + = `c` uses `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:24 + = `a>` uses `b>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:18 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:23:16 │ 23 │ public fun c() { │ ^ │ - = `c` calls `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:24 - = `a>` calls `b>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:18 - = `b>` calls `c>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:21 + = `c` uses `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:24 + = `a>` uses `b>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:18 + = `b>` uses `c>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:21 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:37:16 │ 37 │ public fun z() { │ ^ │ - = `z` calls `z>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:38 + = `z` uses `z>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:38 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:41:16 │ 41 │ public fun a() { │ ^ │ - = `a` calls `b` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:42 - = `b` calls `c` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:45 - = `c` calls `d>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:48 - = `d>` calls `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:51 + = `a` uses `b` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:42 + = `b` uses `c` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:45 + = `c` uses `d>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:48 + = `d>` uses `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:51 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:44:16 │ 44 │ public fun b() { │ ^ │ - = `b` calls `c` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:45 - = `c` calls `d>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:48 - = `d>` calls `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:51 - = `a>` calls `b>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:42 + = `b` uses `c` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:45 + = `c` uses `d>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:48 + = `d>` uses `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:51 + = `a>` uses `b>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:42 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:47:16 │ 47 │ public fun c() { │ ^ │ - = `c` calls `d>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:48 - = `d>` calls `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:51 - = `a>` calls `b>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:42 - = `b>` calls `c>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:45 + = `c` uses `d>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:48 + = `d>` uses `a>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:51 + = `a>` uses `b>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:42 + = `b>` uses `c>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:45 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:50:16 │ 50 │ public fun d() { │ ^ │ - = `d` calls `a` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:51 - = `a` calls `b` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:42 - = `b` calls `c` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:45 - = `c` calls `d>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:48 + = `d` uses `a` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:51 + = `a` uses `b` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:42 + = `b` uses `c` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:45 + = `c` uses `d>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:48 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:58:16 │ 58 │ public fun tl() { │ ^^ │ - = `tl` calls `tr` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:59 - = `tr` calls `bl>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:62 - = `bl>` calls `tl>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:69 + = `tl` uses `tr` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:59 + = `tr` uses `bl>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:62 + = `bl>` uses `tl>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:69 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:61:16 │ 61 │ public fun tr() { │ ^^ │ - = `tr` calls `bl>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:62 - = `bl>` calls `tl>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:69 - = `tl>` calls `tr>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:59 + = `tr` uses `bl>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:62 + = `bl>` uses `tl>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:69 + = `tl>` uses `tr>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:59 -error: cyclic type instantiation: a cycle of recursive calls causes a type to grow without bound +error: cyclic type instantiation: a cycle of recursive uses causes a type to grow without bound ┌─ tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:68:16 │ 68 │ public fun bl() { │ ^^ │ - = `bl` calls `tl` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:69 - = `tl` calls `tr` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:59 - = `tr` calls `bl>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:62 + = `bl` uses `tl` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:69 + = `tl` uses `tr` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:59 + = `tr` uses `bl>` at tests/cyclic-instantiation-checker/v1-typing/infinite_instantiations_invalid.move:62 From d8d9df4927cd7cb920083447f9c3b75b063ebe24 Mon Sep 17 00:00:00 2001 From: Vineeth Kashyap Date: Tue, 8 Jul 2025 11:49:58 -0400 Subject: [PATCH 034/260] [compiler-v2] Forbid function types with key (#16991) Downstreamed-from: 41a3dde0dc5f6b191e63b7b4dc3e5e32bfaff823 --- .../ability-check/fv_as_keys/store_fv.exp | 20 ++++++--- .../checking-lang-v2.2/lambda/with_key.exp | 43 +++++++++++++++++++ .../checking-lang-v2.2/lambda/with_key.move | 43 +++++++++++++++++++ .../file-format-generator/capture_key.exp | 23 ++++++++++ .../file-format-generator/capture_key.move | 11 +++++ .../file-format-generator/capture_key.opt.exp | 23 ++++++++++ .../move-model/src/builder/exp_builder.rs | 10 ++--- 7 files changed, 163 insertions(+), 10 deletions(-) create mode 100644 third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/with_key.exp create mode 100644 third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/with_key.move create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/capture_key.exp create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/capture_key.move create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/capture_key.opt.exp diff --git a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_fv.exp b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_fv.exp index d425fc109f8..fec0864f595 100644 --- a/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_fv.exp +++ b/third_party/move/move-compiler-v2/tests/ability-check/fv_as_keys/store_fv.exp @@ -1,9 +1,19 @@ Diagnostics: -error: Expected a struct type. Global storage operations are restricted to struct types declared in the current module. Found: '|&||u64|u64 has drop + store + key' - ┌─ tests/ability-check/fv_as_keys/store_fv.move:13:5 +error: function types cannot have `key` ability + ┌─ tests/ability-check/fv_as_keys/store_fv.move:12:45 + │ +12 │ fun add_resource_with_fv(acc: &signer, f: | &||u64 |u64 has store+drop+key) { + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: function types cannot have `key` ability + ┌─ tests/ability-check/fv_as_keys/store_fv.move:13:13 │ 13 │ move_to<| &||u64 |u64 has store+drop+key>(acc, f); - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - │ │ - │ Invalid call to MoveTo<|&||u64|u64 has drop + store + key>. + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: function types cannot have `key` ability + ┌─ tests/ability-check/fv_as_keys/store_fv.move:18:12 + │ +18 │ let f: | &||u64 |u64 has store+drop+key = test; + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/with_key.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/with_key.exp new file mode 100644 index 00000000000..eb7031e3a8c --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/with_key.exp @@ -0,0 +1,43 @@ + +Diagnostics: +error: function types cannot have `key` ability + ┌─ tests/checking-lang-v2.2/lambda/with_key.move:2:19 + │ +2 │ fun caller(f: ||u64 has key): u64 { + │ ^^^^^^^^^^^^^ + +error: function types cannot have `key` ability + ┌─ tests/checking-lang-v2.2/lambda/with_key.move:7:16 + │ +7 │ let f: ||u64 has key = || 1; + │ ^^^^^^^^^^^^^ + +error: function types cannot have `key` ability + ┌─ tests/checking-lang-v2.2/lambda/with_key.move:12:16 + │ +12 │ let f: ||u64 has key = || 1; + │ ^^^^^^^^^^^^^ + +error: function types cannot have `key` ability + ┌─ tests/checking-lang-v2.2/lambda/with_key.move:20:18 + │ +20 │ fun apply(f: ||S has key): S { + │ ^^^^^^^^^^^ + +error: function types cannot have `key` ability + ┌─ tests/checking-lang-v2.2/lambda/with_key.move:26:16 + │ +26 │ let f: ||S has key = || s; + │ ^^^^^^^^^^^ + +error: function types cannot have `key` ability + ┌─ tests/checking-lang-v2.2/lambda/with_key.move:38:17 + │ +38 │ let f2: || u64 has copy + key = || 2; + │ ^^^^^^^^^^^^^^^^^^^^^ + +error: function types cannot have `key` ability + ┌─ tests/checking-lang-v2.2/lambda/with_key.move:39:17 + │ +39 │ let f3: || u64 has copy + key = || 3; + │ ^^^^^^^^^^^^^^^^^^^^^ diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/with_key.move b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/with_key.move new file mode 100644 index 00000000000..e1e1b1407dd --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/lambda/with_key.move @@ -0,0 +1,43 @@ +module 0xc0ffee::m { + fun caller(f: ||u64 has key): u64 { + f() + } + + public fun test1(): u64 { + let f: ||u64 has key = || 1; + f() + } + + public fun test2(): u64 { + let f: ||u64 has key = || 1; + caller(f) + } + + struct S has key { + i: u64, + } + + fun apply(f: ||S has key): S { + f() + } + + public fun test3(): S { + let s = S { i: 1 }; + let f: ||S has key = || s; + apply(f) + } +} + +module 0xc0ffee::n { + fun wrap(x: T, y: T, z: T): vector { + vector[x, y, z] + } + + public fun test(): vector<||u64 has copy> { + let f1: || u64 has copy = || 1; + let f2: || u64 has copy + key = || 2; + let f3: || u64 has copy + key = || 3; + let v: vector<||u64 has copy> = wrap<||u64 has copy>(f2, f1, f3); + v + } +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/capture_key.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/capture_key.exp new file mode 100644 index 00000000000..015fe18c442 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/capture_key.exp @@ -0,0 +1,23 @@ + +============ disassembled file-format ================== +// Move bytecode v8 +module c0ffee.m { +struct S has key { + i: u64 +} + +public test(): S /* def_idx: 0 */ { +B0: + 0: LdU64(1) + 1: Pack[0](S) + 2: PackClosure#1 __lambda__1__test(S): S + 3: CallClosure(||S) + 4: Ret +} +__lambda__1__test(s: S): S /* def_idx: 1 */ { +B0: + 0: MoveLoc[0](s: S) + 1: Ret +} +} +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/capture_key.move b/third_party/move/move-compiler-v2/tests/file-format-generator/capture_key.move new file mode 100644 index 00000000000..fbebdb6d0a3 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/capture_key.move @@ -0,0 +1,11 @@ +module 0xc0ffee::m { + struct S has key { + i: u64, + } + + public fun test(): S { + let s = S { i: 1 }; + let f = || s; + f() + } +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/capture_key.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/capture_key.opt.exp new file mode 100644 index 00000000000..015fe18c442 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/capture_key.opt.exp @@ -0,0 +1,23 @@ + +============ disassembled file-format ================== +// Move bytecode v8 +module c0ffee.m { +struct S has key { + i: u64 +} + +public test(): S /* def_idx: 0 */ { +B0: + 0: LdU64(1) + 1: Pack[0](S) + 2: PackClosure#1 __lambda__1__test(S): S + 3: CallClosure(||S) + 4: Ret +} +__lambda__1__test(s: S): S /* def_idx: 1 */ { +B0: + 0: MoveLoc[0](s: S) + 1: Ret +} +} +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-model/src/builder/exp_builder.rs b/third_party/move/move-model/src/builder/exp_builder.rs index 79d28be7719..7d6e8c21d96 100644 --- a/third_party/move/move-model/src/builder/exp_builder.rs +++ b/third_party/move/move-model/src/builder/exp_builder.rs @@ -1069,11 +1069,11 @@ impl ExpTranslator<'_, '_, '_> { vec![self.translate_function_param_or_return_type(result)] }, }; - Type::function( - Type::tuple(arg_tys), - Type::tuple(result_tys), - self.parent.translate_abilities(abilities), - ) + let ability_set = self.parent.translate_abilities(abilities); + if ability_set.has_key() { + self.error(loc, "function types cannot have `key` ability"); + } + Type::function(Type::tuple(arg_tys), Type::tuple(result_tys), ability_set) }, Unit => Type::Tuple(vec![]), Multiple(vst) => { From aab60c8702f1fe4cfe0bec7377df57d64e0f2960 Mon Sep 17 00:00:00 2001 From: Vineeth Kashyap Date: Tue, 8 Jul 2025 14:03:48 -0400 Subject: [PATCH 035/260] [compiler-v2] Add a test comaring resolved and unresolved function values (#16988) Downstreamed-from: d9b02abc6a1ed0516445c6f83fd41dd17479a586 --- .../closures/closure_equality.exp | 1 + .../closures/closure_equality.move | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closure_equality.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closure_equality.move diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closure_equality.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closure_equality.exp new file mode 100644 index 00000000000..fc5a4436b29 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closure_equality.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closure_equality.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closure_equality.move new file mode 100644 index 00000000000..745d09065c6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/closure_equality.move @@ -0,0 +1,31 @@ +//# publish +module 0xc0ffee::m { + public fun identity(t: T): T { + t + } + + struct Wrapper has copy, key, drop { + value: T, + } + + public fun init(s: &signer) { + let f: |u64|u64 has copy + store + drop = identity; + move_to(s, Wrapper { value: f }); + } + + public fun compare(other: |u64|u64 has copy + store + drop, s: &signer): bool { + let this = Wrapper<|u64|u64 has copy + store + drop>[std::signer::address_of(s)].value; + this == other + } +} + +//# run 0xc0ffee::m::init --signers 0xc0ffee + +//# run --signers 0xc0ffee +script { + fun main(s: &signer) { + // compare resolved and unresolved closure + let result = 0xc0ffee::m::compare(0xc0ffee::m::identity, s); + assert!(result); + } +} From 511265172648afc26b61013ca068a395554f38ee Mon Sep 17 00:00:00 2001 From: Vineeth Kashyap Date: Tue, 8 Jul 2025 17:36:33 -0400 Subject: [PATCH 036/260] [vm] [bytecode-verifier] Function type limit fix (#17028) Downstreamed-from: b4ea1413ceef913f75511a635734f3b493d06cb7 --- .../move/move-bytecode-verifier/src/limits.rs | 1 + .../closures/very_large_1.exp | 10 ++++ .../closures/very_large_1.move | 46 +++++++++++++++++++ .../closures/very_large_2.exp | 10 ++++ .../closures/very_large_2.move | 21 +++++++++ 5 files changed, 88 insertions(+) create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_1.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_1.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_2.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_2.move diff --git a/third_party/move/move-bytecode-verifier/src/limits.rs b/third_party/move/move-bytecode-verifier/src/limits.rs index 54542e16b18..8e85f881919 100644 --- a/third_party/move/move-bytecode-verifier/src/limits.rs +++ b/third_party/move/move-bytecode-verifier/src/limits.rs @@ -164,6 +164,7 @@ impl<'a> LimitsVerifier<'a> { return Err(PartialVMError::new(StatusCode::TOO_MANY_PARAMETERS)); } } + type_size += 1; }, SignatureToken::Bool | SignatureToken::U8 diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_1.exp new file mode 100644 index 00000000000..41fb81c8821 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_1.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-46: +Error: Unable to publish module '000000000000000000000000000000000000000000000000000000000000cafe::Module0'. Got VMError: { + major_status: TOO_MANY_TYPE_NODES, + sub_status: None, + location: 0xcafe::Module0, + indices: [], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_1.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_1.move new file mode 100644 index 00000000000..e8012e5bb1b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_1.move @@ -0,0 +1,46 @@ +//# publish +module 0xCAFE::Module0 { + public fun function32() { + *( &mut ({ + let var65: | + (| (| | has copy+drop) | (| (| bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop) | (u8 ) has copy+drop ) has copy+drop), + (| (| | has copy+drop) | (| (| bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop) | (u8 ) has copy+drop ) has copy+drop), + (| (| | has copy+drop) | (| (| bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop) | (u8 ) has copy+drop ) has copy+drop) + | + ( + | + (| bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop), + (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), + (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), + | has copy+drop + ) + has copy+drop + = | + var59: | (| | has copy+drop) | (| (| bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop) | (u8 ) has copy+drop ) has copy+drop, + var60: | (| | has copy+drop) | (| (| bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop) | (u8 ) has copy+drop ) has copy+drop, + var61: | (| | has copy+drop) | (| (| bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop) | (u8 ) has copy+drop ) has copy+drop, + | + { /* _block46 */ + | + var62: | bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop, + var63: | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop, + var64: | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop, + | + {} + }; + var65 + })) = | + var66: | (| | has copy+drop) | (| (| bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop) | (u8 ) has copy+drop ) has copy+drop, + var67: | (| | has copy+drop) | (| (| bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop) | (u8 ) has copy+drop ) has copy+drop, + var68: | (| | has copy+drop) | (| (| bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop), (| (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop) | (u8 ) has copy+drop ) has copy+drop, + | + { /* _block48 */ + | + var69: | bool, bool, u8, bool, u8, u8, (| (| | has copy+drop), (| | has copy+drop), (| | has copy+drop) | (| | has copy+drop ) has copy+drop), (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (u8 ) has copy+drop, + var70: | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop, + var71: | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop) | (| (| | has copy+drop) | (| | has copy+drop ) has copy+drop ) has copy+drop, + | + {} + }; + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_2.exp new file mode 100644 index 00000000000..b1b5875d0a9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_2.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-21: +Error: Unable to publish module '000000000000000000000000000000000000000000000000000000000000cafe::Module0'. Got VMError: { + major_status: TOO_MANY_TYPE_NODES, + sub_status: None, + location: 0xcafe::Module0, + indices: [], + offsets: [], +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_2.move b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_2.move new file mode 100644 index 00000000000..310b9181542 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/no-v1-comparison/closures/very_large_2.move @@ -0,0 +1,21 @@ +//# publish +module 0xCAFE::Module0 { + public fun f1( + var1: &( + | + (| + &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, + | has drop) + | has drop), + ) { } + public fun f2() { + f1(&( + | + var2: | + &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, &u8, + | has drop + | + { } + )); + } +} From c354a3d84d47c9ae7a1daa19f838f4db4a756014 Mon Sep 17 00:00:00 2001 From: Vineeth Kashyap Date: Tue, 8 Jul 2025 18:37:08 -0400 Subject: [PATCH 037/260] [compiler-v2] Fix a bug when we both pass a variable and its reference as arguments (#17026) Downstreamed-from: ce32876a3aedc65897c840cbd481c3b2d8d0ee59 --- .../src/pipeline/ability_processor.rs | 18 ++++------------ .../src/pipeline/reference_safety/mod.rs | 5 +++++ .../tests/file-format-generator/bug_17025.exp | 21 +++++++++++++++++++ .../file-format-generator/bug_17025.move | 6 ++++++ .../file-format-generator/bug_17025.opt.exp | 21 +++++++++++++++++++ 5 files changed, 57 insertions(+), 14 deletions(-) create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/bug_17025.exp create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/bug_17025.move create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/bug_17025.opt.exp diff --git a/third_party/move/move-compiler-v2/src/pipeline/ability_processor.rs b/third_party/move/move-compiler-v2/src/pipeline/ability_processor.rs index bd446bbe1e3..a3bab1bef24 100644 --- a/third_party/move/move-compiler-v2/src/pipeline/ability_processor.rs +++ b/third_party/move/move-compiler-v2/src/pipeline/ability_processor.rs @@ -162,9 +162,8 @@ impl TransferFunctions for CopyDropAnalysis<'_> { let lifetime = self.lifetime.get_info_at(offset); let exit_state = self.exit_state.get_state_at(offset); // Only temps which are used after or borrowed need a copy - let temp_needs_copy = |temp, instr| { - live_var.is_temp_used_after(temp, instr) || lifetime.borrow_kind_before(*temp).is_some() - }; + let temp_needs_copy = + |temp, instr| live_var.is_temp_used_after(temp, instr) || lifetime.is_borrowed(*temp); // References always need to be dropped to satisfy bytecode verifier borrow analysis, other values // only if this execution path can return. let temp_needs_drop = |temp: &TempIndex| { @@ -366,12 +365,7 @@ impl Transformer<'_> { // Only need to perform the actual copy if src is borrowed, as this // information cannot be determined from live-var analysis in later // phases. - if self - .lifetime - .get_info_at(code_offset) - .borrow_kind_after(*src) - .is_some() - { + if self.lifetime.get_info_at(code_offset).is_borrowed(*src) { let ty = self.builder.get_local_type(*src); let temp = self.builder.new_temp(ty); self.builder.emit(Assign(id, temp, *src, AssignKind::Copy)); @@ -445,11 +439,7 @@ impl Transformer<'_> { } for temp in copy_drop_at.needs_drop.iter() { // Give a better error message if we know its borrowed - let is_borrowed = self - .lifetime - .get_info_at(code_offset) - .borrow_kind_after(*temp) - .is_some(); + let is_borrowed = self.lifetime.get_info_at(code_offset).is_borrowed(*temp); self.check_drop(bytecode.get_attr_id(), *temp, || { ( if is_borrowed { diff --git a/third_party/move/move-compiler-v2/src/pipeline/reference_safety/mod.rs b/third_party/move/move-compiler-v2/src/pipeline/reference_safety/mod.rs index 361bc44c17b..efada5b51d0 100644 --- a/third_party/move/move-compiler-v2/src/pipeline/reference_safety/mod.rs +++ b/third_party/move/move-compiler-v2/src/pipeline/reference_safety/mod.rs @@ -56,6 +56,11 @@ impl LifetimeInfoAtCodeOffset { pub fn borrow_kind_after(&self, temp: TempIndex) -> Option { self.after.borrow_kind(temp) } + + /// Returns true if the given temporary is borrowed before or after the program point. + pub fn is_borrowed(&self, temp: TempIndex) -> bool { + self.borrow_kind_before(temp).is_some() || self.borrow_kind_after(temp).is_some() + } } /// A trait to be implemented by reference safety processors diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17025.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17025.exp new file mode 100644 index 00000000000..226e334c4f7 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17025.exp @@ -0,0 +1,21 @@ + +============ disassembled file-format ================== +// Move bytecode v8 +module cafe.Module0 { + + +public f1(_a: &bool, _b: bool) /* def_idx: 0 */ { +B0: + 0: MoveLoc[0](_a: &bool) + 1: Pop + 2: Ret +} +public f2(x: bool) /* def_idx: 1 */ { +B0: + 0: ImmBorrowLoc[0](x: bool) + 1: CopyLoc[0](x: bool) + 2: Call f1(&bool, bool) + 3: Ret +} +} +============ bytecode verification succeeded ======== diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17025.move b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17025.move new file mode 100644 index 00000000000..bcd1e495470 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17025.move @@ -0,0 +1,6 @@ +module 0xCAFE::Module0 { + public fun f1(_a: &bool, _b: bool) {} + public fun f2(x: bool) { + f1(&x, x); + } +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17025.opt.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17025.opt.exp new file mode 100644 index 00000000000..226e334c4f7 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/bug_17025.opt.exp @@ -0,0 +1,21 @@ + +============ disassembled file-format ================== +// Move bytecode v8 +module cafe.Module0 { + + +public f1(_a: &bool, _b: bool) /* def_idx: 0 */ { +B0: + 0: MoveLoc[0](_a: &bool) + 1: Pop + 2: Ret +} +public f2(x: bool) /* def_idx: 1 */ { +B0: + 0: ImmBorrowLoc[0](x: bool) + 1: CopyLoc[0](x: bool) + 2: Call f1(&bool, bool) + 3: Ret +} +} +============ bytecode verification succeeded ======== From 0eb0b4db6614e64827f582a50c39c63a0dc354dd Mon Sep 17 00:00:00 2001 From: wqfish <1171005+wqfish@users.noreply.github.com> Date: Tue, 8 Jul 2025 16:18:54 -0700 Subject: [PATCH 038/260] Upgrade lru to latest version The old versions we are currently using do not implement `Clone`, which makes it inconvenient to use in tests. Downstreamed-from: be5609ee996d91b53e71137d83b79e16b2ba2641 --- Cargo.lock | 42 ++++++------ Cargo.toml | 2 +- .../aptos-validator-interface/src/lib.rs | 3 +- consensus/src/round_manager.rs | 9 ++- crates/aptos-faucet/core/Cargo.toml | 2 +- storage/aptosdb/src/lru_node_cache.rs | 4 +- storage/aptosdb/src/state_merkle_db.rs | 63 ++++++++--------- storage/aptosdb/src/state_store/hot_state.rs | 67 ++++++++++++++++++- .../state_merkle_batch_committer.rs | 6 +- .../src/storage/verified_module_cache.rs | 3 +- types/src/vm/module_metadata.rs | 4 +- 11 files changed, 139 insertions(+), 66 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b69bc3a03d..30bcc9b754e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -873,7 +873,7 @@ dependencies = [ "futures-channel", "hex", "itertools 0.13.0", - "lru 0.7.8", + "lru", "maplit", "mini-moka", "mirai-annotations", @@ -1132,7 +1132,7 @@ dependencies = [ "hex", "indicatif 0.15.0", "itertools 0.13.0", - "lru 0.7.8", + "lru", "move-core-types", "once_cell", "ouroboros", @@ -1674,7 +1674,7 @@ dependencies = [ "hex", "ipnet", "iprange", - "lru 0.9.0", + "lru", "once_cell", "poem", "poem-openapi", @@ -4542,7 +4542,7 @@ dependencies = [ "hex", "itertools 0.13.0", "jsonwebtoken 8.3.0", - "lru 0.7.8", + "lru", "move-binary-format", "move-core-types", "move-model", @@ -4596,7 +4596,7 @@ dependencies = [ "async-recursion", "async-trait", "bcs 0.1.4", - "lru 0.7.8", + "lru", "move-core-types", "tokio", ] @@ -8900,6 +8900,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "foreign-types" version = "0.3.2" @@ -9709,7 +9715,12 @@ dependencies = [ name = "hashbrown" version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] [[package]] name = "hashers" @@ -11372,20 +11383,11 @@ dependencies = [ [[package]] name = "lru" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999beba7b6e8345721bd280141ed958096a2e4abdf74f67ff4ce49b4b54e47a" -dependencies = [ - "hashbrown 0.12.3", -] - -[[package]] -name = "lru" -version = "0.9.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e7d46de488603ffdd5f30afbc64fbba2378214a2c3a2fb83abf3d33126df17" +checksum = "86ea4e65087ff52f3862caff188d489f1fab49a0cb09e01b2e3f1a617b10aaed" dependencies = [ - "hashbrown 0.13.2", + "hashbrown 0.15.3", ] [[package]] @@ -12576,7 +12578,7 @@ dependencies = [ "hex", "lazy_static", "legacy-move-compiler", - "lru 0.7.8", + "lru", "move-binary-format", "move-bytecode-verifier", "move-core-types", @@ -18755,7 +18757,7 @@ dependencies = [ "errno", "js-sys", "libc", - "rustix 0.37.27", + "rustix 0.38.28", "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", "winapi 0.3.9", diff --git a/Cargo.toml b/Cargo.toml index d1735343efe..ccec28f71e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -646,7 +646,7 @@ libfuzzer-sys = "0.4.6" libsecp256k1 = "0.7.0" libtest-mimic = "0.5.2" log = "0.4.17" -lru = "0.7.5" +lru = "0.16.0" lz4 = "1.28.0" maplit = "1.0.2" merlin = "3" diff --git a/aptos-move/aptos-validator-interface/src/lib.rs b/aptos-move/aptos-validator-interface/src/lib.rs index 9bd42b1a7ea..0cd03687065 100644 --- a/aptos-move/aptos-validator-interface/src/lib.rs +++ b/aptos-move/aptos-validator-interface/src/lib.rs @@ -20,6 +20,7 @@ use lru::LruCache; use move_core_types::language_storage::ModuleId; use std::{ collections::HashMap, + num::NonZeroUsize, sync::{Arc, Mutex}, }; use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender}; @@ -101,7 +102,7 @@ async fn handler_thread( std::sync::mpsc::Sender>>, )>, ) { - const M: usize = 1024 * 1024; + const M: NonZeroUsize = NonZeroUsize::new(1024 * 1024).unwrap(); let cache = Arc::new(Mutex::new(LruCache::< (StateKey, Version), Option, diff --git a/consensus/src/round_manager.rs b/consensus/src/round_manager.rs index 6ad77675b82..50d17513f46 100644 --- a/consensus/src/round_manager.rs +++ b/consensus/src/round_manager.rs @@ -76,7 +76,10 @@ use fail::fail_point; use futures::{channel::oneshot, stream::FuturesUnordered, Future, FutureExt, StreamExt}; use lru::LruCache; use serde::Serialize; -use std::{mem::Discriminant, pin::Pin, sync::Arc, time::Duration}; +use std::{ + collections::BTreeMap, mem::Discriminant, num::NonZeroUsize, ops::Add, pin::Pin, sync::Arc, + time::Duration, +}; use tokio::{ sync::oneshot as TokioOneshot, time::{sleep, Instant}, @@ -319,7 +322,9 @@ impl RoundManager { jwk_consensus_config, fast_rand_config, pending_order_votes: PendingOrderVotes::new(), - blocks_with_broadcasted_fast_shares: LruCache::new(5), + blocks_with_broadcasted_fast_shares: LruCache::new( + NonZeroUsize::new(5).expect("LRU capacity should be non-zero."), + ), futures: FuturesUnordered::new(), proposal_status_tracker, } diff --git a/crates/aptos-faucet/core/Cargo.toml b/crates/aptos-faucet/core/Cargo.toml index a078e9c95de..a921c24750b 100644 --- a/crates/aptos-faucet/core/Cargo.toml +++ b/crates/aptos-faucet/core/Cargo.toml @@ -29,7 +29,7 @@ futures = { workspace = true } hex = { workspace = true } ipnet = { workspace = true } iprange = "0.6.7" -lru = "0.9.0" +lru = { workspace = true } once_cell = { workspace = true } poem = { workspace = true } poem-openapi = { workspace = true } diff --git a/storage/aptosdb/src/lru_node_cache.rs b/storage/aptosdb/src/lru_node_cache.rs index 7ec7e4f4ac9..eb50136b4a4 100644 --- a/storage/aptosdb/src/lru_node_cache.rs +++ b/storage/aptosdb/src/lru_node_cache.rs @@ -6,7 +6,7 @@ use aptos_infallible::Mutex; use aptos_jellyfish_merkle::node_type::NodeKey; use aptos_types::{nibble::nibble_path::NibblePath, transaction::Version}; use lru::LruCache; -use std::fmt; +use std::{fmt, num::NonZeroUsize}; const NUM_SHARDS: usize = 256; @@ -21,7 +21,7 @@ impl fmt::Debug for LruNodeCache { } impl LruNodeCache { - pub fn new(max_nodes_per_shard: usize) -> Self { + pub fn new(max_nodes_per_shard: NonZeroUsize) -> Self { Self { // `arr!()` doesn't allow a const in place of the integer literal shards: arr_macro::arr![Mutex::new(LruCache::new(max_nodes_per_shard)); 256], diff --git a/storage/aptosdb/src/state_merkle_db.rs b/storage/aptosdb/src/state_merkle_db.rs index bf6b9a17d28..48db2765094 100644 --- a/storage/aptosdb/src/state_merkle_db.rs +++ b/storage/aptosdb/src/state_merkle_db.rs @@ -42,6 +42,7 @@ use arr_macro::arr; use rayon::prelude::*; use std::{ collections::HashMap, + num::NonZeroUsize, path::{Path, PathBuf}, sync::Arc, time::Instant, @@ -62,10 +63,10 @@ pub struct StateMerkleDb { // Stores sharded part of tree nodes. state_merkle_db_shards: [Arc; NUM_STATE_SHARDS], enable_sharding: bool, - enable_cache: bool, // shard_id -> cache. version_caches: HashMap, VersionedNodeCache>, - lru_cache: LruNodeCache, + // `None` means the cache is not enabled. + lru_cache: Option, } impl StateMerkleDb { @@ -73,19 +74,18 @@ impl StateMerkleDb { db_paths: &StorageDirPaths, rocksdb_configs: RocksdbConfigs, readonly: bool, + // TODO(grao): Currently when this value is set to 0 we disable both caches. This is + // hacky, need to revisit. max_nodes_per_lru_cache_shard: usize, ) -> Result { let sharding = rocksdb_configs.enable_storage_sharding; let state_merkle_db_config = rocksdb_configs.state_merkle_db_config; - // TODO(grao): Currently when this value is set to 0 we disable both caches. This is - // hacky, need to revisit. - let enable_cache = max_nodes_per_lru_cache_shard > 0; let mut version_caches = HashMap::with_capacity(NUM_STATE_SHARDS + 1); version_caches.insert(None, VersionedNodeCache::new()); for i in 0..NUM_STATE_SHARDS { version_caches.insert(Some(i as u8), VersionedNodeCache::new()); } - let lru_cache = LruNodeCache::new(max_nodes_per_lru_cache_shard); + let lru_cache = NonZeroUsize::new(max_nodes_per_lru_cache_shard).map(LruNodeCache::new); if !sharding { info!("Sharded state merkle DB is not enabled!"); let state_merkle_db_path = db_paths.default_root_path().join(STATE_MERKLE_DB_NAME); @@ -99,7 +99,6 @@ impl StateMerkleDb { state_merkle_metadata_db: Arc::clone(&db), state_merkle_db_shards: arr![Arc::clone(&db); 16], enable_sharding: false, - enable_cache, version_caches, lru_cache, }); @@ -109,7 +108,6 @@ impl StateMerkleDb { db_paths, state_merkle_db_config, readonly, - enable_cache, version_caches, lru_cache, ) @@ -517,15 +515,15 @@ impl StateMerkleDb { } pub(crate) fn cache_enabled(&self) -> bool { - self.enable_cache + self.lru_cache.is_some() } pub(crate) fn version_caches(&self) -> &HashMap, VersionedNodeCache> { &self.version_caches } - pub(crate) fn lru_cache(&self) -> &LruNodeCache { - &self.lru_cache + pub(crate) fn lru_cache(&self) -> Option<&LruNodeCache> { + self.lru_cache.as_ref() } pub(crate) fn write_pruner_progress( @@ -561,9 +559,8 @@ impl StateMerkleDb { db_paths: &StorageDirPaths, state_merkle_db_config: RocksdbConfig, readonly: bool, - enable_cache: bool, version_caches: HashMap, VersionedNodeCache>, - lru_cache: LruNodeCache, + lru_cache: Option, ) -> Result { let state_merkle_metadata_db_path = Self::metadata_db_path( db_paths.state_merkle_db_metadata_root_path(), @@ -605,7 +602,6 @@ impl StateMerkleDb { state_merkle_metadata_db, state_merkle_db_shards, enable_sharding: true, - enable_cache, version_caches, lru_cache, }; @@ -788,7 +784,7 @@ impl TreeReader for StateMerkleDb { .observe(start_time.elapsed().as_secs_f64()); return Ok(node_opt); } - let node_opt = if let Some(node_cache) = self + if let Some(node_cache) = self .version_caches .get(&node_key.get_shard_id()) .unwrap() @@ -798,24 +794,29 @@ impl TreeReader for StateMerkleDb { NODE_CACHE_SECONDS .with_label_values(&[tag, "versioned_cache_hit"]) .observe(start_time.elapsed().as_secs_f64()); - node - } else if let Some(node) = self.lru_cache.get(node_key) { - NODE_CACHE_SECONDS - .with_label_values(&[tag, "lru_cache_hit"]) - .observe(start_time.elapsed().as_secs_f64()); - Some(node) - } else { - let node_opt = self - .db_by_key(node_key) - .get::(node_key)?; + return Ok(node); + } + + if let Some(lru_cache) = &self.lru_cache { + if let Some(node) = lru_cache.get(node_key) { + NODE_CACHE_SECONDS + .with_label_values(&[tag, "lru_cache_hit"]) + .observe(start_time.elapsed().as_secs_f64()); + return Ok(Some(node)); + } + } + + let node_opt = self + .db_by_key(node_key) + .get::(node_key)?; + if let Some(lru_cache) = &self.lru_cache { if let Some(node) = &node_opt { - self.lru_cache.put(node_key.clone(), node.clone()); + lru_cache.put(node_key.clone(), node.clone()); } - NODE_CACHE_SECONDS - .with_label_values(&[tag, "cache_miss"]) - .observe(start_time.elapsed().as_secs_f64()); - node_opt - }; + } + NODE_CACHE_SECONDS + .with_label_values(&[tag, "cache_miss"]) + .observe(start_time.elapsed().as_secs_f64()); Ok(node_opt) } diff --git a/storage/aptosdb/src/state_store/hot_state.rs b/storage/aptosdb/src/state_store/hot_state.rs index bb100445662..879aed8e89d 100644 --- a/storage/aptosdb/src/state_store/hot_state.rs +++ b/storage/aptosdb/src/state_store/hot_state.rs @@ -274,6 +274,71 @@ impl Committer { fn should_evict(&self) -> bool { self.base.inner.len() > self.base.max_items - || self.total_key_bytes + self.total_value_bytes > self.base.max_bytes + } + + #[cfg(test)] + fn collect_all(&self) -> Vec<(K, V)> { + assert_eq!(self.head.is_some(), self.tail.is_some()); + + let mut keys = Vec::new(); + let mut values = Vec::new(); + + let mut current_key = self.head.clone(); + while let Some(key) = current_key { + let entry = self.base.inner.get(&key).unwrap(); + assert_eq!(entry.lru.prev, keys.last().cloned()); + keys.push(key); + values.push(entry.data.clone()); + current_key = entry.lru.next.clone(); + } + itertools::zip_eq(keys, values).collect() + } +} + +#[cfg(test)] +mod tests { + use super::{HotStateBase, LRUUpdater}; + use lru::LruCache; + use proptest::{collection::vec, option, prelude::*}; + use std::{num::NonZeroUsize, sync::Arc}; + + const MAX_BYTES: usize = 10000; + const MAX_SINGLE_VALUE_BYTES: usize = 100; + + proptest! { + #[test] + fn test_hot_state_lru( + max_items in 1..10usize, + updates in vec((0..20u64, option::weighted(0.8, 0..1000u64)), 1..50), + ) { + let base = Arc::new(HotStateBase::new_empty( + max_items, + MAX_BYTES, + MAX_SINGLE_VALUE_BYTES, + )); + let mut head = None; + let mut tail = None; + + let mut updater = LRUUpdater::new(base, &mut head, &mut tail); + let mut cache = LruCache::new(NonZeroUsize::new(max_items).unwrap()); + + for (key, value_opt) in updates { + match value_opt { + Some(value) => { + updater.insert(key, value); + cache.put(key, value); + } + None => { + updater.delete(&key); + cache.pop(&key); + } + } + updater.evict(); + + prop_assert_eq!(updater.base.inner.len(), cache.len()); + let items = updater.collect_all(); + prop_assert_eq!(items, cache.iter().map(|(k, v)| (*k, *v)).collect::>()); + } + } } } diff --git a/storage/aptosdb/src/state_store/state_merkle_batch_committer.rs b/storage/aptosdb/src/state_store/state_merkle_batch_committer.rs index 6050253f51d..99b9781a061 100644 --- a/storage/aptosdb/src/state_store/state_merkle_batch_committer.rs +++ b/storage/aptosdb/src/state_store/state_merkle_batch_committer.rs @@ -65,14 +65,12 @@ impl StateMerkleBatchCommitter { .state_merkle_db .commit(current_version, top_levels_batch, batches_for_shards) .expect("State merkle nodes commit failed."); - if self.state_db.state_merkle_db.cache_enabled() { + if let Some(lru_cache) = self.state_db.state_merkle_db.lru_cache() { self.state_db .state_merkle_db .version_caches() .iter() - .for_each(|(_, cache)| { - cache.maybe_evict_version(self.state_db.state_merkle_db.lru_cache()) - }); + .for_each(|(_, cache)| cache.maybe_evict_version(lru_cache)); } info!( diff --git a/third_party/move/move-vm/runtime/src/storage/verified_module_cache.rs b/third_party/move/move-vm/runtime/src/storage/verified_module_cache.rs index 09d64b18990..c8cd2bad351 100644 --- a/third_party/move/move-vm/runtime/src/storage/verified_module_cache.rs +++ b/third_party/move/move-vm/runtime/src/storage/verified_module_cache.rs @@ -3,6 +3,7 @@ use lazy_static::lazy_static; use parking_lot::Mutex; +use std::num::NonZeroUsize; /// Cache key for verified modules. /// @@ -27,7 +28,7 @@ const fn cache_active() -> bool { impl VerifiedModuleCache { /// Maximum size of the cache. When modules are cached, they can skip re-verification. - const VERIFIED_CACHE_SIZE: usize = 100_000; + const VERIFIED_CACHE_SIZE: NonZeroUsize = NonZeroUsize::new(100_000).unwrap(); /// Returns new empty verified module cache. pub(crate) fn empty() -> Self { diff --git a/types/src/vm/module_metadata.rs b/types/src/vm/module_metadata.rs index 8bf245a1f40..32fafc65299 100644 --- a/types/src/vm/module_metadata.rs +++ b/types/src/vm/module_metadata.rs @@ -27,7 +27,7 @@ use move_model::{ model::StructEnv, }; use serde::{Deserialize, Serialize}; -use std::{cell::RefCell, collections::BTreeMap, env, str::FromStr, sync::Arc}; +use std::{cell::RefCell, collections::BTreeMap, env, num::NonZeroUsize, str::FromStr, sync::Arc}; use thiserror::Error; pub mod prelude { @@ -187,7 +187,7 @@ impl KnownAttribute { } } -const METADATA_CACHE_SIZE: usize = 1024; +const METADATA_CACHE_SIZE: NonZeroUsize = NonZeroUsize::new(1024).unwrap(); thread_local! { static V1_METADATA_CACHE: RefCell, Option>>> = RefCell::new(LruCache::new(METADATA_CACHE_SIZE)); From d71e008c1ccedf5c3a3e8008b478af3ae1150eb7 Mon Sep 17 00:00:00 2001 From: "Andrea Cappa (zi0Black)" <13380579+zi0Black@users.noreply.github.com> Date: Thu, 10 Jul 2025 20:39:07 +0200 Subject: [PATCH 039/260] Stack usage verifier early exit on error (#17045) * Handle the unlikely case of overall_push overflow * fmt Downstreamed-from: 6c9d41c9c246e8a8dda56c91838f2d2d17959f43 --- .../move/move-bytecode-verifier/src/stack_usage_verifier.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/third_party/move/move-bytecode-verifier/src/stack_usage_verifier.rs b/third_party/move/move-bytecode-verifier/src/stack_usage_verifier.rs index c2735f91bc6..721e1e97a22 100644 --- a/third_party/move/move-bytecode-verifier/src/stack_usage_verifier.rs +++ b/third_party/move/move-bytecode-verifier/src/stack_usage_verifier.rs @@ -59,6 +59,9 @@ impl<'a> StackUsageVerifier<'a> { let (num_pops, num_pushes) = self.instruction_effect(&code[i as usize])?; if let Some(new_pushes) = u64::checked_add(overall_push, num_pushes) { overall_push = new_pushes + } else { + return Err(PartialVMError::new(StatusCode::VALUE_STACK_PUSH_OVERFLOW) + .at_code_offset(self.current_function(), block_start)); }; // Check that the accumulated pushes does not exceed a pre-defined max size From a204fb488dc18f435b624379c5769e5d3c36fec0 Mon Sep 17 00:00:00 2001 From: George Mitenkov Date: Thu, 10 Jul 2025 22:37:08 +0100 Subject: [PATCH 040/260] [api] Addressing function value todos (#17047) Downstreamed-from: dee41276c97f3e1d373b3ee5a687a1f46f4923bb --- .../tools/move-resource-viewer/src/lib.rs | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/third_party/move/tools/move-resource-viewer/src/lib.rs b/third_party/move/tools/move-resource-viewer/src/lib.rs index 059574f85f9..35e4f41aac0 100644 --- a/third_party/move/tools/move-resource-viewer/src/lib.rs +++ b/third_party/move/tools/move-resource-viewer/src/lib.rs @@ -24,7 +24,7 @@ use move_core_types::{ account_address::AccountAddress, function::{ClosureMask, MoveClosure}, identifier::{IdentStr, Identifier}, - language_storage::{ModuleId, StructTag, TypeTag}, + language_storage::{FunctionParamOrReturnTag, ModuleId, StructTag, TypeTag}, transaction_argument::{convert_txn_args, TransactionArgument}, u256, value::{MoveStruct, MoveTypeLayout, MoveValue}, @@ -487,9 +487,28 @@ impl MoveValueAnnotator { TypeTag::U256 => FatType::U256, TypeTag::U128 => FatType::U128, TypeTag::Vector(ty) => FatType::Vector(Box::new(self.resolve_type_impl(ty, limit)?)), - TypeTag::Function(..) => { - // TODO(#15664) implement functions for fat types - bail!("TODO: support functions for fat types") + TypeTag::Function(function_tag) => { + let mut convert_tags = |tags: &[FunctionParamOrReturnTag]| { + tags.iter() + .map(|t| { + use FunctionParamOrReturnTag::*; + Ok(match t { + Reference(t) => { + FatType::Reference(Box::new(self.resolve_type_impl(t, limit)?)) + }, + MutableReference(t) => FatType::MutableReference(Box::new( + self.resolve_type_impl(t, limit)?, + )), + Value(t) => self.resolve_type_impl(t, limit)?, + }) + }) + .collect::>>() + }; + FatType::Function(Box::new(FatFunctionType { + args: convert_tags(&function_tag.args)?, + results: convert_tags(&function_tag.results)?, + abilities: function_tag.abilities, + })) }, }) } From 1f5d92bcbfb21c1a9dcaa7c12ea80a99a01056eb Mon Sep 17 00:00:00 2001 From: Jun Xu <5827713+junxzm1990@users.noreply.github.com> Date: Fri, 11 Jul 2025 14:41:21 -0600 Subject: [PATCH 041/260] [decompiler]: fix issues in control flow optimizations (#17021) Downstreamed-from: ff5d0fda806d51501aebeab66af97d9160d9283c --- .../tests/abort_example.exp | 56 ++- .../tests/bit_vector_loop_example.exp | 331 +++++++++++------- .../tests/conditionals.exp | 187 +++++++--- .../ast-generator-tests/tests/loops.exp | 316 +++++++++++------ .../ast-generator-tests/tests/match.exp | 90 +++-- .../move/move-model/bytecode/src/astifier.rs | 84 +---- .../move/move-model/src/exp_builder.rs | 22 -- .../move-decompiler/tests/bit_vector.exp | 74 ++-- .../tools/move-decompiler/tests/cfg_opt.exp | 134 +++++++ .../tools/move-decompiler/tests/cfg_opt.move | 56 +++ .../tools/move-decompiler/tests/closure.exp | 9 +- .../move-decompiler/tests/fixed_point32.exp | 36 +- .../move-decompiler/tests/nested_loops.exp | 266 +++++++++----- .../move-decompiler/tests/noexit_loops.exp | 9 +- .../tools/move-decompiler/tests/option.exp | 36 +- .../move-decompiler/tests/simple_map.exp | 62 +++- .../tools/move-decompiler/tests/string.exp | 45 ++- .../tools/move-decompiler/tests/vector.exp | 107 ++++-- 18 files changed, 1300 insertions(+), 620 deletions(-) create mode 100644 third_party/move/tools/move-decompiler/tests/cfg_opt.exp create mode 100644 third_party/move/tools/move-decompiler/tests/cfg_opt.move diff --git a/third_party/move/move-model/bytecode/ast-generator-tests/tests/abort_example.exp b/third_party/move/move-model/bytecode/ast-generator-tests/tests/abort_example.exp index bd030fe1556..2ce16ba8b1c 100644 --- a/third_party/move/move-model/bytecode/ast-generator-tests/tests/abort_example.exp +++ b/third_party/move/move-model/bytecode/ast-generator-tests/tests/abort_example.exp @@ -83,15 +83,18 @@ loop { _t8: u64 = 0; _t1: u64 = _t8; loop { - _t9: u64 = _t1; - _t10: u64 = length; - _t11: bool = Lt(_t9, _t10); - if (Not(_t11)) break; - _t12: u64 = _t1; - _t13: u64 = 1; - _t14: u64 = Add(_t12, _t13); - _t1: u64 = _t14; - continue + loop { + _t9: u64 = _t1; + _t10: u64 = length; + _t11: bool = Lt(_t9, _t10); + if (Not(_t11)) break[1]; + _t12: u64 = _t1; + _t13: u64 = 1; + _t14: u64 = Add(_t12, _t13); + _t1: u64 = _t14; + continue + }; + break }; _t15: u64 = _t1; return _t15 @@ -107,9 +110,12 @@ loop { }; _t1: u64 = 0; loop { - if (Not(Lt(_t1, length))) break; - _t1: u64 = Add(_t1, 1); - continue + loop { + if (Not(Lt(_t1, length))) break[1]; + _t1: u64 = Add(_t1, 1); + continue + }; + break }; return _t1 @@ -118,9 +124,12 @@ if (Not(Gt(length, 0))) Abort(1); if (Not(Lt(length, 100))) Abort(2); _t1: u64 = 0; loop { - if (Not(Lt(_t1, length))) break; - _t1: u64 = Add(_t1, 1); - continue + loop { + if (Not(Lt(_t1, length))) break[1]; + _t1: u64 = Add(_t1, 1); + continue + }; + break }; return _t1 @@ -131,9 +140,12 @@ return _t1 if (Not(Lt(length, 100))) Abort(2); _t1: u64 = 0; loop { - if (Not(Lt(_t1, length))) break; - _t1: u64 = Add(_t1, 1); - continue + loop { + if (Not(Lt(_t1, length))) break[1]; + _t1: u64 = Add(_t1, 1); + continue + }; + break }; return _t1 } @@ -145,7 +157,13 @@ module 0x815::m { if (!(length > 0)) abort 1; if (!(length < 100)) abort 2; _t1 = 0; - while (_t1 < length) _t1 = _t1 + 1; + 'l0: loop { + loop { + if (!(_t1 < length)) break 'l0; + _t1 = _t1 + 1 + }; + break + }; _t1 } } diff --git a/third_party/move/move-model/bytecode/ast-generator-tests/tests/bit_vector_loop_example.exp b/third_party/move/move-model/bytecode/ast-generator-tests/tests/bit_vector_loop_example.exp index 381f6d03f0c..78487aab6fe 100644 --- a/third_party/move/move-model/bytecode/ast-generator-tests/tests/bit_vector_loop_example.exp +++ b/third_party/move/move-model/bytecode/ast-generator-tests/tests/bit_vector_loop_example.exp @@ -383,61 +383,67 @@ loop { break[1] }; loop { - _t14: u64 = _t3; - _t15: &mut vector = _t2; - _t16: &vector = Freeze(true)(_t15); - _t17: u64 = vector::length(_t16); - _t18: bool = Lt(_t14, _t17); - if (Not(_t18)) break; - _t19: &mut vector = _t2; - _t20: u64 = _t3; - _t21: &mut bool = vector::borrow_mut(_t19, _t20); - _t5: &mut bool = _t21; - _t22: bool = false; - _t23: &mut bool = _t5; - _t23 = _t22; - _t24: u64 = _t3; - _t25: u64 = 1; - _t26: u64 = Add(_t24, _t25); - _t3: u64 = _t26; - continue + loop { + _t14: u64 = _t3; + _t15: &mut vector = _t2; + _t16: &vector = Freeze(true)(_t15); + _t17: u64 = vector::length(_t16); + _t18: bool = Lt(_t14, _t17); + if (Not(_t18)) break[1]; + _t19: &mut vector = _t2; + _t20: u64 = _t3; + _t21: &mut bool = vector::borrow_mut(_t19, _t20); + _t5: &mut bool = _t21; + _t22: bool = false; + _t23: &mut bool = _t5; + _t23 = _t22; + _t24: u64 = _t3; + _t25: u64 = 1; + _t26: u64 = Add(_t24, _t25); + _t3: u64 = _t26; + continue + }; + break }; _t27: &mut vector = _t2; break[1] }; loop { - _t29: u64 = _t3; - _t30: &mut BitVector = self; - _t31: &u64 = select m::BitVector.length(_t30); - _t32: u64 = Deref(_t31); - _t33: bool = Lt(_t29, _t32); - if (Not(_t33)) break; - _t34: &mut BitVector = self; - _t35: &BitVector = Freeze(true)(_t34); - _t36: u64 = _t3; - _t37: bool = m::is_index_set(_t35, _t36); loop { + _t29: u64 = _t3; + _t30: &mut BitVector = self; + _t31: &u64 = select m::BitVector.length(_t30); + _t32: u64 = Deref(_t31); + _t33: bool = Lt(_t29, _t32); + if (Not(_t33)) break[1]; + _t34: &mut BitVector = self; + _t35: &BitVector = Freeze(true)(_t34); + _t36: u64 = _t3; + _t37: bool = m::is_index_set(_t35, _t36); loop { - if (Not(_t37)) break; - _t38: &mut BitVector = self; - _t39: u64 = _t3; - _t40: u64 = amount; - _t41: u64 = Sub(_t39, _t40); - m::set(_t38, _t41); - break[1] + loop { + if (Not(_t37)) break; + _t38: &mut BitVector = self; + _t39: u64 = _t3; + _t40: u64 = amount; + _t41: u64 = Sub(_t39, _t40); + m::set(_t38, _t41); + break[1] + }; + _t45: &mut BitVector = self; + _t46: u64 = _t3; + _t47: u64 = amount; + _t48: u64 = Sub(_t46, _t47); + m::unset(_t45, _t48); + break }; - _t45: &mut BitVector = self; - _t46: u64 = _t3; - _t47: u64 = amount; - _t48: u64 = Sub(_t46, _t47); - m::unset(_t45, _t48); - break + _t42: u64 = _t3; + _t43: u64 = 1; + _t44: u64 = Add(_t42, _t43); + _t3: u64 = _t44; + continue }; - _t42: u64 = _t3; - _t43: u64 = 1; - _t44: u64 = Add(_t42, _t43); - _t3: u64 = _t44; - continue + break }; _t49: &mut BitVector = self; _t50: &u64 = select m::BitVector.length(_t49); @@ -446,20 +452,23 @@ loop { _t53: u64 = Sub(_t51, _t52); _t3: u64 = _t53; loop { - _t54: u64 = _t3; - _t55: &mut BitVector = self; - _t56: &u64 = select m::BitVector.length(_t55); - _t57: u64 = Deref(_t56); - _t58: bool = Lt(_t54, _t57); - if (Not(_t58)) break; - _t59: &mut BitVector = self; - _t60: u64 = _t3; - m::unset(_t59, _t60); - _t61: u64 = _t3; - _t62: u64 = 1; - _t63: u64 = Add(_t61, _t62); - _t3: u64 = _t63; - continue + loop { + _t54: u64 = _t3; + _t55: &mut BitVector = self; + _t56: &u64 = select m::BitVector.length(_t55); + _t57: u64 = Deref(_t56); + _t58: bool = Lt(_t54, _t57); + if (Not(_t58)) break[1]; + _t59: &mut BitVector = self; + _t60: u64 = _t3; + m::unset(_t59, _t60); + _t61: u64 = _t3; + _t62: u64 = 1; + _t63: u64 = Add(_t61, _t62); + _t3: u64 = _t63; + continue + }; + break }; _t64: &mut BitVector = self; break @@ -480,33 +489,42 @@ loop { break[1] }; loop { - if (Not(Lt(_t3, vector::length(Freeze(true)(_t2))))) break; - vector::borrow_mut(_t2, _t3) = false; - _t3: u64 = Add(_t3, 1); - continue + loop { + if (Not(Lt(_t3, vector::length(Freeze(true)(_t2))))) break[1]; + vector::borrow_mut(_t2, _t3) = false; + _t3: u64 = Add(_t3, 1); + continue + }; + break }; break[1] }; loop { - if (Not(Lt(_t3, Deref(select m::BitVector.length(self))))) break; loop { + if (Not(Lt(_t3, Deref(select m::BitVector.length(self))))) break[1]; loop { - if (Not(m::is_index_set(Freeze(true)(self), _t3))) break; - m::set(self, Sub(_t3, amount)); - break[1] + loop { + if (Not(m::is_index_set(Freeze(true)(self), _t3))) break; + m::set(self, Sub(_t3, amount)); + break[1] + }; + m::unset(self, Sub(_t3, amount)); + break }; - m::unset(self, Sub(_t3, amount)); - break + _t3: u64 = Add(_t3, 1); + continue }; - _t3: u64 = Add(_t3, 1); - continue + break }; _t3: u64 = Sub(Deref(select m::BitVector.length(self)), amount); loop { - if (Not(Lt(_t3, Deref(select m::BitVector.length(self))))) break; - m::unset(self, _t3); - _t3: u64 = Add(_t3, 1); - continue + loop { + if (Not(Lt(_t3, Deref(select m::BitVector.length(self))))) break[1]; + m::unset(self, _t3); + _t3: u64 = Add(_t3, 1); + continue + }; + break }; break }; @@ -515,37 +533,51 @@ return Tuple() --- If-Transformed Generated AST loop { loop { - if Ge(amount, Deref(select m::BitVector.length(self))) { - _t2: &mut vector = select m::BitVector.bit_field(self); - _t3: u64 = 0 - } else { + loop { + if Ge(amount, Deref(select m::BitVector.length(self))) { + _t2: &mut vector = select m::BitVector.bit_field(self); + _t3: u64 = 0; + break + }; _t3: u64 = amount; - break + break[1] }; loop { - if (Not(Lt(_t3, vector::length(Freeze(true)(_t2))))) break; - vector::borrow_mut(_t2, _t3) = false; - _t3: u64 = Add(_t3, 1); - continue + loop { + if (Not(Lt(_t3, vector::length(Freeze(true)(_t2))))) break[1]; + vector::borrow_mut(_t2, _t3) = false; + _t3: u64 = Add(_t3, 1); + continue + }; + break }; break[1] }; loop { - if (Not(Lt(_t3, Deref(select m::BitVector.length(self))))) break; - if m::is_index_set(Freeze(true)(self), _t3) { - m::set(self, Sub(_t3, amount)) - } else { - m::unset(self, Sub(_t3, amount)) + loop { + if (Not(Lt(_t3, Deref(select m::BitVector.length(self))))) break[1]; + loop { + if m::is_index_set(Freeze(true)(self), _t3) { + m::set(self, Sub(_t3, amount)); + break + }; + m::unset(self, Sub(_t3, amount)); + break + }; + _t3: u64 = Add(_t3, 1); + continue }; - _t3: u64 = Add(_t3, 1); - continue + break }; _t3: u64 = Sub(Deref(select m::BitVector.length(self)), amount); loop { - if (Not(Lt(_t3, Deref(select m::BitVector.length(self))))) break; - m::unset(self, _t3); - _t3: u64 = Add(_t3, 1); - continue + loop { + if (Not(Lt(_t3, Deref(select m::BitVector.length(self))))) break[1]; + m::unset(self, _t3); + _t3: u64 = Add(_t3, 1); + continue + }; + break }; break }; @@ -558,37 +590,51 @@ return Tuple() let _t2: &mut vector; loop { loop { - if Ge(amount, Deref(select m::BitVector.length(self))) { - _t2: &mut vector = select m::BitVector.bit_field(self); - _t3: u64 = 0 - } else { + loop { + if Ge(amount, Deref(select m::BitVector.length(self))) { + _t2: &mut vector = select m::BitVector.bit_field(self); + _t3: u64 = 0; + break + }; _t3: u64 = amount; - break + break[1] }; loop { - if (Not(Lt(_t3, vector::length(Freeze(true)(_t2))))) break; - vector::borrow_mut(_t2, _t3) = false; - _t3: u64 = Add(_t3, 1); - continue + loop { + if (Not(Lt(_t3, vector::length(Freeze(true)(_t2))))) break[1]; + vector::borrow_mut(_t2, _t3) = false; + _t3: u64 = Add(_t3, 1); + continue + }; + break }; break[1] }; loop { - if (Not(Lt(_t3, Deref(select m::BitVector.length(self))))) break; - if m::is_index_set(Freeze(true)(self), _t3) { - m::set(self, Sub(_t3, amount)) - } else { - m::unset(self, Sub(_t3, amount)) + loop { + if (Not(Lt(_t3, Deref(select m::BitVector.length(self))))) break[1]; + loop { + if m::is_index_set(Freeze(true)(self), _t3) { + m::set(self, Sub(_t3, amount)); + break + }; + m::unset(self, Sub(_t3, amount)); + break + }; + _t3: u64 = Add(_t3, 1); + continue }; - _t3: u64 = Add(_t3, 1); - continue + break }; _t3: u64 = Sub(Deref(select m::BitVector.length(self)), amount); loop { - if (Not(Lt(_t3, Deref(select m::BitVector.length(self))))) break; - m::unset(self, _t3); - _t3: u64 = Add(_t3, 1); - continue + loop { + if (Not(Lt(_t3, Deref(select m::BitVector.length(self))))) break[1]; + m::unset(self, _t3); + _t3: u64 = Add(_t3, 1); + continue + }; + break }; break }; @@ -702,29 +748,50 @@ module 0x1::m { public fun shift_left(self: &mut BitVector, amount: u64) { let _t3; let _t2; - 'l0: loop { - loop { - if (amount >= *&self.length) { - _t2 = &mut self.bit_field; - _t3 = 0 - } else { + 'l2: loop { + 'l0: loop { + loop { + if (amount >= *&self.length) { + _t2 = &mut self.bit_field; + _t3 = 0; + break + }; _t3 = amount; + break 'l0 + }; + 'l1: loop { + loop { + if (!(_t3 < 0x1::vector::length(/*freeze*/_t2))) break 'l1; + *0x1::vector::borrow_mut(_t2, _t3) = false; + _t3 = _t3 + 1 + }; break }; - while (_t3 < 0x1::vector::length(/*freeze*/_t2)) { - *0x1::vector::borrow_mut(_t2, _t3) = false; + break 'l2 + }; + 'l3: loop { + loop { + if (!(_t3 < *&self.length)) break 'l3; + loop { + if (is_index_set(/*freeze*/self, _t3)) { + set(self, _t3 - amount); + break + }; + unset(self, _t3 - amount); + break + }; _t3 = _t3 + 1 }; - break 'l0 - }; - while (_t3 < *&self.length) { - if (is_index_set(/*freeze*/self, _t3)) set(self, _t3 - amount) else unset(self, _t3 - amount); - _t3 = _t3 + 1 + break }; _t3 = *&self.length - amount; - while (_t3 < *&self.length) { - unset(self, _t3); - _t3 = _t3 + 1 + 'l4: loop { + loop { + if (!(_t3 < *&self.length)) break 'l4; + unset(self, _t3); + _t3 = _t3 + 1 + }; + break }; break }; diff --git a/third_party/move/move-model/bytecode/ast-generator-tests/tests/conditionals.exp b/third_party/move/move-model/bytecode/ast-generator-tests/tests/conditionals.exp index e094abccf41..1d20c49f670 100644 --- a/third_party/move/move-model/bytecode/ast-generator-tests/tests/conditionals.exp +++ b/third_party/move/move-model/bytecode/ast-generator-tests/tests/conditionals.exp @@ -122,20 +122,26 @@ loop { return _t1 --- If-Transformed Generated AST -if c { - _t1: u8 = 1 -} else { - _t1: u8 = 2 +loop { + if c { + _t1: u8 = 1; + break + }; + _t1: u8 = 2; + break }; return _t1 --- Var-Bound Generated AST { let _t1: u8; - if c { - _t1: u8 = 1 - } else { - _t1: u8 = 2 + loop { + if c { + _t1: u8 = 1; + break + }; + _t1: u8 = 2; + break }; return _t1 } @@ -227,28 +233,34 @@ loop { return _t2 --- If-Transformed Generated AST -if c { +loop { + if Not(c) { + _t2: u8 = 3; + break + }; if d { - _t2: u8 = 1 - } else { - _t2: u8 = 2 - } -} else { - _t2: u8 = 3 + _t2: u8 = 1; + break + }; + _t2: u8 = 2; + break }; return _t2 --- Var-Bound Generated AST { let _t2: u8; - if c { + loop { + if Not(c) { + _t2: u8 = 3; + break + }; if d { - _t2: u8 = 1 - } else { - _t2: u8 = 2 - } - } else { - _t2: u8 = 3 + _t2: u8 = 1; + break + }; + _t2: u8 = 2; + break }; return _t2 } @@ -312,20 +324,26 @@ loop { return _t1 --- If-Transformed Generated AST -if c { - _t1: u64 = 1 -} else { - _t1: u64 = 2 +loop { + if c { + _t1: u64 = 1; + break + }; + _t1: u64 = 2; + break }; return _t1 --- Var-Bound Generated AST { let _t1: u64; - if c { - _t1: u64 = 1 - } else { - _t1: u64 = 2 + loop { + if c { + _t1: u64 = 1; + break + }; + _t1: u64 = 2; + break }; return _t1 } @@ -415,28 +433,34 @@ loop { return _t2 --- If-Transformed Generated AST -if c { - _t2: u8 = 1 -} else { +loop { + if c { + _t2: u8 = 1; + break + }; if d { - _t2: u8 = 2 - } else { - _t2: u8 = 3 - } + _t2: u8 = 2; + break + }; + _t2: u8 = 3; + break }; return _t2 --- Var-Bound Generated AST { let _t2: u8; - if c { - _t2: u8 = 1 - } else { + loop { + if c { + _t2: u8 = 1; + break + }; if d { - _t2: u8 = 2 - } else { - _t2: u8 = 3 - } + _t2: u8 = 2; + break + }; + _t2: u8 = 3; + break }; return _t2 } @@ -545,10 +569,13 @@ return _t1 --- If-Transformed Generated AST x: u64 = Add(x, x); x: u64 = Mul(x, x); -if Gt(x, 0) { - _t1: u64 = Add(x, 1) -} else { - _t1: u64 = Sub(x, 1) +loop { + if Gt(x, 0) { + _t1: u64 = Add(x, 1); + break + }; + _t1: u64 = Sub(x, 1); + break }; return _t1 @@ -557,10 +584,13 @@ return _t1 let _t1: u64; x: u64 = Add(x, x); x: u64 = Mul(x, x); - if Gt(x, 0) { - _t1: u64 = Add(x, 1) - } else { - _t1: u64 = Sub(x, 1) + loop { + if Gt(x, 0) { + _t1: u64 = Add(x, 1); + break + }; + _t1: u64 = Sub(x, 1); + break }; return _t1 } @@ -575,29 +605,72 @@ module 0x815::m { } fun if_else_1(c: bool): u8 { let _t1; - if (c) _t1 = 1u8 else _t1 = 2u8; + loop { + if (c) { + _t1 = 1u8; + break + }; + _t1 = 2u8; + break + }; _t1 } fun if_else_2(c: bool, d: bool): u8 { let _t2; - if (c) if (d) _t2 = 1u8 else _t2 = 2u8 else _t2 = 3u8; + loop { + if (!c) { + _t2 = 3u8; + break + }; + if (d) { + _t2 = 1u8; + break + }; + _t2 = 2u8; + break + }; _t2 } fun if_else_3(c: bool): u64 { let _t1; - if (c) _t1 = 1 else _t1 = 2; + loop { + if (c) { + _t1 = 1; + break + }; + _t1 = 2; + break + }; _t1 } fun if_else_if(c: bool, d: bool): u8 { let _t2; - if (c) _t2 = 1u8 else if (d) _t2 = 2u8 else _t2 = 3u8; + loop { + if (c) { + _t2 = 1u8; + break + }; + if (d) { + _t2 = 2u8; + break + }; + _t2 = 3u8; + break + }; _t2 } fun if_else_with_shared_exp(x: u64): u64 { let _t1; x = x + x; x = x * x; - if (x > 0) _t1 = x + 1 else _t1 = x - 1; + loop { + if (x > 0) { + _t1 = x + 1; + break + }; + _t1 = x - 1; + break + }; _t1 } } diff --git a/third_party/move/move-model/bytecode/ast-generator-tests/tests/loops.exp b/third_party/move/move-model/bytecode/ast-generator-tests/tests/loops.exp index ef55daa883f..bd5d0e2be1c 100644 --- a/third_party/move/move-model/bytecode/ast-generator-tests/tests/loops.exp +++ b/third_party/move/move-model/bytecode/ast-generator-tests/tests/loops.exp @@ -175,58 +175,70 @@ fun m::nested_loop($t0|x: u64): u64 { --- Raw Generated AST loop { - _t1: u64 = x; - _t2: u64 = 0; - _t3: bool = Gt(_t1, _t2); - if (Not(_t3)) break; - _t4: u64 = x; - _t5: u64 = 10; - _t6: bool = Gt(_t4, _t5); loop { - if (Not(_t6)) break; - _t7: u64 = x; - _t8: u64 = 1; - _t9: u64 = Sub(_t7, _t8); - x: u64 = _t9; - break + _t1: u64 = x; + _t2: u64 = 0; + _t3: bool = Gt(_t1, _t2); + if (Not(_t3)) break[1]; + _t4: u64 = x; + _t5: u64 = 10; + _t6: bool = Gt(_t4, _t5); + loop { + if (Not(_t6)) break; + _t7: u64 = x; + _t8: u64 = 1; + _t9: u64 = Sub(_t7, _t8); + x: u64 = _t9; + break + }; + _t10: u64 = x; + _t11: u64 = 1; + _t12: u64 = Sub(_t10, _t11); + x: u64 = _t12; + continue }; - _t10: u64 = x; - _t11: u64 = 1; - _t12: u64 = Sub(_t10, _t11); - x: u64 = _t12; - continue + break }; _t13: u64 = x; return _t13 --- Assign-Transformed Generated AST loop { - if (Not(Gt(x, 0))) break; loop { - if (Not(Gt(x, 10))) break; + if (Not(Gt(x, 0))) break[1]; + loop { + if (Not(Gt(x, 10))) break; + x: u64 = Sub(x, 1); + break + }; x: u64 = Sub(x, 1); - break + continue }; - x: u64 = Sub(x, 1); - continue + break }; return x --- If-Transformed Generated AST loop { - if (Not(Gt(x, 0))) break; - if (Gt(x, 10)) x: u64 = Sub(x, 1); - x: u64 = Sub(x, 1); - continue + loop { + if (Not(Gt(x, 0))) break[1]; + if (Gt(x, 10)) x: u64 = Sub(x, 1); + x: u64 = Sub(x, 1); + continue + }; + break }; return x --- Var-Bound Generated AST loop { - if (Not(Gt(x, 0))) break; - if (Gt(x, 10)) x: u64 = Sub(x, 1); - x: u64 = Sub(x, 1); - continue + loop { + if (Not(Gt(x, 0))) break[1]; + if (Gt(x, 10)) x: u64 = Sub(x, 1); + x: u64 = Sub(x, 1); + continue + }; + break }; return x @@ -262,39 +274,51 @@ fun m::while_1($t0|c: u64) { --- Raw Generated AST loop { - _t1: u64 = c; - _t2: u64 = 0; - _t3: bool = Gt(_t1, _t2); - if (Not(_t3)) break; - _t4: u64 = c; - _t5: u64 = 1; - _t6: u64 = Sub(_t4, _t5); - c: u64 = _t6; - continue + loop { + _t1: u64 = c; + _t2: u64 = 0; + _t3: bool = Gt(_t1, _t2); + if (Not(_t3)) break[1]; + _t4: u64 = c; + _t5: u64 = 1; + _t6: u64 = Sub(_t4, _t5); + c: u64 = _t6; + continue + }; + break }; return Tuple() --- Assign-Transformed Generated AST loop { - if (Not(Gt(c, 0))) break; - c: u64 = Sub(c, 1); - continue + loop { + if (Not(Gt(c, 0))) break[1]; + c: u64 = Sub(c, 1); + continue + }; + break }; return Tuple() --- If-Transformed Generated AST loop { - if (Not(Gt(c, 0))) break; - c: u64 = Sub(c, 1); - continue + loop { + if (Not(Gt(c, 0))) break[1]; + c: u64 = Sub(c, 1); + continue + }; + break }; return Tuple() --- Var-Bound Generated AST loop { - if (Not(Gt(c, 0))) break; - c: u64 = Sub(c, 1); - continue + loop { + if (Not(Gt(c, 0))) break[1]; + c: u64 = Sub(c, 1); + continue + }; + break }; return Tuple() @@ -350,19 +374,22 @@ fun m::while_2($t0|c: u64): u64 { --- Raw Generated AST loop { - _t1: u64 = c; - _t2: u64 = 0; - _t3: bool = Gt(_t1, _t2); - if (Not(_t3)) break; - _t4: u64 = c; - _t5: u64 = 10; - _t6: bool = Ge(_t4, _t5); - if (Not(_t6)) continue; - _t7: u64 = c; - _t8: u64 = 10; - _t9: u64 = Sub(_t7, _t8); - c: u64 = _t9; - continue + loop { + _t1: u64 = c; + _t2: u64 = 0; + _t3: bool = Gt(_t1, _t2); + if (Not(_t3)) break[1]; + _t4: u64 = c; + _t5: u64 = 10; + _t6: bool = Ge(_t4, _t5); + if (Not(_t6)) continue; + _t7: u64 = c; + _t8: u64 = 10; + _t9: u64 = Sub(_t7, _t8); + c: u64 = _t9; + continue + }; + break }; _t10: u64 = c; _t11: u64 = 1; @@ -371,28 +398,37 @@ return _t12 --- Assign-Transformed Generated AST loop { - if (Not(Gt(c, 0))) break; - if (Not(Ge(c, 10))) continue; - c: u64 = Sub(c, 10); - continue + loop { + if (Not(Gt(c, 0))) break[1]; + if (Not(Ge(c, 10))) continue; + c: u64 = Sub(c, 10); + continue + }; + break }; return Add(c, 1) --- If-Transformed Generated AST loop { - if (Not(Gt(c, 0))) break; - if (Not(Ge(c, 10))) continue; - c: u64 = Sub(c, 10); - continue + loop { + if (Not(Gt(c, 0))) break[1]; + if (Not(Ge(c, 10))) continue; + c: u64 = Sub(c, 10); + continue + }; + break }; return Add(c, 1) --- Var-Bound Generated AST loop { - if (Not(Gt(c, 0))) break; - if (Not(Ge(c, 10))) continue; - c: u64 = Sub(c, 10); - continue + loop { + if (Not(Gt(c, 0))) break[1]; + if (Not(Ge(c, 10))) continue; + c: u64 = Sub(c, 10); + continue + }; + break }; return Add(c, 1) @@ -453,66 +489,90 @@ fun m::while_3($t0|c: u64): u64 { --- Raw Generated AST loop { - _t1: u64 = c; - _t2: u64 = 0; - _t3: bool = Gt(_t1, _t2); - if (Not(_t3)) break; loop { - _t4: u64 = c; - _t5: u64 = 10; - _t6: bool = Gt(_t4, _t5); - if (Not(_t6)) break; - _t7: u64 = c; - _t8: u64 = 10; - _t9: u64 = Sub(_t7, _t8); - c: u64 = _t9; + _t1: u64 = c; + _t2: u64 = 0; + _t3: bool = Gt(_t1, _t2); + if (Not(_t3)) break[1]; + loop { + loop { + _t4: u64 = c; + _t5: u64 = 10; + _t6: bool = Gt(_t4, _t5); + if (Not(_t6)) break[1]; + _t7: u64 = c; + _t8: u64 = 10; + _t9: u64 = Sub(_t7, _t8); + c: u64 = _t9; + continue + }; + break + }; + _t10: u64 = c; + _t11: u64 = 1; + _t12: u64 = Sub(_t10, _t11); + c: u64 = _t12; continue }; - _t10: u64 = c; - _t11: u64 = 1; - _t12: u64 = Sub(_t10, _t11); - c: u64 = _t12; - continue + break }; _t13: u64 = c; return _t13 --- Assign-Transformed Generated AST loop { - if (Not(Gt(c, 0))) break; loop { - if (Not(Gt(c, 10))) break; - c: u64 = Sub(c, 10); + if (Not(Gt(c, 0))) break[1]; + loop { + loop { + if (Not(Gt(c, 10))) break[1]; + c: u64 = Sub(c, 10); + continue + }; + break + }; + c: u64 = Sub(c, 1); continue }; - c: u64 = Sub(c, 1); - continue + break }; return c --- If-Transformed Generated AST loop { - if (Not(Gt(c, 0))) break; loop { - if (Not(Gt(c, 10))) break; - c: u64 = Sub(c, 10); + if (Not(Gt(c, 0))) break[1]; + loop { + loop { + if (Not(Gt(c, 10))) break[1]; + c: u64 = Sub(c, 10); + continue + }; + break + }; + c: u64 = Sub(c, 1); continue }; - c: u64 = Sub(c, 1); - continue + break }; return c --- Var-Bound Generated AST loop { - if (Not(Gt(c, 0))) break; loop { - if (Not(Gt(c, 10))) break; - c: u64 = Sub(c, 10); + if (Not(Gt(c, 0))) break[1]; + loop { + loop { + if (Not(Gt(c, 10))) break[1]; + c: u64 = Sub(c, 10); + continue + }; + break + }; + c: u64 = Sub(c, 1); continue }; - c: u64 = Sub(c, 1); - continue + break }; return c @@ -529,26 +589,50 @@ module 0x815::m { c } fun nested_loop(x: u64): u64 { - while (x > 0) { - if (x > 10) x = x - 1; - x = x - 1 + 'l0: loop { + loop { + if (!(x > 0)) break 'l0; + if (x > 10) x = x - 1; + x = x - 1 + }; + break }; x } fun while_1(c: u64) { - while (c > 0) c = c - 1; + 'l0: loop { + loop { + if (!(c > 0)) break 'l0; + c = c - 1 + }; + break + }; } fun while_2(c: u64): u64 { - while (c > 0) { - if (!(c >= 10)) continue; - c = c - 10 + 'l0: loop { + loop { + if (!(c > 0)) break 'l0; + if (!(c >= 10)) continue; + c = c - 10 + }; + break }; c + 1 } fun while_3(c: u64): u64 { - while (c > 0) { - while (c > 10) c = c - 10; - c = c - 1 + 'l0: loop { + loop { + if (!(c > 0)) break 'l0; + 'l1: loop { + loop { + if (!(c > 10)) break 'l1; + c = c - 10 + }; + break + }; + c = c - 1 + }; + break }; c } diff --git a/third_party/move/move-model/bytecode/ast-generator-tests/tests/match.exp b/third_party/move/move-model/bytecode/ast-generator-tests/tests/match.exp index 0b545627c8e..64e16ada60e 100644 --- a/third_party/move/move-model/bytecode/ast-generator-tests/tests/match.exp +++ b/third_party/move/move-model/bytecode/ast-generator-tests/tests/match.exp @@ -99,22 +99,28 @@ loop { return _t1 --- If-Transformed Generated AST -if test_variants m::Entity::Person(self) { - _t1: u64 = Deref(select_variants m::Entity.Person.id(self)) -} else { +loop { + if test_variants m::Entity::Person(self) { + _t1: u64 = Deref(select_variants m::Entity.Person.id(self)); + break + }; if (Not(test_variants m::Entity::Institution(self))) Abort(14566554180833181697); - _t1: u64 = Deref(select_variants m::Entity.Institution.id(self)) + _t1: u64 = Deref(select_variants m::Entity.Institution.id(self)); + break }; return _t1 --- Var-Bound Generated AST { let _t1: u64; - if test_variants m::Entity::Person(self) { - _t1: u64 = Deref(select_variants m::Entity.Person.id(self)) - } else { + loop { + if test_variants m::Entity::Person(self) { + _t1: u64 = Deref(select_variants m::Entity.Person.id(self)); + break + }; if (Not(test_variants m::Entity::Institution(self))) Abort(14566554180833181697); - _t1: u64 = Deref(select_variants m::Entity.Institution.id(self)) + _t1: u64 = Deref(select_variants m::Entity.Institution.id(self)); + break }; return _t1 } @@ -249,16 +255,19 @@ return _t2 --- If-Transformed Generated AST _t1: &Entity = Borrow(Immutable)(self); -if And(test_variants m::Entity::Person(_t1), Gt(Deref(select_variants m::Entity.Person.id(_t1)), 0)) { - m::Entity::Person{ id: _t20 } = self; - _t2: u64 = _t20 -} else { +loop { + if And(test_variants m::Entity::Person(_t1), Gt(Deref(select_variants m::Entity.Person.id(_t1)), 0)) { + m::Entity::Person{ id: _t20 } = self; + _t2: u64 = _t20; + break + }; if test_variants m::Entity::Institution(_t1) { m::Entity::Institution{ id: _t9, admin: _t10 } = self; - _t2: u64 = _t9 - } else { - _t2: u64 = 0 - } + _t2: u64 = _t9; + break + }; + _t2: u64 = 0; + break }; return _t2 @@ -274,16 +283,19 @@ return _t2 { let _t1: &Entity; _t1: &Entity = Borrow(Immutable)(self); - if And(test_variants m::Entity::Person(_t1), Gt(Deref(select_variants m::Entity.Person.id(_t1)), 0)) { - m::Entity::Person{ id: _t20 } = self; - _t2: u64 = _t20 - } else { + loop { + if And(test_variants m::Entity::Person(_t1), Gt(Deref(select_variants m::Entity.Person.id(_t1)), 0)) { + m::Entity::Person{ id: _t20 } = self; + _t2: u64 = _t20; + break + }; if test_variants m::Entity::Institution(_t1) { m::Entity::Institution{ id: _t9, admin: _t10 } = self; - _t2: u64 = _t9 - } else { - _t2: u64 = 0 - } + _t2: u64 = _t9; + break + }; + _t2: u64 = 0; + break }; return _t2 } @@ -305,9 +317,14 @@ module 0x815::m { } fun id(self: &Entity): u64 { let _t1; - if (self is Person) _t1 = *&self.id else { + loop { + if (self is Person) { + _t1 = *&self.id; + break + }; if (!(self is Institution)) abort 14566554180833181697; - _t1 = *&self.id + _t1 = *&self.id; + break }; _t1 } @@ -318,13 +335,20 @@ module 0x815::m { let _t20; let _t1; _t1 = &self; - if ((_t1 is Person) && *&_t1.id > 0) { - Entity::Person{id: _t20} = self; - _t2 = _t20 - } else if (_t1 is Institution) { - Entity::Institution{id: _t9,admin: _t10} = self; - _t2 = _t9 - } else _t2 = 0; + loop { + if ((_t1 is Person) && *&_t1.id > 0) { + Entity::Person{id: _t20} = self; + _t2 = _t20; + break + }; + if (_t1 is Institution) { + Entity::Institution{id: _t9,admin: _t10} = self; + _t2 = _t9; + break + }; + _t2 = 0; + break + }; _t2 } } diff --git a/third_party/move/move-model/bytecode/src/astifier.rs b/third_party/move/move-model/bytecode/src/astifier.rs index 0d0696f15d8..00ad2ba6a49 100644 --- a/third_party/move/move-model/bytecode/src/astifier.rs +++ b/third_party/move/move-model/bytecode/src/astifier.rs @@ -364,12 +364,11 @@ impl<'a> Context<'a> { if label1 == label2 { return true; } - - let mut visited = BTreeSet::new(); - visited.insert(label1); + // starting from `label2`, recursively replace the label and see if we go back to `label1`. + // why no endless iteration: label_subst has no cycles! let mut target = label2; while let Some(s) = label_subst.get(&target) { - if !visited.insert(target) { + if *s == label1 { return true; } target = *s; @@ -799,11 +798,15 @@ impl Generator { }, if_false, ); + // We need to break out from all the inner loops! + let nest = self + .find_break_nest(ctx, if_false) + .expect("the newly added block must exist"); self.used_labels.insert(if_false); - self.add_stm( - ctx.builder - .if_(negated_cond, ctx.builder.break_(&self.current_loc(ctx), 0)), - ); + self.add_stm(ctx.builder.if_( + negated_cond, + ctx.builder.break_(&self.current_loc(ctx), nest), + )); self.gen_jump(ctx, next_block_label, if_true) } } @@ -1426,9 +1429,7 @@ struct IfElseTransformer<'a> { impl ExpRewriterFunctions for IfElseTransformer<'_> { fn rewrite_exp(&mut self, exp: Exp) -> Exp { - if let Some(result) = self.try_make_if_else(exp.clone()) { - self.rewrite_exp_descent(result) - } else if let Some(result) = self.try_make_if(exp.clone()) { + if let Some(result) = self.try_make_if(exp.clone()) { self.rewrite_exp_descent(result) } else { self.rewrite_exp_descent(exp) @@ -1437,67 +1438,6 @@ impl ExpRewriterFunctions for IfElseTransformer<'_> { } impl IfElseTransformer<'_> { - /// Attempts to create an if-then-else from the given expression. - /// This recognizes the pattern below, as produced by the AST - /// generator. Here, with 'does not branch out of a loop' we mean - /// that an expressions does not contain any unbound break or - /// continue statements which point outside the given loop: - /// - /// ```move - /// loop { - /// loop { // no loop header - /// ( if (c_i) break; )+ - /// // no reference to inner loop - /// break[1] - /// } - /// - /// } - /// ==> - /// if (c1 || .. || cn) { - /// loop { - /// - /// } - /// else { - /// loop { - /// where loop_nest -= 1 - /// } - /// } - /// ``` - fn try_make_if_else(&self, exp: Exp) -> Option { - let node_id = exp.node_id(); - let default_loc = self.builder.env().get_node_loc(node_id); - - // Match the pattern as described above - let outer_body = match_ok!(exp.as_ref(), ExpData::Loop(_, _0))?; - let (outer_first, then_branch) = self.builder.extract_first(outer_body.clone()); - let (inner_id, inner_body) = match_ok!(outer_first.as_ref(), ExpData::Loop(_0, _1))?; - let (cond, inner_rest) = self.builder.match_if_break_list(inner_body.clone())?; - // When getting the else branch, do not match exits as there are better treated with - // if without else. - let else_branch = self.builder.extract_terminated_prefix( - &default_loc, - inner_rest, - 1, - /*allow_exit*/ false, - )?; - - // Check whether the inner 'loop' is not a loop header - self.check_no_loop_header(*inner_id)?; - - // Check whether else-branch is not referencing the inner loop - if else_branch.branches_to(0..1) { - return None; - } - // Create result - let else_branch = else_branch.rewrite_loop_nest(-1); - let then_branch = self.builder.seq(&default_loc, then_branch); - Some(self.builder.if_else( - cond.clone(), - self.builder.push_loop_block_into(then_branch), - self.builder.push_loop_block_into(else_branch), - )) - } - /// Attempts to create an if-then (without else) from the given expression. /// This recognizes the pattern below, as produced by the AST /// generator: diff --git a/third_party/move/move-model/src/exp_builder.rs b/third_party/move/move-model/src/exp_builder.rs index f5e5952a616..d3efa7af845 100644 --- a/third_party/move/move-model/src/exp_builder.rs +++ b/third_party/move/move-model/src/exp_builder.rs @@ -156,28 +156,6 @@ impl<'a> ExpBuilder<'a> { } } - /// Pushes a loop block close to the point where it matters, i.e. where there is - /// another loop or a break/continue. - pub fn push_loop_block_into(&self, exp: Exp) -> Exp { - match exp.as_ref() { - ExpData::Loop(..) | ExpData::LoopCont(..) => self.loop_(exp), - ExpData::Sequence(id, elems) => { - if let Some(i) = elems - .iter() - .position(|e| matches!(e.as_ref(), ExpData::Loop(..) | ExpData::LoopCont(..))) - { - let mut new_elems = elems[0..i].to_vec(); - let default_loc = self.env().get_node_loc(*id); - new_elems.push(self.loop_(self.seq(&default_loc, elems[i..].to_vec()))); - self.seq(&default_loc, new_elems) - } else { - exp - } - }, - _ => exp, - } - } - pub fn unfold(&self, substitution: &BTreeMap, exp: Exp) -> Exp { ExpData::rewrite(exp, &mut |e: Exp| { if let ExpData::LocalVar(_, name) = e.as_ref() { diff --git a/third_party/move/tools/move-decompiler/tests/bit_vector.exp b/third_party/move/tools/move-decompiler/tests/bit_vector.exp index 5f27356b6fb..fc3fc721026 100644 --- a/third_party/move/tools/move-decompiler/tests/bit_vector.exp +++ b/third_party/move/tools/move-decompiler/tests/bit_vector.exp @@ -17,7 +17,14 @@ module 0x1::bit_vector { _t2 = start_index; loop { { - while (_t2 < *&self.length && is_index_set(self, _t2)) _t2 = _t2 + 1; + 'l0: loop { + loop { + if (!(_t2 < *&self.length)) break 'l0; + if (!is_index_set(self, _t2)) break 'l0; + _t2 = _t2 + 1 + }; + break + }; break }; break @@ -31,9 +38,13 @@ module 0x1::bit_vector { if (!(length < 1024)) abort 131073; _t1 = 0; _t2 = 0x1::vector::empty(); - while (_t1 < length) { - 0x1::vector::push_back(&mut _t2, false); - _t1 = _t1 + 1 + 'l0: loop { + loop { + if (!(_t1 < length)) break 'l0; + 0x1::vector::push_back(&mut _t2, false); + _t1 = _t1 + 1 + }; + break }; BitVector{length: length,bit_field: _t2} } @@ -45,30 +56,51 @@ module 0x1::bit_vector { let _t4; let _t3; let _t2; - 'l0: loop { - loop { - if (amount >= *&self.length) { - _t2 = &mut self.bit_field; - _t3 = 0; - _t4 = 0x1::vector::length(/*freeze*/_t2) - } else { + 'l2: loop { + 'l0: loop { + loop { + if (amount >= *&self.length) { + _t2 = &mut self.bit_field; + _t3 = 0; + _t4 = 0x1::vector::length(/*freeze*/_t2); + break + }; _t3 = amount; + break 'l0 + }; + 'l1: loop { + loop { + if (!(_t3 < _t4)) break 'l1; + *0x1::vector::borrow_mut(_t2, _t3) = false; + _t3 = _t3 + 1 + }; break }; - while (_t3 < _t4) { - *0x1::vector::borrow_mut(_t2, _t3) = false; + break 'l2 + }; + 'l3: loop { + loop { + if (!(_t3 < *&self.length)) break 'l3; + loop { + if (is_index_set(/*freeze*/self, _t3)) { + set(self, _t3 - amount); + break + }; + unset(self, _t3 - amount); + break + }; _t3 = _t3 + 1 }; - break 'l0 - }; - while (_t3 < *&self.length) { - if (is_index_set(/*freeze*/self, _t3)) set(self, _t3 - amount) else unset(self, _t3 - amount); - _t3 = _t3 + 1 + break }; _t3 = *&self.length - amount; - while (_t3 < *&self.length) { - unset(self, _t3); - _t3 = _t3 + 1 + 'l4: loop { + loop { + if (!(_t3 < *&self.length)) break 'l4; + unset(self, _t3); + _t3 = _t3 + 1 + }; + break }; break }; diff --git a/third_party/move/tools/move-decompiler/tests/cfg_opt.exp b/third_party/move/tools/move-decompiler/tests/cfg_opt.exp new file mode 100644 index 00000000000..6465e603edb --- /dev/null +++ b/third_party/move/tools/move-decompiler/tests/cfg_opt.exp @@ -0,0 +1,134 @@ + +module 0x99::cfg_opt_complex { + enum Admin has drop { + Superuser, + User { + _0: u64, + } + } + enum Entity has drop { + Person { + id: u64, + } + Institution { + id: u64, + admin: Admin, + } + } + fun admin_id(self: &Entity): u64 { + let _t8; + let _t6; + let _t3; + let _t1; + let _t2; + let _t5; + 'l2: loop { + while (!((self is Institution) && (&self.admin is Superuser))) { + 'l0: loop { + while (self is Institution) { + _t5 = &self.admin; + if (!(_t5 is User)) break; + _t2 = &_t5._0; + if (*_t2 > 10) break 'l0; + break + }; + 'l1: loop { + while (self is Institution) { + _t5 = &self.admin; + if (!(_t5 is User)) break; + if (!(*&_t5._0 <= 10)) break; + break 'l1 + }; + _t1 = self; + while (_t1 is Person) { + _t2 = &_t1.id; + if (!(*_t2 > 10)) break; + _t3 = *_t2; + break 'l2 + }; + if (_t1 is Institution) { + _t3 = *&_t1.id; + break 'l2 + }; + _t3 = 0; + break 'l2 + }; + _t1 = self; + 'l3: loop { + while (_t1 is Person) { + _t2 = &_t1.id; + if (!(*_t2 > 10)) break; + _t6 = *_t2; + break 'l3 + }; + if (_t1 is Institution) { + _t6 = *&_t1.id; + break + }; + _t6 = 0; + break + }; + _t3 = _t6 + 5; + break 'l2 + }; + _t1 = self; + 'l4: loop { + while (_t1 is Person) { + _t2 = &_t1.id; + if (!(*_t2 > 10)) break; + _t6 = *_t2; + break 'l4 + }; + if (_t1 is Institution) { + _t6 = *&_t1.id; + break + }; + _t6 = 0; + break + }; + _t3 = *_t2 + _t6; + break 'l2 + }; + 'l5: loop { + while (self is Person) { + _t2 = &self.id; + if (!(*_t2 > 10)) break; + _t8 = *_t2; + break 'l5 + }; + if (self is Institution) { + _t8 = *&self.id; + break + }; + _t8 = 0; + break + }; + _t3 = 1 + _t8; + break + }; + _t3 + } +} + +module 0x99::cfg_opt_simple { + fun test1(x: u64, y: u64): u64 { + 'l0: loop { + loop { + if (!(x > 1 || y > 2)) break 'l0; + y = y + 1 + }; + break + }; + x + 1 + y + } + fun test2(x: u64, y: u64): u64 { + 'l0: loop { + loop { + if (!(x > 1 || y > 2)) break 'l0; + y = y + 1 + }; + break + }; + x + y + } +} diff --git a/third_party/move/tools/move-decompiler/tests/cfg_opt.move b/third_party/move/tools/move-decompiler/tests/cfg_opt.move new file mode 100644 index 00000000000..ecc6a13d638 --- /dev/null +++ b/third_party/move/tools/move-decompiler/tests/cfg_opt.move @@ -0,0 +1,56 @@ +module 0x99::cfg_opt_simple { + fun test1(x: u64, y: u64): u64 { + 'outer: loop{ + loop{ + if (x > 1) break; + if (y > 2) break; + x = x + 1; + break 'outer + }; + y = y + 1 + }; + x + y + } + + fun test2(x: u64, y: u64): u64 { + 'outer: loop{ + loop{ + if (x > 1) break; + if (y > 2) break; + break 'outer + }; + y = y + 1 + }; + x + y + } +} + +module 0x99::cfg_opt_complex { + enum Entity has drop { + Person { id: u64 }, + Institution { id: u64, admin: Admin } + } + + enum Admin has drop { + Superuser, + User(u64) + } + + // Ensure function is inlined so we create nested matches in the next one. + inline fun id(self: &Entity): u64 { + match (self) { + Person{id} if *id > 10 => *id, + Institution{id, ..} => *id, + _ => 0 + } + } + + fun admin_id(self: &Entity): u64 { + match (self) { + Institution{admin: Admin::Superuser, ..} => 1 + self.id(), + Institution{admin: Admin::User(id), ..} if *id > 10 => *id + self.id(), + Institution{admin: Admin::User(id), ..} if *id <= 10 => self.id() + 5, + _ => self.id() + } + } +} diff --git a/third_party/move/tools/move-decompiler/tests/closure.exp b/third_party/move/tools/move-decompiler/tests/closure.exp index 61caec66e5e..9fa0b6bb92d 100644 --- a/third_party/move/tools/move-decompiler/tests/closure.exp +++ b/third_party/move/tools/move-decompiler/tests/closure.exp @@ -23,7 +23,14 @@ module 0x99::basic_struct { } fun test(f: &||(u64)): u64 { let _t1; - if (f == f) _t1 = 1 else _t1 = 2; + loop { + if (f == f) { + _t1 = 1; + break + }; + _t1 = 2; + break + }; _t1 } public fun test_driver(acc: &signer) { diff --git a/third_party/move/tools/move-decompiler/tests/fixed_point32.exp b/third_party/move/tools/move-decompiler/tests/fixed_point32.exp index a7c9846e00d..84da73c05d6 100644 --- a/third_party/move/tools/move-decompiler/tests/fixed_point32.exp +++ b/third_party/move/tools/move-decompiler/tests/fixed_point32.exp @@ -19,7 +19,14 @@ module 0x1::fixed_point32 { _t3 = (denominator as u128) << 32u8; if (!(_t3 != 0u128)) abort 65537; _t4 = ((numerator as u128) << 64u8) / _t3; - if (_t4 != 0u128) _t5 = true else _t5 = numerator == 0; + loop { + if (_t4 != 0u128) { + _t5 = true; + break + }; + _t5 = numerator == 0; + break + }; if (!_t5) abort 131077; if (!(_t4 <= 18446744073709551615u128)) abort 131077; FixedPoint32{value: _t4 as u64} @@ -48,12 +55,26 @@ module 0x1::fixed_point32 { } public fun max(num1: FixedPoint32, num2: FixedPoint32): FixedPoint32 { let _t2; - if (*&(&num1).value > *&(&num2).value) _t2 = num1 else _t2 = num2; + loop { + if (*&(&num1).value > *&(&num2).value) { + _t2 = num1; + break + }; + _t2 = num2; + break + }; _t2 } public fun min(num1: FixedPoint32, num2: FixedPoint32): FixedPoint32 { let _t2; - if (*&(&num1).value < *&(&num2).value) _t2 = num1 else _t2 = num2; + loop { + if (*&(&num1).value < *&(&num2).value) { + _t2 = num1; + break + }; + _t2 = num2; + break + }; _t2 } public fun multiply_u64(val: u64, multiplier: FixedPoint32): u64 { @@ -67,7 +88,14 @@ module 0x1::fixed_point32 { let _t1; _t1 = floor(self) << 32u8; _t2 = _t1 + 2147483648; - if (*&(&self).value < _t2) _t2 = _t1 >> 32u8 else _t2 = ceil(self); + loop { + if (*&(&self).value < _t2) { + _t2 = _t1 >> 32u8; + break + }; + _t2 = ceil(self); + break + }; _t2 } } diff --git a/third_party/move/tools/move-decompiler/tests/nested_loops.exp b/third_party/move/tools/move-decompiler/tests/nested_loops.exp index d659349feb1..2abd0d9dc5e 100644 --- a/third_party/move/tools/move-decompiler/tests/nested_loops.exp +++ b/third_party/move/tools/move-decompiler/tests/nested_loops.exp @@ -10,15 +10,32 @@ module 0x99::nested_loops { _t1 = 0; _t2 = false; 'l0: loop { - if (_t2) _t1 = _t1 + 1 else _t2 = true; - if (!(_t1 < 10)) break; - _t0 = _t0 + 1; - _t3 = _t1; - _t4 = false; - loop { - if (_t4) _t3 = _t3 + 1 else _t4 = true; - if (!(_t3 < 10)) continue 'l0; - _t0 = _t0 + 1 + 'l1: loop { + loop { + if (_t2) { + _t1 = _t1 + 1; + break + }; + _t2 = true; + break + }; + if (!(_t1 < 10)) break 'l0; + _t0 = _t0 + 1; + _t3 = _t1; + _t4 = false; + loop { + loop { + if (_t4) { + _t3 = _t3 + 1; + break + }; + _t4 = true; + break + }; + if (!(_t3 < 10)) continue 'l1; + _t0 = _t0 + 1 + }; + break }; break }; @@ -33,19 +50,29 @@ module 0x99::nested_loops { _t1 = 0; _t2 = false; 'l0: loop { - if (_t2) _t1 = _t1 + 1 else _t2 = true; - if (!(_t1 < 5)) break; - _t0 = _t0 + 1; - _t3 = _t1; 'l1: loop { - if (!(_t3 < 10)) continue 'l0; - _t0 = _t0 + 1; - _t4 = _t3; - _t3 = _t3 + 1; loop { + if (_t2) { + _t1 = _t1 + 1; + break + }; + _t2 = true; + break + }; + if (!(_t1 < 5)) break 'l0; + _t0 = _t0 + 1; + _t3 = _t1; + 'l2: loop { + if (!(_t3 < 10)) continue 'l1; _t0 = _t0 + 1; - if (_t4 > 10) continue 'l1; - _t4 = _t4 + 1 + _t4 = _t3; + _t3 = _t3 + 1; + loop { + _t0 = _t0 + 1; + if (_t4 > 10) continue 'l2; + _t4 = _t4 + 1 + }; + break }; break }; @@ -60,12 +87,22 @@ module 0x99::nested_loops { _t1 = 0; _t2 = false; 'l0: loop { - if (_t2) _t1 = _t1 + 1 else _t2 = true; - if (!(_t1 < 5)) break; - _t0 = _t0 + 1; - loop { - if (!(_t0 < 5)) continue 'l0; - _t0 = _t0 + 10 + 'l1: loop { + loop { + if (_t2) { + _t1 = _t1 + 1; + break + }; + _t2 = true; + break + }; + if (!(_t1 < 5)) break 'l0; + _t0 = _t0 + 1; + loop { + if (!(_t0 < 5)) continue 'l1; + _t0 = _t0 + 10 + }; + break }; break }; @@ -79,16 +116,26 @@ module 0x99::nested_loops { _t0 = 0; _t1 = 0; 'l0: loop { - _t0 = _t0 + 1; - _t2 = 0; - if (_t0 > 3) break; - _t3 = 0; - _t4 = false; - loop { - if (_t4) _t3 = _t3 + 1 else _t4 = true; - if (!(_t3 < 5)) continue 'l0; - _t2 = _t2 + 1; - _t1 = _t1 + 1 + 'l1: loop { + _t0 = _t0 + 1; + _t2 = 0; + if (_t0 > 3) break 'l0; + _t3 = 0; + _t4 = false; + loop { + loop { + if (_t4) { + _t3 = _t3 + 1; + break + }; + _t4 = true; + break + }; + if (!(_t3 < 5)) continue 'l1; + _t2 = _t2 + 1; + _t1 = _t1 + 1 + }; + break }; break }; @@ -100,13 +147,16 @@ module 0x99::nested_loops { _t0 = 0; _t1 = 0; 'l0: loop { - _t0 = _t0 + 1; - _t2 = 0; - if (_t0 > 3) break; - loop { - _t2 = _t2 + 1; - _t1 = _t1 + 1; - if (_t2 > 7) continue 'l0 + 'l1: loop { + _t0 = _t0 + 1; + _t2 = 0; + if (_t0 > 3) break 'l0; + loop { + _t2 = _t2 + 1; + _t1 = _t1 + 1; + if (_t2 > 7) continue 'l1 + }; + break }; break }; @@ -118,13 +168,16 @@ module 0x99::nested_loops { _t0 = 0; _t1 = 0; 'l0: loop { - _t0 = _t0 + 1; - _t2 = 0; - if (_t0 > 3) break; - loop { - if (!(_t2 < 7)) continue 'l0; - _t2 = _t2 + 1; - _t1 = _t1 + 1 + 'l1: loop { + _t0 = _t0 + 1; + _t2 = 0; + if (_t0 > 3) break 'l0; + loop { + if (!(_t2 < 7)) continue 'l1; + _t2 = _t2 + 1; + _t1 = _t1 + 1 + }; + break }; break }; @@ -135,13 +188,17 @@ module 0x99::nested_loops { let _t0; _t0 = 0; _t1 = 0; - 'l0: while (_t0 < 3) { - _t0 = _t0 + 1; - _t2 = 0; - loop { - if (!(_t2 < 7)) continue 'l0; - _t2 = _t2 + 1; - _t1 = _t1 + 1 + 'l0: loop { + 'l1: loop { + if (!(_t0 < 3)) break 'l0; + _t0 = _t0 + 1; + _t2 = 0; + loop { + if (!(_t2 < 7)) continue 'l1; + _t2 = _t2 + 1; + _t1 = _t1 + 1 + }; + break }; break }; @@ -158,21 +215,45 @@ module 0x99::nested_loops { _t1 = 0; _t2 = false; 'l0: loop { - if (_t2) _t1 = _t1 + 1 else _t2 = true; - if (!(_t1 < 10)) break; - _t0 = _t0 + 1; - _t3 = _t1; - _t4 = false; 'l1: loop { - if (_t4) _t3 = _t3 + 1 else _t4 = true; - if (!(_t3 < 10)) continue 'l0; - _t0 = _t0 + 1; - _t5 = _t3; - _t6 = false; loop { - if (_t6) _t5 = _t5 + 1 else _t6 = true; - if (!(_t5 < 10)) continue 'l1; - _t0 = _t0 + 1 + if (_t2) { + _t1 = _t1 + 1; + break + }; + _t2 = true; + break + }; + if (!(_t1 < 10)) break 'l0; + _t0 = _t0 + 1; + _t3 = _t1; + _t4 = false; + 'l2: loop { + loop { + if (_t4) { + _t3 = _t3 + 1; + break + }; + _t4 = true; + break + }; + if (!(_t3 < 10)) continue 'l1; + _t0 = _t0 + 1; + _t5 = _t3; + _t6 = false; + loop { + loop { + if (_t6) { + _t5 = _t5 + 1; + break + }; + _t6 = true; + break + }; + if (!(_t5 < 10)) continue 'l2; + _t0 = _t0 + 1 + }; + break }; break }; @@ -187,19 +268,22 @@ module 0x99::nested_loops { _t0 = 0; _t1 = 0; 'l0: loop { - _t0 = _t0 + 1; - _t2 = _t1; - if (_t1 > 10) break; - _t1 = _t1 + 1; 'l1: loop { _t0 = _t0 + 1; - _t3 = _t2; - if (_t2 > 10) continue 'l0; - _t2 = _t2 + 1; - loop { + _t2 = _t1; + if (_t1 > 10) break 'l0; + _t1 = _t1 + 1; + 'l2: loop { _t0 = _t0 + 1; - if (_t3 > 10) continue 'l1; - _t3 = _t3 + 1 + _t3 = _t2; + if (_t2 > 10) continue 'l1; + _t2 = _t2 + 1; + loop { + _t0 = _t0 + 1; + if (_t3 > 10) continue 'l2; + _t3 = _t3 + 1 + }; + break }; break }; @@ -213,19 +297,23 @@ module 0x99::nested_loops { let _t0; _t0 = 0; _t1 = 0; - 'l0: while (_t1 < 10) { - _t0 = _t0 + 1; - _t2 = _t1; - _t1 = _t1 + 1; + 'l0: loop { 'l1: loop { - if (!(_t2 < 10)) continue 'l0; + if (!(_t1 < 10)) break 'l0; _t0 = _t0 + 1; - _t3 = _t2; - _t2 = _t2 + 1; - loop { - if (!(_t3 < 10)) continue 'l1; + _t2 = _t1; + _t1 = _t1 + 1; + 'l2: loop { + if (!(_t2 < 10)) continue 'l1; _t0 = _t0 + 1; - _t3 = _t3 + 1 + _t3 = _t2; + _t2 = _t2 + 1; + loop { + if (!(_t3 < 10)) continue 'l2; + _t0 = _t0 + 1; + _t3 = _t3 + 1 + }; + break }; break }; diff --git a/third_party/move/tools/move-decompiler/tests/noexit_loops.exp b/third_party/move/tools/move-decompiler/tests/noexit_loops.exp index 4da7cbeff9a..8936743ced7 100644 --- a/third_party/move/tools/move-decompiler/tests/noexit_loops.exp +++ b/third_party/move/tools/move-decompiler/tests/noexit_loops.exp @@ -24,7 +24,14 @@ module 0x99::noexit_loops { } fun f13(cond: bool) { let _t2; - if (cond) _t2 = 0 else _t2 = 1; + loop { + if (cond) { + _t2 = 0; + break + }; + _t2 = 1; + break + }; loop continue } fun f14(p: bool, q: bool) { diff --git a/third_party/move/tools/move-decompiler/tests/option.exp b/third_party/move/tools/move-decompiler/tests/option.exp index a1c20a0c2ad..47c210ea65f 100644 --- a/third_party/move/tools/move-decompiler/tests/option.exp +++ b/third_party/move/tools/move-decompiler/tests/option.exp @@ -29,7 +29,14 @@ module 0x1::option { let _t3; let _t2; _t2 = &self.vec; - if (vector::is_empty(_t2)) _t3 = default_ref else _t3 = vector::borrow(_t2, 0); + loop { + if (vector::is_empty(_t2)) { + _t3 = default_ref; + break + }; + _t3 = vector::borrow(_t2, 0); + break + }; _t3 } public fun destroy_none(self: Option) { @@ -56,7 +63,14 @@ module 0x1::option { let _t5; Option{vec: _t5} = self; _t2 = _t5; - if (vector::is_empty(/*freeze*/&mut _t2)) _t3 = default else _t3 = vector::pop_back(&mut _t2); + loop { + if (vector::is_empty(/*freeze*/&mut _t2)) { + _t3 = default; + break + }; + _t3 = vector::pop_back(&mut _t2); + break + }; _t3 } public fun extract(self: &mut Option): Element { @@ -77,7 +91,14 @@ module 0x1::option { let _t3; let _t2; _t2 = &self.vec; - if (vector::is_empty(_t2)) _t3 = default else _t3 = *vector::borrow(_t2, 0); + loop { + if (vector::is_empty(_t2)) { + _t3 = default; + break + }; + _t3 = *vector::borrow(_t2, 0); + break + }; _t3 } public fun none(): Option { @@ -90,7 +111,14 @@ module 0x1::option { let _t3; let _t2; _t2 = &mut self.vec; - if (vector::is_empty(/*freeze*/_t2)) _t3 = none() else _t3 = some(vector::pop_back(_t2)); + loop { + if (vector::is_empty(/*freeze*/_t2)) { + _t3 = none(); + break + }; + _t3 = some(vector::pop_back(_t2)); + break + }; vector::push_back(_t2, e); _t3 } diff --git a/third_party/move/tools/move-decompiler/tests/simple_map.exp b/third_party/move/tools/move-decompiler/tests/simple_map.exp index 82afda47093..21885278581 100644 --- a/third_party/move/tools/move-decompiler/tests/simple_map.exp +++ b/third_party/move/tools/move-decompiler/tests/simple_map.exp @@ -34,7 +34,14 @@ module 0x1::simple_map { let _t3; _t3 = 0; { - while (!(!(_t3 < vector::length>(&self.data)) || &vector::borrow>(&self.data, _t3).key == key)) _t3 = _t3 + 1; + 'l0: loop { + loop { + if (!(_t3 < vector::length>(&self.data))) break 'l0; + if (&vector::borrow>(&self.data, _t3).key == key) break 'l0; + _t3 = _t3 + 1 + }; + break + }; return option::some(_t3) }; option::none() @@ -66,9 +73,13 @@ module 0x1::simple_map { _t6 = _t4; _t7 = vector::length(&_t5); if (!(_t7 == vector::length(&_t6))) abort 131074; - while (_t7 > 0) { - add(self, vector::pop_back(&mut _t5), vector::pop_back(&mut _t6)); - _t7 = _t7 - 1 + 'l0: loop { + loop { + if (!(_t7 > 0)) break 'l0; + add(self, vector::pop_back(&mut _t5), vector::pop_back(&mut _t6)); + _t7 = _t7 - 1 + }; + break }; vector::destroy_empty(_t5); vector::destroy_empty(_t6); @@ -80,9 +91,13 @@ module 0x1::simple_map { _t1 = &self.data; _t2 = vector::empty(); _t3 = 0; - while (_t3 < vector::length>(_t1)) { - vector::push_back(&mut _t2, *&vector::borrow>(_t1, _t3).key); - _t3 = _t3 + 1 + 'l0: loop { + loop { + if (!(_t3 < vector::length>(_t1))) break 'l0; + vector::push_back(&mut _t2, *&vector::borrow>(_t1, _t3).key); + _t3 = _t3 + 1 + }; + break }; _t2 } @@ -93,9 +108,13 @@ module 0x1::simple_map { _t1 = &self.data; _t2 = vector::empty(); _t3 = 0; - while (_t3 < vector::length>(_t1)) { - vector::push_back(&mut _t2, *&vector::borrow>(_t1, _t3).value); - _t3 = _t3 + 1 + 'l0: loop { + loop { + if (!(_t3 < vector::length>(_t1))) break 'l0; + vector::push_back(&mut _t2, *&vector::borrow>(_t1, _t3).value); + _t3 = _t3 + 1 + }; + break }; _t2 } @@ -130,11 +149,15 @@ module 0x1::simple_map { vector::reverse>(&mut _t3); _t4 = _t3; _t5 = vector::length>(&_t4); - while (_t5 > 0) { - Element{key: _t21,value: _t22} = vector::pop_back>(&mut _t4); - vector::push_back(&mut _t1, _t21); - vector::push_back(&mut _t2, _t22); - _t5 = _t5 - 1 + 'l0: loop { + loop { + if (!(_t5 > 0)) break 'l0; + Element{key: _t21,value: _t22} = vector::pop_back>(&mut _t4); + vector::push_back(&mut _t1, _t21); + vector::push_back(&mut _t2, _t22); + _t5 = _t5 - 1 + }; + break }; vector::destroy_empty>(_t4); (_t1, _t2) @@ -149,7 +172,14 @@ module 0x1::simple_map { _t4 = vector::length>(/*freeze*/_t3); _t5 = 0; { - while (!(!(_t5 < _t4) || &vector::borrow>(/*freeze*/_t3, _t5).key == &key)) _t5 = _t5 + 1; + 'l0: loop { + loop { + if (!(_t5 < _t4)) break 'l0; + if (&vector::borrow>(/*freeze*/_t3, _t5).key == &key) break 'l0; + _t5 = _t5 + 1 + }; + break + }; vector::push_back>(_t3, Element{key: key,value: value}); vector::swap>(_t3, _t5, _t4); Element{key: _t34,value: _t35} = vector::pop_back>(_t3); diff --git a/third_party/move/tools/move-decompiler/tests/string.exp b/third_party/move/tools/move-decompiler/tests/string.exp index 1a87dcb38e0..a4ea27279ec 100644 --- a/third_party/move/tools/move-decompiler/tests/string.exp +++ b/third_party/move/tools/move-decompiler/tests/string.exp @@ -23,7 +23,14 @@ module 0x1::string { let _t4; let _t3; _t3 = &self.bytes; - if (at <= vector::length(_t3)) _t4 = internal_is_char_boundary(_t3, at) else _t4 = false; + loop { + if (at <= vector::length(_t3)) { + _t4 = internal_is_char_boundary(_t3, at); + break + }; + _t4 = false; + break + }; if (!_t4) abort 2; _t6 = sub_string(/*freeze*/self, 0, at); append(&mut _t6, o); @@ -37,9 +44,30 @@ module 0x1::string { let _t5; let _t3; _t3 = &self.bytes; - if (j <= vector::length(_t3)) _t5 = i <= j else _t5 = false; - if (_t5) _t6 = internal_is_char_boundary(_t3, i) else _t6 = false; - if (_t6) _t7 = internal_is_char_boundary(_t3, j) else _t7 = false; + loop { + if (j <= vector::length(_t3)) { + _t5 = i <= j; + break + }; + _t5 = false; + break + }; + loop { + if (_t5) { + _t6 = internal_is_char_boundary(_t3, i); + break + }; + _t6 = false; + break + }; + loop { + if (_t6) { + _t7 = internal_is_char_boundary(_t3, j); + break + }; + _t7 = false; + break + }; if (!_t7) abort 2; String{bytes: internal_sub_string(_t3, i, j)} } @@ -57,7 +85,14 @@ module 0x1::string { native fun internal_sub_string(v: &vector, i: u64, j: u64): vector; public fun try_utf8(bytes: vector): option::Option { let _t1; - if (internal_check_utf8(&bytes)) _t1 = option::some(String{bytes: bytes}) else _t1 = option::none(); + loop { + if (internal_check_utf8(&bytes)) { + _t1 = option::some(String{bytes: bytes}); + break + }; + _t1 = option::none(); + break + }; _t1 } } diff --git a/third_party/move/tools/move-decompiler/tests/vector.exp b/third_party/move/tools/move-decompiler/tests/vector.exp index 22e0c75e28a..7672014d965 100644 --- a/third_party/move/tools/move-decompiler/tests/vector.exp +++ b/third_party/move/tools/move-decompiler/tests/vector.exp @@ -12,7 +12,14 @@ module 0x1::vector { let _t2; _t2 = 0; { - while (!(!(_t2 < length(self)) || borrow(self, _t2) == e)) _t2 = _t2 + 1; + 'l0: loop { + loop { + if (!(_t2 < length(self))) break 'l0; + if (borrow(self, _t2) == e) break 'l0; + _t2 = _t2 + 1 + }; + break + }; return true }; false @@ -21,7 +28,14 @@ module 0x1::vector { let _t2; _t2 = 0; { - while (!(!(_t2 < length(self)) || borrow(self, _t2) == e)) _t2 = _t2 + 1; + 'l0: loop { + loop { + if (!(_t2 < length(self))) break 'l0; + if (borrow(self, _t2) == e) break 'l0; + _t2 = _t2 + 1 + }; + break + }; return (true, _t2) }; (false, 0) @@ -33,9 +47,13 @@ module 0x1::vector { let _t3; if (!(step > 0)) abort 131075; _t3 = empty(); - while (start < end) { - push_back(&mut _t3, start); - start = start + step + 'l0: loop { + loop { + if (!(start < end)) break 'l0; + push_back(&mut _t3, start); + start = start + step + }; + break }; _t3 } @@ -49,9 +67,13 @@ module 0x1::vector { public fun reverse_append(self: &mut vector, other: vector) { let _t2; _t2 = length(&other); - while (_t2 > 0) { - push_back(self, pop_back(&mut other)); - _t2 = _t2 - 1 + 'l0: loop { + loop { + if (!(_t2 > 0)) break 'l0; + push_back(self, pop_back(&mut other)); + _t2 = _t2 - 1 + }; + break }; destroy_empty(other); } @@ -60,9 +82,13 @@ module 0x1::vector { _t3 = length(/*freeze*/self); if (!(i <= _t3)) abort 131072; push_back(self, e); - while (i < _t3) { - swap(self, i, _t3); - i = i + 1 + 'l0: loop { + loop { + if (!(i < _t3)) break 'l0; + swap(self, i, _t3); + i = i + 1 + }; + break }; } public fun is_empty(self: &vector): bool { @@ -72,9 +98,13 @@ module 0x1::vector { let _t2; _t2 = length(/*freeze*/self); if (i >= _t2) abort 131072; - while (i < _t2 - 1) { - i = i + 1; - swap(self, i, i) + 'l0: loop { + loop { + if (!(i < _t2 - 1)) break 'l0; + i = i + 1; + swap(self, i, i) + }; + break }; pop_back(self) } @@ -84,19 +114,25 @@ module 0x1::vector { let _t8; let _t7; (_t7,_t8) = index_of(/*freeze*/self, val); - if (_t7) { - _t12 = empty(); - push_back(&mut _t12, remove(self, _t8)); - _t3 = _t12 - } else _t3 = empty(); + loop { + if (_t7) { + _t12 = empty(); + push_back(&mut _t12, remove(self, _t8)); + _t3 = _t12; + break + }; + _t3 = empty(); + break + }; _t3 } public fun reverse_slice(self: &mut vector, left: u64, right: u64) { if (!(left <= right)) abort 131073; - { + 'l0: loop { if (!(left == right)) { right = right - 1; - while (left < right) { + loop { + if (!(left < right)) break 'l0; swap(self, left, right); left = left + 1; right = right - 1 @@ -123,12 +159,23 @@ module 0x1::vector { public fun slice(self: &vector, start: u64, end: u64): vector { let _t4; let _t3; - if (start <= end) _t3 = end <= length(self) else _t3 = false; + loop { + if (start <= end) { + _t3 = end <= length(self); + break + }; + _t3 = false; + break + }; if (!_t3) abort 131076; _t4 = empty(); - while (start < end) { - push_back(&mut _t4, *borrow(self, start)); - start = start + 1 + 'l0: loop { + loop { + if (!(start < end)) break 'l0; + push_back(&mut _t4, *borrow(self, start)); + start = start + 1 + }; + break }; _t4 } @@ -149,9 +196,13 @@ module 0x1::vector { _t2 = length(/*freeze*/self); if (!(new_len <= _t2)) abort 131072; _t3 = empty(); - while (new_len < _t2) { - push_back(&mut _t3, pop_back(self)); - _t2 = _t2 - 1 + 'l0: loop { + loop { + if (!(new_len < _t2)) break 'l0; + push_back(&mut _t3, pop_back(self)); + _t2 = _t2 - 1 + }; + break }; _t3 } From 6104c0f3eb05b3b56c0c2786377d1258bb571da8 Mon Sep 17 00:00:00 2001 From: Wolfgang Grieskamp Date: Tue, 15 Jul 2025 20:53:49 +0200 Subject: [PATCH 042/260] [move] Move assembler basic functionality (#16631) * [move] Move assembler basic functionality This gets us going on the basic functionality of the new Move assembler. It consumes files of the form `foo.masm` to produce Move bytecode. See the tests for examples. Note this currently does not implement struct definition related ops which will be added later. This PR also provides a new abstraction for building a module via `module_builder`, closing a long known gap about more streamlined generation of Move bytecode. We can move this module out of the assembler if it turns out to be useful. * Addressing reviewer comments. Downstreamed-from: a0ef99a9a9c25f460e7c85bdefbb5b82b0f7efd6 --- Cargo.lock | 18 + Cargo.toml | 2 + .../src/file_format_generator/mod.rs | 2 +- third_party/move/move-compiler-v2/src/lib.rs | 2 +- .../move/move-core/types/src/identifier.rs | 6 + third_party/move/tools/move-asm/Cargo.toml | 36 + .../move/tools/move-asm/src/compiler.rs | 769 +++++++++++++++++ third_party/move/tools/move-asm/src/lib.rs | 107 +++ third_party/move/tools/move-asm/src/main.rs | 13 + .../move/tools/move-asm/src/module_builder.rs | 625 ++++++++++++++ third_party/move/tools/move-asm/src/syntax.rs | 788 ++++++++++++++++++ .../tools/move-asm/tests/address_alias.exp | 15 + .../tools/move-asm/tests/address_alias.masm | 10 + .../move/tools/move-asm/tests/branch.exp | 20 + .../move/tools/move-asm/tests/branch.masm | 13 + .../tools/move-asm/tests/call_same_module.exp | 15 + .../move-asm/tests/call_same_module.masm | 9 + .../tests/call_same_module_generic.exp | 15 + .../tests/call_same_module_generic.masm | 9 + .../move-asm/tests/call_same_module_undef.exp | 6 + .../tests/call_same_module_undef.masm | 9 + .../move/tools/move-asm/tests/closure.exp | 16 + .../move/tools/move-asm/tests/closure.masm | 10 + .../move/tools/move-asm/tests/declare_fun.exp | 17 + .../tools/move-asm/tests/declare_fun.masm | 12 + .../move-asm/tests/declare_generic_fun.exp | 9 + .../move-asm/tests/declare_generic_fun.masm | 4 + .../move/tools/move-asm/tests/testsuite.rs | 57 ++ .../move/tools/move-asm/tests/undef_label.exp | 6 + .../tools/move-asm/tests/undef_label.masm | 5 + .../move/tools/move-asm/tests/undef_local.exp | 6 + .../tools/move-asm/tests/undef_local.masm | 6 + 32 files changed, 2635 insertions(+), 2 deletions(-) create mode 100644 third_party/move/tools/move-asm/Cargo.toml create mode 100644 third_party/move/tools/move-asm/src/compiler.rs create mode 100644 third_party/move/tools/move-asm/src/lib.rs create mode 100644 third_party/move/tools/move-asm/src/main.rs create mode 100644 third_party/move/tools/move-asm/src/module_builder.rs create mode 100644 third_party/move/tools/move-asm/src/syntax.rs create mode 100644 third_party/move/tools/move-asm/tests/address_alias.exp create mode 100644 third_party/move/tools/move-asm/tests/address_alias.masm create mode 100644 third_party/move/tools/move-asm/tests/branch.exp create mode 100644 third_party/move/tools/move-asm/tests/branch.masm create mode 100644 third_party/move/tools/move-asm/tests/call_same_module.exp create mode 100644 third_party/move/tools/move-asm/tests/call_same_module.masm create mode 100644 third_party/move/tools/move-asm/tests/call_same_module_generic.exp create mode 100644 third_party/move/tools/move-asm/tests/call_same_module_generic.masm create mode 100644 third_party/move/tools/move-asm/tests/call_same_module_undef.exp create mode 100644 third_party/move/tools/move-asm/tests/call_same_module_undef.masm create mode 100644 third_party/move/tools/move-asm/tests/closure.exp create mode 100644 third_party/move/tools/move-asm/tests/closure.masm create mode 100644 third_party/move/tools/move-asm/tests/declare_fun.exp create mode 100644 third_party/move/tools/move-asm/tests/declare_fun.masm create mode 100644 third_party/move/tools/move-asm/tests/declare_generic_fun.exp create mode 100644 third_party/move/tools/move-asm/tests/declare_generic_fun.masm create mode 100644 third_party/move/tools/move-asm/tests/testsuite.rs create mode 100644 third_party/move/tools/move-asm/tests/undef_label.exp create mode 100644 third_party/move/tools/move-asm/tests/undef_label.masm create mode 100644 third_party/move/tools/move-asm/tests/undef_local.exp create mode 100644 third_party/move/tools/move-asm/tests/undef_local.masm diff --git a/Cargo.lock b/Cargo.lock index 30bcc9b754e..0e969526aa8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11767,6 +11767,24 @@ dependencies = [ "tempfile", ] +[[package]] +name = "move-asm" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap 4.5.21", + "codespan", + "codespan-reporting", + "datatest-stable", + "either", + "move-binary-format", + "move-command-line-common", + "move-core-types", + "move-disassembler", + "move-ir-types", + "move-prover-test-utils", +] + [[package]] name = "move-ast-generator-tests" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index ccec28f71e8..96afe4dcdc0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -240,6 +240,7 @@ members = [ "third_party/move/move-vm/transactional-tests", "third_party/move/move-vm/types", "third_party/move/testing-infra/transactional-test-runner", + "third_party/move/tools/move-asm", "third_party/move/tools/move-bytecode-utils", "third_party/move/tools/move-bytecode-viewer", "third_party/move/tools/move-cli", @@ -835,6 +836,7 @@ z3tracer = "0.8.0" # MOVE DEPENDENCIES move-abigen = { path = "third_party/move/move-prover/move-abigen" } +move-asm = { path = "third_party/move/tools/move-asm" } move-binary-format = { path = "third_party/move/move-binary-format" } move-borrow-graph = { path = "third_party/move/move-borrow-graph" } move-bytecode-source-map = { path = "third_party/move/move-ir-compiler/move-bytecode-source-map" } diff --git a/third_party/move/move-compiler-v2/src/file_format_generator/mod.rs b/third_party/move/move-compiler-v2/src/file_format_generator/mod.rs index 9a87434a141..55b6d55f741 100644 --- a/third_party/move/move-compiler-v2/src/file_format_generator/mod.rs +++ b/third_party/move/move-compiler-v2/src/file_format_generator/mod.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 mod function_generator; -mod module_generator; +pub mod module_generator; mod peephole_optimizer; use crate::{file_format_generator::module_generator::ModuleContext, options::Options, Experiment}; diff --git a/third_party/move/move-compiler-v2/src/lib.rs b/third_party/move/move-compiler-v2/src/lib.rs index bcc18618334..9df78f74012 100644 --- a/third_party/move/move-compiler-v2/src/lib.rs +++ b/third_party/move/move-compiler-v2/src/lib.rs @@ -7,7 +7,7 @@ pub mod diagnostics; pub mod env_pipeline; mod experiments; pub mod external_checks; -mod file_format_generator; +pub mod file_format_generator; pub mod lint_common; pub mod logging; pub mod options; diff --git a/third_party/move/move-core/types/src/identifier.rs b/third_party/move/move-core/types/src/identifier.rs index 3fdf0ed944a..658319d9013 100644 --- a/third_party/move/move-core/types/src/identifier.rs +++ b/third_party/move/move-core/types/src/identifier.rs @@ -123,6 +123,12 @@ impl Identifier { } } + /// Creates an unchecked `Identifier` instance, allowing characters which + /// are invalid in the language. + pub fn new_unchecked(s: impl Into>) -> Self { + Self(s.into()) + } + /// Returns true if this string is a valid identifier. pub fn is_valid(s: impl AsRef) -> bool { is_valid(s.as_ref()) diff --git a/third_party/move/tools/move-asm/Cargo.toml b/third_party/move/tools/move-asm/Cargo.toml new file mode 100644 index 00000000000..a59cddd5042 --- /dev/null +++ b/third_party/move/tools/move-asm/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "move-asm" +version = "0.1.0" +authors = ["Aptos Labs"] +description = "Move Assembler" +repository = "https://github.com/aptos-labs/aptos-core" +homepage = "https://aptosfoundation.org/" +license = "Apache-2.0" +publish = false +edition = "2021" + +[dependencies] +anyhow = { workspace = true } +clap = { workspace = true, features = ["derive"] } +codespan = { workspace = true } +codespan-reporting = { workspace = true, features = ["serde", "serialization"] } +either = { workspace = true } +move-binary-format = { workspace = true } +move-command-line-common = { workspace = true } +move-core-types = { workspace = true } + +[dev-dependencies] +datatest-stable = { workspace = true } +move-disassembler = { workspace = true } +move-ir-types = { workspace = true } # Because of Loc... +move-prover-test-utils = { workspace = true } + +[features] +default = [] + +[[test]] +name = "testsuite" +harness = false + +[lib] +doctest = false diff --git a/third_party/move/tools/move-asm/src/compiler.rs b/third_party/move/tools/move-asm/src/compiler.rs new file mode 100644 index 00000000000..d1c5220f7e9 --- /dev/null +++ b/third_party/move/tools/move-asm/src/compiler.rs @@ -0,0 +1,769 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Implements the assembler from the abstract syntax into bytecode, +//! using the `ModuleBuilder`. + +use crate::{ + module_builder::{ModuleBuilder, ModuleBuilderOptions}, + syntax, + syntax::{ + map_diag, Argument, AsmResult, Diag, Fun, Instruction, Loc, Local, Type, Unit, UnitId, + Value, + }, +}; +use either::Either; +use move_binary_format::{ + file_format::{ + Bytecode, CodeOffset, CompiledScript, FunctionDefinitionIndex, FunctionHandleIndex, + LocalIndex, SignatureIndex, SignatureToken, TableIndex, + }, + CompiledModule, +}; +use move_core_types::{function::ClosureMask, identifier::Identifier, u256::U256}; +use std::collections::BTreeMap; + +struct Assembler<'a> { + builder: ModuleBuilder<'a>, + diags: Vec, + /// Context available during processing of a function. + fun_context: Option, +} + +struct FunctionContext { + ty_param_map: BTreeMap, + local_map: BTreeMap, +} + +pub(crate) fn compile<'a>( + options: ModuleBuilderOptions, + context_modules: impl IntoIterator, + ast: Unit, +) -> AsmResult> { + let mut compiler = Assembler { + builder: ModuleBuilder::new(options, context_modules, ast.name.module_opt()), + diags: vec![], + fun_context: None, + }; + compiler.unit(&ast); + if compiler.diags.is_empty() { + match ast.name { + UnitId::Script => map_diag(compiler.builder.into_script()).map(Either::Right), + UnitId::Module(_) => map_diag(compiler.builder.into_module()).map(Either::Left), + } + } else { + Err(compiler.diags) + } +} + +impl<'a> Assembler<'a> { + fn unit(&mut self, ast: &Unit) { + let Unit { + name: _, + address_aliases, + module_aliases, + functions, + } = ast; + // Register aliases + for (n, a) in address_aliases { + let res = self.builder.declare_address_alias(n, *a); + self.add_diags(Loc::new(0, 0), res); + } + for (n, m) in module_aliases { + let res = self.builder.declare_module_alias(n, m); + self.add_diags(Loc::new(0, 0), res); + } + + // Declare functions + for fun in functions { + self.declare_fun(fun); + } + + // Define code for functions + if self.diags.is_empty() { + for (pos, fun) in functions.iter().enumerate() { + self.define_fun(FunctionDefinitionIndex::new(pos as TableIndex), fun) + } + } + } + + fn declare_fun(&mut self, fun: &Fun) { + self.setup_fun(fun); + let param_tys: Vec = fun + .params + .iter() + .map(|local| self.build_type(fun.loc, &local.ty)) + .collect(); + let res = self.builder.signature_index(param_tys); + let param_sign = self.add_diags(fun.loc, res).unwrap_or_default(); + let result_tys: Vec = fun + .result + .iter() + .map(|ty| self.build_type(fun.loc, ty)) + .collect(); + let res = self.builder.signature_index(result_tys); + let result_sign = self.add_diags(fun.loc, res).unwrap_or_default(); + let res = self.builder.declare_fun( + false, // TODO(#16582): entry + fun.name.clone(), + fun.visibility, + param_sign, + result_sign, + fun.type_params + .iter() + .map(|(_, abilities)| *abilities) + .collect(), + ); + self.add_diags(fun.loc, res); + } + + fn setup_fun(&mut self, fun: &Fun) { + let ty_param_map = fun + .type_params + .iter() + .enumerate() + .map(|(pos, (id, _))| (id.to_string(), pos as u16)) + .collect(); + self.fun_context = Some(FunctionContext { + ty_param_map, // This is needed for build_type called below + local_map: Default::default(), + }); + self.fun_context.as_mut().unwrap().local_map = fun + .params + .iter() + .chain(fun.locals.iter()) + .enumerate() + .map(|(pos, Local { loc, name, ty })| { + let ty = self.build_type(*loc, ty); + (name.to_string(), (pos as LocalIndex, ty)) + }) + .collect(); + } + + fn require_fun(&self) -> &FunctionContext { + self.fun_context.as_ref().expect("function context") + } + + fn define_fun(&mut self, def_idx: FunctionDefinitionIndex, fun: &Fun) { + if !fun.instrs.is_empty() { + self.setup_fun(fun); + let mut open_branches = BTreeMap::new(); + let mut label_defs = BTreeMap::new(); + let mut code = vec![]; + let mut has_errors = false; + for (offs, instr) in fun.instrs.iter().enumerate() { + if let Some(label) = instr.label.as_ref() { + label_defs.insert(label.clone(), offs as CodeOffset); + } + if let Some(bc) = self.build_instr( + instr, + offs as CodeOffset, + &mut open_branches, + &mut label_defs, + ) { + code.push(bc) + } else { + // else error reported + has_errors = true + } + } + if !has_errors { + // Link forward pointing branch targets + for (offs, (use_loc, label)) in open_branches { + if let Some(target_offs) = label_defs.get(&label) { + match &mut code[offs as usize] { + Bytecode::Branch(open) + | Bytecode::BrTrue(open) + | Bytecode::BrFalse(open) => *open = *target_offs, + _ => panic!("unexpected bytecode"), + }; + } else { + self.error(use_loc, format!("unbound branch label `{}`", label)) + } + } + // Define locals signature. + let locals_start = fun.params.len(); + let mut locals: Vec<(LocalIndex, SignatureToken)> = self + .require_fun() + .local_map + .clone() + .into_iter() + .filter_map(|(_, r)| { + if r.0 as usize >= locals_start { + Some(r) + } else { + None + } + }) + .collect(); + locals.sort_by(|e1, e2| e1.0.cmp(&e2.0)); + let res = self + .builder + .signature_index(locals.into_iter().map(|(_, ty)| ty).collect()); + if let Some(sign_index) = self.add_diags(fun.loc, res) { + self.builder.define_fun_code(def_idx, sign_index, code) + } + } + } + } + + fn build_type(&mut self, loc: Loc, ty: &Type) -> SignatureToken { + let ck_inst = |comp: &mut Self, req: Option, inst: Option<&Vec>| -> bool { + match req { + None => { + if inst.is_some() { + comp.error(loc, "no type arguments expected"); + false + } else { + true + } + }, + Some(count) => { + if inst.map_or(0, |ty| ty.len()) != count { + comp.error(loc, format!("expected {} type arguments", count)); + false + } else { + true + } + }, + } + }; + let tr_inst = |comp: &mut Self, inst: Option<&Vec>| -> Option> { + inst.map(|tys| tys.iter().map(|t| comp.build_type(loc, t)).collect()) + }; + match ty { + Type::Named(partial_id, opt_inst) => { + if partial_id.address.is_none() && partial_id.id_parts.len() == 1 { + match partial_id.id_parts[0].as_str() { + s if self.require_fun().ty_param_map.contains_key(s) => { + SignatureToken::TypeParameter(self.require_fun().ty_param_map[s]) + }, + "u8" => { + ck_inst(self, None, opt_inst.as_ref()); + SignatureToken::U8 + }, + "u16" => { + ck_inst(self, None, opt_inst.as_ref()); + SignatureToken::U16 + }, + "u32" => { + ck_inst(self, None, opt_inst.as_ref()); + SignatureToken::U32 + }, + "u64" => { + ck_inst(self, None, opt_inst.as_ref()); + SignatureToken::U64 + }, + "u128" => { + ck_inst(self, None, opt_inst.as_ref()); + SignatureToken::U128 + }, + "u256" => { + ck_inst(self, None, opt_inst.as_ref()); + SignatureToken::U256 + }, + "bool" => { + ck_inst(self, None, opt_inst.as_ref()); + SignatureToken::Bool + }, + "address" => { + ck_inst(self, None, opt_inst.as_ref()); + SignatureToken::Address + }, + "signer" => { + ck_inst(self, None, opt_inst.as_ref()); + SignatureToken::Signer + }, + "vector" => { + if ck_inst(self, Some(1), opt_inst.as_ref()) { + SignatureToken::Vector(Box::new( + tr_inst(self, opt_inst.as_ref()).unwrap().pop().unwrap(), + )) + } else { + // error reported + SignatureToken::Bool + } + }, + _ => { + self.error(loc, "structs NYI"); + SignatureToken::Bool + }, + } + } else { + self.error(loc, "structs NYI type"); + SignatureToken::Bool + } + }, + Type::Ref(is_mut, ty) => { + let ty = Box::new(self.build_type(loc, ty)); + if *is_mut { + SignatureToken::MutableReference(ty) + } else { + SignatureToken::Reference(ty) + } + }, + Type::Func(args, result, abilities) => SignatureToken::Function( + args.iter().map(|ty| self.build_type(loc, ty)).collect(), + result.iter().map(|ty| self.build_type(loc, ty)).collect(), + *abilities, + ), + } + } + + fn build_instr( + &mut self, + instr: &Instruction, + offs: CodeOffset, + open_branches: &mut BTreeMap, + label_defs: &mut BTreeMap, + ) -> Option { + use Bytecode::*; + let instr_name = instr.name.to_string().to_lowercase(); + let instr = match instr_name.as_str() { + "pop" => { + self.args0(instr)?; + Pop + }, + "ret" => { + self.args0(instr)?; + Ret + }, + "br_true" | "br_false" | "branch" => { + let mk_instr = match instr_name.as_str() { + "br_true" => BrTrue, + "br_false" => BrFalse, + "branch" => Branch, + _ => unreachable!(), + }; + let arg = self.args1(instr)?; + let label = self.simple_id(instr, arg)?; + if let Some(label_offs) = label_defs.get(&label) { + mk_instr(*label_offs) + } else { + // Forward branch, remember we need to link offset + open_branches.insert(offs, (instr.loc, label)); + mk_instr(0) + } + }, + "ld_u8" => { + let arg = self.args1(instr)?; + let num = self.number(instr, arg, U256::from(u8::MAX))?; + LdU8(num.unchecked_as_u8()) + }, + "ld_u16" => { + let arg = self.args1(instr)?; + let num = self.number(instr, arg, U256::from(u16::MAX))?; + LdU16(num.unchecked_as_u16()) + }, + "ld_u32" => { + let arg = self.args1(instr)?; + let num = self.number(instr, arg, U256::from(u32::MAX))?; + LdU32(num.unchecked_as_u32()) + }, + "ld_u64" => { + let arg = self.args1(instr)?; + let num = self.number(instr, arg, U256::from(u64::MAX))?; + LdU64(num.unchecked_as_u64()) + }, + "ld_u128" => { + let arg = self.args1(instr)?; + let num = self.number(instr, arg, U256::from(u128::MAX))?; + LdU128(num.unchecked_as_u128()) + }, + "ld_u256" => { + let arg = self.args1(instr)?; + let num = self.number(instr, arg, U256::max_value())?; + LdU256(num) + }, + + "cast_u8" => { + self.args0(instr)?; + CastU8 + }, + "cast_u16" => { + self.args0(instr)?; + CastU16 + }, + "cast_u32" => { + self.args0(instr)?; + CastU32 + }, + "cast_u64" => { + self.args0(instr)?; + CastU64 + }, + "cast_u128" => { + self.args0(instr)?; + CastU128 + }, + "cast_u256" => { + self.args0(instr)?; + CastU256 + }, + "ld_const" => { + let [arg1, arg2] = self.args2(instr)?; + let ty = self.type_(instr, arg1)?; + let val = self.value_bcs(instr, arg2, &ty)?; + let res = self.builder.const_index(val, ty); + let idx = self.add_diags(instr.loc, res)?; + LdConst(idx) + }, + "ld_false" => { + self.args0(instr)?; + LdFalse + }, + "ld_true" => { + self.args0(instr)?; + LdTrue + }, + "copy_loc" => { + let arg = self.args1(instr)?; + CopyLoc(self.local(instr, arg)?) + }, + "move_loc" => { + let arg = self.args1(instr)?; + MoveLoc(self.local(instr, arg)?) + }, + "st_loc" => { + let arg = self.args1(instr)?; + StLoc(self.local(instr, arg)?) + }, + "call" => { + let arg = self.args1(instr)?; + let (handle_idx, targs_opt) = self.fun_ref(instr, arg)?; + if let Some(targs) = targs_opt { + let res = self.builder.fun_inst_index(handle_idx, targs); + let inst_idx = self.add_diags(instr.loc, res)?; + CallGeneric(inst_idx) + } else { + Call(handle_idx) + } + }, + // TODO: struct and enum instructions + "read_ref" => { + self.args0(instr)?; + ReadRef + }, + "write_ref" => { + self.args0(instr)?; + WriteRef + }, + "freeze_ref" => { + self.args0(instr)?; + FreezeRef + }, + "mut_borrow_loc" => { + let arg = self.args1(instr)?; + MutBorrowLoc(self.local(instr, arg)?) + }, + "imm_borrow_loc" => { + let arg = self.args1(instr)?; + ImmBorrowLoc(self.local(instr, arg)?) + }, + "add" => { + self.args0(instr)?; + Add + }, + "sub" => { + self.args0(instr)?; + Sub + }, + "mul" => { + self.args0(instr)?; + Mul + }, + "mod" => { + self.args0(instr)?; + Mod + }, + "div" => { + self.args0(instr)?; + Div + }, + "bit_or" => { + self.args0(instr)?; + BitOr + }, + "bit_and" => { + self.args0(instr)?; + BitAnd + }, + "xor" => { + self.args0(instr)?; + Xor + }, + "or" => { + self.args0(instr)?; + Or + }, + "and" => { + self.args0(instr)?; + And + }, + "not" => { + self.args0(instr)?; + Not + }, + "eq" => { + self.args0(instr)?; + Eq + }, + "neq" => { + self.args0(instr)?; + Neq + }, + "lt" => { + self.args0(instr)?; + Lt + }, + "gt" => { + self.args0(instr)?; + Gt + }, + "le" => { + self.args0(instr)?; + Le + }, + "ge" => { + self.args0(instr)?; + Ge + }, + "abort" => { + self.args0(instr)?; + Abort + }, + "nop" => { + self.args0(instr)?; + Nop + }, + // TODO: resource operations + "shl" => { + self.args0(instr)?; + Shl + }, + "shr" => { + self.args0(instr)?; + Shr + }, + "vec_pack" => { + let [arg1, arg2] = self.args2(instr)?; + let sign_idx = self.type_index(instr, arg1)?; + let count = self.number(instr, arg2, U256::from(u64::MAX))?; + VecPack(sign_idx, count.unchecked_as_u64()) + }, + "vec_len" => { + let arg = self.args1(instr)?; + let sign_idx = self.type_index(instr, arg)?; + VecLen(sign_idx) + }, + "vec_imm_borrow" => { + let arg = self.args1(instr)?; + let sign_idx = self.type_index(instr, arg)?; + VecImmBorrow(sign_idx) + }, + "vec_mut_borrow" => { + let arg = self.args1(instr)?; + let sign_idx = self.type_index(instr, arg)?; + VecMutBorrow(sign_idx) + }, + "vec_push_back" => { + let arg = self.args1(instr)?; + let sign_idx = self.type_index(instr, arg)?; + VecPushBack(sign_idx) + }, + "vec_pop_back" => { + let arg = self.args1(instr)?; + let sign_idx = self.type_index(instr, arg)?; + VecPopBack(sign_idx) + }, + "vec_unpack" => { + let [arg1, arg2] = self.args2(instr)?; + let sign_idx = self.type_index(instr, arg1)?; + let count = self.number(instr, arg2, U256::from(u64::MAX))?; + VecUnpack(sign_idx, count.unchecked_as_u64()) + }, + "vec_swap" => { + let arg = self.args1(instr)?; + let sign_idx = self.type_index(instr, arg)?; + VecSwap(sign_idx) + }, + "pack_closure" => { + let [arg1, arg2] = self.args2(instr)?; + let (handle_idx, targs_opt) = self.fun_ref(instr, arg1)?; + let closure_mask = ClosureMask::new( + self.number(instr, arg2, U256::from(u64::MAX))? + .unchecked_as_u64(), + ); + if let Some(targs) = targs_opt { + let res = self.builder.fun_inst_index(handle_idx, targs); + let inst_idx = self.add_diags(instr.loc, res)?; + PackClosureGeneric(inst_idx, closure_mask) + } else { + PackClosure(handle_idx, closure_mask) + } + }, + "call_closure" => { + let arg = self.args1(instr)?; + let sign_idx = self.type_index(instr, arg)?; + CallClosure(sign_idx) + }, + _ => { + self.error(instr.loc, format!("unknown instruction `{}`", instr.name)); + return None; + }, + }; + Some(instr) + } + + fn simple_id(&mut self, instr: &Instruction, arg: &Argument) -> Option { + match arg { + Argument::Id(pid, None) if pid.address.is_none() && pid.id_parts.len() == 1 => { + Some(pid.id_parts[0].clone()) + }, + _ => { + self.error(instr.loc, "expected simple identifier"); + None + }, + } + } + + fn fun_ref( + &mut self, + instr: &Instruction, + arg: &Argument, + ) -> Option<(FunctionHandleIndex, Option>)> { + if let Argument::Id(pid, targs) = arg { + let res = self.builder.resolve_fun(&pid.address, &pid.id_parts); + let idx = self.add_diags(instr.loc, res)?; + let targs = targs.as_ref().map(|tys| { + tys.iter() + .map(|ty| self.build_type(instr.loc, ty)) + .collect() + }); + Some((idx, targs)) + } else { + self.error(instr.loc, "expected function name"); + None + } + } + + fn local(&mut self, instr: &Instruction, arg: &Argument) -> Option { + let id = self.simple_id(instr, arg)?; + if let Some((idx, _)) = self.require_fun().local_map.get(id.as_str()) { + Some(*idx) + } else { + self.error(instr.loc, format!("unknown local `{}`", id)); + None + } + } + + fn number(&mut self, instr: &Instruction, arg: &Argument, max: U256) -> Option { + if let Argument::Constant(Value::Number(n)) = arg { + if *n <= max { + Some(*n) + } else { + self.error( + instr.loc, + format!("number {} out of range (max {})", n, max), + ); + None + } + } else { + self.error(instr.loc, "expected number argument"); + None + } + } + + fn type_(&mut self, instr: &Instruction, arg: &Argument) -> Option { + if let Argument::Type(ty) = arg { + Some(self.build_type(instr.loc, ty)) + } else { + self.error(instr.loc, "expected type argument"); + None + } + } + + fn type_index(&mut self, instr: &Instruction, arg: &Argument) -> Option { + let ty = self.type_(instr, arg)?; + let res = self.builder.signature_index(vec![ty]); + self.add_diags(instr.loc, res) + } + + fn value_bcs( + &mut self, + instr: &Instruction, + arg: &Argument, + _ty: &SignatureToken, + ) -> Option> { + if let Argument::Constant(Value::Bytes(bytes)) = arg { + Some(bytes.clone()) + } else { + self.error(instr.loc, "expected byte blob"); + None + } + } + + fn args0(&mut self, instr: &Instruction) -> Option<()> { + if instr.args.is_empty() { + Some(()) + } else { + self.error( + instr.loc, + format!( + "expected zero but found {} arguments for instruction `{}`", + instr.args.len(), + instr.name + ), + ); + None + } + } + + fn args1<'i>(&mut self, instr: &'i Instruction) -> Option<&'i Argument> { + if instr.args.len() == 1 { + Some(&instr.args[0]) + } else { + self.error( + instr.loc, + format!( + "expected 1 but found {} arguments for instruction `{}`", + instr.args.len(), + instr.name + ), + ); + None + } + } + + fn args2<'i>(&mut self, instr: &'i Instruction) -> Option<[&'i Argument; 2]> { + if instr.args.len() == 2 { + Some([&instr.args[0], &instr.args[1]]) + } else { + self.error( + instr.loc, + format!( + "expected 1 but found {} arguments for instruction `{}`", + instr.args.len(), + instr.name + ), + ); + None + } + } + + /// Report error + fn error(&mut self, loc: Loc, msg: impl ToString) { + self.diags.append(&mut syntax::error(loc, msg)) + } + + /// Convert anyhow error to diagnostics in the compiler instance. + fn add_diags(&mut self, loc: Loc, res: anyhow::Result) -> Option { + match res { + Err(e) => { + self.error(loc, e.to_string()); + None + }, + Ok(x) => Some(x), + } + } +} diff --git a/third_party/move/tools/move-asm/src/lib.rs b/third_party/move/tools/move-asm/src/lib.rs new file mode 100644 index 00000000000..128074d9a00 --- /dev/null +++ b/third_party/move/tools/move-asm/src/lib.rs @@ -0,0 +1,107 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Entry point into the Move assembler ('move-asm'). + +pub mod compiler; +pub mod module_builder; +pub mod syntax; + +use crate::{ + module_builder::ModuleBuilderOptions, + syntax::{AsmResult, Diag}, +}; +use anyhow::bail; +use clap::Parser; +use codespan_reporting::{ + files::{Files, SimpleFile}, + term, + term::termcolor::WriteColor, +}; +use either::Either; +use move_binary_format::{file_format::CompiledScript, CompiledModule}; +use std::{fs, io::Write, path::PathBuf}; + +#[derive(Parser, Clone, Debug, Default)] +#[clap(author, version, about)] +pub struct Options { + /// Options for the module builder + #[clap(flatten)] + pub module_builder_options: ModuleBuilderOptions, + + /// Directory where to place assembled code. + #[clap(short, long, default_value = "")] + pub output_dir: String, + + /// Input file. + pub inputs: Vec, +} + +/// Assembles source as specified by options. +pub fn run(error_writer: &mut W) -> anyhow::Result<()> +where + W: Write + WriteColor, +{ + let options = Options::parse(); + if options.inputs.len() != 1 { + bail!("expected exactly one file name for the assembler source") + } + let input_path = options.inputs.first().unwrap(); + let input = fs::read_to_string(input_path)?; + + let result = match assemble(&options, &input) { + Ok(x) => x, + Err(diags) => { + let diag_file = SimpleFile::new(&input_path, &input); + report_diags(error_writer, &diag_file, diags); + bail!("exiting with errors") + }, + }; + + let path = PathBuf::from(input_path).with_extension("mv"); + let mut out_path = PathBuf::from(options.output_dir); + out_path.push(path.file_name().expect("file name available")); + let mut bytes = vec![]; + match result { + Either::Left(m) => m + .serialize_for_version( + Some(options.module_builder_options.bytecode_version), + &mut bytes, + ) + .expect("serialization succeeds"), + Either::Right(s) => s + .serialize_for_version( + Some(options.module_builder_options.bytecode_version), + &mut bytes, + ) + .expect("serialization succeeds"), + } + if let Err(e) = fs::write(&out_path, &bytes) { + bail!("failed to write result to `{}`: {}", out_path.display(), e); + } + Ok(()) +} + +pub fn assemble( + options: &Options, + input: &str, +) -> AsmResult> { + let ast = syntax::parse_asm(input)?; + let result = compiler::compile( + options.module_builder_options.clone(), + std::iter::empty(), + ast, + )?; + Ok(result) +} + +pub(crate) fn report_diags<'a, W: Write + WriteColor>( + error_writer: &mut W, + files: &'a impl Files<'a, FileId = ()>, + diags: Vec, +) { + for diag in diags { + term::emit(error_writer, &term::Config::default(), files, &diag) + .unwrap_or_else(|_| eprintln!("failed to print diagnostics")) + } +} diff --git a/third_party/move/tools/move-asm/src/main.rs b/third_party/move/tools/move-asm/src/main.rs new file mode 100644 index 00000000000..abb32a7c09c --- /dev/null +++ b/third_party/move/tools/move-asm/src/main.rs @@ -0,0 +1,13 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use codespan_reporting::term::termcolor::{ColorChoice, StandardStream}; +use move_asm::run; + +fn main() { + let mut error_writer = StandardStream::stderr(ColorChoice::Auto); + if let Err(e) = run(&mut error_writer) { + eprintln!("error: {:#}", e); + std::process::exit(1) + } +} diff --git a/third_party/move/tools/move-asm/src/module_builder.rs b/third_party/move/tools/move-asm/src/module_builder.rs new file mode 100644 index 00000000000..a7434473169 --- /dev/null +++ b/third_party/move/tools/move-asm/src/module_builder.rs @@ -0,0 +1,625 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Utility for building a `CompiledModule` (or `CompiledScript`). +//! +//! This builder supports building Move bytecode, automatically creating +//! the internal handle tables associated with a bytecode unit. It allows +//! to resolve partial and complete identifiers for functions and structs +//! in the context of the currently build module and a set of context modules. +//! +//! The primary API is for building a `CompiledModule`. This can then be +//! converted (under certain conditions) into a `CompiledScript`. + +use anyhow::{anyhow, bail, Result}; +use clap::Parser; +use move_binary_format::{ + access::ModuleAccess, + file_format::{ + AddressIdentifierIndex, Bytecode, CodeUnit, CompiledScript, Constant, ConstantPoolIndex, + FunctionDefinition, FunctionDefinitionIndex, FunctionHandle, FunctionHandleIndex, + FunctionInstantiation, FunctionInstantiationIndex, IdentifierIndex, ModuleHandle, + ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, StructHandle, + StructHandleIndex, TableIndex, Visibility, + }, + file_format_common::VERSION_DEFAULT, + internals::ModuleIndex, + views::{ + FunctionDefinitionView, FunctionHandleView, ModuleHandleView, ModuleView, StructHandleView, + }, + CompiledModule, +}; +use move_core_types::{ + ability::AbilitySet, account_address::AccountAddress, identifier::Identifier, language_storage, + language_storage::ModuleId, +}; +use std::{ + cell::RefCell, + collections::BTreeMap, + fmt::{Display, Formatter}, +}; + +#[derive(Parser, Clone, Debug)] +#[clap(author, version, about)] +pub struct ModuleBuilderOptions { + /// Whether to perform bounds checks and other validation during assembly. + #[clap(long, default_value_t = true)] + pub validate: bool, + + /// The bytecode version. + #[clap(long, default_value_t = VERSION_DEFAULT)] + pub bytecode_version: u32, +} + +impl Default for ModuleBuilderOptions { + fn default() -> Self { + Self { + validate: true, + bytecode_version: VERSION_DEFAULT, + } + } +} + +#[derive(Default)] +pub struct ModuleBuilder<'a> { + /// The options for building. + options: ModuleBuilderOptions, + /// The module known in the context. + context_modules: BTreeMap, + /// A map of address aliases + address_aliases: BTreeMap, + /// A map of module aliases + module_aliases: BTreeMap, + /// The build module. + module: RefCell, + /// The module index for which we generate code. + this_module_idx: ModuleHandleIndex, + /// A mapping from modules to indices. + module_to_idx: RefCell>, + /// A mapping from identifiers to indices. + name_to_idx: RefCell>, + /// A mapping from addresses to indices. + address_to_idx: RefCell>, + /// A mapping from functions to indices. + fun_to_idx: RefCell>, + /// A mapping from function instantiations to indices. + fun_inst_to_idx: + RefCell>, + /// A mapping from structs to indices. + struct_to_idx: RefCell>, + /// A mapping from type sequences to signature indices. + signature_to_idx: RefCell>, + /// A mapping for constants. + cons_to_idx: RefCell, SignatureToken), ConstantPoolIndex>>, +} + +#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)] +pub struct QualifiedId { + module_id: ModuleId, + id: Identifier, +} + +impl Display for QualifiedId { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}::{}", self.module_id, self.id) + } +} + +impl<'a> ModuleBuilder<'a> { + pub fn new( + options: ModuleBuilderOptions, + context_modules: impl IntoIterator, + module_id_opt: Option<&ModuleId>, + ) -> Self { + let mut module = CompiledModule { + version: options.bytecode_version, + self_module_handle_idx: ModuleHandleIndex(0), + ..Default::default() + }; + + module.module_handles.push(ModuleHandle { + address: AddressIdentifierIndex(0), + name: IdentifierIndex(0), + }); + let ModuleId { + address: script_address, + name: script_name, + } = language_storage::pseudo_script_module_id().clone(); + let (address, name) = if let Some(mid) = module_id_opt { + assert_ne!(mid.address, script_address, "address reserved for scripts"); + (mid.address, mid.name.clone()) + } else { + (script_address, script_name) + }; + module.address_identifiers.push(address); + module.identifiers.push(name); + + let context_modules = context_modules + .into_iter() + .map(|m| (ModuleView::new(m).id(), m)) + .collect(); + Self { + module: RefCell::new(module), + options, + context_modules, + ..Default::default() + } + } + + /// Return result as a module. + pub fn into_module(self) -> Result { + Ok(self.module.take()) + } + + /// Return result as a script. + pub fn into_script(self) -> Result { + // TODO(#16582): script conversion + bail!("NYI: script conversion") + } +} + +// ========================================================================================== +// Declaration of entities in the current module + +// This need to be done before querying any handle indices, so name resolution works. + +impl<'a> ModuleBuilder<'a> { + /// Declares an address alias. + pub fn declare_address_alias(&mut self, name: &Identifier, addr: AccountAddress) -> Result<()> { + if self.address_aliases.insert(name.clone(), addr).is_some() { + bail!("duplicate address alias `{}`", name) + } else { + Ok(()) + } + } + + /// Declares a module alias. This is similar like `use 0x1::mod` in Move. Subsequently, + /// `mod` can be used in resolution. + pub fn declare_module_alias(&mut self, name: &Identifier, module: &ModuleId) -> Result<()> { + if self + .module_aliases + .insert(name.clone(), module.clone()) + .is_some() + { + bail!("duplicate module alias `{}`", name) + } else { + Ok(()) + } + } + + /// Declares a function and adds it to the builder. The function + /// initially does not have any code associated. + /// TODO(#16582): attributes and access specifiers + pub fn declare_fun( + &self, + is_entry: bool, + name: Identifier, + visibility: Visibility, + parameters: SignatureIndex, + return_: SignatureIndex, + type_parameters: Vec, + ) -> Result { + if self.options.validate { + let module_ref = self.module.borrow(); + let module = &*module_ref; + for fdef in &module.function_defs { + let view = FunctionDefinitionView::new(module, fdef); + if view.name() == name.as_ref() { + return Err(anyhow!("duplicate function definition `{}`", name)); + } + } + } + let full_name = self.this_module_id(name.to_owned()); + let name_idx = self.name_index(name.to_owned())?; + let fhdl = FunctionHandle { + module: self.this_module_idx, + name: name_idx, + parameters, + return_, + type_parameters, + access_specifiers: None, + attributes: vec![], + }; + let fhdl_idx = self.index( + &mut self.module.borrow_mut().function_handles, + &mut self.fun_to_idx.borrow_mut(), + full_name, + fhdl, + FunctionHandleIndex, + "function handle", + )?; + let fdef = FunctionDefinition { + function: fhdl_idx, + visibility, + is_entry, + acquires_global_resources: vec![], + code: None, + }; + let new_idx = self.module.borrow().function_defs.len(); + self.bounds_check(new_idx, TableIndex::MAX, "function definition index")?; + let fidx = FunctionDefinitionIndex(new_idx as TableIndex); + self.module.borrow_mut().function_defs.push(fdef); + Ok(fidx) + } + + pub fn define_fun_code( + &self, + def_idx: FunctionDefinitionIndex, + locals: SignatureIndex, + code: Vec, + ) { + self.module.borrow_mut().function_defs[def_idx.0 as usize].code = + Some(CodeUnit { locals, code }); + } + + fn this_module(&self) -> ModuleId { + let module_ref = self.module.borrow(); + let view = ModuleHandleView::new( + &*module_ref, + &module_ref.module_handles[self.this_module_idx.0 as usize], + ); + view.module_id() + } + + fn this_module_id(&self, id: Identifier) -> QualifiedId { + QualifiedId { + module_id: self.this_module(), + id, + } + } + + // ========================================================================================== + // Resolving Names + + /// Resolves a module name, where the name is specified to some extent. + /// - If an address is given, one further name part needs to be present + /// for the module. + /// - If no address is given two name parts must be present, the first + /// an address alias, the 2nd the module name. + pub fn resolve_module( + &self, + address_opt: &Option, + name_parts: &[Identifier], + ) -> Result { + let id = if let Some(addr) = address_opt { + // This must be a fully qualified name + if name_parts.len() != 1 { + bail!("expected one name part after address") + } + ModuleId::new(*addr, name_parts[0].clone()) + } else if name_parts.len() == 2 { + // The first name must be an address alias + if let Some(addr) = self.address_aliases.get(&name_parts[0]) { + ModuleId::new(*addr, name_parts[1].clone()) + } else { + bail!("undeclared address alias `{}`", name_parts[0]) + } + } else { + bail!("expected two name parts") + }; + if self.context_modules.contains_key(&id) || self.this_module() == id { + Ok(id) + } else { + bail!("unknown module `{}`", id) + } + } + + /// Resolves a function name, where the name is specified to some extent. + /// - If an address is given, this is a fully qualified function name. + /// - If no address is given, the last name is the name of a function, + /// and any preceding name parts are passed on to `resolve_module`. + pub fn resolve_fun( + &self, + address_opt: &Option, + name_parts: &[Identifier], + ) -> Result { + if address_opt.is_none() && name_parts.len() == 1 { + // A simple name can only be resolved into a function within this module. + let module = self.module.borrow(); + for fdef in &module.function_defs { + let view = FunctionDefinitionView::new(&*module, fdef); + if view.name() == name_parts[0].as_ref() { + return self.fun_index(QualifiedId { + module_id: self.this_module(), + id: name_parts[0].clone(), + }); + } + } + bail!( + "undeclared function `{}` in `{}`", + name_parts[0], + self.this_module() + ) + } else { + // Pass address and name prefix to resolve_module. + let module_id = + self.resolve_module(address_opt, &name_parts[0..name_parts.len() - 1])?; + self.fun_index(QualifiedId { + module_id, + id: name_parts[name_parts.len() - 1].clone(), + }) + } + } +} + +// ========================================================================================== +// Querying Handle Indices + +impl<'a> ModuleBuilder<'a> { + pub fn module_index(&self, id: ModuleId) -> Result { + if let Some(idx) = self.module_to_idx.borrow().get(&id) { + return Ok(*idx); + } + let ModuleId { address, name } = id.clone(); + let name = self.name_index(name)?; + let address = self.address_index(address)?; + let hdl = ModuleHandle { address, name }; + self.index( + &mut self.module.borrow_mut().module_handles, + &mut self.module_to_idx.borrow_mut(), + id, + hdl, + ModuleHandleIndex, + "module", + ) + } + + pub fn fun_index(&self, id: QualifiedId) -> Result { + if let Some(idx) = self.fun_to_idx.borrow().get(&id).cloned() { + return Ok(idx); + } + if id.module_id == self.this_module() { + // All functions in this module should be already in fun_to_idx via + // declare_fun; so this is known to be undefined. + bail!("unknown function `{}` in the current module", id.id) + } + let hdl = self.import_fun_handle(&id)?; + self.index( + &mut self.module.borrow_mut().function_handles, + &mut self.fun_to_idx.borrow_mut(), + id, + hdl, + FunctionHandleIndex, + "function handle", + ) + } + + pub fn fun_inst_index( + &self, + handle: FunctionHandleIndex, + type_args: Vec, + ) -> Result { + let type_parameters = self.signature_index(type_args)?; + if let Some(idx) = self + .fun_inst_to_idx + .borrow() + .get(&(handle, type_parameters)) + .cloned() + { + return Ok(idx); + } + let inst_handle = FunctionInstantiation { + handle, + type_parameters, + }; + self.index( + &mut self.module.borrow_mut().function_instantiations, + &mut self.fun_inst_to_idx.borrow_mut(), + (handle, type_parameters), + inst_handle, + FunctionInstantiationIndex, + "function instantiation handle", + ) + } + + pub fn struct_index(&self, id: QualifiedId) -> Result { + if let Some(idx) = self.struct_to_idx.borrow().get(&id).cloned() { + return Ok(idx); + } + if id.module_id == self.this_module() { + // All functions in this module should be already in fun_to_idx via + // declare_fun; so this is known to be undefined. + bail!("unknown struct `{}` in the current module", id.id) + } + let hdl = self.import_struct_handle(&id)?; + self.index( + &mut self.module.borrow_mut().struct_handles, + &mut self.struct_to_idx.borrow_mut(), + id, + hdl, + StructHandleIndex, + "struct handle", + ) + } + + pub fn name_index(&self, name: Identifier) -> Result { + self.index( + &mut self.module.borrow_mut().identifiers, + &mut self.name_to_idx.borrow_mut(), + name.clone(), + name, + IdentifierIndex, + "identifier", + ) + } + + pub fn address_index(&self, addr: AccountAddress) -> Result { + self.index( + &mut self.module.borrow_mut().address_identifiers, + &mut self.address_to_idx.borrow_mut(), + addr, + addr, + AddressIdentifierIndex, + "address", + ) + } + + pub fn signature_index(&self, tokens: Vec) -> Result { + let sign = Signature(tokens); + self.index( + &mut self.module.borrow_mut().signatures, + &mut self.signature_to_idx.borrow_mut(), + sign.clone(), + sign, + SignatureIndex, + "signature", + ) + } + + pub fn const_index(&self, data: Vec, type_: SignatureToken) -> Result { + let const_ = Constant { + type_: type_.clone(), + data: data.clone(), + }; + self.index( + &mut self.module.borrow_mut().constant_pool, + &mut self.cons_to_idx.borrow_mut(), + (data, type_), + const_, + ConstantPoolIndex, + "constant", + ) + } + + fn bounds_check(&self, value: usize, max: TableIndex, msg: &str) -> Result { + if self.options.validate && value >= max as usize { + Err(anyhow!( + "exceeded maximal {} table size: {} >= {}", + msg, + value, + max + )) + } else { + Ok(value as TableIndex) + } + } + + fn index( + &self, + table: &mut Vec, + lookup: &mut BTreeMap, + k: K, + d: D, + mk_idx: impl FnOnce(TableIndex) -> I, + msg: &str, + ) -> Result { + if let Some(idx) = lookup.get(&k) { + return Ok(*idx); + } + let idx = mk_idx(self.bounds_check(table.len(), TableIndex::MAX, msg)?); + table.push(d); + lookup.insert(k, idx); + Ok(idx) + } +} + +// ========================================================================================== +// Import of function and struct handles from other modules. + +// Since each module has its own handle tables, data need to be adapted to the current module. + +impl<'a> ModuleBuilder<'a> { + fn import_fun_handle(&self, id: &QualifiedId) -> Result { + let mid = &id.module_id; + let cmod = if let Some(m) = self.context_modules.get(mid) { + *m + } else { + bail!("unknown module `{}`", mid) + }; + let view = ModuleView::new(cmod); + if let Some(fdef) = view.function_definition(&id.id) { + // Copy information from the declaring function into this module. + let fhandle = cmod.function_handle_at(fdef.handle_idx()); + let fview = FunctionHandleView::new(cmod, fhandle); + let module = self.module_index(fview.module_id())?; + let name = self.name_index(fview.name().to_owned())?; + let parameters = self.map_sign(cmod, fview.parameters())?; + let return_ = self.map_sign(cmod, fview.return_())?; + Ok(FunctionHandle { + module, + name, + parameters, + return_, + type_parameters: fhandle.type_parameters.clone(), + access_specifiers: fhandle.access_specifiers.clone(), + attributes: fhandle.attributes.clone(), + }) + } else { + bail!("unknown function `{}` in module `{}`", id.id, mid) + } + } + + fn import_struct_handle(&self, id: &QualifiedId) -> Result { + let mid = &id.module_id; + let cmod = if let Some(m) = self.context_modules.get(mid) { + *m + } else { + bail!("unknown module `{}`", mid) + }; + let view = ModuleView::new(cmod); + if let Some(sdef) = view.struct_definition(&id.id) { + // Copy information from the declaring struct into this module. + let shandle = cmod.struct_handle_at(sdef.handle_idx()); + let sview = StructHandleView::new(cmod, shandle); + let module = self.module_index(sview.module_id())?; + let name = self.name_index(sview.name().to_owned())?; + Ok(StructHandle { + module, + name, + abilities: shandle.abilities, + type_parameters: shandle.type_parameters.clone(), + }) + } else { + bail!("unknown struct `{}` in module `{}`", id.id, mid) + } + } + + fn map_sign(&self, module: &CompiledModule, sig: &Signature) -> Result { + self.signature_index( + sig.0 + .iter() + .map(|tok| self.map_sign_token(module, tok)) + .collect::>>()?, + ) + } + + fn map_sign_token( + &self, + module: &CompiledModule, + tok: &SignatureToken, + ) -> Result { + use SignatureToken::*; + let map_vec = |tys: &[SignatureToken]| -> Result> { + tys.iter() + .map(|ty| self.map_sign_token(module, ty)) + .collect::>>() + }; + Ok(match tok { + Bool | U8 | U64 | U128 | U16 | U32 | U256 | Address | Signer | TypeParameter(_) => { + tok.clone() + }, + Vector(bt) => Vector(Box::new(self.map_sign_token(module, &bt.clone())?)), + Struct(hdl) => { + let view = StructHandleView::new(module, module.struct_handle_at(*hdl)); + let new_hdl = self.struct_index(QualifiedId { + module_id: view.module_id(), + id: view.name().to_owned(), + })?; + Struct(new_hdl) + }, + StructInstantiation(hdl, ty_args) => { + let view = StructHandleView::new(module, module.struct_handle_at(*hdl)); + let new_hdl = self.struct_index(QualifiedId { + module_id: view.module_id(), + id: view.name().to_owned(), + })?; + StructInstantiation(new_hdl, map_vec(ty_args)?) + }, + Function(params, results, abilities) => { + Function(map_vec(params)?, map_vec(results)?, *abilities) + }, + Reference(ty) => Reference(Box::new(self.map_sign_token(module, ty)?)), + MutableReference(ty) => MutableReference(Box::new(self.map_sign_token(module, ty)?)), + }) + } +} diff --git a/third_party/move/tools/move-asm/src/syntax.rs b/third_party/move/tools/move-asm/src/syntax.rs new file mode 100644 index 00000000000..e35ffdf67bd --- /dev/null +++ b/third_party/move/tools/move-asm/src/syntax.rs @@ -0,0 +1,788 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Abstract syntax and parser of the assembler language. +//! +//! Move assembler files (ending in `.masm`) have the following +//! EBNF syntax. Notice that this grammar use indentation +//! expressed as `IND` and newline, denoted as `LF` in the syntax. +//! Moreover, we use `ID` for a simple identifier, and `QID` for +//! a qualified identifier, an optional address constant followed +//! by a sequence of qualified identifiers separated by `::` (as in +//! `0x66::bar::foo`, or `bar::foo`). +//! +//! Notice that line comments are supported and preceded by `//`. +//! +//! ```ignore +//! unit := +//! { address_alias LF } +//! ( "module" QID | "script" ) LF +//! { struct_def | fun_def } +//! +//! struct_def := +//! /*TBD*/ +//! +//! fun_def := +//! fun_modifier "fun" ID "(" [ LIST(local) ] ")" [ tuple_type ] LF +//! { "local" local LF } { instruction LF } +//! +//! fun_modifier := [ [ "public" | "friend" ] "entry" ] +//! +//! local := ID ":" type +//! +//! type := +//! "|" [ LIST(type) ] "|" [ tuple_type ] | simple_type +//! +//! tuple_type := +//! simple_type | "(" LIST(simple_type) ")" +//! +//! simple_type := +//! QID [ type_args ] | "(" type ")" +//! +//! type_args := +//! "<" LIST(type) ">" +//! +//! instruction := +//! ( INDENT | LOOKAHEAD(ID ":") ) +//! opcode [ LIST(argument) ] +//! +//! opcode := IDENT # current instr set +//! +//! argument := +//! VALUE | QID [ type_args ] | type_args +//!``` + +use codespan::{RawIndex, Span}; +use codespan_reporting::diagnostic::{Diagnostic, Label, Severity}; +use move_binary_format::file_format::Visibility; +use move_core_types::{ + ability::{Ability, AbilitySet}, + account_address::AccountAddress, + identifier::{IdentStr, Identifier}, + language_storage::ModuleId, + u256::U256, +}; +use std::{ + collections::{BTreeMap, VecDeque}, + fmt::{Display, Formatter}, + ops::Range, + str::FromStr, + string::ToString, +}; +// ========================================================================================== +// Diagnostics + +/// Currently we use as locations span's (no filename), but keep this abstracted in case +/// we want to change this. +pub(crate) type Loc = Span; + +/// Currently we produce diagnostics for singe files without explicit name. +pub(crate) type Diag = Diagnostic<()>; + +/// A result with a set of diagnostics +pub(crate) type AsmResult = Result>; + +pub(crate) fn error(loc: Loc, message: impl ToString) -> Vec { + vec![Diag::new(Severity::Error) + .with_labels(vec![Label::primary((), loc)]) + .with_message(message.to_string())] +} + +pub(crate) fn loc(range: Range) -> Loc { + Loc::new(range.start as RawIndex, range.end as RawIndex) +} + +pub(crate) fn map_diag(result: anyhow::Result) -> AsmResult { + result.map_err(|err| error(loc(0..0), err.to_string())) +} + +// ========================================================================================== +// Abstract Syntax + +/// Represents the AST for an assembly source +#[derive(Debug)] +pub struct Unit { + /// The name, either script or module. + pub name: UnitId, + /// A list of address aliases. + pub address_aliases: Vec<(Identifier, AccountAddress)>, + /// A list of module aliases. + pub module_aliases: Vec<(Identifier, ModuleId)>, + /// List of functions. + pub functions: Vec, +} + +#[derive(Debug, Clone)] +pub enum UnitId { + Script, + Module(ModuleId), +} + +impl UnitId { + pub fn module_opt(&self) -> Option<&ModuleId> { + match self { + UnitId::Script => None, + UnitId::Module(id) => Some(id), + } + } +} + +#[derive(Debug)] +pub struct Fun { + pub loc: Loc, + pub name: Identifier, + pub visibility: Visibility, + pub type_params: Vec<(Identifier, AbilitySet)>, + pub params: Vec, + pub locals: Vec, + pub result: Vec, + pub instrs: Vec, +} + +#[derive(Debug)] +pub enum Type { + Named(PartialIdent, Option>), + Func(Vec, Vec, AbilitySet), + Ref(/*is_mut*/ bool, Box), +} + +#[derive(Debug)] +pub struct PartialIdent { + /// An optional address. + pub address: Option, + /// A sequence of name parts, separated via `::`. + /// The compiler will check how many are valid in a given context. + pub id_parts: Vec, +} + +#[derive(Debug)] +pub struct Local { + pub loc: Loc, + pub name: Identifier, + pub ty: Type, +} + +#[derive(Debug)] +pub struct Instruction { + pub loc: Loc, + pub label: Option, + pub name: Identifier, + pub args: Vec, +} + +#[derive(Debug)] +pub enum Argument { + Constant(Value), + Id(PartialIdent, Option>), + Type(Type), +} + +#[derive(Debug)] +pub enum Value { + Number(U256), + Bytes(Vec), +} + +// ========================================================================================== +// Parser + +struct AsmParser { + previous_loc: Loc, + next_loc: Loc, + next: Token, + tokens: VecDeque<(Loc, Token)>, +} + +pub fn parse_asm(source: &str) -> AsmResult { + let mut tokens = scan(source.as_bytes())?; + let (loc, next) = tokens.pop_front().expect("scan returns at least one token"); + AsmParser { + previous_loc: loc, + next_loc: loc, + next, + tokens, + } + .unit() +} + +impl AsmParser { + fn advance(&mut self) -> AsmResult<()> { + if self.next == Token::End { + // Ignore -- there are infinite number of `End` from here + Ok(()) + } else { + self.previous_loc = self.next_loc; + (self.next_loc, self.next) = self.tokens.pop_front().unwrap(); + Ok(()) + } + } + + fn is_tok(&self, tok: &Token) -> bool { + tok == &self.next + } + + fn is_soft_kw(&self, kw: &str) -> bool { + matches!(&self.next, Token::Ident(s) if s == kw) + } + + fn is_special(&self, sp: &str) -> bool { + matches!(&self.next, Token::Special(s) if s == sp) + } + + fn is_indent(&self) -> bool { + matches!(self.next, Token::Indent(..)) + } + + fn lookahead_special(&self, sp: &str) -> bool { + matches!(&self.tokens[0].1, Token::Special(s) if s == sp) + } + + fn expect(&mut self, tok: &Token) -> AsmResult<()> { + if !self.is_tok(tok) { + Err(error( + self.next_loc, + format!("expected `{}`, found `{}`", tok, self.next), + )) + } else { + self.advance() + } + } + + fn expect_special(&mut self, sp: &str) -> AsmResult<()> { + if !self.is_special(sp) { + Err(error( + self.next_loc, + format!("expected `{}`, found `{}`", sp, self.next), + )) + } else { + self.advance() + } + } + + fn expect_soft_kw(&mut self, kw: &str) -> AsmResult<()> { + if !self.is_soft_kw(kw) { + Err(error( + self.next_loc, + format!("expected `{}`, found `{}`", kw, self.next), + )) + } else { + self.advance() + } + } + + fn expect_newline(&mut self) -> AsmResult<()> { + self.expect(&Token::Newline)?; + // Skip empty lines. + while self.is_tok(&Token::Newline) { + self.advance()? + } + Ok(()) + } + + fn list( + &mut self, + parser: impl Fn(&mut AsmParser) -> AsmResult, + separator: &str, + ) -> AsmResult> { + let mut result = vec![parser(self)?]; + while self.is_special(separator) { + self.advance()?; + result.push(parser(self)?) + } + Ok(result) + } + + fn value(&mut self) -> AsmResult { + if let Token::Number(num) = &self.next { + let num = *num; + self.advance()?; + Ok(Value::Number(num)) + } else { + Err(error(self.next_loc, "expected value")) + } + } + + fn is_value(&self) -> bool { + matches!(&self.next, Token::Number(..)) + } + + fn address(&mut self) -> AsmResult { + if let Token::Number(num) = &self.next { + let addr = AccountAddress::from_str(&num.to_string()).expect("valid number"); + self.advance()?; + Ok(addr) + } else { + Err(error(self.next_loc, "expected address value")) + } + } + + fn ident(&mut self) -> AsmResult { + if let Token::Ident(str) = &self.next { + let str = str.clone(); + self.advance()?; + Ok(Identifier::new_unchecked(str)) + } else { + Err(error(self.next_loc, "expected identifier")) + } + } + + fn is_ident(&self) -> bool { + matches!(&self.next, Token::Ident(..)) + } + + fn partial_ident(&mut self) -> AsmResult { + let address = if matches!(&self.next, Token::Number(..)) && self.lookahead_special("::") { + let addr = self.address()?; + self.advance()?; + Some(addr) + } else { + None + }; + let id_parts = self.list(Self::ident, "::")?; + Ok(PartialIdent { address, id_parts }) + } + + fn is_partial_ident(&self) -> bool { + matches!(&self.next, Token::Number(..)) && self.lookahead_special("::") + || matches!(&self.next, Token::Ident(..)) + } + + fn type_(&mut self) -> AsmResult { + if self.is_partial_ident() { + let pid = self.partial_ident()?; + let ty_args = self.type_args_opt()?; + Ok(Type::Named(pid, ty_args)) + } else if self.is_special("&") { + self.advance()?; + let is_mut = if self.is_soft_kw("mut") { + self.advance()?; + true + } else { + false + }; + Ok(Type::Ref(is_mut, Box::new(self.type_()?))) + } else if self.is_special("|") { + self.advance()?; + let arg_tys = if self.is_type() { + self.type_list()? + } else { + vec![] + }; + self.expect_special("|")?; + let res_tys = if self.is_type_tuple() { + self.type_tuple()? + } else { + vec![] + }; + let abs = if self.is_soft_kw("has") { + self.advance()?; + self.abilities()? + } else { + AbilitySet::EMPTY + }; + Ok(Type::Func(arg_tys, res_tys, abs)) + } else { + Err(error(self.next_loc, "expected type")) + } + } + + fn is_type(&self) -> bool { + self.is_partial_ident() + } + + fn type_list(&mut self) -> AsmResult> { + self.list(Self::type_, ",") + } + + fn type_tuple(&mut self) -> AsmResult> { + if self.is_type() { + Ok(vec![self.type_()?]) + } else if self.is_special("(") { + self.advance()?; + let res = self.type_list()?; + self.expect_special(")")?; + Ok(res) + } else { + Err(error(self.next_loc, "expected type or type tuple")) + } + } + + fn is_type_tuple(&self) -> bool { + self.is_type() || self.is_special("(") + } + + fn type_args_opt(&mut self) -> AsmResult>> { + if self.is_special("<") { + self.advance()?; + let res = self.type_list()?; + self.expect_special(">")?; + Ok(Some(res)) + } else { + Ok(None) + } + } + + fn abilities(&mut self) -> AsmResult { + let mut res = AbilitySet::EMPTY; + for ab in self.list(Self::ability, "+")? { + res = res.add(ab) + } + Ok(res) + } + + fn ability(&mut self) -> AsmResult { + let ident = self.ident()?; + let ab = match ident.as_str() { + "copy" => Ability::Copy, + "drop" => Ability::Drop, + "key" => Ability::Key, + "store" => Ability::Store, + _ => { + return Err(error( + self.next_loc, + "expected one of copy, drop, key, or store", + )) + }, + }; + Ok(ab) + } + + fn type_params(&mut self) -> AsmResult> { + if !self.is_special("<") { + return Ok(vec![]); + } + self.advance()?; + let result = self.list( + |parser| { + let name = parser.ident()?; + let abs = if parser.is_special(":") { + parser.advance()?; + parser.abilities()? + } else { + AbilitySet::EMPTY + }; + Ok((name, abs)) + }, + ",", + )?; + self.expect_special(">")?; + Ok(result) + } + + fn visibility(&mut self) -> AsmResult { + Ok(if self.is_soft_kw("public") { + self.advance()?; + Visibility::Public + } else if self.is_soft_kw("friend") { + self.advance()?; + Visibility::Friend + } else { + Visibility::Private + }) + } + + fn local_decl(&mut self) -> AsmResult { + let loc = self.next_loc; + let name = self.ident()?; + self.expect_special(":")?; + let ty = self.type_()?; + Ok(Local { loc, name, ty }) + } + + fn argument(&mut self) -> AsmResult { + if self.is_special("<") { + self.advance()?; + let ty = self.type_()?; + self.expect_special(">")?; + Ok(Argument::Type(ty)) + } else if self.is_value() { + let val = self.value()?; + Ok(Argument::Constant(val)) + } else { + let pid = self.partial_ident()?; + let targs = self.type_args_opt()?; + Ok(Argument::Id(pid, targs)) + } + } + + fn is_argument(&self) -> bool { + self.is_value() || self.is_partial_ident() || self.is_special("<") + } + + fn instr(&mut self) -> AsmResult { + let mut loc = self.next_loc; + let mut name = self.ident()?; + let label = if self.is_special(":") { + self.advance()?; + let label = Some(name); + loc = self.next_loc; + name = self.ident()?; + label + } else { + None + }; + let args = if self.is_argument() { + self.list(Self::argument, ",")? + } else { + vec![] + }; + // Extend loc to include args + let loc = Loc::new(loc.start(), self.previous_loc.end()); + Ok(Instruction { + loc, + label, + name, + args, + }) + } + + fn is_fun(&self) -> bool { + self.is_soft_kw("fun") || self.is_soft_kw("public") || self.is_soft_kw("friend") + } + + fn fun(&mut self) -> AsmResult { + let visibility = self.visibility()?; + self.expect_soft_kw("fun")?; + let loc = self.next_loc; + let name = self.ident()?; + let type_params = self.type_params()?; + self.expect_special("(")?; + let params = if self.is_ident() { + self.list(Self::local_decl, ",")? + } else { + vec![] + }; + self.expect_special(")")?; + let result = if self.is_special(":") { + self.advance()?; + self.type_tuple()? + } else { + vec![] + }; + self.expect_newline()?; + let mut locals = vec![]; + let mut instrs = vec![]; + while self.is_indent() || self.is_ident() && self.lookahead_special(":") { + if self.is_indent() { + self.advance()? + } + if self.is_soft_kw("local") { + if !instrs.is_empty() { + return Err(error( + self.next_loc, + "local declarations must precede instructions", + )); + } + self.advance()?; + let local = self.local_decl()?; + locals.push(local); + } else { + instrs.push(self.instr()?) + } + self.expect_newline()? + } + Ok(Fun { + loc, + name, + visibility, + type_params, + params, + locals, + result, + instrs, + }) + } + + fn module_id( + &mut self, + address_aliases: &BTreeMap<&IdentStr, AccountAddress>, + ) -> AsmResult { + let addr = if matches!(&self.next, Token::Number(..)) { + self.address()? + } else if self.is_ident() { + let id = self.ident()?; + if let Some(addr) = address_aliases.get(id.as_ident_str()) { + *addr + } else { + return Err(error( + self.next_loc, + format!("unknown address alias `{}`", id), + )); + } + } else { + return Err(error(self.next_loc, "expected address or address alias")); + }; + self.expect_special("::")?; + let id = self.ident()?; + Ok(ModuleId::new(addr, id)) + } + + fn unit(&mut self) -> AsmResult { + let mut address_aliases = vec![]; + while self.is_soft_kw("address") { + self.advance()?; + let name = self.ident()?; + self.expect_special("=")?; + let addr = self.address()?; + self.expect_newline()?; + address_aliases.push((name, addr)); + } + let address_alias_map: BTreeMap<&IdentStr, AccountAddress> = address_aliases + .iter() + .map(|(name, addr)| (name.as_ident_str(), *addr)) + .collect(); + let mut module_aliases = vec![]; + while self.is_soft_kw("use") { + self.advance()?; + let module = self.module_id(&address_alias_map)?; + self.expect_soft_kw("as")?; + let name = self.ident()?; + self.expect_newline()?; + module_aliases.push((name, module)); + } + let name = if self.is_soft_kw("module") { + self.advance()?; + UnitId::Module(self.module_id(&address_alias_map)?) + } else if self.is_soft_kw("script") { + UnitId::Script + } else { + return Err(error(self.next_loc, "expected `module` or `script` header")); + }; + self.expect_newline()?; + let mut functions = vec![]; + while self.is_fun() { + functions.push(self.fun()?) + } + self.expect(&Token::End)?; + Ok(Unit { + name, + address_aliases, + module_aliases, + functions, + }) + } +} + +// ------------------------------------------------------------------------------------------- +// Scanner + +#[derive(PartialEq, Eq, Debug)] +enum Token { + Number(U256), + Ident(String), + Special(String), + Newline, + Indent(usize), + End, +} + +fn scan(input: &[u8]) -> AsmResult> { + let mut pos = 0; + let end = input.len(); + let mut result = VecDeque::new(); + loop { + // Skip space + let mut start = pos; + while pos < end && matches!(input[pos], b' ' | b'\t' | b'\r') { + pos += 1 + } + // Skip comment + if pos < end && matches!(input[pos], b'#') { + pos += 1; + // Skip until end of line + while pos < end && !matches!(input[pos], b'\n') { + pos += 1 + } + start = pos; + } + // Terminate at end + if pos >= end { + result.push_back((loc(start..pos), Token::End)); + return Ok(result); + } + // Record indent + if pos > start && (start == 0 || matches!(result.back().unwrap().1, Token::Newline)) { + result.push_back((loc(start..pos), Token::Indent(pos - start))); + } + // Identify token + let start = pos; + let ch = input[pos] as char; + if ch == '\n' { + pos += 1; + result.push_back((loc(start..pos), Token::Newline)) + } else if ch.is_ascii_digit() { + let mut digits_start = pos; + let mut radix = 10; + pos += 1; + if pos < end && matches!(input[pos], b'x' | b'X') { + pos += 1; + digits_start = pos; + radix = 16 + } + while pos < end && (input[pos] as char).is_digit(radix) { + pos += 1 + } + let num_str: String = from_bytes(digits_start, &input[digits_start..pos])?; + let Ok(num) = U256::from_str_radix(&num_str, radix) else { + return Err(error( + loc(start..pos), + format!("invalid number `{}`", num_str), + )); + }; + result.push_back((loc(start..pos), Token::Number(num))) + } else if id_start(ch) { + pos += 1; + while pos < end && id_cont(input[pos] as char) { + pos += 1; + } + result.push_back(( + loc(start..pos), + Token::Ident(from_bytes(start, &input[start..pos])?), + )) + } else if special(ch) { + pos += 1; + if ch == ':' && pos < end && input[pos] == b':' { + pos += 1 + } + result.push_back(( + loc(start..pos), + Token::Special(from_bytes(start, &input[start..pos])?), + )); + } else { + return Err(error( + loc(start..pos), + format!("invalid character `{}`", ch), + )); + } + } +} + +fn from_bytes(pos: usize, b: &[u8]) -> AsmResult { + String::from_utf8(b.to_vec()) + .map_err(|_| error(loc(pos..pos + b.len()), "invalid bytes in source")) +} + +fn id_start(ch: char) -> bool { + ch.is_ascii_alphabetic() || ch == '_' || ch == '$' +} + +fn id_cont(ch: char) -> bool { + id_start(ch) || ch.is_ascii_digit() +} + +fn special(ch: char) -> bool { + matches!(ch, '(' | ')' | '<' | '>' | ',' | ':' | '|' | '+' | '=') +} + +impl Display for Token { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Token::Number(n) => write!(f, "{}", n), + Token::Ident(s) => f.write_str(s), + Token::Special(s) => f.write_str(s), + Token::Newline => f.write_str(""), + Token::Indent(_) => f.write_str(""), + Token::End => f.write_str(""), + } + } +} diff --git a/third_party/move/tools/move-asm/tests/address_alias.exp b/third_party/move/tools/move-asm/tests/address_alias.exp new file mode 100644 index 00000000000..400d21242d2 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/address_alias.exp @@ -0,0 +1,15 @@ +// Move bytecode v7 +module 102.test { + + +f(Arg0: u64): u64 /* def_idx: 0 */ { +B0: + 0: Ret +} +g() /* def_idx: 1 */ { +B0: + 0: LdU64(1) + 1: Call f(u64): u64 + 2: Ret +} +} diff --git a/third_party/move/tools/move-asm/tests/address_alias.masm b/third_party/move/tools/move-asm/tests/address_alias.masm new file mode 100644 index 00000000000..c3c05a7acfc --- /dev/null +++ b/third_party/move/tools/move-asm/tests/address_alias.masm @@ -0,0 +1,10 @@ +address acc = 0x66 +module acc::test + +fun f(x: u64): u64 + ret + +fun g() + ld_u64 1 + call acc::test::f + ret diff --git a/third_party/move/tools/move-asm/tests/branch.exp b/third_party/move/tools/move-asm/tests/branch.exp new file mode 100644 index 00000000000..aa395a2920f --- /dev/null +++ b/third_party/move/tools/move-asm/tests/branch.exp @@ -0,0 +1,20 @@ +// Move bytecode v7 +module 102.test { + + +f(Arg0: u64) /* def_idx: 0 */ { +B0: + 0: CopyLoc[0](Arg0: u64) + 1: LdU64(0) + 2: Gt + 3: BrFalse(9) +B1: + 4: CopyLoc[0](Arg0: u64) + 5: LdU64(1) + 6: Sub + 7: StLoc[0](Arg0: u64) + 8: Branch(0) +B2: + 9: Ret +} +} diff --git a/third_party/move/tools/move-asm/tests/branch.masm b/third_party/move/tools/move-asm/tests/branch.masm new file mode 100644 index 00000000000..ac0a8df96b7 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/branch.masm @@ -0,0 +1,13 @@ +module 0x66::test + +fun f(x: u64) +l1: copy_loc x + ld_u64 0 + gt + br_false l2 + copy_loc x + ld_u64 1 + sub + st_loc x + branch l1 +l2: ret diff --git a/third_party/move/tools/move-asm/tests/call_same_module.exp b/third_party/move/tools/move-asm/tests/call_same_module.exp new file mode 100644 index 00000000000..60729089401 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/call_same_module.exp @@ -0,0 +1,15 @@ +// Move bytecode v7 +module 102.test { + + +f(Arg0: u64): u64 /* def_idx: 0 */ { +B0: + 0: Ret +} +g(): u64 /* def_idx: 1 */ { +B0: + 0: LdU64(10) + 1: Call f(u64): u64 + 2: Ret +} +} diff --git a/third_party/move/tools/move-asm/tests/call_same_module.masm b/third_party/move/tools/move-asm/tests/call_same_module.masm new file mode 100644 index 00000000000..c33ee688486 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/call_same_module.masm @@ -0,0 +1,9 @@ +module 0x66::test + +fun f(x: u64): u64 + ret + +fun g(): u64 + ld_u64 10 + call f + ret diff --git a/third_party/move/tools/move-asm/tests/call_same_module_generic.exp b/third_party/move/tools/move-asm/tests/call_same_module_generic.exp new file mode 100644 index 00000000000..61807566472 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/call_same_module_generic.exp @@ -0,0 +1,15 @@ +// Move bytecode v7 +module 102.test { + + +f(Arg0: Ty0): Ty0 /* def_idx: 0 */ { +B0: + 0: Ret +} +g(): u64 /* def_idx: 1 */ { +B0: + 0: LdU64(10) + 1: Call f(u64): u64 + 2: Ret +} +} diff --git a/third_party/move/tools/move-asm/tests/call_same_module_generic.masm b/third_party/move/tools/move-asm/tests/call_same_module_generic.masm new file mode 100644 index 00000000000..af355cb0069 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/call_same_module_generic.masm @@ -0,0 +1,9 @@ +module 0x66::test + +fun f(x: A): A + ret + +fun g(): u64 + ld_u64 10 + call f + ret diff --git a/third_party/move/tools/move-asm/tests/call_same_module_undef.exp b/third_party/move/tools/move-asm/tests/call_same_module_undef.exp new file mode 100644 index 00000000000..b166a2a514c --- /dev/null +++ b/third_party/move/tools/move-asm/tests/call_same_module_undef.exp @@ -0,0 +1,6 @@ +--- Aborting with assembler errors: +error: undeclared function `f1` in `0000000000000000000000000000000000000000000000000000000000000102::test` + ┌─ tests/call_same_module_undef.masm:8:5 + │ +8 │ call f1 + │ ^^^^^^^ diff --git a/third_party/move/tools/move-asm/tests/call_same_module_undef.masm b/third_party/move/tools/move-asm/tests/call_same_module_undef.masm new file mode 100644 index 00000000000..7b8404d7759 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/call_same_module_undef.masm @@ -0,0 +1,9 @@ +module 0x66::test + +fun f(x: u64): u64 + ret + +fun g(): u64 + ld_u64 10 + call f1 + ret diff --git a/third_party/move/tools/move-asm/tests/closure.exp b/third_party/move/tools/move-asm/tests/closure.exp new file mode 100644 index 00000000000..665ce36d7ab --- /dev/null +++ b/third_party/move/tools/move-asm/tests/closure.exp @@ -0,0 +1,16 @@ +// Move bytecode v7 +module 102.test { + + +identity(Arg0: Ty0): Ty0 /* def_idx: 0 */ { +B0: + 0: Ret +} +test(): u64 /* def_idx: 1 */ { +B0: + 0: LdU64(2) + 1: PackClosureGeneric#1 identity(u64): u64 + 2: CallClosure(||u64 has drop) + 3: Ret +} +} diff --git a/third_party/move/tools/move-asm/tests/closure.masm b/third_party/move/tools/move-asm/tests/closure.masm new file mode 100644 index 00000000000..24eef5642d6 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/closure.masm @@ -0,0 +1,10 @@ +module 0x66::test + +fun identity(x: T): T + ret + +fun test(): u64 + ld_u64 2 + pack_closure identity, 1 + call_closure <||u64 has drop> + ret diff --git a/third_party/move/tools/move-asm/tests/declare_fun.exp b/third_party/move/tools/move-asm/tests/declare_fun.exp new file mode 100644 index 00000000000..206e1864fd6 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/declare_fun.exp @@ -0,0 +1,17 @@ +// Move bytecode v7 +module 102.test { + + +f(Arg0: u64): u64 /* def_idx: 0 */ { +L1: loc0: u64 +B0: + 0: CopyLoc[0](Arg0: u64) + 1: LdU64(1) + 2: Add + 3: StLoc[1](loc0: u64) + 4: MoveLoc[0](Arg0: u64) + 5: MoveLoc[1](loc0: u64) + 6: Mod + 7: Ret +} +} diff --git a/third_party/move/tools/move-asm/tests/declare_fun.masm b/third_party/move/tools/move-asm/tests/declare_fun.masm new file mode 100644 index 00000000000..e84f1e8cebd --- /dev/null +++ b/third_party/move/tools/move-asm/tests/declare_fun.masm @@ -0,0 +1,12 @@ +module 0x66::test + +fun f(x: u64): u64 + local y: u64 + copy_loc x + ld_u64 1 + add + st_loc y + move_loc x + move_loc y + mod + ret diff --git a/third_party/move/tools/move-asm/tests/declare_generic_fun.exp b/third_party/move/tools/move-asm/tests/declare_generic_fun.exp new file mode 100644 index 00000000000..284c46786c2 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/declare_generic_fun.exp @@ -0,0 +1,9 @@ +// Move bytecode v7 +module 102.test { + + +f(Arg0: Ty0, Arg1: Ty1): Ty0 * Ty1 /* def_idx: 0 */ { +B0: + 0: Ret +} +} diff --git a/third_party/move/tools/move-asm/tests/declare_generic_fun.masm b/third_party/move/tools/move-asm/tests/declare_generic_fun.masm new file mode 100644 index 00000000000..11944230b29 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/declare_generic_fun.masm @@ -0,0 +1,4 @@ +module 0x66::test + +fun f(x: A, y: B): (A, B) + ret diff --git a/third_party/move/tools/move-asm/tests/testsuite.rs b/third_party/move/tools/move-asm/tests/testsuite.rs new file mode 100644 index 00000000000..619e47cfdad --- /dev/null +++ b/third_party/move/tools/move-asm/tests/testsuite.rs @@ -0,0 +1,57 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use codespan_reporting::{files::SimpleFile, term, term::termcolor::Buffer}; +use either::Either; +use move_asm::{assemble, Options}; +use move_binary_format::binary_views::BinaryIndexedView; +use move_command_line_common::files::FileHash; +use move_disassembler::disassembler::Disassembler; +use move_prover_test_utils::baseline_test; +use std::{fs, path::Path}; + +pub const EXP_EXT: &str = "exp"; + +datatest_stable::harness!(test_runner, "tests", r".*\.masm$"); + +fn test_runner(path: &Path) -> datatest_stable::Result<()> { + let options = Options::default(); + let input = fs::read_to_string(path)?; + + let mut output = String::new(); + match assemble(&options, &input) { + Ok(result) => { + let view = match &result { + Either::Left(c) => BinaryIndexedView::Module(c), + Either::Right(s) => BinaryIndexedView::Script(s), + }; + let loc = move_ir_types::location::Loc::new(FileHash::new(&input), 0, 0); + let disasm = Disassembler::from_view(view, loc) + .expect("create disassembler") + .disassemble() + .expect("disassemble successful"); + output.push_str(&disasm) + }, + Err(diags) => { + let diag_file = SimpleFile::new(path.display().to_string(), &input); + let mut error_writer = Buffer::no_color(); + for diag in diags { + term::emit( + &mut error_writer, + &term::Config::default(), + &diag_file, + &diag, + ) + .unwrap_or_else(|_| eprintln!("failed to print diagnostics")) + } + output.push_str(&format!( + "--- Aborting with assembler errors:\n{}\n", + String::from_utf8_lossy(&error_writer.into_inner()) + )); + }, + } + // Generate/check baseline. + let baseline_path = path.with_extension(EXP_EXT); + baseline_test::verify_or_update_baseline(baseline_path.as_path(), &output)?; + Ok(()) +} diff --git a/third_party/move/tools/move-asm/tests/undef_label.exp b/third_party/move/tools/move-asm/tests/undef_label.exp new file mode 100644 index 00000000000..e0dd61a139e --- /dev/null +++ b/third_party/move/tools/move-asm/tests/undef_label.exp @@ -0,0 +1,6 @@ +--- Aborting with assembler errors: +error: unbound branch label `l3` + ┌─ tests/undef_label.masm:4:5 + │ +4 │ br_false l3 + │ ^^^^^^^^^^^ diff --git a/third_party/move/tools/move-asm/tests/undef_label.masm b/third_party/move/tools/move-asm/tests/undef_label.masm new file mode 100644 index 00000000000..45d5dfdcd5d --- /dev/null +++ b/third_party/move/tools/move-asm/tests/undef_label.masm @@ -0,0 +1,5 @@ +module 0x66::test + +fun f(x: u64) + br_false l3 +l2: ret diff --git a/third_party/move/tools/move-asm/tests/undef_local.exp b/third_party/move/tools/move-asm/tests/undef_local.exp new file mode 100644 index 00000000000..fc101709349 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/undef_local.exp @@ -0,0 +1,6 @@ +--- Aborting with assembler errors: +error: unknown local `z` + ┌─ tests/undef_local.masm:5:5 + │ +5 │ copy_loc z + │ ^^^^^^^^^^ diff --git a/third_party/move/tools/move-asm/tests/undef_local.masm b/third_party/move/tools/move-asm/tests/undef_local.masm new file mode 100644 index 00000000000..16ff8493dba --- /dev/null +++ b/third_party/move/tools/move-asm/tests/undef_local.masm @@ -0,0 +1,6 @@ +module 0x66::test + +fun f(x: u64): u64 + local y: u64 + copy_loc z + ret From 26fe009d3a66d99364b5c4a515d31bef36085951 Mon Sep 17 00:00:00 2001 From: Wolfgang Grieskamp Date: Wed, 16 Jul 2025 00:34:54 +0200 Subject: [PATCH 043/260] [move-asm] Integration into transactional test framework (#17063) * [move-asm] Integration into transactional test framework This connects the transactional test runner to the assembler. The existing tests have been modified to use this integration, as well as some specific tests added. Scripts are now fully supported and smaller bugfixes are done. * Addressing reviewer comments * Addressing reviewer comments Downstreamed-from: e703e390ec48dcf8e2885c5ba179bef1916c4c85 --- Cargo.lock | 11 +- .../move/move-binary-format/src/lib.rs | 1 + .../src/module_to_script.rs | 87 +++++++++++ .../move-command-line-common/src/files.rs | 2 + .../transactional-test-runner/Cargo.toml | 2 + .../src/framework.rs | 65 +++++++- .../transactional-test-runner/src/tasks.rs | 1 + third_party/move/tools/move-asm/Cargo.toml | 9 +- .../src/{compiler.rs => assembler.rs} | 7 +- third_party/move/tools/move-asm/src/lib.rs | 45 ++++-- third_party/move/tools/move-asm/src/main.rs | 6 +- .../move/tools/move-asm/src/module_builder.rs | 142 ++++++++++++------ third_party/move/tools/move-asm/src/syntax.rs | 26 +++- .../tools/move-asm/tests/address_alias.exp | 15 -- .../tests/assembler/address_alias.exp | 21 +++ .../tests/{ => assembler}/address_alias.masm | 3 +- .../move-asm/tests/{ => assembler}/branch.exp | 8 +- .../tests/{ => assembler}/branch.masm | 1 + .../{ => assembler}/call_same_module.exp | 11 +- .../{ => assembler}/call_same_module.masm | 2 + .../call_same_module_generic.exp | 11 +- .../call_same_module_generic.masm | 2 + .../assembler/call_same_module_undef.exp | 10 ++ .../call_same_module_undef.masm | 1 + .../tests/{ => assembler}/closure.exp | 11 +- .../tests/{ => assembler}/closure.masm | 2 + .../tests/{ => assembler}/declare_fun.exp | 8 +- .../tests/{ => assembler}/declare_fun.masm | 1 + .../tests/assembler/declare_generic_fun.exp | 17 +++ .../{ => assembler}/declare_generic_fun.masm | 3 + .../move-asm/tests/assembler/undef_label.exp | 10 ++ .../tests/{ => assembler}/undef_label.masm | 1 + .../move-asm/tests/assembler/undef_local.exp | 10 ++ .../tests/{ => assembler}/undef_local.masm | 1 + .../move-asm/tests/call_same_module_undef.exp | 6 - .../move-asm/tests/declare_generic_fun.exp | 9 -- .../move/tools/move-asm/tests/testsuite.rs | 79 ++++------ .../txn-test-integration/print_bytecode.exp | 27 ++++ .../txn-test-integration/print_bytecode.masm | 21 +++ .../publish_and_run_module.exp | 19 +++ .../publish_and_run_module.masm | 8 + .../publish_script_err.exp | 4 + .../publish_script_err.masm | 5 + .../move/tools/move-asm/tests/undef_label.exp | 6 - .../move/tools/move-asm/tests/undef_local.exp | 6 - 45 files changed, 552 insertions(+), 191 deletions(-) create mode 100644 third_party/move/move-binary-format/src/module_to_script.rs rename third_party/move/tools/move-asm/src/{compiler.rs => assembler.rs} (99%) delete mode 100644 third_party/move/tools/move-asm/tests/address_alias.exp create mode 100644 third_party/move/tools/move-asm/tests/assembler/address_alias.exp rename third_party/move/tools/move-asm/tests/{ => assembler}/address_alias.masm (69%) rename third_party/move/tools/move-asm/tests/{ => assembler}/branch.exp (67%) rename third_party/move/tools/move-asm/tests/{ => assembler}/branch.masm (84%) rename third_party/move/tools/move-asm/tests/{ => assembler}/call_same_module.exp (50%) rename third_party/move/tools/move-asm/tests/{ => assembler}/call_same_module.masm (67%) rename third_party/move/tools/move-asm/tests/{ => assembler}/call_same_module_generic.exp (52%) rename third_party/move/tools/move-asm/tests/{ => assembler}/call_same_module_generic.masm (68%) create mode 100644 third_party/move/tools/move-asm/tests/assembler/call_same_module_undef.exp rename third_party/move/tools/move-asm/tests/{ => assembler}/call_same_module_undef.masm (76%) rename third_party/move/tools/move-asm/tests/{ => assembler}/closure.exp (60%) rename third_party/move/tools/move-asm/tests/{ => assembler}/closure.masm (78%) rename third_party/move/tools/move-asm/tests/{ => assembler}/declare_fun.exp (67%) rename third_party/move/tools/move-asm/tests/{ => assembler}/declare_fun.masm (83%) create mode 100644 third_party/move/tools/move-asm/tests/assembler/declare_generic_fun.exp rename third_party/move/tools/move-asm/tests/{ => assembler}/declare_generic_fun.masm (50%) create mode 100644 third_party/move/tools/move-asm/tests/assembler/undef_label.exp rename third_party/move/tools/move-asm/tests/{ => assembler}/undef_label.masm (66%) create mode 100644 third_party/move/tools/move-asm/tests/assembler/undef_local.exp rename third_party/move/tools/move-asm/tests/{ => assembler}/undef_local.masm (72%) delete mode 100644 third_party/move/tools/move-asm/tests/call_same_module_undef.exp delete mode 100644 third_party/move/tools/move-asm/tests/declare_generic_fun.exp create mode 100644 third_party/move/tools/move-asm/tests/txn-test-integration/print_bytecode.exp create mode 100644 third_party/move/tools/move-asm/tests/txn-test-integration/print_bytecode.masm create mode 100644 third_party/move/tools/move-asm/tests/txn-test-integration/publish_and_run_module.exp create mode 100644 third_party/move/tools/move-asm/tests/txn-test-integration/publish_and_run_module.masm create mode 100644 third_party/move/tools/move-asm/tests/txn-test-integration/publish_script_err.exp create mode 100644 third_party/move/tools/move-asm/tests/txn-test-integration/publish_script_err.masm delete mode 100644 third_party/move/tools/move-asm/tests/undef_label.exp delete mode 100644 third_party/move/tools/move-asm/tests/undef_local.exp diff --git a/Cargo.lock b/Cargo.lock index 0e969526aa8..8776f5101b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11775,14 +11775,13 @@ dependencies = [ "clap 4.5.21", "codespan", "codespan-reporting", - "datatest-stable", "either", + "itertools 0.13.0", + "libtest-mimic", "move-binary-format", - "move-command-line-common", "move-core-types", - "move-disassembler", - "move-ir-types", - "move-prover-test-utils", + "move-transactional-test-runner", + "walkdir", ] [[package]] @@ -12492,7 +12491,9 @@ dependencies = [ "clap 4.5.21", "datatest-stable", "difference", + "either", "legacy-move-compiler", + "move-asm", "move-binary-format", "move-bytecode-source-map", "move-bytecode-verifier", diff --git a/third_party/move/move-binary-format/src/lib.rs b/third_party/move/move-binary-format/src/lib.rs index 9ffa05af1f8..9bd8061d535 100644 --- a/third_party/move/move-binary-format/src/lib.rs +++ b/third_party/move/move-binary-format/src/lib.rs @@ -22,6 +22,7 @@ pub mod deserializer; pub mod file_format; pub mod file_format_common; pub mod internals; +pub mod module_to_script; pub mod normalized; #[cfg(any(test, feature = "fuzzing"))] pub mod proptest_types; diff --git a/third_party/move/move-binary-format/src/module_to_script.rs b/third_party/move/move-binary-format/src/module_to_script.rs new file mode 100644 index 00000000000..4d1c6a86255 --- /dev/null +++ b/third_party/move/move-binary-format/src/module_to_script.rs @@ -0,0 +1,87 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + file_format::{CompiledScript, FunctionDefinition, FunctionHandle}, + CompiledModule, +}; +use anyhow::bail; + +/// Converts a compiled module into a script. The module must define exactly one function +/// and no types. The `main_handle` is the handle info of the one function in the module +/// which must not be contained in function_handles table. +pub fn convert_module_to_script( + module: CompiledModule, + main_handle: FunctionHandle, +) -> anyhow::Result { + let CompiledModule { + version, + self_module_handle_idx: _, + module_handles, + struct_handles, + function_handles, + field_handles: _, + friend_decls: _, + struct_def_instantiations: _, + field_instantiations: _, + struct_defs, + mut function_defs, + function_instantiations, + signatures, + identifiers, + address_identifiers, + constant_pool, + metadata, + struct_variant_handles: _, + struct_variant_instantiations: _, + variant_field_handles: _, + variant_field_instantiations: _, + } = module; + if function_defs.len() != 1 { + bail!("scripts can only contain one function") + } + if !struct_defs.is_empty() { + bail!("scripts cannot have struct or enum declarations") + } + let FunctionDefinition { + function: _, + visibility: _, + is_entry: _, + acquires_global_resources: _, + code, + } = function_defs.pop().unwrap(); + let Some(code) = code else { + bail!("script functions must have a body") + }; + let FunctionHandle { + module: _, + name: _, + parameters, + return_, + type_parameters, + access_specifiers, + attributes: _, + } = main_handle; + if signatures + .get(return_.0 as usize) + .map_or(true, |s| !s.is_empty()) + { + bail!("main function must not return values") + } + Ok(CompiledScript { + version, + module_handles, + struct_handles, + function_handles, + function_instantiations, + signatures, + identifiers, + address_identifiers, + constant_pool, + metadata, + code, + type_parameters, + parameters, + access_specifiers, + }) +} diff --git a/third_party/move/move-command-line-common/src/files.rs b/third_party/move/move-command-line-common/src/files.rs index 79b4e0e5c34..7557f0d059c 100644 --- a/third_party/move/move-command-line-common/src/files.rs +++ b/third_party/move/move-command-line-common/src/files.rs @@ -41,6 +41,8 @@ impl std::fmt::Debug for FileHash { pub const MOVE_EXTENSION: &str = "move"; /// Extension for Move IR files pub const MOVE_IR_EXTENSION: &str = "mvir"; +/// Extension for Move ASM files +pub const MOVE_ASM_EXTENSION: &str = "masm"; /// Extension for Move bytecode files pub const MOVE_COMPILED_EXTENSION: &str = "mv"; /// Extension for Move source map files (mappings from source to bytecode) diff --git a/third_party/move/testing-infra/transactional-test-runner/Cargo.toml b/third_party/move/testing-infra/transactional-test-runner/Cargo.toml index 2d04f1027e5..3f6ec59bd38 100644 --- a/third_party/move/testing-infra/transactional-test-runner/Cargo.toml +++ b/third_party/move/testing-infra/transactional-test-runner/Cargo.toml @@ -12,7 +12,9 @@ edition = "2021" [dependencies] anyhow = { workspace = true } clap = { workspace = true, features = ["derive"] } +either = { workspace = true } legacy-move-compiler = { workspace = true } +move-asm = { workspace = true } move-binary-format = { workspace = true, features = ["testing"] } move-bytecode-source-map = { workspace = true } move-bytecode-verifier = { workspace = true } diff --git a/third_party/move/testing-infra/transactional-test-runner/src/framework.rs b/third_party/move/testing-infra/transactional-test-runner/src/framework.rs index a44ee5f87e4..483dd66e581 100644 --- a/third_party/move/testing-infra/transactional-test-runner/src/framework.rs +++ b/third_party/move/testing-infra/transactional-test-runner/src/framework.rs @@ -11,9 +11,11 @@ use crate::{ }, vm_test_harness::{PrecompiledFilesModules, TestRunConfig}, }; -use anyhow::Result; +use anyhow::{anyhow, bail, Result}; use clap::Parser; +use either::Either; use legacy_move_compiler::{compiled_unit::AnnotatedCompiledUnit, shared::NumericalAddress}; +use move_asm::{self, ModuleOrScript}; use move_binary_format::{ binary_views::BinaryIndexedView, file_format::{CompiledModule, CompiledScript}, @@ -21,7 +23,7 @@ use move_binary_format::{ use move_bytecode_source_map::mapping::SourceMapping; use move_command_line_common::{ address::ParsedAddress, - files::{MOVE_EXTENSION, MOVE_IR_EXTENSION}, + files::{MOVE_ASM_EXTENSION, MOVE_EXTENSION, MOVE_IR_EXTENSION}, testing::{add_update_baseline_fix, format_diff, read_env_update_baseline, EXP_EXT}, types::ParsedType, values::{ParsableValue, ParsedValue}, @@ -42,6 +44,7 @@ use regex::Regex; use std::{ collections::{BTreeMap, BTreeSet, VecDeque}, fmt::{Debug, Write as FmtWrite}, + fs, io::Write, path::Path, str::FromStr, @@ -269,6 +272,10 @@ pub trait MoveTestAdapter<'a>: Sized { let module = compile_ir_module(state.dep_modules(), data_path)?; (None, module, None, None) }, + SyntaxChoice::ASM => { + let module = compile_asm_module(state.dep_modules(), data_path)?; + (None, module, None, None) + }, }; self.register_temp_filename(&data); Ok((data, named_addr_opt, module, opt_model, warnings_opt)) @@ -337,6 +344,10 @@ pub trait MoveTestAdapter<'a>: Sized { let script = compile_ir_script(state.dep_modules(), data_path)?; (script, None, None) }, + SyntaxChoice::ASM => { + let script = compile_asm_script(state.dep_modules(), data_path)?; + (script, None, None) + }, }; Ok((script, opt_model, warning_opt)) } @@ -426,6 +437,11 @@ pub trait MoveTestAdapter<'a>: Sized { self.compiled_state() .add_and_generate_interface_file(module); }, + SyntaxChoice::ASM => { + // TODO(#16582): generate source info for .masm file + self.compiled_state() + .add_and_generate_interface_file(module); + }, }; Ok(merge_output(warnings_opt, output)) }, @@ -602,7 +618,6 @@ pub trait MoveTestAdapter<'a>: Sized { } } } - fn disassembler_for_view(view: BinaryIndexedView) -> Disassembler { let source_mapping = SourceMapping::new_from_view(view, Spanned::unsafe_no_loc(()).loc).expect("source mapping"); @@ -818,6 +833,38 @@ fn compile_ir_script<'a>( Ok(script) } +fn compile_asm_module<'a>( + deps: impl Iterator, + path: &str, +) -> Result { + if let Either::Left(m) = compile_asm(deps, path)? { + Ok(m) + } else { + bail!("expected a module but found a script") + } +} + +fn compile_asm_script<'a>( + deps: impl Iterator, + path: &str, +) -> Result { + if let Either::Right(s) = compile_asm(deps, path)? { + Ok(s) + } else { + bail!("expected a script but found a module") + } +} + +fn compile_asm<'a>( + deps: impl Iterator, + path: &str, +) -> Result { + let options = move_asm::Options::default(); + let source = fs::read_to_string(path)?; + move_asm::assemble(&options, &source, deps) + .map_err(|diags| anyhow!(move_asm::diag_to_string("test", &source, diags))) +} + pub fn run_test_impl<'a, Adapter>( config: TestRunConfig, path: &Path, @@ -833,11 +880,13 @@ where Adapter::Subcommand: Debug, { let extension = path.extension().unwrap().to_str().unwrap(); - let default_syntax = if extension == MOVE_IR_EXTENSION { - SyntaxChoice::IR - } else { - assert!(extension == MOVE_EXTENSION); - SyntaxChoice::Source + let default_syntax = match extension { + MOVE_EXTENSION => SyntaxChoice::Source, + MOVE_IR_EXTENSION => SyntaxChoice::IR, + MOVE_ASM_EXTENSION => SyntaxChoice::ASM, + _ => { + panic!("unexpected extensions `{}`", extension) + }, }; let mut output = String::new(); diff --git a/third_party/move/testing-infra/transactional-test-runner/src/tasks.rs b/third_party/move/testing-infra/transactional-test-runner/src/tasks.rs index 8c1f1403e8b..32516f9ae47 100644 --- a/third_party/move/testing-infra/transactional-test-runner/src/tasks.rs +++ b/third_party/move/testing-infra/transactional-test-runner/src/tasks.rs @@ -190,6 +190,7 @@ impl TaskInput { pub enum SyntaxChoice { Source, IR, + ASM, } /// When printing bytecode, the input program must either be a script or a module. diff --git a/third_party/move/tools/move-asm/Cargo.toml b/third_party/move/tools/move-asm/Cargo.toml index a59cddd5042..59f406f07a0 100644 --- a/third_party/move/tools/move-asm/Cargo.toml +++ b/third_party/move/tools/move-asm/Cargo.toml @@ -16,14 +16,13 @@ codespan = { workspace = true } codespan-reporting = { workspace = true, features = ["serde", "serialization"] } either = { workspace = true } move-binary-format = { workspace = true } -move-command-line-common = { workspace = true } move-core-types = { workspace = true } [dev-dependencies] -datatest-stable = { workspace = true } -move-disassembler = { workspace = true } -move-ir-types = { workspace = true } # Because of Loc... -move-prover-test-utils = { workspace = true } +itertools = { workspace = true } +libtest-mimic = { workspace = true } +move-transactional-test-runner = { workspace = true } +walkdir = { workspace = true } [features] default = [] diff --git a/third_party/move/tools/move-asm/src/compiler.rs b/third_party/move/tools/move-asm/src/assembler.rs similarity index 99% rename from third_party/move/tools/move-asm/src/compiler.rs rename to third_party/move/tools/move-asm/src/assembler.rs index d1c5220f7e9..286d7831ae2 100644 --- a/third_party/move/tools/move-asm/src/compiler.rs +++ b/third_party/move/tools/move-asm/src/assembler.rs @@ -11,12 +11,13 @@ use crate::{ map_diag, Argument, AsmResult, Diag, Fun, Instruction, Loc, Local, Type, Unit, UnitId, Value, }, + ModuleOrScript, }; use either::Either; use move_binary_format::{ file_format::{ - Bytecode, CodeOffset, CompiledScript, FunctionDefinitionIndex, FunctionHandleIndex, - LocalIndex, SignatureIndex, SignatureToken, TableIndex, + Bytecode, CodeOffset, FunctionDefinitionIndex, FunctionHandleIndex, LocalIndex, + SignatureIndex, SignatureToken, TableIndex, }, CompiledModule, }; @@ -39,7 +40,7 @@ pub(crate) fn compile<'a>( options: ModuleBuilderOptions, context_modules: impl IntoIterator, ast: Unit, -) -> AsmResult> { +) -> AsmResult { let mut compiler = Assembler { builder: ModuleBuilder::new(options, context_modules, ast.name.module_opt()), diags: vec![], diff --git a/third_party/move/tools/move-asm/src/lib.rs b/third_party/move/tools/move-asm/src/lib.rs index 128074d9a00..d761d9a9a8b 100644 --- a/third_party/move/tools/move-asm/src/lib.rs +++ b/third_party/move/tools/move-asm/src/lib.rs @@ -3,7 +3,7 @@ //! Entry point into the Move assembler ('move-asm'). -pub mod compiler; +pub mod assembler; pub mod module_builder; pub mod syntax; @@ -11,17 +11,19 @@ use crate::{ module_builder::ModuleBuilderOptions, syntax::{AsmResult, Diag}, }; -use anyhow::bail; +use anyhow::{anyhow, bail}; use clap::Parser; use codespan_reporting::{ files::{Files, SimpleFile}, term, - term::termcolor::WriteColor, + term::{termcolor, termcolor::WriteColor}, }; use either::Either; use move_binary_format::{file_format::CompiledScript, CompiledModule}; use std::{fs, io::Write, path::PathBuf}; +pub type ModuleOrScript = Either; + #[derive(Parser, Clone, Debug, Default)] #[clap(author, version, about)] pub struct Options { @@ -29,6 +31,10 @@ pub struct Options { #[clap(flatten)] pub module_builder_options: ModuleBuilderOptions, + /// List of files with binary dependencies + #[clap(short, long)] + pub deps: Vec, + /// Directory where to place assembled code. #[clap(short, long, default_value = "")] pub output_dir: String, @@ -38,18 +44,26 @@ pub struct Options { } /// Assembles source as specified by options. -pub fn run(error_writer: &mut W) -> anyhow::Result<()> +pub fn run(options: Options, error_writer: &mut W) -> anyhow::Result<()> where W: Write + WriteColor, { - let options = Options::parse(); if options.inputs.len() != 1 { bail!("expected exactly one file name for the assembler source") } let input_path = options.inputs.first().unwrap(); let input = fs::read_to_string(input_path)?; - let result = match assemble(&options, &input) { + let context_modules = options + .deps + .iter() + .map(|file| { + let bytes = fs::read(file).map_err(|e| anyhow!(e))?; + CompiledModule::deserialize(&bytes).map_err(|e| anyhow!(e)) + }) + .collect::>>()?; + + let result = match assemble(&options, &input, context_modules.iter()) { Ok(x) => x, Err(diags) => { let diag_file = SimpleFile::new(&input_path, &input); @@ -82,17 +96,20 @@ where Ok(()) } -pub fn assemble( +pub fn assemble<'a>( options: &Options, input: &str, -) -> AsmResult> { + context_modules: impl Iterator, +) -> AsmResult { let ast = syntax::parse_asm(input)?; - let result = compiler::compile( - options.module_builder_options.clone(), - std::iter::empty(), - ast, - )?; - Ok(result) + assembler::compile(options.module_builder_options.clone(), context_modules, ast) +} + +pub fn diag_to_string(file_name: &str, source: &str, diags: Vec) -> String { + let files = SimpleFile::new(file_name, source); + let mut error_writer = termcolor::Buffer::no_color(); + report_diags(&mut error_writer, &files, diags); + String::from_utf8_lossy(&error_writer.into_inner()).to_string() } pub(crate) fn report_diags<'a, W: Write + WriteColor>( diff --git a/third_party/move/tools/move-asm/src/main.rs b/third_party/move/tools/move-asm/src/main.rs index abb32a7c09c..98d62bdcae2 100644 --- a/third_party/move/tools/move-asm/src/main.rs +++ b/third_party/move/tools/move-asm/src/main.rs @@ -1,12 +1,14 @@ // Copyright (c) Aptos Foundation // SPDX-License-Identifier: Apache-2.0 +use clap::Parser; use codespan_reporting::term::termcolor::{ColorChoice, StandardStream}; -use move_asm::run; +use move_asm::{run, Options}; fn main() { let mut error_writer = StandardStream::stderr(ColorChoice::Auto); - if let Err(e) = run(&mut error_writer) { + let options = Options::parse(); + if let Err(e) = run(options, &mut error_writer) { eprintln!("error: {:#}", e); std::process::exit(1) } diff --git a/third_party/move/tools/move-asm/src/module_builder.rs b/third_party/move/tools/move-asm/src/module_builder.rs index a7434473169..b3568bc5e2d 100644 --- a/third_party/move/tools/move-asm/src/module_builder.rs +++ b/third_party/move/tools/move-asm/src/module_builder.rs @@ -24,6 +24,7 @@ use move_binary_format::{ }, file_format_common::VERSION_DEFAULT, internals::ModuleIndex, + module_to_script::convert_module_to_script, views::{ FunctionDefinitionView, FunctionHandleView, ModuleHandleView, ModuleView, StructHandleView, }, @@ -72,6 +73,10 @@ pub struct ModuleBuilder<'a> { module_aliases: BTreeMap, /// The build module. module: RefCell, + /// If we are building a script, the handle of the main function. This must not + /// be contained in the handle table as it is removed when converting to + /// CompiledScript. + main_handle: RefCell>, /// The module index for which we generate code. this_module_idx: ModuleHandleIndex, /// A mapping from modules to indices. @@ -106,55 +111,81 @@ impl Display for QualifiedId { } impl<'a> ModuleBuilder<'a> { + /// Creates a new module builder, using the given context modules. If the + /// builder is for a script, `module_id_opt` should be `None`, otherwise + /// contain the module id. pub fn new( options: ModuleBuilderOptions, context_modules: impl IntoIterator, module_id_opt: Option<&ModuleId>, ) -> Self { - let mut module = CompiledModule { - version: options.bytecode_version, - self_module_handle_idx: ModuleHandleIndex(0), - ..Default::default() - }; - - module.module_handles.push(ModuleHandle { - address: AddressIdentifierIndex(0), - name: IdentifierIndex(0), - }); - let ModuleId { - address: script_address, - name: script_name, - } = language_storage::pseudo_script_module_id().clone(); - let (address, name) = if let Some(mid) = module_id_opt { - assert_ne!(mid.address, script_address, "address reserved for scripts"); - (mid.address, mid.name.clone()) - } else { - (script_address, script_name) - }; - module.address_identifiers.push(address); - module.identifiers.push(name); - let context_modules = context_modules .into_iter() .map(|m| (ModuleView::new(m).id(), m)) .collect(); - Self { - module: RefCell::new(module), - options, - context_modules, - ..Default::default() + if let Some(mid) = module_id_opt { + let mut module = CompiledModule { + version: options.bytecode_version, + self_module_handle_idx: ModuleHandleIndex(0), + ..Default::default() + }; + module.module_handles.push(ModuleHandle { + address: AddressIdentifierIndex(0), + name: IdentifierIndex(0), + }); + module.address_identifiers.push(mid.address); + module.identifiers.push(mid.name.clone()); + let builder = Self { + module: RefCell::new(module), + options, + context_modules, + ..Default::default() + }; + builder + .module_to_idx + .borrow_mut() + .insert(mid.clone(), ModuleHandleIndex::new(0)); + builder + .address_to_idx + .borrow_mut() + .insert(*mid.address(), AddressIdentifierIndex::new(0)); + builder + .name_to_idx + .borrow_mut() + .insert(mid.name().to_owned(), IdentifierIndex::new(0)); + builder + } else { + // Use a pseudo handle index for scripts + let module = CompiledModule { + version: options.bytecode_version, + self_module_handle_idx: Self::pseudo_script_module_index(), + ..Default::default() + }; + Self { + module: RefCell::new(module), + options, + context_modules, + ..Default::default() + } } } /// Return result as a module. pub fn into_module(self) -> Result { - Ok(self.module.take()) + if self.main_handle.borrow().is_some() { + bail!("a module cannot be built from a script") + } else { + Ok(self.module.take()) + } } /// Return result as a script. pub fn into_script(self) -> Result { - // TODO(#16582): script conversion - bail!("NYI: script conversion") + if let Some(handle) = self.main_handle.replace(None) { + convert_module_to_script(self.into_module()?, handle) + } else { + bail!("a script cannot be built from a module") + } } } @@ -220,14 +251,19 @@ impl<'a> ModuleBuilder<'a> { access_specifiers: None, attributes: vec![], }; - let fhdl_idx = self.index( - &mut self.module.borrow_mut().function_handles, - &mut self.fun_to_idx.borrow_mut(), - full_name, - fhdl, - FunctionHandleIndex, - "function handle", - )?; + let fhdl_idx = if self.is_script() { + *self.main_handle.borrow_mut() = Some(fhdl); + Self::pseudo_script_function_index() + } else { + self.index( + &mut self.module.borrow_mut().function_handles, + &mut self.fun_to_idx.borrow_mut(), + full_name, + fhdl, + FunctionHandleIndex, + "function handle", + )? + }; let fdef = FunctionDefinition { function: fhdl_idx, visibility, @@ -253,12 +289,16 @@ impl<'a> ModuleBuilder<'a> { } fn this_module(&self) -> ModuleId { - let module_ref = self.module.borrow(); - let view = ModuleHandleView::new( - &*module_ref, - &module_ref.module_handles[self.this_module_idx.0 as usize], - ); - view.module_id() + if self.is_script() { + language_storage::pseudo_script_module_id().clone() + } else { + let module_ref = self.module.borrow(); + let view = ModuleHandleView::new( + &*module_ref, + &module_ref.module_handles[self.this_module_idx.0 as usize], + ); + view.module_id() + } } fn this_module_id(&self, id: Identifier) -> QualifiedId { @@ -268,6 +308,18 @@ impl<'a> ModuleBuilder<'a> { } } + fn is_script(&self) -> bool { + self.module.borrow().self_module_handle_idx == Self::pseudo_script_module_index() + } + + fn pseudo_script_module_index() -> ModuleHandleIndex { + ModuleHandleIndex::new(TableIndex::MAX) + } + + fn pseudo_script_function_index() -> FunctionHandleIndex { + FunctionHandleIndex::new(TableIndex::MAX) + } + // ========================================================================================== // Resolving Names diff --git a/third_party/move/tools/move-asm/src/syntax.rs b/third_party/move/tools/move-asm/src/syntax.rs index e35ffdf67bd..36af5e5e0e9 100644 --- a/third_party/move/tools/move-asm/src/syntax.rs +++ b/third_party/move/tools/move-asm/src/syntax.rs @@ -66,7 +66,6 @@ use std::{ collections::{BTreeMap, VecDeque}, fmt::{Display, Formatter}, ops::Range, - str::FromStr, string::ToString, }; // ========================================================================================== @@ -271,6 +270,10 @@ impl AsmParser { } fn expect_newline(&mut self) -> AsmResult<()> { + if self.is_tok(&Token::End) { + // End of file can serve as newline, but is not consumed + return Ok(()); + } self.expect(&Token::Newline)?; // Skip empty lines. while self.is_tok(&Token::Newline) { @@ -308,7 +311,9 @@ impl AsmParser { fn address(&mut self) -> AsmResult { if let Token::Number(num) = &self.next { - let addr = AccountAddress::from_str(&num.to_string()).expect("valid number"); + let mut bytes = num.to_le_bytes().to_vec(); + bytes.reverse(); + let addr = AccountAddress::from_bytes(bytes).expect("valid address value"); self.advance()?; Ok(addr) } else { @@ -618,6 +623,12 @@ impl AsmParser { } fn unit(&mut self) -> AsmResult { + // Skip any empty lines at beginning of file. After that, further empty lines + // are consumed on line break. + while self.is_tok(&Token::Newline) { + self.advance()? + } + // Parse address and module aliases let mut address_aliases = vec![]; while self.is_soft_kw("address") { self.advance()?; @@ -640,15 +651,18 @@ impl AsmParser { self.expect_newline()?; module_aliases.push((name, module)); } + // Parse module header let name = if self.is_soft_kw("module") { self.advance()?; UnitId::Module(self.module_id(&address_alias_map)?) } else if self.is_soft_kw("script") { + self.advance()?; UnitId::Script } else { return Err(error(self.next_loc, "expected `module` or `script` header")); }; self.expect_newline()?; + // Parse definitions let mut functions = vec![]; while self.is_fun() { functions.push(self.fun()?) @@ -682,18 +696,18 @@ fn scan(input: &[u8]) -> AsmResult> { let mut result = VecDeque::new(); loop { // Skip space - let mut start = pos; + let start = pos; while pos < end && matches!(input[pos], b' ' | b'\t' | b'\r') { pos += 1 } // Skip comment - if pos < end && matches!(input[pos], b'#') { - pos += 1; + if pos + 1 < end && matches!(input[pos], b'/') && matches!(input[pos + 1], b'/') { + pos += 2; // Skip until end of line while pos < end && !matches!(input[pos], b'\n') { pos += 1 } - start = pos; + continue; } // Terminate at end if pos >= end { diff --git a/third_party/move/tools/move-asm/tests/address_alias.exp b/third_party/move/tools/move-asm/tests/address_alias.exp deleted file mode 100644 index 400d21242d2..00000000000 --- a/third_party/move/tools/move-asm/tests/address_alias.exp +++ /dev/null @@ -1,15 +0,0 @@ -// Move bytecode v7 -module 102.test { - - -f(Arg0: u64): u64 /* def_idx: 0 */ { -B0: - 0: Ret -} -g() /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Call f(u64): u64 - 2: Ret -} -} diff --git a/third_party/move/tools/move-asm/tests/assembler/address_alias.exp b/third_party/move/tools/move-asm/tests/assembler/address_alias.exp new file mode 100644 index 00000000000..2d729b7307e --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/address_alias.exp @@ -0,0 +1,21 @@ +processed 1 task + +task 0 'publish'. lines 1-11: + +== BEGIN Bytecode == +// Move bytecode v7 +module 66.test { + + +f(Arg0: u64) /* def_idx: 0 */ { +B0: + 0: Ret +} +g() /* def_idx: 1 */ { +B0: + 0: LdU64(1) + 1: Call f(u64) + 2: Ret +} +} +== END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/address_alias.masm b/third_party/move/tools/move-asm/tests/assembler/address_alias.masm similarity index 69% rename from third_party/move/tools/move-asm/tests/address_alias.masm rename to third_party/move/tools/move-asm/tests/assembler/address_alias.masm index c3c05a7acfc..a073bccdc15 100644 --- a/third_party/move/tools/move-asm/tests/address_alias.masm +++ b/third_party/move/tools/move-asm/tests/assembler/address_alias.masm @@ -1,7 +1,8 @@ +//# publish --print-bytecode address acc = 0x66 module acc::test -fun f(x: u64): u64 +fun f(x: u64) ret fun g() diff --git a/third_party/move/tools/move-asm/tests/branch.exp b/third_party/move/tools/move-asm/tests/assembler/branch.exp similarity index 67% rename from third_party/move/tools/move-asm/tests/branch.exp rename to third_party/move/tools/move-asm/tests/assembler/branch.exp index aa395a2920f..15829c161ec 100644 --- a/third_party/move/tools/move-asm/tests/branch.exp +++ b/third_party/move/tools/move-asm/tests/assembler/branch.exp @@ -1,5 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-14: + +== BEGIN Bytecode == // Move bytecode v7 -module 102.test { +module 66.test { f(Arg0: u64) /* def_idx: 0 */ { @@ -18,3 +23,4 @@ B2: 9: Ret } } +== END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/branch.masm b/third_party/move/tools/move-asm/tests/assembler/branch.masm similarity index 84% rename from third_party/move/tools/move-asm/tests/branch.masm rename to third_party/move/tools/move-asm/tests/assembler/branch.masm index ac0a8df96b7..6d7f9f11102 100644 --- a/third_party/move/tools/move-asm/tests/branch.masm +++ b/third_party/move/tools/move-asm/tests/assembler/branch.masm @@ -1,3 +1,4 @@ +//# publish --print-bytecode module 0x66::test fun f(x: u64) diff --git a/third_party/move/tools/move-asm/tests/call_same_module.exp b/third_party/move/tools/move-asm/tests/assembler/call_same_module.exp similarity index 50% rename from third_party/move/tools/move-asm/tests/call_same_module.exp rename to third_party/move/tools/move-asm/tests/assembler/call_same_module.exp index 60729089401..6413e9acad8 100644 --- a/third_party/move/tools/move-asm/tests/call_same_module.exp +++ b/third_party/move/tools/move-asm/tests/assembler/call_same_module.exp @@ -1,10 +1,16 @@ +processed 1 task + +task 0 'publish'. lines 1-11: + +== BEGIN Bytecode == // Move bytecode v7 -module 102.test { +module 66.test { f(Arg0: u64): u64 /* def_idx: 0 */ { B0: - 0: Ret + 0: MoveLoc[0](Arg0: u64) + 1: Ret } g(): u64 /* def_idx: 1 */ { B0: @@ -13,3 +19,4 @@ B0: 2: Ret } } +== END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/call_same_module.masm b/third_party/move/tools/move-asm/tests/assembler/call_same_module.masm similarity index 67% rename from third_party/move/tools/move-asm/tests/call_same_module.masm rename to third_party/move/tools/move-asm/tests/assembler/call_same_module.masm index c33ee688486..bc1fbf126b4 100644 --- a/third_party/move/tools/move-asm/tests/call_same_module.masm +++ b/third_party/move/tools/move-asm/tests/assembler/call_same_module.masm @@ -1,6 +1,8 @@ +//# publish --print-bytecode module 0x66::test fun f(x: u64): u64 + move_loc x ret fun g(): u64 diff --git a/third_party/move/tools/move-asm/tests/call_same_module_generic.exp b/third_party/move/tools/move-asm/tests/assembler/call_same_module_generic.exp similarity index 52% rename from third_party/move/tools/move-asm/tests/call_same_module_generic.exp rename to third_party/move/tools/move-asm/tests/assembler/call_same_module_generic.exp index 61807566472..fabd5d0f73b 100644 --- a/third_party/move/tools/move-asm/tests/call_same_module_generic.exp +++ b/third_party/move/tools/move-asm/tests/assembler/call_same_module_generic.exp @@ -1,10 +1,16 @@ +processed 1 task + +task 0 'publish'. lines 1-11: + +== BEGIN Bytecode == // Move bytecode v7 -module 102.test { +module 66.test { f(Arg0: Ty0): Ty0 /* def_idx: 0 */ { B0: - 0: Ret + 0: MoveLoc[0](Arg0: Ty0) + 1: Ret } g(): u64 /* def_idx: 1 */ { B0: @@ -13,3 +19,4 @@ B0: 2: Ret } } +== END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/call_same_module_generic.masm b/third_party/move/tools/move-asm/tests/assembler/call_same_module_generic.masm similarity index 68% rename from third_party/move/tools/move-asm/tests/call_same_module_generic.masm rename to third_party/move/tools/move-asm/tests/assembler/call_same_module_generic.masm index af355cb0069..523d2d18aa2 100644 --- a/third_party/move/tools/move-asm/tests/call_same_module_generic.masm +++ b/third_party/move/tools/move-asm/tests/assembler/call_same_module_generic.masm @@ -1,6 +1,8 @@ +//# publish --print-bytecode module 0x66::test fun f(x: A): A + move_loc x ret fun g(): u64 diff --git a/third_party/move/tools/move-asm/tests/assembler/call_same_module_undef.exp b/third_party/move/tools/move-asm/tests/assembler/call_same_module_undef.exp new file mode 100644 index 00000000000..f8b32ab66bd --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/call_same_module_undef.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-10: +Error: error: undeclared function `f1` in `0000000000000000000000000000000000000000000000000000000000000066::test` + ┌─ test:7:5 + │ +7 │ call f1 + │ ^^^^^^^ + + diff --git a/third_party/move/tools/move-asm/tests/call_same_module_undef.masm b/third_party/move/tools/move-asm/tests/assembler/call_same_module_undef.masm similarity index 76% rename from third_party/move/tools/move-asm/tests/call_same_module_undef.masm rename to third_party/move/tools/move-asm/tests/assembler/call_same_module_undef.masm index 7b8404d7759..1c657668d4d 100644 --- a/third_party/move/tools/move-asm/tests/call_same_module_undef.masm +++ b/third_party/move/tools/move-asm/tests/assembler/call_same_module_undef.masm @@ -1,3 +1,4 @@ +//# publish --print-bytecode module 0x66::test fun f(x: u64): u64 diff --git a/third_party/move/tools/move-asm/tests/closure.exp b/third_party/move/tools/move-asm/tests/assembler/closure.exp similarity index 60% rename from third_party/move/tools/move-asm/tests/closure.exp rename to third_party/move/tools/move-asm/tests/assembler/closure.exp index 665ce36d7ab..7b19126036f 100644 --- a/third_party/move/tools/move-asm/tests/closure.exp +++ b/third_party/move/tools/move-asm/tests/assembler/closure.exp @@ -1,10 +1,16 @@ +processed 1 task + +task 0 'publish'. lines 1-12: + +== BEGIN Bytecode == // Move bytecode v7 -module 102.test { +module 66.test { identity(Arg0: Ty0): Ty0 /* def_idx: 0 */ { B0: - 0: Ret + 0: MoveLoc[0](Arg0: Ty0) + 1: Ret } test(): u64 /* def_idx: 1 */ { B0: @@ -14,3 +20,4 @@ B0: 3: Ret } } +== END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/closure.masm b/third_party/move/tools/move-asm/tests/assembler/closure.masm similarity index 78% rename from third_party/move/tools/move-asm/tests/closure.masm rename to third_party/move/tools/move-asm/tests/assembler/closure.masm index 24eef5642d6..7858e8fc091 100644 --- a/third_party/move/tools/move-asm/tests/closure.masm +++ b/third_party/move/tools/move-asm/tests/assembler/closure.masm @@ -1,6 +1,8 @@ +//# publish --print-bytecode module 0x66::test fun identity(x: T): T + move_loc x ret fun test(): u64 diff --git a/third_party/move/tools/move-asm/tests/declare_fun.exp b/third_party/move/tools/move-asm/tests/assembler/declare_fun.exp similarity index 67% rename from third_party/move/tools/move-asm/tests/declare_fun.exp rename to third_party/move/tools/move-asm/tests/assembler/declare_fun.exp index 206e1864fd6..b521cc63eed 100644 --- a/third_party/move/tools/move-asm/tests/declare_fun.exp +++ b/third_party/move/tools/move-asm/tests/assembler/declare_fun.exp @@ -1,5 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-13: + +== BEGIN Bytecode == // Move bytecode v7 -module 102.test { +module 66.test { f(Arg0: u64): u64 /* def_idx: 0 */ { @@ -15,3 +20,4 @@ B0: 7: Ret } } +== END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/declare_fun.masm b/third_party/move/tools/move-asm/tests/assembler/declare_fun.masm similarity index 83% rename from third_party/move/tools/move-asm/tests/declare_fun.masm rename to third_party/move/tools/move-asm/tests/assembler/declare_fun.masm index e84f1e8cebd..1b841ca059e 100644 --- a/third_party/move/tools/move-asm/tests/declare_fun.masm +++ b/third_party/move/tools/move-asm/tests/assembler/declare_fun.masm @@ -1,3 +1,4 @@ +//# publish --print-bytecode module 0x66::test fun f(x: u64): u64 diff --git a/third_party/move/tools/move-asm/tests/assembler/declare_generic_fun.exp b/third_party/move/tools/move-asm/tests/assembler/declare_generic_fun.exp new file mode 100644 index 00000000000..c44cca40188 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/declare_generic_fun.exp @@ -0,0 +1,17 @@ +processed 1 task + +task 0 'publish'. lines 1-7: + +== BEGIN Bytecode == +// Move bytecode v7 +module 66.test { + + +f(Arg0: Ty0, Arg1: Ty1): Ty0 * Ty1 /* def_idx: 0 */ { +B0: + 0: MoveLoc[0](Arg0: Ty0) + 1: MoveLoc[1](Arg1: Ty1) + 2: Ret +} +} +== END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/declare_generic_fun.masm b/third_party/move/tools/move-asm/tests/assembler/declare_generic_fun.masm similarity index 50% rename from third_party/move/tools/move-asm/tests/declare_generic_fun.masm rename to third_party/move/tools/move-asm/tests/assembler/declare_generic_fun.masm index 11944230b29..a69690d08ae 100644 --- a/third_party/move/tools/move-asm/tests/declare_generic_fun.masm +++ b/third_party/move/tools/move-asm/tests/assembler/declare_generic_fun.masm @@ -1,4 +1,7 @@ +//# publish --print-bytecode module 0x66::test fun f(x: A, y: B): (A, B) + move_loc x + move_loc y ret diff --git a/third_party/move/tools/move-asm/tests/assembler/undef_label.exp b/third_party/move/tools/move-asm/tests/assembler/undef_label.exp new file mode 100644 index 00000000000..7394efb1f31 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/undef_label.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-6: +Error: error: unbound branch label `l3` + ┌─ test:4:5 + │ +4 │ br_false l3 + │ ^^^^^^^^^^^ + + diff --git a/third_party/move/tools/move-asm/tests/undef_label.masm b/third_party/move/tools/move-asm/tests/assembler/undef_label.masm similarity index 66% rename from third_party/move/tools/move-asm/tests/undef_label.masm rename to third_party/move/tools/move-asm/tests/assembler/undef_label.masm index 45d5dfdcd5d..3b4d5df3b54 100644 --- a/third_party/move/tools/move-asm/tests/undef_label.masm +++ b/third_party/move/tools/move-asm/tests/assembler/undef_label.masm @@ -1,3 +1,4 @@ +//# publish --print-bytecode module 0x66::test fun f(x: u64) diff --git a/third_party/move/tools/move-asm/tests/assembler/undef_local.exp b/third_party/move/tools/move-asm/tests/assembler/undef_local.exp new file mode 100644 index 00000000000..4213b6f0768 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/undef_local.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-7: +Error: error: unknown local `z` + ┌─ test:5:5 + │ +5 │ copy_loc z + │ ^^^^^^^^^^ + + diff --git a/third_party/move/tools/move-asm/tests/undef_local.masm b/third_party/move/tools/move-asm/tests/assembler/undef_local.masm similarity index 72% rename from third_party/move/tools/move-asm/tests/undef_local.masm rename to third_party/move/tools/move-asm/tests/assembler/undef_local.masm index 16ff8493dba..0b713d4714a 100644 --- a/third_party/move/tools/move-asm/tests/undef_local.masm +++ b/third_party/move/tools/move-asm/tests/assembler/undef_local.masm @@ -1,3 +1,4 @@ +//# publish --print-bytecode module 0x66::test fun f(x: u64): u64 diff --git a/third_party/move/tools/move-asm/tests/call_same_module_undef.exp b/third_party/move/tools/move-asm/tests/call_same_module_undef.exp deleted file mode 100644 index b166a2a514c..00000000000 --- a/third_party/move/tools/move-asm/tests/call_same_module_undef.exp +++ /dev/null @@ -1,6 +0,0 @@ ---- Aborting with assembler errors: -error: undeclared function `f1` in `0000000000000000000000000000000000000000000000000000000000000102::test` - ┌─ tests/call_same_module_undef.masm:8:5 - │ -8 │ call f1 - │ ^^^^^^^ diff --git a/third_party/move/tools/move-asm/tests/declare_generic_fun.exp b/third_party/move/tools/move-asm/tests/declare_generic_fun.exp deleted file mode 100644 index 284c46786c2..00000000000 --- a/third_party/move/tools/move-asm/tests/declare_generic_fun.exp +++ /dev/null @@ -1,9 +0,0 @@ -// Move bytecode v7 -module 102.test { - - -f(Arg0: Ty0, Arg1: Ty1): Ty0 * Ty1 /* def_idx: 0 */ { -B0: - 0: Ret -} -} diff --git a/third_party/move/tools/move-asm/tests/testsuite.rs b/third_party/move/tools/move-asm/tests/testsuite.rs index 619e47cfdad..5c9eef546b0 100644 --- a/third_party/move/tools/move-asm/tests/testsuite.rs +++ b/third_party/move/tools/move-asm/tests/testsuite.rs @@ -1,57 +1,32 @@ -// Copyright © Aptos Foundation +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors // SPDX-License-Identifier: Apache-2.0 -use codespan_reporting::{files::SimpleFile, term, term::termcolor::Buffer}; -use either::Either; -use move_asm::{assemble, Options}; -use move_binary_format::binary_views::BinaryIndexedView; -use move_command_line_common::files::FileHash; -use move_disassembler::disassembler::Disassembler; -use move_prover_test_utils::baseline_test; -use std::{fs, path::Path}; +pub const TEST_DIR: &str = "tests"; -pub const EXP_EXT: &str = "exp"; +use itertools::Itertools; +use libtest_mimic::{Arguments, Trial}; +use move_transactional_test_runner::vm_test_harness; +use walkdir::WalkDir; -datatest_stable::harness!(test_runner, "tests", r".*\.masm$"); - -fn test_runner(path: &Path) -> datatest_stable::Result<()> { - let options = Options::default(); - let input = fs::read_to_string(path)?; - - let mut output = String::new(); - match assemble(&options, &input) { - Ok(result) => { - let view = match &result { - Either::Left(c) => BinaryIndexedView::Module(c), - Either::Right(s) => BinaryIndexedView::Script(s), - }; - let loc = move_ir_types::location::Loc::new(FileHash::new(&input), 0, 0); - let disasm = Disassembler::from_view(view, loc) - .expect("create disassembler") - .disassemble() - .expect("disassemble successful"); - output.push_str(&disasm) - }, - Err(diags) => { - let diag_file = SimpleFile::new(path.display().to_string(), &input); - let mut error_writer = Buffer::no_color(); - for diag in diags { - term::emit( - &mut error_writer, - &term::Config::default(), - &diag_file, - &diag, - ) - .unwrap_or_else(|_| eprintln!("failed to print diagnostics")) - } - output.push_str(&format!( - "--- Aborting with assembler errors:\n{}\n", - String::from_utf8_lossy(&error_writer.into_inner()) - )); - }, - } - // Generate/check baseline. - let baseline_path = path.with_extension(EXP_EXT); - baseline_test::verify_or_update_baseline(baseline_path.as_path(), &output)?; - Ok(()) +fn main() { + let mut tests = WalkDir::new("tests") + .follow_links(false) + .min_depth(1) + .into_iter() + .flatten() + .filter_map(|e| { + let p = e.into_path(); + p.to_string_lossy().ends_with(".masm").then_some(p) + }) + .map(|p| { + let prompt = format!("move-asm-txn::{}", p.display()); + Trial::test(prompt, move || { + vm_test_harness::run_test(&p).map_err(|err| format!("{:?}", err).into()) + }) + }) + .collect_vec(); + tests.sort_unstable_by(|a, b| a.name().cmp(b.name())); + let args = Arguments::from_args(); + libtest_mimic::run(&args, tests).exit() } diff --git a/third_party/move/tools/move-asm/tests/txn-test-integration/print_bytecode.exp b/third_party/move/tools/move-asm/tests/txn-test-integration/print_bytecode.exp new file mode 100644 index 00000000000..06cbf225623 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/txn-test-integration/print_bytecode.exp @@ -0,0 +1,27 @@ +processed 3 tasks + +task 0 'print-bytecode'. lines 1-7: +Error: expected a script but found a module + +task 1 'print-bytecode'. lines 9-14: +// Move bytecode v7 +module 66.m { + + +public f(Arg0: u64): u64 /* def_idx: 0 */ { +B0: + 0: MoveLoc[0](Arg0: u64) + 1: Ret +} +} + +task 2 'print-bytecode'. lines 17-21: +// Move bytecode v7 +script { + + +main(Arg0: u64) /* def_idx: 0 */ { +B0: + 0: Ret +} +} diff --git a/third_party/move/tools/move-asm/tests/txn-test-integration/print_bytecode.masm b/third_party/move/tools/move-asm/tests/txn-test-integration/print_bytecode.masm new file mode 100644 index 00000000000..721f5490cc0 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/txn-test-integration/print_bytecode.masm @@ -0,0 +1,21 @@ +//# print-bytecode +// expecting error because default is script +module 0x66::m + +public fun f(x: u64): u64 + move_loc x + ret + +//# print-bytecode --input module +module 0x66::m + +public fun f(x: u64): u64 + move_loc x + ret + + +//# print-bytecode +script + +public fun f(x: u64) + ret diff --git a/third_party/move/tools/move-asm/tests/txn-test-integration/publish_and_run_module.exp b/third_party/move/tools/move-asm/tests/txn-test-integration/publish_and_run_module.exp new file mode 100644 index 00000000000..ce48b829746 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/txn-test-integration/publish_and_run_module.exp @@ -0,0 +1,19 @@ +processed 2 tasks + +task 0 'publish'. lines 1-6: + +== BEGIN Bytecode == +// Move bytecode v7 +module 66.m { + + +public f(Arg0: u64): u64 /* def_idx: 0 */ { +B0: + 0: MoveLoc[0](Arg0: u64) + 1: Ret +} +} +== END Bytecode == + +task 1 'run'. lines 8-8: +return values: 1 diff --git a/third_party/move/tools/move-asm/tests/txn-test-integration/publish_and_run_module.masm b/third_party/move/tools/move-asm/tests/txn-test-integration/publish_and_run_module.masm new file mode 100644 index 00000000000..41bc0122158 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/txn-test-integration/publish_and_run_module.masm @@ -0,0 +1,8 @@ +//# publish --print-bytecode +module 0x66::m + +public fun f(x: u64): u64 + move_loc x + ret + +//# run 0x66::m::f --args 1 --verbose diff --git a/third_party/move/tools/move-asm/tests/txn-test-integration/publish_script_err.exp b/third_party/move/tools/move-asm/tests/txn-test-integration/publish_script_err.exp new file mode 100644 index 00000000000..57bd34105b3 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/txn-test-integration/publish_script_err.exp @@ -0,0 +1,4 @@ +processed 1 task + +task 0 'publish'. lines 1-5: +Error: expected a module but found a script diff --git a/third_party/move/tools/move-asm/tests/txn-test-integration/publish_script_err.masm b/third_party/move/tools/move-asm/tests/txn-test-integration/publish_script_err.masm new file mode 100644 index 00000000000..0cd3dbc9548 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/txn-test-integration/publish_script_err.masm @@ -0,0 +1,5 @@ +//# publish --print-bytecode +script + +public fun f(x: u64) + ret diff --git a/third_party/move/tools/move-asm/tests/undef_label.exp b/third_party/move/tools/move-asm/tests/undef_label.exp deleted file mode 100644 index e0dd61a139e..00000000000 --- a/third_party/move/tools/move-asm/tests/undef_label.exp +++ /dev/null @@ -1,6 +0,0 @@ ---- Aborting with assembler errors: -error: unbound branch label `l3` - ┌─ tests/undef_label.masm:4:5 - │ -4 │ br_false l3 - │ ^^^^^^^^^^^ diff --git a/third_party/move/tools/move-asm/tests/undef_local.exp b/third_party/move/tools/move-asm/tests/undef_local.exp deleted file mode 100644 index fc101709349..00000000000 --- a/third_party/move/tools/move-asm/tests/undef_local.exp +++ /dev/null @@ -1,6 +0,0 @@ ---- Aborting with assembler errors: -error: unknown local `z` - ┌─ tests/undef_local.masm:5:5 - │ -5 │ copy_loc z - │ ^^^^^^^^^^ From 7f7475b31675ce47dacaec3ed54379d370671d0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20M=2E=20Gonz=C3=A1lez?= Date: Wed, 16 Jul 2025 14:16:29 -0300 Subject: [PATCH 044/260] Implemented assert_const linter. (#16776) assert_const flags assert!(true) and assert!(false) and suggests replacements. ... Downstreamed-from: e27cdd9ff4db21d5151c2f677cf6ce98777242d2 --- .../tools/move-linter/src/model_ast_lints.rs | 2 + .../src/model_ast_lints/assert_const.rs | 77 ++++++++++ .../tests/model_ast_lints/assert_const.exp | 121 ++++++++++++++++ .../tests/model_ast_lints/assert_const.move | 136 ++++++++++++++++++ 4 files changed, 336 insertions(+) create mode 100644 third_party/move/tools/move-linter/src/model_ast_lints/assert_const.rs create mode 100644 third_party/move/tools/move-linter/tests/model_ast_lints/assert_const.exp create mode 100644 third_party/move/tools/move-linter/tests/model_ast_lints/assert_const.move diff --git a/third_party/move/tools/move-linter/src/model_ast_lints.rs b/third_party/move/tools/move-linter/src/model_ast_lints.rs index 354f4d6d25e..8aedd7905fd 100644 --- a/third_party/move/tools/move-linter/src/model_ast_lints.rs +++ b/third_party/move/tools/move-linter/src/model_ast_lints.rs @@ -4,6 +4,7 @@ //! This module (and its submodules) contain various model-AST-based lint checks. mod almost_swapped; +mod assert_const; mod blocks_in_conditions; mod needless_bool; mod needless_deref_ref; @@ -22,6 +23,7 @@ use move_compiler_v2::external_checks::ExpChecker; pub fn get_default_linter_pipeline() -> Vec> { vec![ Box::::default(), + Box::::default(), Box::::default(), Box::::default(), Box::::default(), diff --git a/third_party/move/tools/move-linter/src/model_ast_lints/assert_const.rs b/third_party/move/tools/move-linter/src/model_ast_lints/assert_const.rs new file mode 100644 index 00000000000..28b93a0bdb3 --- /dev/null +++ b/third_party/move/tools/move-linter/src/model_ast_lints/assert_const.rs @@ -0,0 +1,77 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! This module implements an expression linter that checks for assert!()s +//! where the condition is either `true` or `false`. +//! Note: As a side-effect, the linter also checks if blocks that are +//! equivalent to asserts. For example, +//! +//! if (true){ +//! }else{ +//! abort(0) +//! }; +//! +//! The linter will flag the the entire if statement as if it were an assert!(). + +use move_compiler_v2::external_checks::ExpChecker; +use move_model::{ + ast::{ExpData, Operation, Value}, + model::FunctionEnv, +}; + +#[derive(Default)] +pub struct AssertConst; + +impl ExpChecker for AssertConst { + fn get_name(&self) -> String { + "assert_const".to_string() + } + + fn visit_expr_pre(&mut self, function: &FunctionEnv, expr: &ExpData) { + let env = function.env(); + if let ExpData::IfElse(id, condition, then, else_) = expr { + if !Self::is_assert(then, else_) { + return; + } + + let condition = Self::get_constant_bool_expression_value(condition); + if let Some(condition) = condition { + let string = if condition { + "This `assert!` can be removed" + } else { + "This `assert!` can replaced with an `abort`" + }; + self.report(env, &env.get_node_loc(*id), string); + } + } + } +} + +impl AssertConst { + fn empty_block(block: &ExpData) -> bool { + if let ExpData::Call(_, Operation::Tuple, exprs) = block { + exprs.is_empty() + } else { + false + } + } + + fn abort_block(block: &ExpData) -> bool { + matches!(block, ExpData::Call(_, Operation::Abort, _)) + } + + /// Returns true if the then and else blocks of an if statements might have + /// been expanded from an assert! macro. Note that is_assert() may return + /// true even if the if statement is literal at the source code instead of + /// being the result of a macro expansion. + fn is_assert(then: &ExpData, else_: &ExpData) -> bool { + Self::empty_block(then) && Self::abort_block(else_) + } + + fn get_constant_bool_expression_value(expr: &ExpData) -> Option { + match expr { + ExpData::Value(_, Value::Bool(x)) => Some(*x), + _ => None, + } + } +} diff --git a/third_party/move/tools/move-linter/tests/model_ast_lints/assert_const.exp b/third_party/move/tools/move-linter/tests/model_ast_lints/assert_const.exp new file mode 100644 index 00000000000..fcb051c7fe8 --- /dev/null +++ b/third_party/move/tools/move-linter/tests/model_ast_lints/assert_const.exp @@ -0,0 +1,121 @@ + +Diagnostics: +warning: [lint] This `assert!` can be removed + ┌─ tests/model_ast_lints/assert_const.move:6:9 + │ +6 │ assert!(true); + │ ^^^^^^ + │ + = To suppress this warning, annotate the function/module with the attribute `#[lint::skip(assert_const)]`. + = For more information, see https://aptos.dev/en/build/smart-contracts/linter#assert_const. + +warning: [lint] This `assert!` can replaced with an `abort` + ┌─ tests/model_ast_lints/assert_const.move:10:9 + │ +10 │ assert!(false); + │ ^^^^^^ + │ + = To suppress this warning, annotate the function/module with the attribute `#[lint::skip(assert_const)]`. + = For more information, see https://aptos.dev/en/build/smart-contracts/linter#assert_const. + +warning: [lint] This `assert!` can be removed + ┌─ tests/model_ast_lints/assert_const.move:14:9 + │ +14 │ assert!(CONSTANT_TRUE); + │ ^^^^^^ + │ + = To suppress this warning, annotate the function/module with the attribute `#[lint::skip(assert_const)]`. + = For more information, see https://aptos.dev/en/build/smart-contracts/linter#assert_const. + +warning: [lint] This `assert!` can replaced with an `abort` + ┌─ tests/model_ast_lints/assert_const.move:18:9 + │ +18 │ assert!(CONSTANT_FALSE); + │ ^^^^^^ + │ + = To suppress this warning, annotate the function/module with the attribute `#[lint::skip(assert_const)]`. + = For more information, see https://aptos.dev/en/build/smart-contracts/linter#assert_const. + +warning: [lint] This `assert!` can be removed + ┌─ tests/model_ast_lints/assert_const.move:22:9 + │ +22 │ assert!(true, 42); + │ ^^^^^^ + │ + = To suppress this warning, annotate the function/module with the attribute `#[lint::skip(assert_const)]`. + = For more information, see https://aptos.dev/en/build/smart-contracts/linter#assert_const. + +warning: [lint] This `assert!` can replaced with an `abort` + ┌─ tests/model_ast_lints/assert_const.move:26:9 + │ +26 │ assert!(false, 42); + │ ^^^^^^ + │ + = To suppress this warning, annotate the function/module with the attribute `#[lint::skip(assert_const)]`. + = For more information, see https://aptos.dev/en/build/smart-contracts/linter#assert_const. + +warning: [lint] This `assert!` can be removed + ┌─ tests/model_ast_lints/assert_const.move:30:9 + │ +30 │ assert!(CONSTANT_TRUE, 42); + │ ^^^^^^ + │ + = To suppress this warning, annotate the function/module with the attribute `#[lint::skip(assert_const)]`. + = For more information, see https://aptos.dev/en/build/smart-contracts/linter#assert_const. + +warning: [lint] This `assert!` can replaced with an `abort` + ┌─ tests/model_ast_lints/assert_const.move:34:9 + │ +34 │ assert!(CONSTANT_FALSE, 42); + │ ^^^^^^ + │ + = To suppress this warning, annotate the function/module with the attribute `#[lint::skip(assert_const)]`. + = For more information, see https://aptos.dev/en/build/smart-contracts/linter#assert_const. + +warning: [lint] This `assert!` can be removed + ┌─ tests/model_ast_lints/assert_const.move:38:9 + │ +38 │ ╭ if (true){ +39 │ │ }else{ +40 │ │ abort(0) +41 │ │ }; + │ ╰─────────^ + │ + = To suppress this warning, annotate the function/module with the attribute `#[lint::skip(assert_const)]`. + = For more information, see https://aptos.dev/en/build/smart-contracts/linter#assert_const. + +warning: [lint] This `assert!` can replaced with an `abort` + ┌─ tests/model_ast_lints/assert_const.move:45:9 + │ +45 │ ╭ if (false){ +46 │ │ }else{ +47 │ │ abort(0) +48 │ │ }; + │ ╰─────────^ + │ + = To suppress this warning, annotate the function/module with the attribute `#[lint::skip(assert_const)]`. + = For more information, see https://aptos.dev/en/build/smart-contracts/linter#assert_const. + +warning: [lint] This `assert!` can be removed + ┌─ tests/model_ast_lints/assert_const.move:52:9 + │ +52 │ ╭ if (CONSTANT_TRUE){ +53 │ │ }else{ +54 │ │ abort(0) +55 │ │ }; + │ ╰─────────^ + │ + = To suppress this warning, annotate the function/module with the attribute `#[lint::skip(assert_const)]`. + = For more information, see https://aptos.dev/en/build/smart-contracts/linter#assert_const. + +warning: [lint] This `assert!` can replaced with an `abort` + ┌─ tests/model_ast_lints/assert_const.move:59:9 + │ +59 │ ╭ if (CONSTANT_FALSE){ +60 │ │ }else{ +61 │ │ abort(0) +62 │ │ }; + │ ╰─────────^ + │ + = To suppress this warning, annotate the function/module with the attribute `#[lint::skip(assert_const)]`. + = For more information, see https://aptos.dev/en/build/smart-contracts/linter#assert_const. diff --git a/third_party/move/tools/move-linter/tests/model_ast_lints/assert_const.move b/third_party/move/tools/move-linter/tests/model_ast_lints/assert_const.move new file mode 100644 index 00000000000..0a93d27b722 --- /dev/null +++ b/third_party/move/tools/move-linter/tests/model_ast_lints/assert_const.move @@ -0,0 +1,136 @@ +module 0xc0ffee::m { + const CONSTANT_TRUE: bool = true; + const CONSTANT_FALSE: bool = false; + + public fun test1_warn() { + assert!(true); + } + + public fun test2_warn() { + assert!(false); + } + + public fun test3_warn() { + assert!(CONSTANT_TRUE); + } + + public fun test4_warn() { + assert!(CONSTANT_FALSE); + } + + public fun test5_warn() { + assert!(true, 42); + } + + public fun test6_warn() { + assert!(false, 42); + } + + public fun test7_warn() { + assert!(CONSTANT_TRUE, 42); + } + + public fun test8_warn() { + assert!(CONSTANT_FALSE, 42); + } + + public fun test9_warn() { + if (true){ + }else{ + abort(0) + }; + } + + public fun test10_warn() { + if (false){ + }else{ + abort(0) + }; + } + + public fun test11_warn() { + if (CONSTANT_TRUE){ + }else{ + abort(0) + }; + } + + public fun test12_warn() { + if (CONSTANT_FALSE){ + }else{ + abort(0) + }; + } + + #[lint::skip(assert_const)] + public fun test1_no_warn() { + assert!(true); + } + + #[lint::skip(assert_const)] + public fun test2_no_warn() { + assert!(false); + } + + #[lint::skip(assert_const)] + public fun test3_no_warn() { + assert!(CONSTANT_TRUE); + } + + #[lint::skip(assert_const)] + public fun test4_no_warn() { + assert!(CONSTANT_FALSE); + } + + #[lint::skip(assert_const)] + public fun test5_no_warn() { + assert!(true, 42); + } + + #[lint::skip(assert_const)] + public fun test6_no_warn() { + assert!(false, 42); + } + + #[lint::skip(assert_const)] + public fun test7_no_warn() { + assert!(CONSTANT_TRUE, 42); + } + + #[lint::skip(assert_const)] + public fun test8_no_warn() { + assert!(CONSTANT_FALSE, 42); + } + + #[lint::skip(assert_const)] + public fun test9_no_warn() { + if (true){ + }else{ + abort(0) + }; + } + + #[lint::skip(assert_const)] + public fun test10_no_warn() { + if (false){ + }else{ + abort(0) + }; + } + + #[lint::skip(assert_const)] + public fun test11_no_warn() { + if (CONSTANT_TRUE){ + }else{ + abort(0) + }; + } + + #[lint::skip(assert_const)] + public fun test12_no_warn() { + if (CONSTANT_FALSE){ + }else{ + abort(0) + }; + } +} From 24c56a629aee41343916c798f2e365a83c71b948 Mon Sep 17 00:00:00 2001 From: Sital Kedia Date: Wed, 16 Jul 2025 10:34:03 -0700 Subject: [PATCH 045/260] Increase max layout default size from 256 to 512 (#17083) Downstreamed-from: a0d83bdf27b991b852be08e7c9ca84ca630a51a5 --- third_party/move/move-vm/runtime/src/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/move/move-vm/runtime/src/config.rs b/third_party/move/move-vm/runtime/src/config.rs index 98be2e5f490..87da37bf255 100644 --- a/third_party/move/move-vm/runtime/src/config.rs +++ b/third_party/move/move-vm/runtime/src/config.rs @@ -42,7 +42,7 @@ impl Default for VMConfig { paranoid_type_checks: false, check_invariant_in_swap_loc: true, max_value_nest_depth: Some(DEFAULT_MAX_VM_VALUE_NESTED_DEPTH), - layout_max_size: 256, + layout_max_size: 512, layout_max_depth: 128, type_max_cost: 0, type_base_cost: 0, From 5d6470ea7f5eabe79723e88086e0760a2d885736 Mon Sep 17 00:00:00 2001 From: Teng Zhang Date: Thu, 17 Jul 2025 20:46:46 +0000 Subject: [PATCH 046/260] add native (#17036) Downstreamed-from: 6b8e7f50442ccade5b3ef11fff520d04b1a7fe56 --- .../aptos-framework/doc/big_ordered_map.md | 844 ++++++++++++++++++ .../framework/aptos-framework/doc/jwks.md | 224 +++++ .../datastructures/big_ordered_map.spec.move | 255 ++++++ .../aptos-framework/sources/jwks.spec.move | 58 ++ .../framework/move-stdlib/doc/vector.md | 12 +- .../framework/move-stdlib/sources/vector.move | 12 +- .../move-prover/boogie-backend/src/lib.rs | 3 + .../boogie-backend/src/prelude/native.bpl | 17 + .../boogie-backend/src/prelude/prelude.bpl | 12 + .../boogie-backend/src/spec_translator.rs | 25 +- .../tests/sources/functional/choice.move | 9 + 11 files changed, 1463 insertions(+), 8 deletions(-) create mode 100644 aptos-move/framework/aptos-framework/sources/datastructures/big_ordered_map.spec.move diff --git a/aptos-move/framework/aptos-framework/doc/big_ordered_map.md b/aptos-move/framework/aptos-framework/doc/big_ordered_map.md index b5d0b75b5a4..7f3a5ce0016 100644 --- a/aptos-move/framework/aptos-framework/doc/big_ordered_map.md +++ b/aptos-move/framework/aptos-framework/doc/big_ordered_map.md @@ -101,6 +101,44 @@ allowing cleaner iterator APIs. - [Function `update_key`](#0x1_big_ordered_map_update_key) - [Function `remove_at`](#0x1_big_ordered_map_remove_at) - [Specification](#@Specification_1) + - [Enum `BigOrderedMap`](#@Specification_1_BigOrderedMap) + - [Function `new`](#@Specification_1_new) + - [Function `new_with_reusable`](#@Specification_1_new_with_reusable) + - [Function `new_with_type_size_hints`](#@Specification_1_new_with_type_size_hints) + - [Function `new_with_config`](#@Specification_1_new_with_config) + - [Function `new_from`](#@Specification_1_new_from) + - [Function `destroy_empty`](#@Specification_1_destroy_empty) + - [Function `allocate_spare_slots`](#@Specification_1_allocate_spare_slots) + - [Function `is_empty`](#@Specification_1_is_empty) + - [Function `compute_length`](#@Specification_1_compute_length) + - [Function `add`](#@Specification_1_add) + - [Function `upsert`](#@Specification_1_upsert) + - [Function `remove`](#@Specification_1_remove) + - [Function `add_all`](#@Specification_1_add_all) + - [Function `pop_front`](#@Specification_1_pop_front) + - [Function `pop_back`](#@Specification_1_pop_back) + - [Function `lower_bound`](#@Specification_1_lower_bound) + - [Function `find`](#@Specification_1_find) + - [Function `contains`](#@Specification_1_contains) + - [Function `borrow`](#@Specification_1_borrow) + - [Function `borrow_mut`](#@Specification_1_borrow_mut) + - [Function `borrow_front`](#@Specification_1_borrow_front) + - [Function `borrow_back`](#@Specification_1_borrow_back) + - [Function `prev_key`](#@Specification_1_prev_key) + - [Function `next_key`](#@Specification_1_next_key) + - [Function `keys`](#@Specification_1_keys) + - [Function `new_begin_iter`](#@Specification_1_new_begin_iter) + - [Function `new_end_iter`](#@Specification_1_new_end_iter) + - [Function `iter_is_begin`](#@Specification_1_iter_is_begin) + - [Function `iter_is_end`](#@Specification_1_iter_is_end) + - [Function `iter_borrow_key`](#@Specification_1_iter_borrow_key) + - [Function `iter_borrow`](#@Specification_1_iter_borrow) + - [Function `iter_borrow_mut`](#@Specification_1_iter_borrow_mut) + - [Function `iter_next`](#@Specification_1_iter_next) + - [Function `iter_prev`](#@Specification_1_iter_prev) + - [Function `validate_dynamic_size_and_init_max_degrees`](#@Specification_1_validate_dynamic_size_and_init_max_degrees) + - [Function `validate_static_size_and_init_max_degrees`](#@Specification_1_validate_static_size_and_init_max_degrees) + - [Function `validate_size_and_init_max_degrees`](#@Specification_1_validate_size_and_init_max_degrees) - [Function `add_at`](#@Specification_1_add_at) - [Function `remove_at`](#@Specification_1_remove_at) @@ -3052,6 +3090,812 @@ Given a path to node (excluding the node itself), which is currently stored unde + + +### Enum `BigOrderedMap` + + +
enum BigOrderedMap<K: store, V: store> has store
+
+ + + +
+ +
+BPlusTreeMap + + +
+Fields + + +
+
+root: big_ordered_map::Node<K, V> +
+
+ Root node. It is stored directly in the resource itself, unlike all other nodes. +
+
+nodes: storage_slots_allocator::StorageSlotsAllocator<big_ordered_map::Node<K, V>> +
+
+ Storage of all non-root nodes. They are stored in separate storage slots. +
+
+min_leaf_index: u64 +
+
+ The node index of the leftmost node. +
+
+max_leaf_index: u64 +
+
+ The node index of the rightmost node. +
+
+constant_kv_size: bool +
+
+ Whether Key and Value have constant serialized size, and if so, + optimize out size checks on every insert. +
+
+inner_max_degree: u16 +
+
+ The max number of children an inner node can have. +
+
+leaf_max_degree: u16 +
+
+ The max number of children a leaf node can have. +
+
+ + +
+ +
+
+ + + +
pragma intrinsic = map,
+    map_new = new,
+    map_destroy_empty = destroy_empty,
+    map_has_key = contains,
+    map_add_no_override = add,
+    map_borrow = borrow,
+    map_borrow_mut = borrow_mut,
+    map_spec_get = spec_get,
+    map_spec_set = spec_set,
+    map_spec_del = spec_remove,
+    map_spec_len = spec_len,
+    map_spec_has_key = spec_contains_key,
+    map_is_empty = is_empty;
+
+ + + + + + + +
native fun spec_len<K, V>(t: BigOrderedMap<K, V>): num;
+
+ + + + + + + +
native fun spec_contains_key<K, V>(t: BigOrderedMap<K, V>, k: K): bool;
+
+ + + + + + + +
native fun spec_set<K, V>(t: BigOrderedMap<K, V>, k: K, v: V): BigOrderedMap<K, V>;
+
+ + + + + + + +
native fun spec_remove<K, V>(t: BigOrderedMap<K, V>, k: K): BigOrderedMap<K, V>;
+
+ + + + + + + +
native fun spec_get<K, V>(t: BigOrderedMap<K, V>, k: K): V;
+
+ + + + + +### Function `new` + + +
public fun new<K: store, V: store>(): big_ordered_map::BigOrderedMap<K, V>
+
+ + + + +
pragma intrinsic;
+
+ + + + + +### Function `new_with_reusable` + + +
public fun new_with_reusable<K: store, V: store>(): big_ordered_map::BigOrderedMap<K, V>
+
+ + + + +
pragma verify = false;
+pragma opaque;
+
+ + + + + +### Function `new_with_type_size_hints` + + +
public fun new_with_type_size_hints<K: store, V: store>(avg_key_bytes: u64, max_key_bytes: u64, avg_value_bytes: u64, max_value_bytes: u64): big_ordered_map::BigOrderedMap<K, V>
+
+ + + + +
pragma verify = false;
+pragma opaque;
+
+ + + + + +### Function `new_with_config` + + +
public fun new_with_config<K: store, V: store>(inner_max_degree: u16, leaf_max_degree: u16, reuse_slots: bool): big_ordered_map::BigOrderedMap<K, V>
+
+ + + + +
pragma verify = false;
+pragma opaque;
+
+ + + + + +### Function `new_from` + + +
public fun new_from<K: copy, drop, store, V: store>(keys: vector<K>, values: vector<V>): big_ordered_map::BigOrderedMap<K, V>
+
+ + + + +
pragma opaque;
+pragma verify = false;
+aborts_if [abstract] exists i in 0..len(keys), j in 0..len(keys) where i != j : keys[i] == keys[j];
+aborts_if [abstract] len(keys) != len(values);
+ensures [abstract] forall k: K {spec_contains_key(result, k)} : vector::spec_contains(keys,k) <==> spec_contains_key(result, k);
+ensures [abstract] forall i in 0..len(keys) : spec_get(result, keys[i]) == values[i];
+ensures [abstract] spec_len(result) == len(keys);
+
+ + + + + +### Function `destroy_empty` + + +
public fun destroy_empty<K: store, V: store>(self: big_ordered_map::BigOrderedMap<K, V>)
+
+ + + + +
pragma intrinsic;
+
+ + + + + +### Function `allocate_spare_slots` + + +
public fun allocate_spare_slots<K: store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, num_to_allocate: u64)
+
+ + + + +
pragma verify = false;
+pragma opaque;
+
+ + + + + +### Function `is_empty` + + +
public fun is_empty<K: store, V: store>(self: &big_ordered_map::BigOrderedMap<K, V>): bool
+
+ + + + +
pragma intrinsic;
+
+ + + + + +### Function `compute_length` + + +
public fun compute_length<K: store, V: store>(self: &big_ordered_map::BigOrderedMap<K, V>): u64
+
+ + + + +
pragma verify = false;
+pragma opaque;
+ensures [abstract] result == spec_len(self);
+
+ + + + + +### Function `add` + + +
public fun add<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, key: K, value: V)
+
+ + + + +
pragma intrinsic;
+
+ + + + + +### Function `upsert` + + +
public fun upsert<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, key: K, value: V): option::Option<V>
+
+ + + + +
pragma opaque;
+pragma verify = false;
+ensures [abstract] !spec_contains_key(old(self), key) ==> option::is_none(result);
+ensures [abstract] spec_contains_key(self, key);
+ensures [abstract] spec_get(self, key) == value;
+ensures [abstract] spec_contains_key(old(self), key) ==> ((option::is_some(result)) && (option::spec_borrow(result) == spec_get(old(
+    self), key)));
+ensures [abstract] !spec_contains_key(old(self), key) ==> spec_len(old(self)) + 1 == spec_len(self);
+ensures [abstract] spec_contains_key(old(self), key) ==> spec_len(old(self)) == spec_len(self);
+ensures [abstract] forall k: K: spec_contains_key(old(self), k) && k != key ==> spec_get(old(self), k) == spec_get(self, k);
+ensures [abstract] forall k: K: spec_contains_key(old(self), k) ==> spec_contains_key(self, k);
+
+ + + + + +### Function `remove` + + +
public fun remove<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, key: &K): V
+
+ + + + +
pragma opaque;
+pragma verify = false;
+aborts_if [abstract] !spec_contains_key(self, key);
+ensures [abstract] !spec_contains_key(self, key);
+ensures [abstract] spec_get(old(self), key) == result;
+ensures [abstract] spec_len(old(self)) == spec_len(self) + 1;
+ensures [abstract] forall k: K where k != key: spec_contains_key(self, k) ==> spec_get(self, k) == spec_get(old(self), k);
+ensures [abstract] forall k: K where k != key: spec_contains_key(old(self), k) == spec_contains_key(self, k);
+
+ + + + + +### Function `add_all` + + +
public fun add_all<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, keys: vector<K>, values: vector<V>)
+
+ + + + +
pragma opaque;
+pragma verify = false;
+
+ + + + + +### Function `pop_front` + + +
public fun pop_front<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>): (K, V)
+
+ + + + +
pragma opaque;
+pragma verify = false;
+
+ + + + + +### Function `pop_back` + + +
public fun pop_back<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>): (K, V)
+
+ + + + +
pragma opaque;
+pragma verify = false;
+
+ + + + + +### Function `lower_bound` + + +
public(friend) fun lower_bound<K: copy, drop, store, V: store>(self: &big_ordered_map::BigOrderedMap<K, V>, key: &K): big_ordered_map::IteratorPtr<K>
+
+ + + + +
pragma opaque;
+pragma verify = false;
+
+ + + + + +### Function `find` + + +
public(friend) fun find<K: copy, drop, store, V: store>(self: &big_ordered_map::BigOrderedMap<K, V>, key: &K): big_ordered_map::IteratorPtr<K>
+
+ + + + +
pragma opaque;
+pragma verify = false;
+
+ + + + + +### Function `contains` + + +
public fun contains<K: copy, drop, store, V: store>(self: &big_ordered_map::BigOrderedMap<K, V>, key: &K): bool
+
+ + + + +
pragma intrinsic;
+
+ + + + + +### Function `borrow` + + +
public fun borrow<K: copy, drop, store, V: store>(self: &big_ordered_map::BigOrderedMap<K, V>, key: &K): &V
+
+ + + + +
pragma intrinsic;
+
+ + + + + +### Function `borrow_mut` + + +
public fun borrow_mut<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, key: &K): &mut V
+
+ + + + +
pragma intrinsic;
+
+ + + + + +### Function `borrow_front` + + +
public fun borrow_front<K: copy, drop, store, V: store>(self: &big_ordered_map::BigOrderedMap<K, V>): (K, &V)
+
+ + + + +
pragma opaque;
+pragma verify = false;
+ensures [abstract] spec_contains_key(self, result_1);
+ensures [abstract] spec_get(self, result_1) == result_2;
+ensures [abstract] forall k: K where k != result_1: spec_contains_key(self, k) ==>
+std::cmp::compare(result_1, k) == std::cmp::Ordering::Less;
+
+ + + + + +### Function `borrow_back` + + +
public fun borrow_back<K: copy, drop, store, V: store>(self: &big_ordered_map::BigOrderedMap<K, V>): (K, &V)
+
+ + + + +
pragma opaque;
+pragma verify = false;
+ensures [abstract] spec_contains_key(self, result_1);
+ensures [abstract] spec_get(self, result_1) == result_2;
+ensures [abstract] forall k: K where k != result_1: spec_contains_key(self, k) ==>
+std::cmp::compare(result_1, k) == std::cmp::Ordering::Greater;
+
+ + + + + +### Function `prev_key` + + +
public fun prev_key<K: copy, drop, store, V: store>(self: &big_ordered_map::BigOrderedMap<K, V>, key: &K): option::Option<K>
+
+ + + + +
pragma opaque;
+pragma verify = false;
+ensures [abstract] result == std::option::spec_none() <==>
+(forall k: K {spec_contains_key(self, k)} where spec_contains_key(self, k)
+&& k != key: std::cmp::compare(key, k) == std::cmp::Ordering::Less);
+ensures [abstract] result.is_some() <==>
+    spec_contains_key(self, option::spec_borrow(result)) &&
+    (std::cmp::compare(option::spec_borrow(result), key) == std::cmp::Ordering::Less)
+    && (forall k: K {spec_contains_key(self, k), std::cmp::compare(option::spec_borrow(result), k), std::cmp::compare(key, k)} where k != option::spec_borrow(result): ((spec_contains_key(self, k) &&
+    std::cmp::compare(k, key) == std::cmp::Ordering::Less)) ==>
+    std::cmp::compare(option::spec_borrow(result), k) == std::cmp::Ordering::Greater);
+
+ + + + + +### Function `next_key` + + +
public fun next_key<K: copy, drop, store, V: store>(self: &big_ordered_map::BigOrderedMap<K, V>, key: &K): option::Option<K>
+
+ + + + +
pragma opaque;
+pragma verify = false;
+ensures [abstract] result == std::option::spec_none() <==>
+(forall k: K {spec_contains_key(self, k)} where spec_contains_key(self, k) && k != key:
+std::cmp::compare(key, k) == std::cmp::Ordering::Greater);
+ensures [abstract] result.is_some() <==>
+    spec_contains_key(self, option::spec_borrow(result)) &&
+    (std::cmp::compare(option::spec_borrow(result), key) == std::cmp::Ordering::Greater)
+    && (forall k: K {spec_contains_key(self, k)} where k != option::spec_borrow(result): ((spec_contains_key(self, k) &&
+    std::cmp::compare(k, key) == std::cmp::Ordering::Greater)) ==>
+    std::cmp::compare(option::spec_borrow(result), k) == std::cmp::Ordering::Less);
+
+ + + + + +### Function `keys` + + +
public fun keys<K: copy, drop, store, V: copy, store>(self: &big_ordered_map::BigOrderedMap<K, V>): vector<K>
+
+ + + + +
pragma verify = false;
+pragma opaque;
+ensures [abstract] forall k: K: vector::spec_contains(result, k) <==> spec_contains_key(self, k);
+
+ + + + + +### Function `new_begin_iter` + + +
public(friend) fun new_begin_iter<K: copy, store, V: store>(self: &big_ordered_map::BigOrderedMap<K, V>): big_ordered_map::IteratorPtr<K>
+
+ + + + +
pragma opaque;
+pragma verify = false;
+
+ + + + + +### Function `new_end_iter` + + +
public(friend) fun new_end_iter<K: copy, store, V: store>(self: &big_ordered_map::BigOrderedMap<K, V>): big_ordered_map::IteratorPtr<K>
+
+ + + + +
pragma opaque;
+pragma verify = false;
+
+ + + + + +### Function `iter_is_begin` + + +
public(friend) fun iter_is_begin<K: store, V: store>(self: &big_ordered_map::IteratorPtr<K>, map: &big_ordered_map::BigOrderedMap<K, V>): bool
+
+ + + + +
pragma opaque;
+pragma verify = false;
+
+ + + + + +### Function `iter_is_end` + + +
public(friend) fun iter_is_end<K: store, V: store>(self: &big_ordered_map::IteratorPtr<K>, _map: &big_ordered_map::BigOrderedMap<K, V>): bool
+
+ + + + +
pragma opaque;
+pragma verify = false;
+
+ + + + + +### Function `iter_borrow_key` + + +
public(friend) fun iter_borrow_key<K>(self: &big_ordered_map::IteratorPtr<K>): &K
+
+ + + + +
pragma opaque;
+pragma verify = false;
+
+ + + + + +### Function `iter_borrow` + + +
public(friend) fun iter_borrow<K: drop, store, V: store>(self: big_ordered_map::IteratorPtr<K>, map: &big_ordered_map::BigOrderedMap<K, V>): &V
+
+ + + + +
pragma opaque;
+pragma verify = false;
+
+ + + + + +### Function `iter_borrow_mut` + + +
public(friend) fun iter_borrow_mut<K: drop, store, V: store>(self: big_ordered_map::IteratorPtr<K>, map: &mut big_ordered_map::BigOrderedMap<K, V>): &mut V
+
+ + + + +
pragma opaque;
+pragma verify = false;
+
+ + + + + +### Function `iter_next` + + +
public(friend) fun iter_next<K: copy, drop, store, V: store>(self: big_ordered_map::IteratorPtr<K>, map: &big_ordered_map::BigOrderedMap<K, V>): big_ordered_map::IteratorPtr<K>
+
+ + + + +
pragma opaque;
+pragma verify = false;
+
+ + + + + +### Function `iter_prev` + + +
public(friend) fun iter_prev<K: copy, drop, store, V: store>(self: big_ordered_map::IteratorPtr<K>, map: &big_ordered_map::BigOrderedMap<K, V>): big_ordered_map::IteratorPtr<K>
+
+ + + + +
pragma opaque;
+pragma verify = false;
+
+ + + + + +### Function `validate_dynamic_size_and_init_max_degrees` + + +
fun validate_dynamic_size_and_init_max_degrees<K: store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, key: &K, value: &V)
+
+ + + + +
pragma verify = false;
+pragma opaque;
+
+ + + + + +### Function `validate_static_size_and_init_max_degrees` + + +
fun validate_static_size_and_init_max_degrees<K: store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>)
+
+ + + + +
pragma verify = false;
+pragma opaque;
+
+ + + + + +### Function `validate_size_and_init_max_degrees` + + +
fun validate_size_and_init_max_degrees<K: store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, key_size: u64, value_size: u64)
+
+ + + + +
pragma verify = false;
+pragma opaque;
+
+ + + ### Function `add_at` diff --git a/aptos-move/framework/aptos-framework/doc/jwks.md b/aptos-move/framework/aptos-framework/doc/jwks.md index a505aea4787..0abe815191d 100644 --- a/aptos-move/framework/aptos-framework/doc/jwks.md +++ b/aptos-move/framework/aptos-framework/doc/jwks.md @@ -59,7 +59,20 @@ have a simple layout which is easily accessible in Rust. - [Function `remove_jwk`](#0x1_jwks_remove_jwk) - [Function `apply_patch`](#0x1_jwks_apply_patch) - [Specification](#@Specification_1) + - [Function `patch_federated_jwks`](#@Specification_1_patch_federated_jwks) + - [Function `update_federated_jwk_set`](#@Specification_1_update_federated_jwk_set) + - [Function `get_patched_jwk`](#@Specification_1_get_patched_jwk) + - [Function `try_get_patched_jwk`](#@Specification_1_try_get_patched_jwk) - [Function `on_new_epoch`](#@Specification_1_on_new_epoch) + - [Function `set_patches`](#@Specification_1_set_patches) + - [Function `upsert_into_observed_jwks`](#@Specification_1_upsert_into_observed_jwks) + - [Function `remove_issuer_from_observed_jwks`](#@Specification_1_remove_issuer_from_observed_jwks) + - [Function `regenerate_patched_jwks`](#@Specification_1_regenerate_patched_jwks) + - [Function `try_get_jwk_by_issuer`](#@Specification_1_try_get_jwk_by_issuer) + - [Function `try_get_jwk_by_id`](#@Specification_1_try_get_jwk_by_id) + - [Function `remove_issuer`](#@Specification_1_remove_issuer) + - [Function `remove_jwk`](#@Specification_1_remove_jwk) + - [Function `apply_patch`](#@Specification_1_apply_patch)
use 0x1::bcs;
@@ -1907,6 +1920,70 @@ Maintains the sorted-by-issuer invariant in 
+
+### Function `patch_federated_jwks`
+
+
+
public fun patch_federated_jwks(jwk_owner: &signer, patches: vector<jwks::Patch>)
+
+ + + + +
pragma verify_duration_estimate = 80;
+
+ + + + + +### Function `update_federated_jwk_set` + + +
public entry fun update_federated_jwk_set(jwk_owner: &signer, iss: vector<u8>, kid_vec: vector<string::String>, alg_vec: vector<string::String>, e_vec: vector<string::String>, n_vec: vector<string::String>)
+
+ + + + +
pragma verify_duration_estimate = 80;
+
+ + + + + +### Function `get_patched_jwk` + + +
public fun get_patched_jwk(issuer: vector<u8>, jwk_id: vector<u8>): jwks::JWK
+
+ + + + +
pragma verify_duration_estimate = 80;
+
+ + + + + +### Function `try_get_patched_jwk` + + +
public fun try_get_patched_jwk(issuer: vector<u8>, jwk_id: vector<u8>): option::Option<jwks::JWK>
+
+ + + + +
pragma verify_duration_estimate = 80;
+
+ + + ### Function `on_new_epoch` @@ -1924,4 +2001,151 @@ Maintains the sorted-by-issuer invariant in + +### Function `set_patches` + + +
public fun set_patches(fx: &signer, patches: vector<jwks::Patch>)
+
+ + + + +
pragma verify_duration_estimate = 80;
+
+ + + + + +### Function `upsert_into_observed_jwks` + + +
public fun upsert_into_observed_jwks(fx: &signer, provider_jwks_vec: vector<jwks::ProviderJWKs>)
+
+ + + + +
pragma verify_duration_estimate = 80;
+
+ + + + + +### Function `remove_issuer_from_observed_jwks` + + +
public fun remove_issuer_from_observed_jwks(fx: &signer, issuer: vector<u8>): option::Option<jwks::ProviderJWKs>
+
+ + + + +
pragma verify_duration_estimate = 80;
+
+ + + + + +### Function `regenerate_patched_jwks` + + +
fun regenerate_patched_jwks()
+
+ + + + +
pragma verify_duration_estimate = 80;
+
+ + + + + +### Function `try_get_jwk_by_issuer` + + +
fun try_get_jwk_by_issuer(jwks: &jwks::AllProvidersJWKs, issuer: vector<u8>, jwk_id: vector<u8>): option::Option<jwks::JWK>
+
+ + + + +
pragma verify_duration_estimate = 80;
+
+ + + + + +### Function `try_get_jwk_by_id` + + +
fun try_get_jwk_by_id(provider_jwks: &jwks::ProviderJWKs, jwk_id: vector<u8>): option::Option<jwks::JWK>
+
+ + + + +
pragma verify_duration_estimate = 80;
+
+ + + + + +### Function `remove_issuer` + + +
fun remove_issuer(jwks: &mut jwks::AllProvidersJWKs, issuer: vector<u8>): option::Option<jwks::ProviderJWKs>
+
+ + + + +
pragma opaque;
+ensures option::spec_is_none(result) <==> (forall jwk: ProviderJWKs where vector::spec_contains(old(jwks).entries, jwk): jwk.issuer != issuer);
+ensures option::spec_is_none(result) ==> old(jwks) == jwks;
+ensures option::spec_is_some(result) ==> vector::spec_contains(old(jwks).entries, option::spec_borrow(result));
+
+ + + + + +### Function `remove_jwk` + + +
fun remove_jwk(jwks: &mut jwks::ProviderJWKs, jwk_id: vector<u8>): option::Option<jwks::JWK>
+
+ + + + +
pragma verify_duration_estimate = 80;
+
+ + + + + +### Function `apply_patch` + + +
fun apply_patch(jwks: &mut jwks::AllProvidersJWKs, patch: jwks::Patch)
+
+ + + + +
pragma verify_duration_estimate = 80;
+
+ + [move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/aptos-framework/sources/datastructures/big_ordered_map.spec.move b/aptos-move/framework/aptos-framework/sources/datastructures/big_ordered_map.spec.move new file mode 100644 index 00000000000..a6c301308c3 --- /dev/null +++ b/aptos-move/framework/aptos-framework/sources/datastructures/big_ordered_map.spec.move @@ -0,0 +1,255 @@ +spec aptos_std::big_ordered_map { + + spec BigOrderedMap { + pragma intrinsic = map, + map_new = new, + map_destroy_empty = destroy_empty, + map_has_key = contains, + map_add_no_override = add, + map_borrow = borrow, + map_borrow_mut = borrow_mut, + map_spec_get = spec_get, + map_spec_set = spec_set, + map_spec_del = spec_remove, + map_spec_len = spec_len, + map_spec_has_key = spec_contains_key, + map_is_empty = is_empty; + } + + spec native fun spec_len(t: BigOrderedMap): num; + spec native fun spec_contains_key(t: BigOrderedMap, k: K): bool; + spec native fun spec_set(t: BigOrderedMap, k: K, v: V): BigOrderedMap; + spec native fun spec_remove(t: BigOrderedMap, k: K): BigOrderedMap; + spec native fun spec_get(t: BigOrderedMap, k: K): V; + + + spec new_with_config { + pragma verify = false; + pragma opaque; + } + + spec new { + pragma intrinsic; + } + + spec new_with_reusable { + pragma verify = false; + pragma opaque; + } + + spec new_with_type_size_hints { + pragma verify = false; + pragma opaque; + } + + spec borrow { + pragma intrinsic; + } + + spec borrow_mut { + pragma intrinsic; + } + + spec contains { + pragma intrinsic; + } + + spec destroy_empty { + pragma intrinsic; + } + + spec add { + pragma intrinsic; + } + + spec remove { + pragma opaque; + pragma verify = false; + aborts_if [abstract] !spec_contains_key(self, key); + ensures [abstract] !spec_contains_key(self, key); + ensures [abstract] spec_get(old(self), key) == result; + ensures [abstract] spec_len(old(self)) == spec_len(self) + 1; + ensures [abstract] forall k: K where k != key: spec_contains_key(self, k) ==> spec_get(self, k) == spec_get(old(self), k); + ensures [abstract] forall k: K where k != key: spec_contains_key(old(self), k) == spec_contains_key(self, k); + } + + spec is_empty { + pragma intrinsic; + } + + spec iter_is_end { + pragma opaque; + pragma verify = false; + } + + spec iter_borrow { + pragma opaque; + pragma verify = false; + } + + spec iter_borrow_mut { + pragma opaque; + pragma verify = false; + } + + spec iter_is_begin { + pragma opaque; + pragma verify = false; + } + + spec lower_bound { + pragma opaque; + pragma verify = false; + } + + spec iter_borrow_key { + pragma opaque; + pragma verify = false; + } + + spec allocate_spare_slots { + pragma verify = false; + pragma opaque; + } + + spec validate_size_and_init_max_degrees { + pragma verify = false; + pragma opaque; + } + + spec validate_dynamic_size_and_init_max_degrees { + pragma verify = false; + pragma opaque; + } + + spec validate_static_size_and_init_max_degrees { + pragma verify = false; + pragma opaque; + } + + spec keys { + pragma verify = false; + pragma opaque; + ensures [abstract] forall k: K: vector::spec_contains(result, k) <==> spec_contains_key(self, k); + } + + spec new_from(keys: vector, values: vector): BigOrderedMap { + pragma opaque; + pragma verify = false; + aborts_if [abstract] exists i in 0..len(keys), j in 0..len(keys) where i != j : keys[i] == keys[j]; + aborts_if [abstract] len(keys) != len(values); + ensures [abstract] forall k: K {spec_contains_key(result, k)} : vector::spec_contains(keys,k) <==> spec_contains_key(result, k); + ensures [abstract] forall i in 0..len(keys) : spec_get(result, keys[i]) == values[i]; + ensures [abstract] spec_len(result) == len(keys); + } + + spec upsert { + pragma opaque; + pragma verify = false; + ensures [abstract] !spec_contains_key(old(self), key) ==> option::is_none(result); + ensures [abstract] spec_contains_key(self, key); + ensures [abstract] spec_get(self, key) == value; + ensures [abstract] spec_contains_key(old(self), key) ==> ((option::is_some(result)) && (option::spec_borrow(result) == spec_get(old( + self), key))); + ensures [abstract] !spec_contains_key(old(self), key) ==> spec_len(old(self)) + 1 == spec_len(self); + ensures [abstract] spec_contains_key(old(self), key) ==> spec_len(old(self)) == spec_len(self); + ensures [abstract] forall k: K: spec_contains_key(old(self), k) && k != key ==> spec_get(old(self), k) == spec_get(self, k); + ensures [abstract] forall k: K: spec_contains_key(old(self), k) ==> spec_contains_key(self, k); + } + + spec add_all { + pragma opaque; + pragma verify = false; + } + + spec borrow_front(self: &BigOrderedMap): (K, &V) { + pragma opaque; + pragma verify = false; + ensures [abstract] spec_contains_key(self, result_1); + ensures [abstract] spec_get(self, result_1) == result_2; + ensures [abstract] forall k: K where k != result_1: spec_contains_key(self, k) ==> + std::cmp::compare(result_1, k) == std::cmp::Ordering::Less; + } + + spec borrow_back { + pragma opaque; + pragma verify = false; + ensures [abstract] spec_contains_key(self, result_1); + ensures [abstract] spec_get(self, result_1) == result_2; + ensures [abstract] forall k: K where k != result_1: spec_contains_key(self, k) ==> + std::cmp::compare(result_1, k) == std::cmp::Ordering::Greater; + } + + spec pop_front(self: &mut BigOrderedMap): (K, V) { + pragma opaque; + pragma verify = false; + } + + spec pop_back { + pragma opaque; + pragma verify = false; + } + + spec prev_key(self: &BigOrderedMap, key: &K): Option { + pragma opaque; + pragma verify = false; + ensures [abstract] result == std::option::spec_none() <==> + (forall k: K {spec_contains_key(self, k)} where spec_contains_key(self, k) + && k != key: std::cmp::compare(key, k) == std::cmp::Ordering::Less); + ensures [abstract] result.is_some() <==> + spec_contains_key(self, option::spec_borrow(result)) && + (std::cmp::compare(option::spec_borrow(result), key) == std::cmp::Ordering::Less) + && (forall k: K {spec_contains_key(self, k), std::cmp::compare(option::spec_borrow(result), k), std::cmp::compare(key, k)} where k != option::spec_borrow(result): ((spec_contains_key(self, k) && + std::cmp::compare(k, key) == std::cmp::Ordering::Less)) ==> + std::cmp::compare(option::spec_borrow(result), k) == std::cmp::Ordering::Greater); + } + + + spec next_key(self: &BigOrderedMap, key: &K): Option { + pragma opaque; + pragma verify = false; + ensures [abstract] result == std::option::spec_none() <==> + (forall k: K {spec_contains_key(self, k)} where spec_contains_key(self, k) && k != key: + std::cmp::compare(key, k) == std::cmp::Ordering::Greater); + ensures [abstract] result.is_some() <==> + spec_contains_key(self, option::spec_borrow(result)) && + (std::cmp::compare(option::spec_borrow(result), key) == std::cmp::Ordering::Greater) + && (forall k: K {spec_contains_key(self, k)} where k != option::spec_borrow(result): ((spec_contains_key(self, k) && + std::cmp::compare(k, key) == std::cmp::Ordering::Greater)) ==> + std::cmp::compare(option::spec_borrow(result), k) == std::cmp::Ordering::Less); + } + + + spec find { + pragma opaque; + pragma verify = false; + } + + spec new_begin_iter { + pragma opaque; + pragma verify = false; + } + + spec new_end_iter { + pragma opaque; + pragma verify = false; + } + + spec iter_next { + pragma opaque; + pragma verify = false; + } + + spec iter_prev { + pragma opaque; + pragma verify = false; + } + + spec compute_length { + pragma verify = false; + pragma opaque; + ensures [abstract] result == spec_len(self); + } + + +} diff --git a/aptos-move/framework/aptos-framework/sources/jwks.spec.move b/aptos-move/framework/aptos-framework/sources/jwks.spec.move index 764b09f125f..d4cc9b83387 100644 --- a/aptos-move/framework/aptos-framework/sources/jwks.spec.move +++ b/aptos-move/framework/aptos-framework/sources/jwks.spec.move @@ -4,4 +4,62 @@ spec aptos_framework::jwks { include config_buffer::OnNewEpochRequirement; aborts_if false; } + + spec patch_federated_jwks(jwk_owner: &signer, patches: vector) { + pragma verify_duration_estimate = 80; + } + + spec update_federated_jwk_set(jwk_owner: &signer, iss: vector, kid_vec: vector, alg_vec: vector, e_vec: vector, n_vec: vector) { + pragma verify_duration_estimate = 80; + } + + spec get_patched_jwk(issuer: vector, jwk_id: vector): JWK { + pragma verify_duration_estimate = 80; + } + + spec upsert_into_observed_jwks(fx: &signer, provider_jwks_vec: vector) { + pragma verify_duration_estimate = 80; + } + + spec regenerate_patched_jwks() { + pragma verify_duration_estimate = 80; + } + + spec try_get_jwk_by_issuer(jwks: &AllProvidersJWKs, issuer: vector, jwk_id: vector): Option { + pragma verify_duration_estimate = 80; + } + + spec remove_jwk(jwks: &mut ProviderJWKs, jwk_id: vector): Option { + pragma verify_duration_estimate = 80; + } + + spec apply_patch(jwks: &mut AllProvidersJWKs, patch: Patch) { + pragma verify_duration_estimate = 80; + } + + spec try_get_patched_jwk(issuer: vector, jwk_id: vector): Option { + pragma verify_duration_estimate = 80; + } + + spec set_patches(fx: &signer, patches: vector) { + pragma verify_duration_estimate = 80; + } + + spec remove_issuer_from_observed_jwks(fx: &signer, issuer: vector): Option { + pragma verify_duration_estimate = 80; + } + + spec try_get_jwk_by_id(provider_jwks: &ProviderJWKs, jwk_id: vector): Option { + pragma verify_duration_estimate = 80; + } + + spec remove_issuer(jwks: &mut AllProvidersJWKs, issuer: vector): Option { + use std::option; + use std::vector; + pragma opaque; + ensures option::spec_is_none(result) <==> (forall jwk: ProviderJWKs where vector::spec_contains(old(jwks).entries, jwk): jwk.issuer != issuer); + ensures option::spec_is_none(result) ==> old(jwks) == jwks; + ensures option::spec_is_some(result) ==> vector::spec_contains(old(jwks).entries, option::spec_borrow(result)); + } + } diff --git a/aptos-move/framework/move-stdlib/doc/vector.md b/aptos-move/framework/move-stdlib/doc/vector.md index 89596d86036..46802a16a10 100644 --- a/aptos-move/framework/move-stdlib/doc/vector.md +++ b/aptos-move/framework/move-stdlib/doc/vector.md @@ -728,7 +728,14 @@ Otherwise, returns (false, 0). let found_index = 0; let i = 0; let len = self.length(); - while (i < len) { + while ({ + spec { + invariant i <= len; + invariant forall j: num where j >= 0 && j < i: !f(self[j]); + invariant find ==> i < len && f(self[i]); + }; + i < len + }) { // Cannot call return in an inline function so we need to resort to break here. if (f(self.borrow(i))) { find = true; @@ -737,6 +744,9 @@ Otherwise, returns (false, 0). }; i += 1; }; + spec { + assert !find <==> (forall j: num where j >= 0 && j < len: !f(self[j])); + }; (find, found_index) }
diff --git a/aptos-move/framework/move-stdlib/sources/vector.move b/aptos-move/framework/move-stdlib/sources/vector.move index 94d8f7f8fae..bbf3b5cb96a 100644 --- a/aptos-move/framework/move-stdlib/sources/vector.move +++ b/aptos-move/framework/move-stdlib/sources/vector.move @@ -237,7 +237,14 @@ module std::vector { let found_index = 0; let i = 0; let len = self.length(); - while (i < len) { + while ({ + spec { + invariant i <= len; + invariant forall j: num where j >= 0 && j < i: !f(self[j]); + invariant find ==> i < len && f(self[i]); + }; + i < len + }) { // Cannot call return in an inline function so we need to resort to break here. if (f(self.borrow(i))) { find = true; @@ -246,6 +253,9 @@ module std::vector { }; i += 1; }; + spec { + assert !find <==> (forall j: num where j >= 0 && j < len: !f(self[j])); + }; (find, found_index) } diff --git a/third_party/move/move-prover/boogie-backend/src/lib.rs b/third_party/move/move-prover/boogie-backend/src/lib.rs index 137a3ab5b16..2f16d9c1730 100644 --- a/third_party/move/move-prover/boogie-backend/src/lib.rs +++ b/third_party/move/move-prover/boogie-backend/src/lib.rs @@ -54,6 +54,7 @@ const TABLE_ARRAY_THEORY: &[u8] = include_bytes!("prelude/table-array-theory.bpl // TODO use named addresses const BCS_MODULE: &str = "0x1::bcs"; +const FROM_BCS_MODULE: &str = "0x1::from_bcs"; const EVENT_MODULE: &str = "0x1::event"; const CMP_MODULE: &str = "0x1::cmp"; @@ -318,6 +319,8 @@ pub fn add_prelude( let bcs_instances = filter_native_ensure_one_inst(BCS_MODULE); context.insert("bcs_instances", &bcs_instances); + let from_bcs_instances = filter_native_ensure_one_inst(FROM_BCS_MODULE); + context.insert("from_bcs_instances", &from_bcs_instances); let event_instances = filter_native_ensure_one_inst(EVENT_MODULE); context.insert("event_instances", &event_instances); diff --git a/third_party/move/move-prover/boogie-backend/src/prelude/native.bpl b/third_party/move/move-prover/boogie-backend/src/prelude/native.bpl index 506707ddf8e..1a1fa15f13d 100644 --- a/third_party/move/move-prover/boogie-backend/src/prelude/native.bpl +++ b/third_party/move/move-prover/boogie-backend/src/prelude/native.bpl @@ -616,6 +616,23 @@ axiom (forall v: int :: {$1_bcs_serialize'address'(v)} {% endmacro hash_module %} +{# FROM_BCS + ==== +#} + +{% macro from_bcs_module(instance) %} +{%- set S = "'" ~ instance.suffix ~ "'" -%} +{%- set T = instance.name -%} + +procedure $1_from_bcs_from_bytes{{S}}(v: Vec int) returns (res: {{T}}); + +function $1_from_bcs_$from_bytes{{S}}(v: Vec int): {{T}}; +axiom (forall v: Vec int :: {$1_from_bcs_deserialize{{S}}(v)} + ( var r := $1_from_bcs_$from_bytes{{S}}(v); r == $1_from_bcs_deserialize{{S}}(v) )); + +{% endmacro from_bcs_module %} + + {# Event Module ============ #} diff --git a/third_party/move/move-prover/boogie-backend/src/prelude/prelude.bpl b/third_party/move/move-prover/boogie-backend/src/prelude/prelude.bpl index cc0e0a031f2..b3247a9f4a8 100644 --- a/third_party/move/move-prover/boogie-backend/src/prelude/prelude.bpl +++ b/third_party/move/move-prover/boogie-backend/src/prelude/prelude.bpl @@ -1208,6 +1208,18 @@ procedure {:inline 1} $1_Signature_ed25519_verify( {%- endfor %} +// ================================================================================== +// Native from_bcs::from_bytes + +{%- for instance in from_bcs_instances %} + +// ---------------------------------------------------------------------------------- +// Native FROM_BCS implementation for element type `{{instance.suffix}}` + +{{ native::from_bcs_module(instance=instance) -}} +{%- endfor %} + + // ================================================================================== // Native Event module diff --git a/third_party/move/move-prover/boogie-backend/src/spec_translator.rs b/third_party/move/move-prover/boogie-backend/src/spec_translator.rs index b2002cf79a5..f26d823c06b 100644 --- a/third_party/move/move-prover/boogie-backend/src/spec_translator.rs +++ b/third_party/move/move-prover/boogie-backend/src/spec_translator.rs @@ -576,6 +576,13 @@ impl SpecTranslator<'_> { ..self.clone() }; + let skip_immutable_reference = |ty: &Type| { + if !ty.is_mutable_reference() { + ty.skip_reference().clone() + } else { + ty.clone() + } + }; // Pairs of context parameter names and boogie types let param_decls = info .free_vars @@ -583,14 +590,15 @@ impl SpecTranslator<'_> { .map(|(s, ty)| { ( s.display(env.symbol_pool()).to_string(), - boogie_type(env, ty.skip_reference()), + boogie_type(env, &skip_immutable_reference(ty)), ) }) - .chain( - info.used_temps - .iter() - .map(|(t, ty)| (format!("$t{}", t), boogie_type(env, ty.skip_reference()))), - ) + .chain(info.used_temps.iter().map(|(t, ty)| { + ( + format!("$t{}", t), + boogie_type(env, &skip_immutable_reference(ty)), + ) + })) .chain(info.used_memory.iter().map(|(m, l)| { let struct_env = &env.get_struct(m.to_qualified_id()); ( @@ -607,6 +615,11 @@ impl SpecTranslator<'_> { let mk_arg = |(n, _): &(String, String)| n.to_owned(); let emit_valid = |n: &str, ty: &Type| { let suffix = boogie_type_suffix(env, ty.skip_reference()); + let n = if ty.is_mutable_reference() { + format!("$Dereference({})", n) + } else { + n.to_owned() + }; emit!(new_spec_trans.writer, "$IsValid'{}'({})", suffix, n); }; let mk_temp = |t: TempIndex| format!("$t{}", t); diff --git a/third_party/move/move-prover/tests/sources/functional/choice.move b/third_party/move/move-prover/tests/sources/functional/choice.move index b47faa814aa..d97620c468c 100644 --- a/third_party/move/move-prover/tests/sources/functional/choice.move +++ b/third_party/move/move-prover/tests/sources/functional/choice.move @@ -303,4 +303,13 @@ module 0x42::TestSome { <= 0); } + public fun get_ballots(ballots: &mut Ballots): &mut Ballot { + &mut ballots.ballots[0] + } + + spec get_ballots { + let index = choose min i in range (ballots.ballots) where ballots.ballots[i].ballot_id.counter == 0; + ensures true; + } + } From 0d21ed23c3abd392186f4e0920810e8d5b19f413 Mon Sep 17 00:00:00 2001 From: Wolfgang Grieskamp Date: Fri, 18 Jul 2025 19:34:17 +0200 Subject: [PATCH 047/260] [move-asm] Struct and enum related features (#17077) * [move-asm] Struct and enum related features This implements declaration of structs and enums as well as the related bytecodes, and completes most of the assembler functionality. There are still things missing (like string constants for byte vectors) but otherwise should be fairly complete, or can be easily extended self-service style. * Addressing reviewer comments. Downstreamed-from: d1efe0044b04777e5a97f3b20e89096ccba7a3cd --- .../src/framework.rs | 21 +- .../move/tools/move-asm/src/assembler.rs | 406 ++++++++++++++++-- .../move/tools/move-asm/src/module_builder.rs | 387 ++++++++++++++++- third_party/move/tools/move-asm/src/syntax.rs | 247 +++++++++-- .../tests/assembler/call_different_module.exp | 35 ++ .../assembler/call_different_module.masm | 16 + .../tests/assembler/declare_entry_fun.exp | 16 + .../tests/assembler/declare_entry_fun.masm | 6 + .../tools/move-asm/tests/assembler/enum.exp | 43 ++ .../tools/move-asm/tests/assembler/enum.masm | 30 ++ .../move-asm/tests/assembler/enum_generic.exp | 43 ++ .../tests/assembler/enum_generic.masm | 30 ++ .../move-asm/tests/assembler/resource.exp | 29 ++ .../move-asm/tests/assembler/resource.masm | 19 + .../tests/assembler/resource_generic.exp | 29 ++ .../tests/assembler/resource_generic.masm | 19 + .../tools/move-asm/tests/assembler/struct.exp | 37 ++ .../move-asm/tests/assembler/struct.masm | 26 ++ .../tests/assembler/struct_generic.exp | 37 ++ .../tests/assembler/struct_generic.masm | 26 ++ .../move-asm/tests/assembler/struct_use.exp | 37 ++ .../move-asm/tests/assembler/struct_use.masm | 19 + .../tests/assembler/unknown_field.exp | 10 + .../tests/assembler/unknown_field.masm | 11 + .../tests/assembler/unknown_variant.exp | 10 + .../tests/assembler/unknown_variant.masm | 12 + 26 files changed, 1511 insertions(+), 90 deletions(-) create mode 100644 third_party/move/tools/move-asm/tests/assembler/call_different_module.exp create mode 100644 third_party/move/tools/move-asm/tests/assembler/call_different_module.masm create mode 100644 third_party/move/tools/move-asm/tests/assembler/declare_entry_fun.exp create mode 100644 third_party/move/tools/move-asm/tests/assembler/declare_entry_fun.masm create mode 100644 third_party/move/tools/move-asm/tests/assembler/enum.exp create mode 100644 third_party/move/tools/move-asm/tests/assembler/enum.masm create mode 100644 third_party/move/tools/move-asm/tests/assembler/enum_generic.exp create mode 100644 third_party/move/tools/move-asm/tests/assembler/enum_generic.masm create mode 100644 third_party/move/tools/move-asm/tests/assembler/resource.exp create mode 100644 third_party/move/tools/move-asm/tests/assembler/resource.masm create mode 100644 third_party/move/tools/move-asm/tests/assembler/resource_generic.exp create mode 100644 third_party/move/tools/move-asm/tests/assembler/resource_generic.masm create mode 100644 third_party/move/tools/move-asm/tests/assembler/struct.exp create mode 100644 third_party/move/tools/move-asm/tests/assembler/struct.masm create mode 100644 third_party/move/tools/move-asm/tests/assembler/struct_generic.exp create mode 100644 third_party/move/tools/move-asm/tests/assembler/struct_generic.masm create mode 100644 third_party/move/tools/move-asm/tests/assembler/struct_use.exp create mode 100644 third_party/move/tools/move-asm/tests/assembler/struct_use.masm create mode 100644 third_party/move/tools/move-asm/tests/assembler/unknown_field.exp create mode 100644 third_party/move/tools/move-asm/tests/assembler/unknown_field.masm create mode 100644 third_party/move/tools/move-asm/tests/assembler/unknown_variant.exp create mode 100644 third_party/move/tools/move-asm/tests/assembler/unknown_variant.masm diff --git a/third_party/move/testing-infra/transactional-test-runner/src/framework.rs b/third_party/move/testing-infra/transactional-test-runner/src/framework.rs index 483dd66e581..18b64e2b077 100644 --- a/third_party/move/testing-infra/transactional-test-runner/src/framework.rs +++ b/third_party/move/testing-infra/transactional-test-runner/src/framework.rs @@ -440,7 +440,7 @@ pub trait MoveTestAdapter<'a>: Sized { SyntaxChoice::ASM => { // TODO(#16582): generate source info for .masm file self.compiled_state() - .add_and_generate_interface_file(module); + .add_without_source_file(named_addr_opt, module); }, }; Ok(merge_output(warnings_opt, output)) @@ -690,6 +690,25 @@ impl<'a> CompiledState<'a> { self.modules.insert(id, processed); } + pub fn add_without_source_file( + &mut self, + named_addr_opt: Option, + module: CompiledModule, + ) { + let id = module.self_id(); + self.check_not_precompiled(&id); + if let Some(named_addr) = named_addr_opt { + self.compiled_module_named_address_mapping + .insert(id.clone(), named_addr); + } + + let processed = ProcessedModule { + module, + source_file: None, + }; + self.modules.insert(id, processed); + } + pub fn add_and_generate_interface_file(&mut self, module: CompiledModule) { let id = module.self_id(); self.check_not_precompiled(&id); diff --git a/third_party/move/tools/move-asm/src/assembler.rs b/third_party/move/tools/move-asm/src/assembler.rs index 286d7831ae2..94e94a21e31 100644 --- a/third_party/move/tools/move-asm/src/assembler.rs +++ b/third_party/move/tools/move-asm/src/assembler.rs @@ -8,16 +8,19 @@ use crate::{ module_builder::{ModuleBuilder, ModuleBuilderOptions}, syntax, syntax::{ - map_diag, Argument, AsmResult, Diag, Fun, Instruction, Loc, Local, Type, Unit, UnitId, - Value, + map_diag, Argument, AsmResult, Decl, Diag, Fun, Instruction, Loc, PartialIdent, Struct, + StructLayout, Type, Unit, UnitId, Value, }, ModuleOrScript, }; use either::Either; use move_binary_format::{ file_format::{ - Bytecode, CodeOffset, FunctionDefinitionIndex, FunctionHandleIndex, LocalIndex, - SignatureIndex, SignatureToken, TableIndex, + Bytecode, CodeOffset, FieldDefinition, FieldHandleIndex, FieldInstantiationIndex, + FunctionDefinitionIndex, FunctionHandleIndex, LocalIndex, MemberCount, SignatureIndex, + SignatureToken, StructDefInstantiationIndex, StructDefinitionIndex, StructFieldInformation, + StructVariantHandleIndex, StructVariantInstantiationIndex, TableIndex, TypeSignature, + VariantDefinition, VariantFieldHandleIndex, VariantFieldInstantiationIndex, VariantIndex, }, CompiledModule, }; @@ -28,10 +31,10 @@ struct Assembler<'a> { builder: ModuleBuilder<'a>, diags: Vec, /// Context available during processing of a function. - fun_context: Option, + resolution_context: Option, } -struct FunctionContext { +struct ResolutionContext { ty_param_map: BTreeMap, local_map: BTreeMap, } @@ -44,7 +47,7 @@ pub(crate) fn compile<'a>( let mut compiler = Assembler { builder: ModuleBuilder::new(options, context_modules, ast.name.module_opt()), diags: vec![], - fun_context: None, + resolution_context: None, }; compiler.unit(&ast); if compiler.diags.is_empty() { @@ -63,6 +66,7 @@ impl<'a> Assembler<'a> { name: _, address_aliases, module_aliases, + structs, functions, } = ast; // Register aliases @@ -75,19 +79,79 @@ impl<'a> Assembler<'a> { self.add_diags(Loc::new(0, 0), res); } + // Declare structs + for str in structs { + self.declare_struct(str) + } + // Declare functions for fun in functions { self.declare_fun(fun); } - // Define code for functions if self.diags.is_empty() { + // Define layout for structs + for (pos, str) in structs.iter().enumerate() { + self.define_struct(StructDefinitionIndex::new(pos as TableIndex), str) + } + + // Define code for functions for (pos, fun) in functions.iter().enumerate() { self.define_fun(FunctionDefinitionIndex::new(pos as TableIndex), fun) } } } + fn declare_struct(&mut self, str: &Struct) { + self.setup_struct(str); + let res = self.builder.declare_struct( + str.name.clone(), + str.type_params + .iter() + .map(|(_, constraints, is_phantom)| (*constraints, *is_phantom)) + .collect(), + str.abilities, + ); + self.add_diags(str.loc, res); + } + + fn define_struct(&mut self, idx: StructDefinitionIndex, str: &Struct) { + self.setup_struct(str); + let layout = match &str.layout { + StructLayout::Singleton(fields) => { + StructFieldInformation::Declared(self.translate_fields(fields)) + }, + StructLayout::Variants(variants) => { + let mut result = vec![]; + for (loc, name, fields) in variants { + let name_res = self.builder.name_index(name.clone()); + if let Some(name) = self.add_diags(*loc, name_res) { + result.push(VariantDefinition { + name, + fields: self.translate_fields(fields), + }) + } + } + StructFieldInformation::DeclaredVariants(result) + }, + }; + self.builder.define_struct_layout(idx, layout) + } + + fn translate_fields(&mut self, fields: &[Decl]) -> Vec { + let mut result = vec![]; + for field in fields { + let name_res = self.builder.name_index(field.name.clone()); + if let Some(name) = self.add_diags(field.loc, name_res) { + result.push(FieldDefinition { + name, + signature: TypeSignature(self.build_type(field.loc, &field.ty)), + }) + } + } + result + } + fn declare_fun(&mut self, fun: &Fun) { self.setup_fun(fun); let param_tys: Vec = fun @@ -104,8 +168,10 @@ impl<'a> Assembler<'a> { .collect(); let res = self.builder.signature_index(result_tys); let result_sign = self.add_diags(fun.loc, res).unwrap_or_default(); + let acquires_res = self.acquires(fun.acquires.iter()); + let acquires = self.add_diags(fun.loc, acquires_res).unwrap_or_default(); let res = self.builder.declare_fun( - false, // TODO(#16582): entry + fun.is_entry, fun.name.clone(), fun.visibility, param_sign, @@ -114,35 +180,52 @@ impl<'a> Assembler<'a> { .iter() .map(|(_, abilities)| *abilities) .collect(), + acquires, ); self.add_diags(fun.loc, res); } + fn acquires<'b>( + &mut self, + ids: impl Iterator, + ) -> anyhow::Result> { + ids.map(|id| self.builder.resolve_struct_def(id.as_ident_str())) + .collect::>>() + } + fn setup_fun(&mut self, fun: &Fun) { - let ty_param_map = fun - .type_params - .iter() - .enumerate() - .map(|(pos, (id, _))| (id.to_string(), pos as u16)) - .collect(); - self.fun_context = Some(FunctionContext { - ty_param_map, // This is needed for build_type called below - local_map: Default::default(), - }); - self.fun_context.as_mut().unwrap().local_map = fun + self.setup_type_params(fun.type_params.iter().map(|(id, _)| id)); + self.resolution_context.as_mut().unwrap().local_map = fun .params .iter() .chain(fun.locals.iter()) .enumerate() - .map(|(pos, Local { loc, name, ty })| { + .map(|(pos, Decl { loc, name, ty })| { let ty = self.build_type(*loc, ty); (name.to_string(), (pos as LocalIndex, ty)) }) .collect(); } - fn require_fun(&self) -> &FunctionContext { - self.fun_context.as_ref().expect("function context") + fn setup_struct(&mut self, str: &Struct) { + self.setup_type_params(str.type_params.iter().map(|(name, _, _)| name)) + } + + fn setup_type_params<'b>(&mut self, params: impl Iterator) { + let ty_param_map = params + .enumerate() + .map(|(pos, id)| (id.to_string(), pos as u16)) + .collect(); + self.resolution_context = Some(ResolutionContext { + ty_param_map, + local_map: Default::default(), + }); + } + + fn require_resolution_context(&self) -> &ResolutionContext { + self.resolution_context + .as_ref() + .expect("resolution context") } fn define_fun(&mut self, def_idx: FunctionDefinitionIndex, fun: &Fun) { @@ -185,7 +268,7 @@ impl<'a> Assembler<'a> { // Define locals signature. let locals_start = fun.params.len(); let mut locals: Vec<(LocalIndex, SignatureToken)> = self - .require_fun() + .require_resolution_context() .local_map .clone() .into_iter() @@ -232,12 +315,31 @@ impl<'a> Assembler<'a> { let tr_inst = |comp: &mut Self, inst: Option<&Vec>| -> Option> { inst.map(|tys| tys.iter().map(|t| comp.build_type(loc, t)).collect()) }; + let tr_named = + |comp: &mut Self, name: &PartialIdent, inst: Option<&Vec>| -> SignatureToken { + let res = comp.builder.resolve_struct(&name.address, &name.id_parts); + if let Some(shdl_idx) = comp.add_diags(loc, res) { + match tr_inst(comp, inst) { + Some(tys) => SignatureToken::StructInstantiation(shdl_idx, tys), + None => SignatureToken::Struct(shdl_idx), + } + } else { + // error reported + SignatureToken::Bool + } + }; match ty { Type::Named(partial_id, opt_inst) => { if partial_id.address.is_none() && partial_id.id_parts.len() == 1 { match partial_id.id_parts[0].as_str() { - s if self.require_fun().ty_param_map.contains_key(s) => { - SignatureToken::TypeParameter(self.require_fun().ty_param_map[s]) + s if self + .require_resolution_context() + .ty_param_map + .contains_key(s) => + { + SignatureToken::TypeParameter( + self.require_resolution_context().ty_param_map[s], + ) }, "u8" => { ck_inst(self, None, opt_inst.as_ref()); @@ -285,14 +387,10 @@ impl<'a> Assembler<'a> { SignatureToken::Bool } }, - _ => { - self.error(loc, "structs NYI"); - SignatureToken::Bool - }, + _ => tr_named(self, partial_id, opt_inst.as_ref()), } } else { - self.error(loc, "structs NYI type"); - SignatureToken::Bool + tr_named(self, partial_id, opt_inst.as_ref()) } }, Type::Ref(is_mut, ty) => { @@ -337,7 +435,7 @@ impl<'a> Assembler<'a> { _ => unreachable!(), }; let arg = self.args1(instr)?; - let label = self.simple_id(instr, arg)?; + let label = self.simple_id(instr, arg, " for label")?; if let Some(label_offs) = label_defs.get(&label) { mk_instr(*label_offs) } else { @@ -376,7 +474,6 @@ impl<'a> Assembler<'a> { let num = self.number(instr, arg, U256::max_value())?; LdU256(num) }, - "cast_u8" => { self.args0(instr)?; CastU8 @@ -457,7 +554,7 @@ impl<'a> Assembler<'a> { let arg = self.args1(instr)?; MutBorrowLoc(self.local(instr, arg)?) }, - "imm_borrow_loc" => { + "borrow_loc" => { let arg = self.args1(instr)?; ImmBorrowLoc(self.local(instr, arg)?) }, @@ -608,6 +705,135 @@ impl<'a> Assembler<'a> { let sign_idx = self.type_index(instr, arg)?; CallClosure(sign_idx) }, + "pack" | "unpack" => { + let (gen_op, op): ( + fn(StructDefInstantiationIndex) -> Bytecode, + fn(StructDefinitionIndex) -> Bytecode, + ) = match instr_name.as_str() { + "pack" => (PackGeneric, Pack), + "unpack" => (UnpackGeneric, Unpack), + _ => unreachable!(), + }; + let arg = self.args1(instr)?; + let (def_idx, targs_opt) = self.struct_ref(instr, arg)?; + if let Some(targs) = targs_opt { + let res = self.builder.struct_def_inst_index(def_idx, targs); + let inst_idx = self.add_diags(instr.loc, res)?; + gen_op(inst_idx) + } else { + op(def_idx) + } + }, + "pack_variant" | "unpack_variant" | "test_variant" => { + let (gen_op, op): ( + fn(StructVariantInstantiationIndex) -> Bytecode, + fn(StructVariantHandleIndex) -> Bytecode, + ) = match instr_name.as_str() { + "pack_variant" => (PackVariantGeneric, PackVariant), + "unpack_variant" => (UnpackVariantGeneric, UnpackVariant), + "test_variant" => (TestVariantGeneric, TestVariant), + _ => unreachable!(), + }; + let [arg1, arg2] = self.args2(instr)?; + let (def_idx, targs_opt) = self.struct_ref(instr, arg1)?; + let variant_idx = self.struct_variant(instr, def_idx, arg2)?; + if let Some(targs) = targs_opt { + let inst_idx = self.add_diags( + instr.loc, + self.builder.variant_inst_index(variant_idx, targs), + )?; + gen_op(inst_idx) + } else { + op(variant_idx) + } + }, + "borrow_field" | "mut_borrow_field" => { + let (gen_op, op): ( + fn(FieldInstantiationIndex) -> Bytecode, + fn(FieldHandleIndex) -> Bytecode, + ) = match instr_name.as_str() { + "borrow_field" => (ImmBorrowFieldGeneric, ImmBorrowField), + "mut_borrow_field" => (MutBorrowFieldGeneric, MutBorrowField), + _ => unreachable!(), + }; + let [arg1, arg2] = self.args2(instr)?; + let (def_idx, targs_opt) = self.struct_ref(instr, arg1)?; + let field_name = self.simple_id(instr, arg2, " for field")?; + let field_offs = self.add_diags( + instr.loc, + self.builder + .resolve_field(def_idx, None, field_name.as_ident_str()), + )?; + let hdl_idx = + self.add_diags(instr.loc, self.builder.field_index(def_idx, field_offs))?; + if let Some(targs) = targs_opt { + let inst_idx = + self.add_diags(instr.loc, self.builder.field_inst_index(hdl_idx, targs))?; + gen_op(inst_idx) + } else { + op(hdl_idx) + } + }, + "borrow_variant_field" | "mut_borrow_variant_field" => { + let (gen_op, op): ( + fn(VariantFieldInstantiationIndex) -> Bytecode, + fn(VariantFieldHandleIndex) -> Bytecode, + ) = match instr_name.as_str() { + "borrow_variant_field" => (ImmBorrowVariantFieldGeneric, ImmBorrowVariantField), + "mut_borrow_variant_field" => { + (MutBorrowVariantFieldGeneric, MutBorrowVariantField) + }, + _ => unreachable!(), + }; + if instr.args.len() < 2 { + self.error( + instr.loc, + "expected at least 2 arguments for variant field borrow", + ); + return None; + } + let (def_idx, targs_opt) = self.struct_ref(instr, &instr.args[0])?; + + let (variants, field_offs) = self.variants(instr, def_idx)?; + let hdl_idx = self.add_diags( + instr.loc, + self.builder + .variant_field_index(def_idx, variants, field_offs), + )?; + if let Some(targs) = targs_opt { + let inst_idx = self.add_diags( + instr.loc, + self.builder.variant_field_inst_index(hdl_idx, targs), + )?; + gen_op(inst_idx) + } else { + op(hdl_idx) + } + }, + "borrow_global" | "mut_borrow_global" | "exists" | "move_from" | "move_to" => { + let (gen_op, op): ( + fn(StructDefInstantiationIndex) -> Bytecode, + fn(StructDefinitionIndex) -> Bytecode, + ) = match instr_name.as_str() { + "borrow_global" => (ImmBorrowGlobalGeneric, ImmBorrowGlobal), + "mut_borrow_global" => (MutBorrowGlobalGeneric, MutBorrowGlobal), + "exists" => (ExistsGeneric, Exists), + "move_from" => (MoveFromGeneric, MoveFrom), + "move_to" => (MoveToGeneric, MoveTo), + _ => unreachable!(), + }; + let arg = self.args1(instr)?; + let (def_idx, targs_opt) = self.struct_ref(instr, arg)?; + if let Some(targs) = targs_opt { + let inst_idx = self.add_diags( + instr.loc, + self.builder.struct_def_inst_index(def_idx, targs), + )?; + gen_op(inst_idx) + } else { + op(def_idx) + } + }, _ => { self.error(instr.loc, format!("unknown instruction `{}`", instr.name)); return None; @@ -616,13 +842,70 @@ impl<'a> Assembler<'a> { Some(instr) } - fn simple_id(&mut self, instr: &Instruction, arg: &Argument) -> Option { + fn variants( + &mut self, + instr: &Instruction, + def_idx: StructDefinitionIndex, + ) -> Option<(Vec, MemberCount)> { + let mut variants = vec![]; + let mut field_offs = None; + for field in &instr.args[1..] { + match field { + Argument::Id( + PartialIdent { + address: None, + id_parts, + }, + None, + ) if id_parts.len() == 2 => { + let variant_idx = self.add_diags( + instr.loc, + self.builder + .resolve_variant(def_idx, id_parts[0].as_ident_str()), + )?; + variants.push(variant_idx); + let offs = self.add_diags( + instr.loc, + self.builder.resolve_field( + def_idx, + Some(variant_idx), + id_parts[1].as_ident_str(), + ), + )?; + if field_offs.map(|cur| cur == offs).unwrap_or(true) { + field_offs = Some(offs) + } else { + self.error( + instr.loc, + format!( + "variants of fields must be \ + at some position, previous was {} while this is {}", + field_offs.unwrap(), + offs + ), + ); + return None; + } + }, + _ => { + self.error( + instr.loc, + "expected `::` to describe field of variant", + ); + return None; + }, + } + } + Some((variants, field_offs?)) + } + + fn simple_id(&mut self, instr: &Instruction, arg: &Argument, ctx: &str) -> Option { match arg { Argument::Id(pid, None) if pid.address.is_none() && pid.id_parts.len() == 1 => { Some(pid.id_parts[0].clone()) }, _ => { - self.error(instr.loc, "expected simple identifier"); + self.error(instr.loc, format!("expected simple identifier{}", ctx)); None }, } @@ -648,9 +931,54 @@ impl<'a> Assembler<'a> { } } + fn struct_ref( + &mut self, + instr: &Instruction, + arg: &Argument, + ) -> Option<(StructDefinitionIndex, Option>)> { + match arg { + Argument::Id( + PartialIdent { + address: None, + id_parts, + }, + targs, + ) if id_parts.len() == 1 => { + let res = self.builder.resolve_struct_def(&id_parts[0]); + let idx = self.add_diags(instr.loc, res)?; + let targs = targs.as_ref().map(|tys| { + tys.iter() + .map(|ty| self.build_type(instr.loc, ty)) + .collect() + }); + Some((idx, targs)) + }, + _ => { + self.error( + instr.loc, + "expected simple struct name with optional type instantiation", + ); + None + }, + } + } + + fn struct_variant( + &mut self, + instr: &Instruction, + def_idx: StructDefinitionIndex, + variant: &Argument, + ) -> Option { + let name = self.simple_id(instr, variant, " for variant")?; + let res = self.builder.resolve_variant(def_idx, name.as_ident_str()); + let variant_idx = self.add_diags(instr.loc, res)?; + let res = self.builder.variant_index(def_idx, variant_idx); + self.add_diags(instr.loc, res) + } + fn local(&mut self, instr: &Instruction, arg: &Argument) -> Option { - let id = self.simple_id(instr, arg)?; - if let Some((idx, _)) = self.require_fun().local_map.get(id.as_str()) { + let id = self.simple_id(instr, arg, " for local")?; + if let Some((idx, _)) = self.require_resolution_context().local_map.get(id.as_str()) { Some(*idx) } else { self.error(instr.loc, format!("unknown local `{}`", id)); diff --git a/third_party/move/tools/move-asm/src/module_builder.rs b/third_party/move/tools/move-asm/src/module_builder.rs index b3568bc5e2d..75669c7f84c 100644 --- a/third_party/move/tools/move-asm/src/module_builder.rs +++ b/third_party/move/tools/move-asm/src/module_builder.rs @@ -17,21 +17,31 @@ use move_binary_format::{ access::ModuleAccess, file_format::{ AddressIdentifierIndex, Bytecode, CodeUnit, CompiledScript, Constant, ConstantPoolIndex, - FunctionDefinition, FunctionDefinitionIndex, FunctionHandle, FunctionHandleIndex, - FunctionInstantiation, FunctionInstantiationIndex, IdentifierIndex, ModuleHandle, - ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, StructHandle, - StructHandleIndex, TableIndex, Visibility, + FieldDefinition, FieldHandle, FieldHandleIndex, FieldInstantiation, + FieldInstantiationIndex, FunctionDefinition, FunctionDefinitionIndex, FunctionHandle, + FunctionHandleIndex, FunctionInstantiation, FunctionInstantiationIndex, IdentifierIndex, + MemberCount, ModuleHandle, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, + StructDefInstantiation, StructDefInstantiationIndex, StructDefinition, + StructDefinitionIndex, StructFieldInformation, StructHandle, StructHandleIndex, + StructTypeParameter, StructVariantHandle, StructVariantHandleIndex, + StructVariantInstantiation, StructVariantInstantiationIndex, TableIndex, + VariantFieldHandle, VariantFieldHandleIndex, VariantFieldInstantiation, + VariantFieldInstantiationIndex, VariantIndex, Visibility, }, file_format_common::VERSION_DEFAULT, internals::ModuleIndex, module_to_script::convert_module_to_script, views::{ - FunctionDefinitionView, FunctionHandleView, ModuleHandleView, ModuleView, StructHandleView, + FunctionDefinitionView, FunctionHandleView, ModuleHandleView, ModuleView, + StructDefinitionView, StructHandleView, }, CompiledModule, }; use move_core_types::{ - ability::AbilitySet, account_address::AccountAddress, identifier::Identifier, language_storage, + ability::AbilitySet, + account_address::AccountAddress, + identifier::{IdentStr, Identifier}, + language_storage, language_storage::ModuleId, }; use std::{ @@ -96,6 +106,30 @@ pub struct ModuleBuilder<'a> { signature_to_idx: RefCell>, /// A mapping for constants. cons_to_idx: RefCell, SignatureToken), ConstantPoolIndex>>, + /// A mapping from struct instantiations to indices. + struct_def_inst_to_idx: + RefCell>, + /// A mapping from fields to indices. Notice that MemberCount is used in the VM for + /// representing field offsets. + field_to_idx: RefCell>, + /// A mapping from generic fields to indices. + field_inst_to_idx: + RefCell>, + /// A mapping from fields with applicable variants and offset to index. + variant_field_to_idx: RefCell< + BTreeMap<(StructDefinitionIndex, Vec, MemberCount), VariantFieldHandleIndex>, + >, + /// A mapping from field instantiations with applicable variants and offset to index. + variant_field_inst_to_idx: RefCell< + BTreeMap<(VariantFieldHandleIndex, SignatureIndex), VariantFieldInstantiationIndex>, + >, + /// A mapping from variants to index. + struct_variant_to_idx: + RefCell>, + /// A mapping from variant instantiations to index. + struct_variant_inst_to_idx: RefCell< + BTreeMap<(StructVariantHandleIndex, SignatureIndex), StructVariantInstantiationIndex>, + >, } #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)] @@ -218,6 +252,69 @@ impl<'a> ModuleBuilder<'a> { } } + /// Declares a struct and adds it to the builder. The struct initially does not have any + /// layout associated. + pub fn declare_struct( + &mut self, + name: Identifier, + type_parameters: Vec<(AbilitySet, bool)>, + abilities: AbilitySet, + ) -> Result { + if self.is_script() { + bail!("script cannot have struct definitions") + } + if self.options.validate { + let module_ref = self.module.borrow(); + let module = &*module_ref; + for sdef in &module.struct_defs { + let view = StructDefinitionView::new(module, sdef); + if view.name() == name.as_ref() { + bail!("duplicate struct definition `{}`", name); + } + } + } + let full_name = self.this_module_id(name.clone()); + let name_idx = self.name_index(name.clone())?; + let shdl = StructHandle { + module: self.this_module_idx, + name: name_idx, + abilities, + type_parameters: type_parameters + .into_iter() + .map(|(constraints, is_phantom)| StructTypeParameter { + constraints, + is_phantom, + }) + .collect(), + }; + let shdl_idx = self.index( + &mut self.module.borrow_mut().struct_handles, + &mut self.struct_to_idx.borrow_mut(), + full_name, + shdl, + StructHandleIndex, + "struct handle", + )?; + let sdef = StructDefinition { + struct_handle: shdl_idx, + // Will be later set by `define_struct_layout` + field_information: StructFieldInformation::Native, + }; + let new_idx = self.module.borrow().struct_defs.len(); + self.bounds_check(new_idx, TableIndex::MAX, "struct definition index")?; + let sidx = StructDefinitionIndex(new_idx as TableIndex); + self.module.borrow_mut().struct_defs.push(sdef); + Ok(sidx) + } + + pub fn define_struct_layout( + &self, + def_idx: StructDefinitionIndex, + layout: StructFieldInformation, + ) { + self.module.borrow_mut().struct_defs[def_idx.0 as usize].field_information = layout + } + /// Declares a function and adds it to the builder. The function /// initially does not have any code associated. /// TODO(#16582): attributes and access specifiers @@ -229,6 +326,7 @@ impl<'a> ModuleBuilder<'a> { parameters: SignatureIndex, return_: SignatureIndex, type_parameters: Vec, + acquires_global_resources: Vec, ) -> Result { if self.options.validate { let module_ref = self.module.borrow(); @@ -268,7 +366,7 @@ impl<'a> ModuleBuilder<'a> { function: fhdl_idx, visibility, is_entry, - acquires_global_resources: vec![], + acquires_global_resources, code: None, }; let new_idx = self.module.borrow().function_defs.len(); @@ -323,11 +421,15 @@ impl<'a> ModuleBuilder<'a> { // ========================================================================================== // Resolving Names + // TODO(#16582): The resolution algorithms here use linear search over tables. If better + // performance is a requirement, we should introduce lookup maps to speed this up. + /// Resolves a module name, where the name is specified to some extent. /// - If an address is given, one further name part needs to be present /// for the module. - /// - If no address is given two name parts must be present, the first + /// - If no address is given and there are two parts, the first /// an address alias, the 2nd the module name. + /// - If no address and one name part, the name must be a module alias pub fn resolve_module( &self, address_opt: &Option, @@ -339,15 +441,27 @@ impl<'a> ModuleBuilder<'a> { bail!("expected one name part after address") } ModuleId::new(*addr, name_parts[0].clone()) - } else if name_parts.len() == 2 { - // The first name must be an address alias - if let Some(addr) = self.address_aliases.get(&name_parts[0]) { - ModuleId::new(*addr, name_parts[1].clone()) - } else { - bail!("undeclared address alias `{}`", name_parts[0]) - } } else { - bail!("expected two name parts") + match name_parts.len() { + 2 => { + // The first name must be an address alias + if let Some(addr) = self.address_aliases.get(&name_parts[0]) { + ModuleId::new(*addr, name_parts[1].clone()) + } else { + bail!("undeclared address alias `{}`", name_parts[0]) + } + }, + 1 => { + if let Some(module) = self.module_aliases.get(&name_parts[0]) { + module.clone() + } else { + bail!("undeclared module alias `{}`", name_parts[0]) + } + }, + _ => { + bail!("expected two name parts") + }, + } }; if self.context_modules.contains_key(&id) || self.this_module() == id { Ok(id) @@ -392,6 +506,107 @@ impl<'a> ModuleBuilder<'a> { }) } } + + /// Same as `resolve_fun` but for structs. + pub fn resolve_struct( + &self, + address_opt: &Option, + name_parts: &[Identifier], + ) -> Result { + if address_opt.is_none() && name_parts.len() == 1 { + // A simple name can only be resolved into a struct within this module. + let module = self.module.borrow(); + for sdef in &module.struct_defs { + let view = StructDefinitionView::new(&*module, sdef); + if view.name() == name_parts[0].as_ref() { + return self.struct_index(QualifiedId { + module_id: self.this_module(), + id: name_parts[0].clone(), + }); + } + } + bail!( + "undeclared struct `{}` in `{}`", + name_parts[0], + self.this_module() + ) + } else { + // Pass address and name prefix to resolve_module. + let module_id = + self.resolve_module(address_opt, &name_parts[0..name_parts.len() - 1])?; + self.struct_index(QualifiedId { + module_id, + id: name_parts[name_parts.len() - 1].clone(), + }) + } + } + + /// Resolves a struct definition in the current module from a simple name. + pub fn resolve_struct_def(&self, name: &IdentStr) -> Result { + let module = self.module.borrow(); + for (pos, sdef) in module.struct_defs.iter().enumerate() { + let view = StructDefinitionView::new(&*module, sdef); + if view.name() == name { + return Ok(StructDefinitionIndex(pos as TableIndex)); + } + } + Err(anyhow!("undeclared struct `{}` in current module", name)) + } + + /// Resolves variant name into variant index. + pub fn resolve_variant( + &self, + struct_def: StructDefinitionIndex, + variant_name: &IdentStr, + ) -> Result { + let module = self.module.borrow(); + if let StructFieldInformation::DeclaredVariants(variants) = + &module.struct_defs[struct_def.into_index()].field_information + { + for (pos, variant) in variants.iter().enumerate() { + let name = module.identifier_at(variant.name); + if name == variant_name { + return Ok(pos as VariantIndex); + } + } + } + Err(anyhow!("undeclared variant `{}`", variant_name)) + } + + pub fn resolve_field( + &self, + struct_def: StructDefinitionIndex, + variant_opt: Option, + field_name: &IdentStr, + ) -> Result { + let module_ref = self.module.borrow(); + let module = &*module_ref; + let find_field = |fields: &[FieldDefinition]| -> Result { + for (pos, field) in fields.iter().enumerate() { + let name = module.identifier_at(field.name); + if name == field_name { + return Ok(pos as MemberCount); + } + } + Err(anyhow!("undeclared field `{}`", field_name)) + }; + match ( + &module.struct_defs[struct_def.into_index()].field_information, + variant_opt, + ) { + (StructFieldInformation::Declared(fields), None) => find_field(fields), + (StructFieldInformation::DeclaredVariants(variants), Some(n)) + if (n as usize) < variants.len() => + { + find_field(&variants[n as usize].fields) + }, + _ => Err(if variant_opt.is_some() { + anyhow!("need variant for field selection of enum") + } else { + anyhow!("invalid variant for field selection of struct") + }), + } + } } // ========================================================================================== @@ -469,8 +684,8 @@ impl<'a> ModuleBuilder<'a> { return Ok(idx); } if id.module_id == self.this_module() { - // All functions in this module should be already in fun_to_idx via - // declare_fun; so this is known to be undefined. + // All functions in this module should be already in struct_to_idx via + // declare_struct; so this is known to be undefined. bail!("unknown struct `{}` in the current module", id.id) } let hdl = self.import_struct_handle(&id)?; @@ -484,6 +699,142 @@ impl<'a> ModuleBuilder<'a> { ) } + pub fn struct_def_inst_index( + &self, + def: StructDefinitionIndex, + targs: Vec, + ) -> Result { + let type_parameters = self.signature_index(targs)?; + let entry = StructDefInstantiation { + def, + type_parameters, + }; + self.index( + &mut self.module.borrow_mut().struct_def_instantiations, + &mut self.struct_def_inst_to_idx.borrow_mut(), + (def, type_parameters), + entry, + StructDefInstantiationIndex, + "struct handle", + ) + } + + pub fn field_index( + &self, + owner: StructDefinitionIndex, + field: MemberCount, + ) -> Result { + let entry = FieldHandle { owner, field }; + self.index( + &mut self.module.borrow_mut().field_handles, + &mut self.field_to_idx.borrow_mut(), + (owner, field), + entry, + FieldHandleIndex, + "field handle", + ) + } + + pub fn field_inst_index( + &self, + handle: FieldHandleIndex, + type_parameters: Vec, + ) -> Result { + let type_parameters = self.signature_index(type_parameters)?; + let entry = FieldInstantiation { + handle, + type_parameters, + }; + self.index( + &mut self.module.borrow_mut().field_instantiations, + &mut self.field_inst_to_idx.borrow_mut(), + (handle, type_parameters), + entry, + FieldInstantiationIndex, + "generic field handle", + ) + } + + pub fn variant_field_index( + &self, + struct_index: StructDefinitionIndex, + variants: Vec, + field: MemberCount, + ) -> Result { + let entry = VariantFieldHandle { + struct_index, + variants: variants.clone(), + field, + }; + self.index( + &mut self.module.borrow_mut().variant_field_handles, + &mut self.variant_field_to_idx.borrow_mut(), + (struct_index, variants, field), + entry, + VariantFieldHandleIndex, + "variant field handle", + ) + } + + pub fn variant_field_inst_index( + &self, + handle: VariantFieldHandleIndex, + type_parameters: Vec, + ) -> Result { + let type_parameters = self.signature_index(type_parameters)?; + let entry = VariantFieldInstantiation { + handle, + type_parameters, + }; + self.index( + &mut self.module.borrow_mut().variant_field_instantiations, + &mut self.variant_field_inst_to_idx.borrow_mut(), + (handle, type_parameters), + entry, + VariantFieldInstantiationIndex, + "generic variant field handle", + ) + } + + pub fn variant_index( + &self, + struct_index: StructDefinitionIndex, + variant: VariantIndex, + ) -> Result { + let entry = StructVariantHandle { + struct_index, + variant, + }; + self.index( + &mut self.module.borrow_mut().struct_variant_handles, + &mut self.struct_variant_to_idx.borrow_mut(), + (struct_index, variant), + entry, + StructVariantHandleIndex, + "struct variant handle", + ) + } + + pub fn variant_inst_index( + &self, + handle: StructVariantHandleIndex, + type_parameters: Vec, + ) -> Result { + let type_parameters = self.signature_index(type_parameters)?; + let entry = StructVariantInstantiation { + handle, + type_parameters, + }; + self.index( + &mut self.module.borrow_mut().struct_variant_instantiations, + &mut self.struct_variant_inst_to_idx.borrow_mut(), + (handle, type_parameters), + entry, + StructVariantInstantiationIndex, + "generic struct variant handle", + ) + } + pub fn name_index(&self, name: Identifier) -> Result { self.index( &mut self.module.borrow_mut().identifiers, diff --git a/third_party/move/tools/move-asm/src/syntax.rs b/third_party/move/tools/move-asm/src/syntax.rs index 36af5e5e0e9..9ddf41c3534 100644 --- a/third_party/move/tools/move-asm/src/syntax.rs +++ b/third_party/move/tools/move-asm/src/syntax.rs @@ -17,14 +17,23 @@ //! unit := //! { address_alias LF } //! ( "module" QID | "script" ) LF -//! { struct_def | fun_def } +//! { const_def | struct_def | fun_def } +//! +//! const_def := "const" ID ":" type "=" VALUE LF //! //! struct_def := -//! /*TBD*/ +//! "struct" ID [ type_args ] fields LF +//! | "enum" ID [ type_args ] LF { INDENT ID fields LF } +//! +//! +//! fields := +//! "(" LIST(type) ")" +//! | "{" LIST(local) "}" +//! //! //! fun_def := -//! fun_modifier "fun" ID "(" [ LIST(local) ] ")" [ tuple_type ] LF -//! { "local" local LF } { instruction LF } +//! fun_modifier "fun" ID [ type_args ] "(" [ LIST(local) ] ")" [ tuple_type ] LF +//! { INDENT "local" local LF } { instruction LF } //! //! fun_modifier := [ [ "public" | "friend" ] "entry" ] //! @@ -43,6 +52,7 @@ //! "<" LIST(type) ">" //! //! instruction := +//! // Allow lables to prefix instructions without indent //! ( INDENT | LOOKAHEAD(ID ":") ) //! opcode [ LIST(argument) ] //! @@ -98,7 +108,7 @@ pub(crate) fn map_diag(result: anyhow::Result) -> AsmResult { // ========================================================================================== // Abstract Syntax -/// Represents the AST for an assembly source +/// Represents the AST for assembler source unit. #[derive(Debug)] pub struct Unit { /// The name, either script or module. @@ -107,7 +117,10 @@ pub struct Unit { pub address_aliases: Vec<(Identifier, AccountAddress)>, /// A list of module aliases. pub module_aliases: Vec<(Identifier, ModuleId)>, - /// List of functions. + /// List of struct definitions (including enums, which are technically + /// a special form of struct). + pub structs: Vec, + /// List of function definitions. pub functions: Vec, } @@ -126,18 +139,38 @@ impl UnitId { } } +#[derive(Debug)] +pub struct Struct { + pub loc: Loc, + pub name: Identifier, + /// Each type parameter is a triple `(name, constraints, is_phantom)` + pub type_params: Vec<(Identifier, AbilitySet, bool)>, + pub abilities: AbilitySet, + pub layout: StructLayout, +} + +#[derive(Debug)] +pub enum StructLayout { + // A struct with a set of field declarations. + Singleton(Vec), + // An enum with a list of variants, each one + // represented by a name and a list fields. + Variants(Vec<(Loc, Identifier, Vec)>), +} + #[derive(Debug)] pub struct Fun { pub loc: Loc, pub name: Identifier, pub visibility: Visibility, + pub is_entry: bool, pub type_params: Vec<(Identifier, AbilitySet)>, - pub params: Vec, - pub locals: Vec, + pub params: Vec, + pub locals: Vec, pub result: Vec, + pub acquires: Vec, pub instrs: Vec, } - #[derive(Debug)] pub enum Type { Named(PartialIdent, Option>), @@ -155,7 +188,7 @@ pub struct PartialIdent { } #[derive(Debug)] -pub struct Local { +pub struct Decl { pub loc: Loc, pub name: Identifier, pub ty: Type, @@ -236,6 +269,14 @@ impl AsmParser { matches!(&self.tokens[0].1, Token::Special(s) if s == sp) } + fn lookahead_newline(&self) -> bool { + matches!(&self.tokens[0].1, Token::Newline) + } + + fn lookahead_soft_kw(&self, kw: &str) -> bool { + matches!(&self.tokens[0].1, Token::Ident(s) if s == kw) + } + fn expect(&mut self, tok: &Token) -> AsmResult<()> { if !self.is_tok(tok) { Err(error( @@ -301,6 +342,7 @@ impl AsmParser { self.advance()?; Ok(Value::Number(num)) } else { + // TODO(#16582): byte strings Err(error(self.next_loc, "expected value")) } } @@ -452,13 +494,26 @@ impl AsmParser { Ok(ab) } - fn type_params(&mut self) -> AsmResult> { + fn type_params( + &mut self, + allow_phantom: bool, + ) -> AsmResult> { if !self.is_special("<") { return Ok(vec![]); } self.advance()?; let result = self.list( |parser| { + let is_phantom = if allow_phantom { + if parser.is_soft_kw("phantom") { + parser.advance()?; + true + } else { + false + } + } else { + false + }; let name = parser.ident()?; let abs = if parser.is_special(":") { parser.advance()?; @@ -466,7 +521,7 @@ impl AsmParser { } else { AbilitySet::EMPTY }; - Ok((name, abs)) + Ok((name, abs, is_phantom)) }, ",", )?; @@ -486,12 +541,12 @@ impl AsmParser { }) } - fn local_decl(&mut self) -> AsmResult { + fn decl(&mut self) -> AsmResult { let loc = self.next_loc; let name = self.ident()?; self.expect_special(":")?; let ty = self.type_()?; - Ok(Local { loc, name, ty }) + Ok(Decl { loc, name, ty }) } fn argument(&mut self) -> AsmResult { @@ -500,7 +555,7 @@ impl AsmParser { let ty = self.type_()?; self.expect_special(">")?; Ok(Argument::Type(ty)) - } else if self.is_value() { + } else if self.is_value() && !self.lookahead_special("::") { let val = self.value()?; Ok(Argument::Constant(val)) } else { @@ -541,19 +596,116 @@ impl AsmParser { }) } + fn is_struct_or_enum(&self) -> bool { + self.is_soft_kw("struct") || self.is_soft_kw("enum") + } + + fn struct_or_enum(&mut self) -> AsmResult { + if self.is_soft_kw("struct") { + self.advance()?; + let (loc, name, type_params, abilities) = self.struct_header()?; + self.expect_newline()?; + let mut fields = vec![]; + while self.is_indent() { + self.advance()?; + fields.push(self.decl()?); + self.expect_newline()? + } + Ok(Struct { + loc, + name, + type_params, + abilities, + layout: StructLayout::Singleton(fields), + }) + } else { + self.expect_soft_kw("enum")?; + let (loc, name, type_params, abilities) = self.struct_header()?; + self.expect_newline()?; + let mut variants = vec![]; + let mut cur_variant_name = None; + let mut cur_loc = Loc::new(0, 0); + let mut cur_fields = vec![]; + while self.is_indent() { + self.advance()?; + if self.is_ident() && self.lookahead_newline() { + // New enum variant + let next_loc = self.next_loc; + let variant_name = self.ident()?; + if let Some(name) = cur_variant_name { + variants.push((cur_loc, name, cur_fields)); + } + cur_loc = next_loc; + cur_variant_name = Some(variant_name); + cur_fields = vec![] + } else { + // Field for current_variant variant + cur_fields.push(self.decl()?) + } + self.expect_newline()?; + } + if let Some(name) = cur_variant_name { + variants.push((cur_loc, name, cur_fields)); + } + if variants.is_empty() { + return Err(error(loc, "enum type must have at least one variant")); + } + Ok(Struct { + loc, + name, + type_params, + abilities, + layout: StructLayout::Variants(variants), + }) + } + } + + fn struct_header( + &mut self, + ) -> AsmResult<( + Loc, + Identifier, + Vec<(Identifier, AbilitySet, bool)>, + AbilitySet, + )> { + let loc = self.next_loc; + let id = self.ident()?; + let ty_params = self.type_params(true /*allow_phantom*/)?; + let abilities = if self.is_soft_kw("has") { + self.advance()?; + self.abilities()? + } else { + AbilitySet::EMPTY + }; + Ok((loc, id, ty_params, abilities)) + } + fn is_fun(&self) -> bool { - self.is_soft_kw("fun") || self.is_soft_kw("public") || self.is_soft_kw("friend") + self.is_soft_kw("fun") + || self.is_soft_kw("entry") + || (self.is_soft_kw("public") || self.is_soft_kw("friend")) + && self.lookahead_soft_kw("fun") } fn fun(&mut self) -> AsmResult { + let is_entry = if self.is_soft_kw("entry") { + self.advance()?; + true + } else { + false + }; let visibility = self.visibility()?; self.expect_soft_kw("fun")?; let loc = self.next_loc; let name = self.ident()?; - let type_params = self.type_params()?; + let type_params = self + .type_params(false /* allow_phantom*/)? + .into_iter() + .map(|(id, ab, _)| (id, ab)) + .collect(); self.expect_special("(")?; let params = if self.is_ident() { - self.list(Self::local_decl, ",")? + self.list(Self::decl, ",")? } else { vec![] }; @@ -564,6 +716,12 @@ impl AsmParser { } else { vec![] }; + let acquires = if self.is_soft_kw("acquires") { + self.advance()?; + self.list(Self::ident, ",")? + } else { + vec![] + }; self.expect_newline()?; let mut locals = vec![]; let mut instrs = vec![]; @@ -579,7 +737,7 @@ impl AsmParser { )); } self.advance()?; - let local = self.local_decl()?; + let local = self.decl()?; locals.push(local); } else { instrs.push(self.instr()?) @@ -590,10 +748,12 @@ impl AsmParser { loc, name, visibility, + is_entry, type_params, params, locals, result, + acquires, instrs, }) } @@ -628,7 +788,7 @@ impl AsmParser { while self.is_tok(&Token::Newline) { self.advance()? } - // Parse address and module aliases + // Parse address aliases let mut address_aliases = vec![]; while self.is_soft_kw("address") { self.advance()?; @@ -642,15 +802,7 @@ impl AsmParser { .iter() .map(|(name, addr)| (name.as_ident_str(), *addr)) .collect(); - let mut module_aliases = vec![]; - while self.is_soft_kw("use") { - self.advance()?; - let module = self.module_id(&address_alias_map)?; - self.expect_soft_kw("as")?; - let name = self.ident()?; - self.expect_newline()?; - module_aliases.push((name, module)); - } + // Parse module header let name = if self.is_soft_kw("module") { self.advance()?; @@ -662,16 +814,44 @@ impl AsmParser { return Err(error(self.next_loc, "expected `module` or `script` header")); }; self.expect_newline()?; + + // Parse module aliases + let mut module_aliases = vec![]; + while self.is_soft_kw("use") { + self.advance()?; + let module = self.module_id(&address_alias_map)?; + let name = if self.is_soft_kw("as") { + self.advance()?; + self.ident()? + } else { + module.name.clone() + }; + self.expect_newline()?; + module_aliases.push((name, module)); + } + // Parse definitions + let mut structs = vec![]; let mut functions = vec![]; - while self.is_fun() { - functions.push(self.fun()?) + + while !self.is_tok(&Token::End) { + if self.is_struct_or_enum() { + structs.push(self.struct_or_enum()?) + } else if self.is_fun() { + functions.push(self.fun()?) + } else { + return Err(error( + self.next_loc, + "expected function or struct declaration", + )); + } } self.expect(&Token::End)?; Ok(Unit { name, address_aliases, module_aliases, + structs, functions, }) } @@ -785,7 +965,10 @@ fn id_cont(ch: char) -> bool { } fn special(ch: char) -> bool { - matches!(ch, '(' | ')' | '<' | '>' | ',' | ':' | '|' | '+' | '=') + matches!( + ch, + '(' | ')' | '<' | '>' | ',' | ':' | '|' | '+' | '=' | '&' + ) } impl Display for Token { diff --git a/third_party/move/tools/move-asm/tests/assembler/call_different_module.exp b/third_party/move/tools/move-asm/tests/assembler/call_different_module.exp new file mode 100644 index 00000000000..cde60cf5b2c --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/call_different_module.exp @@ -0,0 +1,35 @@ +processed 2 tasks + +task 0 'publish'. lines 1-6: + +== BEGIN Bytecode == +// Move bytecode v7 +module 66.test1 { + + +public f(Arg0: u64): u64 /* def_idx: 0 */ { +B0: + 0: MoveLoc[0](Arg0: u64) + 1: Ret +} +} +== END Bytecode == + +task 1 'publish'. lines 9-16: + +== BEGIN Bytecode == +// Move bytecode v7 +module 66.test2 { +use 0000000000000000000000000000000000000000000000000000000000000066::test1; + + + + +g(): u64 /* def_idx: 0 */ { +B0: + 0: LdU64(10) + 1: Call test1::f(u64): u64 + 2: Ret +} +} +== END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/call_different_module.masm b/third_party/move/tools/move-asm/tests/assembler/call_different_module.masm new file mode 100644 index 00000000000..65df0a407ce --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/call_different_module.masm @@ -0,0 +1,16 @@ +//# publish --print-bytecode +module 0x66::test1 + +public fun f(x: u64): u64 + move_loc x + ret + + +//# publish --print-bytecode +module 0x66::test2 +use 0x66::test1 as tm + +fun g(): u64 + ld_u64 10 + call tm::f + ret diff --git a/third_party/move/tools/move-asm/tests/assembler/declare_entry_fun.exp b/third_party/move/tools/move-asm/tests/assembler/declare_entry_fun.exp new file mode 100644 index 00000000000..8d111d6450b --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/declare_entry_fun.exp @@ -0,0 +1,16 @@ +processed 1 task + +task 0 'publish'. lines 1-6: + +== BEGIN Bytecode == +// Move bytecode v7 +module 66.test { + + +entry public f(Arg0: u64): u64 /* def_idx: 0 */ { +B0: + 0: MoveLoc[0](Arg0: u64) + 1: Ret +} +} +== END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/declare_entry_fun.masm b/third_party/move/tools/move-asm/tests/assembler/declare_entry_fun.masm new file mode 100644 index 00000000000..cde2230eec3 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/declare_entry_fun.masm @@ -0,0 +1,6 @@ +//# publish --print-bytecode +module 0x66::test + +entry public fun f(x: u64): u64 + move_loc x + ret diff --git a/third_party/move/tools/move-asm/tests/assembler/enum.exp b/third_party/move/tools/move-asm/tests/assembler/enum.exp new file mode 100644 index 00000000000..9d44e72b213 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/enum.exp @@ -0,0 +1,43 @@ +processed 1 task + +task 0 'publish'. lines 1-30: + +== BEGIN Bytecode == +// Move bytecode v7 +module 66.test { +enum E has drop { + V1{ + _1: u64, + _2: u8 + }, + V2{ + _1: u64, + _2: u32 + } +} + +pack_and_select(): u64 /* def_idx: 0 */ { +B0: + 0: LdU64(1) + 1: LdU8(2) + 2: PackVariant[0](E/V1) + 3: Call select(E): u64 + 4: Ret +} +select(Arg0: E): u64 /* def_idx: 1 */ { +B0: + 0: ImmBorrowLoc[0](Arg0: E) + 1: ImmBorrowVariantField[0](V1._1|V2._1: u64) + 2: ReadRef + 3: Ret +} +pack_and_unpack(): u64 * u32 /* def_idx: 2 */ { +B0: + 0: LdU64(1) + 1: LdU8(2) + 2: PackVariant[0](E/V1) + 3: UnpackVariant[1](E/V2) + 4: Ret +} +} +== END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/enum.masm b/third_party/move/tools/move-asm/tests/assembler/enum.masm new file mode 100644 index 00000000000..389c2982136 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/enum.masm @@ -0,0 +1,30 @@ +//# publish --print-bytecode +module 0x66::test + +enum E has drop + V1 + _1: u64 + _2: u8 + V2 + _1: u64 + _2: u32 + +fun pack_and_select(): u64 + ld_u64 1 + ld_u8 2 + pack_variant E, V1 + call select + ret + +fun select(x: E): u64 + borrow_loc x + borrow_variant_field E, V1::_1, V2::_1 + read_ref + ret + +fun pack_and_unpack(): (u64, u32) + ld_u64 1 + ld_u8 2 + pack_variant E, V1 + unpack_variant E, V2 + ret diff --git a/third_party/move/tools/move-asm/tests/assembler/enum_generic.exp b/third_party/move/tools/move-asm/tests/assembler/enum_generic.exp new file mode 100644 index 00000000000..ee20df6c160 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/enum_generic.exp @@ -0,0 +1,43 @@ +processed 1 task + +task 0 'publish'. lines 1-30: + +== BEGIN Bytecode == +// Move bytecode v7 +module 66.test { +enum E has drop { + V1{ + _1: Ty0, + _2: u8 + }, + V2{ + _1: Ty0, + _2: u32 + } +} + +pack_and_select(): u64 /* def_idx: 0 */ { +B0: + 0: LdU64(1) + 1: LdU8(2) + 2: PackVariantGeneric[0](E/V1) + 3: Call select(E): u64 + 4: Ret +} +select(Arg0: E): u64 /* def_idx: 1 */ { +B0: + 0: ImmBorrowLoc[0](Arg0: E) + 1: ImmBorrowVariantFieldGeneric[0](V1._1|V2._1: Ty0) + 2: ReadRef + 3: Ret +} +pack_and_unpack(): u64 * u32 /* def_idx: 2 */ { +B0: + 0: LdU64(1) + 1: LdU8(2) + 2: PackVariantGeneric[0](E/V1) + 3: UnpackVariantGeneric[1](E/V2) + 4: Ret +} +} +== END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/enum_generic.masm b/third_party/move/tools/move-asm/tests/assembler/enum_generic.masm new file mode 100644 index 00000000000..0157e42966d --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/enum_generic.masm @@ -0,0 +1,30 @@ +//# publish --print-bytecode +module 0x66::test + +enum E has drop + V1 + _1: A + _2: u8 + V2 + _1: A + _2: u32 + +fun pack_and_select(): u64 + ld_u64 1 + ld_u8 2 + pack_variant E, V1 + call select + ret + +fun select(x: E): u64 + borrow_loc x + borrow_variant_field E, V1::_1, V2::_1 + read_ref + ret + +fun pack_and_unpack(): (u64, u32) + ld_u64 1 + ld_u8 2 + pack_variant E, V1 + unpack_variant E, V2 + ret diff --git a/third_party/move/tools/move-asm/tests/assembler/resource.exp b/third_party/move/tools/move-asm/tests/assembler/resource.exp new file mode 100644 index 00000000000..a2d8874e0c8 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/resource.exp @@ -0,0 +1,29 @@ +processed 1 task + +task 0 'publish'. lines 1-19: + +== BEGIN Bytecode == +// Move bytecode v7 +module 66.test { +struct S has drop, key { + x: u64 +} + +move_to(Arg0: &signer) /* def_idx: 0 */ { +B0: + 0: MoveLoc[0](Arg0: &signer) + 1: LdU64(3) + 2: Pack[0](S) + 3: MoveTo[0](S) + 4: Ret +} +borrow(Arg0: address): u64 /* def_idx: 1 */ { +B0: + 0: MoveLoc[0](Arg0: address) + 1: ImmBorrowGlobal[0](S) + 2: ImmBorrowField[0](S.x: u64) + 3: ReadRef + 4: Ret +} +} +== END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/resource.masm b/third_party/move/tools/move-asm/tests/assembler/resource.masm new file mode 100644 index 00000000000..2ed7b306984 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/resource.masm @@ -0,0 +1,19 @@ +//# publish --print-bytecode --verbose +module 0x66::test + +struct S has key+drop + x: u64 + +fun move_to(s: &signer) + move_loc s + ld_u64 3 + pack S + move_to S + ret + +fun borrow(a: address): u64 acquires S + move_loc a + borrow_global S + borrow_field S, x + read_ref + ret diff --git a/third_party/move/tools/move-asm/tests/assembler/resource_generic.exp b/third_party/move/tools/move-asm/tests/assembler/resource_generic.exp new file mode 100644 index 00000000000..fe4b50e474d --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/resource_generic.exp @@ -0,0 +1,29 @@ +processed 1 task + +task 0 'publish'. lines 1-19: + +== BEGIN Bytecode == +// Move bytecode v7 +module 66.test { +struct S has drop, key { + x: Ty0 +} + +move_to(Arg0: &signer) /* def_idx: 0 */ { +B0: + 0: MoveLoc[0](Arg0: &signer) + 1: LdU64(3) + 2: PackGeneric[0](S) + 3: MoveToGeneric[0](S) + 4: Ret +} +borrow(Arg0: address): u64 /* def_idx: 1 */ { +B0: + 0: MoveLoc[0](Arg0: address) + 1: ImmBorrowGlobalGeneric[0](S) + 2: ImmBorrowFieldGeneric[0](S.x: Ty0) + 3: ReadRef + 4: Ret +} +} +== END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/resource_generic.masm b/third_party/move/tools/move-asm/tests/assembler/resource_generic.masm new file mode 100644 index 00000000000..6a8cadf0663 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/resource_generic.masm @@ -0,0 +1,19 @@ +//# publish --print-bytecode --verbose +module 0x66::test + +struct S has key+drop + x: A + +fun move_to(s: &signer) + move_loc s + ld_u64 3 + pack S + move_to S + ret + +fun borrow(a: address): u64 acquires S + move_loc a + borrow_global S + borrow_field S, x + read_ref + ret diff --git a/third_party/move/tools/move-asm/tests/assembler/struct.exp b/third_party/move/tools/move-asm/tests/assembler/struct.exp new file mode 100644 index 00000000000..99b406254b0 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/struct.exp @@ -0,0 +1,37 @@ +processed 1 task + +task 0 'publish'. lines 1-26: + +== BEGIN Bytecode == +// Move bytecode v7 +module 66.test { +struct S has drop { + _1: u64, + _2: u8 +} + +pack_and_select(): u8 /* def_idx: 0 */ { +B0: + 0: LdU64(3) + 1: LdU8(2) + 2: Pack[0](S) + 3: Call select(S): u8 + 4: Ret +} +select(Arg0: S): u8 /* def_idx: 1 */ { +B0: + 0: ImmBorrowLoc[0](Arg0: S) + 1: ImmBorrowField[0](S._2: u8) + 2: ReadRef + 3: Ret +} +pack_and_unpack(): u64 * u8 /* def_idx: 2 */ { +B0: + 0: LdU64(3) + 1: LdU8(2) + 2: Pack[0](S) + 3: Unpack[0](S) + 4: Ret +} +} +== END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/struct.masm b/third_party/move/tools/move-asm/tests/assembler/struct.masm new file mode 100644 index 00000000000..53b0204ae9e --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/struct.masm @@ -0,0 +1,26 @@ +//# publish --print-bytecode +module 0x66::test + +struct S has drop + _1: u64 + _2: u8 + +fun pack_and_select(): u8 + ld_u64 3 + ld_u8 2 + pack S + call select + ret + +fun select(x: S): u8 + borrow_loc x + borrow_field S, _2 + read_ref + ret + +fun pack_and_unpack(): (u64, u8) + ld_u64 3 + ld_u8 2 + pack S + unpack S + ret diff --git a/third_party/move/tools/move-asm/tests/assembler/struct_generic.exp b/third_party/move/tools/move-asm/tests/assembler/struct_generic.exp new file mode 100644 index 00000000000..2be319c4482 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/struct_generic.exp @@ -0,0 +1,37 @@ +processed 1 task + +task 0 'publish'. lines 1-26: + +== BEGIN Bytecode == +// Move bytecode v7 +module 66.test { +struct S has drop { + _1: u64, + _2: Ty0 +} + +pack_and_select(): u8 /* def_idx: 0 */ { +B0: + 0: LdU64(3) + 1: LdU8(2) + 2: PackGeneric[0](S) + 3: Call select(S): u8 + 4: Ret +} +select(Arg0: S): u8 /* def_idx: 1 */ { +B0: + 0: ImmBorrowLoc[0](Arg0: S) + 1: ImmBorrowFieldGeneric[0](S._2: Ty0) + 2: ReadRef + 3: Ret +} +pack_and_unpack(): u64 * u8 /* def_idx: 2 */ { +B0: + 0: LdU64(3) + 1: LdU8(2) + 2: PackGeneric[0](S) + 3: UnpackGeneric[0](S) + 4: Ret +} +} +== END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/struct_generic.masm b/third_party/move/tools/move-asm/tests/assembler/struct_generic.masm new file mode 100644 index 00000000000..12e498045bf --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/struct_generic.masm @@ -0,0 +1,26 @@ +//# publish --print-bytecode +module 0x66::test + +struct S has drop + _1: u64 + _2: A + +fun pack_and_select(): u8 + ld_u64 3 + ld_u8 2 + pack S + call select + ret + +fun select(x: S): u8 + borrow_loc x + borrow_field S, _2 + read_ref + ret + +fun pack_and_unpack(): (u64, u8) + ld_u64 3 + ld_u8 2 + pack S + unpack S + ret diff --git a/third_party/move/tools/move-asm/tests/assembler/struct_use.exp b/third_party/move/tools/move-asm/tests/assembler/struct_use.exp new file mode 100644 index 00000000000..050e3224c8d --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/struct_use.exp @@ -0,0 +1,37 @@ +processed 2 tasks + +task 0 'publish'. lines 1-6: + +== BEGIN Bytecode == +// Move bytecode v7 +module 66.test1 { +struct S has copy, drop { + _1: u64, + _2: u8 +} + + +} +== END Bytecode == + +task 1 'publish'. lines 8-19: + +== BEGIN Bytecode == +// Move bytecode v7 +module 66.test2 { +use 0000000000000000000000000000000000000000000000000000000000000066::test1; + + +struct T has drop { + _1: S +} + +get(Arg0: T): S /* def_idx: 0 */ { +B0: + 0: ImmBorrowLoc[0](Arg0: T) + 1: ImmBorrowField[0](T._1: S) + 2: ReadRef + 3: Ret +} +} +== END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/struct_use.masm b/third_party/move/tools/move-asm/tests/assembler/struct_use.masm new file mode 100644 index 00000000000..3d9e436ac50 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/struct_use.masm @@ -0,0 +1,19 @@ +//# publish --print-bytecode +module 0x66::test1 + +struct S has drop+copy + _1: u64 + _2: u8 + +//# publish --print-bytecode +module 0x66::test2 +use 0x66::test1 + +struct T has drop + _1: 0x66::test1::S + +fun get(x: T): test1::S + borrow_loc x + borrow_field T, _1 + read_ref + ret diff --git a/third_party/move/tools/move-asm/tests/assembler/unknown_field.exp b/third_party/move/tools/move-asm/tests/assembler/unknown_field.exp new file mode 100644 index 00000000000..3eac93fd4a0 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/unknown_field.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-11: +Error: error: undeclared field `bad` + ┌─ test:7:5 + │ +7 │ borrow_field S, bad + │ ^^^^^^^^^^^^^^^^^^^ + + diff --git a/third_party/move/tools/move-asm/tests/assembler/unknown_field.masm b/third_party/move/tools/move-asm/tests/assembler/unknown_field.masm new file mode 100644 index 00000000000..8cd7fc743dc --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/unknown_field.masm @@ -0,0 +1,11 @@ +//# publish --print-bytecode +module 0x66::test + +struct S has drop + x: u64 + +fun select(x: S): u64 + borrow_loc x + borrow_field S, bad + read_ref + ret diff --git a/third_party/move/tools/move-asm/tests/assembler/unknown_variant.exp b/third_party/move/tools/move-asm/tests/assembler/unknown_variant.exp new file mode 100644 index 00000000000..9d97cd86cf1 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/unknown_variant.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-12: +Error: error: undeclared variant `V2` + ┌─ test:8:5 + │ +8 │ borrow_variant_field E, V2::y + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + diff --git a/third_party/move/tools/move-asm/tests/assembler/unknown_variant.masm b/third_party/move/tools/move-asm/tests/assembler/unknown_variant.masm new file mode 100644 index 00000000000..69b5aab9841 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/unknown_variant.masm @@ -0,0 +1,12 @@ +//# publish --print-bytecode +module 0x66::test + +enum E has drop + V1 + x: u64 + +fun select(x: E): u64 + borrow_loc x + borrow_variant_field E, V2::y + read_ref + ret From 2ce64cd8db6af56571fc4ed81857be5527059b9e Mon Sep 17 00:00:00 2001 From: Wolfgang Grieskamp Date: Mon, 21 Jul 2025 13:36:34 -0700 Subject: [PATCH 048/260] [move-asm] Disassembler for new Move Assembler Language (#17091) * [move-asm] Disassembler for new Move Assembler Language This adds a disassembler for the .masm format. This is for now integrated into txn tests by calling an approprivate entry point into the test framework (see `testsuite.rs`), causing those tests to print the new format instead of the legacy Move disassembler. All existing move-asm tests use the new output format. The output has been manually inspected but not yet formally via roundtripping. * Fixing tests Downstreamed-from: f7a54c892cb07df24d9c44c33f48e906559efa18 --- .../move/move-binary-format/src/lib.rs | 2 +- .../src/module_script_conversion.rs | 210 ++++++ .../src/module_to_script.rs | 87 --- .../src/file_format_generator/mod.rs | 4 +- third_party/move/move-model/src/lib.rs | 131 +--- .../transactional-tests/tests/tests.rs | 1 + .../src/framework.rs | 42 +- .../transactional-test-runner/src/tasks.rs | 3 +- .../src/vm_test_harness.rs | 25 + .../move/tools/move-asm/src/assembler.rs | 133 +++- .../move/tools/move-asm/src/disassembler.rs | 705 ++++++++++++++++++ third_party/move/tools/move-asm/src/lib.rs | 119 +-- third_party/move/tools/move-asm/src/main.rs | 2 +- .../move/tools/move-asm/src/module_builder.rs | 4 +- .../tests/assembler/address_alias.exp | 24 +- .../tools/move-asm/tests/assembler/branch.exp | 33 +- .../tests/assembler/call_different_module.exp | 34 +- .../tests/assembler/call_same_module.exp | 26 +- .../assembler/call_same_module_generic.exp | 26 +- .../move-asm/tests/assembler/closure.exp | 28 +- .../tests/assembler/declare_entry_fun.exp | 14 +- .../move-asm/tests/assembler/declare_fun.exp | 29 +- .../tests/assembler/declare_generic_fun.exp | 16 +- .../tools/move-asm/tests/assembler/enum.exp | 69 +- .../move-asm/tests/assembler/enum_generic.exp | 69 +- .../move-asm/tests/assembler/resource.exp | 43 +- .../tests/assembler/resource_generic.exp | 43 +- .../tools/move-asm/tests/assembler/struct.exp | 59 +- .../tests/assembler/struct_generic.exp | 59 +- .../move-asm/tests/assembler/struct_use.exp | 43 +- .../move/tools/move-asm/tests/testsuite.rs | 3 +- .../txn-test-integration/print_bytecode.exp | 26 +- .../publish_and_run_module.exp | 14 +- 33 files changed, 1416 insertions(+), 710 deletions(-) create mode 100644 third_party/move/move-binary-format/src/module_script_conversion.rs delete mode 100644 third_party/move/move-binary-format/src/module_to_script.rs create mode 100644 third_party/move/tools/move-asm/src/disassembler.rs diff --git a/third_party/move/move-binary-format/src/lib.rs b/third_party/move/move-binary-format/src/lib.rs index 9bd8061d535..6fb864cdf01 100644 --- a/third_party/move/move-binary-format/src/lib.rs +++ b/third_party/move/move-binary-format/src/lib.rs @@ -22,7 +22,7 @@ pub mod deserializer; pub mod file_format; pub mod file_format_common; pub mod internals; -pub mod module_to_script; +pub mod module_script_conversion; pub mod normalized; #[cfg(any(test, feature = "fuzzing"))] pub mod proptest_types; diff --git a/third_party/move/move-binary-format/src/module_script_conversion.rs b/third_party/move/move-binary-format/src/module_script_conversion.rs new file mode 100644 index 00000000000..5bde887b5e4 --- /dev/null +++ b/third_party/move/move-binary-format/src/module_script_conversion.rs @@ -0,0 +1,210 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + check_bounds::BoundsChecker, + file_format::{ + AddressIdentifierIndex, CompiledScript, FunctionDefinition, FunctionHandle, + FunctionHandleIndex, IdentifierIndex, ModuleHandle, ModuleHandleIndex, Signature, + SignatureIndex, Visibility, + }, + CompiledModule, +}; +use anyhow::bail; +use move_core_types::{identifier::Identifier, language_storage::pseudo_script_module_id}; + +/// Converts a compiled module into a script. The module must define exactly one function +/// and no types. The `main_handle` is the handle info of the one function in the module +/// which must not be contained in function_handles table. +pub fn module_into_script( + module: CompiledModule, + main_handle: FunctionHandle, +) -> anyhow::Result { + let CompiledModule { + version, + self_module_handle_idx: _, + module_handles, + struct_handles, + function_handles, + field_handles: _, + friend_decls: _, + struct_def_instantiations: _, + field_instantiations: _, + struct_defs, + mut function_defs, + function_instantiations, + signatures, + identifiers, + address_identifiers, + constant_pool, + metadata, + struct_variant_handles: _, + struct_variant_instantiations: _, + variant_field_handles: _, + variant_field_instantiations: _, + } = module; + if function_defs.len() != 1 { + bail!("scripts can only contain one function") + } + if !struct_defs.is_empty() { + bail!("scripts cannot have struct or enum declarations") + } + let FunctionDefinition { + function: _, + visibility: _, + is_entry: _, + acquires_global_resources: _, + code, + } = function_defs.pop().unwrap(); + let Some(code) = code else { + bail!("script functions must have a body") + }; + let FunctionHandle { + module: _, + name: _, + parameters, + return_, + type_parameters, + access_specifiers, + attributes: _, + } = main_handle; + if signatures + .get(return_.0 as usize) + .map_or(true, |s| !s.is_empty()) + { + bail!("main function must not return values") + } + Ok(CompiledScript { + version, + module_handles, + struct_handles, + function_handles, + function_instantiations, + signatures, + identifiers, + address_identifiers, + constant_pool, + metadata, + code, + type_parameters, + parameters, + access_specifiers, + }) +} + +/// Converts a compiled script into a module. The function in the script gets +/// `name` assigned in the produced module. +pub fn script_into_module(compiled_script: CompiledScript, name: &str) -> CompiledModule { + let mut script = compiled_script; + + // Add the "" identifier if it isn't present. + let self_ident_idx = match script + .identifiers + .iter() + .position(|ident| ident.as_ident_str().as_str() == name) + { + Some(idx) => IdentifierIndex::new(idx as u16), + None => { + let idx = IdentifierIndex::new(script.identifiers.len() as u16); + script + .identifiers + .push(Identifier::new(name.to_string()).unwrap()); + idx + }, + }; + + // Add a dummy address if none exists. + let dummy_addr = pseudo_script_module_id().address; + let dummy_addr_idx = match script + .address_identifiers + .iter() + .position(|addr| addr == &dummy_addr) + { + Some(idx) => AddressIdentifierIndex::new(idx as u16), + None => { + let idx = AddressIdentifierIndex::new(script.address_identifiers.len() as u16); + script.address_identifiers.push(dummy_addr); + idx + }, + }; + + // Add a self module handle. + let self_module_handle_idx = match script + .module_handles + .iter() + .position(|handle| handle.address == dummy_addr_idx && handle.name == self_ident_idx) + { + Some(idx) => ModuleHandleIndex::new(idx as u16), + None => { + let idx = ModuleHandleIndex::new(script.module_handles.len() as u16); + script.module_handles.push(ModuleHandle { + address: dummy_addr_idx, + name: self_ident_idx, + }); + idx + }, + }; + + // Find the index to the empty signature []. + // Create one if it doesn't exist. + let return_sig_idx = match script.signatures.iter().position(|sig| sig.0.is_empty()) { + Some(idx) => SignatureIndex::new(idx as u16), + None => { + let idx = SignatureIndex::new(script.signatures.len() as u16); + script.signatures.push(Signature(vec![])); + idx + }, + }; + + // Create a function handle for the main function. + let main_handle_idx = FunctionHandleIndex::new(script.function_handles.len() as u16); + script.function_handles.push(FunctionHandle { + module: self_module_handle_idx, + name: self_ident_idx, + parameters: script.parameters, + return_: return_sig_idx, + type_parameters: script.type_parameters, + access_specifiers: None, // TODO: access specifiers for script functions + attributes: vec![], + }); + + // Create a function definition for the main function. + let main_def = FunctionDefinition { + function: main_handle_idx, + visibility: Visibility::Public, + is_entry: true, + acquires_global_resources: vec![], + code: Some(script.code), + }; + + let module = CompiledModule { + version: script.version, + module_handles: script.module_handles, + self_module_handle_idx, + struct_handles: script.struct_handles, + function_handles: script.function_handles, + field_handles: vec![], + friend_decls: vec![], + + struct_def_instantiations: vec![], + function_instantiations: script.function_instantiations, + field_instantiations: vec![], + + signatures: script.signatures, + + identifiers: script.identifiers, + address_identifiers: script.address_identifiers, + constant_pool: script.constant_pool, + metadata: script.metadata, + + struct_defs: vec![], + function_defs: vec![main_def], + + struct_variant_handles: vec![], + struct_variant_instantiations: vec![], + variant_field_handles: vec![], + variant_field_instantiations: vec![], + }; + BoundsChecker::verify_module(&module).expect("invalid bounds in module"); + module +} diff --git a/third_party/move/move-binary-format/src/module_to_script.rs b/third_party/move/move-binary-format/src/module_to_script.rs deleted file mode 100644 index 4d1c6a86255..00000000000 --- a/third_party/move/move-binary-format/src/module_to_script.rs +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use crate::{ - file_format::{CompiledScript, FunctionDefinition, FunctionHandle}, - CompiledModule, -}; -use anyhow::bail; - -/// Converts a compiled module into a script. The module must define exactly one function -/// and no types. The `main_handle` is the handle info of the one function in the module -/// which must not be contained in function_handles table. -pub fn convert_module_to_script( - module: CompiledModule, - main_handle: FunctionHandle, -) -> anyhow::Result { - let CompiledModule { - version, - self_module_handle_idx: _, - module_handles, - struct_handles, - function_handles, - field_handles: _, - friend_decls: _, - struct_def_instantiations: _, - field_instantiations: _, - struct_defs, - mut function_defs, - function_instantiations, - signatures, - identifiers, - address_identifiers, - constant_pool, - metadata, - struct_variant_handles: _, - struct_variant_instantiations: _, - variant_field_handles: _, - variant_field_instantiations: _, - } = module; - if function_defs.len() != 1 { - bail!("scripts can only contain one function") - } - if !struct_defs.is_empty() { - bail!("scripts cannot have struct or enum declarations") - } - let FunctionDefinition { - function: _, - visibility: _, - is_entry: _, - acquires_global_resources: _, - code, - } = function_defs.pop().unwrap(); - let Some(code) = code else { - bail!("script functions must have a body") - }; - let FunctionHandle { - module: _, - name: _, - parameters, - return_, - type_parameters, - access_specifiers, - attributes: _, - } = main_handle; - if signatures - .get(return_.0 as usize) - .map_or(true, |s| !s.is_empty()) - { - bail!("main function must not return values") - } - Ok(CompiledScript { - version, - module_handles, - struct_handles, - function_handles, - function_instantiations, - signatures, - identifiers, - address_identifiers, - constant_pool, - metadata, - code, - type_parameters, - parameters, - access_specifiers, - }) -} diff --git a/third_party/move/move-compiler-v2/src/file_format_generator/mod.rs b/third_party/move/move-compiler-v2/src/file_format_generator/mod.rs index 55b6d55f741..ce8ba11eb4e 100644 --- a/third_party/move/move-compiler-v2/src/file_format_generator/mod.rs +++ b/third_party/move/move-compiler-v2/src/file_format_generator/mod.rs @@ -8,7 +8,7 @@ mod peephole_optimizer; use crate::{file_format_generator::module_generator::ModuleContext, options::Options, Experiment}; use legacy_move_compiler::compiled_unit as CU; use module_generator::ModuleGenerator; -use move_binary_format::{file_format as FF, internals::ModuleIndex}; +use move_binary_format::{file_format as FF, internals::ModuleIndex, module_script_conversion}; use move_command_line_common::{address::NumericalAddress, parser::NumberFormat}; use move_model::{ast::ModuleName, model::GlobalEnv}; use move_stackless_bytecode::function_target_pipeline::FunctionTargetsHolder; @@ -81,7 +81,7 @@ pub fn generate_file_format( let module_name = ModuleName::pseudo_script_name(env.symbol_pool(), script_index); script_index += 1; - let module = move_model::script_into_module( + let module = module_script_conversion::script_into_module( script.clone(), &module_name.name().display(env.symbol_pool()).to_string(), ); diff --git a/third_party/move/move-model/src/lib.rs b/third_party/move/move-model/src/lib.rs index b74745af0bb..1f3f99e5086 100644 --- a/third_party/move/move-model/src/lib.rs +++ b/third_party/move/move-model/src/lib.rs @@ -26,14 +26,10 @@ use legacy_move_compiler::{ Compiler, Flags, PASS_EXPANSION, PASS_PARSER, }; use move_binary_format::{ - check_bounds::BoundsChecker, - file_format::{ - AddressIdentifierIndex, CompiledModule, CompiledScript, FunctionDefinition, FunctionHandle, - FunctionHandleIndex, IdentifierIndex, ModuleHandle, ModuleHandleIndex, Signature, - SignatureIndex, Visibility, - }, + file_format::{CompiledModule, CompiledScript}, + module_script_conversion, }; -use move_core_types::{account_address::AccountAddress, identifier::Identifier}; +use move_core_types::account_address::AccountAddress; use move_symbol_pool::Symbol as MoveSymbol; use std::{ collections::{BTreeMap, BTreeSet}, @@ -524,126 +520,7 @@ pub fn convert_script_to_module(script: CompiledScript, index: usize) -> Compile .expect("malformed script without function"); let name = script.identifier_at(fhd.name); let unique_name = format!("{}_{}", name, index); - script_into_module(script, &unique_name) -} - -#[allow(deprecated)] -pub fn script_into_module(compiled_script: CompiledScript, name: &str) -> CompiledModule { - let mut script = compiled_script; - - // Add the "" identifier if it isn't present. - // - // Note: When adding an element to the table, in theory it is possible for the index - // to overflow. This will not be a problem if we get rid of the script/module conversion. - let self_ident_idx = match script - .identifiers - .iter() - .position(|ident| ident.as_ident_str().as_str() == name) - { - Some(idx) => IdentifierIndex::new(idx as u16), - None => { - let idx = IdentifierIndex::new(script.identifiers.len() as u16); - script - .identifiers - .push(Identifier::new(name.to_string()).unwrap()); - idx - }, - }; - - // Add a dummy address if none exists. - let dummy_addr = AccountAddress::MAX_ADDRESS; - let dummy_addr_idx = match script - .address_identifiers - .iter() - .position(|addr| addr == &dummy_addr) - { - Some(idx) => AddressIdentifierIndex::new(idx as u16), - None => { - let idx = AddressIdentifierIndex::new(script.address_identifiers.len() as u16); - script.address_identifiers.push(dummy_addr); - idx - }, - }; - - // Add a self module handle. - let self_module_handle_idx = match script - .module_handles - .iter() - .position(|handle| handle.address == dummy_addr_idx && handle.name == self_ident_idx) - { - Some(idx) => ModuleHandleIndex::new(idx as u16), - None => { - let idx = ModuleHandleIndex::new(script.module_handles.len() as u16); - script.module_handles.push(ModuleHandle { - address: dummy_addr_idx, - name: self_ident_idx, - }); - idx - }, - }; - - // Find the index to the empty signature []. - // Create one if it doesn't exist. - let return_sig_idx = match script.signatures.iter().position(|sig| sig.0.is_empty()) { - Some(idx) => SignatureIndex::new(idx as u16), - None => { - let idx = SignatureIndex::new(script.signatures.len() as u16); - script.signatures.push(Signature(vec![])); - idx - }, - }; - - // Create a function handle for the main function. - let main_handle_idx = FunctionHandleIndex::new(script.function_handles.len() as u16); - script.function_handles.push(FunctionHandle { - module: self_module_handle_idx, - name: self_ident_idx, - parameters: script.parameters, - return_: return_sig_idx, - type_parameters: script.type_parameters, - access_specifiers: None, // TODO: access specifiers for script functions - attributes: vec![], - }); - - // Create a function definition for the main function. - let main_def = FunctionDefinition { - function: main_handle_idx, - visibility: Visibility::Public, - is_entry: true, - acquires_global_resources: vec![], - code: Some(script.code), - }; - - let module = CompiledModule { - version: script.version, - module_handles: script.module_handles, - self_module_handle_idx, - struct_handles: script.struct_handles, - function_handles: script.function_handles, - field_handles: vec![], - friend_decls: vec![], - - struct_def_instantiations: vec![], - function_instantiations: script.function_instantiations, - field_instantiations: vec![], - - signatures: script.signatures, - - identifiers: script.identifiers, - address_identifiers: script.address_identifiers, - constant_pool: script.constant_pool, - metadata: script.metadata, - - struct_defs: vec![], - function_defs: vec![main_def], - - struct_variant_handles: vec![], - struct_variant_instantiations: vec![], - variant_field_handles: vec![], - variant_field_instantiations: vec![], - }; - BoundsChecker::verify_module(&module).expect("invalid bounds in module"); - module + module_script_conversion::script_into_module(script, &unique_name) } // ================================================================================================= diff --git a/third_party/move/move-vm/transactional-tests/tests/tests.rs b/third_party/move/move-vm/transactional-tests/tests/tests.rs index c14381f4509..eeda87861e4 100644 --- a/third_party/move/move-vm/transactional-tests/tests/tests.rs +++ b/third_party/move/move-vm/transactional-tests/tests/tests.rs @@ -127,6 +127,7 @@ fn run(path: &Path, config: TestConfig) -> datatest_stable::Result<()> { language_version: config.language_version, experiments, vm_config: config.vm_config, + use_masm: false, }; vm_test_harness::run_test_with_config_and_exp_suffix(vm_test_config, path, &exp_suffix) diff --git a/third_party/move/testing-infra/transactional-test-runner/src/framework.rs b/third_party/move/testing-infra/transactional-test-runner/src/framework.rs index 18b64e2b077..b80702f67f7 100644 --- a/third_party/move/testing-infra/transactional-test-runner/src/framework.rs +++ b/third_party/move/testing-infra/transactional-test-runner/src/framework.rs @@ -15,7 +15,7 @@ use anyhow::{anyhow, bail, Result}; use clap::Parser; use either::Either; use legacy_move_compiler::{compiled_unit::AnnotatedCompiledUnit, shared::NumericalAddress}; -use move_asm::{self, ModuleOrScript}; +use move_asm::assembler; use move_binary_format::{ binary_views::BinaryIndexedView, file_format::{CompiledModule, CompiledScript}, @@ -242,6 +242,7 @@ pub trait MoveTestAdapter<'a>: Sized { language_version, experiments, vm_config: _, + use_masm: _, } => compile_source_unit_v2( state.pre_compiled_deps_v2, state.named_address_mapping.clone(), @@ -318,6 +319,7 @@ pub trait MoveTestAdapter<'a>: Sized { language_version, experiments: v2_experiments, vm_config: _, + use_masm: _, } => compile_source_unit_v2( state.pre_compiled_deps_v2, state.named_address_mapping.clone(), @@ -386,12 +388,22 @@ pub trait MoveTestAdapter<'a>: Sized { PrintBytecodeInputChoice::Script => { let (script, _warning_opt) = self.compile_script(syntax, data, start_line, command_lines_stop)?; - disassembler_for_view(BinaryIndexedView::Script(&script)).disassemble()? + if self.run_config().using_masm() { + move_asm::disassembler::disassemble_script(String::new(), &script)? + } else { + disassembler_for_view(BinaryIndexedView::Script(&script)) + .disassemble()? + } }, PrintBytecodeInputChoice::Module => { let (_data, _named_addr_opt, module, _warnings_opt) = self.compile_module(syntax, data, start_line, command_lines_stop)?; - disassembler_for_view(BinaryIndexedView::Module(&module)).disassemble()? + if self.run_config().using_masm() { + move_asm::disassembler::disassemble_module(String::new(), &module)? + } else { + disassembler_for_view(BinaryIndexedView::Module(&module)) + .disassemble()? + } }, }; Ok(Some(result)) @@ -409,10 +421,14 @@ pub trait MoveTestAdapter<'a>: Sized { self.compile_module(syntax, data, start_line, command_lines_stop)?; self.register_temp_filename(&data); let printed = if print_bytecode { - let disassembler = disassembler_for_view(BinaryIndexedView::Module(&module)); + let out = if self.run_config().using_masm() { + move_asm::disassembler::disassemble_module(String::new(), &module)? + } else { + disassembler_for_view(BinaryIndexedView::Module(&module)).disassemble()? + }; Some(format!( "\n== BEGIN Bytecode ==\n{}\n== END Bytecode ==", - disassembler.disassemble()? + out )) } else { None @@ -461,10 +477,14 @@ pub trait MoveTestAdapter<'a>: Sized { let (script, warning_opt) = self.compile_script(syntax, data, start_line, command_lines_stop)?; let printed = if print_bytecode { - let disassembler = disassembler_for_view(BinaryIndexedView::Script(&script)); + let out = if self.run_config().using_masm() { + move_asm::disassembler::disassemble_script(String::new(), &script)? + } else { + disassembler_for_view(BinaryIndexedView::Script(&script)).disassemble()? + }; Some(format!( "\n== BEGIN Bytecode ==\n{}\n== END Bytecode ==", - disassembler.disassemble()? + out )) } else { None @@ -877,11 +897,11 @@ fn compile_asm_script<'a>( fn compile_asm<'a>( deps: impl Iterator, path: &str, -) -> Result { - let options = move_asm::Options::default(); +) -> Result { + let options = assembler::Options::default(); let source = fs::read_to_string(path)?; - move_asm::assemble(&options, &source, deps) - .map_err(|diags| anyhow!(move_asm::diag_to_string("test", &source, diags))) + assembler::assemble(&options, &source, deps) + .map_err(|diags| anyhow!(assembler::diag_to_string("test", &source, diags))) } pub fn run_test_impl<'a, Adapter>( diff --git a/third_party/move/testing-infra/transactional-test-runner/src/tasks.rs b/third_party/move/testing-infra/transactional-test-runner/src/tasks.rs index 32516f9ae47..45f4e04a8c3 100644 --- a/third_party/move/testing-infra/transactional-test-runner/src/tasks.rs +++ b/third_party/move/testing-infra/transactional-test-runner/src/tasks.rs @@ -207,7 +207,8 @@ pub struct PrintBytecodeCommand { /// The kind of input: either a script, or a module. #[clap(long = "input", value_enum, ignore_case = true, default_value_t = PrintBytecodeInputChoice::Script)] pub input: PrintBytecodeInputChoice, - /// Select Move source ("move") source or MoveIR ("mvir"). Is inferred from filename if absent. + /// Select Move source ("move"), MoveIR ("mvir"), or Move Assembler ("masm"). Is inferred + /// from filename if absent. #[clap(long = "syntax")] pub syntax: Option, } diff --git a/third_party/move/testing-infra/transactional-test-runner/src/vm_test_harness.rs b/third_party/move/testing-infra/transactional-test-runner/src/vm_test_harness.rs index 0b8c8b7cbac..c394ae5d97e 100644 --- a/third_party/move/testing-infra/transactional-test-runner/src/vm_test_harness.rs +++ b/third_party/move/testing-infra/transactional-test-runner/src/vm_test_harness.rs @@ -504,6 +504,9 @@ pub enum TestRunConfig { experiments: Vec<(String, bool)>, /// Configuration for the VM that runs tests. vm_config: VMConfig, + /// Whether to use Move Assembler (.masm) format when printing + /// bytecode. + use_masm: bool, }, } @@ -521,6 +524,20 @@ impl TestRunConfig { paranoid_type_checks: true, ..VMConfig::default() }, + use_masm: false, + } + } + + pub fn with_masm(mut self) -> TestRunConfig { + match &mut self { + Self::CompilerV2 { use_masm, .. } => *use_masm = true, + } + self + } + + pub(crate) fn using_masm(&self) -> bool { + match self { + Self::CompilerV2 { use_masm, .. } => *use_masm, } } } @@ -532,6 +549,14 @@ pub fn run_test(path: &Path) -> Result<(), Box> { ) } +// Notice this will go away once we have removed legacy disassembler +pub fn run_test_print_bytecode_with_masm(path: &Path) -> Result<(), Box> { + run_test_with_config( + TestRunConfig::compiler_v2(LanguageVersion::default(), vec![]).with_masm(), + path, + ) +} + fn precompiled_v2_stdlib() -> &'static PrecompiledFilesModules { &PRECOMPILED_MOVE_STDLIB_V2 } diff --git a/third_party/move/tools/move-asm/src/assembler.rs b/third_party/move/tools/move-asm/src/assembler.rs index 94e94a21e31..fd84fc735b3 100644 --- a/third_party/move/tools/move-asm/src/assembler.rs +++ b/third_party/move/tools/move-asm/src/assembler.rs @@ -11,21 +11,135 @@ use crate::{ map_diag, Argument, AsmResult, Decl, Diag, Fun, Instruction, Loc, PartialIdent, Struct, StructLayout, Type, Unit, UnitId, Value, }, - ModuleOrScript, +}; +use anyhow::{anyhow, bail}; +use clap::Parser; +use codespan_reporting::{ + files::{Files, SimpleFile}, + term, + term::{termcolor, termcolor::WriteColor}, }; use either::Either; use move_binary_format::{ file_format::{ - Bytecode, CodeOffset, FieldDefinition, FieldHandleIndex, FieldInstantiationIndex, - FunctionDefinitionIndex, FunctionHandleIndex, LocalIndex, MemberCount, SignatureIndex, - SignatureToken, StructDefInstantiationIndex, StructDefinitionIndex, StructFieldInformation, - StructVariantHandleIndex, StructVariantInstantiationIndex, TableIndex, TypeSignature, - VariantDefinition, VariantFieldHandleIndex, VariantFieldInstantiationIndex, VariantIndex, + Bytecode, CodeOffset, CompiledScript, FieldDefinition, FieldHandleIndex, + FieldInstantiationIndex, FunctionDefinitionIndex, FunctionHandleIndex, LocalIndex, + MemberCount, SignatureIndex, SignatureToken, StructDefInstantiationIndex, + StructDefinitionIndex, StructFieldInformation, StructVariantHandleIndex, + StructVariantInstantiationIndex, TableIndex, TypeSignature, VariantDefinition, + VariantFieldHandleIndex, VariantFieldInstantiationIndex, VariantIndex, }, CompiledModule, }; use move_core_types::{function::ClosureMask, identifier::Identifier, u256::U256}; -use std::collections::BTreeMap; +use std::{collections::BTreeMap, fs, io::Write, path::PathBuf}; + +// =================================================================================== +// Driver + +pub type ModuleOrScript = Either; + +#[derive(Parser, Clone, Debug, Default)] +#[clap(author, version, about)] +pub struct Options { + /// Options for the module builder + #[clap(flatten)] + pub module_builder_options: ModuleBuilderOptions, + + /// List of files with binary dependencies + #[clap(short, long)] + pub deps: Vec, + + /// Directory where to place assembled code. + #[clap(short, long, default_value = "")] + pub output_dir: String, + + /// Input file. + pub inputs: Vec, +} + +/// Assembles source as specified by options. +pub fn run(options: Options, error_writer: &mut W) -> anyhow::Result<()> +where + W: Write + WriteColor, +{ + if options.inputs.len() != 1 { + bail!("expected exactly one file name for the assembler source") + } + let input_path = options.inputs.first().unwrap(); + let input = fs::read_to_string(input_path)?; + + let context_modules = options + .deps + .iter() + .map(|file| { + let bytes = fs::read(file).map_err(|e| anyhow!(e))?; + CompiledModule::deserialize(&bytes).map_err(|e| anyhow!(e)) + }) + .collect::>>()?; + + let result = match assemble(&options, &input, context_modules.iter()) { + Ok(x) => x, + Err(diags) => { + let diag_file = SimpleFile::new(&input_path, &input); + report_diags(error_writer, &diag_file, diags); + bail!("exiting with errors") + }, + }; + + let path = PathBuf::from(input_path).with_extension("mv"); + let mut out_path = PathBuf::from(options.output_dir); + out_path.push(path.file_name().expect("file name available")); + let mut bytes = vec![]; + match result { + Either::Left(m) => m + .serialize_for_version( + Some(options.module_builder_options.bytecode_version), + &mut bytes, + ) + .expect("serialization succeeds"), + Either::Right(s) => s + .serialize_for_version( + Some(options.module_builder_options.bytecode_version), + &mut bytes, + ) + .expect("serialization succeeds"), + } + if let Err(e) = fs::write(&out_path, &bytes) { + bail!("failed to write result to `{}`: {}", out_path.display(), e); + } + Ok(()) +} + +pub fn assemble<'a>( + options: &Options, + input: &str, + context_modules: impl Iterator, +) -> AsmResult { + let ast = syntax::parse_asm(input)?; + compile(options.module_builder_options.clone(), context_modules, ast) +} + +pub fn diag_to_string(file_name: &str, source: &str, diags: Vec) -> String { + let files = SimpleFile::new(file_name, source); + let mut error_writer = termcolor::Buffer::no_color(); + report_diags(&mut error_writer, &files, diags); + String::from_utf8_lossy(&error_writer.into_inner()).to_string() +} + +pub(crate) fn report_diags<'a, W: Write + WriteColor>( + error_writer: &mut W, + files: &'a impl Files<'a, FileId = ()>, + diags: Vec, +) { + for diag in diags { + term::emit(error_writer, &term::Config::default(), files, &diag) + .unwrap_or_else(|_| eprintln!("failed to print diagnostics")) + } +} + +// =================================================================================== +// Logic struct Assembler<'a> { builder: ModuleBuilder<'a>, @@ -39,7 +153,7 @@ struct ResolutionContext { local_map: BTreeMap, } -pub(crate) fn compile<'a>( +fn compile<'a>( options: ModuleBuilderOptions, context_modules: impl IntoIterator, ast: Unit, @@ -634,7 +748,6 @@ impl<'a> Assembler<'a> { self.args0(instr)?; Nop }, - // TODO: resource operations "shl" => { self.args0(instr)?; Shl @@ -654,7 +767,7 @@ impl<'a> Assembler<'a> { let sign_idx = self.type_index(instr, arg)?; VecLen(sign_idx) }, - "vec_imm_borrow" => { + "vec_borrow" => { let arg = self.args1(instr)?; let sign_idx = self.type_index(instr, arg)?; VecImmBorrow(sign_idx) diff --git a/third_party/move/tools/move-asm/src/disassembler.rs b/third_party/move/tools/move-asm/src/disassembler.rs new file mode 100644 index 00000000000..51d88a39a4a --- /dev/null +++ b/third_party/move/tools/move-asm/src/disassembler.rs @@ -0,0 +1,705 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Disassembler for Move bytecode. + +use anyhow::bail; +use move_binary_format::{ + access::ModuleAccess, + file_format::{ + Bytecode, CodeOffset, CompiledScript, FieldHandleIndex, LocalIndex, SignatureIndex, + SignatureToken, VariantFieldHandleIndex, VariantIndex, Visibility, + }, + module_script_conversion::script_into_module, + views::{ + FieldDefinitionView, FunctionDefinitionView, FunctionHandleView, ModuleView, + StructDefinitionView, StructHandleView, ViewInternals, + }, + CompiledModule, +}; +use move_core_types::{ + ability::AbilitySet, + identifier::Identifier, + language_storage::{pseudo_script_module_id, ModuleId}, +}; +use std::{ + cmp::Ordering, + collections::{BTreeMap, BTreeSet}, + fmt, +}; + +pub fn disassemble_module(out: T, module: &CompiledModule) -> anyhow::Result { + Disassembler::run(out, module) +} + +pub fn disassemble_script(out: T, script: &CompiledScript) -> anyhow::Result { + let script_as_module = script_into_module(script.clone(), "main"); + Disassembler::run(out, &script_as_module) +} + +struct Disassembler +where + T: fmt::Write, +{ + out: T, + self_module: ModuleId, + reverse_module_aliases: BTreeMap, +} + +impl Disassembler { + fn run(out: T, module: &CompiledModule) -> anyhow::Result { + let version = module.version; + let module = ModuleView::new(module); + let mut dis = Disassembler { + out, + self_module: module.id(), + reverse_module_aliases: BTreeMap::new(), + }; + writeln!(dis.out, "// Bytecode version v{}", version)?; + if module.id().address == pseudo_script_module_id().address { + writeln!(dis.out, "script")?; + } else { + writeln!(dis.out, "module {}", module.id().short_str_lossless())?; + } + + // Process used modules, deriving short names for them. + let mut used_short_names = BTreeSet::new(); + for used_module in module.module_handles() { + let id = used_module.module_id(); + if id == module.id() { + continue; + } + let mut short_name = id.name.clone(); + while !used_short_names.insert(short_name.clone()) { + // Make short name unique if needed + short_name = Identifier::new_unchecked(format!("{}_", short_name)) + } + writeln!( + dis.out, + "use {}{}", + id.short_str_lossless(), + if short_name == id.name { + "".to_string() + } else { + format!(" as {}", short_name) + } + )?; + dis.reverse_module_aliases.insert(id, short_name); + } + + // Process struct and function definitions + for str in module.structs() { + dis.struct_(str)?; + writeln!(dis.out)? + } + for (idx, fdef) in module.functions().enumerate() { + writeln!(dis.out, "// Function definition at index {}", idx)?; + dis.fun(fdef)?; + writeln!(dis.out)? + } + + Ok(dis.out) + } + + // -------------------------------------------------------------------------------------- + // Structs and Types + + fn struct_(&mut self, str: StructDefinitionView) -> anyhow::Result<()> { + if str.variant_count() == 0 { + write!(self.out, "struct {}", str.name())?; + } else { + write!(self.out, "enum {}", str.name())?; + } + if !str.type_parameters().is_empty() { + self.list( + str.type_parameters().as_slice(), + |dis, idx, tparam| dis.type_param_decl(tparam.is_phantom, idx, tparam.constraints), + "<", + ",", + ">", + )? + } + writeln!(self.out)?; + if str.variant_count() == 0 { + self.fields(" ", str.fields_optional_variant(None))? + } else { + for variant in 0..str.variant_count() { + let variant_idx = variant as VariantIndex; + writeln!(self.out, " {}", str.variant_name(variant_idx))?; + self.fields(" ", str.fields_optional_variant(Some(variant_idx)))? + } + } + Ok(()) + } + + fn fields<'a>( + &mut self, + indent: &str, + fields: impl DoubleEndedIterator>, + ) -> anyhow::Result<()> { + for field in fields { + write!(self.out, "{}{}: ", indent, field.name())?; + self.type_(field.module(), field.signature_token())?; + writeln!(self.out)? + } + Ok(()) + } + + fn type_param_decl( + &mut self, + is_phantom: bool, + idx: usize, + constraints: AbilitySet, + ) -> anyhow::Result<()> { + if is_phantom { + self.out.write_str("phantom ")?; + } + self.out.write_str(&type_param_name(idx))?; + if !constraints.is_empty() { + write!(self.out, ": {}", constraints)? + } + Ok(()) + } + + fn type_(&mut self, module: &CompiledModule, ty: &SignatureToken) -> anyhow::Result<()> { + use SignatureToken::*; + match ty { + Bool => self.out.write_str("bool")?, + U8 => self.out.write_str("u8")?, + U16 => self.out.write_str("u16")?, + U32 => self.out.write_str("u32")?, + U64 => self.out.write_str("u64")?, + U128 => self.out.write_str("u128")?, + U256 => self.out.write_str("u256")?, + Address => self.out.write_str("address")?, + Signer => self.out.write_str("signer")?, + Vector(elem_ty) => { + self.out.write_str("vector<")?; + self.type_(module, elem_ty)?; + self.out.write_str(">")?; + }, + Function(params, result, abilities) => { + self.list(params, |dis, _, e| dis.type_(module, e), "|", ",", "|")?; + match result.len().cmp(&1) { + Ordering::Less => {}, + Ordering::Equal => self.type_(module, &result[0])?, + Ordering::Greater => { + self.list(result, |dis, _, e| dis.type_(module, e), "(", ",", ")")?; + }, + } + self.out + .write_str(&abilities.display_postfix().to_string())?; + }, + Struct(idx) | StructInstantiation(idx, _) => { + let view = StructHandleView::new(module, module.struct_handle_at(*idx)); + write!( + self.out, + "{}{}", + self.module_id_prefix(&view.module_id())?, + view.name() + )?; + if let StructInstantiation(_, inst) = ty { + self.list(inst, |dis, _, e| dis.type_(module, e), "<", ",", ">")? + } + }, + Reference(elem_ty) => { + self.out.write_str("&")?; + self.type_(module, elem_ty)? + }, + MutableReference(elem_ty) => { + self.out.write_str("&mut ")?; + self.type_(module, elem_ty)? + }, + TypeParameter(idx) => self.out.write_str(&type_param_name(*idx as usize))?, + } + Ok(()) + } + + // -------------------------------------------------------------------------------------- + // Functions + + fn fun(&mut self, fdef: FunctionDefinitionView) -> anyhow::Result<()> { + // Function header + if fdef.is_entry() { + self.out.write_str("entry ")? + } + match fdef.visibility() { + Visibility::Private => {}, + Visibility::Public => self.out.write_str("public ")?, + Visibility::Friend => self.out.write_str("friend ")?, + } + write!(self.out, "fun {}", fdef.name())?; + if !fdef.type_parameters().is_empty() { + self.list( + fdef.type_parameters().as_slice(), + |dis, idx, abilities| dis.type_param_decl(false, idx, *abilities), + "<", + ",", + ">", + )? + } + let arg_tokens = fdef.arg_tokens().collect::>(); + self.list( + &arg_tokens, + |dis, pos, ty| { + write!(dis.out, "{}: ", local_name(pos as LocalIndex))?; + dis.type_(fdef.module(), ty.signature_token()) + }, + "(", + ",", + ")", + )?; + if fdef.return_count() > 0 { + self.out.write_str(": ")?; + if fdef.return_count() > 1 { + self.list( + &fdef.return_tokens().collect::>(), + |dis, _, ty| dis.type_(fdef.module(), ty.signature_token()), + "(", + ",", + ")", + )? + } else { + self.type_( + fdef.module(), + fdef.return_tokens().next().unwrap().signature_token(), + )? + } + } + writeln!(self.out)?; + + if let Some(unit) = fdef.code() { + // Declare locals + let locals_sign = fdef.module().signature_at(unit.locals); + for (pos, ty) in locals_sign.0.iter().enumerate() { + // The actual local number is # of parameters + // plus the position in this list. + write!( + self.out, + " local {}: ", + local_name((arg_tokens.len() + pos) as LocalIndex) + )?; + self.type_(fdef.module(), ty)?; + writeln!(self.out)? + } + // Compute branch labels + let mut label_map: BTreeMap = BTreeMap::new(); + for bc in &unit.code { + match bc { + Bytecode::Branch(offs) | Bytecode::BrTrue(offs) | Bytecode::BrFalse(offs) => { + let curr_count = label_map.len(); + label_map + .entry(*offs) + .or_insert_with(|| format!("l{}", curr_count)); + }, + _ => {}, + } + } + // Emit code + for (offs, bc) in unit.code.iter().enumerate() { + if offs != 0 && offs % 5 == 0 { + writeln!(self.out, " // @{}", offs)? + } + if let Some(label) = label_map.get(&(offs as CodeOffset)) { + write!(self.out, "{:>2}: ", label)?; + } else { + write!(self.out, " ")?; + } + self.bytecode(fdef.module(), &label_map, bc)?; + writeln!(self.out)? + } + } + Ok(()) + } + + fn bytecode( + &mut self, + module: &CompiledModule, + label_map: &BTreeMap, + bc: &Bytecode, + ) -> anyhow::Result<()> { + use Bytecode::*; + match bc { + Pop => write!(self.out, "pop")?, + Ret => write!(self.out, "ret")?, + BrTrue(offs) | BrFalse(offs) | Branch(offs) => { + let Some(label) = label_map.get(offs) else { + bail!("unexpected code offset without label") + }; + match bc { + Branch(_) => write!(self.out, "branch {}", label)?, + BrTrue(_) => write!(self.out, "br_true {}", label)?, + BrFalse(_) => write!(self.out, "br_false {}", label)?, + _ => unreachable!(), + } + }, + LdU8(v) => write!(self.out, "ld_u8 {}", v)?, + LdU16(v) => write!(self.out, "ld_u16 {}", v)?, + LdU32(v) => write!(self.out, "ld_u32 {}", v)?, + LdU64(v) => write!(self.out, "ld_u64 {}", v)?, + LdU128(v) => write!(self.out, "ld_u128 {}", v)?, + LdU256(v) => write!(self.out, "ld_u256 {}", v)?, + CastU8 => write!(self.out, "cast_u8")?, + CastU16 => write!(self.out, "cast_u16")?, + CastU32 => write!(self.out, "cast_u32")?, + CastU64 => write!(self.out, "cast_u64")?, + CastU128 => write!(self.out, "cast_u128")?, + CastU256 => write!(self.out, "cast_u256")?, + LdConst(hdl) => { + write!(self.out, "ld_const ")?; + let cons = module.constant_at(*hdl); + self.type_(module, &cons.type_)?; + write!( + self.out, + ", {}", + value_from_bcs(module, &cons.type_, &cons.data)? + )? + }, + LdTrue => write!(self.out, "ld_true")?, + LdFalse => write!(self.out, "ld_false")?, + CopyLoc(loc) => write!(self.out, "copy_loc {}", local_name(*loc))?, + MoveLoc(loc) => write!(self.out, "move_loc {}", local_name(*loc))?, + StLoc(loc) => write!(self.out, "st_loc {}", local_name(*loc))?, + Call(idx) => { + let view = FunctionHandleView::new(module, module.function_handle_at(*idx)); + write!( + self.out, + "call {}{}", + self.module_id_prefix(&view.module_id())?, + view.name() + )? + }, + CallGeneric(idx) => { + let inst_handle = module.function_instantiation_at(*idx); + let view = + FunctionHandleView::new(module, module.function_handle_at(inst_handle.handle)); + write!( + self.out, + "call {}{}", + self.module_id_prefix(&view.module_id())?, + view.name() + )?; + self.ty_args(module, inst_handle.type_parameters)? + }, + Pack(idx) | Unpack(idx) => { + let op = if matches!(bc, Pack(_)) { + "pack" + } else { + "unpack" + }; + let view = StructDefinitionView::new(module, module.struct_def_at(*idx)); + write!(self.out, "{} {}", op, view.name())? + }, + PackGeneric(idx) | UnpackGeneric(idx) => { + let op = if matches!(bc, PackGeneric(_)) { + "pack" + } else { + "unpack" + }; + let inst_handle = module.struct_instantiation_at(*idx); + let view = StructDefinitionView::new(module, module.struct_def_at(inst_handle.def)); + write!(self.out, "{} {}", op, view.name())?; + self.ty_args(module, inst_handle.type_parameters)? + }, + PackVariant(idx) | UnpackVariant(idx) | TestVariant(idx) => { + let op = match bc { + PackVariant(_) => "pack_variant", + UnpackVariant(_) => "unpack_variant", + _ => "test_variant", + }; + let handle = module.struct_variant_handle_at(*idx); + let view = + StructDefinitionView::new(module, module.struct_def_at(handle.struct_index)); + let variant_name = view.variant_name(handle.variant); + write!(self.out, "{} {}, {}", op, view.name(), variant_name)? + }, + PackVariantGeneric(idx) | UnpackVariantGeneric(idx) | TestVariantGeneric(idx) => { + let op = match bc { + PackVariantGeneric(_) => "pack_variant", + UnpackVariantGeneric(_) => "unpack_variant", + _ => "test_variant", + }; + let inst_handle = module.struct_variant_instantiation_at(*idx); + let handle = module.struct_variant_handle_at(inst_handle.handle); + let view = + StructDefinitionView::new(module, module.struct_def_at(handle.struct_index)); + let variant_name = view.variant_name(handle.variant); + write!(self.out, "{} {}", op, view.name())?; + self.ty_args(module, inst_handle.type_parameters)?; + write!(self.out, ", {}", variant_name)? + }, + ReadRef => write!(self.out, "read_ref")?, + WriteRef => write!(self.out, "write_ref")?, + FreezeRef => write!(self.out, "freeze_ref")?, + MutBorrowLoc(idx) => write!(self.out, "mut_borrow_loc {}", local_name(*idx))?, + ImmBorrowLoc(idx) => write!(self.out, "borrow_loc {}", local_name(*idx))?, + MutBorrowField(idx) => self.borrow_field(module, true, *idx, None)?, + ImmBorrowField(idx) => self.borrow_field(module, false, *idx, None)?, + MutBorrowFieldGeneric(idx) => { + let inst_handle = module.field_instantiation_at(*idx); + self.borrow_field( + module, + true, + inst_handle.handle, + Some(inst_handle.type_parameters), + )? + }, + ImmBorrowFieldGeneric(idx) => { + let inst_handle = module.field_instantiation_at(*idx); + self.borrow_field( + module, + false, + inst_handle.handle, + Some(inst_handle.type_parameters), + )? + }, + MutBorrowVariantField(idx) => self.borrow_variant_field(module, true, *idx, None)?, + ImmBorrowVariantField(idx) => self.borrow_variant_field(module, false, *idx, None)?, + MutBorrowVariantFieldGeneric(idx) => { + let inst_handle = module.variant_field_instantiation_at(*idx); + self.borrow_variant_field( + module, + true, + inst_handle.handle, + Some(inst_handle.type_parameters), + )? + }, + ImmBorrowVariantFieldGeneric(idx) => { + let inst_handle = module.variant_field_instantiation_at(*idx); + self.borrow_variant_field( + module, + false, + inst_handle.handle, + Some(inst_handle.type_parameters), + )? + }, + MutBorrowGlobal(idx) | ImmBorrowGlobal(idx) | Exists(idx) | MoveFrom(idx) + | MoveTo(idx) => { + let op = match bc { + MutBorrowGlobal(_) => "mut_borrow_global", + ImmBorrowGlobal(_) => "borrow_global", + Exists(_) => "exists", + MoveFrom(_) => "move_from", + MoveTo(_) => "move_to", + _ => unreachable!(), + }; + let view = StructDefinitionView::new(module, module.struct_def_at(*idx)); + write!(self.out, "{} {}", op, view.name())? + }, + MutBorrowGlobalGeneric(idx) + | ImmBorrowGlobalGeneric(idx) + | ExistsGeneric(idx) + | MoveFromGeneric(idx) + | MoveToGeneric(idx) => { + let op = match bc { + MutBorrowGlobalGeneric(_) => "mut_borrow_global", + ImmBorrowGlobalGeneric(_) => "borrow_global", + ExistsGeneric(_) => "exists", + MoveFromGeneric(_) => "move_from", + MoveToGeneric(_) => "move_to", + _ => unreachable!(), + }; + let inst_handle = module.struct_instantiation_at(*idx); + let view = StructDefinitionView::new(module, module.struct_def_at(inst_handle.def)); + write!(self.out, "{} {}", op, view.name())?; + self.ty_args(module, inst_handle.type_parameters)? + }, + Add => write!(self.out, "add")?, + Sub => write!(self.out, "sub")?, + Mul => write!(self.out, "mul")?, + Mod => write!(self.out, "mod")?, + Div => write!(self.out, "div")?, + BitOr => write!(self.out, "bit_or")?, + BitAnd => write!(self.out, "bit_and")?, + Xor => write!(self.out, "xor")?, + Or => write!(self.out, "or")?, + And => write!(self.out, "and")?, + Not => write!(self.out, "not")?, + Eq => write!(self.out, "eq")?, + Neq => write!(self.out, "neq")?, + Lt => write!(self.out, "lt")?, + Gt => write!(self.out, "gt")?, + Le => write!(self.out, "le")?, + Ge => write!(self.out, "ge")?, + Abort => write!(self.out, "abort")?, + Nop => write!(self.out, "nop")?, + Shl => write!(self.out, "shl")?, + Shr => write!(self.out, "shr")?, + VecPack(idx, len) => { + write!(self.out, "vec_pack ")?; + self.ty_args(module, *idx)?; + write!(self.out, ", {}", len)?; + }, + VecLen(idx) => { + write!(self.out, "vec_len ")?; + self.ty_args(module, *idx)?; + }, + VecImmBorrow(idx) => { + write!(self.out, "vec_borrow ")?; + self.ty_args(module, *idx)?; + }, + VecMutBorrow(idx) => { + write!(self.out, "vec_mut_borrow ")?; + self.ty_args(module, *idx)?; + }, + VecPushBack(idx) => { + write!(self.out, "vec_push_back ")?; + self.ty_args(module, *idx)?; + }, + VecPopBack(idx) => { + write!(self.out, "vec_pop_back ")?; + self.ty_args(module, *idx)?; + }, + VecUnpack(idx, len) => { + write!(self.out, "vec_unpack ")?; + self.ty_args(module, *idx)?; + write!(self.out, ", {}", len)?; + }, + VecSwap(idx) => { + write!(self.out, "vec_swap ")?; + self.ty_args(module, *idx)?; + }, + PackClosure(idx, mask) => { + let view = FunctionHandleView::new(module, module.function_handle_at(*idx)); + write!( + self.out, + "pack_closure {}{}, {}", + self.module_id_prefix(&view.module_id())?, + view.name(), + mask + )? + }, + PackClosureGeneric(idx, mask) => { + let inst_handle = module.function_instantiation_at(*idx); + let view = + FunctionHandleView::new(module, module.function_handle_at(inst_handle.handle)); + write!( + self.out, + "pack_closure {}{}", + self.module_id_prefix(&view.module_id())?, + view.name() + )?; + self.ty_args(module, inst_handle.type_parameters)?; + write!(self.out, ", {}", mask)? + }, + CallClosure(idx) => { + write!(self.out, "call_closure ")?; + self.ty_args(module, *idx)?; + }, + } + Ok(()) + } + + fn borrow_field( + &mut self, + module: &CompiledModule, + is_mut: bool, + field_idx: FieldHandleIndex, + inst_opt: Option, + ) -> anyhow::Result<()> { + let op = if is_mut { + "mut_borrow_field" + } else { + "borrow_field" + }; + let handle = module.field_handle_at(field_idx); + let view = StructDefinitionView::new(module, module.struct_def_at(handle.owner)); + let field_name = view + .fields_optional_variant(None) + .nth(handle.field as usize) + .map_or("".to_string(), |f| f.name().to_string()); + write!(self.out, "{} {}", op, view.name())?; + if let Some(inst) = inst_opt { + self.ty_args(module, inst)? + } + write!(self.out, ", {}", field_name)?; + Ok(()) + } + + fn borrow_variant_field( + &mut self, + module: &CompiledModule, + is_mut: bool, + field_idx: VariantFieldHandleIndex, + inst_opt: Option, + ) -> anyhow::Result<()> { + let op = if is_mut { + "mut_borrow_variant_field" + } else { + "borrow_variant_field" + }; + let handle = module.variant_field_handle_at(field_idx); + let view = StructDefinitionView::new(module, module.struct_def_at(handle.struct_index)); + write!(self.out, "{} {}", op, view.name())?; + if let Some(inst) = inst_opt { + self.ty_args(module, inst)? + } + for variant_idx in &handle.variants { + let field_name = view + .fields_optional_variant(Some(*variant_idx)) + .nth(handle.field as usize) + .map_or("".to_string(), |f| f.name().to_string()); + write!( + self.out, + ", {}::{}", + view.variant_name(*variant_idx), + field_name + )? + } + Ok(()) + } + + fn ty_args(&mut self, module: &CompiledModule, sign_idx: SignatureIndex) -> anyhow::Result<()> { + let sign = module.signature_at(sign_idx); + self.list(&sign.0, |dis, _, e| dis.type_(module, e), "<", ",", ">") + } + + // -------------------------------------------------------------------------------------- + // General Helpers + + fn module_id_prefix(&self, module_id: &ModuleId) -> anyhow::Result { + if &self.self_module == module_id { + Ok(format!("{}::", self.self_module.name)) + } else if let Some(short) = self.reverse_module_aliases.get(module_id) { + Ok(format!("{}::", short)) + } else { + Ok(format!("{}::", module_id.short_str_lossless())) + } + } + + fn list( + &mut self, + elems: &[E], + writer: impl Fn(&mut Self, usize, &E) -> anyhow::Result<()>, + open: &str, + sep: &str, + close: &str, + ) -> anyhow::Result<()> { + self.out.write_str(open)?; + for (count, elem) in elems.iter().enumerate() { + if count > 0 { + self.out.write_str(sep)? + } + writer(self, count, elem)?; + } + self.out.write_str(close)?; + Ok(()) + } +} + +fn type_param_name(idx: usize) -> String { + format!("T{}", idx) +} + +fn local_name(idx: LocalIndex) -> String { + format!("l{}", idx) +} + +fn value_from_bcs( + _module: &CompiledModule, + _ty: &SignatureToken, + _bcs: &[u8], +) -> anyhow::Result { + // TODO(#16582): implement this + bail!("value bcs not implemented") +} diff --git a/third_party/move/tools/move-asm/src/lib.rs b/third_party/move/tools/move-asm/src/lib.rs index d761d9a9a8b..19d9b3a921a 100644 --- a/third_party/move/tools/move-asm/src/lib.rs +++ b/third_party/move/tools/move-asm/src/lib.rs @@ -1,124 +1,7 @@ // Copyright (c) Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -//! Entry point into the Move assembler ('move-asm'). - pub mod assembler; +pub mod disassembler; pub mod module_builder; pub mod syntax; - -use crate::{ - module_builder::ModuleBuilderOptions, - syntax::{AsmResult, Diag}, -}; -use anyhow::{anyhow, bail}; -use clap::Parser; -use codespan_reporting::{ - files::{Files, SimpleFile}, - term, - term::{termcolor, termcolor::WriteColor}, -}; -use either::Either; -use move_binary_format::{file_format::CompiledScript, CompiledModule}; -use std::{fs, io::Write, path::PathBuf}; - -pub type ModuleOrScript = Either; - -#[derive(Parser, Clone, Debug, Default)] -#[clap(author, version, about)] -pub struct Options { - /// Options for the module builder - #[clap(flatten)] - pub module_builder_options: ModuleBuilderOptions, - - /// List of files with binary dependencies - #[clap(short, long)] - pub deps: Vec, - - /// Directory where to place assembled code. - #[clap(short, long, default_value = "")] - pub output_dir: String, - - /// Input file. - pub inputs: Vec, -} - -/// Assembles source as specified by options. -pub fn run(options: Options, error_writer: &mut W) -> anyhow::Result<()> -where - W: Write + WriteColor, -{ - if options.inputs.len() != 1 { - bail!("expected exactly one file name for the assembler source") - } - let input_path = options.inputs.first().unwrap(); - let input = fs::read_to_string(input_path)?; - - let context_modules = options - .deps - .iter() - .map(|file| { - let bytes = fs::read(file).map_err(|e| anyhow!(e))?; - CompiledModule::deserialize(&bytes).map_err(|e| anyhow!(e)) - }) - .collect::>>()?; - - let result = match assemble(&options, &input, context_modules.iter()) { - Ok(x) => x, - Err(diags) => { - let diag_file = SimpleFile::new(&input_path, &input); - report_diags(error_writer, &diag_file, diags); - bail!("exiting with errors") - }, - }; - - let path = PathBuf::from(input_path).with_extension("mv"); - let mut out_path = PathBuf::from(options.output_dir); - out_path.push(path.file_name().expect("file name available")); - let mut bytes = vec![]; - match result { - Either::Left(m) => m - .serialize_for_version( - Some(options.module_builder_options.bytecode_version), - &mut bytes, - ) - .expect("serialization succeeds"), - Either::Right(s) => s - .serialize_for_version( - Some(options.module_builder_options.bytecode_version), - &mut bytes, - ) - .expect("serialization succeeds"), - } - if let Err(e) = fs::write(&out_path, &bytes) { - bail!("failed to write result to `{}`: {}", out_path.display(), e); - } - Ok(()) -} - -pub fn assemble<'a>( - options: &Options, - input: &str, - context_modules: impl Iterator, -) -> AsmResult { - let ast = syntax::parse_asm(input)?; - assembler::compile(options.module_builder_options.clone(), context_modules, ast) -} - -pub fn diag_to_string(file_name: &str, source: &str, diags: Vec) -> String { - let files = SimpleFile::new(file_name, source); - let mut error_writer = termcolor::Buffer::no_color(); - report_diags(&mut error_writer, &files, diags); - String::from_utf8_lossy(&error_writer.into_inner()).to_string() -} - -pub(crate) fn report_diags<'a, W: Write + WriteColor>( - error_writer: &mut W, - files: &'a impl Files<'a, FileId = ()>, - diags: Vec, -) { - for diag in diags { - term::emit(error_writer, &term::Config::default(), files, &diag) - .unwrap_or_else(|_| eprintln!("failed to print diagnostics")) - } -} diff --git a/third_party/move/tools/move-asm/src/main.rs b/third_party/move/tools/move-asm/src/main.rs index 98d62bdcae2..5da02be8566 100644 --- a/third_party/move/tools/move-asm/src/main.rs +++ b/third_party/move/tools/move-asm/src/main.rs @@ -3,7 +3,7 @@ use clap::Parser; use codespan_reporting::term::termcolor::{ColorChoice, StandardStream}; -use move_asm::{run, Options}; +use move_asm::assembler::{run, Options}; fn main() { let mut error_writer = StandardStream::stderr(ColorChoice::Auto); diff --git a/third_party/move/tools/move-asm/src/module_builder.rs b/third_party/move/tools/move-asm/src/module_builder.rs index 75669c7f84c..63b2656783d 100644 --- a/third_party/move/tools/move-asm/src/module_builder.rs +++ b/third_party/move/tools/move-asm/src/module_builder.rs @@ -30,7 +30,7 @@ use move_binary_format::{ }, file_format_common::VERSION_DEFAULT, internals::ModuleIndex, - module_to_script::convert_module_to_script, + module_script_conversion::module_into_script, views::{ FunctionDefinitionView, FunctionHandleView, ModuleHandleView, ModuleView, StructDefinitionView, StructHandleView, @@ -216,7 +216,7 @@ impl<'a> ModuleBuilder<'a> { /// Return result as a script. pub fn into_script(self) -> Result { if let Some(handle) = self.main_handle.replace(None) { - convert_module_to_script(self.into_module()?, handle) + module_into_script(self.into_module()?, handle) } else { bail!("a script cannot be built from a module") } diff --git a/third_party/move/tools/move-asm/tests/assembler/address_alias.exp b/third_party/move/tools/move-asm/tests/assembler/address_alias.exp index 2d729b7307e..ef452ef4b0e 100644 --- a/third_party/move/tools/move-asm/tests/assembler/address_alias.exp +++ b/third_party/move/tools/move-asm/tests/assembler/address_alias.exp @@ -3,19 +3,17 @@ processed 1 task task 0 'publish'. lines 1-11: == BEGIN Bytecode == -// Move bytecode v7 -module 66.test { +// Bytecode version v7 +module 0x66::test +// Function definition at index 0 +fun f(l0: u64) + ret + +// Function definition at index 1 +fun g() + ld_u64 1 + call test::f + ret -f(Arg0: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -g() /* def_idx: 1 */ { -B0: - 0: LdU64(1) - 1: Call f(u64) - 2: Ret -} -} == END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/branch.exp b/third_party/move/tools/move-asm/tests/assembler/branch.exp index 15829c161ec..90932885613 100644 --- a/third_party/move/tools/move-asm/tests/assembler/branch.exp +++ b/third_party/move/tools/move-asm/tests/assembler/branch.exp @@ -3,24 +3,21 @@ processed 1 task task 0 'publish'. lines 1-14: == BEGIN Bytecode == -// Move bytecode v7 -module 66.test { +// Bytecode version v7 +module 0x66::test +// Function definition at index 0 +fun f(l0: u64) +l1: copy_loc l0 + ld_u64 0 + gt + br_false l0 + copy_loc l0 + // @5 + ld_u64 1 + sub + st_loc l0 + branch l1 +l0: ret -f(Arg0: u64) /* def_idx: 0 */ { -B0: - 0: CopyLoc[0](Arg0: u64) - 1: LdU64(0) - 2: Gt - 3: BrFalse(9) -B1: - 4: CopyLoc[0](Arg0: u64) - 5: LdU64(1) - 6: Sub - 7: StLoc[0](Arg0: u64) - 8: Branch(0) -B2: - 9: Ret -} -} == END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/call_different_module.exp b/third_party/move/tools/move-asm/tests/assembler/call_different_module.exp index cde60cf5b2c..72e1d71ffd7 100644 --- a/third_party/move/tools/move-asm/tests/assembler/call_different_module.exp +++ b/third_party/move/tools/move-asm/tests/assembler/call_different_module.exp @@ -3,33 +3,27 @@ processed 2 tasks task 0 'publish'. lines 1-6: == BEGIN Bytecode == -// Move bytecode v7 -module 66.test1 { +// Bytecode version v7 +module 0x66::test1 +// Function definition at index 0 +public fun f(l0: u64): u64 + move_loc l0 + ret -public f(Arg0: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](Arg0: u64) - 1: Ret -} -} == END Bytecode == task 1 'publish'. lines 9-16: == BEGIN Bytecode == -// Move bytecode v7 -module 66.test2 { -use 0000000000000000000000000000000000000000000000000000000000000066::test1; +// Bytecode version v7 +module 0x66::test2 +use 0x66::test1 +// Function definition at index 0 +fun g(): u64 + ld_u64 10 + call test1::f + ret - - -g(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(10) - 1: Call test1::f(u64): u64 - 2: Ret -} -} == END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/call_same_module.exp b/third_party/move/tools/move-asm/tests/assembler/call_same_module.exp index 6413e9acad8..e0fae083134 100644 --- a/third_party/move/tools/move-asm/tests/assembler/call_same_module.exp +++ b/third_party/move/tools/move-asm/tests/assembler/call_same_module.exp @@ -3,20 +3,18 @@ processed 1 task task 0 'publish'. lines 1-11: == BEGIN Bytecode == -// Move bytecode v7 -module 66.test { +// Bytecode version v7 +module 0x66::test +// Function definition at index 0 +fun f(l0: u64): u64 + move_loc l0 + ret + +// Function definition at index 1 +fun g(): u64 + ld_u64 10 + call test::f + ret -f(Arg0: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](Arg0: u64) - 1: Ret -} -g(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(10) - 1: Call f(u64): u64 - 2: Ret -} -} == END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/call_same_module_generic.exp b/third_party/move/tools/move-asm/tests/assembler/call_same_module_generic.exp index fabd5d0f73b..088bbec1c2c 100644 --- a/third_party/move/tools/move-asm/tests/assembler/call_same_module_generic.exp +++ b/third_party/move/tools/move-asm/tests/assembler/call_same_module_generic.exp @@ -3,20 +3,18 @@ processed 1 task task 0 'publish'. lines 1-11: == BEGIN Bytecode == -// Move bytecode v7 -module 66.test { +// Bytecode version v7 +module 0x66::test +// Function definition at index 0 +fun f(l0: T0): T0 + move_loc l0 + ret + +// Function definition at index 1 +fun g(): u64 + ld_u64 10 + call test::f + ret -f(Arg0: Ty0): Ty0 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](Arg0: Ty0) - 1: Ret -} -g(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(10) - 1: Call f(u64): u64 - 2: Ret -} -} == END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/closure.exp b/third_party/move/tools/move-asm/tests/assembler/closure.exp index 7b19126036f..db90232fdb8 100644 --- a/third_party/move/tools/move-asm/tests/assembler/closure.exp +++ b/third_party/move/tools/move-asm/tests/assembler/closure.exp @@ -3,21 +3,19 @@ processed 1 task task 0 'publish'. lines 1-12: == BEGIN Bytecode == -// Move bytecode v7 -module 66.test { +// Bytecode version v7 +module 0x66::test +// Function definition at index 0 +fun identity(l0: T0): T0 + move_loc l0 + ret + +// Function definition at index 1 +fun test(): u64 + ld_u64 2 + pack_closure test::identity, 1 + call_closure <||u64 has drop> + ret -identity(Arg0: Ty0): Ty0 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](Arg0: Ty0) - 1: Ret -} -test(): u64 /* def_idx: 1 */ { -B0: - 0: LdU64(2) - 1: PackClosureGeneric#1 identity(u64): u64 - 2: CallClosure(||u64 has drop) - 3: Ret -} -} == END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/declare_entry_fun.exp b/third_party/move/tools/move-asm/tests/assembler/declare_entry_fun.exp index 8d111d6450b..46dab87afde 100644 --- a/third_party/move/tools/move-asm/tests/assembler/declare_entry_fun.exp +++ b/third_party/move/tools/move-asm/tests/assembler/declare_entry_fun.exp @@ -3,14 +3,12 @@ processed 1 task task 0 'publish'. lines 1-6: == BEGIN Bytecode == -// Move bytecode v7 -module 66.test { +// Bytecode version v7 +module 0x66::test +// Function definition at index 0 +entry public fun f(l0: u64): u64 + move_loc l0 + ret -entry public f(Arg0: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](Arg0: u64) - 1: Ret -} -} == END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/declare_fun.exp b/third_party/move/tools/move-asm/tests/assembler/declare_fun.exp index b521cc63eed..43a43a184c6 100644 --- a/third_party/move/tools/move-asm/tests/assembler/declare_fun.exp +++ b/third_party/move/tools/move-asm/tests/assembler/declare_fun.exp @@ -3,21 +3,20 @@ processed 1 task task 0 'publish'. lines 1-13: == BEGIN Bytecode == -// Move bytecode v7 -module 66.test { +// Bytecode version v7 +module 0x66::test +// Function definition at index 0 +fun f(l0: u64): u64 + local l1: u64 + copy_loc l0 + ld_u64 1 + add + st_loc l1 + move_loc l0 + // @5 + move_loc l1 + mod + ret -f(Arg0: u64): u64 /* def_idx: 0 */ { -L1: loc0: u64 -B0: - 0: CopyLoc[0](Arg0: u64) - 1: LdU64(1) - 2: Add - 3: StLoc[1](loc0: u64) - 4: MoveLoc[0](Arg0: u64) - 5: MoveLoc[1](loc0: u64) - 6: Mod - 7: Ret -} -} == END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/declare_generic_fun.exp b/third_party/move/tools/move-asm/tests/assembler/declare_generic_fun.exp index c44cca40188..898260f3f47 100644 --- a/third_party/move/tools/move-asm/tests/assembler/declare_generic_fun.exp +++ b/third_party/move/tools/move-asm/tests/assembler/declare_generic_fun.exp @@ -3,15 +3,13 @@ processed 1 task task 0 'publish'. lines 1-7: == BEGIN Bytecode == -// Move bytecode v7 -module 66.test { +// Bytecode version v7 +module 0x66::test +// Function definition at index 0 +fun f(l0: T0,l1: T1): (T0,T1) + move_loc l0 + move_loc l1 + ret -f(Arg0: Ty0, Arg1: Ty1): Ty0 * Ty1 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](Arg0: Ty0) - 1: MoveLoc[1](Arg1: Ty1) - 2: Ret -} -} == END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/enum.exp b/third_party/move/tools/move-asm/tests/assembler/enum.exp index 9d44e72b213..1dd4628f03b 100644 --- a/third_party/move/tools/move-asm/tests/assembler/enum.exp +++ b/third_party/move/tools/move-asm/tests/assembler/enum.exp @@ -3,41 +3,38 @@ processed 1 task task 0 'publish'. lines 1-30: == BEGIN Bytecode == -// Move bytecode v7 -module 66.test { -enum E has drop { - V1{ - _1: u64, - _2: u8 - }, - V2{ - _1: u64, - _2: u32 - } -} +// Bytecode version v7 +module 0x66::test +enum E + V1 + _1: u64 + _2: u8 + V2 + _1: u64 + _2: u32 + +// Function definition at index 0 +fun pack_and_select(): u64 + ld_u64 1 + ld_u8 2 + pack_variant E, V1 + call test::select + ret + +// Function definition at index 1 +fun select(l0: test::E): u64 + borrow_loc l0 + borrow_variant_field E, V1::_1, V2::_1 + read_ref + ret + +// Function definition at index 2 +fun pack_and_unpack(): (u64,u32) + ld_u64 1 + ld_u8 2 + pack_variant E, V1 + unpack_variant E, V2 + ret + -pack_and_select(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: LdU8(2) - 2: PackVariant[0](E/V1) - 3: Call select(E): u64 - 4: Ret -} -select(Arg0: E): u64 /* def_idx: 1 */ { -B0: - 0: ImmBorrowLoc[0](Arg0: E) - 1: ImmBorrowVariantField[0](V1._1|V2._1: u64) - 2: ReadRef - 3: Ret -} -pack_and_unpack(): u64 * u32 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: LdU8(2) - 2: PackVariant[0](E/V1) - 3: UnpackVariant[1](E/V2) - 4: Ret -} -} == END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/enum_generic.exp b/third_party/move/tools/move-asm/tests/assembler/enum_generic.exp index ee20df6c160..084aed47aa7 100644 --- a/third_party/move/tools/move-asm/tests/assembler/enum_generic.exp +++ b/third_party/move/tools/move-asm/tests/assembler/enum_generic.exp @@ -3,41 +3,38 @@ processed 1 task task 0 'publish'. lines 1-30: == BEGIN Bytecode == -// Move bytecode v7 -module 66.test { -enum E has drop { - V1{ - _1: Ty0, - _2: u8 - }, - V2{ - _1: Ty0, - _2: u32 - } -} +// Bytecode version v7 +module 0x66::test +enum E + V1 + _1: T0 + _2: u8 + V2 + _1: T0 + _2: u32 + +// Function definition at index 0 +fun pack_and_select(): u64 + ld_u64 1 + ld_u8 2 + pack_variant E, V1 + call test::select + ret + +// Function definition at index 1 +fun select(l0: test::E): u64 + borrow_loc l0 + borrow_variant_field E, V1::_1, V2::_1 + read_ref + ret + +// Function definition at index 2 +fun pack_and_unpack(): (u64,u32) + ld_u64 1 + ld_u8 2 + pack_variant E, V1 + unpack_variant E, V2 + ret + -pack_and_select(): u64 /* def_idx: 0 */ { -B0: - 0: LdU64(1) - 1: LdU8(2) - 2: PackVariantGeneric[0](E/V1) - 3: Call select(E): u64 - 4: Ret -} -select(Arg0: E): u64 /* def_idx: 1 */ { -B0: - 0: ImmBorrowLoc[0](Arg0: E) - 1: ImmBorrowVariantFieldGeneric[0](V1._1|V2._1: Ty0) - 2: ReadRef - 3: Ret -} -pack_and_unpack(): u64 * u32 /* def_idx: 2 */ { -B0: - 0: LdU64(1) - 1: LdU8(2) - 2: PackVariantGeneric[0](E/V1) - 3: UnpackVariantGeneric[1](E/V2) - 4: Ret -} -} == END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/resource.exp b/third_party/move/tools/move-asm/tests/assembler/resource.exp index a2d8874e0c8..fdc2d282464 100644 --- a/third_party/move/tools/move-asm/tests/assembler/resource.exp +++ b/third_party/move/tools/move-asm/tests/assembler/resource.exp @@ -3,27 +3,26 @@ processed 1 task task 0 'publish'. lines 1-19: == BEGIN Bytecode == -// Move bytecode v7 -module 66.test { -struct S has drop, key { - x: u64 -} +// Bytecode version v7 +module 0x66::test +struct S + x: u64 + +// Function definition at index 0 +fun move_to(l0: &signer) + move_loc l0 + ld_u64 3 + pack S + move_to S + ret + +// Function definition at index 1 +fun borrow(l0: address): u64 + move_loc l0 + borrow_global S + borrow_field S, x + read_ref + ret + -move_to(Arg0: &signer) /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](Arg0: &signer) - 1: LdU64(3) - 2: Pack[0](S) - 3: MoveTo[0](S) - 4: Ret -} -borrow(Arg0: address): u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](Arg0: address) - 1: ImmBorrowGlobal[0](S) - 2: ImmBorrowField[0](S.x: u64) - 3: ReadRef - 4: Ret -} -} == END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/resource_generic.exp b/third_party/move/tools/move-asm/tests/assembler/resource_generic.exp index fe4b50e474d..5113355b41c 100644 --- a/third_party/move/tools/move-asm/tests/assembler/resource_generic.exp +++ b/third_party/move/tools/move-asm/tests/assembler/resource_generic.exp @@ -3,27 +3,26 @@ processed 1 task task 0 'publish'. lines 1-19: == BEGIN Bytecode == -// Move bytecode v7 -module 66.test { -struct S has drop, key { - x: Ty0 -} +// Bytecode version v7 +module 0x66::test +struct S + x: T0 + +// Function definition at index 0 +fun move_to(l0: &signer) + move_loc l0 + ld_u64 3 + pack S + move_to S + ret + +// Function definition at index 1 +fun borrow(l0: address): u64 + move_loc l0 + borrow_global S + borrow_field S, x + read_ref + ret + -move_to(Arg0: &signer) /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](Arg0: &signer) - 1: LdU64(3) - 2: PackGeneric[0](S) - 3: MoveToGeneric[0](S) - 4: Ret -} -borrow(Arg0: address): u64 /* def_idx: 1 */ { -B0: - 0: MoveLoc[0](Arg0: address) - 1: ImmBorrowGlobalGeneric[0](S) - 2: ImmBorrowFieldGeneric[0](S.x: Ty0) - 3: ReadRef - 4: Ret -} -} == END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/struct.exp b/third_party/move/tools/move-asm/tests/assembler/struct.exp index 99b406254b0..7978b2c7e9b 100644 --- a/third_party/move/tools/move-asm/tests/assembler/struct.exp +++ b/third_party/move/tools/move-asm/tests/assembler/struct.exp @@ -3,35 +3,34 @@ processed 1 task task 0 'publish'. lines 1-26: == BEGIN Bytecode == -// Move bytecode v7 -module 66.test { -struct S has drop { - _1: u64, - _2: u8 -} +// Bytecode version v7 +module 0x66::test +struct S + _1: u64 + _2: u8 + +// Function definition at index 0 +fun pack_and_select(): u8 + ld_u64 3 + ld_u8 2 + pack S + call test::select + ret + +// Function definition at index 1 +fun select(l0: test::S): u8 + borrow_loc l0 + borrow_field S, _2 + read_ref + ret + +// Function definition at index 2 +fun pack_and_unpack(): (u64,u8) + ld_u64 3 + ld_u8 2 + pack S + unpack S + ret + -pack_and_select(): u8 /* def_idx: 0 */ { -B0: - 0: LdU64(3) - 1: LdU8(2) - 2: Pack[0](S) - 3: Call select(S): u8 - 4: Ret -} -select(Arg0: S): u8 /* def_idx: 1 */ { -B0: - 0: ImmBorrowLoc[0](Arg0: S) - 1: ImmBorrowField[0](S._2: u8) - 2: ReadRef - 3: Ret -} -pack_and_unpack(): u64 * u8 /* def_idx: 2 */ { -B0: - 0: LdU64(3) - 1: LdU8(2) - 2: Pack[0](S) - 3: Unpack[0](S) - 4: Ret -} -} == END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/struct_generic.exp b/third_party/move/tools/move-asm/tests/assembler/struct_generic.exp index 2be319c4482..6ee0522f8fb 100644 --- a/third_party/move/tools/move-asm/tests/assembler/struct_generic.exp +++ b/third_party/move/tools/move-asm/tests/assembler/struct_generic.exp @@ -3,35 +3,34 @@ processed 1 task task 0 'publish'. lines 1-26: == BEGIN Bytecode == -// Move bytecode v7 -module 66.test { -struct S has drop { - _1: u64, - _2: Ty0 -} +// Bytecode version v7 +module 0x66::test +struct S + _1: u64 + _2: T0 + +// Function definition at index 0 +fun pack_and_select(): u8 + ld_u64 3 + ld_u8 2 + pack S + call test::select + ret + +// Function definition at index 1 +fun select(l0: test::S): u8 + borrow_loc l0 + borrow_field S, _2 + read_ref + ret + +// Function definition at index 2 +fun pack_and_unpack(): (u64,u8) + ld_u64 3 + ld_u8 2 + pack S + unpack S + ret + -pack_and_select(): u8 /* def_idx: 0 */ { -B0: - 0: LdU64(3) - 1: LdU8(2) - 2: PackGeneric[0](S) - 3: Call select(S): u8 - 4: Ret -} -select(Arg0: S): u8 /* def_idx: 1 */ { -B0: - 0: ImmBorrowLoc[0](Arg0: S) - 1: ImmBorrowFieldGeneric[0](S._2: Ty0) - 2: ReadRef - 3: Ret -} -pack_and_unpack(): u64 * u8 /* def_idx: 2 */ { -B0: - 0: LdU64(3) - 1: LdU8(2) - 2: PackGeneric[0](S) - 3: UnpackGeneric[0](S) - 4: Ret -} -} == END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/struct_use.exp b/third_party/move/tools/move-asm/tests/assembler/struct_use.exp index 050e3224c8d..798b37fe60a 100644 --- a/third_party/move/tools/move-asm/tests/assembler/struct_use.exp +++ b/third_party/move/tools/move-asm/tests/assembler/struct_use.exp @@ -3,35 +3,30 @@ processed 2 tasks task 0 'publish'. lines 1-6: == BEGIN Bytecode == -// Move bytecode v7 -module 66.test1 { -struct S has copy, drop { - _1: u64, - _2: u8 -} +// Bytecode version v7 +module 0x66::test1 +struct S + _1: u64 + _2: u8 -} == END Bytecode == task 1 'publish'. lines 8-19: == BEGIN Bytecode == -// Move bytecode v7 -module 66.test2 { -use 0000000000000000000000000000000000000000000000000000000000000066::test1; - - -struct T has drop { - _1: S -} - -get(Arg0: T): S /* def_idx: 0 */ { -B0: - 0: ImmBorrowLoc[0](Arg0: T) - 1: ImmBorrowField[0](T._1: S) - 2: ReadRef - 3: Ret -} -} +// Bytecode version v7 +module 0x66::test2 +use 0x66::test1 +struct T + _1: test1::S + +// Function definition at index 0 +fun get(l0: test2::T): test1::S + borrow_loc l0 + borrow_field T, _1 + read_ref + ret + + == END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/testsuite.rs b/third_party/move/tools/move-asm/tests/testsuite.rs index 5c9eef546b0..7e5a256505f 100644 --- a/third_party/move/tools/move-asm/tests/testsuite.rs +++ b/third_party/move/tools/move-asm/tests/testsuite.rs @@ -22,7 +22,8 @@ fn main() { .map(|p| { let prompt = format!("move-asm-txn::{}", p.display()); Trial::test(prompt, move || { - vm_test_harness::run_test(&p).map_err(|err| format!("{:?}", err).into()) + vm_test_harness::run_test_print_bytecode_with_masm(&p) + .map_err(|err| format!("{:?}", err).into()) }) }) .collect_vec(); diff --git a/third_party/move/tools/move-asm/tests/txn-test-integration/print_bytecode.exp b/third_party/move/tools/move-asm/tests/txn-test-integration/print_bytecode.exp index 06cbf225623..7b8e02667be 100644 --- a/third_party/move/tools/move-asm/tests/txn-test-integration/print_bytecode.exp +++ b/third_party/move/tools/move-asm/tests/txn-test-integration/print_bytecode.exp @@ -4,24 +4,20 @@ task 0 'print-bytecode'. lines 1-7: Error: expected a script but found a module task 1 'print-bytecode'. lines 9-14: -// Move bytecode v7 -module 66.m { +// Bytecode version v7 +module 0x66::m +// Function definition at index 0 +public fun f(l0: u64): u64 + move_loc l0 + ret -public f(Arg0: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](Arg0: u64) - 1: Ret -} -} task 2 'print-bytecode'. lines 17-21: -// Move bytecode v7 -script { +// Bytecode version v7 +script +// Function definition at index 0 +entry public fun main(l0: u64) + ret -main(Arg0: u64) /* def_idx: 0 */ { -B0: - 0: Ret -} -} diff --git a/third_party/move/tools/move-asm/tests/txn-test-integration/publish_and_run_module.exp b/third_party/move/tools/move-asm/tests/txn-test-integration/publish_and_run_module.exp index ce48b829746..b0dc96c3908 100644 --- a/third_party/move/tools/move-asm/tests/txn-test-integration/publish_and_run_module.exp +++ b/third_party/move/tools/move-asm/tests/txn-test-integration/publish_and_run_module.exp @@ -3,16 +3,14 @@ processed 2 tasks task 0 'publish'. lines 1-6: == BEGIN Bytecode == -// Move bytecode v7 -module 66.m { +// Bytecode version v7 +module 0x66::m +// Function definition at index 0 +public fun f(l0: u64): u64 + move_loc l0 + ret -public f(Arg0: u64): u64 /* def_idx: 0 */ { -B0: - 0: MoveLoc[0](Arg0: u64) - 1: Ret -} -} == END Bytecode == task 1 'run'. lines 8-8: From 01a3008f000d83dca7c5120fa306ea35332e8034 Mon Sep 17 00:00:00 2001 From: Wolfgang Grieskamp Date: Tue, 22 Jul 2025 09:13:49 -0700 Subject: [PATCH 049/260] [move-asm] Completing assembler/disassembler functionality (#17106) * [move-asm] Completing assembler/disassembler functionality This adds a few features which have been omitted until now, and should make the assembler code complete: - Full support for `ld_const` - Attributes of functions - Module friend declarations * Addressing reviewer comments Downstreamed-from: 97590c80cc585c44f155b6dfabc599c5532251fd --- Cargo.lock | 1 + .../move/move-binary-format/Cargo.toml | 1 + .../move/move-binary-format/src/errors.rs | 20 ++- .../move-binary-format/src/file_format.rs | 11 +- .../src/framework.rs | 13 +- .../move/tools/move-asm/src/assembler.rs | 52 +++--- .../move/tools/move-asm/src/disassembler.rs | 85 +++++++--- third_party/move/tools/move-asm/src/lib.rs | 1 + .../move/tools/move-asm/src/module_builder.rs | 30 +++- third_party/move/tools/move-asm/src/syntax.rs | 154 ++++++++++++++---- third_party/move/tools/move-asm/src/value.rs | 127 +++++++++++++++ .../move-asm/tests/assembler/attributes.exp | 19 +++ .../move-asm/tests/assembler/attributes.masm | 9 + .../move-asm/tests/assembler/closure.masm | 2 +- .../move-asm/tests/assembler/constants.exp | 84 ++++++++++ .../move-asm/tests/assembler/constants.masm | 62 +++++++ .../tests/assembler/constants_errors.exp | 40 +++++ .../tests/assembler/constants_errors.masm | 26 +++ .../tests/assembler/declare_generic_fun.exp | 2 +- .../tools/move-asm/tests/assembler/enum.exp | 2 +- .../move-asm/tests/assembler/enum_generic.exp | 2 +- .../move-asm/tests/assembler/friends.exp | 37 +++++ .../move-asm/tests/assembler/friends.masm | 15 ++ .../tools/move-asm/tests/assembler/struct.exp | 2 +- .../tests/assembler/struct_generic.exp | 2 +- 25 files changed, 683 insertions(+), 116 deletions(-) create mode 100644 third_party/move/tools/move-asm/src/value.rs create mode 100644 third_party/move/tools/move-asm/tests/assembler/attributes.exp create mode 100644 third_party/move/tools/move-asm/tests/assembler/attributes.masm create mode 100644 third_party/move/tools/move-asm/tests/assembler/constants.exp create mode 100644 third_party/move/tools/move-asm/tests/assembler/constants.masm create mode 100644 third_party/move/tools/move-asm/tests/assembler/constants_errors.exp create mode 100644 third_party/move/tools/move-asm/tests/assembler/constants_errors.masm create mode 100644 third_party/move/tools/move-asm/tests/assembler/friends.exp create mode 100644 third_party/move/tools/move-asm/tests/assembler/friends.masm diff --git a/Cargo.lock b/Cargo.lock index 8776f5101b4..5c5f1588212 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11808,6 +11808,7 @@ dependencies = [ "indexmap 2.7.0", "move-bytecode-spec", "move-core-types", + "once_cell", "proptest", "proptest-derive", "ref-cast", diff --git a/third_party/move/move-binary-format/Cargo.toml b/third_party/move/move-binary-format/Cargo.toml index a701e9992c1..8a9f3bc8728 100644 --- a/third_party/move/move-binary-format/Cargo.toml +++ b/third_party/move/move-binary-format/Cargo.toml @@ -17,6 +17,7 @@ dearbitrary = { workspace = true, optional = true, features = ["derive"] } indexmap = { workspace = true } move-bytecode-spec = { workspace = true } move-core-types = { workspace = true } +once_cell = { workspace = true } proptest = { workspace = true, optional = true } proptest-derive = { workspace = true, optional = true } ref-cast = { workspace = true } diff --git a/third_party/move/move-binary-format/src/errors.rs b/third_party/move/move-binary-format/src/errors.rs index abe6e81c3cc..72ab35b270f 100644 --- a/third_party/move/move-binary-format/src/errors.rs +++ b/third_party/move/move-binary-format/src/errors.rs @@ -10,6 +10,7 @@ use move_core_types::{ language_storage::ModuleId, vm_status::{self, StatusCode, StatusType, VMStatus}, }; +use once_cell::sync::Lazy; use std::fmt; pub type VMResult = ::std::result::Result; @@ -382,12 +383,21 @@ impl PartialVMError { indices, offsets, } = *self.0; - let bt = std::backtrace::Backtrace::capture(); - let message = if std::backtrace::BacktraceStatus::Captured == bt.status() { - if let Some(message) = message { - Some(format!("{}\nBacktrace: {:#?}", message, bt).to_string()) + static MOVE_TEST_DEBUG: Lazy = Lazy::new(|| { + std::env::var("MOVE_TEST_DEBUG").map_or(false, |v| matches!(v.as_str(), "true" | "1")) + }); + let message = if *MOVE_TEST_DEBUG { + // Do this only if env var is set. Otherwise, we cannot use the output in baseline files + // since it is not deterministic. + let bt = std::backtrace::Backtrace::capture(); + if std::backtrace::BacktraceStatus::Captured == bt.status() { + if let Some(message) = message { + Some(format!("{}\nBacktrace: {:#?}", message, bt).to_string()) + } else { + Some(format!("Backtrace: {:#?}", bt).to_string()) + } } else { - Some(format!("Backtrace: {:#?}", bt).to_string()) + message } } else { message diff --git a/third_party/move/move-binary-format/src/file_format.rs b/third_party/move/move-binary-format/src/file_format.rs index 93b7d53afcc..07b475537b8 100644 --- a/third_party/move/move-binary-format/src/file_format.rs +++ b/third_party/move/move-binary-format/src/file_format.rs @@ -49,7 +49,7 @@ use move_core_types::{ use proptest::{collection::vec, prelude::*, strategy::BoxedStrategy}; use ref_cast::RefCast; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::{fmt, fmt::Formatter}; use variant_count::VariantCount; /// Generic index into one of the tables in the binary format. @@ -384,6 +384,15 @@ impl FunctionAttribute { } } +impl fmt::Display for FunctionAttribute { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + FunctionAttribute::Persistent => write!(f, "persistent"), + FunctionAttribute::ModuleLock => write!(f, "module_lock"), + } + } +} + /// A field access info (owner type and offset) #[derive(Clone, Debug, Eq, Hash, PartialEq)] #[cfg_attr(any(test, feature = "fuzzing"), derive(proptest_derive::Arbitrary))] diff --git a/third_party/move/testing-infra/transactional-test-runner/src/framework.rs b/third_party/move/testing-infra/transactional-test-runner/src/framework.rs index b80702f67f7..f6b257d772f 100644 --- a/third_party/move/testing-infra/transactional-test-runner/src/framework.rs +++ b/third_party/move/testing-infra/transactional-test-runner/src/framework.rs @@ -444,20 +444,13 @@ pub trait MoveTestAdapter<'a>: Sized { } let data_path = data.path().to_str().unwrap(); match syntax { - SyntaxChoice::Source => self.compiled_state().add_with_source_file( - named_addr_opt, - module, - (data_path.to_owned(), data), - ), + SyntaxChoice::Source | SyntaxChoice::ASM => self + .compiled_state() + .add_with_source_file(named_addr_opt, module, (data_path.to_owned(), data)), SyntaxChoice::IR => { self.compiled_state() .add_and_generate_interface_file(module); }, - SyntaxChoice::ASM => { - // TODO(#16582): generate source info for .masm file - self.compiled_state() - .add_without_source_file(named_addr_opt, module); - }, }; Ok(merge_output(warnings_opt, output)) }, diff --git a/third_party/move/tools/move-asm/src/assembler.rs b/third_party/move/tools/move-asm/src/assembler.rs index fd84fc735b3..98c21a2b6a8 100644 --- a/third_party/move/tools/move-asm/src/assembler.rs +++ b/third_party/move/tools/move-asm/src/assembler.rs @@ -9,7 +9,7 @@ use crate::{ syntax, syntax::{ map_diag, Argument, AsmResult, Decl, Diag, Fun, Instruction, Loc, PartialIdent, Struct, - StructLayout, Type, Unit, UnitId, Value, + StructLayout, Type, Unit, UnitId, }, }; use anyhow::{anyhow, bail}; @@ -33,7 +33,6 @@ use move_binary_format::{ }; use move_core_types::{function::ClosureMask, identifier::Identifier, u256::U256}; use std::{collections::BTreeMap, fs, io::Write, path::PathBuf}; - // =================================================================================== // Driver @@ -180,6 +179,7 @@ impl<'a> Assembler<'a> { name: _, address_aliases, module_aliases, + friend_modules, structs, functions, } = ast; @@ -193,6 +193,12 @@ impl<'a> Assembler<'a> { self.add_diags(Loc::new(0, 0), res); } + // Register friend modules + for m in friend_modules { + let res = self.builder.declare_friend_module(m); + self.add_diags(Loc::new(0, 0), res); + } + // Declare structs for str in structs { self.declare_struct(str) @@ -288,6 +294,7 @@ impl<'a> Assembler<'a> { fun.is_entry, fun.name.clone(), fun.visibility, + fun.attributes.clone(), param_sign, result_sign, fun.type_params @@ -615,10 +622,17 @@ impl<'a> Assembler<'a> { "ld_const" => { let [arg1, arg2] = self.args2(instr)?; let ty = self.type_(instr, arg1)?; - let val = self.value_bcs(instr, arg2, &ty)?; - let res = self.builder.const_index(val, ty); - let idx = self.add_diags(instr.loc, res)?; - LdConst(idx) + if let Argument::Constant(val) = arg2 { + let move_value = self.add_diags(instr.loc, val.to_move_value(&ty))?; + let bcs = move_value + .simple_serialize() + .expect("value serialization succeeds"); + let idx = self.add_diags(instr.loc, self.builder.const_index(bcs, ty))?; + LdConst(idx) + } else { + self.error(instr.loc, "expected a constant value"); + return None; + } }, "ld_false" => { self.args0(instr)?; @@ -1100,16 +1114,8 @@ impl<'a> Assembler<'a> { } fn number(&mut self, instr: &Instruction, arg: &Argument, max: U256) -> Option { - if let Argument::Constant(Value::Number(n)) = arg { - if *n <= max { - Some(*n) - } else { - self.error( - instr.loc, - format!("number {} out of range (max {})", n, max), - ); - None - } + if let Argument::Constant(val) = arg { + self.add_diags(instr.loc, val.check_number(max)) } else { self.error(instr.loc, "expected number argument"); None @@ -1131,20 +1137,6 @@ impl<'a> Assembler<'a> { self.add_diags(instr.loc, res) } - fn value_bcs( - &mut self, - instr: &Instruction, - arg: &Argument, - _ty: &SignatureToken, - ) -> Option> { - if let Argument::Constant(Value::Bytes(bytes)) = arg { - Some(bytes.clone()) - } else { - self.error(instr.loc, "expected byte blob"); - None - } - } - fn args0(&mut self, instr: &Instruction) -> Option<()> { if instr.args.is_empty() { Some(()) diff --git a/third_party/move/tools/move-asm/src/disassembler.rs b/third_party/move/tools/move-asm/src/disassembler.rs index 51d88a39a4a..b747c95756f 100644 --- a/third_party/move/tools/move-asm/src/disassembler.rs +++ b/third_party/move/tools/move-asm/src/disassembler.rs @@ -3,6 +3,7 @@ //! Disassembler for Move bytecode. +use crate::value::AsmValue; use anyhow::bail; use move_binary_format::{ access::ModuleAccess, @@ -87,6 +88,13 @@ impl Disassembler { dis.reverse_module_aliases.insert(id, short_name); } + // Process friend declarations + for friend in module.module().friend_decls.iter() { + let addr = module.module().address_identifier_at(friend.address); + let name = module.module().identifier_at(friend.name); + writeln!(dis.out, "friend {}::{}", addr.short_str_lossless(), name)? + } + // Process struct and function definitions for str in module.structs() { dis.struct_(str)?; @@ -115,7 +123,7 @@ impl Disassembler { str.type_parameters().as_slice(), |dis, idx, tparam| dis.type_param_decl(tparam.is_phantom, idx, tparam.constraints), "<", - ",", + ", ", ">", )? } @@ -179,12 +187,18 @@ impl Disassembler { self.out.write_str(">")?; }, Function(params, result, abilities) => { - self.list(params, |dis, _, e| dis.type_(module, e), "|", ",", "|")?; + self.list( + params, + |dis, _, e| dis.type_in_function_type(module, e), + "|", + ", ", + "|", + )?; match result.len().cmp(&1) { Ordering::Less => {}, Ordering::Equal => self.type_(module, &result[0])?, Ordering::Greater => { - self.list(result, |dis, _, e| dis.type_(module, e), "(", ",", ")")?; + self.list(result, |dis, _, e| dis.type_(module, e), "(", ", ", ")")?; }, } self.out @@ -199,7 +213,7 @@ impl Disassembler { view.name() )?; if let StructInstantiation(_, inst) = ty { - self.list(inst, |dis, _, e| dis.type_(module, e), "<", ",", ">")? + self.list(inst, |dis, _, e| dis.type_(module, e), "<", ", ", ">")? } }, Reference(elem_ty) => { @@ -215,10 +229,39 @@ impl Disassembler { Ok(()) } + fn type_in_function_type( + &mut self, + module: &CompiledModule, + ty: &SignatureToken, + ) -> anyhow::Result<()> { + // The parser cannot deal with `||||`, it must be written as `|(||)|`. + if matches!(ty, SignatureToken::Function(..)) { + write!(self.out, "(")?; + self.type_(module, ty)?; + write!(self.out, ")")?; + Ok(()) + } else { + self.type_(module, ty) + } + } + // -------------------------------------------------------------------------------------- // Functions fn fun(&mut self, fdef: FunctionDefinitionView) -> anyhow::Result<()> { + if !fdef.attributes().is_empty() { + self.list( + fdef.attributes(), + |dis, _, attr| { + write!(dis.out, "{}", attr)?; + Ok(()) + }, + "#[", + ", ", + "]", + )?; + write!(self.out, " ")? + } // Function header if fdef.is_entry() { self.out.write_str("entry ")? @@ -234,7 +277,7 @@ impl Disassembler { fdef.type_parameters().as_slice(), |dis, idx, abilities| dis.type_param_decl(false, idx, *abilities), "<", - ",", + ", ", ">", )? } @@ -246,7 +289,7 @@ impl Disassembler { dis.type_(fdef.module(), ty.signature_token()) }, "(", - ",", + ", ", ")", )?; if fdef.return_count() > 0 { @@ -256,7 +299,7 @@ impl Disassembler { &fdef.return_tokens().collect::>(), |dis, _, ty| dis.type_(fdef.module(), ty.signature_token()), "(", - ",", + ", ", ")", )? } else { @@ -346,14 +389,19 @@ impl Disassembler { CastU128 => write!(self.out, "cast_u128")?, CastU256 => write!(self.out, "cast_u256")?, LdConst(hdl) => { - write!(self.out, "ld_const ")?; + write!(self.out, "ld_const")?; let cons = module.constant_at(*hdl); + write!(self.out, "<")?; self.type_(module, &cons.type_)?; - write!( - self.out, - ", {}", - value_from_bcs(module, &cons.type_, &cons.data)? - )? + write!(self.out, ">")?; + if let Some(val) = cons + .deserialize_constant() + .and_then(|v| AsmValue::from_move_value(&v).ok()) + { + write!(self.out, " {}", val)? + } else { + write!(self.out, " ")? + } }, LdTrue => write!(self.out, "ld_true")?, LdFalse => write!(self.out, "ld_false")?, @@ -651,7 +699,7 @@ impl Disassembler { fn ty_args(&mut self, module: &CompiledModule, sign_idx: SignatureIndex) -> anyhow::Result<()> { let sign = module.signature_at(sign_idx); - self.list(&sign.0, |dis, _, e| dis.type_(module, e), "<", ",", ">") + self.list(&sign.0, |dis, _, e| dis.type_(module, e), "<", ", ", ">") } // -------------------------------------------------------------------------------------- @@ -694,12 +742,3 @@ fn type_param_name(idx: usize) -> String { fn local_name(idx: LocalIndex) -> String { format!("l{}", idx) } - -fn value_from_bcs( - _module: &CompiledModule, - _ty: &SignatureToken, - _bcs: &[u8], -) -> anyhow::Result { - // TODO(#16582): implement this - bail!("value bcs not implemented") -} diff --git a/third_party/move/tools/move-asm/src/lib.rs b/third_party/move/tools/move-asm/src/lib.rs index 19d9b3a921a..12a40497d35 100644 --- a/third_party/move/tools/move-asm/src/lib.rs +++ b/third_party/move/tools/move-asm/src/lib.rs @@ -5,3 +5,4 @@ pub mod assembler; pub mod disassembler; pub mod module_builder; pub mod syntax; +pub mod value; diff --git a/third_party/move/tools/move-asm/src/module_builder.rs b/third_party/move/tools/move-asm/src/module_builder.rs index 63b2656783d..02c1c3b2cb8 100644 --- a/third_party/move/tools/move-asm/src/module_builder.rs +++ b/third_party/move/tools/move-asm/src/module_builder.rs @@ -18,10 +18,10 @@ use move_binary_format::{ file_format::{ AddressIdentifierIndex, Bytecode, CodeUnit, CompiledScript, Constant, ConstantPoolIndex, FieldDefinition, FieldHandle, FieldHandleIndex, FieldInstantiation, - FieldInstantiationIndex, FunctionDefinition, FunctionDefinitionIndex, FunctionHandle, - FunctionHandleIndex, FunctionInstantiation, FunctionInstantiationIndex, IdentifierIndex, - MemberCount, ModuleHandle, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, - StructDefInstantiation, StructDefInstantiationIndex, StructDefinition, + FieldInstantiationIndex, FunctionAttribute, FunctionDefinition, FunctionDefinitionIndex, + FunctionHandle, FunctionHandleIndex, FunctionInstantiation, FunctionInstantiationIndex, + IdentifierIndex, MemberCount, ModuleHandle, ModuleHandleIndex, Signature, SignatureIndex, + SignatureToken, StructDefInstantiation, StructDefInstantiationIndex, StructDefinition, StructDefinitionIndex, StructFieldInformation, StructHandle, StructHandleIndex, StructTypeParameter, StructVariantHandle, StructVariantHandleIndex, StructVariantInstantiation, StructVariantInstantiationIndex, TableIndex, @@ -252,6 +252,21 @@ impl<'a> ModuleBuilder<'a> { } } + /// Declares a friend module + pub fn declare_friend_module(&mut self, module: &ModuleId) -> Result<()> { + let address = self.address_index(module.address)?; + let name = self.name_index(module.name.clone())?; + let handle = ModuleHandle { address, name }; + if self.options.validate && self.module.borrow().friend_decls.contains(&handle) { + bail!("duplicate friend module `{}`", module.short_str_lossless()) + } + self.module + .borrow_mut() + .friend_decls + .push(ModuleHandle { address, name }); + Ok(()) + } + /// Declares a struct and adds it to the builder. The struct initially does not have any /// layout associated. pub fn declare_struct( @@ -317,12 +332,12 @@ impl<'a> ModuleBuilder<'a> { /// Declares a function and adds it to the builder. The function /// initially does not have any code associated. - /// TODO(#16582): attributes and access specifiers pub fn declare_fun( &self, is_entry: bool, name: Identifier, visibility: Visibility, + attributes: Vec, parameters: SignatureIndex, return_: SignatureIndex, type_parameters: Vec, @@ -331,6 +346,9 @@ impl<'a> ModuleBuilder<'a> { if self.options.validate { let module_ref = self.module.borrow(); let module = &*module_ref; + if self.is_script() && !module.function_defs.is_empty() { + bail!("script can have only one function definition") + } for fdef in &module.function_defs { let view = FunctionDefinitionView::new(module, fdef); if view.name() == name.as_ref() { @@ -347,7 +365,7 @@ impl<'a> ModuleBuilder<'a> { return_, type_parameters, access_specifiers: None, - attributes: vec![], + attributes, }; let fhdl_idx = if self.is_script() { *self.main_handle.borrow_mut() = Some(fhdl); diff --git a/third_party/move/tools/move-asm/src/syntax.rs b/third_party/move/tools/move-asm/src/syntax.rs index 9ddf41c3534..1e501aebec1 100644 --- a/third_party/move/tools/move-asm/src/syntax.rs +++ b/third_party/move/tools/move-asm/src/syntax.rs @@ -17,25 +17,30 @@ //! unit := //! { address_alias LF } //! ( "module" QID | "script" ) LF -//! { const_def | struct_def | fun_def } -//! -//! const_def := "const" ID ":" type "=" VALUE LF +//! { "uses" QID [ "as" ID ] } +//! { struct_def | fun_def } //! //! struct_def := -//! "struct" ID [ type_args ] fields LF -//! | "enum" ID [ type_args ] LF { INDENT ID fields LF } +//! "struct" ID [ type_args ] LF { field } +//! | "enum" ID [ type_args ] LF variant { variant } //! +//! field ::= +//! INDENT ID ":" type LF //! -//! fields := -//! "(" LIST(type) ")" -//! | "{" LIST(local) "}" +//! variant ::= +//! INDENT ID LF { INDENT ID ":" type LF } //! //! //! fun_def := //! fun_modifier "fun" ID [ type_args ] "(" [ LIST(local) ] ")" [ tuple_type ] LF //! { INDENT "local" local LF } { instruction LF } //! -//! fun_modifier := [ [ "public" | "friend" ] "entry" ] +//! fun_modifier := +//! [ "#[" attribute "]" +//! [ "entry" ] +//! [ "public" | "friend" ] +//! +//! attribute := ID //! //! local := ID ":" type //! @@ -43,7 +48,7 @@ //! "|" [ LIST(type) ] "|" [ tuple_type ] | simple_type //! //! tuple_type := -//! simple_type | "(" LIST(simple_type) ")" +//! type | "(" LIST(type) ")" //! //! simple_type := //! QID [ type_args ] | "(" type ")" @@ -62,9 +67,10 @@ //! VALUE | QID [ type_args ] | type_args //!``` +use crate::value::AsmValue; use codespan::{RawIndex, Span}; use codespan_reporting::diagnostic::{Diagnostic, Label, Severity}; -use move_binary_format::file_format::Visibility; +use move_binary_format::file_format::{FunctionAttribute, Visibility}; use move_core_types::{ ability::{Ability, AbilitySet}, account_address::AccountAddress, @@ -117,6 +123,8 @@ pub struct Unit { pub address_aliases: Vec<(Identifier, AccountAddress)>, /// A list of module aliases. pub module_aliases: Vec<(Identifier, ModuleId)>, + /// Friend modules + pub friend_modules: Vec, /// List of struct definitions (including enums, which are technically /// a special form of struct). pub structs: Vec, @@ -164,6 +172,7 @@ pub struct Fun { pub name: Identifier, pub visibility: Visibility, pub is_entry: bool, + pub attributes: Vec, pub type_params: Vec<(Identifier, AbilitySet)>, pub params: Vec, pub locals: Vec, @@ -171,6 +180,7 @@ pub struct Fun { pub acquires: Vec, pub instrs: Vec, } + #[derive(Debug)] pub enum Type { Named(PartialIdent, Option>), @@ -204,17 +214,11 @@ pub struct Instruction { #[derive(Debug)] pub enum Argument { - Constant(Value), + Constant(AsmValue), Id(PartialIdent, Option>), Type(Type), } -#[derive(Debug)] -pub enum Value { - Number(U256), - Bytes(Vec), -} - // ========================================================================================== // Parser @@ -266,15 +270,20 @@ impl AsmParser { } fn lookahead_special(&self, sp: &str) -> bool { - matches!(&self.tokens[0].1, Token::Special(s) if s == sp) + !self.tokens.is_empty() && matches!(&self.tokens[0].1, Token::Special(s) if s == sp) + } + + fn lookahead_special_2(&self, sp: &str) -> bool { + self.tokens.len() > 1 && matches!(&self.tokens[1].1, Token::Special(s) if s == sp) } fn lookahead_newline(&self) -> bool { - matches!(&self.tokens[0].1, Token::Newline) + !self.tokens.is_empty() && matches!(&self.tokens[0].1, Token::Newline) } + #[allow(unused)] fn lookahead_soft_kw(&self, kw: &str) -> bool { - matches!(&self.tokens[0].1, Token::Ident(s) if s == kw) + !self.tokens.is_empty() && matches!(&self.tokens[0].1, Token::Ident(s) if s == kw) } fn expect(&mut self, tok: &Token) -> AsmResult<()> { @@ -336,19 +345,28 @@ impl AsmParser { Ok(result) } - fn value(&mut self) -> AsmResult { + fn value(&mut self) -> AsmResult { if let Token::Number(num) = &self.next { let num = *num; self.advance()?; - Ok(Value::Number(num)) + Ok(AsmValue::Number(num)) + } else if self.is_special("[") { + self.advance()?; + let elems = if self.is_value() { + self.list(Self::value, ",")? + } else { + vec![] + }; + self.expect_special("]")?; + Ok(AsmValue::Vector(elems)) } else { - // TODO(#16582): byte strings Err(error(self.next_loc, "expected value")) } } fn is_value(&self) -> bool { matches!(&self.next, Token::Number(..)) + || matches!(&self.next, Token::Special(s) if s == "[") } fn address(&mut self) -> AsmResult { @@ -395,7 +413,12 @@ impl AsmParser { } fn type_(&mut self) -> AsmResult { - if self.is_partial_ident() { + if self.is_special("(") { + self.advance()?; + let ty = self.type_()?; + self.expect_special(")")?; + Ok(ty) + } else if self.is_partial_ident() { let pid = self.partial_ident()?; let ty_args = self.type_args_opt()?; Ok(Type::Named(pid, ty_args)) @@ -434,7 +457,7 @@ impl AsmParser { } fn is_type(&self) -> bool { - self.is_partial_ident() + self.is_partial_ident() || self.is_special("&") || self.is_special("(") } fn type_list(&mut self) -> AsmResult> { @@ -442,13 +465,13 @@ impl AsmParser { } fn type_tuple(&mut self) -> AsmResult> { - if self.is_type() { - Ok(vec![self.type_()?]) - } else if self.is_special("(") { + if self.is_special("(") { self.advance()?; let res = self.type_list()?; self.expect_special(")")?; Ok(res) + } else if self.is_type() { + Ok(vec![self.type_()?]) } else { Err(error(self.next_loc, "expected type or type tuple")) } @@ -541,6 +564,34 @@ impl AsmParser { }) } + fn attributes(&mut self) -> AsmResult> { + if self.is_special("#") && self.lookahead_special("[") { + self.advance()?; + self.advance()?; + let attrs = self.list( + |parser| { + let attr = if parser.is_soft_kw("persistent") { + FunctionAttribute::Persistent + } else if parser.is_soft_kw("module_lock") { + FunctionAttribute::ModuleLock + } else { + return Err(error( + parser.next_loc, + "expected function attribute `persistent` or `module_lock`", + )); + }; + parser.advance()?; + Ok(attr) + }, + ",", + )?; + self.expect_special("]")?; + Ok(attrs) + } else { + Ok(vec![]) + } + } + fn decl(&mut self) -> AsmResult { let loc = self.next_loc; let name = self.ident()?; @@ -582,7 +633,24 @@ impl AsmParser { None }; let args = if self.is_argument() { - self.list(Self::argument, ",")? + // Special case if first argument is type (``): in this case we do not require + // a comma, so we can write `ld_const val + if self.is_special("<") { + let first = self.argument()?; + let mut args = if self.is_special(",") { + // We still allow a comma + self.advance()?; + self.list(Self::argument, ",")? + } else if self.is_value() { + self.list(Self::argument, ",")? + } else { + vec![] + }; + args.insert(0, first); + args + } else { + self.list(Self::argument, ",")? + } } else { vec![] }; @@ -680,14 +748,19 @@ impl AsmParser { Ok((loc, id, ty_params, abilities)) } - fn is_fun(&self) -> bool { + fn is_first_of_fun(&self) -> bool { + // Notice when this is called we already checked for structs, + // so we only check for the start token (because of modifiers + // and attributes, we would need a deep lookahead otherwise) self.is_soft_kw("fun") || self.is_soft_kw("entry") - || (self.is_soft_kw("public") || self.is_soft_kw("friend")) - && self.lookahead_soft_kw("fun") + || self.is_soft_kw("public") + || self.is_soft_kw("friend") + || self.is_special("#") && self.lookahead_special("[") } fn fun(&mut self) -> AsmResult { + let attributes = self.attributes()?; let is_entry = if self.is_soft_kw("entry") { self.advance()?; true @@ -749,6 +822,7 @@ impl AsmParser { name, visibility, is_entry, + attributes, type_params, params, locals, @@ -830,6 +904,15 @@ impl AsmParser { module_aliases.push((name, module)); } + // Parse friend modules + let mut friend_modules = vec![]; + while self.is_soft_kw("friend") && self.lookahead_special_2("::") { + self.advance()?; + let module = self.module_id(&address_alias_map)?; + self.expect_newline()?; + friend_modules.push(module); + } + // Parse definitions let mut structs = vec![]; let mut functions = vec![]; @@ -837,7 +920,7 @@ impl AsmParser { while !self.is_tok(&Token::End) { if self.is_struct_or_enum() { structs.push(self.struct_or_enum()?) - } else if self.is_fun() { + } else if self.is_first_of_fun() { functions.push(self.fun()?) } else { return Err(error( @@ -851,6 +934,7 @@ impl AsmParser { name, address_aliases, module_aliases, + friend_modules, structs, functions, }) @@ -967,7 +1051,7 @@ fn id_cont(ch: char) -> bool { fn special(ch: char) -> bool { matches!( ch, - '(' | ')' | '<' | '>' | ',' | ':' | '|' | '+' | '=' | '&' + '(' | ')' | '<' | '>' | '[' | ']' | ',' | ':' | '|' | '+' | '=' | '&' | '#' ) } diff --git a/third_party/move/tools/move-asm/src/value.rs b/third_party/move/tools/move-asm/src/value.rs new file mode 100644 index 00000000000..135225f0b59 --- /dev/null +++ b/third_party/move/tools/move-asm/src/value.rs @@ -0,0 +1,127 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +//! Representation of values (constants) in the assembler + +use anyhow::anyhow; +use move_binary_format::file_format::SignatureToken; +use move_core_types::{account_address::AccountAddress, u256::U256, value::MoveValue}; +use std::fmt; + +/// An untyped numeric value, or a vector of such values. +#[derive(Debug)] +pub enum AsmValue { + Number(U256), + Vector(Vec), +} + +impl fmt::Display for AsmValue { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + AsmValue::Number(v) => write!(f, "{}", v), + AsmValue::Vector(vs) => { + write!(f, "[")?; + for (p, v) in vs.iter().enumerate() { + if p > 0 { + write!(f, ", ")? + } + write!(f, "{}", v)? + } + write!(f, "]") + }, + } + } +} + +impl AsmValue { + /// Converts untyped value into typed move value. + pub fn to_move_value(&self, ty: &SignatureToken) -> anyhow::Result { + match ty { + SignatureToken::Bool => { + let num = self.check_number(U256::from(1u8))?; + Ok(MoveValue::Bool(num != U256::zero())) + }, + SignatureToken::U8 => Ok(MoveValue::U8( + self.check_number(U256::from(u8::MAX))?.unchecked_as_u8(), + )), + SignatureToken::U16 => Ok(MoveValue::U16( + self.check_number(U256::from(u16::MAX))?.unchecked_as_u16(), + )), + SignatureToken::U32 => Ok(MoveValue::U32( + self.check_number(U256::from(u32::MAX))?.unchecked_as_u32(), + )), + SignatureToken::U64 => Ok(MoveValue::U64( + self.check_number(U256::from(u64::MAX))?.unchecked_as_u64(), + )), + SignatureToken::U128 => Ok(MoveValue::U128( + self.check_number(U256::from(u128::MAX))? + .unchecked_as_u128(), + )), + SignatureToken::U256 => Ok(MoveValue::U256(self.check_number(U256::max_value())?)), + SignatureToken::Address => Ok(MoveValue::Address(u256_to_address( + self.check_number(U256::max_value())?, + ))), + SignatureToken::Vector(elem_type) => { + if let AsmValue::Vector(vals) = self { + Ok(MoveValue::Vector( + vals.iter() + .map(|v| v.to_move_value(elem_type)) + .collect::>>()?, + )) + } else { + Err(anyhow!("expected vector value")) + } + }, + SignatureToken::Signer + | SignatureToken::Function(_, _, _) + | SignatureToken::Struct(_) + | SignatureToken::StructInstantiation(_, _) + | SignatureToken::Reference(_) + | SignatureToken::MutableReference(_) + | SignatureToken::TypeParameter(_) => Err(anyhow!("invalid type for constant value")), + } + } + + pub fn check_number(&self, max: U256) -> anyhow::Result { + if let AsmValue::Number(n) = self { + if *n <= max { + Ok(*n) + } else { + Err(anyhow!("number {} out of range (max {})", n, max)) + } + } else { + Err(anyhow!("expected a number but found a vector")) + } + } + + pub fn from_move_value(value: &MoveValue) -> anyhow::Result { + match value { + MoveValue::Bool(v) => Ok(AsmValue::Number(U256::from(if *v { 1u8 } else { 0u8 }))), + MoveValue::U8(v) => Ok(AsmValue::Number(U256::from(*v))), + MoveValue::U16(v) => Ok(AsmValue::Number(U256::from(*v))), + MoveValue::U32(v) => Ok(AsmValue::Number(U256::from(*v))), + MoveValue::U64(v) => Ok(AsmValue::Number(U256::from(*v))), + MoveValue::U128(v) => Ok(AsmValue::Number(U256::from(*v))), + MoveValue::U256(v) => Ok(AsmValue::Number(*v)), + MoveValue::Address(v) => Ok(AsmValue::Number(address_to_u256(*v))), + MoveValue::Vector(vs) => Ok(AsmValue::Vector( + vs.iter() + .map(Self::from_move_value) + .collect::>>()?, + )), + _ => Err(anyhow!("invalid constant value")), + } + } +} + +pub(crate) fn u256_to_address(num: U256) -> AccountAddress { + let mut bytes = num.to_le_bytes().to_vec(); + bytes.reverse(); + AccountAddress::from_bytes(bytes).expect("valid address value") +} + +pub(crate) fn address_to_u256(addr: AccountAddress) -> U256 { + let mut bytes = addr.into_bytes(); + bytes.reverse(); + U256::from_le_bytes(&bytes) +} diff --git a/third_party/move/tools/move-asm/tests/assembler/attributes.exp b/third_party/move/tools/move-asm/tests/assembler/attributes.exp new file mode 100644 index 00000000000..ea8438dab45 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/attributes.exp @@ -0,0 +1,19 @@ +processed 1 task + +task 0 'publish'. lines 1-9: + +== BEGIN Bytecode == +// Bytecode version v7 +module 0x66::test +// Function definition at index 0 +#[module_lock] public fun f(): u8 + ld_u8 255 + ret + +// Function definition at index 1 +#[persistent] fun g(): u8 + ld_u8 255 + ret + + +== END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/attributes.masm b/third_party/move/tools/move-asm/tests/assembler/attributes.masm new file mode 100644 index 00000000000..262eede692f --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/attributes.masm @@ -0,0 +1,9 @@ +//# publish --print-bytecode +module 0x66::test +#[module_lock] public fun f(): u8 + ld_u8 255 + ret + +#[persistent] fun g(): u8 + ld_u8 255 + ret diff --git a/third_party/move/tools/move-asm/tests/assembler/closure.masm b/third_party/move/tools/move-asm/tests/assembler/closure.masm index 7858e8fc091..467253d6804 100644 --- a/third_party/move/tools/move-asm/tests/assembler/closure.masm +++ b/third_party/move/tools/move-asm/tests/assembler/closure.masm @@ -8,5 +8,5 @@ fun identity(x: T): T fun test(): u64 ld_u64 2 pack_closure identity, 1 - call_closure <||u64 has drop> + call_closure < | |u64 has drop> ret diff --git a/third_party/move/tools/move-asm/tests/assembler/constants.exp b/third_party/move/tools/move-asm/tests/assembler/constants.exp new file mode 100644 index 00000000000..1a8398fc6ed --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/constants.exp @@ -0,0 +1,84 @@ +processed 1 task + +task 0 'publish'. lines 1-62: + +== BEGIN Bytecode == +// Bytecode version v7 +module 0x66::test +// Function definition at index 0 +fun f_u8(): u8 + ld_u8 255 + ret + +// Function definition at index 1 +fun f_u16(): u16 + ld_u16 65535 + ret + +// Function definition at index 2 +fun f_u32(): u32 + ld_u32 4294967295 + ret + +// Function definition at index 3 +fun f_u64(): u64 + ld_u64 18446744073709551615 + ret + +// Function definition at index 4 +fun f_u128(): u128 + ld_u128 340282366920938463463374607431768211455 + ret + +// Function definition at index 5 +fun f_u256(): u256 + ld_u256 115792089237316195423570985008687907853269984665640564039457584007913129639935 + ret + +// Function definition at index 6 +fun c_u8(): u8 + ld_const 255 + ret + +// Function definition at index 7 +fun c_u16(): u16 + ld_const 65535 + ret + +// Function definition at index 8 +fun c_u32(): u32 + ld_const 4294967295 + ret + +// Function definition at index 9 +fun c_u64(): u64 + ld_const 18446744073709551615 + ret + +// Function definition at index 10 +fun c_u128(): u128 + ld_const 340282366920938463463374607431768211455 + ret + +// Function definition at index 11 +fun c_u256(): u256 + ld_const 115792089237316195423570985008687907853269984665640564039457584007913129639935 + ret + +// Function definition at index 12 +fun c_vec_u8(): vector + ld_const> [255, 0] + ret + +// Function definition at index 13 +fun c_vec_address(): vector
+ ld_const> [102, 51966] + ret + +// Function definition at index 14 +fun c_vec_vec_address(): vector> + ld_const>> [[102], [51966], []] + ret + + +== END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/constants.masm b/third_party/move/tools/move-asm/tests/assembler/constants.masm new file mode 100644 index 00000000000..f694b861aef --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/constants.masm @@ -0,0 +1,62 @@ +//# publish --print-bytecode +module 0x66::test + +fun f_u8(): u8 + ld_u8 255 + ret + +fun f_u16(): u16 + ld_u16 65535 + ret + +fun f_u32(): u32 + ld_u32 4294967295 + ret + +fun f_u64(): u64 + ld_u64 18446744073709551615 + ret + +fun f_u128(): u128 + ld_u128 340282366920938463463374607431768211455 + ret + +fun f_u256(): u256 + ld_u256 115792089237316195423570985008687907853269984665640564039457584007913129639935 + ret + +fun c_u8(): u8 + ld_const 255 + ret + +fun c_u16(): u16 + ld_const 65535 + ret + +fun c_u32(): u32 + ld_const 4294967295 + ret + +fun c_u64(): u64 + ld_const 18446744073709551615 + ret + +fun c_u128(): u128 + ld_const 340282366920938463463374607431768211455 + ret + +fun c_u256(): u256 + ld_const 115792089237316195423570985008687907853269984665640564039457584007913129639935 + ret + +fun c_vec_u8(): vector + ld_const> [255, 0] + ret + +fun c_vec_address(): vector
+ ld_const> [0x66, 0xcafe] + ret + +fun c_vec_vec_address(): vector> + ld_const>> [[0x66], [0xcafe], []] + ret diff --git a/third_party/move/tools/move-asm/tests/assembler/constants_errors.exp b/third_party/move/tools/move-asm/tests/assembler/constants_errors.exp new file mode 100644 index 00000000000..ea369914e3b --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/constants_errors.exp @@ -0,0 +1,40 @@ +processed 1 task + +task 0 'publish'. lines 1-26: +Error: error: number 512 out of range (max 255) + ┌─ test:4:5 + │ +4 │ ld_u8 512 + │ ^^^^^^^^^ + +error: expected number argument + ┌─ test:7:5 + │ +7 │ ld_u16 ident + │ ^^^^^^^^^^^^ + +error: number 65536 out of range (max 65535) + ┌─ test:10:5 + │ +10 │ ld_const 65536 + │ ^^^^^^^^^^^^^^^^^^^ + +error: number 512 out of range (max 255) + ┌─ test:13:5 + │ +13 │ ld_const 512 + │ ^^^^^^^^^^^^^^^^ + +error: number 256 out of range (max 255) + ┌─ test:16:5 + │ +16 │ ld_const> [256, 0] + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected vector value + ┌─ test:19:5 + │ +19 │ ld_const> 256 + │ ^^^^^^^^^^^^^^^^^^^^^^^^ + + diff --git a/third_party/move/tools/move-asm/tests/assembler/constants_errors.masm b/third_party/move/tools/move-asm/tests/assembler/constants_errors.masm new file mode 100644 index 00000000000..f70e3c6063f --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/constants_errors.masm @@ -0,0 +1,26 @@ +//# publish --print-bytecode +module 0x66::test + +fun f_u8(): u8 + ld_u8 512 + ret + +fun f_u16(): u16 + ld_u16 ident + ret + +fun c_u16(): u16 + ld_const 65536 + ret + +fun c_u8(): u128 + ld_const 512 + ret + +fun c_vec_u8(): vector + ld_const> [256, 0] + ret + +fun c_vec_u8_2(): vector + ld_const> 256 + ret diff --git a/third_party/move/tools/move-asm/tests/assembler/declare_generic_fun.exp b/third_party/move/tools/move-asm/tests/assembler/declare_generic_fun.exp index 898260f3f47..272821f7310 100644 --- a/third_party/move/tools/move-asm/tests/assembler/declare_generic_fun.exp +++ b/third_party/move/tools/move-asm/tests/assembler/declare_generic_fun.exp @@ -6,7 +6,7 @@ task 0 'publish'. lines 1-7: // Bytecode version v7 module 0x66::test // Function definition at index 0 -fun f(l0: T0,l1: T1): (T0,T1) +fun f(l0: T0, l1: T1): (T0, T1) move_loc l0 move_loc l1 ret diff --git a/third_party/move/tools/move-asm/tests/assembler/enum.exp b/third_party/move/tools/move-asm/tests/assembler/enum.exp index 1dd4628f03b..fbdb40d92e1 100644 --- a/third_party/move/tools/move-asm/tests/assembler/enum.exp +++ b/third_party/move/tools/move-asm/tests/assembler/enum.exp @@ -29,7 +29,7 @@ fun select(l0: test::E): u64 ret // Function definition at index 2 -fun pack_and_unpack(): (u64,u32) +fun pack_and_unpack(): (u64, u32) ld_u64 1 ld_u8 2 pack_variant E, V1 diff --git a/third_party/move/tools/move-asm/tests/assembler/enum_generic.exp b/third_party/move/tools/move-asm/tests/assembler/enum_generic.exp index 084aed47aa7..7c5f1ed08ee 100644 --- a/third_party/move/tools/move-asm/tests/assembler/enum_generic.exp +++ b/third_party/move/tools/move-asm/tests/assembler/enum_generic.exp @@ -29,7 +29,7 @@ fun select(l0: test::E): u64 ret // Function definition at index 2 -fun pack_and_unpack(): (u64,u32) +fun pack_and_unpack(): (u64, u32) ld_u64 1 ld_u8 2 pack_variant E, V1 diff --git a/third_party/move/tools/move-asm/tests/assembler/friends.exp b/third_party/move/tools/move-asm/tests/assembler/friends.exp new file mode 100644 index 00000000000..2fa0255215f --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/friends.exp @@ -0,0 +1,37 @@ +processed 3 tasks + +task 0 'publish'. lines 1-2: + +== BEGIN Bytecode == +// Bytecode version v7 +module 0x66::test1 + +== END Bytecode == + +task 1 'publish'. lines 4-9: + +== BEGIN Bytecode == +// Bytecode version v7 +module 0x66::test2 +friend 66::test1 +// Function definition at index 0 +friend fun friend_fun(): u8 + ld_u8 255 + ret + + +== END Bytecode == + +task 2 'publish'. lines 11-15: + +== BEGIN Bytecode == +// Bytecode version v7 +module 0x66::test1 +use 0x66::test2 +// Function definition at index 0 +fun added_fun(): u8 + call test2::friend_fun + ret + + +== END Bytecode == diff --git a/third_party/move/tools/move-asm/tests/assembler/friends.masm b/third_party/move/tools/move-asm/tests/assembler/friends.masm new file mode 100644 index 00000000000..b2a769e2780 --- /dev/null +++ b/third_party/move/tools/move-asm/tests/assembler/friends.masm @@ -0,0 +1,15 @@ +//# publish --print-bytecode +module 0x66::test1 + +//# publish --print-bytecode +module 0x66::test2 +friend 0x66::test1 +friend fun friend_fun(): u8 + ld_u8 255 + ret + +//# publish --print-bytecode +module 0x66::test1 +fun added_fun(): u8 + call 0x66::test2::friend_fun + ret diff --git a/third_party/move/tools/move-asm/tests/assembler/struct.exp b/third_party/move/tools/move-asm/tests/assembler/struct.exp index 7978b2c7e9b..25b4cbea76b 100644 --- a/third_party/move/tools/move-asm/tests/assembler/struct.exp +++ b/third_party/move/tools/move-asm/tests/assembler/struct.exp @@ -25,7 +25,7 @@ fun select(l0: test::S): u8 ret // Function definition at index 2 -fun pack_and_unpack(): (u64,u8) +fun pack_and_unpack(): (u64, u8) ld_u64 3 ld_u8 2 pack S diff --git a/third_party/move/tools/move-asm/tests/assembler/struct_generic.exp b/third_party/move/tools/move-asm/tests/assembler/struct_generic.exp index 6ee0522f8fb..e409719f645 100644 --- a/third_party/move/tools/move-asm/tests/assembler/struct_generic.exp +++ b/third_party/move/tools/move-asm/tests/assembler/struct_generic.exp @@ -25,7 +25,7 @@ fun select(l0: test::S): u8 ret // Function definition at index 2 -fun pack_and_unpack(): (u64,u8) +fun pack_and_unpack(): (u64, u8) ld_u64 3 ld_u8 2 pack S From 8c3f0a8f3108ada0a39fc1cd13eccdd96d8b645e Mon Sep 17 00:00:00 2001 From: Wolfgang Grieskamp Date: Tue, 22 Jul 2025 13:00:36 -0700 Subject: [PATCH 050/260] [function values] Mark language version 2.2 to be stable and bytecode version 8 the default (#17116) This configures 2.2 which enables function values to be stable on compiler side, allowing people to submit to chain without errors or warnings. Also, the bytecode version is to have default of VERSION_8. This are all changes on CLI/compiler side and not for node code, which is guarded by according feature flags. Downstreamed-from: b1caac068cf63e3cf8dd32d840dd53f2d666571d --- Cargo.lock | 99 +++++++++++++++++++ aptos-move/framework/src/built_package.rs | 4 +- crates/aptos/CHANGELOG.md | 8 ++ crates/aptos/Cargo.toml | 6 +- .../acquires/acquires_error.exp | 2 +- third_party/move/move-model/src/metadata.rs | 8 +- third_party/move/scripts/move_pr.sh | 1 + 7 files changed, 119 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5c5f1588212..42e0bb35fad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -302,6 +302,105 @@ dependencies = [ "num-traits", ] +[[package]] +name = "aptos" +version = "7.6.1" +dependencies = [ + "anyhow", + "aptos-api-types", + "aptos-backup-cli", + "aptos-bitvec", + "aptos-build-info", + "aptos-cached-packages", + "aptos-cli-common", + "aptos-config", + "aptos-crypto", + "aptos-faucet-core", + "aptos-framework", + "aptos-gas-profiling", + "aptos-gas-schedule", + "aptos-genesis", + "aptos-github-client", + "aptos-global-constants", + "aptos-indexer-grpc-server-framework", + "aptos-indexer-processor-sdk", + "aptos-keygen", + "aptos-ledger", + "aptos-localnet", + "aptos-logger", + "aptos-move-debugger", + "aptos-network-checker", + "aptos-node", + "aptos-rest-client", + "aptos-sdk", + "aptos-storage-interface", + "aptos-telemetry", + "aptos-temppath", + "aptos-types", + "aptos-vm", + "aptos-vm-environment", + "aptos-vm-genesis", + "aptos-vm-logging", + "aptos-vm-types", + "aptos-workspace-server", + "async-trait", + "backoff", + "base64 0.13.1", + "bcs 0.1.4", + "bollard", + "chrono", + "clap 4.5.21", + "clap_complete", + "colored", + "dashmap 7.0.0-rc2", + "diesel", + "diesel-async", + "dirs 5.0.1", + "futures", + "hex", + "indoc", + "itertools 0.13.0", + "jemallocator", + "legacy-move-compiler", + "maplit", + "move-binary-format", + "move-bytecode-source-map", + "move-cli", + "move-command-line-common", + "move-compiler-v2", + "move-core-types", + "move-coverage", + "move-disassembler", + "move-ir-types", + "move-linter", + "move-model", + "move-package", + "move-prover-boogie-backend", + "move-symbol-pool", + "move-unit-test", + "move-vm-runtime", + "open", + "pathsearch", + "poem", + "processor", + "rand 0.7.3", + "regex", + "reqwest 0.11.23", + "self_update", + "serde", + "serde_json", + "serde_yaml 0.8.26", + "set_env", + "shadow-rs", + "tempfile", + "thiserror", + "tokio", + "toml 0.7.8", + "tracing", + "tracing-subscriber 0.3.18", + "url", +] + [[package]] name = "aptos-abstract-gas-usage" version = "0.1.0" diff --git a/aptos-move/framework/src/built_package.rs b/aptos-move/framework/src/built_package.rs index 178ddd4032b..8f9e6e8b11e 100644 --- a/aptos-move/framework/src/built_package.rs +++ b/aptos-move/framework/src/built_package.rs @@ -26,7 +26,7 @@ use legacy_move_compiler::{ compiled_unit::{CompiledUnit, NamedCompiledModule}, shared::NumericalAddress, }; -use move_binary_format::{file_format_common, file_format_common::VERSION_7, CompiledModule}; +use move_binary_format::{file_format_common, file_format_common::VERSION_DEFAULT, CompiledModule}; use move_command_line_common::files::MOVE_COMPILED_EXTENSION; use move_compiler_v2::{external_checks::ExternalChecks, options::Options, Experiment}; use move_core_types::{language_storage::ModuleId, metadata::Metadata}; @@ -144,7 +144,7 @@ impl Default for BuildOptions { impl BuildOptions { pub fn move_2() -> Self { BuildOptions { - bytecode_version: Some(VERSION_7), + bytecode_version: Some(VERSION_DEFAULT), language_version: Some(LanguageVersion::latest_stable()), compiler_version: Some(CompilerVersion::latest_stable()), ..Self::default() diff --git a/crates/aptos/CHANGELOG.md b/crates/aptos/CHANGELOG.md index 56b91842ebe..3811cffd96a 100644 --- a/crates/aptos/CHANGELOG.md +++ b/crates/aptos/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to the Movement CLI will be captured in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) and the format set out by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). # Unreleased + +## [7.6.1] +- Mark language version 2.2 as stable. + +## [7.6.0] +- Sets up confidential assets for localnet under the experimental address 0x7 + +## [7.5.0] - Fix auto-update CLI command to work with more OS's including Mac and Linux on ARM ## [7.4.0] diff --git a/crates/aptos/Cargo.toml b/crates/aptos/Cargo.toml index b8ee4591cbe..a9669bfae47 100644 --- a/crates/aptos/Cargo.toml +++ b/crates/aptos/Cargo.toml @@ -1,7 +1,7 @@ [package] -name = "movement" -description = "Movement tool for management of nodes and interacting with Movement" -version = "7.4.0" +name = "aptos" +description = "Aptos tool for management of nodes and interacting with the blockchain" +version = "7.6.1" # Workspace inherited keys authors = { workspace = true } diff --git a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/acquires/acquires_error.exp b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/acquires/acquires_error.exp index 5739d8c3551..72d92fa930a 100644 --- a/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/acquires/acquires_error.exp +++ b/third_party/move/move-compiler-v2/tests/checking-lang-v2.2/acquires/acquires_error.exp @@ -8,7 +8,7 @@ error: missing acquires annotation for `R` 15 │ let r = borrow_global(a); │ ------------------- acquired here │ - = since Move 2.2-unstable, `acquires` is inferred by the compiler and can be omitted from the function declaration. + = since Move 2.2, `acquires` is inferred by the compiler and can be omitted from the function declaration. error: unnecessary acquires annotation ┌─ tests/checking-lang-v2.2/acquires/acquires_error.move:14:40 diff --git a/third_party/move/move-model/src/metadata.rs b/third_party/move/move-model/src/metadata.rs index b9cc6985e92..8ac7e3466bd 100644 --- a/third_party/move/move-model/src/metadata.rs +++ b/third_party/move/move-model/src/metadata.rs @@ -13,6 +13,8 @@ use std::{ }; const UNSTABLE_MARKER: &str = "-unstable"; +// 2.2, even though stable, produces several warnings in the frameworks which we first need to fix +// before we can make it the default pub const LATEST_STABLE_LANGUAGE_VERSION_VALUE: LanguageVersion = LanguageVersion::V2_1; pub const LATEST_STABLE_COMPILER_VERSION_VALUE: CompilerVersion = CompilerVersion::V2_0; pub const LATEST_STABLE_LANGUAGE_VERSION: &str = LATEST_STABLE_LANGUAGE_VERSION_VALUE.to_str(); @@ -190,7 +192,7 @@ pub enum LanguageVersion { V2_0, /// The 2.1 version of Move, V2_1, - /// The currently unstable 2.2 version of Move + /// The 2.2 version of Move V2_2, /// The currently unstable 2.3 version of Move V2_3, @@ -262,8 +264,8 @@ impl LanguageVersion { pub const fn unstable(self) -> bool { use LanguageVersion::*; match self { - V1 | V2_0 | V2_1 => false, - V2_2 | V2_3 => true, + V1 | V2_0 | V2_1 | V2_2 => false, + V2_3 => true, } } diff --git a/third_party/move/scripts/move_pr.sh b/third_party/move/scripts/move_pr.sh index c7a0ee4f261..ab1a6228bf8 100755 --- a/third_party/move/scripts/move_pr.sh +++ b/third_party/move/scripts/move_pr.sh @@ -98,6 +98,7 @@ MOVE_CRATES="\ -p move-vm-runtime\ -p move-vm-types\ -p move-ast-generator-tests\ + -p tools/move-asm\ " # This is a list of crates for integration testing. From 4be5ca7d2e4904d576ac398b1ec4c5550d963fb9 Mon Sep 17 00:00:00 2001 From: "Andrea Cappa (zi0Black)" <13380579+zi0Black@users.noreply.github.com> Date: Thu, 24 Jul 2025 13:37:48 +0100 Subject: [PATCH 051/260] [fuzzer] Bridge transactional tests format and fuzzers (#16715) * Update dependencies and enhance fuzzer functionality - Added a new transaction fuzzer compatible with transactional test format. - Updated `.gitignore` to exclude `test-casr-report/`. - Enhanced `fuzz.sh` to allow for coverage report generation with existing profdata files. - Refactored fuzzer targets to utilize new dependencies and improve code structure. - Introduced functions for generating runnable states from all test sources, including transactional tests and e2e tests. These changes aim to improve the fuzzer's capabilities and streamline the testing process. * Enhance fuzzer data update workflow and improve error handling - Updated the fuzzer data update workflow to download and process both standard and transactional seed corpora. - Added new steps to generate runnable states from e2e tests and transactional tests. - Refactored the handling of transaction execution results to better manage unexpected gas usage scenarios. * remove dead-code Downstreamed-from: 916aede09a8c0d6c89a6b977b85499b4d496ab39 --- Cargo.lock | 9 + testsuite/fuzzer/.gitignore | 1 + testsuite/fuzzer/Cargo.toml | 9 +- .../data/0x1/function_values/any/Move.toml | 13 + .../0x1/function_values/any/sources/any.move | 26 + .../data/0x1/function_values/ref/Move.toml | 13 + .../0x1/function_values/ref/sources/ref.move | 31 + testsuite/fuzzer/fuzz.sh | 37 +- testsuite/fuzzer/fuzz/Cargo.toml | 8 + .../fuzz/fuzz_targets/move/aptosvm_publish.rs | 9 +- .../move/aptosvm_publish_and_run.rs | 63 +- .../aptosvm_publish_and_run_transactional.rs | 419 ++++++++++++ .../bytecode_verifier_compiled_modules.rs | 2 +- .../fuzz_targets/move/type_tag_to_string.rs | 4 +- .../fuzz_targets/move/utils/authenticator.rs | 2 +- .../fuzz/fuzz_targets/move/utils/helpers.rs | 33 - .../fuzzer/fuzz/fuzz_targets/move/utils/vm.rs | 36 +- testsuite/fuzzer/src/lib.rs | 9 + testsuite/fuzzer/src/main.rs | 38 +- testsuite/fuzzer/src/types.rs | 105 +++ testsuite/fuzzer/src/utils.rs | 636 ++++++++++++------ .../transactional-test-runner/Cargo.toml | 7 + .../transactional-test-runner/src/lib.rs | 2 + .../src/transactional_ops.rs | 592 ++++++++++++++++ .../src/vm_test_harness.rs | 5 + 25 files changed, 1786 insertions(+), 323 deletions(-) create mode 100644 testsuite/fuzzer/data/0x1/function_values/any/Move.toml create mode 100644 testsuite/fuzzer/data/0x1/function_values/any/sources/any.move create mode 100644 testsuite/fuzzer/data/0x1/function_values/ref/Move.toml create mode 100644 testsuite/fuzzer/data/0x1/function_values/ref/sources/ref.move create mode 100644 testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish_and_run_transactional.rs create mode 100644 testsuite/fuzzer/src/lib.rs create mode 100644 testsuite/fuzzer/src/types.rs create mode 100644 third_party/move/testing-infra/transactional-test-runner/src/transactional_ops.rs diff --git a/Cargo.lock b/Cargo.lock index 42e0bb35fad..190f4688c51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9223,6 +9223,7 @@ name = "fuzzer" version = "0.1.0" dependencies = [ "aptos-framework", + "aptos-language-e2e-tests", "aptos-types", "arbitrary", "base64 0.21.7", @@ -9233,6 +9234,8 @@ dependencies = [ "hex", "move-binary-format", "move-core-types", + "move-model", + "move-transactional-test-runner", "rayon", "sha2 0.9.9", "walkdir", @@ -9254,10 +9257,12 @@ dependencies = [ "arbitrary", "base64 0.13.1", "bcs 0.1.4", + "fuzzer", "libfuzzer-sys", "move-binary-format", "move-bytecode-verifier", "move-core-types", + "move-transactional-test-runner", "move-vm-types", "once_cell", "rayon", @@ -12588,8 +12593,12 @@ name = "move-transactional-test-runner" version = "0.1.0" dependencies = [ "anyhow", + "aptos-framework", + "arbitrary", + "bcs 0.1.4", "clap 4.5.21", "datatest-stable", + "dearbitrary", "difference", "either", "legacy-move-compiler", diff --git a/testsuite/fuzzer/.gitignore b/testsuite/fuzzer/.gitignore index b7cc4f77a77..d4258a3eb5a 100644 --- a/testsuite/fuzzer/.gitignore +++ b/testsuite/fuzzer/.gitignore @@ -2,3 +2,4 @@ *.crash perf.data perf.data.old +test-casr-report/ \ No newline at end of file diff --git a/testsuite/fuzzer/Cargo.toml b/testsuite/fuzzer/Cargo.toml index d0cf589dcdb..146dad89c71 100644 --- a/testsuite/fuzzer/Cargo.toml +++ b/testsuite/fuzzer/Cargo.toml @@ -6,16 +6,19 @@ license = { workspace = true } [dependencies] aptos-framework = { workspace = true } +aptos-language-e2e-tests = { workspace = true } aptos-types = { workspace = true } -arbitrary = { workspace = true } +arbitrary = { workspace = true, features = ["derive"] } base64 = "0.21.7" bcs = { workspace = true } -clap = { workspace = true } +clap = { workspace = true, features = ["derive"] } csv = { workspace = true } dearbitrary = { workspace = true } hex = { workspace = true } move-binary-format = { workspace = true, features = ["fuzzing"] } -move-core-types = { workspace = true, features = ["fuzzing"] } +move-core-types = { workspace = true } +move-model = { workspace = true } +move-transactional-test-runner = { workspace = true, features = ["fuzzing"] } rayon = { workspace = true } sha2 = { workspace = true } walkdir = { workspace = true } diff --git a/testsuite/fuzzer/data/0x1/function_values/any/Move.toml b/testsuite/fuzzer/data/0x1/function_values/any/Move.toml new file mode 100644 index 00000000000..fd233e31941 --- /dev/null +++ b/testsuite/fuzzer/data/0x1/function_values/any/Move.toml @@ -0,0 +1,13 @@ +[package] +name = "fv_any" +version = "1.0.0" +authors = [] + +[addresses] +poc = "0xcaffe" + +[dependencies] +MoveStdlib = { local = "../../../../../../aptos-move/framework/move-stdlib" } +AptosFramework = { local = "../../../../../../aptos-move/framework/aptos-framework" } +AptosStdlib = { local = "../../../../../../aptos-move/framework/aptos-stdlib" } + \ No newline at end of file diff --git a/testsuite/fuzzer/data/0x1/function_values/any/sources/any.move b/testsuite/fuzzer/data/0x1/function_values/any/sources/any.move new file mode 100644 index 00000000000..6c7d99db2a6 --- /dev/null +++ b/testsuite/fuzzer/data/0x1/function_values/any/sources/any.move @@ -0,0 +1,26 @@ +module poc::fv_any { + use std::any; + struct A {} + + public fun make_potato(): A { + A {} + } + + public fun destroy_potato(x: A) { + A {} = x; + } + + public fun zzz(): || { + let potato = make_potato(); + || destroy_potato(potato) + } + + public entry fun win() { + let x: || (||) has drop + store = zzz; + + let a = 0x1::any::pack(x); + + let b = 0x1::any::unpack<|| (|| has drop + store)>(a); + b(); + } +} diff --git a/testsuite/fuzzer/data/0x1/function_values/ref/Move.toml b/testsuite/fuzzer/data/0x1/function_values/ref/Move.toml new file mode 100644 index 00000000000..07f1b8c6d7f --- /dev/null +++ b/testsuite/fuzzer/data/0x1/function_values/ref/Move.toml @@ -0,0 +1,13 @@ +[package] +name = "fv_ref" +version = "1.0.0" +authors = [] + +[addresses] +poc = "0xcaffe" + +[dependencies] +MoveStdlib = { local = "../../../../../../aptos-move/framework/move-stdlib" } +AptosFramework = { local = "../../../../../../aptos-move/framework/aptos-framework" } +AptosStdlib = { local = "../../../../../../aptos-move/framework/aptos-stdlib" } + \ No newline at end of file diff --git a/testsuite/fuzzer/data/0x1/function_values/ref/sources/ref.move b/testsuite/fuzzer/data/0x1/function_values/ref/sources/ref.move new file mode 100644 index 00000000000..783eb18d739 --- /dev/null +++ b/testsuite/fuzzer/data/0x1/function_values/ref/sources/ref.move @@ -0,0 +1,31 @@ +module poc::fv_ref { + use std::debug; + struct DropCopy has drop, copy; + + + public fun assn(ref: &mut T, x: T){ + *ref = x; + } + + public entry fun foo() { + let x = DropCopy; + + // closure capturing x: DropCopy + let a: ||u64 has drop = ||{ + let DropCopy = x; + 1 + }; + + // harmless copy+drop function + let pwn: ||u64 has drop + copy = ||1; + + // swap them + // 0x1::mem::replace<||u64 has drop + copy>(&mut pwn, a); + assn<||u64 has drop + copy>(&mut pwn, a); + + // copy the closure with captured DropCopy + let pwncopy = copy pwn; + pwn(); + pwncopy(); + } +} diff --git a/testsuite/fuzzer/fuzz.sh b/testsuite/fuzzer/fuzz.sh index c36392eee9e..868bc3a7c9f 100755 --- a/testsuite/fuzzer/fuzz.sh +++ b/testsuite/fuzzer/fuzz.sh @@ -7,7 +7,10 @@ NIGHTLY_VERSION="nightly-2025-04-03" # GDRIVE format https://docs.google.com/uc?export=download&id=DOCID # "https://storage.googleapis.com/aptos-core-corpora/move_aptosvm_publish_seed_corpus.zip" -CORPUS_ZIPS=("https://storage.googleapis.com/aptos-core-corpora/move_aptosvm_publish_and_run_seed_corpus.zip") +CORPUS_ZIPS=( + "https://storage.googleapis.com/aptos-core-corpora/move_aptosvm_publish_and_run_seed_corpus.zip" + "https://storage.googleapis.com/aptos-core-corpora/move_aptosvm_publish_and_run_transactional_seed_corpus.zip" +) # This save time excluding some features needed only for specific targets # Downside: fuzzers which require specific features need to recompile all dependencies @@ -262,12 +265,32 @@ function coverage() { install-coverage-tools fi - clean-coverage $fuzz_target - local corpus_dir="fuzz/corpus/$fuzz_target" + local profdata_file="fuzz/coverage/$fuzz_target/coverage.profdata" local coverage_dir="./fuzz/coverage/$fuzz_target/report" mkdir -p $coverage_dir - - if [ ! -d "fuzz/coverage/$fuzz_target/raw" ]; then + + if [ -f "$profdata_file" ]; then + local profdata_time + profdata_time=$(stat -f "%Sm" "$profdata_file") + echo "Found existing profdata file created at: $profdata_time" + read -p "Do you want to (c)lean and regenerate or (g)enerate report with existing file? [c/g]: " choice + case "$choice" in + c|C ) + clean-coverage $fuzz_target + local corpus_dir="fuzz/corpus/$fuzz_target" + cargo_fuzz coverage $fuzz_target $corpus_dir + ;; + g|G ) + echo "Using existing profdata file..." + ;; + * ) + echo "Invalid choice. Exiting." + exit 1 + ;; + esac + else + clean-coverage $fuzz_target + local corpus_dir="fuzz/corpus/$fuzz_target" cargo_fuzz coverage $fuzz_target $corpus_dir fi @@ -283,7 +306,7 @@ function coverage() { # Generate the coverage report cargo +$NIGHTLY_VERSION cov -- show $fuzz_target_bin \ --format=html \ - --instr-profile=fuzz/coverage/$fuzz_target/coverage.profdata \ + --instr-profile=$profdata_file \ --show-directory-coverage \ --output-dir=$coverage_dir \ -Xdemangler=rustfilt \ @@ -361,7 +384,7 @@ function run() { if [[ "$OSTYPE" == "darwin"* ]]; then cargo_fuzz run $features --sanitizer address -O $fuzz_target $testcase -- -fork=4 #-ignore_crashes=1 else - cargo_fuzz run $features --sanitizer address -O $fuzz_target $testcase -- -rss_limit_mb=4096 -fork=10 #-ignore_crashes=1 + cargo_fuzz run $features --sanitizer none -O $fuzz_target $testcase -- -rss_limit_mb=4096 -fork=4 -ignore_crashes=1 fi } diff --git a/testsuite/fuzzer/fuzz/Cargo.toml b/testsuite/fuzzer/fuzz/Cargo.toml index 905bbfa200b..b0b7dbe7231 100644 --- a/testsuite/fuzzer/fuzz/Cargo.toml +++ b/testsuite/fuzzer/fuzz/Cargo.toml @@ -21,10 +21,12 @@ aptos-vm-environment = { workspace = true } arbitrary = { workspace = true, features = ["derive"] } base64 = { workspace = true } bcs = { workspace = true } +fuzzer = { path = "../" } libfuzzer-sys = "0.4.9" move-binary-format = { workspace = true, features = ["fuzzing"] } move-bytecode-verifier = { workspace = true } move-core-types = { workspace = true, features = ["fuzzing"] } +move-transactional-test-runner = { workspace = true, features = ["fuzzing"] } move-vm-types = { workspace = true, features = ["fuzzing"] } once_cell = { workspace = true } rayon = { workspace = true } @@ -101,3 +103,9 @@ name = "type_tag_to_string" path = "fuzz_targets/move/type_tag_to_string.rs" test = false doc = false + +[[bin]] +name = "move_aptosvm_publish_and_run_transactional" +path = "fuzz_targets/move/aptosvm_publish_and_run_transactional.rs" +test = false +doc = false diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish.rs index d0de51f1bea..e3bbda46da0 100644 --- a/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish.rs +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish.rs @@ -8,6 +8,7 @@ use aptos_language_e2e_tests::executor::FakeExecutor; use aptos_transaction_simulation::GENESIS_CHANGE_SET_HEAD; use aptos_types::{chain_id::ChainId, write_set::WriteSet}; use aptos_vm::AptosVM; +use fuzzer::{ExecVariant, RunnableState}; use libfuzzer_sys::{fuzz_target, Corpus}; use move_binary_format::{ access::ModuleAccess, @@ -19,7 +20,7 @@ use std::{ collections::{BTreeMap, HashSet}, sync::Arc, }; -use utils::vm::{publish_group, sort_by_deps, ExecVariant, RunnableState}; +use utils::vm::{publish_group, sort_by_deps}; // genesis write set generated once for each fuzzing session static VM: Lazy = Lazy::new(|| GENESIS_CHANGE_SET_HEAD.write_set().clone()); @@ -52,9 +53,9 @@ fn run_case(mut input: RunnableState) -> Result<(), Corpus> { } if let ExecVariant::Script { - script: s, - type_args: _, - args: _, + _script: s, + _type_args: _, + _args: _, } = &input.exec_variant { // reject bad scripts fast lite diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish_and_run.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish_and_run.rs index e92824cc168..e4047d4d1fd 100644 --- a/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish_and_run.rs +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish_and_run.rs @@ -31,10 +31,8 @@ use std::{ time::Instant, }; mod utils; -use utils::vm::{ - check_for_invariant_violation, publish_group, sort_by_deps, ExecVariant, - FuzzerRunnableAuthenticator, RunnableState, -}; +use fuzzer::{Authenticator, ExecVariant, RunnableState}; +use utils::vm::{check_for_invariant_violation, publish_group, sort_by_deps, BYTECODE_VERSION}; // genesis write set generated once for each fuzzing session static VM_WRITE_SET: Lazy = Lazy::new(|| GENESIS_CHANGE_SET_HEAD.write_set().clone()); @@ -85,8 +83,8 @@ fn check_for_invariant_violation_vmerror(e: VMError) { // filter modules fn filter_modules(input: &RunnableState) -> Result<(), Corpus> { // reject any TypeParameter exceeds the maximum allowed value (Avoid known Ivariant Violation) - if let ExecVariant::Script { script, .. } = input.exec_variant.clone() { - for signature in script.signatures { + if let ExecVariant::Script { _script, .. } = input.exec_variant.clone() { + for signature in _script.signatures { for sign_token in signature.0.iter() { if let SignatureToken::TypeParameter(idx) = sign_token { if *idx > MAX_TYPE_PARAMETER_VALUE { @@ -113,7 +111,7 @@ fn run_case(mut input: RunnableState) -> Result<(), Corpus> { filter_modules(&input)?; let verifier_config = prod_configs::aptos_prod_verifier_config(&Features::default()); - let deserializer_config = DeserializerConfig::new(8, 255); + let deserializer_config = DeserializerConfig::new(BYTECODE_VERSION, 255); for m in input.dep_modules.iter_mut() { // m.metadata = vec![]; // we could optimize metadata to only contain aptos metadata @@ -121,7 +119,8 @@ fn run_case(mut input: RunnableState) -> Result<(), Corpus> { // reject bad modules fast let mut module_code: Vec = vec![]; - m.serialize(&mut module_code).map_err(|_| Corpus::Keep)?; + m.serialize_for_version(Some(BYTECODE_VERSION), &mut module_code) + .map_err(|_| Corpus::Reject)?; let m_de = CompiledModule::deserialize_with_config(&module_code, &deserializer_config) .map_err(|_| Corpus::Reject)?; move_bytecode_verifier::verify_module_with_config(&verifier_config, &m_de).map_err(|e| { @@ -131,14 +130,15 @@ fn run_case(mut input: RunnableState) -> Result<(), Corpus> { } if let ExecVariant::Script { - script: s, - type_args: _, - args: _, + _script: s, + _type_args: _, + _args: _, } = &input.exec_variant { // reject bad scripts fast let mut script_code: Vec = vec![]; - s.serialize(&mut script_code).map_err(|_| Corpus::Keep)?; + s.serialize_for_version(Some(BYTECODE_VERSION), &mut script_code) + .map_err(|_| Corpus::Reject)?; let s_de = CompiledScript::deserialize_with_config(&script_code, &deserializer_config) .map_err(|_| Corpus::Reject)?; move_bytecode_verifier::verify_script_with_config(&verifier_config, &s_de).map_err(|e| { @@ -212,13 +212,13 @@ fn run_case(mut input: RunnableState) -> Result<(), Corpus> { // build tx let tx = match input.exec_variant.clone() { ExecVariant::Script { - script, - type_args, - args, + _script: script, + _type_args: type_args, + _args: args, } => { let mut script_bytes = vec![]; script - .serialize(&mut script_bytes) + .serialize_for_version(Some(BYTECODE_VERSION), &mut script_bytes) .map_err(|_| Corpus::Reject)?; sender_acc .transaction() @@ -235,10 +235,10 @@ fn run_case(mut input: RunnableState) -> Result<(), Corpus> { ))) }, ExecVariant::CallFunction { - module, - function, - type_args, - args, + _module: module, + _function: function, + _type_args: type_args, + _args: args, } => { // convert FunctionDefinitionIndex to function name... { let cm = input @@ -277,13 +277,13 @@ fn run_case(mut input: RunnableState) -> Result<(), Corpus> { }; let raw_tx = tx.raw(); let tx = match input.tx_auth_type { - FuzzerRunnableAuthenticator::Ed25519 { sender: _ } => raw_tx + Authenticator::Ed25519 { _sender: _ } => raw_tx .sign(&sender_acc.privkey, sender_acc.pubkey.as_ed25519().unwrap()) .map_err(|_| Corpus::Reject)? .into_inner(), - FuzzerRunnableAuthenticator::MultiAgent { - sender: _, - secondary_signers, + Authenticator::MultiAgent { + _sender: _, + _secondary_signers: secondary_signers, } => { // higher number here slows down fuzzer significatly due to slow signing process. if secondary_signers.len() > 10 { @@ -304,10 +304,10 @@ fn run_case(mut input: RunnableState) -> Result<(), Corpus> { .map_err(|_| Corpus::Reject)? .into_inner() }, - FuzzerRunnableAuthenticator::FeePayer { - sender: _, - secondary_signers, - fee_payer, + Authenticator::FeePayer { + _sender: _, + _secondary_signers: secondary_signers, + _fee_payer: fee_payer, } => { // higher number here slows down fuzzer significatly due to slow signing process. if secondary_signers.len() > 10 { @@ -368,7 +368,9 @@ fn run_case(mut input: RunnableState) -> Result<(), Corpus> { let status = match tdbg!(res.status()) { TransactionStatus::Keep(status) => status, TransactionStatus::Discard(e) => { - if e.status_type() == StatusType::InvariantViolation { + if e.status_type() == StatusType::InvariantViolation + || e.status_type() == StatusType::Unknown + { panic!("invariant violation {:?}", e); } return Err(Corpus::Keep); @@ -379,7 +381,8 @@ fn run_case(mut input: RunnableState) -> Result<(), Corpus> { ExecutionStatus::Success => (), ExecutionStatus::MiscellaneousError(e) => { if let Some(e) = e { - if e.status_type() == StatusType::InvariantViolation + if (e.status_type() == StatusType::InvariantViolation + || e.status_type() == StatusType::Unknown) && *e != StatusCode::TYPE_RESOLUTION_FAILURE && *e != StatusCode::STORAGE_ERROR { diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish_and_run_transactional.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish_and_run_transactional.rs new file mode 100644 index 00000000000..9286b348b7a --- /dev/null +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/aptosvm_publish_and_run_transactional.rs @@ -0,0 +1,419 @@ +#![no_main] + +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_language_e2e_tests::{account::Account, executor::FakeExecutor}; +use aptos_transaction_simulation::GENESIS_CHANGE_SET_HEAD; +use aptos_types::{ + chain_id::ChainId, + on_chain_config::Features, + transaction::{ + EntryFunction, ExecutionStatus, Script, SignedTransaction, TransactionArgument, + TransactionPayload, TransactionStatus, + }, + write_set::WriteSet, +}; +use aptos_vm::AptosVM; +use aptos_vm_environment::prod_configs; +use libfuzzer_sys::{fuzz_target, Corpus}; +use move_binary_format::{ + access::ModuleAccess, + deserializer::DeserializerConfig, + errors::VMError, + file_format::{CompiledModule, CompiledScript, SignatureToken}, +}; +use move_core_types::vm_status::{StatusCode, StatusType}; +use move_transactional_test_runner::transactional_ops::TransactionalOperation; +use once_cell::sync::Lazy; +use std::{ + collections::{BTreeMap, HashSet}, + sync::Arc, +}; +mod utils; +use fuzzer::{ExecVariant, RunnableStateWithOperations}; +use utils::vm::{check_for_invariant_violation, publish_group, sort_by_deps, BYTECODE_VERSION}; + +// genesis write set generated once for each fuzzing session +static VM_WRITE_SET: Lazy = Lazy::new(|| GENESIS_CHANGE_SET_HEAD.write_set().clone()); + +const FUZZER_CONCURRENCY_LEVEL: usize = 1; +static TP: Lazy> = Lazy::new(|| { + Arc::new( + rayon::ThreadPoolBuilder::new() + .num_threads(FUZZER_CONCURRENCY_LEVEL) + .build() + .unwrap(), + ) +}); + +const MAX_TYPE_PARAMETER_VALUE: u16 = 64 / 4 * 16; // third_party/move/move-bytecode-verifier/src/signature_v2.rs#L1306-L1312 + +// List of known false positive messages for invariant violations +// If some invariant violation do not come with a message, we need to attach a message to it at throwing site. +const KNOWN_FALSE_POSITIVES: &[&str] = &["too many type parameters/arguments in the program"]; + +fn check_for_invariant_violation_vmerror(e: VMError) { + if e.status_type() == StatusType::InvariantViolation { + let is_known_false_positive = e.message().map_or(false, |msg| { + KNOWN_FALSE_POSITIVES + .iter() + .any(|known| msg.starts_with(known)) + }); + + if !is_known_false_positive && e.status_type() == StatusType::InvariantViolation { + panic!( + "invariant violation {:?}\n{}{:?} {}", + e, + "RUST_BACKTRACE=1 DEBUG_VM_STATUS=", + e.major_status(), + "./fuzz.sh run move_aptosvm_publish_and_run " + ); + } + } +} + +// filter modules +fn filter_modules(input: &RunnableStateWithOperations) -> Result<(), Corpus> { + // reject any TypeParameter exceeds the maximum allowed value (Avoid known Ivariant Violation) + for operation in input.operations.iter() { + match operation { + TransactionalOperation::PublishModule { _module } => { + for signature in _module.signatures.iter() { + for sign_token in signature.0.iter() { + if let SignatureToken::TypeParameter(idx) = sign_token { + if *idx > MAX_TYPE_PARAMETER_VALUE { + return Err(Corpus::Reject); + } + } + } + } + }, + TransactionalOperation::RunScript { _script, .. } => { + for signature in _script.signatures.iter() { + for sign_token in signature.0.iter() { + if let SignatureToken::TypeParameter(idx) = sign_token { + if *idx > MAX_TYPE_PARAMETER_VALUE { + return Err(Corpus::Reject); + } + } + } + } + }, + _ => (), + } + } + Ok(()) +} + +#[allow(clippy::literal_string_with_formatting_args)] +fn run_case(input: RunnableStateWithOperations) -> Result<(), Corpus> { + tdbg!(&input); + + // filter modules + tdbg!("filtering modules"); + filter_modules(&input)?; + + let verifier_config = prod_configs::aptos_prod_verifier_config(&Features::default()); + let deserializer_config = DeserializerConfig::new(BYTECODE_VERSION, 255); + + let mut dep_modules: Vec = vec![]; + let mut exec_variant_opt: Option = None; + + for operation in input.operations.iter() { + match operation { + TransactionalOperation::PublishModule { _module } => { + dep_modules.push(_module.clone()); + }, + TransactionalOperation::RunScript { + _script, + _type_args, + _args, + } => { + if exec_variant_opt.is_none() { + exec_variant_opt = Some(ExecVariant::Script { + _script: _script.clone(), + _type_args: _type_args.clone(), + _args: _args.clone(), + }); + } + }, + TransactionalOperation::CallFunction { + _module, + _function, + _type_args, + _args, + } => { + if exec_variant_opt.is_none() { + exec_variant_opt = Some(ExecVariant::CallFunction { + _module: _module.clone(), + _function: *_function, + _type_args: _type_args.clone(), + _args: _args.clone(), + }); + } + }, + } + } + + tdbg!("verifying scripts"); + for exec_variant in exec_variant_opt.iter() { + match exec_variant { + // reject bad scripts fast + ExecVariant::Script { + _script, + _type_args: _, + _args: _, + } => { + let mut script_code: Vec = vec![]; + tdbg!("serializing script"); + _script + .serialize_for_version(Some(BYTECODE_VERSION), &mut script_code) + .map_err(|_| Corpus::Reject)?; + tdbg!("deserializing script"); + let s_de = + CompiledScript::deserialize_with_config(&script_code, &deserializer_config) + .map_err(|_| Corpus::Reject)?; + tdbg!("verifying script"); + move_bytecode_verifier::verify_script_with_config(&verifier_config, &s_de).map_err( + |e| { + check_for_invariant_violation_vmerror(e); + Corpus::Reject + }, + )? + }, + _ => (), + } + } + + tdbg!("verifying modules"); + for m in dep_modules.iter_mut() { + // m.metadata = vec![]; // we could optimize metadata to only contain aptos metadata + // m.version = VERSION_MAX; + + // reject bad modules fast + let mut module_code: Vec = vec![]; + m.serialize_for_version(Some(BYTECODE_VERSION), &mut module_code) + .map_err(|_| Corpus::Reject)?; + let m_de = CompiledModule::deserialize_with_config(&module_code, &deserializer_config) + .map_err(|_| Corpus::Reject)?; + move_bytecode_verifier::verify_module_with_config(&verifier_config, &m_de).map_err(|e| { + check_for_invariant_violation_vmerror(e); + Corpus::Reject + })? + } + + tdbg!("checking no duplicates"); + // check no duplicates + let mset: HashSet<_> = dep_modules.iter().map(|m| m.self_id()).collect(); + if mset.len() != dep_modules.len() { + return Err(Corpus::Reject); + } + + tdbg!("topologically ordering modules"); + // topologically order modules + let all_modules = dep_modules.clone(); + let map = all_modules + .into_iter() + .map(|m| (m.self_id(), m)) + .collect::>(); + let mut order = vec![]; + for id in map.keys() { + let mut visited = HashSet::new(); + sort_by_deps(&map, &mut order, id.clone(), &mut visited)?; + } + + tdbg!("grouping same address modules in packages"); + // group same address modules in packages. keep local ordering. + let mut packages: Vec> = Vec::new(); + let mut remaining_modules_map = map.clone(); // Clone the map as we'll be removing items + + for module_id_to_start_package in &order { + // `order` is the globally sorted Vec + // If the module that could start a new package isn't in our remaining set, + // it means its entire package has likely been processed already via an earlier module_id in `order`. + if !remaining_modules_map.contains_key(module_id_to_start_package) { + continue; + } + + let package_address = module_id_to_start_package.address(); + let mut current_package_for_address: Vec = Vec::new(); + + // Iterate through the globally sorted `order` list again. + // This ensures that modules for `package_address` are added to `current_package_for_address` + // in their correct topological sub-order. + for module_id_in_global_order in &order { + if module_id_in_global_order.address() == package_address { + // If this module belongs to the current package_address, + // try to remove it from `remaining_modules_map`. + // If successful, it means it hasn't been added to any package yet. + if let Some(module) = remaining_modules_map.remove(module_id_in_global_order) { + current_package_for_address.push(module); + } + } + } + + if !current_package_for_address.is_empty() { + packages.push(current_package_for_address); + } + } + + AptosVM::set_concurrency_level_once(FUZZER_CONCURRENCY_LEVEL); + let mut vm = FakeExecutor::from_genesis_with_existing_thread_pool( + &VM_WRITE_SET, + ChainId::mainnet(), + Arc::clone(&TP), + ) + .set_not_parallel(); + + // publish all packages + for group in packages { + let sender = *group[0].address(); + let acc = vm.new_account_at(sender); + publish_group(&mut vm, &acc, &group, 0)?; + } + + // TODO: use the sender from the input when added in future + let sender_acc = if true { + // create sender pub/priv key. initialize and fund account + vm.create_accounts(1, input.tx_auth_type.sender().fund_amount(), 0) + .remove(0) + } else { + // only create sender pub/priv key. do not initialize + Account::new() + }; + + // build txs + tdbg!("building txs"); + let mut txs = vec![]; + for exec_variant in exec_variant_opt.iter() { + let tx = match exec_variant { + ExecVariant::Script { + _script, + _type_args, + _args, + } => { + let mut script_bytes = vec![]; + _script + .serialize_for_version(Some(BYTECODE_VERSION), &mut script_bytes) + .map_err(|_| Corpus::Reject)?; + sender_acc + .transaction() + .gas_unit_price(100) + .max_gas_amount(1000) + .sequence_number(0) + .payload(TransactionPayload::Script(Script::new( + script_bytes, + _type_args.clone(), + _args + .iter() + .map(|x| x.clone().try_into()) + .collect::, _>>() + .map_err(|_| Corpus::Reject)?, + ))) + }, + ExecVariant::CallFunction { + _module, + _function, + _type_args, + _args, + } => { + // convert FunctionDefinitionIndex to function name... { + let cm = dep_modules + .iter() + .find(|m| m.self_id() == *_module) + .ok_or(Corpus::Reject)?; + let fhi = cm + .function_defs + .get(_function.0 as usize) + .ok_or(Corpus::Reject)? + .function; + let function_identifier_index = cm + .function_handles + .get(fhi.0 as usize) + .ok_or(Corpus::Reject)? + .name; + let function_name = cm + .identifiers + .get(function_identifier_index.0 as usize) + .ok_or(Corpus::Reject)? + .clone(); + // } + sender_acc + .transaction() + .gas_unit_price(100) + .max_gas_amount(1000) + .sequence_number(0) + .payload(TransactionPayload::EntryFunction(EntryFunction::new( + _module.clone(), + function_name, + _type_args.clone(), + _args.clone(), + ))) + }, + }; + txs.push(tx); + } + + tdbg!("signing txs"); + let txs: Vec<_> = txs + .into_iter() + .map(|tx| { + let raw_tx = tx.raw(); + raw_tx + .sign(&sender_acc.privkey, sender_acc.pubkey.as_ed25519().unwrap()) + .map_err(|_| Corpus::Reject) + .map(|signed_internal| signed_internal.into_inner()) + }) + .collect::, Corpus>>()?; + + // exec tx + // Note: one tx per block. + tdbg!("exec start"); + for tx in txs.iter() { + let res = vm + .execute_block(vec![tx.clone()]) + .map_err(|e| { + check_for_invariant_violation(e); + Corpus::Keep + })? + .pop() + .expect("expect 1 output"); + + // if error exit gracefully + let status = match tdbg!(res.status()) { + TransactionStatus::Keep(status) => status, + TransactionStatus::Discard(e) => { + if e.status_type() == StatusType::InvariantViolation { + panic!("invariant violation {:?}", e); + } + return Err(Corpus::Keep); + }, + _ => return Err(Corpus::Keep), + }; + match tdbg!(status) { + ExecutionStatus::Success | ExecutionStatus::OutOfGas => { + vm.apply_write_set(res.write_set()) + }, + ExecutionStatus::MiscellaneousError(e) => { + if let Some(e) = e { + if e.status_type() == StatusType::InvariantViolation + && *e != StatusCode::TYPE_RESOLUTION_FAILURE + && *e != StatusCode::STORAGE_ERROR + { + panic!("invariant violation {:?}, {:?}", e, res.auxiliary_data()); + } + } + return Err(Corpus::Keep); + }, + _ => return Err(Corpus::Keep), + }; + } + tdbg!("exec end"); + + Ok(()) +} + +fuzz_target!(|fuzz_data: RunnableStateWithOperations| -> Corpus { + run_case(fuzz_data).err().unwrap_or(Corpus::Keep) +}); diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/bytecode_verifier_compiled_modules.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/bytecode_verifier_compiled_modules.rs index fced79cd3be..f8adc7b87e5 100644 --- a/testsuite/fuzzer/fuzz/fuzz_targets/move/bytecode_verifier_compiled_modules.rs +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/bytecode_verifier_compiled_modules.rs @@ -9,7 +9,7 @@ use libfuzzer_sys::{fuzz_target, Corpus}; use move_binary_format::errors::VMError; use move_core_types::vm_status::StatusType; mod utils; -use utils::vm::RunnableState; +use fuzzer::RunnableState; fn check_for_invariant_violation_vmerror(e: VMError) { if e.status_type() == StatusType::InvariantViolation diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/type_tag_to_string.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/type_tag_to_string.rs index 6e3a4a1929a..2f18bcbaf4e 100644 --- a/testsuite/fuzzer/fuzz/fuzz_targets/move/type_tag_to_string.rs +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/type_tag_to_string.rs @@ -18,8 +18,8 @@ struct FuzzData { fn is_valid_type_tag(type_tag: &TypeTag) -> bool { match type_tag { TypeTag::Struct(struct_tag) => { - Identifier::is_valid(&struct_tag.module.to_string()) - && Identifier::is_valid(&struct_tag.name.to_string()) + Identifier::is_valid(struct_tag.module.to_string()) + && Identifier::is_valid(struct_tag.name.to_string()) && struct_tag.type_args.iter().all(is_valid_type_tag) }, TypeTag::Vector(inner_type_tag) => is_valid_type_tag(inner_type_tag), diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/authenticator.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/authenticator.rs index 1dc04685b92..04d24d252f7 100644 --- a/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/authenticator.rs +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/authenticator.rs @@ -3,9 +3,9 @@ #![allow(dead_code)] -use super::helpers::UserAccount; use aptos_types::keyless::{AnyKeylessPublicKey, EphemeralCertificate}; use arbitrary::Arbitrary; +use fuzzer::UserAccount; use serde::{Deserialize, Serialize}; use serde_json; diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/helpers.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/helpers.rs index bb0a4b5f31f..27d5443ecab 100644 --- a/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/helpers.rs +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/helpers.rs @@ -3,8 +3,6 @@ #![allow(dead_code)] -use aptos_language_e2e_tests::{account::Account, executor::FakeExecutor}; -use arbitrary::Arbitrary; use move_binary_format::file_format::CompiledModule; use move_core_types::value::{MoveStructLayout, MoveTypeLayout}; @@ -33,37 +31,6 @@ macro_rules! tdbg { }; } -#[derive(Debug, Arbitrary, Eq, PartialEq, Clone, Copy)] -pub enum FundAmount { - Zero, - Poor, - Rich, -} - -#[derive(Debug, Arbitrary, Eq, PartialEq, Clone, Copy)] -pub struct UserAccount { - is_inited_and_funded: bool, - fund: FundAmount, -} - -impl UserAccount { - pub fn fund_amount(&self) -> u64 { - match self.fund { - FundAmount::Zero => 0, - FundAmount::Poor => 1_000, - FundAmount::Rich => 1_000_000_000_000_000, - } - } - - pub fn convert_account(&self, vm: &mut FakeExecutor) -> Account { - if self.is_inited_and_funded { - vm.create_accounts(1, self.fund_amount(), 0).remove(0) - } else { - Account::new() - } - } -} - pub(crate) fn is_valid_layout(layout: &MoveTypeLayout) -> bool { use MoveTypeLayout as L; diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/vm.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/vm.rs index 1e3fc543138..b0655c88d17 100644 --- a/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/vm.rs +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/utils/vm.rs @@ -3,7 +3,6 @@ #![allow(dead_code)] -use super::helpers::UserAccount; use crate::tdbg; use aptos_cached_packages::aptos_stdlib::code_publish_package_txn; use aptos_framework::natives::code::{ @@ -12,18 +11,17 @@ use aptos_framework::natives::code::{ use aptos_language_e2e_tests::{account::Account, executor::FakeExecutor}; use aptos_types::transaction::{ExecutionStatus, TransactionPayload, TransactionStatus}; use arbitrary::Arbitrary; +use fuzzer::UserAccount; use libfuzzer_sys::Corpus; -use move_binary_format::{ - access::ModuleAccess, - file_format::{CompiledModule, CompiledScript, FunctionDefinitionIndex}, -}; +use move_binary_format::{access::ModuleAccess, file_format::CompiledModule}; use move_core_types::{ - language_storage::{ModuleId, TypeTag}, - value::MoveValue, + language_storage::ModuleId, vm_status::{StatusCode, StatusType, VMStatus}, }; use std::collections::{BTreeMap, BTreeSet, HashSet}; +pub const BYTECODE_VERSION: u32 = 8; + // Used to fuzz the MoveVM #[derive(Debug, Arbitrary, Eq, PartialEq, Clone)] pub enum FuzzerRunnableAuthenticator { @@ -58,28 +56,6 @@ impl FuzzerRunnableAuthenticator { } } -#[derive(Debug, Arbitrary, Eq, PartialEq, Clone)] -pub enum ExecVariant { - Script { - script: CompiledScript, - type_args: Vec, - args: Vec, - }, - CallFunction { - module: ModuleId, - function: FunctionDefinitionIndex, - type_args: Vec, - args: Vec>, - }, -} - -#[derive(Debug, Arbitrary, Eq, PartialEq, Clone)] -pub struct RunnableState { - pub dep_modules: Vec, - pub exec_variant: ExecVariant, - pub tx_auth_type: FuzzerRunnableAuthenticator, -} - // used for ordering modules topologically pub(crate) fn sort_by_deps( map: &BTreeMap, @@ -145,7 +121,7 @@ fn publish_transaction_payload(modules: &[CompiledModule]) -> TransactionPayload for module in modules { let mut module_code: Vec = vec![]; module - .serialize(&mut module_code) + .serialize_for_version(Some(BYTECODE_VERSION), &mut module_code) .expect("Module must serialize"); pkg_code.push(module_code); } diff --git a/testsuite/fuzzer/src/lib.rs b/testsuite/fuzzer/src/lib.rs new file mode 100644 index 00000000000..64b479b1829 --- /dev/null +++ b/testsuite/fuzzer/src/lib.rs @@ -0,0 +1,9 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +pub mod types; +pub mod utils; + +pub use types::{ + Authenticator, ExecVariant, FundAmount, RunnableState, RunnableStateWithOperations, UserAccount, +}; diff --git a/testsuite/fuzzer/src/main.rs b/testsuite/fuzzer/src/main.rs index d6400724b91..f7c119dc0d4 100644 --- a/testsuite/fuzzer/src/main.rs +++ b/testsuite/fuzzer/src/main.rs @@ -1,7 +1,6 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -mod utils; use clap::{Arg, Command}; fn main() { @@ -67,6 +66,16 @@ fn main() { .index(2), ) ) + .subcommand( + Command::new("generate_runnable_states_from_all_tests") + .about("Generates runnable states from all test sources (e2e, transactional, and compiler v2 tests).") + .arg( + Arg::new("destination_path") + .help("Path to write the runnable states to") + .required(true) + .index(1), + ) + ) .get_matches(); match matches.subcommand() { @@ -74,7 +83,7 @@ fn main() { let module_path = sub_m.get_one::("module_path").unwrap(); // Call the function with the provided arguments - if let Err(e) = utils::cli::compile_federated_jwk(module_path) { + if let Err(e) = fuzzer::utils::cli::compile_federated_jwk(module_path) { eprintln!("Error compiling module: {}", e); std::process::exit(1); } else { @@ -86,7 +95,8 @@ fn main() { let destination_path = sub_m.get_one::("destination_path").unwrap(); // Call the function with the provided arguments - if let Err(e) = utils::cli::generate_runnable_state(csv_path, destination_path) { + if let Err(e) = fuzzer::utils::cli::generate_runnable_state(csv_path, destination_path) + { eprintln!("Error generating runnable state: {}", e); std::process::exit(1); } else { @@ -98,9 +108,10 @@ fn main() { let destination_path = sub_m.get_one::("destination_path").unwrap(); // Call the function with the provided arguments - if let Err(e) = - utils::cli::generate_runnable_state_from_project(project_path, destination_path) - { + if let Err(e) = fuzzer::utils::cli::generate_runnable_state_from_project( + project_path, + destination_path, + ) { eprintln!("Error generating runnable state: {}", e); std::process::exit(1); } else { @@ -113,7 +124,7 @@ fn main() { // Call the function with the provided arguments if let Err(e) = - utils::cli::generate_runnable_states_recursive(base_dir, destination_path) + fuzzer::utils::cli::generate_runnable_states_recursive(base_dir, destination_path) { eprintln!("Error generating runnable states recursively: {}", e); std::process::exit(1); @@ -121,6 +132,19 @@ fn main() { println!("Runnable states generated successfully."); } }, + Some(("generate_runnable_states_from_all_tests", sub_m)) => { + let destination_path = sub_m.get_one::("destination_path").unwrap(); + + // Call the function with the provided arguments + if let Err(e) = + fuzzer::utils::cli::generate_runnable_states_from_all_tests(destination_path) + { + eprintln!("Error: {}", e); + std::process::exit(1); + } else { + println!("Runnable states generated successfully from all test sources."); + } + }, // Handle other subcommands or default behavior _ => { println!("No valid subcommand was used. Use --help for more information."); diff --git a/testsuite/fuzzer/src/types.rs b/testsuite/fuzzer/src/types.rs new file mode 100644 index 00000000000..45e860e542d --- /dev/null +++ b/testsuite/fuzzer/src/types.rs @@ -0,0 +1,105 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_language_e2e_tests::{account::Account, executor::FakeExecutor}; +use arbitrary::Arbitrary; +use dearbitrary::Dearbitrary; +use move_binary_format::file_format::{CompiledModule, CompiledScript, FunctionDefinitionIndex}; +use move_core_types::{ + language_storage::{ModuleId, TypeTag}, + value::MoveValue, +}; +use move_transactional_test_runner::transactional_ops::TransactionalOperation; + +// Originally from testsuite/fuzzer/fuzz/fuzz_targets/move/utils/helpers.rs +// (with Dearbitrary added and fields made public) +#[derive(Debug, Arbitrary, Dearbitrary, Eq, PartialEq, Clone, Copy)] +pub enum FundAmount { + Zero, + Poor, + Rich, +} + +// Originally from testsuite/fuzzer/fuzz/fuzz_targets/move/utils/helpers.rs +// (with Dearbitrary added and fields made public) +#[derive(Debug, Arbitrary, Dearbitrary, Eq, PartialEq, Clone, Copy)] +pub struct UserAccount { + pub is_inited_and_funded: bool, + pub fund: FundAmount, +} + +impl UserAccount { + pub fn fund_amount(&self) -> u64 { + match self.fund { + FundAmount::Zero => 0, + FundAmount::Poor => 1_000, + FundAmount::Rich => 1_000_000_000_000_000, + } + } + + pub fn convert_account(&self, vm: &mut FakeExecutor) -> Account { + if self.is_inited_and_funded { + vm.create_accounts(1, self.fund_amount(), 0).remove(0) + } else { + Account::new() + } + } +} + +// Originally from testsuite/fuzzer/src/utils.rs +#[derive(Debug, Eq, PartialEq, Clone, Arbitrary, Dearbitrary)] +pub enum ExecVariant { + Script { + _script: CompiledScript, + _type_args: Vec, + _args: Vec, + }, + CallFunction { + _module: ModuleId, + _function: FunctionDefinitionIndex, + _type_args: Vec, + _args: Vec>, + }, +} + +// Originally from testsuite/fuzzer/src/utils.rs +#[derive(Debug, Arbitrary, Dearbitrary, Eq, PartialEq, Clone)] +pub enum Authenticator { + Ed25519 { + _sender: UserAccount, + }, + MultiAgent { + _sender: UserAccount, + _secondary_signers: Vec, + }, + FeePayer { + _sender: UserAccount, + _secondary_signers: Vec, + _fee_payer: UserAccount, + }, +} + +impl Authenticator { + pub fn sender(&self) -> UserAccount { + match self { + Authenticator::Ed25519 { _sender } => *_sender, + Authenticator::MultiAgent { _sender, .. } => *_sender, + Authenticator::FeePayer { _sender, .. } => *_sender, + } + } +} + +// Originally from testsuite/fuzzer/src/utils.rs +#[derive(Debug, Eq, PartialEq, Clone, Arbitrary, Dearbitrary)] +pub struct RunnableState { + pub dep_modules: Vec, + pub exec_variant: ExecVariant, + pub tx_auth_type: Authenticator, +} + +// Originally from testsuite/fuzzer/src/utils.rs +#[derive(Debug, Eq, PartialEq, Clone, Arbitrary, Dearbitrary)] +pub struct RunnableStateWithOperations { + pub operations: Vec, + pub tx_auth_type: Authenticator, +} diff --git a/testsuite/fuzzer/src/utils.rs b/testsuite/fuzzer/src/utils.rs index c9f4b2a1353..e1001977a30 100644 --- a/testsuite/fuzzer/src/utils.rs +++ b/testsuite/fuzzer/src/utils.rs @@ -3,12 +3,18 @@ #[allow(dead_code)] #[allow(unused_variables)] -pub(crate) mod cli { +pub mod cli { + // Import from crate root (lib.rs) + use crate::{ + Authenticator, ExecVariant, FundAmount, RunnableState, RunnableStateWithOperations, + UserAccount, + }; use aptos_framework::{BuildOptions, BuiltPackage}; use aptos_types::{ account_address::AccountAddress, transaction::{EntryFunction, Script, TransactionPayload}, }; + // Import traits for their methods use arbitrary::Arbitrary; use base64::{engine::general_purpose::STANDARD, Engine as _}; use dearbitrary::Dearbitrary; @@ -16,22 +22,49 @@ pub(crate) mod cli { access::ModuleAccess, file_format::{CompiledModule, CompiledScript, FunctionDefinitionIndex, SignatureToken}, }; - use move_core_types::{ - ident_str, - identifier::Identifier, - language_storage::{ModuleId, TypeTag}, - value::MoveValue, + use move_core_types::{ident_str, identifier::Identifier, language_storage::ModuleId}; + use move_model::metadata::{CompilerVersion, LanguageVersion}; + // Import official transactional test runner functions + use move_transactional_test_runner::{ + tasks::{taskify, EmptyCommand, TaskCommand, TaskInput}, + vm_test_harness::{ + precompiled_v2_stdlib_fuzzer, AdapterExecuteArgs, AdapterPublishArgs, + PrecompiledFilesModules, + }, }; use rayon::prelude::*; use sha2::{Digest, Sha256}; - use std::{collections::HashMap, fs::File, io::Write, path::PathBuf}; + use std::{ + collections::{HashMap, VecDeque}, + fs::File, + io::Write, + path::PathBuf, + }; use walkdir::WalkDir; + macro_rules! debug_println_error { + ($($arg:tt)*) => { + if std::env::var("DEBUG").unwrap_or_default() == "1" { + println!($($arg)*); + } + }; + } + + /// Standard build options for consistent compilation across the fuzzer + pub(crate) fn standard_build_options() -> BuildOptions { + BuildOptions { + language_version: Some(LanguageVersion::default()), // This is V2_1 (latest stable) + compiler_version: Some(CompilerVersion::latest_stable()), // This is V2_0 + bytecode_version: Some(8), // Use VERSION_MAX to match official transactional test runner + ..BuildOptions::default() + } + } + /// Compiles a Move module from source code. /// The compiled module and its metadata are returned serialized. /// Those can be used to publish the module on-chain via code_publish_package_txn(). - pub(crate) fn compile_federated_jwk(module_path: &str) -> Result<(), String> { - let package = BuiltPackage::build(PathBuf::from(module_path), BuildOptions::default()) + pub fn compile_federated_jwk(module_path: &str) -> Result<(), String> { + let package = BuiltPackage::build(PathBuf::from(module_path), standard_build_options()) .map_err(|e| e.to_string())?; let transaction_payload = generate_script_payload_jwk(&package); @@ -107,63 +140,93 @@ pub(crate) mod cli { )) } - /// Data types for generate VM fuzzer corpora - #[derive(Debug, Eq, PartialEq, arbitrary::Arbitrary, dearbitrary::Dearbitrary)] - pub enum ExecVariant { - Script { - script: CompiledScript, - type_args: Vec, - args: Vec, - }, - CallFunction { - module: ModuleId, - function: FunctionDefinitionIndex, - type_args: Vec, - args: Vec>, - }, + /// Parse a transactional test file + /// + /// This uses the framework taskify function to parse transactional test files + pub fn parse_transactional_test( + file_path: &std::path::Path, + ) -> Result< + VecDeque< + TaskInput< + TaskCommand, + >, + >, + String, + > { + taskify(file_path) + .map(|vec| vec.into_iter().collect()) + .map_err(|e| e.to_string()) } - #[derive(Debug, Arbitrary, Dearbitrary, Eq, PartialEq, Clone)] - pub enum FundAmount { - Zero, - Poor, - Rich, - } + /// Convert transactional test to runnable state using the framework's compilation logic + pub fn transactional_test_to_runnable_state( + file_path: &std::path::Path, + pre_compiled_deps: &PrecompiledFilesModules, + ) -> Result { + use move_model::metadata::LanguageVersion; + use move_transactional_test_runner::{ + framework::MoveTestAdapter, + tasks::SyntaxChoice, + transactional_ops::{tasks_to_transactional_operations, MinimalAdapter}, + vm_test_harness::TestRunConfig, + }; - #[derive(Debug, Arbitrary, Dearbitrary, Eq, PartialEq, Clone)] - pub struct UserAccount { - pub is_inited_and_funded: bool, - pub fund: FundAmount, - } + // Parse the transactional test file + let mut tasks = parse_transactional_test(file_path)?; + + // Create a minimal test configuration + let run_config = TestRunConfig::compiler_v2(LanguageVersion::latest(), vec![]); + + let first_task = tasks.pop_front().unwrap(); + let init_opt = match &first_task.command { + TaskCommand::Init(_, _) => Some(first_task.map(|known| match known { + TaskCommand::Init(command, extra_args) => (command, extra_args), + _ => unreachable!(), + })), + _ => { + tasks.push_front(first_task); + None + }, + }; - #[derive(Debug, Arbitrary, Dearbitrary, Eq, PartialEq, Clone)] - pub enum Authenticator { - Ed25519 { - sender: UserAccount, - }, - MultiAgent { - sender: UserAccount, - secondary_signers: Vec, - }, - FeePayer { - sender: UserAccount, - secondary_signers: Vec, - fee_payer: UserAccount, - }, - } - #[derive(Debug, Eq, arbitrary::Arbitrary, dearbitrary::Dearbitrary, PartialEq)] - pub struct RunnableState { - pub dep_modules: Vec, - pub exec_variant: ExecVariant, - pub tx_auth_type: Authenticator, + // Create our minimal adapter + let (mut adapter, _init_output) = MinimalAdapter::init( + SyntaxChoice::Source, + run_config, + pre_compiled_deps, + init_opt, + ); + + // Use the framework's helper function to convert tasks to operations + let operations = tasks_to_transactional_operations(&mut adapter, tasks) + .map_err(|e| format!("Failed to convert tasks to operations: {}", e))?; + + if operations.is_empty() { + return Err("No valid operations found in transactional test".to_string()); + } + + // Limit the number of operations to prevent performance issues + const MAX_OPERATIONS: usize = 10; + let operations = if operations.len() > MAX_OPERATIONS { + operations.into_iter().take(MAX_OPERATIONS).collect() + } else { + operations + }; + + Ok(RunnableStateWithOperations { + operations, + tx_auth_type: Authenticator::Ed25519 { + _sender: UserAccount { + is_inited_and_funded: true, + fund: FundAmount::Rich, + }, + }, + }) } /// Convert module to RunnableState data structure /// This is used to run the module in the VM - pub(crate) fn generate_runnable_state( - csv_path: &str, - destination_path: &str, - ) -> Result<(), String> { + pub fn generate_runnable_state(csv_path: &str, destination_path: &str) -> Result<(), String> { std::fs::create_dir_all(destination_path).map_err(|e| e.to_string())?; let runnable_states = to_runnablestate_from_csv(&read_csv(csv_path)); let mut cnt: usize = 0; @@ -176,11 +239,11 @@ pub(crate) mod cli { let runnable_state_generated = RunnableState::arbitrary_take_rest(u).map_err(|e| e.to_string())?; if runnable_state.0 != runnable_state_generated { - println!( + debug_println_error!( "Failed : {:#?}", runnable_state.0.dep_modules[0] ); - println!("Failed : {:#?} \n", runnable_state.1); + debug_println_error!("Failed : {:#?} \n", runnable_state.1); cnt += 1; } let mut hasher = Sha256::new(); @@ -215,25 +278,19 @@ pub(crate) mod cli { record.get(2).unwrap() ), }; - /* - let bytecode: Vec = match hex::decode(decoded_bytecode.clone()) { - Ok(bytecode) => bytecode, - Err(err) => panic!("Error decoding {:?}, Decoded Error: {:?}, bytecode: {:?}", address, err, decoded_bytecode), - }; - */ let serialized = record.get(2).unwrap(); let account_address = match AccountAddress::from_hex_literal(address) { Ok(addr) => addr, Err(err) => { - eprintln!("Invalid address {}: {:?}", address, err); + debug_println_error!("Invalid address {}: {:?}", address, err); continue; }, }; let identifier = match Identifier::new(module_name) { Ok(id) => id, Err(err) => { - eprintln!("Invalid module name {}: {:?}", module_name, err); + debug_println_error!("Invalid module name {}: {:?}", module_name, err); continue; }, }; @@ -241,7 +298,7 @@ pub(crate) mod cli { let compiled_module = match CompiledModule::deserialize(&bytecode) { Ok(module) => module, Err(err) => { - eprintln!("Error deserializing module: {:?}", err); + debug_println_error!("Error deserializing module: {:?}", err); continue; // Skip to the next iteration of the loop }, }; @@ -258,13 +315,13 @@ pub(crate) mod cli { let runnable_state = RunnableState { dep_modules: vec![tuple.0.to_owned()], exec_variant: ExecVariant::CallFunction { - module: module_id.to_owned(), - function: FunctionDefinitionIndex::new(0), - type_args: vec![], - args: vec![], + _module: module_id.to_owned(), + _function: FunctionDefinitionIndex::new(0), + _type_args: vec![], + _args: vec![], }, tx_auth_type: Authenticator::Ed25519 { - sender: UserAccount { + _sender: UserAccount { is_inited_and_funded: true, fund: FundAmount::Rich, }, @@ -284,151 +341,204 @@ pub(crate) mod cli { } } - fn to_runnablestate_from_package(package: &BuiltPackage) -> Result { + fn to_runnablestate_from_script( + script: Vec, + all_modules: &[CompiledModule], + ) -> Result { + let compiled_script = CompiledScript::deserialize(&script) + .map_err(|e| format!("Failed to deserialize script: {}", e))?; + + Ok(RunnableState { + dep_modules: all_modules.to_vec(), // TODO: Check which module in all_modules is actually a dependency + exec_variant: ExecVariant::Script { + _script: compiled_script, + _type_args: vec![], // Default to no type args + _args: vec![], // Default to no args + }, + tx_auth_type: Authenticator::Ed25519 { + _sender: UserAccount { + is_inited_and_funded: true, + fund: FundAmount::Rich, + }, + }, + }) + } + + // TODO: Refactor to build arguments for the function + // TODO2: Check which module in all_modules is actually a dependency + fn to_runnablestate_from_module( + module: CompiledModule, + all_modules: &[CompiledModule], + ) -> Result, String> { + let mut runnable_states = Vec::new(); + + // Find all entry functions in the module + for (func_idx, func_def) in module.function_defs.iter().enumerate() { + if func_def.is_entry { + let module_id = module.self_id(); + let function_handle = &module.function_handles[func_def.function.0 as usize]; + + // Skip generic functions + if !function_handle.type_parameters.is_empty() { + debug_println_error!( + "Skipping generic entry function {}::{}", + module_id, + module.identifier_at(function_handle.name) + ); + continue; + } + + let function_signature = &module.signatures[function_handle.parameters.0 as usize]; + + // Skip functions with non-signer parameters after signer parameters + if !function_signature.0.is_empty() + && !is_signer_or_reference(&function_signature.0[0]) + { + debug_println_error!( + "Skipping function {}::{} with non-signer parameters after signer", + module_id, + module.identifier_at(function_handle.name) + ); + continue; + } + + let runnable_state = RunnableState { + dep_modules: all_modules.to_vec(), + exec_variant: ExecVariant::CallFunction { + _module: module_id, + _function: FunctionDefinitionIndex::new(func_idx as u16), + _type_args: vec![], + _args: vec![], + }, + tx_auth_type: Authenticator::Ed25519 { + _sender: UserAccount { + is_inited_and_funded: true, + fund: FundAmount::Rich, + }, + }, + }; + + runnable_states.push(runnable_state); + } + } + + Ok(runnable_states) + } + + fn to_runnablestate_from_package(package: &BuiltPackage) -> Result, String> { + let mut runnable_states = Vec::new(); let modules = package.extract_code(); + let scripts = package.extract_script_code(); - // Create a vector to hold all compiled modules + // Process all modules let mut compiled_modules = Vec::new(); - for module_bytes in modules { if let Ok(module) = CompiledModule::deserialize(&module_bytes) { compiled_modules.push(module); } } - if compiled_modules.is_empty() { - return Err("No valid modules found in package".to_string()); - } - - // Find the first module with an entry function - let mut primary_module = None; - let mut function_def_idx = None; - + // Process each module for module in &compiled_modules { - for (idx, func_def) in module.function_defs.iter().enumerate() { - if func_def.is_entry { - primary_module = Some(module); - function_def_idx = Some(idx); - break; - } - } - if primary_module.is_some() { - break; + match to_runnablestate_from_module(module.clone(), &compiled_modules) { + Ok(states) => runnable_states.extend(states), + Err(e) => { + debug_println_error!("Failed to process module {}: {}", module.self_id(), e) + }, } } - // If no entry function found, use the first function of the first module - let (primary_module, function_def_idx) = if let (Some(module), Some(idx)) = - (primary_module, function_def_idx) - { - (module, idx) - } else if !compiled_modules.is_empty() && !compiled_modules[0].function_defs.is_empty() { - (&compiled_modules[0], 0) - } else { - return Err("No functions found in any module".to_string()); - }; - - let module_id = primary_module.self_id(); - let function_def = &primary_module.function_defs[function_def_idx]; - let function_handle = &primary_module.function_handles[function_def.function.0 as usize]; - - // Check if the function has type parameters (is generic) - let has_type_params = !function_handle.type_parameters.is_empty(); - - // Return error if the function is generic - if has_type_params { - return Err(format!( - "Entry function {}::{} has {} type parameters. Generic entry functions are not supported.", - module_id, - primary_module.identifier_at(function_handle.name), - function_handle.type_parameters.len() - )); + // Process all scripts + for script in scripts { + match to_runnablestate_from_script(script, &compiled_modules) { + Ok(state) => runnable_states.push(state), + Err(e) => debug_println_error!("Failed to process script: {}", e), + } } - let type_args = vec![]; - - let function_signature = &primary_module.signatures[function_handle.parameters.0 as usize]; - - // Check if there are any non-signer parameters after the signer parameters - let has_non_signer_params = if !function_signature.0.is_empty() { - !is_signer_or_reference(&function_signature.0[0]) - } else { - false - }; - - let args = if has_non_signer_params { - return Err( - "Entry function has non-signer parameters after signer parameters".to_string(), - ); - } else { - vec![] - }; - - println!( - "Using module: {}, function idx: {}", - module_id, function_def_idx - ); - - // Create a single runnable state with all modules as dependencies - let runnable_state = RunnableState { - dep_modules: compiled_modules, - exec_variant: ExecVariant::CallFunction { - module: module_id, - function: FunctionDefinitionIndex::new(function_def_idx as u16), - type_args, - args, - }, - tx_auth_type: Authenticator::Ed25519 { - sender: UserAccount { - is_inited_and_funded: true, - fund: FundAmount::Rich, - }, - }, - }; + if runnable_states.is_empty() { + return Err("No valid runnable states found in package".to_string()); + } - Ok(runnable_state) + Ok(runnable_states) } fn compile_source_code_from_project(project_path: &str) -> Result { - let package = BuiltPackage::build(PathBuf::from(project_path), BuildOptions::default()) - .map_err(|e| e.to_string())?; - - Ok(package) + // Wrap the build in catch_unwind to handle panics + match std::panic::catch_unwind(|| { + BuiltPackage::build( + PathBuf::from(project_path), + BuildOptions::move_2().set_latest_language(), + ) + }) { + Ok(result) => result.map_err(|e| e.to_string()), + Err(e) => { + let error_msg = if let Some(s) = e.downcast_ref::() { + s.clone() + } else if let Some(s) = e.downcast_ref::<&str>() { + s.to_string() + } else { + "Unknown panic during build".to_string() + }; + Err(format!("Build panicked: {}", error_msg)) + }, + } } - //Generate Runnable State from Project folder - //It can be used to create custom Move packages to extend coverage as needed - //Inside data folder, at the left level of the project, you can find some examples - pub(crate) fn generate_runnable_state_from_project( + /// Given a path to a project directory and a destination path, + /// this function compiles the project, converts it into RunnableState(s), + /// and writes these states to individual files in the destination directory. + pub fn generate_runnable_state_from_project( project_path: &str, destination_path: &str, ) -> Result<(), String> { std::fs::create_dir_all(destination_path).map_err(|e| e.to_string())?; let package = compile_source_code_from_project(project_path)?; - let runnable_state = to_runnablestate_from_package(&package)?; - - println!("Generated runnable state from package"); + let runnable_states = to_runnablestate_from_package(&package)?; - // Serialize the runnable state - let bytes = runnable_state.dearbitrary_first().finish(); + for (idx, runnable_state) in runnable_states.into_iter().enumerate() { + // Serialize the runnable state + let bytes = runnable_state.dearbitrary_first().finish(); + let mut hasher = Sha256::new(); + hasher.update(&bytes); + let hash = hasher.finalize(); - // Generate a filename based on hash - let mut hasher = Sha256::new(); - hasher.update(&bytes); - let hash = hasher.finalize(); - let filename = format!("{}/{}.bytes", destination_path, hex::encode(hash)); + // Generate filename based on the type of runnable state + let filename = match &runnable_state.exec_variant { + ExecVariant::Script { .. } => { + format!("{}/script_{}.bytes", destination_path, hex::encode(hash)) + }, + ExecVariant::CallFunction { + _module: module, .. + } => { + let mut hasher = Sha256::new(); + hasher.update(&bytes); + format!( + "{}/module_{}_{}.bytes", + destination_path, + module, + hex::encode(hasher.finalize()) + ) + }, + }; - // Write to file - let mut file = File::create(&filename).map_err(|e| e.to_string())?; - file.write_all(&bytes).map_err(|e| e.to_string())?; - println!("Runnable state saved to {}", filename); + // Write to file + if let Err(e) = File::create(&filename).and_then(|mut f| f.write_all(&bytes)) { + debug_println_error!("Failed to write runnable state {}: {}", idx, e); + } else { + println!("Runnable state saved to {}", filename); + } + } Ok(()) } - //Generate Runnable States recursively from all Move.toml projects under base directory - pub(crate) fn generate_runnable_states_recursive( + /// Recursively finds all Move.toml files within a given base directory, + /// compiles each corresponding project, converts them into RunnableState(s), + /// and writes these states to individual files in a specified destination directory. + /// Skips any projects that fail to compile or convert. + pub fn generate_runnable_states_recursive( base_dir: &str, destination_path: &str, ) -> Result<(), String> { @@ -452,45 +562,161 @@ pub(crate) mod cli { match compile_source_code_from_project(project_dir) { Ok(package) => { match to_runnablestate_from_package(&package) { + Ok(runnable_states) => { + println!("Generated runnable states from package at {}", project_dir); + + // Serialize the runnable states + for (idx, runnable_state) in runnable_states.into_iter().enumerate() { + let bytes = runnable_state.dearbitrary_first().finish(); + + // Generate filename based on the type of runnable state + let filename = match &runnable_state.exec_variant { + ExecVariant::Script { .. } => { + format!("{}/script_{}.bytes", destination_path, idx) + }, + ExecVariant::CallFunction { + _module: module, .. + } => { + let mut hasher = Sha256::new(); + hasher.update(&bytes); + format!( + "{}/module_{}_{}.bytes", + destination_path, + module, + hex::encode(hasher.finalize()) + ) + }, + }; + + // Write to file + if let Err(e) = + File::create(&filename).and_then(|mut f| f.write_all(&bytes)) + { + debug_println_error!( + "Failed to write runnable state {}: {}", + idx, + e + ); + } else { + println!("Runnable state saved to {}", filename); + } + } + }, + Err(e) => { + debug_println_error!( + "Failed to generate runnable states for {}: {}", + project_dir, + e + ); + }, + } + }, + Err(e) => { + debug_println_error!("Failed to compile project at {}: {}", project_dir, e); + }, + } + }); + + Ok(()) + } + + /// Generates runnable states from all known test sources, including + /// e2e tests, transactional tests, and compiler v2 tests. + /// The generated states are written to individual files in the specified destination directory. + /// This function leverages precompiled standard library modules for efficiency. + pub fn generate_runnable_states_from_all_tests(destination_path: &str) -> Result<(), String> { + std::fs::create_dir_all(destination_path).map_err(|e| e.to_string())?; + + // Build once the framework + let pre_compiled_deps = precompiled_v2_stdlib_fuzzer(); + + // Process transactional tests from move-compiler-v2 + let transactional_test_dirs = vec![ + "", + "../../third_party/move/move-compiler-v2/transactional-tests/tests", + ]; + + for test_dir in transactional_test_dirs { + if std::path::Path::new(test_dir).exists() { + println!("Processing transactional tests from: {}", test_dir); + + for entry in WalkDir::new(test_dir) + .follow_links(false) + .into_iter() + .filter_map(|e| e.ok()) + .filter(|entry| entry.path().extension().is_some_and(|ext| ext == "move")) + { + match transactional_test_to_runnable_state(entry.path(), pre_compiled_deps) { Ok(runnable_state) => { - println!("Generated runnable state from package at {}", project_dir); + if runnable_state.operations.is_empty() { + debug_println_error!("Skipping empty transactional test (no operations produced): {}", entry.path().display()); + continue; + } - // Serialize the runnable state let bytes = runnable_state.dearbitrary_first().finish(); - - // Generate a filename based on hash let mut hasher = Sha256::new(); hasher.update(&bytes); let hash = hasher.finalize(); - let filename = - format!("{}/{}.bytes", destination_path, hex::encode(hash)); - // Write to file + let filename = format!( + "{}/transactional_test_{}.bytes", + destination_path, + hex::encode(hash) + ); + if let Err(e) = File::create(&filename).and_then(|mut f| f.write_all(&bytes)) { - println!( - "Failed to write runnable state for {}: {}", - project_dir, e + debug_println_error!( + "Failed to write transactional test {}: {}", + entry.path().display(), + e ); } else { - println!("Runnable state saved to {}", filename); + println!("Transactional test saved to {}", filename); } }, Err(e) => { - println!( - "Failed to generate runnable state for {}: {}", - project_dir, e - ); + // More detailed error logging + if e.contains("No valid operations found") + || e.contains("Skipping unsupported task command") + || e.contains("must be the first command") + { + // These might be benign (e.g. test file with only //# init or specific ordering issues) + debug_println_error!( + "Skipping transactional test {}: {}", + entry.path().display(), + e + ); + } else { + // eprintln is better for user-facing errors if this becomes a CLI tool part + // For fuzzer internal logic, debug_println_error or a dedicated logger is fine. + debug_println_error!( + "Error processing transactional test {}: {}", + entry.path().display(), + e + ); + } }, } - }, - Err(e) => { - println!("Failed to compile project at {}: {}", project_dir, e); - }, + } } - }); + } + // Process Move projects recursively from common test directories + let move_test_dirs = vec![ + //"../../aptos-move/move-examples", + //"../../aptos-move/e2e-move-tests", + ]; + + for test_dir in move_test_dirs { + if std::path::Path::new(test_dir).exists() { + println!("Processing Move projects from: {}", test_dir); + if let Err(e) = generate_runnable_states_recursive(test_dir, destination_path) { + debug_println_error!("Failed to process {}: {}", test_dir, e); + } + } + } Ok(()) } } diff --git a/third_party/move/testing-infra/transactional-test-runner/Cargo.toml b/third_party/move/testing-infra/transactional-test-runner/Cargo.toml index 3f6ec59bd38..cb2c215d897 100644 --- a/third_party/move/testing-infra/transactional-test-runner/Cargo.toml +++ b/third_party/move/testing-infra/transactional-test-runner/Cargo.toml @@ -11,6 +11,7 @@ edition = "2021" [dependencies] anyhow = { workspace = true } +aptos-framework = { workspace = true, optional = true } clap = { workspace = true, features = ["derive"] } either = { workspace = true } legacy-move-compiler = { workspace = true } @@ -36,6 +37,11 @@ regex = { workspace = true } tempfile = { workspace = true } termcolor = { workspace = true } +# Optional dependencies for fuzzing +arbitrary = { workspace = true, optional = true } +bcs = { workspace = true, optional = true } +dearbitrary = { workspace = true, optional = true } + [dev-dependencies] datatest-stable = { workspace = true } difference = { workspace = true } @@ -46,3 +52,4 @@ harness = false [features] failpoints = ['move-vm-runtime/failpoints'] +fuzzing = ["arbitrary", "dearbitrary", "aptos-framework", "bcs"] diff --git a/third_party/move/testing-infra/transactional-test-runner/src/lib.rs b/third_party/move/testing-infra/transactional-test-runner/src/lib.rs index 8be1f95d5f5..301523e80c6 100644 --- a/third_party/move/testing-infra/transactional-test-runner/src/lib.rs +++ b/third_party/move/testing-infra/transactional-test-runner/src/lib.rs @@ -6,4 +6,6 @@ pub mod framework; pub mod tasks; +#[cfg(feature = "fuzzing")] +pub mod transactional_ops; pub mod vm_test_harness; diff --git a/third_party/move/testing-infra/transactional-test-runner/src/transactional_ops.rs b/third_party/move/testing-infra/transactional-test-runner/src/transactional_ops.rs new file mode 100644 index 00000000000..a582a546c4a --- /dev/null +++ b/third_party/move/testing-infra/transactional-test-runner/src/transactional_ops.rs @@ -0,0 +1,592 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! Transactional operations for building and executing transactional tests. +//! This module provides helper functions and data types for converting +//! transactional test files into executable operations. +use crate::{ + framework::{CompiledState, MoveTestAdapter}, + tasks::{ + EmptyCommand, InitCommand, PublishCommand, RunCommand, SyntaxChoice, TaskCommand, TaskInput, + }, + vm_test_harness::{ + AdapterExecuteArgs, AdapterPublishArgs, PrecompiledFilesModules, TestRunConfig, + }, +}; +use anyhow::Result; +use move_binary_format::{ + access::ModuleAccess, + file_format::{ + CompiledModule, CompiledScript, FunctionDefinition, FunctionDefinitionIndex, + FunctionHandle, SignatureToken, Visibility, + }, +}; +use move_command_line_common::{ + files::verify_and_create_named_address_mapping, values::ParsableValue, +}; +use move_core_types::{ + account_address::AccountAddress, + identifier::{IdentStr, Identifier}, + language_storage::{ModuleId, TypeTag}, + value::{MoveTypeLayout, MoveValue}, +}; +use move_vm_runtime::move_vm::SerializedReturnValues; +use move_vm_types::values::Value; +use std::{ + collections::{BTreeMap, BTreeSet, VecDeque}, + io::Write, +}; + +/// Minimal adapter implementation for transactional test processing +/// This adapter provides the minimum functionality needed to compile and process +/// transactional test files without executing them. +pub struct MinimalAdapter<'a> { + compiled_state: CompiledState<'a>, + default_syntax: SyntaxChoice, + run_config: TestRunConfig, +} + +impl<'a> MoveTestAdapter<'a> for MinimalAdapter<'a> { + type ExtraInitArgs = EmptyCommand; + type ExtraPublishArgs = AdapterPublishArgs; + type ExtraRunArgs = AdapterExecuteArgs; + type ExtraValueArgs = (); + type Subcommand = EmptyCommand; + + fn compiled_state(&mut self) -> &mut CompiledState<'a> { + &mut self.compiled_state + } + + fn default_syntax(&self) -> SyntaxChoice { + self.default_syntax + } + + fn known_attributes(&self) -> &BTreeSet { + static EMPTY_SET: std::sync::LazyLock> = + std::sync::LazyLock::new(BTreeSet::new); + &EMPTY_SET + } + + fn init( + default_syntax: SyntaxChoice, + run_config: TestRunConfig, + pre_compiled_deps_v2: &'a PrecompiledFilesModules, + init_data: Option>, + ) -> (Self, Option) { + // Named address mapping + let additional_named_address_mapping = match init_data.as_ref().map(|t| &t.command) { + Some((InitCommand { named_addresses }, _)) => { + verify_and_create_named_address_mapping(named_addresses.clone()).unwrap() + }, + None => BTreeMap::new(), + }; + + let mut named_address_mapping = aptos_framework::named_addresses().clone(); + + for (name, addr) in additional_named_address_mapping.clone() { + if named_address_mapping.contains_key(&name) { + panic!("Invalid init. The named address '{}' already exists.", name) + } + named_address_mapping.insert(name, addr); + } + + let compiled_state = CompiledState::new(named_address_mapping, pre_compiled_deps_v2, None); + ( + MinimalAdapter { + compiled_state, + default_syntax, + run_config, + }, + None, + ) + } + + // All of these are required minimal functions to be implemented + fn publish_module( + &mut self, + _module: CompiledModule, + _named_addr_opt: Option, + _gas_budget: Option, + _extra: Self::ExtraPublishArgs, + ) -> Result<(Option, CompiledModule)> { + unimplemented!("MinimalAdapter is only used for compilation, not execution") + } + + fn execute_script( + &mut self, + _script: CompiledScript, + _type_args: Vec, + _signers: Vec, + _args: Vec, + _gas_budget: Option, + _extra: Self::ExtraRunArgs, + ) -> Result> { + unimplemented!("MinimalAdapter is only used for compilation, not execution") + } + + fn call_function( + &mut self, + _module: &ModuleId, + _function: &IdentStr, + _type_args: Vec, + _signers: Vec, + _args: Vec, + _gas_budget: Option, + _extra: Self::ExtraRunArgs, + ) -> Result<(Option, SerializedReturnValues)> { + unimplemented!("MinimalAdapter is only used for compilation, not execution") + } + + fn view_data( + &mut self, + _address: AccountAddress, + _module: &ModuleId, + _resource: &IdentStr, + _type_args: Vec, + ) -> Result { + unimplemented!("MinimalAdapter is only used for compilation, not execution") + } + + fn handle_subcommand( + &mut self, + _subcommand: TaskInput, + ) -> Result> { + unimplemented!("MinimalAdapter is only used for compilation, not execution") + } + + fn deserialize(&self, _bytes: &[u8], _layout: &MoveTypeLayout) -> Option { + unimplemented!("MinimalAdapter is only used for compilation, not execution") + } + + // We need this to set the compiler version to the latest version + fn run_config(&self) -> TestRunConfig { + self.run_config.clone() + } +} + +/// Represents a single operation in a transactional test sequence +#[derive(Debug, Eq, PartialEq, Clone, arbitrary::Arbitrary, dearbitrary::Dearbitrary)] +pub enum TransactionalOperation { + /// Publish one or more modules + PublishModule { _module: CompiledModule }, + /// Run a script + RunScript { + _script: CompiledScript, + _type_args: Vec, + _args: Vec, + }, + /// Call a function in a published module + CallFunction { + _module: ModuleId, + _function: FunctionDefinitionIndex, + _type_args: Vec, + _args: Vec>, + }, +} + +/// Helper function to convert a sequence of TaskInputs into TransactionalOperations +/// using the framework's internal compilation functions +pub fn tasks_to_transactional_operations<'a, Adapter>( + adapter: &mut Adapter, + tasks: VecDeque< + TaskInput< + TaskCommand< + Adapter::ExtraInitArgs, + Adapter::ExtraPublishArgs, + Adapter::ExtraValueArgs, + Adapter::ExtraRunArgs, + Adapter::Subcommand, + >, + >, + >, +) -> Result> +where + Adapter: MoveTestAdapter<'a>, + Adapter::ExtraValueArgs: ParsableValue, + ::ConcreteValue: Into + Clone, +{ + let mut operations = Vec::new(); + let mut published_modules = Vec::new(); + + for task in tasks { + match task.command { + TaskCommand::Publish( + PublishCommand { + gas_budget: _, + syntax, + print_bytecode: _, + }, + _extra_args, + ) => { + let syntax = syntax.unwrap_or_else(|| adapter.default_syntax()); + let (data, named_addr_opt, module, _warnings_opt) = adapter.compile_module( + syntax, + task.data, + task.start_line, + task.command_lines_stop, + )?; + + // Track the module for function resolution + published_modules.push(module.clone()); + let data_path = data.path().to_str().unwrap(); + adapter.compiled_state().add_with_source_file( + named_addr_opt, + module.clone(), + (data_path.to_owned(), data), + ); + + operations.push(TransactionalOperation::PublishModule { _module: module }); + }, + TaskCommand::Run( + RunCommand { + signers: _, + args, + type_args, + gas_budget: _, + syntax, + name: None, // Because script call main function + print_bytecode: _, + }, + _extra_args, + ) => { + // Script execution + let syntax = syntax.unwrap_or_else(|| adapter.default_syntax()); + let (script, _warning_opt) = adapter.compile_script( + syntax, + task.data, + task.start_line, + task.command_lines_stop, + )?; + + let resolved_args = adapter.compiled_state().resolve_args(args)?; + let resolved_type_args = adapter.compiled_state().resolve_type_args(type_args)?; + + // Convert resolved args to MoveValue - they are already ConcreteValue + let move_args: Vec = + resolved_args.into_iter().map(|arg| arg.into()).collect(); + + operations.push(TransactionalOperation::RunScript { + _script: script, + _type_args: resolved_type_args, + _args: move_args, + }); + }, + TaskCommand::Run( + RunCommand { + signers: _, + args, + type_args, + gas_budget: _, + syntax: _, + name: Some((raw_addr, module_name, function_name)), + print_bytecode: _, + }, + _extra_args, + ) => { + // Function call + let addr = adapter.compiled_state().resolve_address(&raw_addr); + let module_id = ModuleId::new(addr, module_name.clone()); + let resolved_type_args = adapter.compiled_state().resolve_type_args(type_args)?; + let resolved_args_concrete_values = adapter.compiled_state().resolve_args(args)?; + + let target_compiled_module = published_modules + .iter() + .find(|m| m.self_id() == module_id) + .ok_or_else(|| { + anyhow::anyhow!("Module {} not found for function call", module_id) + })?; + + let (target_func_def, target_func_handle, func_idx) = target_compiled_module + .function_defs + .iter() + .enumerate() + .find_map(|(idx, f_def)| { + let f_handle = + &target_compiled_module.function_handles[f_def.function.0 as usize]; + if target_compiled_module.identifier_at(f_handle.name).as_str() + == function_name.as_str() + { + Some((f_def, f_handle, FunctionDefinitionIndex::new(idx as u16))) + } else { + None + } + }) + .ok_or_else(|| { + anyhow::anyhow!( + "Function {} not found in module {}", + function_name, + module_id + ) + })?; + + let return_sig = target_compiled_module.signature_at(target_func_handle.return_); + // Transactional test runner does works mainly with public functions, so we need to wrap them in a script + // to make it runnable in the VM flow used by the fuzzer. + let needs_wrapper = !return_sig.0.is_empty() || !target_func_def.is_entry; + + if needs_wrapper { + if std::env::var("DEBUG").is_ok() { + println!( + "[transactional_ops] Wrapper needed for {}::{}", + module_id, function_name + ); + } + let wrapper_script_source = generate_script_wrapper_for_non_entry_function( + &module_id, + target_compiled_module, + target_func_def, + target_func_handle, + &resolved_type_args, + )?; + // store the wrapper script source in a temp file + let mut temp_file = tempfile::NamedTempFile::new()?; + temp_file.write_all(wrapper_script_source.as_bytes())?; + + let (compiled_wrapper_script, _warnings_opt) = + adapter.compile_script(SyntaxChoice::Source, Some(temp_file), 0, 0)?; + + let move_args: Vec = resolved_args_concrete_values + .into_iter() + .map(|arg| arg.into()) + .collect(); + + operations.push(TransactionalOperation::RunScript { + _script: compiled_wrapper_script, + _type_args: resolved_type_args, + _args: move_args, + }); + } else { + let serialized_args: Vec> = resolved_args_concrete_values + .into_iter() + .map(|arg| { + let move_value: MoveValue = arg.into(); + bcs::to_bytes(&move_value) + .map_err(|e| anyhow::anyhow!("Failed to serialize argument: {}", e)) + }) + .collect::>>()?; + + operations.push(TransactionalOperation::CallFunction { + _module: module_id, + _function: func_idx, + _type_args: resolved_type_args, + _args: serialized_args, + }); + } + }, + _ => { + // Skip other task types (Init, PrintBytecode, View, Subcommand) + continue; + }, + } + } + + Ok(operations) +} + +// Helper to convert SignatureToken to a Move type string for the wrapper script +fn signature_token_to_move_type_string_for_wrapper( + token: &SignatureToken, + module: &CompiledModule, +) -> anyhow::Result { + match token { + SignatureToken::Bool => Ok("bool".to_string()), + SignatureToken::U8 => Ok("u8".to_string()), + SignatureToken::U16 => Ok("u16".to_string()), + SignatureToken::U32 => Ok("u32".to_string()), + SignatureToken::U64 => Ok("u64".to_string()), + SignatureToken::U128 => Ok("u128".to_string()), + SignatureToken::U256 => Ok("u256".to_string()), + SignatureToken::Address => Ok("address".to_string()), + SignatureToken::Signer => Ok("signer".to_string()), + SignatureToken::Vector(inner_token) => Ok(format!( + "vector<{}>", + signature_token_to_move_type_string_for_wrapper(inner_token, module)? + )), + SignatureToken::Function(args, returns, abilities) => { + let args_str = args + .iter() + .map(|t| signature_token_to_move_type_string_for_wrapper(t, module)) + .collect::>>()?; + let returns_str = returns + .iter() + .map(|t| signature_token_to_move_type_string_for_wrapper(t, module)) + .collect::>>()?; + Ok(format!( + "|{}|{}{}", + args_str.join(", "), + returns_str.join(", "), + abilities.display_postfix() + )) + }, + SignatureToken::Struct(sh_idx) => { + let struct_handle = module.struct_handle_at(*sh_idx); + let mh = module.module_handle_at(struct_handle.module); + let struct_name = module.identifier_at(struct_handle.name); + let module_name = module.identifier_at(mh.name); + let module_addr = module.address_identifier_at(mh.address); + Ok(format!( + "{}::{}::{}", + module_addr.to_hex_literal(), + module_name, + struct_name + )) + }, + SignatureToken::StructInstantiation(sh_idx, type_args) => { + let struct_handle = module.struct_handle_at(*sh_idx); + let mh = module.module_handle_at(struct_handle.module); + let struct_name = module.identifier_at(struct_handle.name); + let module_name = module.identifier_at(mh.name); + let module_addr = module.address_identifier_at(mh.address); + let type_arg_strings: Vec = type_args + .iter() + .map(|t| signature_token_to_move_type_string_for_wrapper(t, module)) + .collect::>>()?; + Ok(format!( + "{}::{}::{}<{}>", + module_addr.to_hex_literal(), + module_name, + struct_name, + type_arg_strings.join(", ") + )) + }, + SignatureToken::TypeParameter(idx) => Ok(format!("T{}", idx)), + SignatureToken::Reference(inner_token) => Ok(format!( + "&{}", + signature_token_to_move_type_string_for_wrapper(inner_token, module)? + )), + SignatureToken::MutableReference(inner_token) => Ok(format!( + "&mut {}", + signature_token_to_move_type_string_for_wrapper(inner_token, module)? + )), + } +} + +// Generates the Move source code for a wrapper script. +fn generate_script_wrapper_for_non_entry_function( + _target_module_id: &ModuleId, + target_module: &CompiledModule, + _target_func_def: &FunctionDefinition, + target_func_handle: &FunctionHandle, + _target_type_args: &[TypeTag], +) -> anyhow::Result { + let func_name_ident = target_module.identifier_at(target_func_handle.name); + + // skip if the function is not public + if _target_func_def.visibility != Visibility::Public { + return Err(anyhow::anyhow!( + "Function {} is not public", + func_name_ident.to_string() + )); + } + + let module_handle = target_module.module_handle_at(target_func_handle.module); + let module_name_ident = target_module.identifier_at(module_handle.name); + let module_addr_literal = target_module + .address_identifier_at(module_handle.address) + .to_hex_literal(); + + let parameters_sig = target_module.signature_at(target_func_handle.parameters); + let return_sig = target_module.signature_at(target_func_handle.return_); + + let has_signer_by_value = parameters_sig + .0 + .iter() + .any(|t| *t == SignatureToken::Signer); + let script_signer_param = if has_signer_by_value { + "s: signer" + } else { + "s: &signer" + }; + let mut script_params_str_parts = vec![script_signer_param.to_string()]; + let mut call_args_str_parts = vec![]; + + for (i, param_token) in parameters_sig.0.iter().enumerate() { + match param_token { + SignatureToken::Signer => { + call_args_str_parts.push("s".to_string()); + }, + SignatureToken::Reference(inner_token) + if matches!(**inner_token, SignatureToken::Signer) => + { + if has_signer_by_value { + call_args_str_parts.push("&s".to_string()); + } else { + call_args_str_parts.push("s".to_string()); + } + }, + _ => { + let type_str = + signature_token_to_move_type_string_for_wrapper(param_token, target_module)?; + script_params_str_parts.push(format!("arg{}: {}", i, type_str)); + call_args_str_parts.push(format!("arg{}", i)); + }, + } + } + + let type_parameters_decl_str = if target_func_handle.type_parameters.is_empty() { + String::new() + } else { + let params: Vec = (0..target_func_handle.type_parameters.len()) + .map(|i| format!("T{}", i)) + .collect(); + format!("<{}>", params.join(", ")) + }; + + // Check if the function returns a unit type (empty tuple) + let is_unit_return = return_sig.0.is_empty(); + + // Generate the function call line based on return type + let function_call_line = if is_unit_return { + // For unit return types, don't assign to a variable + format!( + "{}::{}{}({});", + module_name_ident, + func_name_ident, + type_parameters_decl_str, + call_args_str_parts.join(", ") + ) + } else { + // For non-unit return types, assign to a variable. + // If multiple values are returned, destructure the tuple. + let num_return_values = return_sig.0.len(); + let bindings = if num_return_values > 1 { + format!("({})", vec!["_"; num_return_values].join(", ")) + } else { + "_".to_string() + }; + format!( + "let {} = {}::{}{}({});", + bindings, + module_name_ident, + func_name_ident, + type_parameters_decl_str, + call_args_str_parts.join(", ") + ) + }; + + let script_source = format!( + r#" +script {{ + use {}::{}; + + fun main{}({}) {{ + {} + }} +}} + "#, + module_addr_literal, + module_name_ident, + type_parameters_decl_str, + script_params_str_parts.join(", "), + function_call_line + ); + + if std::env::var("DEBUG").is_ok() { + println!( + "[transactional_ops] Generated wrapper script source:\n{}", + script_source + ); + } + Ok(script_source) +} diff --git a/third_party/move/testing-infra/transactional-test-runner/src/vm_test_harness.rs b/third_party/move/testing-infra/transactional-test-runner/src/vm_test_harness.rs index c394ae5d97e..9f9fa764f3e 100644 --- a/third_party/move/testing-infra/transactional-test-runner/src/vm_test_harness.rs +++ b/third_party/move/testing-infra/transactional-test-runner/src/vm_test_harness.rs @@ -561,6 +561,11 @@ fn precompiled_v2_stdlib() -> &'static PrecompiledFilesModules { &PRECOMPILED_MOVE_STDLIB_V2 } +#[cfg(feature = "fuzzing")] +pub fn precompiled_v2_stdlib_fuzzer() -> &'static PrecompiledFilesModules { + &PRECOMPILED_MOVE_STDLIB_V2 +} + pub fn run_test_with_config( config: TestRunConfig, path: &Path, From adb3b905ec67fe2cc1458ce4838c0466389e7169 Mon Sep 17 00:00:00 2001 From: Wolfgang Grieskamp Date: Fri, 25 Jul 2025 14:19:22 -0700 Subject: [PATCH 052/260] [move-vm] Adding negative FV tests for bytecode and runtime verifier (#17147) * [move-vm] Adding negative FV tests for bytecode and runtime verifier This adds a number of tests (wrong code) which are run in two ways: one with bytecode verifier enabled where expect it to be caught in the verifier, one with bytecode verifier disabled where we expect it to be called by paranoid mode. One bug was discovered this far by this approach, where paranoid mode seems to miss a check (https://github.com/aptos-labs/aptos-core/issues/17137). Also changes the way how the verifier is disabled by using a configuration option. The failpoints used before can't be used with parallel test execution. * Fixing false positive bug #17137 (actually a bug in the tests), cleaning up. * Apply suggestions from code review * Addressing reviewer comments Downstreamed-from: e1b13f2556dde9f6cc8869fe3ae8ad72c25ef333 --- .../aptos-vm-environment/src/prod_configs.rs | 3 +- .../move/move-binary-format/src/errors.rs | 21 ++- .../src/unit_tests/dependencies_tests.rs | 18 ++- .../src/dependencies.rs | 11 +- .../move-bytecode-verifier/src/verifier.rs | 27 +++- third_party/move/move-ir-compiler/src/main.rs | 15 ++- .../move/move-vm/runtime/src/interpreter.rs | 2 + .../runtime/src/storage/environment.rs | 4 +- .../closure_assign_local_num.baseline.exp | 12 ++ .../closure_assign_local_num.masm | 82 ++++++++++++ .../closure_assign_local_num.paranoid.exp | 12 ++ .../closure_assign_local_struct.baseline.exp | 12 ++ .../closure_assign_local_struct.masm | 66 ++++++++++ .../closure_assign_local_struct.paranoid.exp | 12 ++ .../closure_assign_pass.baseline.exp | 12 ++ .../closure_assign_pass.masm | 86 ++++++++++++ .../closure_assign_pass.paranoid.exp | 12 ++ .../closure_assign_refs.baseline.exp | 12 ++ .../closure_assign_refs.masm | 66 ++++++++++ .../closure_assign_refs.paranoid.exp | 12 ++ .../closure_call_typing.baseline.exp | 45 +++++++ .../closure_call_typing.masm | 93 +++++++++++++ .../closure_call_typing.paranoid.exp | 45 +++++++ .../closure_captured_typing.baseline.exp | 45 +++++++ .../closure_captured_typing.masm | 122 ++++++++++++++++++ .../closure_captured_typing.paranoid.exp | 45 +++++++ .../closure_delayed_typing.baseline.exp | 23 ++++ .../closure_delayed_typing.masm | 85 ++++++++++++ .../closure_delayed_typing.paranoid.exp | 23 ++++ .../closure_drop.baseline.exp | 12 ++ .../function_values_safety/closure_drop.masm | 59 +++++++++ .../closure_drop.paranoid.exp | 12 ++ .../closure_store.baseline.exp | 25 ++++ .../function_values_safety/closure_store.masm | 33 +++++ .../closure_store.paranoid.exp | 12 ++ .../transactional-tests/tests/tests.rs | 62 ++++----- .../src/vm_test_harness.rs | 4 + third_party/move/tools/move-asm/src/syntax.rs | 8 +- 38 files changed, 1184 insertions(+), 66 deletions(-) create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_assign_local_num.baseline.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_assign_local_num.masm create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_assign_local_num.paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_assign_local_struct.baseline.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_assign_local_struct.masm create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_assign_local_struct.paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_assign_pass.baseline.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_assign_pass.masm create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_assign_pass.paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_assign_refs.baseline.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_assign_refs.masm create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_assign_refs.paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_call_typing.baseline.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_call_typing.masm create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_call_typing.paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_captured_typing.baseline.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_captured_typing.masm create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_captured_typing.paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_delayed_typing.baseline.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_delayed_typing.masm create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_delayed_typing.paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_drop.baseline.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_drop.masm create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_drop.paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_store.baseline.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_store.masm create mode 100644 third_party/move/move-vm/transactional-tests/tests/function_values_safety/closure_store.paranoid.exp diff --git a/aptos-move/aptos-vm-environment/src/prod_configs.rs b/aptos-move/aptos-vm-environment/src/prod_configs.rs index 5131c622f39..f33c268b283 100644 --- a/aptos-move/aptos-vm-environment/src/prod_configs.rs +++ b/aptos-move/aptos-vm-environment/src/prod_configs.rs @@ -14,7 +14,7 @@ use aptos_types::{ state_store::StateView, }; use move_binary_format::deserializer::DeserializerConfig; -use move_bytecode_verifier::VerifierConfig; +use move_bytecode_verifier::{verifier::VerificationScope, VerifierConfig}; use move_vm_runtime::config::VMConfig; use move_vm_types::{ loaded_data::runtime_types::TypeBuilder, values::DEFAULT_MAX_VM_VALUE_NESTED_DEPTH, @@ -85,6 +85,7 @@ pub fn aptos_prod_verifier_config(features: &Features) -> VerifierConfig { // Note: we reuse the `enable_function_values` flag to set various stricter limits on types. VerifierConfig { + scope: VerificationScope::Everything, max_loop_depth: Some(5), max_generic_instantiation_length: Some(32), max_function_parameters: Some(128), diff --git a/third_party/move/move-binary-format/src/errors.rs b/third_party/move/move-binary-format/src/errors.rs index 72ab35b270f..30f3ee022c1 100644 --- a/third_party/move/move-binary-format/src/errors.rs +++ b/third_party/move/move-binary-format/src/errors.rs @@ -10,13 +10,28 @@ use move_core_types::{ language_storage::ModuleId, vm_status::{self, StatusCode, StatusType, VMStatus}, }; -use once_cell::sync::Lazy; +use once_cell::sync::{Lazy, OnceCell}; use std::fmt; pub type VMResult = ::std::result::Result; pub type BinaryLoaderResult = ::std::result::Result; pub type PartialVMResult = ::std::result::Result; +static STABLE_TEST_DISPLAY: OnceCell = OnceCell::new(); + +/// Call this function if display of errors should be stable for baseline tests. +/// Specifically, no stack traces should be generated, as they contain transitive +/// file locations. +pub fn set_stable_test_display() { + STABLE_TEST_DISPLAY.set(true).unwrap_or(()) +} + +/// Check whether stable test display is enabled. This can be used by other components +/// to adjust their output. +pub fn is_stable_test_display() -> bool { + STABLE_TEST_DISPLAY.get().copied().unwrap_or(false) +} + /// This macro is used to panic while debugging fuzzing crashes obtaining the right stack trace. /// e.g. DEBUG_VM_STATUS=ABORTED,UNKNOWN_INVARIANT_VIOLATION_ERROR ./fuzz.sh run move_aptosvm_publish_and_run /// third_party/move/move-core/types/src/vm_status.rs:506 for the list of status codes. @@ -416,7 +431,9 @@ impl PartialVMError { pub fn new(major_status: StatusCode) -> Self { debug_assert!(major_status != StatusCode::EXECUTED); - let message = if major_status == StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR { + let message = if major_status == StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR + && !is_stable_test_display() + { let mut len = 5; let mut trace: String = "Unknown invariant violation generated:\n".to_string(); backtrace::trace(|frame| { diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/dependencies_tests.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/dependencies_tests.rs index 30acf6b0013..ed4df8b9127 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/dependencies_tests.rs +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/dependencies_tests.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use move_binary_format::file_format::*; -use move_bytecode_verifier::dependencies; +use move_bytecode_verifier::{dependencies, VerifierConfig}; use move_core_types::{ ability::AbilitySet, account_address::AccountAddress, identifier::Identifier, vm_status::StatusCode, @@ -276,20 +276,23 @@ fn deprecated_script_visibility_checks_valid() { // module uses script functions from script context let is_valid = true; let non_generic_call_mod = mk_invoking_module(false, is_valid); - let result = dependencies::verify_module(&non_generic_call_mod, deps); + let result = + dependencies::verify_module(&VerifierConfig::default(), &non_generic_call_mod, deps); assert!(result.is_ok()); let generic_call_mod = mk_invoking_module(true, is_valid); - let result = dependencies::verify_module(&generic_call_mod, deps); + let result = dependencies::verify_module(&VerifierConfig::default(), &generic_call_mod, deps); assert!(result.is_ok()); // script uses script functions let non_generic_call_script = mk_invoking_script(false); - let result = dependencies::verify_script(&non_generic_call_script, deps); + let result = + dependencies::verify_script(&VerifierConfig::default(), &non_generic_call_script, deps); assert!(result.is_ok()); let generic_call_script = mk_invoking_script(true); - let result = dependencies::verify_script(&generic_call_script, deps); + let result = + dependencies::verify_script(&VerifierConfig::default(), &generic_call_script, deps); assert!(result.is_ok()); } @@ -303,14 +306,15 @@ fn deprecated_script_visibility_checks_invalid() { // module uses script functions from script context let not_valid = false; let non_generic_call_mod = mk_invoking_module(false, not_valid); - let result = dependencies::verify_module(&non_generic_call_mod, deps); + let result = + dependencies::verify_module(&VerifierConfig::default(), &non_generic_call_mod, deps); assert_eq!( result.unwrap_err().major_status(), StatusCode::CALLED_SCRIPT_VISIBLE_FROM_NON_SCRIPT_VISIBLE, ); let generic_call_mod = mk_invoking_module(true, not_valid); - let result = dependencies::verify_module(&generic_call_mod, deps); + let result = dependencies::verify_module(&VerifierConfig::default(), &generic_call_mod, deps); assert_eq!( result.unwrap_err().major_status(), StatusCode::CALLED_SCRIPT_VISIBLE_FROM_NON_SCRIPT_VISIBLE, diff --git a/third_party/move/move-bytecode-verifier/src/dependencies.rs b/third_party/move/move-bytecode-verifier/src/dependencies.rs index 3dd868b5e8e..a3c8332b0ca 100644 --- a/third_party/move/move-bytecode-verifier/src/dependencies.rs +++ b/third_party/move/move-bytecode-verifier/src/dependencies.rs @@ -3,6 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 //! This module contains verification of usage of dependencies for modules and scripts. +use crate::{verifier::VerificationScope, VerifierConfig}; use move_binary_format::{ access::{ModuleAccess, ScriptAccess}, binary_views::BinaryIndexedView, @@ -170,10 +171,13 @@ impl<'a, 'b> Context<'a, 'b> { } pub fn verify_module<'a>( + config: &VerifierConfig, module: &CompiledModule, dependencies: impl IntoIterator, ) -> VMResult<()> { - fail::fail_point!("skip-verification-for-paranoid-tests", |_| { Ok(()) }); + if matches!(config.scope, VerificationScope::Nothing) { + return Ok(()); + } verify_module_impl(module, dependencies) .map_err(|e| e.finish(Location::Module(module.self_id()))) } @@ -191,10 +195,13 @@ fn verify_module_impl<'a>( } pub fn verify_script<'a>( + config: &VerifierConfig, script: &CompiledScript, dependencies: impl IntoIterator, ) -> VMResult<()> { - fail::fail_point!("skip-verification-for-paranoid-tests", |_| { Ok(()) }); + if matches!(config.scope, VerificationScope::Nothing) { + return Ok(()); + } verify_script_impl(script, dependencies).map_err(|e| e.finish(Location::Script)) } diff --git a/third_party/move/move-bytecode-verifier/src/verifier.rs b/third_party/move/move-bytecode-verifier/src/verifier.rs index 10d64d4659a..32f9ca954f1 100644 --- a/third_party/move/move-bytecode-verifier/src/verifier.rs +++ b/third_party/move/move-bytecode-verifier/src/verifier.rs @@ -22,6 +22,7 @@ use std::time::Instant; #[derive(Debug, Clone, Eq, PartialEq, Serialize)] pub struct VerifierConfig { + pub scope: VerificationScope, pub max_loop_depth: Option, pub max_function_parameters: Option, pub max_generic_instantiation_length: Option, @@ -49,6 +50,15 @@ pub struct VerifierConfig { pub max_type_depth: Option, } +/// Scope of verification. +#[derive(Debug, Clone, Eq, PartialEq, Serialize)] +pub enum VerificationScope { + /// Do all verification + Everything, + /// The remaining variants are for testing and should never be used in production + Nothing, +} + /// Helper for a "canonical" verification of a module. /// /// Clients that rely on verification should call the proper passes @@ -106,8 +116,9 @@ pub fn verify_module_with_config_for_test_with_version( } pub fn verify_module_with_config(config: &VerifierConfig, module: &CompiledModule) -> VMResult<()> { - fail::fail_point!("skip-verification-for-paranoid-tests", |_| { Ok(()) }); - + if matches!(config.scope, VerificationScope::Nothing) { + return Ok(()); + } let prev_state = move_core_types::state::set_state(VMState::VERIFIER); let result = std::panic::catch_unwind(|| { // Always needs to run bound checker first as subsequent passes depend on it @@ -167,8 +178,9 @@ pub fn verify_script(script: &CompiledScript) -> VMResult<()> { } pub fn verify_script_with_config(config: &VerifierConfig, script: &CompiledScript) -> VMResult<()> { - fail::fail_point!("skip-verification-for-paranoid-tests", |_| { Ok(()) }); - + if matches!(config.scope, VerificationScope::Nothing) { + return Ok(()); + } let prev_state = move_core_types::state::set_state(VMState::VERIFIER); let result = std::panic::catch_unwind(|| { // Always needs to run bound checker first as subsequent passes depend on it @@ -207,6 +219,7 @@ pub fn verify_script_with_config(config: &VerifierConfig, script: &CompiledScrip impl Default for VerifierConfig { fn default() -> Self { Self { + scope: VerificationScope::Everything, max_loop_depth: None, max_function_parameters: None, max_generic_instantiation_length: None, @@ -266,6 +279,7 @@ impl VerifierConfig { /// An approximation of what config is used in production. pub fn production() -> Self { Self { + scope: VerificationScope::Everything, max_loop_depth: Some(5), max_generic_instantiation_length: Some(32), max_function_parameters: Some(128), @@ -299,4 +313,9 @@ impl VerifierConfig { max_type_depth: Some(20), } } + + /// Set verification scope + pub fn set_scope(self, scope: VerificationScope) -> Self { + Self { scope, ..self } + } } diff --git a/third_party/move/move-ir-compiler/src/main.rs b/third_party/move/move-ir-compiler/src/main.rs index 4d271961a23..31b04899f0a 100644 --- a/third_party/move/move-ir-compiler/src/main.rs +++ b/third_party/move/move-ir-compiler/src/main.rs @@ -10,7 +10,10 @@ use move_binary_format::{ errors::VMError, file_format::{CompiledModule, CompiledScript}, }; -use move_bytecode_verifier::{dependencies, verify_module, verify_script}; +use move_bytecode_verifier::{ + dependencies, verify_module, verify_module_with_config, verify_script_with_config, + VerifierConfig, +}; use move_command_line_common::files::{ MOVE_COMPILED_EXTENSION, MOVE_IR_EXTENSION, SOURCE_MAP_EXTENSION, }; @@ -52,15 +55,17 @@ fn print_error_and_exit(verification_error: &VMError) -> ! { } fn do_verify_module(module: &CompiledModule, dependencies: &[CompiledModule]) { - verify_module(module).unwrap_or_else(|err| print_error_and_exit(&err)); - if let Err(err) = dependencies::verify_module(module, dependencies) { + let config = VerifierConfig::default(); + verify_module_with_config(&config, module).unwrap_or_else(|err| print_error_and_exit(&err)); + if let Err(err) = dependencies::verify_module(&config, module, dependencies) { print_error_and_exit(&err); } } fn do_verify_script(script: &CompiledScript, dependencies: &[CompiledModule]) { - verify_script(script).unwrap_or_else(|err| print_error_and_exit(&err)); - if let Err(err) = dependencies::verify_script(script, dependencies) { + let config = VerifierConfig::default(); + verify_script_with_config(&config, script).unwrap_or_else(|err| print_error_and_exit(&err)); + if let Err(err) = dependencies::verify_script(&config, script, dependencies) { print_error_and_exit(&err); } } diff --git a/third_party/move/move-vm/runtime/src/interpreter.rs b/third_party/move/move-vm/runtime/src/interpreter.rs index ce550802cf9..87a796df2bf 100644 --- a/third_party/move/move-vm/runtime/src/interpreter.rs +++ b/third_party/move/move-vm/runtime/src/interpreter.rs @@ -27,6 +27,7 @@ use crate::{ }; use fail::fail_point; use move_binary_format::{ + errors, errors::*, file_format::{ AccessKind, Bytecode, FunctionHandleIndex, FunctionInstantiationIndex, SignatureIndex, @@ -1380,6 +1381,7 @@ where // We do not consider speculative invariant violations. if err.status_type() == StatusType::InvariantViolation && err.major_status() != StatusCode::SPECULATIVE_EXECUTION_ABORT_ERROR + && !errors::is_stable_test_display() { let location = err.location().clone(); let state = self.internal_state_str(current_frame); diff --git a/third_party/move/move-vm/runtime/src/storage/environment.rs b/third_party/move/move-vm/runtime/src/storage/environment.rs index 8846e77b633..01155de2ab1 100644 --- a/third_party/move/move-vm/runtime/src/storage/environment.rs +++ b/third_party/move/move-vm/runtime/src/storage/environment.rs @@ -69,7 +69,7 @@ pub struct RuntimeEnvironment { /// different verifier configurations (e.g. straddling an epoch boundary where the config /// changed) would treat each other's cached entries as their own — a module accepted under /// a more permissive config could be skipped under a stricter one. - /// + /// /// Invariant: must stay in line with `vm_config.verifier_config`. Any mutation of `vm_config.verifier_config` must /// recompute this digest. verifier_config_digest: [u8; 32], @@ -142,6 +142,7 @@ impl RuntimeEnvironment { immediate_dependencies: &[Arc], ) -> VMResult + +Flame Graph + +Reset Zoom +Search + + +0x9948f11daa6050176be4906927851f6b223ce0337a070694ca43885d6a821668::fungible_asset_example::init_module (5,385,835 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::code::check_code_publishing_permission (24,057,635 samples, 0.04%) + + + +0x51cfa95373b018c7bf7f137a2a93a780d5fa4b2de19f46625e37eebff461f3a3::liquidity_pool::init_module (6,298,041 samples, 0.01%) + + + +0x24cebb88f7a868d50426d50348da168c020c925a04c67e65ea45d1adbc90db06::ambassador::mint_numbered_ambassador_token_by_user (907,196,128 samples, 1.64%) + + + +0x04e9cdcbe92ada7e1ea7f688f4018caa2ed11dd6e0fb47955346bf302a767408::fungible_asset_example::init_module (4,708,464 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::withdraw_sanity_check (27,319,727 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_permissioned_signer_enabled (9,206,719 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (5,141,547 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::check_permission_capacity_above (8,563,283 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_default_account_resource_enabled (18,908,031 samples, 0.03%) + + + +0x1bcdc65264ff11e2aa76a2b53f3f46d6d456ada8f0722abe1fdb5fe4846df7c8::liquidity_pool_wrapper::create_pool (70,968,046 samples, 0.13%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_permissioned_signer_enabled (7,947,048 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::add (746,678,581 samples, 1.35%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::destroy_permissioned_handle (154,545,866 samples, 0.28%) + + + +0x0000000000000000000000000000000000000000000000000000000000000004::collection::create_collection_address (27,461,935 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000004::token::generate_mutator_ref (10,264,400 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::replace_key_inplace (124,548,699 samples, 0.23%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::is_permissioned_signer (10,303,780 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::is_permissioned_signer (4,867,164 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_default_account_resource_enabled (18,529,956 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_account::transfer (199,161,568 samples, 0.36%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::remove (16,975,650 samples, 0.03%) + + + +0xeb90dbea041a49287e12af1e523f50efded889ca5fcd470998fbe7bb3bc563b9::fungible_asset_example::init_module (4,952,036 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::remove (2,240,651,019 samples, 4.05%) +0x00.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::insert (295,507,034 samples, 0.53%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::new (5,147,555 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (125,028,282 samples, 0.23%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::mint_internal (8,357,635 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::primary_store_address (32,147,886 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::upsert (24,922,018 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::iter_borrow (13,902,462 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::is_lt (22,773,484 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::register (64,283,169 samples, 0.12%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (9,980,796 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::remove (582,813,685 samples, 1.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::borrow (242,673,256 samples, 0.44%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::append (113,652,043 samples, 0.21%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::create_signer::create_signer (14,358,876 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,757,500 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_hash::sip_hash_from_value (47,474,626 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::validate_dynamic_size_and_init_max_degrees (7,743,297 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::genesis::create_initialize_validators_with_commission (53,324,084 samples, 0.10%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::borrow (61,410,627 samples, 0.11%) + + + +0x6fc74285e11f81e966c7d67d62f2ad4bad4c662116a672c8d603db309c946e22::fungible_asset_example::init_module (5,251,337 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::dispatchable_fungible_asset::deposit (32,963,659 samples, 0.06%) + + + +0x8753bfb0c0ce026233b9645f580351e44ca7672d5296143cebbd2f4f7746490b::coin_example::init_module (16,347,164 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::trim (154,794,275 samples, 0.28%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize_with_parallelizable_supply (17,625,417 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,825,167 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (12,242,868 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::mint_token (430,546,122 samples, 0.78%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add_at (1,297,754,260 samples, 2.34%) +0.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::default_to_concurrent_fungible_balance_enabled (5,273,661 samples, 0.01%) + + + +0x9b435da8729de6ea9e0106d5d47e442100f9829cc4d6b4755421dcd2e69e247c::fungible_asset_example::init_module (4,988,998 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::upsert (7,260,059 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (30,454,021 samples, 0.06%) + + + +0x59751998dc73e3ce112b95b971392fb5d8d52f2ddedb0e5c974f76d6841c8690::maps_example::test_add_remove_ordered_map (1,557,490,535 samples, 2.81%) +0x.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (12,174,709 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::split_one_bucket (24,641,476 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::simple_map::find (384,748,198 samples, 0.70%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::bcs::to_bytes (6,584,502 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,583,248 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (24,212,052 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::string::utf8 (10,255,908 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::assert_collection_exists (17,949,170 samples, 0.03%) + + + +0x3e7fd217c1367d4e80c278d1266607957da657dfa48db8016b2096419a37fe3e::resource_groups_example::set (18,116,699 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::direct_deposit (45,378,993 samples, 0.08%) + + + +0x8686c82863266f5134d9fd5311a94b423cb98288adebed635999db773f802688::coin_example::init_module (16,309,460 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::symbol (6,200,957 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains_box (7,580,087 samples, 0.01%) + + + +0xe7de0ac63e1bdaadb9400daa013a754bbdd16faa7de47cfca3f2ef6bb5d893fe::permissioned_transfer::transfer_permissioned (1,368,156,379 samples, 2.47%) +0x.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::increment_sequence_number (7,546,584 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::address_to_object (10,153,208 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::mint_internal (13,408,495 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::module_event_migration_enabled (7,395,713 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_default_account_resource_enabled (7,803,405 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::new_with_config (9,124,170 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::remove_link (19,623,309 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (4,706,375 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::compare (22,049,959 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,680,793 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::deposit_sanity_check (14,028,749 samples, 0.03%) + + + +0x0bf2450c78e7bc920d729214d7a327451a2cceda5bf27ef7e0311b0ceb41124f::coin_example::init_module (18,251,709 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object (5,154,125 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::compare (24,594,530 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::genesis::initialize_validator (8,466,253 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add (40,535,663 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::mint_internal (7,928,241 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (8,172,349 samples, 0.01%) + + + +0x8753bfb0c0ce026233b9645f580351e44ca7672d5296143cebbd2f4f7746490b::objects::create_objects (688,256,458 samples, 1.24%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_account_if_does_not_exist (5,717,332 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::store_exists (5,860,581 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::borrow (44,167,456 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::mint (14,751,966 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (4,710,834 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::address_to_object (17,694,496 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::insert (11,673,692 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::is_empty (7,897,351 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::add (41,452,333 samples, 0.07%) + + + +0x19dea829a84271dcd892c174870c63d5c1baba99ddb952216d5b5815f4296f60::coin_example::init_module (17,443,625 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::bcs::to_bytes (94,323,676 samples, 0.17%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::remove (191,606,450 samples, 0.35%) + + + +0xef570729dd075b7d28b0fdd7f717ba0eebb17d87974b439ff952a0a845eb4423::coin_example::init_module (16,375,210 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::remove (18,627,162 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::ensure_primary_store_exists (217,481,612 samples, 0.39%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::stake::add_stake (4,923,754 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (33,842,035 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::signer_from_permissioned_handle (9,708,787 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::mint (1,354,289,168 samples, 2.45%) +0x.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::singleton (19,318,914 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::create_store (36,210,624 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_governance::store_signer_cap (5,256,122 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::burn_internal (14,255,508 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_permissioned_signer_enabled (5,288,990 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_default_account_resource_enabled (5,729,749 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::remove (348,329,738 samples, 0.63%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::deposit_with_ref (20,554,155 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::genesis::create_initialize_validator (42,656,961 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::genesis::create_account (12,517,125 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (7,078,250 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::compare (120,076,387 samples, 0.22%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::create_primary_store (117,386,645 samples, 0.21%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add_at (299,847,042 samples, 0.54%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::upsert (149,397,099 samples, 0.27%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_deposit (8,922,878 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::upsert (2,685,655,880 samples, 4.85%) +0x0000.. + + +0x1195cf41798980141fb20a57d8d9e123a210f80180fbe2d307379cab0ed4b27c::coin_example::init_module (16,514,668 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::is_empty (9,687,292 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_validation::prologue_common (94,448,934 samples, 0.17%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_enabled (8,881,536 samples, 0.02%) + + + +0x3257ababdfa165c9b16f8f2a2d2dec58c83dcdea9bdf550c7c60f4b6b5b06feb::liquidity_pool::init_module (5,828,585 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::is_permissioned_signer (8,728,836 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::compare (15,141,100 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::grant_permission_by_address (254,886,896 samples, 0.46%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::mint_internal (12,344,698 samples, 0.02%) + + + +0x63ca834489731b89c8f75e63a4fc65cfea775d20c69d0ec65fa105329715121b::vector_picture::update (9,804,504 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add (69,434,615 samples, 0.13%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::add_fungibility (50,713,550 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::address_to_object (11,116,461 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::internal_lower_bound (401,691,995 samples, 0.73%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::deposit_token (304,323,054 samples, 0.55%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::stake::initialize_owner (5,040,747 samples, 0.01%) + + + +0x59751998dc73e3ce112b95b971392fb5d8d52f2ddedb0e5c974f76d6841c8690::coin_example::init_module (15,891,289 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::balance (75,791,035 samples, 0.14%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_account_if_does_not_exist (5,454,287 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_named_object (46,229,840 samples, 0.08%) + + + +0x14171b275ed8de29a4b4b4fa3c178ca317f16481432d150d42889c4d5f2b0e8b::coin_example::init_module (16,401,293 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::deposit_token (309,479,419 samples, 0.56%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,701,043 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::module_event_migration_enabled (7,236,967 samples, 0.01%) + + + +0x266bd01f3c436c20be957674405563323c71f2c7df612638136b2d9d3689fc37::vector_example::generate_vec (186,205,249 samples, 0.34%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,539,710 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::genesis::create_initialize_validators (62,533,917 samples, 0.11%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add_at (68,629,514 samples, 0.12%) + + + +0xab7f7aaaaa5edf4a7a8f19fe268ff5d3d0ad81293c22372582d48dc52ceea209::resource_groups_example::set (9,208,509 samples, 0.02%) + + + +0xceea15bd81a80dae592da4fca2a5576de8e685b2a8d3571f77c13857a5415d64::simple::loop_arithmetic (567,709,124 samples, 1.03%) + + + +0xbd3ad01b3983ac748103d27139071721edd713d9bed75a79bd8b8872bd87648c::counter_with_milestone::increment_milestone (29,144,469 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::trim (142,328,131 samples, 0.26%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::append (143,307,875 samples, 0.26%) + + + +0xeb90dbea041a49287e12af1e523f50efded889ca5fcd470998fbe7bb3bc563b9::maps_example::test_add_remove_simple_map (1,735,074,990 samples, 3.13%) +0xe.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,904,253 samples, 0.02%) + + + +0xab7f7aaaaa5edf4a7a8f19fe268ff5d3d0ad81293c22372582d48dc52ceea209::coin_example::init_module (16,410,794 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow (28,294,034 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::is_empty (7,647,940 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::create_primary_store (127,817,788 samples, 0.23%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::withdraw_with_event_internal (48,974,665 samples, 0.09%) + + + +0xac708b3a0f534018ceee7051284609e9bc1e53ebf549898a435db0f62e34c3f3::liquidity_pool::get_amount_out (134,854,876 samples, 0.24%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains_box (7,372,623 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::generate_transfer_ref (6,431,327 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::internal_lower_bound (8,209,784 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_guid (62,427,589 samples, 0.11%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::deposit_token (279,599,130 samples, 0.51%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::add_link (61,080,821 samples, 0.11%) + + + +0xac708b3a0f534018ceee7051284609e9bc1e53ebf549898a435db0f62e34c3f3::liquidity_pool::init_module (5,787,834 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::direct_deposit (50,430,244 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::deposit_dispatch_function (10,008,091 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::iter_is_end (6,908,620 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::has_balance_dispatch_function (6,240,506 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_coin::mint (5,307,419 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::iter_prev (39,046,097 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::withdraw_sanity_check (25,566,404 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::copyable_any::pack (4,987,452 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,679,708 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (17,638,109 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::update_key (405,724,222 samples, 0.73%) + + + +0x1bcdc65264ff11e2aa76a2b53f3f46d6d456ada8f0722abe1fdb5fe4846df7c8::liquidity_pool::create (33,350,835 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,687,501 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (19,331,973 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_account::fungible_transfer_only (118,278,779 samples, 0.21%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (12,422,874 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::bucket_index (7,920,794 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (622,861,316 samples, 1.13%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::deposit_token (274,657,221 samples, 0.50%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::internal_lower_bound (4,891,996 samples, 0.01%) + + + +0xac708b3a0f534018ceee7051284609e9bc1e53ebf549898a435db0f62e34c3f3::liquidity_pool::create (29,783,130 samples, 0.05%) + + + +0x266bd01f3c436c20be957674405563323c71f2c7df612638136b2d9d3689fc37::coin_example::init_module (17,507,625 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::balance_impl (10,706,792 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_validation::unified_prologue_v2 (133,584,015 samples, 0.24%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains_box (6,078,250 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000004::token::create_numbered_token (202,575,395 samples, 0.37%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::add (18,457,919 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (4,727,377 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (71,249,788 samples, 0.13%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow_box (5,367,992 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add (1,742,372,809 samples, 3.15%) +0x0.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::coin_to_fungible_asset (519,379,428 samples, 0.94%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_guid (11,065,331 samples, 0.02%) + + + +0xe6cb3c664eaf640e1a834bdb9e7c500df2b6de51018258037f6303856758e0df::token_v1::get_signer (12,449,415 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_withdraw (7,260,507 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::compare (12,319,343 samples, 0.02%) + + + +0xbc7c15e7eb9f4083c80f330a8e5d48344af530b6306aec6583a02dbcc0128fed::smart_table_picture::create (10,994,330 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::balance_impl (11,639,136 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::borrow_mut (67,484,890 samples, 0.12%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (8,135,965 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::operations_default_to_fa_apt_store_enabled (4,856,757 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::concurrent_fungible_assets_enabled (5,333,793 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::exists_at (6,563,746 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::remove (8,086,451 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::is_permissioned_signer (9,128,304 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::add_box (7,150,214 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::generate_mint_ref (6,586,338 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains_box (6,619,294 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::upsert (1,556,371,504 samples, 2.81%) +0x.. + + +0x9b435da8729de6ea9e0106d5d47e442100f9829cc4d6b4755421dcd2e69e247c::vector_example::test_remove_insert (873,394,417 samples, 1.58%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::destroy_empty (8,813,582 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::remove (84,781,225 samples, 0.15%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::withdraw_token (76,402,724 samples, 0.14%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::remove (20,155,242 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::store_exists (5,816,334 samples, 0.01%) + + + +0x24cebb88f7a868d50426d50348da168c020c925a04c67e65ea45d1adbc90db06::ambassador::mint_ambassador_token_impl (514,747,674 samples, 0.93%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (6,448,790 samples, 0.01%) + + + +0xe6cb3c664eaf640e1a834bdb9e7c500df2b6de51018258037f6303856758e0df::coin_example::init_module (16,087,039 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::operations_default_to_fa_apt_store_enabled (5,092,665 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::add (11,684,692 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (12,338,625 samples, 0.02%) + + + +0x19dea829a84271dcd892c174870c63d5c1baba99ddb952216d5b5815f4296f60::fungible_asset_example::init_module (5,038,580 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000004::collection::create_unlimited_collection (4,852,290 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::fill_reserved_slot (26,120,495 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::exists_at (14,397,697 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_framework_reserved_account (8,925,952 samples, 0.02%) + + + +0x1bcdc65264ff11e2aa76a2b53f3f46d6d456ada8f0722abe1fdb5fe4846df7c8::liquidity_pool_wrapper::create_fungible_asset (4,824,128 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow (18,538,918 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (5,167,621 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::option::extract (19,864,993 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::length (4,751,615 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::increase_supply (6,423,412 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_account::transfer (454,515,287 samples, 0.82%) + + + +0x0bf2450c78e7bc920d729214d7a327451a2cceda5bf27ef7e0311b0ceb41124f::permissioned_transfer::transfer (262,608,104 samples, 0.47%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::direct_deposit (44,441,887 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::balance (46,628,219 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,776,794 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_hash::sip_hash_from_value (31,291,332 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (61,988,500 samples, 0.11%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::is_permissioned_signer (9,303,842 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_account_if_does_not_exist (5,887,001 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,874,582 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::compare (12,514,893 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::guid::create (4,845,835 samples, 0.01%) + + + +0xe6cb3c664eaf640e1a834bdb9e7c500df2b6de51018258037f6303856758e0df::token_v1::token_v1_mint_and_transfer_nft_sequential (1,683,731,881 samples, 3.04%) +0xe.. + + +0x0000000000000000000000000000000000000000000000000000000000000007::confidential_asset::init_module (46,522,457 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,551,377 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::singleton (5,025,552 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::dispatchable_fungible_asset::deposit (36,091,694 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::bcs::to_bytes (6,805,309 samples, 0.01%) + + + +0x12e644495af037e00e2e2a31a5627184d2e26cbf0fe27f790c837f71d4203cd7::vector_example::test_trim_append (799,331,547 samples, 1.44%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_permissioned_signer_enabled (8,263,760 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::ensure_primary_store_exists (227,974,463 samples, 0.41%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::mint_internal (13,428,826 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::destroy_empty_node (6,645,506 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::object_from_constructor_ref (4,731,160 samples, 0.01%) + + + +0x51cfa95373b018c7bf7f137a2a93a780d5fa4b2de19f46625e37eebff461f3a3::vector_picture::create (88,647,500 samples, 0.16%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,630,498 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::direct_transfer (449,820,258 samples, 0.81%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_deposit (10,344,249 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::new_event_handle (22,024,831 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::primary_store_address (31,525,595 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::upsert (748,510,448 samples, 1.35%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::withdraw_with_event_internal (49,664,552 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::withdraw_permission_check_by_address (23,769,113 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::withdraw_permission_check_by_address (215,796,348 samples, 0.39%) + + + +0x6fc74285e11f81e966c7d67d62f2ad4bad4c662116a672c8d603db309c946e22::maps_example::test_add_remove_big_ordered_map (3,090,752,373 samples, 5.58%) +0x6fc74.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_context::generate_auid_address (33,462,207 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_enabled (8,984,032 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::create_primary_store_enabled_fungible_asset (90,834,255 samples, 0.16%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account_abstraction::register_derivable_authentication_function (11,255,741 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::write_to_event_store (92,097,050 samples, 0.17%) + + + +0x2ef39d4b60160509cac7019488190e7bec3d5e24372784a9687cf4267c6c4fcc::vector_example::generate_vec (88,360,339 samples, 0.16%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (22,212,871 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::mint (19,798,412 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::has_balance_dispatch_function (6,800,090 samples, 0.01%) + + + +0xa79008c2f80644b3281a33bb65b5235f72edc53b617b2f8beb9c178abef9354d::fungible_asset_example::mint (447,523,437 samples, 0.81%) + + + +0x11043a7dcbc2d15b7d37cb307cda8c82dde4664d521e99fc7ddd3b7f5d029179::objects::create_objects (366,372,780 samples, 0.66%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::address_burn_from_for_gas (31,863,853 samples, 0.06%) + + + +0x581b3e873d7b39c4064141941ba74ccbdd673311a476116a09904f7e0287d247::smart_table_picture::create (11,793,960 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_withdraw (7,921,752 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (14,669,962 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (7,309,874 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::contains (427,093,719 samples, 0.77%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::borrow_mut (19,212,683 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object (25,878,537 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (285,717,684 samples, 0.52%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::borrow_mut (24,946,802 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,757,415 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::withdraw_token (75,632,078 samples, 0.14%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_deposit (16,764,409 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (16,103,040 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_governance::initialize_partial_voting (9,249,416 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (14,817,408 samples, 0.03%) + + + +0xef570729dd075b7d28b0fdd7f717ba0eebb17d87974b439ff952a0a845eb4423::vector_example::test_middle_move_range (841,318,071 samples, 1.52%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains_box (7,486,166 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add_or_upsert_impl (1,226,800,607 samples, 2.22%) +0.. + + +0x5e0de5290d2530a3729fff53b81d1795e3a3b71138732ae17bd5d713de8904b9::fungible_asset_example::init_module (5,031,374 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000004::property_map::prepare_input (9,446,748 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::exists_at (8,334,791 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::is_permissioned_signer (5,208,163 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (30,542,076 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::create_store (37,800,216 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_governance::initialize (28,486,871 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::module_event_migration_enabled (4,720,043 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add_or_upsert_impl (3,530,193,691 samples, 6.38%) +0x000000.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::internal_lower_bound (19,371,829 samples, 0.04%) + + + +0xac708b3a0f534018ceee7051284609e9bc1e53ebf549898a435db0f62e34c3f3::liquidity_pool::swap (514,755,106 samples, 0.93%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::code::check_dependencies (505,214,447 samples, 0.91%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::is_account_registered (22,773,454 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::withdraw_permission_check (26,598,363 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::is_permissioned_signer (16,460,880 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::module_event_migration_enabled (7,786,534 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (9,645,497 samples, 0.02%) + + + +0xa79008c2f80644b3281a33bb65b5235f72edc53b617b2f8beb9c178abef9354d::fungible_asset_example::mint_p (575,562,120 samples, 1.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow_box (9,763,831 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::replace_root (4,713,662 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::create_primary_store (136,233,571 samples, 0.25%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::internal_find (5,271,085 samples, 0.01%) + + + +0x11043a7dcbc2d15b7d37cb307cda8c82dde4664d521e99fc7ddd3b7f5d029179::coin_example::init_module (16,126,876 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_context::generate_unique_address (131,662,696 samples, 0.24%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::remove (9,366,563 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::is_lt (7,907,125 samples, 0.01%) + + + +0xac708b3a0f534018ceee7051284609e9bc1e53ebf549898a435db0f62e34c3f3::liquidity_pool_wrapper::initialize_liquid_pair (116,293,664 samples, 0.21%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (9,110,568 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::add (5,278,838 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::contains (36,306,694 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::deposit (57,657,282 samples, 0.10%) + + + +0xe971e2f18f362cc48d711134cf8b270c87f23e3304e340dc9b8d1b00704111d2::vector_picture::update (124,099,417 samples, 0.22%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,553,914 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_withdraw (8,047,661 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000004::token::generate_burn_ref (6,465,114 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow_mut (10,526,038 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_enabled (9,046,468 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (5,106,040 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow_box (5,834,783 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object (33,429,542 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (12,154,125 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_validation::unified_epilogue_v2 (139,108,517 samples, 0.25%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::mem::replace (7,102,295 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::remove (381,598,150 samples, 0.69%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,717,791 samples, 0.01%) + + + +0x581b3e873d7b39c4064141941ba74ccbdd673311a476116a09904f7e0287d247::smart_table_picture::update (3,972,636,764 samples, 7.18%) +0x581b3e8.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::primary_store_address (20,606,559 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::mint_token (457,328,853 samples, 0.83%) + + + +0xe971e2f18f362cc48d711134cf8b270c87f23e3304e340dc9b8d1b00704111d2::liquidity_pool::init_module (6,357,625 samples, 0.01%) + + + +0x1bcdc65264ff11e2aa76a2b53f3f46d6d456ada8f0722abe1fdb5fe4846df7c8::liquidity_pool::swap (484,727,077 samples, 0.88%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object (1,869,550,150 samples, 3.38%) +0x0.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_account_if_does_not_exist (5,597,758 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::iter_borrow (7,719,511 samples, 0.01%) + + + +0xa79008c2f80644b3281a33bb65b5235f72edc53b617b2f8beb9c178abef9354d::fungible_asset_example::init_module (5,128,201 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (1,560,303,744 samples, 2.82%) +0x.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::balance (42,939,838 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object (31,498,580 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::primary_store_address (29,675,160 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,533,919 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::exists_at (9,210,249 samples, 0.02%) + + + +0x24cebb88f7a868d50426d50348da168c020c925a04c67e65ea45d1adbc90db06::ambassador::create_ambassador_collection (7,009,291 samples, 0.01%) + + + +0x5cb9b3017d5a8b166c06d23575bba9498b86db361a599af889d5f833778c2ee9::objects::create_objects (289,916,335 samples, 0.52%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add_or_upsert_impl (42,802,155 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_hash::sip_hash_from_value (30,676,569 samples, 0.06%) + + + +0x8686c82863266f5134d9fd5311a94b423cb98288adebed635999db773f802688::token_v1::token_v1_create_token_data (26,158,460 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::remove_at (942,714,646 samples, 1.70%) + + + +0x1bcdc65264ff11e2aa76a2b53f3f46d6d456ada8f0722abe1fdb5fe4846df7c8::liquidity_pool::init_module (6,593,293 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow_box_mut (5,517,912 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::new_event_handle (108,878,469 samples, 0.20%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::stake::initialize_stake_owner (13,120,000 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::get_collection_supply (37,256,242 samples, 0.07%) + + + +0xef570729dd075b7d28b0fdd7f717ba0eebb17d87974b439ff952a0a845eb4423::fungible_asset_example::init_module (4,845,168 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,228,123 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::remove (338,338,125 samples, 0.61%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,472,416 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (8,202,968 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit_event (565,830,735 samples, 1.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000007::confidential_asset::init_module_for_genesis (91,181,499 samples, 0.16%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow (46,956,116 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::balance (51,124,216 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (12,199,240 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add (7,882,952 samples, 0.01%) + + + +0x2ef39d4b60160509cac7019488190e7bec3d5e24372784a9687cf4267c6c4fcc::coin_example::init_module (16,588,791 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,605,543 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (16,590,332 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_permissioned_signer_enabled (4,791,208 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::iter_is_begin (19,868,942 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (70,304,319 samples, 0.13%) + + + +0x0bf2450c78e7bc920d729214d7a327451a2cceda5bf27ef7e0311b0ceb41124f::fungible_asset_example::init_module (4,962,537 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_permissioned_signer_enabled (4,918,828 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::deposit_dispatch_function (5,359,837 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::remove_at (17,178,116 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::primary_store_address (19,019,966 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::load_factor (9,345,592 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_guid (64,202,030 samples, 0.12%) + + + +0x1bcdc65264ff11e2aa76a2b53f3f46d6d456ada8f0722abe1fdb5fe4846df7c8::liquidity_pool_wrapper::swap (1,252,000,252 samples, 2.26%) +0.. + + +0x0000000000000000000000000000000000000000000000000000000000000003::property_map::empty (5,060,446 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::add_link (5,080,879 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (12,409,250 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::generate_signer (12,160,026 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (12,669,386 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::upsert (8,557,952 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::borrow_mut (55,500,189 samples, 0.10%) + + + +0xac708b3a0f534018ceee7051284609e9bc1e53ebf549898a435db0f62e34c3f3::liquidity_pool::mint (13,650,826 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::balance_impl (6,528,255 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_address (16,049,919 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow_mut (20,321,188 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::deposit_sanity_check (14,946,633 samples, 0.03%) + + + +0xa79008c2f80644b3281a33bb65b5235f72edc53b617b2f8beb9c178abef9354d::fungible_asset_example::get_metadata (58,658,712 samples, 0.11%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (7,883,663 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::reserve_slot (18,492,603 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::primary_store_exists (51,111,166 samples, 0.09%) + + + +0x5cb9b3017d5a8b166c06d23575bba9498b86db361a599af889d5f833778c2ee9::coin_example::init_module (16,215,624 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::increase_supply (5,910,326 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_deposit (7,594,085 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::option::extract (5,204,373 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_account::is_fungible_balance_at_least (19,370,834 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::compare (13,684,191 samples, 0.02%) + + + +all (55,346,729,665 samples, 100%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::grant_apt_permission (345,086,930 samples, 0.62%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,965,335 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::destroy_empty (30,975,007 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::code::publish_package (1,059,047,085 samples, 1.91%) +0.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::check_permission_capacity_above (13,415,012 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains_box (9,436,793 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (8,103,158 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::create_tokendata (19,333,669 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::iter_is_begin (24,278,838 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::new_event_handle (10,609,491 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::string::append_utf8 (12,110,077 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (21,118,886 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,674,500 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::is_lt (12,677,310 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_hash::sip_hash_from_value (48,013,171 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::object_from_constructor_ref (4,734,950 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::simple_map::remove (337,409,385 samples, 0.61%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::borrow_mut (108,203,443 samples, 0.20%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_default_account_resource_enabled (18,218,578 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (4,693,774 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::is_empty (9,669,835 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize_internal (4,805,542 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::has_balance_dispatch_function (15,794,833 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (8,421,831 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::initialize_token_store (171,966,413 samples, 0.31%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::genesis::initialize_core_resources_and_aptos_coin (156,802,884 samples, 0.28%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains_box (6,192,375 samples, 0.01%) + + + +0xeb90dbea041a49287e12af1e523f50efded889ca5fcd470998fbe7bb3bc563b9::coin_example::init_module (16,830,336 samples, 0.03%) + + + +0x8686c82863266f5134d9fd5311a94b423cb98288adebed635999db773f802688::token_v1::token_v1_mint_and_transfer_ft (1,150,613,726 samples, 2.08%) +0.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_guid (6,307,335 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::trim (9,045,474 samples, 0.02%) + + + +0xe7de0ac63e1bdaadb9400daa013a754bbdd16faa7de47cfca3f2ef6bb5d893fe::coin_example::init_module (16,771,582 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_guid (4,697,158 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (4,722,831 samples, 0.01%) + + + +0x266bd01f3c436c20be957674405563323c71f2c7df612638136b2d9d3689fc37::fungible_asset_example::init_module (4,932,707 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (194,326,076 samples, 0.35%) + + + +0x14171b275ed8de29a4b4b4fa3c178ca317f16481432d150d42889c4d5f2b0e8b::vector_example::generate_vec (184,636,958 samples, 0.33%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::reconfiguration::initialize (33,146,455 samples, 0.06%) + + + +0x9b435da8729de6ea9e0106d5d47e442100f9829cc4d6b4755421dcd2e69e247c::vector_example::generate_vec (186,464,835 samples, 0.34%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add (4,589,393,082 samples, 8.29%) +0x000000000.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (33,900,397 samples, 0.06%) + + + +0x8686c82863266f5134d9fd5311a94b423cb98288adebed635999db773f802688::token_v1::get_signer (12,366,245 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_guid (63,541,048 samples, 0.11%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::aggregator_v2_is_at_least_api_enabled (7,668,344 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::default_to_concurrent_fungible_balance_enabled (5,042,249 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::remove_and_reserve (31,629,774 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::mint (21,502,123 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (12,508,668 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (9,704,757 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::is_lt (13,752,811 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::check_permission_consume (15,428,407 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_deposit (9,689,450 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::borrow_mut (46,951,305 samples, 0.08%) + + + +0xe6cb3c664eaf640e1a834bdb9e7c500df2b6de51018258037f6303856758e0df::token_v1::mint_nft_sequential (905,870,822 samples, 1.64%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::next_slot_index (7,054,962 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::owns (8,201,837 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,515,377 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::decimals (6,158,504 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_context::generate_auid_address (341,860,114 samples, 0.62%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::has_balance_dispatch_function (13,639,742 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::simple_map::find (133,255,892 samples, 0.24%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::withdraw (96,997,925 samples, 0.18%) + + + +0x46f904440346ac55c23e48f1c080426cbc973b8bb268d8482b48502e02b23e86::vector_example::generate_vec (9,363,750 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow (25,950,502 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (175,471,851 samples, 0.32%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::is_coin_initialized (12,585,412 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::withdraw (90,525,296 samples, 0.16%) + + + +0x504281e16926b35e2e0b22d9c9724346f326530e04f032c9da0f7715984d7baa::coin_example::init_module (16,290,251 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::new_with_config (6,692,048 samples, 0.01%) + + + +0x1bcdc65264ff11e2aa76a2b53f3f46d6d456ada8f0722abe1fdb5fe4846df7c8::liquidity_pool::mint (14,982,042 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::bucket_index (6,478,001 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::property_map::empty (5,279,219 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,747,335 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::internal_lower_bound (8,567,009 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::remove (83,741,082 samples, 0.15%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_permissioned_signer_enabled (4,950,748 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::create_permissioned_handle (114,719,846 samples, 0.21%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::module_event_migration_enabled (4,762,161 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (13,067,006 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add_or_upsert_impl (25,611,035 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_fee::burn_fee (64,762,402 samples, 0.12%) + + + +0x504281e16926b35e2e0b22d9c9724346f326530e04f032c9da0f7715984d7baa::maps_example::test_add_remove_big_ordered_map (8,555,122,898 samples, 15.46%) +0x504281e16926b35e2e0b2.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::address_to_object (11,132,663 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,921,042 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_default_account_resource_enabled (4,819,750 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::direct_deposit (49,142,634 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::find_leaf_path (662,382,985 samples, 1.20%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::validate_static_size_and_init_max_degrees (7,816,396 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (51,143,688 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::burn_internal (8,210,463 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::insert (208,965,219 samples, 0.38%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (159,486,278 samples, 0.29%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow_mut (28,153,742 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (7,265,709 samples, 0.01%) + + + +0x3257ababdfa165c9b16f8f2a2d2dec58c83dcdea9bdf550c7c60f4b6b5b06feb::vector_picture::create (83,779,366 samples, 0.15%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (9,232,873 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::internal_find (56,836,669 samples, 0.10%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::transfer_with_ref (22,053,851 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::find_leaf_path (1,181,338,731 samples, 2.13%) +0.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_enabled (9,220,166 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (6,207,702 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::check_permission_exists (18,396,471 samples, 0.03%) + + + +0x12e644495af037e00e2e2a31a5627184d2e26cbf0fe27f790c837f71d4203cd7::coin_example::init_module (16,513,042 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (9,041,126 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::new (4,963,420 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_enabled (6,177,950 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::initialize_token_store (159,663,055 samples, 0.29%) + + + +0x12e644495af037e00e2e2a31a5627184d2e26cbf0fe27f790c837f71d4203cd7::vector_example::generate_vec (118,852,748 samples, 0.21%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (9,950,724 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::ensure_paired_metadata (350,519,725 samples, 0.63%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::create_primary_store_enabled_fungible_asset (15,526,331 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::load_factor (5,983,931 samples, 0.01%) + + + +0x24cebb88f7a868d50426d50348da168c020c925a04c67e65ea45d1adbc90db06::ambassador::mint_numbered_ambassador_token (708,783,593 samples, 1.28%) + + + +0x6fc74285e11f81e966c7d67d62f2ad4bad4c662116a672c8d603db309c946e22::coin_example::init_module (17,717,916 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (9,165,823 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::create_guid (61,357,007 samples, 0.11%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (7,512,292 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::option::borrow (8,532,015 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::code::publish_package_txn (1,595,342,084 samples, 2.88%) +0x.. + + +0x9b435da8729de6ea9e0106d5d47e442100f9829cc4d6b4755421dcd2e69e247c::coin_example::init_module (16,150,585 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object (22,926,797 samples, 0.04%) + + + +0x5e0de5290d2530a3729fff53b81d1795e3a3b71138732ae17bd5d713de8904b9::coin_example::mint_p (1,731,472,453 samples, 3.13%) +0x5.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::remove_link (5,359,836 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::iter_prev (47,650,615 samples, 0.09%) + + + +0x04e9cdcbe92ada7e1ea7f688f4018caa2ed11dd6e0fb47955346bf302a767408::vector_example::generate_vec (189,177,417 samples, 0.34%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,881,290 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::withdraw_permission_check (24,900,964 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (110,750,182 samples, 0.20%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::primary_store_address (21,958,884 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (5,001,254 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_account::burn_from_fungible_store_for_gas (49,355,730 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::option::destroy_none (7,400,981 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::string::append (5,297,665 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_validation::check_for_replay_protection_regular_txn (14,447,913 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (17,828,457 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::borrow (110,921,803 samples, 0.20%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,808,791 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::primary_store_exists (55,461,247 samples, 0.10%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::internal_lower_bound (228,073,104 samples, 0.41%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (15,488,043 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_context::generate_unique_address (12,846,873 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize_internal (9,134,208 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (162,191,948 samples, 0.29%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::check_permission_consume (16,472,277 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object (185,456,332 samples, 0.34%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::append (147,198,737 samples, 0.27%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::direct_transfer (456,909,641 samples, 0.83%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::is_lt (11,738,712 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::borrow_mut (43,778,045 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (6,901,503 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::insert (51,873,119 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (8,664,162 samples, 0.02%) + + + +0xac708b3a0f534018ceee7051284609e9bc1e53ebf549898a435db0f62e34c3f3::liquidity_pool_wrapper::create_pool (63,712,378 samples, 0.12%) + + + +0xe971e2f18f362cc48d711134cf8b270c87f23e3304e340dc9b8d1b00704111d2::vector_picture::create (88,295,167 samples, 0.16%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,431,627 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (20,546,996 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::stake::initialize_pending_transaction_fee (36,511,624 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object (30,738,502 samples, 0.06%) + + + +0x2ef39d4b60160509cac7019488190e7bec3d5e24372784a9687cf4267c6c4fcc::vector_example::test_trim_append (178,992,255 samples, 0.32%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::check_permission_consume (7,935,621 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::add_link (17,548,586 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::create_tokendata (19,417,084 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow_mut (8,778,100 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_account::is_fungible_balance_at_least (15,037,165 samples, 0.03%) + + + +0xe6cb3c664eaf640e1a834bdb9e7c500df2b6de51018258037f6303856758e0df::token_v1::token_v1_create_token_data (26,047,210 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (7,330,001 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::is_lt (11,688,037 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::bucket_index (5,239,675 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::generate_burn_ref (6,419,036 samples, 0.01%) + + + +0xac708b3a0f534018ceee7051284609e9bc1e53ebf549898a435db0f62e34c3f3::liquidity_pool_wrapper::swap (1,247,714,755 samples, 2.25%) +0.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (19,375,456 samples, 0.04%) + + + +0x3e7fd217c1367d4e80c278d1266607957da657dfa48db8016b2096419a37fe3e::coin_example::init_module (16,300,252 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::ensure_primary_store_exists (213,344,873 samples, 0.39%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,364,456 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (5,087,671 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::add (9,972,376 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::check_permission_consume (15,425,007 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (5,178,461 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::borrow_mut (20,965,474 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::remove (13,911,945 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::timestamp::now_seconds (4,935,294 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::default_to_concurrent_fungible_balance_enabled (5,121,623 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::is_permissioned_signer (9,606,534 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::object_from_constructor_ref (4,734,052 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (18,870,780 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_default_account_resource_enabled (18,467,547 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::simple_map::add (794,092,857 samples, 1.43%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::initialize_token_store (156,966,298 samples, 0.28%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::add (669,594,044 samples, 1.21%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::is_permissioned_signer (17,439,185 samples, 0.03%) + + + +0xbc7c15e7eb9f4083c80f330a8e5d48344af530b6306aec6583a02dbcc0128fed::smart_table_picture::update (2,303,191,819 samples, 4.16%) +0xbc.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::option::borrow (4,722,580 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::balance_of (9,524,714 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::string::append (5,147,750 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (5,116,247 samples, 0.01%) + + + +0xe6cb3c664eaf640e1a834bdb9e7c500df2b6de51018258037f6303856758e0df::token_v1::build_token_name (30,704,695 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::ensure_primary_store_exists (191,137,561 samples, 0.35%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,717,002 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::initialize_token_store (174,013,515 samples, 0.31%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::compare (8,561,037 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::internal_new_begin_iter (20,815,591 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::deposit (329,533,242 samples, 0.60%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (4,820,412 samples, 0.01%) + + + +0x266bd01f3c436c20be957674405563323c71f2c7df612638136b2d9d3689fc37::vector_example::test_remove_insert (1,430,756,024 samples, 2.59%) +0x.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains_box (6,220,041 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::pop_front (57,633,238 samples, 0.10%) + + + +0x46f904440346ac55c23e48f1c080426cbc973b8bb268d8482b48502e02b23e86::coin_example::init_module (16,627,956 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::add (34,742,826 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::balance (69,850,749 samples, 0.13%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::borrow (67,087,119 samples, 0.12%) + + + +0x8686c82863266f5134d9fd5311a94b423cb98288adebed635999db773f802688::token_v1::token_v1_initialize_collection (59,675,881 samples, 0.11%) + + + +0x19dea829a84271dcd892c174870c63d5c1baba99ddb952216d5b5815f4296f60::maps_example::test_add_remove_ordered_map (5,716,835,651 samples, 10.33%) +0x19dea829a8427.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::new_event_handle (101,878,592 samples, 0.18%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_coin::initialize (36,720,457 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::remove_and_reserve (8,617,169 samples, 0.02%) + + + +0x5e0de5290d2530a3729fff53b81d1795e3a3b71138732ae17bd5d713de8904b9::coin_example::init_module (17,218,208 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_permissioned_signer_enabled (4,708,084 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,836,001 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (46,750,133 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_address (16,387,553 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::guid::create (43,287,749 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (11,700,173 samples, 0.02%) + + + +0x04e9cdcbe92ada7e1ea7f688f4018caa2ed11dd6e0fb47955346bf302a767408::coin_example::init_module (16,832,209 samples, 0.03%) + + + +0x594e3921c57b1380975ada61d3a574551a5f7df189876dbbd87dff82cda4f982::liquidity_pool::init_module (5,828,250 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::deposit (61,585,954 samples, 0.11%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (14,795,766 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::burn (22,560,722 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (15,722,535 samples, 0.03%) + + + +0x2ef39d4b60160509cac7019488190e7bec3d5e24372784a9687cf4267c6c4fcc::fungible_asset_example::init_module (6,187,043 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (7,969,422 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::deposit_dispatch_function (4,833,791 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (5,245,706 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::aggregator_v2_is_at_least_api_enabled (12,643,738 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aggregator_v2::is_at_least (15,767,346 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::deposit (7,170,837 samples, 0.01%) + + + +0x1bcdc65264ff11e2aa76a2b53f3f46d6d456ada8f0722abe1fdb5fe4846df7c8::liquidity_pool_wrapper::initialize_liquid_pair (129,691,259 samples, 0.23%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::object_from_constructor_ref (4,750,626 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,718,417 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_permissioned_signer_enabled (5,399,508 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::name (6,266,363 samples, 0.01%) + + + +0x1195cf41798980141fb20a57d8d9e123a210f80180fbe2d307379cab0ed4b27c::vector_example::generate_vec (18,813,830 samples, 0.03%) + + + +0x1bcdc65264ff11e2aa76a2b53f3f46d6d456ada8f0722abe1fdb5fe4846df7c8::liquidity_pool::get_amount_out (97,757,227 samples, 0.18%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::remove (12,170,599 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::increase_supply (6,454,452 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::genesis::initialize (227,504,870 samples, 0.41%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (12,519,749 samples, 0.02%) + + + +0x51cfa95373b018c7bf7f137a2a93a780d5fa4b2de19f46625e37eebff461f3a3::vector_picture::check (123,190,291 samples, 0.22%) + + + +0x14171b275ed8de29a4b4b4fa3c178ca317f16481432d150d42889c4d5f2b0e8b::vector_example::test_trim_append (371,482,374 samples, 0.67%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::new_event_handle (100,172,878 samples, 0.18%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_deposit (10,246,289 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::create_primary_store (108,530,261 samples, 0.20%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::validate_dynamic_size_and_init_max_degrees (9,902,548 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::borrow_mut (18,168,582 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::contains (35,162,999 samples, 0.06%) + + + +0x04e9cdcbe92ada7e1ea7f688f4018caa2ed11dd6e0fb47955346bf302a767408::vector_example::test_trim_append (1,111,354,625 samples, 2.01%) +0.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::create_store (37,624,807 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (4,817,753 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::is_lt (20,764,828 samples, 0.04%) + + + +0x594e3921c57b1380975ada61d3a574551a5f7df189876dbbd87dff82cda4f982::vector_picture::create (601,775,667 samples, 1.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::insert (56,370,441 samples, 0.10%) + + + +0xe6cb3c664eaf640e1a834bdb9e7c500df2b6de51018258037f6303856758e0df::token_v1::token_v1_create_token_data (167,016,707 samples, 0.30%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::property_map::new (9,883,258 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (6,657,007 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::add (3,442,740,360 samples, 6.22%) +0x000000.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::is_permissioned_signer_enabled (4,768,379 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::iter_is_begin (7,624,564 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::deposit (1,085,484,621 samples, 1.96%) +0.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,605,585 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::object_native_derived_address_enabled (7,552,045 samples, 0.01%) + + + +0xa79008c2f80644b3281a33bb65b5235f72edc53b617b2f8beb9c178abef9354d::coin_example::init_module (17,524,499 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (11,413,293 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::new_event_handle (23,091,560 samples, 0.04%) + + + +0x1bcdc65264ff11e2aa76a2b53f3f46d6d456ada8f0722abe1fdb5fe4846df7c8::liquidity_pool_wrapper::add_liquidity (20,089,376 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::deposit (353,457,655 samples, 0.64%) + + + +0x504281e16926b35e2e0b22d9c9724346f326530e04f032c9da0f7715984d7baa::fungible_asset_example::init_module (5,181,335 samples, 0.01%) + + + +0x9948f11daa6050176be4906927851f6b223ce0337a070694ca43885d6a821668::coin_example::init_module (17,745,459 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::internal_lower_bound (22,345,414 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (5,038,834 samples, 0.01%) + + + +0x581b3e873d7b39c4064141941ba74ccbdd673311a476116a09904f7e0287d247::liquidity_pool::init_module (6,634,000 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (19,268,592 samples, 0.03%) + + + +0x46f904440346ac55c23e48f1c080426cbc973b8bb268d8482b48502e02b23e86::vector_example::test_trim_append (730,259,441 samples, 1.32%) + + + +0x3e7fd217c1367d4e80c278d1266607957da657dfa48db8016b2096419a37fe3e::resource_groups_example::set_3 (35,615,989 samples, 0.06%) + + + +0x374c567d86c4bfbe7b22224a6a9efe2311b93d7115b349f68596e15bbde1f7cf::counter_with_milestone::increment_milestone (51,413,955 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_internal (8,284,209 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::create_pairing (52,516,710 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000004::collection::increment_supply (20,529,967 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::stored_to_index (7,319,445 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_withdraw (7,736,792 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::binary_search (311,816,327 samples, 0.56%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (12,464,333 samples, 0.02%) + + + +0x9948f11daa6050176be4906927851f6b223ce0337a070694ca43885d6a821668::objects::create_objects (2,870,535,384 samples, 5.19%) +0x9948.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::insert (85,752,543 samples, 0.15%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::bucket_index (5,070,029 samples, 0.01%) + + + +0xef570729dd075b7d28b0fdd7f717ba0eebb17d87974b439ff952a0a845eb4423::vector_example::generate_vec (238,084,206 samples, 0.43%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::remove (10,659,120 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::owns (7,676,743 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::decrease_supply (7,158,171 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains (7,474,875 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object (28,489,145 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,797,542 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::features::default_to_concurrent_fungible_balance_enabled (5,241,053 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::borrow_mut (8,603,968 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::new_with_config (35,180,929 samples, 0.06%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,790,209 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains_box (7,349,584 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::register (91,495,457 samples, 0.17%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_deposit (18,067,318 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::internal_find (16,200,400 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::borrow (134,493,995 samples, 0.24%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object (210,798,431 samples, 0.38%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::is_permissioned_signer (9,647,877 samples, 0.02%) + + + +0xe6cb3c664eaf640e1a834bdb9e7c500df2b6de51018258037f6303856758e0df::token_v1::token_v1_initialize_collection (59,602,002 samples, 0.11%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (7,220,541 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::bucket_index (8,167,946 samples, 0.01%) + + + +0xbc7c15e7eb9f4083c80f330a8e5d48344af530b6306aec6583a02dbcc0128fed::liquidity_pool::init_module (6,445,501 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (20,427,429 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,997,999 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table::contains_box (5,163,206 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::unchecked_deposit (7,326,215 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000004::property_map::add_typed (46,862,222 samples, 0.08%) + + + +0x0000000000000000000000000000000000000000000000000000000000000004::property_map::init (5,432,788 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::balance_of (9,787,812 samples, 0.02%) + + + +0xcc06ae22a4425ea36680d3df96c0ccc98f3e5c9c43771ddeda0506656fda5eb7::simple::emit_events (1,066,172,614 samples, 1.93%) +0.. + + +0x0000000000000000000000000000000000000000000000000000000000000001::big_ordered_map::add_or_upsert_impl (5,562,745 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::fill_reserved_slot (7,476,506 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_coin::configure_accounts_for_test (10,440,090 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::balance (68,824,876 samples, 0.12%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (12,887,709 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::string::utf8 (5,586,498 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::new_event_handle (10,602,629 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_context::generate_unique_address (14,454,537 samples, 0.03%) + + + +0xe1367aab40e405230929737f522f7c13a9c4d85667aef12054ed1f89584d87aa::liquidity_pool::init_module (6,811,666 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::cmp::is_lt (112,828,915 samples, 0.20%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (6,980,249 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_user_derived_object_address (6,885,251 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (5,048,167 samples, 0.01%) + + + +0x4e2ca9154fea8f1bf409b19a7df42313447c3c232245e4efb030b8f668c26f70::simple::loop_nop (948,994,668 samples, 1.71%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::add (432,148,324 samples, 0.78%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::account::new_event_handle (107,891,239 samples, 0.19%) + + + +0x24cebb88f7a868d50426d50348da168c020c925a04c67e65ea45d1adbc90db06::ambassador::init_module (9,129,083 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::managed_coin::initialize (12,423,583 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::primary_fungible_store::deposit (326,222,604 samples, 0.59%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::transaction_context::generate_auid_address (37,427,648 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::storage_slots_allocator::fill_reserved_slot (90,807,209 samples, 0.16%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::event::emit (6,735,846 samples, 0.01%) + + + +0x63ca834489731b89c8f75e63a4fc65cfea775d20c69d0ec65fa105329715121b::liquidity_pool::init_module (5,788,376 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::balance_impl (11,352,312 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::contains (732,646,955 samples, 1.32%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aptos_account::fungible_transfer_only (344,527,713 samples, 0.62%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::create_store (36,220,615 samples, 0.07%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::smart_table::split_one_bucket (51,435,746 samples, 0.09%) + + + +0xac708b3a0f534018ceee7051284609e9bc1e53ebf549898a435db0f62e34c3f3::liquidity_pool_wrapper::add_liquidity (18,331,243 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::add (4,747,413 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::internal_lower_bound (30,369,520 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::assert_master_signer (14,625,585 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::authorize_increase (191,420,521 samples, 0.35%) + + + +0xe1367aab40e405230929737f522f7c13a9c4d85667aef12054ed1f89584d87aa::vector_picture::check (8,497,083 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000003::token::create_tokendata (105,625,738 samples, 0.19%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::dispatchable_fungible_asset::deposit (49,685,000 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::simple_map::add (7,966,529 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::permissioned_signer::check_permission_consume (162,571,811 samples, 0.29%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::trim (158,698,179 samples, 0.29%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::object_from_constructor_ref (4,894,204 samples, 0.01%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::fungible_asset::mint (21,497,452 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::ordered_map::iter_prev (14,932,184 samples, 0.03%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::aggregator_v2::is_at_least (25,519,455 samples, 0.05%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::swap_remove (9,347,241 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object_address (13,215,549 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::singleton (23,740,641 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::table_with_length::borrow_mut (48,386,422 samples, 0.09%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::object::create_object (22,601,661 samples, 0.04%) + + + +0x1195cf41798980141fb20a57d8d9e123a210f80180fbe2d307379cab0ed4b27c::vector_example::test_middle_move_range (350,396,776 samples, 0.63%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::move_range (20,914,813 samples, 0.04%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::vector::is_empty (11,888,300 samples, 0.02%) + + + +0x0000000000000000000000000000000000000000000000000000000000000001::coin::initialize (7,308,749 samples, 0.01%) + + + diff --git a/third_party/move/move-vm/profiler/fold.awk b/third_party/move/move-vm/profiler/fold.awk new file mode 100644 index 00000000000..91a355f2761 --- /dev/null +++ b/third_party/move/move-vm/profiler/fold.awk @@ -0,0 +1,20 @@ +BEGIN { + depth = 0 +} + +$1 == "BEGIN" { + stack[depth] = $2 + depth++ +} + +$1 == "END" { + # print current stack + out = stack[0] + for (i = 1; i < depth; i++) { + out = out ";" stack[i] + } + print out, $2 + + # pop + depth-- +} diff --git a/third_party/move/move-vm/profiler/profile.sh b/third_party/move/move-vm/profiler/profile.sh new file mode 100755 index 00000000000..aa7031d611e --- /dev/null +++ b/third_party/move/move-vm/profiler/profile.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +set -euo pipefail + +############################################# +# CONFIG +############################################# + +SCRIPT_DIR="$(dirname $0)" + +BIN_PATH=$1 +TRACE_SCRIPT="$SCRIPT_DIR/trace.d" +FOLD_SCRIPT="$SCRIPT_DIR/fold.awk" + +OUT_RAW=$(mktemp /tmp/dtrace-raw.XXXXXX) +OUT_FOLDED=$(mktemp /tmp/dtrace-folded.XXXXXX) +OUT_SVG="flame.svg" + +############################################# +# LOGGING +############################################# + +red() { printf '\033[31m%s\033[0m\n' "$*" >&2; } +green() { printf '\033[32m%s\033[0m\n' "$*" >&2; } +yellow() { printf '\033[33m%s\033[0m\n' "$*" >&2; } +blue() { printf '\033[34m%s\033[0m\n' "$*" >&2; } + +log() { blue "==> $*"; } + +############################################# +# TOOL CHECKING +############################################# + +require() { + if ! command -v "$1" >/dev/null 2>&1; then + red "Error: '$1' not found in PATH" + exit 1 + fi +} + +require awk +require flamegraph.pl + +############################################# +# CLEANUP +############################################# + +TARGET_PID="" + +cleanup() { + # Kill the benchmark program if it's still alive + if [[ -n "${TARGET_PID:-}" ]] && kill -0 "$TARGET_PID" 2>/dev/null; then + yellow "Stopping benchmark (PID $TARGET_PID)…" + kill "$TARGET_PID" 2>/dev/null || true + wait "$TARGET_PID" 2>/dev/null || true + fi + + # Remove temporary files + [[ -f "${OUT_RAW:-}" ]] && rm -f "$OUT_RAW" + [[ -f "${OUT_FOLDED:-}" ]] && rm -f "$OUT_FOLDED" +} +trap cleanup EXIT + +############################################# +# MAIN WORKFLOW +############################################# + +log "Starting benchmark with tracing…" +sudo dtrace -q -s "$TRACE_SCRIPT" -c "$BIN_PATH" > "$OUT_RAW" + +log "Folding stack output…" +awk -f "$FOLD_SCRIPT" "$OUT_RAW" > "$OUT_FOLDED" + +log "Generating flamegraph…" +flamegraph.pl "$OUT_FOLDED" > "$OUT_SVG" + +green "Done!" +green "Flamegraph written to: $OUT_SVG" diff --git a/third_party/move/move-vm/profiler/src/lib.rs b/third_party/move/move-vm/profiler/src/lib.rs new file mode 100644 index 00000000000..369346e208c --- /dev/null +++ b/third_party/move/move-vm/profiler/src/lib.rs @@ -0,0 +1,110 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use move_vm_types::instr::Instruction; +use once_cell::sync::Lazy; +#[cfg(feature = "probe-profiler")] +use probe::ProbeProfiler; + +#[cfg(feature = "probe-profiler")] +pub mod probe; + +#[cfg(feature = "probe-profiler")] +pub type ActiveProfiler = ProbeProfiler; + +#[cfg(not(feature = "probe-profiler"))] +pub type ActiveProfiler = NoopProfiler; + +pub type FnGuard = ::FnGuard; + +pub static VM_PROFILER: Lazy = Lazy::new(ActiveProfiler::default); + +/// A function that can be profiled. +pub trait ProfilerFunction { + fn name(&self) -> String; +} + +/// An instruction that can be profiled. +pub trait ProfilerInstruction { + fn name(&self) -> String; +} + +impl ProfilerInstruction for Instruction { + fn name(&self) -> String { + self.name().to_string() + } +} + +/// A profiler for Move VM execution. +pub trait Profiler { + type FnGuard; + type InstrGuard; + + /// Start profiling a function and return a guard. + /// The guard ends profiling when dropped, so it should be held for the duration of the function execution. + fn function_start(&self, function: &F) -> Self::FnGuard + where + F: ProfilerFunction; + + /// Start profiling an instruction and return a guard. + /// The guard ends profiling when dropped, so it should be held for the duration of the instruction execution. + fn instruction_start(&self, instruction: &I) -> Self::InstrGuard + where + I: ProfilerInstruction; +} + +pub struct NoopFnGuard; +pub struct NoopInstrGuard; + +/// A no-op profiler that does nothing. +#[derive(Default)] +pub struct NoopProfiler; + +impl Profiler for NoopProfiler { + type FnGuard = NoopFnGuard; + type InstrGuard = NoopInstrGuard; + + fn function_start(&self, _function: &F) -> Self::FnGuard + where + F: ProfilerFunction, + { + NoopFnGuard + } + + fn instruction_start(&self, _instruction: &I) -> Self::InstrGuard + where + I: ProfilerInstruction, + { + NoopInstrGuard + } +} + +#[cfg(test)] +mod tests { + use crate::{Profiler, ProfilerFunction, VM_PROFILER}; + use move_vm_types::instr::Instruction; + use std::{thread::sleep, time::Duration}; + + struct DummyFunction<'a>(&'a str); + + impl ProfilerFunction for DummyFunction<'_> { + fn name(&self) -> String { + self.0.to_string() + } + } + + #[test] + fn test_profiler() { + let _fg = VM_PROFILER.function_start(&DummyFunction("foo")); + sleep(Duration::from_millis(100)); + execute_instruction(&Instruction::And); + execute_instruction(&Instruction::Or); + execute_instruction(&Instruction::Not); + sleep(Duration::from_millis(100)); + } + + fn execute_instruction(instr: &Instruction) { + let _ig = VM_PROFILER.instruction_start(instr); + sleep(Duration::from_millis(100)); + } +} diff --git a/third_party/move/move-vm/profiler/src/probe.rs b/third_party/move/move-vm/profiler/src/probe.rs new file mode 100644 index 00000000000..9d2ce123f80 --- /dev/null +++ b/third_party/move/move-vm/profiler/src/probe.rs @@ -0,0 +1,107 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{Profiler, ProfilerFunction, ProfilerInstruction}; +use std::time::Instant; + +#[usdt::provider] +mod vm_profiler { + fn function_entry(function_name: String) {} + fn function_exit(nanos: u64) {} + + fn instruction_entry(instruction_name: String) {} + fn instruction_exit(nanos: u64) {} +} + +/// A profiler that emits USDT (Userland Statically Defined Tracing) probes. +/// See [usdt](https://crates.io/crates/usdt) for more details. +/// +/// It emits the following probes for function and instruction entry/exit: +/// - `function_entry(function_name: String)` +/// - `function_exit(nanos: u64)` +/// - `instruction_entry(instruction_name: String)` +/// - `instruction_exit(nanos: u64)` +/// Note that the exit probes include the elapsed time in nanoseconds. +pub struct ProbeProfiler; + +impl Default for ProbeProfiler { + fn default() -> Self { + usdt::register_probes().expect("Failed to register probes"); + Self + } +} + +impl Profiler for ProbeProfiler { + type FnGuard = ProbeFnGuard; + type InstrGuard = ProbeInstrGuard; + + #[inline] + fn function_start(&self, function: &F) -> Self::FnGuard + where + F: ProfilerFunction, + { + ProbeFnGuard::new(function) + } + + #[inline] + fn instruction_start(&self, instruction: &I) -> Self::InstrGuard + where + I: ProfilerInstruction, + { + ProbeInstrGuard::new(instruction) + } +} + +pub struct ProbeFnGuard { + start: Instant, +} + +impl ProbeFnGuard { + #[must_use] + fn new(function: &F) -> Self + where + F: ProfilerFunction, + { + vm_profiler::function_entry!(|| function.name()); + + Self { + start: Instant::now(), + } + } +} + +impl Drop for ProbeFnGuard { + fn drop(&mut self) { + vm_profiler::function_exit!(|| { + let dt = self.start.elapsed(); + dt.as_nanos() as u64 + }); + } +} + +pub struct ProbeInstrGuard { + start: Instant, +} + +impl ProbeInstrGuard { + #[must_use] + fn new(instruction: &I) -> Self + where + I: ProfilerInstruction, + { + vm_profiler::instruction_entry!(|| instruction.name()); + + Self { + start: Instant::now(), + } + } +} + +impl Drop for ProbeInstrGuard { + fn drop(&mut self) { + vm_profiler::instruction_exit!(|| { + let dt = self.start.elapsed(); + dt.as_nanos() as u64 + }); + } +} diff --git a/third_party/move/move-vm/profiler/trace.d b/third_party/move/move-vm/profiler/trace.d new file mode 100644 index 00000000000..f69a5db0864 --- /dev/null +++ b/third_party/move/move-vm/profiler/trace.d @@ -0,0 +1,13 @@ +#pragma D + +/* Function probes */ + +vm_profiler*:::function_entry +{ + printf("BEGIN %s\n", copyinstr(arg0)); +} + +vm_profiler*:::function_exit +{ + printf("END %llu\n", (unsigned long long)arg0); +} diff --git a/third_party/move/move-vm/runtime/Cargo.toml b/third_party/move/move-vm/runtime/Cargo.toml index 28cf60dce0e..0e166f99af0 100644 --- a/third_party/move/move-vm/runtime/Cargo.toml +++ b/third_party/move/move-vm/runtime/Cargo.toml @@ -28,6 +28,7 @@ move-binary-format = { workspace = true } move-bytecode-verifier = { workspace = true } move-core-types = { workspace = true } move-vm-metrics = { workspace = true } +move-vm-profiler = { workspace = true } move-vm-types = { workspace = true } once_cell = { workspace = true } parking_lot = { workspace = true } @@ -52,6 +53,7 @@ test-case = { workspace = true } default = [ "inline-callstack", ] +profiling = ["move-vm-profiler/probe-profiler"] testing = [] fuzzing = ["move-vm-types/fuzzing"] failpoints = ["fail/failpoints"] diff --git a/third_party/move/move-vm/runtime/src/debug.rs b/third_party/move/move-vm/runtime/src/debug.rs index 286d6c8c733..068d81766eb 100644 --- a/third_party/move/move-vm/runtime/src/debug.rs +++ b/third_party/move/move-vm/runtime/src/debug.rs @@ -2,10 +2,11 @@ // Copyright (c) The Move Contributors // SPDX-License-Identifier: Apache-2.0 -use crate::{ - instr::Instruction, interpreter::InterpreterDebugInterface, LoadedFunction, RuntimeEnvironment, +use crate::{interpreter::InterpreterDebugInterface, LoadedFunction, RuntimeEnvironment}; +use move_vm_types::{ + instr::Instruction, + values::{self, Locals}, }; -use move_vm_types::values::{self, Locals}; use std::{ collections::BTreeSet, io::{self, Write}, diff --git a/third_party/move/move-vm/runtime/src/execution_tracing/recorders.rs b/third_party/move/move-vm/runtime/src/execution_tracing/recorders.rs index ab95a4d7f33..8c4c061d742 100644 --- a/third_party/move/move-vm/runtime/src/execution_tracing/recorders.rs +++ b/third_party/move/move-vm/runtime/src/execution_tracing/recorders.rs @@ -5,12 +5,12 @@ use crate::{ execution_tracing::{trace::DynamicCall, Trace}, - instr::Instruction, LoadedFunction, }; use bitvec::vec::BitVec; use fxhash::FxHasher64; use move_core_types::function::ClosureMask; +use move_vm_types::instr::Instruction; use std::hash::{Hash, Hasher}; /// Interface for recording the trace at runtime. It is sufficient to record branch decisions as diff --git a/third_party/move/move-vm/runtime/src/execution_tracing/trace.rs b/third_party/move/move-vm/runtime/src/execution_tracing/trace.rs index 13022f72556..d309cf42557 100644 --- a/third_party/move/move-vm/runtime/src/execution_tracing/trace.rs +++ b/third_party/move/move-vm/runtime/src/execution_tracing/trace.rs @@ -4,12 +4,11 @@ //! Defines the trace data structure which is sufficient to replay Move program execution without //! requiring any data accesses (only access to code loader is needed). -use crate::{ - execution_tracing::recorders::BytecodeFingerprintRecorder, instr::Instruction, LoadedFunction, -}; +use crate::{execution_tracing::recorders::BytecodeFingerprintRecorder, LoadedFunction}; use bitvec::vec::BitVec; use move_binary_format::errors::{PartialVMError, PartialVMResult}; use move_core_types::function::ClosureMask; +use move_vm_types::instr::Instruction; /// A non-static call record in the trace. Used for entry-points and closures. #[derive(Clone)] diff --git a/third_party/move/move-vm/runtime/src/frame.rs b/third_party/move/move-vm/runtime/src/frame.rs index aa3caa314a7..e645e2cbfa6 100644 --- a/third_party/move/move-vm/runtime/src/frame.rs +++ b/third_party/move/move-vm/runtime/src/frame.rs @@ -26,6 +26,7 @@ use move_core_types::{ ability::Ability, account_address::AccountAddress, gas_algebra::NumTypeNodes, identifier::IdentStr, language_storage::ModuleId, vm_status::StatusCode, }; +use move_vm_profiler::FnGuard; use move_vm_types::{ gas::GasMeter, loaded_data::{ @@ -56,6 +57,10 @@ pub(crate) struct Frame { pub(crate) ty_builder: TypeBuilder, // Currently being executed function. pub(crate) function: Rc, + // Guard used to profile the execution of this function. + // Note that this is only stored to keep it alive for the lifetime of the frame. + // It is an option so we can pass `None` during the runtime type checks. + pub(crate) _guard: Option, // How this frame was established. pub(crate) call_type: CallType, // Locals for this execution context and their instantiated types. @@ -154,6 +159,7 @@ impl Frame { call_type: CallType, vm_config: &VMConfig, function: Rc, + guard: Option, locals: Locals, frame_cache: Rc>, ) -> PartialVMResult { @@ -213,6 +219,7 @@ impl Frame { ty_builder, locals, function, + _guard: guard, call_type, local_tys, frame_cache, diff --git a/third_party/move/move-vm/runtime/src/interpreter.rs b/third_party/move/move-vm/runtime/src/interpreter.rs index ba9ecf27afe..2c5868c426a 100644 --- a/third_party/move/move-vm/runtime/src/interpreter.rs +++ b/third_party/move/move-vm/runtime/src/interpreter.rs @@ -9,7 +9,6 @@ use crate::{ execution_tracing::TraceRecorder, frame::Frame, frame_type_cache::{FrameTypeCache, PerInstructionCache}, - instr::Instruction, interpreter_caches::InterpreterFunctionCaches, loader::LazyLoadedFunction, module_traversal::TraversalContext, @@ -43,9 +42,11 @@ use move_core_types::{ sub_status::unknown_invariant_violation::EPARANOID_FAILURE, StatusCode, StatusType, }, }; +use move_vm_profiler::{FnGuard, Profiler, VM_PROFILER}; use move_vm_types::{ debug_write, debug_writeln, gas::{GasMeter, SimpleInstruction}, + instr::Instruction, loaded_data::{runtime_access_specifier::AccessInstance, runtime_types::Type}, natives::function::NativeResult, ty_interner::InternedTypePool, @@ -343,6 +344,8 @@ where function: Rc, args: Vec, ) -> VMResult> { + let fn_guard = VM_PROFILER.function_start(function.as_ref()); + let num_locals = function.local_tys().len(); let mut locals = Locals::new(num_locals); for (i, value) in args.into_iter().enumerate() { @@ -368,6 +371,7 @@ where CallType::Regular, self.vm_config, function, + Some(fn_guard), locals, frame_cache, ) @@ -467,6 +471,8 @@ where (function, frame_cache) }; + let fn_guard = VM_PROFILER.function_start(function.as_ref()); + RTTCheck::check_call_visibility( ¤t_frame.function, &function, @@ -509,6 +515,7 @@ where &mut current_frame, gas_meter, function, + fn_guard, CallType::Regular, frame_cache, ClosureMask::empty(), @@ -561,6 +568,8 @@ where (function, frame_cache) }; + let fn_guard = VM_PROFILER.function_start(function.as_ref()); + RTTCheck::check_call_visibility( ¤t_frame.function, &function, @@ -611,6 +620,7 @@ where &mut current_frame, gas_meter, function, + fn_guard, CallType::Regular, frame_cache, ClosureMask::empty(), @@ -625,6 +635,7 @@ where .pop_as::() .map_err(|e| set_err_info!(current_frame, e))? .unpack(); + let lazy_function = LazyLoadedFunction::expect_this_impl(fun.as_ref()) .map_err(|e| set_err_info!(current_frame, e))?; let mask = lazy_function.closure_mask(); @@ -651,6 +662,8 @@ where .as_resolved(self.loader, gas_meter, traversal_context) .map_err(|e| set_err_info!(current_frame, e))?; + let fn_guard = VM_PROFILER.function_start(callee.as_ref()); + RTTCheck::check_call_visibility( ¤t_frame.function, &callee, @@ -711,6 +724,7 @@ where &mut current_frame, gas_meter, callee, + fn_guard, CallType::ClosureDynamicDispatch, // Make sure the frame cache is empty for the new call. frame_cache, @@ -822,6 +836,7 @@ where current_frame: &mut Frame, gas_meter: &mut impl GasMeter, function: Rc, + fn_guard: FnGuard, call_type: CallType, frame_cache: Rc>, mask: ClosureMask, @@ -840,6 +855,7 @@ where current_frame, gas_meter, function, + fn_guard, call_type, frame_cache, mask, @@ -875,6 +891,7 @@ where current_frame: &Frame, gas_meter: &mut impl GasMeter, function: Rc, + fn_guard: FnGuard, call_type: CallType, frame_cache: Rc>, mask: ClosureMask, @@ -922,6 +939,7 @@ where call_type, self.vm_config, function, + Some(fn_guard), locals, frame_cache, ) @@ -1117,6 +1135,9 @@ where ty_args_id, )?; + // Note: the profiler begins measuring at this point, so it captures only execution time, not loading time. + let fn_guard = VM_PROFILER.function_start(&target_func); + RTTCheck::check_call_visibility( function, &target_func, @@ -1157,6 +1178,7 @@ where current_frame, gas_meter, Rc::new(target_func), + fn_guard, CallType::NativeDynamicDispatch, frame_cache, ClosureMask::empty(), @@ -1949,6 +1971,8 @@ impl Frame { ) }); + let _guard = VM_PROFILER.instruction_start(instruction); + // Paranoid Mode: Perform the type stack transition check to make sure all type safety requirements has been met. // // We will run the checks for only the control flow instructions and StLoc here. The majority of checks will be diff --git a/third_party/move/move-vm/runtime/src/lib.rs b/third_party/move/move-vm/runtime/src/lib.rs index fe98239b8a7..019fb9827cf 100644 --- a/third_party/move/move-vm/runtime/src/lib.rs +++ b/third_party/move/move-vm/runtime/src/lib.rs @@ -19,7 +19,6 @@ pub mod native_functions; #[macro_use] pub mod tracing; pub mod config; -pub mod instr; pub mod module_traversal; // Only include debugging functionality in debug builds diff --git a/third_party/move/move-vm/runtime/src/loader/function.rs b/third_party/move/move-vm/runtime/src/loader/function.rs index b7a1c04ccb0..5d437df499c 100644 --- a/third_party/move/move-vm/runtime/src/loader/function.rs +++ b/third_party/move/move-vm/runtime/src/loader/function.rs @@ -3,7 +3,6 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - instr::Instruction, loader::{access_specifier_loader::load_access_specifier, Module, Script}, module_traversal::TraversalContext, native_functions::{NativeFunction, NativeFunctions, UnboxedNativeFunction}, @@ -26,8 +25,10 @@ use move_core_types::{ value::MoveTypeLayout, vm_status::StatusCode, }; +use move_vm_profiler::ProfilerFunction; use move_vm_types::{ gas::DependencyGasMeter, + instr::Instruction, loaded_data::{ runtime_access_specifier::AccessSpecifier, runtime_types::{StructIdentifier, Type}, @@ -143,6 +144,13 @@ pub struct LoadedFunction { pub function: Arc, } +impl ProfilerFunction for LoadedFunction { + #[inline] + fn name(&self) -> String { + self.name_as_pretty_string() + } +} + impl LoadedFunction { pub(crate) fn owner(&self) -> &LoadedFunctionOwner { &self.owner diff --git a/third_party/move/move-vm/runtime/src/move_vm.rs b/third_party/move/move-vm/runtime/src/move_vm.rs index e10edee48cf..e8d54eed209 100644 --- a/third_party/move/move-vm/runtime/src/move_vm.rs +++ b/third_party/move/move-vm/runtime/src/move_vm.rs @@ -117,6 +117,7 @@ impl MoveVM { let return_values = { let _timer = VM_TIMER.timer_with_label("Interpreter::entrypoint"); + Interpreter::entrypoint( function, deserialized_args, diff --git a/third_party/move/move-vm/runtime/src/runtime_ref_checks.rs b/third_party/move/move-vm/runtime/src/runtime_ref_checks.rs index d659db07f4d..bb4732e8ebf 100644 --- a/third_party/move/move-vm/runtime/src/runtime_ref_checks.rs +++ b/third_party/move/move-vm/runtime/src/runtime_ref_checks.rs @@ -78,7 +78,7 @@ //! one of the reference parameters. They are also transformed to point to the //! corresponding access path tree node in the caller's frame (if it exists). -use crate::{frame::Frame, frame_type_cache::FrameTypeCache, instr::Instruction, LoadedFunction}; +use crate::{frame::Frame, frame_type_cache::FrameTypeCache, LoadedFunction}; use fxhash::FxBuildHasher; use hashbrown::HashMap; use move_binary_format::{ @@ -89,7 +89,7 @@ use move_core_types::{ function::ClosureMask, vm_status::{sub_status::unknown_invariant_violation::EREFERENCE_SAFETY_FAILURE, StatusCode}, }; -use move_vm_types::loaded_data::runtime_types::Type; +use move_vm_types::{instr::Instruction, loaded_data::runtime_types::Type}; use std::{collections::BTreeSet, slice}; /// A deterministic hash map (used in the Rust compiler), expected to perform well. diff --git a/third_party/move/move-vm/runtime/src/runtime_type_checks.rs b/third_party/move/move-vm/runtime/src/runtime_type_checks.rs index 8cf754a16d6..ccdf18147b9 100644 --- a/third_party/move/move-vm/runtime/src/runtime_type_checks.rs +++ b/third_party/move/move-vm/runtime/src/runtime_type_checks.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - frame::Frame, frame_type_cache::FrameTypeCache, instr::Instruction, interpreter::Stack, + frame::Frame, frame_type_cache::FrameTypeCache, interpreter::Stack, reentrancy_checker::CallType, Function, LoadedFunction, }; use move_binary_format::errors::*; @@ -11,7 +11,10 @@ use move_core_types::{ function::ClosureMask, vm_status::{sub_status::unknown_invariant_violation::EPARANOID_FAILURE, StatusCode}, }; -use move_vm_types::loaded_data::runtime_types::{Type, TypeBuilder}; +use move_vm_types::{ + instr::Instruction, + loaded_data::runtime_types::{Type, TypeBuilder}, +}; pub(crate) trait RuntimeTypeCheck { /// Paranoid type checks to perform before instruction execution. diff --git a/third_party/move/move-vm/runtime/src/runtime_type_checks_async.rs b/third_party/move/move-vm/runtime/src/runtime_type_checks_async.rs index 885c2f7858d..11153aa9e31 100644 --- a/third_party/move/move-vm/runtime/src/runtime_type_checks_async.rs +++ b/third_party/move/move-vm/runtime/src/runtime_type_checks_async.rs @@ -24,7 +24,6 @@ use crate::{ execution_tracing::{Trace, TraceCursor}, frame::Frame, frame_type_cache::{FrameTypeCache, PerInstructionCache}, - instr::Instruction, interpreter::{CallStack, Stack}, interpreter_caches::InterpreterFunctionCaches, loader::FunctionHandle, @@ -41,6 +40,7 @@ use move_binary_format::{ use move_core_types::function::ClosureMask; use move_vm_types::{ gas::UnmeteredGasMeter, + instr::Instruction, loaded_data::runtime_types::{Type, TypeBuilder}, ty_interner::{InternedTypePool, TypeVecId}, values::{Locals, Value}, @@ -594,6 +594,7 @@ where CallType::Regular, self.vm_config, function, + None, locals, frame_cache, ) @@ -640,6 +641,7 @@ where call_type, self.vm_config, callee, + None, locals, callee_frame_cache, )?; diff --git a/third_party/move/move-vm/runtime/src/tracing.rs b/third_party/move/move-vm/runtime/src/tracing.rs index d733c2e3cc2..56741ec1408 100644 --- a/third_party/move/move-vm/runtime/src/tracing.rs +++ b/third_party/move/move-vm/runtime/src/tracing.rs @@ -5,10 +5,10 @@ #[cfg(feature = "debugging")] use crate::debug::DebugContext; #[cfg(feature = "debugging")] -use crate::instr::Instruction; -#[cfg(feature = "debugging")] use crate::{interpreter::InterpreterDebugInterface, loader::LoadedFunction, RuntimeEnvironment}; #[cfg(feature = "debugging")] +use move_vm_types::instr::Instruction; +#[cfg(feature = "debugging")] use ::{ move_vm_types::values::Locals, once_cell::sync::Lazy, diff --git a/third_party/move/move-vm/runtime/src/instr.rs b/third_party/move/move-vm/types/src/instr.rs similarity index 62% rename from third_party/move/move-vm/runtime/src/instr.rs rename to third_party/move/move-vm/types/src/instr.rs index c7e43b31023..ce3c9d23ea6 100644 --- a/third_party/move/move-vm/runtime/src/instr.rs +++ b/third_party/move/move-vm/types/src/instr.rs @@ -126,6 +126,116 @@ pub enum Instruction { Negate, } +impl Instruction { + pub fn name(&self) -> &str { + match self { + Instruction::Pop => "pop", + Instruction::Ret => "ret", + Instruction::BrTrue(_) => "br_true", + Instruction::BrFalse(_) => "br_false", + Instruction::Branch(_) => "branch", + Instruction::LdU8(_) => "ld_u8", + Instruction::LdU64(_) => "ld_u64", + Instruction::LdU128(_) => "ld_u128", + Instruction::CastU8 => "cast_u8", + Instruction::CastU64 => "cast_u64", + Instruction::CastU128 => "cast_u128", + Instruction::LdConst(_) => "ld_const", + Instruction::LdTrue => "ld_true", + Instruction::LdFalse => "ld_false", + Instruction::CopyLoc(_) => "copy_loc", + Instruction::MoveLoc(_) => "move_loc", + Instruction::StLoc(_) => "st_loc", + Instruction::Call(_) => "call", + Instruction::CallGeneric(_) => "call_generic", + Instruction::Pack(_) => "pack", + Instruction::PackGeneric(_) => "pack_generic", + Instruction::PackVariant(_) => "pack_variant", + Instruction::PackVariantGeneric(_) => "pack_variant_generic", + Instruction::Unpack(_) => "unpack", + Instruction::UnpackGeneric(_) => "unpack_generic", + Instruction::UnpackVariant(_) => "unpack_variant", + Instruction::UnpackVariantGeneric(_) => "unpack_variant_generic", + Instruction::TestVariant(_) => "test_variant", + Instruction::TestVariantGeneric(_) => "test_variant_generic", + Instruction::ReadRef => "read_ref", + Instruction::WriteRef => "write_ref", + Instruction::FreezeRef => "freeze_ref", + Instruction::MutBorrowLoc(_) => "mut_borrow_loc", + Instruction::ImmBorrowLoc(_) => "imm_borrow_loc", + Instruction::MutBorrowField(_) => "mut_borrow_field", + Instruction::MutBorrowVariantField(_) => "mut_borrow_variant_field", + Instruction::MutBorrowFieldGeneric(_) => "mut_borrow_field_generic", + Instruction::MutBorrowVariantFieldGeneric(_) => "mut_borrow_variant_field_generic", + Instruction::ImmBorrowField(_) => "imm_borrow_field", + Instruction::ImmBorrowVariantField(_) => "imm_borrow_variant_field", + Instruction::ImmBorrowFieldGeneric(_) => "imm_borrow_field_generic", + Instruction::ImmBorrowVariantFieldGeneric(_) => "imm_borrow_variant_field_generic", + Instruction::MutBorrowGlobal(_) => "mut_borrow_global", + Instruction::MutBorrowGlobalGeneric(_) => "mut_borrow_global_generic", + Instruction::ImmBorrowGlobal(_) => "imm_borrow_global", + Instruction::ImmBorrowGlobalGeneric(_) => "imm_borrow_global_generic", + Instruction::Add => "add", + Instruction::Sub => "sub", + Instruction::Mul => "mul", + Instruction::Mod => "mod", + Instruction::Div => "div", + Instruction::BitOr => "bit_or", + Instruction::BitAnd => "bit_and", + Instruction::Xor => "xor", + Instruction::Or => "or", + Instruction::And => "and", + Instruction::Not => "not", + Instruction::Eq => "eq", + Instruction::Neq => "neq", + Instruction::Lt => "lt", + Instruction::Gt => "gt", + Instruction::Le => "le", + Instruction::Ge => "ge", + Instruction::Abort => "abort", + Instruction::Nop => "nop", + Instruction::Exists(_) => "exists", + Instruction::ExistsGeneric(_) => "exists_generic", + Instruction::MoveFrom(_) => "move_from", + Instruction::MoveFromGeneric(_) => "move_from_generic", + Instruction::MoveTo(_) => "move_to", + Instruction::MoveToGeneric(_) => "move_to_generic", + Instruction::Shl => "shl", + Instruction::Shr => "shr", + Instruction::VecPack(_, _) => "vec_pack", + Instruction::VecLen(_) => "vec_len", + Instruction::VecImmBorrow(_) => "vec_imm_borrow", + Instruction::VecMutBorrow(_) => "vec_mut_borrow", + Instruction::VecPushBack(_) => "vec_push_back", + Instruction::VecPopBack(_) => "vec_pop_back", + Instruction::VecUnpack(_, _) => "vec_unpack", + Instruction::VecSwap(_) => "vec_swap", + Instruction::PackClosure(_, _) => "pack_closure", + Instruction::PackClosureGeneric(_, _) => "pack_closure_generic", + Instruction::CallClosure(_) => "call_closure", + Instruction::LdU16(_) => "ld_u16", + Instruction::LdU32(_) => "ld_u32", + Instruction::LdU256(_) => "ld_u256", + Instruction::CastU16 => "cast_u16", + Instruction::CastU32 => "cast_u32", + Instruction::CastU256 => "cast_u256", + Instruction::LdI8(_) => "ld_i8", + Instruction::LdI16(_) => "ld_i16", + Instruction::LdI32(_) => "ld_i32", + Instruction::LdI64(_) => "ld_i64", + Instruction::LdI128(_) => "ld_i128", + Instruction::LdI256(_) => "ld_i256", + Instruction::CastI8 => "cast_i8", + Instruction::CastI16 => "cast_i16", + Instruction::CastI32 => "cast_i32", + Instruction::CastI64 => "cast_i64", + Instruction::CastI128 => "cast_i128", + Instruction::CastI256 => "cast_i256", + Instruction::Negate => "negate", + } + } +} + impl From for Instruction { fn from(bytecode: Bytecode) -> Self { use Bytecode as B; diff --git a/third_party/move/move-vm/types/src/lib.rs b/third_party/move/move-vm/types/src/lib.rs index ad7658b18ba..ac2f893a56d 100644 --- a/third_party/move/move-vm/types/src/lib.rs +++ b/third_party/move/move-vm/types/src/lib.rs @@ -34,6 +34,7 @@ macro_rules! debug_writeln { pub mod code; pub mod delayed_values; pub mod gas; +pub mod instr; pub mod interner; pub mod loaded_data; pub mod module_id_interner; From b86255d8fefb242e0a2df0af1e680c5e5ec9cd4d Mon Sep 17 00:00:00 2001 From: George Mitenkov Date: Thu, 20 Nov 2025 14:11:21 +0000 Subject: [PATCH 256/260] [vm] Add stack size checking at function boundaries (#18167) Downstreamed-from: 4f44a3dd8e889ea853aa7b0dc1a8dd0d0b33a8d9 --- testsuite/single_node_performance_values.tsv | 3 + third_party/move/move-vm/runtime/src/frame.rs | 8 ++ .../move/move-vm/runtime/src/interpreter.rs | 93 +++++++++---------- .../runtime/src/runtime_type_checks.rs | 51 ---------- .../runtime/src/runtime_type_checks_async.rs | 2 + .../trusted_trusted_err.async-paranoid.exp | 43 +++++++++ .../trusted_trusted_err.baseline.exp | 57 ++++++++++++ .../tests/stack_size/trusted_trusted_err.masm | 59 ++++++++++++ .../trusted_trusted_err.paranoid.exp | 43 +++++++++ .../trusted_trusted_ok.async-paranoid.exp | 6 ++ .../trusted_trusted_ok.baseline.exp | 6 ++ .../tests/stack_size/trusted_trusted_ok.masm | 31 +++++++ .../trusted_trusted_ok.paranoid.exp | 6 ++ .../trusted_untrusted_err.async-paranoid.exp | 45 +++++++++ .../trusted_untrusted_err.baseline.exp | 85 +++++++++++++++++ .../stack_size/trusted_untrusted_err.masm | 65 +++++++++++++ .../trusted_untrusted_err.paranoid.exp | 45 +++++++++ .../trusted_untrusted_ok.async-paranoid.exp | 7 ++ .../trusted_untrusted_ok.baseline.exp | 7 ++ .../stack_size/trusted_untrusted_ok.masm | 34 +++++++ .../trusted_untrusted_ok.paranoid.exp | 7 ++ .../untrusted_trusted_err.async-paranoid.exp | 45 +++++++++ .../untrusted_trusted_err.baseline.exp | 85 +++++++++++++++++ .../stack_size/untrusted_trusted_err.masm | 65 +++++++++++++ .../untrusted_trusted_err.paranoid.exp | 45 +++++++++ .../untrusted_trusted_ok.async-paranoid.exp | 7 ++ .../untrusted_trusted_ok.baseline.exp | 7 ++ .../stack_size/untrusted_trusted_ok.masm | 34 +++++++ .../untrusted_trusted_ok.paranoid.exp | 7 ++ ...untrusted_untrusted_err.async-paranoid.exp | 43 +++++++++ .../untrusted_untrusted_err.baseline.exp | 57 ++++++++++++ .../stack_size/untrusted_untrusted_err.masm | 59 ++++++++++++ .../untrusted_untrusted_err.paranoid.exp | 43 +++++++++ .../untrusted_untrusted_ok.async-paranoid.exp | 6 ++ .../untrusted_untrusted_ok.baseline.exp | 6 ++ .../stack_size/untrusted_untrusted_ok.masm | 31 +++++++ .../untrusted_untrusted_ok.paranoid.exp | 6 ++ .../transactional-tests/tests/tests.rs | 16 ++-- 38 files changed, 1161 insertions(+), 104 deletions(-) create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_err.async-paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_err.baseline.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_err.masm create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_err.paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_ok.async-paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_ok.baseline.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_ok.masm create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_ok.paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_err.async-paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_err.baseline.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_err.masm create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_err.paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_ok.async-paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_ok.baseline.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_ok.masm create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_ok.paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_err.async-paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_err.baseline.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_err.masm create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_err.paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_ok.async-paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_ok.baseline.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_ok.masm create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_ok.paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_err.async-paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_err.baseline.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_err.masm create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_err.paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_ok.async-paranoid.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_ok.baseline.exp create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_ok.masm create mode 100644 third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_ok.paranoid.exp diff --git a/testsuite/single_node_performance_values.tsv b/testsuite/single_node_performance_values.tsv index 8f58373b680..1a15f025fd0 100644 --- a/testsuite/single_node_performance_values.tsv +++ b/testsuite/single_node_performance_values.tsv @@ -49,6 +49,9 @@ order-book-balanced-matches25-pct50-markets 1 VM 4 0.972 1.033 3759.4 order-book-balanced-matches80-pct50-markets 1 VM 4 0.997 1.006 3996.1 order-book-balanced-size-skewed80-pct50-markets 1 VM 4 0.997 1.039 3838.0 monotonic-counter-single 1 VM 4 0.987 1.009 45350.3 +fibonacci-recursive20 1 VM 4 0.987 1.009 45350.3 +fibonacci-tail-recursive20 1 VM 4 0.987 1.009 45350.3 +fibonacci-iterative20 1 VM 4 0.987 1.009 45350.3 no_commit_apt-fa-transfer 1 VM 4 0.995 1.011 35616.6 no_commit_apt-fa-transfer 1 NativeVM 4 0.994 1.030 60946.4 no_commit_apt-fa-transfer 1 AptosVMSpeculative 4 0.998 1.021 10321.9 diff --git a/third_party/move/move-vm/runtime/src/frame.rs b/third_party/move/move-vm/runtime/src/frame.rs index e645e2cbfa6..499f59badcf 100644 --- a/third_party/move/move-vm/runtime/src/frame.rs +++ b/third_party/move/move-vm/runtime/src/frame.rs @@ -4,6 +4,7 @@ use crate::{ config::VMConfig, frame_type_cache::FrameTypeCache, + interpreter::Stack, loader::{FunctionHandle, LoadedFunctionOwner, StructVariantInfo, VariantFieldInfo}, module_traversal::TraversalContext, reentrancy_checker::CallType, @@ -69,6 +70,10 @@ pub(crate) struct Frame { // Cache of types accessed in this frame, to improve performance when accessing // and constructing types. pub(crate) frame_cache: Rc>, + // Saved value stack size of the caller that created this frame. + pub(crate) caller_value_stack_size: u32, + // Saved type stack size of the caller that created this frame. + pub(crate) caller_type_stack_size: u32, } impl AccessSpecifierEnv for Frame { @@ -162,6 +167,7 @@ impl Frame { guard: Option, locals: Locals, frame_cache: Rc>, + stack: &Stack, ) -> PartialVMResult { let ty_args = function.ty_args(); @@ -223,6 +229,8 @@ impl Frame { call_type, local_tys, frame_cache, + caller_value_stack_size: stack.value.len() as u32, + caller_type_stack_size: stack.types.len() as u32, }) } diff --git a/third_party/move/move-vm/runtime/src/interpreter.rs b/third_party/move/move-vm/runtime/src/interpreter.rs index 2c5868c426a..ab2ac501bb0 100644 --- a/third_party/move/move-vm/runtime/src/interpreter.rs +++ b/third_party/move/move-vm/runtime/src/interpreter.rs @@ -374,6 +374,7 @@ where Some(fn_guard), locals, frame_cache, + &self.operand_stack, ) .map_err(|err| self.set_location(err))?; @@ -402,6 +403,15 @@ where .charge_drop_frame(non_ref_vals.iter()) .map_err(|e| set_err_info!(current_frame, e))?; + let actual_stack_size = self.operand_stack.value.len(); + let expected_stack_size = current_frame.function.return_tys().len() + + current_frame.caller_value_stack_size as usize; + if actual_stack_size != expected_stack_size { + let err = current_frame + .stack_size_mismatch_error(expected_stack_size, actual_stack_size); + return Err(set_err_info!(current_frame, err)); + } + self.call_stack .type_check_return::(&mut self.operand_stack, &mut current_frame) .map_err(|e| set_err_info!(current_frame, e))?; @@ -760,16 +770,32 @@ impl CallStack { let callee_has_rt_checks = RTTCheck::should_perform_checks(¤t_frame.function.function); if callee_has_rt_checks { + let num_return_tys = current_frame.function.return_tys().len(); + let actual_type_stack_size = operand_stack.types.len(); + let expected_type_stack_size = + num_return_tys + current_frame.caller_type_stack_size as usize; + if actual_type_stack_size != expected_type_stack_size { + return Err(current_frame + .stack_size_mismatch_error(expected_type_stack_size, actual_type_stack_size)); + } self.check_return_tys::(operand_stack, current_frame)?; if !caller_has_rt_checks { // The callee has pushed return types, but they aren't used by // the caller, so need to be removed. - operand_stack.remove_tys(current_frame.function.return_tys().len())?; + operand_stack.remove_tys(num_return_tys)?; } } else if caller_has_rt_checks { - // We are not runtime checking this function, but in the caller, - // so we must push the return types of the function onto the type stack, - // following the runtime type checking protocol. + // We are not runtime checking this function, but in the caller, so we must push the + // return types of the function onto the type stack, following the runtime type + // checking protocol. Also, we should check that the type stack is balanced: if callee + // has no runtime checks, type stack should be at the same state. + let actual_type_stack_size = operand_stack.types.len(); + let expected_type_stack_size = current_frame.caller_type_stack_size as usize; + if actual_type_stack_size != expected_type_stack_size { + return Err(current_frame + .stack_size_mismatch_error(expected_type_stack_size, actual_type_stack_size)); + } + let ty_args = current_frame.function.ty_args(); if ty_args.is_empty() { for ret_ty in current_frame.function.return_tys() { @@ -795,17 +821,6 @@ impl CallStack { current_frame: &mut Frame, ) -> PartialVMResult<()> { let expected_ret_tys = current_frame.function.return_tys(); - if !RTTCheck::is_partial_checker() - && self.0.is_empty() - && operand_stack.types.len() != expected_ret_tys.len() - { - // If we have full stack available and this is the outermost call on the stack, the - // type stack must contain exactly the expected number of returns. - return Err(PartialVMError::new_invariant_violation( - "unbalanced stack at end of execution", - ) - .with_sub_status(EPARANOID_FAILURE)); - } if expected_ret_tys.is_empty() { return Ok(()); } @@ -942,6 +957,7 @@ where Some(fn_guard), locals, frame_cache, + &self.operand_stack, ) } @@ -1708,7 +1724,7 @@ pub(crate) const ACCESS_STACK_SIZE_LIMIT: usize = 256; /// The operand and runtime-type stacks. pub(crate) struct Stack { - value: Vec, + pub(crate) value: Vec, pub(crate) types: Vec, } @@ -1848,18 +1864,6 @@ impl Stack { let len = self.types.len(); Ok(&self.types[(len - n)..]) } - - #[cfg_attr(feature = "force-inline", inline(always))] - pub(crate) fn check_balance(&self) -> PartialVMResult<()> { - if self.types.len() != self.value.len() { - return Err( - PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR).with_message( - "Paranoid Mode: Type and value stack need to be balanced".to_string(), - ), - ); - } - Ok(()) - } } /// A call stack. @@ -1981,10 +1985,6 @@ impl Frame { // The reason for this design is we charge gas during instruction execution and we want to perform checks only after // proper gas has been charged for each instruction. - RTTCheck::check_operand_stack_balance( - &self.function.function, - &interpreter.operand_stack, - )?; RTTCheck::pre_execution_type_stack_transition( self, &mut interpreter.operand_stack, @@ -2938,10 +2938,6 @@ impl Frame { instruction, frame_cache, )?; - RTTCheck::check_operand_stack_balance( - &self.function.function, - &interpreter.operand_stack, - )?; RTRCheck::post_execution_transition( self, instruction, @@ -2951,18 +2947,10 @@ impl Frame { // invariant: advance to pc +1 is iff instruction at pc executed without aborting self.pc += 1; } - // ok we are out, it's a branch, check the pc for good luck - // TODO: re-work the logic here. Tests should have a more - // natural way to plug in + + // If out of the loop - it was a branch. if self.pc as usize >= code.len() { - if cfg!(test) { - // In order to test the behavior of an instruction stream, hitting end of the - // code should report no error so that we can check the - // locals. - return Ok(ExitCode::Return); - } else { - return Err(PartialVMError::new(StatusCode::PC_OVERFLOW)); - } + return Err(PartialVMError::new(StatusCode::PC_OVERFLOW)); } } } @@ -2973,4 +2961,15 @@ impl Frame { Some(id) => Location::Module(id.clone()), } } + + #[cold] + fn stack_size_mismatch_error(&self, expected: usize, actual: usize) -> PartialVMError { + let err = PartialVMError::new_invariant_violation(format!( + "Stack size mismatch when returning from {}: expected: {}, got: {}", + self.function.name_as_pretty_string(), + expected, + actual + )); + err.with_sub_status(EPARANOID_FAILURE) + } } diff --git a/third_party/move/move-vm/runtime/src/runtime_type_checks.rs b/third_party/move/move-vm/runtime/src/runtime_type_checks.rs index ccdf18147b9..70799fc05fe 100644 --- a/third_party/move/move-vm/runtime/src/runtime_type_checks.rs +++ b/third_party/move/move-vm/runtime/src/runtime_type_checks.rs @@ -33,19 +33,9 @@ pub(crate) trait RuntimeTypeCheck { ty_cache: &mut FrameTypeCache, ) -> PartialVMResult<()>; - /// Paranoid check that operand and type stacks have the same size - fn check_operand_stack_balance( - for_fun: &Function, - operand_stack: &Stack, - ) -> PartialVMResult<()>; - /// For any other checks are performed externally fn should_perform_checks(for_fun: &Function) -> bool; - /// Whether this is a partial checker, in which some parts of the code are checked and - /// others not. This is needed for certain info only valid in full checking. - fn is_partial_checker() -> bool; - /// Performs a runtime check of the caller is allowed to call the callee for any type of call, /// including native dynamic dispatch or calling a closure. #[cfg_attr(feature = "force-inline", inline(always))] @@ -248,24 +238,11 @@ impl RuntimeTypeCheck for NoRuntimeTypeCheck { Ok(()) } - #[cfg_attr(feature = "force-inline", inline(always))] - fn check_operand_stack_balance( - _for_fun: &Function, - _operand_stack: &Stack, - ) -> PartialVMResult<()> { - Ok(()) - } - #[cfg_attr(feature = "force-inline", inline(always))] fn should_perform_checks(_for_fun: &Function) -> bool { false } - #[cfg_attr(feature = "force-inline", inline(always))] - fn is_partial_checker() -> bool { - false - } - #[cfg_attr(feature = "force-inline", inline(always))] fn check_cross_module_regular_call_visibility( _caller: &LoadedFunction, @@ -951,24 +928,11 @@ impl RuntimeTypeCheck for FullRuntimeTypeCheck { Ok(()) } - #[cfg_attr(feature = "force-inline", inline(always))] - fn check_operand_stack_balance( - _for_fun: &Function, - operand_stack: &Stack, - ) -> PartialVMResult<()> { - operand_stack.check_balance() - } - #[cfg_attr(feature = "force-inline", inline(always))] fn should_perform_checks(_for_fun: &Function) -> bool { true } - #[cfg_attr(feature = "force-inline", inline(always))] - fn is_partial_checker() -> bool { - false - } - #[cfg_attr(feature = "force-inline", inline(always))] fn check_cross_module_regular_call_visibility( caller: &LoadedFunction, @@ -1048,25 +1012,10 @@ impl RuntimeTypeCheck for UntrustedOnlyRuntimeTypeCheck { } } - #[cfg_attr(feature = "force-inline", inline(always))] - fn check_operand_stack_balance( - _for_fun: &Function, - _operand_stack: &Stack, - ) -> PartialVMResult<()> { - // We cannot have a global stack balancing without traversing the frame stack, - // so skip in this mode. - Ok(()) - } - fn should_perform_checks(for_fun: &Function) -> bool { !for_fun.is_trusted } - #[cfg_attr(feature = "force-inline", inline(always))] - fn is_partial_checker() -> bool { - true - } - #[cfg_attr(feature = "force-inline", inline(always))] fn check_cross_module_regular_call_visibility( caller: &LoadedFunction, diff --git a/third_party/move/move-vm/runtime/src/runtime_type_checks_async.rs b/third_party/move/move-vm/runtime/src/runtime_type_checks_async.rs index 11153aa9e31..4ddb33df8af 100644 --- a/third_party/move/move-vm/runtime/src/runtime_type_checks_async.rs +++ b/third_party/move/move-vm/runtime/src/runtime_type_checks_async.rs @@ -597,6 +597,7 @@ where None, locals, frame_cache, + &self.type_stack, ) } @@ -644,6 +645,7 @@ where None, locals, callee_frame_cache, + &self.type_stack, )?; std::mem::swap(current_frame, &mut frame); self.call_stack.push(frame).map_err(|_| { diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_err.async-paranoid.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_err.async-paranoid.exp new file mode 100644 index 00000000000..51d27674468 --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_err.async-paranoid.exp @@ -0,0 +1,43 @@ +processed 6 tasks +task 0 lines 1-23: publish [module 0x3::trusted] +task 1 lines 26-50: publish [module 0x4::trusted] +task 2 lines 53-53: run --verbose 0x3::trusted::sum_10_20 +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000003::trusted::return_20: expected: 3, got: 2, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x3::trusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: None, +} +task 3 lines 55-55: run --verbose 0x3::trusted::sum_10_20_closure +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000003::trusted::return_20: expected: 3, got: 2, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x3::trusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: None, +} +task 4 lines 57-57: run --verbose 0x4::trusted::sum_10_20_30_40 +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000004::trusted::return_20_30_40: expected: 3, got: 4, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x4::trusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 3)], + exec_state: None, +} +task 5 lines 59-59: run --verbose 0x4::trusted::sum_10_20_30_40_closure +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000004::trusted::return_20_30_40: expected: 3, got: 4, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x4::trusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 3)], + exec_state: None, +} diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_err.baseline.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_err.baseline.exp new file mode 100644 index 00000000000..e55905ac68d --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_err.baseline.exp @@ -0,0 +1,57 @@ +processed 6 tasks +task 0 lines 1-23: publish [module 0x3::trusted] +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000003::trusted'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x3::trusted, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} +task 1 lines 26-50: publish [module 0x4::trusted] +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000004::trusted'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x4::trusted, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} +task 2 lines 53-53: run --verbose 0x3::trusted::sum_10_20 +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000003::trusted doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 3 lines 55-55: run --verbose 0x3::trusted::sum_10_20_closure +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000003::trusted doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 4 lines 57-57: run --verbose 0x4::trusted::sum_10_20_30_40 +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000004::trusted doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 5 lines 59-59: run --verbose 0x4::trusted::sum_10_20_30_40_closure +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000004::trusted doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_err.masm b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_err.masm new file mode 100644 index 00000000000..0b0fcd16c02 --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_err.masm @@ -0,0 +1,59 @@ +//# publish +module 0x3::trusted + +fun return_20(): (u64, u64) + ld_u64 20 + ret + +public fun sum_10_20(): u64 + ld_u64 10 + call return_20 + add + add + ret + +public fun sum_10_20_closure(): u64 + ld_u64 10 + // stack size is 1 + pack_closure return_20, 0 + call_closure<||(u64, u64)> + // on return, stack size is 3 + add + add + ret + + +//# publish +module 0x4::trusted + +fun return_20_30_40(): (u64, u64) + ld_u64 20 + ld_u64 30 + ld_u64 40 + ret + +public fun sum_10_20_30_40(): u64 + ld_u64 10 + call return_20_30_40 + add + add + ret + +public fun sum_10_20_30_40_closure(): u64 + ld_u64 10 + // stack size is 1 + pack_closure return_20_30_40, 0 + call_closure<||(u64, u64)> + // on return, stack size is 3 + add + add + ret + + +//# run --verbose 0x3::trusted::sum_10_20 + +//# run --verbose 0x3::trusted::sum_10_20_closure + +//# run --verbose 0x4::trusted::sum_10_20_30_40 + +//# run --verbose 0x4::trusted::sum_10_20_30_40_closure diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_err.paranoid.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_err.paranoid.exp new file mode 100644 index 00000000000..51d27674468 --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_err.paranoid.exp @@ -0,0 +1,43 @@ +processed 6 tasks +task 0 lines 1-23: publish [module 0x3::trusted] +task 1 lines 26-50: publish [module 0x4::trusted] +task 2 lines 53-53: run --verbose 0x3::trusted::sum_10_20 +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000003::trusted::return_20: expected: 3, got: 2, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x3::trusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: None, +} +task 3 lines 55-55: run --verbose 0x3::trusted::sum_10_20_closure +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000003::trusted::return_20: expected: 3, got: 2, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x3::trusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: None, +} +task 4 lines 57-57: run --verbose 0x4::trusted::sum_10_20_30_40 +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000004::trusted::return_20_30_40: expected: 3, got: 4, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x4::trusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 3)], + exec_state: None, +} +task 5 lines 59-59: run --verbose 0x4::trusted::sum_10_20_30_40_closure +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000004::trusted::return_20_30_40: expected: 3, got: 4, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x4::trusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 3)], + exec_state: None, +} diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_ok.async-paranoid.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_ok.async-paranoid.exp new file mode 100644 index 00000000000..e6e29318a6c --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_ok.async-paranoid.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 1-26: publish [module 0x3::trusted] +task 1 lines 29-29: run --verbose 0x3::trusted::sum_10_20_30 +return values: 60 +task 2 lines 31-31: run --verbose 0x3::trusted::sum_10_20_30_closure +return values: 60 diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_ok.baseline.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_ok.baseline.exp new file mode 100644 index 00000000000..e6e29318a6c --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_ok.baseline.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 1-26: publish [module 0x3::trusted] +task 1 lines 29-29: run --verbose 0x3::trusted::sum_10_20_30 +return values: 60 +task 2 lines 31-31: run --verbose 0x3::trusted::sum_10_20_30_closure +return values: 60 diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_ok.masm b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_ok.masm new file mode 100644 index 00000000000..4e0272ce5e8 --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_ok.masm @@ -0,0 +1,31 @@ +//# publish +module 0x3::trusted + +fun return_20_30(): (u64, u64) + ld_u64 20 + ld_u64 30 + ret + +public fun sum_10_20_30(): u64 + ld_u64 10 + // stack size is 1 + call return_20_30 + // on return, stack size is 3 + add + add + ret + +public fun sum_10_20_30_closure(): u64 + ld_u64 10 + // stack size is 1 + pack_closure return_20_30, 0 + call_closure<||(u64, u64)> + // on return, stack size is 3 + add + add + ret + + +//# run --verbose 0x3::trusted::sum_10_20_30 + +//# run --verbose 0x3::trusted::sum_10_20_30_closure diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_ok.paranoid.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_ok.paranoid.exp new file mode 100644 index 00000000000..e6e29318a6c --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_trusted_ok.paranoid.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 1-26: publish [module 0x3::trusted] +task 1 lines 29-29: run --verbose 0x3::trusted::sum_10_20_30 +return values: 60 +task 2 lines 31-31: run --verbose 0x3::trusted::sum_10_20_30_closure +return values: 60 diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_err.async-paranoid.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_err.async-paranoid.exp new file mode 100644 index 00000000000..135fa14ebd1 --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_err.async-paranoid.exp @@ -0,0 +1,45 @@ +processed 8 tasks +task 0 lines 1-6: publish [module 0x33::untrusted] +task 1 lines 8-26: publish [module 0x3::trusted] +task 2 lines 29-36: publish [module 0x44::untrusted] +task 3 lines 38-56: publish [module 0x4::trusted] +task 4 lines 59-59: run --verbose 0x3::trusted::sum_10_20 +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000033::untrusted::return_20: expected: 3, got: 2, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x33::untrusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: None, +} +task 5 lines 61-61: run --verbose 0x3::trusted::sum_10_20_closure +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000033::untrusted::return_20: expected: 3, got: 2, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x33::untrusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: None, +} +task 6 lines 63-63: run --verbose 0x4::trusted::sum_10_20_30_40 +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000044::untrusted::return_20_30_40: expected: 3, got: 4, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x44::untrusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 3)], + exec_state: None, +} +task 7 lines 65-65: run --verbose 0x4::trusted::sum_10_20_30_40_closure +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000044::untrusted::return_20_30_40: expected: 3, got: 4, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x44::untrusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 3)], + exec_state: None, +} diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_err.baseline.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_err.baseline.exp new file mode 100644 index 00000000000..f8c4548ece8 --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_err.baseline.exp @@ -0,0 +1,85 @@ +processed 8 tasks +task 0 lines 1-6: publish [module 0x33::untrusted] +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000033::untrusted'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x33::untrusted, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} +task 1 lines 8-26: publish [module 0x3::trusted] +Error: error: unknown module `0000000000000000000000000000000000000000000000000000000000000033::untrusted` + ┌─ test:12:5 + │ +12 │ call 0x33::untrusted::return_20 + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unknown module `0000000000000000000000000000000000000000000000000000000000000033::untrusted` + ┌─ test:19:5 + │ +19 │ pack_closure 0x33::untrusted::return_20, 0 + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +task 2 lines 29-36: publish [module 0x44::untrusted] +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000044::untrusted'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x44::untrusted, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} +task 3 lines 38-56: publish [module 0x4::trusted] +Error: error: unknown module `0000000000000000000000000000000000000000000000000000000000000044::untrusted` + ┌─ test:42:5 + │ +42 │ call 0x44::untrusted::return_20_30_40 + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unknown module `0000000000000000000000000000000000000000000000000000000000000044::untrusted` + ┌─ test:49:5 + │ +49 │ pack_closure 0x44::untrusted::return_20_30_40, 0 + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +task 4 lines 59-59: run --verbose 0x3::trusted::sum_10_20 +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000003::trusted doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 5 lines 61-61: run --verbose 0x3::trusted::sum_10_20_closure +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000003::trusted doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 6 lines 63-63: run --verbose 0x4::trusted::sum_10_20_30_40 +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000004::trusted doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 7 lines 65-65: run --verbose 0x4::trusted::sum_10_20_30_40_closure +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000004::trusted doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_err.masm b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_err.masm new file mode 100644 index 00000000000..7996b91657d --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_err.masm @@ -0,0 +1,65 @@ +//# publish +module 0x33::untrusted + +public fun return_20(): (u64, u64) + ld_u64 20 + ret + +//# publish +module 0x3::trusted + +public fun sum_10_20(): u64 + ld_u64 10 + call 0x33::untrusted::return_20 + add + add + ret + +public fun sum_10_20_closure(): u64 + ld_u64 10 + // stack size is 1 + pack_closure 0x33::untrusted::return_20, 0 + call_closure<||(u64, u64)> + // on return, stack size is 3 + add + add + ret + + +//# publish +module 0x44::untrusted + +public fun return_20_30_40(): (u64, u64) + ld_u64 20 + ld_u64 30 + ld_u64 40 + ret + +//# publish +module 0x4::trusted + +public fun sum_10_20_30_40(): u64 + ld_u64 10 + call 0x44::untrusted::return_20_30_40 + add + add + ret + +public fun sum_10_20_30_40_closure(): u64 + ld_u64 10 + // stack size is 1 + pack_closure 0x44::untrusted::return_20_30_40, 0 + call_closure<||(u64, u64)> + // on return, stack size is 3 + add + add + ret + + +//# run --verbose 0x3::trusted::sum_10_20 + +//# run --verbose 0x3::trusted::sum_10_20_closure + +//# run --verbose 0x4::trusted::sum_10_20_30_40 + +//# run --verbose 0x4::trusted::sum_10_20_30_40_closure diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_err.paranoid.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_err.paranoid.exp new file mode 100644 index 00000000000..135fa14ebd1 --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_err.paranoid.exp @@ -0,0 +1,45 @@ +processed 8 tasks +task 0 lines 1-6: publish [module 0x33::untrusted] +task 1 lines 8-26: publish [module 0x3::trusted] +task 2 lines 29-36: publish [module 0x44::untrusted] +task 3 lines 38-56: publish [module 0x4::trusted] +task 4 lines 59-59: run --verbose 0x3::trusted::sum_10_20 +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000033::untrusted::return_20: expected: 3, got: 2, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x33::untrusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: None, +} +task 5 lines 61-61: run --verbose 0x3::trusted::sum_10_20_closure +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000033::untrusted::return_20: expected: 3, got: 2, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x33::untrusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: None, +} +task 6 lines 63-63: run --verbose 0x4::trusted::sum_10_20_30_40 +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000044::untrusted::return_20_30_40: expected: 3, got: 4, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x44::untrusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 3)], + exec_state: None, +} +task 7 lines 65-65: run --verbose 0x4::trusted::sum_10_20_30_40_closure +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000044::untrusted::return_20_30_40: expected: 3, got: 4, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x44::untrusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 3)], + exec_state: None, +} diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_ok.async-paranoid.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_ok.async-paranoid.exp new file mode 100644 index 00000000000..c91e3631543 --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_ok.async-paranoid.exp @@ -0,0 +1,7 @@ +processed 4 tasks +task 0 lines 1-7: publish [module 0x33::untrusted] +task 1 lines 9-29: publish [module 0x3::trusted] +task 2 lines 32-32: run --verbose 0x3::trusted::sum_10_20_30 +return values: 60 +task 3 lines 34-34: run --verbose 0x3::trusted::sum_10_20_30_closure +return values: 60 diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_ok.baseline.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_ok.baseline.exp new file mode 100644 index 00000000000..c91e3631543 --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_ok.baseline.exp @@ -0,0 +1,7 @@ +processed 4 tasks +task 0 lines 1-7: publish [module 0x33::untrusted] +task 1 lines 9-29: publish [module 0x3::trusted] +task 2 lines 32-32: run --verbose 0x3::trusted::sum_10_20_30 +return values: 60 +task 3 lines 34-34: run --verbose 0x3::trusted::sum_10_20_30_closure +return values: 60 diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_ok.masm b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_ok.masm new file mode 100644 index 00000000000..012e159cbcd --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_ok.masm @@ -0,0 +1,34 @@ +//# publish +module 0x33::untrusted + +public fun return_20_30(): (u64, u64) + ld_u64 20 + ld_u64 30 + ret + +//# publish +module 0x3::trusted + +public fun sum_10_20_30(): u64 + ld_u64 10 + // stack size is 1 + call 0x33::untrusted::return_20_30 + // on return, stack size is 3 + add + add + ret + +public fun sum_10_20_30_closure(): u64 + ld_u64 10 + // stack size is 1 + pack_closure 0x33::untrusted::return_20_30, 0 + call_closure<||(u64, u64)> + // on return, stack size is 3 + add + add + ret + + +//# run --verbose 0x3::trusted::sum_10_20_30 + +//# run --verbose 0x3::trusted::sum_10_20_30_closure diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_ok.paranoid.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_ok.paranoid.exp new file mode 100644 index 00000000000..c91e3631543 --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/trusted_untrusted_ok.paranoid.exp @@ -0,0 +1,7 @@ +processed 4 tasks +task 0 lines 1-7: publish [module 0x33::untrusted] +task 1 lines 9-29: publish [module 0x3::trusted] +task 2 lines 32-32: run --verbose 0x3::trusted::sum_10_20_30 +return values: 60 +task 3 lines 34-34: run --verbose 0x3::trusted::sum_10_20_30_closure +return values: 60 diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_err.async-paranoid.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_err.async-paranoid.exp new file mode 100644 index 00000000000..84684049a9c --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_err.async-paranoid.exp @@ -0,0 +1,45 @@ +processed 8 tasks +task 0 lines 1-6: publish [module 0x3::trusted] +task 1 lines 8-26: publish [module 0x33::untrusted] +task 2 lines 29-36: publish [module 0x4::trusted] +task 3 lines 38-56: publish [module 0x44::untrusted] +task 4 lines 59-59: run --verbose 0x33::untrusted::sum_10_20 +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000003::trusted::return_20: expected: 3, got: 2, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x3::trusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: None, +} +task 5 lines 61-61: run --verbose 0x33::untrusted::sum_10_20_closure +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000003::trusted::return_20: expected: 3, got: 2, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x3::trusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: None, +} +task 6 lines 63-63: run --verbose 0x44::untrusted::sum_10_20_30_40 +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000004::trusted::return_20_30_40: expected: 3, got: 4, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x4::trusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 3)], + exec_state: None, +} +task 7 lines 65-65: run --verbose 0x44::untrusted::sum_10_20_30_40_closure +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000004::trusted::return_20_30_40: expected: 3, got: 4, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x4::trusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 3)], + exec_state: None, +} diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_err.baseline.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_err.baseline.exp new file mode 100644 index 00000000000..90ff2d3428e --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_err.baseline.exp @@ -0,0 +1,85 @@ +processed 8 tasks +task 0 lines 1-6: publish [module 0x3::trusted] +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000003::trusted'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x3::trusted, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} +task 1 lines 8-26: publish [module 0x33::untrusted] +Error: error: unknown module `0000000000000000000000000000000000000000000000000000000000000003::trusted` + ┌─ test:12:5 + │ +12 │ call 0x3::trusted::return_20 + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unknown module `0000000000000000000000000000000000000000000000000000000000000003::trusted` + ┌─ test:19:5 + │ +19 │ pack_closure 0x3::trusted::return_20, 0 + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +task 2 lines 29-36: publish [module 0x4::trusted] +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000004::trusted'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x4::trusted, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} +task 3 lines 38-56: publish [module 0x44::untrusted] +Error: error: unknown module `0000000000000000000000000000000000000000000000000000000000000004::trusted` + ┌─ test:42:5 + │ +42 │ call 0x4::trusted::return_20_30_40 + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unknown module `0000000000000000000000000000000000000000000000000000000000000004::trusted` + ┌─ test:49:5 + │ +49 │ pack_closure 0x4::trusted::return_20_30_40, 0 + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +task 4 lines 59-59: run --verbose 0x33::untrusted::sum_10_20 +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000033::untrusted doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 5 lines 61-61: run --verbose 0x33::untrusted::sum_10_20_closure +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000033::untrusted doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 6 lines 63-63: run --verbose 0x44::untrusted::sum_10_20_30_40 +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000044::untrusted doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 7 lines 65-65: run --verbose 0x44::untrusted::sum_10_20_30_40_closure +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000044::untrusted doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_err.masm b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_err.masm new file mode 100644 index 00000000000..dcccb4ca8f8 --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_err.masm @@ -0,0 +1,65 @@ +//# publish +module 0x3::trusted + +public fun return_20(): (u64, u64) + ld_u64 20 + ret + +//# publish +module 0x33::untrusted + +public fun sum_10_20(): u64 + ld_u64 10 + call 0x3::trusted::return_20 + add + add + ret + +public fun sum_10_20_closure(): u64 + ld_u64 10 + // stack size is 1 + pack_closure 0x3::trusted::return_20, 0 + call_closure<||(u64, u64)> + // on return, stack size is 3 + add + add + ret + + +//# publish +module 0x4::trusted + +public fun return_20_30_40(): (u64, u64) + ld_u64 20 + ld_u64 30 + ld_u64 40 + ret + +//# publish +module 0x44::untrusted + +public fun sum_10_20_30_40(): u64 + ld_u64 10 + call 0x4::trusted::return_20_30_40 + add + add + ret + +public fun sum_10_20_30_40_closure(): u64 + ld_u64 10 + // stack size is 1 + pack_closure 0x4::trusted::return_20_30_40, 0 + call_closure<||(u64, u64)> + // on return, stack size is 3 + add + add + ret + + +//# run --verbose 0x33::untrusted::sum_10_20 + +//# run --verbose 0x33::untrusted::sum_10_20_closure + +//# run --verbose 0x44::untrusted::sum_10_20_30_40 + +//# run --verbose 0x44::untrusted::sum_10_20_30_40_closure diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_err.paranoid.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_err.paranoid.exp new file mode 100644 index 00000000000..84684049a9c --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_err.paranoid.exp @@ -0,0 +1,45 @@ +processed 8 tasks +task 0 lines 1-6: publish [module 0x3::trusted] +task 1 lines 8-26: publish [module 0x33::untrusted] +task 2 lines 29-36: publish [module 0x4::trusted] +task 3 lines 38-56: publish [module 0x44::untrusted] +task 4 lines 59-59: run --verbose 0x33::untrusted::sum_10_20 +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000003::trusted::return_20: expected: 3, got: 2, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x3::trusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: None, +} +task 5 lines 61-61: run --verbose 0x33::untrusted::sum_10_20_closure +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000003::trusted::return_20: expected: 3, got: 2, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x3::trusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: None, +} +task 6 lines 63-63: run --verbose 0x44::untrusted::sum_10_20_30_40 +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000004::trusted::return_20_30_40: expected: 3, got: 4, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x4::trusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 3)], + exec_state: None, +} +task 7 lines 65-65: run --verbose 0x44::untrusted::sum_10_20_30_40_closure +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000004::trusted::return_20_30_40: expected: 3, got: 4, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x4::trusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 3)], + exec_state: None, +} diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_ok.async-paranoid.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_ok.async-paranoid.exp new file mode 100644 index 00000000000..fb2d5a9416d --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_ok.async-paranoid.exp @@ -0,0 +1,7 @@ +processed 4 tasks +task 0 lines 1-7: publish [module 0x3::trusted] +task 1 lines 9-29: publish [module 0x33::untrusted] +task 2 lines 32-32: run --verbose 0x33::untrusted::sum_10_20_30 +return values: 60 +task 3 lines 34-34: run --verbose 0x33::untrusted::sum_10_20_30_closure +return values: 60 diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_ok.baseline.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_ok.baseline.exp new file mode 100644 index 00000000000..fb2d5a9416d --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_ok.baseline.exp @@ -0,0 +1,7 @@ +processed 4 tasks +task 0 lines 1-7: publish [module 0x3::trusted] +task 1 lines 9-29: publish [module 0x33::untrusted] +task 2 lines 32-32: run --verbose 0x33::untrusted::sum_10_20_30 +return values: 60 +task 3 lines 34-34: run --verbose 0x33::untrusted::sum_10_20_30_closure +return values: 60 diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_ok.masm b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_ok.masm new file mode 100644 index 00000000000..4665bda1bb5 --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_ok.masm @@ -0,0 +1,34 @@ +//# publish +module 0x3::trusted + +public fun return_20_30(): (u64, u64) + ld_u64 20 + ld_u64 30 + ret + +//# publish +module 0x33::untrusted + +public fun sum_10_20_30(): u64 + ld_u64 10 + // stack size is 1 + call 0x3::trusted::return_20_30 + // on return, stack size is 3 + add + add + ret + +public fun sum_10_20_30_closure(): u64 + ld_u64 10 + // stack size is 1 + pack_closure 0x3::trusted::return_20_30, 0 + call_closure<||(u64, u64)> + // on return, stack size is 3 + add + add + ret + + +//# run --verbose 0x33::untrusted::sum_10_20_30 + +//# run --verbose 0x33::untrusted::sum_10_20_30_closure diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_ok.paranoid.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_ok.paranoid.exp new file mode 100644 index 00000000000..fb2d5a9416d --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_trusted_ok.paranoid.exp @@ -0,0 +1,7 @@ +processed 4 tasks +task 0 lines 1-7: publish [module 0x3::trusted] +task 1 lines 9-29: publish [module 0x33::untrusted] +task 2 lines 32-32: run --verbose 0x33::untrusted::sum_10_20_30 +return values: 60 +task 3 lines 34-34: run --verbose 0x33::untrusted::sum_10_20_30_closure +return values: 60 diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_err.async-paranoid.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_err.async-paranoid.exp new file mode 100644 index 00000000000..cc1d6f4138e --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_err.async-paranoid.exp @@ -0,0 +1,43 @@ +processed 6 tasks +task 0 lines 1-23: publish [module 0x33::untrusted] +task 1 lines 26-50: publish [module 0x44::untrusted] +task 2 lines 53-53: run --verbose 0x33::untrusted::sum_10_20 +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000033::untrusted::return_20: expected: 3, got: 2, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x33::untrusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: None, +} +task 3 lines 55-55: run --verbose 0x33::untrusted::sum_10_20_closure +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000033::untrusted::return_20: expected: 3, got: 2, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x33::untrusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: None, +} +task 4 lines 57-57: run --verbose 0x44::untrusted::sum_10_20_30_40 +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000044::untrusted::return_20_30_40: expected: 3, got: 4, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x44::untrusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 3)], + exec_state: None, +} +task 5 lines 59-59: run --verbose 0x44::untrusted::sum_10_20_30_40_closure +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000044::untrusted::return_20_30_40: expected: 3, got: 4, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x44::untrusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 3)], + exec_state: None, +} diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_err.baseline.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_err.baseline.exp new file mode 100644 index 00000000000..c567cbc9c44 --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_err.baseline.exp @@ -0,0 +1,57 @@ +processed 6 tasks +task 0 lines 1-23: publish [module 0x33::untrusted] +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000033::untrusted'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x33::untrusted, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} +task 1 lines 26-50: publish [module 0x44::untrusted] +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000044::untrusted'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x44::untrusted, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} +task 2 lines 53-53: run --verbose 0x33::untrusted::sum_10_20 +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000033::untrusted doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 3 lines 55-55: run --verbose 0x33::untrusted::sum_10_20_closure +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000033::untrusted doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 4 lines 57-57: run --verbose 0x44::untrusted::sum_10_20_30_40 +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000044::untrusted doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} +task 5 lines 59-59: run --verbose 0x44::untrusted::sum_10_20_30_40_closure +Error: Function execution failed with VMError: { + message: Linker Error: Module 0000000000000000000000000000000000000000000000000000000000000044::untrusted doesn't exist, + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], + exec_state: None, +} diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_err.masm b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_err.masm new file mode 100644 index 00000000000..f06e0f7614e --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_err.masm @@ -0,0 +1,59 @@ +//# publish +module 0x33::untrusted + +fun return_20(): (u64, u64) + ld_u64 20 + ret + +public fun sum_10_20(): u64 + ld_u64 10 + call return_20 + add + add + ret + +public fun sum_10_20_closure(): u64 + ld_u64 10 + // stack size is 1 + pack_closure return_20, 0 + call_closure<||(u64, u64)> + // on return, stack size is 3 + add + add + ret + + +//# publish +module 0x44::untrusted + +fun return_20_30_40(): (u64, u64) + ld_u64 20 + ld_u64 30 + ld_u64 40 + ret + +public fun sum_10_20_30_40(): u64 + ld_u64 10 + call return_20_30_40 + add + add + ret + +public fun sum_10_20_30_40_closure(): u64 + ld_u64 10 + // stack size is 1 + pack_closure return_20_30_40, 0 + call_closure<||(u64, u64)> + // on return, stack size is 3 + add + add + ret + + +//# run --verbose 0x33::untrusted::sum_10_20 + +//# run --verbose 0x33::untrusted::sum_10_20_closure + +//# run --verbose 0x44::untrusted::sum_10_20_30_40 + +//# run --verbose 0x44::untrusted::sum_10_20_30_40_closure diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_err.paranoid.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_err.paranoid.exp new file mode 100644 index 00000000000..cc1d6f4138e --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_err.paranoid.exp @@ -0,0 +1,43 @@ +processed 6 tasks +task 0 lines 1-23: publish [module 0x33::untrusted] +task 1 lines 26-50: publish [module 0x44::untrusted] +task 2 lines 53-53: run --verbose 0x33::untrusted::sum_10_20 +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000033::untrusted::return_20: expected: 3, got: 2, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x33::untrusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: None, +} +task 3 lines 55-55: run --verbose 0x33::untrusted::sum_10_20_closure +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000033::untrusted::return_20: expected: 3, got: 2, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x33::untrusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], + exec_state: None, +} +task 4 lines 57-57: run --verbose 0x44::untrusted::sum_10_20_30_40 +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000044::untrusted::return_20_30_40: expected: 3, got: 4, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x44::untrusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 3)], + exec_state: None, +} +task 5 lines 59-59: run --verbose 0x44::untrusted::sum_10_20_30_40_closure +Error: Function execution failed with VMError: { + message: Stack size mismatch when returning from 0x0000000000000000000000000000000000000000000000000000000000000044::untrusted::return_20_30_40: expected: 3, got: 4, + major_status: UNKNOWN_INVARIANT_VIOLATION_ERROR, + sub_status: Some(1), + location: 0x44::untrusted, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 3)], + exec_state: None, +} diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_ok.async-paranoid.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_ok.async-paranoid.exp new file mode 100644 index 00000000000..5fb9841d73c --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_ok.async-paranoid.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 1-26: publish [module 0x33::untrusted] +task 1 lines 29-29: run --verbose 0x33::untrusted::sum_10_20_30 +return values: 60 +task 2 lines 31-31: run --verbose 0x33::untrusted::sum_10_20_30_closure +return values: 60 diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_ok.baseline.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_ok.baseline.exp new file mode 100644 index 00000000000..5fb9841d73c --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_ok.baseline.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 1-26: publish [module 0x33::untrusted] +task 1 lines 29-29: run --verbose 0x33::untrusted::sum_10_20_30 +return values: 60 +task 2 lines 31-31: run --verbose 0x33::untrusted::sum_10_20_30_closure +return values: 60 diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_ok.masm b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_ok.masm new file mode 100644 index 00000000000..a1a5b7bfed1 --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_ok.masm @@ -0,0 +1,31 @@ +//# publish +module 0x33::untrusted + +fun return_20_30(): (u64, u64) + ld_u64 20 + ld_u64 30 + ret + +public fun sum_10_20_30(): u64 + ld_u64 10 + // stack size is 1 + call return_20_30 + // on return, stack size is 3 + add + add + ret + +public fun sum_10_20_30_closure(): u64 + ld_u64 10 + // stack size is 1 + pack_closure return_20_30, 0 + call_closure<||(u64, u64)> + // on return, stack size is 3 + add + add + ret + + +//# run --verbose 0x33::untrusted::sum_10_20_30 + +//# run --verbose 0x33::untrusted::sum_10_20_30_closure diff --git a/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_ok.paranoid.exp b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_ok.paranoid.exp new file mode 100644 index 00000000000..5fb9841d73c --- /dev/null +++ b/third_party/move/move-vm/transactional-tests/tests/stack_size/untrusted_untrusted_ok.paranoid.exp @@ -0,0 +1,6 @@ +processed 3 tasks +task 0 lines 1-26: publish [module 0x33::untrusted] +task 1 lines 29-29: run --verbose 0x33::untrusted::sum_10_20_30 +return values: 60 +task 2 lines 31-31: run --verbose 0x33::untrusted::sum_10_20_30_closure +return values: 60 diff --git a/third_party/move/move-vm/transactional-tests/tests/tests.rs b/third_party/move/move-vm/transactional-tests/tests/tests.rs index 16081dbb423..c57e9d918c1 100644 --- a/third_party/move/move-vm/transactional-tests/tests/tests.rs +++ b/third_party/move/move-vm/transactional-tests/tests/tests.rs @@ -60,8 +60,9 @@ static TEST_CONFIGS: Lazy> = Lazy::new(|| { // Note: for functions values the difference between generated files are stack // traces only (attached for in-place checks, set to None for async checks). "/function_values_safety/", - "/trusted_code/", "/paranoid-tests/", + "/stack_size/", + "/trusted_code/", ], exclude: &[], tracing: true, @@ -77,8 +78,9 @@ static TEST_CONFIGS: Lazy> = Lazy::new(|| { ), include: &[ "/function_values_safety/", - "/trusted_code/", "/paranoid-tests/", + "/stack_size/", + "/trusted_code/", ], exclude: &[], tracing: false, @@ -96,12 +98,13 @@ static TEST_CONFIGS: Lazy> = Lazy::new(|| { }, include: &[], exclude: &[ + "/function_values_safety/", "/lazy_loading/", "/paranoid-tests/", - "/function_values_safety/", - "/trusted_code/", - "/tracing/", "/runtime_ref_checks/", + "/stack_size/", + "/tracing/", + "/trusted_code/", ], tracing: false, }, @@ -154,8 +157,9 @@ const SEPARATE_BASELINE: &[&str] = &[ "/function_values_safety/", "/module_publishing/", "/re_entrancy/", - "/trusted_code/", "/runtime_ref_checks/", + "/stack_size/", + "/trusted_code/", ]; fn get_config_by_name(name: &str) -> TestConfig { From 12f91373ae515740d21e2ac80c927bb71fef46a4 Mon Sep 17 00:00:00 2001 From: George Mitenkov Date: Fri, 21 Nov 2025 00:34:47 +0000 Subject: [PATCH 257/260] [vm] Use &[Type] for native type args (#18171) Downstreamed-from: f134e676b22f84b85e673b238c20fc11332648f1 --- .../aptos-native-interface/src/builder.rs | 10 +- .../aptos-native-interface/src/helpers.rs | 20 ---- .../aptos-native-interface/src/native.rs | 7 +- .../aptos-vm-profiling/src/bins/run_move.rs | 2 +- .../framework/move-stdlib/src/natives/bcs.rs | 21 ++-- .../framework/move-stdlib/src/natives/cmp.rs | 2 +- .../framework/move-stdlib/src/natives/hash.rs | 4 +- .../framework/move-stdlib/src/natives/mem.rs | 2 +- .../move-stdlib/src/natives/signer.rs | 2 +- .../move-stdlib/src/natives/string.rs | 8 +- .../move-stdlib/src/natives/unit_test.rs | 2 +- .../move-stdlib/src/natives/vector.rs | 2 +- aptos-move/framework/src/natives/account.rs | 2 +- .../src/natives/account_abstraction.rs | 4 +- .../natives/aggregator_natives/aggregator.rs | 8 +- .../aggregator_natives/aggregator_factory.rs | 2 +- .../aggregator_natives/aggregator_v2.rs | 28 ++--- aptos-move/framework/src/natives/code.rs | 2 +- .../framework/src/natives/consensus_config.rs | 2 +- .../framework/src/natives/create_signer.rs | 2 +- .../cryptography/algebra/arithmetics/add.rs | 2 +- .../cryptography/algebra/arithmetics/div.rs | 2 +- .../algebra/arithmetics/double.rs | 2 +- .../cryptography/algebra/arithmetics/inv.rs | 2 +- .../cryptography/algebra/arithmetics/mul.rs | 2 +- .../cryptography/algebra/arithmetics/neg.rs | 2 +- .../algebra/arithmetics/scalar_mul.rs | 4 +- .../cryptography/algebra/arithmetics/sqr.rs | 2 +- .../cryptography/algebra/arithmetics/sub.rs | 2 +- .../natives/cryptography/algebra/casting.rs | 4 +- .../natives/cryptography/algebra/constants.rs | 6 +- .../src/natives/cryptography/algebra/eq.rs | 2 +- .../cryptography/algebra/hash_to_structure.rs | 2 +- .../src/natives/cryptography/algebra/new.rs | 2 +- .../natives/cryptography/algebra/pairing.rs | 4 +- .../src/natives/cryptography/algebra/rand.rs | 2 +- .../cryptography/algebra/serialization.rs | 4 +- .../src/natives/cryptography/bls12381.rs | 48 ++++---- .../src/natives/cryptography/bulletproofs.rs | 16 +-- .../src/natives/cryptography/ed25519.rs | 10 +- .../src/natives/cryptography/multi_ed25519.rs | 16 +-- .../cryptography/ristretto255_point.rs | 36 +++--- .../cryptography/ristretto255_scalar.rs | 24 ++-- .../src/natives/cryptography/secp256k1.rs | 2 +- aptos-move/framework/src/natives/debug.rs | 8 +- .../natives/dispatchable_fungible_asset.rs | 4 +- aptos-move/framework/src/natives/event.rs | 32 +++--- .../framework/src/natives/function_info.rs | 6 +- aptos-move/framework/src/natives/hash.rs | 12 +- aptos-move/framework/src/natives/object.rs | 8 +- .../src/natives/permissioned_signer.rs | 8 +- .../framework/src/natives/randomness.rs | 4 +- .../framework/src/natives/state_storage.rs | 2 +- .../framework/src/natives/string_utils.rs | 4 +- .../src/natives/transaction_context.rs | 107 ++++++++++++++++-- aptos-move/framework/src/natives/type_info.rs | 6 +- aptos-move/framework/src/natives/util.rs | 2 +- aptos-move/framework/table-natives/src/lib.rs | 14 +-- .../move-table-extension/src/lib.rs | 14 +-- .../crates/natives/src/account.rs | 4 +- .../crates/natives/src/signature.rs | 4 +- .../move/move-stdlib/src/natives/bcs.rs | 6 +- .../move/move-stdlib/src/natives/debug.rs | 16 +-- .../move/move-stdlib/src/natives/event.rs | 2 +- .../move/move-stdlib/src/natives/hash.rs | 4 +- .../move/move-stdlib/src/natives/signer.rs | 2 +- .../move/move-stdlib/src/natives/string.rs | 8 +- .../move/move-stdlib/src/natives/type_name.rs | 2 +- .../move/move-stdlib/src/natives/unit_test.rs | 2 +- .../move/move-vm/runtime/src/interpreter.rs | 2 +- .../move-vm/runtime/src/native_functions.rs | 2 +- 71 files changed, 338 insertions(+), 277 deletions(-) diff --git a/aptos-move/aptos-native-interface/src/builder.rs b/aptos-move/aptos-native-interface/src/builder.rs index b65e6fcb397..bd090a5bf78 100644 --- a/aptos-move/aptos-native-interface/src/builder.rs +++ b/aptos-move/aptos-native-interface/src/builder.rs @@ -81,9 +81,9 @@ impl SafeNativeBuilder { /// allowing the client to use [`SafeNativeContext`] instead of Move VM's [`NativeContext`]. pub fn make_native(&self, native: F) -> NativeFunction where - F: Fn( + F: for<'a> Fn( &mut SafeNativeContext, - Vec, + &'a [Type], VecDeque, ) -> SafeNativeResult> + Send @@ -95,7 +95,7 @@ impl SafeNativeBuilder { let enable_incremental_gas_charging = self.enable_incremental_gas_charging; - let closure = move |context: &mut NativeContext, ty_args, args| { + let closure = move |context: &mut NativeContext, ty_args: &[Type], args| { use SafeNativeError::*; let mut context = SafeNativeContext { @@ -175,9 +175,9 @@ impl SafeNativeBuilder { ) -> impl Iterator + 'a where 'b: 'a, - F: Fn( + F: for<'c> Fn( &mut SafeNativeContext, - Vec, + &'c [Type], VecDeque, ) -> SafeNativeResult> + Send diff --git a/aptos-move/aptos-native-interface/src/helpers.rs b/aptos-move/aptos-native-interface/src/helpers.rs index 22519f393ce..f0674f520fe 100644 --- a/aptos-move/aptos-native-interface/src/helpers.rs +++ b/aptos-move/aptos-native-interface/src/helpers.rs @@ -60,26 +60,6 @@ macro_rules! safely_assert_eq { }}; } -/// Pops a `Type` argument off the type argument stack inside a safe native. Returns a -/// `SafeNativeError::InvariantViolation(UNKNOWN_INVARIANT_VIOLATION_ERROR)` in case there are not -/// enough arguments on the stack. -/// -/// NOTE: Expects as its argument an object that has a `fn pop(&self) -> Option<_>` method (e.g., a `Vec<_>`) -#[macro_export] -macro_rules! safely_pop_type_arg { - ($ty_args:ident) => {{ - use $crate::reexports::move_vm_types::natives::function::{PartialVMError, StatusCode}; - match $ty_args.pop() { - Some(ty) => ty, - None => { - return Err($crate::SafeNativeError::InvariantViolation( - PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR), - )) - }, - } - }}; -} - /// Like `pop_vec_arg` but for safe natives that return `SafeNativeResult`. /// (Duplicates code from above, unfortunately.) #[macro_export] diff --git a/aptos-move/aptos-native-interface/src/native.rs b/aptos-move/aptos-native-interface/src/native.rs index e917307b85c..02c096bc857 100644 --- a/aptos-move/aptos-native-interface/src/native.rs +++ b/aptos-move/aptos-native-interface/src/native.rs @@ -10,8 +10,5 @@ use std::collections::VecDeque; /// /// A raw native needs to be made into a closure that carries various configurations before /// it can be used in the VM. -pub type RawSafeNative = fn( - &mut SafeNativeContext, - Vec, - VecDeque, -) -> SafeNativeResult>; +pub type RawSafeNative = + fn(&mut SafeNativeContext, &[Type], VecDeque) -> SafeNativeResult>; diff --git a/aptos-move/aptos-vm-profiling/src/bins/run_move.rs b/aptos-move/aptos-vm-profiling/src/bins/run_move.rs index c2969f48f37..bbc65e9511f 100644 --- a/aptos-move/aptos-vm-profiling/src/bins/run_move.rs +++ b/aptos-move/aptos-vm-profiling/src/bins/run_move.rs @@ -37,7 +37,7 @@ enum Entrypoint { } fn make_native_create_signer() -> NativeFunction { - Arc::new(|_context, ty_args: Vec, mut args: VecDeque| { + Arc::new(|_context, ty_args: &[Type], mut args: VecDeque| { assert!(ty_args.is_empty()); assert_eq!(args.len(), 1); diff --git a/aptos-move/framework/move-stdlib/src/natives/bcs.rs b/aptos-move/framework/move-stdlib/src/natives/bcs.rs index 3c5ec2c32e9..babfd7eb5b9 100644 --- a/aptos-move/framework/move-stdlib/src/natives/bcs.rs +++ b/aptos-move/framework/move-stdlib/src/natives/bcs.rs @@ -53,17 +53,16 @@ pub fn create_option_u64(enum_option_enabled: bool, value: Option) -> Value * **************************************************************************************************/ /// Rust implementation of Move's `native public fun to_bytes(&T): vector` -#[inline] fn native_to_bytes( context: &mut SafeNativeContext, - mut ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert!(ty_args.len() == 1); debug_assert!(args.len() == 1); let ref_to_val = safely_pop_arg!(args, Reference); - let arg_type = ty_args.pop().unwrap(); + let arg_type = &ty_args[0]; let layout = if context.get_feature_flags().is_lazy_loading_enabled() { // With lazy loading, propagate the error directly. This is because errors here are likely @@ -76,9 +75,9 @@ fn native_to_bytes( // - Constructing layout runs into dependency limit. // - We cannot do `context.charge(BCS_TO_BYTES_FAILURE)?;` because then we can end up in // the state where out of gas and dependency limit are hit at the same time. - context.type_to_type_layout(&arg_type)? + context.type_to_type_layout(arg_type)? } else { - match context.type_to_type_layout(&arg_type) { + match context.type_to_type_layout(arg_type) { Ok(layout) => layout, Err(_) => { context.charge(BCS_TO_BYTES_FAILURE)?; @@ -125,7 +124,7 @@ fn native_to_bytes( **************************************************************************************************/ fn native_serialized_size( context: &mut SafeNativeContext, - mut ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert!(ty_args.len() == 1); @@ -134,9 +133,9 @@ fn native_serialized_size( context.charge(BCS_SERIALIZED_SIZE_BASE)?; let reference = safely_pop_arg!(args, Reference); - let ty = ty_args.pop().unwrap(); + let ty = &ty_args[0]; - let serialized_size = match serialized_size_impl(context, reference, &ty) { + let serialized_size = match serialized_size_impl(context, reference, ty) { Ok(serialized_size) => serialized_size as u64, Err(_) => { context.charge(BCS_SERIALIZED_SIZE_FAILURE)?; @@ -173,15 +172,15 @@ fn serialized_size_impl( fn native_constant_serialized_size( context: &mut SafeNativeContext, - mut ty_args: Vec, + ty_args: &[Type], _args: VecDeque, ) -> SafeNativeResult> { debug_assert!(ty_args.len() == 1); context.charge(BCS_CONSTANT_SERIALIZED_SIZE_BASE)?; - let ty = ty_args.pop().unwrap(); - let ty_layout = context.type_to_type_layout(&ty)?; + let ty = &ty_args[0]; + let ty_layout = context.type_to_type_layout(ty)?; let (visited_count, serialized_size_result) = constant_serialized_size(&ty_layout); context diff --git a/aptos-move/framework/move-stdlib/src/natives/cmp.rs b/aptos-move/framework/move-stdlib/src/natives/cmp.rs index e3950b81736..ce2380ed6a9 100644 --- a/aptos-move/framework/move-stdlib/src/natives/cmp.rs +++ b/aptos-move/framework/move-stdlib/src/natives/cmp.rs @@ -35,7 +35,7 @@ const ORDERING_GREATER_THAN_VARIANT: u16 = 2; **************************************************************************************************/ fn native_compare( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], args: VecDeque, ) -> SafeNativeResult> { debug_assert!(args.len() == 2); diff --git a/aptos-move/framework/move-stdlib/src/natives/hash.rs b/aptos-move/framework/move-stdlib/src/natives/hash.rs index 2509cb321ac..279a467b094 100644 --- a/aptos-move/framework/move-stdlib/src/natives/hash.rs +++ b/aptos-move/framework/move-stdlib/src/natives/hash.rs @@ -26,7 +26,7 @@ use std::collections::VecDeque; #[inline] fn native_sha2_256( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(_ty_args.is_empty()); @@ -51,7 +51,7 @@ fn native_sha2_256( #[inline] fn native_sha3_256( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(_ty_args.is_empty()); diff --git a/aptos-move/framework/move-stdlib/src/natives/mem.rs b/aptos-move/framework/move-stdlib/src/natives/mem.rs index 578d4dc02d6..9c7b3bdd252 100644 --- a/aptos-move/framework/move-stdlib/src/natives/mem.rs +++ b/aptos-move/framework/move-stdlib/src/natives/mem.rs @@ -28,7 +28,7 @@ pub const EFEATURE_NOT_ENABLED: u64 = 1; **************************************************************************************************/ fn native_swap( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { if !context diff --git a/aptos-move/framework/move-stdlib/src/natives/signer.rs b/aptos-move/framework/move-stdlib/src/natives/signer.rs index e0e202fd3ca..68c3ff01878 100644 --- a/aptos-move/framework/move-stdlib/src/natives/signer.rs +++ b/aptos-move/framework/move-stdlib/src/natives/signer.rs @@ -26,7 +26,7 @@ use std::collections::VecDeque; #[inline] fn native_borrow_address( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(_ty_args.is_empty()); diff --git a/aptos-move/framework/move-stdlib/src/natives/string.rs b/aptos-move/framework/move-stdlib/src/natives/string.rs index f90f7050491..92f78b58a2f 100644 --- a/aptos-move/framework/move-stdlib/src/natives/string.rs +++ b/aptos-move/framework/move-stdlib/src/natives/string.rs @@ -36,7 +36,7 @@ use std::collections::VecDeque; **************************************************************************************************/ fn native_check_utf8( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert!(args.len() == 1); @@ -62,7 +62,7 @@ fn native_check_utf8( **************************************************************************************************/ fn native_is_char_boundary( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert!(args.len() == 2); @@ -88,7 +88,7 @@ fn native_is_char_boundary( **************************************************************************************************/ fn native_sub_string( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert!(args.len() == 3); @@ -124,7 +124,7 @@ fn native_sub_string( **************************************************************************************************/ fn native_index_of( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert!(args.len() == 2); diff --git a/aptos-move/framework/move-stdlib/src/natives/unit_test.rs b/aptos-move/framework/move-stdlib/src/natives/unit_test.rs index 6ce5045be3d..a41726c3596 100644 --- a/aptos-move/framework/move-stdlib/src/natives/unit_test.rs +++ b/aptos-move/framework/move-stdlib/src/natives/unit_test.rs @@ -29,7 +29,7 @@ fn to_le_bytes(i: u64) -> [u8; AccountAddress::LENGTH] { fn native_create_signers_for_testing( _context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert!(ty_args.is_empty()); diff --git a/aptos-move/framework/move-stdlib/src/natives/vector.rs b/aptos-move/framework/move-stdlib/src/natives/vector.rs index edb15ad0f79..74d4da2b755 100644 --- a/aptos-move/framework/move-stdlib/src/natives/vector.rs +++ b/aptos-move/framework/move-stdlib/src/natives/vector.rs @@ -38,7 +38,7 @@ pub const EFEATURE_NOT_ENABLED: u64 = 2; **************************************************************************************************/ fn native_move_range( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { if !context diff --git a/aptos-move/framework/src/natives/account.rs b/aptos-move/framework/src/natives/account.rs index 163ca71f008..8eb2c96f36b 100644 --- a/aptos-move/framework/src/natives/account.rs +++ b/aptos-move/framework/src/natives/account.rs @@ -27,7 +27,7 @@ pub struct CreateAddressGasParameters { fn native_create_address( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(ty_args.is_empty()); diff --git a/aptos-move/framework/src/natives/account_abstraction.rs b/aptos-move/framework/src/natives/account_abstraction.rs index c236fafb9a2..a45f3def94f 100644 --- a/aptos-move/framework/src/natives/account_abstraction.rs +++ b/aptos-move/framework/src/natives/account_abstraction.rs @@ -21,7 +21,7 @@ use std::collections::VecDeque; **************************************************************************************************/ pub(crate) fn native_dispatch( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { let (module_name, func_name) = extract_function_info(&mut arguments)?; @@ -38,7 +38,7 @@ pub(crate) fn native_dispatch( Err(SafeNativeError::FunctionDispatch { module_name, func_name, - ty_args, + ty_args: ty_args.to_vec(), args: arguments.into_iter().collect(), }) } diff --git a/aptos-move/framework/src/natives/aggregator_natives/aggregator.rs b/aptos-move/framework/src/natives/aggregator_natives/aggregator.rs index 628fc7f5917..80db680c1f2 100644 --- a/aptos-move/framework/src/natives/aggregator_natives/aggregator.rs +++ b/aptos-move/framework/src/natives/aggregator_natives/aggregator.rs @@ -26,7 +26,7 @@ use std::collections::VecDeque; **************************************************************************************************/ fn native_add( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert_eq!(args.len(), 2); @@ -55,7 +55,7 @@ fn native_add( **************************************************************************************************/ fn native_read( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert_eq!(args.len(), 1); @@ -84,7 +84,7 @@ fn native_read( fn native_sub( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert_eq!(args.len(), 2); @@ -113,7 +113,7 @@ fn native_sub( **************************************************************************************************/ fn native_destroy( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert_eq!(args.len(), 1); diff --git a/aptos-move/framework/src/natives/aggregator_natives/aggregator_factory.rs b/aptos-move/framework/src/natives/aggregator_natives/aggregator_factory.rs index ff7b2695c4b..8245e0db24f 100644 --- a/aptos-move/framework/src/natives/aggregator_natives/aggregator_factory.rs +++ b/aptos-move/framework/src/natives/aggregator_natives/aggregator_factory.rs @@ -28,7 +28,7 @@ use std::collections::VecDeque; **************************************************************************************************/ fn native_new_aggregator( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert_eq!(args.len(), 2); diff --git a/aptos-move/framework/src/natives/aggregator_natives/aggregator_v2.rs b/aptos-move/framework/src/natives/aggregator_natives/aggregator_v2.rs index 6de952539f0..71f192a6219 100644 --- a/aptos-move/framework/src/natives/aggregator_natives/aggregator_v2.rs +++ b/aptos-move/framework/src/natives/aggregator_natives/aggregator_v2.rs @@ -137,7 +137,7 @@ fn create_aggregator_with_max_value( fn native_create_aggregator( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert_eq!(args.len(), 1); @@ -154,7 +154,7 @@ fn native_create_aggregator( fn native_create_unbounded_aggregator( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], args: VecDeque, ) -> SafeNativeResult> { debug_assert_eq!(args.len(), 0); @@ -170,7 +170,7 @@ fn native_create_unbounded_aggregator( **************************************************************************************************/ fn native_try_add( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert_eq!(args.len(), 2); @@ -216,7 +216,7 @@ fn native_try_add( **************************************************************************************************/ fn native_try_sub( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert_eq!(args.len(), 2); @@ -259,7 +259,7 @@ fn native_try_sub( fn native_is_at_least_impl( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert_eq!(args.len(), 2); @@ -297,7 +297,7 @@ fn native_is_at_least_impl( fn native_read( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert_eq!(args.len(), 1); @@ -333,7 +333,7 @@ fn native_read( fn native_snapshot( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert_eq!(args.len(), 1); @@ -368,7 +368,7 @@ fn native_snapshot( fn native_create_snapshot( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert_eq!(ty_args.len(), 1); @@ -406,7 +406,7 @@ fn native_create_snapshot( fn native_copy_snapshot( _context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], _args: VecDeque, ) -> SafeNativeResult> { Err(SafeNativeError::Abort { @@ -420,7 +420,7 @@ fn native_copy_snapshot( fn native_read_snapshot( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert_eq!(ty_args.len(), 1); @@ -449,7 +449,7 @@ fn native_read_snapshot( **************************************************************************************************/ fn native_string_concat( _context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], _args: VecDeque, ) -> SafeNativeResult> { // Deprecated function in favor of `derive_string_concat`. @@ -464,7 +464,7 @@ fn native_string_concat( fn native_read_derived_string( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert_eq!(ty_args.len(), 0); @@ -489,7 +489,7 @@ fn native_read_derived_string( fn native_create_derived_string( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert_eq!(ty_args.len(), 0); @@ -530,7 +530,7 @@ fn native_create_derived_string( fn native_derive_string_concat( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert_eq!(ty_args.len(), 1); diff --git a/aptos-move/framework/src/natives/code.rs b/aptos-move/framework/src/natives/code.rs index 08fdcc2d29c..c7c72b7a64c 100644 --- a/aptos-move/framework/src/natives/code.rs +++ b/aptos-move/framework/src/natives/code.rs @@ -263,7 +263,7 @@ fn unpack_allowed_dep(v: Value) -> PartialVMResult<(AccountAddress, String)> { **************************************************************************************************/ fn native_request_publish( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert!(matches!(args.len(), 4 | 5)); diff --git a/aptos-move/framework/src/natives/consensus_config.rs b/aptos-move/framework/src/natives/consensus_config.rs index 2cccebf7f66..380c1c6d7c2 100644 --- a/aptos-move/framework/src/natives/consensus_config.rs +++ b/aptos-move/framework/src/natives/consensus_config.rs @@ -12,7 +12,7 @@ use std::collections::VecDeque; pub fn validator_txn_enabled( _context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { let config_bytes = safely_pop_arg!(args, Vec); diff --git a/aptos-move/framework/src/natives/create_signer.rs b/aptos-move/framework/src/natives/create_signer.rs index 6ba6f79b578..c268595e33d 100644 --- a/aptos-move/framework/src/natives/create_signer.rs +++ b/aptos-move/framework/src/natives/create_signer.rs @@ -19,7 +19,7 @@ use std::collections::VecDeque; **************************************************************************************************/ pub(crate) fn native_create_signer( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(ty_args.is_empty()); diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/add.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/add.rs index 60e422e73dd..113d3a5a221 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/add.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/add.rs @@ -22,7 +22,7 @@ use std::{ pub fn add_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(1, ty_args.len()); diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/div.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/div.rs index 439979e0b53..9c6fd62fa30 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/div.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/div.rs @@ -37,7 +37,7 @@ macro_rules! ark_div_internal { pub fn div_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(1, ty_args.len()); diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/double.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/double.rs index 02b525c4a40..0ab7f59d871 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/double.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/double.rs @@ -20,7 +20,7 @@ use std::{collections::VecDeque, rc::Rc}; pub fn double_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(1, ty_args.len()); diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/inv.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/inv.rs index 96d55bfce30..578a36a7776 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/inv.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/inv.rs @@ -35,7 +35,7 @@ macro_rules! ark_inverse_internal { pub fn inv_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { let structure_opt = structure_from_ty_arg!(context, &ty_args[0]); diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/mul.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/mul.rs index 3d56b6d6d73..b30f92488fe 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/mul.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/mul.rs @@ -18,7 +18,7 @@ use std::{collections::VecDeque, ops::Mul, rc::Rc}; pub fn mul_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(1, ty_args.len()); diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/neg.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/neg.rs index f0af2be6625..743028f89c7 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/neg.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/neg.rs @@ -21,7 +21,7 @@ use std::{collections::VecDeque, ops::Neg, rc::Rc}; pub fn neg_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(1, ty_args.len()); diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/scalar_mul.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/scalar_mul.rs index 4f847cb5ce5..0cad06f4182 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/scalar_mul.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/scalar_mul.rs @@ -98,7 +98,7 @@ macro_rules! ark_msm_bigint_wnaf_cost { pub fn scalar_mul_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(2, ty_args.len()); @@ -246,7 +246,7 @@ macro_rules! ark_msm_internal { pub fn multi_scalar_mul_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(2, ty_args.len()); diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sqr.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sqr.rs index d5ffab5ef58..737dfe4aff9 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sqr.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sqr.rs @@ -19,7 +19,7 @@ use std::{collections::VecDeque, rc::Rc}; pub fn sqr_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { let structure_opt = structure_from_ty_arg!(context, &ty_args[0]); diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sub.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sub.rs index 2817d2262ca..3b744bd2c75 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sub.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sub.rs @@ -22,7 +22,7 @@ use std::{ pub fn sub_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(1, ty_args.len()); diff --git a/aptos-move/framework/src/natives/cryptography/algebra/casting.rs b/aptos-move/framework/src/natives/cryptography/algebra/casting.rs index e18b86a1288..f3822e0ea3a 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/casting.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/casting.rs @@ -44,7 +44,7 @@ macro_rules! abort_unless_casting_enabled { pub fn downcast_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(2, ty_args.len()); @@ -83,7 +83,7 @@ pub fn downcast_internal( pub fn upcast_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(2, ty_args.len()); diff --git a/aptos-move/framework/src/natives/cryptography/algebra/constants.rs b/aptos-move/framework/src/natives/cryptography/algebra/constants.rs index 70c33dec03d..e5a46eca458 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/constants.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/constants.rs @@ -32,7 +32,7 @@ macro_rules! ark_constant_op_internal { pub fn zero_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut _args: VecDeque, ) -> SafeNativeResult> { let structure_opt = structure_from_ty_arg!(context, &ty_args[0]); @@ -100,7 +100,7 @@ pub fn zero_internal( pub fn one_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut _args: VecDeque, ) -> SafeNativeResult> { let structure_opt = structure_from_ty_arg!(context, &ty_args[0]); @@ -175,7 +175,7 @@ pub fn one_internal( pub fn order_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut _args: VecDeque, ) -> SafeNativeResult> { assert_eq!(1, ty_args.len()); diff --git a/aptos-move/framework/src/natives/cryptography/algebra/eq.rs b/aptos-move/framework/src/natives/cryptography/algebra/eq.rs index b4836720b77..9b2f564d0ed 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/eq.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/eq.rs @@ -31,7 +31,7 @@ macro_rules! ark_eq_internal { pub fn eq_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(1, ty_args.len()); diff --git a/aptos-move/framework/src/natives/cryptography/algebra/hash_to_structure.rs b/aptos-move/framework/src/natives/cryptography/algebra/hash_to_structure.rs index 889f9d8a291..086afbd3dea 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/hash_to_structure.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/hash_to_structure.rs @@ -88,7 +88,7 @@ macro_rules! hash_to_bls12381gx_cost { pub fn hash_to_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(2, ty_args.len()); diff --git a/aptos-move/framework/src/natives/cryptography/algebra/new.rs b/aptos-move/framework/src/natives/cryptography/algebra/new.rs index 05050c50ed4..58beef332f7 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/new.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/new.rs @@ -29,7 +29,7 @@ macro_rules! from_u64_internal { pub fn from_u64_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(1, ty_args.len()); diff --git a/aptos-move/framework/src/natives/cryptography/algebra/pairing.rs b/aptos-move/framework/src/natives/cryptography/algebra/pairing.rs index dafbbcd50aa..eb2e5cc649f 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/pairing.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/pairing.rs @@ -127,7 +127,7 @@ macro_rules! multi_pairing_internal { } pub fn multi_pairing_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(3, ty_args.len()); @@ -170,7 +170,7 @@ pub fn multi_pairing_internal( pub fn pairing_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(3, ty_args.len()); diff --git a/aptos-move/framework/src/natives/cryptography/algebra/rand.rs b/aptos-move/framework/src/natives/cryptography/algebra/rand.rs index 334618bc0b5..927536d935f 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/rand.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/rand.rs @@ -52,7 +52,7 @@ macro_rules! ark_rand_internal { #[cfg(feature = "testing")] pub fn rand_insecure_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut _args: VecDeque, ) -> SafeNativeResult> { assert_eq!(1, ty_args.len()); diff --git a/aptos-move/framework/src/natives/cryptography/algebra/serialization.rs b/aptos-move/framework/src/natives/cryptography/algebra/serialization.rs index b77427a4f7d..15469a580d0 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/serialization.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/serialization.rs @@ -130,7 +130,7 @@ macro_rules! serialize_element { pub fn serialize_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(2, ty_args.len()); @@ -341,7 +341,7 @@ macro_rules! ark_ec_point_deserialize_internal { pub fn deserialize_internal( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(2, ty_args.len()); diff --git a/aptos-move/framework/src/natives/cryptography/bls12381.rs b/aptos-move/framework/src/natives/cryptography/bls12381.rs index 357ea2c24eb..dddd5f56e73 100644 --- a/aptos-move/framework/src/natives/cryptography/bls12381.rs +++ b/aptos-move/framework/src/natives/cryptography/bls12381.rs @@ -211,11 +211,11 @@ fn signature_verify( /// failed. pub fn bls12381_verify_signature_helper( context: &mut SafeNativeContext, - _ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, check_pk_subgroup: bool, ) -> SafeNativeResult> { - debug_assert!(_ty_args.is_empty()); + debug_assert!(ty_args.is_empty()); debug_assert!(arguments.len() == 3); context.charge(BLS12381_BASE)?; @@ -267,10 +267,10 @@ pub fn bls12381_verify_signature_helper( **************************************************************************************************/ fn native_bls12381_aggregate_pubkeys( context: &mut SafeNativeContext, - _ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { - debug_assert!(_ty_args.is_empty()); + debug_assert!(ty_args.is_empty()); debug_assert!(arguments.len() == 1); // Parses a Vec> of all serialized public keys @@ -323,10 +323,10 @@ fn native_bls12381_aggregate_pubkeys( **************************************************************************************************/ pub fn native_bls12381_aggregate_signatures( context: &mut SafeNativeContext, - _ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { - debug_assert!(_ty_args.is_empty()); + debug_assert!(ty_args.is_empty()); debug_assert!(arguments.len() == 1); // Parses a Vec> of all serialized signatures @@ -370,10 +370,10 @@ pub fn native_bls12381_aggregate_signatures( **************************************************************************************************/ pub fn native_bls12381_signature_subgroup_check( context: &mut SafeNativeContext, - _ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { - debug_assert!(_ty_args.is_empty()); + debug_assert!(ty_args.is_empty()); debug_assert!(arguments.len() == 1); context.charge(BLS12381_BASE)?; @@ -400,10 +400,10 @@ pub fn native_bls12381_signature_subgroup_check( **************************************************************************************************/ fn native_bls12381_validate_pubkey( context: &mut SafeNativeContext, - _ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { - debug_assert!(_ty_args.is_empty()); + debug_assert!(ty_args.is_empty()); debug_assert!(arguments.len() == 1); context.charge(BLS12381_BASE)?; @@ -451,10 +451,10 @@ fn native_bls12381_validate_pubkey( **************************************************************************************************/ pub fn native_bls12381_verify_aggregate_signature( context: &mut SafeNativeContext, - _ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { - debug_assert!(_ty_args.is_empty()); + debug_assert!(ty_args.is_empty()); debug_assert!(arguments.len() == 3); context.charge(BLS12381_BASE)?; @@ -523,11 +523,11 @@ pub fn native_bls12381_verify_aggregate_signature( **************************************************************************************************/ pub fn native_bls12381_verify_multisignature( context: &mut SafeNativeContext, - _ty_args: Vec, + ty_args: &[Type], arguments: VecDeque, ) -> SafeNativeResult> { let check_pk_subgroup = false; - bls12381_verify_signature_helper(context, _ty_args, arguments, check_pk_subgroup) + bls12381_verify_signature_helper(context, ty_args, arguments, check_pk_subgroup) } /*************************************************************************************************** @@ -544,14 +544,14 @@ pub fn native_bls12381_verify_multisignature( **************************************************************************************************/ pub fn native_bls12381_verify_normal_signature( context: &mut SafeNativeContext, - _ty_args: Vec, + ty_args: &[Type], arguments: VecDeque, ) -> SafeNativeResult> { // For normal (non-aggregated) signatures, PK's typically don't come with PoPs and the caller // might forget to check prime-order subgroup membership of the PK. Therefore, we always enforce // it here. let check_pk_subgroup = true; - bls12381_verify_signature_helper(context, _ty_args, arguments, check_pk_subgroup) + bls12381_verify_signature_helper(context, ty_args, arguments, check_pk_subgroup) } /*************************************************************************************************** @@ -566,10 +566,10 @@ pub fn native_bls12381_verify_normal_signature( **************************************************************************************************/ fn native_bls12381_verify_proof_of_possession( context: &mut SafeNativeContext, - _ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { - debug_assert!(_ty_args.is_empty()); + debug_assert!(ty_args.is_empty()); debug_assert!(arguments.len() == 2); context.charge(BLS12381_BASE)?; @@ -607,20 +607,20 @@ fn native_bls12381_verify_proof_of_possession( **************************************************************************************************/ pub fn native_bls12381_verify_signature_share( context: &mut SafeNativeContext, - _ty_args: Vec, + ty_args: &[Type], arguments: VecDeque, ) -> SafeNativeResult> { // For signature shares, the caller is REQUIRED to check the PK's PoP, and thus the PK is in the // prime-order subgroup. let check_pk_subgroup = false; - bls12381_verify_signature_helper(context, _ty_args, arguments, check_pk_subgroup) + bls12381_verify_signature_helper(context, ty_args, arguments, check_pk_subgroup) } #[cfg(feature = "testing")] pub fn native_generate_keys( _context: &mut SafeNativeContext, - _ty_args: Vec, - mut _arguments: VecDeque, + _ty_args: &[Type], + _arguments: VecDeque, ) -> SafeNativeResult> { let key_pair = KeyPair::::generate(&mut OsRng); Ok(smallvec![ @@ -632,7 +632,7 @@ pub fn native_generate_keys( #[cfg(feature = "testing")] pub fn native_sign( _context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { let msg = safely_pop_arg!(arguments, Vec); @@ -647,7 +647,7 @@ pub fn native_sign( #[cfg(feature = "testing")] pub fn native_generate_proof_of_possession( _context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { let sk_bytes = safely_pop_arg!(arguments, Vec); diff --git a/aptos-move/framework/src/natives/cryptography/bulletproofs.rs b/aptos-move/framework/src/natives/cryptography/bulletproofs.rs index 9432cf6f4f7..7a3d0a347ce 100644 --- a/aptos-move/framework/src/natives/cryptography/bulletproofs.rs +++ b/aptos-move/framework/src/natives/cryptography/bulletproofs.rs @@ -67,10 +67,10 @@ fn resolve_pedersen_bases( fn native_verify_range_proof( context: &mut SafeNativeContext, - _ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { - debug_assert!(_ty_args.is_empty()); + debug_assert!(ty_args.is_empty()); debug_assert!(args.len() == 6); let dst = safely_pop_arg!(args, Vec); @@ -94,10 +94,10 @@ fn native_verify_range_proof( fn native_verify_batch_range_proof( context: &mut SafeNativeContext, - _ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { - debug_assert!(_ty_args.is_empty()); + debug_assert!(ty_args.is_empty()); debug_assert!(args.len() == 6); let dst = safely_pop_arg!(args, Vec); @@ -131,10 +131,10 @@ fn native_verify_batch_range_proof( #[cfg(feature = "testing")] fn native_test_only_prove_range( context: &mut SafeNativeContext, - _ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { - debug_assert!(_ty_args.is_empty()); + debug_assert!(ty_args.is_empty()); debug_assert!(args.len() == 6); let rand_base_handle = get_point_handle(&safely_pop_arg!(args, StructRef))?; @@ -181,10 +181,10 @@ fn native_test_only_prove_range( #[cfg(feature = "testing")] fn native_test_only_batch_prove_range( context: &mut SafeNativeContext, - _ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { - debug_assert!(_ty_args.is_empty()); + debug_assert!(ty_args.is_empty()); debug_assert!(args.len() == 6); let rand_base_handle = get_point_handle(&safely_pop_arg!(args, StructRef))?; diff --git a/aptos-move/framework/src/natives/cryptography/ed25519.rs b/aptos-move/framework/src/natives/cryptography/ed25519.rs index 5c48576849e..698567c60b4 100644 --- a/aptos-move/framework/src/natives/cryptography/ed25519.rs +++ b/aptos-move/framework/src/natives/cryptography/ed25519.rs @@ -40,10 +40,10 @@ pub mod abort_codes { **************************************************************************************************/ fn native_public_key_validate( context: &mut SafeNativeContext, - _ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { - debug_assert!(_ty_args.is_empty()); + debug_assert!(ty_args.is_empty()); debug_assert!(arguments.len() == 1); let key_bytes = safely_pop_arg!(arguments, Vec); @@ -97,7 +97,7 @@ fn native_public_key_validate( **************************************************************************************************/ fn native_signature_verify_strict( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(_ty_args.is_empty()); @@ -184,7 +184,7 @@ pub fn make_all( #[cfg(feature = "testing")] fn native_test_only_generate_keys_internal( _context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut _args: VecDeque, ) -> SafeNativeResult> { let key_pair = KeyPair::::generate(&mut OsRng); @@ -197,7 +197,7 @@ fn native_test_only_generate_keys_internal( #[cfg(feature = "testing")] fn native_test_only_sign_internal( _context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { let msg_bytes = safely_pop_arg!(args, Vec); diff --git a/aptos-move/framework/src/natives/cryptography/multi_ed25519.rs b/aptos-move/framework/src/natives/cryptography/multi_ed25519.rs index d22b85e8256..40d80f918eb 100644 --- a/aptos-move/framework/src/natives/cryptography/multi_ed25519.rs +++ b/aptos-move/framework/src/natives/cryptography/multi_ed25519.rs @@ -41,10 +41,10 @@ const E_MULTI_ED25519_SK_DESERIALIZATION_FAILED: u64 = 0x0A_0003; /// See `public_key_validate_v2_internal` comments in `multi_ed25519.move`. fn native_public_key_validate_v2( context: &mut SafeNativeContext, - _ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { - safely_assert_eq!(_ty_args.len(), 0); + safely_assert_eq!(ty_args.len(), 0); safely_assert_eq!(arguments.len(), 1); let pks_bytes = safely_pop_arg!(arguments, Vec); @@ -70,10 +70,10 @@ fn native_public_key_validate_v2( fn native_public_key_validate_with_gas_fix( context: &mut SafeNativeContext, - _ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { - safely_assert_eq!(_ty_args.len(), 0); + safely_assert_eq!(ty_args.len(), 0); safely_assert_eq!(arguments.len(), 1); let pks_bytes = safely_pop_arg!(arguments, Vec); @@ -127,10 +127,10 @@ fn num_valid_subpks( fn native_signature_verify_strict( context: &mut SafeNativeContext, - _ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { - debug_assert!(_ty_args.is_empty()); + debug_assert!(ty_args.is_empty()); debug_assert!(arguments.len() == 3); let msg = safely_pop_arg!(arguments, Vec); @@ -172,7 +172,7 @@ fn native_signature_verify_strict( #[cfg(feature = "testing")] fn native_generate_keys( _context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { let n = safely_pop_arg!(arguments, u8); @@ -207,7 +207,7 @@ fn native_generate_keys( #[cfg(feature = "testing")] fn native_sign( _context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { let message = safely_pop_arg!(arguments, Vec); diff --git a/aptos-move/framework/src/natives/cryptography/ristretto255_point.rs b/aptos-move/framework/src/natives/cryptography/ristretto255_point.rs index 0d76afc81b4..1fd643e804b 100644 --- a/aptos-move/framework/src/natives/cryptography/ristretto255_point.rs +++ b/aptos-move/framework/src/natives/cryptography/ristretto255_point.rs @@ -227,7 +227,7 @@ fn decompress_maybe_non_canonical_point_bytes( pub(crate) fn native_point_identity( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], args: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(ty_args.len(), 0); @@ -244,10 +244,10 @@ pub(crate) fn native_point_identity( pub(crate) fn native_point_is_canonical( context: &mut SafeNativeContext, - _ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { - safely_assert_eq!(_ty_args.len(), 0); + safely_assert_eq!(ty_args.len(), 0); safely_assert_eq!(args.len(), 1); let bytes = safely_pop_arg!(args, Vec); @@ -259,10 +259,10 @@ pub(crate) fn native_point_is_canonical( pub(crate) fn native_point_decompress( context: &mut SafeNativeContext, - _ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { - safely_assert_eq!(_ty_args.len(), 0); + safely_assert_eq!(ty_args.len(), 0); safely_assert_eq!(args.len(), 1); let bytes = safely_pop_arg!(args, Vec); @@ -288,7 +288,7 @@ pub(crate) fn native_point_decompress( pub(crate) fn native_point_clone( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(ty_args.len(), 0); @@ -308,7 +308,7 @@ pub(crate) fn native_point_clone( pub(crate) fn native_point_compress( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(ty_args.len(), 0); @@ -327,7 +327,7 @@ pub(crate) fn native_point_compress( pub(crate) fn native_point_mul( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(ty_args.len(), 0); @@ -359,7 +359,7 @@ pub(crate) fn native_point_mul( pub(crate) fn native_point_equals( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(ty_args.len(), 0); @@ -382,7 +382,7 @@ pub(crate) fn native_point_equals( pub(crate) fn native_point_neg( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(ty_args.len(), 0); @@ -414,7 +414,7 @@ pub(crate) fn native_point_neg( pub(crate) fn native_point_add( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(ty_args.len(), 0); @@ -456,7 +456,7 @@ pub(crate) fn native_point_add( pub(crate) fn native_point_sub( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(ty_args.len(), 0); @@ -497,7 +497,7 @@ pub(crate) fn native_point_sub( pub(crate) fn native_basepoint_mul( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(ty_args.len(), 0); @@ -520,7 +520,7 @@ pub(crate) fn native_basepoint_mul( #[allow(non_snake_case)] pub(crate) fn native_basepoint_double_mul( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(ty_args.len(), 0); @@ -546,7 +546,7 @@ pub(crate) fn native_basepoint_double_mul( // NOTE: This was supposed to be more clearly named with *_sha2_512_* pub(crate) fn native_new_point_from_sha512( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(ty_args.len(), 0); @@ -570,7 +570,7 @@ pub(crate) fn native_new_point_from_sha512( pub(crate) fn native_new_point_from_64_uniform_bytes( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(ty_args.len(), 0); @@ -591,7 +591,7 @@ pub(crate) fn native_new_point_from_64_uniform_bytes( pub(crate) fn native_double_scalar_mul( context: &mut SafeNativeContext, - mut _ty_args: Vec, + mut _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(args.len(), 4); @@ -628,7 +628,7 @@ pub(crate) fn native_double_scalar_mul( /// function. pub(crate) fn safe_native_multi_scalar_mul_no_floating_point( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(args.len(), 2); diff --git a/aptos-move/framework/src/natives/cryptography/ristretto255_scalar.rs b/aptos-move/framework/src/natives/cryptography/ristretto255_scalar.rs index 21e70817902..256ffeee843 100644 --- a/aptos-move/framework/src/natives/cryptography/ristretto255_scalar.rs +++ b/aptos-move/framework/src/natives/cryptography/ristretto255_scalar.rs @@ -28,7 +28,7 @@ use std::{ /// This is a test-only native that charges zero gas. It is only exported in testing mode. pub(crate) fn native_scalar_random( _context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], args: VecDeque, ) -> SafeNativeResult> { debug_assert!(_ty_args.is_empty()); @@ -48,7 +48,7 @@ pub(crate) fn native_scalar_random( pub(crate) fn native_scalar_is_canonical( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(_ty_args.len(), 0); @@ -74,7 +74,7 @@ pub(crate) fn native_scalar_is_canonical( pub(crate) fn native_scalar_invert( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(_ty_args.len(), 0); @@ -91,7 +91,7 @@ pub(crate) fn native_scalar_invert( // NOTE: This was supposed to be more clearly named with *_sha2_512_*. pub(crate) fn native_scalar_from_sha512( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(_ty_args.len(), 0); @@ -112,7 +112,7 @@ pub(crate) fn native_scalar_from_sha512( pub(crate) fn native_scalar_mul( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(_ty_args.len(), 0); @@ -130,7 +130,7 @@ pub(crate) fn native_scalar_mul( pub(crate) fn native_scalar_add( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(_ty_args.len(), 0); @@ -148,7 +148,7 @@ pub(crate) fn native_scalar_add( pub(crate) fn native_scalar_sub( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(_ty_args.len(), 0); @@ -166,7 +166,7 @@ pub(crate) fn native_scalar_sub( pub(crate) fn native_scalar_neg( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(_ty_args.len(), 0); @@ -183,7 +183,7 @@ pub(crate) fn native_scalar_neg( pub(crate) fn native_scalar_from_u64( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(_ty_args.len(), 0); @@ -200,7 +200,7 @@ pub(crate) fn native_scalar_from_u64( pub(crate) fn native_scalar_from_u128( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(_ty_args.len(), 0); @@ -217,7 +217,7 @@ pub(crate) fn native_scalar_from_u128( pub(crate) fn native_scalar_reduced_from_32_bytes( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(_ty_args.len(), 0); @@ -234,7 +234,7 @@ pub(crate) fn native_scalar_reduced_from_32_bytes( pub(crate) fn native_scalar_uniform_from_64_bytes( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(_ty_args.len(), 0); diff --git a/aptos-move/framework/src/natives/cryptography/secp256k1.rs b/aptos-move/framework/src/natives/cryptography/secp256k1.rs index 73632b3a644..88d6c0e8ab0 100644 --- a/aptos-move/framework/src/natives/cryptography/secp256k1.rs +++ b/aptos-move/framework/src/natives/cryptography/secp256k1.rs @@ -26,7 +26,7 @@ pub mod abort_codes { **************************************************************************************************/ fn native_ecdsa_recover( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(_ty_args.is_empty()); diff --git a/aptos-move/framework/src/natives/debug.rs b/aptos-move/framework/src/natives/debug.rs index 25922f99fe2..1a0a8518c2f 100644 --- a/aptos-move/framework/src/natives/debug.rs +++ b/aptos-move/framework/src/natives/debug.rs @@ -27,7 +27,7 @@ use std::collections::VecDeque; #[inline] fn native_print( _: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert!(ty_args.is_empty()); @@ -54,7 +54,7 @@ fn native_print( #[inline] fn native_stack_trace( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], args: VecDeque, ) -> SafeNativeResult> { debug_assert!(ty_args.is_empty()); @@ -73,7 +73,7 @@ fn native_stack_trace( #[inline] fn native_old_debug_print( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { if cfg!(feature = "testing") { @@ -91,7 +91,7 @@ fn native_old_debug_print( #[inline] fn native_old_print_stacktrace( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], args: VecDeque, ) -> SafeNativeResult> { debug_assert!(ty_args.is_empty()); diff --git a/aptos-move/framework/src/natives/dispatchable_fungible_asset.rs b/aptos-move/framework/src/natives/dispatchable_fungible_asset.rs index 8d299545e65..787c5806ba3 100644 --- a/aptos-move/framework/src/natives/dispatchable_fungible_asset.rs +++ b/aptos-move/framework/src/natives/dispatchable_fungible_asset.rs @@ -21,7 +21,7 @@ use std::collections::VecDeque; **************************************************************************************************/ pub(crate) fn native_dispatch( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { let (module_name, func_name) = extract_function_info(&mut arguments)?; @@ -50,7 +50,7 @@ pub(crate) fn native_dispatch( Err(SafeNativeError::FunctionDispatch { module_name, func_name, - ty_args, + ty_args: ty_args.to_vec(), args: arguments.into_iter().collect(), }) } diff --git a/aptos-move/framework/src/natives/event.rs b/aptos-move/framework/src/natives/event.rs index 4884e1aeed3..f5a6f61e526 100644 --- a/aptos-move/framework/src/natives/event.rs +++ b/aptos-move/framework/src/natives/event.rs @@ -94,13 +94,13 @@ impl NativeEventContext { #[inline] fn native_write_to_event_store( context: &mut SafeNativeContext, - mut ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(ty_args.len() == 1); debug_assert!(arguments.len() == 3); - let ty = ty_args.pop().unwrap(); + let ty = &ty_args[0]; let msg = arguments.pop_back().unwrap(); let seq_num = safely_pop_arg!(arguments, u64); let guid = safely_pop_arg!(arguments, Vec); @@ -110,9 +110,9 @@ fn native_write_to_event_store( EVENT_WRITE_TO_EVENT_STORE_BASE + EVENT_WRITE_TO_EVENT_STORE_PER_ABSTRACT_VALUE_UNIT * context.abs_val_size(&msg)?, )?; - let ty_tag = context.type_to_type_tag(&ty)?; + let ty_tag = context.type_to_type_tag(ty)?; let (layout, contains_delayed_fields) = context - .type_to_type_layout_with_delayed_fields(&ty)? + .type_to_type_layout_with_delayed_fields(ty)? .unpack(); let function_value_extension = context.function_value_extension(); @@ -146,13 +146,13 @@ fn native_write_to_event_store( #[cfg(feature = "testing")] fn native_emitted_events_by_handle( context: &mut SafeNativeContext, - mut ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(ty_args.len() == 1); debug_assert!(arguments.len() == 1); - let ty = ty_args.pop().unwrap(); + let ty = &ty_args[0]; let mut guid = safely_pop_arg!(arguments, StructRef) .borrow_field(1)? .value_as::()? @@ -179,8 +179,8 @@ fn native_emitted_events_by_handle( })? .value_as::()?; let key = EventKey::new(creation_num, addr); - let ty_tag = context.type_to_type_tag(&ty)?; - let ty_layout = context.type_to_type_layout_check_no_delayed_fields(&ty)?; + let ty_tag = context.type_to_type_tag(ty)?; + let ty_layout = context.type_to_type_layout_check_no_delayed_fields(ty)?; let ctx = context.extensions().get::(); let events = ctx .emitted_v1_events(&key, &ty_tag) @@ -204,16 +204,16 @@ fn native_emitted_events_by_handle( #[cfg(feature = "testing")] fn native_emitted_events( context: &mut SafeNativeContext, - mut ty_args: Vec, + ty_args: &[Type], arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(ty_args.len() == 1); debug_assert!(arguments.is_empty()); - let ty = ty_args.pop().unwrap(); + let ty = &ty_args[0]; - let ty_tag = context.type_to_type_tag(&ty)?; - let ty_layout = context.type_to_type_layout_check_no_delayed_fields(&ty)?; + let ty_tag = context.type_to_type_tag(ty)?; + let ty_layout = context.type_to_type_layout_check_no_delayed_fields(ty)?; let ctx = context.extensions().get::(); let events = ctx @@ -239,13 +239,13 @@ fn native_emitted_events( #[inline] fn native_write_module_event_to_store( context: &mut SafeNativeContext, - mut ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(ty_args.len() == 1); debug_assert!(arguments.len() == 1); - let ty = ty_args.pop().unwrap(); + let ty = &ty_args[0]; let msg = arguments.pop_back().unwrap(); context.charge( @@ -253,7 +253,7 @@ fn native_write_module_event_to_store( + EVENT_WRITE_TO_EVENT_STORE_PER_ABSTRACT_VALUE_UNIT * context.abs_val_size(&msg)?, )?; - let type_tag = context.type_to_type_tag(&ty)?; + let type_tag = context.type_to_type_tag(ty)?; // Additional runtime check for module call. let stack_frames = context.stack_frames(1); @@ -287,7 +287,7 @@ fn native_write_module_event_to_store( } let (layout, contains_delayed_fields) = context - .type_to_type_layout_with_delayed_fields(&ty)? + .type_to_type_layout_with_delayed_fields(ty)? .unpack(); let function_value_extension = context.function_value_extension(); diff --git a/aptos-move/framework/src/natives/function_info.rs b/aptos-move/framework/src/natives/function_info.rs index ef137823360..1a4c5d97090 100644 --- a/aptos-move/framework/src/natives/function_info.rs +++ b/aptos-move/framework/src/natives/function_info.rs @@ -72,7 +72,7 @@ pub(crate) fn extract_function_info( **************************************************************************************************/ fn native_check_dispatch_type_compatibility_impl( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(arguments.len() == 2); @@ -142,7 +142,7 @@ fn native_check_dispatch_type_compatibility_impl( **************************************************************************************************/ fn native_is_identifier( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(arguments.len() == 1); @@ -174,7 +174,7 @@ fn native_is_identifier( **************************************************************************************************/ fn native_load_function_impl( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(arguments.len() == 1); diff --git a/aptos-move/framework/src/natives/hash.rs b/aptos-move/framework/src/natives/hash.rs index da91b3d8b20..84f0264bb58 100644 --- a/aptos-move/framework/src/natives/hash.rs +++ b/aptos-move/framework/src/natives/hash.rs @@ -23,7 +23,7 @@ use tiny_keccak::{Hasher as KeccakHasher, Keccak}; **************************************************************************************************/ fn native_sip_hash( context: &mut SafeNativeContext, - mut _ty_args: Vec, + mut _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert!(_ty_args.is_empty()); @@ -44,7 +44,7 @@ fn native_sip_hash( fn native_keccak256( context: &mut SafeNativeContext, - mut _ty_args: Vec, + mut _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert!(_ty_args.is_empty()); @@ -65,7 +65,7 @@ fn native_keccak256( fn native_sha2_512( context: &mut SafeNativeContext, - mut _ty_args: Vec, + mut _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert!(_ty_args.is_empty()); @@ -85,7 +85,7 @@ fn native_sha2_512( fn native_sha3_512( context: &mut SafeNativeContext, - mut _ty_args: Vec, + mut _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert!(_ty_args.is_empty()); @@ -111,7 +111,7 @@ pub struct Blake2B256HashGasParameters { fn native_blake2b_256( context: &mut SafeNativeContext, - mut _ty_args: Vec, + mut _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(_ty_args.len(), 0); @@ -138,7 +138,7 @@ pub struct Ripemd160HashGasParameters { fn native_ripemd160( context: &mut SafeNativeContext, - mut _ty_args: Vec, + mut _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert!(_ty_args.is_empty()); diff --git a/aptos-move/framework/src/natives/object.rs b/aptos-move/framework/src/natives/object.rs index ee824db9689..a8caf6d9a20 100644 --- a/aptos-move/framework/src/natives/object.rs +++ b/aptos-move/framework/src/natives/object.rs @@ -65,18 +65,18 @@ pub struct ExistsAtGasParameters { fn native_exists_at( context: &mut SafeNativeContext, - mut ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { safely_assert_eq!(ty_args.len(), 1); safely_assert_eq!(args.len(), 1); - let type_ = ty_args.pop().unwrap(); + let type_ = &ty_args[0]; let address = safely_pop_arg!(args, AccountAddress); context.charge(OBJECT_EXISTS_AT_BASE)?; - let (exists, num_bytes) = context.exists_at(address, &type_).map_err(|err| { + let (exists, num_bytes) = context.exists_at(address, type_).map_err(|err| { PartialVMError::new(StatusCode::VM_EXTENSION_ERROR).with_message(format!( "Failed to read resource: {:?} at {}. With error: {}", type_, address, err @@ -100,7 +100,7 @@ fn native_exists_at( **************************************************************************************************/ fn native_create_user_derived_object_address_impl( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert!(ty_args.is_empty()); diff --git a/aptos-move/framework/src/natives/permissioned_signer.rs b/aptos-move/framework/src/natives/permissioned_signer.rs index 658bc7a8778..9536f3877a4 100644 --- a/aptos-move/framework/src/natives/permissioned_signer.rs +++ b/aptos-move/framework/src/natives/permissioned_signer.rs @@ -30,7 +30,7 @@ const EPERMISSION_SIGNER_DISABLED: u64 = 9; **************************************************************************************************/ fn native_is_permissioned_signer_impl( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(arguments.len() == 1); @@ -61,7 +61,7 @@ fn native_is_permissioned_signer_impl( **************************************************************************************************/ fn native_permission_address( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert!(args.len() == 1); @@ -94,7 +94,7 @@ fn native_permission_address( **************************************************************************************************/ fn native_signer_from_permissioned( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(arguments.len() == 2); @@ -127,7 +127,7 @@ fn native_signer_from_permissioned( #[inline] fn native_borrow_address( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(_ty_args.is_empty()); diff --git a/aptos-move/framework/src/natives/randomness.rs b/aptos-move/framework/src/natives/randomness.rs index 8547fcd3487..dd49cb41cf9 100644 --- a/aptos-move/framework/src/natives/randomness.rs +++ b/aptos-move/framework/src/natives/randomness.rs @@ -71,7 +71,7 @@ impl RandomnessContext { pub fn fetch_and_increment_txn_counter( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], _args: VecDeque, ) -> SafeNativeResult> { if context.gas_feature_version() >= RELEASE_V1_23 { @@ -92,7 +92,7 @@ pub fn fetch_and_increment_txn_counter( pub fn is_unbiasable( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], _args: VecDeque, ) -> SafeNativeResult> { // Because we need to run a special transaction prologue to pre-charge maximum diff --git a/aptos-move/framework/src/natives/state_storage.rs b/aptos-move/framework/src/natives/state_storage.rs index d4cfe4e5b30..ef2f4038449 100644 --- a/aptos-move/framework/src/natives/state_storage.rs +++ b/aptos-move/framework/src/natives/state_storage.rs @@ -51,7 +51,7 @@ impl<'a> NativeStateStorageContext<'a> { /// guarantees a fresh state view then. fn native_get_usage( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], _args: VecDeque, ) -> SafeNativeResult> { assert!(_ty_args.is_empty()); diff --git a/aptos-move/framework/src/natives/string_utils.rs b/aptos-move/framework/src/natives/string_utils.rs index d5d0285dd7f..3db4e95afba 100644 --- a/aptos-move/framework/src/natives/string_utils.rs +++ b/aptos-move/framework/src/natives/string_utils.rs @@ -558,7 +558,7 @@ pub(crate) fn native_format_debug( fn native_format( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(ty_args.len() == 1); @@ -592,7 +592,7 @@ fn native_format( fn native_format_list( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(ty_args.len() == 1); diff --git a/aptos-move/framework/src/natives/transaction_context.rs b/aptos-move/framework/src/natives/transaction_context.rs index adc7941887b..3c8ffa76f9a 100644 --- a/aptos-move/framework/src/natives/transaction_context.rs +++ b/aptos-move/framework/src/natives/transaction_context.rs @@ -96,7 +96,7 @@ impl NativeTransactionContext { **************************************************************************************************/ fn native_get_txn_hash( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], _args: VecDeque, ) -> SafeNativeResult> { context.charge(TRANSACTION_CONTEXT_GET_TXN_HASH_BASE)?; @@ -115,7 +115,7 @@ fn native_get_txn_hash( **************************************************************************************************/ fn native_generate_unique_address( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], _args: VecDeque, ) -> SafeNativeResult> { context.charge(TRANSACTION_CONTEXT_GENERATE_UNIQUE_ADDRESS_BASE)?; @@ -133,6 +133,91 @@ fn native_generate_unique_address( Ok(smallvec![Value::address(auid)]) } +/*************************************************************************************************** + * native fun monotonically_increasing_counter_internal + * + * gas cost: base_cost + * + **************************************************************************************************/ +fn native_monotonically_increasing_counter_internal( + context: &mut SafeNativeContext, + _ty_args: &[Type], + mut args: VecDeque, +) -> SafeNativeResult> { + context.charge(TRANSACTION_CONTEXT_MONOTONICALLY_INCREASING_COUNTER_BASE)?; + + let transaction_context = context + .extensions_mut() + .get_mut::(); + if transaction_context.local_counter == u16::MAX { + return Err(SafeNativeError::Abort { + abort_code: error::invalid_state( + abort_codes::EMONOTONICALLY_INCREASING_COUNTER_OVERFLOW, + ), + }); + } + transaction_context.local_counter += 1; + let local_counter = transaction_context.local_counter as u128; + let session_counter = transaction_context.session_counter as u128; + + let user_transaction_context_opt = get_user_transaction_context_opt_from_context(context); + if let Some(user_transaction_context) = user_transaction_context_opt { + // monotonically_increasing_counter (128 bits) = ` || timestamp_us (64 bits) || transaction_index (32 bits) || session counter (8 bits) || local_counter (16 bits)` + let timestamp_us = safely_pop_arg!(args, u64); + let transaction_index = user_transaction_context.transaction_index(); + + if let Some(transaction_index) = transaction_index { + let mut monotonically_increasing_counter: u128 = (timestamp_us as u128) << 56; + monotonically_increasing_counter |= (transaction_index as u128) << 24; + monotonically_increasing_counter |= session_counter << 16; + monotonically_increasing_counter |= local_counter; + Ok(smallvec![Value::u128(monotonically_increasing_counter)]) + } else { + Err(SafeNativeError::Abort { + abort_code: error::invalid_state(abort_codes::ETRANSACTION_INDEX_NOT_AVAILABLE), + }) + } + } else { + // When transaction context is not available, return an error + Err(SafeNativeError::Abort { + abort_code: error::invalid_state(abort_codes::ETRANSACTION_CONTEXT_NOT_AVAILABLE), + }) + } +} + +/*************************************************************************************************** + * native fun monotonically_increasing_counter_internal_for_test_only + * + * gas cost: base_cost + * + * This is a test-only version that returns increasing counter values without requiring + * a user transaction context. Used when COMPILE_FOR_TESTING flag is enabled. + * + **************************************************************************************************/ +fn native_monotonically_increasing_counter_internal_for_test_only( + context: &mut SafeNativeContext, + _ty_args: &[Type], + _args: VecDeque, +) -> SafeNativeResult> { + context.charge(TRANSACTION_CONTEXT_MONOTONICALLY_INCREASING_COUNTER_BASE)?; + + let transaction_context = context + .extensions_mut() + .get_mut::(); + if transaction_context.local_counter == u16::MAX { + return Err(SafeNativeError::Abort { + abort_code: error::invalid_state( + abort_codes::EMONOTONICALLY_INCREASING_COUNTER_OVERFLOW, + ), + }); + } + transaction_context.local_counter += 1; + let local_counter = transaction_context.local_counter as u128; + + // For testing, return just the local counter value to verify monotonically increasing behavior + Ok(smallvec![Value::u128(local_counter)]) +} + /*************************************************************************************************** * native fun get_script_hash * @@ -141,7 +226,7 @@ fn native_generate_unique_address( **************************************************************************************************/ fn native_get_script_hash( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], _args: VecDeque, ) -> SafeNativeResult> { context.charge(TRANSACTION_CONTEXT_GET_SCRIPT_HASH_BASE)?; @@ -155,7 +240,7 @@ fn native_get_script_hash( fn native_sender_internal( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], _args: VecDeque, ) -> SafeNativeResult> { context.charge(TRANSACTION_CONTEXT_SENDER_BASE)?; @@ -172,7 +257,7 @@ fn native_sender_internal( fn native_secondary_signers_internal( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], _args: VecDeque, ) -> SafeNativeResult> { context.charge(TRANSACTION_CONTEXT_SECONDARY_SIGNERS_BASE)?; @@ -194,7 +279,7 @@ fn native_secondary_signers_internal( fn native_gas_payer_internal( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], _args: VecDeque, ) -> SafeNativeResult> { context.charge(TRANSACTION_CONTEXT_FEE_PAYER_BASE)?; @@ -211,7 +296,7 @@ fn native_gas_payer_internal( fn native_max_gas_amount_internal( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], _args: VecDeque, ) -> SafeNativeResult> { context.charge(TRANSACTION_CONTEXT_MAX_GAS_AMOUNT_BASE)?; @@ -228,7 +313,7 @@ fn native_max_gas_amount_internal( fn native_gas_unit_price_internal( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], _args: VecDeque, ) -> SafeNativeResult> { context.charge(TRANSACTION_CONTEXT_GAS_UNIT_PRICE_BASE)?; @@ -245,7 +330,7 @@ fn native_gas_unit_price_internal( fn native_chain_id_internal( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], _args: VecDeque, ) -> SafeNativeResult> { context.charge(TRANSACTION_CONTEXT_CHAIN_ID_BASE)?; @@ -325,7 +410,7 @@ fn create_entry_function_payload( fn native_entry_function_payload_internal( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], _args: VecDeque, ) -> SafeNativeResult> { context.charge(TRANSACTION_CONTEXT_ENTRY_FUNCTION_PAYLOAD_BASE)?; @@ -353,7 +438,7 @@ fn native_entry_function_payload_internal( fn native_multisig_payload_internal( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], _args: VecDeque, ) -> SafeNativeResult> { context.charge(TRANSACTION_CONTEXT_MULTISIG_PAYLOAD_BASE)?; diff --git a/aptos-move/framework/src/natives/type_info.rs b/aptos-move/framework/src/natives/type_info.rs index b33e3271ee6..c3b87d6d2fc 100644 --- a/aptos-move/framework/src/natives/type_info.rs +++ b/aptos-move/framework/src/natives/type_info.rs @@ -46,7 +46,7 @@ fn type_of_internal(struct_tag: &StructTag) -> Result, std: **************************************************************************************************/ fn native_type_of( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(ty_args.len() == 1); @@ -83,7 +83,7 @@ fn native_type_of( **************************************************************************************************/ fn native_type_name( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(ty_args.len() == 1); @@ -112,7 +112,7 @@ fn native_type_name( **************************************************************************************************/ fn native_chain_id( context: &mut SafeNativeContext, - _ty_args: Vec, + _ty_args: &[Type], arguments: VecDeque, ) -> SafeNativeResult> { debug_assert!(_ty_args.is_empty()); diff --git a/aptos-move/framework/src/natives/util.rs b/aptos-move/framework/src/natives/util.rs index 444cc143e3f..7606a81b779 100644 --- a/aptos-move/framework/src/natives/util.rs +++ b/aptos-move/framework/src/natives/util.rs @@ -29,7 +29,7 @@ const EFROM_BYTES: u64 = 0x01_0001; **************************************************************************************************/ fn native_from_bytes( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { debug_assert_eq!(ty_args.len(), 1); diff --git a/aptos-move/framework/table-natives/src/lib.rs b/aptos-move/framework/table-natives/src/lib.rs index e3b0da398d9..2ad58bc3a03 100644 --- a/aptos-move/framework/table-natives/src/lib.rs +++ b/aptos-move/framework/table-natives/src/lib.rs @@ -347,7 +347,7 @@ fn charge_load_cost( fn native_new_table_handle( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], args: VecDeque, ) -> SafeNativeResult> { assert_eq!(ty_args.len(), 2); @@ -380,7 +380,7 @@ fn native_new_table_handle( fn native_add_box( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(ty_args.len(), 3); @@ -438,7 +438,7 @@ fn native_add_box( fn native_borrow_box( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(ty_args.len(), 3); @@ -494,7 +494,7 @@ fn native_borrow_box( fn native_contains_box( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(ty_args.len(), 3); @@ -548,7 +548,7 @@ fn native_contains_box( fn native_remove_box( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(ty_args.len(), 3); @@ -605,7 +605,7 @@ fn native_remove_box( fn native_destroy_empty_box( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> SafeNativeResult> { assert_eq!(ty_args.len(), 3); @@ -628,7 +628,7 @@ fn native_destroy_empty_box( fn native_drop_unchecked_box( context: &mut SafeNativeContext, - ty_args: Vec, + ty_args: &[Type], args: VecDeque, ) -> SafeNativeResult> { assert_eq!(ty_args.len(), 3); diff --git a/third_party/move/extensions/move-table-extension/src/lib.rs b/third_party/move/extensions/move-table-extension/src/lib.rs index 3e2c8c5bf99..917bf6f422e 100644 --- a/third_party/move/extensions/move-table-extension/src/lib.rs +++ b/third_party/move/extensions/move-table-extension/src/lib.rs @@ -355,7 +355,7 @@ pub struct NewTableHandleGasParameters { fn native_new_table_handle( gas_params: &NewTableHandleGasParameters, context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], args: VecDeque, ) -> PartialVMResult { assert_eq!(ty_args.len(), 2); @@ -404,7 +404,7 @@ fn native_add_box( common_gas_params: &CommonGasParameters, gas_params: &AddBoxGasParameters, context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { assert_eq!(ty_args.len(), 3); @@ -458,7 +458,7 @@ fn native_borrow_box( common_gas_params: &CommonGasParameters, gas_params: &BorrowBoxGasParameters, context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { assert_eq!(ty_args.len(), 3); @@ -511,7 +511,7 @@ fn native_contains_box( common_gas_params: &CommonGasParameters, gas_params: &ContainsBoxGasParameters, context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { assert_eq!(ty_args.len(), 3); @@ -563,7 +563,7 @@ fn native_remove_box( common_gas_params: &CommonGasParameters, gas_params: &RemoveGasParameters, context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { assert_eq!(ty_args.len(), 3); @@ -614,7 +614,7 @@ pub struct DestroyEmptyBoxGasParameters { fn native_destroy_empty_box( gas_params: &DestroyEmptyBoxGasParameters, context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { assert_eq!(ty_args.len(), 3); @@ -649,7 +649,7 @@ pub struct DropUncheckedBoxGasParameters { fn native_drop_unchecked_box( gas_params: &DropUncheckedBoxGasParameters, _context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], args: VecDeque, ) -> PartialVMResult { assert_eq!(ty_args.len(), 3); diff --git a/third_party/move/move-examples/diem-framework/crates/natives/src/account.rs b/third_party/move/move-examples/diem-framework/crates/natives/src/account.rs index 026bb9ff4bb..eae9d0baef6 100644 --- a/third_party/move/move-examples/diem-framework/crates/natives/src/account.rs +++ b/third_party/move/move-examples/diem-framework/crates/natives/src/account.rs @@ -13,7 +13,7 @@ use std::collections::VecDeque; pub fn native_create_signer( _context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> PartialVMResult { debug_assert!(ty_args.is_empty()); @@ -29,7 +29,7 @@ pub fn native_create_signer( /// remain for replaying old transactions pub fn native_destroy_signer( _context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], arguments: VecDeque, ) -> PartialVMResult { debug_assert!(ty_args.is_empty()); diff --git a/third_party/move/move-examples/diem-framework/crates/natives/src/signature.rs b/third_party/move/move-examples/diem-framework/crates/natives/src/signature.rs index cab54afaacb..f16e030f1af 100644 --- a/third_party/move/move-examples/diem-framework/crates/natives/src/signature.rs +++ b/third_party/move/move-examples/diem-framework/crates/natives/src/signature.rs @@ -13,7 +13,7 @@ use std::{collections::VecDeque, convert::TryFrom}; pub fn native_ed25519_publickey_validation( _context: &mut NativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> PartialVMResult { debug_assert!(_ty_args.is_empty()); @@ -30,7 +30,7 @@ pub fn native_ed25519_publickey_validation( pub fn native_ed25519_signature_verification( _context: &mut NativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> PartialVMResult { debug_assert!(_ty_args.is_empty()); diff --git a/third_party/move/move-stdlib/src/natives/bcs.rs b/third_party/move/move-stdlib/src/natives/bcs.rs index 1904d06de6c..90238c16223 100644 --- a/third_party/move/move-stdlib/src/natives/bcs.rs +++ b/third_party/move/move-stdlib/src/natives/bcs.rs @@ -41,7 +41,7 @@ pub struct ToBytesGasParameters { fn native_to_bytes( gas_params: &ToBytesGasParameters, context: &mut NativeContext, - mut ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { debug_assert!(ty_args.len() == 1); @@ -51,10 +51,10 @@ fn native_to_bytes( // pop type and value let ref_to_val = pop_arg!(args, Reference); - let arg_type = ty_args.pop().unwrap(); + let arg_type = &ty_args[0]; // get type layout - let layout = match context.type_to_type_layout(&arg_type) { + let layout = match context.type_to_type_layout(arg_type) { Ok(layout) => layout, Err(_) => { cost += gas_params.failure; diff --git a/third_party/move/move-stdlib/src/natives/debug.rs b/third_party/move/move-stdlib/src/natives/debug.rs index 86befb63ee5..b6dac55ed2e 100644 --- a/third_party/move/move-stdlib/src/natives/debug.rs +++ b/third_party/move/move-stdlib/src/natives/debug.rs @@ -30,7 +30,7 @@ pub struct PrintGasParameters { fn native_print( gas_params: &PrintGasParameters, _context: &mut NativeContext, - mut ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, _move_std_addr: AccountAddress, ) -> PartialVMResult { @@ -38,7 +38,7 @@ fn native_print( debug_assert!(args.len() == 1); let _val = args.pop_back().unwrap(); - let _ty = ty_args.pop().unwrap(); + let _ty = &ty_args[0]; // No-op if the feature flag is not present. #[cfg(feature = "testing")] @@ -93,7 +93,7 @@ pub struct PrintStackTraceGasParameters { fn native_print_stack_trace( gas_params: &PrintStackTraceGasParameters, context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], args: VecDeque, ) -> PartialVMResult { debug_assert!(ty_args.is_empty()); @@ -255,7 +255,7 @@ mod testing { context: &mut NativeContext, out: &mut String, val: Value, - ty: Type, + ty: &Type, move_std_addr: &AccountAddress, depth: usize, canonicalize: bool, @@ -266,13 +266,13 @@ mod testing { // this debug implementation is // 1. Not used in production, instead debug implementation from 0x1::string_utils is used. // 2. Not called in block-execution context where delayed fields are relevant. - let ty_layout = context.type_to_type_layout_check_no_delayed_fields(&ty)?; + let ty_layout = context.type_to_type_layout_check_no_delayed_fields(ty)?; match ty_layout.as_ref() { MoveTypeLayout::Vector(_) => { // Get the inner type T of a vector. Again, we should not see any delayed fields // in the debug context. - let inner_ty = get_vector_inner_type(&ty)?; + let inner_ty = get_vector_inner_type(ty)?; let inner_tyl = context.type_to_type_layout_check_no_delayed_fields(inner_ty)?; match inner_tyl.as_ref() { @@ -298,7 +298,7 @@ mod testing { context, out, val, - inner_ty.clone(), + inner_ty, move_std_addr, depth, canonicalize, @@ -345,7 +345,7 @@ mod testing { }, }; - let annotated_struct_layout = get_annotated_struct_layout(context, &ty)?; + let annotated_struct_layout = get_annotated_struct_layout(context, ty)?; let decorated_struct = move_struct.decorate(&annotated_struct_layout); print_move_value( diff --git a/third_party/move/move-stdlib/src/natives/event.rs b/third_party/move/move-stdlib/src/natives/event.rs index 5ab61c203f8..716b7b52cc6 100644 --- a/third_party/move/move-stdlib/src/natives/event.rs +++ b/third_party/move/move-stdlib/src/natives/event.rs @@ -28,7 +28,7 @@ pub struct WriteToEventStoreGasParameters { fn native_write_to_event_store( gas_params: &WriteToEventStoreGasParameters, _context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], mut arguments: VecDeque, ) -> PartialVMResult { debug_assert!(ty_args.len() == 1); diff --git a/third_party/move/move-stdlib/src/natives/hash.rs b/third_party/move/move-stdlib/src/natives/hash.rs index f915fa77cd9..516f6e0eab0 100644 --- a/third_party/move/move-stdlib/src/natives/hash.rs +++ b/third_party/move/move-stdlib/src/natives/hash.rs @@ -31,7 +31,7 @@ pub struct Sha2_256GasParameters { fn native_sha2_256( gas_params: &Sha2_256GasParameters, _context: &mut NativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> PartialVMResult { debug_assert!(_ty_args.is_empty()); @@ -77,7 +77,7 @@ pub struct Sha3_256GasParameters { fn native_sha3_256( gas_params: &Sha3_256GasParameters, _context: &mut NativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> PartialVMResult { debug_assert!(_ty_args.is_empty()); diff --git a/third_party/move/move-stdlib/src/natives/signer.rs b/third_party/move/move-stdlib/src/natives/signer.rs index 90c8ccac06b..2f4f513ab14 100644 --- a/third_party/move/move-stdlib/src/natives/signer.rs +++ b/third_party/move/move-stdlib/src/natives/signer.rs @@ -30,7 +30,7 @@ pub struct BorrowAddressGasParameters { fn native_borrow_address( gas_params: &BorrowAddressGasParameters, _context: &mut NativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut arguments: VecDeque, ) -> PartialVMResult { debug_assert!(_ty_args.is_empty()); diff --git a/third_party/move/move-stdlib/src/natives/string.rs b/third_party/move/move-stdlib/src/natives/string.rs index 24b1074dc07..daea83ce60f 100644 --- a/third_party/move/move-stdlib/src/natives/string.rs +++ b/third_party/move/move-stdlib/src/natives/string.rs @@ -39,7 +39,7 @@ pub struct CheckUtf8GasParameters { fn native_check_utf8( gas_params: &CheckUtf8GasParameters, _context: &mut NativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { debug_assert!(args.len() == 1); @@ -75,7 +75,7 @@ pub struct IsCharBoundaryGasParameters { fn native_is_char_boundary( gas_params: &IsCharBoundaryGasParameters, _context: &mut NativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { debug_assert!(args.len() == 2); @@ -112,7 +112,7 @@ pub struct SubStringGasParameters { fn native_sub_string( gas_params: &SubStringGasParameters, _context: &mut NativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { debug_assert!(args.len() == 3); @@ -160,7 +160,7 @@ pub struct IndexOfGasParameters { fn native_index_of( gas_params: &IndexOfGasParameters, _context: &mut NativeContext, - _ty_args: Vec, + _ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { debug_assert!(args.len() == 2); diff --git a/third_party/move/move-stdlib/src/natives/type_name.rs b/third_party/move/move-stdlib/src/natives/type_name.rs index 897ea168602..788d9f8215e 100644 --- a/third_party/move/move-stdlib/src/natives/type_name.rs +++ b/third_party/move/move-stdlib/src/natives/type_name.rs @@ -21,7 +21,7 @@ pub struct GetGasParameters { fn native_get( gas_params: &GetGasParameters, context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], arguments: VecDeque, ) -> PartialVMResult { debug_assert_eq!(ty_args.len(), 1); diff --git a/third_party/move/move-stdlib/src/natives/unit_test.rs b/third_party/move/move-stdlib/src/natives/unit_test.rs index a00dfeb68a3..6b4592edf09 100644 --- a/third_party/move/move-stdlib/src/natives/unit_test.rs +++ b/third_party/move/move-stdlib/src/natives/unit_test.rs @@ -37,7 +37,7 @@ pub struct CreateSignersForTestingGasParameters { fn native_create_signers_for_testing( gas_params: &CreateSignersForTestingGasParameters, _context: &mut NativeContext, - ty_args: Vec, + ty_args: &[Type], mut args: VecDeque, ) -> PartialVMResult { debug_assert!(ty_args.is_empty()); diff --git a/third_party/move/move-vm/runtime/src/interpreter.rs b/third_party/move/move-vm/runtime/src/interpreter.rs index ab2ac501bb0..f9977fd084c 100644 --- a/third_party/move/move-vm/runtime/src/interpreter.rs +++ b/third_party/move/move-vm/runtime/src/interpreter.rs @@ -1071,7 +1071,7 @@ where gas_meter, traversal_context, ); - let result = native_function(&mut native_context, ty_args.to_vec(), args)?; + let result = native_function(&mut native_context, ty_args, args)?; // Note(Gas): The order by which gas is charged / error gets returned MUST NOT be modified // here or otherwise it becomes an incompatible change!!! diff --git a/third_party/move/move-vm/runtime/src/native_functions.rs b/third_party/move/move-vm/runtime/src/native_functions.rs index 64b2d5f9fd4..acbf566cf23 100644 --- a/third_party/move/move-vm/runtime/src/native_functions.rs +++ b/third_party/move/move-vm/runtime/src/native_functions.rs @@ -45,7 +45,7 @@ use std::{ }; use triomphe::Arc as TriompheArc; -pub type UnboxedNativeFunction = dyn Fn(&mut NativeContext, Vec, VecDeque) -> PartialVMResult +pub type UnboxedNativeFunction = dyn for<'a> Fn(&mut NativeContext, &'a [Type], VecDeque) -> PartialVMResult + Send + Sync + 'static; From 4147976405b7a490a53778b6d8a05fc4957a9a89 Mon Sep 17 00:00:00 2001 From: Bo Wu Date: Wed, 27 May 2026 15:38:07 -0700 Subject: [PATCH 258/260] Preserve verifier cache config digest key --- .../runtime/src/storage/environment.rs | 34 +++++++++++++------ .../src/storage/verified_module_cache.rs | 28 ++++++++++----- 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/third_party/move/move-vm/runtime/src/storage/environment.rs b/third_party/move/move-vm/runtime/src/storage/environment.rs index 0561bdfc368..fd48ebb4c5f 100644 --- a/third_party/move/move-vm/runtime/src/storage/environment.rs +++ b/third_party/move/move-vm/runtime/src/storage/environment.rs @@ -35,6 +35,7 @@ use move_vm_types::{ module_id_interner::InternedModuleIdPool, ty_interner::InternedTypePool, }; +use sha3::{Digest, Sha3_256}; use std::sync::Arc; const OPTION_MODULE_BYTES: &[u8] = include_bytes!("option.mv"); @@ -66,6 +67,20 @@ pub struct RuntimeEnvironment { /// speculatively because type tag information does not change with module publishes. ty_tag_cache: Arc, + /// SHA3-256 digest of the BCS-serialized [VerifierConfig] from `vm_config`. Precomputed at + /// construction time so it can be combined with the module hash to form the + /// [VERIFIED_MODULES_CACHE] cache key without re-hashing the config on every lookup. + /// + /// Why this exists: the verified-module cache is a process-global LRU shared across all + /// runtime environments. Without a per-config component in the key, two threads using + /// different verifier configurations (e.g. straddling an epoch boundary where the config + /// changed) would treat each other's cached entries as their own. A module accepted under + /// a more permissive config could be skipped under a stricter one. + /// + /// Invariant: must stay in line with `vm_config.verifier_config`. Any mutation of + /// `vm_config.verifier_config` must recompute this digest. + verifier_config_digest: [u8; 32], + /// Pool of interned type representations. Same lifetime as struct index map. interned_ty_pool: Arc, @@ -112,6 +127,7 @@ impl RuntimeEnvironment { natives, struct_name_index_map: Arc::new(StructNameIndexMap::empty()), ty_tag_cache: Arc::new(TypeTagCache::empty()), + verifier_config_digest, interned_ty_pool: Arc::new(InternedTypePool::new()), interned_module_id_pool: Arc::new(InternedModuleIdPool::new()), } @@ -185,7 +201,7 @@ impl RuntimeEnvironment { module_size: usize, module_hash: &[u8; 32], ) -> VMResult { - if !VERIFIED_MODULES_CACHE.contains(module_hash) { + if !VERIFIED_MODULES_CACHE.contains(module_hash, &self.verifier_config_digest) { let _timer = VM_TIMER.timer_with_label("move_bytecode_verifier::verify_module_with_config"); @@ -199,7 +215,7 @@ impl RuntimeEnvironment { compiled_module.as_ref(), )?; check_natives(compiled_module.as_ref())?; - VERIFIED_MODULES_CACHE.put(*module_hash); + VERIFIED_MODULES_CACHE.put(*module_hash, self.verifier_config_digest); } Ok(LocallyVerifiedModule(compiled_module, module_size)) @@ -439,6 +455,7 @@ impl Clone for RuntimeEnvironment { natives: self.natives.clone(), struct_name_index_map: Arc::clone(&self.struct_name_index_map), ty_tag_cache: Arc::clone(&self.ty_tag_cache), + verifier_config_digest: self.verifier_config_digest, interned_ty_pool: Arc::clone(&self.interned_ty_pool), interned_module_id_pool: Arc::clone(&self.interned_module_id_pool), } @@ -450,8 +467,8 @@ impl Clone for RuntimeEnvironment { /// Used as the per-environment component of the verified-module cache key (see /// [RuntimeEnvironment::verifier_config_digest] for the reasoning). fn digest_verifier_config(vm_config: &VMConfig) -> [u8; 32] { - let serialized = bcs::to_bytes(&vm_config.verifier_config) - .expect("VerifierConfig must be BCS-serializable"); + let serialized = + bcs::to_bytes(&vm_config.verifier_config).expect("VerifierConfig must be BCS-serializable"); let mut hasher = Sha3_256::new(); hasher.update(&serialized); hasher.finalize().into() @@ -532,10 +549,8 @@ mod tests { #[test] fn verifier_config_digest_changes_with_config() { - let env_a = - RuntimeEnvironment::new_with_config(vec![], config_with_loop_depth(Some(8))); - let env_b = - RuntimeEnvironment::new_with_config(vec![], config_with_loop_depth(Some(16))); + let env_a = RuntimeEnvironment::new_with_config(vec![], config_with_loop_depth(Some(8))); + let env_b = RuntimeEnvironment::new_with_config(vec![], config_with_loop_depth(Some(16))); assert_ne!( env_a.verifier_config_digest, env_b.verifier_config_digest, "different verifier configs must yield different cache-key digests, otherwise a \ @@ -552,8 +567,7 @@ mod tests { #[test] fn verifier_config_digest_preserved_when_enabling_delayed_fields() { - let mut env = - RuntimeEnvironment::new_with_config(vec![], config_with_loop_depth(Some(4))); + let mut env = RuntimeEnvironment::new_with_config(vec![], config_with_loop_depth(Some(4))); let before = env.verifier_config_digest; env.enable_delayed_field_optimization(); assert_eq!( diff --git a/third_party/move/move-vm/runtime/src/storage/verified_module_cache.rs b/third_party/move/move-vm/runtime/src/storage/verified_module_cache.rs index aae87f734af..16d91476f57 100644 --- a/third_party/move/move-vm/runtime/src/storage/verified_module_cache.rs +++ b/third_party/move/move-vm/runtime/src/storage/verified_module_cache.rs @@ -36,19 +36,29 @@ impl VerifiedModuleCache { Self(Mutex::new(lru::LruCache::new(Self::VERIFIED_CACHE_SIZE))) } - /// Returns true if the module hash is contained in the cache. For tests, the cache is treated - /// as empty at all times. - pub(crate) fn contains(&self, module_hash: &[u8; 32]) -> bool { + /// Returns true if the (module hash, verifier config digest) pair is contained in the cache. + /// For tests, the cache is treated as empty at all times. + pub(crate) fn contains( + &self, + module_hash: &[u8; 32], + verifier_config_digest: &[u8; 32], + ) -> bool { // Note: need to use get to update LRU queue. - verifier_cache_enabled() && self.0.lock().get(module_hash).is_some() + verifier_cache_enabled() + && self + .0 + .lock() + .get(&(*module_hash, *verifier_config_digest)) + .is_some() } - /// Inserts the hash into the cache, marking the corresponding as locally verified. For tests, - /// entries are not added to the cache. - pub(crate) fn put(&self, module_hash: [u8; 32]) { + /// Inserts the (module hash, verifier config digest) pair into the cache, marking the + /// corresponding module as locally verified under that configuration. For tests, entries are + /// not added to the cache. + pub(crate) fn put(&self, module_hash: [u8; 32], verifier_config_digest: [u8; 32]) { if verifier_cache_enabled() { let mut cache = self.0.lock(); - cache.put(module_hash, ()); + cache.put((module_hash, verifier_config_digest), ()); } } @@ -75,7 +85,7 @@ fn verifier_cache_enabled() -> bool { false } else { // Cache is enabled in non-test environments only. - true + cache_active() } } } From 9162de4f802a2e735ffce8885d35bb7cd465997f Mon Sep 17 00:00:00 2001 From: Bo Wu Date: Tue, 16 Jun 2026 09:54:15 -0700 Subject: [PATCH 259/260] fix: update local test fixtures for move upgrade --- .../src/tests/driver_factory.rs | 15 ++---- testsuite/smoke-test/src/consensus/helpers.rs | 46 +++++++++++-------- testsuite/smoke-test/src/execution_pool.rs | 3 ++ testsuite/smoke-test/src/rest_api.rs | 2 + testsuite/smoke-test/src/state_sync.rs | 4 +- 5 files changed, 40 insertions(+), 30 deletions(-) diff --git a/state-sync/state-sync-driver/src/tests/driver_factory.rs b/state-sync/state-sync-driver/src/tests/driver_factory.rs index a80ae04354f..296e79a10d5 100644 --- a/state-sync/state-sync-driver/src/tests/driver_factory.rs +++ b/state-sync/state-sync-driver/src/tests/driver_factory.rs @@ -48,15 +48,10 @@ fn test_new_initialized_configs() { // Bootstrap the database let (node_config, _) = test_config(); - bootstrap_genesis::(&db_rw, get_genesis_txn(&node_config).unwrap()) - .unwrap(); - - // Get the actual waypoint from the bootstrapped database - let genesis_ledger_info = db_rw.reader.get_latest_ledger_info().unwrap(); - let waypoint = aptos_types::waypoint::Waypoint::new_any(genesis_ledger_info.ledger_info()); - - // Set the global waypoint version for event notifications - set_waypoint_version(waypoint.version()); + let genesis_waypoint = + bootstrap_genesis::(&db_rw, get_genesis_txn(&node_config).unwrap()) + .unwrap(); + set_waypoint_version(genesis_waypoint.version()); // Create mempool and consensus notifiers let (mempool_notifier, _) = new_mempool_notifier_listener_pair(100); @@ -98,7 +93,7 @@ fn test_new_initialized_configs() { let _ = DriverFactory::create_and_spawn_driver( true, &node_config, - waypoint, + node_config.base.waypoint.waypoint(), db_rw, chunk_executor, mempool_notifier, diff --git a/testsuite/smoke-test/src/consensus/helpers.rs b/testsuite/smoke-test/src/consensus/helpers.rs index 51d5bb9e86b..f00fc6a4a1d 100644 --- a/testsuite/smoke-test/src/consensus/helpers.rs +++ b/testsuite/smoke-test/src/consensus/helpers.rs @@ -20,25 +20,33 @@ pub async fn generate_traffic_and_assert_committed( .await .unwrap(); - let txn_stat = generate_traffic(swarm, nodes, duration, 100, vec![vec![ - ( - TransactionType::CoinTransfer { - invalid_transaction_ratio: 0, - sender_use_account_pool: false, - non_conflicting: false, - use_fa_transfer: true, - }, - 70, - ), - ( - TransactionType::AccountGeneration { - add_created_accounts_to_pool: true, - max_account_working_set: 1_000_000, - creation_balance: 5_000_000, - }, - 20, - ), - ]]) + let txn_stat = generate_traffic( + swarm, + nodes, + duration, + 100, + vec![vec![ + ( + TransactionType::CoinTransfer { + invalid_transaction_ratio: 0, + sender_use_account_pool: false, + non_conflicting: false, + use_fa_transfer: true, + use_txn_payload_v2_format: false, + use_orderless_transactions: false, + }, + 70, + ), + ( + TransactionType::AccountGeneration { + add_created_accounts_to_pool: true, + max_account_working_set: 1_000_000, + creation_balance: 5_000_000, + }, + 20, + ), + ]], + ) .await .unwrap(); println!("{:?}", txn_stat.rate()); diff --git a/testsuite/smoke-test/src/execution_pool.rs b/testsuite/smoke-test/src/execution_pool.rs index d0c82a6fb13..a81e914ea47 100644 --- a/testsuite/smoke-test/src/execution_pool.rs +++ b/testsuite/smoke-test/src/execution_pool.rs @@ -42,6 +42,9 @@ pub async fn assert_on_chain_consensus_config_window_size( OnChainConsensusConfig::V4 { window_size, .. } => { assert_eq!(window_size.map(|v| v), expected_window_size) }, + OnChainConsensusConfig::V5 { window_size, .. } => { + assert_eq!(window_size.map(|v| v), expected_window_size) + }, } } diff --git a/testsuite/smoke-test/src/rest_api.rs b/testsuite/smoke-test/src/rest_api.rs index ac7ac0a6446..3dbdcd53ed9 100644 --- a/testsuite/smoke-test/src/rest_api.rs +++ b/testsuite/smoke-test/src/rest_api.rs @@ -125,6 +125,8 @@ async fn test_gas_estimation_inner(swarm: &mut LocalSwarm) { sender_use_account_pool: false, non_conflicting: false, use_fa_transfer: true, + use_txn_payload_v2_format: false, + use_orderless_transactions: false, }, 100, )]], diff --git a/testsuite/smoke-test/src/state_sync.rs b/testsuite/smoke-test/src/state_sync.rs index c0534258d9e..bc84f31eda6 100644 --- a/testsuite/smoke-test/src/state_sync.rs +++ b/testsuite/smoke-test/src/state_sync.rs @@ -659,7 +659,9 @@ async fn test_validator_sync_and_participate(fast_sync: bool, epoch_changes: boo OnChainConsensusConfig::V1(consensus_config) => consensus_config, OnChainConsensusConfig::V2(consensus_config) => consensus_config, OnChainConsensusConfig::V3 { alg, .. } => alg.unwrap_jolteon_config_v1().clone(), - OnChainConsensusConfig::V4 { alg, .. } => alg.unwrap_jolteon_config_v1().clone(), + OnChainConsensusConfig::V4 { alg, .. } | OnChainConsensusConfig::V5 { alg, .. } => { + alg.unwrap_jolteon_config_v1().clone() + }, }; let leader_reputation_type = match &consensus_config.proposer_election_type { ProposerElectionType::LeaderReputation(leader_reputation_type) => { From 270ccd60e49216014a9abe8460a5d12727e66832 Mon Sep 17 00:00:00 2001 From: Ji Ru Date: Thu, 18 Jun 2026 11:20:36 -0400 Subject: [PATCH 260/260] fix(move): default language v2.1 / bytecode v7, mark v2.2 unstable, restore movement crate name --- crates/aptos/Cargo.toml | 2 +- .../move/move-binary-format/src/file_format_common.rs | 4 ++-- third_party/move/move-model/src/metadata.rs | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/aptos/Cargo.toml b/crates/aptos/Cargo.toml index 97a2075e6e5..c5a8693cfde 100644 --- a/crates/aptos/Cargo.toml +++ b/crates/aptos/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "aptos" +name = "movement" description = "Aptos tool for management of nodes and interacting with the blockchain" version = "7.10.1" diff --git a/third_party/move/move-binary-format/src/file_format_common.rs b/third_party/move/move-binary-format/src/file_format_common.rs index 53da7b56303..4209e508960 100644 --- a/third_party/move/move-binary-format/src/file_format_common.rs +++ b/third_party/move/move-binary-format/src/file_format_common.rs @@ -558,10 +558,10 @@ pub const VERSION_MAX: u32 = VERSION_9; /// Mark which version is the default version. This is the version used by default by tools like /// the compiler. Notice that this version might be different from the one supported on nodes. /// The node's max version is determined by the on-chain config for that node. -pub const VERSION_DEFAULT: u32 = VERSION_8; +pub const VERSION_DEFAULT: u32 = VERSION_7; /// Mark which version is the default version if compiling Move 2. -pub const VERSION_DEFAULT_LANG_V2: u32 = VERSION_8; +pub const VERSION_DEFAULT_LANG_V2: u32 = VERSION_7; /// Mark which version is the default version if compiling with language version 2.3 pub const VERSION_DEFAULT_LANG_V2_3: u32 = VERSION_9; diff --git a/third_party/move/move-model/src/metadata.rs b/third_party/move/move-model/src/metadata.rs index 29a846fc4b0..acf24f2042c 100644 --- a/third_party/move/move-model/src/metadata.rs +++ b/third_party/move/move-model/src/metadata.rs @@ -17,7 +17,7 @@ use std::{ const UNSTABLE_MARKER: &str = "-unstable"; // 2.2, even though stable, produces several warnings in the frameworks which we first need to fix // before we can make it the default -pub const LATEST_STABLE_LANGUAGE_VERSION_VALUE: LanguageVersion = LanguageVersion::V2_2; +pub const LATEST_STABLE_LANGUAGE_VERSION_VALUE: LanguageVersion = LanguageVersion::V2_1; pub const LATEST_STABLE_COMPILER_VERSION_VALUE: CompilerVersion = CompilerVersion::V2_0; pub const LATEST_STABLE_LANGUAGE_VERSION: &str = LATEST_STABLE_LANGUAGE_VERSION_VALUE.to_str(); pub const LATEST_STABLE_COMPILER_VERSION: &str = LATEST_STABLE_COMPILER_VERSION_VALUE.to_str(); @@ -283,8 +283,8 @@ impl LanguageVersion { pub const fn unstable(self) -> bool { use LanguageVersion::*; match self { - V1 | V2_0 | V2_1 | V2_2 => false, - V2_3 | V2_4 | V2_5 => true, + V1 | V2_0 | V2_1 => false, + V2_2 | V2_3 | V2_4 | V2_5 => true, } }