Skip to content

Commit

Permalink
[fix] Draft for using delta-writes in TransactionOutput and ChangeSet
Browse files Browse the repository at this point in the history
  • Loading branch information
georgemitenkov committed Jul 26, 2022
1 parent 720190d commit 5d8e933
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 58 deletions.
20 changes: 17 additions & 3 deletions aptos-move/aptos-vm/src/adapter_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ use crate::{counters::*, data_cache::StateViewCache};
use anyhow::Result;
use aptos_state_view::StateView;
use aptos_types::{
transaction::{SignatureCheckedTransaction, SignedTransaction, VMValidatorResult},
transaction::{
SignatureCheckedTransaction, SignedTransaction, TransactionOutputWithDeltas,
VMValidatorResult,
},
vm_status::{StatusCode, VMStatus},
};

Expand Down Expand Up @@ -64,7 +67,7 @@ pub trait VMAdapter {
txn: &PreprocessedTransaction,
data_cache: &S,
log_context: &AdapterLogSchema,
) -> Result<(VMStatus, TransactionOutput, Option<String>), VMStatus>;
) -> Result<(VMStatus, TransactionOutputWithDeltas, Option<String>), VMStatus>;
}

/// Validate a signed transaction by performing the following:
Expand Down Expand Up @@ -199,13 +202,17 @@ pub(crate) fn execute_block_impl<A: VMAdapter, S: StateView>(
debug!(log_context, "Retry after reconfiguration");
continue;
};
let (vm_status, output, sender) = adapter.execute_single_transaction(
let (vm_status, output_with_deltas, sender) = adapter.execute_single_transaction(
&txn,
&data_cache.as_move_resolver(),
&log_context,
)?;
// TODO: here we extract deltas so that we can use them later
let output = output_with_deltas.into();
if !output.status().is_discarded() {
data_cache.push_write_set(output.write_set());
// TODO: also apply deltas.
// data_cache.try_apply_deltas(deltas); (consumes deltas, error on overflow)
} else {
match sender {
Some(s) => trace!(
Expand Down Expand Up @@ -273,6 +280,13 @@ pub(crate) fn preprocess_transaction<A: VMAdapter>(txn: Transaction) -> Preproce
}
}

pub(crate) fn discard_error_vm_status_with_deltas(
err: VMStatus,
) -> (VMStatus, TransactionOutputWithDeltas) {
let (vm_status, empty_output) = discard_error_vm_status(err);
(vm_status, TransactionOutputWithDeltas::from(empty_output))
}

pub(crate) fn discard_error_vm_status(err: VMStatus) -> (VMStatus, TransactionOutput) {
let vm_status = err.clone();
let error_code = match err.keep_or_discard() {
Expand Down
139 changes: 98 additions & 41 deletions aptos-move/aptos-vm/src/aptos_vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
use crate::{
adapter_common,
adapter_common::{
discard_error_output, discard_error_vm_status, validate_signature_checked_transaction,
validate_signed_transaction, PreprocessedTransaction, VMAdapter,
discard_error_output, discard_error_vm_status, discard_error_vm_status_with_deltas,
validate_signature_checked_transaction, validate_signed_transaction,
PreprocessedTransaction, VMAdapter,
},
aptos_vm_impl::{
charge_global_write_gas_usage, get_transaction_output, AptosVMImpl, AptosVMInternals,
charge_global_write_gas_usage, get_transaction_output, get_transaction_output_with_deltas,
AptosVMImpl, AptosVMInternals,
},
counters::*,
data_cache::{AsMoveResolver, StateViewCache},
Expand All @@ -31,8 +33,8 @@ use aptos_types::{
on_chain_config::{new_epoch_event_key, VMConfig, VMPublishingOption, Version},
transaction::{
ChangeSet, ExecutionStatus, ModuleBundle, SignatureCheckedTransaction, SignedTransaction,
Transaction, TransactionOutput, TransactionPayload, TransactionStatus, VMValidatorResult,
WriteSetPayload,
Transaction, TransactionOutput, TransactionOutputWithDeltas, TransactionPayload,
TransactionStatus, VMValidatorResult, WriteSetPayload,
},
vm_status::{StatusCode, VMStatus},
write_set::{WriteSet, WriteSetMut},
Expand Down Expand Up @@ -152,7 +154,7 @@ impl AptosVM {
txn_data: &TransactionMetadata,
storage: &S,
log_context: &AdapterLogSchema,
) -> TransactionOutput {
) -> TransactionOutputWithDeltas {
self.failed_transaction_cleanup_and_keep_vm_status(
error_code,
gas_status,
Expand All @@ -170,7 +172,7 @@ impl AptosVM {
txn_data: &TransactionMetadata,
storage: &S,
log_context: &AdapterLogSchema,
) -> (VMStatus, TransactionOutput) {
) -> (VMStatus, TransactionOutputWithDeltas) {
gas_status.set_metering(false);
let mut session = self.0.new_session(storage, SessionId::txn_meta(txn_data));
match TransactionStatus::from(error_code.clone()) {
Expand All @@ -185,21 +187,22 @@ impl AptosVM {
self.0
.run_failure_epilogue(&mut session, gas_status, txn_data, log_context)
{
return discard_error_vm_status(e);
return discard_error_vm_status_with_deltas(e);
}
let txn_output = get_transaction_output(
let txn_output = get_transaction_output_with_deltas(
&mut (),
session,
gas_status.remaining_gas(),
txn_data,
status,
)
.unwrap_or_else(|e| discard_error_vm_status(e).1);
.unwrap_or_else(|e| discard_error_vm_status_with_deltas(e).1);
(error_code, txn_output)
}
TransactionStatus::Discard(status) => {
(VMStatus::Error(status), discard_error_output(status))
}
TransactionStatus::Discard(status) => (
VMStatus::Error(status),
TransactionOutputWithDeltas::from(discard_error_output(status)),
),
TransactionStatus::Retry => unreachable!(),
}
}
Expand All @@ -210,14 +213,14 @@ impl AptosVM {
gas_status: &mut GasStatus,
txn_data: &TransactionMetadata,
log_context: &AdapterLogSchema,
) -> Result<(VMStatus, TransactionOutput), VMStatus> {
) -> Result<(VMStatus, TransactionOutputWithDeltas), VMStatus> {
gas_status.set_metering(false);
self.0
.run_success_epilogue(&mut session, gas_status, txn_data, log_context)?;

Ok((
VMStatus::Executed,
get_transaction_output(
get_transaction_output_with_deltas(
&mut (),
session,
gas_status.remaining_gas(),
Expand All @@ -227,14 +230,14 @@ impl AptosVM {
))
}

fn execute_script_or_script_function<S: MoveResolverExt>(
fn execute_script_or_script_function_with_deltas<S: MoveResolverExt>(
&self,
mut session: SessionExt<S>,
gas_status: &mut GasStatus,
txn_data: &TransactionMetadata,
payload: &TransactionPayload,
log_context: &AdapterLogSchema,
) -> Result<(VMStatus, TransactionOutput), VMStatus> {
) -> Result<(VMStatus, TransactionOutputWithDeltas), VMStatus> {
fail_point!("move_adapter::execute_script_or_script_function", |_| {
Err(VMStatus::Error(
StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR,
Expand Down Expand Up @@ -302,6 +305,24 @@ impl AptosVM {
}
}

fn execute_script_or_script_function<S: MoveResolverExt>(
&self,
mut session: SessionExt<S>,
gas_status: &mut GasStatus,
txn_data: &TransactionMetadata,
payload: &TransactionPayload,
log_context: &AdapterLogSchema,
) -> Result<(VMStatus, TransactionOutput), VMStatus> {
self.execute_script_or_script_function_with_deltas(
session,
gas_status,
txn_data,
payload,
log_context,
)
.map(|(vm_status, output)| (vm_status, output.into()))
}

fn verify_module_bundle<S: MoveResolverExt>(
session: &mut SessionExt<S>,
module_bundle: &ModuleBundle,
Expand Down Expand Up @@ -372,14 +393,14 @@ impl AptosVM {
Ok(())
}

fn execute_modules<S: MoveResolverExt>(
fn execute_modules_with_deltas<S: MoveResolverExt>(
&self,
mut session: SessionExt<S>,
gas_status: &mut GasStatus,
txn_data: &TransactionMetadata,
modules: &ModuleBundle,
log_context: &AdapterLogSchema,
) -> Result<(VMStatus, TransactionOutput), VMStatus> {
) -> Result<(VMStatus, TransactionOutputWithDeltas), VMStatus> {
fail_point!("move_adapter::execute_module", |_| {
Err(VMStatus::Error(
StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR,
Expand Down Expand Up @@ -415,17 +436,29 @@ impl AptosVM {
self.success_transaction_cleanup(session, gas_status, txn_data, log_context)
}

fn execute_modules<S: MoveResolverExt>(
&self,
mut session: SessionExt<S>,
gas_status: &mut GasStatus,
txn_data: &TransactionMetadata,
modules: &ModuleBundle,
log_context: &AdapterLogSchema,
) -> Result<(VMStatus, TransactionOutput), VMStatus> {
self.execute_modules_with_deltas(session, gas_status, txn_data, modules, log_context)
.map(|(vm_status, output)| (vm_status, output.into()))
}

pub(crate) fn execute_user_transaction<S: MoveResolverExt>(
&self,
storage: &S,
txn: &SignatureCheckedTransaction,
log_context: &AdapterLogSchema,
) -> (VMStatus, TransactionOutput) {
) -> (VMStatus, TransactionOutputWithDeltas) {
macro_rules! unwrap_or_discard {
($res: expr) => {
match $res {
Ok(s) => s,
Err(e) => return discard_error_vm_status(e),
Err(e) => return discard_error_vm_status_with_deltas(e),
}
};
}
Expand All @@ -439,7 +472,7 @@ impl AptosVM {
false,
log_context,
) {
return discard_error_vm_status(err);
return discard_error_vm_status_with_deltas(err);
};

let gas_schedule = unwrap_or_discard!(self.0.get_gas_schedule(log_context));
Expand All @@ -449,18 +482,24 @@ impl AptosVM {
let result = match txn.payload() {
payload @ TransactionPayload::Script(_)
| payload @ TransactionPayload::ScriptFunction(_) => self
.execute_script_or_script_function(
.execute_script_or_script_function_with_deltas(
session,
&mut gas_status,
&txn_data,
payload,
log_context,
),
TransactionPayload::ModuleBundle(m) => {
self.execute_modules(session, &mut gas_status, &txn_data, m, log_context)
}
TransactionPayload::ModuleBundle(m) => self.execute_modules_with_deltas(
session,
&mut gas_status,
&txn_data,
m,
log_context,
),
TransactionPayload::WriteSet(_) => {
return discard_error_vm_status(VMStatus::Error(StatusCode::UNREACHABLE));
return discard_error_vm_status_with_deltas(VMStatus::Error(
StatusCode::UNREACHABLE,
));
}
};

Expand All @@ -475,7 +514,7 @@ impl AptosVM {
Err(err) => {
let txn_status = TransactionStatus::from(err.clone());
if txn_status.is_discarded() {
discard_error_vm_status(err)
discard_error_vm_status_with_deltas(err)
} else {
self.failed_transaction_cleanup_and_keep_vm_status(
err,
Expand Down Expand Up @@ -973,20 +1012,28 @@ impl VMAdapter for AptosVM {
txn: &PreprocessedTransaction,
data_cache: &S,
log_context: &AdapterLogSchema,
) -> Result<(VMStatus, TransactionOutput, Option<String>), VMStatus> {
) -> Result<(VMStatus, TransactionOutputWithDeltas, Option<String>), VMStatus> {
Ok(match txn {
PreprocessedTransaction::BlockMetadata(block_metadata) => {
let (vm_status, output) =
self.process_block_prologue(data_cache, block_metadata.clone(), log_context)?;
(vm_status, output, Some("block_prologue".to_string()))
(
vm_status,
TransactionOutputWithDeltas::from(output),
Some("block_prologue".to_string()),
)
}
PreprocessedTransaction::WaypointWriteSet(write_set_payload) => {
let (vm_status, output) = self.process_waypoint_change_set(
data_cache,
write_set_payload.clone(),
log_context,
)?;
(vm_status, output, Some("waypoint_write_set".to_string()))
(
vm_status,
TransactionOutputWithDeltas::from(output),
Some("waypoint_write_set".to_string()),
)
}
PreprocessedTransaction::UserTransaction(txn) => {
let sender = txn.sender().to_string();
Expand All @@ -1008,12 +1055,16 @@ impl VMAdapter for AptosVM {
PreprocessedTransaction::WriteSet(txn) => {
let (vm_status, output) =
self.process_writeset_transaction(data_cache, txn, log_context)?;
(vm_status, output, Some("write_set".to_string()))
(
vm_status,
TransactionOutputWithDeltas::from(output),
Some("write_set".to_string()),
)
}
PreprocessedTransaction::InvalidSignature => {
let (vm_status, output) =
discard_error_vm_status(VMStatus::Error(StatusCode::INVALID_SIGNATURE));
(vm_status, output, None)
(vm_status, TransactionOutputWithDeltas::from(output), None)
}
PreprocessedTransaction::StateCheckpoint => {
let output = TransactionOutput::new(
Expand All @@ -1022,7 +1073,11 @@ impl VMAdapter for AptosVM {
0,
TransactionStatus::Keep(ExecutionStatus::Success),
);
(VMStatus::Executed, output, Some("state_checkpoint".into()))
(
VMStatus::Executed,
TransactionOutputWithDeltas::from(output),
Some("state_checkpoint".into()),
)
}
})
}
Expand Down Expand Up @@ -1110,13 +1165,15 @@ impl AptosSimulationVM {
if txn_status.is_discarded() {
discard_error_vm_status(err)
} else {
self.0.failed_transaction_cleanup_and_keep_vm_status(
err,
&mut gas_status,
&txn_data,
storage,
log_context,
)
let (vm_status, empty_output) =
self.0.failed_transaction_cleanup_and_keep_vm_status(
err,
&mut gas_status,
&txn_data,
storage,
log_context,
);
(vm_status, empty_output.into())
}
}
}
Expand Down
Loading

0 comments on commit 5d8e933

Please sign in to comment.