Skip to content

Commit

Permalink
Allow sui client call command to set gas price (#16648)
Browse files Browse the repository at this point in the history
## Description 

This PR only adds the `gas_price` option in the `sui client call`
command.

I can add this option to other `sui client` command if there is a need
for it.

## Test Plan 

How did you test the new or updated feature?

---
If your changes are not user-facing and do not break anything, you can
skip the following section. Otherwise, please briefly describe what has
changed under the Release Notes section.

### Type of Change (Check all that apply)

- [ ] protocol change
- [ ] user-visible impact
- [ ] breaking change for a client SDKs
- [ ] breaking change for FNs (FN binary must upgrade)
- [ ] breaking change for validators or node operators (must upgrade
binaries)
- [ ] breaking change for on-chain data layout
- [ ] necessitate either a data wipe or data migration

### Release notes
  • Loading branch information
halfprice authored Mar 17, 2024
1 parent 49102dd commit 8df080f
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 4 deletions.
7 changes: 7 additions & 0 deletions crates/sui-cluster-test/src/test_case/coin_index_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ impl TestCaseImpl for CoinIndexTest {
args,
None,
rgp * 2_000_000,
None,
)
.await
.unwrap();
Expand Down Expand Up @@ -251,6 +252,7 @@ impl TestCaseImpl for CoinIndexTest {
],
None,
rgp * 2_000_000,
None,
)
.await
.unwrap();
Expand Down Expand Up @@ -316,6 +318,7 @@ impl TestCaseImpl for CoinIndexTest {
args,
None,
rgp * 2_000_000,
None,
)
.await
.unwrap();
Expand Down Expand Up @@ -355,6 +358,7 @@ impl TestCaseImpl for CoinIndexTest {
],
None,
rgp * 2_000_000,
None,
)
.await
.unwrap();
Expand Down Expand Up @@ -386,6 +390,7 @@ impl TestCaseImpl for CoinIndexTest {
],
None,
rgp * 2_000_000,
None,
)
.await
.unwrap();
Expand Down Expand Up @@ -455,6 +460,7 @@ impl TestCaseImpl for CoinIndexTest {
],
None,
rgp * 2_000_000,
None,
)
.await
.unwrap();
Expand Down Expand Up @@ -701,6 +707,7 @@ async fn add_to_envelope(
],
None,
rgp * 2_000_000,
None,
)
.await
.unwrap();
Expand Down
1 change: 1 addition & 0 deletions crates/sui-json-rpc/src/transaction_builder_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ impl TransactionBuilderServer for TransactionBuilderApi {
rpc_arguments,
gas,
*gas_budget,
None,
)
.await?,
)?)
Expand Down
2 changes: 2 additions & 0 deletions crates/sui-sdk/examples/tic_tac_toe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ impl TicTacToe {
],
None, // The node will pick a gas object belong to the signer if not provided.
1000,
None,
)
.await?;

Expand Down Expand Up @@ -188,6 +189,7 @@ impl TicTacToe {
],
None,
1000,
None,
)
.await?;

Expand Down
7 changes: 6 additions & 1 deletion crates/sui-transaction-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ impl TransactionBuilder {
call_args: Vec<SuiJsonValue>,
gas: Option<ObjectID>,
gas_budget: u64,
gas_price: Option<u64>,
) -> anyhow::Result<TransactionData> {
let mut builder = ProgrammableTransactionBuilder::new();
self.single_move_call(
Expand All @@ -279,7 +280,11 @@ impl TransactionBuilder {
_ => None,
})
.collect();
let gas_price = self.0.get_reference_gas_price().await?;
let gas_price = if let Some(gas_price) = gas_price {
gas_price
} else {
self.0.get_reference_gas_price().await?
};
let gas = self
.select_gas(signer, gas, gas_budget, input_objects, gas_price)
.await?;
Expand Down
11 changes: 9 additions & 2 deletions crates/sui/src/client_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,10 @@ pub enum SuiClientCommands {
#[clap(long)]
gas_budget: u64,

/// Optional gas price for this call. Currently use only for testing and not in production enviroments.
#[clap(hide = true)]
gas_price: Option<u64>,

/// Instead of executing the transaction, serialize the bcs bytes of the unsigned transaction data
/// (TransactionData) using base64 encoding, and print out the string <TX_BYTES>. The string can
/// be used to execute transaction with `sui client execute-signed-tx --tx-bytes <TX_BYTES>`.
Expand Down Expand Up @@ -1128,12 +1132,14 @@ impl SuiClientCommands {
type_args,
gas,
gas_budget,
gas_price,
args,
serialize_unsigned_transaction,
serialize_signed_transaction,
} => {
let tx_data = construct_move_call_transaction(
package, &module, &function, type_args, gas, gas_budget, args, context,
package, &module, &function, type_args, gas, gas_budget, gas_price, args,
context,
)
.await?;
serialize_or_execute!(
Expand Down Expand Up @@ -2070,6 +2076,7 @@ async fn construct_move_call_transaction(
type_args: Vec<TypeTag>,
gas: Option<ObjectID>,
gas_budget: u64,
gas_price: Option<u64>,
args: Vec<SuiJsonValue>,
context: &mut WalletContext,
) -> Result<TransactionData, anyhow::Error> {
Expand All @@ -2090,7 +2097,7 @@ async fn construct_move_call_transaction(
client
.transaction_builder()
.move_call(
sender, package, module, function, type_args, args, gas, gas_budget,
sender, package, module, function, type_args, args, gas, gas_budget, gas_price,
)
.await
}
Expand Down
72 changes: 71 additions & 1 deletion crates/sui/tests/cli_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ use sui_config::{
use sui_json::SuiJsonValue;
use sui_json_rpc_types::{
OwnedObjectRef, SuiObjectData, SuiObjectDataFilter, SuiObjectDataOptions, SuiObjectResponse,
SuiObjectResponseQuery, SuiTransactionBlockEffects, SuiTransactionBlockEffectsAPI,
SuiObjectResponseQuery, SuiTransactionBlockDataAPI, SuiTransactionBlockEffects,
SuiTransactionBlockEffectsAPI,
};
use sui_keys::keystore::AccountKeystore;
use sui_macros::sim_test;
Expand Down Expand Up @@ -259,6 +260,7 @@ async fn test_ptb_publish_and_complex_arg_resolution() -> Result<(), anyhow::Err
type_args: vec![],
gas: None,
gas_budget: rgp * TEST_ONLY_GAS_UNIT_FOR_PUBLISH,
gas_price: None,
args: vec![],
serialize_unsigned_transaction: false,
serialize_signed_transaction: false,
Expand Down Expand Up @@ -606,6 +608,7 @@ async fn test_move_call_args_linter_command() -> Result<(), anyhow::Error> {
args,
gas: None,
gas_budget: TEST_ONLY_GAS_UNIT_FOR_OBJECT_BASICS * rgp,
gas_price: None,
serialize_unsigned_transaction: false,
serialize_signed_transaction: false,
}
Expand Down Expand Up @@ -645,6 +648,7 @@ async fn test_move_call_args_linter_command() -> Result<(), anyhow::Error> {
args: args.to_vec(),
gas: Some(gas),
gas_budget: TEST_ONLY_GAS_UNIT_FOR_OBJECT_BASICS * rgp,
gas_price: None,
serialize_unsigned_transaction: false,
serialize_signed_transaction: false,
}
Expand All @@ -671,6 +675,7 @@ async fn test_move_call_args_linter_command() -> Result<(), anyhow::Error> {
args: args.to_vec(),
gas: Some(gas),
gas_budget: TEST_ONLY_GAS_UNIT_FOR_OBJECT_BASICS * rgp,
gas_price: None,
serialize_unsigned_transaction: false,
serialize_signed_transaction: false,
}
Expand All @@ -679,6 +684,32 @@ async fn test_move_call_args_linter_command() -> Result<(), anyhow::Error> {

assert!(resp.is_err());

// Try a transfer with explicitly set gas price.
// It should fail due to that gas price is below RGP.
let args = vec![
SuiJsonValue::new(json!(created_obj))?,
SuiJsonValue::new(json!(address2))?,
];

let resp = SuiClientCommands::Call {
package,
module: "object_basics".to_string(),
function: "transfer".to_string(),
type_args: vec![],
args: args.to_vec(),
gas: Some(gas),
gas_budget: rgp * TEST_ONLY_GAS_UNIT_FOR_OBJECT_BASICS,
gas_price: Some(1),
serialize_unsigned_transaction: false,
serialize_signed_transaction: false,
}
.execute(context)
.await;

assert!(resp.is_err());
let err_string = format!("{} ", resp.err().unwrap());
assert!(err_string.contains("Gas price 1 under reference gas price"));

// FIXME: uncomment once we figure out what is going on with `resolve_and_type_check`
// let err_string = format!("{} ", resp.err().unwrap());
// let framework_addr = SUI_FRAMEWORK_ADDRESS.to_hex_literal();
Expand All @@ -699,12 +730,43 @@ async fn test_move_call_args_linter_command() -> Result<(), anyhow::Error> {
args: args.to_vec(),
gas: Some(gas),
gas_budget: rgp * TEST_ONLY_GAS_UNIT_FOR_OBJECT_BASICS,
gas_price: None,
serialize_unsigned_transaction: false,
serialize_signed_transaction: false,
}
.execute(context)
.await?;

// Try a call with customized gas price.
let args = vec![
SuiJsonValue::new(json!("123"))?,
SuiJsonValue::new(json!(address1))?,
];

let result = SuiClientCommands::Call {
package,
module: "object_basics".to_string(),
function: "create".to_string(),
type_args: vec![],
args,
gas: None,
gas_budget: TEST_ONLY_GAS_UNIT_FOR_OBJECT_BASICS * rgp,
gas_price: Some(12345),
serialize_unsigned_transaction: false,
serialize_signed_transaction: false,
}
.execute(context)
.await?;

if let SuiClientCommandResult::Call(txn_response) = result {
assert_eq!(
txn_response.transaction.unwrap().data.gas_data().price,
12345
);
} else {
panic!("Command failed with unexpected result.")
};

Ok(())
}

Expand Down Expand Up @@ -845,6 +907,7 @@ async fn test_delete_shared_object() -> Result<(), anyhow::Error> {
type_args: vec![],
gas: None,
gas_budget: rgp * TEST_ONLY_GAS_UNIT_FOR_PUBLISH,
gas_price: None,
args: vec![],
serialize_unsigned_transaction: false,
serialize_signed_transaction: false,
Expand All @@ -867,6 +930,7 @@ async fn test_delete_shared_object() -> Result<(), anyhow::Error> {
type_args: vec![],
gas: None,
gas_budget: rgp * TEST_ONLY_GAS_UNIT_FOR_PUBLISH,
gas_price: None,
args: vec![SuiJsonValue::from_str(&shared_id.to_string()).unwrap()],
serialize_unsigned_transaction: false,
serialize_signed_transaction: false,
Expand Down Expand Up @@ -952,6 +1016,7 @@ async fn test_receive_argument() -> Result<(), anyhow::Error> {
type_args: vec![],
gas: None,
gas_budget: rgp * TEST_ONLY_GAS_UNIT_FOR_PUBLISH,
gas_price: None,
args: vec![],
serialize_unsigned_transaction: false,
serialize_signed_transaction: false,
Expand Down Expand Up @@ -990,6 +1055,7 @@ async fn test_receive_argument() -> Result<(), anyhow::Error> {
type_args: vec![],
gas: None,
gas_budget: rgp * TEST_ONLY_GAS_UNIT_FOR_PUBLISH,
gas_price: None,
args: vec![
SuiJsonValue::from_str(&parent.object_id.to_string()).unwrap(),
SuiJsonValue::from_str(&child.object_id.to_string()).unwrap(),
Expand Down Expand Up @@ -1078,6 +1144,7 @@ async fn test_receive_argument_by_immut_ref() -> Result<(), anyhow::Error> {
type_args: vec![],
gas: None,
gas_budget: rgp * TEST_ONLY_GAS_UNIT_FOR_PUBLISH,
gas_price: None,
args: vec![],
serialize_unsigned_transaction: false,
serialize_signed_transaction: false,
Expand Down Expand Up @@ -1116,6 +1183,7 @@ async fn test_receive_argument_by_immut_ref() -> Result<(), anyhow::Error> {
type_args: vec![],
gas: None,
gas_budget: rgp * TEST_ONLY_GAS_UNIT_FOR_PUBLISH,
gas_price: None,
args: vec![
SuiJsonValue::from_str(&parent.object_id.to_string()).unwrap(),
SuiJsonValue::from_str(&child.object_id.to_string()).unwrap(),
Expand Down Expand Up @@ -1204,6 +1272,7 @@ async fn test_receive_argument_by_mut_ref() -> Result<(), anyhow::Error> {
type_args: vec![],
gas: None,
gas_budget: rgp * TEST_ONLY_GAS_UNIT_FOR_PUBLISH,
gas_price: None,
args: vec![],
serialize_unsigned_transaction: false,
serialize_signed_transaction: false,
Expand Down Expand Up @@ -1242,6 +1311,7 @@ async fn test_receive_argument_by_mut_ref() -> Result<(), anyhow::Error> {
type_args: vec![],
gas: None,
gas_budget: rgp * TEST_ONLY_GAS_UNIT_FOR_PUBLISH,
gas_price: None,
args: vec![
SuiJsonValue::from_str(&parent.object_id.to_string()).unwrap(),
SuiJsonValue::from_str(&child.object_id.to_string()).unwrap(),
Expand Down

0 comments on commit 8df080f

Please sign in to comment.