Module P.Mempool

type t

Mempool type. This immutable functional state keeps track of operations added to the mempool, and allows to detect conflicts between them and a new candidate operation.

type validation_info

Validation info type required to validate and add operations to a mempool.

type conflict_handler = existing_operation:(Operation_hash.t * operation) -> new_operation:(Operation_hash.t * operation) -> [ `Keep | `Replace ]

Type of the function that may be provided in order to resolve a potential conflict when adding an operation to an existing mempool or when merging two mempools. This handler may be defined as a simple order relation over operations (e.g. prioritize the most profitable operations) or an arbitrary one (e.g. prioritize operations where the source is a specific manager).

Returning `Keep will leave the mempool unchanged and retain the existing_operation while returning `Replace will remove existing_operation and add new_operation instead.

type operation_conflict =
  1. | Operation_conflict of {
    1. existing : Operation_hash.t;
    2. new_operation : Operation_hash.t;
    }
type add_result =
  1. | Added
    (*

    Added means that an operation was successfully added to the mempool without any conflict.

    *)
  2. | Replaced of {
    1. removed : Operation_hash.t;
    }
    (*

    Replaced {removed} means that an operation was successfully added but there was a conflict with the removed operation which was removed from the mempool.

    *)
  3. | Unchanged
    (*

    Unchanged means that there was a conflict with an existing operation which was considered better by the conflict_handler, therefore the new operation is discarded and the mempool remains unchanged.

    *)

Return type when adding an operation to the mempool

type add_error =
  1. | Validation_error of Error_monad.error Error_monad.trace
    (*

    Validation_error _ means that the operation is invalid.

    *)
  2. | Add_conflict of operation_conflict
    (*

    Add_conflict _ means that an operation conflicts with an existing one. This error will only be obtained when no conflict_handler was provided. Moreover, Validation_error _ takes precedence over Add_conflict _ which implies that we have the implicit invariant that the operation would be valid if there was no conflict. Therefore, if add_operation would have to be called again, it would be redondant to check the operation's signature.

    *)

Error type returned when adding an operation to the mempool fails.

type merge_error =
  1. | Incompatible_mempool
    (*

    Incompatible_mempool _ means that the two mempools are not built ontop of the same head and therefore cannot be considered.

    *)
  2. | Merge_conflict of operation_conflict
    (*

    Merge_conflict _ arises when two mempool contains conflicting operations and no conflict_handler was provided.

    *)

Error type returned when the merge of two mempools fails.

Initialize a static validation_info and mempool, required to validate and add operations, and an incremental and serializable mempool.

val encoding : t Data_encoding.t

Mempool encoding

val add_operation : ?check_signature:bool -> ?conflict_handler:conflict_handler -> validation_info -> t -> (Operation_hash.t * operation) -> (t * add_result, add_error) Pervasives.result Lwt.t

Adds an operation to a mempool if and only if it is valid and does not conflict with previously added operation.

This function checks the validity of an operation and tries to add it to the mempool.

If a validation error is triggered, the result will be a Validation_error. If a conflict with a previous operation exists, the result will be Add_conflict is then checked. Important: no Add_conflict will be raised if a conflict_handler is provided (see add_result).

If no error is raised the operation is potentially added to the mempool depending on the add_result value.

val remove_operation : t -> Operation_hash.t -> t

remove_operation mempool oph removes the operation oph from the mempool. The mempool remains unchanged when oph is not present in the mempool

val merge : ?conflict_handler:conflict_handler -> t -> t -> (t, merge_error) Pervasives.result

merge ?conflict_handler mempool mempool' merges mempool' into mempool.

Mempools may only be merged if they are compatible: i.e. both have been initialised with the same predecessor block. Otherwise, the Incompatible_mempool error is returned.

Conflicts between operations from the two mempools can occur. Similarly as add_operation, a Merge_conflict error may be raised when no conflict_handler is provided.

existing_operation in conflict_handler ~existing_operation ~new_operation references operations present in mempool while new_operation will reference operations present in mempool'.

val operations : t -> operation Operation_hash.Map.t

operations mempool returns the map of operations present in mempool.