diff --git a/docs/protocols/alpha.rst b/docs/protocols/alpha.rst index c24900574fefe961345fcf96649bcdcd8f0f61cb..7c12d6ef9e8b8ab0de12cf17753a294604e1f3d6 100644 --- a/docs/protocols/alpha.rst +++ b/docs/protocols/alpha.rst @@ -23,6 +23,11 @@ Breaking Changes - Reveal operations can only occur at the head of a manager operation batch (MR :gl:`!5182`). +- Operations with non-deserializable scripts may now be propagated and + included in blocks. If such an operation is in a block, its + application will fail so the operation will have no effect, but its + fees will still be taken. (MR :gl:`!5506`) + RPC Changes ----------- @@ -45,6 +50,11 @@ Bug Fixes enforcing that failing reveal operations do not take effect (MR :gl:`!5182`). +- Consume constant gas `Michelson_v1_gas.Cost_of.manager_operation` + during precheck: this fixes some cases of operations passing + precheck even though they obviously do not have enough gas to apply + the external operation, e.g. when `gas_limit = 0`. (MR :gl:`!5506`) + Minor Changes ------------- @@ -65,3 +75,12 @@ Internal - Rename `run_view` into `run_tzip4_view` for consistency with `run_script_view`. Does not affect the existing `run_view` RPC. (MR :gl:`!4810`) + +- Precheck no longer returns the gas it has consumed. Instead of + "replaying" the gas from precheck, `apply_manager_contents` consumes + the same gas again step by step. (MR :gl:`!5506`) + +- Precheck no longer tries to deserialize scripts. It does still check + that the operation has enough gas for these deserializations (by + consuming an estimated gas cost based on the bytes size: this has + not changed). (MR :gl:`!5506`) diff --git a/src/proto_alpha/lib_protocol/alpha_context.ml b/src/proto_alpha/lib_protocol/alpha_context.ml index 2acb7c5fc8bff52d7370f932ce1da297ff0426a0..86775bd3fb124a7562d2622d1917cf659996a9e7 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.ml +++ b/src/proto_alpha/lib_protocol/alpha_context.ml @@ -152,6 +152,10 @@ module Script = struct Raw_context.consume_gas ctxt (Script_repr.force_bytes_cost lexpr) >>? fun ctxt -> Script_repr.force_bytes lexpr >|? fun v -> (v, ctxt) + + let consume_decoding_gas ctxt lexpr = + let gas_cost = Script_repr.stable_force_decode_cost lexpr in + Raw_context.consume_gas ctxt gas_cost end module Fees = Fees_storage diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 079e751a7ad961f03c5590a544ed56c128d013f1..70ff62e9a81d79ad1de34ecb93d073db5227590e 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -692,6 +692,18 @@ module Script : sig val force_bytes_in_context : context -> lazy_expr -> (bytes * context) tzresult + (** [consume_decoding_gas ctxt lexpr] substracts (a lower bound on) + the cost to deserialize [lexpr] from the current operation gas + level in [ctxt]. The cost does not depend on the internal state + of the lazy_expr. + + @return [Error Operation_quota_exceeded] if the operation gas + level would fall below [0]. + + This mimics the gas consuming part of {!force_decode_in_context} + called with [consume_deserialization_gas:Always]. *) + val consume_decoding_gas : context -> lazy_expr -> context tzresult + val unit_parameter : lazy_expr val strip_locations_cost : _ michelson_node -> Gas.cost diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index fba134a20eb19d0c456535006794d8fda3420ef1..7d4f268b2c9d1965e8c3fa108ac68239c1d68987 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -122,6 +122,7 @@ type error += | Invalid_activation of {pkh : Ed25519.Public_key_hash.t} | Multiple_revelation | Gas_quota_exceeded_init_deserialize + | Insufficient_gas_for_manager | Inconsistent_sources | Failing_noop_error | Zero_frozen_deposits of Signature.Public_key_hash.t @@ -725,6 +726,19 @@ let () = Data_encoding.empty (function Gas_quota_exceeded_init_deserialize -> Some () | _ -> None) (fun () -> Gas_quota_exceeded_init_deserialize) ; + register_error_kind + `Permanent + ~id:"operation.insufficient_gas_for_manager" + ~title:"Not enough gas for initial manager cost" + ~description: + (Format.asprintf + "Gas limit was not high enough to cover the initial cost of manager \ + operations. At least %a expected." + Gas.pp_cost + Michelson_v1_gas.Cost_of.manager_operation) + Data_encoding.empty + (function Insufficient_gas_for_manager -> Some () | _ -> None) + (fun () -> Insufficient_gas_for_manager) ; register_error_kind `Permanent ~id:"operation.inconsistent_sources" @@ -1108,24 +1122,6 @@ let apply_origination ~ctxt ~storage_type ~storage ~unparsed_code *) -let prepare_apply_manager_operation_content ~ctxt ~source - ~gas_consumed_in_precheck = - let before_operation = - (* This context is not used for backtracking. Only to compute - gas consumption and originations for the operation result. *) - ctxt - in - Contract.must_exist ctxt source >>=? fun () -> - Gas.consume ctxt Michelson_v1_gas.Cost_of.manager_operation >>?= fun ctxt -> - (match gas_consumed_in_precheck with - | None -> Ok ctxt - | Some gas -> Gas.consume ctxt gas) - >>?= fun ctxt -> - let consume_deserialization_gas = Script.When_needed in - (* [note]: deserialization gas has already been accounted for in the gas - consumed by the precheck and the lazy_exprs have been forced. *) - return (ctxt, before_operation, consume_deserialization_gas) - let apply_internal_manager_operation_content : type kind. context -> @@ -1139,12 +1135,15 @@ let apply_internal_manager_operation_content : * Script_typed_ir.packed_internal_operation list) tzresult Lwt.t = - fun ctxt mode ~payer ~source ~chain_id operation -> - prepare_apply_manager_operation_content - ~ctxt - ~source - ~gas_consumed_in_precheck:None - >>=? fun (ctxt, before_operation, consume_deserialization_gas) -> + fun ctxt_before_op mode ~payer ~source ~chain_id operation -> + Contract.must_exist ctxt_before_op source >>=? fun () -> + Gas.consume ctxt_before_op Michelson_v1_gas.Cost_of.manager_operation + >>?= fun ctxt -> + (* Note that [ctxt_before_op] will be used again later to compute + gas consumption and originations for the operation result (by + comparing it with the [ctxt] we will have at the end of the + application). *) + let consume_deserialization_gas = Script.When_needed in match operation with | Transaction_to_contract { @@ -1163,7 +1162,7 @@ let apply_internal_manager_operation_content : ~pkh ~parameter:(Typed_arg (location, parameters_ty, typed_parameters)) ~entrypoint - ~before_operation + ~before_operation:ctxt_before_op >|=? fun (ctxt, res, ops) -> ( ctxt, (ITransaction_result res @@ -1185,7 +1184,7 @@ let apply_internal_manager_operation_content : ~contract_hash ~amount ~entrypoint - ~before_operation + ~before_operation:ctxt_before_op ~payer ~chain_id ~mode @@ -1200,7 +1199,7 @@ let apply_internal_manager_operation_content : ~parameters ~payer ~dst_rollup:destination - ~since:before_operation + ~since:ctxt_before_op | Origination { origination = {delegate; script; credit}; @@ -1222,11 +1221,11 @@ let apply_internal_manager_operation_content : ~delegate ~source ~credit - ~before_operation + ~before_operation:ctxt_before_op >|=? fun (ctxt, origination_result, ops) -> (ctxt, IOrigination_result origination_result, ops) | Delegation delegate -> - apply_delegation ~ctxt ~source ~delegate ~before_operation + apply_delegation ~ctxt ~source ~delegate ~before_operation:ctxt_before_op >|=? fun (ctxt, consumed_gas, ops) -> (ctxt, IDelegation_result {consumed_gas}, ops) @@ -1236,7 +1235,6 @@ let apply_external_manager_operation_content : Script_ir_translator.unparsing_mode -> source:public_key_hash -> chain_id:Chain_id.t -> - gas_consumed_in_precheck:Gas.cost option -> fee:Tez.t -> kind manager_operation -> (context @@ -1244,13 +1242,24 @@ let apply_external_manager_operation_content : * Script_typed_ir.packed_internal_operation list) tzresult Lwt.t = - fun ctxt mode ~source ~chain_id ~gas_consumed_in_precheck ~fee operation -> + fun ctxt_before_op mode ~source ~chain_id ~fee operation -> let source_contract = Contract.Implicit source in - prepare_apply_manager_operation_content - ~ctxt - ~source:source_contract - ~gas_consumed_in_precheck - >>=? fun (ctxt, before_operation, consume_deserialization_gas) -> + Contract.must_exist ctxt_before_op source_contract >>=? fun () -> + Gas.consume ctxt_before_op Michelson_v1_gas.Cost_of.manager_operation + >>?= fun ctxt -> + (* Note that [ctxt_before_op] will be used again later to compute + gas consumption and originations for the operation result (by + comparing it with the [ctxt] we will have at the end of the + application). *) + let consume_deserialization_gas = + (* Note that we used to set this to [Script.When_needed] because + the deserialization gas was accounted for in the gas consumed + by precheck. However, we no longer have access to this precheck + gas, so we want to always consume the deserialization gas + again, independently of the internal state of the lazy_exprs in + the arguments. *) + Script.Always + in match operation with | Reveal pk -> (* TODO #2603 @@ -1275,7 +1284,7 @@ let apply_external_manager_operation_content : return ( ctxt, (Reveal_result - {consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt} + {consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt} : kind successful_manager_operation_result), [] ) | Transaction {amount; parameters; destination = Implicit pkh; entrypoint} -> @@ -1291,7 +1300,7 @@ let apply_external_manager_operation_content : ~pkh ~parameter:(Untyped_arg parameters) ~entrypoint - ~before_operation + ~before_operation:ctxt_before_op >|=? fun (ctxt, res, ops) -> (ctxt, Transaction_result res, ops) | Transaction {amount; parameters; destination = Originated contract_hash; entrypoint} @@ -1307,7 +1316,7 @@ let apply_external_manager_operation_content : ~contract_hash ~amount ~entrypoint - ~before_operation + ~before_operation:ctxt_before_op ~payer:source ~chain_id ~mode @@ -1401,7 +1410,7 @@ let apply_external_manager_operation_content : Tx_rollup_dispatch_tickets_result { balance_updates = []; - consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt; + consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt; paid_storage_size_diff; } in @@ -1437,7 +1446,7 @@ let apply_external_manager_operation_content : Transfer_ticket_result { balance_updates = []; - consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt; + consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt; paid_storage_size_diff; } in @@ -1481,11 +1490,15 @@ let apply_external_manager_operation_content : ~delegate ~source:source_contract ~credit - ~before_operation + ~before_operation:ctxt_before_op >|=? fun (ctxt, origination_result, ops) -> (ctxt, Origination_result origination_result, ops) | Delegation delegate -> - apply_delegation ~ctxt ~source:source_contract ~delegate ~before_operation + apply_delegation + ~ctxt + ~source:source_contract + ~delegate + ~before_operation:ctxt_before_op >|=? fun (ctxt, consumed_gas, ops) -> (ctxt, Delegation_result {consumed_gas}, ops) | Register_global_constant {value} -> @@ -1514,7 +1527,7 @@ let apply_external_manager_operation_content : Register_global_constant_result { balance_updates = []; - consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt; + consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt; size_of_constant = paid_size; global_address = address; } @@ -1545,14 +1558,14 @@ let apply_external_manager_operation_content : return ( ctxt, Set_deposits_limit_result - {consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt}, + {consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt}, [] ) | Tx_rollup_origination -> Tx_rollup.originate ctxt >>=? fun (ctxt, originated_tx_rollup) -> let result = Tx_rollup_origination_result { - consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt; + consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt; originated_tx_rollup; balance_updates = []; } @@ -1560,6 +1573,8 @@ let apply_external_manager_operation_content : return (ctxt, result, []) | Tx_rollup_submit_batch {tx_rollup; content; burn_limit} -> let message, message_size = Tx_rollup_message.make_batch content in + Tx_rollup_gas.hash_cost message_size >>?= fun cost -> + Gas.consume ctxt cost >>?= fun ctxt -> Tx_rollup_state.get ctxt tx_rollup >>=? fun (ctxt, state) -> Tx_rollup_inbox.append_message ctxt tx_rollup state message >>=? fun (ctxt, state, paid_storage_size_diff) -> @@ -1571,7 +1586,7 @@ let apply_external_manager_operation_content : let result = Tx_rollup_submit_batch_result { - consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt; + consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt; balance_updates; paid_storage_size_diff; } @@ -1613,7 +1628,7 @@ let apply_external_manager_operation_content : let result = Tx_rollup_commit_result { - consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt; + consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt; balance_updates = burn_update @ balance_updates; } in @@ -1632,7 +1647,7 @@ let apply_external_manager_operation_content : let result = Tx_rollup_return_bond_result { - consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt; + consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt; balance_updates; } in @@ -1645,7 +1660,7 @@ let apply_external_manager_operation_content : let result = Tx_rollup_finalize_commitment_result { - consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt; + consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt; balance_updates = []; level; } @@ -1659,7 +1674,7 @@ let apply_external_manager_operation_content : let result = Tx_rollup_remove_commitment_result { - consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt; + consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt; balance_updates = []; level; } @@ -1765,20 +1780,20 @@ let apply_external_manager_operation_content : let result = Tx_rollup_rejection_result { - consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt; + consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt; balance_updates; } in return (ctxt, result, []) | Dal_publish_slot_header {slot} -> Dal_apply.apply_publish_slot_header ctxt slot fee >>?= fun ctxt -> - let consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt in + let consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt in let result = Dal_publish_slot_header_result {consumed_gas} in return (ctxt, result, []) | Sc_rollup_originate {kind; boot_sector; parameters_ty} -> Sc_rollup_operations.originate ctxt ~kind ~boot_sector ~parameters_ty >>=? fun ({address; size}, ctxt) -> - let consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt in + let consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt in let result = Sc_rollup_originate_result {address; consumed_gas; size; balance_updates = []} @@ -1787,19 +1802,19 @@ let apply_external_manager_operation_content : | Sc_rollup_add_messages {rollup; messages} -> Sc_rollup.Inbox.add_external_messages ctxt rollup messages >>=? fun (inbox_after, _size, ctxt) -> - let consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt in + let consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt in let result = Sc_rollup_add_messages_result {consumed_gas; inbox_after} in return (ctxt, result, []) | Sc_rollup_cement {rollup; commitment} -> Sc_rollup.Stake_storage.cement_commitment ctxt rollup commitment >>=? fun ctxt -> - let consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt in + let consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt in let result = Sc_rollup_cement_result {consumed_gas} in return (ctxt, result, []) | Sc_rollup_publish {rollup; commitment} -> Sc_rollup.Stake_storage.publish_commitment ctxt rollup source commitment >>=? fun (staked_hash, published_at_level, ctxt, balance_updates) -> - let consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt in + let consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt in let result = Sc_rollup_publish_result {staked_hash; consumed_gas; published_at_level; balance_updates} @@ -1820,7 +1835,7 @@ let apply_external_manager_operation_content : let stakers = Sc_rollup.Game.Index.make source opponent in Sc_rollup.Refutation_storage.apply_outcome ctxt rollup stakers o) >>=? fun (status, ctxt, balance_updates) -> - let consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt in + let consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt in let result = Sc_rollup_refute_result {status; consumed_gas; balance_updates} in @@ -1830,7 +1845,7 @@ let apply_external_manager_operation_content : >>=? fun (outcome, ctxt) -> Sc_rollup.Refutation_storage.apply_outcome ctxt rollup stakers outcome >>=? fun (status, ctxt, balance_updates) -> - let consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt in + let consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt in let result = Sc_rollup_timeout_result {status; consumed_gas; balance_updates} in @@ -1860,7 +1875,7 @@ let apply_external_manager_operation_content : let result = Sc_rollup_recover_bond_result { - consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt; + consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt; balance_updates; } in @@ -1912,7 +1927,7 @@ let apply_internal_manager_operations ctxt mode ~payer ~chain_id ops = apply ctxt [] ops let precheck_manager_contents (type kind) ctxt (op : kind Kind.manager contents) - ~(only_batch : bool) : (context * precheck_result) tzresult Lwt.t = + ~(only_batch : bool) : (context * Receipt.balance_updates) tzresult Lwt.t = let[@coq_match_with_default] (Manager_operation { source; @@ -1936,49 +1951,36 @@ let precheck_manager_contents (type kind) ctxt (op : kind Kind.manager contents) @@ Gas.consume_limit_in_block ctxt gas_limit >>?= fun ctxt -> let ctxt = Gas.set_limit ctxt gas_limit in - let ctxt_before = ctxt in + record_trace + Insufficient_gas_for_manager + (Gas.consume ctxt Michelson_v1_gas.Cost_of.manager_operation) + >>?= fun ctxt -> Fees.check_storage_limit ctxt ~storage_limit >>?= fun () -> let source_contract = Contract.Implicit source in Contract.must_be_allocated ctxt source_contract >>=? fun () -> Contract.check_counter_increment ctxt source counter >>=? fun () -> - let consume_deserialization_gas = Script.Always in - (* We want to always consume the deserialization gas here, independently of - the internal state of the lazy_exprs in the arguments. Otherwise we might - risk getting different results if the operation has already been - deserialized before (e.g. when retrieve in JSON format). *) + let consume_decoding_gas ctxt lexpr = + record_trace Gas_quota_exceeded_init_deserialize + @@ (* Fail early if the operation does not have enough gas to + cover the deserialization cost. We always consider the full + deserialization cost, independently from the internal state + of the lazy_expr. Otherwise we might risk getting different + results if the operation has already been deserialized + before (e.g. when retrieved in JSON format). Note that the + lazy_expr is not actually decoded here; its deserialization + cost is estimated from the size of its bytes. *) + Script.consume_decoding_gas ctxt lexpr + in (match operation with | Reveal pk -> Contract.check_public_key pk source >>?= fun () -> return ctxt | Transaction {parameters; _} -> - Lwt.return - @@ record_trace Gas_quota_exceeded_init_deserialize - @@ (* Fail early if not enough gas for complete deserialization - cost or if deserialization fails. The gas consumed here is - "replayed" in [apply_manager_contents]. *) - ( Script.force_decode_in_context - ~consume_deserialization_gas - ctxt - parameters - >|? fun (_arg, ctxt) -> ctxt ) + Lwt.return @@ consume_decoding_gas ctxt parameters | Origination {script; _} -> Lwt.return - @@ record_trace Gas_quota_exceeded_init_deserialize - @@ (* See comment in the Transaction branch *) - ( Script.force_decode_in_context - ~consume_deserialization_gas - ctxt - script.code - >>? fun (_code, ctxt) -> - Script.force_decode_in_context - ~consume_deserialization_gas - ctxt - script.storage - >|? fun (_storage, ctxt) -> ctxt ) + ( consume_decoding_gas ctxt script.code >>? fun ctxt -> + consume_decoding_gas ctxt script.storage ) | Register_global_constant {value} -> - Lwt.return - @@ record_trace Gas_quota_exceeded_init_deserialize - @@ (* See comment in the Transaction branch *) - ( Script.force_decode_in_context ~consume_deserialization_gas ctxt value - >|? fun (_value, ctxt) -> ctxt ) + Lwt.return @@ consume_decoding_gas ctxt value | Delegation _ | Set_deposits_limit _ -> return ctxt | Tx_rollup_origination -> assert_tx_rollup_feature_enabled ctxt >|=? fun () -> ctxt @@ -1998,12 +2000,8 @@ let precheck_manager_contents (type kind) ctxt (op : kind Kind.manager contents) | Transfer_ticket {contents; ty; _} -> assert_tx_rollup_feature_enabled ctxt >>=? fun () -> Lwt.return - @@ record_trace Gas_quota_exceeded_init_deserialize - @@ (* See comment in the Transaction branch *) - ( Script.force_decode_in_context ~consume_deserialization_gas ctxt contents - >>? fun (_contents, ctxt) -> - Script.force_decode_in_context ~consume_deserialization_gas ctxt ty - >|? fun (_ty, ctxt) -> ctxt ) + @@ ( consume_decoding_gas ctxt contents >>? fun ctxt -> + consume_decoding_gas ctxt ty ) | Tx_rollup_dispatch_tickets {tickets_info; message_result_path; _} -> assert_tx_rollup_feature_enabled ctxt >>=? fun () -> let Constants.Parametric. @@ -2024,18 +2022,12 @@ let precheck_manager_contents (type kind) ctxt (op : kind Kind.manager contents) Tx_rollup_errors.Too_many_withdrawals >>?= fun () -> record_trace Gas_quota_exceeded_init_deserialize - @@ (* See comment in the Transaction branch *) - List.fold_left_e - (fun ctxt Tx_rollup_reveal.{contents; ty; _} -> - Script.force_decode_in_context - ~consume_deserialization_gas - ctxt - contents - >>? fun (_contents, ctxt) -> - Script.force_decode_in_context ~consume_deserialization_gas ctxt ty - >|? fun (_ty, ctxt) -> ctxt) - ctxt - tickets_info + @@ List.fold_left_e + (fun ctxt Tx_rollup_reveal.{contents; ty; _} -> + Script.consume_decoding_gas ctxt contents >>? fun ctxt -> + Script.consume_decoding_gas ctxt ty) + ctxt + tickets_info >>?= fun ctxt -> return ctxt | Tx_rollup_rejection {message_path; message_result_path; previous_message_result_path; _} -> @@ -2075,9 +2067,6 @@ let precheck_manager_contents (type kind) ctxt (op : kind Kind.manager contents) >>=? fun ctxt -> Contract.increment_counter ctxt source >>=? fun ctxt -> Token.transfer ctxt (`Contract source_contract) `Block_fees fee - >|=? fun (ctxt, balance_updates) -> - let consumed_gas = Gas.consumed ~since:ctxt_before ~until:ctxt in - (ctxt, {balance_updates; consumed_gas}) let burn_transaction_storage_fees ctxt trr ~storage_limit ~payer = match trr with @@ -2288,7 +2277,7 @@ let burn_internal_storage_fees : | IDelegation_result _ -> return (ctxt, storage_limit, smopr) let apply_manager_contents (type kind) ctxt mode chain_id - ~gas_consumed_in_precheck (op : kind Kind.manager contents) : + (op : kind Kind.manager contents) : (success_or_failure * kind manager_operation_result * packed_internal_manager_operation_result list) @@ -2311,7 +2300,6 @@ let apply_manager_contents (type kind) ctxt mode chain_id ctxt mode ~source - ~gas_consumed_in_precheck ~chain_id ~fee operation @@ -2379,10 +2367,7 @@ let rec mark_skipped : fun ~payload_producer level prechecked_contents_list -> match[@coq_match_with_default] prechecked_contents_list with | PrecheckedSingle - { - contents = Manager_operation {operation; _}; - result = {balance_updates; _}; - } -> + {contents = Manager_operation {operation; _}; balance_updates} -> Single_result (Manager_operation_result { @@ -2391,11 +2376,7 @@ let rec mark_skipped : internal_operation_results = []; }) | PrecheckedCons - ( { - contents = Manager_operation {operation; _}; - result = {balance_updates; _}; - }, - rest ) -> + ({contents = Manager_operation {operation; _}; balance_updates}, rest) -> Cons_result ( Manager_operation_result { @@ -2445,14 +2426,14 @@ let precheck_manager_contents_list ctxt contents_list ~mempool_mode = match contents_list with | Single contents -> precheck_manager_contents ctxt contents ~only_batch:mempool_mode - >>=? fun (ctxt, result) -> - return (ctxt, PrecheckedSingle {contents; result}) + >>=? fun (ctxt, balance_updates) -> + return (ctxt, PrecheckedSingle {contents; balance_updates}) | Cons (contents, rest) -> precheck_manager_contents ctxt contents ~only_batch:mempool_mode - >>=? fun (ctxt, result) -> + >>=? fun (ctxt, balance_updates) -> rec_precheck_manager_contents_list ctxt rest >>=? fun (ctxt, results_rest) -> - return (ctxt, PrecheckedCons ({contents; result}, results_rest)) + return (ctxt, PrecheckedCons ({contents; balance_updates}, results_rest)) in let ctxt = if mempool_mode then Gas.reset_block_gas ctxt else ctxt in check_counters_consistency contents_list >>=? fun () -> @@ -2525,17 +2506,8 @@ let rec apply_manager_contents_list_rec : fun ctxt mode ~payload_producer chain_id prechecked_contents_list -> let level = Level.current ctxt in match[@coq_match_with_default] prechecked_contents_list with - | PrecheckedSingle - { - contents = Manager_operation _ as op; - result = {consumed_gas; balance_updates}; - } -> - apply_manager_contents - ctxt - mode - chain_id - ~gas_consumed_in_precheck:(Some (Gas.cost_of_gas consumed_gas)) - op + | PrecheckedSingle {contents = Manager_operation _ as op; balance_updates} -> + apply_manager_contents ctxt mode chain_id op >|= fun (ctxt_result, operation_result, internal_operation_results) -> let result = Manager_operation_result @@ -2543,18 +2515,8 @@ let rec apply_manager_contents_list_rec : in (ctxt_result, Single_result result) | PrecheckedCons - ( { - contents = Manager_operation _ as op; - result = {consumed_gas; balance_updates}; - }, - rest ) -> ( - apply_manager_contents - ctxt - mode - chain_id - ~gas_consumed_in_precheck:(Some (Gas.cost_of_gas consumed_gas)) - op - >>= function + ({contents = Manager_operation _ as op; balance_updates}, rest) -> ( + apply_manager_contents ctxt mode chain_id op >>= function | Failure, operation_result, internal_operation_results -> let result = Manager_operation_result diff --git a/src/proto_alpha/lib_protocol/apply.mli b/src/proto_alpha/lib_protocol/apply.mli index 286a1014b9929d6e793d51f24817c8e652b700fc..ae2d7c9fff29774abfdd02ecf475f9d0277c919f 100644 --- a/src/proto_alpha/lib_protocol/apply.mli +++ b/src/proto_alpha/lib_protocol/apply.mli @@ -39,6 +39,7 @@ open Apply_results type error += | Internal_operation_replay of packed_internal_contents | Gas_quota_exceeded_init_deserialize + | Insufficient_gas_for_manager | Tx_rollup_feature_disabled | Tx_rollup_invalid_transaction_ticket_amount | Sc_rollup_feature_disabled diff --git a/src/proto_alpha/lib_protocol/apply_results.ml b/src/proto_alpha/lib_protocol/apply_results.ml index 59039dcfbaffff0854a018a9d43bad84d20104df..e24da912fc8ee8ba79bbee7c24bad30a960281c4 100644 --- a/src/proto_alpha/lib_protocol/apply_results.ml +++ b/src/proto_alpha/lib_protocol/apply_results.ml @@ -3320,14 +3320,9 @@ let block_metadata_encoding = the feature flag will be activated. *) (varopt "dal_slot_availability" Dal.Endorsement.encoding))) -type precheck_result = { - consumed_gas : Gas.Arith.fp; - balance_updates : Receipt.balance_updates; -} - type 'kind prechecked_contents = { contents : 'kind contents; - result : precheck_result; + balance_updates : Receipt.balance_updates; } type _ prechecked_contents_list = diff --git a/src/proto_alpha/lib_protocol/apply_results.mli b/src/proto_alpha/lib_protocol/apply_results.mli index 8bdf1ea66bc53c96d293883655b14401fed200ab..009fbdbbc34073f9fc620b6a72707cb64122cf69 100644 --- a/src/proto_alpha/lib_protocol/apply_results.mli +++ b/src/proto_alpha/lib_protocol/apply_results.mli @@ -426,14 +426,9 @@ type block_metadata = { val block_metadata_encoding : block_metadata Data_encoding.encoding -type precheck_result = { - consumed_gas : Gas.Arith.fp; - balance_updates : Receipt.balance_updates; -} - type 'kind prechecked_contents = { contents : 'kind contents; - result : precheck_result; + balance_updates : Receipt.balance_updates; } type _ prechecked_contents_list = diff --git a/src/proto_alpha/lib_protocol/michelson_v1_gas.ml b/src/proto_alpha/lib_protocol/michelson_v1_gas.ml index 34797b492572d95a6a96812f663c3a32017d9136..39f89d88f157c7f33da62fbd0127fcce6a0465cb 100644 --- a/src/proto_alpha/lib_protocol/michelson_v1_gas.ml +++ b/src/proto_alpha/lib_protocol/michelson_v1_gas.ml @@ -48,7 +48,9 @@ module Cost_of = struct let int_bytes (z : 'a Script_int.num) = z_bytes (Script_int.to_zint z) - let manager_operation = step_cost @@ S.safe_int 1_000 + let manager_operation_int = 1_000 + + let manager_operation = step_cost @@ S.safe_int manager_operation_int module Generated_costs = struct (* Automatically generated costs functions. *) @@ -1824,3 +1826,7 @@ module Cost_of = struct atomic_step_cost (cost_ENCODING_Chest ~plaintext_size) end end + +module Internal_for_tests = struct + let int_cost_of_manager_operation = Cost_of.manager_operation_int +end diff --git a/src/proto_alpha/lib_protocol/michelson_v1_gas.mli b/src/proto_alpha/lib_protocol/michelson_v1_gas.mli index 1bbb9cc97691bb5a9f1bc9a1e3044edeb8947794..c87e1a14a64ac4280cec130bb28bec8a28fa0586 100644 --- a/src/proto_alpha/lib_protocol/michelson_v1_gas.mli +++ b/src/proto_alpha/lib_protocol/michelson_v1_gas.mli @@ -505,3 +505,8 @@ module Cost_of : sig val chest : plaintext_size:int -> Gas.cost end end + +module Internal_for_tests : sig + (** [int] value of {!Cost_of.manager_operation} *) + val int_cost_of_manager_operation : int +end diff --git a/src/proto_alpha/lib_protocol/test/helpers/op.ml b/src/proto_alpha/lib_protocol/test/helpers/op.ml index b54ed3ce535596f129441bb2162073c2eece5027..53da6f52100bf357dc2340db844c18e7c3156b27 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/op.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/op.ml @@ -151,6 +151,25 @@ let batch_operations ?(recompute_counters = false) ~source ctxt Environment.wrap_tzresult @@ Operation.of_list operations >>?= fun operations -> return @@ sign account.sk ctxt operations +type gas_limit = Max | High | Low | Zero | Custom_gas of Gas.Arith.integral + +let default_low_gas_limit = + Gas.Arith.integral_of_int_exn + Michelson_v1_gas.Internal_for_tests.int_cost_of_manager_operation + +let default_high_gas_limit = + Gas.Arith.integral_of_int_exn + (49_000 + Michelson_v1_gas.Internal_for_tests.int_cost_of_manager_operation) + +let resolve_gas_limit ctxt = function + | Max -> + Context.get_constants ctxt >>=? fun c -> + return c.parametric.hard_gas_limit_per_operation + | High -> return default_high_gas_limit + | Low -> return default_low_gas_limit + | Zero -> return Gas.Arith.zero + | Custom_gas x -> return x + let combine_operations ?public_key ?counter ?spurious_operation ~source ctxt (packed_operations : packed_operation list) = assert (match packed_operations with [] -> false | _ :: _ -> true) ; @@ -194,7 +213,7 @@ let combine_operations ?public_key ?counter ?spurious_operation ~source ctxt fee = Tez.zero; counter; operation = Reveal public_key; - gas_limit = Gas.Arith.integral_of_int_exn 10_000; + gas_limit = default_high_gas_limit; storage_limit = Z.zero; } in @@ -243,21 +262,18 @@ let combine_operations ?public_key ?counter ?spurious_operation ~source ctxt integration tests. Instead, we went for the minimal interference path and left original behaviour as default. *) let manager_operation ?(force_reveal = true) ?counter ?(fee = Tez.zero) - ?gas_limit ?storage_limit ?public_key ~source ctxt operation = + ?(gas_limit = High) ?storage_limit ?public_key ~source ctxt operation = (match counter with | Some counter -> return counter | None -> Context.Contract.counter ctxt source) >>=? fun counter -> Context.get_constants ctxt >>=? fun c -> - let gas_limit = - let default = c.parametric.hard_gas_limit_per_operation in - Option.value ~default gas_limit - in let storage_limit = Option.value ~default:c.parametric.hard_storage_limit_per_operation storage_limit in + resolve_gas_limit ctxt gas_limit >>=? fun gas_limit -> Context.Contract.manager ctxt source >>=? fun account -> let public_key = Option.value ~default:account.pk public_key in let counter = Z.succ counter in @@ -288,7 +304,7 @@ let manager_operation ?(force_reveal = true) ?counter ?(fee = Tez.zero) fee = Tez.zero; counter; operation = Reveal public_key; - gas_limit = Gas.Arith.integral_of_int_exn 10_000; + gas_limit = default_high_gas_limit; storage_limit = Z.zero; } in @@ -305,8 +321,7 @@ let manager_operation ?(force_reveal = true) ?counter ?(fee = Tez.zero) in Contents_list (Cons (op_reveal, Single op)) -let revelation ?(fee = Tez.zero) - ?(gas_limit = Gas.Arith.integral_of_int_exn 10000) ?(storage_limit = Z.zero) +let revelation ?(fee = Tez.zero) ?(gas_limit = High) ?(storage_limit = Z.zero) ?counter ?(forge_pkh = None) ctxt public_key = (* If Some pkh is provided to ?forge_pkh we take that hash at face value, otherwise we honestly compute the hash from @@ -317,7 +332,7 @@ let revelation ?(fee = Tez.zero) | Some pkh -> pkh | None -> Signature.Public_key.hash public_key in - + resolve_gas_limit ctxt gas_limit >>=? fun gas_limit -> let source = Contract.Implicit pkh in (match counter with | None -> Context.Contract.counter ctxt source @@ -437,16 +452,11 @@ let transaction ?force_reveal ?counter ?fee ?gas_limit ?storage_limit let delegation ?force_reveal ?fee ?gas_limit ?counter ?storage_limit ctxt source dst = let top = Delegation dst in - let gas_limit = - match gas_limit with - | None -> Gas.Arith.integral_of_int_exn 1000 - | Some g -> g - in manager_operation ?force_reveal ?fee ?counter - ~gas_limit + ?gas_limit ?storage_limit ~source ctxt @@ -458,17 +468,12 @@ let delegation ?force_reveal ?fee ?gas_limit ?counter ?storage_limit ctxt source let set_deposits_limit ?force_reveal ?fee ?gas_limit ?storage_limit ?counter ctxt source limit = let top = Set_deposits_limit limit in - let gas_limit = - match gas_limit with - | None -> Gas.Arith.integral_of_int_exn 1000 - | Some g -> g - in manager_operation ?force_reveal ?fee ?counter ?storage_limit - ~gas_limit + ?gas_limit ~source ctxt top diff --git a/src/proto_alpha/lib_protocol/test/helpers/op.mli b/src/proto_alpha/lib_protocol/test/helpers/op.mli index 066c62a9f14ee7360b539a380e1c5919e9f1d900..df18aab209c118a35895d7e9594031a18076a5f1 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/op.mli +++ b/src/proto_alpha/lib_protocol/test/helpers/op.mli @@ -59,11 +59,21 @@ val miss_signed_endorsement : Context.t -> Kind.endorsement Operation.t tzresult Lwt.t +type gas_limit = + | Max (** Max corresponds to the [max_gas_limit_per_operation] constant. *) + | High + (** High corresponds to [50_000] gas unit which should cover a + majority of use-cases. This is the default used when forging + manager operations. *) + | Low (** Low corresponds to the gas entry cost of a manager operation *) + | Zero + | Custom_gas of Gas.Arith.integral + val transaction : ?force_reveal:bool -> ?counter:Z.t -> ?fee:Tez.tez -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:Z.t -> ?parameters:Script.lazy_expr -> ?entrypoint:Entrypoint.t -> @@ -74,22 +84,22 @@ val transaction : Operation.packed tzresult Lwt.t (** Same as [transaction], but with a more generic destination - parameter. It is said unsafe because it can construct transactions - that will always fail, such as + parameter. It is said unsafe because it can construct transactions + that will always fail, such as {ul {li Transaction to the deposit entrypoint of a transaction - rollup, as these transactions are necessarily internals.}} + rollup, as these transactions are necessarily internals.}} Optional arguments allow to override defaults: {ul {li [?force_reveal:bool]: prepend the operation to reveal - [source]'s public key if the latter has not been revealed - yet. Enabled (set to [true]) by default.}}*) + [source]'s public key if the latter has not been revealed + yet. Enabled (set to [true]) by default.}}*) val unsafe_transaction : ?force_reveal:bool -> ?counter:counter -> ?fee:Tez.t -> - ?gas_limit:Fixed_point_repr.integral_tag Gas.Arith.t -> + ?gas_limit:gas_limit -> ?storage_limit:counter -> ?parameters: Michelson_v1_primitives.prim Micheline.canonical Data_encoding.lazy_t -> @@ -103,7 +113,7 @@ val unsafe_transaction : val delegation : ?force_reveal:bool -> ?fee:Tez.tez -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?counter:Z.t -> ?storage_limit:Z.t -> Context.t -> @@ -114,7 +124,7 @@ val delegation : val set_deposits_limit : ?force_reveal:bool -> ?fee:Tez.tez -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:Z.t -> ?counter:Z.t -> Context.t -> @@ -142,7 +152,7 @@ val set_deposits_limit : *) val revelation : ?fee:Tez.t -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:counter -> ?counter:counter -> ?forge_pkh:public_key_hash option -> @@ -163,8 +173,8 @@ val failing_noop : Optional arguments allow to override defaults: {ul {li [?force_reveal:bool]: prepend the operation to reveal - [source]'s public key if the latter has not been revealed - yet. Enabled (set to [true]) by default.}}*) + [source]'s public key if the latter has not been revealed + yet. Enabled (set to [true]) by default.}}*) val contract_origination : ?force_reveal:bool -> ?counter:Z.t -> @@ -173,7 +183,7 @@ val contract_origination : ?public_key:public_key -> ?credit:Tez.tez -> ?fee:Tez.tez -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:Z.t -> Context.t -> Contract.t -> @@ -187,7 +197,7 @@ val contract_origination_hash : ?public_key:public_key -> ?credit:Tez.tez -> ?fee:Tez.tez -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:Z.t -> Context.t -> Contract.t -> @@ -200,7 +210,7 @@ val register_global_constant : ?counter:Z.t -> ?public_key:Signature.public_key -> ?fee:Tez.tez -> - ?gas_limit:Alpha_context.Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:Z.t -> Context.t -> (* Account doing the registration *) @@ -243,8 +253,8 @@ val combine_operations : packed_operation tzresult Lwt.t (** Batch a list of (already signed) operations and (re-)sign with the - [source]. No revelation is inserted and the counters are kept as - they are unless [recompute_counters] is set to [true] (defaults false). *) + [source]. No revelation is inserted and the counters are kept as + they are unless [recompute_counters] is set to [true] (defaults false). *) val batch_operations : ?recompute_counters:bool -> source:Contract.t -> @@ -285,7 +295,7 @@ val tx_rollup_origination : ?force_reveal:bool -> ?counter:Z.t -> ?fee:Tez.tez -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:Z.t -> Context.t -> Contract.t -> @@ -298,14 +308,14 @@ val tx_rollup_origination : Optional arguments allow to override defaults: {ul {li [?force_reveal:bool]: prepend the operation to reveal - [source]'s public key if the latter has not been revealed - yet. Enabled (set to [true]) by default.}}*) + [source]'s public key if the latter has not been revealed + yet. Enabled (set to [true]) by default.}}*) val tx_rollup_submit_batch : ?force_reveal:bool -> ?counter:Z.t -> ?fee:Tez.tez -> ?burn_limit:Tez.tez -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:Z.t -> Context.t -> Contract.t -> @@ -314,18 +324,18 @@ val tx_rollup_submit_batch : Operation.packed tzresult Lwt.t (** [tx_rollup_commit ctxt source tx_rollup commitment] Commits to a - tx. + tx. Optional arguments allow to override defaults: {ul {li [?force_reveal:bool]: prepend the operation to reveal - [source]'s public key if the latter has not been revealed - yet. Enabled (set to [true]) by default.}}*) + [source]'s public key if the latter has not been revealed + yet. Enabled (set to [true]) by default.}}*) val tx_rollup_commit : ?force_reveal:bool -> ?counter:Z.t -> ?fee:Tez.tez -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:Z.t -> Context.t -> Contract.t -> @@ -334,18 +344,18 @@ val tx_rollup_commit : Operation.packed tzresult Lwt.t (** [tx_rollup_return_bond ctxt source tx_rollup] returns a commitment - bond. + bond. Optional arguments allow to override defaults: {ul {li [?force_reveal:bool]: prepend the operation to reveal - [source]'s public key if the latter has not been revealed - yet. Enabled (set to [true]) by default.}}*) + [source]'s public key if the latter has not been revealed + yet. Enabled (set to [true]) by default.}}*) val tx_rollup_return_bond : ?force_reveal:bool -> ?counter:Z.t -> ?fee:Tez.tez -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:Z.t -> Context.t -> Contract.t -> @@ -353,18 +363,18 @@ val tx_rollup_return_bond : Operation.packed tzresult Lwt.t (** [tx_rollup_finalize ctxt source tx_rollup] finalizes the most - recent final level of a rollup. + recent final level of a rollup. Optional arguments allow to override defaults: {ul {li [?force_reveal:bool]: prepend the operation to reveal - [source]'s public key if the latter has not been revealed - yet. Enabled (set to [true]) by default.}}*) + [source]'s public key if the latter has not been revealed + yet. Enabled (set to [true]) by default.}}*) val tx_rollup_finalize : ?force_reveal:bool -> ?counter:Z.t -> ?fee:Tez.tez -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:Z.t -> Context.t -> Contract.t -> @@ -377,7 +387,7 @@ val tx_rollup_remove_commitment : ?force_reveal:bool -> ?counter:Z.t -> ?fee:Tez.tez -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:Z.t -> Context.t -> Contract.t -> @@ -385,21 +395,21 @@ val tx_rollup_remove_commitment : Operation.packed tzresult Lwt.t (** [tx_rollup_dispatch_tickets ctxt ~source ~message_index tx_rollup - level context_hash tickets_info] sends all tickets from - [tickets_info] to the appropriate implicit accounts, as authorized - by the [message_index]th hash of the commitment of [tx_rollup] - posted for [level]. + level context_hash tickets_info] sends all tickets from + [tickets_info] to the appropriate implicit accounts, as authorized + by the [message_index]th hash of the commitment of [tx_rollup] + posted for [level]. Optional arguments allow to override defaults: {ul {li [?force_reveal:bool]: prepend the operation to reveal - [source]'s public key if the latter has not been revealed - yet. Enabled (set to [true]) by default.}} *) + [source]'s public key if the latter has not been revealed + yet. Enabled (set to [true]) by default.}} *) val tx_rollup_dispatch_tickets : ?force_reveal:bool -> ?counter:counter -> ?fee:Tez.t -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:counter -> Context.t -> source:Contract.t -> @@ -433,13 +443,13 @@ val tx_rollup_dispatch_tickets : Optional arguments allow to override defaults: {ul {li [?force_reveal:bool]: prepend the operation to reveal - [source]'s public key if the latter has not been revealed - yet. Enabled (set to [true]) by default.}}*) + [source]'s public key if the latter has not been revealed + yet. Enabled (set to [true]) by default.}}*) val transfer_ticket : ?force_reveal:bool -> ?counter:counter -> ?fee:Tez.t -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:counter -> Context.t -> source:Contract.t -> @@ -452,18 +462,18 @@ val transfer_ticket : (packed_operation, tztrace) result Lwt.t (** [tx_rollup_reject ctxt source tx_rollup tx_rollup level message - index proof] Rejects a tx rollup commitment. + index proof] Rejects a tx rollup commitment. Optional arguments allow to override defaults: {ul {li [?force_reveal:bool]: prepend the operation to reveal - [source]'s public key if the latter has not been revealed - yet. Enabled (set to [true]) by default.}}*) + [source]'s public key if the latter has not been revealed + yet. Enabled (set to [true]) by default.}}*) val tx_rollup_reject : ?force_reveal:bool -> ?counter:Z.t -> ?fee:Tez.tez -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:Z.t -> Context.t -> Contract.t -> @@ -480,20 +490,20 @@ val tx_rollup_reject : Operation.packed tzresult Lwt.t (** [sc_rollup_origination ctxt source kind boot_sector] originates a - new smart contract rollup of some given [kind] booting using - [boot_sector]. The process is the same as in - [tx_rollup_origination]. + new smart contract rollup of some given [kind] booting using + [boot_sector]. The process is the same as in + [tx_rollup_origination]. Optional arguments allow to override defaults: {ul {li [?force_reveal:bool]: prepend the operation to reveal - [source]'s public key if the latter has not been revealed - yet. Enabled (set to [true]) by default.}}*) + [source]'s public key if the latter has not been revealed + yet. Enabled (set to [true]) by default.}}*) val sc_rollup_origination : ?force_reveal:bool -> ?counter:counter -> ?fee:Tez.t -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:counter -> Context.t -> Contract.t -> @@ -503,19 +513,19 @@ val sc_rollup_origination : (packed_operation * Sc_rollup.t) tzresult Lwt.t (** [sc_rollup_publish ctxt source rollup commitment] tries to publish - a commitment to the SCORU. Optional arguments allow to override - defaults: + a commitment to the SCORU. Optional arguments allow to override + defaults: Optional arguments allow to override defaults: {ul {li [?force_reveal:bool]: prepend the operation to reveal - [source]'s public key if the latter has not been revealed - yet. Enabled (set to [true]) by default.}} *) + [source]'s public key if the latter has not been revealed + yet. Enabled (set to [true]) by default.}} *) val sc_rollup_publish : ?force_reveal:bool -> ?counter:Z.t -> ?fee:Tez.tez -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:Z.t -> Context.t -> Contract.t -> @@ -524,18 +534,18 @@ val sc_rollup_publish : Operation.packed tzresult Lwt.t (** [sc_rollup_cement ctxt source rollup commitment] tries to cement - the specified commitment. + the specified commitment. Optional arguments allow to override defaults: {ul {li [?force_reveal:bool]: prepend the operation to reveal - [source]'s public key if the latter has not been revealed - yet. Enabled (set to [true]) by default.}}*) + [source]'s public key if the latter has not been revealed + yet. Enabled (set to [true]) by default.}}*) val sc_rollup_cement : ?force_reveal:bool -> ?counter:Z.t -> ?fee:Tez.tez -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:Z.t -> Context.t -> Contract.t -> @@ -546,7 +556,7 @@ val sc_rollup_cement : val sc_rollup_execute_outbox_message : ?counter:counter -> ?fee:Tez.t -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:counter -> ?force_reveal:bool -> Context.t -> @@ -563,7 +573,7 @@ val sc_rollup_execute_outbox_message : val sc_rollup_recover_bond : ?counter:Z.t -> ?fee:Tez.tez -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:Z.t -> ?force_reveal:bool -> Context.t -> @@ -575,7 +585,7 @@ val sc_rollup_add_messages : ?force_reveal:bool -> ?counter:Z.t -> ?fee:Tez.tez -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:Z.t -> Context.t -> Contract.t -> @@ -587,7 +597,7 @@ val sc_rollup_refute : ?force_reveal:bool -> ?counter:Z.t -> ?fee:Tez.tez -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:Z.t -> Context.t -> Contract.t -> @@ -601,7 +611,7 @@ val sc_rollup_timeout : ?force_reveal:bool -> ?counter:Z.t -> ?fee:Tez.tez -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:Z.t -> Context.t -> Contract.t -> @@ -613,7 +623,7 @@ val dal_publish_slot_header : ?force_reveal:bool -> ?counter:counter -> ?fee:Tez.t -> - ?gas_limit:Gas.Arith.integral -> + ?gas_limit:gas_limit -> ?storage_limit:counter -> Context.t -> Contract.t -> diff --git a/src/proto_alpha/lib_protocol/test/helpers/sapling_helpers.ml b/src/proto_alpha/lib_protocol/test/helpers/sapling_helpers.ml index 9deac42be4eecca5f9ffaaf0c143ab4e64677013..8742fd957b08cea01451a8dc43df614c5ef465ed 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/sapling_helpers.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/sapling_helpers.ml @@ -395,6 +395,7 @@ module Interpreter_helpers = struct in let fee = Test_tez.of_int 10 in Op.transaction + ~gas_limit:Max ~fee (B block) src diff --git a/src/proto_alpha/lib_protocol/test/helpers/transfers.ml b/src/proto_alpha/lib_protocol/test/helpers/transfers.ml index ac185cd069d3f1d57ef5a62148ab4487a68fb425..086e7d4530bf4481c2b7dddfb248e90687d42487 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/transfers.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/transfers.ml @@ -35,7 +35,7 @@ let transfer_and_check_balances ?(with_burn = false) ~loc b ?(fee = Tez.zero) let* bal_dst = Context.Contract.balance (I b) dst in let* op = Op.transaction - ~gas_limit:(Alpha_context.Gas.Arith.integral_of_int_exn 3000) + ~gas_limit:(Custom_gas (Alpha_context.Gas.Arith.integral_of_int_exn 3000)) (I b) ~fee src diff --git a/src/proto_alpha/lib_protocol/test/integration/gas/test_gas_levels.ml b/src/proto_alpha/lib_protocol/test/integration/gas/test_gas_levels.ml index 0f5d52e56ce72fdf3996ac352c7c419e6a80a1c9..568a88ba29551f45e5c0f6ee065d1ffc95103529 100644 --- a/src/proto_alpha/lib_protocol/test/integration/gas/test_gas_levels.ml +++ b/src/proto_alpha/lib_protocol/test/integration/gas/test_gas_levels.ml @@ -310,7 +310,12 @@ let combine_operations_with_gas ?counter block src list_dst = let rec make_op_list full_gas op_list = function | [] -> return (full_gas, List.rev op_list) | (dst, gas_limit) :: t -> - Op.transaction ~gas_limit (B block) src dst Alpha_context.Tez.zero + Op.transaction + ~gas_limit:(Custom_gas gas_limit) + (B block) + src + dst + Alpha_context.Tez.zero >>=? fun op -> make_op_list (Alpha_context.Gas.Arith.add full_gas gas_limit) @@ -344,7 +349,9 @@ let bake_operations_with_gas ?counter block src list_list_dst = return (block, consumed_gas, gas_limit_total) let basic_gas_sampler () = - Alpha_context.Gas.Arith.integral_of_int_exn (100 + Random.int 900) + Alpha_context.Gas.Arith.integral_of_int_exn + (Michelson_v1_gas.Internal_for_tests.int_cost_of_manager_operation + 100 + + Random.int 900) let generic_test_block_one_origination contract gas_sampler structure = block_with_one_origination contract >>=? fun (block, src, dst) -> @@ -436,6 +443,40 @@ let test_block_mixed_operations () = >>=? fun (_block, consumed_gas, gas_limit_total) -> check_consumed_gas consumed_gas gas_limit_total +(** Test that emptying an account costs gas *) +let test_emptying_account_gas () = + let open Alpha_context in + Context.init1 ~consensus_threshold:0 () >>=? fun (b, bootstrap) -> + let {Account.pkh; pk; _} = Account.new_account () in + let {Account.pkh = pkh'; _} = Account.new_account () in + let contract = Contract.Implicit pkh in + let amount = Test_tez.of_int 10 in + Op.transaction (B b) bootstrap contract amount >>=? fun op1 -> + Block.bake ~operation:op1 b >>=? fun b -> + Op.revelation ~fee:Tez.zero (B b) pk >>=? fun op2 -> + Block.bake ~operation:op2 b >>=? fun b -> + let gas_limit = + Op.Custom_gas + (Gas.Arith.integral_of_int_exn + Michelson_v1_gas.Internal_for_tests.int_cost_of_manager_operation) + in + Op.delegation ~fee:amount ~gas_limit (B b) contract (Some pkh') >>=? fun op -> + Incremental.begin_construction b >>=? fun i -> + (* The delegation operation should not be valid as the operation + effect would be to remove [contract] from the ledger and this + generates an extra gas cost. + + This semantics is not expected: see + https://gitlab.com/tezos/tezos/-/issues/3188 *) + Incremental.add_operation + ~expect_failure:(function + | [Environment.Ecoproto_error Raw_context.Operation_quota_exceeded] -> + return_unit + | _err -> assert false) + i + op + >>=? fun _i -> return_unit + let quick (what, how) = Tztest.tztest what `Quick how let tests = @@ -468,6 +509,7 @@ let tests = test_malformed_block_max_limit_reached' ); ( "Test the gas consumption of various operations", test_block_mixed_operations ); + ("Test that emptying an account costs gas", test_emptying_account_gas); ] @ make_batch_test_block_one_origination "nil" nil_contract basic_gas_sampler @ make_batch_test_block_one_origination diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_sapling.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_sapling.ml index c6d9669667fede5842808ae032f565416bac4f9d..312d4b8eaaa8a98cdc5689912bf893559629bc6e 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_sapling.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_sapling.ml @@ -726,7 +726,7 @@ module Interpreter_tests = struct Incremental.begin_construction b >>=? fun incr -> let fee = Test_tez.of_int 10 in let dst = Alpha_context.Contract.Originated dst in - Op.transaction ~fee (B b) src0 dst Tez.zero ~parameters + Op.transaction ~gas_limit:Max ~fee (B b) src0 dst Tez.zero ~parameters >>=? fun operation -> Incremental.add_operation (* TODO make more precise *) ~expect_apply_failure:(fun _ -> return_unit) @@ -761,7 +761,7 @@ module Interpreter_tests = struct in Incremental.begin_construction b >>=? fun incr -> let fee = Test_tez.of_int 10 in - Op.transaction ~fee (B b) src0 dst Tez.zero ~parameters + Op.transaction ~gas_limit:Max ~fee (B b) src0 dst Tez.zero ~parameters >>=? fun operation -> Incremental.add_operation (* TODO make more precise *) ~expect_apply_failure:(fun _ -> return_unit) @@ -911,6 +911,7 @@ module Interpreter_tests = struct let fee = Test_tez.of_int 10 in Tez.one_mutez *? Int64.of_int 15 >>?= fun amount_tez -> Op.transaction + ~gas_limit:Max ~fee (B block_start) src @@ -925,6 +926,7 @@ module Interpreter_tests = struct let pkh = Context.Contract.pkh src in Alpha_context.Contract.get_counter ctx pkh >>= wrap >>=? fun counter -> Op.transaction + ~gas_limit:Max ~counter ~fee (B block_start) @@ -1006,7 +1008,14 @@ module Interpreter_tests = struct in let parameters = parameters_of_list list_transac in let dst = Contract.Originated dst in - Op.transaction ~fee:(Test_tez.of_int 10) (B b) src dst Tez.zero ~parameters + Op.transaction + ~gas_limit:Max + ~fee:(Test_tez.of_int 10) + (B b) + src + dst + Tez.zero + ~parameters >>=? fun operation -> next_block b operation >>=? fun _b -> return_unit @@ -1046,10 +1055,24 @@ module Interpreter_tests = struct in let fee = Test_tez.of_int 10 in let dst = Contract.Originated dst in - Op.transaction ~fee (B b) src dst Tez.zero ~parameters:parameters_1 + Op.transaction + ~gas_limit:Max + ~fee + (B b) + src + dst + Tez.zero + ~parameters:parameters_1 >>=? fun operation -> next_block b operation >>=? fun b -> - Op.transaction ~fee (B b) src dst Tez.zero ~parameters:parameters_2 + Op.transaction + ~gas_limit:Max + ~fee + (B b) + src + dst + Tez.zero + ~parameters:parameters_2 >>=? fun operation -> next_block b operation >>=? fun b -> Incremental.begin_construction b >>=? fun incr -> @@ -1118,7 +1141,8 @@ module Interpreter_tests = struct in let fee = Test_tez.of_int 10 in let dst = Contract.Originated dst in - Op.transaction ~fee (B b) src dst Tez.zero ~parameters >>=? fun operation -> + Op.transaction ~gas_limit:Max ~fee (B b) src dst Tez.zero ~parameters + >>=? fun operation -> next_block b operation >>=? fun b -> let contract = "0x" ^ to_hex dst Alpha_context.Contract.encoding in let hex_transac_2 = hex_shield ~memo_size:8 w anti_replay_2 in @@ -1127,7 +1151,7 @@ module Interpreter_tests = struct Alpha_context.Script.(lazy_expr (Expr.from_string string)) in let dst_2 = Contract.Originated dst_2 in - Op.transaction ~fee (B b) src dst_2 Tez.zero ~parameters + Op.transaction ~gas_limit:Max ~fee (B b) src dst_2 Tez.zero ~parameters >>=? fun operation -> next_block b operation >>=? fun _b -> return_unit end diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_balance.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_balance.ml index af27dd965232668d76315e4229f0faa19f27e7e5..f3d74a420ebbff1cbbdcf56e6b903a1e989b5be9 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_balance.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_balance.ml @@ -53,6 +53,7 @@ let transaction block ~baker ~sender ~entrypoint ~recipient ~parameters = let* operation = Op.transaction (B block) + ~gas_limit:Max ~entrypoint ~parameters ~fee:Tez.one diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_manager.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_manager.ml index 59792cdbb07dbd7ce9be3565b2cafbe750efc54c..6fb79efb53f620e37f05672791fd399f0f28c638 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_manager.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_manager.ml @@ -117,6 +117,7 @@ let transaction block ~sender ~recipient ~amount ~parameters = let* operation = Op.transaction (I block) + ~gas_limit:Max ~entrypoint:Entrypoint.default ~parameters ~fee:Tez.zero diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/manager_operation_helpers.ml b/src/proto_alpha/lib_protocol/test/integration/operations/manager_operation_helpers.ml index 3038d9a50d680da9123dbc5f75f6d45ce85ace57..2b20bee48b5fbadd34ca7ae05f63cb9f9ba73ac1 100644 --- a/src/proto_alpha/lib_protocol/test/integration/operations/manager_operation_helpers.ml +++ b/src/proto_alpha/lib_protocol/test/integration/operations/manager_operation_helpers.ml @@ -60,7 +60,7 @@ let init_context ?hard_gas_limit_per_block () = in (* Set a gas_limit to avoid the default gas_limit of the helpers ([hard_gas_limit_per_operation]) *) - let gas_limit = Gas.Arith.integral_of_int_exn 10_000 in + let gas_limit = Op.Custom_gas (Gas.Arith.integral_of_int_exn 10_000) in (* Create and fund an account use for originate a Tx and a Sc rollup *) let rollup_account = Account.new_account () in diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/test_batched_manager_operation_precheck.ml b/src/proto_alpha/lib_protocol/test/integration/operations/test_batched_manager_operation_precheck.ml index c4e73a3e2f0588ab34953d1c3b4edeee0852bb7d..d2acfd9f11ccf6b5eb395431a55a03d124374da3 100644 --- a/src/proto_alpha/lib_protocol/test/integration/operations/test_batched_manager_operation_precheck.ml +++ b/src/proto_alpha/lib_protocol/test/integration/operations/test_batched_manager_operation_precheck.ml @@ -318,11 +318,23 @@ let test_batch_exceeding_block_gas ~mempool_mode kind1 kind2 () = let* reveal = mk_reveal ~counter ~source infos in let counter = Z.succ counter in let operation gas_limit = - select_op ~gas_limit ~counter ~force_reveal:false ~source kind1 infos + select_op + ~gas_limit:(Custom_gas gas_limit) + ~counter + ~force_reveal:false + ~source + kind1 + infos in let counter = Z.succ counter in let operation2 gas_limit = - select_op ~gas_limit ~counter ~force_reveal:false ~source kind2 infos + select_op + ~gas_limit:(Custom_gas gas_limit) + ~counter + ~force_reveal:false + ~source + kind2 + infos in let* op_case1 = operation g_limit in let* op2_case1 = operation2 Gas.Arith.zero in diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/test_combined_operations.ml b/src/proto_alpha/lib_protocol/test/integration/operations/test_combined_operations.ml index b36db3359d24b4cb15851b274dc72916c526fe0b..71baae6762925c9837172e59b99180efd6b0470d 100644 --- a/src/proto_alpha/lib_protocol/test/integration/operations/test_combined_operations.ml +++ b/src/proto_alpha/lib_protocol/test/integration/operations/test_combined_operations.ml @@ -48,7 +48,7 @@ open Alpha_context let ten_tez = Test_tez.of_int 10 -let gas_limit = Alpha_context.Gas.Arith.integral_of_int_exn 3000 +let gas_limit = Op.Custom_gas (Alpha_context.Gas.Arith.integral_of_int_exn 3000) (** Groups ten transactions between the same parties. *) let test_multiple_transfers () = diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/test_manager_operation_precheck.ml b/src/proto_alpha/lib_protocol/test/integration/operations/test_manager_operation_precheck.ml index aa5e863073c35d15271b006296ce224697e8edf9..f13c4796e8903cbc0e10cfd9aa3fd14de3d626e7 100644 --- a/src/proto_alpha/lib_protocol/test/integration/operations/test_manager_operation_precheck.ml +++ b/src/proto_alpha/lib_protocol/test/integration/operations/test_manager_operation_precheck.ml @@ -126,7 +126,7 @@ let low_gas_limit_diagnostic (infos : infos) op = let test_low_gas_limit kind () = let open Lwt_result_syntax in let* infos = init_context () in - let gas_limit = Gas.Arith.zero in + let gas_limit = Op.Low in let* op = select_op ~gas_limit ~force_reveal:true ~source:infos.contract1 kind infos in @@ -154,7 +154,7 @@ let high_gas_limit_diagnostic (infos : infos) op = let test_high_gas_limit kind () = let open Lwt_result_syntax in let* infos = init_context () in - let gas_limit = Gas.Arith.integral_of_int_exn 10_000_000 in + let gas_limit = Op.Custom_gas (Gas.Arith.integral_of_int_exn 10_000_000) in let* op = select_op ~gas_limit ~force_reveal:true ~source:infos.contract1 kind infos in @@ -391,7 +391,9 @@ let exceeding_block_gas_diagnostic ~mempool_mode (infos : infos) op = let test_exceeding_block_gas ~mempool_mode kind () = let open Lwt_result_syntax in let* infos = init_context ~hard_gas_limit_per_block:gb_limit () in - let gas_limit = Gas.Arith.add gb_limit Gas.Arith.(integral_of_int_exn 1) in + let gas_limit = + Op.Custom_gas (Gas.Arith.add gb_limit Gas.Arith.(integral_of_int_exn 1)) + in let* operation = select_op ~force_reveal:true ~source:infos.contract1 ~gas_limit kind infos in diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/test_reveal.ml b/src/proto_alpha/lib_protocol/test/integration/operations/test_reveal.ml index ee3b1c24183e58b653806625babf4ad15ed2892d..b2baee4da48e60ba3fb60b1da8bc881e5a25ba7d 100644 --- a/src/proto_alpha/lib_protocol/test/integration/operations/test_reveal.ml +++ b/src/proto_alpha/lib_protocol/test/integration/operations/test_reveal.ml @@ -407,7 +407,14 @@ let test_already_revealed_manager_in_batch () = With !5182 we have fixed this situation by revealing the manager contract at application time. The following test isolates the failing reveal and asserts that the manager is not revealed after - the failing op. *) + the failing op. + + As of !5506, the reveal operation does not pass precheck + anyway. Unfortunately, this means that this test has lost some of + its original purpose. Fortunately, {!test_empty_account_on_reveal} + offers a similar scenario to what this test was supposed to do: a + reveal fails during application and we check that the contract is + not revealed afterward. *) let test_no_reveal_when_gas_exhausted () = Context.init1 ~consensus_threshold:0 () >>=? fun (blk, c) -> let new_c = Account.new_account () in @@ -423,17 +430,19 @@ let test_no_reveal_when_gas_exhausted () = | false -> ()) >>=? fun () -> (* We craft a new (bad) reveal operation with a 0 gas_limit *) - Op.revelation ~fee:Tez.zero ~gas_limit:Gas.Arith.zero (B blk) new_c.pk - >>=? fun op -> + Op.revelation ~fee:Tez.zero ~gas_limit:Zero (B blk) new_c.pk >>=? fun op -> Incremental.begin_construction blk >>=? fun inc -> (* The application of this operation is expected to fail with a {! Protocol.Raw_context.Operation_quota_exceeded} error *) - let expect_apply_failure = function - | [Environment.Ecoproto_error Raw_context.Operation_quota_exceeded] -> + let expect_failure = function + | [ + Environment.Ecoproto_error Apply.Insufficient_gas_for_manager; + Environment.Ecoproto_error Raw_context.Operation_quota_exceeded; + ] -> return_unit | _ -> assert false in - Incremental.add_operation ~expect_apply_failure inc op >>=? fun inc -> + Incremental.add_operation ~expect_failure inc op >>=? fun inc -> (* We assert the manager key is still unrevealed, as the operation has failed *) Context.Contract.is_manager_key_revealed (I inc) new_contract >>=? fun revelead -> @@ -555,7 +564,7 @@ let test_valid_reveal_after_gas_exhausted_one () = >>=? fun () -> Incremental.begin_construction blk >>=? fun inc -> (* We first craft a (bad) reveal operation with a 0 gas_limit *) - Op.revelation ~fee:Tez.zero ~gas_limit:Gas.Arith.zero (B blk) new_c.pk + Op.revelation ~fee:Tez.zero ~gas_limit:Zero (B blk) new_c.pk >>=? fun bad_reveal -> (* While the second is a valid one *) Op.revelation ~fee:Tez.zero (I inc) new_c.pk >>=? fun good_reveal -> diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml b/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml index cdf741070779abb34c716a5a79f22858fc9bca0f..0917d6acebba04cd59a33ec29303500fe5762993 100644 --- a/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml +++ b/src/proto_alpha/lib_protocol/test/integration/operations/test_tx_rollup.ml @@ -930,11 +930,10 @@ let fill_inbox b tx_rollup contract contents k = Context.Contract.counter (B b) contract >>=? fun counter -> Incremental.begin_construction b >>=? fun i -> let rec fill_inbox i inbox_size counter = - (* By default, the [gas_limit] is the maximum gas that can be - consumed by an operation. We set a lower (arbitrary) limit to - be able to reach the size limit of an operation. *) + (* We set an arbitrary gas limit to be able to reach the size + limit of an operation. *) Op.tx_rollup_submit_batch - ~gas_limit:(Gas.Arith.integral_of_int_exn 20_000) + ~gas_limit:(Custom_gas (Gas.Arith.integral_of_int_exn 20_000)) ~counter (I i) contract @@ -990,7 +989,7 @@ let test_inbox_count_too_big () = consumed by an operation. We set a lower (arbitrary) limit to be able to reach the size limit of an operation. *) Op.tx_rollup_submit_batch - ~gas_limit:(Gas.Arith.integral_of_int_exn 3_500) + ~gas_limit:(Custom_gas (Gas.Arith.integral_of_int_exn 3_500)) ~counter (I i) contract @@ -1005,7 +1004,7 @@ let test_inbox_count_too_big () = Context.Contract.counter (B b) contract >>=? fun counter -> fill_inbox i counter message_count >>=? fun (i, counter) -> Op.tx_rollup_submit_batch - ~gas_limit:(Gas.Arith.integral_of_int_exn 2_500) + ~gas_limit:(Custom_gas (Gas.Arith.integral_of_int_exn 2_500)) ~counter (I i) contract @@ -2510,6 +2509,7 @@ module Rejection = struct tx_rollup level message + ~gas_limit:Max ~message_position ~message_path ~message_result_hash @@ -3484,7 +3484,7 @@ module Rejection = struct let message0, _ = Tx_rollup_message.make_batch "xoxo" in let message0_hash = Tx_rollup_message_hash.hash_uncarbonated message0 in Op.tx_rollup_submit_batch - ~gas_limit:(Gas.Arith.integral_of_int_exn 2_500) + ~gas_limit:(Custom_gas (Gas.Arith.integral_of_int_exn 2_500)) (I i) account tx_rollup diff --git a/tezt/lib_tezos/constant.ml b/tezt/lib_tezos/constant.ml index b543a289ae3f1e62c558f22cd8091616d5a55632..42c55d9d9700294821a86dc33aee4710b3233cc2 100644 --- a/tezt/lib_tezos/constant.ml +++ b/tezt/lib_tezos/constant.ml @@ -78,6 +78,10 @@ let implicit_account_burn = (** The default time to live of an operation (in block) *) let max_op_ttl = 120 +(** Constant gas cost required for every manager operation. Should + match [Michelson_v1_gas.Cost_of.manager_operation]. *) +let manager_operation_gas_cost = 1000 + (** A valid base58 encoded layer-2 address to be used to test transaction rollups. *) let tx_rollup_l2_address = "tz4MSfZsn6kMDczShy8PMeB628TNukn9hi2K" diff --git a/tezt/tests/baking.ml b/tezt/tests/baking.ml index 1e4fe630d71aa979b697479e9a0a86b60ec9050b..d1e69d88341cda829f0e1f4d8c711cf33eed559c 100644 --- a/tezt/tests/baking.ml +++ b/tezt/tests/baking.ml @@ -681,7 +681,14 @@ let baking_operation_exception = Operation.Manager.( inject [ - make ~source:new_account ~fee:9_000_000 + make + ~source:new_account + ~fee:9_000_000 + (* Emptying an account costs gas: we add 400 to the + minimal manager operation gas cost to cover this + possibility. See issue + https://gitlab.com/tezos/tezos/-/issues/3188 *) + ~gas_limit:(Constant.manager_operation_gas_cost + 400) @@ delegation ~delegate:new_account (); ] client) diff --git a/tezt/tests/manager_operations.ml b/tezt/tests/manager_operations.ml index ee0fe982e0fba7dfea6a15acdc063e1166491fa8..337fb427c88a36d75e76894e4d3e86fe395311fa 100644 --- a/tezt/tests/manager_operations.ml +++ b/tezt/tests/manager_operations.ml @@ -907,16 +907,19 @@ module Deserialisation = struct in unit - let test_not_enough_gas_deserialization = + let test_not_enough_gas_deserialization ~supports ~manager_operation_cost = Protocol.register_test ~__FILE__ ~title:"Contract call with not enough gas to deserialize argument" + ~supports ~tags:["precheck"; "gas"; "deserialization"] @@ fun protocol -> let* nodes = Helpers.init ~protocol () in let* contract = originate_noop_contract nodes.main in let size_kB = 20 in - let min_deserialization_gas = deserialization_gas ~size_kB in + let min_deserialization_gas = + manager_operation_cost + deserialization_gas ~size_kB + in let* _ = Memchecks.with_refused_checks ~__LOC__ nodes @@ fun () -> inject_call_with_bytes @@ -928,6 +931,16 @@ module Deserialisation = struct in unit + let test_not_enough_gas_deserialization protocols = + test_not_enough_gas_deserialization + ~supports:(Protocol.Until_protocol 13) + ~manager_operation_cost:0 + protocols ; + test_not_enough_gas_deserialization + ~supports:(Protocol.From_protocol 14) + ~manager_operation_cost:Constant.manager_operation_gas_cost + protocols + let test_deserialization_gas_accounting = Protocol.register_test ~__FILE__ @@ -1402,20 +1415,16 @@ module Simple_transfers = struct Constant.bootstrap2 ~revealed:true - let test_simple_transfer_not_enough_gas = + let test_simple_transfer_not_enough_gas ~supports decide_error = Protocol.register_test ~__FILE__ ~title:"Simple transfer with not enough gas" ~tags:["transaction"; "transfer"] + ~supports @@ fun protocol -> let* nodes = Helpers.init ~protocol () in let* _ = - Memchecks.with_applied_checks - ~__LOC__ - nodes - ~expected_statuses:["failed"] - ~expected_errors:[["gas_exhausted.operation"]] - @@ fun () -> + decide_error nodes @@ fun () -> Operation.inject_transfer ~protocol ~source:Constant.bootstrap2 @@ -1428,6 +1437,22 @@ module Simple_transfers = struct in unit + let test_simple_transfer_not_enough_gas protocols = + test_simple_transfer_not_enough_gas + ~supports:(Protocol.From_protocol 14) + (fun nodes -> Memchecks.with_refused_checks ~__LOC__ nodes) + protocols ; + test_simple_transfer_not_enough_gas + ~supports:(Protocol.Until_protocol 13) + (fun nodes f -> + Memchecks.with_applied_checks + ~__LOC__ + nodes + ~expected_statuses:["failed"] + ~expected_errors:[["gas_exhausted.operation"]] + f) + protocols + (* FIXME: https://gitlab.com/tezos/tezos/-/issues/2077 Once this issue is fixed change the test to check that the operation is refused and not propagated. diff --git a/tezt/tests/replace_by_fees.ml b/tezt/tests/replace_by_fees.ml index 6dc223d91be93922094a0c38ad8fd8832568428d..b05367efc173ade72bd4ec44b0058998a8b8d1bb 100644 --- a/tezt/tests/replace_by_fees.ml +++ b/tezt/tests/replace_by_fees.ml @@ -106,7 +106,7 @@ let default_fee = 1000 let replacement_fee = minimal_replacement_fee default_fee (* Default gas limit used in the tests of this module *) -let default_gas = 1000 +let default_gas = 1000 + Constant.manager_operation_gas_cost (* Default transferred amount used in the tests of this module *) let default_amount = 1 @@ -411,15 +411,14 @@ let replace_simple_op_with_a_batched_low_fees = ~postcheck2:(fun nodes h1 _h2 -> op_is_applied ~__LOC__ nodes h1) () -(* Sum of fees of the second operation is ok, ans gas is ok in the whole batch. - So, replacement is ok. *) +(* Sum of fees of the second operation is ok, and gas is ok in the + whole batch. So, replacement is ok. *) let replace_simple_op_with_a_batched = replacement_test_helper ~__LOC__ ~title:"2nd operation's gas limit is constant. Replacement possible." - ~op1:default_op - ~op2: - {default_op with gas = default_gas / 2; fee = (replacement_fee / 2) + 1} + ~op1:{default_op with gas = default_gas * 2} + ~op2:{default_op with gas = default_gas; fee = (replacement_fee / 2) + 1} ~size2:2 ~incheck1:check_applied ~incheck2:check_applied