Skip to content

Commit 3559896

Browse files
Merge pull request casper-network#5160 from EdHastingsCasperAssociation/native-transfer-deploy-entry-point-name-fix
[BUGFIX] Deploy native transfer entry point name resolution
2 parents 7172e75 + 777e612 commit 3559896

5 files changed

Lines changed: 147 additions & 45 deletions

File tree

node/src/components/contract_runtime/operations.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,11 @@ pub fn execute_finalized_block(
553553
.with_added_consumed(gas_limit)
554554
.with_burn_result(burn_result)
555555
.map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?;
556+
} else {
557+
artifact_builder.with_error_message(format!(
558+
"Attempt to call unsupported native mint entrypoint: {}",
559+
entry_point
560+
));
556561
}
557562
}
558563
lane_id if lane_id == AUCTION_LANE_ID => {

node/src/reactor/main_reactor/tests/transactions.rs

Lines changed: 126 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3825,19 +3825,15 @@ async fn successful_purse_to_account_transfer() {
38253825
);
38263826
}
38273827

3828-
#[tokio::test]
3829-
async fn native_transfer_deploy_with_source_purse_should_succeed() {
3830-
let config = SingleTransactionTestCase::default_test_config()
3831-
.with_pricing_handling(PricingHandling::Fixed)
3832-
.with_refund_handling(RefundHandling::NoRefund)
3833-
.with_fee_handling(FeeHandling::NoFee)
3834-
.with_gas_hold_balance_handling(HoldBalanceHandling::Accrued);
3835-
3828+
async fn bob_transfers_to_charlie_via_native_transfer_deploy(
3829+
configs_override: ConfigsOverride,
3830+
with_source: bool,
3831+
) -> ExecutionResult {
38363832
let mut test = SingleTransactionTestCase::new(
38373833
ALICE_SECRET_KEY.clone(),
38383834
BOB_SECRET_KEY.clone(),
38393835
CHARLIE_SECRET_KEY.clone(),
3840-
Some(config),
3836+
Some(configs_override),
38413837
)
38423838
.await;
38433839

@@ -3852,9 +3848,15 @@ async fn native_transfer_deploy_with_source_purse_should_succeed() {
38523848
BOB_PUBLIC_KEY.to_account_hash(),
38533849
);
38543850

3851+
let source = if with_source {
3852+
Some(entity.main_purse())
3853+
} else {
3854+
None
3855+
};
3856+
38553857
let mut txn: Transaction = Deploy::native_transfer(
38563858
CHAIN_NAME.to_string(),
3857-
Some(entity.main_purse()),
3859+
source,
38583860
BOB_PUBLIC_KEY.clone(),
38593861
CHARLIE_PUBLIC_KEY.clone(),
38603862
None,
@@ -3865,43 +3867,87 @@ async fn native_transfer_deploy_with_source_purse_should_succeed() {
38653867
.into();
38663868
txn.sign(&BOB_SECRET_KEY);
38673869
let (_txn_hash, _block_height, exec_result) = test.send_transaction(txn).await;
3868-
assert!(exec_result_is_success(&exec_result), "{:?}", exec_result);
3870+
exec_result
38693871
}
38703872

38713873
#[tokio::test]
3872-
async fn native_transfer_deploy_without_source_purse_should_succeed() {
3874+
async fn should_transfer_with_source_purse_deploy_fixed_norefund_nofee() {
38733875
let config = SingleTransactionTestCase::default_test_config()
38743876
.with_pricing_handling(PricingHandling::Fixed)
38753877
.with_refund_handling(RefundHandling::NoRefund)
38763878
.with_fee_handling(FeeHandling::NoFee)
38773879
.with_gas_hold_balance_handling(HoldBalanceHandling::Accrued);
3880+
let exec_result = bob_transfers_to_charlie_via_native_transfer_deploy(config, true).await;
38783881

3879-
let mut test = SingleTransactionTestCase::new(
3880-
ALICE_SECRET_KEY.clone(),
3881-
BOB_SECRET_KEY.clone(),
3882-
CHARLIE_SECRET_KEY.clone(),
3883-
Some(config),
3884-
)
3885-
.await;
3882+
assert!(exec_result_is_success(&exec_result), "{:?}", exec_result);
3883+
assert_eq!(
3884+
exec_result.transfers().len(),
3885+
1,
3886+
"native transfer should have exactly 1 transfer"
3887+
);
3888+
}
38863889

3887-
test.fixture
3888-
.run_until_consensus_in_era(ERA_ONE, ONE_MIN)
3889-
.await;
3890+
#[tokio::test]
3891+
async fn should_transfer_with_source_purse_deploy_payment_limited_refund_fee() {
3892+
let config = SingleTransactionTestCase::default_test_config()
3893+
.with_pricing_handling(PricingHandling::PaymentLimited)
3894+
.with_refund_handling(RefundHandling::Refund {
3895+
refund_ratio: Ratio::new(99, 100),
3896+
})
3897+
.with_fee_handling(FeeHandling::PayToProposer)
3898+
.with_gas_hold_balance_handling(HoldBalanceHandling::Accrued);
3899+
let exec_result = bob_transfers_to_charlie_via_native_transfer_deploy(config, true).await;
3900+
assert!(exec_result_is_success(&exec_result), "{:?}", exec_result);
3901+
assert_eq!(
3902+
exec_result.transfers().len(),
3903+
1,
3904+
"native transfer should have exactly 1 transfer"
3905+
);
3906+
assert_eq!(
3907+
exec_result.refund(),
3908+
Some(U512::zero()),
3909+
"cost should equal consumed thus no refund"
3910+
);
3911+
}
3912+
3913+
#[tokio::test]
3914+
async fn should_transfer_with_main_purse_deploy_fixed_norefund_nofee() {
3915+
let config = SingleTransactionTestCase::default_test_config()
3916+
.with_pricing_handling(PricingHandling::Fixed)
3917+
.with_refund_handling(RefundHandling::NoRefund)
3918+
.with_fee_handling(FeeHandling::NoFee)
3919+
.with_gas_hold_balance_handling(HoldBalanceHandling::Accrued);
3920+
let exec_result = bob_transfers_to_charlie_via_native_transfer_deploy(config, false).await;
38903921

3891-
let mut txn: Transaction = Deploy::native_transfer(
3892-
CHAIN_NAME.to_string(),
3893-
None,
3894-
BOB_PUBLIC_KEY.clone(),
3895-
CHARLIE_PUBLIC_KEY.clone(),
3896-
None,
3897-
Timestamp::now(),
3898-
TimeDiff::from_seconds(600),
3899-
10,
3900-
)
3901-
.into();
3902-
txn.sign(&BOB_SECRET_KEY);
3903-
let (_txn_hash, _block_height, exec_result) = test.send_transaction(txn).await;
39043922
assert!(exec_result_is_success(&exec_result), "{:?}", exec_result);
3923+
assert_eq!(
3924+
exec_result.transfers().len(),
3925+
1,
3926+
"native transfer should have exactly 1 transfer"
3927+
);
3928+
}
3929+
3930+
#[tokio::test]
3931+
async fn should_transfer_with_main_purse_deploy_payment_limited_refund_fee() {
3932+
let config = SingleTransactionTestCase::default_test_config()
3933+
.with_pricing_handling(PricingHandling::PaymentLimited)
3934+
.with_refund_handling(RefundHandling::Refund {
3935+
refund_ratio: Ratio::new(99, 100),
3936+
})
3937+
.with_fee_handling(FeeHandling::PayToProposer)
3938+
.with_gas_hold_balance_handling(HoldBalanceHandling::Accrued);
3939+
let exec_result = bob_transfers_to_charlie_via_native_transfer_deploy(config, false).await;
3940+
assert!(exec_result_is_success(&exec_result), "{:?}", exec_result);
3941+
assert_eq!(
3942+
exec_result.transfers().len(),
3943+
1,
3944+
"native transfer should have exactly 1 transfer"
3945+
);
3946+
assert_eq!(
3947+
exec_result.refund(),
3948+
Some(U512::zero()),
3949+
"cost should equal consumed thus no refund"
3950+
);
39053951
}
39063952

39073953
#[tokio::test]
@@ -4510,7 +4556,7 @@ async fn should_allow_native_burn() {
45104556
.with_initiator_addr(PublicKey::from(&**BOB_SECRET_KEY))
45114557
.build()
45124558
.unwrap();
4513-
let price = txn_v1
4559+
let payment = txn_v1
45144560
.payment_amount()
45154561
.expect("must have payment amount as txns are using payment_limited");
45164562
let mut txn = Transaction::from(txn_v1);
@@ -4520,9 +4566,52 @@ async fn should_allow_native_burn() {
45204566
let ExecutionResult::V2(result) = exec_result else {
45214567
panic!("Expected ExecutionResult::V2 but got {:?}", exec_result);
45224568
};
4523-
let expected_cost: U512 = U512::from(price) * MIN_GAS_PRICE;
4569+
let expected_cost: U512 = U512::from(payment) * MIN_GAS_PRICE;
4570+
assert_eq!(result.error_message.as_deref(), None);
4571+
assert_eq!(result.cost, expected_cost);
4572+
}
4573+
4574+
#[tokio::test]
4575+
async fn should_allow_native_transfer_v1() {
4576+
let config = SingleTransactionTestCase::default_test_config()
4577+
.with_pricing_handling(PricingHandling::PaymentLimited)
4578+
.with_refund_handling(RefundHandling::Refund {
4579+
refund_ratio: Ratio::new(99, 100),
4580+
})
4581+
.with_fee_handling(FeeHandling::PayToProposer)
4582+
.with_gas_hold_balance_handling(HoldBalanceHandling::Accrued);
4583+
4584+
let mut test = SingleTransactionTestCase::new(
4585+
ALICE_SECRET_KEY.clone(),
4586+
BOB_SECRET_KEY.clone(),
4587+
CHARLIE_SECRET_KEY.clone(),
4588+
Some(config),
4589+
)
4590+
.await;
4591+
4592+
let transfer_amount = U512::from(100);
4593+
4594+
let txn_v1 =
4595+
TransactionV1Builder::new_transfer(transfer_amount, None, CHARLIE_PUBLIC_KEY.clone(), None)
4596+
.unwrap()
4597+
.with_chain_name(CHAIN_NAME)
4598+
.with_initiator_addr(PublicKey::from(&**BOB_SECRET_KEY))
4599+
.build()
4600+
.unwrap();
4601+
let payment = txn_v1
4602+
.payment_amount()
4603+
.expect("must have payment amount as txns are using payment_limited");
4604+
let mut txn = Transaction::from(txn_v1);
4605+
txn.sign(&BOB_SECRET_KEY);
4606+
4607+
let (_txn_hash, _block_height, exec_result) = test.send_transaction(txn).await;
4608+
let ExecutionResult::V2(result) = exec_result else {
4609+
panic!("Expected ExecutionResult::V2 but got {:?}", exec_result);
4610+
};
4611+
let expected_cost: U512 = U512::from(payment) * MIN_GAS_PRICE;
45244612
assert_eq!(result.error_message.as_deref(), None);
45254613
assert_eq!(result.cost, expected_cost);
4614+
assert_eq!(result.transfers.len(), 1, "should have exactly 1 transfer");
45264615
}
45274616

45284617
#[tokio::test]

types/src/execution/execution_result.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ pub enum ExecutionResult {
3737
}
3838

3939
impl ExecutionResult {
40-
/// Returns refund amount.
41-
pub fn refund(&self) -> Option<U512> {
40+
/// Returns cost.
41+
pub fn cost(&self) -> U512 {
4242
match self {
43-
ExecutionResult::V1(_) => None,
44-
ExecutionResult::V2(result) => Some(result.refund),
43+
ExecutionResult::V1(result) => result.cost(),
44+
ExecutionResult::V2(result) => result.cost,
4545
}
4646
}
4747

@@ -53,6 +53,14 @@ impl ExecutionResult {
5353
}
5454
}
5555

56+
/// Returns refund amount.
57+
pub fn refund(&self) -> Option<U512> {
58+
match self {
59+
ExecutionResult::V1(_) => None,
60+
ExecutionResult::V2(result) => Some(result.refund),
61+
}
62+
}
63+
5664
/// Returns a random ExecutionResult.
5765
#[cfg(any(feature = "testing", test))]
5866
pub fn random(rng: &mut TestRng) -> Self {

types/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ pub use semver::{ParseSemVerError, SemVer, SEM_VER_SERIALIZED_LENGTH};
186186
pub use stored_value::{
187187
GlobalStateIdentifier, StoredValue, StoredValueTag, TypeMismatch as StoredValueTypeMismatch,
188188
};
189+
pub use system::mint::METHOD_TRANSFER;
189190
pub use tagged::Tagged;
190191
#[cfg(any(feature = "std", test))]
191192
pub use timestamp::serde_option_time_diff;

types/src/transaction/deploy/executable_deploy_item.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use crate::{
2424
system::mint::ARG_AMOUNT,
2525
transaction::{RuntimeArgs, TransferTarget},
2626
AddressableEntityHash, AddressableEntityIdentifier, Gas, Motes, PackageIdentifier, Phase, URef,
27-
U512,
27+
METHOD_TRANSFER, U512,
2828
};
2929
#[cfg(any(feature = "testing", test))]
3030
use crate::{testing::TestRng, CLValue};
@@ -255,9 +255,8 @@ impl ExecutableDeployItem {
255255
/// Returns the entry point name.
256256
pub fn entry_point_name(&self) -> &str {
257257
match self {
258-
ExecutableDeployItem::ModuleBytes { .. } | ExecutableDeployItem::Transfer { .. } => {
259-
DEFAULT_ENTRY_POINT_NAME
260-
}
258+
ExecutableDeployItem::ModuleBytes { .. } => DEFAULT_ENTRY_POINT_NAME,
259+
ExecutableDeployItem::Transfer { .. } => METHOD_TRANSFER,
261260
ExecutableDeployItem::StoredVersionedContractByName { entry_point, .. }
262261
| ExecutableDeployItem::StoredVersionedContractByHash { entry_point, .. }
263262
| ExecutableDeployItem::StoredContractByHash { entry_point, .. }

0 commit comments

Comments
 (0)