Anoma.Node.Logging (Anoma v0.29.0)

I am the Logging Engine.

I combine the classic logger with replay functionality. In particular, I store the most recent data coming outside of a Node so that if it fails I can re-do the actions fed to me in a linear fashion.

Public API

I provide the following public functionality:

Replay

Other

Summary

Types

I am the loggging message type flag.

t()

I am the type of the Logging Engine.

Functions

Returns a specification to start this module under a supervisor.

I am the initialization function for the Logging Engine.

I am the log event function.

I am the logging filter.

I am the function getting the replay arguments for replay.

I am the replay setup function, the first step in the replay process.

I am the function making a table copy for replay.

I am the function to be played on restarts of the Anoma node with known ID.

I am the start_link function of the Logging Engine.

I am the name of the event table.

I am a function trying to launch a node.

Types

@type flag() :: :info | :debug | :warning | :error

I am the loggging message type flag.

I specify what logging levels are currently supported by the Logging Engine.

@type t() :: %Anoma.Node.Logging{node_id: String.t() | nil, table: atom()}

I am the type of the Logging Engine.

I store a Node ID with which I am associated alongside a table which stores all relevant events.

Fields

  • :node_id - The ID of the Node to which a Logging Engine
             instantiation is bound.
  • :table - The name of the table to which all replay events are
           written.
           Default: __MODULE__.Events

Functions

Link to this function

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

I am the initialization function for the Logging Engine.

From the specified arguments, I get the Node ID, the table name, as well as the boolean indicating whether the table should be backed by RocksDB.

I then initialize the table with the given name and backing options, subscribe to logging messages and then launch the Engine with the given options.

Link to this function

log_event(node_id, flag, msg)

@spec log_event(String.t(), flag(), binary()) :: :ok

I am the log event function.

I provide an interface to "log" new messages in an easy format.

Given a Node ID, a flag, and a message, I create a new event with appropriate flag and message.

Link to this function

logging_filter()

@spec logging_filter() :: Anoma.Node.Logging.LoggingFilter.t()

I am the logging filter.

I filter for any incoming messages the Logging Engine cares about.

Link to this function

replay_args(list)

@spec replay_args(height: integer(), mempool: list()) :: [
  mempool: list(),
  ordering: list(),
  storage: list()
]

I am the function getting the replay arguments for replay.

Given a current height alongside mempool info, I set the ordering and storage info appropriately and put all transaction trifecta arguments in an order.

Link to this function

replay_setup(event_table, block_table)

@spec replay_setup(atom(), atom()) :: [height: integer(), mempool: list()]

I am the replay setup function, the first step in the replay process.

All tables here are the original ones from which we get info.

This gives me the height, the round, as well as the replay Mempool struct.

Link to this function

replay_table_clone(values_table, updates_table, node_id)

@spec replay_table_clone(atom(), atom(), String.t()) :: any()

I am the function making a table copy for replay.

Given original updates and values table used by the Storage, I copy their data to separate tables for a new node. Used for trying a replay on a mock node.

Link to this function

restart_with_replay(node_id)

@spec restart_with_replay(String.t()) :: DynamicSupervisor.on_start_child()

I am the function to be played on restarts of the Anoma node with known ID.

I sync the event table with the blocks submitted and then launch a mock node with a new ID with replay arguments.

If the replay succeeds, I reproduce it on the node with the ID provided. Otherwise, the only initialization information I reproduce are heights and rounds for the Transaction subsystem.

Link to this function

start_link(args)

@spec start_link([startup_options()]) :: term()

I am the start_link function of the Logging Engine.

I register the Engine with the supplied Node ID provided by the arguments and check that the table keyword has been provided.

Link to this function

table_name(node_id)

@spec table_name(String.t()) :: atom()

I am the name of the event table.

Given a Node ID, I create an appropriately named Event table for it.

Link to this function

try_launch(mock_id, replay_args)

@spec try_launch(String.t(), any()) :: :ok | :error

I am a function trying to launch a node.

Given some replay arguments, I provide the core logic to be run by a separate task to test whether the original data has been corrupted or note.

Namely, a launch a Node with given replay arguments and make sure that the final consensus gets provided.