From 99be81639f43a317cceaa8d1bdcbaa973dc76baf Mon Sep 17 00:00:00 2001 From: Gregory Roussac Date: Thu, 17 Oct 2024 16:21:46 +0200 Subject: [PATCH] Changing TransactionV1 structure follwing https://github.com/casper-network/casper-node/pull/4890 (#191) * merge changes * Cargo types * is_install_upgrade / additional_computation_factor wip * Fix tests and additional_computation_factor * Update json-schema --- Cargo.toml | 16 +- lib/cli/error.rs | 4 - lib/cli/parse.rs | 117 +++++++++--- lib/cli/tests.rs | 261 ++++++++++++++++++-------- lib/cli/transaction.rs | 6 +- lib/cli/transaction_builder_params.rs | 8 +- lib/cli/transaction_str_params.rs | 3 + src/transaction/creation_common.rs | 126 ++++++------- 8 files changed, 350 insertions(+), 191 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a83e53c4..1ce6b5a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,29 +29,29 @@ default = ["async-trait", "clap", "clap_complete", "std-fs-io"] std-fs-io = ["casper-types/std-fs-io"] [dependencies] -async-trait = { version = "0.1.59", default-features = false, optional = true } +async-trait = { version = "0.1.74", default-features = false, optional = true } base16 = "0.2.1" casper-types = { version = "5.0.0", features = ["std", "json-schema"] } clap = { version = "~4.4", features = ["cargo", "deprecated"], optional = true } clap_complete = { version = "~4.4", default-features = false, optional = true } hex-buffer-serde = "0.4.0" -humantime = "2" -itertools = "0.11.0" +humantime = "2.1.0" +itertools = "0.12.0" jsonrpc-lite = "0.6.0" num-traits = "0.2.15" -once_cell = "1" +once_cell = "1.18.0" rand = "0.8.5" reqwest = { version = "0.12.5", features = ["json"] } -schemars = "0.8.13" +schemars = "0.8.18" serde = { version = "1", default-features = false, features = ["derive"] } serde-map-to-array = "1.1.1" serde_json = { version = "1", features = ["preserve_order"] } thiserror = "1" -tokio = { version = "1.38.0", features = ["macros", "rt", "sync", "time"] } -uint = "0.9.4" +tokio = { version = "1.39.3", features = ["macros", "rt", "sync", "time"] } +uint = "0.9.5" [dev-dependencies] -tempfile = "3.7.1" +tempfile = "3.8.1" [patch.crates-io] casper-types = { git = "https://github.com/casper-network/casper-node.git", branch = "feat-2.0" } diff --git a/lib/cli/error.rs b/lib/cli/error.rs index 5f012c86..87adf3a9 100644 --- a/lib/cli/error.rs +++ b/lib/cli/error.rs @@ -184,10 +184,6 @@ pub enum CliError { #[error("Failed to parse a transfer target")] FailedToParseTransferTarget, - /// Failed to parse transaction category. - #[error("Failed to parse a transaction category")] - FailedToParseTransactionCategory, - /// Failed to parse a validator public key. #[error("Failed to parse a validator public key")] FailedToParseValidatorPublicKey, diff --git a/lib/cli/parse.rs b/lib/cli/parse.rs index be9c81c0..d9cc0e33 100644 --- a/lib/cli/parse.rs +++ b/lib/cli/parse.rs @@ -824,50 +824,51 @@ pub(super) fn public_key(public_key: &str) -> Result, CliError pub(super) fn pricing_mode( pricing_mode_identifier_str: &str, - maybe_payment_amount_str: &str, - maybe_gas_price_tolerance_str: &str, - maybe_standard_payment_str: &str, + payment_amount_str: &str, + gas_price_tolerance_str: &str, + additional_computation_factor_str: &str, + standard_payment_str: &str, maybe_receipt: Option, ) -> Result { match pricing_mode_identifier_str.to_lowercase().as_str() { "classic" => { - if maybe_gas_price_tolerance_str.is_empty() { + if gas_price_tolerance_str.is_empty() { return Err(CliError::InvalidArgument { context: "gas_price_tolerance", error: "Gas price tolerance is required".to_string(), }); } - if maybe_payment_amount_str.is_empty() { + if payment_amount_str.is_empty() { return Err(CliError::InvalidArgument { context: "payment_amount", error: "Payment amount is required".to_string(), }); } - if maybe_standard_payment_str.is_empty() { + if standard_payment_str.is_empty() { return Err(CliError::InvalidArgument { context: "standard_payment", error: "Standard payment flag is required".to_string(), }); } - let gas_price_tolerance = - maybe_gas_price_tolerance_str - .parse::() - .map_err(|error| CliError::FailedToParseInt { - context: "gas_price_tolerance", - error, - })?; - let payment_amount = maybe_payment_amount_str.parse::().map_err(|error| { + let gas_price_tolerance = gas_price_tolerance_str.parse::().map_err(|error| { CliError::FailedToParseInt { - context: "payment_amount", + context: "gas_price_tolerance", error, } })?; - let standard_payment = maybe_standard_payment_str - .parse::() - .map_err(|error| CliError::FailedToParseBool { + let payment_amount = + payment_amount_str + .parse::() + .map_err(|error| CliError::FailedToParseInt { + context: "payment_amount", + error, + })?; + let standard_payment = standard_payment_str.parse::().map_err(|error| { + CliError::FailedToParseBool { context: "standard_payment", error, - })?; + } + })?; Ok(PricingMode::Classic { payment_amount, gas_price_tolerance, @@ -875,21 +876,33 @@ pub(super) fn pricing_mode( }) } "fixed" => { - if maybe_gas_price_tolerance_str.is_empty() { + if gas_price_tolerance_str.is_empty() { return Err(CliError::InvalidArgument { context: "gas_price_tolerance", error: "Gas price tolerance is required".to_string(), }); } - let gas_price_tolerance = - maybe_gas_price_tolerance_str + let gas_price_tolerance = gas_price_tolerance_str.parse::().map_err(|error| { + CliError::FailedToParseInt { + context: "gas_price_tolerance", + error, + } + })?; + + // Additional Computation Factor defaults to 0 if the string is empty + let additional_computation_factor = if additional_computation_factor_str.is_empty() { + u8::default() + } else { + additional_computation_factor_str .parse::() .map_err(|error| CliError::FailedToParseInt { - context: "gas_price_tolerance", + context: "additional_computation_factor", error, - })?; + })? + }; Ok(PricingMode::Fixed { gas_price_tolerance, + additional_computation_factor, }) } "reserved" => { @@ -1689,11 +1702,38 @@ mod tests { let pricing_mode_str = "fixed"; let payment_amount = ""; let gas_price_tolerance = "10"; + let additional_computation_factor = "1"; + let standard_payment = ""; + let parsed = pricing_mode( + pricing_mode_str, + payment_amount, + gas_price_tolerance, + additional_computation_factor, + standard_payment, + None, + ) + .unwrap(); + assert_eq!( + parsed, + PricingMode::Fixed { + additional_computation_factor: 1, + gas_price_tolerance: 10, + } + ); + } + + #[test] + fn should_parse_fixed_pricing_mode_identifier_without_additional_computation_factor() { + let pricing_mode_str = "fixed"; + let payment_amount = ""; + let gas_price_tolerance = "10"; + let additional_computation_factor = ""; let standard_payment = ""; let parsed = pricing_mode( pricing_mode_str, payment_amount, gas_price_tolerance, + additional_computation_factor, standard_payment, None, ) @@ -1701,20 +1741,24 @@ mod tests { assert_eq!( parsed, PricingMode::Fixed { + additional_computation_factor: 0, gas_price_tolerance: 10, } ); } + #[test] fn should_parse_reserved_pricing_mode() { let pricing_mode_str = "reserved"; let payment_amount = ""; let gas_price_tolerance = ""; + let additional_computation_factor = "0"; let standard_payment = ""; let parsed = pricing_mode( pricing_mode_str, payment_amount, gas_price_tolerance, + additional_computation_factor, standard_payment, Some(Digest::from_hex(VALID_HASH).unwrap()), ) @@ -1732,10 +1776,12 @@ mod tests { let payment_amount = "10"; let standard_payment = "true"; let gas_price_tolerance = "10"; + let additional_computation_factor = "0"; let parsed = pricing_mode( pricing_mode_str, payment_amount, gas_price_tolerance, + additional_computation_factor, standard_payment, None, ) @@ -1756,10 +1802,12 @@ mod tests { let payment_amount = "10"; let standard_payment = "true"; let gas_price_tolerance = "10"; + let additional_computation_factor = "0"; let parsed = pricing_mode( pricing_mode_str, payment_amount, gas_price_tolerance, + additional_computation_factor, standard_payment, None, ); @@ -1767,16 +1815,37 @@ mod tests { assert!(matches!(parsed, Err(CliError::InvalidArgument { .. }))); } + #[test] + fn should_fail_to_parse_invalid_additional_computation_factor() { + let pricing_mode_str = "fixed"; + let payment_amount = "10"; + let standard_payment = "true"; + let gas_price_tolerance = "10"; + let additional_computation_factor = "invalid"; + let parsed = pricing_mode( + pricing_mode_str, + payment_amount, + gas_price_tolerance, + additional_computation_factor, + standard_payment, + None, + ); + assert!(parsed.is_err()); + assert!(matches!(parsed, Err(CliError::FailedToParseInt { .. }))); + } + #[test] fn should_fail_to_parse_classic_without_amount() { let pricing_mode_str = "classic"; let payment_amount = ""; let standard_payment = "true"; let gas_price_tolerance = "10"; + let additional_computation_factor = "0"; let parsed = pricing_mode( pricing_mode_str, payment_amount, gas_price_tolerance, + additional_computation_factor, standard_payment, None, ); diff --git a/lib/cli/tests.rs b/lib/cli/tests.rs index 93fb5700..6cc85bd6 100644 --- a/lib/cli/tests.rs +++ b/lib/cli/tests.rs @@ -85,6 +85,13 @@ const SAMPLE_DEPLOY: &str = r#"{ ] }"#; +#[cfg(test)] +pub(crate) const ARGS_MAP_KEY: u16 = 0; +#[cfg(test)] +pub(crate) const TARGET_MAP_KEY: u16 = 1; +#[cfg(test)] +pub(crate) const ENTRY_POINT_MAP_KEY: u16 = 2; + pub fn deploy_params_without_account() -> DeployStrParams<'static> { DeployStrParams { secret_key: "", @@ -434,57 +441,32 @@ mod transaction { use super::*; use crate::Error::TransactionBuild; use casper_types::{ - bytesrepr::Bytes, PackageAddr, TransactionEntryPoint, TransactionInvocationTarget, - TransactionRuntime, TransactionTarget, TransactionV1BuilderError, TransferTarget, + bytesrepr::Bytes, PackageAddr, RuntimeArgs, TransactionEntryPoint, + TransactionInvocationTarget, TransactionRuntime, TransactionTarget, + TransactionV1BuilderError, TransferTarget, }; const SAMPLE_TRANSACTION: &str = r#"{ - "hash": "f868596bbfd729547ffa25c3421df29d6650cec73e9fe3d0aff633fe2d6ac952", - "header": { - "chain_name": "test", - "timestamp": "2024-01-26T19:08:53.498Z", + "hash": "57144349509f7cb9374e0f38b4e4910526b397a38f0dc21eaae1df916df66aae", + "payload": { + "initiator_addr": { + "PublicKey": "01722e1b3d31bef0ba832121bd2941aae6a246d0d05ac95aa16dd587cc5469871d" + }, + "timestamp": "2024-10-07T16:45:27.994Z", "ttl": "30m", - "body_hash": "fb94fd83178e3acf22546beebf5f44692499d681c4381f6d145d85ff9b5fc152", + "chain_name": "test", "pricing_mode": { "Fixed": { + "additional_computation_factor": 0, "gas_price_tolerance": 10 } }, - "initiator_addr": { - "PublicKey": "01722e1b3d31bef0ba832121bd2941aae6a246d0d05ac95aa16dd587cc5469871d" + "fields": { + "0": "020000000600000074617267657421000000722e1b3d31bef0ba832121bd2941aae6a246d0d05ac95aa16dd587cc5469871d010c06000000616d6f756e7402000000010a08", + "1": "010000000000000000000100000000", + "2": "010000000000000000000100000002", + "3": "010000000000000000000100000000" } }, - "body": { - "args": [ - [ - "source", - { - "cl_type": "URef", - "bytes": "722e1b3d31bef0ba832121bd2941aae6a246d0d05ac95aa16dd587cc5469871d01", - "parsed": "uref-722e1b3d31bef0ba832121bd2941aae6a246d0d05ac95aa16dd587cc5469871d-001" - } - ], - [ - "target", - { - "cl_type": "URef", - "bytes": "722e1b3d31bef0ba832121bd2941aae6a246d0d05ac95aa16dd587cc5469871d01", - "parsed": "uref-722e1b3d31bef0ba832121bd2941aae6a246d0d05ac95aa16dd587cc5469871d-001" - } - ], - [ - "amount", - { - "cl_type": "U512", - "bytes": "010a", - "parsed": "10" - } - ] - ], - "target": "Native", - "entry_point": "Transfer", - "transaction_category": 0, - "scheduling": "Standard" - }, "approvals": [] } "#; @@ -539,6 +521,7 @@ mod transaction { output_path: "", payment_amount: "100", gas_price_tolerance: "10", + additional_computation_factor: "", receipt: SAMPLE_DIGEST, standard_payment: "true", }; @@ -560,7 +543,8 @@ mod transaction { transaction .as_ref() .unwrap() - .args() + .deserialize_field::(ARGS_MAP_KEY) + .unwrap() .get("public_key") .unwrap(), public_key_cl @@ -568,11 +552,18 @@ mod transaction { assert!(transaction .as_ref() .unwrap() - .args() + .deserialize_field::(ARGS_MAP_KEY) + .unwrap() .get("delegation_rate") .is_some()); assert_eq!( - transaction.as_ref().unwrap().args().get("amount").unwrap(), + transaction + .as_ref() + .unwrap() + .deserialize_field::(ARGS_MAP_KEY) + .unwrap() + .get("amount") + .unwrap(), amount_cl ); } @@ -601,6 +592,7 @@ mod transaction { output_path: "", payment_amount: "100", gas_price_tolerance: "10", + additional_computation_factor: "", receipt: SAMPLE_DIGEST, standard_payment: "true", }; @@ -617,14 +609,21 @@ mod transaction { assert!(transaction.is_ok(), "{:?}", transaction); assert_eq!(transaction.as_ref().unwrap().chain_name(), "delegate"); assert_eq!( - transaction.as_ref().unwrap().args().get("amount").unwrap(), + transaction + .as_ref() + .unwrap() + .deserialize_field::(ARGS_MAP_KEY) + .unwrap() + .get("amount") + .unwrap(), amount_cl ); assert_eq!( transaction .as_ref() .unwrap() - .args() + .deserialize_field::(ARGS_MAP_KEY) + .unwrap() .get("delegator") .unwrap(), delegator_public_key_cl @@ -633,7 +632,8 @@ mod transaction { transaction .as_ref() .unwrap() - .args() + .deserialize_field::(ARGS_MAP_KEY) + .unwrap() .get("validator") .unwrap(), validator_public_key_cl @@ -662,6 +662,7 @@ mod transaction { output_path: "", payment_amount: "100", gas_price_tolerance: "10", + additional_computation_factor: "0", receipt: SAMPLE_DIGEST, standard_payment: "true", }; @@ -675,14 +676,21 @@ mod transaction { assert!(transaction.is_ok(), "{:?}", transaction); assert_eq!(transaction.as_ref().unwrap().chain_name(), "withdraw-bid"); assert_eq!( - transaction.as_ref().unwrap().args().get("amount").unwrap(), + transaction + .as_ref() + .unwrap() + .deserialize_field::(ARGS_MAP_KEY) + .unwrap() + .get("amount") + .unwrap(), amount_cl ); assert_eq!( transaction .as_ref() .unwrap() - .args() + .deserialize_field::(ARGS_MAP_KEY) + .unwrap() .get("public_key") .unwrap(), public_key_cl @@ -714,6 +722,7 @@ mod transaction { output_path: "", payment_amount: "100", gas_price_tolerance: "10", + additional_computation_factor: "0", receipt: SAMPLE_DIGEST, standard_payment: "true", }; @@ -730,14 +739,21 @@ mod transaction { assert!(transaction.is_ok(), "{:?}", transaction); assert_eq!(transaction.as_ref().unwrap().chain_name(), "undelegate"); assert_eq!( - transaction.as_ref().unwrap().args().get("amount").unwrap(), + transaction + .as_ref() + .unwrap() + .deserialize_field::(ARGS_MAP_KEY) + .unwrap() + .get("amount") + .unwrap(), amount_cl ); assert_eq!( transaction .as_ref() .unwrap() - .args() + .deserialize_field::(ARGS_MAP_KEY) + .unwrap() .get("delegator") .unwrap(), delegator_public_key_cl @@ -746,7 +762,8 @@ mod transaction { transaction .as_ref() .unwrap() - .args() + .deserialize_field::(ARGS_MAP_KEY) + .unwrap() .get("validator") .unwrap(), validator_public_key_cl @@ -781,6 +798,7 @@ mod transaction { output_path: "", payment_amount: "100", gas_price_tolerance: "10", + additional_computation_factor: "", receipt: SAMPLE_DIGEST, standard_payment: "true", }; @@ -796,14 +814,21 @@ mod transaction { assert!(transaction.is_ok(), "{:?}", transaction); assert_eq!(transaction.as_ref().unwrap().chain_name(), "redelegate"); assert_eq!( - transaction.as_ref().unwrap().args().get("amount").unwrap(), + transaction + .as_ref() + .unwrap() + .deserialize_field::(ARGS_MAP_KEY) + .unwrap() + .get("amount") + .unwrap(), amount_cl ); assert_eq!( transaction .as_ref() .unwrap() - .args() + .deserialize_field::(ARGS_MAP_KEY) + .unwrap() .get("delegator") .unwrap(), delegator_public_key_cl @@ -812,7 +837,8 @@ mod transaction { transaction .as_ref() .unwrap() - .args() + .deserialize_field::(ARGS_MAP_KEY) + .unwrap() .get("validator") .unwrap(), validator_public_key_cl @@ -821,7 +847,8 @@ mod transaction { transaction .as_ref() .unwrap() - .args() + .deserialize_field::(ARGS_MAP_KEY) + .unwrap() .get("new_validator") .unwrap(), new_validator_public_key_cl @@ -852,6 +879,7 @@ mod transaction { output_path: "", payment_amount: "100", gas_price_tolerance: "10", + additional_computation_factor: "0", receipt: SAMPLE_DIGEST, standard_payment: "true", }; @@ -869,10 +897,21 @@ mod transaction { "invocable-entity" ); assert_eq!( - transaction.as_ref().unwrap().body().entry_point(), - entry_point_ref + transaction + .as_ref() + .unwrap() + .deserialize_field::(ENTRY_POINT_MAP_KEY) + .unwrap(), + *entry_point_ref + ); + assert_eq!( + transaction + .as_ref() + .unwrap() + .deserialize_field::(TARGET_MAP_KEY) + .unwrap(), + *target ); - assert_eq!(transaction.as_ref().unwrap().body().target(), target); } #[test] fn should_create_invocable_entity_alias_transaction() { @@ -894,6 +933,7 @@ mod transaction { payment_amount: "100", gas_price_tolerance: "10", receipt: SAMPLE_DIGEST, + additional_computation_factor: "", standard_payment: "true", }; @@ -909,10 +949,21 @@ mod transaction { "invocable-entity-alias" ); assert_eq!( - transaction.as_ref().unwrap().body().entry_point(), - &TransactionEntryPoint::Custom("entry-point-alias".to_string()) + transaction + .as_ref() + .unwrap() + .deserialize_field::(ENTRY_POINT_MAP_KEY) + .unwrap(), + TransactionEntryPoint::Custom("entry-point-alias".to_string()) + ); + assert_eq!( + transaction + .as_ref() + .unwrap() + .deserialize_field::(TARGET_MAP_KEY) + .unwrap(), + *target ); - assert_eq!(transaction.as_ref().unwrap().body().target(), target); } #[test] fn should_create_package_transaction() { @@ -939,6 +990,7 @@ mod transaction { payment_amount: "100", gas_price_tolerance: "10", receipt: SAMPLE_DIGEST, + additional_computation_factor: "", standard_payment: "true", }; @@ -952,10 +1004,21 @@ mod transaction { assert!(transaction.is_ok(), "{:?}", transaction); assert_eq!(transaction.as_ref().unwrap().chain_name(), "package"); assert_eq!( - transaction.as_ref().unwrap().body().entry_point(), - &TransactionEntryPoint::Custom("test-entry-point-package".to_string()) + transaction + .as_ref() + .unwrap() + .deserialize_field::(ENTRY_POINT_MAP_KEY) + .unwrap(), + TransactionEntryPoint::Custom("test-entry-point-package".to_string()) + ); + assert_eq!( + transaction + .as_ref() + .unwrap() + .deserialize_field::(TARGET_MAP_KEY) + .unwrap(), + *target ); - assert_eq!(transaction.as_ref().unwrap().body().target(), target); } #[test] fn should_create_package_alias_transaction() { @@ -981,6 +1044,7 @@ mod transaction { output_path: "", payment_amount: "100", gas_price_tolerance: "10", + additional_computation_factor: "", receipt: SAMPLE_DIGEST, standard_payment: "true", }; @@ -995,15 +1059,28 @@ mod transaction { assert!(transaction.is_ok(), "{:?}", transaction); assert_eq!(transaction.as_ref().unwrap().chain_name(), "package"); assert_eq!( - transaction.as_ref().unwrap().body().entry_point(), - &TransactionEntryPoint::Custom("test-entry-point-package".to_string()) + transaction + .as_ref() + .unwrap() + .deserialize_field::(ENTRY_POINT_MAP_KEY) + .unwrap(), + TransactionEntryPoint::Custom("test-entry-point-package".to_string()) + ); + assert_eq!( + transaction + .as_ref() + .unwrap() + .deserialize_field::(TARGET_MAP_KEY) + .unwrap(), + *target ); - assert_eq!(transaction.as_ref().unwrap().body().target(), target); } #[test] fn should_create_session_transaction() { let transaction_bytes = Bytes::from(vec![1u8; 32]); + let is_install_upgrade = true; let target = &TransactionTarget::Session { + is_install_upgrade, runtime: TransactionRuntime::VmCasperV1, module_bytes: transaction_bytes.clone(), }; @@ -1019,23 +1096,35 @@ mod transaction { output_path: "", payment_amount: "100", gas_price_tolerance: "10", + additional_computation_factor: "0", receipt: SAMPLE_DIGEST, standard_payment: "true", }; let transaction_builder_params = TransactionBuilderParams::Session { + is_install_upgrade, transaction_bytes, - transaction_category: casper_types::TransactionCategory::Large, }; let transaction = create_transaction(transaction_builder_params, transaction_string_params, true); assert!(transaction.is_ok(), "{:?}", transaction); assert_eq!(transaction.as_ref().unwrap().chain_name(), "session"); assert_eq!( - transaction.as_ref().unwrap().body().entry_point(), - &TransactionEntryPoint::Call + transaction + .as_ref() + .unwrap() + .deserialize_field::(ENTRY_POINT_MAP_KEY) + .unwrap(), + TransactionEntryPoint::Call + ); + assert_eq!( + transaction + .as_ref() + .unwrap() + .deserialize_field::(TARGET_MAP_KEY) + .unwrap(), + *target ); - assert_eq!(transaction.as_ref().unwrap().body().target(), target); } #[test] fn should_create_transfer_transaction() { @@ -1067,6 +1156,7 @@ mod transaction { output_path: "", payment_amount: "100", gas_price_tolerance: "10", + additional_computation_factor: "1", receipt: SAMPLE_DIGEST, standard_payment: "true", }; @@ -1082,15 +1172,31 @@ mod transaction { assert!(transaction.is_ok(), "{:?}", transaction); assert_eq!(transaction.as_ref().unwrap().chain_name(), "transfer"); assert_eq!( - transaction.as_ref().unwrap().body().entry_point(), - &TransactionEntryPoint::Transfer + transaction + .as_ref() + .unwrap() + .deserialize_field::(ENTRY_POINT_MAP_KEY) + .unwrap(), + TransactionEntryPoint::Transfer ); assert_eq!( - transaction.as_ref().unwrap().args().get("source").unwrap(), + transaction + .as_ref() + .unwrap() + .deserialize_field::(ARGS_MAP_KEY) + .unwrap() + .get("source") + .unwrap(), source_uref_cl ); assert_eq!( - transaction.as_ref().unwrap().args().get("target").unwrap(), + transaction + .as_ref() + .unwrap() + .deserialize_field::(ARGS_MAP_KEY) + .unwrap() + .get("target") + .unwrap(), target_uref_cl ); } @@ -1108,6 +1214,7 @@ mod transaction { output_path: "", payment_amount: "100", gas_price_tolerance: "10", + additional_computation_factor: "", receipt: SAMPLE_DIGEST, standard_payment: "true", }; @@ -1144,6 +1251,7 @@ mod transaction { output_path: "", payment_amount: "100", gas_price_tolerance: "10", + additional_computation_factor: "", receipt: SAMPLE_DIGEST, standard_payment: "true", }; @@ -1177,6 +1285,7 @@ mod transaction { output_path: "", payment_amount: "100", gas_price_tolerance: "", + additional_computation_factor: "", receipt: SAMPLE_DIGEST, standard_payment: "true", }; diff --git a/lib/cli/transaction.rs b/lib/cli/transaction.rs index 9a84ab8e..dc9c30c5 100644 --- a/lib/cli/transaction.rs +++ b/lib/cli/transaction.rs @@ -58,6 +58,7 @@ pub fn create_transaction( transaction_params.pricing_mode, transaction_params.payment_amount, transaction_params.gas_price_tolerance, + transaction_params.additional_computation_factor, transaction_params.standard_payment, Some(digest), )? @@ -66,6 +67,7 @@ pub fn create_transaction( transaction_params.pricing_mode, transaction_params.payment_amount, transaction_params.gas_price_tolerance, + transaction_params.additional_computation_factor, transaction_params.standard_payment, None, )? @@ -296,11 +298,11 @@ pub fn make_transaction_builder( Ok(transaction_builder) } TransactionBuilderParams::Session { + is_install_upgrade, transaction_bytes, - transaction_category, } => { let transaction_builder = - TransactionV1Builder::new_session(transaction_category, transaction_bytes); + TransactionV1Builder::new_session(is_install_upgrade, transaction_bytes); Ok(transaction_builder) } TransactionBuilderParams::Transfer { diff --git a/lib/cli/transaction_builder_params.rs b/lib/cli/transaction_builder_params.rs index 373c8d91..245db3e4 100644 --- a/lib/cli/transaction_builder_params.rs +++ b/lib/cli/transaction_builder_params.rs @@ -1,7 +1,5 @@ use casper_types::bytesrepr::Bytes; -use casper_types::{ - AddressableEntityHash, PackageHash, PublicKey, TransactionCategory, TransferTarget, URef, U512, -}; +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 @@ -83,10 +81,10 @@ pub enum TransactionBuilderParams<'a> { }, /// Parameters for the session variant of the transaction builder Session { + /// Flag determining if the Wasm is an install/upgrade. + is_install_upgrade: bool, /// The Bytes to be run by the execution engine for the session transaction transaction_bytes: Bytes, - /// Transaction category - transaction_category: TransactionCategory, }, /// 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 e7e694f2..83dce87a 100644 --- a/lib/cli/transaction_str_params.rs +++ b/lib/cli/transaction_str_params.rs @@ -56,6 +56,9 @@ pub struct TransactionStrParams<'a> { pub session_args_json: &'a str, /// The pricing mode to use with the transaction pub pricing_mode: &'a str, + /// User-specified additional computation factor for "fixed" pricing_mode (minimum 0) + /// if "0" is provided, no additional logic is applied to the computation limit. + pub additional_computation_factor: &'a str, /// The optional output path for the transaction, if writing it to a file. pub output_path: &'a str, /// The payment amount for executing the transaction diff --git a/src/transaction/creation_common.rs b/src/transaction/creation_common.rs index daf52920..f55d5eb1 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, ChainName, MaximumDelegationRate, MinimumDelegationRate, @@ -48,6 +47,8 @@ pub(super) enum DisplayOrder { StandardPayment, Receipt, GasPriceTolerance, + AdditionalComputationFactor, + IsInstallUpgrade, TransactionAmount, Validator, NewValidator, @@ -195,6 +196,7 @@ pub(super) mod chain_name { Arg::new(ARG_NAME) .long(ARG_NAME) .value_name(ARG_VALUE_NAME) + .required(true) .help(ARG_HELP) .display_order(DisplayOrder::ChainName as usize) } @@ -506,6 +508,38 @@ pub(super) mod pricing_mode { } } +pub(super) mod additional_computation_factor { + use super::*; + pub(in crate::transaction) const ARG_NAME: &str = "additional-computation-factor"; + + const ARG_VALUE_NAME: &str = common::ARG_INTEGER; + + const ARG_ALIAS: &str = "additional-computation"; + const ARG_SHORT: char = 'c'; + const ARG_HELP: &str = + "User-specified additional computation factor for \"fixed\" pricing_mode"; + const ARG_DEFAULT: &str = "0"; + + pub(in crate::transaction) fn arg() -> Arg { + Arg::new(ARG_NAME) + .long(ARG_NAME) + .alias(ARG_ALIAS) + .short(ARG_SHORT) + .required(false) + .default_value(ARG_DEFAULT) + .value_name(ARG_VALUE_NAME) + .help(ARG_HELP) + .display_order(DisplayOrder::AdditionalComputationFactor as usize) + } + + pub fn get(matches: &ArgMatches) -> &str { + matches + .get_one::(ARG_NAME) + .map(String::as_str) + .unwrap_or_default() + } +} + pub(super) mod initiator_address { use super::*; pub(in crate::transaction) const ARG_NAME: &str = "initiator-address"; @@ -605,6 +639,7 @@ pub(super) fn apply_common_creation_options( .arg(output::arg()) .arg(payment_amount::arg()) .arg(pricing_mode::arg()) + .arg(additional_computation_factor::arg()) .arg(gas_price_tolerance::arg()) .arg(receipt::arg()) .arg(standard_payment::arg()) @@ -671,7 +706,7 @@ pub(super) mod transaction_path { use super::*; const ARG_NAME: &str = "transaction-path"; - const ARG_SHORT: char = 'i'; + const ARG_SHORT: char = 't'; const ARG_VALUE_NAME: &str = common::ARG_PATH; const ARG_HELP: &str = "Path to input transaction file"; @@ -690,80 +725,23 @@ pub(super) mod transaction_path { } } -pub(super) mod transaction_category { - use std::str::FromStr; - - use casper_types::TransactionCategory; - use clap::{value_parser, ValueEnum}; - +pub(super) mod is_install_upgrade { use super::*; - const ARG_NAME: &str = "category"; - const ARG_SHORT: char = 'c'; - const ARG_VALUE_NAME: &str = "install-upgrade|large|medium|small"; - const ARG_HELP: &str = "Transaction category"; + const ARG_NAME: &str = "install-upgrade"; + const ARG_HELP: &str = "Flag to indicate if the Wasm is an install/upgrade"; - #[derive(Debug, Clone, Copy)] - pub(super) enum Category { - InstallUpgrade, - Large, - Medium, - Small, - } - - impl Category { - pub(super) fn into_transaction_v1_category(self) -> TransactionCategory { - match self { - Self::InstallUpgrade => TransactionCategory::InstallUpgrade, - Self::Large => TransactionCategory::Large, - Self::Medium => TransactionCategory::Medium, - Self::Small => TransactionCategory::Small, - } - } - } - - impl ValueEnum for Category { - fn value_variants<'a>() -> &'a [Self] { - &[Self::InstallUpgrade, Self::Large, Self::Medium, Self::Small] - } - - fn to_possible_value(&self) -> Option { - Some(match self { - Self::InstallUpgrade => clap::builder::PossibleValue::new("install-upgrade"), - Self::Large => clap::builder::PossibleValue::new("large"), - Self::Medium => clap::builder::PossibleValue::new("medium"), - Self::Small => clap::builder::PossibleValue::new("small"), - }) - } - } - - impl FromStr for Category { - type Err = String; - - fn from_str(s: &str) -> Result { - match s.to_lowercase().as_str() { - "install-upgrade" => Ok(Category::InstallUpgrade), - "large" => Ok(Category::Large), - "medium" => Ok(Category::Medium), - "small" => Ok(Category::Small), - _ => Err(format!("'{}' is not a valid size option", s)), - } - } - } - - pub fn arg() -> Arg { + pub fn arg(order: usize) -> Arg { Arg::new(ARG_NAME) - .required(true) .long(ARG_NAME) - .short(ARG_SHORT) - .value_name(ARG_VALUE_NAME) + .required(false) + .action(ArgAction::SetTrue) .help(ARG_HELP) - .display_order(DisplayOrder::TransactionCategory as usize) - .value_parser(value_parser!(Category)) + .display_order(order) } - pub(super) fn get(matches: &ArgMatches) -> Option<&Category> { - matches.get_one(ARG_NAME) + pub fn get(matches: &ArgMatches) -> bool { + matches.args_present() } } @@ -1710,12 +1688,11 @@ pub(super) mod session { let transaction_bytes = parse::transaction_module_bytes(transaction_path_str.unwrap_or_default())?; - let transaction_category = *transaction_category::get(matches) - .ok_or(CliError::FailedToParseTransactionCategory)?; + let is_install_upgrade: bool = is_install_upgrade::get(matches); let params = TransactionBuilderParams::Session { + is_install_upgrade, transaction_bytes, - transaction_category: transaction_category.into_transaction_v1_category(), }; let transaction_str_params = build_transaction_str_params(matches, ACCEPT_SESSION_ARGS); Ok((params, transaction_str_params)) @@ -1725,7 +1702,9 @@ pub(super) mod session { add_bid_subcommand .arg(transaction_path::arg()) .arg(session_entry_point::arg()) - .arg(transaction_category::arg()) + .arg(is_install_upgrade::arg( + DisplayOrder::IsInstallUpgrade as usize, + )) } } @@ -1903,6 +1882,7 @@ pub(super) fn build_transaction_str_params( let chain_name = chain_name::get(matches); let maybe_pricing_mode = pricing_mode::get(matches); let gas_price_tolerance = gas_price_tolerance::get(matches); + let additional_computation_factor = additional_computation_factor::get(matches); let payment_amount = payment_amount::get(matches); let receipt = receipt::get(matches); let standard_payment = standard_payment::get(matches); @@ -1925,6 +1905,7 @@ pub(super) fn build_transaction_str_params( output_path: maybe_output_path, payment_amount, gas_price_tolerance, + additional_computation_factor, receipt, standard_payment, } @@ -1939,6 +1920,7 @@ pub(super) fn build_transaction_str_params( output_path: maybe_output_path, payment_amount, gas_price_tolerance, + additional_computation_factor, receipt, standard_payment, ..Default::default()