Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Fema Analysis On the Pinger

fema-analysis-pinger.livemd

Fema Analysis On the Pinger

Index

  1. Toc
  2. User
    1. Data
  3. Contributing
    1. Understanding Any Module
    2. Style Guide
    3. Writing Documents
    4. Examples Over Testing
    5. Git
    6. Hoon
    7. Iex
    8. Mnesia Vs Actor State
    9. Observer
    10. Testing
      1. Running Tests
      2. Writing Tests
  4. Visualization
    1. Actors
  5. Hoon
    1. Calling
    2. Dumping
    3. Setting Up
  6. Analysis
    1. Fema Analysis Pinger
  7. Logging
  8. Vm_interface

Analysis

This document contains a FEMA analysis on Anoma.Node.Pinger.

The pinger module is responsible for producing blocks at a set time.

In order to get a good feeling of the errors, this document will:

  1. Cover the traces of it’s public API
  2. Do a more indpeth analysis of the effects, inducing the key calls
  3. Disect how the module could fail
  4. Locate how the API could be misused and create a failure case
  5. Look at the codebase for potential areas where this could occur
  6. Note the nock-on effects on a failing actor on other actors in the Anoma system.
  7. Write out each bug in full effect.
  8. Provide a summary of the findings with the precieved severity level

Pinger API Tracing

Let us startup the Anoma Environment to run the code in.

alias Anoma.Node.{Mempool, Router, Pinger}
alias Anoma.Storage
alias Anoma.Node.Storage.Ordering
import TestHelper.Nock

name = :anoma
node = Anoma.Node.state(name)
:all_good
:all_good

The Pinger has 2 public methods that we can abuse Anoma.Node.Pinger.start/1 and Anoma.Node.Pinger.set_timer/2.

Let use begin by first tracing what all these methods do in depth

Kino.Process.render_seq_trace(
  [Process.whereis(node.pinger.server)],
  fn ->
    # we should use the router, but pinger is special
    Pinger.set_timer(node.pinger, 20)
  end,
  message_label: &Anoma.Utility.message_label/1
)
sequenceDiagram
participant 0 AS self();
participant 1 AS Anoma.Node.Pinger HFn/uuQ5P5oDd3yBKS2rDz+Nx++XqLKOL+zJdO70aJg=;
0->>1: CALL: set
1->>0: INFO: tuple
"Timer set to 20"

In Depth Analysis

Now that we have seen the rough API of the Pinger, let us now look deeper at how the interactions work, and see what we can derive.

The first bit to note is that set_timer does not actually trigger the pinger to start sending

Analyzing the code, we can see that if state.time is set properly, then the pinger will handle a self call of :execute.

Kino.Process.render_seq_trace(
  [Process.whereis(node.pinger.server)],
  fn ->
    # we should use the router, but pinger is special
    send(Process.whereis(node.pinger.server), :execute)
    :timer.sleep(1)
  end,
  message_label: &Anoma.Utility.message_label/1
)
sequenceDiagram
participant 2 AS Anoma.Node.Mempool 4/XLsEdgkzoiXSBYoBHJexd5ax8K1Sp7feQki1HV45k=;
participant 0 AS self();
participant 1 AS Anoma.Node.Pinger HFn/uuQ5P5oDd3yBKS2rDz+Nx++XqLKOL+zJdO70aJg=;
0->>1: INFO: execute
1->>2: CALL: execute
:ok

Potential Failure Modes

Failure of use around the codebase

Death of the Actor

If the actor dies, then the only effect is that blocks won’t be producted like expected.

In production this is critical as the chain will halt.

On a developer’s testing box this is rather benign, as block production should happen on demand, rather than on intervels.

Full Details of the Failure modes

Summary Of Failures

Failure States Severity Comment
xyz low important for operation