From 7994d19692183e690980dfef76ddc4cfaeddab7c Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Mon, 23 May 2022 18:56:50 +0200 Subject: [PATCH 1/8] Proto/apply: do not reuse gas consumed by precheck in apply Co-authored-by: Diane Gallois-Wong [Precheck] no longer returns the gas it consumed. Instead, [apply] should consume all the gas again: that's why we now set [consume_deserialization_gas] to [Always] when applying an external manager operation. Similarly, when applying a [Tx_rollup_submit_batch], [hash_cost message_size] consumed in [precheck] is now also consumed in [apply]. This refactoring makes [precheck] and [apply] less interdependent, as a first step toward making [precheck] into a [validate_operation] function that covers any kind of operation and is called directly from [Main] (cf %Pipelining). --- docs/protocols/alpha.rst | 4 + src/proto_alpha/lib_protocol/apply.ml | 99 ++++++------------- src/proto_alpha/lib_protocol/apply_results.ml | 7 +- .../lib_protocol/apply_results.mli | 7 +- 4 files changed, 38 insertions(+), 79 deletions(-) diff --git a/docs/protocols/alpha.rst b/docs/protocols/alpha.rst index c24900574fef..e2da7e0ea8cd 100644 --- a/docs/protocols/alpha.rst +++ b/docs/protocols/alpha.rst @@ -65,3 +65,7 @@ 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`) diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index fba134a20eb1..33a315d9b14d 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -1108,8 +1108,7 @@ let apply_origination ~ctxt ~storage_type ~storage ~unparsed_code *) -let prepare_apply_manager_operation_content ~ctxt ~source - ~gas_consumed_in_precheck = +let prepare_apply_manager_operation_content ~ctxt ~source = let before_operation = (* This context is not used for backtracking. Only to compute gas consumption and originations for the operation result. *) @@ -1117,14 +1116,7 @@ let prepare_apply_manager_operation_content ~ctxt ~source 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) + return (ctxt, before_operation) let apply_internal_manager_operation_content : type kind. @@ -1140,11 +1132,9 @@ let apply_internal_manager_operation_content : 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) -> + prepare_apply_manager_operation_content ~ctxt ~source + >>=? fun (ctxt, before_operation) -> + let consume_deserialization_gas = Script.When_needed in match operation with | Transaction_to_contract { @@ -1236,7 +1226,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 +1233,19 @@ 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 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) -> + prepare_apply_manager_operation_content ~ctxt ~source:source_contract + >>=? fun (ctxt, before_operation) -> + 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 @@ -1560,6 +1555,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) -> @@ -1912,7 +1909,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,7 +1933,6 @@ 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 Fees.check_storage_limit ctxt ~storage_limit >>?= fun () -> let source_contract = Contract.Implicit source in Contract.must_be_allocated ctxt source_contract >>=? fun () -> @@ -1952,8 +1948,7 @@ let precheck_manager_contents (type kind) ctxt (op : kind Kind.manager contents) 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]. *) + cost or if deserialization fails. *) ( Script.force_decode_in_context ~consume_deserialization_gas ctxt @@ -2075,9 +2070,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 +2280,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 +2303,6 @@ let apply_manager_contents (type kind) ctxt mode chain_id ctxt mode ~source - ~gas_consumed_in_precheck ~chain_id ~fee operation @@ -2379,10 +2370,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 +2379,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 +2429,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 +2509,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 +2518,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_results.ml b/src/proto_alpha/lib_protocol/apply_results.ml index 59039dcfbaff..e24da912fc8e 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 8bdf1ea66bc5..009fbdbbc340 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 = -- GitLab From 5d12ba15b8f95a690f9e849f44e6f6502338afa2 Mon Sep 17 00:00:00 2001 From: Diane Gallois-Wong Date: Wed, 8 Jun 2022 10:36:15 +0200 Subject: [PATCH 2/8] Proto/apply: remove prepare_apply_manager_operation_content Various changes have resulted in [prepare_apply_manager_operation_content] factorizing very little code, and making the beginning of [apply_external_manager_operation_content] and [apply_internal_manager_operation_content] needlessly complicated. We remove it and inline its content instead. --- src/proto_alpha/lib_protocol/apply.ml | 28 +++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index 33a315d9b14d..b19d80c24fd6 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -1108,16 +1108,6 @@ let apply_origination ~ctxt ~storage_type ~storage ~unparsed_code *) -let prepare_apply_manager_operation_content ~ctxt ~source = - 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 -> - return (ctxt, before_operation) - let apply_internal_manager_operation_content : type kind. context -> @@ -1132,8 +1122,13 @@ let apply_internal_manager_operation_content : tzresult Lwt.t = fun ctxt mode ~payer ~source ~chain_id operation -> - prepare_apply_manager_operation_content ~ctxt ~source - >>=? fun (ctxt, before_operation) -> + 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 -> let consume_deserialization_gas = Script.When_needed in match operation with | Transaction_to_contract @@ -1234,9 +1229,14 @@ let apply_external_manager_operation_content : tzresult Lwt.t = fun ctxt mode ~source ~chain_id ~fee operation -> + let before_operation = + (* This context is not used for backtracking, only to compute gas + consumption and originations for the operation result. *) + ctxt + in let source_contract = Contract.Implicit source in - prepare_apply_manager_operation_content ~ctxt ~source:source_contract - >>=? fun (ctxt, before_operation) -> + Contract.must_exist ctxt source_contract >>=? fun () -> + Gas.consume ctxt Michelson_v1_gas.Cost_of.manager_operation >>?= fun ctxt -> 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 -- GitLab From 18fd267fad6a1485b6cc26330b925bd926cf236a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Delbianco?= Date: Thu, 9 Jun 2022 13:58:47 +0200 Subject: [PATCH 3/8] Proto/apply: remove identity let binding Remove "let before_operation = ctxt". Instead, use directly the function argument, and give a clearer name. --- src/proto_alpha/lib_protocol/apply.ml | 94 ++++++++++++++------------- 1 file changed, 49 insertions(+), 45 deletions(-) diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index b19d80c24fd6..d60f6ec8d69e 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -1121,14 +1121,14 @@ let apply_internal_manager_operation_content : * Script_typed_ir.packed_internal_operation list) tzresult Lwt.t = - fun ctxt mode ~payer ~source ~chain_id operation -> - 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 -> + 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 @@ -1148,7 +1148,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 @@ -1170,7 +1170,7 @@ let apply_internal_manager_operation_content : ~contract_hash ~amount ~entrypoint - ~before_operation + ~before_operation:ctxt_before_op ~payer ~chain_id ~mode @@ -1185,7 +1185,7 @@ let apply_internal_manager_operation_content : ~parameters ~payer ~dst_rollup:destination - ~since:before_operation + ~since:ctxt_before_op | Origination { origination = {delegate; script; credit}; @@ -1207,11 +1207,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) @@ -1228,15 +1228,15 @@ let apply_external_manager_operation_content : * Script_typed_ir.packed_internal_operation list) tzresult Lwt.t = - fun ctxt mode ~source ~chain_id ~fee operation -> - let before_operation = - (* This context is not used for backtracking, only to compute gas - consumption and originations for the operation result. *) - ctxt - in + fun ctxt_before_op mode ~source ~chain_id ~fee operation -> let source_contract = Contract.Implicit source in - Contract.must_exist ctxt source_contract >>=? fun () -> - Gas.consume ctxt Michelson_v1_gas.Cost_of.manager_operation >>?= fun ctxt -> + 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 @@ -1270,7 +1270,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} -> @@ -1286,7 +1286,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} @@ -1302,7 +1302,7 @@ let apply_external_manager_operation_content : ~contract_hash ~amount ~entrypoint - ~before_operation + ~before_operation:ctxt_before_op ~payer:source ~chain_id ~mode @@ -1396,7 +1396,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 @@ -1432,7 +1432,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 @@ -1476,11 +1476,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} -> @@ -1509,7 +1513,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; } @@ -1540,14 +1544,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 = []; } @@ -1568,7 +1572,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; } @@ -1610,7 +1614,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 @@ -1629,7 +1633,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 @@ -1642,7 +1646,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; } @@ -1656,7 +1660,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; } @@ -1762,20 +1766,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 = []} @@ -1784,19 +1788,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} @@ -1817,7 +1821,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 @@ -1827,7 +1831,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 @@ -1857,7 +1861,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 -- GitLab From 143d05b31c5e724833929478d4a48874e00e00ce Mon Sep 17 00:00:00 2001 From: Diane Gallois-Wong Date: Wed, 8 Jun 2022 11:06:36 +0200 Subject: [PATCH 4/8] Proto: do not decode scripts in precheck 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). This is a semantic change: if the deserialization fails, the operation will now pass precheck but its application will fail. This means that the operation may be included in a block, in which case the fees will be taken but the operation will have no further effects. --- docs/protocols/alpha.rst | 10 +++ src/proto_alpha/lib_protocol/alpha_context.ml | 4 + .../lib_protocol/alpha_context.mli | 12 +++ src/proto_alpha/lib_protocol/apply.ml | 73 ++++++------------- 4 files changed, 50 insertions(+), 49 deletions(-) diff --git a/docs/protocols/alpha.rst b/docs/protocols/alpha.rst index e2da7e0ea8cd..52ac34e3165d 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 ----------- @@ -69,3 +74,8 @@ Internal - 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 2acb7c5fc8bf..86775bd3fb12 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 079e751a7ad9..70ff62e9a81d 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 d60f6ec8d69e..de062d47d171 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -1941,43 +1941,28 @@ let precheck_manager_contents (type kind) ctxt (op : kind Kind.manager contents) 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. *) - ( 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 @@ -1997,12 +1982,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. @@ -2023,18 +2004,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; _} -> -- GitLab From 34ce7a6e5ae282292ffb9e8419a7bad334e71e1d Mon Sep 17 00:00:00 2001 From: Diane Gallois-Wong Date: Thu, 2 Jun 2022 10:50:13 +0200 Subject: [PATCH 5/8] Proto: consume constant cost of manager operation in precheck Co-authored-by: Albin Coquereau This gas consumption should have been part of precheck from the beginning. This makes some operations that used to fail in apply for lack of gas, to fail in precheck instead (with the same Operation_quota_exceeded error). Update some tests accordingly: - In test_reveal.ml, test_no_reveal_when_exhausted was expected to fail in apply for lack of gas, so we replace expect_apply_failure with expect_failure. - In test_delegation.ml, test_self_delegation_emptying_contract is expected to fail in apply with another error, but our changes caused it to fail in precheck because of the gas, so we increased its gas_limit. - In test_gas_levels.ml, many tests used to fail in apply for lack of gas, but it wasn't important since the block gas level is updated during precheck. Having them fail in precheck instead is a problem, so we increased the gas_limit of the relevant operations. More test updates to come in the next commits --- docs/protocols/alpha.rst | 5 +++ src/proto_alpha/lib_protocol/apply.ml | 18 ++++++++++ src/proto_alpha/lib_protocol/apply.mli | 1 + .../lib_protocol/michelson_v1_gas.ml | 8 ++++- .../lib_protocol/michelson_v1_gas.mli | 5 +++ .../lib_protocol/test/helpers/op.ml | 35 +++++++++---------- .../lib_protocol/test/helpers/op.mli | 2 +- .../integration/consensus/test_delegation.ml | 9 ++++- .../test/integration/gas/test_gas_levels.ml | 4 ++- .../integration/operations/test_reveal.ml | 18 +++++++--- 10 files changed, 78 insertions(+), 27 deletions(-) diff --git a/docs/protocols/alpha.rst b/docs/protocols/alpha.rst index 52ac34e3165d..7c12d6ef9e8b 100644 --- a/docs/protocols/alpha.rst +++ b/docs/protocols/alpha.rst @@ -50,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 ------------- diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index de062d47d171..7d4f268b2c9d 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" @@ -1937,6 +1951,10 @@ 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 + 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 () -> diff --git a/src/proto_alpha/lib_protocol/apply.mli b/src/proto_alpha/lib_protocol/apply.mli index 286a1014b992..ae2d7c9fff29 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/michelson_v1_gas.ml b/src/proto_alpha/lib_protocol/michelson_v1_gas.ml index 34797b492572..39f89d88f157 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 1bbb9cc97691..c87e1a14a64a 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 b54ed3ce5355..a9b17e9f36fe 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/op.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/op.ml @@ -151,6 +151,14 @@ let batch_operations ?(recompute_counters = false) ~source ctxt Environment.wrap_tzresult @@ Operation.of_list operations >>?= fun operations -> return @@ sign account.sk ctxt operations +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 + (10_000 + Michelson_v1_gas.Internal_for_tests.int_cost_of_manager_operation) + let combine_operations ?public_key ?counter ?spurious_operation ~source ctxt (packed_operations : packed_operation list) = assert (match packed_operations with [] -> false | _ :: _ -> true) ; @@ -194,7 +202,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 @@ -288,7 +296,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,9 +313,8 @@ 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) - ?counter ?(forge_pkh = None) ctxt public_key = +let revelation ?(fee = Tez.zero) ?(gas_limit = default_high_gas_limit) + ?(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 [public_key]. This is useful to test forging Reveal operations @@ -434,14 +441,9 @@ let transaction ?force_reveal ?counter ?fee ?gas_limit ?storage_limit dst amount -let delegation ?force_reveal ?fee ?gas_limit ?counter ?storage_limit ctxt source - dst = +let delegation ?force_reveal ?fee ?(gas_limit = default_low_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 @@ -455,14 +457,9 @@ let delegation ?force_reveal ?fee ?gas_limit ?counter ?storage_limit ctxt source Context.Contract.manager ctxt source >|=? fun account -> sign account.sk ctxt sop -let set_deposits_limit ?force_reveal ?fee ?gas_limit ?storage_limit ?counter - ctxt source limit = +let set_deposits_limit ?force_reveal ?fee ?(gas_limit = default_low_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 diff --git a/src/proto_alpha/lib_protocol/test/helpers/op.mli b/src/proto_alpha/lib_protocol/test/helpers/op.mli index 066c62a9f14e..f3f4056937d2 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/op.mli +++ b/src/proto_alpha/lib_protocol/test/helpers/op.mli @@ -89,7 +89,7 @@ val unsafe_transaction : ?force_reveal:bool -> ?counter:counter -> ?fee:Tez.t -> - ?gas_limit:Fixed_point_repr.integral_tag Gas.Arith.t -> + ?gas_limit:Gas.Arith.integral -> ?storage_limit:counter -> ?parameters: Michelson_v1_primitives.prim Micheline.canonical Data_encoding.lazy_t -> diff --git a/src/proto_alpha/lib_protocol/test/integration/consensus/test_delegation.ml b/src/proto_alpha/lib_protocol/test/integration/consensus/test_delegation.ml index 086678fa2c54..cf475c81352e 100644 --- a/src/proto_alpha/lib_protocol/test/integration/consensus/test_delegation.ml +++ b/src/proto_alpha/lib_protocol/test/integration/consensus/test_delegation.ml @@ -1228,7 +1228,14 @@ let test_self_delegation_emptying_contract () = Incremental.add_operation i op >>=? fun i -> Op.revelation ~fee:Tez.zero (I i) pk >>=? fun op -> Incremental.add_operation i op >>=? fun i -> - Op.delegation ~fee:amount (I i) contract (Some delegate_pkh) >>=? fun op -> + let gas_limit = + (* This is empirically about just enough gas so that the operation + does not fail for lack of gas. *) + Gas.Arith.integral_of_int_exn + (Michelson_v1_gas.Internal_for_tests.int_cost_of_manager_operation + 400) + in + Op.delegation ~fee:amount ~gas_limit (I i) contract (Some delegate_pkh) + >>=? fun op -> (Context.Contract.is_manager_key_revealed (I i) contract >>=? function | false -> failwith "contract should exist" | true -> return_unit) 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 0f5d52e56ce7..26cd9527f403 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 @@ -344,7 +344,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) -> 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 ee3b1c24183e..02131df41600 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 @@ -428,12 +435,15 @@ let test_no_reveal_when_gas_exhausted () = 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 -> -- GitLab From c9476537761201cbaba64d3db6232486eae983d1 Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Thu, 9 Jun 2022 10:47:19 +0200 Subject: [PATCH 6/8] Tezt: adapt tests with manager_opearation_gas_cost --- tezt/lib_tezos/constant.ml | 4 +++ tezt/tests/baking.ml | 9 ++++++- tezt/tests/manager_operations.ml | 43 +++++++++++++++++++++++++------- tezt/tests/replace_by_fees.ml | 11 ++++---- 4 files changed, 51 insertions(+), 16 deletions(-) diff --git a/tezt/lib_tezos/constant.ml b/tezt/lib_tezos/constant.ml index b543a289ae3f..42c55d9d9700 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 1e4fe630d71a..d1e69d88341c 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 ee0fe982e0fb..337fb427c88a 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 6dc223d91be9..b05367efc173 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 -- GitLab From ddd9ed84fcaa3eec897c35af95e0fc8b9ae16656 Mon Sep 17 00:00:00 2001 From: vbot Date: Thu, 9 Jun 2022 14:04:11 +0200 Subject: [PATCH 7/8] Proto/Tests: change gas limit argument and adapt tests --- .../lib_protocol/test/helpers/op.ml | 38 +++-- .../lib_protocol/test/helpers/op.mli | 148 ++++++++++-------- .../test/helpers/sapling_helpers.ml | 1 + .../lib_protocol/test/helpers/transfers.ml | 2 +- .../integration/consensus/test_delegation.ml | 9 +- .../test/integration/gas/test_gas_levels.ml | 7 +- .../integration/michelson/test_sapling.ml | 38 ++++- .../michelson/test_ticket_balance.ml | 1 + .../michelson/test_ticket_manager.ml | 1 + .../operations/manager_operation_helpers.ml | 2 +- ...test_batched_manager_operation_precheck.ml | 16 +- .../operations/test_combined_operations.ml | 2 +- .../test_manager_operation_precheck.ml | 8 +- .../integration/operations/test_reveal.ml | 5 +- .../integration/operations/test_tx_rollup.ml | 14 +- 15 files changed, 174 insertions(+), 118 deletions(-) diff --git a/src/proto_alpha/lib_protocol/test/helpers/op.ml b/src/proto_alpha/lib_protocol/test/helpers/op.ml index a9b17e9f36fe..53da6f52100b 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/op.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/op.ml @@ -151,13 +151,24 @@ 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 - (10_000 + Michelson_v1_gas.Internal_for_tests.int_cost_of_manager_operation) + (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) = @@ -251,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 @@ -313,8 +321,8 @@ 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 = default_high_gas_limit) - ?(storage_limit = Z.zero) ?counter ?(forge_pkh = None) ctxt public_key = +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 [public_key]. This is useful to test forging Reveal operations @@ -324,7 +332,7 @@ let revelation ?(fee = Tez.zero) ?(gas_limit = default_high_gas_limit) | 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 @@ -441,14 +449,14 @@ let transaction ?force_reveal ?counter ?fee ?gas_limit ?storage_limit dst amount -let delegation ?force_reveal ?fee ?(gas_limit = default_low_gas_limit) ?counter - ?storage_limit ctxt source dst = +let delegation ?force_reveal ?fee ?gas_limit ?counter ?storage_limit ctxt source + dst = let top = Delegation dst in manager_operation ?force_reveal ?fee ?counter - ~gas_limit + ?gas_limit ?storage_limit ~source ctxt @@ -457,15 +465,15 @@ let delegation ?force_reveal ?fee ?(gas_limit = default_low_gas_limit) ?counter Context.Contract.manager ctxt source >|=? fun account -> sign account.sk ctxt sop -let set_deposits_limit ?force_reveal ?fee ?(gas_limit = default_low_gas_limit) - ?storage_limit ?counter ctxt source limit = +let set_deposits_limit ?force_reveal ?fee ?gas_limit ?storage_limit ?counter + ctxt source limit = let top = Set_deposits_limit limit 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 f3f4056937d2..df18aab209c1 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:Gas.Arith.integral -> + ?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 9deac42be4ee..8742fd957b08 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 ac185cd069d3..086e7d4530bf 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/consensus/test_delegation.ml b/src/proto_alpha/lib_protocol/test/integration/consensus/test_delegation.ml index cf475c81352e..086678fa2c54 100644 --- a/src/proto_alpha/lib_protocol/test/integration/consensus/test_delegation.ml +++ b/src/proto_alpha/lib_protocol/test/integration/consensus/test_delegation.ml @@ -1228,14 +1228,7 @@ let test_self_delegation_emptying_contract () = Incremental.add_operation i op >>=? fun i -> Op.revelation ~fee:Tez.zero (I i) pk >>=? fun op -> Incremental.add_operation i op >>=? fun i -> - let gas_limit = - (* This is empirically about just enough gas so that the operation - does not fail for lack of gas. *) - Gas.Arith.integral_of_int_exn - (Michelson_v1_gas.Internal_for_tests.int_cost_of_manager_operation + 400) - in - Op.delegation ~fee:amount ~gas_limit (I i) contract (Some delegate_pkh) - >>=? fun op -> + Op.delegation ~fee:amount (I i) contract (Some delegate_pkh) >>=? fun op -> (Context.Contract.is_manager_key_revealed (I i) contract >>=? function | false -> failwith "contract should exist" | true -> return_unit) 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 26cd9527f403..065b7502d06b 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) 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 c6d9669667fe..312d4b8eaaa8 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 af27dd965232..f3d74a420ebb 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 59792cdbb07d..6fb79efb53f6 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 3038d9a50d68..2b20bee48b5f 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 c4e73a3e2f05..d2acfd9f11cc 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 b36db3359d24..71baae676292 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 aa5e863073c3..f13c4796e890 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 02131df41600..b2baee4da48e 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 @@ -430,8 +430,7 @@ 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 *) @@ -565,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 cdf741070779..0917d6acebba 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 -- GitLab From 010d87123b0201135bd1d80c6d24d376100de0bb Mon Sep 17 00:00:00 2001 From: vbot Date: Thu, 9 Jun 2022 16:07:43 +0200 Subject: [PATCH 8/8] Proto/Tests: add a test checking that emptying an account costs gas --- .../test/integration/gas/test_gas_levels.ml | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) 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 065b7502d06b..568a88ba2955 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 @@ -443,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 = @@ -475,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 -- GitLab