From d62944567c00066da45db9adb4af6e4cd70057dd Mon Sep 17 00:00:00 2001 From: Xun Li Date: Fri, 7 Jan 2022 23:16:10 -0800 Subject: [PATCH] Add tests for transfer gas logic --- .../src/unit_tests/authority_tests.rs | 63 +++++++++++++++++++ fastx_types/src/gas.rs | 14 ++++- 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/fastpay_core/src/unit_tests/authority_tests.rs b/fastpay_core/src/unit_tests/authority_tests.rs index c8a33e9d4bcf4..f9a06769867ec 100644 --- a/fastpay_core/src/unit_tests/authority_tests.rs +++ b/fastpay_core/src/unit_tests/authority_tests.rs @@ -186,6 +186,31 @@ async fn test_handle_transfer_order_ok() { ); } +#[tokio::test] +async fn test_handle_transfer_zero_balance() { + let (sender, sender_key) = get_key_pair(); + let recipient = Address::FastPay(dbg_addr(2)); + let object_id = ObjectID::random(); + let authority_state = init_state_with_ids(vec![(sender, object_id)]).await; + + // Create a gas object with 0 balance. + let gas_object_id = ObjectID::random(); + let gas_object = Object::with_id_owner_gas_for_testing(gas_object_id, sender, 0); + authority_state + .init_order_lock((gas_object_id, 0.into(), gas_object.digest())) + .await; + authority_state.insert_object(gas_object).await; + + let transfer_order = + init_transfer_order(sender, &sender_key, recipient, object_id, gas_object_id); + + let result = authority_state.handle_order(transfer_order.clone()).await; + assert!(result + .unwrap_err() + .to_string() + .contains("Gas balance is 0, smaller than minimum requirement of 8 for object transfer.")); +} + async fn send_and_confirm_order( authority: &mut AuthorityState, order: Order, @@ -656,6 +681,44 @@ async fn test_handle_confirmation_order_receiver_equal_sender() { .is_some()); } +#[tokio::test] +async fn test_handle_confirmation_order_gas() { + let run_test_with_gas = |gas: u64| async move { + let (sender, sender_key) = get_key_pair(); + let recipient = dbg_addr(2); + let object_id = ObjectID::random(); + let authority_state = init_state_with_ids(vec![(sender, object_id)]).await; + + // Create a gas object with insufficient balance. + let gas_object_id = ObjectID::random(); + let gas_object = Object::with_id_owner_gas_for_testing(gas_object_id, sender, gas); + authority_state + .init_order_lock((gas_object_id, 0.into(), gas_object.digest())) + .await; + authority_state.insert_object(gas_object).await; + + let certified_transfer_order = init_certified_transfer_order( + sender, + &sender_key, + Address::FastPay(recipient), + object_id, + gas_object_id, + &authority_state, + ); + + authority_state + .handle_confirmation_order(ConfirmationOrder::new(certified_transfer_order.clone())) + .await + }; + let result = run_test_with_gas(10).await; + assert!(result + .unwrap_err() + .to_string() + .contains("Gas balance is 10, not enough to pay 12")); + let result = run_test_with_gas(20).await; + assert!(result.is_ok()); +} + #[tokio::test] async fn test_handle_confirmation_order_ok() { let (sender, sender_key) = get_key_pair(); diff --git a/fastx_types/src/gas.rs b/fastx_types/src/gas.rs index fd5ce041d4f16..0ce31c1a3854d 100644 --- a/fastx_types/src/gas.rs +++ b/fastx_types/src/gas.rs @@ -21,12 +21,20 @@ macro_rules! ok_or_gas_error { const MIN_MOVE_CALL_GAS: u64 = 10; const MIN_MOVE_PUBLISH_GAS: u64 = 10; +const MIN_OBJ_TRANSFER_GAS: u64 = 8; pub fn check_gas_requirement(order: &Order, gas_object: &Object) -> FastPayResult { match &order.kind { - OrderKind::Transfer(_) => { - // TODO: Add gas logic for transfer orders. - Ok(()) + OrderKind::Transfer(t) => { + debug_assert_eq!(t.gas_payment.0, gas_object.id()); + let balance = get_gas_balance(gas_object)?; + ok_or_gas_error!( + balance >= MIN_OBJ_TRANSFER_GAS, + format!( + "Gas balance is {}, smaller than minimum requirement of {} for object transfer.", + balance, MIN_OBJ_TRANSFER_GAS + ) + ) } OrderKind::Publish(publish) => { debug_assert_eq!(publish.gas_payment.0, gas_object.id());