diff --git a/CHANGES.rst b/CHANGES.rst index 99933b62d49237866443af13f16f1d6142b662fa..49877f3c87a5f84ba27777b255a4b0ed1925a281 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -28,6 +28,9 @@ Node Client ------ +- Simulation returns correct errors on batches of operations where some are + backtracked, failed and/or skipped. + Accuser ------- diff --git a/src/proto_013_PtJakart/lib_client/injection.ml b/src/proto_013_PtJakart/lib_client/injection.ml index a4448cd68f37a7242b75d0854ce7a66ba059204e..9920a9a4ddd094de884817ac31daf01cd2ba3383 100644 --- a/src/proto_013_PtJakart/lib_client/injection.ml +++ b/src/proto_013_PtJakart/lib_client/injection.ml @@ -315,32 +315,32 @@ let estimated_gas_single (type kind) match result with | Applied res | Backtracked (res, _) -> ( match res with - | Transaction_result (Transaction_to_contract_result {consumed_gas; _}) - | Transaction_result (Transaction_to_tx_rollup_result {consumed_gas; _}) - -> - Ok consumed_gas - | Origination_result {consumed_gas; _} -> Ok consumed_gas - | Reveal_result {consumed_gas} -> Ok consumed_gas - | Delegation_result {consumed_gas} -> Ok consumed_gas - | Register_global_constant_result {consumed_gas; _} -> Ok consumed_gas - | Set_deposits_limit_result {consumed_gas} -> Ok consumed_gas - | Tx_rollup_origination_result {consumed_gas; _} -> Ok consumed_gas - | Tx_rollup_submit_batch_result {consumed_gas; _} -> Ok consumed_gas - | Tx_rollup_commit_result {consumed_gas; _} -> Ok consumed_gas - | Tx_rollup_return_bond_result {consumed_gas; _} -> Ok consumed_gas - | Tx_rollup_finalize_commitment_result {consumed_gas; _} -> - Ok consumed_gas - | Tx_rollup_remove_commitment_result {consumed_gas; _} -> - Ok consumed_gas - | Tx_rollup_rejection_result {consumed_gas; _} -> Ok consumed_gas - | Tx_rollup_dispatch_tickets_result {consumed_gas; _} -> Ok consumed_gas - | Transfer_ticket_result {consumed_gas; _} -> Ok consumed_gas - | Sc_rollup_originate_result {consumed_gas; _} -> Ok consumed_gas - | Sc_rollup_add_messages_result {consumed_gas; _} -> Ok consumed_gas - | Sc_rollup_cement_result {consumed_gas; _} -> Ok consumed_gas - | Sc_rollup_publish_result {consumed_gas; _} -> Ok consumed_gas) + | Transaction_result + ( Transaction_to_contract_result {consumed_gas; _} + | Transaction_to_tx_rollup_result {consumed_gas; _} ) + | Origination_result {consumed_gas; _} + | Reveal_result {consumed_gas} + | Delegation_result {consumed_gas} + | Register_global_constant_result {consumed_gas; _} + | Set_deposits_limit_result {consumed_gas} + | Tx_rollup_origination_result {consumed_gas; _} + | Tx_rollup_submit_batch_result {consumed_gas; _} + | Tx_rollup_commit_result {consumed_gas; _} + | Tx_rollup_return_bond_result {consumed_gas; _} + | Tx_rollup_finalize_commitment_result {consumed_gas; _} + | Tx_rollup_remove_commitment_result {consumed_gas; _} + | Tx_rollup_rejection_result {consumed_gas; _} + | Tx_rollup_dispatch_tickets_result {consumed_gas; _} + | Transfer_ticket_result {consumed_gas; _} + | Sc_rollup_originate_result {consumed_gas; _} + | Sc_rollup_add_messages_result {consumed_gas; _} + | Sc_rollup_cement_result {consumed_gas; _} + | Sc_rollup_publish_result {consumed_gas; _} -> + Ok consumed_gas) | Skipped _ -> - Ok Gas.Arith.zero (* there must be another error for this to happen *) + error_with "Cannot estimate gas of skipped operation" + (* There must be another error for this to happen, and it should not + surface (the force mode catches it). *) | Failed (_, errs) -> Error (Environment.wrap_tztrace errs) in consumed_gas operation_result >>? fun gas -> @@ -364,43 +364,39 @@ let estimated_storage_single (type kind) ~tx_rollup_origination_size if allocated_destination_contract then Ok (Z.add paid_storage_size_diff origination_size) else Ok paid_storage_size_diff - | Transaction_result (Transaction_to_tx_rollup_result _) -> - (* TODO: https://gitlab.com/tezos/tezos/-/issues/2339 - Storage fees for transaction rollup. - We need to charge for newly allocated storage (as we do for - Michelson’s big map). *) - Ok Z.zero | Origination_result {paid_storage_size_diff; _} -> Ok (Z.add paid_storage_size_diff origination_size) - | Reveal_result _ -> Ok Z.zero - | Delegation_result _ -> Ok Z.zero | Register_global_constant_result {size_of_constant; _} -> Ok size_of_constant - | Set_deposits_limit_result _ -> Ok Z.zero | Tx_rollup_origination_result _ -> Ok tx_rollup_origination_size - | Tx_rollup_submit_batch_result {paid_storage_size_diff; _} -> - Ok paid_storage_size_diff - | Tx_rollup_commit_result _ -> Ok Z.zero - | Tx_rollup_return_bond_result _ -> Ok Z.zero - | Tx_rollup_finalize_commitment_result _ -> Ok Z.zero - | Tx_rollup_remove_commitment_result _ -> Ok Z.zero - | Tx_rollup_rejection_result _ -> Ok Z.zero - | Tx_rollup_dispatch_tickets_result {paid_storage_size_diff; _} -> - Ok paid_storage_size_diff + | Tx_rollup_submit_batch_result {paid_storage_size_diff; _} + | Tx_rollup_dispatch_tickets_result {paid_storage_size_diff; _} | Transfer_ticket_result {paid_storage_size_diff; _} -> Ok paid_storage_size_diff | Sc_rollup_originate_result {size; _} -> Ok size - | Sc_rollup_add_messages_result _ -> Ok Z.zero + | Transaction_result (Transaction_to_tx_rollup_result _) -> + (* TODO: https://gitlab.com/tezos/tezos/-/issues/2339 + Storage fees for transaction rollup. + We need to charge for newly allocated storage (as we do for + Michelson’s big map). *) + Ok Z.zero + | Reveal_result _ | Delegation_result _ | Set_deposits_limit_result _ + | Tx_rollup_commit_result _ | Tx_rollup_return_bond_result _ + | Tx_rollup_finalize_commitment_result _ + | Tx_rollup_remove_commitment_result _ | Tx_rollup_rejection_result _ + | Sc_rollup_add_messages_result _ (* The following Sc_rollup operations have zero storage cost because we consider them to be paid in the stake deposit. TODO: https://gitlab.com/tezos/tezos/-/issues/2686 Document why this is safe. *) - | Sc_rollup_cement_result _ -> Ok Z.zero - | Sc_rollup_publish_result _ -> Ok Z.zero) + | Sc_rollup_cement_result _ | Sc_rollup_publish_result _ -> + Ok Z.zero) | Skipped _ -> - Ok Z.zero (* there must be another error for this to happen *) + error_with "Cannot estimate storage of skipped operation" + (* There must be another error for this to happen, and it should not + surface (the force mode catches it). *) | Failed (_, errs) -> Error (Environment.wrap_tztrace errs) in storage_size_diff operation_result >>? fun storage -> @@ -438,29 +434,24 @@ let originated_contracts_single (type kind) | Applied res | Backtracked (res, _) -> ( match res with | Transaction_result - (Transaction_to_contract_result {originated_contracts; _}) -> - Ok originated_contracts - | Transaction_result (Transaction_to_tx_rollup_result _) -> Ok [] + (Transaction_to_contract_result {originated_contracts; _}) | Origination_result {originated_contracts; _} -> Ok originated_contracts - | Register_global_constant_result _ -> Ok [] - | Reveal_result _ -> Ok [] - | Delegation_result _ -> Ok [] - | Set_deposits_limit_result _ -> Ok [] - | Tx_rollup_origination_result _ -> Ok [] - | Tx_rollup_submit_batch_result _ -> Ok [] - | Tx_rollup_commit_result _ -> Ok [] - | Tx_rollup_return_bond_result _ -> Ok [] - | Tx_rollup_finalize_commitment_result _ -> Ok [] - | Tx_rollup_remove_commitment_result _ -> Ok [] - | Tx_rollup_rejection_result _ -> Ok [] - | Tx_rollup_dispatch_tickets_result _ -> Ok [] - | Transfer_ticket_result _ -> Ok [] - | Sc_rollup_originate_result _ -> Ok [] - | Sc_rollup_add_messages_result _ -> Ok [] - | Sc_rollup_cement_result _ -> Ok [] - | Sc_rollup_publish_result _ -> Ok []) - | Skipped _ -> Ok [] (* there must be another error for this to happen *) + | Transaction_result (Transaction_to_tx_rollup_result _) + | Register_global_constant_result _ | Reveal_result _ + | Delegation_result _ | Set_deposits_limit_result _ + | Tx_rollup_origination_result _ | Tx_rollup_submit_batch_result _ + | Tx_rollup_commit_result _ | Tx_rollup_return_bond_result _ + | Tx_rollup_finalize_commitment_result _ + | Tx_rollup_remove_commitment_result _ | Tx_rollup_rejection_result _ + | Tx_rollup_dispatch_tickets_result _ | Transfer_ticket_result _ + | Sc_rollup_originate_result _ | Sc_rollup_add_messages_result _ + | Sc_rollup_cement_result _ | Sc_rollup_publish_result _ -> + Ok []) + | Skipped _ -> + error_with "Cannot know originated contracts of skipped operation" + (* There must be another error for this to happen, and it should not + surface (the force mode catches it). *) | Failed (_, errs) -> Error (Environment.wrap_tztrace errs) in originated_contracts operation_result >>? fun contracts -> diff --git a/src/proto_013_PtJakart/lib_client_commands/client_proto_context_commands.ml b/src/proto_013_PtJakart/lib_client_commands/client_proto_context_commands.ml index d7859b232f76890b3527f3e387141600110c7f87..0bd5a3b9e0ea4048e01ebf8bc26d7475bf3ff65e 100644 --- a/src/proto_013_PtJakart/lib_client_commands/client_proto_context_commands.ml +++ b/src/proto_013_PtJakart/lib_client_commands/client_proto_context_commands.ml @@ -1200,11 +1200,12 @@ let commands_rw () = ~desc: "Execute multiple transfers from a single source account.\n\ If one of the transfers fails, none of them get executed." - (args17 + (args18 default_fee_arg dry_run_switch verbose_signing_switch simulate_switch + force_switch default_gas_limit_arg default_storage_limit_arg counter_arg @@ -1238,6 +1239,7 @@ let commands_rw () = dry_run, verbose_signing, simulation, + force, gas_limit, storage_limit, counter, @@ -1254,6 +1256,22 @@ let commands_rw () = (_, source) operations_json cctxt -> + (* When --force is used we want to inject the transfer even if it fails. + In that case we cannot rely on simulation to compute limits and fees + so we require the corresponding options to be set. *) + let check_force_dependency name = function + | None -> + cctxt#error + "When the --force switch is used, the %s option is required." + name + | _ -> Lwt.return_unit + in + (if force && not simulation then + check_force_dependency "--gas-limit" gas_limit >>= fun () -> + check_force_dependency "--storage-limit" storage_limit >>= fun () -> + check_force_dependency "--fee" fee + else Lwt.return_unit) + >>= fun () -> let fee_parameter = { Injection.minimal_fees; @@ -1305,6 +1323,7 @@ let commands_rw () = ~dry_run ~verbose_signing ~simulation + ~force ~source ~fee:(Limit.of_option fee) ~gas_limit:(Limit.of_option gas_limit) diff --git a/src/proto_014_PtKathma/lib_client/injection.ml b/src/proto_014_PtKathma/lib_client/injection.ml index 3aeb28e294b1eb07dc793f661f9fbddf4d637907..99b610f2faee9e2d4886aa5d2b3d31beeb2a095b 100644 --- a/src/proto_014_PtKathma/lib_client/injection.ml +++ b/src/proto_014_PtKathma/lib_client/injection.ml @@ -310,39 +310,37 @@ let estimated_gas_single (type kind) | Transaction_result ( Transaction_to_contract_result {consumed_gas; _} | Transaction_to_tx_rollup_result {consumed_gas; _} - | Transaction_to_sc_rollup_result {consumed_gas; _} ) -> - Ok consumed_gas - | Origination_result {consumed_gas; _} -> Ok consumed_gas - | Reveal_result {consumed_gas} -> Ok consumed_gas - | Delegation_result {consumed_gas} -> Ok consumed_gas - | Register_global_constant_result {consumed_gas; _} -> Ok consumed_gas - | Set_deposits_limit_result {consumed_gas} -> Ok consumed_gas - | Increase_paid_storage_result {consumed_gas; _} -> Ok consumed_gas - | Tx_rollup_origination_result {consumed_gas; _} -> Ok consumed_gas - | Tx_rollup_submit_batch_result {consumed_gas; _} -> Ok consumed_gas - | Tx_rollup_commit_result {consumed_gas; _} -> Ok consumed_gas - | Tx_rollup_return_bond_result {consumed_gas; _} -> Ok consumed_gas - | Tx_rollup_finalize_commitment_result {consumed_gas; _} -> - Ok consumed_gas - | Tx_rollup_remove_commitment_result {consumed_gas; _} -> - Ok consumed_gas - | Tx_rollup_rejection_result {consumed_gas; _} -> Ok consumed_gas - | Tx_rollup_dispatch_tickets_result {consumed_gas; _} -> Ok consumed_gas - | Transfer_ticket_result {consumed_gas; _} -> Ok consumed_gas - | Dal_publish_slot_header_result {consumed_gas; _} -> Ok consumed_gas - | Sc_rollup_originate_result {consumed_gas; _} -> Ok consumed_gas - | Sc_rollup_add_messages_result {consumed_gas; _} -> Ok consumed_gas - | Sc_rollup_cement_result {consumed_gas; _} -> Ok consumed_gas - | Sc_rollup_publish_result {consumed_gas; _} -> Ok consumed_gas - | Sc_rollup_refute_result {consumed_gas; _} -> Ok consumed_gas - | Sc_rollup_timeout_result {consumed_gas; _} -> Ok consumed_gas - | Sc_rollup_execute_outbox_message_result {consumed_gas; _} -> - Ok consumed_gas - | Sc_rollup_recover_bond_result {consumed_gas; _} -> Ok consumed_gas + | Transaction_to_sc_rollup_result {consumed_gas; _} ) + | Origination_result {consumed_gas; _} + | Reveal_result {consumed_gas} + | Delegation_result {consumed_gas} + | Register_global_constant_result {consumed_gas; _} + | Set_deposits_limit_result {consumed_gas} + | Increase_paid_storage_result {consumed_gas; _} + | Tx_rollup_origination_result {consumed_gas; _} + | Tx_rollup_submit_batch_result {consumed_gas; _} + | Tx_rollup_commit_result {consumed_gas; _} + | Tx_rollup_return_bond_result {consumed_gas; _} + | Tx_rollup_finalize_commitment_result {consumed_gas; _} + | Tx_rollup_remove_commitment_result {consumed_gas; _} + | Tx_rollup_rejection_result {consumed_gas; _} + | Tx_rollup_dispatch_tickets_result {consumed_gas; _} + | Transfer_ticket_result {consumed_gas; _} + | Dal_publish_slot_header_result {consumed_gas; _} + | Sc_rollup_originate_result {consumed_gas; _} + | Sc_rollup_add_messages_result {consumed_gas; _} + | Sc_rollup_cement_result {consumed_gas; _} + | Sc_rollup_publish_result {consumed_gas; _} + | Sc_rollup_refute_result {consumed_gas; _} + | Sc_rollup_timeout_result {consumed_gas; _} + | Sc_rollup_execute_outbox_message_result {consumed_gas; _} + | Sc_rollup_recover_bond_result {consumed_gas; _} | Sc_rollup_dal_slot_subscribe_result {consumed_gas; _} -> Ok consumed_gas) | Skipped _ -> - Ok Gas.Arith.zero (* there must be another error for this to happen *) + error_with "Cannot estimate gas of skipped operation" + (* There must be another error for this to happen, and it should not + surface (the force mode catches it). *) | Failed (_, errs) -> Error (Environment.wrap_tztrace errs) in let internal_consumed_gas (type kind) @@ -383,51 +381,45 @@ let estimated_storage_single (type kind) ~tx_rollup_origination_size if allocated_destination_contract then Ok (Z.add paid_storage_size_diff origination_size) else Ok paid_storage_size_diff - | Transaction_result (Transaction_to_tx_rollup_result _) -> - (* TODO: https://gitlab.com/tezos/tezos/-/issues/2339 - Storage fees for transaction rollup. - We need to charge for newly allocated storage (as we do for - Michelson’s big map). *) - Ok Z.zero - | Transaction_result (Transaction_to_sc_rollup_result _) -> Ok Z.zero | Origination_result {paid_storage_size_diff; _} -> Ok (Z.add paid_storage_size_diff origination_size) - | Reveal_result _ -> Ok Z.zero - | Delegation_result _ -> Ok Z.zero | Register_global_constant_result {size_of_constant; _} -> Ok size_of_constant - | Set_deposits_limit_result _ -> Ok Z.zero - | Increase_paid_storage_result _ -> Ok Z.zero | Tx_rollup_origination_result _ -> Ok tx_rollup_origination_size | Tx_rollup_submit_batch_result {paid_storage_size_diff; _} - | Sc_rollup_execute_outbox_message_result {paid_storage_size_diff; _} -> - Ok paid_storage_size_diff - | Tx_rollup_commit_result _ -> Ok Z.zero - | Tx_rollup_return_bond_result _ -> Ok Z.zero - | Tx_rollup_finalize_commitment_result _ -> Ok Z.zero - | Tx_rollup_remove_commitment_result _ -> Ok Z.zero - | Tx_rollup_rejection_result _ -> Ok Z.zero - | Tx_rollup_dispatch_tickets_result {paid_storage_size_diff; _} -> - Ok paid_storage_size_diff + | Sc_rollup_execute_outbox_message_result {paid_storage_size_diff; _} + | Tx_rollup_dispatch_tickets_result {paid_storage_size_diff; _} | Transfer_ticket_result {paid_storage_size_diff; _} -> Ok paid_storage_size_diff - | Dal_publish_slot_header_result _ -> Ok Z.zero | Sc_rollup_originate_result {size; _} -> Ok size - | Sc_rollup_add_messages_result _ -> Ok Z.zero + | Transaction_result (Transaction_to_tx_rollup_result _) -> + (* TODO: https://gitlab.com/tezos/tezos/-/issues/2339 + Storage fees for transaction rollup. + We need to charge for newly allocated storage (as we do for + Michelson’s big map). *) + Ok Z.zero + | Transaction_result (Transaction_to_sc_rollup_result _) + | Reveal_result _ | Delegation_result _ | Set_deposits_limit_result _ + | Increase_paid_storage_result _ | Tx_rollup_commit_result _ + | Tx_rollup_return_bond_result _ + | Tx_rollup_finalize_commitment_result _ + | Tx_rollup_remove_commitment_result _ | Tx_rollup_rejection_result _ + | Dal_publish_slot_header_result _ | Sc_rollup_add_messages_result _ (* The following Sc_rollup operations have zero storage cost because we consider them to be paid in the stake deposit. TODO: https://gitlab.com/tezos/tezos/-/issues/2686 Document why this is safe. *) - | Sc_rollup_cement_result _ -> Ok Z.zero - | Sc_rollup_publish_result _ -> Ok Z.zero - | Sc_rollup_refute_result _ -> Ok Z.zero - | Sc_rollup_timeout_result _ -> Ok Z.zero - | Sc_rollup_recover_bond_result _ -> Ok Z.zero - | Sc_rollup_dal_slot_subscribe_result _ -> Ok Z.zero) + | Sc_rollup_cement_result _ | Sc_rollup_publish_result _ + | Sc_rollup_refute_result _ | Sc_rollup_timeout_result _ + | Sc_rollup_recover_bond_result _ + | Sc_rollup_dal_slot_subscribe_result _ -> + Ok Z.zero) | Skipped _ -> - Ok Z.zero (* there must be another error for this to happen *) + error_with "Cannot estimate storage of skipped operation" + (* There must be another error for this to happen, and it should not + surface (the force mode catches it). *) | Failed (_, errs) -> Error (Environment.wrap_tztrace errs) in let internal_storage_size_diff (type kind) @@ -441,16 +433,17 @@ let estimated_storage_single (type kind) ~tx_rollup_origination_size if allocated_destination_contract then Ok (Z.add paid_storage_size_diff origination_size) else Ok paid_storage_size_diff + | IOrigination_result {paid_storage_size_diff; _} -> + Ok (Z.add paid_storage_size_diff origination_size) | ITransaction_result (Transaction_to_tx_rollup_result _) -> (* TODO: https://gitlab.com/tezos/tezos/-/issues/2339 Storage fees for transaction rollup. We need to charge for newly allocated storage (as we do for Michelson’s big map). *) Ok Z.zero - | ITransaction_result (Transaction_to_sc_rollup_result _) -> Ok Z.zero - | IOrigination_result {paid_storage_size_diff; _} -> - Ok (Z.add paid_storage_size_diff origination_size) - | IDelegation_result _ | IEvent_result _ -> Ok Z.zero) + | ITransaction_result (Transaction_to_sc_rollup_result _) + | IDelegation_result _ | IEvent_result _ -> + Ok Z.zero) | Skipped _ -> Ok Z.zero (* there must be another error for this to happen *) | Failed (_, errs) -> Error (Environment.wrap_tztrace errs) @@ -490,39 +483,31 @@ let originated_contracts_single (type kind) | Applied res | Backtracked (res, _) -> ( match res with | Transaction_result - (Transaction_to_contract_result {originated_contracts; _}) -> + (Transaction_to_contract_result {originated_contracts; _}) + | Origination_result {originated_contracts; _} -> Ok originated_contracts | Transaction_result ( Transaction_to_tx_rollup_result _ - | Transaction_to_sc_rollup_result _ ) -> - Ok [] - | Origination_result {originated_contracts; _} -> - Ok originated_contracts - | Register_global_constant_result _ -> Ok [] - | Reveal_result _ -> Ok [] - | Delegation_result _ -> Ok [] - | Set_deposits_limit_result _ -> Ok [] - | Increase_paid_storage_result _ -> Ok [] - | Tx_rollup_origination_result _ -> Ok [] - | Tx_rollup_submit_batch_result _ -> Ok [] - | Tx_rollup_commit_result _ -> Ok [] - | Tx_rollup_return_bond_result _ -> Ok [] - | Tx_rollup_finalize_commitment_result _ -> Ok [] - | Tx_rollup_remove_commitment_result _ -> Ok [] - | Tx_rollup_rejection_result _ -> Ok [] - | Tx_rollup_dispatch_tickets_result _ -> Ok [] - | Transfer_ticket_result _ -> Ok [] - | Dal_publish_slot_header_result _ -> Ok [] - | Sc_rollup_originate_result _ -> Ok [] - | Sc_rollup_add_messages_result _ -> Ok [] - | Sc_rollup_cement_result _ -> Ok [] - | Sc_rollup_publish_result _ -> Ok [] - | Sc_rollup_refute_result _ -> Ok [] - | Sc_rollup_timeout_result _ -> Ok [] - | Sc_rollup_execute_outbox_message_result _ -> Ok [] - | Sc_rollup_recover_bond_result _ -> Ok [] - | Sc_rollup_dal_slot_subscribe_result _ -> Ok []) - | Skipped _ -> Ok [] (* there must be another error for this to happen *) + | Transaction_to_sc_rollup_result _ ) + | Register_global_constant_result _ | Reveal_result _ + | Delegation_result _ | Set_deposits_limit_result _ + | Increase_paid_storage_result _ | Tx_rollup_origination_result _ + | Tx_rollup_submit_batch_result _ | Tx_rollup_commit_result _ + | Tx_rollup_return_bond_result _ + | Tx_rollup_finalize_commitment_result _ + | Tx_rollup_remove_commitment_result _ | Tx_rollup_rejection_result _ + | Tx_rollup_dispatch_tickets_result _ | Transfer_ticket_result _ + | Dal_publish_slot_header_result _ | Sc_rollup_originate_result _ + | Sc_rollup_add_messages_result _ | Sc_rollup_cement_result _ + | Sc_rollup_publish_result _ | Sc_rollup_refute_result _ + | Sc_rollup_timeout_result _ | Sc_rollup_execute_outbox_message_result _ + | Sc_rollup_recover_bond_result _ + | Sc_rollup_dal_slot_subscribe_result _ -> + Ok []) + | Skipped _ -> + error_with "Cannot know originated contracts of skipped operation" + (* There must be another error for this to happen, and it should not + surface (the force mode catches it). *) | Failed (_, errs) -> Error (Environment.wrap_tztrace errs) in let internal_originated_contracts (type kind) @@ -531,15 +516,14 @@ let originated_contracts_single (type kind) | Applied res | Backtracked (res, _) -> ( match res with | ITransaction_result - (Transaction_to_contract_result {originated_contracts; _}) -> + (Transaction_to_contract_result {originated_contracts; _}) + | IOrigination_result {originated_contracts; _} -> Ok originated_contracts | ITransaction_result ( Transaction_to_tx_rollup_result _ - | Transaction_to_sc_rollup_result _ ) -> - Ok [] - | IOrigination_result {originated_contracts; _} -> - Ok originated_contracts - | IDelegation_result _ | IEvent_result _ -> Ok []) + | Transaction_to_sc_rollup_result _ ) + | IDelegation_result _ | IEvent_result _ -> + Ok []) | Skipped _ -> Ok [] (* there must be another error for this to happen *) | Failed (_, errs) -> Error (Environment.wrap_tztrace errs) in diff --git a/src/proto_014_PtKathma/lib_client_commands/client_proto_context_commands.ml b/src/proto_014_PtKathma/lib_client_commands/client_proto_context_commands.ml index e0859c683207a28b56595c57d226ba7a8823fed9..a0c2173c1aa90f87bfa774ebf13ba8b7b8fd68be 100644 --- a/src/proto_014_PtKathma/lib_client_commands/client_proto_context_commands.ml +++ b/src/proto_014_PtKathma/lib_client_commands/client_proto_context_commands.ml @@ -1054,11 +1054,12 @@ let commands_rw () = ~desc: "Execute multiple transfers from a single source account.\n\ If one of the transfers fails, none of them get executed." - (args12 + (args13 default_fee_arg dry_run_switch verbose_signing_switch simulate_switch + force_switch default_gas_limit_arg default_storage_limit_arg counter_arg @@ -1087,6 +1088,7 @@ let commands_rw () = dry_run, verbose_signing, simulation, + force, gas_limit, storage_limit, counter, @@ -1098,6 +1100,22 @@ let commands_rw () = source operations_json cctxt -> + (* When --force is used we want to inject the transfer even if it fails. + In that case we cannot rely on simulation to compute limits and fees + so we require the corresponding options to be set. *) + let check_force_dependency name = function + | None -> + cctxt#error + "When the --force switch is used, the %s option is required." + name + | _ -> Lwt.return_unit + in + (if force && not simulation then + check_force_dependency "--gas-limit" gas_limit >>= fun () -> + check_force_dependency "--storage-limit" storage_limit >>= fun () -> + check_force_dependency "--fee" fee + else Lwt.return_unit) + >>= fun () -> let prepare i = prepare_batch_operation cctxt @@ -1139,6 +1157,7 @@ let commands_rw () = ~dry_run ~verbose_signing ~simulation + ~force ~source ~fee:(Limit.of_option fee) ~gas_limit:(Limit.of_option gas_limit) diff --git a/src/proto_alpha/lib_client/injection.ml b/src/proto_alpha/lib_client/injection.ml index 7b7f475945487fdbbc065d0f4fa87bfbd1fd7335..d336b485d1b06585eddbb1b7fc3aadda4ee4e797 100644 --- a/src/proto_alpha/lib_client/injection.ml +++ b/src/proto_alpha/lib_client/injection.ml @@ -310,39 +310,37 @@ let estimated_gas_single (type kind) | Transaction_result ( Transaction_to_contract_result {consumed_gas; _} | Transaction_to_tx_rollup_result {consumed_gas; _} - | Transaction_to_sc_rollup_result {consumed_gas; _} ) -> - Ok consumed_gas - | Origination_result {consumed_gas; _} -> Ok consumed_gas - | Reveal_result {consumed_gas} -> Ok consumed_gas - | Delegation_result {consumed_gas} -> Ok consumed_gas - | Register_global_constant_result {consumed_gas; _} -> Ok consumed_gas - | Set_deposits_limit_result {consumed_gas} -> Ok consumed_gas - | Increase_paid_storage_result {consumed_gas; _} -> Ok consumed_gas - | Tx_rollup_origination_result {consumed_gas; _} -> Ok consumed_gas - | Tx_rollup_submit_batch_result {consumed_gas; _} -> Ok consumed_gas - | Tx_rollup_commit_result {consumed_gas; _} -> Ok consumed_gas - | Tx_rollup_return_bond_result {consumed_gas; _} -> Ok consumed_gas - | Tx_rollup_finalize_commitment_result {consumed_gas; _} -> - Ok consumed_gas - | Tx_rollup_remove_commitment_result {consumed_gas; _} -> - Ok consumed_gas - | Tx_rollup_rejection_result {consumed_gas; _} -> Ok consumed_gas - | Tx_rollup_dispatch_tickets_result {consumed_gas; _} -> Ok consumed_gas - | Transfer_ticket_result {consumed_gas; _} -> Ok consumed_gas - | Dal_publish_slot_header_result {consumed_gas; _} -> Ok consumed_gas - | Sc_rollup_originate_result {consumed_gas; _} -> Ok consumed_gas - | Sc_rollup_add_messages_result {consumed_gas; _} -> Ok consumed_gas - | Sc_rollup_cement_result {consumed_gas; _} -> Ok consumed_gas - | Sc_rollup_publish_result {consumed_gas; _} -> Ok consumed_gas - | Sc_rollup_refute_result {consumed_gas; _} -> Ok consumed_gas - | Sc_rollup_timeout_result {consumed_gas; _} -> Ok consumed_gas - | Sc_rollup_execute_outbox_message_result {consumed_gas; _} -> - Ok consumed_gas - | Sc_rollup_recover_bond_result {consumed_gas; _} -> Ok consumed_gas + | Transaction_to_sc_rollup_result {consumed_gas; _} ) + | Origination_result {consumed_gas; _} + | Reveal_result {consumed_gas} + | Delegation_result {consumed_gas} + | Register_global_constant_result {consumed_gas; _} + | Set_deposits_limit_result {consumed_gas} + | Increase_paid_storage_result {consumed_gas; _} + | Tx_rollup_origination_result {consumed_gas; _} + | Tx_rollup_submit_batch_result {consumed_gas; _} + | Tx_rollup_commit_result {consumed_gas; _} + | Tx_rollup_return_bond_result {consumed_gas; _} + | Tx_rollup_finalize_commitment_result {consumed_gas; _} + | Tx_rollup_remove_commitment_result {consumed_gas; _} + | Tx_rollup_rejection_result {consumed_gas; _} + | Tx_rollup_dispatch_tickets_result {consumed_gas; _} + | Transfer_ticket_result {consumed_gas; _} + | Dal_publish_slot_header_result {consumed_gas; _} + | Sc_rollup_originate_result {consumed_gas; _} + | Sc_rollup_add_messages_result {consumed_gas; _} + | Sc_rollup_cement_result {consumed_gas; _} + | Sc_rollup_publish_result {consumed_gas; _} + | Sc_rollup_refute_result {consumed_gas; _} + | Sc_rollup_timeout_result {consumed_gas; _} + | Sc_rollup_execute_outbox_message_result {consumed_gas; _} + | Sc_rollup_recover_bond_result {consumed_gas; _} | Sc_rollup_dal_slot_subscribe_result {consumed_gas; _} -> Ok consumed_gas) | Skipped _ -> - Ok Gas.Arith.zero (* there must be another error for this to happen *) + error_with "Cannot estimate gas of skipped operation" + (* There must be another error for this to happen, and it should not + surface (the force mode catches it). *) | Failed (_, errs) -> Error (Environment.wrap_tztrace errs) in let internal_consumed_gas (type kind) @@ -383,51 +381,45 @@ let estimated_storage_single (type kind) ~tx_rollup_origination_size if allocated_destination_contract then Ok (Z.add paid_storage_size_diff origination_size) else Ok paid_storage_size_diff - | Transaction_result (Transaction_to_tx_rollup_result _) -> - (* TODO: https://gitlab.com/tezos/tezos/-/issues/2339 - Storage fees for transaction rollup. - We need to charge for newly allocated storage (as we do for - Michelson’s big map). *) - Ok Z.zero - | Transaction_result (Transaction_to_sc_rollup_result _) -> Ok Z.zero | Origination_result {paid_storage_size_diff; _} -> Ok (Z.add paid_storage_size_diff origination_size) - | Reveal_result _ -> Ok Z.zero - | Delegation_result _ -> Ok Z.zero | Register_global_constant_result {size_of_constant; _} -> Ok size_of_constant - | Set_deposits_limit_result _ -> Ok Z.zero - | Increase_paid_storage_result _ -> Ok Z.zero | Tx_rollup_origination_result _ -> Ok tx_rollup_origination_size | Tx_rollup_submit_batch_result {paid_storage_size_diff; _} - | Sc_rollup_execute_outbox_message_result {paid_storage_size_diff; _} -> - Ok paid_storage_size_diff - | Tx_rollup_commit_result _ -> Ok Z.zero - | Tx_rollup_return_bond_result _ -> Ok Z.zero - | Tx_rollup_finalize_commitment_result _ -> Ok Z.zero - | Tx_rollup_remove_commitment_result _ -> Ok Z.zero - | Tx_rollup_rejection_result _ -> Ok Z.zero - | Tx_rollup_dispatch_tickets_result {paid_storage_size_diff; _} -> - Ok paid_storage_size_diff + | Sc_rollup_execute_outbox_message_result {paid_storage_size_diff; _} + | Tx_rollup_dispatch_tickets_result {paid_storage_size_diff; _} | Transfer_ticket_result {paid_storage_size_diff; _} -> Ok paid_storage_size_diff - | Dal_publish_slot_header_result _ -> Ok Z.zero | Sc_rollup_originate_result {size; _} -> Ok size - | Sc_rollup_add_messages_result _ -> Ok Z.zero + | Transaction_result (Transaction_to_tx_rollup_result _) -> + (* TODO: https://gitlab.com/tezos/tezos/-/issues/2339 + Storage fees for transaction rollup. + We need to charge for newly allocated storage (as we do for + Michelson’s big map). *) + Ok Z.zero + | Transaction_result (Transaction_to_sc_rollup_result _) + | Reveal_result _ | Delegation_result _ | Set_deposits_limit_result _ + | Increase_paid_storage_result _ | Tx_rollup_commit_result _ + | Tx_rollup_return_bond_result _ + | Tx_rollup_finalize_commitment_result _ + | Tx_rollup_remove_commitment_result _ | Tx_rollup_rejection_result _ + | Dal_publish_slot_header_result _ | Sc_rollup_add_messages_result _ (* The following Sc_rollup operations have zero storage cost because we consider them to be paid in the stake deposit. TODO: https://gitlab.com/tezos/tezos/-/issues/2686 Document why this is safe. *) - | Sc_rollup_cement_result _ -> Ok Z.zero - | Sc_rollup_publish_result _ -> Ok Z.zero - | Sc_rollup_refute_result _ -> Ok Z.zero - | Sc_rollup_timeout_result _ -> Ok Z.zero - | Sc_rollup_recover_bond_result _ -> Ok Z.zero - | Sc_rollup_dal_slot_subscribe_result _ -> Ok Z.zero) + | Sc_rollup_cement_result _ | Sc_rollup_publish_result _ + | Sc_rollup_refute_result _ | Sc_rollup_timeout_result _ + | Sc_rollup_recover_bond_result _ + | Sc_rollup_dal_slot_subscribe_result _ -> + Ok Z.zero) | Skipped _ -> - Ok Z.zero (* there must be another error for this to happen *) + error_with "Cannot estimate storage of skipped operation" + (* There must be another error for this to happen, and it should not + surface (the force mode catches it). *) | Failed (_, errs) -> Error (Environment.wrap_tztrace errs) in let internal_storage_size_diff (type kind) @@ -441,16 +433,17 @@ let estimated_storage_single (type kind) ~tx_rollup_origination_size if allocated_destination_contract then Ok (Z.add paid_storage_size_diff origination_size) else Ok paid_storage_size_diff + | IOrigination_result {paid_storage_size_diff; _} -> + Ok (Z.add paid_storage_size_diff origination_size) | ITransaction_result (Transaction_to_tx_rollup_result _) -> (* TODO: https://gitlab.com/tezos/tezos/-/issues/2339 Storage fees for transaction rollup. We need to charge for newly allocated storage (as we do for Michelson’s big map). *) Ok Z.zero - | ITransaction_result (Transaction_to_sc_rollup_result _) -> Ok Z.zero - | IOrigination_result {paid_storage_size_diff; _} -> - Ok (Z.add paid_storage_size_diff origination_size) - | IDelegation_result _ | IEvent_result _ -> Ok Z.zero) + | ITransaction_result (Transaction_to_sc_rollup_result _) + | IDelegation_result _ | IEvent_result _ -> + Ok Z.zero) | Skipped _ -> Ok Z.zero (* there must be another error for this to happen *) | Failed (_, errs) -> Error (Environment.wrap_tztrace errs) @@ -490,39 +483,31 @@ let originated_contracts_single (type kind) | Applied res | Backtracked (res, _) -> ( match res with | Transaction_result - (Transaction_to_contract_result {originated_contracts; _}) -> + (Transaction_to_contract_result {originated_contracts; _}) + | Origination_result {originated_contracts; _} -> Ok originated_contracts | Transaction_result ( Transaction_to_tx_rollup_result _ - | Transaction_to_sc_rollup_result _ ) -> - Ok [] - | Origination_result {originated_contracts; _} -> - Ok originated_contracts - | Register_global_constant_result _ -> Ok [] - | Reveal_result _ -> Ok [] - | Delegation_result _ -> Ok [] - | Set_deposits_limit_result _ -> Ok [] - | Increase_paid_storage_result _ -> Ok [] - | Tx_rollup_origination_result _ -> Ok [] - | Tx_rollup_submit_batch_result _ -> Ok [] - | Tx_rollup_commit_result _ -> Ok [] - | Tx_rollup_return_bond_result _ -> Ok [] - | Tx_rollup_finalize_commitment_result _ -> Ok [] - | Tx_rollup_remove_commitment_result _ -> Ok [] - | Tx_rollup_rejection_result _ -> Ok [] - | Tx_rollup_dispatch_tickets_result _ -> Ok [] - | Transfer_ticket_result _ -> Ok [] - | Dal_publish_slot_header_result _ -> Ok [] - | Sc_rollup_originate_result _ -> Ok [] - | Sc_rollup_add_messages_result _ -> Ok [] - | Sc_rollup_cement_result _ -> Ok [] - | Sc_rollup_publish_result _ -> Ok [] - | Sc_rollup_refute_result _ -> Ok [] - | Sc_rollup_timeout_result _ -> Ok [] - | Sc_rollup_execute_outbox_message_result _ -> Ok [] - | Sc_rollup_recover_bond_result _ -> Ok [] - | Sc_rollup_dal_slot_subscribe_result _ -> Ok []) - | Skipped _ -> Ok [] (* there must be another error for this to happen *) + | Transaction_to_sc_rollup_result _ ) + | Register_global_constant_result _ | Reveal_result _ + | Delegation_result _ | Set_deposits_limit_result _ + | Increase_paid_storage_result _ | Tx_rollup_origination_result _ + | Tx_rollup_submit_batch_result _ | Tx_rollup_commit_result _ + | Tx_rollup_return_bond_result _ + | Tx_rollup_finalize_commitment_result _ + | Tx_rollup_remove_commitment_result _ | Tx_rollup_rejection_result _ + | Tx_rollup_dispatch_tickets_result _ | Transfer_ticket_result _ + | Dal_publish_slot_header_result _ | Sc_rollup_originate_result _ + | Sc_rollup_add_messages_result _ | Sc_rollup_cement_result _ + | Sc_rollup_publish_result _ | Sc_rollup_refute_result _ + | Sc_rollup_timeout_result _ | Sc_rollup_execute_outbox_message_result _ + | Sc_rollup_recover_bond_result _ + | Sc_rollup_dal_slot_subscribe_result _ -> + Ok []) + | Skipped _ -> + error_with "Cannot know originated contracts of skipped operation" + (* There must be another error for this to happen, and it should not + surface (the force mode catches it). *) | Failed (_, errs) -> Error (Environment.wrap_tztrace errs) in let internal_originated_contracts (type kind) @@ -531,15 +516,14 @@ let originated_contracts_single (type kind) | Applied res | Backtracked (res, _) -> ( match res with | ITransaction_result - (Transaction_to_contract_result {originated_contracts; _}) -> + (Transaction_to_contract_result {originated_contracts; _}) + | IOrigination_result {originated_contracts; _} -> Ok originated_contracts | ITransaction_result ( Transaction_to_tx_rollup_result _ - | Transaction_to_sc_rollup_result _ ) -> - Ok [] - | IOrigination_result {originated_contracts; _} -> - Ok originated_contracts - | IDelegation_result _ | IEvent_result _ -> Ok []) + | Transaction_to_sc_rollup_result _ ) + | IDelegation_result _ | IEvent_result _ -> + Ok []) | Skipped _ -> Ok [] (* there must be another error for this to happen *) | Failed (_, errs) -> Error (Environment.wrap_tztrace errs) in diff --git a/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml b/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml index 55bcd59fb8a8b21117b01ad14684359fd5d5f419..6199fa41afe42115d089e233f1b40b8574d3d4c5 100644 --- a/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml +++ b/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml @@ -1054,11 +1054,12 @@ let commands_rw () = ~desc: "Execute multiple transfers from a single source account.\n\ If one of the transfers fails, none of them get executed." - (args12 + (args13 default_fee_arg dry_run_switch verbose_signing_switch simulate_switch + force_switch default_gas_limit_arg default_storage_limit_arg counter_arg @@ -1087,6 +1088,7 @@ let commands_rw () = dry_run, verbose_signing, simulation, + force, gas_limit, storage_limit, counter, @@ -1098,6 +1100,22 @@ let commands_rw () = source operations_json cctxt -> + (* When --force is used we want to inject the transfer even if it fails. + In that case we cannot rely on simulation to compute limits and fees + so we require the corresponding options to be set. *) + let check_force_dependency name = function + | None -> + cctxt#error + "When the --force switch is used, the %s option is required." + name + | _ -> Lwt.return_unit + in + (if force && not simulation then + check_force_dependency "--gas-limit" gas_limit >>= fun () -> + check_force_dependency "--storage-limit" storage_limit >>= fun () -> + check_force_dependency "--fee" fee + else Lwt.return_unit) + >>= fun () -> let prepare i = prepare_batch_operation cctxt @@ -1139,6 +1157,7 @@ let commands_rw () = ~dry_run ~verbose_signing ~simulation + ~force ~source ~fee:(Limit.of_option fee) ~gas_limit:(Limit.of_option gas_limit) diff --git a/tezt/lib_tezos/client.ml b/tezt/lib_tezos/client.ml index 4d0859317d2c07fb35fdb30856ba4c834ec66cc4..e39e0469534d68a99d8edcf458693ffc8c90ebd3 100644 --- a/tezt/lib_tezos/client.ml +++ b/tezt/lib_tezos/client.ml @@ -790,40 +790,28 @@ let transfer ?hooks ?log_output ?endpoint ?wait ?burn_cap ?fee ?gas_limit client |> Process.check ?expect_failure -let spawn_multiple_transfers ?log_output ?endpoint ?(wait = "none") ?burn_cap - ?fee_cap ?gas_limit ?storage_limit ?counter ?arg ~giver ~json_batch client = - spawn_command - ?log_output - ?endpoint - client - (["--wait"; wait] - @ ["multiple"; "transfers"; "from"; giver; "using"; json_batch] - @ Option.fold - ~none:[] - ~some:(fun f -> ["--fee-cap"; Tez.to_string f; "--force-low-fee"]) - fee_cap - @ optional_arg "burn-cap" Tez.to_string burn_cap - @ optional_arg "gas-limit" string_of_int gas_limit - @ optional_arg "storage-limit" string_of_int storage_limit - @ optional_arg "counter" string_of_int counter - @ optional_arg "arg" Fun.id arg) - -let multiple_transfers ?log_output ?endpoint ?wait ?burn_cap ?fee_cap ?gas_limit - ?storage_limit ?counter ?arg ~giver ~json_batch client = - spawn_multiple_transfers - ?log_output - ?endpoint - ?wait - ?burn_cap - ?fee_cap - ?gas_limit - ?storage_limit - ?counter - ?arg - ~giver - ~json_batch - client - |> Process.check +let multiple_transfers ?log_output ?endpoint ?(wait = "none") ?burn_cap ?fee_cap + ?gas_limit ?storage_limit ?counter ?(simulation = false) ?(force = false) + ~giver ~json_batch client = + let value = + spawn_command + ?log_output + ?endpoint + client + (["--wait"; wait] + @ ["multiple"; "transfers"; "from"; giver; "using"; json_batch] + @ Option.fold + ~none:[] + ~some:(fun f -> ["--fee-cap"; Tez.to_string f; "--force-low-fee"]) + fee_cap + @ optional_arg "burn-cap" Tez.to_string burn_cap + @ optional_arg "gas-limit" string_of_int gas_limit + @ optional_arg "storage-limit" string_of_int storage_limit + @ optional_arg "counter" string_of_int counter + @ (if simulation then ["--simulation"] else []) + @ if force then ["--force"] else []) + in + {value; run = Process.check} let spawn_get_delegate ?endpoint ~src client = spawn_command ?endpoint client ["get"; "delegate"; "for"; src] diff --git a/tezt/lib_tezos/client.mli b/tezt/lib_tezos/client.mli index e3e40989bb1aa1d308778b6ada7f86b63bbae555..3bff5b48cc09d9ad7166f2b486e495a67b41c1d0 100644 --- a/tezt/lib_tezos/client.mli +++ b/tezt/lib_tezos/client.mli @@ -630,27 +630,12 @@ val multiple_transfers : ?gas_limit:int -> ?storage_limit:int -> ?counter:int -> - ?arg:string -> - giver:string -> - json_batch:string -> - t -> - unit Lwt.t - -(** Same as [multiple_transfers], but do not wait for the process to exit. *) -val spawn_multiple_transfers : - ?log_output:bool -> - ?endpoint:endpoint -> - ?wait:string -> - ?burn_cap:Tez.t -> - ?fee_cap:Tez.t -> - ?gas_limit:int -> - ?storage_limit:int -> - ?counter:int -> - ?arg:string -> + ?simulation:bool -> + ?force:bool -> giver:string -> json_batch:string -> t -> - Process.t + unit Runnable.process (** Run tezos-client get delegate for . Returns [Some address] if delegate is set or [None] otherwise. *) diff --git a/tezt/long_tests/script_cache.ml b/tezt/long_tests/script_cache.ml index 3fec0857a2c276191317137bdf8d8c01435d06a1..5de3109f4b68c92e2c35cdd25f7b3386ed02fa29 100644 --- a/tezt/long_tests/script_cache.ml +++ b/tezt/long_tests/script_cache.ml @@ -193,7 +193,7 @@ let call_contract contract_id k client = (** [call_contracts calls client] bakes a block with multiple contract [calls] using [client]. It returns the amount of consumed gas. *) let call_contracts calls client = - let* () = + let*! () = Client.multiple_transfers ~log_output:false ~fee_cap:Tez.(of_int 9999999) diff --git a/tezt/tests/client_commands.ml b/tezt/tests/client_commands.ml index 639f7b638e12d242e0e7c2188d28f396a97d31f3..2f41c4c10d7964fd42dbc1d395fb866ee1d78b3a 100644 --- a/tezt/tests/client_commands.ml +++ b/tezt/tests/client_commands.ml @@ -63,6 +63,32 @@ module Simulation = struct client |> k + let multiple_transfers ~args ?simulation ?force k protocol = + let* _node, client = Client.init_with_protocol `Client ~protocol () in + let* contract = Helpers.originate_fail_on_false client in + let batches = + Ezjsonm.list + (fun arg -> + `O + [ + ("destination", `String contract); + ("amount", `String "2"); + ("arg", `String arg); + ]) + args + in + let file = Temp.file "batch.json" in + let oc = open_out file in + Ezjsonm.to_channel oc batches ; + close_out oc ; + Client.multiple_transfers + ~giver:Constant.bootstrap1.public_key_hash + ~json_batch:file + ?simulation + ?force + client + |> k + let successful = Protocol.register_test ~__FILE__ @@ -70,6 +96,16 @@ module Simulation = struct ~tags:["client"; "simulation"; "success"] @@ transfer ~arg:"True" ~simulation:true Process.check + let successful_multiple = + Protocol.register_test + ~__FILE__ + ~title:"Simulation of successful operation batch" + ~tags:["client"; "simulation"; "success"; "multiple"; "batch"] + @@ multiple_transfers + ~args:["True"; "True"; "True"] + ~simulation:true + Runnable.run + let failing = Protocol.register_test ~__FILE__ @@ -90,6 +126,25 @@ module Simulation = struct Test.fail "Did not report operation failure" ; unit + let failing_multiple_force = + Protocol.register_test + ~__FILE__ + ~title:"Simulation of failing batch with force" + ~tags:["client"; "simulation"; "failing"; "multiple"; "batch"; "force"] + @@ multiple_transfers + ~args:["True"; "False"; "True"] + ~simulation:true + ~force:true + @@ fun Runnable.{value; _} -> + let* stdout = Process.check_and_read_stdout ~expect_failure:false value in + if + stdout + =~! rex + "This transaction was BACKTRACKED[\\S\\s.]*This operation \ + FAILED[\\S\\s.]*This operation was skipped" + then Test.fail "Did not report operation backtracked/failure/skipping" ; + unit + let injection_force = Protocol.register_test ~__FILE__ @@ -100,11 +155,26 @@ module Simulation = struct ~exit_code:1 ~msg:(rex "--gas-limit option is required") + let injection_multiple_force = + Protocol.register_test + ~__FILE__ + ~title:"Injecting of failing operations batch with force" + ~tags:["client"; "injection"; "failing"; "force"; "multiple"; "batch"] + @@ multiple_transfers ~args:["True"; "False"; "True"] ~force:true + @@ fun Runnable.{value; _} -> + Process.check_error + value + ~exit_code:1 + ~msg:(rex "--gas-limit option is required") + let register protocol = successful protocol ; + successful_multiple protocol ; failing protocol ; failing_force protocol ; - injection_force protocol + failing_multiple_force protocol ; + injection_force protocol ; + injection_multiple_force protocol end module Transfer = struct @@ -303,6 +373,6 @@ module Dry_run = struct end let register ~protocols = - Simulation.register [Jakarta; Alpha] ; + Simulation.register protocols ; Transfer.register protocols ; Dry_run.register protocols diff --git a/tezt/tests/mockup.ml b/tezt/tests/mockup.ml index a574f9b5b5849d8b096a83c65af042510a0ea017..83105c949a555f9b051df2afebaf489061b9224f 100644 --- a/tezt/tests/mockup.ml +++ b/tezt/tests/mockup.ml @@ -569,7 +569,13 @@ let test_multiple_transfers = let oc = open_out file in Ezjsonm.to_channel oc (batch 200) ; close_out oc ; - Client.multiple_transfers ~giver:"bootstrap2" ~json_batch:file client + let*! () = + Client.multiple_transfers + ~giver:Constant.bootstrap2.alias + ~json_batch:file + client + in + unit let test_empty_block_baking = Protocol.register_test