diff --git a/docs/protocols/alpha.rst b/docs/protocols/alpha.rst index 070b6b3158b667423c05867f335b66e39c9044a2..3bb9fd36088110b95293d45deac88570f90389b0 100644 --- a/docs/protocols/alpha.rst +++ b/docs/protocols/alpha.rst @@ -80,3 +80,10 @@ Internal - Move notion of Smart rollup address in the shell to make it common to all protocols, and expose it in the environment. (MR :gl:`!8562`) + +- Add ``mock_counter`` to the context, with two commands to get and update its content, + only the later one consuming gas (MR :gl:`!8759`) + +- Michelson: add two new instructions ``GET_COUNTER`` and ``SET_COUNTER`` to push the current + value of the mock counter, or to set the current value of the mock counter, respectively. + (MR :gl:`!8759`) diff --git a/manifest/main.ml b/manifest/main.ml index 0b0aab8c6ef4430375c1615b696b3e9ca1615d30..05b3b4a3ae82dd664811bb55538981974d60ee97 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -4638,6 +4638,7 @@ end = struct [ ("test_annotations", true); ("test_block_time_instructions", true); + ("test_mock_counter_instructions", N.(number >= 018)); ("test_contract_event", true); ("test_global_constants_storage", true); ("test_interpretation", true); @@ -4891,6 +4892,7 @@ end = struct ("test_dal_slot_proof", N.(number >= 016)); ("test_tx_rollup_l2_apply", N.(number >= 015 && number <= 016)); ("test_tx_rollup_l2", N.(number >= 015 && number <= 016)); + ("test_mock_counter_storage", N.(number >= 018)); ] |> List.filter_map (fun (n, b) -> if b then Some n else None) in diff --git a/mock_counter_test.tz b/mock_counter_test.tz new file mode 100644 index 0000000000000000000000000000000000000000..c661ab960092460d8b0b0a3b57ed8d7be114fc23 --- /dev/null +++ b/mock_counter_test.tz @@ -0,0 +1,3 @@ +{ parameter (or (int %set) (int %update)) ; + storage unit ; + code { UNPAIR ; IF_LEFT { SET_COUNTER } { GET_COUNTER ; ADD ; SET_COUNTER } ; NIL operation ; PAIR } } \ No newline at end of file diff --git a/src/proto_alpha/lib_benchmarks_proto/interpreter_benchmarks.ml b/src/proto_alpha/lib_benchmarks_proto/interpreter_benchmarks.ml index 25268a0bf556e61d8df8a862ce10dc0564d768ae..dce1c6e8c8314d69c09cfa995d7c8e5ae49b34ab 100644 --- a/src/proto_alpha/lib_benchmarks_proto/interpreter_benchmarks.ml +++ b/src/proto_alpha/lib_benchmarks_proto/interpreter_benchmarks.ml @@ -2551,6 +2551,20 @@ module Registration_section = struct ~kinstr:(IBalance (dummy_loc, halt)) () + let () = + simple_benchmark + ~name:Interpreter_workload.N_IGet_counter + ~stack_type:bot + ~kinstr:(IGet_counter (dummy_loc, halt)) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_ISet_counter + ~stack_type:(int @$ bot) + ~kinstr:(ISet_counter (dummy_loc, halt)) + () + let () = simple_benchmark ~name:Interpreter_workload.N_ILevel diff --git a/src/proto_alpha/lib_benchmarks_proto/interpreter_model.ml b/src/proto_alpha/lib_benchmarks_proto/interpreter_model.ml index 76866083af3b034d32357d0f9a71ea81b36f0f72..0f04b623576b09ee9b5952a59cf5c61e6682ea34 100644 --- a/src/proto_alpha/lib_benchmarks_proto/interpreter_model.ml +++ b/src/proto_alpha/lib_benchmarks_proto/interpreter_model.ml @@ -410,9 +410,10 @@ let ir_model instr_or_cont = | N_IEmpty_set | N_IEmpty_map | N_IEmpty_big_map | N_IOr | N_IAnd | N_IXor | N_INot | N_IIf | N_ILoop | N_ILoop_left | N_IDip | N_IExec | N_IView | N_ILambda | N_IFailwith | N_IAddress | N_ICreate_contract - | N_ISet_delegate | N_INow | N_IMin_block_time | N_IBalance | N_IHash_key - | N_IUnpack | N_ISource | N_ISender | N_ISelf | N_IAmount | N_IChainId - | N_ILevel | N_ISelf_address | N_INever | N_IUnpair | N_IVoting_power + | N_ISet_delegate | N_INow | N_IMin_block_time | N_IGet_counter + | N_ISet_counter | N_IBalance | N_IHash_key | N_IUnpack | N_ISource + | N_ISender | N_ISelf | N_IAmount | N_IChainId | N_ILevel + | N_ISelf_address | N_INever | N_IUnpair | N_IVoting_power | N_ITotal_voting_power | N_IList_size | N_ISet_size | N_IMap_size | N_ISapling_empty_state -> const1_model name |> m diff --git a/src/proto_alpha/lib_benchmarks_proto/interpreter_workload.ml b/src/proto_alpha/lib_benchmarks_proto/interpreter_workload.ml index 9929847fff539942e12e7cd7797c9c0ef72b3ecd..137696729086259ce879b238b62cb230513601f1 100644 --- a/src/proto_alpha/lib_benchmarks_proto/interpreter_workload.ml +++ b/src/proto_alpha/lib_benchmarks_proto/interpreter_workload.ml @@ -175,6 +175,8 @@ type instruction_name = | N_INow | N_IMin_block_time (* other *) + | N_IGet_counter + | N_ISet_counter | N_IBalance | N_ILevel | N_IView @@ -377,6 +379,8 @@ let string_of_instruction_name : instruction_name -> string = | N_ISet_delegate -> "N_ISet_delegate" | N_INow -> "N_INow" | N_IMin_block_time -> "N_IMin_block_time" + | N_IGet_counter -> "N_IGet_counter" + | N_ISet_counter -> "N_ISet_counter" | N_IBalance -> "N_IBalance" | N_ICheck_signature_ed25519 -> "N_ICheck_signature_ed25519" | N_ICheck_signature_secp256k1 -> "N_ICheck_signature_secp256k1" @@ -603,6 +607,8 @@ let all_instructions = N_ISet_delegate; N_INow; N_IMin_block_time; + N_IGet_counter; + N_ISet_counter; N_IBalance; N_ICheck_signature_ed25519; N_ICheck_signature_secp256k1; @@ -1016,6 +1022,12 @@ module Instructions = struct let min_block_time = ir_sized_step N_IMin_block_time nullary + (** cost model for the GET_COUNTER instruction *) + let get_counter = ir_sized_step N_IGet_counter nullary + + (** cost model for the SET_COUNTER instruction *) + let set_counter = ir_sized_step N_ISet_counter nullary + let balance = ir_sized_step N_IBalance nullary let check_signature_ed25519 _pk _signature message = @@ -1514,6 +1526,8 @@ let extract_ir_sized_step : let log_time = Z.log2 Z.(one + Script_int.to_zint time) |> Size.of_int in Instructions.open_chest log_time plaintext_size | IMin_block_time _, _ -> Instructions.min_block_time + | IGet_counter _, _ -> Instructions.get_counter + | ISet_counter _, _ -> Instructions.set_counter | IEmit _, _ -> Instructions.emit | ILsl_bytes (_, _), (x, (y, _)) -> let y = diff --git a/src/proto_alpha/lib_client/client_proto_context.ml b/src/proto_alpha/lib_client/client_proto_context.ml index adbf31fb9cbf74903a6ab1f5b188e1389aa929d3..70a4fc8f2c06eb1dcd706bd2ff9c21aca3c03243 100644 --- a/src/proto_alpha/lib_client/client_proto_context.ml +++ b/src/proto_alpha/lib_client/client_proto_context.ml @@ -30,6 +30,44 @@ open Tezos_micheline open Client_proto_contracts open Client_keys +let build_mock_counter_update ?fee ?gas_limit ?storage_limit ~value () = + let operation = Mock_counter_update {value} in + Injection.prepare_manager_operation + ~fee:(Limit.of_option fee) + ~gas_limit:(Limit.of_option gas_limit) + ~storage_limit:(Limit.of_option storage_limit) + operation + +let mock_counter_update (cctxt : #full) ~chain ~block ?confirmations ?dry_run + ?verbose_signing ?simulation ?fee mgr ~src_pk ~src_sk ~value ~fee_parameter + = + let open Lwt_result_syntax in + let op = build_mock_counter_update ?fee ~value () in + let annotated_op = Annotated_manager_operation.Single_manager op in + Injection.inject_manager_operation + cctxt + ~chain + ~block + ?confirmations + ?dry_run + ?verbose_signing + ?simulation + ~source:mgr + ~fee:(Limit.of_option fee) + ~storage_limit:Limit.unknown + ~gas_limit:Limit.unknown + ~src_pk + ~src_sk + ~fee_parameter + annotated_op + >>=? fun (oph, _, op, result) -> + match Apply_results.pack_contents_list op result with + | Apply_results.Single_and_result ((Manager_operation _ as op), result) -> + return (oph, op, result) + +let mock_counter_get (rpc : #rpc_context) ~chain ~block = + Alpha_services.Mock_counter.mock_counter rpc (chain, block) + let get_balance (rpc : #rpc_context) ~chain ~block contract = Alpha_services.Contract.balance rpc (chain, block) contract diff --git a/src/proto_alpha/lib_client/client_proto_context.mli b/src/proto_alpha/lib_client/client_proto_context.mli index 3502993bc9938692a9acc0048745a0052c7c3a39..1acc7a2e958b632224dcba28abd3f5c9cf763a12 100644 --- a/src/proto_alpha/lib_client/client_proto_context.mli +++ b/src/proto_alpha/lib_client/client_proto_context.mli @@ -26,6 +26,30 @@ open Protocol open Alpha_context +(** Calls {!Tezos_protocol_alpha.Protocol.Alpha_context.Mock_counter.update_value}. *) +val mock_counter_update : + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?confirmations:int -> + ?dry_run:bool -> + ?verbose_signing:bool -> + ?simulation:bool -> + ?fee:Tez.tez -> + public_key_hash -> + src_pk:public_key -> + src_sk:Client_keys.sk_uri -> + value:Z.t -> + fee_parameter:Injection.fee_parameter -> + Kind.mock_counter_update Kind.manager Injection.result tzresult Lwt.t + +(** Calls {!Tezos_protocol_alpha.Protocol.Alpha_context.Mock_counter.get_value}. *) +val mock_counter_get : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + Z.t tzresult Lwt.t + (** Calls {!Tezos_protocol_alpha.Protocol.Contract_services.list}. *) val list_contract_labels : #Protocol_client_context.full -> diff --git a/src/proto_alpha/lib_client/injection.ml b/src/proto_alpha/lib_client/injection.ml index 74df530ace43da60e554bc1caf3ddd882f797724..594dd89c0c0ded4b925b361d68c12a8cb1f1d9e0 100644 --- a/src/proto_alpha/lib_client/injection.ml +++ b/src/proto_alpha/lib_client/injection.ml @@ -342,7 +342,8 @@ let estimated_gas_single (type kind) Ok consumed_gas | Zk_rollup_origination_result {consumed_gas; _} -> Ok consumed_gas | Zk_rollup_publish_result {consumed_gas; _} -> Ok consumed_gas - | Zk_rollup_update_result {consumed_gas; _} -> Ok consumed_gas) + | Zk_rollup_update_result {consumed_gas; _} -> Ok consumed_gas + | Mock_counter_update_result {consumed_gas; _} -> Ok consumed_gas) | Skipped _ -> error_with "Cannot estimate gas of skipped operation" (* There must be another error for this to happen, and it should not @@ -412,7 +413,7 @@ let estimated_storage_single (type kind) ~origination_size *) | Sc_rollup_cement_result _ | Sc_rollup_publish_result _ | Sc_rollup_refute_result _ | Sc_rollup_timeout_result _ - | Sc_rollup_recover_bond_result _ -> + | Sc_rollup_recover_bond_result _ | Mock_counter_update_result _ -> Ok Z.zero) | Skipped _ -> error_with "Cannot estimate storage of skipped operation" @@ -486,7 +487,8 @@ let originated_contracts_single (type kind) | Sc_rollup_refute_result _ | Sc_rollup_timeout_result _ | Sc_rollup_execute_outbox_message_result _ | Sc_rollup_recover_bond_result _ | Zk_rollup_origination_result _ - | Zk_rollup_publish_result _ | Zk_rollup_update_result _ -> + | Zk_rollup_publish_result _ | Zk_rollup_update_result _ + | Mock_counter_update_result _ -> Ok []) | Skipped _ -> error_with "Cannot know originated contracts of skipped operation" diff --git a/src/proto_alpha/lib_client/operation_result.ml b/src/proto_alpha/lib_client/operation_result.ml index 696a52972d879fa49c81f4573d449832cd427c82..325871abf8d2ca2304aebcac0cf2dd85b869ec57 100644 --- a/src/proto_alpha/lib_client/operation_result.ml +++ b/src/proto_alpha/lib_client/operation_result.ml @@ -330,6 +330,8 @@ let pp_manager_operation_content (type kind) source ppf Format.fprintf ppf "Epoxy publish:@,From: %a" Contract.pp source | Zk_rollup_update _ -> Format.fprintf ppf "Epoxy update:@,From: %a" Contract.pp source + | Mock_counter_update {value} -> + Format.fprintf ppf "Update mock counter with value: %a" Z.pp_print value let pp_balance_updates ppf balance_updates = let open Receipt in @@ -714,6 +716,11 @@ let pp_manager_operation_contents_result ppf op_result = pp_paid_storage_size_diff ppf paid_storage_size_diff ; pp_balance_updates ppf balance_updates in + let pp_mock_counter_update_result + (Mock_counter_update_result {consumed_gas; paid_storage_size_diff}) = + pp_consumed_gas ppf consumed_gas ; + pp_paid_storage_size_diff ppf paid_storage_size_diff + in let manager_operation_name (type kind) (result : kind successful_manager_operation_result) = @@ -741,6 +748,7 @@ let pp_manager_operation_contents_result ppf op_result = | Zk_rollup_origination_result _ -> "epoxy originate" | Zk_rollup_publish_result _ -> "epoxy publish" | Zk_rollup_update_result _ -> "epoxy update" + | Mock_counter_update_result _ -> "mock counter update" in let pp_manager_operation_contents_result (type kind) ppf (result : kind successful_manager_operation_result) = @@ -773,6 +781,7 @@ let pp_manager_operation_contents_result ppf op_result = | Zk_rollup_origination_result _ as op -> pp_zk_rollup_origination_result op | Zk_rollup_publish_result _ as op -> pp_zk_rollup_publish_result op | Zk_rollup_update_result _ as op -> pp_zk_rollup_update_result op + | Mock_counter_update_result _ as op -> pp_mock_counter_update_result op in pp_operation_result ~operation_name:manager_operation_name diff --git a/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml b/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml index 757fbb8111a4d5c3c9f0f701004b36b419461555..fd29cc28017dc36cad32a4204195058d8b7a7893 100644 --- a/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml +++ b/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml @@ -1082,6 +1082,66 @@ let commands_rw () = let open Tezos_micheline in let open Tezos_clic in [ + command + ~group + ~desc:"Update value of mock counter" + (args5 + fee_arg + dry_run_switch + verbose_signing_switch + simulate_switch + fee_parameter_args) + (prefixes ["update"; "mock"; "counter"] + @@ prefix "with" + @@ param + ~name:"value" + ~desc:"value to increase mock counter with" + int_parameter + @@ Contract_alias.destination_param ~name:"src" ~desc:"source contract" + @@ stop) + (fun (fee, dry_run, verbose_signing, simulation, fee_parameter) + (value : int) + contract + (cctxt : Protocol_client_context.full) -> + let open Lwt_result_syntax in + let* source = + match contract with + | Originated contract -> + Managed_contract.get_contract_manager cctxt contract + | Implicit mgr -> return mgr + in + let* _, src_pk, src_sk = Client_keys.get_key cctxt source in + let* (_ : _ Injection.result) = + mock_counter_update + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ~simulation + ~fee_parameter + ?fee + source + ~src_pk + ~src_sk + ~value:(Z.of_int value) + in + return_unit); + command + ~group + ~desc:"Get value of mock counter" + no_options + (prefixes ["get"; "mock"; "counter"] @@ stop) + (fun () (cctxt : Protocol_client_context.full) -> + let open Lwt_result_syntax in + let* value = + mock_counter_get cctxt ~chain:cctxt#chain ~block:cctxt#block + in + let*! () = + cctxt#answer "Value of the mock counter: %a" Z.pp_print value + in + return_unit); command ~group ~desc:"Set the delegate of a contract." diff --git a/src/proto_alpha/lib_plugin/RPC.ml b/src/proto_alpha/lib_plugin/RPC.ml index 4869459ded9fbed2d612b81a007269db8763a155..35220579745bbdce703df1ba8f0b230da9c7da87 100644 --- a/src/proto_alpha/lib_plugin/RPC.ml +++ b/src/proto_alpha/lib_plugin/RPC.ml @@ -865,6 +865,8 @@ module Scripts = struct | ISet_delegate _ -> pp_print_string fmt "SET_DELEGATE" | INow _ -> pp_print_string fmt "NOW" | IMin_block_time _ -> pp_print_string fmt "MIN_BLOCK_TIME" + | IGet_counter _ -> pp_print_string fmt "GET_COUNTER" + | ISet_counter _ -> pp_print_string fmt "SET_COUNTER" | IBalance _ -> pp_print_string fmt "BALANCE" | ILevel _ -> pp_print_string fmt "LEVEL" | ICheck_signature _ -> pp_print_string fmt "CHECK_SIGNATURE" diff --git a/src/proto_alpha/lib_plugin/script_interpreter_logging.ml b/src/proto_alpha/lib_plugin/script_interpreter_logging.ml index 663283db73ec2f9a5727fd0431cd7df410f1a8a8..b18b9e8498e89f9b5b926cdb09174134cc6f6626 100644 --- a/src/proto_alpha/lib_plugin/script_interpreter_logging.ml +++ b/src/proto_alpha/lib_plugin/script_interpreter_logging.ml @@ -1719,6 +1719,23 @@ module Stack_utils = struct continuation = k; reconstruct = (fun k -> IMin_block_time (loc, k)); } + | IGet_counter (loc, k), s -> + let s = Item_t (int_t, s) in + ok + @@ Ex_split_kinstr + { + cont_init_stack = s; + continuation = k; + reconstruct = (fun k -> IGet_counter (loc, k)); + } + | ISet_counter (loc, k), Item_t (_, s) -> + ok + @@ Ex_split_kinstr + { + cont_init_stack = s; + continuation = k; + reconstruct = (fun k -> ISet_counter (loc, k)); + } | IEmit {loc; ty; unparsed_ty; tag; k}, Item_t (_, s) -> let s = Item_t (operation_t, s) in ok diff --git a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL index 68c78822f3cb4dbadf204ccb496d930914be933b..a696a95696d41ecb07bffe33585ca3b835f04c2e 100644 --- a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL +++ b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL @@ -195,6 +195,8 @@ "Destination_storage", + "Mock_counter_storage", + "Alpha_context", "Script_string", "Script_timestamp", diff --git a/src/proto_alpha/lib_protocol/alpha_context.ml b/src/proto_alpha/lib_protocol/alpha_context.ml index d0ec1f30c0daa4868129218673986a053bda1c61..71eb8232484e5eda95737e759b18a290eaae3321 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.ml +++ b/src/proto_alpha/lib_protocol/alpha_context.ml @@ -668,3 +668,7 @@ module Cache = Cache_repr module Internal_for_tests = struct let to_raw x = x end + +module Mock_counter = struct + include Mock_counter_storage +end diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 8ac38dd6f90bc26199dd8400d495131f995984b5..1d6a059da830a45d55edd422842cc8aaa41a6923 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -577,6 +577,7 @@ module Script : sig | I_GE | I_GET | I_GET_AND_UPDATE + | I_GET_COUNTER | I_GT | I_HASH_KEY | I_IF @@ -614,6 +615,7 @@ module Script : sig | I_SENDER | I_SELF | I_SELF_ADDRESS + | I_SET_COUNTER | I_SLICE | I_STEPS_TO_QUOTA | I_SUB @@ -4577,6 +4579,8 @@ module Kind : sig type zk_rollup_update = Zk_rollup_update_kind + type mock_counter_update = Mock_counter_update_kind + type 'a manager = | Reveal_manager_kind : reveal manager | Transaction_manager_kind : transaction manager @@ -4601,6 +4605,7 @@ module Kind : sig | Zk_rollup_origination_manager_kind : zk_rollup_origination manager | Zk_rollup_publish_manager_kind : zk_rollup_publish manager | Zk_rollup_update_manager_kind : zk_rollup_update manager + | Mock_counter_update_manager_kind : mock_counter_update manager end (** All the definitions below are re-exported from {!Operation_repr}. *) @@ -4808,6 +4813,10 @@ and _ manager_operation = update : Zk_rollup.Update.t; } -> Kind.zk_rollup_update manager_operation + | Mock_counter_update : { + value : Z.t; + } + -> Kind.mock_counter_update manager_operation type packed_manager_operation = | Manager : 'kind manager_operation -> packed_manager_operation @@ -5001,6 +5010,8 @@ module Operation : sig val zk_rollup_update_case : Kind.zk_rollup_update Kind.manager case + val mock_counter_update_case : Kind.mock_counter_update Kind.manager case + module Manager_operations : sig type 'b case = | MCase : { @@ -5057,6 +5068,8 @@ module Operation : sig val zk_rollup_publish_case : Kind.zk_rollup_publish case val zk_rollup_update_case : Kind.zk_rollup_update case + + val mock_counter_update_case : Kind.mock_counter_update case end end @@ -5389,3 +5402,10 @@ module Fees : sig val check_storage_limit : context -> storage_limit:Z.t -> unit tzresult end + +(** This module re-exports definitions from {!Mock_counter_storage}. *) +module Mock_counter : sig + val update_value : context -> Z.t -> (context * int) tzresult Lwt.t + + val get_value : context -> (context * Z.t) tzresult Lwt.t +end diff --git a/src/proto_alpha/lib_protocol/alpha_services.ml b/src/proto_alpha/lib_protocol/alpha_services.ml index 5f3e5b2dd68da6a992d6736f19e79b279ce23148..bfcb7ea9556e1c9ba388afd097b9d7fca2cb6373 100644 --- a/src/proto_alpha/lib_protocol/alpha_services.ml +++ b/src/proto_alpha/lib_protocol/alpha_services.ml @@ -299,6 +299,27 @@ module Cache = struct RPC_context.make_call0 S.contract_rank ctxt block () contract end +module Mock_counter = struct + module S = struct + let mock_counter = + RPC_service.get_service + ~description:"Access the value of the mock counter" + ~query:RPC_query.empty + ~output:Data_encoding.z + RPC_path.(custom_root / "context" / "mock_counter") + end + + let register () = + let open Services_registration in + let open Lwt_result_syntax in + register0 ~chunked:false S.mock_counter (fun ctxt () () -> + let* _, value = Mock_counter.get_value ctxt in + return value) + + let mock_counter ctxt block = + RPC_context.make_call0 S.mock_counter ctxt block () () +end + let register () = Contract.register () ; Constants.register () ; @@ -308,4 +329,5 @@ let register () = Voting.register () ; Sapling.register () ; Liquidity_baking.register () ; - Cache.register () + Cache.register () ; + Mock_counter.register () diff --git a/src/proto_alpha/lib_protocol/alpha_services.mli b/src/proto_alpha/lib_protocol/alpha_services.mli index 14235f19a699785940202b9a499741ff6932bf8d..e6de593484c9829b812bf076229cadedb8029864 100644 --- a/src/proto_alpha/lib_protocol/alpha_services.mli +++ b/src/proto_alpha/lib_protocol/alpha_services.mli @@ -92,4 +92,10 @@ module Cache : sig int option shell_tzresult Lwt.t end +(** Define mock counter RPC interface. *) +module Mock_counter : sig + (** Get value of mock counter through RPC. *) + val mock_counter : 'a #RPC_context.simple -> 'a -> Z.t shell_tzresult Lwt.t +end + val register : unit -> unit diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index 13927ad65550a8f9ae7d6e5fc4b2ea821aeaceac..2e5c5bc959dd205038a7ea802477419ee6429a21 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -1137,6 +1137,18 @@ let apply_manager_operation : Zk_rollup_apply.publish ~ctxt_before_op ~ctxt ~zk_rollup ~l2_ops:ops | Zk_rollup_update {zk_rollup; update} -> Zk_rollup_apply.update ~ctxt_before_op ~ctxt ~zk_rollup ~update + | Mock_counter_update {value} -> + let open Lwt_result_syntax in + let+ ctxt, paid_storage_size_diff = + Mock_counter.update_value ctxt value + in + ( ctxt, + Mock_counter_update_result + { + consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt; + paid_storage_size_diff = Z.of_int paid_storage_size_diff; + }, + [] ) type success_or_failure = Success of context | Failure @@ -1359,6 +1371,7 @@ let burn_manager_storage_fees : ( ctxt, storage_limit, Zk_rollup_update_result {payload with balance_updates} ) + | Mock_counter_update_result _ -> return (ctxt, storage_limit, smopr) (** [burn_internal_storage_fees ctxt smopr storage_limit payer] burns the storage fees associated to an internal operation result [smopr]. diff --git a/src/proto_alpha/lib_protocol/apply_results.ml b/src/proto_alpha/lib_protocol/apply_results.ml index 9778fad1feb8d04f9199f1677cfaca609ae0f065..155e52af21b7c72701cdf1e52065d1744ffc5ff4 100644 --- a/src/proto_alpha/lib_protocol/apply_results.ml +++ b/src/proto_alpha/lib_protocol/apply_results.ml @@ -151,6 +151,11 @@ type _ successful_manager_operation_result = paid_storage_size_diff : Z.t; } -> Kind.zk_rollup_update successful_manager_operation_result + | Mock_counter_update_result : { + consumed_gas : Gas.Arith.fp; + paid_storage_size_diff : Z.t; + } + -> Kind.mock_counter_update successful_manager_operation_result let migration_origination_result_to_successful_manager_operation_result ({ @@ -831,6 +836,25 @@ module Manager_result = struct (balance_updates, consumed_gas)) ~inj:(fun (balance_updates, consumed_gas) -> Sc_rollup_recover_bond_result {balance_updates; consumed_gas}) + + let mock_counter_update_case = + make + ~op_case:Operation.Encoding.Manager_operations.mock_counter_update_case + ~encoding: + Data_encoding.( + obj2 + (dft "consumed_milligas" Gas.Arith.n_fp_encoding Gas.Arith.zero) + (dft "paid_storage_size_diff" z Z.zero)) + ~select:(function + | Successful_manager_result (Mock_counter_update_result _ as op) -> + Some op + | _ -> None) + ~kind:Kind.Mock_counter_update_manager_kind + ~proj:(function + | Mock_counter_update_result {consumed_gas; paid_storage_size_diff} -> + (consumed_gas, paid_storage_size_diff)) + ~inj:(fun (consumed_gas, paid_storage_size_diff) -> + Mock_counter_update_result {consumed_gas; paid_storage_size_diff}) end let successful_manager_operation_result_encoding : @@ -999,6 +1023,10 @@ let equal_manager_kind : | Kind.Zk_rollup_update_manager_kind, Kind.Zk_rollup_update_manager_kind -> Some Eq | Kind.Zk_rollup_update_manager_kind, _ -> None + | Kind.Mock_counter_update_manager_kind, Kind.Mock_counter_update_manager_kind + -> + Some Eq + | Kind.Mock_counter_update_manager_kind, _ -> None module Encoding = struct type 'kind case = @@ -1588,6 +1616,17 @@ module Encoding = struct -> Some (op, res) | _ -> None) + + let mock_counter_update_case = + make_manager_case + Operation.Encoding.mock_counter_update_case + Manager_result.mock_counter_update_case + (function + | Contents_and_result + ( (Manager_operation {operation = Mock_counter_update _; _} as op), + res ) -> + Some (op, res) + | _ -> None) end let contents_result_encoding = @@ -1642,6 +1681,7 @@ let contents_result_encoding = make zk_rollup_origination_case; make zk_rollup_publish_case; make zk_rollup_update_case; + make mock_counter_update_case; ] let contents_and_result_encoding = @@ -1701,6 +1741,7 @@ let contents_and_result_encoding = make zk_rollup_origination_case; make zk_rollup_publish_case; make zk_rollup_update_case; + make mock_counter_update_case; ] type 'kind contents_result_list = @@ -2378,6 +2419,32 @@ let kind_equal : } ) -> Some Eq | Manager_operation {operation = Zk_rollup_update _; _}, _ -> None + | ( Manager_operation {operation = Mock_counter_update _; _}, + Manager_operation_result + {operation_result = Applied (Mock_counter_update_result _); _} ) -> + Some Eq + | ( Manager_operation {operation = Mock_counter_update _; _}, + Manager_operation_result + {operation_result = Backtracked (Mock_counter_update_result _, _); _} ) + -> + Some Eq + | ( Manager_operation {operation = Mock_counter_update _; _}, + Manager_operation_result + { + operation_result = + Failed (Alpha_context.Kind.Mock_counter_update_manager_kind, _); + _; + } ) -> + Some Eq + | ( Manager_operation {operation = Mock_counter_update _; _}, + Manager_operation_result + { + operation_result = + Skipped Alpha_context.Kind.Mock_counter_update_manager_kind; + _; + } ) -> + Some Eq + | Manager_operation {operation = Mock_counter_update _; _}, _ -> None let rec kind_equal_list : type kind kind2. diff --git a/src/proto_alpha/lib_protocol/apply_results.mli b/src/proto_alpha/lib_protocol/apply_results.mli index 6011179e6dd9236af91bcc7fbe9e7d13de8e3ae2..05badf580946141a32b92c5572b016b2f532a1b5 100644 --- a/src/proto_alpha/lib_protocol/apply_results.mli +++ b/src/proto_alpha/lib_protocol/apply_results.mli @@ -256,6 +256,11 @@ and _ successful_manager_operation_result = paid_storage_size_diff : Z.t; } -> Kind.zk_rollup_update successful_manager_operation_result + | Mock_counter_update_result : { + consumed_gas : Gas.Arith.fp; + paid_storage_size_diff : Z.t; + } + -> Kind.mock_counter_update successful_manager_operation_result and packed_successful_manager_operation_result = | Successful_manager_result : diff --git a/src/proto_alpha/lib_protocol/dune b/src/proto_alpha/lib_protocol/dune index f67e2eb7ffb6e5dbd30711c25f25c4c228c2f9fd..68bf2d072b11c6dc8ee025c8a433aa1aebeb3d05 100644 --- a/src/proto_alpha/lib_protocol/dune +++ b/src/proto_alpha/lib_protocol/dune @@ -207,6 +207,7 @@ Sc_rollup_refutation_storage Zk_rollup_errors Destination_storage + Mock_counter_storage Alpha_context Script_string Script_timestamp @@ -488,6 +489,7 @@ sc_rollup_refutation_storage.ml sc_rollup_refutation_storage.mli zk_rollup_errors.ml destination_storage.ml destination_storage.mli + mock_counter_storage.ml mock_counter_storage.mli alpha_context.ml alpha_context.mli script_string.ml script_string.mli script_timestamp.ml script_timestamp.mli @@ -770,6 +772,7 @@ sc_rollup_refutation_storage.ml sc_rollup_refutation_storage.mli zk_rollup_errors.ml destination_storage.ml destination_storage.mli + mock_counter_storage.ml mock_counter_storage.mli alpha_context.ml alpha_context.mli script_string.ml script_string.mli script_timestamp.ml script_timestamp.mli @@ -1036,6 +1039,7 @@ sc_rollup_refutation_storage.ml sc_rollup_refutation_storage.mli zk_rollup_errors.ml destination_storage.ml destination_storage.mli + mock_counter_storage.ml mock_counter_storage.mli alpha_context.ml alpha_context.mli script_string.ml script_string.mli script_timestamp.ml script_timestamp.mli diff --git a/src/proto_alpha/lib_protocol/michelson_v1_gas.ml b/src/proto_alpha/lib_protocol/michelson_v1_gas.ml index e548e6aceb8b3b0d0faa92349c073a170a065010..b2b39530c71ee118120afb24d374175ab011df26 100644 --- a/src/proto_alpha/lib_protocol/michelson_v1_gas.ml +++ b/src/proto_alpha/lib_protocol/michelson_v1_gas.ml @@ -432,6 +432,10 @@ module Cost_of = struct let min_block_time = atomic_step_cost cost_N_IMin_block_time + let get_counter = atomic_step_cost cost_N_IGet_counter + + let set_counter = atomic_step_cost cost_N_ISet_counter + let source = atomic_step_cost cost_N_ISource let sender = atomic_step_cost cost_N_ISender diff --git a/src/proto_alpha/lib_protocol/michelson_v1_gas.mli b/src/proto_alpha/lib_protocol/michelson_v1_gas.mli index 012db06656f486550a0e027a378741ec1ae71893..bcaa1a54c6d012112ed73695a2d079d968431937 100644 --- a/src/proto_alpha/lib_protocol/michelson_v1_gas.mli +++ b/src/proto_alpha/lib_protocol/michelson_v1_gas.mli @@ -359,6 +359,12 @@ module Cost_of : sig val min_block_time : Gas.cost + (** cost model for the GET_COUNTER instruction *) + val get_counter : Gas.cost + + (** cost model for the SET_COUNTER instruction *) + val set_counter : Gas.cost + val hash_key : Signature.Public_key.t -> Gas.cost val source : Gas.cost diff --git a/src/proto_alpha/lib_protocol/michelson_v1_gas_costs_generated.ml b/src/proto_alpha/lib_protocol/michelson_v1_gas_costs_generated.ml index 15286d499890a2e0803ed2dfcac5fb61fa75374e..5b00ae21f42510dd24b4864d4116f43bdb424d07 100644 --- a/src/proto_alpha/lib_protocol/michelson_v1_gas_costs_generated.ml +++ b/src/proto_alpha/lib_protocol/michelson_v1_gas_costs_generated.ml @@ -430,6 +430,16 @@ let cost_N_INow = S.safe_int 10 (* model N_IMin_block_time *) let cost_N_IMin_block_time = S.safe_int 20 +(* model N_IGet_counter *) + +(** Allocates safe default number of bytes. *) +let cost_N_IGet_counter = S.safe_int 20 + +(* model N_ISet_counter *) + +(** Allocates safe default number of bytes. *) +let cost_N_ISet_counter = S.safe_int 20 + (* model N_IOpen_chest *) (* 612000 + chest * 19 + time * 19050 *) let cost_N_IOpen_chest time chest = diff --git a/src/proto_alpha/lib_protocol/michelson_v1_primitives.ml b/src/proto_alpha/lib_protocol/michelson_v1_primitives.ml index c0bf8dfc858e5e8aa09363e3f549d2268eec5559..63fb1d788b93bc266b882479d7abc8fe68c38518 100644 --- a/src/proto_alpha/lib_protocol/michelson_v1_primitives.ml +++ b/src/proto_alpha/lib_protocol/michelson_v1_primitives.ml @@ -85,6 +85,7 @@ type prim = | I_GE | I_GET | I_GET_AND_UPDATE + | I_GET_COUNTER | I_GT | I_HASH_KEY | I_IF @@ -122,6 +123,7 @@ type prim = | I_SENDER | I_SELF | I_SELF_ADDRESS + | I_SET_COUNTER | I_SLICE | I_STEPS_TO_QUOTA | I_SUB @@ -213,14 +215,14 @@ let namespace = function | I_COMPARE | I_CONCAT | I_CONS | I_CONTRACT | I_CREATE_ACCOUNT | I_CREATE_CONTRACT | I_DIG | I_DIP | I_DROP | I_DUG | I_DUP | I_VIEW | I_EDIV | I_EMPTY_BIG_MAP | I_EMPTY_MAP | I_EMPTY_SET | I_EQ | I_EXEC | I_FAILWITH - | I_GE | I_GET | I_GET_AND_UPDATE | I_GT | I_HASH_KEY | I_IF | I_IF_CONS - | I_IF_LEFT | I_IF_NONE | I_IMPLICIT_ACCOUNT | I_INT | I_ISNAT | I_ITER - | I_JOIN_TICKETS | I_KECCAK | I_LAMBDA | I_LAMBDA_REC | I_LE | I_LEFT + | I_GE | I_GET | I_GET_AND_UPDATE | I_GET_COUNTER | I_GT | I_HASH_KEY | I_IF + | I_IF_CONS | I_IF_LEFT | I_IF_NONE | I_IMPLICIT_ACCOUNT | I_INT | I_ISNAT + | I_ITER | I_JOIN_TICKETS | I_KECCAK | I_LAMBDA | I_LAMBDA_REC | I_LE | I_LEFT | I_LEVEL | I_LOOP | I_LOOP_LEFT | I_LSL | I_LSR | I_LT | I_MAP | I_MEM | I_MUL | I_NEG | I_NEQ | I_NEVER | I_NIL | I_NONE | I_NOT | I_NOW | I_MIN_BLOCK_TIME | I_OR | I_PACK | I_PAIR | I_PAIRING_CHECK | I_PUSH | I_READ_TICKET | I_RENAME | I_RIGHT | I_SAPLING_EMPTY_STATE - | I_SAPLING_VERIFY_UPDATE | I_SELF | I_SELF_ADDRESS | I_SENDER + | I_SAPLING_VERIFY_UPDATE | I_SELF | I_SELF_ADDRESS | I_SENDER | I_SET_COUNTER | I_SET_DELEGATE | I_SHA256 | I_SHA512 | I_SHA3 | I_SIZE | I_SLICE | I_SOME | I_SOURCE | I_SPLIT_TICKET | I_STEPS_TO_QUOTA | I_SUB | I_SUB_MUTEZ | I_SWAP | I_TICKET | I_TICKET_DEPRECATED | I_TOTAL_VOTING_POWER | I_TRANSFER_TOKENS @@ -297,6 +299,7 @@ let string_of_prim = function | I_GE -> "GE" | I_GET -> "GET" | I_GET_AND_UPDATE -> "GET_AND_UPDATE" + | I_GET_COUNTER -> "GET_COUNTER" | I_GT -> "GT" | I_HASH_KEY -> "HASH_KEY" | I_IF -> "IF" @@ -333,6 +336,7 @@ let string_of_prim = function | I_SENDER -> "SENDER" | I_SELF -> "SELF" | I_SELF_ADDRESS -> "SELF_ADDRESS" + | I_SET_COUNTER -> "SET_COUNTER" | I_SLICE -> "SLICE" | I_STEPS_TO_QUOTA -> "STEPS_TO_QUOTA" | I_SUB -> "SUB" @@ -457,6 +461,7 @@ let prim_of_string = function | "GE" -> ok I_GE | "GET" -> ok I_GET | "GET_AND_UPDATE" -> ok I_GET_AND_UPDATE + | "GET_COUNTER" -> ok I_GET_COUNTER | "GT" -> ok I_GT | "HASH_KEY" -> ok I_HASH_KEY | "IF" -> ok I_IF @@ -497,6 +502,7 @@ let prim_of_string = function | "SENDER" -> ok I_SENDER | "SELF" -> ok I_SELF | "SELF_ADDRESS" -> ok I_SELF_ADDRESS + | "SET_COUNTER" -> ok I_SET_COUNTER | "SLICE" -> ok I_SLICE | "STEPS_TO_QUOTA" -> ok I_STEPS_TO_QUOTA | "SUB" -> ok I_SUB @@ -784,7 +790,11 @@ let prim_encoding = ("LAMBDA_REC", I_LAMBDA_REC); ("TICKET", I_TICKET); ("BYTES", I_BYTES); - ("NAT", I_NAT) + ("NAT", I_NAT); + (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) + (* Alpha_018 addition *) + ("GET_COUNTER", I_GET_COUNTER); + ("SET_COUNTER", I_SET_COUNTER) (* New instructions must be added here, for backward compatibility of the encoding. *) (* Keep the comment above at the end of the list *); ] diff --git a/src/proto_alpha/lib_protocol/michelson_v1_primitives.mli b/src/proto_alpha/lib_protocol/michelson_v1_primitives.mli index 761631190abad0277bf956b546bdb0afc6f38448..7ca2afca888d97a103e91e1b5c0ca5194ed4646d 100644 --- a/src/proto_alpha/lib_protocol/michelson_v1_primitives.mli +++ b/src/proto_alpha/lib_protocol/michelson_v1_primitives.mli @@ -97,6 +97,7 @@ type prim = | I_GE | I_GET | I_GET_AND_UPDATE + | I_GET_COUNTER | I_GT | I_HASH_KEY | I_IF @@ -134,6 +135,7 @@ type prim = | I_SENDER | I_SELF | I_SELF_ADDRESS + | I_SET_COUNTER | I_SLICE | I_STEPS_TO_QUOTA | I_SUB diff --git a/src/proto_alpha/lib_protocol/mock_counter_storage.ml b/src/proto_alpha/lib_protocol/mock_counter_storage.ml new file mode 100644 index 0000000000000000000000000000000000000000..54e98070d463bc5cfdb2326bcb79d11921263b63 --- /dev/null +++ b/src/proto_alpha/lib_protocol/mock_counter_storage.ml @@ -0,0 +1,53 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 TriliTech *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Chose the key of the "mock_counter" in the map storage to be Int64.zero, + as it is not important. Chose the Z.of_int 0 return value as the default for + when the mock_counter is not initialised. *) + +let mock_counter_key = Int64.zero + +let update_value ctxt value = + let open Lwt_result_syntax in + let* ctxt, stored_value = Storage.Mock_counter.find ctxt mock_counter_key in + match stored_value with + | Some prev_value -> + let new_value = Z.add prev_value value in + let* new_ctxt, size_diff = + Storage.Mock_counter.update ctxt mock_counter_key new_value + in + return (new_ctxt, size_diff) + | None -> + let* new_ctxt, size_diff = + Storage.Mock_counter.init ctxt mock_counter_key value + in + return (new_ctxt, size_diff) + +let get_value ctxt = + let open Lwt_result_syntax in + let* ctxt, stored_value = Storage.Mock_counter.find ctxt mock_counter_key in + match stored_value with + | Some value -> return (ctxt, value) + | None -> return (ctxt, Z.of_int 0) diff --git a/src/proto_alpha/lib_protocol/mock_counter_storage.mli b/src/proto_alpha/lib_protocol/mock_counter_storage.mli new file mode 100644 index 0000000000000000000000000000000000000000..07ce1e4a7aa0f1f8a0327690dff76da6c953b8dd --- /dev/null +++ b/src/proto_alpha/lib_protocol/mock_counter_storage.mli @@ -0,0 +1,36 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 TriliTech *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Functions to update/retrieve the value of the mock counter *) + +(** [update_value context z] adds z to the current value of the mock counter + from context, or initialises the counter with z, if the mock counter was not + yet initialised in context. *) +val update_value : Raw_context.t -> Z.t -> (Raw_context.t * int) tzresult Lwt.t + +(** [get_value context] retrieves the current value of the mock counter from + the current context, or returns a default value if the mock counter was + not yet initialised. *) +val get_value : Raw_context.t -> (Raw_context.t * Z.t) tzresult Lwt.t diff --git a/src/proto_alpha/lib_protocol/operation_repr.ml b/src/proto_alpha/lib_protocol/operation_repr.ml index 7d89955b1199c55ed96b11c3513277ad76d1a0ef..cfff010ade58c2e5d954415c52c19a905b0e352d 100644 --- a/src/proto_alpha/lib_protocol/operation_repr.ml +++ b/src/proto_alpha/lib_protocol/operation_repr.ml @@ -111,6 +111,8 @@ module Kind = struct type zk_rollup_update = Zk_rollup_update_kind + type mock_counter_update = Mock_counter_update_kind + type 'a manager = | Reveal_manager_kind : reveal manager | Transaction_manager_kind : transaction manager @@ -135,6 +137,7 @@ module Kind = struct | Zk_rollup_origination_manager_kind : zk_rollup_origination manager | Zk_rollup_publish_manager_kind : zk_rollup_publish manager | Zk_rollup_update_manager_kind : zk_rollup_update manager + | Mock_counter_update_manager_kind : mock_counter_update manager end type 'a consensus_operation_type = @@ -412,6 +415,10 @@ and _ manager_operation = update : Zk_rollup_update_repr.t; } -> Kind.zk_rollup_update manager_operation + | Mock_counter_update : { + value : Z.t; + } + -> Kind.mock_counter_update manager_operation let manager_kind : type kind. kind manager_operation -> kind Kind.manager = function @@ -437,6 +444,7 @@ let manager_kind : type kind. kind manager_operation -> kind Kind.manager = | Zk_rollup_origination _ -> Kind.Zk_rollup_origination_manager_kind | Zk_rollup_publish _ -> Kind.Zk_rollup_publish_manager_kind | Zk_rollup_update _ -> Kind.Zk_rollup_update_manager_kind + | Mock_counter_update _ -> Kind.Mock_counter_update_manager_kind type packed_manager_operation = | Manager : 'kind manager_operation -> packed_manager_operation @@ -551,6 +559,8 @@ let dal_offset = 230 let dal_publish_slot_header_tag = dal_offset + 0 +let mock_counter_update_tag = 240 + let zk_rollup_operation_tag_offset = 250 let zk_rollup_operation_create_tag = zk_rollup_operation_tag_offset + 0 @@ -1018,6 +1028,19 @@ module Encoding = struct (fun (sc_rollup, staker) -> Sc_rollup_recover_bond {sc_rollup; staker}); } + + let mock_counter_update_case = + MCase + { + tag = mock_counter_update_tag; + name = "mock_counter_update"; + encoding = obj1 (req "value" Data_encoding.z); + select = + (function + | Manager (Mock_counter_update _ as op) -> Some op | _ -> None); + proj = (function Mock_counter_update {value} -> value); + inj = (fun value -> Mock_counter_update {value}); + } end type 'b case = @@ -1555,6 +1578,11 @@ module Encoding = struct zk_rollup_operation_update_tag Manager_operations.zk_rollup_update_case + let mock_counter_update_case = + make_manager_case + mock_counter_update_tag + Manager_operations.mock_counter_update_case + type packed_case = PCase : 'b case -> packed_case let common_cases = @@ -1589,6 +1617,7 @@ module Encoding = struct PCase zk_rollup_origination_case; PCase zk_rollup_publish_case; PCase zk_rollup_update_case; + PCase mock_counter_update_case; ] let contents_cases = @@ -2056,6 +2085,8 @@ let equal_manager_operation_kind : | Zk_rollup_publish _, _ -> None | Zk_rollup_update _, Zk_rollup_update _ -> Some Eq | Zk_rollup_update _, _ -> None + | Mock_counter_update _, Mock_counter_update _ -> Some Eq + | Mock_counter_update _, _ -> None let equal_contents_kind : type a b. a contents -> b contents -> (a, b) eq option = diff --git a/src/proto_alpha/lib_protocol/operation_repr.mli b/src/proto_alpha/lib_protocol/operation_repr.mli index 370f4a115f21b49ee99a62758e16bf481d007693..1baa5af8b18db97ddcdc06b08806fc7f08c421e7 100644 --- a/src/proto_alpha/lib_protocol/operation_repr.mli +++ b/src/proto_alpha/lib_protocol/operation_repr.mli @@ -54,6 +54,7 @@ - zk rollup origination - zk rollup publish - zk rollup update + - mock counter update Each of them can be encoded as raw bytes. Operations are distinguished at type level using phantom type parameters. [packed_operation] type allows @@ -145,6 +146,9 @@ module Kind : sig type zk_rollup_update = Zk_rollup_update_kind + (** Define mock counter update manager operation kind. *) + type mock_counter_update = Mock_counter_update_kind + type 'a manager = | Reveal_manager_kind : reveal manager | Transaction_manager_kind : transaction manager @@ -169,6 +173,7 @@ module Kind : sig | Zk_rollup_origination_manager_kind : zk_rollup_origination manager | Zk_rollup_publish_manager_kind : zk_rollup_publish manager | Zk_rollup_update_manager_kind : zk_rollup_update manager + | Mock_counter_update_manager_kind : mock_counter_update manager end type 'a consensus_operation_type = @@ -503,6 +508,10 @@ and _ manager_operation = update : Zk_rollup_update_repr.t; } -> Kind.zk_rollup_update manager_operation + | Mock_counter_update : { + value : Z.t; + } + -> Kind.mock_counter_update manager_operation type packed_manager_operation = | Manager : 'kind manager_operation -> packed_manager_operation @@ -762,6 +771,9 @@ module Encoding : sig val zk_rollup_update_case : Kind.zk_rollup_update Kind.manager case + (** Encode the mock counter manager operation. *) + val mock_counter_update_case : Kind.mock_counter_update Kind.manager case + module Manager_operations : sig type 'b case = | MCase : { @@ -818,6 +830,9 @@ module Encoding : sig val zk_rollup_publish_case : Kind.zk_rollup_publish case val zk_rollup_update_case : Kind.zk_rollup_update case + + (** Define mock counter update manager operation. *) + val mock_counter_update_case : Kind.mock_counter_update case end end diff --git a/src/proto_alpha/lib_protocol/script_interpreter.ml b/src/proto_alpha/lib_protocol/script_interpreter.ml index e90e9c291fb0689bab4037e0035dee90420be853..64b7c0058fc313ff7378443e01c21bc41380dbca 100644 --- a/src/proto_alpha/lib_protocol/script_interpreter.ml +++ b/src/proto_alpha/lib_protocol/script_interpreter.ml @@ -1284,6 +1284,27 @@ module Raw = struct in let new_stack = (accu, stack) in (step [@ocaml.tailcall]) g gas k ks min_block_time new_stack + | IGet_counter (_, k) -> + let ctxt = update_context gas ctxt in + let open Lwt_result_syntax in + let* ctxt, z_counter = Alpha_context.Mock_counter.get_value ctxt in + let int_counter = Script_int.of_int64 @@ Z.to_int64 z_counter in + let gas, ctxt = local_gas_counter_and_outdated_context ctxt in + let new_stack = (accu, stack) in + (step [@ocaml.tailcall]) (ctxt, sc) gas k ks int_counter new_stack + | ISet_counter (_, k) -> + let x = accu and y, stack = stack in + let value = Script_int.to_zint x in + let ctxt = update_context gas ctxt in + let open Lwt_result_syntax in + let* ctxt, z_counter = Alpha_context.Mock_counter.get_value ctxt in + let* ctxt, _ = + Alpha_context.Mock_counter.update_value + ctxt + (Z.sub value z_counter) + in + let gas, ctxt = local_gas_counter_and_outdated_context ctxt in + (step [@ocaml.tailcall]) (ctxt, sc) gas k ks y stack | ICheck_signature (_, k) -> let key = accu and signature, (message, stack) = stack in let res = Script_signature.check key signature message in diff --git a/src/proto_alpha/lib_protocol/script_interpreter_defs.ml b/src/proto_alpha/lib_protocol/script_interpreter_defs.ml index 7b6265d4e76df2659dd12e14a5a5b104e05c2e9f..0fb5b10dcbd7b783c2a23dcbbf1ca4a31758503d 100644 --- a/src/proto_alpha/lib_protocol/script_interpreter_defs.ml +++ b/src/proto_alpha/lib_protocol/script_interpreter_defs.ml @@ -360,6 +360,8 @@ let cost_of_instr : type a s r f. (a, s, r, f) kinstr -> a -> s -> Gas.cost = | ILevel _ -> Interp_costs.level | INow _ -> Interp_costs.now | IMin_block_time _ -> Interp_costs.min_block_time + | IGet_counter _ -> Interp_costs.get_counter + | ISet_counter _ -> Interp_costs.set_counter | ISapling_empty_state _ -> Interp_costs.sapling_empty_state | ISource _ -> Interp_costs.source | ISender _ -> Interp_costs.sender diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index 4093dccc15385cefc3e4498e63d35390abeca56d..2b753c9b4d8df08fb4098430596d8f419e2f80b6 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -4046,6 +4046,14 @@ and parse_instr : loc {apply = (fun k -> IMin_block_time (loc, k))} (Item_t (nat_t, stack)) + | Prim (loc, I_GET_COUNTER, [], _), stack -> + typed + ctxt + loc + {apply = (fun k -> IGet_counter (loc, k))} + (Item_t (int_t, stack)) + | Prim (loc, I_SET_COUNTER, [], _), Item_t (Int_t, rest) -> + typed ctxt loc {apply = (fun k -> ISet_counter (loc, k))} rest | Prim (loc, I_AMOUNT, [], annot), stack -> check_var_annot loc annot >>?= fun () -> let instr = {apply = (fun k -> IAmount (loc, k))} in diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.ml b/src/proto_alpha/lib_protocol/script_typed_ir.ml index 2edc9f236e7d46ad11d4c5e9ad0a698c81365c65..7a907df2d0ae121fd2eb3741c686a3a8b501e267 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.ml +++ b/src/proto_alpha/lib_protocol/script_typed_ir.ml @@ -914,6 +914,12 @@ and ('before_top, 'before, 'result_top, 'result) kinstr = | IMin_block_time : Script.location * (n num, 'a * 'S, 'r, 'F) kinstr -> ('a, 'S, 'r, 'F) kinstr + | IGet_counter : + Script.location * (z num, 'a * 'S, 'r, 'F) kinstr + -> ('a, 'S, 'r, 'F) kinstr + | ISet_counter : + Script.location * ('a, 'S, 'r, 'F) kinstr + -> (z num, 'a * 'S, 'r, 'F) kinstr | IBalance : Script.location * (Tez.t, 'a * 'S, 'r, 'F) kinstr -> ('a, 'S, 'r, 'F) kinstr @@ -1653,6 +1659,8 @@ let kinstr_location : type a s b f. (a, s, b, f) kinstr -> Script.location = | ISet_delegate (loc, _) -> loc | INow (loc, _) -> loc | IMin_block_time (loc, _) -> loc + | IGet_counter (loc, _) -> loc + | ISet_counter (loc, _) -> loc | IBalance (loc, _) -> loc | ILevel (loc, _) -> loc | ICheck_signature (loc, _) -> loc @@ -2202,6 +2210,8 @@ let kinstr_traverse i init f = | ISet_delegate (_, k) -> (next [@ocaml.tailcall]) k | INow (_, k) -> (next [@ocaml.tailcall]) k | IMin_block_time (_, k) -> (next [@ocaml.tailcall]) k + | IGet_counter (_, k) -> (next [@ocaml.tailcall]) k + | ISet_counter (_, k) -> (next [@ocaml.tailcall]) k | IBalance (_, k) -> (next [@ocaml.tailcall]) k | ILevel (_, k) -> (next [@ocaml.tailcall]) k | ICheck_signature (_, k) -> (next [@ocaml.tailcall]) k diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.mli b/src/proto_alpha/lib_protocol/script_typed_ir.mli index ff246e041dce4b44787d94fa0bb87c769fd875b3..bab1fee58e1f3e7c6a80402c309ddcefbf9f90d2 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.mli +++ b/src/proto_alpha/lib_protocol/script_typed_ir.mli @@ -902,6 +902,12 @@ and ('before_top, 'before, 'result_top, 'result) kinstr = | IMin_block_time : Script.location * (n num, 'a * 'S, 'r, 'F) kinstr -> ('a, 'S, 'r, 'F) kinstr + | IGet_counter : + Script.location * (z num, 'a * 'S, 'r, 'F) kinstr + -> ('a, 'S, 'r, 'F) kinstr + | ISet_counter : + Script.location * ('a, 'S, 'r, 'F) kinstr + -> (z num, 'a * 'S, 'r, 'F) kinstr | IBalance : Script.location * (Tez.t, 'a * 'S, 'r, 'F) kinstr -> ('a, 'S, 'r, 'F) kinstr diff --git a/src/proto_alpha/lib_protocol/script_typed_ir_size.ml b/src/proto_alpha/lib_protocol/script_typed_ir_size.ml index 2bb0e205b60425c020c298df173bea7c8be4c80b..70c6f36d02e9cdf554d5be10df8b79b917b1e065 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir_size.ml +++ b/src/proto_alpha/lib_protocol/script_typed_ir_size.ml @@ -587,6 +587,8 @@ and kinstr_size : | ISet_delegate (loc, k) -> ret_succ_adding accu (base1 loc k) | INow (loc, k) -> ret_succ_adding accu (base1 loc k) | IMin_block_time (loc, k) -> ret_succ_adding accu (base1 loc k) + | IGet_counter (loc, k) -> ret_succ_adding accu (base1 loc k) + | ISet_counter (loc, k) -> ret_succ_adding accu (base1 loc k) | IBalance (loc, k) -> ret_succ_adding accu (base1 loc k) | ILevel (loc, k) -> ret_succ_adding accu (base1 loc k) | ICheck_signature (loc, k) -> ret_succ_adding accu (base1 loc k) diff --git a/src/proto_alpha/lib_protocol/storage.ml b/src/proto_alpha/lib_protocol/storage.ml index 86e52b2cf4076d971e8d47305c9c8c0365f415d4..e77806689aafe58a9253050a8c3bb370af5fa575 100644 --- a/src/proto_alpha/lib_protocol/storage.ml +++ b/src/proto_alpha/lib_protocol/storage.ml @@ -409,6 +409,53 @@ module Contract = struct (Tez_repr) end +module Mock_counter : + Non_iterable_indexed_carbonated_data_storage + with type t := Raw_context.t + and type key = int64 + and type value = Z.t = + Make_indexed_carbonated_data_storage + (Make_subcontext (Registered) (Raw_context) + (struct + let name = ["mock_counter"] + end)) + (Make_index (struct + type t = int64 + + let rpc_arg = + let construct = Int64.to_string in + let destruct hash = + Int64.of_string_opt hash + |> Result.of_option ~error:"Cannot parse mock counter" + in + RPC_arg.make + ~descr:"The position of a mock counter" + ~name:"mock_counter_position" + ~construct + ~destruct + () + + let encoding = + Data_encoding.def + "mock_counter_position" + ~title:"Mock counter position" + ~description:"The position of a mock counter" + Data_encoding.int64 + + let compare = Compare.Int64.compare + + let path_length = 1 + + let to_path c l = Int64.to_string c :: l + + let of_path = function [c] -> Int64.of_string_opt c | _ -> None + end)) + (struct + type t = Z.t + + let encoding = Data_encoding.z + end) + module type NEXT = sig type id diff --git a/src/proto_alpha/lib_protocol/storage.mli b/src/proto_alpha/lib_protocol/storage.mli index a82d10ee85a5042ff486251e965114c77bf70b48..e0b5cd8b0251c6c43c3b524ade612d7dde957749 100644 --- a/src/proto_alpha/lib_protocol/storage.mli +++ b/src/proto_alpha/lib_protocol/storage.mli @@ -231,6 +231,14 @@ module Contract : sig and type t := Raw_context.t end +(** Includes a key-value pair to store the value of the mock counter. The key + is a default constant. *) +module Mock_counter : + Non_iterable_indexed_carbonated_data_storage + with type t := Raw_context.t + and type key = int64 + and type value = Z.t + module Big_map : sig type id = Lazy_storage_kind.Big_map.Id.t diff --git a/src/proto_alpha/lib_protocol/test/helpers/block.ml b/src/proto_alpha/lib_protocol/test/helpers/block.ml index f4a27c7aaf6570fae59dea986484825152b14b2e..5e1669169c6b075a84ab8d561f158f1473f5fbfa 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/block.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/block.ml @@ -901,7 +901,8 @@ let bake_n_with_all_balance_updates ?(baking_mode = Application) ?policy | Sc_rollup_refute_result _ | Sc_rollup_timeout_result _ | Sc_rollup_execute_outbox_message_result _ | Sc_rollup_recover_bond_result _ | Zk_rollup_origination_result _ - | Zk_rollup_publish_result _ | Zk_rollup_update_result _ -> + | Zk_rollup_publish_result _ | Zk_rollup_update_result _ + | Mock_counter_update_result _ -> balance_updates_rev | Transaction_result ( Transaction_to_contract_result {balance_updates; _} @@ -947,7 +948,8 @@ let bake_n_with_origination_results ?(baking_mode = Application) ?policy n b = | Successful_manager_result (Sc_rollup_recover_bond_result _) | Successful_manager_result (Zk_rollup_origination_result _) | Successful_manager_result (Zk_rollup_publish_result _) - | Successful_manager_result (Zk_rollup_update_result _) -> + | Successful_manager_result (Zk_rollup_update_result _) + | Successful_manager_result (Mock_counter_update_result _) -> origination_results_rev | Successful_manager_result (Origination_result x) -> Origination_result x :: origination_results_rev) diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/dune b/src/proto_alpha/lib_protocol/test/integration/michelson/dune index b2b7e98360c084985434e0950d3f9a728126c0ea..c2e957ac3014cecc3f788d092e1234f81a9d2e92 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/dune +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/dune @@ -37,6 +37,7 @@ (modules test_annotations test_block_time_instructions + test_mock_counter_instructions test_contract_event test_global_constants_storage test_interpretation diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_mock_counter_instructions.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_mock_counter_instructions.ml new file mode 100644 index 0000000000000000000000000000000000000000..63e3bdb2bd635b05715bf804649b06156c9bb684 --- /dev/null +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_mock_counter_instructions.ml @@ -0,0 +1,123 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 TriliTech *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (Michelson mock counter instructions) + Invocation: dune exec src/proto_alpha/lib_protocol/test/integration/michelson/main.exe \ + -- --file test_mock_counter_instructions.ml + Subject: This module tests that Michelson instructions related to mock counter are correct. +*) + +open Protocol +open Alpha_context +open Lwt_result_syntax + +let make_context () = + let* block, _ = Context.init1 () in + let* incr = Incremental.begin_construction block in + return (Incremental.alpha_ctxt incr) + +let test_mock_counter_get () = + let open Lwt_result_wrap_syntax in + let* context = make_context () in + let* result, _ = + Contract_helpers.run_script + context + ~storage:"0" + ~parameter:"Unit" + {| { parameter unit; storage int; code { DROP; GET_COUNTER; NIL operation; PAIR } } |} + () + in + let*@ _, expected_value = Mock_counter.get_value context in + match Micheline.root result.storage with + | Int (_, result_storage) when Z.equal result_storage expected_value -> + return_unit + | _ -> + failwith + "Expected storage to be %a, but got %a" + Z.pp_print + expected_value + Micheline_printer.print_expr + (Micheline_printer.printable + Michelson_v1_primitives.string_of_prim + result.storage) + +let test_mock_counter_update () = + let open Lwt_result_wrap_syntax in + let* context = make_context () in + let* result, _ = + Contract_helpers.run_script + context + ~storage:"0" + ~parameter:"Unit" + {| + { parameter unit; + storage int; + code + { DROP; + GET_COUNTER; + PUSH int 17; + ADD; + SET_COUNTER; + GET_COUNTER; + NIL operation; + PAIR } } + |} + () + in + let*@ _, past_value = Mock_counter.get_value context in + let expected_value = Z.add past_value (Z.of_int 17) in + match Micheline.root result.storage with + | Int (_, result_storage) when Z.equal result_storage expected_value -> + return_unit + | _ -> + failwith + "Expected storage to be %a, but got %a" + Z.pp_print + expected_value + Micheline_printer.print_expr + (Micheline_printer.printable + Michelson_v1_primitives.string_of_prim + result.storage) + +let tests = + [ + Tztest.tztest + "GET_COUNTER gives current value of mock counter" + `Quick + test_mock_counter_get; + Tztest.tztest + "SET_COUNTER set a new value for the mock counter" + `Quick + test_mock_counter_update; + ] + +let () = + Alcotest_lwt.run + ~__FILE__ + Protocol.name + [("mock counter instructions", tests)] + |> Lwt_main.run diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_script_typed_ir_size.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_script_typed_ir_size.ml index 6422c891e5d9471a7d33f80edd42ce19e92515c2..c783d4ec05f6c4ac32f70ed049806f8e74f2759b 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_script_typed_ir_size.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_script_typed_ir_size.ml @@ -904,6 +904,8 @@ let check_kinstr_size () = Kinstr ("ISet_delegate", ISet_delegate (loc, halt ())); Kinstr ("INow", INow (loc, halt ())); Kinstr ("IMin_block_time", IMin_block_time (loc, halt ())); + Kinstr ("IGet_counter", IGet_counter (loc, halt ())); + Kinstr ("ISet_counter", ISet_counter (loc, halt ())); Kinstr ("IBalance", IBalance (loc, halt ())); Kinstr ("ILevel", ILevel (loc, halt ())); Kinstr ("ICheck_signature", ICheck_signature (loc, halt ())); diff --git a/src/proto_alpha/lib_protocol/test/integration/validate/test_sanity.ml b/src/proto_alpha/lib_protocol/test/integration/validate/test_sanity.ml index 3d0aaa65df45bc7357898fdef797cfab98edd6b6..77d81147ece192158857acba6a4364d56ec9a399 100644 --- a/src/proto_alpha/lib_protocol/test/integration/validate/test_sanity.ml +++ b/src/proto_alpha/lib_protocol/test/integration/validate/test_sanity.ml @@ -87,7 +87,7 @@ let ensure_kind infos kind = | Sc_rollup_add_messages _ | Sc_rollup_refute _ | Sc_rollup_timeout _ | Sc_rollup_execute_outbox_message _ | Sc_rollup_recover_bond _ | Dal_publish_slot_header _ | Zk_rollup_origination _ - | Zk_rollup_publish _ | Zk_rollup_update _ ), + | Zk_rollup_publish _ | Zk_rollup_update _ | Mock_counter_update _ ), _ ) -> assert false) | Single _ -> assert false diff --git a/src/proto_alpha/lib_protocol/test/unit/dune b/src/proto_alpha/lib_protocol/test/unit/dune index 75d1f001ab4b3a83ca7b8e1d72fa5a8d39b43c5a..1fb381ada128fc66adb7afe6f6a4e5f70a567a36 100644 --- a/src/proto_alpha/lib_protocol/test/unit/dune +++ b/src/proto_alpha/lib_protocol/test/unit/dune @@ -71,7 +71,8 @@ test_sc_rollup_inbox_legacy test_sc_rollup_wasm test_local_contexts - test_dal_slot_proof)) + test_dal_slot_proof + test_mock_counter_storage)) (executable (name main) diff --git a/src/proto_alpha/lib_protocol/test/unit/test_mock_counter_storage.ml b/src/proto_alpha/lib_protocol/test/unit/test_mock_counter_storage.ml new file mode 100644 index 0000000000000000000000000000000000000000..32c506f770161822eaa50be99560965ba0848e86 --- /dev/null +++ b/src/proto_alpha/lib_protocol/test/unit/test_mock_counter_storage.ml @@ -0,0 +1,74 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 TriliTech *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol Mock_counter_storage + Invocation: dune exec src/proto_alpha/lib_protocol/test/unit/main.exe \ + -- --file test_mock_counter_storage.ml + Subject: Tests for the Counter onboarding challenge +*) +open Protocol + +open Alpha_context +open Lwt_result_syntax + +let make_context () = + let* block, _contract = Context.init1 () in + let* incr = Incremental.begin_construction block in + return (Incremental.alpha_ctxt incr) + +let test_init () = + let* ctxt = make_context () in + let _ = + let* new_ctxt, _ = Mock_counter.update_value ctxt (Z.of_int 1) in + let* _, new_value = Mock_counter.get_value new_ctxt in + assert (new_value = Z.of_int 1) ; + return_unit + in + return_unit + +let test_add () = + let* ctxt = make_context () in + let _ = + let* new_ctxt1, _ = Mock_counter.update_value ctxt (Z.of_int 1) in + let* new_ctxt1, new_value1 = Mock_counter.get_value new_ctxt1 in + assert (new_value1 = Z.of_int 1) ; + let* new_ctxt2, _ = Mock_counter.update_value new_ctxt1 (Z.of_int 2) in + let* _, new_value2 = Mock_counter.get_value new_ctxt2 in + assert (new_value2 = Z.of_int 3) ; + return_unit + in + return_unit + +let tests = + [ + Tztest.tztest "Initialise mock counter with value" `Quick test_init; + Tztest.tztest "Initialise mock counter and add value" `Quick test_add; + ] + +let () = + Alcotest_lwt.run ~__FILE__ Protocol.name [("mock counter tests", tests)] + |> Lwt_main.run diff --git a/src/proto_alpha/lib_protocol/validate.ml b/src/proto_alpha/lib_protocol/validate.ml index dba8f7026b81f09cf4b1dbea17cae680f2581e6e..d734725df297f771190cd3bb0e12c1673aa94ee5 100644 --- a/src/proto_alpha/lib_protocol/validate.ml +++ b/src/proto_alpha/lib_protocol/validate.ml @@ -2117,6 +2117,7 @@ module Manager = struct Dal_apply.validate_publish_slot_header vi.ctxt slot_header | Zk_rollup_origination _ | Zk_rollup_publish _ | Zk_rollup_update _ -> assert_zk_rollup_feature_enabled vi + | Mock_counter_update _ -> return_unit in (* Gas should no longer be consumed below this point, because it would not take into account any gas consumed during the pattern diff --git a/src/proto_alpha/lib_sc_rollup_node/daemon.ml b/src/proto_alpha/lib_sc_rollup_node/daemon.ml index a53ac6cb324c75f7bbf76cb61e01c1438f2b0404..9e779a92b6963764f85fca9f5ecca7533842e00c 100644 --- a/src/proto_alpha/lib_sc_rollup_node/daemon.ml +++ b/src/proto_alpha/lib_sc_rollup_node/daemon.ml @@ -240,7 +240,7 @@ module Make (PVM : Pvm.S) = struct | Update_consensus_key _ | Register_global_constant _ | Set_deposits_limit _ | Increase_paid_storage _ | Transfer_ticket _ | Sc_rollup_originate _ | Zk_rollup_origination _ | Zk_rollup_publish _ - | Zk_rollup_update _ -> + | Zk_rollup_update _ | Mock_counter_update _ -> false in if not (is_for_my_rollup operation) then return_unit diff --git a/tezt/lib_tezos/client.ml b/tezt/lib_tezos/client.ml index c1c46e0184e8388742ca87c94e7f2615f0a1154a..431bf406920949231370fab6271f35298171dc28 100644 --- a/tezt/lib_tezos/client.ml +++ b/tezt/lib_tezos/client.ml @@ -3967,3 +3967,22 @@ let get_timestamp ?endpoint ?block ?seconds client = |> Process.check_and_read_stdout in return (String.trim output) + +let mock_counter_update ~src value client = + spawn_command + client + [ + "--wait"; + "none"; + "update"; + "mock"; + "counter"; + "with"; + Int.to_string value; + src; + ] + |> Process.check + +let mock_counter_get client = + spawn_command client ["get"; "mock"; "counter"] + |> Process.check_and_read_stdout diff --git a/tezt/lib_tezos/client.mli b/tezt/lib_tezos/client.mli index dfcf270478939497bede67028fcdea431a4ab5a1..46dd52b6a375c72466f12722308ad02d41e0cc95 100644 --- a/tezt/lib_tezos/client.mli +++ b/tezt/lib_tezos/client.mli @@ -2845,3 +2845,9 @@ val get_timestamp : (** Same as [get_timestamp], but do not wait for the process to exit. *) val spawn_get_timestamp : ?endpoint:endpoint -> ?block:string -> ?seconds:bool -> t -> Process.t + +(** Run [tezos-client update mock counter with
]. *) +val mock_counter_update : src:string -> int -> t -> unit Lwt.t + +(** Run [tezos-client get mock counter]. *) +val mock_counter_get : t -> string Lwt.t diff --git a/tezt/tests/main.ml b/tezt/tests/main.ml index 0e63ab26eced5ae27969cf511be5a60435fb38a1..26c22979fca3ebd8ac0edadbe548f4e5ff6c3632 100644 --- a/tezt/tests/main.ml +++ b/tezt/tests/main.ml @@ -143,6 +143,7 @@ let register_protocol_tests_that_use_supports_correctly () = Light.register ~protocols ; Liquidity_baking_per_block_votes.register ~protocols ; Manager_operations.register ~protocols ; + Mock_counter.register ~protocols ; Mockup.register ~protocols ; Mockup.register_global_constants ~protocols ; Monitor_operations.register ~protocols ; diff --git a/tezt/tests/mock_counter.ml b/tezt/tests/mock_counter.ml new file mode 100644 index 0000000000000000000000000000000000000000..052f823d136cd2073bee35fbb3e82e40cabe2956 --- /dev/null +++ b/tezt/tests/mock_counter.ml @@ -0,0 +1,60 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 TriliTech *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Testing + ------- + Component: Mock_counter + Invocation: dune exec tezt/tests/main.exe -- --file mock_counter.ml + Subject: Tests for the client's mock_counter commands +*) + +let get_mock_counter_pp value = + "Value of the mock counter: " ^ Int.to_string value ^ "\n" + +let test_update_mock_counter = + Protocol.register_test + ~__FILE__ + ~title:"Update mock counter twice" + ~tags:["mock_counter"] + ~supports:(Protocol.From_protocol 018) + @@ fun protocol -> + let test_value1 = 17 in + let* _, client = Client.init_with_protocol ~protocol `Client () in + let* () = Client.mock_counter_update ~src:"bootstrap1" test_value1 client in + let* () = Client.bake_for_and_wait client in + let* value1 = Client.mock_counter_get client in + Check.(value1 = get_mock_counter_pp test_value1) + Check.string + ~error_msg:"Wrong mock counter value. Expected %R. Got %L" ; + let test_value2 = 100 in + let* () = Client.mock_counter_update ~src:"bootstrap2" test_value2 client in + let* () = Client.bake_for_and_wait client in + let* value2 = Client.mock_counter_get client in + Check.(value2 = get_mock_counter_pp (test_value1 + test_value2)) + Check.string + ~error_msg:"Wrong mock counter value. Expected %R. Got %L " ; + unit + +let register ~protocols = test_update_mock_counter protocols