From f18852fe57aa3b853f7687a9342c6843a38def0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Papierski?= Date: Tue, 13 Aug 2024 16:53:55 +0200 Subject: [PATCH 1/6] Fix tests --- lib/cli/simple_args.rs | 4 ++-- lib/cli/tests.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/cli/simple_args.rs b/lib/cli/simple_args.rs index 86c2fbb9..20098dd5 100644 --- a/lib/cli/simple_args.rs +++ b/lib/cli/simple_args.rs @@ -2,7 +2,7 @@ pub mod help; -use std::{fmt::Debug, mem, str::FromStr}; +use std::{fmt::Debug, str::FromStr}; use num_traits::Num; @@ -87,7 +87,7 @@ fn parse_int( value: &str, ) -> Result { let parse = || { - let bit_width = mem::size_of::() * 8; + let bit_width = size_of::() * 8; if value.is_empty() { return Err(CliError::InvalidCLValue(format!( "can't parse '' as u{}", diff --git a/lib/cli/tests.rs b/lib/cli/tests.rs index e301b6ce..8f96c375 100644 --- a/lib/cli/tests.rs +++ b/lib/cli/tests.rs @@ -481,8 +481,8 @@ mod transaction { #[test] fn should_sign_transaction() { - let bytes = SAMPLE_TRANSACTION.as_bytes(); - let transaction = crate::read_transaction(bytes).unwrap(); + let bytes = serde_json::to_string_pretty(&*SAMPLE_TRANSACTION).unwrap(); + let transaction = crate::read_transaction(bytes.as_bytes()).unwrap(); assert_eq!( transaction.approvals().len(), 0, From 0235430000236af0fc2c8e1a369d29f90fb50ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Papierski?= Date: Tue, 13 Aug 2024 19:03:53 +0200 Subject: [PATCH 2/6] Add bunch of new args. --- Cargo.toml | 3 +- lib/cli/parse.rs | 30 ++++ lib/cli/tests.rs | 50 ++++++- lib/cli/transaction.rs | 38 +++-- lib/cli/transaction_builder_params.rs | 14 ++ lib/cli/transaction_str_params.rs | 8 ++ src/transaction/creation_common.rs | 200 ++++++++++++++++++++++++-- 7 files changed, 323 insertions(+), 20 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5520da9c..97464236 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,7 +59,8 @@ uint = "0.9.5" tempfile = "3.8.1" [patch.crates-io] -casper-types = { version = "5.0.0", git = "https://github.com/casper-network/casper-node", branch = "feat-2.0" } +#casper-types = { git = "https://github.com/mpapierski/casper-node.git", branch = "new-execution-engine" } +casper-types = { path = "../casper-node/types" } [package.metadata.deb] features = ["vendored-openssl"] diff --git a/lib/cli/parse.rs b/lib/cli/parse.rs index d8d05c2d..e5c52f65 100644 --- a/lib/cli/parse.rs +++ b/lib/cli/parse.rs @@ -974,6 +974,32 @@ pub(super) fn pricing_mode( receipt: maybe_receipt.unwrap_or_default(), }) } + "gas-limited" => { + if maybe_gas_limit.is_empty() { + return Err(CliError::InvalidArgument { + context: "pricing_mode", + error: "Gas limited pricing mode requires a provided gas limit".to_string(), + }); + } + let gas_limit = + maybe_gas_limit + .parse::() + .map_err(|error| CliError::FailedToParseInt { + context: "gas_limit", + error, + })?; + let gas_price_tolerance = + maybe_gas_price_tolerance_str + .parse::() + .map_err(|error| CliError::FailedToParseInt { + context: "gas_price_tolerance", + error, + })?; + Ok(PricingMode::GasLimited { + gas_limit, + gas_price_tolerance, + }) + } _ => Err(CliError::InvalidArgument { context: "pricing_mode", error: "Invalid pricing mode identifier".to_string(), @@ -1807,6 +1833,7 @@ mod tests { fn should_parse_fixed_pricing_mode_identifier() { let pricing_mode_str = "fixed"; let payment_amount = ""; + let gas_limit = ""; let gas_price_tolerance = "10"; let additional_computation_factor = "1"; let standard_payment = ""; @@ -1881,6 +1908,7 @@ mod tests { let pricing_mode_str = "classic"; let payment_amount = "10"; let standard_payment = "true"; + let gas_limit = ""; let gas_price_tolerance = "10"; let additional_computation_factor = "0"; let parsed = pricing_mode( @@ -1907,6 +1935,7 @@ mod tests { let pricing_mode_str = "invalid"; let payment_amount = "10"; let standard_payment = "true"; + let gas_limit = ""; let gas_price_tolerance = "10"; let additional_computation_factor = "0"; let parsed = pricing_mode( @@ -1945,6 +1974,7 @@ mod tests { let pricing_mode_str = "classic"; let payment_amount = ""; let standard_payment = "true"; + let gas_limit = ""; let gas_price_tolerance = "10"; let additional_computation_factor = "0"; let parsed = pricing_mode( diff --git a/lib/cli/tests.rs b/lib/cli/tests.rs index 8f96c375..7f543d31 100644 --- a/lib/cli/tests.rs +++ b/lib/cli/tests.rs @@ -530,6 +530,9 @@ mod transaction { additional_computation_factor: "", receipt: SAMPLE_DIGEST, standard_payment: "true", + transferred_value: "0", + gas_limit: "", + session_entry_point: None, }; let transaction_builder_params = TransactionBuilderParams::AddBid { @@ -601,6 +604,9 @@ mod transaction { additional_computation_factor: "", receipt: SAMPLE_DIGEST, standard_payment: "true", + transferred_value: "0", + gas_limit: "", + session_entry_point: None, }; let transaction_builder_params = TransactionBuilderParams::Delegate { @@ -656,7 +662,7 @@ mod transaction { let public_key_cl = &CLValue::from_t(&public_key).unwrap(); let amount_cl = &CLValue::from_t(amount).unwrap(); - let transaction_string_params = TransactionStrParams { + let transaction_str_params = TransactionStrParams { secret_key: "", timestamp: "", ttl: "30min", @@ -671,7 +677,11 @@ mod transaction { additional_computation_factor: "0", receipt: SAMPLE_DIGEST, standard_payment: "true", + transferred_value: "0", + gas_limit: "", + session_entry_point: None, }; + let transaction_string_params = transaction_str_params; let transaction_builder_params = TransactionBuilderParams::WithdrawBid { public_key, amount }; @@ -731,6 +741,9 @@ mod transaction { additional_computation_factor: "0", receipt: SAMPLE_DIGEST, standard_payment: "true", + transferred_value: "0", + gas_limit: "", + session_entry_point: None, }; let transaction_builder_params = TransactionBuilderParams::Undelegate { @@ -807,6 +820,9 @@ mod transaction { additional_computation_factor: "", receipt: SAMPLE_DIGEST, standard_payment: "true", + transferred_value: "0", + gas_limit: "", + session_entry_point: None, }; let transaction_builder_params = TransactionBuilderParams::Redelegate { @@ -888,11 +904,15 @@ mod transaction { additional_computation_factor: "0", receipt: SAMPLE_DIGEST, standard_payment: "true", + transferred_value: "0", + gas_limit: "", + session_entry_point: None, }; let transaction_builder_params = TransactionBuilderParams::InvocableEntity { entity_hash: entity_hash.into(), entry_point: "test-entry-point", + runtime: TransactionRuntime::VmCasperV1, }; let transaction = create_transaction(transaction_builder_params, transaction_string_params, true); @@ -941,11 +961,15 @@ mod transaction { receipt: SAMPLE_DIGEST, additional_computation_factor: "", standard_payment: "true", + transferred_value: "0", + gas_limit: "", + session_entry_point: None, }; let transaction_builder_params = TransactionBuilderParams::InvocableEntityAlias { entity_alias: "alias", entry_point: "entry-point-alias", + runtime: TransactionRuntime::VmCasperV1, }; let transaction = create_transaction(transaction_builder_params, transaction_string_params, true); @@ -998,12 +1022,16 @@ mod transaction { receipt: SAMPLE_DIGEST, additional_computation_factor: "", standard_payment: "true", + transferred_value: "0", + gas_limit: "", + session_entry_point: None, }; let transaction_builder_params = TransactionBuilderParams::Package { package_hash: package_addr.into(), entry_point, maybe_entity_version, + runtime: TransactionRuntime::VmCasperV1, }; let transaction = create_transaction(transaction_builder_params, transaction_string_params, true); @@ -1053,12 +1081,16 @@ mod transaction { additional_computation_factor: "", receipt: SAMPLE_DIGEST, standard_payment: "true", + transferred_value: "0", + gas_limit: "", + session_entry_point: None, }; let transaction_builder_params = TransactionBuilderParams::PackageAlias { package_alias: &package_name, entry_point, maybe_entity_version, + runtime: TransactionRuntime::VmCasperV1, }; let transaction = create_transaction(transaction_builder_params, transaction_string_params, true); @@ -1105,11 +1137,15 @@ mod transaction { additional_computation_factor: "0", receipt: SAMPLE_DIGEST, standard_payment: "true", + transferred_value: "0", + gas_limit: "", + session_entry_point: None, }; let transaction_builder_params = TransactionBuilderParams::Session { is_install_upgrade, transaction_bytes, + runtime: TransactionRuntime::VmCasperV1, }; let transaction = create_transaction(transaction_builder_params, transaction_string_params, true); @@ -1165,6 +1201,9 @@ mod transaction { additional_computation_factor: "1", receipt: SAMPLE_DIGEST, standard_payment: "true", + transferred_value: "0", + gas_limit: "", + session_entry_point: None, }; let transaction_builder_params = TransactionBuilderParams::Transfer { @@ -1223,6 +1262,9 @@ mod transaction { additional_computation_factor: "", receipt: SAMPLE_DIGEST, standard_payment: "true", + transferred_value: "0", + gas_limit: "", + session_entry_point: None, }; let transaction_builder_params = TransactionBuilderParams::Transfer { maybe_source: Default::default(), @@ -1262,6 +1304,9 @@ mod transaction { additional_computation_factor: "", receipt: SAMPLE_DIGEST, standard_payment: "true", + transferred_value: "0", + gas_limit: "", + session_entry_point: None, }; let transaction_builder_params = TransactionBuilderParams::AddBid { public_key: PublicKey::from_hex(SAMPLE_ACCOUNT).unwrap(), @@ -1296,6 +1341,9 @@ mod transaction { additional_computation_factor: "", receipt: SAMPLE_DIGEST, standard_payment: "true", + transferred_value: "0", + gas_limit: "", + session_entry_point: None, }; let transaction_builder_params = TransactionBuilderParams::AddBid { public_key: PublicKey::from_hex(SAMPLE_ACCOUNT).unwrap(), diff --git a/lib/cli/transaction.rs b/lib/cli/transaction.rs index b6df42f3..08c4e83b 100644 --- a/lib/cli/transaction.rs +++ b/lib/cli/transaction.rs @@ -57,6 +57,7 @@ pub fn create_transaction( transaction_params.payment_amount, transaction_params.gas_price_tolerance, transaction_params.additional_computation_factor, + transaction_params.gas_limit, transaction_params.standard_payment, Some(digest), )? @@ -66,6 +67,7 @@ pub fn create_transaction( transaction_params.payment_amount, transaction_params.gas_price_tolerance, transaction_params.additional_computation_factor, + transaction_params.gas_limit, transaction_params.standard_payment, None, )? @@ -81,6 +83,11 @@ pub fn create_transaction( if !args.is_empty() { transaction_builder = transaction_builder.with_runtime_args(args); } + + if let Some(session_entry_point) = transaction_params.session_entry_point { + transaction_builder = transaction_builder.with_entry_point(session_entry_point); + } + if let Some(secret_key) = &maybe_secret_key { transaction_builder = transaction_builder.with_secret_key(secret_key); } @@ -91,6 +98,7 @@ pub fn create_transaction( } let txn = transaction_builder.build().map_err(crate::Error::from)?; + dbg!(&txn); Ok(txn) } @@ -264,19 +272,25 @@ pub fn make_transaction_builder( TransactionBuilderParams::InvocableEntity { entity_hash, entry_point, + runtime, } => { - let transaction_builder = - TransactionV1Builder::new_targeting_invocable_entity(entity_hash, entry_point); + let transaction_builder = TransactionV1Builder::new_targeting_invocable_entity( + entity_hash, + entry_point, + runtime, + ); Ok(transaction_builder) } TransactionBuilderParams::InvocableEntityAlias { entity_alias, entry_point, + runtime, } => { let transaction_builder = TransactionV1Builder::new_targeting_invocable_entity_via_alias( entity_alias, entry_point, + runtime, ); Ok(transaction_builder) } @@ -284,11 +298,13 @@ pub fn make_transaction_builder( package_hash, maybe_entity_version, entry_point, + runtime, } => { let transaction_builder = TransactionV1Builder::new_targeting_package( package_hash, maybe_entity_version, entry_point, + runtime, ); Ok(transaction_builder) } @@ -296,20 +312,26 @@ pub fn make_transaction_builder( package_alias, maybe_entity_version, entry_point, + runtime, } => { - let transaction_builder = TransactionV1Builder::new_targeting_package_via_alias( - package_alias, - maybe_entity_version, - entry_point, - ); + let new_targeting_package_via_alias = + TransactionV1Builder::new_targeting_package_via_alias( + package_alias, + maybe_entity_version, + entry_point, + runtime, + ); + let transaction_builder = new_targeting_package_via_alias; Ok(transaction_builder) } TransactionBuilderParams::Session { is_install_upgrade, transaction_bytes, + transaction_category, + runtime, } => { let transaction_builder = - TransactionV1Builder::new_session(is_install_upgrade, transaction_bytes); + TransactionV1Builder::new_session(is_install_upgrade, transaction_bytes, runtime); Ok(transaction_builder) } TransactionBuilderParams::Transfer { diff --git a/lib/cli/transaction_builder_params.rs b/lib/cli/transaction_builder_params.rs index 803058f0..50a04e90 100644 --- a/lib/cli/transaction_builder_params.rs +++ b/lib/cli/transaction_builder_params.rs @@ -1,5 +1,9 @@ use casper_types::bytesrepr::Bytes; use casper_types::{AddressableEntityHash, PackageHash, PublicKey, TransferTarget, URef, U512}; +use casper_types::{ + AddressableEntityHash, PackageHash, PublicKey, TransactionCategory, TransactionRuntime, + TransferTarget, URef, U512, +}; /// An enum representing the parameters needed to construct a transaction builder /// for the commands concerning the creation of a transaction @@ -54,6 +58,8 @@ pub enum TransactionBuilderParams<'a> { entity_hash: AddressableEntityHash, /// The entry point for the invocable entity transaction entry_point: &'a str, + /// Transaction Runtime. + runtime: TransactionRuntime, }, /// Parameters for the invocable entity alias variant of the transaction builder InvocableEntityAlias { @@ -61,6 +67,8 @@ pub enum TransactionBuilderParams<'a> { entity_alias: &'a str, /// The entry_point for the invocable entity alias transaction entry_point: &'a str, + /// Transaction Runtime. + runtime: TransactionRuntime, }, /// Parameters for the package variant of the transaction builder Package { @@ -70,6 +78,8 @@ pub enum TransactionBuilderParams<'a> { maybe_entity_version: Option, /// The entry_point for the package transaction entry_point: &'a str, + /// Transaction Runtime. + runtime: TransactionRuntime, }, /// Parameters for the package alias variant of the transaction builder PackageAlias { @@ -79,6 +89,8 @@ pub enum TransactionBuilderParams<'a> { maybe_entity_version: Option, /// The entry point for the package alias transaction entry_point: &'a str, + /// Transaction Runtime. + runtime: TransactionRuntime, }, /// Parameters for the session variant of the transaction builder Session { @@ -86,6 +98,8 @@ pub enum TransactionBuilderParams<'a> { is_install_upgrade: bool, /// The Bytes to be run by the execution engine for the session transaction transaction_bytes: Bytes, + /// Transaction Runtime. + runtime: TransactionRuntime, }, /// Parameters for the transfer variant of the transaction builder Transfer { diff --git a/lib/cli/transaction_str_params.rs b/lib/cli/transaction_str_params.rs index 017c3210..89207834 100644 --- a/lib/cli/transaction_str_params.rs +++ b/lib/cli/transaction_str_params.rs @@ -69,4 +69,12 @@ pub struct TransactionStrParams<'a> { pub receipt: &'a str, /// Standard payment. pub standard_payment: &'a str, + /// Gas limit for the transaction. + pub gas_limit: &'a str, + /// Transaferred value. + pub transferred_value: &'a str, + /// The entry point for the session. + /// + /// None means "call" (aka default) entry point. + pub session_entry_point: Option<&'a str>, } diff --git a/src/transaction/creation_common.rs b/src/transaction/creation_common.rs index 4e29bde7..1b3a3e82 100644 --- a/src/transaction/creation_common.rs +++ b/src/transaction/creation_common.rs @@ -30,6 +30,8 @@ pub(super) enum DisplayOrder { TransferId, Timestamp, Ttl, + TransactionCategory, + TransferredValue, ChainName, MaximumDelegationRate, MinimumDelegationRate, @@ -44,11 +46,13 @@ pub(super) enum DisplayOrder { EntityAlias, PaymentAmount, PricingMode, + TransactionRuntime, StandardPayment, Receipt, GasPriceTolerance, AdditionalComputationFactor, IsInstallUpgrade, + GasLimit, TransactionAmount, Validator, NewValidator, @@ -407,6 +411,35 @@ pub(super) mod gas_price_tolerance { } } +pub(super) mod gas_limit { + use super::*; + pub(in crate::transaction) const ARG_NAME: &str = "gas-limit"; + + const ARG_VALUE_NAME: &str = common::ARG_INTEGER; + + const ARG_ALIAS: &str = "gas-limit"; + const ARG_SHORT: char = 'l'; + const ARG_HELP: &str = + "The maximum amount of gas the user is willing to pay for the transaction"; + + pub(in crate::transaction) fn arg() -> Arg { + Arg::new(ARG_NAME) + .long(ARG_NAME) + .alias(ARG_ALIAS) + .short(ARG_SHORT) + .required(true) + .value_name(ARG_VALUE_NAME) + .help(ARG_HELP) + .display_order(DisplayOrder::GasPriceTolerance as usize) + } + + pub fn get(matches: &ArgMatches) -> &str { + matches + .get_one::(ARG_NAME) + .map(String::as_str) + .unwrap_or_default() + } +} pub(super) mod transfer_amount { use super::*; pub(in crate::transaction) const ARG_NAME: &str = "transfer-amount"; @@ -460,25 +493,28 @@ pub(super) mod pricing_mode { Classic, Reserved, Fixed, + GasLimited, } impl PricingMode { const CLASSIC: &'static str = "classic"; const RESERVED: &'static str = "reserved"; const FIXED: &'static str = "fixed"; + const GAS_LIMITED: &'static str = "gas-limited"; pub(crate) fn as_str(&self) -> &str { match self { Self::Classic => Self::CLASSIC, Self::Reserved => Self::RESERVED, Self::Fixed => Self::FIXED, + Self::GasLimited => Self::GAS_LIMITED, } } } impl ValueEnum for PricingMode { fn value_variants<'a>() -> &'a [Self] { - &[Self::Classic, Self::Reserved, Self::Fixed] + &[Self::Classic, Self::Reserved, Self::Fixed, Self::GasLimited] } fn to_possible_value(&self) -> Option { @@ -486,6 +522,7 @@ pub(super) mod pricing_mode { Self::Classic => PossibleValue::new(PricingMode::CLASSIC), Self::Reserved => PossibleValue::new(PricingMode::RESERVED), Self::Fixed => PossibleValue::new(PricingMode::FIXED), + Self::GasLimited => PossibleValue::new(PricingMode::GAS_LIMITED), }) } } @@ -498,6 +535,7 @@ pub(super) mod pricing_mode { PricingMode::CLASSIC => Ok(Self::Classic), PricingMode::RESERVED => Ok(Self::Reserved), PricingMode::FIXED => Ok(Self::Fixed), + PricingMode::GAS_LIMITED => Ok(Self::GasLimited), _ => Err(format!("'{}' is not a valid pricing option", s)), } } @@ -540,6 +578,86 @@ pub(super) mod additional_computation_factor { } } +pub(super) mod transaction_runtime { + use super::*; + use clap::{builder::PossibleValue, value_parser, ValueEnum}; + use std::str::FromStr; + + pub(in crate::transaction) const ARG_NAME: &str = "transaction-runtime"; + + const ARG_VALUE_NAME: &str = "vm-casper-v1|vm-casper-v2"; + const ARG_HELP: &str = "Transaction runtime"; + const ARG_DEFAULT: &str = TransactionRuntime::VM_CASPER_V2; + + pub(in crate::transaction) fn arg() -> Arg { + Arg::new(ARG_NAME) + .long(ARG_NAME) + .required(false) + .value_name(ARG_VALUE_NAME) + .default_value(ARG_DEFAULT) + .help(ARG_HELP) + .display_order(DisplayOrder::PricingMode as usize) + .value_parser(value_parser!(TransactionRuntime)) + } + + #[derive(Debug, Clone, Copy, Default)] + pub enum TransactionRuntime { + #[default] + VmCasperV1, + VmCasperV2, + } + + impl From for casper_types::TransactionRuntime { + fn from(runtime: TransactionRuntime) -> Self { + match runtime { + TransactionRuntime::VmCasperV1 => casper_types::TransactionRuntime::VmCasperV1, + TransactionRuntime::VmCasperV2 => casper_types::TransactionRuntime::VmCasperV2, + } + } + } + + impl TransactionRuntime { + const VM_CASPER_V1: &'static str = "vm-casper-v1"; + const VM_CASPER_V2: &'static str = "vm-casper-v2"; + + pub(crate) fn as_str(&self) -> &str { + match self { + Self::VmCasperV1 => Self::VM_CASPER_V1, + Self::VmCasperV2 => Self::VM_CASPER_V2, + } + } + } + + impl ValueEnum for TransactionRuntime { + fn value_variants<'a>() -> &'a [Self] { + &[Self::VmCasperV1, Self::VmCasperV2] + } + + fn to_possible_value(&self) -> Option { + Some(match self { + Self::VmCasperV1 => PossibleValue::new(TransactionRuntime::VM_CASPER_V1), + Self::VmCasperV2 => PossibleValue::new(TransactionRuntime::VM_CASPER_V2), + }) + } + } + + impl FromStr for TransactionRuntime { + type Err = String; + + fn from_str(s: &str) -> Result { + match s.to_lowercase().as_str() { + Self::VM_CASPER_V1 => Ok(Self::VmCasperV1), + Self::VM_CASPER_V2 => Ok(Self::VmCasperV2), + _ => Err(format!("'{}' is not a valid transaction runtime", s)), + } + } + } + + pub fn get(matches: &ArgMatches) -> Option<&TransactionRuntime> { + matches.get_one(ARG_NAME) + } +} + pub(super) mod initiator_address { use super::*; pub(in crate::transaction) const ARG_NAME: &str = "initiator-address"; @@ -745,6 +863,34 @@ pub(super) mod is_install_upgrade { } } +pub(super) mod transferred_value { + use std::str::FromStr; + + use casper_types::TransactionCategory; + use clap::{value_parser, ValueEnum}; + + use super::*; + + const ARG_NAME: &str = "transferred-value"; + const ARG_SHORT: char = 't'; + const ARG_VALUE_NAME: &str = "integer"; + const ARG_HELP: &str = "Transferred token value"; + + pub fn arg() -> Arg { + Arg::new(ARG_NAME) + .required(true) + .long(ARG_NAME) + .short(ARG_SHORT) + .value_name(ARG_VALUE_NAME) + .help(ARG_HELP) + .display_order(DisplayOrder::TransferredValue as usize) + } + + pub(super) fn get(matches: &ArgMatches) -> Option<&String> { + matches.get_one(ARG_NAME) + } +} + pub(super) mod public_key { use super::*; use casper_client::cli::CliError; @@ -888,11 +1034,8 @@ pub(super) mod session_entry_point { .display_order(DisplayOrder::SessionEntryPoint as usize) } - pub fn get(matches: &ArgMatches) -> &str { - matches - .get_one::(ARG_NAME) - .map(String::as_str) - .unwrap_or_default() + pub fn get(matches: &ArgMatches) -> Option<&str> { + matches.get_one::(ARG_NAME).map(String::as_str) } } @@ -1481,12 +1624,14 @@ pub(super) mod invocable_entity { let entity_addr_str = entity_addr::get(matches)?; let entity_addr = entity_addr::parse_entity_addr(entity_addr_str)?; + let runtime = transaction_runtime::get(matches); - let entry_point = session_entry_point::get(matches); + let entry_point = session_entry_point::get(matches).unwrap_or_default(); let params = TransactionBuilderParams::InvocableEntity { entity_hash: entity_addr.into(), // TODO: Skip `entity_addr` and match directly for hash? entry_point, + runtime: runtime.cloned().unwrap_or_default().into(), }; let transaction_str_params = build_transaction_str_params(matches, ACCEPT_SESSION_ARGS); Ok((params, transaction_str_params)) @@ -1528,11 +1673,16 @@ pub(super) mod invocable_entity_alias { show_json_args_examples_and_exit_if_required(matches); let entity_alias = entity_alias_arg::get(matches); - let entry_point = session_entry_point::get(matches); + let entry_point = session_entry_point::get(matches).unwrap_or_default(); + let runtime = transaction_runtime::get(matches) + .cloned() + .unwrap_or_default() + .into(); let params = TransactionBuilderParams::InvocableEntityAlias { entity_alias, entry_point, + runtime, }; let transaction_str_params = build_transaction_str_params(matches, ACCEPT_SESSION_ARGS); Ok((params, transaction_str_params)) @@ -1576,13 +1726,18 @@ pub(super) mod package { let maybe_package_addr_str = package_addr::get(matches); let package_addr = package_addr::parse_package_addr(maybe_package_addr_str)?; let maybe_entity_version = session_version::get(matches); + let runtime = transaction_runtime::get(matches) + .cloned() + .unwrap_or_default() + .into(); - let entry_point = session_entry_point::get(matches); + let entry_point = session_entry_point::get(matches).unwrap_or_default(); let params = TransactionBuilderParams::Package { package_hash: package_addr.into(), // TODO: Skip `package_addr` and match directly for hash? maybe_entity_version, entry_point, + runtime, }; let transaction_str_params = build_transaction_str_params(matches, ACCEPT_SESSION_ARGS); Ok((params, transaction_str_params)) @@ -1628,12 +1783,17 @@ pub(super) mod package_alias { let maybe_entity_version = session_version::get(matches); - let entry_point = session_entry_point::get(matches); + let entry_point = session_entry_point::get(matches).unwrap_or_default(); + let runtime = transaction_runtime::get(matches) + .cloned() + .unwrap_or_default() + .into(); let params = TransactionBuilderParams::PackageAlias { package_alias, maybe_entity_version, entry_point, + runtime, }; let transaction_str_params = build_transaction_str_params(matches, ACCEPT_SESSION_ARGS); Ok((params, transaction_str_params)) @@ -1690,9 +1850,18 @@ pub(super) mod session { let is_install_upgrade: bool = is_install_upgrade::get(matches); + let runtime = transaction_runtime::get(matches) + .cloned() + .unwrap_or_default() + .into(); + + let entrypoint = session_entry_point::get(matches); + let params = TransactionBuilderParams::Session { is_install_upgrade, transaction_bytes, + transaction_category: transaction_category.into_transaction_v1_category(), + runtime, }; let transaction_str_params = build_transaction_str_params(matches, ACCEPT_SESSION_ARGS); Ok((params, transaction_str_params)) @@ -1705,6 +1874,10 @@ pub(super) mod session { .arg(is_install_upgrade::arg( DisplayOrder::IsInstallUpgrade as usize, )) + .arg(transaction_category::arg()) + .arg(transaction_runtime::arg()) + .arg(gas_limit::arg()) + .arg(transferred_value::arg()) } } @@ -1886,9 +2059,11 @@ pub(super) fn build_transaction_str_params( let payment_amount = payment_amount::get(matches); let receipt = receipt::get(matches); let standard_payment = standard_payment::get(matches); + let gas_limit = gas_limit::get(matches); let maybe_output_path = output::get(matches).unwrap_or_default(); let initiator_addr = initiator_address::get(matches); + let session_entry_point = session_entry_point::get(matches); if obtain_session_args { let session_args_simple = arg_simple::session::get(matches); @@ -1908,6 +2083,11 @@ pub(super) fn build_transaction_str_params( additional_computation_factor, receipt, standard_payment, + transferred_value: transferred_value::get(matches) + .map(|tv| tv.as_str()) + .unwrap_or_default(), + gas_limit, + session_entry_point, } } else { TransactionStrParams { From 39460c25b90fbb4cbde5caaeae4799f06eb92228 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Papierski?= Date: Wed, 14 Aug 2024 19:17:57 +0200 Subject: [PATCH 3/6] Update to match new-execution-engine branch. --- lib/cli/error.rs | 8 ++++ lib/cli/parse.rs | 68 +++++++++++++-------------- lib/cli/session_str_params.rs | 1 + lib/cli/simple_args.rs | 2 +- lib/cli/tests.rs | 26 ++++++++++ lib/cli/transaction.rs | 30 ++++++++---- lib/cli/transaction_builder_params.rs | 17 +++++-- lib/cli/transaction_str_params.rs | 2 + src/transaction/creation_common.rs | 63 +++++++++++++++++++++++-- 9 files changed, 163 insertions(+), 54 deletions(-) diff --git a/lib/cli/error.rs b/lib/cli/error.rs index 8eee10d5..8fce4017 100644 --- a/lib/cli/error.rs +++ b/lib/cli/error.rs @@ -1,5 +1,6 @@ use std::{num::ParseIntError, str::ParseBoolError}; +use base16::DecodeError; use humantime::{DurationError, TimestampError}; use thiserror::Error; @@ -187,6 +188,13 @@ pub enum CliError { /// Failed to parse a validator public key. #[error("Failed to parse a validator public key")] FailedToParseValidatorPublicKey, + + /// Failed to parse base16 bytes. + #[error("Failed to parse base16 bytes: {0}")] + FailedToParseBase16(#[from] DecodeError), + + #[error("Unexpected transaction args variant")] + UnexpectedTransactionArgsVariant, } impl From for CliError { diff --git a/lib/cli/parse.rs b/lib/cli/parse.rs index e5c52f65..c9c1f129 100644 --- a/lib/cli/parse.rs +++ b/lib/cli/parse.rs @@ -15,6 +15,8 @@ use casper_types::{ EntityAddr, ExecutableDeployItem, HashAddr, Key, NamedArg, PricingMode, PublicKey, RuntimeArgs, TimeDiff, Timestamp, TransactionHash, TransactionV1Hash, TransferTarget, UIntParseError, URef, U512, + TransactionArgs, + }; use super::{simple_args, CliError, PaymentStrParams, SessionStrParams}; @@ -244,12 +246,19 @@ fn check_no_conflicting_arg_types( pub fn args_from_simple_or_json( simple: Option, json: Option, -) -> RuntimeArgs { + chunked: Option>, +) -> TransactionArgs { // We can have exactly zero or one of the two as `Some`. - match (simple, json) { - (Some(args), None) | (None, Some(args)) => args, - (None, None) => RuntimeArgs::new(), - _ => unreachable!("should not have more than one of simple, json args"), + match chunked { + Some(chunked) => TransactionArgs::Bytesrepr(chunked.into()), + None => { + let named_args = match (simple, json) { + (Some(args), None) | (None, Some(args)) => args, + (None, None) => RuntimeArgs::new(), + _ => unreachable!("should not have more than one of simple, json args"), + }; + TransactionArgs::Named(named_args) + }, } } @@ -361,6 +370,7 @@ pub(super) fn session_executable_deploy_item( session_version, session_entry_point, is_session_transfer: session_transfer, + session_chunked_args, } = params; // This is to make sure that we're using &str consistently in the macro call below. let is_session_transfer = if session_transfer { "true" } else { "" }; @@ -390,9 +400,11 @@ pub(super) fn session_executable_deploy_item( let session_args = args_from_simple_or_json( arg_simple::session::parse(session_args_simple)?, args_json::session::parse(session_args_json)?, + session_chunked_args.map(ToOwned::to_owned), ); if session_transfer { + let session_args = session_args.as_named().unwrap().clone(); if session_args.is_empty() { return Err(CliError::InvalidArgument { context: "is_session_transfer", @@ -406,6 +418,8 @@ pub(super) fn session_executable_deploy_item( error: session_entry_point.to_string(), }; if let Some(session_name) = name(session_name) { + let session_args = session_args.as_named().unwrap().clone(); + return Ok(ExecutableDeployItem::StoredContractByName { name: session_name, entry_point: entry_point(session_entry_point).ok_or_else(invalid_entry_point)?, @@ -414,6 +428,7 @@ pub(super) fn session_executable_deploy_item( } if let Some(session_hash) = contract_hash(session_hash)? { + let session_args = session_args.as_named().unwrap().clone(); return Ok(ExecutableDeployItem::StoredContractByHash { hash: session_hash.into(), entry_point: entry_point(session_entry_point).ok_or_else(invalid_entry_point)?, @@ -423,6 +438,7 @@ pub(super) fn session_executable_deploy_item( let version = version(session_version)?; if let Some(package_name) = name(session_package_name) { + let session_args = session_args.as_named().unwrap().clone(); return Ok(ExecutableDeployItem::StoredVersionedContractByName { name: package_name, version, // defaults to highest enabled version @@ -432,6 +448,7 @@ pub(super) fn session_executable_deploy_item( } if let Some(package_hash) = contract_hash(session_package_hash)? { + let session_args = session_args.as_named().unwrap().clone(); return Ok(ExecutableDeployItem::StoredVersionedContractByHash { hash: package_hash.into(), version, // defaults to highest enabled version @@ -454,9 +471,11 @@ pub(super) fn session_executable_deploy_item( }); }; + let args = session_args.as_named().ok_or(CliError::UnexpectedTransactionArgsVariant)?; + Ok(ExecutableDeployItem::ModuleBytes { module_bytes, - args: session_args, + args: args.clone(), }) } @@ -540,6 +559,7 @@ pub(super) fn payment_executable_deploy_item( let payment_args = args_from_simple_or_json( arg_simple::payment::parse(payment_args_simple)?, args_json::payment::parse(payment_args_json)?, + None, ); if let Ok(payment_args) = standard_payment(payment_amount) { @@ -554,6 +574,8 @@ pub(super) fn payment_executable_deploy_item( error: payment_entry_point.to_string(), }; + let payment_args = payment_args.as_named().cloned().ok_or(CliError::UnexpectedTransactionArgsVariant)?; + if let Some(payment_name) = name(payment_name) { return Ok(ExecutableDeployItem::StoredContractByName { name: payment_name, @@ -927,7 +949,7 @@ pub(super) fn pricing_mode( error, } })?; - Ok(PricingMode::Classic { + Ok(PricingMode::PaymentLimited { payment_amount, gas_price_tolerance, standard_payment, @@ -974,32 +996,6 @@ pub(super) fn pricing_mode( receipt: maybe_receipt.unwrap_or_default(), }) } - "gas-limited" => { - if maybe_gas_limit.is_empty() { - return Err(CliError::InvalidArgument { - context: "pricing_mode", - error: "Gas limited pricing mode requires a provided gas limit".to_string(), - }); - } - let gas_limit = - maybe_gas_limit - .parse::() - .map_err(|error| CliError::FailedToParseInt { - context: "gas_limit", - error, - })?; - let gas_price_tolerance = - maybe_gas_price_tolerance_str - .parse::() - .map_err(|error| CliError::FailedToParseInt { - context: "gas_price_tolerance", - error, - })?; - Ok(PricingMode::GasLimited { - gas_limit, - gas_price_tolerance, - }) - } _ => Err(CliError::InvalidArgument { context: "pricing_mode", error: "Invalid pricing mode identifier".to_string(), @@ -1062,6 +1058,7 @@ mod tests { session_version: "", session_entry_point: "entrypoint", is_session_transfer: false, + session_chunked_args: None, }) .unwrap_err(); @@ -1111,7 +1108,8 @@ mod tests { session_args_json: "", session_version: "", session_entry_point: "", - is_session_transfer: false + is_session_transfer: false, + session_chunked_args: None, }), Err(CliError::ConflictingArguments { context, .. }) if context == test_context )); @@ -1922,7 +1920,7 @@ mod tests { .unwrap(); assert_eq!( parsed, - PricingMode::Classic { + PricingMode::PaymentLimited { payment_amount: 10, gas_price_tolerance: 10, standard_payment: true, diff --git a/lib/cli/session_str_params.rs b/lib/cli/session_str_params.rs index 8c57cdca..3599cfe1 100644 --- a/lib/cli/session_str_params.rs +++ b/lib/cli/session_str_params.rs @@ -39,6 +39,7 @@ pub struct SessionStrParams<'a> { pub(super) session_version: &'a str, pub(super) session_entry_point: &'a str, pub(super) is_session_transfer: bool, + pub(super) session_chunked_args: Option<&'a [u8]>, } impl<'a> SessionStrParams<'a> { diff --git a/lib/cli/simple_args.rs b/lib/cli/simple_args.rs index 20098dd5..55807abb 100644 --- a/lib/cli/simple_args.rs +++ b/lib/cli/simple_args.rs @@ -2,7 +2,7 @@ pub mod help; -use std::{fmt::Debug, str::FromStr}; +use std::{fmt::Debug, mem::size_of, str::FromStr}; use num_traits::Num; diff --git a/lib/cli/tests.rs b/lib/cli/tests.rs index 7f543d31..3b33f675 100644 --- a/lib/cli/tests.rs +++ b/lib/cli/tests.rs @@ -533,6 +533,7 @@ mod transaction { transferred_value: "0", gas_limit: "", session_entry_point: None, + chunked_args: None, }; let transaction_builder_params = TransactionBuilderParams::AddBid { @@ -607,6 +608,7 @@ mod transaction { transferred_value: "0", gas_limit: "", session_entry_point: None, + chunked_args: None, }; let transaction_builder_params = TransactionBuilderParams::Delegate { @@ -680,6 +682,7 @@ mod transaction { transferred_value: "0", gas_limit: "", session_entry_point: None, + chunked_args: None, }; let transaction_string_params = transaction_str_params; @@ -744,6 +747,7 @@ mod transaction { transferred_value: "0", gas_limit: "", session_entry_point: None, + chunked_args: None, }; let transaction_builder_params = TransactionBuilderParams::Undelegate { @@ -823,6 +827,7 @@ mod transaction { transferred_value: "0", gas_limit: "", session_entry_point: None, + chunked_args: None, }; let transaction_builder_params = TransactionBuilderParams::Redelegate { @@ -885,6 +890,7 @@ mod transaction { let target = &TransactionTarget::Stored { id: TransactionInvocationTarget::ByHash(entity_hash), runtime: TransactionRuntime::VmCasperV1, + transferred_value: 0, }; let entry_point_ref = &TransactionEntryPoint::Custom(entry_point); @@ -907,12 +913,14 @@ mod transaction { transferred_value: "0", gas_limit: "", session_entry_point: None, + chunked_args: None, }; let transaction_builder_params = TransactionBuilderParams::InvocableEntity { entity_hash: entity_hash.into(), entry_point: "test-entry-point", runtime: TransactionRuntime::VmCasperV1, + transferred_value: 0, }; let transaction = create_transaction(transaction_builder_params, transaction_string_params, true); @@ -945,6 +953,7 @@ mod transaction { let target = &TransactionTarget::Stored { id: TransactionInvocationTarget::ByName(alias), runtime: TransactionRuntime::VmCasperV1, + transferred_value: 0, }; let transaction_string_params = TransactionStrParams { secret_key: "", @@ -964,12 +973,14 @@ mod transaction { transferred_value: "0", gas_limit: "", session_entry_point: None, + chunked_args: None, }; let transaction_builder_params = TransactionBuilderParams::InvocableEntityAlias { entity_alias: "alias", entry_point: "entry-point-alias", runtime: TransactionRuntime::VmCasperV1, + transferred_value: 0, }; let transaction = create_transaction(transaction_builder_params, transaction_string_params, true); @@ -1006,6 +1017,7 @@ mod transaction { version: maybe_entity_version, }, runtime: TransactionRuntime::VmCasperV1, + transferred_value: 0, }; let transaction_string_params = TransactionStrParams { secret_key: "", @@ -1025,6 +1037,7 @@ mod transaction { transferred_value: "0", gas_limit: "", session_entry_point: None, + chunked_args: None, }; let transaction_builder_params = TransactionBuilderParams::Package { @@ -1032,6 +1045,7 @@ mod transaction { entry_point, maybe_entity_version, runtime: TransactionRuntime::VmCasperV1, + transferred_value: 0, }; let transaction = create_transaction(transaction_builder_params, transaction_string_params, true); @@ -1065,6 +1079,7 @@ mod transaction { version: maybe_entity_version, }, runtime: TransactionRuntime::VmCasperV1, + transferred_value: 0, }; let transaction_string_params = TransactionStrParams { secret_key: "", @@ -1084,6 +1099,7 @@ mod transaction { transferred_value: "0", gas_limit: "", session_entry_point: None, + chunked_args: None, }; let transaction_builder_params = TransactionBuilderParams::PackageAlias { @@ -1091,6 +1107,7 @@ mod transaction { entry_point, maybe_entity_version, runtime: TransactionRuntime::VmCasperV1, + transferred_value: 0, }; let transaction = create_transaction(transaction_builder_params, transaction_string_params, true); @@ -1121,6 +1138,8 @@ mod transaction { is_install_upgrade, runtime: TransactionRuntime::VmCasperV1, module_bytes: transaction_bytes.clone(), + transferred_value: 0, + seed: None, }; let transaction_string_params = TransactionStrParams { secret_key: "", @@ -1140,12 +1159,15 @@ mod transaction { transferred_value: "0", gas_limit: "", session_entry_point: None, + chunked_args: None, }; let transaction_builder_params = TransactionBuilderParams::Session { is_install_upgrade, transaction_bytes, runtime: TransactionRuntime::VmCasperV1, + transferred_value: 0, + seed: None, }; let transaction = create_transaction(transaction_builder_params, transaction_string_params, true); @@ -1204,6 +1226,7 @@ mod transaction { transferred_value: "0", gas_limit: "", session_entry_point: None, + chunked_args: None, }; let transaction_builder_params = TransactionBuilderParams::Transfer { @@ -1265,6 +1288,7 @@ mod transaction { transferred_value: "0", gas_limit: "", session_entry_point: None, + chunked_args: None, }; let transaction_builder_params = TransactionBuilderParams::Transfer { maybe_source: Default::default(), @@ -1307,6 +1331,7 @@ mod transaction { transferred_value: "0", gas_limit: "", session_entry_point: None, + chunked_args: None, }; let transaction_builder_params = TransactionBuilderParams::AddBid { public_key: PublicKey::from_hex(SAMPLE_ACCOUNT).unwrap(), @@ -1344,6 +1369,7 @@ mod transaction { transferred_value: "0", gas_limit: "", session_entry_point: None, + chunked_args: None, }; let transaction_builder_params = TransactionBuilderParams::AddBid { public_key: PublicKey::from_hex(SAMPLE_ACCOUNT).unwrap(), diff --git a/lib/cli/transaction.rs b/lib/cli/transaction.rs index 08c4e83b..29022927 100644 --- a/lib/cli/transaction.rs +++ b/lib/cli/transaction.rs @@ -11,7 +11,7 @@ use crate::{ SuccessResponse, }; use casper_types::{ - Digest, InitiatorAddr, SecretKey, Transaction, TransactionV1, TransactionV1Builder, + Digest, InitiatorAddr, SecretKey, Transaction, TransactionEntryPoint, TransactionV1, TransactionV1Builder }; pub fn create_transaction( @@ -58,8 +58,8 @@ pub fn create_transaction( transaction_params.gas_price_tolerance, transaction_params.additional_computation_factor, transaction_params.gas_limit, - transaction_params.standard_payment, Some(digest), + )? } else { parse::pricing_mode( @@ -68,7 +68,6 @@ pub fn create_transaction( transaction_params.gas_price_tolerance, transaction_params.additional_computation_factor, transaction_params.gas_limit, - transaction_params.standard_payment, None, )? }; @@ -78,14 +77,15 @@ pub fn create_transaction( let maybe_json_args = parse::args_json::session::parse(transaction_params.session_args_json)?; let maybe_simple_args = parse::arg_simple::session::parse(&transaction_params.session_args_simple)?; + let maybe_chunked_args = transaction_params.chunked_args; - let args = parse::args_from_simple_or_json(maybe_simple_args, maybe_json_args); - if !args.is_empty() { - transaction_builder = transaction_builder.with_runtime_args(args); - } + let args = + parse::args_from_simple_or_json(maybe_simple_args, maybe_json_args, maybe_chunked_args); + + transaction_builder = transaction_builder.with_transaction_args(args); if let Some(session_entry_point) = transaction_params.session_entry_point { - transaction_builder = transaction_builder.with_entry_point(session_entry_point); + transaction_builder = transaction_builder.with_entry_point(TransactionEntryPoint::Custom(session_entry_point.to_owned())); } if let Some(secret_key) = &maybe_secret_key { @@ -273,11 +273,13 @@ pub fn make_transaction_builder( entity_hash, entry_point, runtime, + transferred_value, } => { let transaction_builder = TransactionV1Builder::new_targeting_invocable_entity( entity_hash, entry_point, runtime, + transferred_value, ); Ok(transaction_builder) } @@ -285,12 +287,14 @@ pub fn make_transaction_builder( entity_alias, entry_point, runtime, + transferred_value, } => { let transaction_builder = TransactionV1Builder::new_targeting_invocable_entity_via_alias( entity_alias, entry_point, runtime, + transferred_value, ); Ok(transaction_builder) } @@ -299,12 +303,14 @@ pub fn make_transaction_builder( maybe_entity_version, entry_point, runtime, + transferred_value, } => { let transaction_builder = TransactionV1Builder::new_targeting_package( package_hash, maybe_entity_version, entry_point, runtime, + transferred_value, ); Ok(transaction_builder) } @@ -313,6 +319,8 @@ pub fn make_transaction_builder( maybe_entity_version, entry_point, runtime, + transferred_value, + } => { let new_targeting_package_via_alias = TransactionV1Builder::new_targeting_package_via_alias( @@ -320,6 +328,7 @@ pub fn make_transaction_builder( maybe_entity_version, entry_point, runtime, + transferred_value, ); let transaction_builder = new_targeting_package_via_alias; Ok(transaction_builder) @@ -327,11 +336,12 @@ pub fn make_transaction_builder( TransactionBuilderParams::Session { is_install_upgrade, transaction_bytes, - transaction_category, runtime, + transferred_value, + seed, } => { let transaction_builder = - TransactionV1Builder::new_session(is_install_upgrade, transaction_bytes, runtime); + TransactionV1Builder::new_session(is_install_upgrade, transaction_bytes, runtime, transferred_value, seed); Ok(transaction_builder) } TransactionBuilderParams::Transfer { diff --git a/lib/cli/transaction_builder_params.rs b/lib/cli/transaction_builder_params.rs index 50a04e90..9f8100ca 100644 --- a/lib/cli/transaction_builder_params.rs +++ b/lib/cli/transaction_builder_params.rs @@ -1,9 +1,6 @@ use casper_types::bytesrepr::Bytes; use casper_types::{AddressableEntityHash, PackageHash, PublicKey, TransferTarget, URef, U512}; -use casper_types::{ - AddressableEntityHash, PackageHash, PublicKey, TransactionCategory, TransactionRuntime, - TransferTarget, URef, U512, -}; +use casper_types::TransactionRuntime; /// An enum representing the parameters needed to construct a transaction builder /// for the commands concerning the creation of a transaction @@ -60,6 +57,8 @@ pub enum TransactionBuilderParams<'a> { entry_point: &'a str, /// Transaction Runtime. runtime: TransactionRuntime, + /// The amount to be transferred in the invocable entity transaction. + transferred_value: u64, }, /// Parameters for the invocable entity alias variant of the transaction builder InvocableEntityAlias { @@ -69,6 +68,8 @@ pub enum TransactionBuilderParams<'a> { entry_point: &'a str, /// Transaction Runtime. runtime: TransactionRuntime, + /// Transferred value. + transferred_value: u64, }, /// Parameters for the package variant of the transaction builder Package { @@ -80,6 +81,8 @@ pub enum TransactionBuilderParams<'a> { entry_point: &'a str, /// Transaction Runtime. runtime: TransactionRuntime, + /// Transferred value. + transferred_value: u64, }, /// Parameters for the package alias variant of the transaction builder PackageAlias { @@ -91,6 +94,8 @@ pub enum TransactionBuilderParams<'a> { entry_point: &'a str, /// Transaction Runtime. runtime: TransactionRuntime, + /// Transferred value. + transferred_value: u64, }, /// Parameters for the session variant of the transaction builder Session { @@ -100,6 +105,10 @@ pub enum TransactionBuilderParams<'a> { transaction_bytes: Bytes, /// Transaction Runtime. runtime: TransactionRuntime, + /// Transferred value. + transferred_value: u64, + /// The optional seed for the session transaction + seed: Option<[u8; 32]>, }, /// Parameters for the transfer variant of the transaction builder Transfer { diff --git a/lib/cli/transaction_str_params.rs b/lib/cli/transaction_str_params.rs index 89207834..31147236 100644 --- a/lib/cli/transaction_str_params.rs +++ b/lib/cli/transaction_str_params.rs @@ -77,4 +77,6 @@ pub struct TransactionStrParams<'a> { /// /// None means "call" (aka default) entry point. pub session_entry_point: Option<&'a str>, + /// Chunked arguments for the transaction. + pub chunked_args: Option>, } diff --git a/src/transaction/creation_common.rs b/src/transaction/creation_common.rs index 1b3a3e82..a3cf1e88 100644 --- a/src/transaction/creation_common.rs +++ b/src/transaction/creation_common.rs @@ -38,6 +38,7 @@ pub(super) enum DisplayOrder { Source, SessionArgSimple, SessionArgsJson, + ChunkedArgs, SessionEntryPoint, SessionVersion, PublicKey, @@ -303,6 +304,38 @@ pub(super) mod args_json { } } +/// Handles providing the arg for and retrieval of chunked arguments passed as base16 string. +pub(super) mod chunked_args { + use super::*; + use once_cell::sync::Lazy; + + pub const ARG_NAME: &str = "chunked-args"; + + const ARG_VALUE_NAME: &str = "BYTES"; + + static ARG_HELP: Lazy = Lazy::new(|| { + format!( + "Chunked arg bytes as base16 '--{}'.", + show_json_args_examples::ARG_NAME, + ) + }); + + pub fn get(matches: &ArgMatches) -> Option> { + matches + .get_one::(ARG_NAME) + .and_then(|data| base16::decode(data).ok()) + } + + pub fn arg() -> Arg { + Arg::new(ARG_NAME) + .long(ARG_NAME) + .required(false) + .value_name(ARG_VALUE_NAME) + .help(ARG_HELP.as_str()) + .display_order(DisplayOrder::ChunkedArgs as usize) + } +} + pub(super) mod payment_amount { use super::*; pub(in crate::transaction) const ARG_NAME: &str = "payment-amount"; @@ -866,7 +899,6 @@ pub(super) mod is_install_upgrade { pub(super) mod transferred_value { use std::str::FromStr; - use casper_types::TransactionCategory; use clap::{value_parser, ValueEnum}; use super::*; @@ -1627,11 +1659,15 @@ pub(super) mod invocable_entity { let runtime = transaction_runtime::get(matches); let entry_point = session_entry_point::get(matches).unwrap_or_default(); + let transferred_value = transferred_value::get(matches) + .map(|value| value.parse::().unwrap()) + .unwrap_or_default(); let params = TransactionBuilderParams::InvocableEntity { entity_hash: entity_addr.into(), // TODO: Skip `entity_addr` and match directly for hash? entry_point, runtime: runtime.cloned().unwrap_or_default().into(), + transferred_value, }; let transaction_str_params = build_transaction_str_params(matches, ACCEPT_SESSION_ARGS); Ok((params, transaction_str_params)) @@ -1678,11 +1714,15 @@ pub(super) mod invocable_entity_alias { .cloned() .unwrap_or_default() .into(); + let transferred_value= transferred_value::get(matches) + .map(|value| value.parse::().unwrap()) + .unwrap_or_default(); let params = TransactionBuilderParams::InvocableEntityAlias { entity_alias, entry_point, runtime, + transferred_value, }; let transaction_str_params = build_transaction_str_params(matches, ACCEPT_SESSION_ARGS); Ok((params, transaction_str_params)) @@ -1732,12 +1772,15 @@ pub(super) mod package { .into(); let entry_point = session_entry_point::get(matches).unwrap_or_default(); - + let transferred_value = transferred_value::get(matches) + .map(|value| value.parse::().unwrap()) + .unwrap_or_default(); let params = TransactionBuilderParams::Package { package_hash: package_addr.into(), // TODO: Skip `package_addr` and match directly for hash? maybe_entity_version, entry_point, runtime, + transferred_value, }; let transaction_str_params = build_transaction_str_params(matches, ACCEPT_SESSION_ARGS); Ok((params, transaction_str_params)) @@ -1788,12 +1831,16 @@ pub(super) mod package_alias { .cloned() .unwrap_or_default() .into(); + let transferred_value = transferred_value::get(matches) + .map(|value| value.parse::().unwrap()) + .unwrap_or_default(); let params = TransactionBuilderParams::PackageAlias { package_alias, maybe_entity_version, entry_point, runtime, + transferred_value, }; let transaction_str_params = build_transaction_str_params(matches, ACCEPT_SESSION_ARGS); Ok((params, transaction_str_params)) @@ -1857,11 +1904,17 @@ pub(super) mod session { let entrypoint = session_entry_point::get(matches); + let transferred_value = transferred_value::get(matches) + .map(|value| value.parse::().unwrap()) + .unwrap_or_default(); + let seed = None; // TODO: support seeds + let params = TransactionBuilderParams::Session { is_install_upgrade, transaction_bytes, - transaction_category: transaction_category.into_transaction_v1_category(), runtime, + transferred_value, + seed, }; let transaction_str_params = build_transaction_str_params(matches, ACCEPT_SESSION_ARGS); Ok((params, transaction_str_params)) @@ -1874,10 +1927,10 @@ pub(super) mod session { .arg(is_install_upgrade::arg( DisplayOrder::IsInstallUpgrade as usize, )) - .arg(transaction_category::arg()) .arg(transaction_runtime::arg()) .arg(gas_limit::arg()) .arg(transferred_value::arg()) + .arg(chunked_args::arg()) } } @@ -2064,6 +2117,7 @@ pub(super) fn build_transaction_str_params( let maybe_output_path = output::get(matches).unwrap_or_default(); let initiator_addr = initiator_address::get(matches); let session_entry_point = session_entry_point::get(matches); + let chunked_args = chunked_args::get(matches); if obtain_session_args { let session_args_simple = arg_simple::session::get(matches); @@ -2088,6 +2142,7 @@ pub(super) fn build_transaction_str_params( .unwrap_or_default(), gas_limit, session_entry_point, + chunked_args, } } else { TransactionStrParams { From 339afa967cf7ad1e1577a7d72ff4585d92c5fb55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Papierski?= Date: Mon, 19 Aug 2024 17:32:46 +0200 Subject: [PATCH 4/6] Update for invocable entity --- src/transaction/creation_common.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/transaction/creation_common.rs b/src/transaction/creation_common.rs index a3cf1e88..72d16eef 100644 --- a/src/transaction/creation_common.rs +++ b/src/transaction/creation_common.rs @@ -1677,6 +1677,10 @@ pub(super) mod invocable_entity { add_bid_subcommand .arg(entity_addr::arg()) .arg(session_entry_point::arg()) + .arg(transaction_runtime::arg()) + .arg(gas_limit::arg()) + .arg(transferred_value::arg()) + .arg(chunked_args::arg()) } } pub(super) mod invocable_entity_alias { From 1af74cb7a194f177dea50c4c9874e7bd85fddfea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Papierski?= Date: Thu, 14 Nov 2024 12:24:46 +0100 Subject: [PATCH 5/6] Add support for VM2 txs. --- Cargo.toml | 3 +- lib/cli/error.rs | 1 + lib/cli/parse.rs | 18 ++++++---- lib/cli/transaction.rs | 47 ++++++++++++++++++--------- lib/cli/transaction_builder_params.rs | 2 +- src/transaction/creation_common.rs | 27 ++------------- 6 files changed, 49 insertions(+), 49 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 97464236..00232b59 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,8 +59,7 @@ uint = "0.9.5" tempfile = "3.8.1" [patch.crates-io] -#casper-types = { git = "https://github.com/mpapierski/casper-node.git", branch = "new-execution-engine" } -casper-types = { path = "../casper-node/types" } +casper-types = { git = "https://github.com/casper-network/casper-node.git", branch = "feat-2.0" } [package.metadata.deb] features = ["vendored-openssl"] diff --git a/lib/cli/error.rs b/lib/cli/error.rs index 8fce4017..7c23f6d2 100644 --- a/lib/cli/error.rs +++ b/lib/cli/error.rs @@ -193,6 +193,7 @@ pub enum CliError { #[error("Failed to parse base16 bytes: {0}")] FailedToParseBase16(#[from] DecodeError), + /// Unexpected transaction args variant. #[error("Unexpected transaction args variant")] UnexpectedTransactionArgsVariant, } diff --git a/lib/cli/parse.rs b/lib/cli/parse.rs index c9c1f129..e6833da0 100644 --- a/lib/cli/parse.rs +++ b/lib/cli/parse.rs @@ -13,10 +13,8 @@ use casper_types::SecretKey; use casper_types::{ account::AccountHash, bytesrepr::Bytes, crypto, AsymmetricType, BlockHash, DeployHash, Digest, EntityAddr, ExecutableDeployItem, HashAddr, Key, NamedArg, PricingMode, PublicKey, RuntimeArgs, - TimeDiff, Timestamp, TransactionHash, TransactionV1Hash, TransferTarget, UIntParseError, URef, - U512, - TransactionArgs, - + TimeDiff, Timestamp, TransactionArgs, TransactionHash, TransactionV1Hash, TransferTarget, + UIntParseError, URef, U512, }; use super::{simple_args, CliError, PaymentStrParams, SessionStrParams}; @@ -248,6 +246,7 @@ pub fn args_from_simple_or_json( json: Option, chunked: Option>, ) -> TransactionArgs { + dbg!(&simple, &json, &chunked); // We can have exactly zero or one of the two as `Some`. match chunked { Some(chunked) => TransactionArgs::Bytesrepr(chunked.into()), @@ -258,7 +257,7 @@ pub fn args_from_simple_or_json( _ => unreachable!("should not have more than one of simple, json args"), }; TransactionArgs::Named(named_args) - }, + } } } @@ -471,7 +470,9 @@ pub(super) fn session_executable_deploy_item( }); }; - let args = session_args.as_named().ok_or(CliError::UnexpectedTransactionArgsVariant)?; + let args = session_args + .as_named() + .ok_or(CliError::UnexpectedTransactionArgsVariant)?; Ok(ExecutableDeployItem::ModuleBytes { module_bytes, @@ -574,7 +575,10 @@ pub(super) fn payment_executable_deploy_item( error: payment_entry_point.to_string(), }; - let payment_args = payment_args.as_named().cloned().ok_or(CliError::UnexpectedTransactionArgsVariant)?; + let payment_args = payment_args + .as_named() + .cloned() + .ok_or(CliError::UnexpectedTransactionArgsVariant)?; if let Some(payment_name) = name(payment_name) { return Ok(ExecutableDeployItem::StoredContractByName { diff --git a/lib/cli/transaction.rs b/lib/cli/transaction.rs index 29022927..17059bb7 100644 --- a/lib/cli/transaction.rs +++ b/lib/cli/transaction.rs @@ -11,7 +11,8 @@ use crate::{ SuccessResponse, }; use casper_types::{ - Digest, InitiatorAddr, SecretKey, Transaction, TransactionEntryPoint, TransactionV1, TransactionV1Builder + Digest, InitiatorAddr, SecretKey, Transaction, TransactionArgs, TransactionEntryPoint, + TransactionRuntime, TransactionV1, TransactionV1Builder, }; pub fn create_transaction( @@ -31,6 +32,8 @@ pub fn create_transaction( let ttl = parse::ttl(transaction_params.ttl)?; let maybe_session_account = parse::session_account(&transaction_params.initiator_addr)?; + let is_v2_wasm = matches!(&builder_params, TransactionBuilderParams::Session { runtime, .. } if runtime == &TransactionRuntime::VmCasperV2); + let mut transaction_builder = make_transaction_builder(builder_params)?; transaction_builder = transaction_builder @@ -44,6 +47,7 @@ pub fn create_transaction( error: "pricing_mode is required to be non empty".to_string(), }); } + let pricing_mode = if transaction_params.pricing_mode.to_lowercase().as_str() == "reserved" { let digest = Digest::from_hex(transaction_params.receipt).map_err(|error| { CliError::FailedToParseDigest { @@ -57,9 +61,8 @@ pub fn create_transaction( transaction_params.payment_amount, transaction_params.gas_price_tolerance, transaction_params.additional_computation_factor, - transaction_params.gas_limit, + transaction_params.standard_payment, Some(digest), - )? } else { parse::pricing_mode( @@ -67,7 +70,7 @@ pub fn create_transaction( transaction_params.payment_amount, transaction_params.gas_price_tolerance, transaction_params.additional_computation_factor, - transaction_params.gas_limit, + transaction_params.standard_payment, None, )? }; @@ -77,15 +80,25 @@ pub fn create_transaction( let maybe_json_args = parse::args_json::session::parse(transaction_params.session_args_json)?; let maybe_simple_args = parse::arg_simple::session::parse(&transaction_params.session_args_simple)?; - let maybe_chunked_args = transaction_params.chunked_args; - - let args = - parse::args_from_simple_or_json(maybe_simple_args, maybe_json_args, maybe_chunked_args); + let chunked = transaction_params.chunked_args; - transaction_builder = transaction_builder.with_transaction_args(args); + let args = parse::args_from_simple_or_json(maybe_simple_args, maybe_json_args, chunked); + match args { + TransactionArgs::Named(named_args) => { + if !named_args.is_empty() { + transaction_builder = transaction_builder.with_runtime_args(named_args); + } + } + TransactionArgs::Bytesrepr(chunked_args) => { + transaction_builder = transaction_builder.with_chunked_args(chunked_args); + } + } - if let Some(session_entry_point) = transaction_params.session_entry_point { - transaction_builder = transaction_builder.with_entry_point(TransactionEntryPoint::Custom(session_entry_point.to_owned())); + if is_v2_wasm { + if let Some(entry_point) = transaction_params.session_entry_point { + transaction_builder = transaction_builder + .with_entry_point(TransactionEntryPoint::Custom(entry_point.to_owned())); + } } if let Some(secret_key) = &maybe_secret_key { @@ -98,7 +111,7 @@ pub fn create_transaction( } let txn = transaction_builder.build().map_err(crate::Error::from)?; - dbg!(&txn); + // dbg!(&txn); Ok(txn) } @@ -320,7 +333,6 @@ pub fn make_transaction_builder( entry_point, runtime, transferred_value, - } => { let new_targeting_package_via_alias = TransactionV1Builder::new_targeting_package_via_alias( @@ -340,8 +352,13 @@ pub fn make_transaction_builder( transferred_value, seed, } => { - let transaction_builder = - TransactionV1Builder::new_session(is_install_upgrade, transaction_bytes, runtime, transferred_value, seed); + let transaction_builder = TransactionV1Builder::new_session( + is_install_upgrade, + transaction_bytes, + runtime, + transferred_value, + seed, + ); Ok(transaction_builder) } TransactionBuilderParams::Transfer { diff --git a/lib/cli/transaction_builder_params.rs b/lib/cli/transaction_builder_params.rs index 9f8100ca..fb8374d6 100644 --- a/lib/cli/transaction_builder_params.rs +++ b/lib/cli/transaction_builder_params.rs @@ -1,6 +1,6 @@ use casper_types::bytesrepr::Bytes; -use casper_types::{AddressableEntityHash, PackageHash, PublicKey, TransferTarget, URef, U512}; use casper_types::TransactionRuntime; +use casper_types::{AddressableEntityHash, PackageHash, PublicKey, TransferTarget, URef, U512}; /// An enum representing the parameters needed to construct a transaction builder /// for the commands concerning the creation of a transaction diff --git a/src/transaction/creation_common.rs b/src/transaction/creation_common.rs index 72d16eef..5af6bcd8 100644 --- a/src/transaction/creation_common.rs +++ b/src/transaction/creation_common.rs @@ -30,7 +30,6 @@ pub(super) enum DisplayOrder { TransferId, Timestamp, Ttl, - TransactionCategory, TransferredValue, ChainName, MaximumDelegationRate, @@ -47,13 +46,11 @@ pub(super) enum DisplayOrder { EntityAlias, PaymentAmount, PricingMode, - TransactionRuntime, StandardPayment, Receipt, GasPriceTolerance, AdditionalComputationFactor, IsInstallUpgrade, - GasLimit, TransactionAmount, Validator, NewValidator, @@ -526,28 +523,25 @@ pub(super) mod pricing_mode { Classic, Reserved, Fixed, - GasLimited, } impl PricingMode { const CLASSIC: &'static str = "classic"; const RESERVED: &'static str = "reserved"; const FIXED: &'static str = "fixed"; - const GAS_LIMITED: &'static str = "gas-limited"; pub(crate) fn as_str(&self) -> &str { match self { Self::Classic => Self::CLASSIC, Self::Reserved => Self::RESERVED, Self::Fixed => Self::FIXED, - Self::GasLimited => Self::GAS_LIMITED, } } } impl ValueEnum for PricingMode { fn value_variants<'a>() -> &'a [Self] { - &[Self::Classic, Self::Reserved, Self::Fixed, Self::GasLimited] + &[Self::Classic, Self::Reserved, Self::Fixed] } fn to_possible_value(&self) -> Option { @@ -555,7 +549,6 @@ pub(super) mod pricing_mode { Self::Classic => PossibleValue::new(PricingMode::CLASSIC), Self::Reserved => PossibleValue::new(PricingMode::RESERVED), Self::Fixed => PossibleValue::new(PricingMode::FIXED), - Self::GasLimited => PossibleValue::new(PricingMode::GAS_LIMITED), }) } } @@ -568,7 +561,6 @@ pub(super) mod pricing_mode { PricingMode::CLASSIC => Ok(Self::Classic), PricingMode::RESERVED => Ok(Self::Reserved), PricingMode::FIXED => Ok(Self::Fixed), - PricingMode::GAS_LIMITED => Ok(Self::GasLimited), _ => Err(format!("'{}' is not a valid pricing option", s)), } } @@ -652,13 +644,6 @@ pub(super) mod transaction_runtime { impl TransactionRuntime { const VM_CASPER_V1: &'static str = "vm-casper-v1"; const VM_CASPER_V2: &'static str = "vm-casper-v2"; - - pub(crate) fn as_str(&self) -> &str { - match self { - Self::VmCasperV1 => Self::VM_CASPER_V1, - Self::VmCasperV2 => Self::VM_CASPER_V2, - } - } } impl ValueEnum for TransactionRuntime { @@ -897,14 +882,10 @@ pub(super) mod is_install_upgrade { } pub(super) mod transferred_value { - use std::str::FromStr; - - use clap::{value_parser, ValueEnum}; - use super::*; const ARG_NAME: &str = "transferred-value"; - const ARG_SHORT: char = 't'; + const ARG_SHORT: char = 'T'; const ARG_VALUE_NAME: &str = "integer"; const ARG_HELP: &str = "Transferred token value"; @@ -1718,7 +1699,7 @@ pub(super) mod invocable_entity_alias { .cloned() .unwrap_or_default() .into(); - let transferred_value= transferred_value::get(matches) + let transferred_value = transferred_value::get(matches) .map(|value| value.parse::().unwrap()) .unwrap_or_default(); @@ -1906,8 +1887,6 @@ pub(super) mod session { .unwrap_or_default() .into(); - let entrypoint = session_entry_point::get(matches); - let transferred_value = transferred_value::get(matches) .map(|value| value.parse::().unwrap()) .unwrap_or_default(); From 9b14f5c3d53ce62da4e8feae1677eec65219f17c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Papierski?= Date: Tue, 19 Nov 2024 16:00:27 +0100 Subject: [PATCH 6/6] Fix test --- lib/cli/parse.rs | 5 ----- lib/cli/tests.rs | 53 +++++++++++++++++++++++++----------------------- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/lib/cli/parse.rs b/lib/cli/parse.rs index e6833da0..dad170d3 100644 --- a/lib/cli/parse.rs +++ b/lib/cli/parse.rs @@ -246,7 +246,6 @@ pub fn args_from_simple_or_json( json: Option, chunked: Option>, ) -> TransactionArgs { - dbg!(&simple, &json, &chunked); // We can have exactly zero or one of the two as `Some`. match chunked { Some(chunked) => TransactionArgs::Bytesrepr(chunked.into()), @@ -1835,7 +1834,6 @@ mod tests { fn should_parse_fixed_pricing_mode_identifier() { let pricing_mode_str = "fixed"; let payment_amount = ""; - let gas_limit = ""; let gas_price_tolerance = "10"; let additional_computation_factor = "1"; let standard_payment = ""; @@ -1910,7 +1908,6 @@ mod tests { let pricing_mode_str = "classic"; let payment_amount = "10"; let standard_payment = "true"; - let gas_limit = ""; let gas_price_tolerance = "10"; let additional_computation_factor = "0"; let parsed = pricing_mode( @@ -1937,7 +1934,6 @@ mod tests { let pricing_mode_str = "invalid"; let payment_amount = "10"; let standard_payment = "true"; - let gas_limit = ""; let gas_price_tolerance = "10"; let additional_computation_factor = "0"; let parsed = pricing_mode( @@ -1976,7 +1972,6 @@ mod tests { let pricing_mode_str = "classic"; let payment_amount = ""; let standard_payment = "true"; - let gas_limit = ""; let gas_price_tolerance = "10"; let additional_computation_factor = "0"; let parsed = pricing_mode( diff --git a/lib/cli/tests.rs b/lib/cli/tests.rs index 3b33f675..f3761d3b 100644 --- a/lib/cli/tests.rs +++ b/lib/cli/tests.rs @@ -451,31 +451,34 @@ mod transaction { TransactionInvocationTarget, TransactionRuntime, TransactionTarget, TransactionV1BuilderError, TransferTarget, }; - const SAMPLE_TRANSACTION: &str = r#"{ - "hash": "57144349509f7cb9374e0f38b4e4910526b397a38f0dc21eaae1df916df66aae", - "payload": { - "initiator_addr": { - "PublicKey": "01722e1b3d31bef0ba832121bd2941aae6a246d0d05ac95aa16dd587cc5469871d" - }, - "timestamp": "2024-10-07T16:45:27.994Z", - "ttl": "30m", - "chain_name": "test", - "pricing_mode": { - "Fixed": { - "additional_computation_factor": 0, - "gas_price_tolerance": 10 - } - }, - "fields": { - "0": "020000000600000074617267657421000000722e1b3d31bef0ba832121bd2941aae6a246d0d05ac95aa16dd587cc5469871d010c06000000616d6f756e7402000000010a08", - "1": "010000000000000000000100000000", - "2": "010000000000000000000100000002", - "3": "010000000000000000000100000000" - } - }, - "approvals": [] -} -"#; + use once_cell::sync::Lazy; + use serde_json::json; + static SAMPLE_TRANSACTION: Lazy = Lazy::new(|| { + json!({ + "hash": "57144349509f7cb9374e0f38b4e4910526b397a38f0dc21eaae1df916df66aae", + "payload": { + "initiator_addr": { + "PublicKey": "01722e1b3d31bef0ba832121bd2941aae6a246d0d05ac95aa16dd587cc5469871d", + }, + "timestamp": "2024-10-07T16:45:27.994Z", + "ttl": "30m", + "chain_name": "test", + "pricing_mode": { + "Fixed": { + "additional_computation_factor": 0, + "gas_price_tolerance": 10, + } + }, + "fields": { + "0": "020000000600000074617267657421000000722e1b3d31bef0ba832121bd2941aae6a246d0d05ac95aa16dd587cc5469871d010c06000000616d6f756e7402000000010a08", + "1": "010000000000000000000100000000", + "2": "010000000000000000000100000002", + "3": "010000000000000000000100000000", + } + }, + "approvals": [], + }) + }); const SAMPLE_DIGEST: &str = "01722e1b3d31bef0ba832121bd2941aae6a246d0d05ac95aa16dd587cc5469871d";