Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MoveOS] Refactor MoveOS, make the pre_execute and post_execute functions be pre-transaction config #504

Merged
merged 1 commit into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 30 additions & 5 deletions crates/rooch-executor/src/actor/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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::<TransactionValidator>();
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) => {
Expand All @@ -100,6 +103,28 @@ impl ExecutorActor {
}
}
}

pub fn validate_authenticator(
&self,
ctx: &TxContext,
authenticator: AuthenticatorInfo,
) -> Result<(Vec<FunctionCall>, Vec<FunctionCall>)> {
let tx_validator = self.moveos.as_module_bundle::<TransactionValidator>();
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 {}
Expand Down
2 changes: 2 additions & 0 deletions crates/rooch-framework/doc/auth_validator.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8>)
fun pre_execute(ctx: &mut StorageContext)
fun post_execute(ctx: &mut StorageContext)


- [Constants](#@Constants_0)
Expand Down
Original file line number Diff line number Diff line change
@@ -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<u8>)
/// fun pre_execute(ctx: &mut StorageContext)
/// fun post_execute(ctx: &mut StorageContext)
module rooch_framework::auth_validator{
use std::error;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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(){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
) {
}
}
64 changes: 64 additions & 0 deletions crates/rooch-framework/src/bindings/auth_validator.rs
Original file line number Diff line number Diff line change
@@ -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<u8>) -> 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![])
}
}
1 change: 1 addition & 0 deletions crates/rooch-framework/src/bindings/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
32 changes: 14 additions & 18 deletions crates/rooch-framework/src/bindings/transaction_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<AuthValidator> {
let tx_validator_call = FunctionCall::new(
Self::function_id(Self::VALIDATE_FUNCTION_NAME),
vec![],
Expand All @@ -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(),
],
Expand All @@ -49,28 +49,24 @@ impl<'a> TransactionValidator<'a> {
bcs::from_bytes::<AuthValidator>(&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> {
Expand Down
Binary file modified crates/rooch-genesis/genesis/genesis
Binary file not shown.
13 changes: 0 additions & 13 deletions crates/rooch-genesis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -52,22 +51,10 @@ impl RoochGenesis {
pub fn build_with_option(option: BuildOption) -> Result<Self> {
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();
Expand Down
23 changes: 22 additions & 1 deletion moveos/moveos-types/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<FunctionCall>,
/// if the post_execute_functions is not empty, the MoveOS will call the functions after the transaction is executed.
pub post_execute_functions: Vec<FunctionCall>,
}

impl MoveOSTransaction {
Expand All @@ -199,18 +203,35 @@ 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<FunctionCall>) {
self.pre_execute_functions.extend(functions);
}

pub fn append_post_execute_functions(&mut self, functions: Vec<FunctionCall>) {
self.post_execute_functions.extend(functions);
}
}

#[derive(Debug, Clone)]
pub struct VerifiedMoveOSTransaction {
pub ctx: TxContext,
pub action: VerifiedMoveAction,
pub pre_execute_functions: Vec<FunctionCall>,
pub post_execute_functions: Vec<FunctionCall>,
}

/// TransactionOutput is the execution result of a MoveOS transaction
Expand Down
Loading
Loading