Skip to content

Commit

Permalink
impl native functions for TxContext
Browse files Browse the repository at this point in the history
  • Loading branch information
dariorussi committed Feb 19, 2025
1 parent ac273c3 commit 9953050
Show file tree
Hide file tree
Showing 11 changed files with 698 additions and 55 deletions.
26 changes: 19 additions & 7 deletions crates/sui-move/src/unit_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@ use move_package::BuildConfig;
use move_unit_test::{extensions::set_extension_hook, UnitTestingConfig};
use move_vm_runtime::native_extensions::NativeContextExtensions;
use once_cell::sync::Lazy;
use std::{cell::RefCell, collections::BTreeMap, path::Path, sync::Arc};
use std::{cell::RefCell, collections::BTreeMap, path::Path, rc::Rc, sync::Arc};
use sui_move_build::decorate_warnings;
use sui_move_natives::test_scenario::InMemoryTestStore;
use sui_move_natives::{object_runtime::ObjectRuntime, NativesCostTable};
use sui_move_natives::{object_runtime::TransactionContext, test_scenario::InMemoryTestStore};
use sui_protocol_config::ProtocolConfig;
use sui_types::{
gas_model::tables::initial_cost_schedule_for_unit_tests, in_memory_storage::InMemoryStorage,
base_types::{SuiAddress, TxContext},
digests::TransactionDigest,
gas_model::tables::initial_cost_schedule_for_unit_tests,
in_memory_storage::InMemoryStorage,
metrics::LimitsMetrics,
};

Expand Down Expand Up @@ -60,9 +63,11 @@ impl Test {
// Create a separate test store per-thread.
thread_local! {
static TEST_STORE_INNER: RefCell<InMemoryStorage> = RefCell::new(InMemoryStorage::default());
// static TEST_TX_CONTEXT_INNER: RefCell<TransactionContext> = RefCell::new(TransactionContext);
}

static TEST_STORE: Lazy<InMemoryTestStore> = Lazy::new(|| InMemoryTestStore(&TEST_STORE_INNER));
// static TEST_TX_CONTEXT: Lazy<TransactionContext> = Lazy::new(|| InMemoryTestStore(&TEST_TX_CONTEXT_INNER));

static SET_EXTENSION_HOOK: Lazy<()> =
Lazy::new(|| set_extension_hook(Box::new(new_testing_object_and_natives_cost_runtime)));
Expand Down Expand Up @@ -113,6 +118,7 @@ fn new_testing_object_and_natives_cost_runtime(ext: &mut NativeContextExtensions
let registry = prometheus::Registry::new();
let metrics = Arc::new(LimitsMetrics::new(&registry));
let store = Lazy::force(&TEST_STORE);
let protocol_config = ProtocolConfig::get_for_max_version_UNSAFE();

ext.add(ObjectRuntime::new(
store,
Expand All @@ -122,9 +128,15 @@ fn new_testing_object_and_natives_cost_runtime(ext: &mut NativeContextExtensions
metrics,
0, // epoch id
));
ext.add(NativesCostTable::from_protocol_config(
&ProtocolConfig::get_for_max_version_UNSAFE(),
));

ext.add(NativesCostTable::from_protocol_config(&protocol_config));
let tx_context = TxContext::new_from_components(
Box::leak(Box::new(SuiAddress::ZERO)),
Box::leak(Box::new(TransactionDigest::default())),
&0,
0,
0,
None,
);
ext.add(TransactionContext::new(Rc::new(RefCell::new(tx_context))));
ext.add(store);
}
49 changes: 49 additions & 0 deletions crates/sui-protocol-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ const MAX_PROTOCOL_VERSION: u64 = 74;
// Enable all gas costs for load_nitro_attestation.
// Enable zstd compression for consensus tonic network in mainnet.
// Enable the new commit rule for devnet.
// Make `TxContext` Move API native

#[derive(Copy, Clone, Debug, Hash, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub struct ProtocolVersion(u64);
Expand Down Expand Up @@ -622,6 +623,10 @@ struct FeatureFlags {
// If true, enable zstd compression for consensus tonic network.
#[serde(skip_serializing_if = "is_false")]
consensus_zstd_compression: bool,

// If true, enable `TxContext` Move API to go native.
#[serde(skip_serializing_if = "is_false")]
move_native_context: bool,
}

fn is_false(b: &bool) -> bool {
Expand Down Expand Up @@ -1087,6 +1092,16 @@ pub struct ProtocolConfig {
// TxContext
// Cost params for the Move native function `transfer_impl<T: key>(obj: T, recipient: address)`
tx_context_derive_id_cost_base: Option<u64>,
tx_context_sender_cost_base: Option<u64>,
tx_context_epoch_cost_base: Option<u64>,
tx_context_epoch_timestamp_ms_cost_base: Option<u64>,
tx_context_digest_cost_base: Option<u64>,
tx_context_sponsor_cost_base: Option<u64>,
tx_context_ids_created_cost_base: Option<u64>,
tx_context_replace_cost_base: Option<u64>,
tx_context_inc_epoch_timestamp_cost_base: Option<u64>,
tx_context_inc_epoch_cost_base: Option<u64>,
tx_context_fresh_id_cost_base: Option<u64>,

// Types
// Cost params for the Move native function `is_one_time_witness<T: drop>(_: &T): bool`
Expand Down Expand Up @@ -1802,9 +1817,14 @@ impl ProtocolConfig {
pub fn consensus_zstd_compression(&self) -> bool {
self.feature_flags.consensus_zstd_compression
}

pub fn enable_nitro_attestation(&self) -> bool {
self.feature_flags.enable_nitro_attestation
}

pub fn move_native_context(&self) -> bool {
self.feature_flags.move_native_context
}
}

#[cfg(not(msim))]
Expand Down Expand Up @@ -2097,6 +2117,16 @@ impl ProtocolConfig {
// `tx_context` module
// Cost params for the Move native function `transfer_impl<T: key>(obj: T, recipient: address)`
tx_context_derive_id_cost_base: Some(52),
tx_context_sender_cost_base: None,
tx_context_epoch_cost_base: None,
tx_context_epoch_timestamp_ms_cost_base: None,
tx_context_digest_cost_base: None,
tx_context_sponsor_cost_base: None,
tx_context_ids_created_cost_base: None,
tx_context_replace_cost_base: None,
tx_context_inc_epoch_timestamp_cost_base: None,
tx_context_inc_epoch_cost_base: None,
tx_context_fresh_id_cost_base: None,

// `types` module
// Cost params for the Move native function `is_one_time_witness<T: drop>(_: &T): bool`
Expand Down Expand Up @@ -3245,6 +3275,25 @@ impl ProtocolConfig {
if chain != Chain::Mainnet && chain != Chain::Testnet {
cfg.feature_flags.consensus_linearize_subdag_v2 = true;
}

if chain != Chain::Mainnet {
// Assuming a round rate of max 15/sec, then using a gc depth of 60 allow blocks within a window of ~4 seconds
// to be included before be considered garbage collected.
cfg.consensus_gc_depth = Some(60);
}

cfg.feature_flags.move_native_context = false;

cfg.tx_context_sender_cost_base = Some(30);
cfg.tx_context_epoch_cost_base = Some(30);
cfg.tx_context_epoch_timestamp_ms_cost_base = Some(30);
cfg.tx_context_digest_cost_base = Some(30);
cfg.tx_context_sponsor_cost_base = Some(30);
cfg.tx_context_ids_created_cost_base = Some(30);
cfg.tx_context_replace_cost_base = Some(30);
cfg.tx_context_inc_epoch_timestamp_cost_base = Some(30);
cfg.tx_context_inc_epoch_cost_base = Some(30);
cfg.tx_context_fresh_id_cost_base = Some(30);
}
// Use this template when making changes:
//
Expand Down
52 changes: 45 additions & 7 deletions crates/sui-types/src/base_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1099,21 +1099,33 @@ impl TxContext {
self.epoch
}

/// Derive a globally unique object ID by hashing self.digest | self.ids_created
pub fn fresh_id(&mut self) -> ObjectID {
let id = ObjectID::derive_id(self.digest(), self.ids_created);
pub fn sender(&self) -> SuiAddress {
SuiAddress::from(ObjectID(self.sender))
}

self.ids_created += 1;
id
pub fn epoch_timestamp_ms(&self) -> u64 {
self.epoch_timestamp_ms
}

/// Return the transaction digest, to include in new objects
pub fn digest(&self) -> TransactionDigest {
TransactionDigest::new(self.digest.clone().try_into().unwrap())
}

pub fn sender(&self) -> SuiAddress {
SuiAddress::from(ObjectID(self.sender))
pub fn sponsor(&self) -> Option<SuiAddress> {
self.sponsor.map(SuiAddress::from)
}

pub fn ids_created(&self) -> u64 {
self.ids_created
}

/// Derive a globally unique object ID by hashing self.digest | self.ids_created
pub fn fresh_id(&mut self) -> ObjectID {
let id = ObjectID::derive_id(self.digest(), self.ids_created);

self.ids_created += 1;
id
}

pub fn to_bcs_legacy_context(&self) -> Vec<u8> {
Expand Down Expand Up @@ -1142,6 +1154,32 @@ impl TxContext {
self.ids_created = other.ids_created;
Ok(())
}

//
// Move test only API
//
pub fn inc_epoch(&mut self) {
self.epoch += 1;
}

pub fn inc_epoch_timestamp(&mut self, delta_ms: u64) {
self.epoch_timestamp_ms += delta_ms;
}

pub fn replace(
&mut self,
sender: AccountAddress,
tx_hash: Vec<u8>,
epoch: u64,
epoch_timestamp_ms: u64,
ids_created: u64,
) {
self.sender = sender;
self.digest = tx_hash;
self.epoch = epoch;
self.epoch_timestamp_ms = epoch_timestamp_ms;
self.ids_created = ids_created;
}
}

// TODO: rename to version
Expand Down
8 changes: 6 additions & 2 deletions sui-execution/latest/sui-adapter/src/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ pub use checked::*;
mod checked {
#[cfg(feature = "tracing")]
use move_vm_config::runtime::VMProfilerConfig;
use std::cell::RefCell;
use std::path::PathBuf;
use std::rc::Rc;
use std::{collections::BTreeMap, sync::Arc};

use anyhow::Result;
Expand All @@ -22,7 +24,7 @@ mod checked {
move_vm::MoveVM, native_extensions::NativeContextExtensions,
native_functions::NativeFunctionTable,
};
use sui_move_natives::object_runtime;
use sui_move_natives::object_runtime::{self, TransactionContext};
use sui_types::metrics::BytecodeVerifierMetrics;
use sui_verifier::check_for_verifier_timeout;
use tracing::instrument;
Expand Down Expand Up @@ -85,8 +87,9 @@ mod checked {
is_metered: bool,
protocol_config: &'r ProtocolConfig,
metrics: Arc<LimitsMetrics>,
current_epoch_id: EpochId,
tx_context: Rc<RefCell<TxContext>>,
) -> NativeContextExtensions<'r> {
let current_epoch_id: EpochId = tx_context.borrow().epoch();
let mut extensions = NativeContextExtensions::default();
extensions.add(ObjectRuntime::new(
child_resolver,
Expand All @@ -97,6 +100,7 @@ mod checked {
current_epoch_id,
));
extensions.add(NativesCostTable::from_protocol_config(protocol_config));
extensions.add(TransactionContext::new(tx_context));
extensions
}

Expand Down
Loading

0 comments on commit 9953050

Please sign in to comment.