diff --git a/crates/sui/src/client_commands.rs b/crates/sui/src/client_commands.rs index 59eb70b5b74d5..2dc7c97407146 100644 --- a/crates/sui/src/client_commands.rs +++ b/crates/sui/src/client_commands.rs @@ -81,6 +81,7 @@ use crate::key_identity::{get_identity_address, KeyIdentity}; #[cfg(test)] mod profiler_tests; +#[macro_export] macro_rules! serialize_or_execute { ($tx_data:expr, $serialize_unsigned:expr, $serialize_signed:expr, $context:expr, $result_variant:ident) => {{ assert!( diff --git a/crates/sui/src/client_ptb/ast.rs b/crates/sui/src/client_ptb/ast.rs index 20539d7686cba..9604828b60729 100644 --- a/crates/sui/src/client_ptb/ast.rs +++ b/crates/sui/src/client_ptb/ast.rs @@ -31,6 +31,8 @@ pub const GAS_BUDGET: &str = "gas-budget"; pub const SUMMARY: &str = "summary"; pub const GAS_COIN: &str = "gas-coin"; pub const JSON: &str = "json"; +pub const SERIALIZE_UNSIGNED: &str = "serialize-unsigned-transaction"; +pub const SERIALIZE_SIGNED: &str = "serialize-signed-transaction"; // Types pub const U8: &str = "u8"; @@ -67,6 +69,8 @@ pub const COMMANDS: &[&str] = &[ SUMMARY, GAS_COIN, JSON, + SERIALIZE_UNSIGNED, + SERIALIZE_SIGNED, ]; pub fn is_keyword(s: &str) -> bool { @@ -97,6 +101,8 @@ pub struct Program { pub struct ProgramMetadata { pub preview_set: bool, pub summary_set: bool, + pub serialize_unsigned_set: bool, + pub serialize_signed_set: bool, pub gas_object_id: Option>, pub json_set: bool, pub gas_budget: Spanned, diff --git a/crates/sui/src/client_ptb/parser.rs b/crates/sui/src/client_ptb/parser.rs index 9491fda1ac9fa..5021a5eca3098 100644 --- a/crates/sui/src/client_ptb/parser.rs +++ b/crates/sui/src/client_ptb/parser.rs @@ -37,6 +37,8 @@ struct ProgramParsingState { preview_set: bool, summary_set: bool, warn_shadows_set: bool, + serialize_unsigned_set: bool, + serialize_signed_set: bool, json_set: bool, gas_object_id: Option>, gas_budget: Option>, @@ -56,6 +58,8 @@ impl<'a, I: Iterator> ProgramParser<'a, I> { preview_set: false, summary_set: false, warn_shadows_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, json_set: false, gas_object_id: None, gas_budget: None, @@ -99,6 +103,8 @@ impl<'a, I: Iterator> ProgramParser<'a, I> { } match lexeme { + L(T::Command, A::SERIALIZE_UNSIGNED) => flag!(serialize_unsigned_set), + L(T::Command, A::SERIALIZE_SIGNED) => flag!(serialize_signed_set), L(T::Command, A::SUMMARY) => flag!(summary_set), L(T::Command, A::JSON) => flag!(json_set), L(T::Command, A::PREVIEW) => flag!(preview_set), @@ -201,6 +207,8 @@ impl<'a, I: Iterator> ProgramParser<'a, I> { A::ProgramMetadata { preview_set: self.state.preview_set, summary_set: self.state.summary_set, + serialize_unsigned_set: self.state.serialize_unsigned_set, + serialize_signed_set: self.state.serialize_signed_set, gas_object_id: self.state.gas_object_id, json_set: self.state.json_set, gas_budget, diff --git a/crates/sui/src/client_ptb/ptb.rs b/crates/sui/src/client_ptb/ptb.rs index 4ca021487e952..e18f90d7f62e1 100644 --- a/crates/sui/src/client_ptb/ptb.rs +++ b/crates/sui/src/client_ptb/ptb.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ + client_commands::SuiClientCommandResult, client_ptb::{ ast::{ParsedProgram, Program}, builder::PTBBuilder, @@ -12,6 +13,8 @@ use crate::{ sp, }; +use super::{ast::ProgramMetadata, lexer::Lexer, parser::ProgramParser}; +use crate::serialize_or_execute; use anyhow::{anyhow, Error}; use clap::{arg, Args, ValueHint}; use move_core_types::account_address::AccountAddress; @@ -27,11 +30,11 @@ use sui_types::{ digests::TransactionDigest, gas::GasCostSummary, quorum_driver_types::ExecuteTransactionRequestType, - transaction::{ProgrammableTransaction, Transaction, TransactionData}, + transaction::{ + ProgrammableTransaction, SenderSignedData, Transaction, TransactionData, TransactionDataAPI, + }, }; -use super::{ast::ProgramMetadata, lexer::Lexer, parser::ProgramParser}; - #[derive(Clone, Debug, Args)] #[clap(disable_help_flag = true)] pub struct PTB { @@ -88,6 +91,10 @@ impl PTB { Ok(parsed) => parsed, }; + if program_metadata.serialize_unsigned_set && program_metadata.serialize_signed_set { + anyhow::bail!("Cannot serialize both signed and unsigned PTBs"); + } + if program_metadata.preview_set { println!( "{}", @@ -157,6 +164,17 @@ impl PTB { program_metadata.gas_budget.value, gas_price, ); + + if program_metadata.serialize_unsigned_set { + serialize_or_execute!(tx_data, true, false, context, PTB).print(true); + return Ok(()); + } + + if program_metadata.serialize_signed_set { + serialize_or_execute!(tx_data, false, true, context, PTB).print(true); + return Ok(()); + } + // sign the tx let signature = context @@ -382,6 +400,16 @@ pub fn ptb_description() -> clap::Command { --"preview" "Preview the list of PTB transactions instead of executing them." )) + .arg(arg!( + --"serialize-unsigned-transaction" + "Instead of executing the transaction, serialize the bcs bytes of the unsigned \ + transaction data using base64 encoding." + )) + .arg(arg!( + --"serialize-signed-transaction" + "Instead of executing the transaction, serialize the bcs bytes of the signed \ + transaction data using base64 encoding." + )) .arg(arg!( --"summary" "Show only a short summary (digest, execution status, gas cost). \ diff --git a/crates/sui/src/client_ptb/snapshots/sui__client_ptb__parser__tests__parse_commands.snap b/crates/sui/src/client_ptb/snapshots/sui__client_ptb__parser__tests__parse_commands.snap index ac6792a0a0ce7..d8ac25d236e61 100644 --- a/crates/sui/src/client_ptb/snapshots/sui__client_ptb__parser__tests__parse_commands.snap +++ b/crates/sui/src/client_ptb/snapshots/sui__client_ptb__parser__tests__parse_commands.snap @@ -27,6 +27,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -62,6 +64,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -106,6 +110,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -169,6 +175,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -223,6 +231,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -292,6 +302,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -355,6 +367,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -409,6 +423,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -472,6 +488,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -526,6 +544,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -568,6 +588,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -629,6 +651,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -737,6 +761,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -822,6 +848,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -907,6 +935,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -943,6 +973,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -1004,6 +1036,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -1050,6 +1084,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -1096,6 +1132,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -1170,6 +1208,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -1222,6 +1262,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -1278,6 +1320,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -1297,6 +1341,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: Some( Spanned { span: Span { @@ -1324,6 +1370,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: true, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -1343,6 +1391,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: true, gas_budget: Spanned { @@ -1362,6 +1412,8 @@ expression: parsed ProgramMetadata { preview_set: true, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -1381,6 +1433,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { diff --git a/crates/sui/src/client_ptb/snapshots/sui__client_ptb__parser__tests__parse_publish.snap b/crates/sui/src/client_ptb/snapshots/sui__client_ptb__parser__tests__parse_publish.snap index ca0feb1be39e3..e4ac714c42be8 100644 --- a/crates/sui/src/client_ptb/snapshots/sui__client_ptb__parser__tests__parse_publish.snap +++ b/crates/sui/src/client_ptb/snapshots/sui__client_ptb__parser__tests__parse_publish.snap @@ -27,6 +27,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { @@ -62,6 +64,8 @@ expression: parsed ProgramMetadata { preview_set: false, summary_set: false, + serialize_unsigned_set: false, + serialize_signed_set: false, gas_object_id: None, json_set: false, gas_budget: Spanned { diff --git a/crates/sui/src/lib.rs b/crates/sui/src/lib.rs index 071f5258cb605..148112334045e 100644 --- a/crates/sui/src/lib.rs +++ b/crates/sui/src/lib.rs @@ -3,6 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 pub mod client_commands; +#[macro_use] pub mod client_ptb; pub mod console; pub mod fire_drill;