Skip to content

Commit

Permalink
Adding new monitor (Safe Liveness Expiration) (#44)
Browse files Browse the repository at this point in the history
* feat: add liveness expiration base

* chore: clean up metrics + lib + name

* chore: remove the comment address

* chore: add new address

* feat: add the `livenessGuard` + `livenessModule`

* feat: add the missing metrics

* refactor: change some minor and rename variables.

* clean: clean the CLI.go before sending it.

* feat: add `README.md`

* chore: fix the test.

* chore: fix readme.

* feat: add new readme and clean the readme of the projects

* chore: readme fix

* Update README.md

* chore: fix typo and links

* chore: fix typos
  • Loading branch information
Ethnical authored Jun 21, 2024
1 parent acdc61e commit d15c7b1
Show file tree
Hide file tree
Showing 14 changed files with 4,865 additions and 86 deletions.
147 changes: 64 additions & 83 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,121 +1,102 @@
# Monitorism

A blockchain surveillance tool that supports monitoring for the OP Stack and EVM-compatible chains.

⚠️ Caution: *Monitorism* is currently in its beta phase and is under active migration 🔨. This implies that *Monitorism* is presently not fully stable. ⚠️
## Monitors Component

## Development
After cloning, please run `./bootstrap.sh` to set up the development environment correctly.
The list of all the monitors currently built into monitorism is below.

## Intro
The cli has the ability to spin up a monitor for varying activities, each emmitting metrics used to setup alerts.
```
COMMANDS:
multisig Monitors OptimismPortal pause status, Safe nonce, and Pre-Signed nonce stored in 1Password
fault Monitors output roots posted on L1 against L2
withdrawals Monitors proven withdrawals on L1 against L2
balances Monitors account balances
secrets Monitors secrets revealed in the CheckSecrets dripcheck
```
### Global Events Monitor

Each monitor has some common configuration, configurable both via cli or env with defaults.
```
OPTIONS:
--log.level value [$MONITORISM_LOG_LEVEL] The lowest log level that will be output (default: INFO)
--log.format value [$MONITORISM_LOG_FORMAT] Format the log output. Supported formats: 'text', 'terminal', 'logfmt', 'json', 'json-pretty', (default: text)
--log.color [$MONITORISM_LOG_COLOR] Color the log output if in terminal mode (default: false)
--metrics.enabled [$MONITORISM_METRICS_ENABLED] Enable the metrics server (default: false)
--metrics.addr value [$MONITORISM_METRICS_ADDR] Metrics listening address (default: "0.0.0.0")
--metrics.port value [$MONITORISM_METRICS_PORT] Metrics listening port (default: 7300)
--loop.interval.msec value [$MONITORISM_LOOP_INTERVAL_MSEC] Loop interval of the monitor in milliseconds (default: 60000)
```
![df2b94999628ce8eee98fb60f45667e54be9b13db82add6aa77888f355137329](https://github.com/ethereum-optimism/monitorism/assets/23560242/b8d36a0f-8a17-4e22-be5a-3e9f3586b3ab)

The Global Events Monitor is made for to taking YAML rules as configuration and monitoring the events that are emitted on the chain.

## Monitors
| `op-monitorism/global_events` | [README](https://github.com/ethereum-optimism/monitorism/blob/main/op-monitorism/global_events/README.md) |
| ----------------------------- | --------------------------------------------------------------------------------------------------------- |

In addition the common configuration, each monitor also has their specific configuration
### Liveness Expiration Monitor

* **Note**: The environment variable prefix for monitor-specific configuration is different than the global monitor config described above.
![ab27497cea05fbd51b7b1c2ecde5bc69307ac0f27349f6bba4f3f21423116071](https://github.com/ethereum-optimism/monitorism/assets/23560242/af7a7e29-fff5-4df3-82f0-94c2f28fde84)

The Liveness Expiration Monitor is made for monitoring the liveness expiration on Safes.

| `op-monitorism/liveness_expiration` | [README](https://github.com/ethereum-optimism/monitorism/blob/main/op-monitorism/liveness_expiration/README.md) |
| ----------------------------------- | --------------------------------------------------------------------------------------------------------------- |

### Fault Monitor

The fault monitor checks for changes in output roots posted to the `L2OutputOracle` contract. On change, reconstructing the output root from a trusted L2 source and looking for a match
```
OPTIONS:
--l1.node.url value [$FAULT_MON_L1_NODE_URL] Node URL of L1 peer (default: "127.0.0.1:8545")
--l2.node.url value [$FAULT_MON_L2_NODE_URL] Node URL of L2 peer (default: "127.0.0.1:9545")
--start.output.index value [$FAULT_MON_START_OUTPUT_INDEX] Output index to start from. -1 to find first unfinalized index (default: -1)
--optimismportal.address value [$FAULT_MON_OPTIMISM_PORTAL] Address of the OptimismPortal contract
```
The fault monitor checks for changes in output roots posted to the `L2OutputOracle` contract.
On change, reconstructing the output root from a trusted L2 source and looking for a match.

On mismatch the `isCurrentlyMismatched` metrics is set to `1`.
| `op-monitorism/fault` | [README](https://github.com/ethereum-optimism/monitorism/blob/main/op-monitorism/fault/README.md) |
| --------------------- | ------------------------------------------------------------------------------------------------- |

### Withdrawals Monitor

The withdrawals monitor checks for new withdrawals that have been proven to the `OptimismPortal` contract. Each withdrawal is checked against the `L2ToL1MessagePasser` contract
```
OPTIONS:
--l1.node.url value [$WITHDRAWAL_MON_L1_NODE_URL] Node URL of L1 peer (default: "127.0.0.1:8545")
--l2.node.url value [$WITHDRAWAL_MON_L2_NODE_URL] Node URL of L2 peer (default: "127.0.0.1:9545")
--event.block.range value [$WITHDRAWAL_MON_EVENT_BLOCK_RANGE] Max block range when scanning for events (default: 1000)
--start.block.height value [$WITHDRAWAL_MON_START_BLOCK_HEIGHT] Starting height to scan for events
--optimismportal.address value [$WITHDRAWAL_MON_OPTIMISM_PORTAL] Address of the OptimismPortal contract
```
The withdrawals monitor checks for new withdrawals that have been proven to the `OptimismPortal` contract.
Each withdrawal is checked against the `L2ToL1MessagePasser` contract.

If a proven withdrawal is missing from L2, the `isDetectingForgeries` metrics is set to `1`.
| `op-monitorism/withdrawals` | [README](https://github.com/ethereum-optimism/monitorism/blob/main/op-monitorism/withdrawals/README.md) |
| --------------------------- | ------------------------------------------------------------------------------------------------------- |

### Balances Monitor

The balances monitor simply emits a metric reporting the balances for the configured accounts.
```
OPTIONS:
--node.url value [$BALANCE_MON_NODE_URL] Node URL of a peer (default: "127.0.0.1:8545")
--accounts address:nickname [ --accounts address:nickname ] [$BALANCE_MON_ACCOUNTS] One or accounts formatted via address:nickname
```

| `op-monitorism/balances` | [README](https://github.com/ethereum-optimism/monitorism/blob/main/op-monitorism/balances/README.md) |
| ------------------------ | ---------------------------------------------------------------------------------------------------- |

### Multisig Monitor

The multisig monitor reports the paused status of the `OptimismPortal` contract. If set, the latest nonce of the configued `Safe` address. And also if set, the latest presigned nonce stored in One Password. The latest presigned nonce is identifyed by looking for items in the configued vault that follow a `ready-<nonce>.json` name. The highest nonce of this item name format is reported.
The multisig monitor reports the paused status of the `OptimismPortal` contract.
If set, the latest nonce of the configued `Safe` address. And also if set, the latest presigned nonce stored in One Password.
The latest presigned nonce is identifyed by looking for items in the configued vault that follow a `ready-<nonce>.json` name.
The highest nonce of this item name format is reported.

* **NOTE**: In order to read from one password, the `OP_SERVICE_ACCOUNT_TOKEN` environment variable must be set granting the process permission to access the specified vault.

```
OPTIONS:
--l1.node.url value [$MULTISIG_MON_L1_NODE_URL] Node URL of L1 peer (default: "127.0.0.1:8545")
--optimismportal.address value [$MULTISIG_MON_OPTIMISM_PORTAL] Address of the OptimismPortal contract
--nickname value [$MULTISIG_MON_NICKNAME] Nickname of chain being monitored
--safe.address value [$MULTISIG_MON_SAFE] Address of the Safe contract
--op.vault value [$MULTISIG_MON_1PASS_VAULT_NAME] 1Pass Vault name storing presigned safe txs following a 'ready-<nonce>.json' item name format
```
| `op-monitorism/multisig` | [README](https://github.com/ethereum-optimism/monitorism/blob/main/op-monitorism/multisig/README.md) |
| ------------------------ | ---------------------------------------------------------------------------------------------------- |

### Drippie Monitor

The drippie monitor tracks the execution and executability of drips within a Drippie contract.

```
OPTIONS:
--l1.node.url value Node URL of L1 peer (default: "127.0.0.1:8545") [$DRIPPIE_MON_L1_NODE_URL]
--drippie.address value Address of the Drippie contract [$DRIPPIE_MON_DRIPPIE]
--log.level value The lowest log level that will be output (default: INFO) [$MONITORISM_LOG_LEVEL]
--log.format value Format the log output. Supported formats: 'text', 'terminal', 'logfmt', 'json', 'json-pretty', (default: text) [$MONITORISM_LOG_FORMAT]
--log.color Color the log output if in terminal mode (default: false) [$MONITORISM_LOG_COLOR]
--metrics.enabled Enable the metrics server (default: false) [$MONITORISM_METRICS_ENABLED]
--metrics.addr value Metrics listening address (default: "0.0.0.0") [$MONITORISM_METRICS_ADDR]
--metrics.port value Metrics listening port (default: 7300) [$MONITORISM_METRICS_PORT]
--loop.interval.msec value Loop interval of the monitor in milliseconds (default: 60000) [$MONITORISM_LOOP_INTERVAL_MSEC]
```
| `op-monitorism/drippie` | [README](https://github.com/ethereum-optimism/monitorism/blob/main/op-monitorism/multisig/README.md) |
| ----------------------- | ---------------------------------------------------------------------------------------------------- |

### Secrets Monitor

The secrets monitor takes a Drippie contract as a parameter and monitors for any drips within that contract that use the CheckSecrets dripcheck contract. CheckSecrets is a dripcheck that allows a drip to begin once a specific secret has been revealed (after a delay period) and cancels the drip if a second secret is revealed. It's important to monitor for these secrets being revealed as this could be a sign that the secret storage platform has been compromised and someone is attempting to exflitrate the ETH controlled by that drip.

| `op-monitorism/secrets` | [README](https://github.com/ethereum-optimism/monitorism/blob/main/op-monitorism/multisig/README.md) |
| ----------------------- | ---------------------------------------------------------------------------------------------------- |

## CLI and Docs

## Development
After cloning, please run `./bootstrap.sh` to set up the development environment correctly.

## Intro
The cli has the ability to spin up a monitor for varying activities, each emmitting metrics used to setup alerts.

```
COMMANDS:
multisig Monitors OptimismPortal pause status, Safe nonce, and Pre-Signed nonce stored in 1Password
fault Monitors output roots posted on L1 against L2
withdrawals Monitors proven withdrawals on L1 against L2
balances Monitors account balances
secrets Monitors secrets revealed in the CheckSecrets dripcheck
```

Each monitor has some common configuration, configurable both via cli or env with defaults.

```
OPTIONS:
--l1.node.url value Node URL of L1 peer (default: "127.0.0.1:8545") [$SECRETS_MON_L1_NODE_URL]
--drippie.address value Address of the Drippie contract [$SECRETS_MON_DRIPPIE]
--log.level value The lowest log level that will be output (default: INFO) [$MONITORISM_LOG_LEVEL]
--log.format value Format the log output. Supported formats: 'text', 'terminal', 'logfmt', 'json', 'json-pretty', (default: text) [$MONITORISM_LOG_FORMAT]
--log.color Color the log output if in terminal mode (default: false) [$MONITORISM_LOG_COLOR]
--metrics.enabled Enable the metrics server (default: false) [$MONITORISM_METRICS_ENABLED]
--metrics.addr value Metrics listening address (default: "0.0.0.0") [$MONITORISM_METRICS_ADDR]
--metrics.port value Metrics listening port (default: 7300) [$MONITORISM_METRICS_PORT]
--loop.interval.msec value Loop interval of the monitor in milliseconds (default: 60000) [$MONITORISM_LOOP_INTERVAL_MSEC]
--log.level value [$MONITORISM_LOG_LEVEL] The lowest log level that will be output (default: INFO)
--log.format value [$MONITORISM_LOG_FORMAT] Format the log output. Supported formats: 'text', 'terminal', 'logfmt', 'json', 'json-pretty', (default: text)
--log.color [$MONITORISM_LOG_COLOR] Color the log output if in terminal mode (default: false)
--metrics.enabled [$MONITORISM_METRICS_ENABLED] Enable the metrics server (default: false)
--metrics.addr value [$MONITORISM_METRICS_ADDR] Metrics listening address (default: "0.0.0.0")
--metrics.port value [$MONITORISM_METRICS_PORT] Metrics listening port (default: 7300)
--loop.interval.msec value [$MONITORISM_LOOP_INTERVAL_MSEC] Loop interval of the monitor in milliseconds (default: 60000)
```
9 changes: 9 additions & 0 deletions op-monitorism/balances/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
### Balances Monitor

The balances monitor simply emits a metric reporting the balances for the configured accounts.

```
OPTIONS:
--node.url value [$BALANCE_MON_NODE_URL] Node URL of a peer (default: "127.0.0.1:8545")
--accounts address:nickname [ --accounts address:nickname ] [$BALANCE_MON_ACCOUNTS] One or accounts formatted via address:nickname
```
28 changes: 25 additions & 3 deletions op-monitorism/cmd/monitorism/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import (
"github.com/ethereum-optimism/monitorism/op-monitorism/drippie"
"github.com/ethereum-optimism/monitorism/op-monitorism/fault"
"github.com/ethereum-optimism/monitorism/op-monitorism/global_events"
"github.com/ethereum-optimism/monitorism/op-monitorism/liveness_expiration"
"github.com/ethereum-optimism/monitorism/op-monitorism/multisig"
"github.com/ethereum-optimism/monitorism/op-monitorism/secrets"
"github.com/ethereum-optimism/monitorism/op-monitorism/withdrawals"

"github.com/ethereum-optimism/optimism/op-service/cliapp"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
Expand Down Expand Up @@ -82,7 +82,14 @@ func newCli(GitCommit string, GitDate string) *cli.App {
Usage: "Monitors global events with YAML configuration",
Description: "Monitors global events with YAML configuration",
Flags: append(global_events.CLIFlags("GLOBAL_EVENT_MON"), defaultFlags...),
Action: cliapp.LifecycleCmd(global_eventsMain),
Action: cliapp.LifecycleCmd(GlobalEventMain),
},
{
Name: "liveness_expiration",
Usage: "Monitor the liveness expiration on Gnosis Safe.",
Description: "Monitor the liveness expiration on Gnosis Safe.",
Flags: append(liveness_expiration.CLIFlags("LIVENESS_EXPIRATION_MON"), defaultFlags...),
Action: cliapp.LifecycleCmd(LivenessExpirationMain),
},
{
Name: "version",
Expand All @@ -97,7 +104,22 @@ func newCli(GitCommit string, GitDate string) *cli.App {
}
}

func global_eventsMain(ctx *cli.Context, closeApp context.CancelCauseFunc) (cliapp.Lifecycle, error) {
func LivenessExpirationMain(ctx *cli.Context, closeApp context.CancelCauseFunc) (cliapp.Lifecycle, error) {
log := oplog.NewLogger(oplog.AppOut(ctx), oplog.ReadCLIConfig(ctx))
cfg, err := liveness_expiration.ReadCLIFlags(ctx)
if err != nil {
return nil, fmt.Errorf("failed to parse LivenessExpiration config from flags: %w", err)
}

metricsRegistry := opmetrics.NewRegistry()
monitor, err := liveness_expiration.NewMonitor(ctx.Context, log, opmetrics.With(metricsRegistry), cfg)
if err != nil {
return nil, fmt.Errorf("failed to create LivenessExpiration monitor: %w", err)
}

return monitorism.NewCliApp(ctx, log, metricsRegistry, monitor)
}
func GlobalEventMain(ctx *cli.Context, closeApp context.CancelCauseFunc) (cliapp.Lifecycle, error) {
log := oplog.NewLogger(oplog.AppOut(ctx), oplog.ReadCLIConfig(ctx))
cfg, err := global_events.ReadCLIFlags(ctx)
if err != nil {
Expand Down
16 changes: 16 additions & 0 deletions op-monitorism/drippie/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
### Drippie Monitor

The drippie monitor tracks the execution and executability of drips within a Drippie contract.

```
OPTIONS:
--l1.node.url value Node URL of L1 peer (default: "127.0.0.1:8545") [$DRIPPIE_MON_L1_NODE_URL]
--drippie.address value Address of the Drippie contract [$DRIPPIE_MON_DRIPPIE]
--log.level value The lowest log level that will be output (default: INFO) [$MONITORISM_LOG_LEVEL]
--log.format value Format the log output. Supported formats: 'text', 'terminal', 'logfmt', 'json', 'json-pretty', (default: text) [$MONITORISM_LOG_FORMAT]
--log.color Color the log output if in terminal mode (default: false) [$MONITORISM_LOG_COLOR]
--metrics.enabled Enable the metrics server (default: false) [$MONITORISM_METRICS_ENABLED]
--metrics.addr value Metrics listening address (default: "0.0.0.0") [$MONITORISM_METRICS_ADDR]
--metrics.port value Metrics listening port (default: 7300) [$MONITORISM_METRICS_PORT]
--loop.interval.msec value Loop interval of the monitor in milliseconds (default: 60000) [$MONITORISM_LOOP_INTERVAL_MSEC]
```
13 changes: 13 additions & 0 deletions op-monitorism/fault/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
### Fault Monitor

The fault monitor checks for changes in output roots posted to the `L2OutputOracle` contract. On change, reconstructing the output root from a trusted L2 source and looking for a match

```
OPTIONS:
--l1.node.url value [$FAULT_MON_L1_NODE_URL] Node URL of L1 peer (default: "127.0.0.1:8545")
--l2.node.url value [$FAULT_MON_L2_NODE_URL] Node URL of L2 peer (default: "127.0.0.1:9545")
--start.output.index value [$FAULT_MON_START_OUTPUT_INDEX] Output index to start from. -1 to find first unfinalized index (default: -1)
--optimismportal.address value [$FAULT_MON_OPTIMISM_PORTAL] Address of the OptimismPortal contract
```

On mismatch the `isCurrentlyMismatched` metrics is set to `1`.
Loading

0 comments on commit d15c7b1

Please sign in to comment.