Skip to content

Commit

Permalink
Parallelizing Signature Verification in the Executor
Browse files Browse the repository at this point in the history
Signature Verification takes a significant amount of time (about 50% more time) and thus parallelizing it is expected to improve the performance of the code significantly.
  • Loading branch information
Gauri-Agarwal authored and calibra-opensource committed Jul 2, 2019
1 parent 3df5d7b commit ca31ab0
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 23 deletions.
1 change: 1 addition & 0 deletions language/vm/vm_runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ edition = "2018"
rental = "0.5.3"
tiny-keccak = "1.4.2"
proptest = "0.9"
rayon = "1.1"

bytecode_verifier = { path = "../../bytecode_verifier" }
canonical_serialization = { path = "../../../common/canonical_serialization" }
Expand Down
37 changes: 26 additions & 11 deletions language/vm/vm_runtime/src/block_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ use crate::{
};
use config::config::VMPublishingOption;
use logger::prelude::*;
use rayon::prelude::*;
use state_view::StateView;
use types::{
transaction::{SignedTransaction, TransactionOutput, TransactionStatus},
transaction::{
SignatureCheckedTransaction, SignedTransaction, TransactionOutput, TransactionStatus,
},
vm_error::{ExecutionStatus, VMStatus, VMValidationStatus},
write_set::WriteSet,
};
Expand Down Expand Up @@ -57,15 +60,27 @@ pub fn execute_block<'alloc>(
let module_cache = BlockModuleCache::new(code_cache, ModuleFetcherImpl::new(data_view));
let mut data_cache = BlockDataCache::new(data_view);
let mut result = vec![];
for txn in txn_block.into_iter() {
let output = transaction_flow(
txn,
&module_cache,
script_cache,
&data_cache,
mode,
publishing_option,
);

let signature_verified_block: Vec<Result<SignatureCheckedTransaction, VMStatus>> = txn_block
.into_par_iter()
.map(|txn| match txn.check_signature() {
Ok(t) => Ok(t),
Err(_) => Err(VMStatus::Validation(VMValidationStatus::InvalidSignature)),
})
.collect();

for transaction in signature_verified_block {
let output = match transaction {
Ok(t) => transaction_flow(
t,
&module_cache,
script_cache,
&data_cache,
mode,
publishing_option,
),
Err(vm_status) => ExecutedTransaction::discard_error_output(vm_status),
};
data_cache.push_write_set(&output.write_set());
result.push(output);
}
Expand All @@ -87,7 +102,7 @@ pub fn execute_block<'alloc>(
/// include those newly published modules. This function will also update the `script_cache` to
/// cache this `txn`
fn transaction_flow<'alloc, P>(
txn: SignedTransaction,
txn: SignatureCheckedTransaction,
module_cache: P,
script_cache: &ScriptCache<'alloc>,
data_cache: &BlockDataCache<'_>,
Expand Down
6 changes: 3 additions & 3 deletions language/vm/vm_runtime/src/process_txn/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
};
use config::config::VMPublishingOption;
use std::marker::PhantomData;
use types::transaction::SignedTransaction;
use types::transaction::SignatureCheckedTransaction;
use vm_cache_map::Arena;

pub mod execute;
Expand All @@ -21,7 +21,7 @@ where
'alloc: 'txn,
P: ModuleCache<'alloc>,
{
txn: SignedTransaction,
txn: SignatureCheckedTransaction,
module_cache: P,
data_cache: &'txn RemoteCache,
allocator: &'txn Arena<LoadedModule>,
Expand All @@ -35,7 +35,7 @@ where
{
/// Creates a new instance of `ProcessTransaction`.
pub fn new(
txn: SignedTransaction,
txn: SignatureCheckedTransaction,
module_cache: P,
data_cache: &'txn RemoteCache,
allocator: &'txn Arena<LoadedModule>,
Expand Down
7 changes: 0 additions & 7 deletions language/vm/vm_runtime/src/process_txn/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,6 @@ where
allocator,
..
} = process_txn;
let txn = match txn.check_signature() {
Ok(txn) => txn,
Err(_) => {
error!("[VM] Invalid signature");
return Err(VMStatus::Validation(VMValidationStatus::InvalidSignature));
}
};

let txn_state = match txn.payload() {
TransactionPayload::Program(program) => {
Expand Down
10 changes: 8 additions & 2 deletions language/vm/vm_runtime/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use logger::prelude::*;
use state_view::StateView;
use types::{
transaction::{SignedTransaction, TransactionOutput},
vm_error::VMStatus,
vm_error::{VMStatus, VMValidationStatus},
};
use vm_cache_map::Arena;

Expand Down Expand Up @@ -73,7 +73,13 @@ impl<'alloc> VMRuntime<'alloc> {
let data_cache = BlockDataCache::new(data_view);

let arena = Arena::new();
let process_txn = ProcessTransaction::new(txn, module_cache, &data_cache, &arena);
let signature_verified_txn = match txn.check_signature() {
Ok(t) => t,
Err(_) => return Some(VMStatus::Validation(VMValidationStatus::InvalidSignature)),
};

let process_txn =
ProcessTransaction::new(signature_verified_txn, module_cache, &data_cache, &arena);
let mode = if data_view.is_genesis() {
ValidationMode::Genesis
} else {
Expand Down

0 comments on commit ca31ab0

Please sign in to comment.