123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2023 Nomadic Labs, <contact@nomadic-labs.com> *)(* Copyright (c) 2023 Functori, <contact@functori.com> *)(* *)(* 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. *)(* *)(*****************************************************************************)(** Defines the strategy for a worker. *)typeinjection_strategy=[`Each_block(** Inject pending operations after each new L1 block *)|`Delay_blockoffloat(** [`Delay_block f] strategy waits for [f] * the next block time to be
elapsed before injecting pending operations. This strategy allows for
maximizing the number of the same kind of operations to include in a
block. *)](** Explanation for unsuccessful operations (that are included in a block). *)typeunsuccessful_status=|Other_branch(** The operation is included in a block that is not on the main chain
anymore, because of a reorganization. *)|Backtracked(** The operation is backtracked because of a further failing operation in
the same batch. *)|Skipped(** The operation is skipped because of a previous failing operation in
the same batch. *)|Failedoferrortrace(** The operation failed with the provided error. *)|Never_included(** The operation was injected but never included after the injection
TTL. *)typeoperation_status=Successful|Unsuccessfulofunsuccessful_statustypesimulation_status={index_in_batch:int;status:operation_status}type'unsigned_opsimulation_result={operations_statuses:simulation_statuslist;unsigned_operation:'unsigned_op;}(** Action to be taken for unsuccessful operation. *)typeretry_action=|Retry(** The operation is retried by being re-queued for injection. *)|Forget(** The operation is forgotten without error. *)|Abortoferrortrace(** The error for the failing operation should be propagated at a higher
level. *)(** Signature for tags used in injector *)moduletypeTAG=sigincludeStdlib.Set.OrderedTypeincludeStdlib.Hashtbl.HashedTypewithtypet:=tvalpp:Format.formatter->t->unitvalencoding:tData_encoding.tendmoduletypePARAM_OPERATION=sig(** The abstract type of operations to inject *)typet(** An encoding for injector's operations *)valencoding:tData_encoding.t(** Pretty-printing injector's operations *)valpp:Format.formatter->t->unit(** If [unique op = true], then the injector's queue will only contain at most
one operation [op]. Otherwise, it will allow duplicate such operations to
appear in the queue. *)valunique:t->boolend(** Internal representation of injector operations. *)moduletypeINJECTOR_OPERATION=sigtypeoperation(** Hash with b58check encoding iop(53), for ids of injector operations *)moduleId:Tezos_crypto.Intfs.HASH(** Alias for L1 operations ids *)typeid=Id.t(** Structure to keep track of injection errors. *)typeerrors={count:int;last_error:tztraceoption}(** The type of L1 operations that are injected on Tezos. These have an id
attached to them that allows tracking and retrieving their status. *)typet=private{id:id;operation:operation;mutableerrors:errors}(** [make op] returns an L1 operation with the corresponding hash. *)valmake:operation->t(** Encoding for L1 operations *)valencoding:tData_encoding.t(** Pretty printer for L1 operations. Only the relevant part for the rollup node
is printed. *)valpp:Format.formatter->t->unit(** Register an error as occurring during injection of an operation. Its
internal error counter is incremented. *)valregister_error:t->tztrace->unitend(** Module type for parameter of functor {!Injector_functor.Make}. *)moduletypePARAMETERS=sig(** The type of the state that the injector can access *)typestate(** A module which contains the different tags for the injector *)moduleTag:TAG(** A module for the injector operations *)moduleOperation:PARAM_OPERATION(** Where to put the events for this injector *)valevents_section:stringlist(** Coarse approximation for the number of operation of each tag we expect to
inject for each block. *)valtable_estimated_size:Tag.t->int(** Action (see {!retry_action}) to be taken on unsuccessful operation (see
{!unsuccessful_status}). *)valretry_unsuccessful_operation:state->Operation.t->unsuccessful_status->retry_actionLwt.t(** The tag of a manager operation. This is used to send operations to the
correct queue automatically (when signer is not provided) and to recover
persistent information. *)valoperation_tag:Operation.t->Tag.t(** Returns the fee_parameter (to compute fee w.r.t. gas, size, etc.) and the
caps of fee and burn for each operation. *)valfee_parameter:state->Operation.t->Injector_common.fee_parameter(** Returns the gas safety guard for each operation if it should be different
from the client default (100). *)valsafety_guard:Operation.t->intoption(** Indicate which operations should be persisted on disk to be reinjected
upon restart. *)valpersist_operation:Operation.t->boolendmoduletypePROTOCOL_CLIENT=sigtypestatetypeoperationtypeunsigned_operationvalmax_operation_data_length:int(** The validation pass of manager operations. *)valmanager_pass:int(** [operation_status block oph ~index] returns the status of the operation at
position [index] in the L1 batch [oph] included in the block [block]. It
returns [None] if the operation with the given index is not in the
block. *)valoperation_status:state->Block_hash.t->Operation_hash.t->index:int->operation_statusoptiontzresultLwt.t(** Size of an operation in bytes according to the protocol. This only
accounts for the actual content of the corresponding manager operation
(and not its fees, gas, etc.). *)valoperation_size:operation->int(** An upper bound of the overhead added to manager operations in
bytes. Typically, this would include the source, fees, counter, gas limit,
and storage limit. *)valoperation_size_overhead:int(** Simulating a batch of operations. This function returns the simulation
result for each of these operations (with its associated index in the
batch, in case there is a revelation operation added) together with a
Tezos raw unsigned operation that can be directly injected on a node if
one wishes to. *)valsimulate_operations:#Client_context.full->force:bool->source:Signature.public_key_hash->src_pk:Signature.public_key->successor_level:bool->fee_parameter:Injector_common.fee_parameter->?safety_guard:int->operationlist->(unsigned_operationsimulation_result,[`Exceeds_quotasoftztrace|`TzErroroftztrace])resultLwt.t(** Sign an unsigned operation an return the serialized signed operation,
ready for injection. *)valsign_operation:#Client_context.full->Client_keys.sk_uri->unsigned_operation->bytestzresultLwt.t(** [time_until_next_block state block_header] computes the time until the
block following [block_header], with respect to the current time. *)valtime_until_next_block:state->Tezos_base.Block_header.shell_headeroption->Ptime.span(** Run protocol specific checks for injector configuration/state. *)valchecks:state->unittzresultend(** Output signature for functor {!Injector_functor.Make}. *)moduletypeS=sigtypestatetypetagtypeoperationmoduleInj_operation:INJECTOR_OPERATIONwithtypeoperation=operation(** Information stored about an L1 operation that was injected on a Tezos
node. *)typeinjected_info={op:Inj_operation.t;(** The injector operation. *)oph:Operation_hash.t;(** The hash of the operation which contains [op] (this can be an L1 batch
of several manager operations). *)op_index:int;(** The index of the operation [op] in the L1 batch corresponding to [oph]. *)}(** Information stored about an L1 operation that was included in a Tezos
block. *)typeincluded_info={op:Inj_operation.t;(** The injector operation. *)oph:Operation_hash.t;(** The hash of the operation which contains [op] (this can be an L1 batch
of several manager operations). *)op_index:int;(** The index of the operation [op] in the L1 batch corresponding to [oph]. *)l1_block:Block_hash.t;(** The hash of the L1 block in which the operation was included. *)l1_level:int32;(** The level of [l1_block]. *)}(** Status of an operation in the injector. *)typestatus=|Pendingofoperation(** The operation is pending injection. *)|Injectedofinjected_info(** The operation has been injected successfully in the node. *)|Includedofincluded_info(** The operation has been included in a L1 block. *)(** Initializes the injector with the rollup node state, for a list
of signers, and start the workers. Each signer's list has its
own worker with a queue of operations to inject.
[retention_period] is the number of blocks for which the injector keeps
the included information for, must be positive or zero. By default (when
[0]), the injector will not keep information longer than necessary. It can
be useful to set this value to something [> 0] if we want to retrieve
information about operations included on L1 for a given period.
[allowed_attempts] is the number of attempts that will be made to inject
an operation. Operations whose injection fails a number of times greater
than this value will be discarded from the queue.
[injection_ttl] is the number of blocks after which an operation that is
injected but never include is retried.
Each pkh's list and tag list of [signers] must be disjoint. *)valinit:#Client_context.full->data_dir:string->?retention_period:int->?allowed_attempts:int->?injection_ttl:int->Layer_1.t->state->signers:(Signature.public_key_hashlist*injection_strategy*taglist)list->unittzresultLwt.t(** Add an operation as pending injection in the injector. It returns the id
of the operation in the injector queue. *)valadd_pending_operation:operation->Inj_operation.Id.ttzresultLwt.t(** Trigger an injection of the pending operations for all workers. If [tags]
is given, only the workers which have a tag in [tags] inject their pending
operations. [header] must be provided for the [`Delay_block] strategy to
compute the next block timestamp. *)valinject:?tags:taglist->?header:Tezos_base.Block_header.shell_header->unit->unitLwt.t(** Shutdown the injectors, waiting for the ongoing request to be processed. *)valshutdown:unit->unitLwt.t(** The status of an operation in the injector. *)valoperation_status:Inj_operation.Id.t->statusoption(** Returns the total operations per worker queue and in total. This function
is constant time excepted for the injectors iteration. *)valtotal_queued_operations:unit->(taglist*int)list*int(** Returns the queues of the injectors, with the oldest elements first. If
[tag] is provided, returns the queue for the injector which handles this
tag. *)valget_queues:?tag:tag->unit->(taglist*Inj_operation.tlist)list(** Clears the injectors queues completely. If [tag] is provided, only queues
for the injector which handles this tag is cleared. *)valclear_queues:?tag:tag->unit->unittzresultLwt.t(** Register a protocol client for a specific protocol to be used by the
injector. This function {b must} be called for all protocols that the
injector is meant support. *)valregister_proto_client:Protocol_hash.t->(modulePROTOCOL_CLIENTwithtypeoperation=operationandtypestate=state)->unitend