package tezos-shell

  1. Overview
  2. Docs
type error_classification = [
  1. | `Branch_delayed of Tezos_error_monad.TzCore.error list
  2. | `Branch_refused of Tezos_error_monad.TzCore.error list
  3. | `Refused of Tezos_error_monad.TzCore.error list
  4. | `Outdated of Tezos_error_monad.TzCore.error list
]

Classifications which correspond to errors

type classification = [
  1. | `Applied
  2. | `Prechecked
  3. | error_classification
]

Classification of an operation in the mempool

type 'protocol_data bounded_map

map bounded_map gets the underling map of the bounded_map.

type parameters = {
  1. map_size_limit : int;
  2. on_discarded_operation : Tezos_crypto.Operation_hash.t -> unit;
}
type 'protocol_data t = private {
  1. parameters : parameters;
  2. refused : 'protocol_data bounded_map;
  3. outdated : 'protocol_data bounded_map;
  4. branch_refused : 'protocol_data bounded_map;
  5. branch_delayed : 'protocol_data bounded_map;
  6. mutable applied_rev : 'protocol_data Prevalidation.operation list;
  7. mutable prechecked : 'protocol_data Prevalidation.operation Tezos_crypto.Operation_hash.Map.t;
  8. mutable unparsable : Tezos_crypto.Operation_hash.Set.t;
  9. mutable in_mempool : ('protocol_data Prevalidation.operation * classification) Tezos_crypto.Operation_hash.Map.t;
}

Invariants ensured by this module **provided that the caller does not add an operation which is already present in t**:

  • The field in_mempool is the set of all operation hashes present in fields: refused; branch_refused; branch_delayed; prechecked; applied.
  • An operation cannot be at the same time in two of the following fields: refused; branch_refused; branch_delayed; prechecked; applied.

Note: unparsable operations are handled in a different way because they cannot be handled as a Prevalidation.operation since this datatype requires an operation to be parsable. Hence, unparsable operations are handled differently. In particular, unparsable operations are removed on flush.

Note: We could always enforce these invariants by checking in add whether the operation is already present. However, this would make the behavior of add less predictable, so we do not think this to be an improvement from the point of view of the caller.

val create : parameters -> 'protocol_data t

create parameters returns an empty t whose bounded maps hold at most parameters.map_size_limit values. The on_discarded_operation is called when a new operation is added and an old one is discarded because the limit was reached.

Invalid_argument is raised if ring_size is 0 or less.

val is_empty : 'protocol_data t -> bool

is_empty t returns true iff t doesn't contain any operation.

val is_in_mempool : Tezos_crypto.Operation_hash.t -> 'protocol_data t -> ('protocol_data Prevalidation.operation * classification) option

is_in_mempool oph classes indicates whether oph is present in field in_mempool of classes. It returns the corresponding operation and its classification if present, and None otherwise.

val is_known_unparsable : Tezos_crypto.Operation_hash.t -> 'protocol_data t -> bool

is_known_unparsable oph returns true if the oph is associated to an operation which is known to be unparsable. false otherwise.

val remove : Tezos_crypto.Operation_hash.t -> 'protocol_data t -> ('protocol_data Prevalidation.operation * classification) option

remove oph classes removes operation of hash oph from all fields of classes. If the oph was classified as Applied, the function is in O(n) with n being the length of classes.applied. Otherwise, the function is O(log n) with n the number of operations in the corresponding class.

If oph was found, its classification as well as the operation it was bound to are returned. If oph was not found, None is returned.

Warning: If an operation is removed from the applied field, this may invalidate the classification of all the other operations. It is left to the caller to restore a consistent state.

val add : classification -> 'protocol_data Prevalidation.operation -> 'protocol_data t -> unit

add ~notify classification op classes adds the operation op classified as classification to the classifier classes. The classes.parameters.on_discarded_operation callback is called for any operation discarded in this process. Currently, an operation is discarded in the following cases:

  • the corresponding error class field is full. In that case, the new operation is added to the class, and the removed one is discarded.
  • an operation is classified as Refused.

Note that a Refused operation may thus be passed twice to on_discarded_operation: as soon as it is added, and if it is removed because the classes.refused bounded map is full.

As a summary:

  • Applied and Prechecked are never discarded
  • Branch_refused and Branch_delayed are discarded 0 or 1 time (if the corresponding bounded_map is full)
  • Refused is discarded 1 or 2 times (if the corresponding bounded_map is full)
val add_unparsable : Tezos_crypto.Operation_hash.t -> 'protocol_data t -> unit

add_unparsable oph classes adds oph as an unparsable operation. unparsable operations are removed automatically by the recycle_operations function. on_discard_operation is also called on those operations.

type 'block block_tools = {
  1. hash : 'block -> Tezos_crypto.Block_hash.t;
    (*

    The hash of a block

    *)
  2. operations : 'block -> Tezos_base.Operation.t list list;
    (*

    The list of operations of a block ordered by their validation pass

    *)
  3. all_operation_hashes : 'block -> Tezos_crypto.Operation_hash.t list list;
    (*

    The list of hashes of operations of a block ordered by their validation pass. Could be implemented using operations but this lets an alternative implementation to be provided.

    *)
}

Functions to query data on a polymorphic block-like type 'block.

type 'block chain_tools = {
  1. clear_or_cancel : Tezos_crypto.Operation_hash.t -> unit;
    (*

    Removes the operation from the distributed database.

    *)
  2. inject_operation : Tezos_crypto.Operation_hash.t -> Tezos_base.Operation.t -> unit Lwt.t;
    (*

    Puts the operation in the distributed database. Returns false if the hash is already in the distributed database

    *)
  3. new_blocks : from_block:'block -> to_block:'block -> ('block * 'block list) Lwt.t;
    (*

    new_blocks ~from_block ~to_block returns a pair (ancestor, path), where ancestor is the common ancestor of from_block and to_block and where path is the chain from ancestor (excluded) to to_block (included).

    • raises assert

      failure when the two provided blocks do not belong to the same chain.

    *)
  4. read_predecessor_opt : 'block -> 'block option Lwt.t;
    (*

    read_predecessor_opt block returns the direct predecessor of block or None if it cannot be found.

    *)
}

A wrapper over chain-related modules, to make client code easier to emulate, and hence to test

val recycle_operations : from_branch:'block -> to_branch:'block -> live_blocks:Tezos_crypto.Block_hash.Set.t -> classes:'protocol_data t -> parse: (Tezos_crypto.Operation_hash.t -> Tezos_base.Operation.t -> 'protocol_data Prevalidation.operation option) -> pending: 'protocol_data Prevalidation.operation Tezos_crypto.Operation_hash.Map.t -> block_store:'block block_tools -> chain:'block chain_tools -> handle_branch_refused:bool -> 'protocol_data Prevalidation.operation Tezos_crypto.Operation_hash.Map.t Lwt.t

recycle_operations returns the new pending operations when a reorganisation or a head update occurs. Returned operations come from:

1. operations in from_branch that are NOT in to_branch, 2. operations in the relevant classes of classification 3. operations the pending map

This function guarantees that the branch of all returned operations is in live_blocks (live_blocks acts as a filter).

Operation which where included in from_branch and which are NOT in to_branch need to be parsed again using the parse argument. If the parsing fails those operations are just dropped. This may happen if those operations comes from another protocol.

See also Internal_for_tests.handle_live_operations.

OCaml

Innovation. Community. Security.