From 432a25a604fbf282f54512f06140dfa5fda3f919 Mon Sep 17 00:00:00 2001 From: jolestar Date: Tue, 18 Jul 2023 12:20:30 +0800 Subject: [PATCH] [MoveOS] Refactor MoveOS, make the pre_execute and post_execute functions be pre-transaction config --- crates/rooch-executor/src/actor/executor.rs | 35 ++++++++-- crates/rooch-framework/doc/auth_validator.md | 2 + .../auth_validator/auth_validator.move | 2 + .../auth_validator/ecdsa_validator.move | 9 +++ .../auth_validator/ed25519_validator.move | 10 +++ .../multi_ed25519_validator.move | 9 +++ .../src/bindings/auth_validator.rs | 64 ++++++++++++++++++ crates/rooch-framework/src/bindings/mod.rs | 1 + .../src/bindings/transaction_validator.rs | 32 ++++----- crates/rooch-genesis/genesis/genesis | Bin 36309 -> 36475 bytes crates/rooch-genesis/src/lib.rs | 13 ---- moveos/moveos-types/src/transaction.rs | 23 ++++++- moveos/moveos/src/moveos.rs | 47 +++++++------ moveos/moveos/src/vm/moveos_vm.rs | 51 ++++++-------- 14 files changed, 212 insertions(+), 86 deletions(-) create mode 100644 crates/rooch-framework/src/bindings/auth_validator.rs diff --git a/crates/rooch-executor/src/actor/executor.rs b/crates/rooch-executor/src/actor/executor.rs index 2588b01f5..609188ccf 100644 --- a/crates/rooch-executor/src/actor/executor.rs +++ b/crates/rooch-executor/src/actor/executor.rs @@ -23,13 +23,17 @@ use moveos_types::module_binding::MoveFunctionCaller; use moveos_types::move_types::as_struct_tag; use moveos_types::state::{AnnotatedState, State}; use moveos_types::state_resolver::{AnnotatedStateReader, StateReader}; +use moveos_types::transaction::FunctionCall; use moveos_types::transaction::TransactionExecutionInfo; use moveos_types::transaction::VerifiedMoveOSTransaction; +use moveos_types::tx_context::TxContext; use rooch_framework::bindings::address_mapping::AddressMapping; +use rooch_framework::bindings::auth_validator::AuthValidatorCaller; use rooch_framework::bindings::transaction_validator::TransactionValidator; use rooch_genesis::RoochGenesis; use rooch_store::RoochDB; use rooch_types::address::MultiChainAddress; +use rooch_types::transaction::AuthenticatorInfo; use rooch_types::transaction::{AbstractTransaction, TransactionSequenceMapping}; pub struct ExecutorActor { @@ -76,18 +80,17 @@ impl ExecutorActor { let mut moveos_tx = tx.construct_moveos_transaction(resolved_sender?)?; - let result = { - let tx_validator = self.moveos.as_module_bundle::(); - tx_validator.validate(&moveos_tx.ctx, authenticator) - }; + let result = self.validate_authenticator(&moveos_tx.ctx, authenticator); match result { - Ok(_) => { + Ok((pre_execute_functions, post_execute_functions)) => { // Add the original multichain address to the context moveos_tx .ctx .add(multi_chain_address_sender) .expect("add sender to context failed"); + moveos_tx.append_pre_execute_functions(pre_execute_functions); + moveos_tx.append_post_execute_functions(post_execute_functions); Ok(self.moveos.verify(moveos_tx)?) } Err(e) => { @@ -100,6 +103,28 @@ impl ExecutorActor { } } } + + pub fn validate_authenticator( + &self, + ctx: &TxContext, + authenticator: AuthenticatorInfo, + ) -> Result<(Vec, Vec)> { + let tx_validator = self.moveos.as_module_bundle::(); + let auth_validator = tx_validator.validate(ctx, authenticator.clone())?; + let auth_validator_caller = AuthValidatorCaller::new(&self.moveos, auth_validator); + auth_validator_caller.validate(ctx, authenticator.authenticator.payload)?; + // pre_execute_function: TransactionValidator first, then AuthValidator + let pre_execute_functions = vec![ + TransactionValidator::pre_execute_function_call(), + auth_validator_caller.pre_execute_function_call(), + ]; + // post_execute_function: AuthValidator first, then TransactionValidator + let post_execute_functions = vec![ + auth_validator_caller.post_execute_function_call(), + TransactionValidator::post_execute_function_call(), + ]; + Ok((pre_execute_functions, post_execute_functions)) + } } impl Actor for ExecutorActor {} diff --git a/crates/rooch-framework/doc/auth_validator.md b/crates/rooch-framework/doc/auth_validator.md index a9c795be4..30d1e2ee9 100644 --- a/crates/rooch-framework/doc/auth_validator.md +++ b/crates/rooch-framework/doc/auth_validator.md @@ -6,6 +6,8 @@ This module contains the error code for auth_validator module The auth_validator implementation should contain the following functions public fun validate(ctx: &StorageContext, payload: vector) +fun pre_execute(ctx: &mut StorageContext) +fun post_execute(ctx: &mut StorageContext) - [Constants](#@Constants_0) diff --git a/crates/rooch-framework/sources/auth_validator/auth_validator.move b/crates/rooch-framework/sources/auth_validator/auth_validator.move index 639949192..964cbc39e 100644 --- a/crates/rooch-framework/sources/auth_validator/auth_validator.move +++ b/crates/rooch-framework/sources/auth_validator/auth_validator.move @@ -1,6 +1,8 @@ /// This module contains the error code for auth_validator module /// The auth_validator implementation should contain the following functions /// public fun validate(ctx: &StorageContext, payload: vector) +/// fun pre_execute(ctx: &mut StorageContext) +/// fun post_execute(ctx: &mut StorageContext) module rooch_framework::auth_validator{ use std::error; diff --git a/crates/rooch-framework/sources/auth_validator/ecdsa_validator.move b/crates/rooch-framework/sources/auth_validator/ecdsa_validator.move index 423c347ea..9c2e090f9 100644 --- a/crates/rooch-framework/sources/auth_validator/ecdsa_validator.move +++ b/crates/rooch-framework/sources/auth_validator/ecdsa_validator.move @@ -25,4 +25,13 @@ module rooch_framework::ecdsa_validator { auth_validator::error_invalid_authenticator()); } + fun pre_execute( + _ctx: &mut StorageContext, + ) { + } + + fun post_execute( + _ctx: &mut StorageContext, + ) { + } } \ No newline at end of file diff --git a/crates/rooch-framework/sources/auth_validator/ed25519_validator.move b/crates/rooch-framework/sources/auth_validator/ed25519_validator.move index d863bdc16..c1266a0b9 100644 --- a/crates/rooch-framework/sources/auth_validator/ed25519_validator.move +++ b/crates/rooch-framework/sources/auth_validator/ed25519_validator.move @@ -85,6 +85,16 @@ module rooch_framework::ed25519_validator { auth_validator::error_invalid_account_auth_key()); } + fun pre_execute( + _ctx: &mut StorageContext, + ) { + } + + fun post_execute( + _ctx: &mut StorageContext, + ) { + } + // this test ensures that the ed25519_public_key_to_address function is compatible with the one in the rust code #[test] fun test_ed25519_public_key_to_address(){ diff --git a/crates/rooch-framework/sources/auth_validator/multi_ed25519_validator.move b/crates/rooch-framework/sources/auth_validator/multi_ed25519_validator.move index 47127e6e4..5a6be253f 100644 --- a/crates/rooch-framework/sources/auth_validator/multi_ed25519_validator.move +++ b/crates/rooch-framework/sources/auth_validator/multi_ed25519_validator.move @@ -17,4 +17,13 @@ module rooch_framework::multi_ed25519_validator { abort std::error::not_implemented(1) } + fun pre_execute( + _ctx: &mut StorageContext, + ) { + } + + fun post_execute( + _ctx: &mut StorageContext, + ) { + } } \ No newline at end of file diff --git a/crates/rooch-framework/src/bindings/auth_validator.rs b/crates/rooch-framework/src/bindings/auth_validator.rs new file mode 100644 index 000000000..34d6680f9 --- /dev/null +++ b/crates/rooch-framework/src/bindings/auth_validator.rs @@ -0,0 +1,64 @@ +// Copyright (c) RoochNetwork +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::Result; +use move_core_types::value::MoveValue; +use moveos_types::{ + module_binding::MoveFunctionCaller, move_types::FunctionId, transaction::FunctionCall, + tx_context::TxContext, +}; +use rooch_types::framework::auth_validator_registry::AuthValidator; + +use super::transaction_validator::TransactionValidator; + +/// Rust bindings for developer custom auth validator module +/// Because the module is not in RoochFramework, we need to dynamically determine the module id base on the AuthValidator struct +pub struct AuthValidatorCaller<'a> { + caller: &'a dyn MoveFunctionCaller, + auth_validator: AuthValidator, +} + +impl<'a> AuthValidatorCaller<'a> { + pub fn new(caller: &'a dyn MoveFunctionCaller, auth_validator: AuthValidator) -> Self { + Self { + caller, + auth_validator, + } + } + + pub fn validate(&self, ctx: &TxContext, payload: Vec) -> Result<()> { + let auth_validator_call = FunctionCall::new( + self.auth_validator.validator_function_id(), + vec![], + vec![MoveValue::vector_u8(payload).simple_serialize().unwrap()], + ); + self.caller + .call_function(ctx, auth_validator_call) + .map(|values| { + debug_assert!(values.is_empty(), "should not have return values"); + })?; + Ok(()) + } + + pub fn pre_execute_function_id(&self) -> FunctionId { + FunctionId::new( + self.auth_validator.validator_module_id(), + TransactionValidator::PRE_EXECUTE_FUNCTION_NAME.to_owned(), + ) + } + + pub fn pre_execute_function_call(&self) -> FunctionCall { + FunctionCall::new(self.pre_execute_function_id(), vec![], vec![]) + } + + pub fn post_execute_function_id(&self) -> FunctionId { + FunctionId::new( + self.auth_validator.validator_module_id(), + TransactionValidator::POST_EXECUTE_FUNCTION_NAME.to_owned(), + ) + } + + pub fn post_execute_function_call(&self) -> FunctionCall { + FunctionCall::new(self.post_execute_function_id(), vec![], vec![]) + } +} diff --git a/crates/rooch-framework/src/bindings/mod.rs b/crates/rooch-framework/src/bindings/mod.rs index 5d4641cb1..7fd63065d 100644 --- a/crates/rooch-framework/src/bindings/mod.rs +++ b/crates/rooch-framework/src/bindings/mod.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 pub mod address_mapping; +pub mod auth_validator; pub mod ed25519_validator; pub mod empty; pub mod transaction_validator; diff --git a/crates/rooch-framework/src/bindings/transaction_validator.rs b/crates/rooch-framework/src/bindings/transaction_validator.rs index d3b7e41e0..e69acc565 100644 --- a/crates/rooch-framework/src/bindings/transaction_validator.rs +++ b/crates/rooch-framework/src/bindings/transaction_validator.rs @@ -21,11 +21,11 @@ pub struct TransactionValidator<'a> { } impl<'a> TransactionValidator<'a> { - const VALIDATE_FUNCTION_NAME: &'static IdentStr = ident_str!("validate"); - const PRE_EXECUTE_FUNCTION_NAME: &IdentStr = ident_str!("pre_execute"); - const POST_EXECUTE_FUNCTION_NAME: &IdentStr = ident_str!("post_execute"); + pub const VALIDATE_FUNCTION_NAME: &'static IdentStr = ident_str!("validate"); + pub const PRE_EXECUTE_FUNCTION_NAME: &IdentStr = ident_str!("pre_execute"); + pub const POST_EXECUTE_FUNCTION_NAME: &IdentStr = ident_str!("post_execute"); - pub fn validate(&self, ctx: &TxContext, auth: AuthenticatorInfo) -> Result<()> { + pub fn validate(&self, ctx: &TxContext, auth: AuthenticatorInfo) -> Result { let tx_validator_call = FunctionCall::new( Self::function_id(Self::VALIDATE_FUNCTION_NAME), vec![], @@ -36,7 +36,7 @@ impl<'a> TransactionValidator<'a> { MoveValue::U64(auth.authenticator.scheme) .simple_serialize() .unwrap(), - MoveValue::vector_u8(auth.authenticator.payload.clone()) + MoveValue::vector_u8(auth.authenticator.payload) .simple_serialize() .unwrap(), ], @@ -49,28 +49,24 @@ impl<'a> TransactionValidator<'a> { bcs::from_bytes::(&value.value) .expect("should be a valid auth validator") })?; - let auth_validator_call = FunctionCall::new( - auth_validator.validator_function_id(), - vec![], - vec![MoveValue::vector_u8(auth.authenticator.payload) - .simple_serialize() - .unwrap()], - ); - self.caller - .call_function(ctx, auth_validator_call) - .map(|values| { - debug_assert!(values.is_empty(), "should not have return values"); - })?; - Ok(()) + Ok(auth_validator) } pub fn pre_execute_function_id() -> FunctionId { Self::function_id(Self::PRE_EXECUTE_FUNCTION_NAME) } + pub fn pre_execute_function_call() -> FunctionCall { + FunctionCall::new(Self::pre_execute_function_id(), vec![], vec![]) + } + pub fn post_execute_function_id() -> FunctionId { Self::function_id(Self::POST_EXECUTE_FUNCTION_NAME) } + + pub fn post_execute_function_call() -> FunctionCall { + FunctionCall::new(Self::post_execute_function_id(), vec![], vec![]) + } } impl<'a> ModuleBundle<'a> for TransactionValidator<'a> { diff --git a/crates/rooch-genesis/genesis/genesis b/crates/rooch-genesis/genesis/genesis index 19edd43e6c01e9d5721177dee9627b21af4cd2a9..be26577469b3eb4c402cb68a87971b420aeafe7f 100644 GIT binary patch delta 799 zcmZ{iJ!lkB5XWcceeLbO+q<{9oQZDqVlGA{27+P)K~q@TXro5V1uaA&*oX;dEF@hZ zMtKUtrLhze5DrrK0YS6~C}|W$EG#4lh7ju@I2-Y+aEqC@Z}$E7H}ijQ8?-S?k5)g+y)pUb!{y_(mB!8Khx_Ihk|V{g)#qy)FUJnv^^2z$Yq!LM^lPL6 zAcvqy2O@4)J$ZBBJ_fIFM9)zeE|9WMXb%7)5eNw+`FjNjptE3*00M!4A=l9ayb>(M zul~eDoBwjA*I$|_`fpQher-JUM~80g<-hU6f?3XVIU^Y$mf_QSv&*9zBs{vDkmAch=Y*g_PYtPKLJ?89{u5pwu0s18YJE!8s=*)5*gv puz*W?xFoEKmDRjr6JlXm+O@C|I+8KDlH94PE@_^;KAEuRKLEe@aTEXm delta 678 zcmZ{hJ7`ov6o$_^^SqC}yK}RNdECe*Bq2eYfQ4Wah#(dssEFB!yBd~=pb-sutso+S zG%E3~BItq&YH45*ELGBqSO`YYG62(fS&PBG`7neYG4&wKRlF0E}Qt-+OwHdXdeS}rLOum1ERM?;%07N1X5=gOJ0s>#)Q;P`chlv9n`r_2-+Syukcy{K( z$?4ko%(>ax!fbl9d^0ha$$<kDS$coqkV#!)j=u#skv%iUU6UX#p zCRt;WXEc(L0F!`Zhzwn2kDH9elL~~d`I~^x((%gl|EM-9*GBBWR3eHn6agcJ6o`mM z!3i0toRh6)b+u!(;r&JQ5n_rXQL4#h4Am;0H&>`3>@8K*-_)?*)GBzb|`=1Ug|qvbTs}wzoUBXg$vh zqZ~$v+9%|#cxI?txrGy$9xNxV`-=v9KO&0fh z>DQ&5q3;3`9HLFQzoS01wLe+!##}mA?;B=;BqJyrUfW=V4npID4=(RyVEQ<#Jjd<| Z>Fau@a~z@$WJE5O{c6A!THote<6nFWZ#w`0 diff --git a/crates/rooch-genesis/src/lib.rs b/crates/rooch-genesis/src/lib.rs index 60d770f96..9af236107 100644 --- a/crates/rooch-genesis/src/lib.rs +++ b/crates/rooch-genesis/src/lib.rs @@ -9,7 +9,6 @@ use moveos::moveos::MoveOSConfig; use moveos_stdlib_builder::BuildOptions; use moveos_types::transaction::{MoveAction, MoveOSTransaction}; use once_cell::sync::Lazy; -use rooch_framework::bindings::transaction_validator; use serde::{Deserialize, Serialize}; use std::{ fs::File, @@ -52,22 +51,10 @@ impl RoochGenesis { pub fn build_with_option(option: BuildOption) -> Result { let config = MoveOSConfig { vm_config: VMConfig::default(), - pre_execute_function: Some( - transaction_validator::TransactionValidator::pre_execute_function_id(), - ), - post_execute_function: Some( - transaction_validator::TransactionValidator::post_execute_function_id(), - ), }; let config_for_test = MoveOSConfig { vm_config: VMConfig::default(), - pre_execute_function: Some( - transaction_validator::TransactionValidator::pre_execute_function_id(), - ), - post_execute_function: Some( - transaction_validator::TransactionValidator::post_execute_function_id(), - ), }; let gas_params = rooch_framework::natives::GasParameters::zeros(); diff --git a/moveos/moveos-types/src/transaction.rs b/moveos/moveos-types/src/transaction.rs index 3933424a1..7fd4873c7 100644 --- a/moveos/moveos-types/src/transaction.rs +++ b/moveos/moveos-types/src/transaction.rs @@ -187,6 +187,10 @@ impl Display for VerifiedMoveAction { pub struct MoveOSTransaction { pub ctx: TxContext, pub action: MoveAction, + /// if the pre_execute_functions is not empty, the MoveOS will call the functions before the transaction is executed. + pub pre_execute_functions: Vec, + /// if the post_execute_functions is not empty, the MoveOS will call the functions after the transaction is executed. + pub post_execute_functions: Vec, } impl MoveOSTransaction { @@ -199,11 +203,26 @@ impl MoveOSTransaction { Self { ctx, action: sender_and_action.1, + pre_execute_functions: vec![], + post_execute_functions: vec![], } } pub fn new(ctx: TxContext, action: MoveAction) -> Self { - Self { ctx, action } + Self { + ctx, + action, + pre_execute_functions: vec![], + post_execute_functions: vec![], + } + } + + pub fn append_pre_execute_functions(&mut self, functions: Vec) { + self.pre_execute_functions.extend(functions); + } + + pub fn append_post_execute_functions(&mut self, functions: Vec) { + self.post_execute_functions.extend(functions); } } @@ -211,6 +230,8 @@ impl MoveOSTransaction { pub struct VerifiedMoveOSTransaction { pub ctx: TxContext, pub action: VerifiedMoveAction, + pub pre_execute_functions: Vec, + pub post_execute_functions: Vec, } /// TransactionOutput is the execution result of a MoveOS transaction diff --git a/moveos/moveos/src/moveos.rs b/moveos/moveos/src/moveos.rs index 3e4dbb9b8..767e16661 100644 --- a/moveos/moveos/src/moveos.rs +++ b/moveos/moveos/src/moveos.rs @@ -17,7 +17,6 @@ use moveos_store::MoveOSDB; use moveos_store::{event_store::EventStore, state_store::StateDB}; use moveos_types::function_return_value::FunctionReturnValue; use moveos_types::module_binding::MoveFunctionCaller; -use moveos_types::move_types::FunctionId; use moveos_types::state_resolver::MoveOSResolverProxy; use moveos_types::transaction::{MoveOSTransaction, TransactionOutput, VerifiedMoveOSTransaction}; use moveos_types::tx_context::TxContext; @@ -25,10 +24,6 @@ use moveos_types::{h256::H256, transaction::FunctionCall}; pub struct MoveOSConfig { pub vm_config: VMConfig, - /// if the pre_execute_function is set, the MoveOS will call the function before the transaction is executed. - pub pre_execute_function: Option, - /// if the post_execute_function is set, the MoveOS will call the function after the transaction is executed. - pub post_execute_function: Option, } impl std::fmt::Debug for MoveOSConfig { @@ -42,8 +37,6 @@ impl std::fmt::Debug for MoveOSConfig { "vm_config.paranoid_type_checks", &self.vm_config.paranoid_type_checks, ) - .field("pre_execute_function", &self.pre_execute_function) - .field("post_execute_function", &self.post_execute_function) .finish() } } @@ -57,8 +50,6 @@ impl Clone for MoveOSConfig { max_binary_format_version: self.vm_config.max_binary_format_version, paranoid_type_checks: self.vm_config.paranoid_type_checks, }, - pre_execute_function: self.pre_execute_function.clone(), - post_execute_function: self.post_execute_function.clone(), } } } @@ -74,12 +65,7 @@ impl MoveOS { natives: impl IntoIterator, config: MoveOSConfig, ) -> Result { - let vm = MoveOSVM::new( - natives, - config.vm_config, - config.pre_execute_function, - config.post_execute_function, - )?; + let vm = MoveOSVM::new(natives, config.vm_config)?; Ok(Self { vm, db: MoveOSResolverProxy(db), @@ -101,7 +87,12 @@ impl MoveOS { } fn verify_and_execute_genesis_tx(&mut self, tx: MoveOSTransaction) -> Result<()> { - let MoveOSTransaction { ctx, action } = tx; + let MoveOSTransaction { + ctx, + action, + pre_execute_functions: _, + post_execute_functions: _, + } = tx; let mut session = self.vm.new_genesis_session(&self.db, ctx); let verified_action = session.verify_move_action(action)?; @@ -132,7 +123,12 @@ impl MoveOS { } pub fn verify(&self, tx: MoveOSTransaction) -> Result { - let MoveOSTransaction { ctx, action } = tx; + let MoveOSTransaction { + ctx, + action, + pre_execute_functions, + post_execute_functions, + } = tx; let gas_meter = UnmeteredGasMeter; let session = self @@ -144,11 +140,18 @@ impl MoveOS { Ok(VerifiedMoveOSTransaction { ctx, action: verified_action, + pre_execute_functions, + post_execute_functions, }) } pub fn execute(&mut self, tx: VerifiedMoveOSTransaction) -> Result<(H256, TransactionOutput)> { - let VerifiedMoveOSTransaction { ctx, action } = tx; + let VerifiedMoveOSTransaction { + ctx, + action, + pre_execute_functions, + post_execute_functions, + } = tx; let tx_hash = ctx.tx_hash(); if log::log_enabled!(log::Level::Debug) { log::debug!( @@ -160,7 +163,13 @@ impl MoveOS { } //TODO define the gas meter. let gas_meter = UnmeteredGasMeter; - let mut session = self.vm.new_session(&self.db, ctx, gas_meter); + let mut session = self.vm.new_session( + &self.db, + ctx, + pre_execute_functions, + post_execute_functions, + gas_meter, + ); let execute_result = session.execute_move_action(action); if execute_result.is_err() { log::warn!("execute tx({}) error: {:?}", tx_hash, execute_result); diff --git a/moveos/moveos/src/vm/moveos_vm.rs b/moveos/moveos/src/vm/moveos_vm.rs index b6c20cd8d..0f18198a2 100644 --- a/moveos/moveos/src/vm/moveos_vm.rs +++ b/moveos/moveos/src/vm/moveos_vm.rs @@ -46,21 +46,15 @@ use std::{borrow::Borrow, sync::Arc}; /// MoveOSVM is a wrapper of MoveVM with MoveOS specific features. pub struct MoveOSVM { inner: MoveVM, - pre_execute_function: Option, - post_execute_function: Option, } impl MoveOSVM { pub fn new( natives: impl IntoIterator, vm_config: VMConfig, - pre_execute_function: Option, - post_execute_function: Option, ) -> VMResult { Ok(Self { inner: MoveVM::new_with_config(natives, vm_config)?, - pre_execute_function, - post_execute_function, }) } @@ -68,14 +62,16 @@ impl MoveOSVM { &self, remote: &'r S, ctx: TxContext, + pre_execute_functions: Vec, + post_execute_functions: Vec, gas_meter: G, ) -> MoveOSSession<'r, '_, S, G> { MoveOSSession::new( &self.inner, remote, ctx, - self.pre_execute_function.clone(), - self.post_execute_function.clone(), + pre_execute_functions, + post_execute_functions, gas_meter, false, ) @@ -89,7 +85,7 @@ impl MoveOSVM { //Do not charge gas for genesis session let gas_meter = UnmeteredGasMeter; // Genesis session do not need to execute pre_execute and post_execute function - MoveOSSession::new(&self.inner, remote, ctx, None, None, gas_meter, false) + MoveOSSession::new(&self.inner, remote, ctx, vec![], vec![], gas_meter, false) } pub fn new_readonly_session<'r, S: MoveOSResolver, G: GasMeter>( @@ -98,7 +94,7 @@ impl MoveOSVM { ctx: TxContext, gas_meter: G, ) -> MoveOSSession<'r, '_, S, G> { - MoveOSSession::new(&self.inner, remote, ctx, None, None, gas_meter, true) + MoveOSSession::new(&self.inner, remote, ctx, vec![], vec![], gas_meter, true) } } @@ -110,8 +106,8 @@ pub struct MoveOSSession<'r, 'l, S, G> { remote: &'r S, session: Session<'r, 'l, S>, ctx: StorageContext, - pre_execute_function: Option, - post_execute_function: Option, + pre_execute_functions: Vec, + post_execute_functions: Vec, gas_meter: G, read_only: bool, } @@ -125,18 +121,18 @@ where vm: &'l MoveVM, remote: &'r S, ctx: TxContext, - pre_execute_function: Option, - post_execute_function: Option, + pre_execute_functions: Vec, + post_execute_functions: Vec, gas_meter: G, read_only: bool, ) -> Self { if read_only { assert!( - pre_execute_function.is_none(), + pre_execute_functions.is_empty(), "pre_execute_function is not allowed in read only session" ); assert!( - post_execute_function.is_none(), + post_execute_functions.is_empty(), "post_execute_function is not allowed in read only session" ); } @@ -146,8 +142,8 @@ where remote, session: Self::new_inner_session(vm, remote), ctx, - pre_execute_function, - post_execute_function, + pre_execute_functions, + post_execute_functions, gas_meter, read_only, }; @@ -449,13 +445,11 @@ where // the read_only function should not execute pre_execute function // this ensure via the check in new_session let mut pre_execute_session = self; - if let Some(pre_execute_function) = &pre_execute_session.pre_execute_function { + for function_call in pre_execute_session.pre_execute_functions.clone() { + //TODO handle pre_execute function error + //Because if we allow user to write pre_execute function, we need to handle the error pre_execute_session - .execute_function_bypass_visibility(FunctionCall::new( - pre_execute_function.clone(), - vec![], - vec![], - )) + .execute_function_bypass_visibility(function_call) .expect("pre_execute function should always success"); } pre_execute_session @@ -473,13 +467,10 @@ where self.respawn() } }; - if let Some(post_execute_function) = &post_execute_session.post_execute_function { + for function_call in post_execute_session.post_execute_functions.clone() { + //TODO handle post_execute function error post_execute_session - .execute_function_bypass_visibility(FunctionCall::new( - post_execute_function.clone(), - vec![], - vec![], - )) + .execute_function_bypass_visibility(function_call) .expect("post_execute function should always success"); } (post_execute_session, execute_status)