diff --git a/crates/sui-adapter-transactional-tests/tests/size_limits/deleted_id_limits_tests.snap b/crates/sui-adapter-transactional-tests/tests/size_limits/deleted_id_limits_tests.snap index 81c5f83004a75..725d343c7ae2a 100644 --- a/crates/sui-adapter-transactional-tests/tests/size_limits/deleted_id_limits_tests.snap +++ b/crates/sui-adapter-transactional-tests/tests/size_limits/deleted_id_limits_tests.snap @@ -22,14 +22,14 @@ gas summary: computation_cost: 1000000, storage_cost: 988000, storage_rebate: 9 task 4, lines 39-41: //# run Test::M1::delete_n_ids --args 2048 --gas-budget 100000000000000 mutated: object(0,0) -gas summary: computation_cost: 19000000, storage_cost: 988000, storage_rebate: 978120, non_refundable_storage_fee: 9880 +gas summary: computation_cost: 11000000, storage_cost: 988000, storage_rebate: 978120, non_refundable_storage_fee: 9880 task 5, lines 42-44: //# run Test::M1::delete_n_ids --args 2049 --gas-budget 100000000000000 -Error: Transaction Effects Status: Move Primitive Runtime Error. Location: sui::tx_context::derive_id (function index 6) at offset 0. Arithmetic error, stack overflow, max value depth, etc. -Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: MovePrimitiveRuntimeError(MoveLocationOpt(Some(MoveLocation { module: ModuleId { address: sui, name: Identifier("tx_context") }, function: 6, instruction: 0, function_name: Some("derive_id") }))), source: Some(VMError { major_status: MEMORY_LIMIT_EXCEEDED, sub_status: Some(2), message: Some("Creating more than 2048 IDs is not allowed"), exec_state: None, location: Module(ModuleId { address: sui, name: Identifier("tx_context") }), indices: [], offsets: [(FunctionDefinitionIndex(6), 0)] }), command: Some(0) } } +Error: Transaction Effects Status: Move Primitive Runtime Error. Location: sui::tx_context::fresh_id (function index 10) at offset 0. Arithmetic error, stack overflow, max value depth, etc. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: MovePrimitiveRuntimeError(MoveLocationOpt(Some(MoveLocation { module: ModuleId { address: sui, name: Identifier("tx_context") }, function: 10, instruction: 0, function_name: Some("fresh_id") }))), source: Some(VMError { major_status: MEMORY_LIMIT_EXCEEDED, sub_status: Some(2), message: Some("Creating more than 2048 IDs is not allowed"), exec_state: None, location: Module(ModuleId { address: sui, name: Identifier("tx_context") }), indices: [], offsets: [(FunctionDefinitionIndex(10), 0)] }), command: Some(0) } } task 6, line 45: //# run Test::M1::delete_n_ids --args 4096 --gas-budget 100000000000000 -Error: Transaction Effects Status: Move Primitive Runtime Error. Location: sui::tx_context::derive_id (function index 6) at offset 0. Arithmetic error, stack overflow, max value depth, etc. -Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: MovePrimitiveRuntimeError(MoveLocationOpt(Some(MoveLocation { module: ModuleId { address: sui, name: Identifier("tx_context") }, function: 6, instruction: 0, function_name: Some("derive_id") }))), source: Some(VMError { major_status: MEMORY_LIMIT_EXCEEDED, sub_status: Some(2), message: Some("Creating more than 2048 IDs is not allowed"), exec_state: None, location: Module(ModuleId { address: sui, name: Identifier("tx_context") }), indices: [], offsets: [(FunctionDefinitionIndex(6), 0)] }), command: Some(0) } } +Error: Transaction Effects Status: Move Primitive Runtime Error. Location: sui::tx_context::fresh_id (function index 10) at offset 0. Arithmetic error, stack overflow, max value depth, etc. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: MovePrimitiveRuntimeError(MoveLocationOpt(Some(MoveLocation { module: ModuleId { address: sui, name: Identifier("tx_context") }, function: 10, instruction: 0, function_name: Some("fresh_id") }))), source: Some(VMError { major_status: MEMORY_LIMIT_EXCEEDED, sub_status: Some(2), message: Some("Creating more than 2048 IDs is not allowed"), exec_state: None, location: Module(ModuleId { address: sui, name: Identifier("tx_context") }), indices: [], offsets: [(FunctionDefinitionIndex(10), 0)] }), command: Some(0) } } diff --git a/crates/sui-adapter-transactional-tests/tests/size_limits/new_id_limits_tests.snap b/crates/sui-adapter-transactional-tests/tests/size_limits/new_id_limits_tests.snap index bcc322d61fb38..90df60293c6dd 100644 --- a/crates/sui-adapter-transactional-tests/tests/size_limits/new_id_limits_tests.snap +++ b/crates/sui-adapter-transactional-tests/tests/size_limits/new_id_limits_tests.snap @@ -22,14 +22,14 @@ gas summary: computation_cost: 1000000, storage_cost: 988000, storage_rebate: 9 task 4, lines 40-42: //# run Test::M1::create_n_ids --args 2048 --gas-budget 100000000000000 mutated: object(0,0) -gas summary: computation_cost: 19000000, storage_cost: 988000, storage_rebate: 978120, non_refundable_storage_fee: 9880 +gas summary: computation_cost: 11000000, storage_cost: 988000, storage_rebate: 978120, non_refundable_storage_fee: 9880 task 5, lines 43-45: //# run Test::M1::create_n_ids --args 2049 --gas-budget 100000000000000 -Error: Transaction Effects Status: Move Primitive Runtime Error. Location: sui::tx_context::derive_id (function index 6) at offset 0. Arithmetic error, stack overflow, max value depth, etc. -Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: MovePrimitiveRuntimeError(MoveLocationOpt(Some(MoveLocation { module: ModuleId { address: sui, name: Identifier("tx_context") }, function: 6, instruction: 0, function_name: Some("derive_id") }))), source: Some(VMError { major_status: MEMORY_LIMIT_EXCEEDED, sub_status: Some(2), message: Some("Creating more than 2048 IDs is not allowed"), exec_state: None, location: Module(ModuleId { address: sui, name: Identifier("tx_context") }), indices: [], offsets: [(FunctionDefinitionIndex(6), 0)] }), command: Some(0) } } +Error: Transaction Effects Status: Move Primitive Runtime Error. Location: sui::tx_context::fresh_id (function index 10) at offset 0. Arithmetic error, stack overflow, max value depth, etc. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: MovePrimitiveRuntimeError(MoveLocationOpt(Some(MoveLocation { module: ModuleId { address: sui, name: Identifier("tx_context") }, function: 10, instruction: 0, function_name: Some("fresh_id") }))), source: Some(VMError { major_status: MEMORY_LIMIT_EXCEEDED, sub_status: Some(2), message: Some("Creating more than 2048 IDs is not allowed"), exec_state: None, location: Module(ModuleId { address: sui, name: Identifier("tx_context") }), indices: [], offsets: [(FunctionDefinitionIndex(10), 0)] }), command: Some(0) } } task 6, line 46: //# run Test::M1::create_n_ids --args 4096 --gas-budget 100000000000000 -Error: Transaction Effects Status: Move Primitive Runtime Error. Location: sui::tx_context::derive_id (function index 6) at offset 0. Arithmetic error, stack overflow, max value depth, etc. -Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: MovePrimitiveRuntimeError(MoveLocationOpt(Some(MoveLocation { module: ModuleId { address: sui, name: Identifier("tx_context") }, function: 6, instruction: 0, function_name: Some("derive_id") }))), source: Some(VMError { major_status: MEMORY_LIMIT_EXCEEDED, sub_status: Some(2), message: Some("Creating more than 2048 IDs is not allowed"), exec_state: None, location: Module(ModuleId { address: sui, name: Identifier("tx_context") }), indices: [], offsets: [(FunctionDefinitionIndex(6), 0)] }), command: Some(0) } } +Error: Transaction Effects Status: Move Primitive Runtime Error. Location: sui::tx_context::fresh_id (function index 10) at offset 0. Arithmetic error, stack overflow, max value depth, etc. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: MovePrimitiveRuntimeError(MoveLocationOpt(Some(MoveLocation { module: ModuleId { address: sui, name: Identifier("tx_context") }, function: 10, instruction: 0, function_name: Some("fresh_id") }))), source: Some(VMError { major_status: MEMORY_LIMIT_EXCEEDED, sub_status: Some(2), message: Some("Creating more than 2048 IDs is not allowed"), exec_state: None, location: Module(ModuleId { address: sui, name: Identifier("tx_context") }), indices: [], offsets: [(FunctionDefinitionIndex(10), 0)] }), command: Some(0) } } diff --git a/crates/sui-adapter-transactional-tests/tests/size_limits/object_runtime_limits.snap b/crates/sui-adapter-transactional-tests/tests/size_limits/object_runtime_limits.snap index 7cc28298d7546..6beb329ecad73 100644 --- a/crates/sui-adapter-transactional-tests/tests/size_limits/object_runtime_limits.snap +++ b/crates/sui-adapter-transactional-tests/tests/size_limits/object_runtime_limits.snap @@ -22,7 +22,7 @@ task 3, line 30: //# run a::m::add_n_items --sender A --args 1000 --gas-budget 1000000000000 --summarize created: 2000 mutated: 1 -gas summary: computation_cost: 198000000, storage_cost: 2691388000, storage_rebate: 978120, non_refundable_storage_fee: 9880 +gas summary: computation_cost: 199000000, storage_cost: 2691388000, storage_rebate: 978120, non_refundable_storage_fee: 9880 task 4, line 32: //# run a::m::add_n_items --sender A --args 1025 --gas-budget 1000000000000 diff --git a/crates/sui-adapter-transactional-tests/tests/size_limits/transfered_id_limits_tests.snap b/crates/sui-adapter-transactional-tests/tests/size_limits/transfered_id_limits_tests.snap index db12714ca5895..194ba2834b325 100644 --- a/crates/sui-adapter-transactional-tests/tests/size_limits/transfered_id_limits_tests.snap +++ b/crates/sui-adapter-transactional-tests/tests/size_limits/transfered_id_limits_tests.snap @@ -25,24 +25,24 @@ task 4, lines 39-41: //# run Test::M1::transfer_n_ids --args 2048 --gas-budget 100000000000000 --summarize created: 2048 mutated: 1 -gas summary: computation_cost: 17000000, storage_cost: 2522485600, storage_rebate: 978120, non_refundable_storage_fee: 9880 +gas summary: computation_cost: 14000000, storage_cost: 2522485600, storage_rebate: 978120, non_refundable_storage_fee: 9880 task 5, lines 42-44: //# run Test::M1::transfer_n_ids --args 2049 --gas-budget 100000000000000 -Error: Transaction Effects Status: Move Primitive Runtime Error. Location: sui::tx_context::derive_id (function index 6) at offset 0. Arithmetic error, stack overflow, max value depth, etc. -Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: MovePrimitiveRuntimeError(MoveLocationOpt(Some(MoveLocation { module: ModuleId { address: sui, name: Identifier("tx_context") }, function: 6, instruction: 0, function_name: Some("derive_id") }))), source: Some(VMError { major_status: MEMORY_LIMIT_EXCEEDED, sub_status: Some(2), message: Some("Creating more than 2048 IDs is not allowed"), exec_state: None, location: Module(ModuleId { address: sui, name: Identifier("tx_context") }), indices: [], offsets: [(FunctionDefinitionIndex(6), 0)] }), command: Some(0) } } +Error: Transaction Effects Status: Move Primitive Runtime Error. Location: sui::tx_context::fresh_id (function index 10) at offset 0. Arithmetic error, stack overflow, max value depth, etc. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: MovePrimitiveRuntimeError(MoveLocationOpt(Some(MoveLocation { module: ModuleId { address: sui, name: Identifier("tx_context") }, function: 10, instruction: 0, function_name: Some("fresh_id") }))), source: Some(VMError { major_status: MEMORY_LIMIT_EXCEEDED, sub_status: Some(2), message: Some("Creating more than 2048 IDs is not allowed"), exec_state: None, location: Module(ModuleId { address: sui, name: Identifier("tx_context") }), indices: [], offsets: [(FunctionDefinitionIndex(10), 0)] }), command: Some(0) } } task 6, lines 45-47: //# run Test::M1::transfer_n_ids --args 4096 --gas-budget 100000000000000 -Error: Transaction Effects Status: Move Primitive Runtime Error. Location: sui::tx_context::derive_id (function index 6) at offset 0. Arithmetic error, stack overflow, max value depth, etc. -Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: MovePrimitiveRuntimeError(MoveLocationOpt(Some(MoveLocation { module: ModuleId { address: sui, name: Identifier("tx_context") }, function: 6, instruction: 0, function_name: Some("derive_id") }))), source: Some(VMError { major_status: MEMORY_LIMIT_EXCEEDED, sub_status: Some(2), message: Some("Creating more than 2048 IDs is not allowed"), exec_state: None, location: Module(ModuleId { address: sui, name: Identifier("tx_context") }), indices: [], offsets: [(FunctionDefinitionIndex(6), 0)] }), command: Some(0) } } +Error: Transaction Effects Status: Move Primitive Runtime Error. Location: sui::tx_context::fresh_id (function index 10) at offset 0. Arithmetic error, stack overflow, max value depth, etc. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: MovePrimitiveRuntimeError(MoveLocationOpt(Some(MoveLocation { module: ModuleId { address: sui, name: Identifier("tx_context") }, function: 10, instruction: 0, function_name: Some("fresh_id") }))), source: Some(VMError { major_status: MEMORY_LIMIT_EXCEEDED, sub_status: Some(2), message: Some("Creating more than 2048 IDs is not allowed"), exec_state: None, location: Module(ModuleId { address: sui, name: Identifier("tx_context") }), indices: [], offsets: [(FunctionDefinitionIndex(10), 0)] }), command: Some(0) } } task 7, lines 48-50: //# run Test::M1::transfer_n_ids --args 2049 --gas-budget 100000000000000 -Error: Transaction Effects Status: Move Primitive Runtime Error. Location: sui::tx_context::derive_id (function index 6) at offset 0. Arithmetic error, stack overflow, max value depth, etc. -Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: MovePrimitiveRuntimeError(MoveLocationOpt(Some(MoveLocation { module: ModuleId { address: sui, name: Identifier("tx_context") }, function: 6, instruction: 0, function_name: Some("derive_id") }))), source: Some(VMError { major_status: MEMORY_LIMIT_EXCEEDED, sub_status: Some(2), message: Some("Creating more than 2048 IDs is not allowed"), exec_state: None, location: Module(ModuleId { address: sui, name: Identifier("tx_context") }), indices: [], offsets: [(FunctionDefinitionIndex(6), 0)] }), command: Some(0) } } +Error: Transaction Effects Status: Move Primitive Runtime Error. Location: sui::tx_context::fresh_id (function index 10) at offset 0. Arithmetic error, stack overflow, max value depth, etc. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: MovePrimitiveRuntimeError(MoveLocationOpt(Some(MoveLocation { module: ModuleId { address: sui, name: Identifier("tx_context") }, function: 10, instruction: 0, function_name: Some("fresh_id") }))), source: Some(VMError { major_status: MEMORY_LIMIT_EXCEEDED, sub_status: Some(2), message: Some("Creating more than 2048 IDs is not allowed"), exec_state: None, location: Module(ModuleId { address: sui, name: Identifier("tx_context") }), indices: [], offsets: [(FunctionDefinitionIndex(10), 0)] }), command: Some(0) } } task 8, line 51: //# run Test::M1::transfer_n_ids --args 4096 --gas-budget 100000000000000 -Error: Transaction Effects Status: Move Primitive Runtime Error. Location: sui::tx_context::derive_id (function index 6) at offset 0. Arithmetic error, stack overflow, max value depth, etc. -Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: MovePrimitiveRuntimeError(MoveLocationOpt(Some(MoveLocation { module: ModuleId { address: sui, name: Identifier("tx_context") }, function: 6, instruction: 0, function_name: Some("derive_id") }))), source: Some(VMError { major_status: MEMORY_LIMIT_EXCEEDED, sub_status: Some(2), message: Some("Creating more than 2048 IDs is not allowed"), exec_state: None, location: Module(ModuleId { address: sui, name: Identifier("tx_context") }), indices: [], offsets: [(FunctionDefinitionIndex(6), 0)] }), command: Some(0) } } +Error: Transaction Effects Status: Move Primitive Runtime Error. Location: sui::tx_context::fresh_id (function index 10) at offset 0. Arithmetic error, stack overflow, max value depth, etc. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: MovePrimitiveRuntimeError(MoveLocationOpt(Some(MoveLocation { module: ModuleId { address: sui, name: Identifier("tx_context") }, function: 10, instruction: 0, function_name: Some("fresh_id") }))), source: Some(VMError { major_status: MEMORY_LIMIT_EXCEEDED, sub_status: Some(2), message: Some("Creating more than 2048 IDs is not allowed"), exec_state: None, location: Module(ModuleId { address: sui, name: Identifier("tx_context") }), indices: [], offsets: [(FunctionDefinitionIndex(10), 0)] }), command: Some(0) } } diff --git a/crates/sui-core/src/unit_tests/authority_tests.rs b/crates/sui-core/src/unit_tests/authority_tests.rs index a7de998db8bc7..5afc2a3b85d18 100644 --- a/crates/sui-core/src/unit_tests/authority_tests.rs +++ b/crates/sui-core/src/unit_tests/authority_tests.rs @@ -1679,14 +1679,18 @@ async fn test_publish_dependent_module_ok() { }; let authority = init_state_with_objects(vec![gas_payment_object]).await; + let epoch_store = authority.epoch_store_for_testing(); + let protocol_config = epoch_store.protocol_config(); let rgp = authority.reference_gas_price_for_testing().unwrap(); + let gas_price = rgp; + let gas_budget = gas_price * TEST_ONLY_GAS_UNIT_FOR_PUBLISH; let data = TransactionData::new_module( sender, gas_payment_object_ref, vec![dependent_module_bytes], vec![ObjectID::from(*genesis_module.address())], - rgp * TEST_ONLY_GAS_UNIT_FOR_PUBLISH, - rgp, + gas_budget, + gas_price, ); let transaction = to_sender_signed_transaction(data, &sender_key); @@ -1694,8 +1698,10 @@ async fn test_publish_dependent_module_ok() { &sender, transaction.digest(), &EpochData::new_test(), - rgp, + gas_price, + gas_budget, None, + protocol_config.move_native_context(), ) .fresh_id(); @@ -1718,12 +1724,11 @@ async fn test_publish_module_no_dependencies_ok() { let authority = init_state_with_objects(vec![]).await; let rgp = authority.reference_gas_price_for_testing().unwrap(); let gas_payment_object_id = ObjectID::random(); + + let epoch_store = authority.epoch_store_for_testing(); + let protocol_config = epoch_store.protocol_config(); // Use the max budget to avoid running out of gas. - let gas_balance = { - let epoch_store = authority.epoch_store_for_testing(); - let protocol_config = epoch_store.protocol_config(); - protocol_config.max_tx_gas() - }; + let gas_balance = protocol_config.max_tx_gas(); let gas_payment_object = Object::with_id_owner_gas_for_testing(gas_payment_object_id, sender, gas_balance); let gas_payment_object_ref = gas_payment_object.compute_object_reference(); @@ -1736,21 +1741,25 @@ async fn test_publish_module_no_dependencies_ok() { .unwrap(); let module_bytes = vec![module_bytes]; let dependencies = vec![]; // no dependencies + let gas_price = rgp; + let gas_budget = gas_price * TEST_ONLY_GAS_UNIT_FOR_PUBLISH; let data = TransactionData::new_module( sender, gas_payment_object_ref, module_bytes, dependencies, - rgp * TEST_ONLY_GAS_UNIT_FOR_PUBLISH, - rgp, + gas_budget, + gas_price, ); let transaction = to_sender_signed_transaction(data, &sender_key); let _module_object_id = TxContext::new( &sender, transaction.digest(), &EpochData::new_test(), - rgp, + gas_price, + gas_budget, None, + protocol_config.move_native_context(), ) .fresh_id(); let signed_effects = send_and_confirm_transaction(&authority, transaction) diff --git a/crates/sui-framework/docs/sui/tx_context.md b/crates/sui-framework/docs/sui/tx_context.md index 6d0ee6c248f3f..762b40edaf1b1 100644 --- a/crates/sui-framework/docs/sui/tx_context.md +++ b/crates/sui-framework/docs/sui/tx_context.md @@ -6,15 +6,25 @@ title: Module `sui::tx_context` - [Struct `TxContext`](#sui_tx_context_TxContext) - [Function `sender`](#sui_tx_context_sender) +- [Function `native_sender`](#sui_tx_context_native_sender) - [Function `digest`](#sui_tx_context_digest) - [Function `epoch`](#sui_tx_context_epoch) +- [Function `native_epoch`](#sui_tx_context_native_epoch) - [Function `epoch_timestamp_ms`](#sui_tx_context_epoch_timestamp_ms) +- [Function `native_epoch_timestamp_ms`](#sui_tx_context_native_epoch_timestamp_ms) +- [Function `sponsor`](#sui_tx_context_sponsor) +- [Function `native_sponsor`](#sui_tx_context_native_sponsor) - [Function `fresh_object_address`](#sui_tx_context_fresh_object_address) +- [Function `fresh_id`](#sui_tx_context_fresh_id) - [Function `ids_created`](#sui_tx_context_ids_created) -- [Function `derive_id`](#sui_tx_context_derive_id) +- [Function `native_ids_created`](#sui_tx_context_native_ids_created) +- [Function `native_gas_price`](#sui_tx_context_native_gas_price) +- [Function `native_gas_budget`](#sui_tx_context_native_gas_budget) -
+use std::option;
+use std::vector;
+
@@ -81,7 +91,7 @@ Return the address of the user that signed the current
transaction
-public fun sender(self: &sui::tx_context::TxContext): address
+public fun sender(_self: &sui::tx_context::TxContext): address
@@ -90,13 +100,35 @@ transaction
Implementation
-public fun sender(self: &TxContext): address {
- self.sender
+public fun sender(_self: &TxContext): address {
+ native_sender()
}
+
+
+
+
+## Function `native_sender`
+
+
+
+fun native_sender(): address
+
+
+
+
+
+Implementation
+
+
+native fun native_sender(): address;
+
+
+
+
@@ -132,7 +164,7 @@ Please do not use as a source of randomness.
Return the current epoch
-public fun epoch(self: &sui::tx_context::TxContext): u64
+public fun epoch(_self: &sui::tx_context::TxContext): u64
@@ -141,13 +173,35 @@ Return the current epoch
Implementation
-public fun epoch(self: &TxContext): u64 {
- self.epoch
+public fun epoch(_self: &TxContext): u64 {
+ native_epoch()
}
+
+
+
+
+## Function `native_epoch`
+
+
+
+fun native_epoch(): u64
+
+
+
+
+
+Implementation
+
+
+native fun native_epoch(): u64;
+
+
+
+
@@ -157,7 +211,54 @@ Return the current epoch
Return the epoch start time as a unix timestamp in milliseconds.
-public fun epoch_timestamp_ms(self: &sui::tx_context::TxContext): u64
+public fun epoch_timestamp_ms(_self: &sui::tx_context::TxContext): u64
+
+
+
+
+
+Implementation
+
+
+public fun epoch_timestamp_ms(_self: &TxContext): u64 {
+ native_epoch_timestamp_ms()
+}
+
+
+
+
+
+
+
+
+## Function `native_epoch_timestamp_ms`
+
+
+
+fun native_epoch_timestamp_ms(): u64
+
+
+
+
+
+Implementation
+
+
+native fun native_epoch_timestamp_ms(): u64;
+
+
+
+
+
+
+
+
+## Function `sponsor`
+
+Return the adress of the transaction sponsor or None
if there was no sponsor.
+
+
+public fun sponsor(_self: &sui::tx_context::TxContext): std::option::Option<address>
@@ -166,13 +267,35 @@ Return the epoch start time as a unix timestamp in milliseconds.
Implementation
-public fun epoch_timestamp_ms(self: &TxContext): u64 {
- self.epoch_timestamp_ms
+public fun sponsor(_self: &TxContext): Option<address> {
+ native_sponsor()
}
+
+
+
+
+## Function `native_sponsor`
+
+
+
+fun native_sponsor(): std::option::Option<address>
+
+
+
+
+
+Implementation
+
+
+native fun native_sponsor(): Option<address>;
+
+
+
+
@@ -184,7 +307,7 @@ occur as the address for a user.
In other words, the generated address is a globally unique object ID.
-public fun fresh_object_address(ctx: &mut sui::tx_context::TxContext): address
+public fun fresh_object_address(_ctx: &mut sui::tx_context::TxContext): address
@@ -193,16 +316,35 @@ In other words, the generated address is a globally unique object ID.
Implementation
-public fun fresh_object_address(ctx: &mut TxContext): address {
- let ids_created = ctx.ids_created;
- let id = derive_id(*&ctx.tx_hash, ids_created);
- ctx.ids_created = ids_created + 1;
- id
+public fun fresh_object_address(_ctx: &mut TxContext): address {
+ fresh_id()
}
+
+
+
+
+## Function `fresh_id`
+
+
+
+fun fresh_id(): address
+
+
+
+
+
+Implementation
+
+
+native fun fresh_id(): address;
+
+
+
+
@@ -213,7 +355,7 @@ Return the number of id's created by the current transaction.
Hidden for now, but may expose later
-fun ids_created(self: &sui::tx_context::TxContext): u64
+fun ids_created(_self: &sui::tx_context::TxContext): u64
@@ -222,8 +364,8 @@ Hidden for now, but may expose later
Implementation
-fun ids_created(self: &TxContext): u64 {
- self.ids_created
+fun ids_created(_self: &TxContext): u64 {
+ native_ids_created()
}
@@ -231,14 +373,57 @@ Hidden for now, but may expose later
-
+
+
+## Function `native_ids_created`
+
+
+
+fun native_ids_created(): u64
+
+
+
+
+
+Implementation
+
+
+native fun native_ids_created(): u64;
+
+
+
+
+
+
+
+
+## Function `native_gas_price`
+
+
+
+fun native_gas_price(): u64
+
+
+
+
+
+Implementation
+
+
+native fun native_gas_price(): u64;
+
+
+
+
+
+
+
-## Function `derive_id`
+## Function `native_gas_budget`
-Native function for deriving an ID via hash(tx_hash || ids_created)
-fun derive_id(tx_hash: vector<u8>, ids_created: u64): address
+fun native_gas_budget(): u64
@@ -247,7 +432,7 @@ Native function for deriving an ID via hash(tx_hash || ids_created)
Implementation
-native fun derive_id(tx_hash: vector<u8>, ids_created: u64): address;
+native fun native_gas_budget(): u64;
diff --git a/crates/sui-framework/packages/sui-framework/sources/tx_context.move b/crates/sui-framework/packages/sui-framework/sources/tx_context.move
index 1fdef9ff83a81..ed63c4ac3b616 100644
--- a/crates/sui-framework/packages/sui-framework/sources/tx_context.move
+++ b/crates/sui-framework/packages/sui-framework/sources/tx_context.move
@@ -15,6 +15,7 @@ const EBadTxHashLength: u64 = 0;
/// Attempt to get the most recent created object ID when none has been created.
const ENoIDsCreated: u64 = 1;
+#[allow(unused_field)]
/// Information about the transaction currently being executed.
/// This cannot be constructed by a transaction--it is a privileged object created by
/// the VM and passed in to the entrypoint of the transaction as `&mut TxContext`.
@@ -34,9 +35,10 @@ public struct TxContext has drop {
/// Return the address of the user that signed the current
/// transaction
-public fun sender(self: &TxContext): address {
- self.sender
+public fun sender(_self: &TxContext): address {
+ native_sender()
}
+native fun native_sender(): address;
/// Return the transaction digest (hash of transaction inputs).
/// Please do not use as a source of randomness.
@@ -45,34 +47,46 @@ public fun digest(self: &TxContext): &vector {
}
/// Return the current epoch
-public fun epoch(self: &TxContext): u64 {
- self.epoch
+public fun epoch(_self: &TxContext): u64 {
+ native_epoch()
}
+native fun native_epoch(): u64;
/// Return the epoch start time as a unix timestamp in milliseconds.
-public fun epoch_timestamp_ms(self: &TxContext): u64 {
- self.epoch_timestamp_ms
+public fun epoch_timestamp_ms(_self: &TxContext): u64 {
+ native_epoch_timestamp_ms()
}
+native fun native_epoch_timestamp_ms(): u64;
+
+/// Return the adress of the transaction sponsor or `None` if there was no sponsor.
+public fun sponsor(_self: &TxContext): Option {
+ native_sponsor()
+}
+native fun native_sponsor(): Option;
/// Create an `address` that has not been used. As it is an object address, it will never
/// occur as the address for a user.
/// In other words, the generated address is a globally unique object ID.
-public fun fresh_object_address(ctx: &mut TxContext): address {
- let ids_created = ctx.ids_created;
- let id = derive_id(*&ctx.tx_hash, ids_created);
- ctx.ids_created = ids_created + 1;
- id
+public fun fresh_object_address(_ctx: &mut TxContext): address {
+ fresh_id()
}
+native fun fresh_id(): address;
#[allow(unused_function)]
/// Return the number of id's created by the current transaction.
/// Hidden for now, but may expose later
-fun ids_created(self: &TxContext): u64 {
- self.ids_created
+fun ids_created(_self: &TxContext): u64 {
+ native_ids_created()
}
+native fun native_ids_created(): u64;
-/// Native function for deriving an ID via hash(tx_hash || ids_created)
-native fun derive_id(tx_hash: vector, ids_created: u64): address;
+#[allow(unused_function)]
+// native function to retrieve gas price, currently not exposed
+native fun native_gas_price(): u64;
+
+#[allow(unused_function)]
+// native function to retrieve gas budget, currently not exposed
+native fun native_gas_budget(): u64;
// ==== test-only functions ====
@@ -86,7 +100,15 @@ public fun new(
ids_created: u64,
): TxContext {
assert!(tx_hash.length() == TX_HASH_LENGTH, EBadTxHashLength);
- TxContext { sender, tx_hash, epoch, epoch_timestamp_ms, ids_created }
+ replace(sender, tx_hash, epoch, epoch_timestamp_ms, ids_created);
+ // return an empty TxContext given all the info is held on the native side (call above)
+ TxContext {
+ sender: @0x0,
+ tx_hash,
+ epoch: 0,
+ epoch_timestamp_ms: 0,
+ ids_created: 0,
+ }
}
#[test_only]
@@ -125,17 +147,39 @@ public fun get_ids_created(self: &TxContext): u64 {
#[test_only]
/// Return the most recent created object ID.
public fun last_created_object_id(self: &TxContext): address {
- let ids_created = self.ids_created;
+ let ids_created = self.ids_created();
assert!(ids_created > 0, ENoIDsCreated);
- derive_id(*&self.tx_hash, ids_created - 1)
+ derive_id(*self.digest(), ids_created - 1)
}
+#[test_only]
+/// Native function for deriving an ID via hash(tx_hash || ids_created)
+native fun derive_id(tx_hash: vector, ids_created: u64): address;
#[test_only]
public fun increment_epoch_number(self: &mut TxContext) {
- self.epoch = self.epoch + 1
+ let sender = self.sender();
+ let tx_hash = *self.digest();
+ let epoch = self.epoch() + 1;
+ let epoch_timestamp_ms = self.epoch_timestamp_ms();
+ let ids_created = self.ids_created();
+ replace(sender, tx_hash, epoch, epoch_timestamp_ms, ids_created);
}
#[test_only]
public fun increment_epoch_timestamp(self: &mut TxContext, delta_ms: u64) {
- self.epoch_timestamp_ms = self.epoch_timestamp_ms + delta_ms
+ let sender = self.sender();
+ let tx_hash = *self.digest();
+ let epoch = self.epoch();
+ let epoch_timestamp_ms = self.epoch_timestamp_ms() + delta_ms;
+ let ids_created = self.ids_created();
+ replace(sender, tx_hash, epoch, epoch_timestamp_ms, ids_created);
}
+
+#[test_only]
+native fun replace(
+ sender: address,
+ tx_hash: vector,
+ epoch: u64,
+ epoch_timestamp_ms: u64,
+ ids_created: u64,
+);
diff --git a/crates/sui-framework/packages_compiled/sui-framework b/crates/sui-framework/packages_compiled/sui-framework
index 2ff5694239ff8..a708fc27d723b 100644
Binary files a/crates/sui-framework/packages_compiled/sui-framework and b/crates/sui-framework/packages_compiled/sui-framework differ
diff --git a/crates/sui-framework/published_api.txt b/crates/sui-framework/published_api.txt
index 383546c067f34..ce999d5d2b68d 100644
--- a/crates/sui-framework/published_api.txt
+++ b/crates/sui-framework/published_api.txt
@@ -1126,22 +1126,46 @@ TxContext
sender
public fun
0x2::tx_context
+native_sender
+ fun
+ 0x2::tx_context
digest
public fun
0x2::tx_context
epoch
public fun
0x2::tx_context
+native_epoch
+ fun
+ 0x2::tx_context
epoch_timestamp_ms
public fun
0x2::tx_context
+native_epoch_timestamp_ms
+ fun
+ 0x2::tx_context
+sponsor
+ public fun
+ 0x2::tx_context
+native_sponsor
+ fun
+ 0x2::tx_context
fresh_object_address
public fun
0x2::tx_context
+fresh_id
+ fun
+ 0x2::tx_context
ids_created
fun
0x2::tx_context
-derive_id
+native_ids_created
+ fun
+ 0x2::tx_context
+native_gas_price
+ fun
+ 0x2::tx_context
+native_gas_budget
fun
0x2::tx_context
ID
diff --git a/crates/sui-move/src/unit_test.rs b/crates/sui-move/src/unit_test.rs
index 6d9afd93b35e5..c8a9bcf93a8b8 100644
--- a/crates/sui-move/src/unit_test.rs
+++ b/crates/sui-move/src/unit_test.rs
@@ -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::{test_scenario::InMemoryTestStore, transaction_context::TransactionContext};
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,
};
@@ -113,6 +116,7 @@ fn new_testing_object_and_natives_cost_runtime(ext: &mut NativeContextExtensions
let registry = prometheus::Registry::new();
let metrics = Arc::new(LimitsMetrics::new(®istry));
let store = Lazy::force(&TEST_STORE);
+ let protocol_config = ProtocolConfig::get_for_max_version_UNSAFE();
ext.add(ObjectRuntime::new(
store,
@@ -122,9 +126,19 @@ 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,
+ 0,
+ None,
+ protocol_config.move_native_context(),
+ );
+ ext.add(TransactionContext::new_for_testing(Rc::new(RefCell::new(
+ tx_context,
+ ))));
ext.add(store);
}
diff --git a/crates/sui-open-rpc/spec/openrpc.json b/crates/sui-open-rpc/spec/openrpc.json
index a8d128dc6de7f..0f4d42d1e2ed0 100644
--- a/crates/sui-open-rpc/spec/openrpc.json
+++ b/crates/sui-open-rpc/spec/openrpc.json
@@ -1334,6 +1334,7 @@
"loaded_child_object_format_type": false,
"loaded_child_objects_fixed": true,
"missing_type_is_compatibility_error": true,
+ "move_native_context": false,
"mysticeti_fastpath": false,
"mysticeti_leader_scoring_and_schedule": false,
"mysticeti_use_committed_subdag_digest": false,
@@ -1944,6 +1945,15 @@
"tx_context_derive_id_cost_base": {
"u64": "52"
},
+ "tx_context_epoch_cost_base": null,
+ "tx_context_epoch_timestamp_ms_cost_base": null,
+ "tx_context_fresh_id_cost_base": null,
+ "tx_context_gas_budget_cost_base": null,
+ "tx_context_gas_price_cost_base": null,
+ "tx_context_ids_created_cost_base": null,
+ "tx_context_replace_cost_base": null,
+ "tx_context_sender_cost_base": null,
+ "tx_context_sponsor_cost_base": null,
"type_name_get_base_cost": null,
"type_name_get_per_byte_cost": null,
"types_is_one_time_witness_cost_base": {
diff --git a/crates/sui-protocol-config/src/lib.rs b/crates/sui-protocol-config/src/lib.rs
index bf889c41e3fd2..94e23db19502c 100644
--- a/crates/sui-protocol-config/src/lib.rs
+++ b/crates/sui-protocol-config/src/lib.rs
@@ -219,6 +219,8 @@ const MAX_PROTOCOL_VERSION: u64 = 76;
// Enable the new commit rule for devnet.
// Version 75: Enable passkey auth in testnet.
// Version 76: Deprecate Deepbook V2 order placement and deposit.
+// Make `TxContext` Move API native
+
#[derive(Copy, Clone, Debug, Hash, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub struct ProtocolVersion(u64);
@@ -623,6 +625,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 {
@@ -1085,6 +1091,15 @@ pub struct ProtocolConfig {
// TxContext
// Cost params for the Move native function `transfer_impl(obj: T, recipient: address)`
tx_context_derive_id_cost_base: Option,
+ tx_context_fresh_id_cost_base: Option,
+ tx_context_sender_cost_base: Option,
+ tx_context_epoch_cost_base: Option,
+ tx_context_epoch_timestamp_ms_cost_base: Option,
+ tx_context_sponsor_cost_base: Option,
+ tx_context_gas_price_cost_base: Option,
+ tx_context_gas_budget_cost_base: Option,
+ tx_context_ids_created_cost_base: Option,
+ tx_context_replace_cost_base: Option,
// Types
// Cost params for the Move native function `is_one_time_witness(_: &T): bool`
@@ -1799,6 +1814,7 @@ 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
}
@@ -1808,6 +1824,10 @@ impl ProtocolConfig {
// parameters.
0
}
+
+ pub fn move_native_context(&self) -> bool {
+ self.feature_flags.move_native_context
+ }
}
#[cfg(not(msim))]
@@ -2100,6 +2120,15 @@ impl ProtocolConfig {
// `tx_context` module
// Cost params for the Move native function `transfer_impl(obj: T, recipient: address)`
tx_context_derive_id_cost_base: Some(52),
+ tx_context_fresh_id_cost_base: None,
+ tx_context_sender_cost_base: None,
+ tx_context_epoch_cost_base: None,
+ tx_context_epoch_timestamp_ms_cost_base: None,
+ tx_context_sponsor_cost_base: None,
+ tx_context_gas_price_cost_base: None,
+ tx_context_gas_budget_cost_base: None,
+ tx_context_ids_created_cost_base: None,
+ tx_context_replace_cost_base: None,
// `types` module
// Cost params for the Move native function `is_one_time_witness(_: &T): bool`
@@ -3254,7 +3283,19 @@ impl ProtocolConfig {
cfg.feature_flags.passkey_auth = true;
}
}
- 76 => {}
+ 76 => {
+ cfg.feature_flags.move_native_context = true;
+
+ cfg.tx_context_fresh_id_cost_base = Some(30);
+ 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_sponsor_cost_base = Some(30);
+ cfg.tx_context_gas_price_cost_base = Some(30);
+ cfg.tx_context_gas_budget_cost_base = Some(30);
+ cfg.tx_context_ids_created_cost_base = Some(30);
+ cfg.tx_context_replace_cost_base = Some(30);
+ }
// Use this template when making changes:
//
// // modify an existing constant.
diff --git a/crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__Mainnet_version_76.snap b/crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__Mainnet_version_76.snap
index 655be0bd4431d..7218258d9e4e7 100644
--- a/crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__Mainnet_version_76.snap
+++ b/crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__Mainnet_version_76.snap
@@ -71,6 +71,7 @@ feature_flags:
convert_type_argument_error: true
variant_nodes: true
consensus_zstd_compression: true
+ move_native_context: true
max_tx_size_bytes: 131072
max_input_objects: 2048
max_size_written_objects: 5000000
@@ -194,6 +195,15 @@ transfer_freeze_object_cost_base: 52
transfer_share_object_cost_base: 52
transfer_receive_object_cost_base: 52
tx_context_derive_id_cost_base: 52
+tx_context_fresh_id_cost_base: 30
+tx_context_sender_cost_base: 30
+tx_context_epoch_cost_base: 30
+tx_context_epoch_timestamp_ms_cost_base: 30
+tx_context_sponsor_cost_base: 30
+tx_context_gas_price_cost_base: 30
+tx_context_gas_budget_cost_base: 30
+tx_context_ids_created_cost_base: 30
+tx_context_replace_cost_base: 30
types_is_one_time_witness_cost_base: 52
types_is_one_time_witness_type_tag_cost_per_byte: 2
types_is_one_time_witness_type_cost_per_byte: 2
diff --git a/crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__Testnet_version_76.snap b/crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__Testnet_version_76.snap
index 2725b0958ee18..7f2a00d8ee428 100644
--- a/crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__Testnet_version_76.snap
+++ b/crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__Testnet_version_76.snap
@@ -1,7 +1,6 @@
---
source: crates/sui-protocol-config/src/lib.rs
expression: "ProtocolConfig::get_for_version(cur, *chain_id)"
-snapshot_kind: text
---
version: 76
feature_flags:
@@ -74,6 +73,7 @@ feature_flags:
convert_type_argument_error: true
variant_nodes: true
consensus_zstd_compression: true
+ move_native_context: true
max_tx_size_bytes: 131072
max_input_objects: 2048
max_size_written_objects: 5000000
@@ -197,6 +197,15 @@ transfer_freeze_object_cost_base: 52
transfer_share_object_cost_base: 52
transfer_receive_object_cost_base: 52
tx_context_derive_id_cost_base: 52
+tx_context_fresh_id_cost_base: 30
+tx_context_sender_cost_base: 30
+tx_context_epoch_cost_base: 30
+tx_context_epoch_timestamp_ms_cost_base: 30
+tx_context_sponsor_cost_base: 30
+tx_context_gas_price_cost_base: 30
+tx_context_gas_budget_cost_base: 30
+tx_context_ids_created_cost_base: 30
+tx_context_replace_cost_base: 30
types_is_one_time_witness_cost_base: 52
types_is_one_time_witness_type_tag_cost_per_byte: 2
types_is_one_time_witness_type_cost_per_byte: 2
diff --git a/crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__version_76.snap b/crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__version_76.snap
index 8cea8608b8131..ef1bfef3d12b1 100644
--- a/crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__version_76.snap
+++ b/crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__version_76.snap
@@ -80,6 +80,7 @@ feature_flags:
convert_type_argument_error: true
variant_nodes: true
consensus_zstd_compression: true
+ move_native_context: true
max_tx_size_bytes: 131072
max_input_objects: 2048
max_size_written_objects: 5000000
@@ -203,6 +204,15 @@ transfer_freeze_object_cost_base: 52
transfer_share_object_cost_base: 52
transfer_receive_object_cost_base: 52
tx_context_derive_id_cost_base: 52
+tx_context_fresh_id_cost_base: 30
+tx_context_sender_cost_base: 30
+tx_context_epoch_cost_base: 30
+tx_context_epoch_timestamp_ms_cost_base: 30
+tx_context_sponsor_cost_base: 30
+tx_context_gas_price_cost_base: 30
+tx_context_gas_budget_cost_base: 30
+tx_context_ids_created_cost_base: 30
+tx_context_replace_cost_base: 30
types_is_one_time_witness_cost_base: 52
types_is_one_time_witness_type_tag_cost_per_byte: 2
types_is_one_time_witness_type_cost_per_byte: 2
diff --git a/crates/sui-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap b/crates/sui-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap
index 2e494f01cdb9a..a250a59954a83 100644
--- a/crates/sui-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap
+++ b/crates/sui-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap
@@ -240,13 +240,13 @@ validators:
next_epoch_worker_address: ~
extra_fields:
id:
- id: "0x63c951f50d71f7fa58e90fee1820ed27a15f47602cbc0640d58c5675d9cc93cf"
+ id: "0xfbc66761ecf533bf49976257c3a7a73df702bcb74bca68cff29ed3654aa253ee"
size: 0
voting_power: 10000
- operation_cap_id: "0x99a1cb0cfa940302fd08144dec6460b0225cf8ba438081ac32fcd00389092c4d"
+ operation_cap_id: "0x4ea8c7e54ff773b09caa5f5ee9d299750c2c7d9415edcf0a76ab7cab5e1687ae"
gas_price: 1000
staking_pool:
- id: "0x430f34db68b99ed1c4a02d009f6423b35dd2ce2bb5015c02df4a3ab8fd671a6f"
+ id: "0x509cba75e0bd7dc2bd7183dbf731d4f704c7f6d4b07323f723e31ad1231ea4ac"
activation_epoch: 0
deactivation_epoch: ~
sui_balance: 20000000000000000
@@ -254,14 +254,14 @@ validators:
value: 0
pool_token_balance: 20000000000000000
exchange_rates:
- id: "0x68047818ec2262573e5a7241853b364559e84d2b7a93973853c3f52c46e6103d"
+ id: "0xbd714ff50b7c26029ffede3a3d319035e51f9a068b912d0a7ed1f3adcd1792bd"
size: 1
pending_stake: 0
pending_total_sui_withdraw: 0
pending_pool_token_withdraw: 0
extra_fields:
id:
- id: "0x1203f7e9fb0a1503d530013ab3e1df797ed34e6e72d457caea9a250ed64e9b12"
+ id: "0xfa7b5626df86afe793d2f3594776b7dcef30a299fafa9d691cdbe5a281a6bc02"
size: 0
commission_rate: 200
next_epoch_stake: 20000000000000000
@@ -269,27 +269,27 @@ validators:
next_epoch_commission_rate: 200
extra_fields:
id:
- id: "0xa208610c482bbf00d12ecb7ed113e3ec6cead7d292b5ddba487c67ae343b7420"
+ id: "0x2ec475193b06c3cf9463998dc5d314ae2e5ab422e389bda6315afb4633cc5464"
size: 0
pending_active_validators:
contents:
- id: "0x4ce4f20ae616257e491b61ed95f256062baf815b92181cd2028436bc9ffaedf6"
+ id: "0x6a533ee971df19eb82f59e2f6ed6752a0e694c7e49f398193056b30c2dede4da"
size: 0
pending_removals: []
staking_pool_mappings:
- id: "0xc226eef39a3c111c373bb4dd3871640d8ce2f9adca35da36d1363a707eda918b"
+ id: "0x4bb65144da3bad311a1c6731149d6d44275f8fbaa1f55b44cad676be4f3c7b45"
size: 1
inactive_validators:
- id: "0xb7cf484096138508283d7e305874cd6e73eccca33d9ac2a8abbe33f8c854c11c"
+ id: "0x10f7df5eab007a95baed107d2d9ce9b01817f2110a95a87ea81fbaee6a781a9f"
size: 0
validator_candidates:
- id: "0x05d9257a640e27a15f19b4e8aef7f892c2a66924e30c4af57153e3240cee33de"
+ id: "0xad0024d42975862931f1ceed3220766632924d017136122a294a8ff552c6eb6e"
size: 0
at_risk_validators:
contents: []
extra_fields:
id:
- id: "0xf91d9dc9849f07f3f38732aa9c40a9b0bb83a68a9b6324f8d59e66bc2dec76e0"
+ id: "0x716df94174cc205f3b9fdbd5f756e3457a95f7c83f0e7e577aeefbce5c5e9661"
size: 0
storage_fund:
total_object_storage_rebates:
@@ -306,7 +306,7 @@ parameters:
validator_low_stake_grace_period: 7
extra_fields:
id:
- id: "0xb86c133b102926c433bc95f2cb054c956e0a80567a3b39b9a9163520e725b1a8"
+ id: "0xe63c4f6f34480af9081c2138b8578462aa46237fd2766e4a10ced32d8f35de11"
size: 0
reference_gas_price: 1000
validator_report_records:
@@ -320,7 +320,7 @@ stake_subsidy:
stake_subsidy_decrease_rate: 1000
extra_fields:
id:
- id: "0x311ae5223405603a7741ce24339390240c2a97c70d785f5116e4316520920156"
+ id: "0xb44969eac6b234d4e436fc607aa22d7bdc4276d9fe22c20e5d4cbe8884d76cca"
size: 0
safe_mode: false
safe_mode_storage_rewards:
@@ -332,5 +332,5 @@ safe_mode_non_refundable_storage_fee: 0
epoch_start_timestamp_ms: 10
extra_fields:
id:
- id: "0xfe0661290995d4a00c6d2775d900c03b5dc67ba1294f823b2c8d6f29b0a677f2"
+ id: "0x7d45dd0ddecf7817735c7f3c57d6f9ad01f91e9ec710e35ff04195267017c49a"
size: 0
diff --git a/crates/sui-types/src/base_types.rs b/crates/sui-types/src/base_types.rs
index f5efa88d1eba8..309dd017f8df0 100644
--- a/crates/sui-types/src/base_types.rs
+++ b/crates/sui-types/src/base_types.rs
@@ -1019,8 +1019,12 @@ pub struct TxContext {
ids_created: u64,
// gas price passed to transaction as input
gas_price: u64,
+ // gas budget passed to transaction as input
+ gas_budget: u64,
// address of the sponsor if any
sponsor: Option,
+ // flag to indicate whether the Move implementaion is native or not
+ is_native: bool,
}
#[derive(PartialEq, Eq, Clone, Copy)]
@@ -1039,7 +1043,9 @@ impl TxContext {
digest: &TransactionDigest,
epoch_data: &EpochData,
gas_price: u64,
+ gas_budget: u64,
sponsor: Option,
+ is_native: bool,
) -> Self {
Self::new_from_components(
sender,
@@ -1047,7 +1053,9 @@ impl TxContext {
&epoch_data.epoch_id(),
epoch_data.epoch_start_timestamp(),
gas_price,
+ gas_budget,
sponsor,
+ is_native,
)
}
@@ -1057,7 +1065,9 @@ impl TxContext {
epoch_id: &EpochId,
epoch_timestamp_ms: u64,
gas_price: u64,
+ gas_budget: u64,
sponsor: Option,
+ is_native: bool,
) -> Self {
Self {
sender: AccountAddress::new(sender.0),
@@ -1066,7 +1076,9 @@ impl TxContext {
epoch_timestamp_ms,
ids_created: 0,
gas_price,
+ gas_budget,
sponsor: sponsor.map(|s| s.into()),
+ is_native,
}
}
@@ -1099,12 +1111,12 @@ 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
@@ -1112,12 +1124,47 @@ impl TxContext {
TransactionDigest::new(self.digest.clone().try_into().unwrap())
}
- pub fn sender(&self) -> SuiAddress {
- SuiAddress::from(ObjectID(self.sender))
+ pub fn sponsor(&self) -> Option {
+ self.sponsor.map(SuiAddress::from)
+ }
+
+ pub fn gas_price(&self) -> u64 {
+ self.gas_price
+ }
+
+ pub fn gas_budget(&self) -> u64 {
+ self.gas_budget
+ }
+
+ 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 {
- let move_context: MoveLegacyTxContext = self.into();
+ let move_context: MoveLegacyTxContext = if self.is_native {
+ let tx_context = &TxContext {
+ sender: AccountAddress::ZERO,
+ digest: self.digest.clone(),
+ epoch: 0,
+ epoch_timestamp_ms: 0,
+ ids_created: 0,
+ gas_price: 0,
+ gas_budget: 0,
+ sponsor: None,
+ is_native: true,
+ };
+ tx_context.into()
+ } else {
+ self.into()
+ };
bcs::to_bytes(&move_context).unwrap()
}
@@ -1130,18 +1177,38 @@ impl TxContext {
/// serialize/deserialize and this is the reason why this method
/// consumes the other context..
pub fn update_state(&mut self, other: MoveLegacyTxContext) -> Result<(), ExecutionError> {
- if self.sender != other.sender
- || self.digest != other.digest
- || other.ids_created < self.ids_created
- {
- return Err(ExecutionError::new_with_source(
- ExecutionErrorKind::InvariantViolation,
- "Immutable fields for TxContext changed",
- ));
+ if !self.is_native {
+ if self.sender != other.sender
+ || self.digest != other.digest
+ || other.ids_created < self.ids_created
+ {
+ return Err(ExecutionError::new_with_source(
+ ExecutionErrorKind::InvariantViolation,
+ "Immutable fields for TxContext changed",
+ ));
+ }
+ self.ids_created = other.ids_created;
}
- self.ids_created = other.ids_created;
Ok(())
}
+
+ //
+ // Move test only API
+ //
+ pub fn replace(
+ &mut self,
+ sender: AccountAddress,
+ tx_hash: Vec,
+ 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
diff --git a/sui-execution/latest/sui-adapter/src/adapter.rs b/sui-execution/latest/sui-adapter/src/adapter.rs
index 99551458bb1e7..5b78aee4a6621 100644
--- a/sui-execution/latest/sui-adapter/src/adapter.rs
+++ b/sui-execution/latest/sui-adapter/src/adapter.rs
@@ -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;
@@ -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, transaction_context::TransactionContext};
use sui_types::metrics::BytecodeVerifierMetrics;
use sui_verifier::check_for_verifier_timeout;
use tracing::instrument;
@@ -85,8 +87,9 @@ mod checked {
is_metered: bool,
protocol_config: &'r ProtocolConfig,
metrics: Arc,
- current_epoch_id: EpochId,
+ tx_context: Rc>,
) -> NativeContextExtensions<'r> {
+ let current_epoch_id: EpochId = tx_context.borrow().epoch();
let mut extensions = NativeContextExtensions::default();
extensions.add(ObjectRuntime::new(
child_resolver,
@@ -97,6 +100,7 @@ mod checked {
current_epoch_id,
));
extensions.add(NativesCostTable::from_protocol_config(protocol_config));
+ extensions.add(TransactionContext::new(tx_context));
extensions
}
diff --git a/sui-execution/latest/sui-adapter/src/execution_engine.rs b/sui-execution/latest/sui-adapter/src/execution_engine.rs
index 21aa916b65e87..0907916dedc3e 100644
--- a/sui-execution/latest/sui-adapter/src/execution_engine.rs
+++ b/sui-execution/latest/sui-adapter/src/execution_engine.rs
@@ -10,7 +10,7 @@ mod checked {
use move_binary_format::CompiledModule;
use move_trace_format::format::MoveTraceBuilder;
use move_vm_runtime::move_vm::MoveVM;
- use std::{collections::HashSet, sync::Arc};
+ use std::{cell::RefCell, collections::HashSet, rc::Rc, sync::Arc};
use sui_types::balance::{
BALANCE_CREATE_REWARDS_FUNCTION_NAME, BALANCE_DESTROY_REBATES_FUNCTION_NAME,
BALANCE_MODULE_NAME,
@@ -140,14 +140,17 @@ mod checked {
protocol_config,
);
- let mut tx_ctx = TxContext::new_from_components(
+ let tx_ctx = TxContext::new_from_components(
&transaction_signer,
&transaction_digest,
epoch_id,
epoch_timestamp_ms,
gas_price,
+ gas_data.budget,
sponsor,
+ protocol_config.move_native_context(),
);
+ let tx_ctx = Rc::new(RefCell::new(tx_ctx));
let is_epoch_change = transaction_kind.is_end_of_epoch_tx();
@@ -156,7 +159,7 @@ mod checked {
&mut temporary_store,
transaction_kind,
&mut gas_charger,
- &mut tx_ctx,
+ tx_ctx,
move_vm,
protocol_config,
metrics,
@@ -260,7 +263,7 @@ mod checked {
protocol_config: &ProtocolConfig,
metrics: Arc,
move_vm: &Arc,
- tx_context: &mut TxContext,
+ tx_context: Rc>,
input_objects: CheckedInputObjects,
pt: ProgrammableTransaction,
) -> Result {
@@ -269,11 +272,11 @@ mod checked {
store,
input_objects,
vec![],
- tx_context.digest(),
+ tx_context.borrow().digest(),
protocol_config,
0,
);
- let mut gas_charger = GasCharger::new_unmetered(tx_context.digest());
+ let mut gas_charger = GasCharger::new_unmetered(tx_context.borrow().digest());
programmable_transactions::execution::execute::(
protocol_config,
metrics,
@@ -294,7 +297,7 @@ mod checked {
temporary_store: &mut TemporaryStore<'_>,
transaction_kind: TransactionKind,
gas_charger: &mut GasCharger,
- tx_ctx: &mut TxContext,
+ tx_ctx: Rc>,
move_vm: &Arc,
protocol_config: &ProtocolConfig,
metrics: Arc,
@@ -318,7 +321,7 @@ mod checked {
let is_genesis_tx = matches!(transaction_kind, TransactionKind::Genesis(_));
let advance_epoch_gas_summary = transaction_kind.get_advance_epoch_tx_gas_summary();
- let digest = tx_ctx.digest();
+ let digest = tx_ctx.borrow().digest();
// We must charge object read here during transaction execution, because if this fails
// we must still ensure an effect is committed and all objects versions incremented
@@ -585,7 +588,7 @@ mod checked {
fn execution_loop(
temporary_store: &mut TemporaryStore<'_>,
transaction_kind: TransactionKind,
- tx_ctx: &mut TxContext,
+ tx_ctx: Rc>,
move_vm: &Arc,
gas_charger: &mut GasCharger,
protocol_config: &ProtocolConfig,
@@ -610,7 +613,7 @@ mod checked {
Ok((Mode::empty_results(), vec![]))
}
TransactionKind::Genesis(GenesisTransaction { objects }) => {
- if tx_ctx.epoch() != 0 {
+ if tx_ctx.borrow().epoch() != 0 {
panic!("BUG: Genesis Transactions can only be executed in epoch 0");
}
@@ -620,7 +623,7 @@ mod checked {
let object = ObjectInner {
data,
owner,
- previous_transaction: tx_ctx.digest(),
+ previous_transaction: tx_ctx.borrow().digest(),
storage_rebate: 0,
};
temporary_store.create_object(object.into());
@@ -917,7 +920,7 @@ mod checked {
builder: ProgrammableTransactionBuilder,
change_epoch: ChangeEpoch,
temporary_store: &mut TemporaryStore<'_>,
- tx_ctx: &mut TxContext,
+ tx_ctx: Rc>,
move_vm: &Arc,
gas_charger: &mut GasCharger,
protocol_config: &ProtocolConfig,
@@ -941,7 +944,7 @@ mod checked {
metrics.clone(),
move_vm,
temporary_store,
- tx_ctx,
+ tx_ctx.clone(),
gas_charger,
advance_epoch_pt,
trace_builder_opt,
@@ -971,7 +974,7 @@ mod checked {
metrics.clone(),
move_vm,
temporary_store,
- tx_ctx,
+ tx_ctx.clone(),
gas_charger,
advance_epoch_safe_mode_pt,
trace_builder_opt,
@@ -1016,14 +1019,14 @@ mod checked {
fn process_system_packages(
change_epoch: ChangeEpoch,
temporary_store: &mut TemporaryStore<'_>,
- tx_ctx: &mut TxContext,
+ tx_ctx: Rc>,
move_vm: &MoveVM,
gas_charger: &mut GasCharger,
protocol_config: &ProtocolConfig,
metrics: Arc,
trace_builder_opt: &mut Option,
) {
- let digest = tx_ctx.digest();
+ let digest = tx_ctx.borrow().digest();
let binary_config = to_binary_config(protocol_config);
for (version, modules, dependencies) in change_epoch.system_packages.into_iter() {
let deserialized_modules: Vec<_> = modules
@@ -1046,7 +1049,7 @@ mod checked {
metrics.clone(),
move_vm,
temporary_store,
- tx_ctx,
+ tx_ctx.clone(),
gas_charger,
publish_pt,
trace_builder_opt,
@@ -1087,7 +1090,7 @@ mod checked {
fn setup_consensus_commit(
consensus_commit_timestamp_ms: CheckpointTimestamp,
temporary_store: &mut TemporaryStore<'_>,
- tx_ctx: &mut TxContext,
+ tx_ctx: Rc>,
move_vm: &Arc,
gas_charger: &mut GasCharger,
protocol_config: &ProtocolConfig,
@@ -1228,7 +1231,7 @@ mod checked {
fn setup_authenticator_state_update(
update: AuthenticatorStateUpdate,
temporary_store: &mut TemporaryStore<'_>,
- tx_ctx: &mut TxContext,
+ tx_ctx: Rc>,
move_vm: &Arc,
gas_charger: &mut GasCharger,
protocol_config: &ProtocolConfig,
@@ -1297,7 +1300,7 @@ mod checked {
fn setup_randomness_state_update(
update: RandomnessStateUpdate,
temporary_store: &mut TemporaryStore<'_>,
- tx_ctx: &mut TxContext,
+ tx_ctx: Rc>,
move_vm: &Arc,
gas_charger: &mut GasCharger,
protocol_config: &ProtocolConfig,
diff --git a/sui-execution/latest/sui-adapter/src/programmable_transactions/context.rs b/sui-execution/latest/sui-adapter/src/programmable_transactions/context.rs
index 4048df3c2dbc5..784c1eb805c1f 100644
--- a/sui-execution/latest/sui-adapter/src/programmable_transactions/context.rs
+++ b/sui-execution/latest/sui-adapter/src/programmable_transactions/context.rs
@@ -5,10 +5,11 @@ pub use checked::*;
#[sui_macros::with_checked_arithmetic]
mod checked {
- use std::collections::BTreeSet;
use std::{
borrow::Borrow,
- collections::{BTreeMap, HashMap},
+ cell::RefCell,
+ collections::{BTreeMap, BTreeSet, HashMap},
+ rc::Rc,
sync::Arc,
};
@@ -80,7 +81,7 @@ mod checked {
pub state_view: &'state dyn ExecutionState,
/// A shared transaction context, contains transaction digest information and manages the
/// creation of new object IDs
- pub tx_context: &'a mut TxContext,
+ pub tx_context: Rc>,
/// The gas charger used for metering
pub gas_charger: &'a mut GasCharger,
/// Additional transfers not from the Move runtime
@@ -122,7 +123,7 @@ mod checked {
metrics: Arc,
vm: &'vm MoveVM,
state_view: &'state dyn ExecutionState,
- tx_context: &'a mut TxContext,
+ tx_context: Rc>,
gas_charger: &'a mut GasCharger,
inputs: Vec,
) -> Result
@@ -190,7 +191,7 @@ mod checked {
!gas_charger.is_unmetered(),
protocol_config,
metrics.clone(),
- tx_context.epoch(),
+ tx_context.clone(),
);
// Set the profiler if in CLI
@@ -199,7 +200,8 @@ mod checked {
use move_vm_profiler::GasProfiler;
use move_vm_types::gas::GasMeter;
- let tx_digest = tx_context.digest();
+ let ref_context: &RefCell = tx_context.borrow();
+ let tx_digest = ref_context.borrow().digest();
let remaining_gas: u64 =
move_vm_types::gas::GasMeter::remaining_gas(gas_charger.move_gas_status())
.into();
@@ -237,7 +239,7 @@ mod checked {
/// Create a new ID and update the state
pub fn fresh_id(&mut self) -> Result {
- let object_id = self.tx_context.fresh_id();
+ let object_id = self.tx_context.borrow_mut().fresh_id();
let object_runtime: &mut ObjectRuntime = self.native_extensions.get_mut();
object_runtime
.new_id(object_id)
@@ -610,7 +612,8 @@ mod checked {
state_view,
..
} = self;
- let tx_digest = tx_context.digest();
+ let ref_context: &RefCell = tx_context.borrow();
+ let tx_digest = ref_context.borrow().digest();
let gas_id_opt = gas.object_metadata.as_ref().map(|info| info.id());
let mut loaded_runtime_objects = BTreeMap::new();
let mut additional_writes = BTreeMap::new();
@@ -843,7 +846,7 @@ mod checked {
Event::new(
module_id.address(),
module_id.name(),
- tx_context.sender(),
+ ref_context.borrow().sender(),
tag,
contents,
)
diff --git a/sui-execution/latest/sui-adapter/src/programmable_transactions/execution.rs b/sui-execution/latest/sui-adapter/src/programmable_transactions/execution.rs
index 6f765602511e3..cbb5cbc546a55 100644
--- a/sui-execution/latest/sui-adapter/src/programmable_transactions/execution.rs
+++ b/sui-execution/latest/sui-adapter/src/programmable_transactions/execution.rs
@@ -30,11 +30,13 @@ mod checked {
};
use move_vm_types::loaded_data::runtime_types::{CachedDatatype, Type};
use serde::{de::DeserializeSeed, Deserialize};
- use std::time::Instant;
use std::{
+ cell::RefCell,
collections::{BTreeMap, BTreeSet},
fmt,
+ rc::Rc,
sync::Arc,
+ time::Instant,
};
use sui_move_natives::object_runtime::ObjectRuntime;
use sui_protocol_config::ProtocolConfig;
@@ -75,7 +77,7 @@ mod checked {
metrics: Arc,
vm: &MoveVM,
state_view: &mut dyn ExecutionState,
- tx_context: &mut TxContext,
+ tx_context: Rc>,
gas_charger: &mut GasCharger,
pt: ProgrammableTransaction,
trace_builder_opt: &mut Option,
@@ -105,7 +107,7 @@ mod checked {
metrics: Arc,
vm: &MoveVM,
state_view: &mut dyn ExecutionState,
- tx_context: &mut TxContext,
+ tx_context: Rc>,
gas_charger: &mut GasCharger,
pt: ProgrammableTransaction,
trace_builder_opt: &mut Option,
@@ -552,7 +554,7 @@ mod checked {
// do not calculate or substitute id for predefined packages
(*modules[0].self_id().address()).into()
} else {
- let id = context.tx_context.fresh_id();
+ let id = context.tx_context.borrow_mut().fresh_id();
substitute_package_id(&mut modules, id)?;
id
};
@@ -666,7 +668,7 @@ mod checked {
substitute_package_id(&mut modules, runtime_id)?;
// Upgraded packages share their predecessor's runtime ID but get a new storage ID.
- let storage_id = context.tx_context.fresh_id();
+ let storage_id = context.tx_context.borrow_mut().fresh_id();
let dependencies = fetch_packages(context, &dep_ids)?;
let package = context.upgrade_package(
@@ -843,7 +845,7 @@ mod checked {
match tx_context_kind {
TxContextKind::None => (),
TxContextKind::Mutable | TxContextKind::Immutable => {
- serialized_arguments.push(context.tx_context.to_bcs_legacy_context());
+ serialized_arguments.push(context.tx_context.borrow().to_bcs_legacy_context());
}
}
// script visibility checked manually for entry points
@@ -873,7 +875,7 @@ mod checked {
"Unable to deserialize TxContext bytes. {e}"
))
})?;
- context.tx_context.update_state(updated_ctx)?;
+ context.tx_context.borrow_mut().update_state(updated_ctx)?;
}
Ok(result)
}
diff --git a/sui-execution/latest/sui-move-natives/src/lib.rs b/sui-execution/latest/sui-move-natives/src/lib.rs
index f89dfb8ecb709..dac3914d38974 100644
--- a/sui-execution/latest/sui-move-natives/src/lib.rs
+++ b/sui-execution/latest/sui-move-natives/src/lib.rs
@@ -31,7 +31,12 @@ use self::{
transfer::{
TransferFreezeObjectCostParams, TransferInternalCostParams, TransferShareObjectCostParams,
},
- tx_context::TxContextDeriveIdCostParams,
+ tx_context::{
+ TxContextDeriveIdCostParams, TxContextEpochCostParams, TxContextEpochTimestampMsCostParams,
+ TxContextFreshIdCostParams, TxContextGasBudgetCostParams, TxContextGasPriceCostParams,
+ TxContextIdsCreatedCostParams, TxContextReplaceCostParams, TxContextSenderCostParams,
+ TxContextSponsorCostParams,
+ },
types::TypesIsOneTimeWitnessCostParams,
validator::ValidatorValidateMetadataBcsCostParams,
};
@@ -74,11 +79,14 @@ pub mod object_runtime;
mod random;
pub mod test_scenario;
mod test_utils;
+pub mod transaction_context;
mod transfer;
mod tx_context;
mod types;
mod validator;
+// TODO: remove in later PRs once we define the proper cost of native functions
+const DEFAULT_UNUSED_TX_CONTEXT_ENTRY_COST: u64 = 10;
#[derive(Tid)]
pub struct NativesCostTable {
// Address natives
@@ -113,6 +121,15 @@ pub struct NativesCostTable {
// TxContext
pub tx_context_derive_id_cost_params: TxContextDeriveIdCostParams,
+ pub tx_context_fresh_id_cost_params: TxContextFreshIdCostParams,
+ pub tx_context_sender_cost_params: TxContextSenderCostParams,
+ pub tx_context_epoch_cost_params: TxContextEpochCostParams,
+ pub tx_context_epoch_timestamp_ms_cost_params: TxContextEpochTimestampMsCostParams,
+ pub tx_context_sponsor_cost_params: TxContextSponsorCostParams,
+ pub tx_context_gas_price_cost_params: TxContextGasPriceCostParams,
+ pub tx_context_gas_budget_cost_params: TxContextGasBudgetCostParams,
+ pub tx_context_ids_created_cost_params: TxContextIdsCreatedCostParams,
+ pub tx_context_replace_cost_params: TxContextReplaceCostParams,
// Type
pub type_is_one_time_witness_cost_params: TypesIsOneTimeWitnessCostParams,
@@ -338,11 +355,77 @@ impl NativesCostTable {
.transfer_share_object_cost_base()
.into(),
},
+ // tx_context
tx_context_derive_id_cost_params: TxContextDeriveIdCostParams {
tx_context_derive_id_cost_base: protocol_config
.tx_context_derive_id_cost_base()
.into(),
},
+ tx_context_fresh_id_cost_params: TxContextFreshIdCostParams {
+ tx_context_fresh_id_cost_base: if protocol_config.move_native_context() {
+ protocol_config.tx_context_fresh_id_cost_base().into()
+ } else {
+ DEFAULT_UNUSED_TX_CONTEXT_ENTRY_COST.into()
+ },
+ },
+ tx_context_sender_cost_params: TxContextSenderCostParams {
+ tx_context_sender_cost_base: if protocol_config.move_native_context() {
+ protocol_config.tx_context_sender_cost_base().into()
+ } else {
+ DEFAULT_UNUSED_TX_CONTEXT_ENTRY_COST.into()
+ },
+ },
+ tx_context_epoch_cost_params: TxContextEpochCostParams {
+ tx_context_epoch_cost_base: if protocol_config.move_native_context() {
+ protocol_config.tx_context_epoch_cost_base().into()
+ } else {
+ DEFAULT_UNUSED_TX_CONTEXT_ENTRY_COST.into()
+ },
+ },
+ tx_context_epoch_timestamp_ms_cost_params: TxContextEpochTimestampMsCostParams {
+ tx_context_epoch_timestamp_ms_cost_base: if protocol_config.move_native_context() {
+ protocol_config
+ .tx_context_epoch_timestamp_ms_cost_base()
+ .into()
+ } else {
+ DEFAULT_UNUSED_TX_CONTEXT_ENTRY_COST.into()
+ },
+ },
+ tx_context_sponsor_cost_params: TxContextSponsorCostParams {
+ tx_context_sponsor_cost_base: if protocol_config.move_native_context() {
+ protocol_config.tx_context_sponsor_cost_base().into()
+ } else {
+ DEFAULT_UNUSED_TX_CONTEXT_ENTRY_COST.into()
+ },
+ },
+ tx_context_gas_price_cost_params: TxContextGasPriceCostParams {
+ tx_context_gas_price_cost_base: if protocol_config.move_native_context() {
+ protocol_config.tx_context_gas_price_cost_base().into()
+ } else {
+ DEFAULT_UNUSED_TX_CONTEXT_ENTRY_COST.into()
+ },
+ },
+ tx_context_gas_budget_cost_params: TxContextGasBudgetCostParams {
+ tx_context_gas_budget_cost_base: if protocol_config.move_native_context() {
+ protocol_config.tx_context_gas_budget_cost_base().into()
+ } else {
+ DEFAULT_UNUSED_TX_CONTEXT_ENTRY_COST.into()
+ },
+ },
+ tx_context_ids_created_cost_params: TxContextIdsCreatedCostParams {
+ tx_context_ids_created_cost_base: if protocol_config.move_native_context() {
+ protocol_config.tx_context_ids_created_cost_base().into()
+ } else {
+ DEFAULT_UNUSED_TX_CONTEXT_ENTRY_COST.into()
+ },
+ },
+ tx_context_replace_cost_params: TxContextReplaceCostParams {
+ tx_context_replace_cost_base: if protocol_config.move_native_context() {
+ protocol_config.tx_context_replace_cost_base().into()
+ } else {
+ DEFAULT_UNUSED_TX_CONTEXT_ENTRY_COST.into()
+ },
+ },
type_is_one_time_witness_cost_params: TypesIsOneTimeWitnessCostParams {
types_is_one_time_witness_cost_base: protocol_config
.types_is_one_time_witness_cost_base()
@@ -1027,6 +1110,43 @@ pub fn all_natives(silent: bool, protocol_config: &ProtocolConfig) -> NativeFunc
"derive_id",
make_native!(tx_context::derive_id),
),
+ ("tx_context", "fresh_id", make_native!(tx_context::fresh_id)),
+ (
+ "tx_context",
+ "native_sender",
+ make_native!(tx_context::sender),
+ ),
+ (
+ "tx_context",
+ "native_epoch",
+ make_native!(tx_context::epoch),
+ ),
+ (
+ "tx_context",
+ "native_epoch_timestamp_ms",
+ make_native!(tx_context::epoch_timestamp_ms),
+ ),
+ (
+ "tx_context",
+ "native_sponsor",
+ make_native!(tx_context::sponsor),
+ ),
+ (
+ "tx_context",
+ "native_gas_price",
+ make_native!(tx_context::gas_price),
+ ),
+ (
+ "tx_context",
+ "native_gas_budget",
+ make_native!(tx_context::gas_budget),
+ ),
+ (
+ "tx_context",
+ "native_ids_created",
+ make_native!(tx_context::ids_created),
+ ),
+ ("tx_context", "replace", make_native!(tx_context::replace)),
(
"types",
"is_one_time_witness",
diff --git a/sui-execution/latest/sui-move-natives/src/transaction_context/mod.rs b/sui-execution/latest/sui-move-natives/src/transaction_context/mod.rs
new file mode 100644
index 0000000000000..17e1375303309
--- /dev/null
+++ b/sui-execution/latest/sui-move-natives/src/transaction_context/mod.rs
@@ -0,0 +1,95 @@
+// Copyright (c) Mysten Labs, Inc.
+// SPDX-License-Identifier: Apache-2.0
+
+use better_any::{Tid, TidAble};
+use move_core_types::account_address::AccountAddress;
+use std::{cell::RefCell, rc::Rc};
+use sui_types::{
+ base_types::{ObjectID, SuiAddress, TxContext},
+ committee::EpochId,
+ digests::TransactionDigest,
+};
+
+// TransactionContext is a wrapper around TxContext that is exposed to NativeContextExtensions
+// in order to provide transaction context information to Move native functions.
+// Holds a Rc> to allow for mutation of the TxContext.
+#[derive(Tid)]
+pub struct TransactionContext {
+ pub(crate) tx_context: Rc>,
+ test_only: bool,
+}
+
+impl TransactionContext {
+ pub fn new(tx_context: Rc>) -> Self {
+ Self {
+ tx_context,
+ test_only: false,
+ }
+ }
+
+ pub fn new_for_testing(tx_context: Rc>) -> Self {
+ Self {
+ tx_context,
+ test_only: true,
+ }
+ }
+
+ pub fn sender(&self) -> SuiAddress {
+ self.tx_context.borrow().sender()
+ }
+
+ pub fn epoch(&self) -> EpochId {
+ self.tx_context.borrow().epoch()
+ }
+
+ pub fn epoch_timestamp_ms(&self) -> u64 {
+ self.tx_context.borrow().epoch_timestamp_ms()
+ }
+
+ pub fn digest(&self) -> TransactionDigest {
+ self.tx_context.borrow().digest()
+ }
+
+ pub fn sponsor(&self) -> Option {
+ self.tx_context.borrow().sponsor()
+ }
+
+ pub fn gas_price(&self) -> u64 {
+ self.tx_context.borrow().gas_price()
+ }
+
+ pub fn gas_budget(&self) -> u64 {
+ self.tx_context.borrow().gas_budget()
+ }
+
+ pub fn ids_created(&self) -> u64 {
+ self.tx_context.borrow().ids_created()
+ }
+
+ pub fn fresh_id(&self) -> ObjectID {
+ self.tx_context.borrow_mut().fresh_id()
+ }
+
+ //
+ // Test only function
+ //
+ pub fn replace(
+ &self,
+ sender: AccountAddress,
+ tx_hash: Vec,
+ epoch: u64,
+ epoch_timestamp_ms: u64,
+ ids_created: u64,
+ ) {
+ if !self.test_only {
+ unreachable!("`replace` called on a non testing scenario");
+ }
+ self.tx_context.borrow_mut().replace(
+ sender,
+ tx_hash,
+ epoch,
+ epoch_timestamp_ms,
+ ids_created,
+ );
+ }
+}
diff --git a/sui-execution/latest/sui-move-natives/src/tx_context.rs b/sui-execution/latest/sui-move-natives/src/tx_context.rs
index 1a208098b409d..35d22ac75ee9b 100644
--- a/sui-execution/latest/sui-move-natives/src/tx_context.rs
+++ b/sui-execution/latest/sui-move-natives/src/tx_context.rs
@@ -5,13 +5,18 @@ use move_binary_format::errors::PartialVMResult;
use move_core_types::{account_address::AccountAddress, gas_algebra::InternalGas};
use move_vm_runtime::{native_charge_gas_early_exit, native_functions::NativeContext};
use move_vm_types::{
- loaded_data::runtime_types::Type, natives::function::NativeResult, pop_arg, values::Value,
+ loaded_data::runtime_types::Type,
+ natives::function::NativeResult,
+ pop_arg,
+ values::{Struct, Value, Vector},
};
use smallvec::smallvec;
use std::{collections::VecDeque, convert::TryFrom};
-use sui_types::base_types::{ObjectID, TransactionDigest};
+use sui_types::base_types::{ObjectID, SuiAddress, TransactionDigest};
-use crate::{object_runtime::ObjectRuntime, NativesCostTable};
+use crate::{
+ object_runtime::ObjectRuntime, transaction_context::TransactionContext, NativesCostTable,
+};
#[derive(Clone)]
pub struct TxContextDeriveIdCostParams {
@@ -54,3 +59,346 @@ pub fn derive_id(
smallvec![Value::address(address)],
))
}
+
+#[derive(Clone)]
+pub struct TxContextFreshIdCostParams {
+ pub tx_context_fresh_id_cost_base: InternalGas,
+}
+/***************************************************************************************************
+ * native fun fresh_id
+ * Implementation of the Move native function `fun fresh_id(): address`
+ **************************************************************************************************/
+pub fn fresh_id(
+ context: &mut NativeContext,
+ ty_args: Vec,
+ args: VecDeque,
+) -> PartialVMResult {
+ debug_assert!(ty_args.is_empty());
+ debug_assert!(args.is_empty());
+
+ let tx_context_fresh_id_cost_params = context
+ .extensions_mut()
+ .get::()
+ .tx_context_fresh_id_cost_params
+ .clone();
+ native_charge_gas_early_exit!(
+ context,
+ tx_context_fresh_id_cost_params.tx_context_fresh_id_cost_base
+ );
+
+ let transaction_context: &mut TransactionContext = context.extensions_mut().get_mut();
+ let fresh_id = transaction_context.fresh_id();
+ let object_runtime: &mut ObjectRuntime = context.extensions_mut().get_mut();
+ object_runtime.new_id(fresh_id)?;
+
+ Ok(NativeResult::ok(
+ context.gas_used(),
+ smallvec![Value::address(fresh_id.into())],
+ ))
+}
+
+#[derive(Clone)]
+pub struct TxContextSenderCostParams {
+ pub tx_context_sender_cost_base: InternalGas,
+}
+/***************************************************************************************************
+ * native fun native_sender
+ * Implementation of the Move native function `fun native_sender(): address`
+ **************************************************************************************************/
+pub fn sender(
+ context: &mut NativeContext,
+ ty_args: Vec,
+ args: VecDeque,
+) -> PartialVMResult {
+ debug_assert!(ty_args.is_empty());
+ debug_assert!(args.is_empty());
+
+ let tx_context_sender_cost_params = context
+ .extensions_mut()
+ .get::()
+ .tx_context_sender_cost_params
+ .clone();
+ native_charge_gas_early_exit!(
+ context,
+ tx_context_sender_cost_params.tx_context_sender_cost_base
+ );
+
+ let transaction_context: &mut TransactionContext = context.extensions_mut().get_mut();
+ let sender = transaction_context.sender();
+
+ Ok(NativeResult::ok(
+ context.gas_used(),
+ smallvec![Value::address(sender.into())],
+ ))
+}
+
+#[derive(Clone)]
+pub struct TxContextEpochCostParams {
+ pub tx_context_epoch_cost_base: InternalGas,
+}
+/***************************************************************************************************
+ * native fun native_epoch
+ * Implementation of the Move native function `fun native_epoch(): u64`
+ **************************************************************************************************/
+pub fn epoch(
+ context: &mut NativeContext,
+ ty_args: Vec,
+ args: VecDeque,
+) -> PartialVMResult {
+ debug_assert!(ty_args.is_empty());
+ debug_assert!(args.is_empty());
+
+ let tx_context_epoch_cost_params = context
+ .extensions_mut()
+ .get::()
+ .tx_context_epoch_cost_params
+ .clone();
+ native_charge_gas_early_exit!(
+ context,
+ tx_context_epoch_cost_params.tx_context_epoch_cost_base
+ );
+
+ let transaction_context: &mut TransactionContext = context.extensions_mut().get_mut();
+ let epoch = transaction_context.epoch();
+
+ Ok(NativeResult::ok(
+ context.gas_used(),
+ smallvec![Value::u64(epoch)],
+ ))
+}
+
+#[derive(Clone)]
+pub struct TxContextEpochTimestampMsCostParams {
+ pub tx_context_epoch_timestamp_ms_cost_base: InternalGas,
+}
+/***************************************************************************************************
+ * native fun native_epoch_timestamp_ms
+ * Implementation of the Move native function `fun native_epoch_timestamp_ms(): u64`
+ **************************************************************************************************/
+pub fn epoch_timestamp_ms(
+ context: &mut NativeContext,
+ ty_args: Vec,
+ args: VecDeque,
+) -> PartialVMResult {
+ debug_assert!(ty_args.is_empty());
+ debug_assert!(args.is_empty());
+
+ let tx_context_epoch_timestamp_ms_cost_params = context
+ .extensions_mut()
+ .get::()
+ .tx_context_epoch_timestamp_ms_cost_params
+ .clone();
+ native_charge_gas_early_exit!(
+ context,
+ tx_context_epoch_timestamp_ms_cost_params.tx_context_epoch_timestamp_ms_cost_base
+ );
+
+ let transaction_context: &mut TransactionContext = context.extensions_mut().get_mut();
+ let timestamp = transaction_context.epoch_timestamp_ms();
+
+ Ok(NativeResult::ok(
+ context.gas_used(),
+ smallvec![Value::u64(timestamp)],
+ ))
+}
+
+#[derive(Clone)]
+pub struct TxContextSponsorCostParams {
+ pub tx_context_sponsor_cost_base: InternalGas,
+}
+/***************************************************************************************************
+ * native fun native_sponsor
+ * Implementation of the Move native function `fun native_sponsor(): Option`
+ **************************************************************************************************/
+pub fn sponsor(
+ context: &mut NativeContext,
+ ty_args: Vec,
+ args: VecDeque,
+) -> PartialVMResult {
+ debug_assert!(ty_args.is_empty());
+ debug_assert!(args.is_empty());
+
+ let tx_context_sponsor_cost_params = context
+ .extensions_mut()
+ .get::()
+ .tx_context_sponsor_cost_params
+ .clone();
+ native_charge_gas_early_exit!(
+ context,
+ tx_context_sponsor_cost_params.tx_context_sponsor_cost_base
+ );
+
+ let transaction_context: &mut TransactionContext = context.extensions_mut().get_mut();
+ let sponsor = to_option(transaction_context.sponsor())?;
+
+ Ok(NativeResult::ok(context.gas_used(), smallvec![sponsor]))
+}
+
+fn to_option(value: Option) -> PartialVMResult {
+ let vector = Type::Vector(Box::new(Type::Address));
+ match value {
+ Some(value) => {
+ let value = vec![AccountAddress::new(value.to_inner())];
+ Ok(Value::struct_(Struct::pack(vec![Vector::pack(
+ &vector,
+ vec![Value::vector_address(value)],
+ )?])))
+ }
+ None => Ok(Value::struct_(Struct::pack(vec![Vector::empty(&vector)?]))),
+ }
+}
+
+#[derive(Clone)]
+pub struct TxContextGasPriceCostParams {
+ pub tx_context_gas_price_cost_base: InternalGas,
+}
+/***************************************************************************************************
+ * native fun native_gas_price
+ * Implementation of the Move native function `fun native_gas_price(): u64`
+ **************************************************************************************************/
+pub fn gas_price(
+ context: &mut NativeContext,
+ ty_args: Vec,
+ args: VecDeque,
+) -> PartialVMResult {
+ debug_assert!(ty_args.is_empty());
+ debug_assert!(args.is_empty());
+
+ let tx_context_gas_price_cost_params = context
+ .extensions_mut()
+ .get::()
+ .tx_context_gas_price_cost_params
+ .clone();
+ native_charge_gas_early_exit!(
+ context,
+ tx_context_gas_price_cost_params.tx_context_gas_price_cost_base
+ );
+
+ let transaction_context: &mut TransactionContext = context.extensions_mut().get_mut();
+ let gas_price = transaction_context.gas_price();
+
+ Ok(NativeResult::ok(
+ context.gas_used(),
+ smallvec![Value::u64(gas_price)],
+ ))
+}
+
+#[derive(Clone)]
+pub struct TxContextGasBudgetCostParams {
+ pub tx_context_gas_budget_cost_base: InternalGas,
+}
+/***************************************************************************************************
+ * native fun native_gas_budget
+ * Implementation of the Move native function `fun native_gas_budget(): u64`
+ **************************************************************************************************/
+pub fn gas_budget(
+ context: &mut NativeContext,
+ ty_args: Vec,
+ args: VecDeque,
+) -> PartialVMResult {
+ debug_assert!(ty_args.is_empty());
+ debug_assert!(args.is_empty());
+
+ let tx_context_gas_budget_cost_params = context
+ .extensions_mut()
+ .get::()
+ .tx_context_gas_budget_cost_params
+ .clone();
+ native_charge_gas_early_exit!(
+ context,
+ tx_context_gas_budget_cost_params.tx_context_gas_budget_cost_base
+ );
+
+ let transaction_context: &mut TransactionContext = context.extensions_mut().get_mut();
+ let gas_budget = transaction_context.gas_budget();
+
+ Ok(NativeResult::ok(
+ context.gas_used(),
+ smallvec![Value::u64(gas_budget)],
+ ))
+}
+
+#[derive(Clone)]
+pub struct TxContextIdsCreatedCostParams {
+ pub tx_context_ids_created_cost_base: InternalGas,
+}
+/***************************************************************************************************
+ * native fun native_ids_created
+ * Implementation of the Move native function `fun native_ids_created(): u64`
+ **************************************************************************************************/
+pub fn ids_created(
+ context: &mut NativeContext,
+ ty_args: Vec,
+ args: VecDeque,
+) -> PartialVMResult {
+ debug_assert!(ty_args.is_empty());
+ debug_assert!(args.is_empty());
+
+ let tx_context_ids_created_cost_params = context
+ .extensions_mut()
+ .get::()
+ .tx_context_ids_created_cost_params
+ .clone();
+ native_charge_gas_early_exit!(
+ context,
+ tx_context_ids_created_cost_params.tx_context_ids_created_cost_base
+ );
+
+ let transaction_context: &mut TransactionContext = context.extensions_mut().get_mut();
+ let ids_created = transaction_context.ids_created();
+
+ Ok(NativeResult::ok(
+ context.gas_used(),
+ smallvec![Value::u64(ids_created)],
+ ))
+}
+
+// //
+// // Test only function
+// //
+#[derive(Clone)]
+pub struct TxContextReplaceCostParams {
+ pub tx_context_replace_cost_base: InternalGas,
+}
+/***************************************************************************************************
+ * native fun native_replace
+ * Implementation of the Move native function
+ * ```
+ * fun native_replace(
+ * sender: address,
+ * tx_hash: vector,
+ * epoch: u64,
+ * epoch_timestamp_ms: u64,
+ * ids_created: u64,
+ * )
+ * ```
+ * Used by all testing functions that have to change a value in the `TransactionContext`.
+ **************************************************************************************************/
+pub fn replace(
+ context: &mut NativeContext,
+ ty_args: Vec,
+ mut args: VecDeque,
+) -> PartialVMResult {
+ debug_assert!(ty_args.is_empty());
+ debug_assert!(args.len() == 5);
+
+ let tx_context_replace_cost_params = context
+ .extensions_mut()
+ .get::()
+ .tx_context_replace_cost_params
+ .clone();
+ native_charge_gas_early_exit!(
+ context,
+ tx_context_replace_cost_params.tx_context_replace_cost_base
+ );
+
+ let ids_created: u64 = pop_arg!(args, u64);
+ let epoch_timestamp_ms: u64 = pop_arg!(args, u64);
+ let epoch: u64 = pop_arg!(args, u64);
+ let tx_hash: Vec = pop_arg!(args, Vec);
+ let sender: AccountAddress = pop_arg!(args, AccountAddress);
+ let transaction_context: &mut TransactionContext = context.extensions_mut().get_mut();
+ transaction_context.replace(sender, tx_hash, epoch, epoch_timestamp_ms, ids_created);
+
+ Ok(NativeResult::ok(context.gas_used(), smallvec![]))
+}
diff --git a/sui-execution/src/latest.rs b/sui-execution/src/latest.rs
index 125cd9dcd8a02..821c9cd5a7d1d 100644
--- a/sui-execution/src/latest.rs
+++ b/sui-execution/src/latest.rs
@@ -4,7 +4,7 @@
use move_binary_format::CompiledModule;
use move_trace_format::format::MoveTraceBuilder;
use move_vm_config::verifier::{MeterConfig, VerifierConfig};
-use std::{collections::HashSet, path::PathBuf, sync::Arc};
+use std::{cell::RefCell, collections::HashSet, path::PathBuf, rc::Rc, sync::Arc};
use sui_protocol_config::ProtocolConfig;
use sui_types::execution::ExecutionTiming;
use sui_types::transaction::GasData;
@@ -180,21 +180,24 @@ impl executor::Executor for Executor {
input_objects: CheckedInputObjects,
pt: ProgrammableTransaction,
) -> Result {
- let mut tx_context = TxContext::new_from_components(
+ let tx_context = TxContext::new_from_components(
&SuiAddress::default(),
transaction_digest,
&epoch_id,
epoch_timestamp_ms,
- // genesis transaction: RGP: 1, sponsor: None
+ // genesis transaction: RGP: 1, budget: 1M, sponsor: None
1,
+ 1_000_000,
None,
+ protocol_config.move_native_context(),
);
+ let tx_context = Rc::new(RefCell::new(tx_context));
execute_genesis_state_update(
store,
protocol_config,
metrics,
&self.0,
- &mut tx_context,
+ tx_context,
input_objects,
pt,
)
diff --git a/sui-execution/src/v0.rs b/sui-execution/src/v0.rs
index 3d19d57eb172a..08aeac9c5f835 100644
--- a/sui-execution/src/v0.rs
+++ b/sui-execution/src/v0.rs
@@ -188,10 +188,12 @@ impl executor::Executor for Executor {
transaction_digest,
&epoch_id,
epoch_timestamp_ms,
- // genesis transaction: RGP: 1, sponsor: None
+ // genesis transaction: RGP: 1, budget: 1M, sponsor: None
// Those values are unused anyway in execution versions before 3 (or latest)
1,
+ 1_000_000,
None,
+ protocol_config.move_native_context(),
);
execute_genesis_state_update(
store,
diff --git a/sui-execution/src/v1.rs b/sui-execution/src/v1.rs
index 8fdf1996f4bd2..04bc7fd89a163 100644
--- a/sui-execution/src/v1.rs
+++ b/sui-execution/src/v1.rs
@@ -188,10 +188,12 @@ impl executor::Executor for Executor {
transaction_digest,
&epoch_id,
epoch_timestamp_ms,
- // genesis transaction: RGP: 1, sponsor: None
+ // genesis transaction: RGP: 1, budget: 1M, sponsor: None
// Those values are unused anyway in execution versions before 3 (or latest)
1,
+ 1_000_000,
None,
+ protocol_config.move_native_context(),
);
execute_genesis_state_update(
store,
diff --git a/sui-execution/src/v2.rs b/sui-execution/src/v2.rs
index fd332db0663b4..b8d5b442d2b22 100644
--- a/sui-execution/src/v2.rs
+++ b/sui-execution/src/v2.rs
@@ -188,10 +188,12 @@ impl executor::Executor for Executor {
transaction_digest,
&epoch_id,
epoch_timestamp_ms,
- // genesis transaction: RGP: 1, sponsor: None
+ // genesis transaction: RGP: 1, budget: 1M, sponsor: None
// Those values are unused anyway in execution versions before 3 (or latest)
1,
+ 1_000_000,
None,
+ protocol_config.move_native_context(),
);
execute_genesis_state_update(
store,
diff --git a/sui-execution/v0/sui-adapter/src/execution_engine.rs b/sui-execution/v0/sui-adapter/src/execution_engine.rs
index 920e1552cd733..20c2e7960ff29 100644
--- a/sui-execution/v0/sui-adapter/src/execution_engine.rs
+++ b/sui-execution/v0/sui-adapter/src/execution_engine.rs
@@ -89,7 +89,9 @@ mod checked {
epoch_timestamp_ms,
// Those values are unused in execution versions before 3 (or latest)
1,
+ 1_000_000,
None,
+ protocol_config.move_native_context(),
);
let is_epoch_change = matches!(transaction_kind, TransactionKind::ChangeEpoch(_));
diff --git a/sui-execution/v1/sui-adapter/src/execution_engine.rs b/sui-execution/v1/sui-adapter/src/execution_engine.rs
index 1670794ed301e..1722ebc09db1c 100644
--- a/sui-execution/v1/sui-adapter/src/execution_engine.rs
+++ b/sui-execution/v1/sui-adapter/src/execution_engine.rs
@@ -105,7 +105,9 @@ mod checked {
epoch_timestamp_ms,
// Those values are unused in execution versions before 3 (or latest)
1,
+ 1_000_000,
None,
+ protocol_config.move_native_context(),
);
let is_epoch_change = transaction_kind.is_end_of_epoch_tx();
diff --git a/sui-execution/v2/sui-adapter/src/execution_engine.rs b/sui-execution/v2/sui-adapter/src/execution_engine.rs
index 1cf536717eb6c..b16f514de8640 100644
--- a/sui-execution/v2/sui-adapter/src/execution_engine.rs
+++ b/sui-execution/v2/sui-adapter/src/execution_engine.rs
@@ -116,7 +116,9 @@ mod checked {
epoch_timestamp_ms,
// Those values are unused in execution versions before 3 (or latest)
1,
+ 1_000_000,
None,
+ protocol_config.move_native_context(),
);
let is_epoch_change = transaction_kind.is_end_of_epoch_tx();