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

[BlockSTM] Per-block Gas Limit #7488

Merged
merged 65 commits into from
May 17, 2023
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
a2fdc21
Halt PE when module r/w intersects
danielxiangzl Dec 10, 2022
fde12ef
Refactoring
danielxiangzl Dec 11, 2022
eeac7ae
adding ExecutionHalted
danielxiangzl Dec 12, 2022
a7fd742
fix
danielxiangzl Dec 12, 2022
25db9d5
Merge branch 'main' into daniel-PE-module-fallback
danielxiangzl Dec 12, 2022
e14d371
Merge branch 'main' into daniel-PE-module-fallback
danielxiangzl Dec 17, 2022
b801351
rebase
danielxiangzl Dec 20, 2022
36c661d
address comments
danielxiangzl Dec 20, 2022
13b386c
Merge branch 'main' into daniel-PE-module-fallback
danielxiangzl Dec 20, 2022
2591610
address comments
danielxiangzl Dec 21, 2022
588dd4d
Merge branch 'main' into daniel-PE-module-fallback
danielxiangzl Dec 21, 2022
a223680
address comments
danielxiangzl Dec 22, 2022
f8c4f85
Merge branch 'main' into daniel-PE-module-fallback
danielxiangzl Dec 22, 2022
90ab072
nit
danielxiangzl Dec 22, 2022
84d8090
rebase
danielxiangzl Feb 2, 2023
ce8e383
Merge branch 'main' into daniel-PE-module-fallback
danielxiangzl Feb 2, 2023
4b56d43
update comments
danielxiangzl Feb 2, 2023
66f5a93
lint
danielxiangzl Feb 2, 2023
cea3c06
Merge branch 'daniel-PE-module-fallback' of github.com:aptos-labs/apt…
danielxiangzl Feb 2, 2023
517f818
Merge branch 'main' into daniel-PE-module-fallback
danielxiangzl Feb 3, 2023
8e2fee7
Merge branch 'main' into daniel-PE-module-fallback
danielxiangzl Mar 6, 2023
985d829
Merge branch 'main' into daniel-PE-module-fallback
danielxiangzl Mar 8, 2023
752bd1a
Merge branch 'main' into daniel-PE-module-fallback
danielxiangzl Mar 12, 2023
1fdf0a7
Merge branch 'main' into daniel-module-fallback
danielxiangzl Mar 29, 2023
13b9426
lint and tests
danielxiangzl Mar 29, 2023
84e7fdc
adding early halt for Abort and SkipRest
danielxiangzl Mar 30, 2023
585eb60
add per block gas
danielxiangzl Mar 30, 2023
3938ca1
sequential gas limit
danielxiangzl Mar 30, 2023
92c4b8b
resolving comments and adding metric counters
danielxiangzl Apr 3, 2023
9c27d1a
adding back StateCheckpoint
danielxiangzl Apr 4, 2023
f4f4d91
passing per-block gas limit to execution, but not state sync
danielxiangzl Apr 5, 2023
5e30733
gas limit on benchmarks
danielxiangzl Apr 5, 2023
fa5b942
refactor statecheckpoint, fix part of executor tests
danielxiangzl Apr 5, 2023
54a4425
append statecheckpoint when commit, fix more tests
danielxiangzl Apr 6, 2023
f604e90
nit
danielxiangzl Apr 6, 2023
c74d2df
resolve comments
danielxiangzl Apr 7, 2023
911cadf
adding tests for block gas limit
danielxiangzl Apr 10, 2023
57e9fb6
adding on chain config and fix tests
danielxiangzl Apr 11, 2023
9af8e45
test compatibility
danielxiangzl Apr 11, 2023
596c21b
Merge branch 'main' into daniel-per-block-gas
danielxiangzl Apr 11, 2023
439ce6a
fix tests, test block gas limit on forge
danielxiangzl Apr 12, 2023
c389a67
Merge branch 'daniel-per-block-gas' of github.com:aptos-labs/aptos-co…
danielxiangzl Apr 12, 2023
0361873
more counters
danielxiangzl Apr 12, 2023
b50b6ca
rebase
danielxiangzl Apr 18, 2023
413b4e3
Merge branch 'main' into daniel-per-block-gas
danielxiangzl Apr 18, 2023
adc0ae6
nit
danielxiangzl Apr 18, 2023
217356b
only flush logs of committed txns
danielxiangzl Apr 18, 2023
e3d39e7
Merge branch 'main' into daniel-per-block-gas
danielxiangzl Apr 21, 2023
88465a9
rebase
danielxiangzl Apr 24, 2023
84b6fff
fix commit race
danielxiangzl May 11, 2023
a09e522
resolve comments
danielxiangzl May 11, 2023
d092021
rebase
danielxiangzl May 11, 2023
eddab15
Merge branch 'main' into daniel-per-block-gas
danielxiangzl May 11, 2023
240ed5b
nit
danielxiangzl May 11, 2023
4c7b2df
Merge branch 'daniel-per-block-gas' of github.com:aptos-labs/aptos-co…
danielxiangzl May 11, 2023
5e5acf3
rebase
danielxiangzl May 15, 2023
d7ea33b
on-chain config default
danielxiangzl May 15, 2023
575c04f
Merge branch 'main' into daniel-per-block-gas
danielxiangzl May 15, 2023
bc4a4cd
nit
danielxiangzl May 16, 2023
3dbad83
Merge branch 'daniel-per-block-gas' of github.com:aptos-labs/aptos-co…
danielxiangzl May 16, 2023
0e34687
Merge branch 'main' into daniel-per-block-gas
danielxiangzl May 16, 2023
18b903a
rebase
danielxiangzl May 17, 2023
2451a1c
Merge branch 'main' into daniel-per-block-gas
danielxiangzl May 17, 2023
110cb60
rebase
danielxiangzl May 17, 2023
dfd15ce
Merge branch 'daniel-per-block-gas' of github.com:aptos-labs/aptos-co…
danielxiangzl May 17, 2023
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
5 changes: 5 additions & 0 deletions aptos-move/aptos-vm/src/block_executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ impl BlockExecutorTransactionOutput for AptosTransactionOutput {
TransactionStatus::Retry,
)))
}

/// Return the amount of gas consumed by the transaction.
fn gas_used(&self) -> u64 {
gelash marked this conversation as resolved.
Show resolved Hide resolved
self.0.txn_output().gas_used()
}
}

pub struct BlockAptosVM();
Expand Down
65 changes: 59 additions & 6 deletions aptos-move/block-executor/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
},
errors::*,
output_delta_resolver::OutputDeltaResolver,
scheduler::{Scheduler, SchedulerTask, Wave},
scheduler::{DependencyStatus, Scheduler, SchedulerTask, Wave},
task::{ExecutionStatus, ExecutorTask, Transaction, TransactionOutput},
txn_last_input_output::TxnLastInputOutput,
view::{LatestView, MVHashMapView},
Expand All @@ -34,6 +34,9 @@ use std::{
sync::atomic::{AtomicBool, Ordering},
};

// todo: add this number to config and think about the number.
const PER_BLOCK_GAS_LIMIT: u64 = 100000;

pub static RAYON_EXEC_POOL: Lazy<rayon::ThreadPool> = Lazy::new(|| {
rayon::ThreadPoolBuilder::new()
.num_threads(num_cpus::get())
Expand Down Expand Up @@ -141,7 +144,15 @@ where
versioned_cache.delete(&k, idx_to_execute);
}

last_input_output.record(idx_to_execute, speculative_view.take_reads(), result);
if last_input_output
.record(idx_to_execute, speculative_view.take_reads(), result)
.is_err()
{
// When there is module publishing r/w intersection, can early halt BlockSTM to
// fallback to sequential execution.
scheduler.halt();
return SchedulerTask::NoTask;
}
scheduler.finish_execution(idx_to_execute, incarnation, updates_outside)
}

Expand All @@ -160,7 +171,7 @@ where
let (idx_to_validate, incarnation) = version_to_validate;
let read_set = last_input_output
.read_set(idx_to_validate)
.expect("Prior read-set must be recorded");
.expect("[BlockSTM]: Prior read-set must be recorded");

let valid = read_set.iter().all(|r| {
match versioned_cache.fetch_data(r.path(), idx_to_validate) {
Expand Down Expand Up @@ -216,16 +227,48 @@ where

let _timer = WORK_WITH_TASK_SECONDS.start_timer();
let mut scheduler_task = SchedulerTask::NoTask;
let mut accumulated_gas = 0;
loop {
// Only one thread try_commit to avoid contention.
if committing {
// Keep committing txns until there is no more that can be committed now.
while let Some(txn_idx) = scheduler.try_commit() {
// Committed the last transaction, BlockSTM finishes execution.
if txn_idx as usize + 1 == block.len() {
// Committed the last transaction / everything.
scheduler_task = SchedulerTask::Done;
break;
}

// When there is a txn with Abort or SkipRest as the execution output, can early halt BlockSTM.
if let ExecutionStatus::Abort(_) | ExecutionStatus::SkipRest(_) =
danielxiangzl marked this conversation as resolved.
Show resolved Hide resolved
last_input_output.write_set(txn_idx).as_ref()
{
scheduler.halt();
break;
}

// Calculating the accumulated gas of the committed txns.
let txn_gas = match last_input_output.write_set(txn_idx).as_ref() {
ExecutionStatus::Success(output) => output.gas_used(),
_ => unreachable!(),
};
accumulated_gas += txn_gas;

// When the accumulated gas of the committed txns exceeds PER_BLOCK_GAS_LIMIT, early halt BlockSTM.
if accumulated_gas >= PER_BLOCK_GAS_LIMIT {
// Set the execution output status to be SkipRest, to skip the rest of the txns.
last_input_output.update_to_skip_rest(txn_idx);
scheduler.halt();
break;
}

// Remark: When early halting the BlockSTM, we have to make sure the current / new tasks
// will be properly handled by the threads. For instance, it is possible that the committing
// thread holds an execution task from the last iteration, and then early halts the BlockSTM
// due to a txn execution abort. In this case, we cannot reset the scheduler_task of the
// committing thread (to be Done), otherwise some other pending thread waiting for the execution
// will be pending on read forever (since the halt logic let the execution task to wake up such
// pending task).
}
}
scheduler_task = match scheduler_task {
Expand All @@ -248,7 +291,7 @@ where
SchedulerTask::ExecutionTask(_, Some(condvar)) => {
let (lock, cvar) = &*condvar;
// Mark dependency resolved.
*lock.lock() = true;
*lock.lock() = DependencyStatus::Resolved;
// Wake up the process waiting for dependency.
cvar.notify_one();

Expand Down Expand Up @@ -358,6 +401,7 @@ where
let mut data_map = BTreeMap::new();

let mut ret = Vec::with_capacity(num_txns);
let mut accumulated_gas = 0;
for (idx, txn) in signature_verified_block.iter().enumerate() {
let res = executor.execute_transaction(
&LatestView::<T, S>::new_btree_view(base_view, &data_map, idx as TxnIndex),
Expand All @@ -367,7 +411,7 @@ where
);

let must_skip = matches!(res, ExecutionStatus::SkipRest(_));

let txn_gas;
match res {
ExecutionStatus::Success(output) | ExecutionStatus::SkipRest(output) => {
assert_eq!(
Expand All @@ -379,6 +423,7 @@ where
for (ap, write_op) in output.get_writes().into_iter() {
data_map.insert(ap, write_op);
}
txn_gas = output.gas_used();
danielxiangzl marked this conversation as resolved.
Show resolved Hide resolved
ret.push(output);
},
ExecutionStatus::Abort(err) => {
Expand All @@ -390,6 +435,14 @@ where
if must_skip {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could merge this check with must_skip || accumulated_gas >= PER_BLOCK_GAS_LIMIT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually need to separate them to distinguish reconfiguration from exceeding the per-block gas limit.

break;
}

// Calculating the accumulated gas of the committed txns.
accumulated_gas += txn_gas;

// When the accumulated gas of the committed txns exceeds PER_BLOCK_GAS_LIMIT, halt sequential execution.
if accumulated_gas >= PER_BLOCK_GAS_LIMIT {
break;
}
}

ret.resize_with(num_txns, E::Output::skip_output);
Expand Down
9 changes: 8 additions & 1 deletion aptos-move/block-executor/src/proptest_types/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,10 @@ where
let mut reads_result = vec![];
for k in reads[read_idx].iter() {
// TODO: later test errors as well? (by fixing state_view behavior).
reads_result.push(view.get_state_value_bytes(k).unwrap());
match view.get_state_value_bytes(k) {
Ok(v) => reads_result.push(v),
Err(_) => reads_result.push(None),
}
}
ExecutionStatus::Success(Output(
writes_and_deltas[write_idx].0.clone(),
Expand Down Expand Up @@ -484,6 +487,10 @@ where
fn skip_output() -> Self {
Self(vec![], vec![], vec![])
}

fn gas_used(&self) -> u64 {
0
}
}

///////////////////////////////////////////////////////////////////////////
Expand Down
Loading