Skip to content

Commit

Permalink
Changed the way transaction lanes are calculated if the transaction h…
Browse files Browse the repository at this point in the history
…as PricingMode::PaymentLimited. For wasm based transaction with that pricing mode the `payment_amount` field will be used as size estimate to determine the wasm lane.
  • Loading branch information
Jakub Zajkowski committed Dec 12, 2024
1 parent c881b11 commit e8240d5
Show file tree
Hide file tree
Showing 9 changed files with 295 additions and 49 deletions.
5 changes: 3 additions & 2 deletions node/src/components/transaction_buffer/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1123,8 +1123,9 @@ fn make_test_chainspec(max_standard_count: u64, max_mint_count: u64) -> Arc<Chai
transaction_v1_config.native_mint_lane =
TransactionLimitsDefinition::try_from(vec![0, 1024, 1024, 65_000_000_000, max_mint_count])
.unwrap();
transaction_v1_config.wasm_lanes =
vec![TransactionLimitsDefinition::try_from(large_lane).unwrap()];
transaction_v1_config.set_wasm_lanes(vec![
TransactionLimitsDefinition::try_from(large_lane).unwrap()
]);

let transaction_config = TransactionConfig {
transaction_v1_config,
Expand Down
2 changes: 1 addition & 1 deletion node/src/types/appendable_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ impl AppendableBlock {
for lane_id in self
.transaction_config
.transaction_v1_config
.wasm_lanes
.wasm_lanes()
.iter()
.map(|lane| lane.id())
{
Expand Down
7 changes: 5 additions & 2 deletions node/src/types/transaction/meta_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,11 @@ impl MetaTransaction {
) -> Result<Self, InvalidTransaction> {
match transaction {
Transaction::Deploy(deploy) => Ok(MetaTransaction::Deploy(deploy.clone())),
Transaction::V1(v1) => MetaTransactionV1::from_transaction_v1(v1, transaction_config)
.map(MetaTransaction::V1),
Transaction::V1(v1) => MetaTransactionV1::from_transaction_v1(
v1,
&transaction_config.transaction_v1_config,
)
.map(MetaTransaction::V1),
}
}

Expand Down
137 changes: 133 additions & 4 deletions node/src/types/transaction/meta_transaction/meta_transaction_v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use casper_types::{
HashAddr, InitiatorAddr, InvalidTransaction, InvalidTransactionV1, PricingHandling,
PricingMode, TimeDiff, Timestamp, TransactionArgs, TransactionConfig, TransactionEntryPoint,
TransactionRuntimeParams, TransactionScheduling, TransactionTarget, TransactionV1,
TransactionV1ExcessiveSizeError, TransactionV1Hash, U512,
TransactionV1Config, TransactionV1ExcessiveSizeError, TransactionV1Hash, U512,
};
use core::fmt::{self, Debug, Display, Formatter};
use datasize::DataSize;
Expand Down Expand Up @@ -45,7 +45,7 @@ pub struct MetaTransactionV1 {
impl MetaTransactionV1 {
pub fn from_transaction_v1(
v1: &TransactionV1,
transaction_config: &TransactionConfig,
transaction_v1_config: &TransactionV1Config,
) -> Result<MetaTransactionV1, InvalidTransaction> {
let args: TransactionArgs = v1.deserialize_field(ARGS_MAP_KEY).map_err(|error| {
InvalidTransaction::V1(InvalidTransactionV1::CouldNotDeserializeField { error })
Expand All @@ -70,13 +70,18 @@ impl MetaTransactionV1 {

let payload_hash = v1.payload_hash()?;
let serialized_length = v1.serialized_length();
let size_estimation = match v1.payload().pricing_mode() {
PricingMode::PaymentLimited { payment_amount, .. } => *payment_amount,
PricingMode::Fixed { .. } => serialized_length as u64,
PricingMode::Prepaid { .. } => serialized_length as u64,
};

let lane_id = calculate_transaction_lane(
&entry_point,
&target,
v1.pricing_mode().additional_computation_factor(),
transaction_config,
serialized_length as u64,
transaction_v1_config,
size_estimation,
)?;
let transaction_lane =
TransactionLane::try_from(lane_id).map_err(Into::<InvalidTransaction>::into)?;
Expand Down Expand Up @@ -701,3 +706,127 @@ impl Display for MetaTransactionV1 {
)
}
}

#[cfg(test)]
mod tests {
use super::MetaTransactionV1;
use crate::types::transaction::transaction_v1_builder::TransactionV1Builder;
use casper_types::{
testing::TestRng, InvalidTransaction, InvalidTransactionV1, PricingMode, SecretKey,
TransactionInvocationTarget, TransactionLimitsDefinition, TransactionRuntimeParams,
TransactionV1Config,
};

#[test]
fn limited_amount_should_determine_transaction_lane_for_session() {
let rng = &mut TestRng::new();
let secret_key = SecretKey::random(rng);
let pricing_mode = PricingMode::PaymentLimited {
payment_amount: 1001,
gas_price_tolerance: 1,
standard_payment: true,
};

let transaction_v1 = TransactionV1Builder::new_session(
false,
vec![1; 30].into(),
TransactionRuntimeParams::VmCasperV1,
)
.with_chain_name("x".to_string())
.with_pricing_mode(pricing_mode)
.with_secret_key(&secret_key)
.build()
.unwrap();
let config = build_v1_config();

let meta_transaction = MetaTransactionV1::from_transaction_v1(&transaction_v1, &config)
.expect("meta transaction should be valid");
assert_eq!(meta_transaction.transaction_lane(), 4);
}

#[test]
fn limited_amount_should_fail_if_does_not_fit_in_any_lane() {
let rng = &mut TestRng::new();
let secret_key = SecretKey::random(rng);
let pricing_mode = PricingMode::PaymentLimited {
payment_amount: 1000000,
gas_price_tolerance: 1,
standard_payment: true,
};

let transaction_v1 = TransactionV1Builder::new_session(
false,
vec![1; 30].into(),
TransactionRuntimeParams::VmCasperV1,
)
.with_chain_name("x".to_string())
.with_pricing_mode(pricing_mode)
.with_secret_key(&secret_key)
.build()
.unwrap();
let config = build_v1_config();

let res = MetaTransactionV1::from_transaction_v1(&transaction_v1, &config);
assert!(matches!(
res,
Err(InvalidTransaction::V1(
InvalidTransactionV1::NoWasmLaneMatchesTransaction()
))
))
}

#[test]
fn limited_amount_should_determine_transaction_lane_for_stored() {
let rng = &mut TestRng::new();
let secret_key = SecretKey::random(rng);
let pricing_mode = PricingMode::PaymentLimited {
payment_amount: 1001,
gas_price_tolerance: 1,
standard_payment: true,
};

let transaction_v1 = TransactionV1Builder::new_targeting_stored(
TransactionInvocationTarget::ByName("xyz".to_string()),
"abc",
TransactionRuntimeParams::VmCasperV1,
)
.with_chain_name("x".to_string())
.with_secret_key(&secret_key)
.with_pricing_mode(pricing_mode)
.build()
.unwrap();
let config = build_v1_config();

let meta_transaction = MetaTransactionV1::from_transaction_v1(&transaction_v1, &config)
.expect("meta transaction should be valid");
assert_eq!(meta_transaction.transaction_lane(), 4);
}

fn build_v1_config() -> TransactionV1Config {
let mut config = TransactionV1Config::default();
config.set_wasm_lanes(vec![
TransactionLimitsDefinition {
id: 3,
max_transaction_length: 100,
max_transaction_args_length: 100,
max_transaction_gas_limit: 100,
max_transaction_count: 10,
},
TransactionLimitsDefinition {
id: 4,
max_transaction_length: 10000,
max_transaction_args_length: 100,
max_transaction_gas_limit: 100,
max_transaction_count: 10,
},
TransactionLimitsDefinition {
id: 5,
max_transaction_length: 1000,
max_transaction_args_length: 100,
max_transaction_gas_limit: 100,
max_transaction_count: 10,
},
]);
config
}
}
21 changes: 10 additions & 11 deletions node/src/types/transaction/meta_transaction/transaction_lane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ use core::{
};

use casper_types::{
InvalidTransaction, InvalidTransactionV1, TransactionConfig, TransactionEntryPoint,
TransactionRuntimeParams, TransactionTarget, TransactionV1Config, AUCTION_LANE_ID,
INSTALL_UPGRADE_LANE_ID, MINT_LANE_ID,
InvalidTransaction, InvalidTransactionV1, TransactionEntryPoint, TransactionRuntimeParams,
TransactionTarget, TransactionV1Config, AUCTION_LANE_ID, INSTALL_UPGRADE_LANE_ID, MINT_LANE_ID,
};
use datasize::DataSize;
use serde::Serialize;
Expand Down Expand Up @@ -72,8 +71,8 @@ pub(crate) fn calculate_transaction_lane(
entry_point: &TransactionEntryPoint,
target: &TransactionTarget,
additional_computation_factor: u8,
transaction_config: &TransactionConfig,
transaction_size: u64,
config: &TransactionV1Config,
size_estimation: u64,
) -> Result<u8, InvalidTransactionV1> {
match target {
TransactionTarget::Native => match entry_point {
Expand All @@ -96,8 +95,8 @@ pub(crate) fn calculate_transaction_lane(
},
TransactionTarget::Stored { .. } => match entry_point {
TransactionEntryPoint::Custom(_) => get_lane_for_non_install_wasm(
&transaction_config.transaction_v1_config,
transaction_size,
config,
size_estimation,
additional_computation_factor,
),
TransactionEntryPoint::Call
Expand Down Expand Up @@ -126,8 +125,8 @@ pub(crate) fn calculate_transaction_lane(
Ok(INSTALL_UPGRADE_LANE_ID)
} else {
get_lane_for_non_install_wasm(
&transaction_config.transaction_v1_config,
transaction_size,
config,
size_estimation,
additional_computation_factor,
)
}
Expand Down Expand Up @@ -158,8 +157,8 @@ pub(crate) fn calculate_transaction_lane(
Ok(INSTALL_UPGRADE_LANE_ID)
} else {
get_lane_for_non_install_wasm(
&transaction_config.transaction_v1_config,
transaction_size,
config,
size_estimation,
additional_computation_factor,
)
}
Expand Down
Loading

0 comments on commit e8240d5

Please sign in to comment.