Commit f257c034 authored by Andreas Bigger's avatar Andreas Bigger

feat: op-node docs

parent e1e8445d
// Package heartbeat provides a service for sending heartbeats to a server.
package heartbeat
import (
......@@ -22,6 +23,8 @@ type Payload struct {
ChainID uint64 `json:"chainID"`
}
// Beat sends a heartbeat to the server at the given URL. It will send a heartbeat immediately, and then every SendInterval.
// Beat spawns a goroutine that will send heartbeats until the context is canceled.
func Beat(
ctx context.Context,
log log.Logger,
......
// Package metrics provides a set of metrics for the op-node.
package metrics
import (
......@@ -63,6 +64,7 @@ type Metricer interface {
Document() []metrics.DocumentedMetric
}
// Metrics tracks all the metrics for the op-node.
type Metrics struct {
Info *prometheus.GaugeVec
Up prometheus.Gauge
......@@ -118,6 +120,7 @@ type Metrics struct {
var _ Metricer = (*Metrics)(nil)
// NewMetrics creates a new [Metrics] instance with the given process name.
func NewMetrics(procName string) *Metrics {
if procName == "" {
procName = "default"
......
......@@ -140,6 +140,8 @@ func BuildGlobalGossipParams(cfg *rollup.Config) pubsub.GossipSubParams {
return params
}
// NewGossipSub configures a new pubsub instance with the specified parameters.
// PubSub uses a GossipSubRouter as it's router under the hood.
func NewGossipSub(p2pCtx context.Context, h host.Host, cfg *rollup.Config, gossipConf GossipSetupConfigurables, m GossipMetricer) (*pubsub.PubSub, error) {
denyList, err := pubsub.NewTimeCachedBlacklist(30 * time.Second)
if err != nil {
......
......@@ -23,6 +23,7 @@ import (
"github.com/ethereum-optimism/optimism/op-node/rollup"
)
// NodeP2P is a p2p node, which can be used to gossip messages.
type NodeP2P struct {
host host.Host // p2p host (optional, may be nil)
gater ConnectionGater // p2p gater, to ban/unban peers with, may be nil even with p2p enabled
......@@ -34,6 +35,8 @@ type NodeP2P struct {
gsOut GossipOut // p2p gossip application interface for publishing
}
// NewNodeP2P creates a new p2p node, and returns a reference to it. If the p2p is disabled, it returns nil.
// If metrics are configured, a bandwidth monitor will be spawned in a goroutine.
func NewNodeP2P(resourcesCtx context.Context, rollupCfg *rollup.Config, log log.Logger, setup SetupP2P, gossipIn GossipIn, runCfg GossipRuntimeConfig, metrics metrics.Metricer) (*NodeP2P, error) {
if setup == nil {
return nil, errors.New("p2p node cannot be created without setup")
......
......@@ -12,9 +12,9 @@ import (
"github.com/ethereum/go-ethereum/rpc"
)
// IterativeBatchCall is an util to create a job to fetch many RPC requests in batches,
// and enable the caller to parallelize easily and safely, handle and re-try errors,
// and pick a batch size all by simply calling Fetch again and again until it returns io.EOF.
// IterativeBatchCall batches many RPC requests with safe and easy parallelization.
// Request errors are handled and re-tried, and the batch size is configurable.
// Executing IterativeBatchCall is as simple as calling Fetch repeatedly until it returns io.EOF.
type IterativeBatchCall[K any, V any] struct {
completed uint32 // tracks how far to completing all requests we are
resetLock sync.RWMutex // ensures we do not concurrently read (incl. fetch) / reset
......@@ -77,7 +77,7 @@ func (ibc *IterativeBatchCall[K, V]) Reset() {
}
// Fetch fetches more of the data, and returns io.EOF when all data has been fetched.
// This method is safe to call concurrently: it will parallelize the fetching work.
// This method is safe to call concurrently; it will parallelize the fetching work.
// If no work is available, but the fetching is not done yet,
// then Fetch will block until the next thing can be fetched, or until the context expires.
func (ibc *IterativeBatchCall[K, V]) Fetch(ctx context.Context) error {
......
// Package sources exports a number of clients used to access ethereum chain data.
//
// There are a number of these exported clients used by the op-node:
// [L1Client] wraps an RPC client to retrieve L1 ethereum data.
// [L2Client] wraps an RPC client to retrieve L2 ethereum data.
// [RollupClient] wraps an RPC client to retrieve rollup data.
// [EngineClient] extends the [L2Client] providing engine API bindings.
//
// Internally, the listed clients wrap an [EthClient] which itself wraps a specified RPC client.
package sources
import (
......@@ -126,8 +135,8 @@ func (s *EthClient) OnReceiptsMethodErr(m ReceiptsFetchingMethod, err error) {
}
}
// NewEthClient wraps a RPC with bindings to fetch ethereum data,
// while logging errors, parallel-requests constraint, tracking metrics (optional), and caching.
// NewEthClient returns an [EthClient], wrapping an RPC with bindings to fetch ethereum data with added error logging,
// metric tracking, and caching. The [EthClient] uses a [LimitRPC] wrapper to limit the number of concurrent RPC requests.
func NewEthClient(client client.RPC, log log.Logger, metrics caching.Metrics, config *EthClientConfig) (*EthClient, error) {
if err := config.Check(); err != nil {
return nil, fmt.Errorf("bad config, cannot create L1 source: %w", err)
......
......@@ -68,6 +68,8 @@ func NewL1Client(client client.RPC, log log.Logger, metrics caching.Metrics, con
}, nil
}
// L1BlockRefByLabel returns the [eth.L1BlockRef] for the given block label.
// Notice, we cannot cache a block reference by label because labels are not guaranteed to be unique.
func (s *L1Client) L1BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L1BlockRef, error) {
info, err := s.InfoByLabel(ctx, label)
if err != nil {
......@@ -83,6 +85,8 @@ func (s *L1Client) L1BlockRefByLabel(ctx context.Context, label eth.BlockLabel)
return ref, nil
}
// L1BlockRefByNumber returns an [eth.L1BlockRef] for the given block number.
// Notice, we cannot cache a block reference by number because L1 re-orgs can invalidate the cached block reference.
func (s *L1Client) L1BlockRefByNumber(ctx context.Context, num uint64) (eth.L1BlockRef, error) {
info, err := s.InfoByNumber(ctx, num)
if err != nil {
......@@ -93,6 +97,8 @@ func (s *L1Client) L1BlockRefByNumber(ctx context.Context, num uint64) (eth.L1Bl
return ref, nil
}
// L1BlockRefByHash returns the [eth.L1BlockRef] for the given block hash.
// We cache the block reference by hash as it is safe to assume collision will not occur.
func (s *L1Client) L1BlockRefByHash(ctx context.Context, hash common.Hash) (eth.L1BlockRef, error) {
if v, ok := s.l1BlockRefsCache.Get(hash); ok {
return v.(eth.L1BlockRef), nil
......
......@@ -70,6 +70,9 @@ type L2Client struct {
systemConfigsCache *caching.LRUCache
}
// NewL2Client constructs a new L2Client instance. The L2Client is a thin wrapper around the EthClient with added functions
// for fetching and caching eth.L2BlockRef values. This includes fetching an L2BlockRef by block number, label, or hash.
// See: [L2BlockRefByLabel], [L2BlockRefByNumber], [L2BlockRefByHash]
func NewL2Client(client client.RPC, log log.Logger, metrics caching.Metrics, config *L2ClientConfig) (*L2Client, error) {
ethClient, err := NewEthClient(client, log, metrics, &config.EthClientConfig)
if err != nil {
......@@ -84,7 +87,7 @@ func NewL2Client(client client.RPC, log log.Logger, metrics caching.Metrics, con
}, nil
}
// L2BlockRefByLabel returns the L2 block reference for the given label.
// L2BlockRefByLabel returns the [eth.L2BlockRef] for the given block label.
func (s *L2Client) L2BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L2BlockRef, error) {
payload, err := s.PayloadByLabel(ctx, label)
if err != nil {
......@@ -104,7 +107,7 @@ func (s *L2Client) L2BlockRefByLabel(ctx context.Context, label eth.BlockLabel)
return ref, nil
}
// L2BlockRefByNumber returns the L2 block reference for the given block number.
// L2BlockRefByNumber returns the [eth.L2BlockRef] for the given block number.
func (s *L2Client) L2BlockRefByNumber(ctx context.Context, num uint64) (eth.L2BlockRef, error) {
payload, err := s.PayloadByNumber(ctx, num)
if err != nil {
......@@ -119,7 +122,7 @@ func (s *L2Client) L2BlockRefByNumber(ctx context.Context, num uint64) (eth.L2Bl
return ref, nil
}
// L2BlockRefByHash returns the L2 block reference for the given block hash.
// L2BlockRefByHash returns the [eth.L2BlockRef] for the given block hash.
// The returned BlockRef may not be in the canonical chain.
func (s *L2Client) L2BlockRefByHash(ctx context.Context, hash common.Hash) (eth.L2BlockRef, error) {
if ref, ok := s.l2BlockRefsCache.Get(hash); ok {
......@@ -139,8 +142,8 @@ func (s *L2Client) L2BlockRefByHash(ctx context.Context, hash common.Hash) (eth.
return ref, nil
}
// SystemConfigByL2Hash returns the system config (matching the config updates up to and including the L1 origin) for the given L2 block hash.
// The returned SystemConfig may not be in the canonical chain when the hash is not canonical.
// SystemConfigByL2Hash returns the [eth.SystemConfig] (matching the config updates up to and including the L1 origin) for the given L2 block hash.
// The returned [eth.SystemConfig] may not be in the canonical chain when the hash is not canonical.
func (s *L2Client) SystemConfigByL2Hash(ctx context.Context, hash common.Hash) (eth.SystemConfig, error) {
if ref, ok := s.systemConfigsCache.Get(hash); ok {
return ref.(eth.SystemConfig), nil
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment