Release v0.3.0

This commit is contained in:
Manu Herrera
2020-11-09 10:05:29 -03:00
parent 4e9aa7a3c5
commit 8107c4478b
1265 changed files with 440488 additions and 107809 deletions

View File

@@ -0,0 +1,36 @@
package build
// DeploymentType is an enum specifying the deployment to compile.
type DeploymentType byte
const (
// Development is a deployment that includes extra testing hooks and
// logging configurations.
Development DeploymentType = iota
// Production is a deployment that strips out testing logic and uses
// Default logging.
Production
)
// String returns a human readable name for a build type.
func (b DeploymentType) String() string {
switch b {
case Development:
return "development"
case Production:
return "production"
default:
return "unknown"
}
}
// IsProdBuild returns true if this is a production build.
func IsProdBuild() bool {
return Deployment == Production
}
// IsDevBuild returns true if this is a development build.
func IsDevBuild() bool {
return Deployment == Development
}

View File

@@ -0,0 +1,6 @@
// +build dev
package build
// Deployment specifies a development build.
const Deployment = Development

View File

@@ -0,0 +1,6 @@
// +build !dev
package build
// Deployment specifies a production build.
const Deployment = Production

200
vendor/github.com/lightningnetwork/lnd/build/log.go generated vendored Normal file
View File

@@ -0,0 +1,200 @@
package build
import (
"fmt"
"io"
"strings"
"github.com/btcsuite/btclog"
)
// LogType is an indicating the type of logging specified by the build flag.
type LogType byte
const (
// LogTypeNone indicates no logging.
LogTypeNone LogType = iota
// LogTypeStdOut all logging is written directly to stdout.
LogTypeStdOut
// LogTypeDefault logs to both stdout and a given io.PipeWriter.
LogTypeDefault
)
// String returns a human readable identifier for the logging type.
func (t LogType) String() string {
switch t {
case LogTypeNone:
return "none"
case LogTypeStdOut:
return "stdout"
case LogTypeDefault:
return "default"
default:
return "unknown"
}
}
// LogWriter is a stub type whose behavior can be changed using the build flags
// "stdlog" and "nolog". The default behavior is to write to both stdout and the
// RotatorPipe. Passing "stdlog" will cause it only to write to stdout, and
// "nolog" implements Write as a no-op.
type LogWriter struct {
// RotatorPipe is the write-end pipe for writing to the log rotator. It
// is written to by the Write method of the LogWriter type. This only
// needs to be set if neither the stdlog or nolog builds are set.
RotatorPipe *io.PipeWriter
}
// NewSubLogger constructs a new subsystem log from the current LogWriter
// implementation. This is primarily intended for use with stdlog, as the actual
// writer is shared amongst all instantiations.
func NewSubLogger(subsystem string,
genSubLogger func(string) btclog.Logger) btclog.Logger {
switch Deployment {
// For production builds, generate a new subsystem logger from the
// primary log backend. If no function is provided, logging will be
// disabled.
case Production:
if genSubLogger != nil {
return genSubLogger(subsystem)
}
// For development builds, we must handle two distinct types of logging:
// unit tests and running the live daemon, e.g. for integration testing.
case Development:
switch LoggingType {
// Default logging is used when running the standalone daemon.
// We'll use the optional sublogger constructor to mimic the
// production behavior.
case LogTypeDefault:
if genSubLogger != nil {
return genSubLogger(subsystem)
}
// Logging to stdout is used in unit tests. It is not important
// that they share the same backend, since all output is written
// to std out.
case LogTypeStdOut:
backend := btclog.NewBackend(&LogWriter{})
logger := backend.Logger(subsystem)
// Set the logging level of the stdout logger to use the
// configured logging level specified by build flags.
level, _ := btclog.LevelFromString(LogLevel)
logger.SetLevel(level)
return logger
}
}
// For any other configurations, we'll disable logging.
return btclog.Disabled
}
// SubLoggers is a type that holds a map of subsystem loggers keyed by their
// subsystem name.
type SubLoggers map[string]btclog.Logger
// LeveledSubLogger provides the ability to retrieve the subsystem loggers of
// a logger and set their log levels individually or all at once.
type LeveledSubLogger interface {
// SubLoggers returns the map of all registered subsystem loggers.
SubLoggers() SubLoggers
// SupportedSubsystems returns a slice of strings containing the names
// of the supported subsystems. Should ideally correspond to the keys
// of the subsystem logger map and be sorted.
SupportedSubsystems() []string
// SetLogLevel assigns an individual subsystem logger a new log level.
SetLogLevel(subsystemID string, logLevel string)
// SetLogLevels assigns all subsystem loggers the same new log level.
SetLogLevels(logLevel string)
}
// ParseAndSetDebugLevels attempts to parse the specified debug level and set
// the levels accordingly on the given logger. An appropriate error is returned
// if anything is invalid.
func ParseAndSetDebugLevels(level string, logger LeveledSubLogger) error {
// When the specified string doesn't have any delimiters, treat it as
// the log level for all subsystems.
if !strings.Contains(level, ",") && !strings.Contains(level, "=") {
// Validate debug log level.
if !validLogLevel(level) {
str := "the specified debug level [%v] is invalid"
return fmt.Errorf(str, level)
}
// Change the logging level for all subsystems.
logger.SetLogLevels(level)
return nil
}
// Split the specified string into subsystem/level pairs while detecting
// issues and update the log levels accordingly.
for _, logLevelPair := range strings.Split(level, ",") {
if !strings.Contains(logLevelPair, "=") {
str := "the specified debug level contains an " +
"invalid subsystem/level pair [%v]"
return fmt.Errorf(str, logLevelPair)
}
// Extract the specified subsystem and log level.
fields := strings.Split(logLevelPair, "=")
if len(fields) != 2 {
str := "the specified debug level has an invalid " +
"format [%v] -- use format subsystem1=level1," +
"subsystem2=level2"
return fmt.Errorf(str, logLevelPair)
}
subsysID, logLevel := fields[0], fields[1]
subLoggers := logger.SubLoggers()
// Validate subsystem.
if _, exists := subLoggers[subsysID]; !exists {
str := "the specified subsystem [%v] is invalid -- " +
"supported subsystems are %v"
return fmt.Errorf(
str, subsysID, logger.SupportedSubsystems(),
)
}
// Validate log level.
if !validLogLevel(logLevel) {
str := "the specified debug level [%v] is invalid"
return fmt.Errorf(str, logLevel)
}
logger.SetLogLevel(subsysID, logLevel)
}
return nil
}
// validLogLevel returns whether or not logLevel is a valid debug log level.
func validLogLevel(logLevel string) bool {
switch logLevel {
case "trace":
fallthrough
case "debug":
fallthrough
case "info":
fallthrough
case "warn":
fallthrough
case "error":
fallthrough
case "critical":
fallthrough
case "off":
return true
}
return false
}

View File

@@ -0,0 +1,18 @@
// +build !stdlog,!nolog
package build
import "os"
// LoggingType is a log type that writes to both stdout and the log rotator, if
// present.
const LoggingType = LogTypeDefault
// Write writes the byte slice to both stdout and the log rotator, if present.
func (w *LogWriter) Write(b []byte) (int, error) {
os.Stdout.Write(b)
if w.RotatorPipe != nil {
w.RotatorPipe.Write(b)
}
return len(b), nil
}

View File

@@ -0,0 +1,11 @@
// +build nolog
package build
// LoggingType is a log type that writes no logs.
const LoggingType = LogTypeNone
// Write is a noop.
func (w *LogWriter) Write(b []byte) (int, error) {
return len(b), nil
}

View File

@@ -0,0 +1,14 @@
// +build stdlog
package build
import "os"
// LoggingType is a log type that only writes to stdout.
const LoggingType = LogTypeStdOut
// Write writes the provided byte slice to stdout.
func (w *LogWriter) Write(b []byte) (int, error) {
os.Stdout.Write(b)
return len(b), nil
}

View File

@@ -0,0 +1,6 @@
// +build dev,critical
package build
// LogLevel specifies a critical log level.
var LogLevel = "critical"

View File

@@ -0,0 +1,6 @@
// +build dev,debug
package build
// LogLevel specifies a debug log level.
var LogLevel = "debug"

View File

@@ -0,0 +1,6 @@
// +build !info,!debug,!trace,!warn,!error,!critical,!off
package build
// LogLevel specifies a default log level of info.
var LogLevel = "info"

View File

@@ -0,0 +1,6 @@
// +build dev,error
package build
// LogLevel specifies an error log level.
var LogLevel = "error"

View File

@@ -0,0 +1,6 @@
// +build dev,info
package build
// LogLevel specifies an info log level.
var LogLevel = "info"

View File

@@ -0,0 +1,6 @@
// +build dev,off
package build
// LogLevel specifies an off log level.
var LogLevel = "off"

View File

@@ -0,0 +1,6 @@
// +build dev,trace
package build
// LogLevel specifies a trace log level.
var LogLevel = "trace"

View File

@@ -0,0 +1,6 @@
// +build dev,warn
package build
// LogLevel specifies a warning log level.
var LogLevel = "warn"

View File

@@ -0,0 +1,151 @@
package build
import (
"fmt"
"io"
"os"
"path/filepath"
"sort"
"github.com/btcsuite/btclog"
"github.com/jrick/logrotate/rotator"
)
// RotatingLogWriter is a wrapper around the LogWriter that supports log file
// rotation.
type RotatingLogWriter struct {
// GenSubLogger is a function that returns a new logger for a subsystem
// belonging to the current RotatingLogWriter.
GenSubLogger func(string) btclog.Logger
logWriter *LogWriter
backendLog *btclog.Backend
logRotator *rotator.Rotator
subsystemLoggers SubLoggers
}
// A compile time check to ensure RotatingLogWriter implements the
// LeveledSubLogger interface.
var _ LeveledSubLogger = (*RotatingLogWriter)(nil)
// NewRotatingLogWriter creates a new file rotating log writer.
//
// NOTE: `InitLogRotator` must be called to set up log rotation after creating
// the writer.
func NewRotatingLogWriter() *RotatingLogWriter {
logWriter := &LogWriter{}
backendLog := btclog.NewBackend(logWriter)
return &RotatingLogWriter{
GenSubLogger: backendLog.Logger,
logWriter: logWriter,
backendLog: backendLog,
subsystemLoggers: SubLoggers{},
}
}
// RegisterSubLogger registers a new subsystem logger.
func (r *RotatingLogWriter) RegisterSubLogger(subsystem string,
logger btclog.Logger) {
r.subsystemLoggers[subsystem] = logger
}
// InitLogRotator initializes the log file rotator to write logs to logFile and
// create roll files in the same directory. It should be called as early on
// startup and possible and must be closed on shutdown by calling `Close`.
func (r *RotatingLogWriter) InitLogRotator(logFile string, maxLogFileSize int,
maxLogFiles int) error {
logDir, _ := filepath.Split(logFile)
err := os.MkdirAll(logDir, 0700)
if err != nil {
return fmt.Errorf("failed to create log directory: %v", err)
}
r.logRotator, err = rotator.New(
logFile, int64(maxLogFileSize*1024), false, maxLogFiles,
)
if err != nil {
return fmt.Errorf("failed to create file rotator: %v", err)
}
// Run rotator as a goroutine now but make sure we catch any errors
// that happen in case something with the rotation goes wrong during
// runtime (like running out of disk space or not being allowed to
// create a new logfile for whatever reason).
pr, pw := io.Pipe()
go func() {
err := r.logRotator.Run(pr)
if err != nil {
_, _ = fmt.Fprintf(os.Stderr,
"failed to run file rotator: %v\n", err)
}
}()
r.logWriter.RotatorPipe = pw
return nil
}
// Close closes the underlying log rotator if it has already been created.
func (r *RotatingLogWriter) Close() error {
if r.logRotator != nil {
return r.logRotator.Close()
}
return nil
}
// SubLoggers returns all currently registered subsystem loggers for this log
// writer.
//
// NOTE: This is part of the LeveledSubLogger interface.
func (r *RotatingLogWriter) SubLoggers() SubLoggers {
return r.subsystemLoggers
}
// SupportedSubsystems returns a sorted string slice of all keys in the
// subsystems map, corresponding to the names of the subsystems.
//
// NOTE: This is part of the LeveledSubLogger interface.
func (r *RotatingLogWriter) SupportedSubsystems() []string {
// Convert the subsystemLoggers map keys to a string slice.
subsystems := make([]string, 0, len(r.subsystemLoggers))
for subsysID := range r.subsystemLoggers {
subsystems = append(subsystems, subsysID)
}
// Sort the subsystems for stable display.
sort.Strings(subsystems)
return subsystems
}
// SetLogLevel sets the logging level for provided subsystem. Invalid
// subsystems are ignored. Uninitialized subsystems are dynamically created as
// needed.
//
// NOTE: This is part of the LeveledSubLogger interface.
func (r *RotatingLogWriter) SetLogLevel(subsystemID string, logLevel string) {
// Ignore invalid subsystems.
logger, ok := r.subsystemLoggers[subsystemID]
if !ok {
return
}
// Defaults to info if the log level is invalid.
level, _ := btclog.LevelFromString(logLevel)
logger.SetLevel(level)
}
// SetLogLevels sets the log level for all subsystem loggers to the passed
// level. It also dynamically creates the subsystem loggers as needed, so it
// can be used to initialize the logging system.
//
// NOTE: This is part of the LeveledSubLogger interface.
func (r *RotatingLogWriter) SetLogLevels(logLevel string) {
// Configure all sub-systems with the new logging level. Dynamically
// create loggers as needed.
for subsystemID := range r.subsystemLoggers {
r.SetLogLevel(subsystemID, logLevel)
}
}

View File

@@ -0,0 +1,112 @@
package build
import "github.com/btcsuite/btclog"
// PrefixLog is a pass-through logger that adds a prefix to every logged line.
type PrefixLog struct {
log btclog.Logger
prefix string
}
// NewPrefixLog instantiates a new prefixed logger.
func NewPrefixLog(prefix string, log btclog.Logger) *PrefixLog {
return &PrefixLog{
prefix: prefix,
log: log,
}
}
// addFormatPrefix prepends the prefix to a format string.
func (p *PrefixLog) addFormatPrefix(s string) string {
return p.prefix + " " + s
}
// addArgsPrefix prepends the prefix to a list of arguments.
func (p *PrefixLog) addArgsPrefix(args []interface{}) []interface{} {
return append([]interface{}{p.prefix}, args...)
}
// Tracef formats message according to format specifier and writes to to log
// with LevelTrace.
func (p *PrefixLog) Tracef(format string, params ...interface{}) {
p.log.Tracef(p.addFormatPrefix(format), params...)
}
// Debugf formats message according to format specifier and writes to log with
// LevelDebug.
func (p *PrefixLog) Debugf(format string, params ...interface{}) {
p.log.Debugf(p.addFormatPrefix(format), params...)
}
// Infof formats message according to format specifier and writes to log with
// LevelInfo.
func (p *PrefixLog) Infof(format string, params ...interface{}) {
p.log.Infof(p.addFormatPrefix(format), params...)
}
// Warnf formats message according to format specifier and writes to to log with
// LevelWarn.
func (p *PrefixLog) Warnf(format string, params ...interface{}) {
p.log.Warnf(p.addFormatPrefix(format), params...)
}
// Errorf formats message according to format specifier and writes to to log
// with LevelError.
func (p *PrefixLog) Errorf(format string, params ...interface{}) {
p.log.Errorf(p.addFormatPrefix(format), params...)
}
// Criticalf formats message according to format specifier and writes to log
// with LevelCritical.
func (p *PrefixLog) Criticalf(format string, params ...interface{}) {
p.log.Criticalf(p.addFormatPrefix(format), params...)
}
// Trace formats message using the default formats for its operands and writes
// to log with LevelTrace.
func (p *PrefixLog) Trace(v ...interface{}) {
p.log.Trace(p.addArgsPrefix(v)...)
}
// Debug formats message using the default formats for its operands and writes
// to log with LevelDebug.
func (p *PrefixLog) Debug(v ...interface{}) {
p.log.Debug(p.addArgsPrefix(v)...)
}
// Info formats message using the default formats for its operands and writes to
// log with LevelInfo.
func (p *PrefixLog) Info(v ...interface{}) {
p.log.Info(p.addArgsPrefix(v)...)
}
// Warn formats message using the default formats for its operands and writes to
// log with LevelWarn.
func (p *PrefixLog) Warn(v ...interface{}) {
p.log.Warn(p.addArgsPrefix(v)...)
}
// Error formats message using the default formats for its operands and writes
// to log with LevelError.
func (p *PrefixLog) Error(v ...interface{}) {
p.log.Error(p.addArgsPrefix(v)...)
}
// Critical formats message using the default formats for its operands and
// writes to log with LevelCritical.
func (p *PrefixLog) Critical(v ...interface{}) {
p.log.Critical(p.addArgsPrefix(v)...)
}
// Level returns the current logging level.
func (p *PrefixLog) Level() btclog.Level {
return p.log.Level()
}
// SetLevel changes the logging level to the passed level.
func (p *PrefixLog) SetLevel(level btclog.Level) {
p.log.SetLevel(level)
}
// Assert that PrefixLog fulfills the btclog.Logger interface.
var _ btclog.Logger = &PrefixLog{}

View File

@@ -0,0 +1,90 @@
// Copyright (c) 2013-2017 The btcsuite developers
// Copyright (c) 2015-2016 The Decred developers
// Heavily inspired by https://github.com/btcsuite/btcd/blob/master/version.go
// Copyright (C) 2015-2017 The Lightning Network Developers
package build
import (
"fmt"
"strings"
)
var (
// Commit stores the current commit of this build, which includes the
// most recent tag, the number of commits since that tag (if non-zero),
// the commit hash, and a dirty marker. This should be set using the
// -ldflags during compilation.
Commit string
// CommitHash stores the current commit hash of this build, this should
// be set using the -ldflags during compilation.
CommitHash string
// RawTags contains the raw set of build tags, separated by commas. This
// should be set using -ldflags during compilation.
RawTags string
// GoVersion stores the go version that the executable was compiled
// with. This hsould be set using -ldflags during compilation.
GoVersion string
)
// semanticAlphabet is the set of characters that are permitted for use in an
// AppPreRelease.
const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-."
// These constants define the application version and follow the semantic
// versioning 2.0.0 spec (http://semver.org/).
const (
// AppMajor defines the major version of this binary.
AppMajor uint = 0
// AppMinor defines the minor version of this binary.
AppMinor uint = 10
// AppPatch defines the application patch for this binary.
AppPatch uint = 4
// AppPreRelease MUST only contain characters from semanticAlphabet
// per the semantic versioning spec.
AppPreRelease = "beta"
)
func init() {
// Assert that AppPreRelease is valid according to the semantic
// versioning guidelines for pre-release version and build metadata
// strings. In particular it MUST only contain characters in
// semanticAlphabet.
for _, r := range AppPreRelease {
if !strings.ContainsRune(semanticAlphabet, r) {
panic(fmt.Errorf("rune: %v is not in the semantic "+
"alphabet", r))
}
}
}
// Version returns the application version as a properly formed string per the
// semantic versioning 2.0.0 spec (http://semver.org/).
func Version() string {
// Start with the major, minor, and patch versions.
version := fmt.Sprintf("%d.%d.%d", AppMajor, AppMinor, AppPatch)
// Append pre-release version if there is one. The hyphen called for by
// the semantic versioning spec is automatically appended and should not
// be contained in the pre-release string.
if AppPreRelease != "" {
version = fmt.Sprintf("%s-%s", version, AppPreRelease)
}
return version
}
// Tags returns the list of build tags that were compiled into the executable.
func Tags() []string {
if len(RawTags) == 0 {
return nil
}
return strings.Split(RawTags, ",")
}