faraday

package module
v0.2.18-alpha Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 26, 2026 License: MIT Imports: 47 Imported by: 2

README

faraday

MIT licensed

Faraday is a suite of tools built to help node operators and businesses run lnd, the leading implementation of the Lightning Network. Faraday’s tools decrease the operational overhead of running a Lightning node and make it easier to build businesses on Lightning. The current features in the Faraday suite provide insight into node channel performance and support for accounting with both on-chain and off-chain reports for lnd.

LND

Note that Faraday requires lnd to be built with all of its subservers and requires running at least v0.11.1. Download the official release binary or see the instructions in the lnd repo for more detailed installation instructions. If you choose to build lnd from source, following command to enable all the relevant subservers:

make install tags="signrpc walletrpc chainrpc invoicesrpc"

Installation

A Makefile is provided. To install faraday and all its dependencies, run:

git clone https://github.com/lightninglabs/faraday.git
cd faraday
make && make install

Usage

Faraday connects to a single instance of lnd. It requires access to lnd's admin.macaroon (or a custom scoped macaroon, see below) and a valid TLS certificate. It will attempt to use the default lnd values if no command line flags are specified.

./faraday                                                   \
--lnd.macaroonpath={full path to lnd's admin.macaroon}   \
--lnd.tlscertpath={path to lnd cert}                        \
--lnd.rpcserver={host:port of lnd's rpcserver} 

By default, faraday runs on mainnet. The --network flag can be used to run in test environments.

Baking a custom macaroon for Faraday

Faraday needs to derive a shared key with lnd to create an encryption password for its macaroon database. That's why on top of the permissions in the readonly.macaroon the uri:/signrpc.Signer/DeriveSharedKey is also required. A custom scoped macaroon just for Faraday can be baked with:

lncli bakemacaroon onchain:read offchain:read address:read peers:read info:read invoices:read uri:/signrpc.Signer/DeriveSharedKey

Authentication and transport security

The gRPC and REST connections of faraday are encrypted with TLS and secured with macaroon authentication the same way lnd is.

If no custom faraday directory is set then the TLS certificate is stored in ~/.faraday/<network>/tls.cert and the base macaroon in ~/.faraday/<network>/faraday.macaroon.

The frcli command will pick up these file automatically on mainnet if no custom faraday directory is used. For other networks it should be sufficient to add the --network flag to tell the CLI in what sub directory to look for the files.

For more information on macaroons, see the macaroon documentation of lnd.

NOTE: Faraday's macaroons are independent from lnd's. The same macaroon cannot be used for both faraday and lnd.

Chain Backend

Faraday offers node accounting services which require access to a Bitcoin node with --txindex set so that it can perform transaction lookup. Currently the CloseReport endpoint requires this connection, and will fail if it is not present. It is strongly recommended to provide this connection when utilizing the NodeAudit endpoint, but it is not required. This connection is optional, and all other endpoints will function if it is not configured.

To connect Faraday to bitcoind:

--connect_bitcoin                       \
--bitcoin.host={host:port of bitcoind}  \
--bitcoin.user={bitcoind username}      \
--bitcoin.password={bitcoind  password}

To connect Faraday to btcd:

--connect_bitcoin                   \
--bitcoin.host={host:port of btcd}  \
--bitcoin.user={btcd username}      \
--bitcoin.password={btcd password}  \
--bitcoin.usetls                    \
--bitcoin.tlspath={path to btcd cert}
RPCServer

Faraday serves requests over grpc by default on localhost:8465. This default can be overwritten:

--rpclisten={host:port to listen for requests}
Channel Event Storage

Faraday records channel events (online/offline transitions and balance updates) in its database. On high-frequency channels this table can grow without bound, so a size ceiling is enabled by default, with an optional age-based retention window:

--chanevents.max-events={maximum number of events to retain}
--chanevents.retention={minimum duration of events to keep, e.g. 1440h}

By default only the size ceiling is active: a maximum of 7 million events (--chanevents.max-events=7000000, roughly 1 GB of storage). Age-based retention is disabled by default (--chanevents.retention=0) so that history is never aged out unless an operator opts in. The retention window is a Go duration string (e.g. 1440h for 60 days). The two limits are applied independently:

  1. Size Ceiling (Hard Limit): If the database exceeds max-events, older events are pruned unconditionally to ensure the database size is strictly capped, preventing disk filling. Newer events inside the retention window can still be pruned if needed to satisfy this size limit.
  2. Age Threshold (Freshness): When retention is set to a non-zero duration, any events older than that window are automatically pruned to keep history fresh, even if the database size is below max-events.

Because the two limits are independent, disabling pruning entirely requires turning off both: --chanevents.max-events=0 --chanevents.retention=0. Setting only max-events=0 disables the size ceiling, leaving the table bounded only by any retention window that has been configured.

As a rough rule of thumb, each channel event consumes on the order of 140 bytes of storage once table and index overhead is taken into account. The default --chanevents.max-events=7000000 therefore bounds the table at roughly 1 GB (7 million events × ~140 bytes ≈ 1 GB). For roughly 100 MB use --chanevents.max-events=700000. These are approximations measured on a compacted SQLite database, and actual usage runs higher on a live database (write-ahead log, page fragmentation) and varies by backend.

Cli Tool

The RPC server can be conveniently accessed using a command line tool.

  1. Run faraday as detailed above
./frcli {command}
Commands
  • insights: expose metrics gathered for one or many channels.
  • revenue: generate a revenue report over a time period for one or many channels.
  • outliers: close recommendations based whether channels are outliers based on a variety of metrics.
  • threshold: close recommendations based on thresholds a variety of metrics.
  • audit: produce an accounting report for your node over a period of time, please see the accounting documentation for details. Chain backend strongly recommended, fee entries for channel closes and sweeps will be missing if a chain connection is not provided.
  • fiat: get the USD price for an amount of Bitcoin at a given time, currently obtained from CoinCap's historical price API.
  • closereport: provides a channel specific fee report, including fees paid on chain. This endpoint is currently only implemented for cooperative closes. Requires chain backend.
Metrics currently tracked

The following metrics are tracked in faraday and exposed via insights and used for outliers and threshold close recommendations.

  • Uptime
  • Revenue
  • Total Volume
  • Incoming Volume
  • Outgoing Volume

Development

If you would like to contribute to Faraday, please see our issues page for currently open issues. If a feature that you would like to add is not covered by an existing issue, please open an issue to discuss the proposed addition. Contributions are hugely appreciated, and we will do our best to review pull requests timeously.

Tests

To run all the unit tests in the repo:

make check

To run Faraday's itests locally, you will need docker installed. To run all itests:

make itest

Individual itests can also be run using:

./run_itest.sh {test name}

Documentation

Overview

Package faraday contains the main function for faraday.

Index

Constants

View Source
const (
	DefaultNetwork = "mainnet"

	// DatabaseBackendSqlite is the name of the SQLite database backend.
	DatabaseBackendSqlite = "sqlite"

	// DatabaseBackendPostgres is the name of the Postgres database backend.
	DatabaseBackendPostgres = "postgres"
)
View Source
const Subsystem = "FRDY"

Subsystem defines the logging code for this subsystem.

Variables

View Source
var (
	// FaradayDirBase is the default main directory where faraday stores its
	// data.
	FaradayDirBase = btcutil.AppDataDir("faraday", false)

	// DefaultTLSCertFilename is the default file name for the autogenerated
	// TLS certificate.
	DefaultTLSCertFilename = "tls.cert"

	// DefaultTLSKeyFilename is the default file name for the autogenerated
	// TLS key.
	DefaultTLSKeyFilename = "tls.key"

	// DefaultTLSCertPath is the default full path of the autogenerated TLS
	// certificate.
	DefaultTLSCertPath = filepath.Join(
		FaradayDirBase, DefaultNetwork, DefaultTLSCertFilename,
	)

	// DefaultTLSKeyPath is the default full path of the autogenerated TLS
	// key.
	DefaultTLSKeyPath = filepath.Join(
		FaradayDirBase, DefaultNetwork, DefaultTLSKeyFilename,
	)

	// DefaultMacaroonFilename is the default file name for the
	// autogenerated faraday macaroon.
	DefaultMacaroonFilename = "faraday.macaroon"

	// DefaultMacaroonPath is the default full path of the base faraday
	// macaroon.
	DefaultMacaroonPath = filepath.Join(
		FaradayDirBase, DefaultNetwork, DefaultMacaroonFilename,
	)

	// DefaultLndDir is the default location where we look for lnd's tls and
	// macaroon files.
	DefaultLndDir = btcutil.AppDataDir("lnd", false)

	// DefaultLndMacaroonPath is the default location where we look for a
	// macaroon to use when connecting to lnd.
	DefaultLndMacaroonPath = filepath.Join(
		DefaultLndDir, "data", "chain", "bitcoin", DefaultNetwork,
		defaultLndMacaroon,
	)
)
View Source
var Commit string

Commit stores the current commit hash of this build, this should be set using the -ldflags during compilation.

View Source
var MinLndVersion = &verrpc.Version{
	AppMajor: 0,
	AppMinor: 15,
	AppPatch: 4,
}

MinLndVersion is the minimum lnd version required. Note that apis that are only available in more recent versions are available at compile time, so this version should be bumped if additional functionality is included that depends on newer apis.

Functions

func Main

func Main() error

Main is the real entry point for faraday. It is required to ensure that defers are properly executed when os.Exit() is called.

func NewStores

func NewStores(cfg Config, clock clock.Clock) (*stores, error)

NewStores creates a new stores instance based on the chosen database backend.

func SetupLoggers

func SetupLoggers(root *build.SubLoggerManager, intercept signal.Interceptor)

SetupLoggers initializes all package-global logger variables.

func UseLogger

func UseLogger(logger btclog.Logger)

UseLogger uses a specified Logger to output package logging info. This should be used in preference to SetLogWriter if the caller is also using btclog.

func ValidateConfig

func ValidateConfig(config *Config) error

ValidateConfig sanitizes all file system paths and makes sure no incompatible configuration combinations are used.

func Version

func Version() string

Version returns the application version as a properly formed string per the semantic versioning 2.0.0 spec (http://semver.org/).

Types

type Config

type Config struct {
	// Lnd holds the configuration options for the connection to lnd.
	Lnd *LndConfig `group:"lnd" namespace:"lnd"`

	// FaradayDir is the main directory where faraday stores all its data.
	FaradayDir string `` /* 151-byte string literal not displayed */

	// ChainConn specifies whether to attempt connecting to a bitcoin backend.
	ChainConn bool `` /* 161-byte string literal not displayed */

	ShowVersion bool `long:"version" description:"Display version information and exit"`

	// MinimumMonitored is the minimum amount of time that a channel must be monitored for before we consider it for termination.
	MinimumMonitored time.Duration `` /* 163-byte string literal not displayed */

	// Network is a string containing the network we're running on.
	Network string `` /* 135-byte string literal not displayed */

	// DebugLevel is a string defining the log level for the service either
	// for all subsystems the same or individual level by subsystem.
	DebugLevel string `long:"debuglevel" description:"Debug level for faraday and its subsystems."`

	TLSCertPath        string        `long:"tlscertpath" description:"Path to write the TLS certificate for faraday's RPC and REST services."`
	TLSKeyPath         string        `long:"tlskeypath" description:"Path to write the TLS private key for faraday's RPC and REST services."`
	TLSExtraIPs        []string      `long:"tlsextraip" description:"Adds an extra IP to the generated certificate."`
	TLSExtraDomains    []string      `long:"tlsextradomain" description:"Adds an extra domain to the generated certificate."`
	TLSAutoRefresh     bool          `long:"tlsautorefresh" description:"Re-generate TLS certificate and key if the IPs or domains are changed."`
	TLSDisableAutofill bool          `` /* 174-byte string literal not displayed */
	TLSCertDuration    time.Duration `long:"tlscertduration" description:"The duration for which the auto-generated TLS certificate will be valid for."`

	MacaroonPath string `long:"macaroonpath" description:"Path to write the macaroon for faraday's RPC and REST services if it doesn't exist."`

	// RPCListen is the listen address for the faraday rpc server.
	RPCListen string `long:"rpclisten" description:"Address to listen on for gRPC clients."`

	// RESTListen is the listen address for the faraday REST server.
	RESTListen string `long:"restlisten" description:"Address to listen on for REST clients. If not specified, no REST listener will be started."`

	// CORSOrigin specifies the CORS header that should be set on REST responses. No header is added if the value is empty.
	CORSOrigin string `long:"corsorigin" description:"The value to send in the Access-Control-Allow-Origin header. Header will be omitted if empty."`

	// Bitcoin is the configuration required to connect to a bitcoin node.
	Bitcoin *chain.BitcoinConfig `group:"bitcoin" namespace:"bitcoin"`

	// Logging controls various aspects of pool logging.
	Logging *build.LogConfig `group:"logging" namespace:"logging"`

	// DatabaseBackend is the database backend we will use for storing all
	// liveness data.
	DatabaseBackend string `` /* 129-byte string literal not displayed */

	// Sqlite holds the configuration options for a SQLite database
	// backend.
	Sqlite *db.SqliteConfig `group:"sqlite" namespace:"sqlite"`

	// Postgres holds the configuration options for a Postgres database
	Postgres *sqldb.PostgresConfig `group:"postgres" namespace:"postgres"`

	// ChanEvents holds the configuration options for channel event safety
	// pruning.
	ChanEvents *chanevents.Config `group:"chanevents" namespace:"chanevents"`
}

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns all default values for the Config struct.

type Faraday

type Faraday struct {
	*frdrpcserver.RPCServer
	// contains filtered or unexported fields
}

Faraday is a struct that houses the faraday daemon and its dependencies.

func New

func New(cfg *Config) *Faraday

New creates a new Faraday instance with the given configuration.

func (*Faraday) Start

func (f *Faraday) Start() error

Start starts faraday and its dependencies with an RPC server included.

func (*Faraday) StartAsSubserver

func (f *Faraday) StartAsSubserver(lndGrpc *lndclient.GrpcLndServices,
	withMacaroonService bool) error

StartAsSubserver is an alternative to Start where the RPC server does not create its own gRPC server but registers to an existing one. The same goes for REST (if enabled), instead of creating an own mux and HTTP server, we register to an existing one.

func (*Faraday) Stop

func (f *Faraday) Stop() error

Stop shuts down Faraday: the RPC servers, macaroon service, and, if Faraday owns the lnd connection (standalone mode via Start), the lnd connection as well. In subserver mode (started via StartAsSubserver) the lnd connection is left open for the parent process to manage.

Calling Stop on an already stopped or never-started instance is a no-op and returns nil.

func (*Faraday) ValidateMacaroon

func (f *Faraday) ValidateMacaroon(ctx context.Context,
	requiredPermissions []bakery.Op, fullMethod string) error

ValidateMacaroon extracts the macaroon from the context's gRPC metadata, checks its signature, makes sure all specified permissions for the called method are contained within and finally ensures all caveat conditions are met. A non-nil error is returned if any of the checks fail. This method is needed to enable faraday running as an external subserver in the same process as lnd but still validate its own macaroons.

type LndConfig

type LndConfig struct {
	// RPCServer is host:port that lnd's RPC server is listening on.
	RPCServer string `long:"rpcserver" description:"host:port that LND is listening for RPC connections on"`

	// MacaroonDir is the directory that contains all the macaroon files
	// required for the remote connection.
	MacaroonDir string `long:"macaroondir" description:"DEPRECATED: Use macaroonpath."`

	// MacaroonPath is the path to the single macaroon that should be used
	// instead of needing to specify the macaroon directory that contains
	// all of lnd's macaroons. The specified macaroon MUST have all
	// permissions that all the subservers use, otherwise permission errors
	// will occur.
	MacaroonPath string `` /* 304-byte string literal not displayed */

	// TLSCertPath is the path to the tls cert that faraday should use.
	TLSCertPath string `long:"tlscertpath" description:"Path to TLS cert"`

	// RequestTimeout is the maximum time to wait for a response from lnd.
	RequestTimeout time.Duration `` /* 136-byte string literal not displayed */
}

Directories

Path Synopsis
Package chanevents contains functions for monitoring and storing channel events such as online/offline and balance updates.
Package chanevents contains functions for monitoring and storing channel events such as online/offline and balance updates.
cmd
faraday command
frcli command
Package dataset provides a basic dataset type which provides functionality for detecting inter-quartile range outliers.
Package dataset provides a basic dataset type which provides functionality for detecting inter-quartile range outliers.
db
sqlc
Package sqlc provides a set of custom database queries and utilities for interacting with the SQL database used in the application.
Package sqlc provides a set of custom database queries and utilities for interacting with the SQL database used in the application.
frdrpc module
Package frdrpcserver contains the server logic for faraday's grpc server which serves requests for close recommendations.
Package frdrpcserver contains the server logic for faraday's grpc server which serves requests for close recommendations.
Package lndwrap wraps various calls to lndclient for convenience.
Package lndwrap wraps various calls to lndclient for convenience.
Package recommend provides recommendations for closing channels with the constraints provided in its close recommendation config.
Package recommend provides recommendations for closing channels with the constraints provided in its close recommendation config.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL