Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 68 additions & 9 deletions node/src/components/transaction_acceptor/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,11 @@ enum TestScenario {
DeployWithMangledTransferAmount,
DeployWithoutTransferTarget,
DeployWithoutTransferAmount,
DeployWithPaymentOne,
BalanceCheckForDeploySentByPeer,
InvalidPricingModeForTransactionV1,
TooLowGasPriceToleranceForTransactionV1,
TransactionWithPaymentOne,
TooLowGasPriceToleranceForDeploy,
InvalidFields,
InvalidFieldsFromPeer,
Expand Down Expand Up @@ -256,6 +258,7 @@ impl TestScenario {
| TestScenario::DeployWithMangledPaymentAmount
| TestScenario::DeployWithMangledTransferAmount
| TestScenario::DeployWithoutTransferAmount
| TestScenario::DeployWithPaymentOne
| TestScenario::DeployWithoutTransferTarget
| TestScenario::FromClientCustomPaymentContract(_)
| TestScenario::FromClientCustomPaymentContractPackage(_)
Expand All @@ -267,6 +270,7 @@ impl TestScenario {
| TestScenario::InvalidPricingModeForTransactionV1
| TestScenario::TooLowGasPriceToleranceForTransactionV1
| TestScenario::TooLowGasPriceToleranceForDeploy
| TestScenario::TransactionWithPaymentOne
| TestScenario::InvalidFields
| TestScenario::InvalidArgumentsKind
| TestScenario::WasmTransactionWithTooBigPayment
Expand Down Expand Up @@ -412,6 +416,33 @@ impl TestScenario {
TestScenario::DeployWithMangledTransferAmount => {
Transaction::from(Deploy::random_with_mangled_transfer_amount(rng))
}
TestScenario::DeployWithPaymentOne => {
Transaction::from(Deploy::random_with_payment_one(rng))
}

TestScenario::TransactionWithPaymentOne => {
let timestamp = Timestamp::now()
+ Config::default().timestamp_leeway
+ TimeDiff::from_millis(100);
let ttl = TimeDiff::from_seconds(300);
let txn = TransactionV1Builder::new_session(
false,
Bytes::from(vec![1]),
TransactionRuntimeParams::VmCasperV1,
)
.with_pricing_mode(PricingMode::PaymentLimited {
payment_amount: 1u64,
gas_price_tolerance: 2,
standard_payment: true,
})
.with_chain_name("casper-example")
.with_timestamp(timestamp)
.with_ttl(ttl)
.with_secret_key(&secret_key)
.build()
.unwrap();
Transaction::from(txn)
}

TestScenario::FromPeerCustomPaymentContract(contract_scenario)
| TestScenario::FromClientCustomPaymentContract(contract_scenario) => {
Expand Down Expand Up @@ -753,6 +784,7 @@ impl TestScenario {
| TestScenario::DeployWithMangledTransferAmount
| TestScenario::DeployWithoutTransferAmount
| TestScenario::DeployWithoutTransferTarget
| TestScenario::DeployWithPaymentOne
| TestScenario::BalanceCheckForDeploySentByPeer
| TestScenario::FromClientExpired(_) => false,
TestScenario::FromPeerCustomPaymentContract(contract_scenario)
Expand All @@ -775,15 +807,16 @@ impl TestScenario {
| ContractPackageScenario::MissingPackageAtHash
| ContractPackageScenario::MissingContractVersion => false,
}
}
TestScenario::InvalidPricingModeForTransactionV1 => false,
TestScenario::TooLowGasPriceToleranceForTransactionV1 => false,
TestScenario::TooLowGasPriceToleranceForDeploy => false,
TestScenario::InvalidFields => false,
TestScenario::InvalidFieldsFromPeer => false,
TestScenario::InvalidArgumentsKind => false,
TestScenario::WasmTransactionWithTooBigPayment => false,
TestScenario::WasmDeployWithTooBigPayment => false,
},
TestScenario::InvalidPricingModeForTransactionV1
| TestScenario::TooLowGasPriceToleranceForTransactionV1
| TestScenario::TransactionWithPaymentOne
| TestScenario::TooLowGasPriceToleranceForDeploy
| TestScenario::InvalidFields
| TestScenario::InvalidFieldsFromPeer
| TestScenario::InvalidArgumentsKind
| TestScenario::WasmTransactionWithTooBigPayment
| TestScenario::WasmDeployWithTooBigPayment => false,
}
}

Expand Down Expand Up @@ -1343,9 +1376,11 @@ async fn run_transaction_acceptor_without_timeout(
| TestScenario::DeployWithMangledTransferAmount
| TestScenario::DeployWithoutTransferTarget
| TestScenario::DeployWithoutTransferAmount
| TestScenario::DeployWithPaymentOne
| TestScenario::InvalidPricingModeForTransactionV1
| TestScenario::FromClientExpired(_)
| TestScenario::TooLowGasPriceToleranceForTransactionV1
| TestScenario::TransactionWithPaymentOne
| TestScenario::TooLowGasPriceToleranceForDeploy
| TestScenario::InvalidFields
| TestScenario::InvalidArgumentsKind
Expand Down Expand Up @@ -2468,6 +2503,18 @@ async fn should_reject_deploy_with_empty_module_bytes_in_session() {
))
}

#[tokio::test]
async fn should_reject_deploy_with_insufficient_payment() {
let test_scenario = TestScenario::DeployWithPaymentOne;
let result = run_transaction_acceptor(test_scenario).await;
assert!(matches!(
result,
Err(super::Error::InvalidTransaction(
InvalidTransaction::Deploy(InvalidDeploy::InvalidPaymentAmount)
))
))
}

#[tokio::test]
async fn should_reject_deploy_with_transfer_in_payment() {
let test_scenario = TestScenario::DeployWithNativeTransferInPayment;
Expand Down Expand Up @@ -2618,6 +2665,18 @@ async fn should_reject_transaction_v1_with_too_low_gas_price_tolerance() {
))
}

#[tokio::test]
async fn should_reject_transaction_v1_with_insufficient_payment() {
let test_scenario = TestScenario::TransactionWithPaymentOne;
let result = run_transaction_acceptor(test_scenario).await;
assert!(matches!(
result,
Err(super::Error::InvalidTransaction(InvalidTransaction::V1(
InvalidTransactionV1::InvalidPaymentAmount
)))
))
}

#[tokio::test]
async fn should_reject_deploy_with_too_low_gas_price_tolerance() {
let test_scenario = TestScenario::TooLowGasPriceToleranceForDeploy;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,8 @@ impl MetaTransactionV1 {
if *payment_amount < expected_payment {
return Err(InvalidTransactionV1::InvalidPaymentAmount);
}
} else if *payment_amount < chainspec.core_config.baseline_motes_amount {
return Err(InvalidTransactionV1::InvalidPaymentAmount);
}
} else {
return Err(InvalidTransactionV1::InvalidPricingMode {
Expand Down
143 changes: 128 additions & 15 deletions types/src/transaction/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,23 @@ impl Deploy {
attempted: Box::new(attempted),
});
}
} else {
let payment_args = self.payment().args();
let payment_amount = payment_args
.get(ARG_AMOUNT)
.ok_or_else(|| {
debug!("missing transfer 'amount' runtime argument");
InvalidDeploy::MissingTransferAmount
})?
.clone()
.into_t::<U512>()
.map_err(|_| {
debug!("failed to parse transfer 'amount' runtime argument as a U512");
InvalidDeploy::FailedToParseTransferAmount
})?;
if payment_amount < U512::from(chainspec.core_config.baseline_motes_amount) {
return Err(InvalidDeploy::InvalidPaymentAmount);
}
}

Ok(())
Expand Down Expand Up @@ -652,8 +669,9 @@ impl Deploy {
"source" => PublicKey::random(rng).to_account_hash(),
"target" => PublicKey::random(rng).to_account_hash(),
};
let payment_amount = 10_000_000_000u64;
let payment_args = runtime_args! {
"amount" => U512::from(10),
"amount" => U512::from(payment_amount),
};
let session = ExecutableDeployItem::Transfer {
args: transfer_args,
Expand Down Expand Up @@ -732,6 +750,55 @@ impl Deploy {
Self::random_transfer_with_payment(rng, payment)
}

/// Returns a random invalid `Deploy` with insufficient payment amount.
#[cfg(any(all(feature = "std", feature = "testing"), test))]
pub fn random_with_payment_one(rng: &mut TestRng) -> Self {
let timestamp = Timestamp::now();
let ttl = TimeDiff::from_seconds(rng.gen_range(60..3600));
let payment_args = runtime_args! {
"amount" => U512::one()
};
let payment = ExecutableDeployItem::ModuleBytes {
module_bytes: Bytes::new(),
args: payment_args,
};
let gas_price = rng.gen_range(1..4);

let dependencies = vec![];
let chain_name = String::from("casper-example");
let session = rng.gen();

let secret_key = SecretKey::random(rng);

Deploy::new_signed(
timestamp,
ttl,
gas_price,
dependencies,
chain_name,
payment,
session,
&secret_key,
None,
)
}

/// Returns a random invalid `Deploy` with insufficient payment amount.
#[cfg(any(all(feature = "std", feature = "testing"), test))]
pub fn random_with_insufficient_payment_amount(
Comment thread
EdHastingsCasperAssociation marked this conversation as resolved.
rng: &mut TestRng,
payment_amount: U512,
) -> Self {
let payment_args = runtime_args! {
"amount" => payment_amount
};
let payment = ExecutableDeployItem::ModuleBytes {
module_bytes: Bytes::new(),
args: payment_args,
};
Self::random_transfer_with_payment(rng, payment)
}

/// Returns a random invalid `Deploy` with an invalid value for the payment amount.
#[cfg(any(all(feature = "std", feature = "testing"), test))]
pub fn random_with_oversized_payment_amount(rng: &mut TestRng) -> Self {
Expand Down Expand Up @@ -866,12 +933,40 @@ impl Deploy {
/// hash, but calling an invalid entry point.
#[cfg(any(all(feature = "std", feature = "testing"), test))]
pub fn random_with_missing_entry_point_in_session_contract(rng: &mut TestRng) -> Self {
let timestamp = Timestamp::now();
let ttl = TimeDiff::from_seconds(rng.gen_range(60..3600));
let session = ExecutableDeployItem::StoredContractByHash {
hash: [19; 32].into(),
entry_point: "non-existent-entry-point".to_string(),
args: Default::default(),
};
Self::random_transfer_with_session(rng, session)

let payment_amount = 10_000_000_000u64;
let payment_args = runtime_args! {
"amount" => U512::from(payment_amount)
};
let payment = ExecutableDeployItem::ModuleBytes {
module_bytes: Bytes::new(),
args: payment_args,
};
let gas_price = rng.gen_range(1..4);

let dependencies = vec![];
let chain_name = String::from("casper-example");

let secret_key = SecretKey::random(rng);

Deploy::new_signed(
timestamp,
ttl,
gas_price,
dependencies,
chain_name,
payment,
session,
&secret_key,
None,
)
}

/// Returns a random `Deploy` with custom session specified as a stored versioned contract by
Expand Down Expand Up @@ -905,14 +1000,8 @@ impl Deploy {
module_bytes: Bytes::new(),
args: payment_args,
};
let contract_name = match maybe_contract_name {
None => "Test".to_string(),
Some(contract_name) => contract_name,
};
let entry_point_name = match maybe_entry_point_name {
None => "Test".to_string(),
Some(entry_point_name) => entry_point_name,
};
let contract_name = maybe_contract_name.unwrap_or_else(|| "Test".to_string());
let entry_point_name = maybe_entry_point_name.unwrap_or_else(|| "Test".to_string());
let session = ExecutableDeployItem::StoredVersionedContractByName {
name: contract_name,
version: None,
Expand All @@ -923,10 +1012,7 @@ impl Deploy {
None => SecretKey::random(rng),
Some(secret_key) => secret_key,
};
let timestamp = match maybe_timestamp {
None => Timestamp::now(),
Some(timestamp) => timestamp,
};
let timestamp = maybe_timestamp.unwrap_or_else(Timestamp::now);
let ttl = match maybe_ttl {
None => TimeDiff::from_seconds(rng.gen_range(60..3600)),
Some(ttl) => ttl,
Expand Down Expand Up @@ -1017,7 +1103,34 @@ impl Deploy {
module_bytes: Bytes::new(),
args: Default::default(),
};
Self::random_transfer_with_session(rng, session)
let timestamp = Timestamp::now();
let ttl = TimeDiff::from_seconds(rng.gen_range(60..3600));
let amount = 10_000_000_000u64;
let payment_args = runtime_args! {
"amount" => U512::from(amount)
};
let payment = ExecutableDeployItem::ModuleBytes {
module_bytes: Bytes::new(),
args: payment_args,
};
let gas_price = 1;

let dependencies = vec![];
let chain_name = String::from("casper-example");

let secret_key = SecretKey::random(rng);

Deploy::new_signed(
timestamp,
ttl,
gas_price,
dependencies,
chain_name,
payment,
session,
&secret_key,
None,
)
}

/// Returns a random invalid `Deploy` with an expired TTL.
Expand Down