diff --git a/aptos-move/aptos-vm/src/block_executor/mod.rs b/aptos-move/aptos-vm/src/block_executor/mod.rs
index de16c676676b69..25d5d97d7d5234 100644
--- a/aptos-move/aptos-vm/src/block_executor/mod.rs
+++ b/aptos-move/aptos-vm/src/block_executor/mod.rs
@@ -127,7 +127,7 @@ pub struct AptosTransactionOutput {
}
impl AptosTransactionOutput {
- pub(crate) fn new(output: VMOutput) -> Self {
+ pub fn new(output: VMOutput) -> Self {
Self {
vm_output: Mutex::new(Some(output)),
committed_output: OnceCell::new(),
@@ -138,7 +138,7 @@ impl AptosTransactionOutput {
self.committed_output.get().unwrap()
}
- fn take_output(mut self) -> TransactionOutput {
+ pub fn take_output(mut self) -> TransactionOutput {
match self.committed_output.take() {
Some(output) => output,
// TODO: revisit whether we should always get it via committed, or o.w. create a
diff --git a/aptos-move/framework/aptos-framework/doc/fungible_asset.md b/aptos-move/framework/aptos-framework/doc/fungible_asset.md
index a7fd696d9d8fe8..17ee3056667dad 100644
--- a/aptos-move/framework/aptos-framework/doc/fungible_asset.md
+++ b/aptos-move/framework/aptos-framework/doc/fungible_asset.md
@@ -3468,25 +3468,23 @@ Decrease the supply of a fungible asset by burning.
};
let metadata_address = object::object_address(metadata);
- if (amount == 0) {
- if (exists<ConcurrentSupply>(metadata_address)) {
- let supply = borrow_global_mut<ConcurrentSupply>(metadata_address);
+ if (exists<ConcurrentSupply>(metadata_address)) {
+ let supply = borrow_global_mut<ConcurrentSupply>(metadata_address);
- assert!(
- aggregator_v2::try_sub(&mut supply.current, (amount as u128)),
- error::out_of_range(ESUPPLY_UNDERFLOW)
- );
- } else if (exists<Supply>(metadata_address)) {
- assert!(exists<Supply>(metadata_address), error::not_found(ESUPPLY_NOT_FOUND));
- let supply = borrow_global_mut<Supply>(metadata_address);
- assert!(
- supply.current >= (amount as u128),
- error::invalid_state(ESUPPLY_UNDERFLOW)
- );
- supply.current = supply.current - (amount as u128);
- } else {
- assert!(false, error::not_found(ESUPPLY_NOT_FOUND));
- }
+ assert!(
+ aggregator_v2::try_sub(&mut supply.current, (amount as u128)),
+ error::out_of_range(ESUPPLY_UNDERFLOW)
+ );
+ } else if (exists<Supply>(metadata_address)) {
+ assert!(exists<Supply>(metadata_address), error::not_found(ESUPPLY_NOT_FOUND));
+ let supply = borrow_global_mut<Supply>(metadata_address);
+ assert!(
+ supply.current >= (amount as u128),
+ error::invalid_state(ESUPPLY_UNDERFLOW)
+ );
+ supply.current = supply.current - (amount as u128);
+ } else {
+ assert!(false, error::not_found(ESUPPLY_NOT_FOUND));
}
}
diff --git a/execution/executor-benchmark/src/db_access.rs b/execution/executor-benchmark/src/db_access.rs
index 5a475bcfc0509c..ec645db4fab900 100644
--- a/execution/executor-benchmark/src/db_access.rs
+++ b/execution/executor-benchmark/src/db_access.rs
@@ -6,13 +6,14 @@ use aptos_types::{
account_address::AccountAddress,
account_config::{
AccountResource, CoinInfoResource, CoinStoreResource, ConcurrentSupplyResource,
- FungibleStoreResource, ObjectCoreResource, ObjectGroupResource,
+ FungibleStoreResource, ObjectCoreResource, ObjectGroupResource, TypeInfoResource,
},
event::{EventHandle, EventKey},
state_store::{state_key::StateKey, StateView},
write_set::TOTAL_SUPPLY_STATE_KEY,
AptosCoinType, CoinType,
};
+use itertools::Itertools;
use move_core_types::{
identifier::Identifier,
language_storage::{StructTag, TypeTag},
@@ -168,4 +169,28 @@ impl DbAccessUtil {
pub fn new_object_core(address: AccountAddress, owner: AccountAddress) -> ObjectCoreResource {
ObjectCoreResource::new(owner, false, EventHandle::new(EventKey::new(1, address), 0))
}
+
+ pub fn new_type_info_resource() -> anyhow::Result {
+ let struct_tag = T::struct_tag();
+ Ok(TypeInfoResource {
+ account_address: struct_tag.address,
+ module_name: bcs::to_bytes(&struct_tag.module.to_string())?,
+ struct_name: bcs::to_bytes(
+ &if struct_tag.type_args.is_empty() {
+ struct_tag.name.to_string()
+ } else {
+ format!(
+ "{}<{}>",
+ struct_tag.name,
+ struct_tag
+ .type_args
+ .iter()
+ .map(|v| v.to_string())
+ .join(", ")
+ )
+ .to_string()
+ },
+ )?,
+ })
+ }
}
diff --git a/execution/executor-benchmark/src/lib.rs b/execution/executor-benchmark/src/lib.rs
index 8a6285424c38ee..c4892381ba4780 100644
--- a/execution/executor-benchmark/src/lib.rs
+++ b/execution/executor-benchmark/src/lib.rs
@@ -907,7 +907,7 @@ mod tests {
};
let other_db = init_db(&config);
- let other_executor = BlockExecutor::::new(other_db.clone());
+ let other_executor = BlockExecutor::::new(other_db.clone());
let parent_block_id = other_executor.committed_block_id();
let block_id = HashValue::random();
diff --git a/execution/executor-benchmark/src/native/native_vm.rs b/execution/executor-benchmark/src/native/native_vm.rs
index 7264af09085099..7d032db683a5c9 100644
--- a/execution/executor-benchmark/src/native/native_vm.rs
+++ b/execution/executor-benchmark/src/native/native_vm.rs
@@ -28,7 +28,7 @@ use aptos_types::{
account_config::{
primary_apt_store, AccountResource, CoinDeposit, CoinInfoResource, CoinRegister,
CoinStoreResource, CoinWithdraw, ConcurrentSupplyResource, DepositFAEvent,
- FungibleStoreResource, TypeInfoResource, WithdrawFAEvent,
+ FungibleStoreResource, WithdrawFAEvent,
},
block_executor::config::{
BlockExecutorConfig, BlockExecutorConfigFromOnchain, BlockExecutorLocalConfig,
@@ -825,7 +825,7 @@ impl NativeVMExecutorTask {
events.push((
CoinRegister {
account: AccountAddress::ONE,
- type_info: TypeInfoResource::new::()
+ type_info: DbAccessUtil::new_type_info_resource::()
.map_err(hide_error)?,
}
.create_event_v2(),
diff --git a/execution/executor-benchmark/src/native/parallel_uncoordinated_block_executor.rs b/execution/executor-benchmark/src/native/parallel_uncoordinated_block_executor.rs
index dc8198844c5db1..585539a51d36f0 100644
--- a/execution/executor-benchmark/src/native/parallel_uncoordinated_block_executor.rs
+++ b/execution/executor-benchmark/src/native/parallel_uncoordinated_block_executor.rs
@@ -13,7 +13,7 @@ use aptos_types::{
account_config::{
primary_apt_store, AccountResource, CoinDeposit, CoinInfoResource, CoinRegister,
CoinStoreResource, CoinWithdraw, ConcurrentSupplyResource, DepositFAEvent,
- FungibleStoreResource, TypeInfoResource, WithdrawFAEvent,
+ FungibleStoreResource, WithdrawFAEvent,
},
block_executor::config::BlockExecutorConfigFromOnchain,
contract_event::ContractEvent,
@@ -30,14 +30,12 @@ use aptos_types::{
AptosCoinType,
};
use aptos_vm::VMBlockExecutor;
-use dashmap::{mapref::one::RefMut, DashMap};
+use dashmap::{mapref::one::{Ref, RefMut}, DashMap};
use once_cell::sync::OnceCell;
use rayon::iter::{IntoParallelIterator, IntoParallelRefIterator, ParallelIterator};
+use thread_local::ThreadLocal;
use std::{
- collections::{BTreeMap, HashMap},
- hash::RandomState,
- sync::atomic::{AtomicU64, Ordering},
- u64,
+ cell::Cell, collections::{BTreeMap, HashMap}, hash::RandomState, sync::atomic::{AtomicU64, Ordering}, u64
};
/// Executes transactions fully, and produces TransactionOutput (with final WriteSet)
@@ -697,7 +695,7 @@ impl CommonNativeRawTransactionExecutor for NativeRawTransactionExecutor {
output.events.push(
CoinRegister {
account: AccountAddress::ONE,
- type_info: TypeInfoResource::new::()?,
+ type_info: DbAccessUtil::new_type_info_resource::()?,
}
.create_event_v2(),
);
@@ -789,8 +787,15 @@ fn compute_deltas_for_batch(
deltas
}
+const USE_THREAD_LOCAL_SUPPLY: bool = true;
+
struct CoinSupply {
- total_supply: u128,
+ pub total_supply: u128,
+}
+
+struct SupplyWithDecrement {
+ pub base: u128,
+ pub decrement: ThreadLocal>,
}
enum CachedResource {
@@ -800,6 +805,7 @@ enum CachedResource {
AptCoinStore(CoinStoreResource),
AptCoinInfo(CoinInfoResource),
AptCoinSupply(CoinSupply),
+ SupplyDecrement(SupplyWithDecrement),
}
pub struct NativeValueCacheRawTransactionExecutor {
@@ -876,37 +882,37 @@ impl CommonNativeRawTransactionExecutor for NativeValueCacheRawTransactionExecut
state_view: &(impl StateView + Sync),
_output: &mut IncrementalOutput,
) -> Result<()> {
- let concurrent_supply_rg_tag = &self.db_util.common.concurrent_supply;
- let cache_key = StateKey::resource(&AccountAddress::TEN, concurrent_supply_rg_tag).unwrap();
-
- let mut entry = self.cache.entry(cache_key).or_insert_with(|| {
- let apt_metadata_object_state_key = self
- .db_util
- .new_state_key_object_resource_group(&AccountAddress::TEN);
-
- let mut apt_metadata_object =
- DbAccessUtil::get_resource_group(&apt_metadata_object_state_key, state_view)
- .unwrap()
- .unwrap();
-
- CachedResource::FungibleSupply(
- bcs::from_bytes::(
- &apt_metadata_object
- .remove(concurrent_supply_rg_tag)
- .unwrap(),
- )
- .unwrap(),
- )
- });
-
- match entry.value_mut() {
- CachedResource::FungibleSupply(fungible_supply) => {
- fungible_supply
- .current
- .set(fungible_supply.current.get() - gas as u128);
- },
- _ => panic!("wrong type"),
- };
+ let cache_key = StateKey::resource(&AccountAddress::TEN, &self.db_util.common.concurrent_supply).unwrap();
+
+ if USE_THREAD_LOCAL_SUPPLY {
+ let entry = self.cache_get_or_init(&cache_key, |_key| {
+ let concurrent_supply = self.fetch_concurrent_supply(state_view);
+ CachedResource::SupplyDecrement(SupplyWithDecrement {
+ base: *concurrent_supply.current.get(),
+ decrement: ThreadLocal::new(),
+ })
+ });
+ match entry.value() {
+ CachedResource::SupplyDecrement(SupplyWithDecrement { decrement, .. }) => {
+ let decrement_cell = decrement.get_or_default();
+ decrement_cell.set(decrement_cell.get() + gas as u128);
+ },
+ _ => panic!("wrong type"),
+ }
+ } else {
+ let mut entry = self.cache_get_mut_or_init(&cache_key, |_key| {
+ let concurrent_supply = self.fetch_concurrent_supply(state_view);
+ CachedResource::FungibleSupply(concurrent_supply)
+ });
+ match entry.value_mut() {
+ CachedResource::FungibleSupply(fungible_supply) => {
+ fungible_supply
+ .current
+ .set(fungible_supply.current.get() - gas as u128);
+ },
+ _ => panic!("wrong type"),
+ };
+ }
Ok(())
}
@@ -934,20 +940,40 @@ impl CommonNativeRawTransactionExecutor for NativeValueCacheRawTransactionExecut
total_supply_state_key
});
- let mut total_supply_entry = self.cache_get_mut_or_init(total_supply_state_key, |key| {
- CachedResource::AptCoinSupply(CoinSupply {
- total_supply: DbAccessUtil::get_value::(key, state_view)
- .unwrap()
- .unwrap(),
- })
- });
+ if USE_THREAD_LOCAL_SUPPLY {
+ let total_supply_entry = self.cache_get_or_init(total_supply_state_key, |key| {
+ CachedResource::SupplyDecrement(SupplyWithDecrement {
+ base: DbAccessUtil::get_value::(key, state_view)
+ .unwrap()
+ .unwrap(),
+ decrement: ThreadLocal::new()
+ })
+ });
+ match total_supply_entry.value() {
+ CachedResource::SupplyDecrement(SupplyWithDecrement { decrement, .. }) => {
+ let decrement_cell = decrement.get_or_default();
+ decrement_cell.set(decrement_cell.get() + gas as u128);
+ },
+ _ => panic!("wrong type"),
+ }
+ } else {
+ let mut total_supply_entry = self.cache_get_mut_or_init(total_supply_state_key, |key| {
+ CachedResource::AptCoinSupply(CoinSupply {
+ total_supply: DbAccessUtil::get_value::(key, state_view)
+ .unwrap()
+ .unwrap(),
+ })
+ });
+
+ match total_supply_entry.value_mut() {
+ CachedResource::AptCoinSupply(coin_supply) => {
+ coin_supply.total_supply -= gas as u128;
+ },
+ _ => panic!("wrong type"),
+ };
+ }
+
- match total_supply_entry.value_mut() {
- CachedResource::AptCoinSupply(coin_supply) => {
- coin_supply.total_supply -= gas as u128;
- },
- _ => panic!("wrong type"),
- };
Ok(())
}
@@ -1003,6 +1029,19 @@ impl CommonNativeRawTransactionExecutor for NativeValueCacheRawTransactionExecut
}
impl NativeValueCacheRawTransactionExecutor {
+ fn cache_get_or_init<'a>(
+ &'a self,
+ key: &StateKey,
+ init_value: impl FnOnce(&StateKey) -> CachedResource,
+ ) -> Ref<'a, StateKey, CachedResource, RandomState> {
+ // Data in cache is going to be the hot path, so short-circuit here to avoid cloning the key.
+ if let Some(ref_mut) = self.cache.get(key) {
+ return ref_mut;
+ }
+
+ self.cache.entry(key.clone()).or_insert(init_value(key)).downgrade()
+ }
+
fn cache_get_mut_or_init<'a>(
&'a self,
key: &StateKey,
@@ -1016,6 +1055,27 @@ impl NativeValueCacheRawTransactionExecutor {
self.cache.entry(key.clone()).or_insert(init_value(key))
}
+ fn fetch_concurrent_supply(&self, state_view: &(impl StateView + Sync)) -> ConcurrentSupplyResource {
+ let concurrent_supply_rg_tag = &self.db_util.common.concurrent_supply;
+
+ let apt_metadata_object_state_key = self
+ .db_util
+ .new_state_key_object_resource_group(&AccountAddress::TEN);
+
+ let mut apt_metadata_object =
+ DbAccessUtil::get_resource_group(&apt_metadata_object_state_key, state_view)
+ .unwrap()
+ .unwrap();
+
+ let concurrent_supply = bcs::from_bytes::(
+ &apt_metadata_object
+ .remove(concurrent_supply_rg_tag)
+ .unwrap(),
+ )
+ .unwrap();
+ concurrent_supply
+ }
+
fn update_fa_balance(
&self,
account: AccountAddress,
@@ -1094,6 +1154,7 @@ impl NativeValueCacheRawTransactionExecutor {
pub struct NativeNoStorageRawTransactionExecutor {
seq_nums: DashMap,
balances: DashMap,
+ total_supply_decrement: ThreadLocal>,
total_supply: AtomicU64,
}
@@ -1186,6 +1247,7 @@ impl RawTransactionExecutor for NativeNoStorageRawTransactionExecutor {
Self {
seq_nums: DashMap::new(),
balances: DashMap::new(),
+ total_supply_decrement: ThreadLocal::new(),
total_supply: AtomicU64::new(u64::MAX),
}
}
@@ -1200,7 +1262,13 @@ impl RawTransactionExecutor for NativeNoStorageRawTransactionExecutor {
) -> Result {
let gas_units = 4;
let gas = gas_units * 100;
- self.total_supply.fetch_sub(gas, Ordering::Relaxed);
+
+ if USE_THREAD_LOCAL_SUPPLY {
+ let decrement_cell = self.total_supply_decrement.get_or_default();
+ decrement_cell.set(decrement_cell.get() + gas as u128);
+ } else {
+ self.total_supply.fetch_sub(gas, Ordering::Relaxed);
+ }
let output = IncrementalOutput::new();
let (sender, sequence_number) = match txn {
@@ -1244,7 +1312,6 @@ impl RawTransactionExecutor for NativeNoStorageRawTransactionExecutor {
amounts,
..
} => {
-
let mut deltas = compute_deltas_for_batch(recipients, amounts, sender);
let amount_from_sender = -deltas.remove(&sender).unwrap_or(0);
@@ -1266,7 +1333,6 @@ impl RawTransactionExecutor for NativeNoStorageRawTransactionExecutor {
};
self.seq_nums.insert(sender, sequence_number);
- account.sequence_number = sequence_number + 1;
output.into_success_output(gas)
}
}
diff --git a/types/src/lib.rs b/types/src/lib.rs
index 95d59f1232060c..9081b6c0f0a4d0 100644
--- a/types/src/lib.rs
+++ b/types/src/lib.rs
@@ -25,7 +25,6 @@ pub mod jwks;
pub mod ledger_info;
pub mod mempool_status;
pub mod move_any;
-pub mod move_event_v2;
pub mod move_fixed_point;
pub mod move_utils;
pub mod network_address;
diff --git a/types/src/move_event_v2.rs b/types/src/move_event_v2.rs
deleted file mode 100644
index bd6b2c2cd6de22..00000000000000
--- a/types/src/move_event_v2.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright © Aptos Foundation
-// SPDX-License-Identifier: Apache-2.0
-
-use crate::contract_event::ContractEvent;
-use move_core_types::{language_storage::TypeTag, move_resource::MoveStructType};
-use serde::Serialize;
-
-pub trait MoveEventV2: MoveStructType + Serialize {
- fn create_event_v2(&self) -> ContractEvent {
- ContractEvent::new_v2(
- TypeTag::Struct(Box::new(Self::struct_tag())),
- bcs::to_bytes(self).unwrap(),
- )
- }
-}
| |