Skip to content

Latest commit

 

History

History

monitor

sourcify-monitor

Sourcify Monitor is a standalone service that listens to various EVM chains for new contract creations and automatically submits them to the Sourcify API for verification.

This is only possible for Solidity contracts that has its metadata hash published in a DecentralizedStorage (IPFS, Swarm, etc). Currently only IPFS is supported.

Learn more about the contract metadata in the Solidity docs and Sourcify docs. We also have a nice playground showing everything in action at playground.sourcify.dev.

Config

Chains to Monitor

First you need to provide which chains to monitor in a json file.

[
  {
    "chainId": 1,
    "name": "Ethereum Mainnet",
    "rpc": ["http://localhost:8545", "https://mainnet.infura.io/v3/{INFURA_API_KEY}"],
  },
  {
    "chainId": 11155111,
    "name": "Ethereum Sepolia Testnet",
    "rpc": ["http://localhost:8545", "https://rpc2.sepolia.org/ "],
  },
  ...
]

Infura and Alchemy keys must be placed in the url string as above in {INFURA_API_KEY}

See monitorChains.json for a full example and to see which chains we monitor ourselves. You can also use the chainid.network/chains.json to find chains.

Monitor Config

Optionally you can pass a monitor config in a config.json file. If you don't, the default config will be used. If you leave any field blank, it will be filled with the default config.

The structure of the file is as such:

  decentralizedStorages: {
    ipfs: {
      enabled: true,
      gateways: [
        // Passing gateway as a string will use default settings
        "https://ipfs.io/ipfs/",
        // If you need gateways specific settings you can pass them in an object
        {
          url: "http://localhost:8080/ipfs/",
          headers: {
            "Authentication": "xxx"
          }
        }
      ],
      // Time when the request to the gateway will timeout i.e. canceled in ms
      timeout: 30000,
      // Time between each request to the gateway in ms
      interval: 5000,
      // Number of retries before giving up
      retries: 5,
      // (optional) Headers passed to the fetch headers parameter
      headers: {}
    },
    // can also have swarm
  },
  // Sourcify instances to verify the contracts on. Can be multiple
  sourcifyServerURLs: ["https://sourcify.dev/server/", "http://localhost:5555/"],
  sourcifyRequestOptions: {
    // Maximum number of retry attempts for contract verification requests after encountering an error
    maxRetries: 3,
    // Delay in milliseconds between each retry attempt for verification requests to Sourcify
    retryDelay: 30000,
  },
  defaultChainConfig: {
    // Block to start monitoring from. If undefined, it will start from the latest block by asking the RPC `eth_blockNumber`
    startBlock: undefined,
    // Time between each block check in ms. This value is dynamically adjusted based on the block time.
    // When a block is successfully fetched, it's decreased by `blockIntervalFactor`, and vice versa.
    blockInterval: 10000,
    // The factor to increase/decrease the block interval by. Must be greater than 1.
    blockIntervalFactor: 1.1,
    // The upper and lower limit of the block interval in ms
    blockIntervalUpperLimit: 300000,
    blockIntervalLowerLimit: 100,
    // Time between each `eth_getCode` requets in ms
    bytecodeInterval: 5000,
    // Number of retries before giving up getting the contract bytecode.
    bytecodeNumberOfTries: 5,
  },
  // Can also pass each chain the same config as above. Non specified fields will be filled with the defaultChainConfig. Non specified chains will use the whole defaultChainConfig.
  chainConfigs: {
    1: {
      startBlock: 10000000,
      blockInterval: 12000, // Ethereum mainnet is set to 12s
    }
  }

Environment variables

By default you can pass the following environment variables in .env.template for authenticating with the RPCs:

# If your RPCs are Alchemy or Infura
# In the rpc url it must have {INFURA_API_KEY} or {ALCHEMY_API_KEY}
ALCHEMY_API_KEY=
INFURA_API_KEY=

# ethpandaops.io authentication
CF_ACCESS_CLIENT_ID=
CF_ACCESS_CLIENT_SECRET=

# Overrides the log level. Normally, if NODE_ENV production set to "info", otherwise "debug". Values can be silly, debug, info, warn, error
NODE_LOG_LEVEL=
# Port of the HTTP server to change the log level dynamically while the monitor is running
NODE_LOG_LEVEL_SERVER_PORT=3333

Usage

You can run the Sourcify Monitor in two ways:

1. Run locally

Clone the Sourcify monorepo

git clone [email protected]:ethereum/sourcify.git
cd sourcify

Install and build the project:

npm install
npx lerna run build --scope sourcify-monitor

Run

node dist/index.js --chainsPath /path/to/your-chains.json --configPath /path/to/config.json

The --chainsPath and --configPath are optional. If not provided, the default paths will be used.

2. Run via Docker

If you want to build yourself, the builds need to be run from the project root context, e.g.:

cd sourcify/ && docker build -f services/server/Dockerfile .

The containers are published in the Github Container Registry

The recommended way to run the Sourcify Monitor is via Docker.

You need to pass the monitorChains.json and config.json files to the container. You can do this by mounting them as volumes:

$ docker pull ghcr.io/ethereum/sourcify/monitor:latest
$ docker run \
  -v /path/to/chains.json:/home/app/services/monitor/monitorChains.json \
  -v /path/to/config.json:/home/app/services/monitor/config.json \
  -e ALCHEMY_API_KEY=xxx \
  -e INFURA_API_KEY=xxx \
  ghcr.io/ethereum/sourcify/monitor:latest

Setting log levels dynamically

The default log level of the monitor is set to "info". You can change the default value by setting the env var NODE_LOG_LEVEL on start.

You can also change the log level dynamically while the monitor is running through a simple (unauthenticated) HTTP server endpoint. The server port is set in NODE_LOG_LEVEL_SERVER_PORT env var (default: 3333). Simply call:

curl -X POST -H "Content-Type: application/json" -d '{"level": "debug"}' http://localhost:3333