Merge pull request #4757 from Crypt-iQ/fmgr_1109

funding: move Manager to own package
This commit is contained in:
Eugene 2020-12-17 11:43:12 -05:00 committed by GitHub
commit e0439965bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 653 additions and 657 deletions

@ -27,6 +27,7 @@ import (
"github.com/lightningnetwork/lnd/chanbackup"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/discovery"
"github.com/lightningnetwork/lnd/funding"
"github.com/lightningnetwork/lnd/htlcswitch"
"github.com/lightningnetwork/lnd/htlcswitch/hodl"
"github.com/lightningnetwork/lnd/input"
@ -413,7 +414,7 @@ func DefaultConfig() Config {
Autopilot: &lncfg.AutoPilot{
MaxChannels: 5,
Allocation: 0.6,
MinChannelSize: int64(minChanFundingSize),
MinChannelSize: int64(funding.MinChanFundingSize),
MaxChannelSize: int64(MaxFundingAmount),
MinConfs: 1,
ConfTarget: autopilot.DefaultConfTarget,
@ -429,7 +430,7 @@ func DefaultConfig() Config {
HeightHintCacheQueryDisable: defaultHeightHintCacheQueryDisable,
Alias: defaultAlias,
Color: defaultColor,
MinChanSize: int64(minChanFundingSize),
MinChanSize: int64(funding.MinChanFundingSize),
MaxChanSize: int64(0),
DefaultRemoteMaxHtlcs: defaultRemoteMaxHtlcs,
NumGraphSyncPeers: defaultMinPeers,
@ -689,8 +690,8 @@ func ValidateConfig(cfg Config, usageMessage string) (*Config, error) {
// Ensure that the specified values for the min and max channel size
// are within the bounds of the normal chan size constraints.
if cfg.Autopilot.MinChannelSize < int64(minChanFundingSize) {
cfg.Autopilot.MinChannelSize = int64(minChanFundingSize)
if cfg.Autopilot.MinChannelSize < int64(funding.MinChanFundingSize) {
cfg.Autopilot.MinChannelSize = int64(funding.MinChanFundingSize)
}
if cfg.Autopilot.MaxChannelSize > int64(MaxFundingAmount) {
cfg.Autopilot.MaxChannelSize = int64(MaxFundingAmount)
@ -707,9 +708,9 @@ func ValidateConfig(cfg Config, usageMessage string) (*Config, error) {
// If unset (marked by 0 value), then enforce proper default.
if cfg.MaxChanSize == 0 {
if cfg.ProtocolOptions.Wumbo() {
cfg.MaxChanSize = int64(MaxBtcFundingAmountWumbo)
cfg.MaxChanSize = int64(funding.MaxBtcFundingAmountWumbo)
} else {
cfg.MaxChanSize = int64(MaxBtcFundingAmount)
cfg.MaxChanSize = int64(funding.MaxBtcFundingAmount)
}
}
@ -857,7 +858,7 @@ func ValidateConfig(cfg Config, usageMessage string) (*Config, error) {
"litecoin.active must be set to 1 (true)", funcName)
case cfg.Litecoin.Active:
err := cfg.Litecoin.Validate(minTimeLockDelta, minLtcRemoteDelay)
err := cfg.Litecoin.Validate(minTimeLockDelta, funding.MinLtcRemoteDelay)
if err != nil {
return nil, err
}
@ -941,7 +942,7 @@ func ValidateConfig(cfg Config, usageMessage string) (*Config, error) {
// Finally we'll register the litecoin chain as our current
// primary chain.
cfg.registeredChains.RegisterPrimaryChain(chainreg.LitecoinChain)
MaxFundingAmount = maxLtcFundingAmount
MaxFundingAmount = funding.MaxLtcFundingAmount
case cfg.Bitcoin.Active:
// Multiple networks can't be selected simultaneously. Count
@ -982,7 +983,7 @@ func ValidateConfig(cfg Config, usageMessage string) (*Config, error) {
return nil, err
}
err := cfg.Bitcoin.Validate(minTimeLockDelta, minBtcRemoteDelay)
err := cfg.Bitcoin.Validate(minTimeLockDelta, funding.MinBtcRemoteDelay)
if err != nil {
return nil, err
}
@ -1060,8 +1061,8 @@ func ValidateConfig(cfg Config, usageMessage string) (*Config, error) {
// Ensure that the specified values for the min and max channel size
// don't are within the bounds of the normal chan size constraints.
if cfg.Autopilot.MinChannelSize < int64(minChanFundingSize) {
cfg.Autopilot.MinChannelSize = int64(minChanFundingSize)
if cfg.Autopilot.MinChannelSize < int64(funding.MinChanFundingSize) {
cfg.Autopilot.MinChannelSize = int64(funding.MinChanFundingSize)
}
if cfg.Autopilot.MaxChannelSize > int64(MaxFundingAmount) {
cfg.Autopilot.MaxChannelSize = int64(MaxFundingAmount)

@ -1,20 +1,21 @@
package fmgr
package funding
import (
"github.com/lightningnetwork/lnd/lnpeer"
"github.com/lightningnetwork/lnd/lnwire"
)
// Manager is an interface that describes the basic operation of a funding
// manager. It should at a minimum process a subset of lnwire messages that
// Controller is an interface with basic funding flow functions.
// It describes the basic functionality of a funding manager.
// It should at a minimum process a subset of lnwire messages that
// are denoted as funding messages.
type Manager interface {
type Controller interface {
// ProcessFundingMsg processes a funding message represented by the
// lnwire.Message parameter along with the Peer object representing a
// connection to the counterparty.
ProcessFundingMsg(lnwire.Message, lnpeer.Peer)
// IsPendingChannel is used to determine whether to send an Error message
// to the funding manager or not.
// IsPendingChannel returns whether a particular 32-byte identifier
// represents a pending channel in the Controller implementation.
IsPendingChannel([32]byte, lnpeer.Peer) bool
}

27
funding/log.go Normal file

@ -0,0 +1,27 @@
package funding
import (
"github.com/btcsuite/btclog"
"github.com/lightningnetwork/lnd/build"
)
// Subsystem defines the logging code for this subsystem.
const Subsystem = "FNDG"
// log is a logger that is initialized with the btclog.Disabled logger.
var log btclog.Logger
// The default amount of logging is none.
func init() {
UseLogger(build.NewSubLogger(Subsystem, nil))
}
// DisableLog disables all logging output.
func DisableLog() {
UseLogger(btclog.Disabled)
}
// UseLogger uses a specified Logger to output package logging info.
func UseLogger(logger btclog.Logger) {
log = logger
}

@ -1,9 +1,10 @@
package lnd
package funding
import (
"bytes"
"encoding/binary"
"fmt"
"io"
"sync"
"time"
@ -34,32 +35,46 @@ import (
"golang.org/x/crypto/salsa20"
)
var (
// byteOrder defines the endian-ness we use for encoding to and from
// buffers.
byteOrder = binary.BigEndian
)
// WriteOutpoint writes an outpoint to an io.Writer. This is not the same as
// the channeldb variant as this uses WriteVarBytes for the Hash.
func WriteOutpoint(w io.Writer, o *wire.OutPoint) error {
scratch := make([]byte, 4)
if err := wire.WriteVarBytes(w, 0, o.Hash[:]); err != nil {
return err
}
byteOrder.PutUint32(scratch, o.Index)
_, err := w.Write(scratch)
return err
}
const (
// TODO(roasbeef): tune
msgBufferSize = 50
// MinBtcRemoteDelay is the minimum CSV delay we will require the remote
// to use for its commitment transaction.
MinBtcRemoteDelay uint16 = 144
// minBtcRemoteDelay and maxBtcRemoteDelay is the extremes of the
// Bitcoin CSV delay we will require the remote to use for its
// commitment transaction. The actual delay we will require will be
// somewhere between these values, depending on channel size.
minBtcRemoteDelay uint16 = 144
maxBtcRemoteDelay uint16 = 2016
// MaxBtcRemoteDelay is the maximum CSV delay we will require the remote
// to use for its commitment transaction.
MaxBtcRemoteDelay uint16 = 2016
// minLtcRemoteDelay and maxLtcRemoteDelay is the extremes of the
// Litecoin CSV delay we will require the remote to use for its
// commitment transaction. The actual delay we will require will be
// somewhere between these values, depending on channel size.
minLtcRemoteDelay uint16 = 576
maxLtcRemoteDelay uint16 = 8064
// MinLtcRemoteDelay is the minimum Litecoin CSV delay we will require the
// remote to use for its commitment transaction.
MinLtcRemoteDelay uint16 = 576
// maxWaitNumBlocksFundingConf is the maximum number of blocks to wait
// for the funding transaction to be confirmed before forgetting
// channels that aren't initiated by us. 2016 blocks is ~2 weeks.
maxWaitNumBlocksFundingConf = 2016
// MaxLtcRemoteDelay is the maximum Litecoin CSV delay we will require the
// remote to use for its commitment transaction.
MaxLtcRemoteDelay uint16 = 8064
// minChanFundingSize is the smallest channel that we'll allow to be
// MinChanFundingSize is the smallest channel that we'll allow to be
// created over the RPC interface.
minChanFundingSize = btcutil.Amount(20000)
MinChanFundingSize = btcutil.Amount(20000)
// MaxBtcFundingAmount is a soft-limit of the maximum channel size
// currently accepted on the Bitcoin chain within the Lightning
@ -73,24 +88,21 @@ const (
// you and limitless channel size (apart from 21 million cap)
MaxBtcFundingAmountWumbo = btcutil.Amount(1000000000)
// maxLtcFundingAmount is a soft-limit of the maximum channel size
// MaxLtcFundingAmount is a soft-limit of the maximum channel size
// currently accepted on the Litecoin chain within the Lightning
// Protocol.
maxLtcFundingAmount = MaxBtcFundingAmount * chainreg.BtcToLtcConversionRate
MaxLtcFundingAmount = MaxBtcFundingAmount * chainreg.BtcToLtcConversionRate
// TODO(roasbeef): tune
msgBufferSize = 50
// maxWaitNumBlocksFundingConf is the maximum number of blocks to wait
// for the funding transaction to be confirmed before forgetting
// channels that aren't initiated by us. 2016 blocks is ~2 weeks.
maxWaitNumBlocksFundingConf = 2016
)
var (
// MaxFundingAmount is a soft-limit of the maximum channel size
// currently accepted within the Lightning Protocol. This limit is
// defined in BOLT-0002, and serves as an initial precautionary limit
// while implementations are battle tested in the real world.
//
// At the moment, this value depends on which chain is active. It is set
// to the value under the Bitcoin chain as default.
//
// TODO(roasbeef): add command line param to modify
MaxFundingAmount = MaxBtcFundingAmount
// ErrFundingManagerShuttingDown is an error returned when attempting to
// process a funding request/message but the funding manager has already
// been signaled to shut down.
@ -159,14 +171,82 @@ func (r *reservationWithCtx) updateTimestamp() {
r.lastUpdated = time.Now()
}
// initFundingMsg is sent by an outside subsystem to the funding manager in
// InitFundingMsg is sent by an outside subsystem to the funding manager in
// order to kick off a funding workflow with a specified target peer. The
// original request which defines the parameters of the funding workflow are
// embedded within this message giving the funding manager full context w.r.t
// the workflow.
type initFundingMsg struct {
peer lnpeer.Peer
*openChanReq
type InitFundingMsg struct {
// Peer is the peer that we want to open a channel to.
Peer lnpeer.Peer
// TargetPubkey is the public key of the peer.
TargetPubkey *btcec.PublicKey
// ChainHash is the target genesis hash for this channel.
ChainHash chainhash.Hash
// SubtractFees set to true means that fees will be subtracted
// from the LocalFundingAmt.
SubtractFees bool
// LocalFundingAmt is the size of the channel.
LocalFundingAmt btcutil.Amount
// PushAmt is the amount pushed to the counterparty.
PushAmt lnwire.MilliSatoshi
// FundingFeePerKw is the fee for the funding transaction.
FundingFeePerKw chainfee.SatPerKWeight
// Private determines whether or not this channel will be private.
Private bool
// MinHtlcIn is the minimum incoming HTLC that we accept.
MinHtlcIn lnwire.MilliSatoshi
// RemoteCsvDelay is the CSV delay we require for the remote peer.
RemoteCsvDelay uint16
// MinConfs indicates the minimum number of confirmations that each
// output selected to fund the channel should satisfy.
MinConfs int32
// ShutdownScript is an optional upfront shutdown script for the
// channel. This value is optional, so may be nil.
ShutdownScript lnwire.DeliveryAddress
// MaxValueInFlight is the maximum amount of coins in MilliSatoshi
// that can be pending within the channel. It only applies to the
// remote party.
MaxValueInFlight lnwire.MilliSatoshi
// MaxHtlcs is the maximum number of HTLCs that the remote peer
// can offer us.
MaxHtlcs uint16
// MaxLocalCsv is the maximum local csv delay we will accept from our
// peer.
MaxLocalCsv uint16
// ChanFunder is an optional channel funder that allows the caller to
// control exactly how the channel funding is carried out. If not
// specified, then the default chanfunding.WalletAssembler will be
// used.
ChanFunder chanfunding.Assembler
// PendingChanID is not all zeroes (the default value), then this will
// be the pending channel ID used for the funding flow within the wire
// protocol.
PendingChanID [32]byte
// Updates is a channel which updates to the opening status of the channel
// are sent on.
Updates chan *lnrpc.OpenStatusUpdate
// Err is a channel which errors encountered during the funding flow are
// sent on.
Err chan error
}
// fundingMsg is sent by the ProcessFundingMsg function and packages a
@ -194,10 +274,10 @@ func newSerializedKey(pubKey *btcec.PublicKey) serializedPubKey {
return s
}
// fundingConfig defines the configuration for the FundingManager. All elements
// Config defines the configuration for the FundingManager. All elements
// within the configuration MUST be non-nil for the FundingManager to carry out
// its duties.
type fundingConfig struct {
type Config struct {
// NoWumboChans indicates if we're to reject all incoming wumbo channel
// requests, and also reject all outgoing wumbo channel requests.
NoWumboChans bool
@ -372,7 +452,7 @@ type fundingConfig struct {
MaxAnchorsCommitFeeRate chainfee.SatPerKWeight
}
// fundingManager acts as an orchestrator/bridge between the wallet's
// Manager acts as an orchestrator/bridge between the wallet's
// 'ChannelReservation' workflow, and the wire protocol's funding initiation
// messages. Any requests to initiate the funding workflow for a channel,
// either kicked-off locally or remotely are handled by the funding manager.
@ -381,13 +461,13 @@ type fundingConfig struct {
// the channel workflow. Additionally, any temporary or permanent access
// controls between the wallet and remote peers are enforced via the funding
// manager.
type fundingManager struct {
type Manager struct {
started sync.Once
stopped sync.Once
// cfg is a copy of the configuration struct that the FundingManager
// was initialized with.
cfg *fundingConfig
cfg *Config
// chanIDKey is a cryptographically random key that's used to generate
// temporary channel ID's.
@ -417,13 +497,9 @@ type fundingManager struct {
// external sub-systems using the ProcessFundingMsg call.
fundingMsgs chan *fundingMsg
// queries is a channel which receives requests to query the internal
// state of the funding manager.
queries chan interface{}
// fundingRequests is a channel used to receive channel initiation
// requests from a local subsystem within the daemon.
fundingRequests chan *initFundingMsg
fundingRequests chan *InitFundingMsg
// newChanBarriers is a map from a channel ID to a 'barrier' which will
// be signalled once the channel is fully open. This barrier acts as a
@ -478,27 +554,26 @@ var (
ErrChannelNotFound = fmt.Errorf("channel not found")
)
// newFundingManager creates and initializes a new instance of the
// NewFundingManager creates and initializes a new instance of the
// fundingManager.
func newFundingManager(cfg fundingConfig) (*fundingManager, error) {
return &fundingManager{
func NewFundingManager(cfg Config) (*Manager, error) {
return &Manager{
cfg: &cfg,
chanIDKey: cfg.TempChanIDSeed,
activeReservations: make(map[serializedPubKey]pendingChannels),
signedReservations: make(map[lnwire.ChannelID][32]byte),
newChanBarriers: make(map[lnwire.ChannelID]chan struct{}),
fundingMsgs: make(chan *fundingMsg, msgBufferSize),
fundingRequests: make(chan *initFundingMsg, msgBufferSize),
fundingRequests: make(chan *InitFundingMsg, msgBufferSize),
localDiscoverySignals: make(map[lnwire.ChannelID]chan struct{}),
handleFundingLockedBarriers: make(map[lnwire.ChannelID]struct{}),
queries: make(chan interface{}, 1),
quit: make(chan struct{}),
}, nil
}
// Start launches all helper goroutines required for handling requests sent
// to the funding manager.
func (f *fundingManager) Start() error {
func (f *Manager) Start() error {
var err error
f.started.Do(func() {
err = f.start()
@ -506,8 +581,8 @@ func (f *fundingManager) Start() error {
return err
}
func (f *fundingManager) start() error {
fndgLog.Tracef("Funding manager running")
func (f *Manager) start() error {
log.Tracef("Funding manager running")
// Upon restart, the Funding Manager will check the database to load any
// channels that were waiting for their funding transactions to be
@ -529,7 +604,7 @@ func (f *fundingManager) start() error {
// funding transaction if we're the initiator.
if channel.IsPending {
f.barrierMtx.Lock()
fndgLog.Tracef("Loading pending ChannelPoint(%v), "+
log.Tracef("Loading pending ChannelPoint(%v), "+
"creating chan barrier",
channel.FundingOutpoint)
@ -548,7 +623,7 @@ func (f *fundingManager) start() error {
var fundingTxBuf bytes.Buffer
err := channel.FundingTxn.Serialize(&fundingTxBuf)
if err != nil {
fndgLog.Errorf("Unable to serialize "+
log.Errorf("Unable to serialize "+
"funding transaction %v: %v",
channel.FundingTxn.TxHash(), err)
@ -559,7 +634,7 @@ func (f *fundingManager) start() error {
fundingTxBuf.Reset()
}
fndgLog.Debugf("Rebroadcasting funding tx for "+
log.Debugf("Rebroadcasting funding tx for "+
"ChannelPoint(%v): %x",
channel.FundingOutpoint,
fundingTxBuf.Bytes())
@ -575,7 +650,7 @@ func (f *fundingManager) start() error {
channel.FundingTxn, label,
)
if err != nil {
fndgLog.Errorf("Unable to rebroadcast "+
log.Errorf("Unable to rebroadcast "+
"funding tx %x for "+
"ChannelPoint(%v): %v",
fundingTxBuf.Bytes(),
@ -600,26 +675,17 @@ func (f *fundingManager) start() error {
// Stop signals all helper goroutines to execute a graceful shutdown. This
// method will block until all goroutines have exited.
func (f *fundingManager) Stop() error {
var err error
func (f *Manager) Stop() {
f.stopped.Do(func() {
err = f.stop()
})
return err
}
func (f *fundingManager) stop() error {
fndgLog.Infof("Funding manager shutting down")
log.Info("Funding manager shutting down")
close(f.quit)
f.wg.Wait()
return nil
})
}
// nextPendingChanID returns the next free pending channel ID to be used to
// identify a particular future channel funding workflow.
func (f *fundingManager) nextPendingChanID() [32]byte {
func (f *Manager) nextPendingChanID() [32]byte {
// Obtain a fresh nonce. We do this by encoding the current nonce
// counter, then incrementing it by one.
f.nonceMtx.Lock()
@ -639,52 +705,12 @@ func (f *fundingManager) nextPendingChanID() [32]byte {
return nextChanID
}
type pendingChannel struct {
identityPub *btcec.PublicKey
channelPoint *wire.OutPoint
capacity btcutil.Amount
localBalance btcutil.Amount
remoteBalance btcutil.Amount
}
type pendingChansReq struct {
resp chan []*pendingChannel
err chan error
}
// PendingChannels returns a slice describing all the channels which are
// currently pending at the last state of the funding workflow.
func (f *fundingManager) PendingChannels() ([]*pendingChannel, error) {
respChan := make(chan []*pendingChannel, 1)
errChan := make(chan error, 1)
req := &pendingChansReq{
resp: respChan,
err: errChan,
}
select {
case f.queries <- req:
case <-f.quit:
return nil, ErrFundingManagerShuttingDown
}
select {
case resp := <-respChan:
return resp, nil
case err := <-errChan:
return nil, err
case <-f.quit:
return nil, ErrFundingManagerShuttingDown
}
}
// CancelPeerReservations cancels all active reservations associated with the
// passed node. This will ensure any outputs which have been pre committed,
// (and thus locked from coin selection), are properly freed.
func (f *fundingManager) CancelPeerReservations(nodePub [33]byte) {
func (f *Manager) CancelPeerReservations(nodePub [33]byte) {
fndgLog.Debugf("Cancelling all reservations for peer %x", nodePub[:])
log.Debugf("Cancelling all reservations for peer %x", nodePub[:])
f.resMtx.Lock()
defer f.resMtx.Unlock()
@ -694,7 +720,7 @@ func (f *fundingManager) CancelPeerReservations(nodePub [33]byte) {
// to be done.
nodeReservations, ok := f.activeReservations[nodePub]
if !ok {
fndgLog.Debugf("No active reservations for node: %x", nodePub[:])
log.Debugf("No active reservations for node: %x", nodePub[:])
return
}
@ -703,7 +729,7 @@ func (f *fundingManager) CancelPeerReservations(nodePub [33]byte) {
// reservation map.
for pendingID, resCtx := range nodeReservations {
if err := resCtx.reservation.Cancel(); err != nil {
fndgLog.Errorf("unable to cancel reservation for "+
log.Errorf("unable to cancel reservation for "+
"node=%x: %v", nodePub[:], err)
}
@ -722,15 +748,15 @@ func (f *fundingManager) CancelPeerReservations(nodePub [33]byte) {
//
// TODO(roasbeef): if peer disconnects, and haven't yet broadcast funding
// transaction, then all reservations should be cleared.
func (f *fundingManager) failFundingFlow(peer lnpeer.Peer, tempChanID [32]byte,
func (f *Manager) failFundingFlow(peer lnpeer.Peer, tempChanID [32]byte,
fundingErr error) {
fndgLog.Debugf("Failing funding flow for pending_id=%x: %v",
log.Debugf("Failing funding flow for pending_id=%x: %v",
tempChanID, fundingErr)
ctx, err := f.cancelReservationCtx(peer.IdentityKey(), tempChanID, false)
if err != nil {
fndgLog.Errorf("unable to cancel reservation: %v", err)
log.Errorf("unable to cancel reservation: %v", err)
}
// In case the case where the reservation existed, send the funding
@ -763,10 +789,10 @@ func (f *fundingManager) failFundingFlow(peer lnpeer.Peer, tempChanID [32]byte,
Data: msg,
}
fndgLog.Debugf("Sending funding error to peer (%x): %v",
log.Debugf("Sending funding error to peer (%x): %v",
peer.IdentityKey().SerializeCompressed(), spew.Sdump(errMsg))
if err := peer.SendMessage(false, errMsg); err != nil {
fndgLog.Errorf("unable to send error message to peer %v", err)
log.Errorf("unable to send error message to peer %v", err)
}
}
@ -774,7 +800,7 @@ func (f *fundingManager) failFundingFlow(peer lnpeer.Peer, tempChanID [32]byte,
// funding workflow between the wallet, and any outside peers or local callers.
//
// NOTE: This MUST be run as a goroutine.
func (f *fundingManager) reservationCoordinator() {
func (f *Manager) reservationCoordinator() {
defer f.wg.Done()
zombieSweepTicker := time.NewTicker(f.cfg.ZombieSweeperInterval)
@ -805,11 +831,6 @@ func (f *fundingManager) reservationCoordinator() {
case <-zombieSweepTicker.C:
f.pruneZombieReservations()
case req := <-f.queries:
switch msg := req.(type) {
case *pendingChansReq:
f.handlePendingChannels(msg)
}
case <-f.quit:
return
}
@ -824,7 +845,7 @@ func (f *fundingManager) reservationCoordinator() {
// to get OpenStatusUpdates.
//
// NOTE: This MUST be run as a goroutine.
func (f *fundingManager) advanceFundingState(channel *channeldb.OpenChannel,
func (f *Manager) advanceFundingState(channel *channeldb.OpenChannel,
pendingChanID [32]byte, updateChan chan<- *lnrpc.OpenStatusUpdate) {
defer f.wg.Done()
@ -834,7 +855,7 @@ func (f *fundingManager) advanceFundingState(channel *channeldb.OpenChannel,
if channel.IsPending {
err := f.advancePendingChannelState(channel, pendingChanID)
if err != nil {
fndgLog.Errorf("Unable to advance pending state of "+
log.Errorf("Unable to advance pending state of "+
"ChannelPoint(%v): %v",
channel.FundingOutpoint, err)
return
@ -846,7 +867,7 @@ func (f *fundingManager) advanceFundingState(channel *channeldb.OpenChannel,
nil, channel, nil,
)
if err != nil {
fndgLog.Errorf("Unable to create LightningChannel(%v): %v",
log.Errorf("Unable to create LightningChannel(%v): %v",
channel.FundingOutpoint, err)
return
}
@ -861,13 +882,13 @@ func (f *fundingManager) advanceFundingState(channel *channeldb.OpenChannel,
// network.
// TODO(halseth): could do graph consistency check
// here, and re-add the edge if missing.
fndgLog.Debugf("ChannelPoint(%v) with chan_id=%x not "+
log.Debugf("ChannelPoint(%v) with chan_id=%x not "+
"found in opening database, assuming already "+
"announced to the network",
channel.FundingOutpoint, pendingChanID)
return
} else if err != nil {
fndgLog.Errorf("Unable to query database for "+
log.Errorf("Unable to query database for "+
"channel opening state(%v): %v",
channel.FundingOutpoint, err)
return
@ -882,7 +903,7 @@ func (f *fundingManager) advanceFundingState(channel *channeldb.OpenChannel,
channelState, updateChan,
)
if err != nil {
fndgLog.Errorf("Unable to advance state(%v): %v",
log.Errorf("Unable to advance state(%v): %v",
channel.FundingOutpoint, err)
return
}
@ -893,14 +914,14 @@ func (f *fundingManager) advanceFundingState(channel *channeldb.OpenChannel,
// machine. This method is synchronous and the new channel opening state will
// have been written to the database when it successfully returns. The
// updateChan can be set non-nil to get OpenStatusUpdates.
func (f *fundingManager) stateStep(channel *channeldb.OpenChannel,
func (f *Manager) stateStep(channel *channeldb.OpenChannel,
lnChannel *lnwallet.LightningChannel,
shortChanID *lnwire.ShortChannelID, pendingChanID [32]byte,
channelState channelOpeningState,
updateChan chan<- *lnrpc.OpenStatusUpdate) error {
chanID := lnwire.NewChanIDFromOutPoint(&channel.FundingOutpoint)
fndgLog.Debugf("Channel(%v) with ShortChanID %v has opening state %v",
log.Debugf("Channel(%v) with ShortChanID %v has opening state %v",
chanID, shortChanID, channelState)
switch channelState {
@ -927,7 +948,7 @@ func (f *fundingManager) stateStep(channel *channeldb.OpenChannel,
" fundingLockedSent: %v", err)
}
fndgLog.Debugf("Channel(%v) with ShortChanID %v: successfully "+
log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
"sent FundingLocked", chanID, shortChanID)
return nil
@ -954,7 +975,7 @@ func (f *fundingManager) stateStep(channel *channeldb.OpenChannel,
" addedToRouterGraph: %v", err)
}
fndgLog.Debugf("Channel(%v) with ShortChanID %v: successfully "+
log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
"added to router graph", chanID, shortChanID)
// Give the caller a final update notifying them that
@ -1007,7 +1028,7 @@ func (f *fundingManager) stateStep(channel *channeldb.OpenChannel,
err)
}
fndgLog.Debugf("Channel(%v) with ShortChanID %v: successfully "+
log.Debugf("Channel(%v) with ShortChanID %v: successfully "+
"announced", chanID, shortChanID)
return nil
@ -1018,7 +1039,7 @@ func (f *fundingManager) stateStep(channel *channeldb.OpenChannel,
// advancePendingChannelState waits for a pending channel's funding tx to
// confirm, and marks it open in the database when that happens.
func (f *fundingManager) advancePendingChannelState(
func (f *Manager) advancePendingChannelState(
channel *channeldb.OpenChannel, pendingChanID [32]byte) error {
confChannel, err := f.waitForFundingWithTimeout(channel)
@ -1086,7 +1107,7 @@ func (f *fundingManager) advancePendingChannelState(
// Success, funding transaction was confirmed.
chanID := lnwire.NewChanIDFromOutPoint(&channel.FundingOutpoint)
fndgLog.Debugf("ChannelID(%v) is now fully confirmed! "+
log.Debugf("ChannelID(%v) is now fully confirmed! "+
"(shortChanID=%v)", chanID, confChannel.shortChanID)
err = f.handleFundingConfirmation(channel, confChannel)
@ -1099,36 +1120,9 @@ func (f *fundingManager) advancePendingChannelState(
return nil
}
// handlePendingChannels responds to a request for details concerning all
// currently pending channels waiting for the final phase of the funding
// workflow (funding txn confirmation).
func (f *fundingManager) handlePendingChannels(msg *pendingChansReq) {
var pendingChannels []*pendingChannel
dbPendingChannels, err := f.cfg.Wallet.Cfg.Database.FetchPendingChannels()
if err != nil {
msg.err <- err
return
}
for _, dbPendingChan := range dbPendingChannels {
pendingChan := &pendingChannel{
identityPub: dbPendingChan.IdentityPub,
channelPoint: &dbPendingChan.FundingOutpoint,
capacity: dbPendingChan.Capacity,
localBalance: dbPendingChan.LocalCommitment.LocalBalance.ToSatoshis(),
remoteBalance: dbPendingChan.LocalCommitment.RemoteBalance.ToSatoshis(),
}
pendingChannels = append(pendingChannels, pendingChan)
}
msg.resp <- pendingChannels
}
// ProcessFundingMsg sends a message to the internal fundingManager goroutine,
// allowing it to handle the lnwire.Message.
func (f *fundingManager) ProcessFundingMsg(msg lnwire.Message, peer lnpeer.Peer) {
func (f *Manager) ProcessFundingMsg(msg lnwire.Message, peer lnpeer.Peer) {
select {
case f.fundingMsgs <- &fundingMsg{msg, peer}:
case <-f.quit:
@ -1179,7 +1173,7 @@ func commitmentType(localFeatures,
//
// TODO(roasbeef): add error chan to all, let channelManager handle
// error+propagate
func (f *fundingManager) handleFundingOpen(peer lnpeer.Peer,
func (f *Manager) handleFundingOpen(peer lnpeer.Peer,
msg *lnwire.OpenChannel) {
// Check number of pending channels to be smaller than maximum allowed
@ -1244,7 +1238,7 @@ func (f *fundingManager) handleFundingOpen(peer lnpeer.Peer,
isSynced, _, err := f.cfg.Wallet.IsSynced()
if err != nil || !isSynced {
if err != nil {
fndgLog.Errorf("unable to query wallet: %v", err)
log.Errorf("unable to query wallet: %v", err)
}
f.failFundingFlow(
peer, msg.PendingChannelID,
@ -1300,7 +1294,7 @@ func (f *fundingManager) handleFundingOpen(peer lnpeer.Peer,
return
}
fndgLog.Infof("Recv'd fundingRequest(amt=%v, push=%v, delay=%v, "+
log.Infof("Recv'd fundingRequest(amt=%v, push=%v, delay=%v, "+
"pendingId=%x) from peer(%x)", amt, msg.PushAmount,
msg.CsvDelay, msg.PendingChannelID,
peer.IdentityKey().SerializeCompressed())
@ -1335,7 +1329,7 @@ func (f *fundingManager) handleFundingOpen(peer lnpeer.Peer,
reservation, err := f.cfg.Wallet.InitChannelReservation(req)
if err != nil {
fndgLog.Errorf("Unable to initialize reservation: %v", err)
log.Errorf("Unable to initialize reservation: %v", err)
f.failFundingFlow(peer, msg.PendingChannelID, err)
return
}
@ -1366,7 +1360,7 @@ func (f *fundingManager) handleFundingOpen(peer lnpeer.Peer,
channelConstraints, f.cfg.MaxLocalCSVDelay,
)
if err != nil {
fndgLog.Errorf("Unacceptable channel constraints: %v", err)
log.Errorf("Unacceptable channel constraints: %v", err)
f.failFundingFlow(peer, msg.PendingChannelID, err)
return
}
@ -1394,7 +1388,7 @@ func (f *fundingManager) handleFundingOpen(peer lnpeer.Peer,
}
reservation.SetOurUpfrontShutdown(shutdown)
fndgLog.Infof("Requiring %v confirmations for pendingChan(%x): "+
log.Infof("Requiring %v confirmations for pendingChan(%x): "+
"amt=%v, push_amt=%v, committype=%v, upfrontShutdown=%x", numConfsReq,
msg.PendingChannelID, amt, msg.PushAmount,
commitType, msg.UpfrontShutdownScript)
@ -1486,14 +1480,14 @@ func (f *fundingManager) handleFundingOpen(peer lnpeer.Peer,
}
err = reservation.ProcessSingleContribution(remoteContribution)
if err != nil {
fndgLog.Errorf("unable to add contribution reservation: %v", err)
log.Errorf("unable to add contribution reservation: %v", err)
f.failFundingFlow(peer, msg.PendingChannelID, err)
return
}
fndgLog.Infof("Sending fundingResp for pending_id(%x)",
log.Infof("Sending fundingResp for pending_id(%x)",
msg.PendingChannelID)
fndgLog.Debugf("Remote party accepted commitment constraints: %v",
log.Debugf("Remote party accepted commitment constraints: %v",
spew.Sdump(remoteContribution.ChannelConfig.ChannelConstraints))
// With the initiator's contribution recorded, respond with our
@ -1518,7 +1512,7 @@ func (f *fundingManager) handleFundingOpen(peer lnpeer.Peer,
}
if err := peer.SendMessage(true, &fundingAccept); err != nil {
fndgLog.Errorf("unable to send funding response to peer: %v", err)
log.Errorf("unable to send funding response to peer: %v", err)
f.failFundingFlow(peer, msg.PendingChannelID, err)
return
}
@ -1527,7 +1521,7 @@ func (f *fundingManager) handleFundingOpen(peer lnpeer.Peer,
// handleFundingAccept processes a response to the workflow initiation sent by
// the remote peer. This message then queues a message with the funding
// outpoint, and a commitment signature to the remote peer.
func (f *fundingManager) handleFundingAccept(peer lnpeer.Peer,
func (f *Manager) handleFundingAccept(peer lnpeer.Peer,
msg *lnwire.AcceptChannel) {
pendingChanID := msg.PendingChannelID
@ -1535,7 +1529,7 @@ func (f *fundingManager) handleFundingAccept(peer lnpeer.Peer,
resCtx, err := f.getReservationCtx(peerKey, pendingChanID)
if err != nil {
fndgLog.Warnf("Can't find reservation (peerKey:%v, chan_id:%v)",
log.Warnf("Can't find reservation (peerKey:%v, chan_id:%v)",
peerKey, pendingChanID)
return
}
@ -1543,7 +1537,7 @@ func (f *fundingManager) handleFundingAccept(peer lnpeer.Peer,
// Update the timestamp once the fundingAcceptMsg has been handled.
defer resCtx.updateTimestamp()
fndgLog.Infof("Recv'd fundingResponse for pending_id(%x)",
log.Infof("Recv'd fundingResponse for pending_id(%x)",
pendingChanID[:])
// The required number of confirmations should not be greater than the
@ -1553,7 +1547,7 @@ func (f *fundingManager) handleFundingAccept(peer lnpeer.Peer,
err := lnwallet.ErrNumConfsTooLarge(
msg.MinAcceptDepth, chainntnfs.MaxNumConfs,
)
fndgLog.Warnf("Unacceptable channel constraints: %v", err)
log.Warnf("Unacceptable channel constraints: %v", err)
f.failFundingFlow(peer, msg.PendingChannelID, err)
return
}
@ -1574,7 +1568,7 @@ func (f *fundingManager) handleFundingAccept(peer lnpeer.Peer,
channelConstraints, resCtx.maxLocalCsv,
)
if err != nil {
fndgLog.Warnf("Unacceptable channel constraints: %v", err)
log.Warnf("Unacceptable channel constraints: %v", err)
f.failFundingFlow(peer, msg.PendingChannelID, err)
return
}
@ -1629,7 +1623,7 @@ func (f *fundingManager) handleFundingAccept(peer lnpeer.Peer,
// construct the PSBT back to the caller.
addr, amt, packet, err := psbtErr.Intent.FundingParams()
if err != nil {
fndgLog.Errorf("Unable to process PSBT funding params "+
log.Errorf("Unable to process PSBT funding params "+
"for contribution from %v: %v", peerKey, err)
f.failFundingFlow(peer, msg.PendingChannelID, err)
return
@ -1637,7 +1631,7 @@ func (f *fundingManager) handleFundingAccept(peer lnpeer.Peer,
var buf bytes.Buffer
err = packet.Serialize(&buf)
if err != nil {
fndgLog.Errorf("Unable to serialize PSBT for "+
log.Errorf("Unable to serialize PSBT for "+
"contribution from %v: %v", peerKey, err)
f.failFundingFlow(peer, msg.PendingChannelID, err)
return
@ -1654,15 +1648,15 @@ func (f *fundingManager) handleFundingAccept(peer lnpeer.Peer,
}
psbtIntent = psbtErr.Intent
} else if err != nil {
fndgLog.Errorf("Unable to process contribution from %v: %v",
log.Errorf("Unable to process contribution from %v: %v",
peerKey, err)
f.failFundingFlow(peer, msg.PendingChannelID, err)
return
}
fndgLog.Infof("pendingChan(%x): remote party proposes num_confs=%v, "+
log.Infof("pendingChan(%x): remote party proposes num_confs=%v, "+
"csv_delay=%v", pendingChanID[:], msg.MinAcceptDepth, msg.CsvDelay)
fndgLog.Debugf("Remote party accepted commitment constraints: %v",
log.Debugf("Remote party accepted commitment constraints: %v",
spew.Sdump(remoteContribution.ChannelConfig.ChannelConstraints))
// If the user requested funding through a PSBT, we cannot directly
@ -1691,14 +1685,14 @@ func (f *fundingManager) handleFundingAccept(peer lnpeer.Peer,
// is continued.
//
// NOTE: This method must be called as a goroutine.
func (f *fundingManager) waitForPsbt(intent *chanfunding.PsbtIntent,
func (f *Manager) waitForPsbt(intent *chanfunding.PsbtIntent,
resCtx *reservationWithCtx, pendingChanID [32]byte) {
// failFlow is a helper that logs an error message with the current
// context and then fails the funding flow.
peerKey := resCtx.peer.IdentityKey()
failFlow := func(errMsg string, cause error) {
fndgLog.Errorf("Unable to handle funding accept message "+
log.Errorf("Unable to handle funding accept message "+
"for peer_key=%x, pending_chan_id=%x: %s: %v",
peerKey.SerializeCompressed(), pendingChanID, errMsg,
cause)
@ -1721,7 +1715,7 @@ func (f *fundingManager) waitForPsbt(intent *chanfunding.PsbtIntent,
// to send another fail message. But we want to inform the user
// about what happened.
case chanfunding.ErrRemoteCanceled:
fndgLog.Infof("Remote canceled, aborting PSBT flow "+
log.Infof("Remote canceled, aborting PSBT flow "+
"for peer_key=%x, pending_chan_id=%x",
peerKey.SerializeCompressed(), pendingChanID)
return
@ -1750,7 +1744,7 @@ func (f *fundingManager) waitForPsbt(intent *chanfunding.PsbtIntent,
// Handle a server shutdown as well because the reservation won't
// survive a restart as it's in memory only.
case <-f.quit:
fndgLog.Errorf("Unable to handle funding accept message "+
log.Errorf("Unable to handle funding accept message "+
"for peer_key=%x, pending_chan_id=%x: funding manager "+
"shutting down", peerKey.SerializeCompressed(),
pendingChanID)
@ -1761,7 +1755,7 @@ func (f *fundingManager) waitForPsbt(intent *chanfunding.PsbtIntent,
// continueFundingAccept continues the channel funding flow once our
// contribution is finalized, the channel output is known and the funding
// transaction is signed.
func (f *fundingManager) continueFundingAccept(resCtx *reservationWithCtx,
func (f *Manager) continueFundingAccept(resCtx *reservationWithCtx,
pendingChanID [32]byte) {
// Now that we have their contribution, we can extract, then send over
@ -1776,7 +1770,7 @@ func (f *fundingManager) continueFundingAccept(resCtx *reservationWithCtx,
// fully open.
f.barrierMtx.Lock()
channelID := lnwire.NewChanIDFromOutPoint(outPoint)
fndgLog.Debugf("Creating chan barrier for ChanID(%v)", channelID)
log.Debugf("Creating chan barrier for ChanID(%v)", channelID)
f.newChanBarriers[channelID] = make(chan struct{})
f.barrierMtx.Unlock()
@ -1788,7 +1782,7 @@ func (f *fundingManager) continueFundingAccept(resCtx *reservationWithCtx,
f.signedReservations[channelID] = pendingChanID
f.resMtx.Unlock()
fndgLog.Infof("Generated ChannelPoint(%v) for pending_id(%x)", outPoint,
log.Infof("Generated ChannelPoint(%v) for pending_id(%x)", outPoint,
pendingChanID[:])
var err error
@ -1798,12 +1792,12 @@ func (f *fundingManager) continueFundingAccept(resCtx *reservationWithCtx,
}
fundingCreated.CommitSig, err = lnwire.NewSigFromSignature(sig)
if err != nil {
fndgLog.Errorf("Unable to parse signature: %v", err)
log.Errorf("Unable to parse signature: %v", err)
f.failFundingFlow(resCtx.peer, pendingChanID, err)
return
}
if err := resCtx.peer.SendMessage(true, fundingCreated); err != nil {
fndgLog.Errorf("Unable to send funding complete message: %v", err)
log.Errorf("Unable to send funding complete message: %v", err)
f.failFundingFlow(resCtx.peer, pendingChanID, err)
return
}
@ -1813,7 +1807,7 @@ func (f *fundingManager) continueFundingAccept(resCtx *reservationWithCtx,
// the responding side of a single funder workflow. Once this message has been
// processed, a signature is sent to the remote peer allowing it to broadcast
// the funding transaction, progressing the workflow into the final stage.
func (f *fundingManager) handleFundingCreated(peer lnpeer.Peer,
func (f *Manager) handleFundingCreated(peer lnpeer.Peer,
msg *lnwire.FundingCreated) {
peerKey := peer.IdentityKey()
@ -1821,7 +1815,7 @@ func (f *fundingManager) handleFundingCreated(peer lnpeer.Peer,
resCtx, err := f.getReservationCtx(peerKey, pendingChanID)
if err != nil {
fndgLog.Warnf("can't find reservation (peer_id:%v, chan_id:%x)",
log.Warnf("can't find reservation (peer_id:%v, chan_id:%x)",
peerKey, pendingChanID[:])
return
}
@ -1832,12 +1826,12 @@ func (f *fundingManager) handleFundingCreated(peer lnpeer.Peer,
// initiator's commitment transaction, then send our own if it's valid.
// TODO(roasbeef): make case (p vs P) consistent throughout
fundingOut := msg.FundingPoint
fndgLog.Infof("completing pending_id(%x) with ChannelPoint(%v)",
log.Infof("completing pending_id(%x) with ChannelPoint(%v)",
pendingChanID[:], fundingOut)
commitSig, err := msg.CommitSig.ToSignature()
if err != nil {
fndgLog.Errorf("unable to parse signature: %v", err)
log.Errorf("unable to parse signature: %v", err)
f.failFundingFlow(peer, pendingChanID, err)
return
}
@ -1852,7 +1846,7 @@ func (f *fundingManager) handleFundingCreated(peer lnpeer.Peer,
)
if err != nil {
// TODO(roasbeef): better error logging: peerID, channelID, etc.
fndgLog.Errorf("unable to complete single reservation: %v", err)
log.Errorf("unable to complete single reservation: %v", err)
f.failFundingFlow(peer, pendingChanID, err)
return
}
@ -1883,7 +1877,7 @@ func (f *fundingManager) handleFundingCreated(peer lnpeer.Peer,
if err := completeChan.CloseChannel(
closeInfo, channeldb.ChanStatusLocalCloseInitiator,
); err != nil {
fndgLog.Errorf("Failed closing channel %v: %v",
log.Errorf("Failed closing channel %v: %v",
completeChan.FundingOutpoint, err)
}
}
@ -1894,11 +1888,11 @@ func (f *fundingManager) handleFundingCreated(peer lnpeer.Peer,
// fully open.
f.barrierMtx.Lock()
channelID := lnwire.NewChanIDFromOutPoint(&fundingOut)
fndgLog.Debugf("Creating chan barrier for ChanID(%v)", channelID)
log.Debugf("Creating chan barrier for ChanID(%v)", channelID)
f.newChanBarriers[channelID] = make(chan struct{})
f.barrierMtx.Unlock()
fndgLog.Infof("sending FundingSigned for pending_id(%x) over "+
log.Infof("sending FundingSigned for pending_id(%x) over "+
"ChannelPoint(%v)", pendingChanID[:], fundingOut)
// With their signature for our version of the commitment transaction
@ -1906,7 +1900,7 @@ func (f *fundingManager) handleFundingCreated(peer lnpeer.Peer,
_, sig := resCtx.reservation.OurSignatures()
ourCommitSig, err := lnwire.NewSigFromSignature(sig)
if err != nil {
fndgLog.Errorf("unable to parse signature: %v", err)
log.Errorf("unable to parse signature: %v", err)
f.failFundingFlow(peer, pendingChanID, err)
deleteFromDatabase()
return
@ -1917,7 +1911,7 @@ func (f *fundingManager) handleFundingCreated(peer lnpeer.Peer,
CommitSig: ourCommitSig,
}
if err := peer.SendMessage(true, fundingSigned); err != nil {
fndgLog.Errorf("unable to send FundingSigned message: %v", err)
log.Errorf("unable to send FundingSigned message: %v", err)
f.failFundingFlow(peer, pendingChanID, err)
deleteFromDatabase()
return
@ -1927,7 +1921,7 @@ func (f *fundingManager) handleFundingCreated(peer lnpeer.Peer,
// send it to the ChainArbitrator so it can watch for any on-chain
// actions during this final confirmation stage.
if err := f.cfg.WatchNewChannel(completeChan, peerKey); err != nil {
fndgLog.Errorf("Unable to send new ChannelPoint(%v) for "+
log.Errorf("Unable to send new ChannelPoint(%v) for "+
"arbitration: %v", fundingOut, err)
}
@ -1967,7 +1961,7 @@ func (f *fundingManager) handleFundingCreated(peer lnpeer.Peer,
// broadcast. Once the funding transaction reaches a sufficient number of
// confirmations, a message is sent to the responding peer along with a compact
// encoding of the location of the channel within the blockchain.
func (f *fundingManager) handleFundingSigned(peer lnpeer.Peer,
func (f *Manager) handleFundingSigned(peer lnpeer.Peer,
msg *lnwire.FundingSigned) {
// As the funding signed message will reference the reservation by its
@ -1980,7 +1974,7 @@ func (f *fundingManager) handleFundingSigned(peer lnpeer.Peer,
if !ok {
err := fmt.Errorf("unable to find signed reservation for "+
"chan_id=%x", msg.ChanID)
fndgLog.Warnf(err.Error())
log.Warnf(err.Error())
f.failFundingFlow(peer, msg.ChanID, err)
return
}
@ -1988,7 +1982,7 @@ func (f *fundingManager) handleFundingSigned(peer lnpeer.Peer,
peerKey := peer.IdentityKey()
resCtx, err := f.getReservationCtx(peerKey, pendingChanID)
if err != nil {
fndgLog.Warnf("Unable to find reservation (peer_id:%v, "+
log.Warnf("Unable to find reservation (peer_id:%v, "+
"chan_id:%x)", peerKey, pendingChanID[:])
// TODO: add ErrChanNotFound?
f.failFundingFlow(peer, pendingChanID, err)
@ -2009,7 +2003,7 @@ func (f *fundingManager) handleFundingSigned(peer lnpeer.Peer,
// the state to disk as we can now open the channel.
commitSig, err := msg.CommitSig.ToSignature()
if err != nil {
fndgLog.Errorf("Unable to parse signature: %v", err)
log.Errorf("Unable to parse signature: %v", err)
f.failFundingFlow(peer, pendingChanID, err)
return
}
@ -2018,7 +2012,7 @@ func (f *fundingManager) handleFundingSigned(peer lnpeer.Peer,
nil, commitSig,
)
if err != nil {
fndgLog.Errorf("Unable to complete reservation sign "+
log.Errorf("Unable to complete reservation sign "+
"complete: %v", err)
f.failFundingFlow(peer, pendingChanID, err)
return
@ -2034,7 +2028,7 @@ func (f *fundingManager) handleFundingSigned(peer lnpeer.Peer,
fundingTx := completeChan.FundingTxn
var fundingTxBuf bytes.Buffer
if err := fundingTx.Serialize(&fundingTxBuf); err != nil {
fndgLog.Errorf("Unable to serialize funding "+
log.Errorf("Unable to serialize funding "+
"transaction %v: %v", fundingTx.TxHash(), err)
// Clear the buffer of any bytes that were written
@ -2043,7 +2037,7 @@ func (f *fundingManager) handleFundingSigned(peer lnpeer.Peer,
fundingTxBuf.Reset()
}
fndgLog.Infof("Broadcasting funding tx for ChannelPoint(%v): %x",
log.Infof("Broadcasting funding tx for ChannelPoint(%v): %x",
completeChan.FundingOutpoint, fundingTxBuf.Bytes())
// Set a nil short channel ID at this stage because we do not
@ -2054,7 +2048,7 @@ func (f *fundingManager) handleFundingSigned(peer lnpeer.Peer,
err = f.cfg.PublishTransaction(fundingTx, label)
if err != nil {
fndgLog.Errorf("Unable to broadcast funding tx %x for "+
log.Errorf("Unable to broadcast funding tx %x for "+
"ChannelPoint(%v): %v", fundingTxBuf.Bytes(),
completeChan.FundingOutpoint, err)
@ -2073,11 +2067,11 @@ func (f *fundingManager) handleFundingSigned(peer lnpeer.Peer,
// watch for any on-chain actions before the channel has fully
// confirmed.
if err := f.cfg.WatchNewChannel(completeChan, peerKey); err != nil {
fndgLog.Errorf("Unable to send new ChannelPoint(%v) for "+
log.Errorf("Unable to send new ChannelPoint(%v) for "+
"arbitration: %v", fundingPoint, err)
}
fndgLog.Infof("Finalizing pending_id(%x) over ChannelPoint(%v), "+
log.Infof("Finalizing pending_id(%x) over ChannelPoint(%v), "+
"waiting for channel open on-chain", pendingChanID[:],
fundingPoint)
@ -2129,7 +2123,7 @@ type confirmedChannel struct {
// channel initiator and the maxWaitNumBlocksFundingConf has passed from the
// funding broadcast height. In case of confirmation, the short channel ID of
// the channel and the funding transaction will be returned.
func (f *fundingManager) waitForFundingWithTimeout(
func (f *Manager) waitForFundingWithTimeout(
ch *channeldb.OpenChannel) (*confirmedChannel, error) {
confChan := make(chan *confirmedChannel)
@ -2192,7 +2186,7 @@ func makeFundingScript(channel *channeldb.OpenChannel) ([]byte, error) {
// a *lnwire.ShortChannelID will be passed to confChan.
//
// NOTE: This MUST be run as a goroutine.
func (f *fundingManager) waitForFundingConfirmation(
func (f *Manager) waitForFundingConfirmation(
completeChan *channeldb.OpenChannel, cancelChan <-chan struct{},
confChan chan<- *confirmedChannel) {
@ -2204,7 +2198,7 @@ func (f *fundingManager) waitForFundingConfirmation(
txid := completeChan.FundingOutpoint.Hash
fundingScript, err := makeFundingScript(completeChan)
if err != nil {
fndgLog.Errorf("unable to create funding script for "+
log.Errorf("unable to create funding script for "+
"ChannelPoint(%v): %v", completeChan.FundingOutpoint,
err)
return
@ -2215,13 +2209,13 @@ func (f *fundingManager) waitForFundingConfirmation(
completeChan.FundingBroadcastHeight,
)
if err != nil {
fndgLog.Errorf("Unable to register for confirmation of "+
log.Errorf("Unable to register for confirmation of "+
"ChannelPoint(%v): %v", completeChan.FundingOutpoint,
err)
return
}
fndgLog.Infof("Waiting for funding tx (%v) to reach %v confirmations",
log.Infof("Waiting for funding tx (%v) to reach %v confirmations",
txid, numConfs)
var confDetails *chainntnfs.TxConfirmation
@ -2234,27 +2228,27 @@ func (f *fundingManager) waitForFundingConfirmation(
// fallthrough
case <-cancelChan:
fndgLog.Warnf("canceled waiting for funding confirmation, "+
log.Warnf("canceled waiting for funding confirmation, "+
"stopping funding flow for ChannelPoint(%v)",
completeChan.FundingOutpoint)
return
case <-f.quit:
fndgLog.Warnf("fundingManager shutting down, stopping funding "+
log.Warnf("fundingManager shutting down, stopping funding "+
"flow for ChannelPoint(%v)",
completeChan.FundingOutpoint)
return
}
if !ok {
fndgLog.Warnf("ChainNotifier shutting down, cannot complete "+
log.Warnf("ChainNotifier shutting down, cannot complete "+
"funding flow for ChannelPoint(%v)",
completeChan.FundingOutpoint)
return
}
fundingPoint := completeChan.FundingOutpoint
fndgLog.Infof("ChannelPoint(%v) is now active: ChannelID(%v)",
log.Infof("ChannelPoint(%v) is now active: ChannelID(%v)",
fundingPoint, lnwire.NewChanIDFromOutPoint(&fundingPoint))
// With the block height and the transaction index known, we can
@ -2283,7 +2277,7 @@ func (f *fundingManager) waitForFundingConfirmation(
//
// NOTE: timeoutChan MUST be buffered.
// NOTE: This MUST be run as a goroutine.
func (f *fundingManager) waitForTimeout(completeChan *channeldb.OpenChannel,
func (f *Manager) waitForTimeout(completeChan *channeldb.OpenChannel,
cancelChan <-chan struct{}, timeoutChan chan<- error) {
defer f.wg.Done()
@ -2310,7 +2304,7 @@ func (f *fundingManager) waitForTimeout(completeChan *channeldb.OpenChannel,
// Close the timeout channel and exit if the block is
// aboce the max height.
if uint32(epoch.Height) >= maxHeight {
fndgLog.Warnf("Waited for %v blocks without "+
log.Warnf("Waited for %v blocks without "+
"seeing funding transaction confirmed,"+
" cancelling.",
maxWaitNumBlocksFundingConf)
@ -2339,7 +2333,7 @@ func (f *fundingManager) waitForTimeout(completeChan *channeldb.OpenChannel,
// the channelOpeningState markedOpen. In addition it will report the now
// decided short channel ID to the switch, and close the local discovery signal
// for this channel.
func (f *fundingManager) handleFundingConfirmation(
func (f *Manager) handleFundingConfirmation(
completeChan *channeldb.OpenChannel,
confChannel *confirmedChannel) error {
@ -2389,7 +2383,7 @@ func (f *fundingManager) handleFundingConfirmation(
// short chan id from disk.
err = f.cfg.ReportShortChanID(fundingPoint)
if err != nil {
fndgLog.Errorf("unable to report short chan id: %v", err)
log.Errorf("unable to report short chan id: %v", err)
}
// If we opened the channel, and lnd's wallet published our funding tx
@ -2407,7 +2401,7 @@ func (f *fundingManager) handleFundingConfirmation(
completeChan.FundingOutpoint.Hash, label,
)
if err != nil {
fndgLog.Errorf("unable to update label: %v", err)
log.Errorf("unable to update label: %v", err)
}
}
@ -2427,7 +2421,7 @@ func (f *fundingManager) handleFundingConfirmation(
// sendFundingLocked creates and sends the fundingLocked message.
// This should be called after the funding transaction has been confirmed,
// and the channelState is 'markedOpen'.
func (f *fundingManager) sendFundingLocked(
func (f *Manager) sendFundingLocked(
completeChan *channeldb.OpenChannel, channel *lnwallet.LightningChannel,
shortChanID *lnwire.ShortChannelID) error {
@ -2468,7 +2462,7 @@ func (f *fundingManager) sendFundingLocked(
return ErrFundingManagerShuttingDown
}
fndgLog.Infof("Peer(%x) is online, sending FundingLocked "+
log.Infof("Peer(%x) is online, sending FundingLocked "+
"for ChannelID(%v)", peerKey, chanID)
if err := peer.SendMessage(true, fundingLockedMsg); err == nil {
@ -2477,7 +2471,7 @@ func (f *fundingManager) sendFundingLocked(
break
}
fndgLog.Warnf("Unable to send fundingLocked to peer %x: %v. "+
log.Warnf("Unable to send fundingLocked to peer %x: %v. "+
"Will retry when online", peerKey, err)
}
@ -2489,7 +2483,7 @@ func (f *fundingManager) sendFundingLocked(
// These announcement messages are NOT broadcasted to the greater network,
// only to the channel counter party. The proofs required to announce the
// channel to the greater network will be created and sent in annAfterSixConfs.
func (f *fundingManager) addToRouterGraph(completeChan *channeldb.OpenChannel,
func (f *Manager) addToRouterGraph(completeChan *channeldb.OpenChannel,
shortChanID *lnwire.ShortChannelID) error {
chanID := lnwire.NewChanIDFromOutPoint(&completeChan.FundingOutpoint)
@ -2537,7 +2531,7 @@ func (f *fundingManager) addToRouterGraph(completeChan *channeldb.OpenChannel,
if err != nil {
if routing.IsError(err, routing.ErrOutdated,
routing.ErrIgnored) {
fndgLog.Debugf("Router rejected "+
log.Debugf("Router rejected "+
"ChannelAnnouncement: %v", err)
} else {
return fmt.Errorf("error sending channel "+
@ -2554,7 +2548,7 @@ func (f *fundingManager) addToRouterGraph(completeChan *channeldb.OpenChannel,
if err != nil {
if routing.IsError(err, routing.ErrOutdated,
routing.ErrIgnored) {
fndgLog.Debugf("Router rejected "+
log.Debugf("Router rejected "+
"ChannelUpdate: %v", err)
} else {
return fmt.Errorf("error sending channel "+
@ -2574,7 +2568,7 @@ func (f *fundingManager) addToRouterGraph(completeChan *channeldb.OpenChannel,
// 'addedToRouterGraph') and the channel is ready to be used. This is the last
// step in the channel opening process, and the opening state will be deleted
// from the database if successful.
func (f *fundingManager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
func (f *Manager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
shortChanID *lnwire.ShortChannelID) error {
// If this channel is not meant to be announced to the greater network,
@ -2582,7 +2576,7 @@ func (f *fundingManager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
// don't leak any of our information.
announceChan := completeChan.ChannelFlags&lnwire.FFAnnounceChannel != 0
if !announceChan {
fndgLog.Debugf("Will not announce private channel %v.",
log.Debugf("Will not announce private channel %v.",
shortChanID.ToUint64())
peerChan := make(chan lnpeer.Peer, 1)
@ -2609,7 +2603,7 @@ func (f *fundingManager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
&completeChan.FundingOutpoint,
)
pubKey := peer.PubKey()
fndgLog.Debugf("Sending our NodeAnnouncement for "+
log.Debugf("Sending our NodeAnnouncement for "+
"ChannelID(%v) to %x", chanID, pubKey)
// TODO(halseth): make reliable. If the peer is not online this
@ -2627,7 +2621,7 @@ func (f *fundingManager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
numConfs = 6
}
txid := completeChan.FundingOutpoint.Hash
fndgLog.Debugf("Will announce channel %v after ChannelPoint"+
log.Debugf("Will announce channel %v after ChannelPoint"+
"(%v) has gotten %d confirmations",
shortChanID.ToUint64(), completeChan.FundingOutpoint,
numConfs)
@ -2673,7 +2667,7 @@ func (f *fundingManager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
fundingPoint := completeChan.FundingOutpoint
chanID := lnwire.NewChanIDFromOutPoint(&fundingPoint)
fndgLog.Infof("Announcing ChannelPoint(%v), short_chan_id=%v",
log.Infof("Announcing ChannelPoint(%v), short_chan_id=%v",
&fundingPoint, shortChanID)
// Create and broadcast the proofs required to make this channel
@ -2688,7 +2682,7 @@ func (f *fundingManager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
return fmt.Errorf("channel announcement failed: %v", err)
}
fndgLog.Debugf("Channel with ChannelPoint(%v), short_chan_id=%v "+
log.Debugf("Channel with ChannelPoint(%v), short_chan_id=%v "+
"announced", &fundingPoint, shortChanID)
}
@ -2697,11 +2691,11 @@ func (f *fundingManager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
// handleFundingLocked finalizes the channel funding process and enables the
// channel to enter normal operating mode.
func (f *fundingManager) handleFundingLocked(peer lnpeer.Peer,
func (f *Manager) handleFundingLocked(peer lnpeer.Peer,
msg *lnwire.FundingLocked) {
defer f.wg.Done()
fndgLog.Debugf("Received FundingLocked for ChannelID(%v) from "+
log.Debugf("Received FundingLocked for ChannelID(%v) from "+
"peer %x", msg.ChanID,
peer.IdentityKey().SerializeCompressed())
@ -2710,7 +2704,7 @@ func (f *fundingManager) handleFundingLocked(peer lnpeer.Peer,
f.handleFundingLockedMtx.Lock()
_, ok := f.handleFundingLockedBarriers[msg.ChanID]
if ok {
fndgLog.Infof("Already handling fundingLocked for "+
log.Infof("Already handling fundingLocked for "+
"ChannelID(%v), ignoring.", msg.ChanID)
f.handleFundingLockedMtx.Unlock()
return
@ -2757,7 +2751,7 @@ func (f *fundingManager) handleFundingLocked(peer lnpeer.Peer,
chanID := msg.ChanID
channel, err := f.cfg.FindChannel(chanID)
if err != nil {
fndgLog.Errorf("Unable to locate ChannelID(%v), cannot complete "+
log.Errorf("Unable to locate ChannelID(%v), cannot complete "+
"funding", chanID)
return
}
@ -2765,7 +2759,7 @@ func (f *fundingManager) handleFundingLocked(peer lnpeer.Peer,
// If the RemoteNextRevocation is non-nil, it means that we have
// already processed fundingLocked for this channel, so ignore.
if channel.RemoteNextRevocation != nil {
fndgLog.Infof("Received duplicate fundingLocked for "+
log.Infof("Received duplicate fundingLocked for "+
"ChannelID(%v), ignoring.", chanID)
return
}
@ -2776,7 +2770,7 @@ func (f *fundingManager) handleFundingLocked(peer lnpeer.Peer,
// other sub-systems.
err = channel.InsertNextRevocation(msg.NextPerCommitmentPoint)
if err != nil {
fndgLog.Errorf("unable to insert next commitment point: %v", err)
log.Errorf("unable to insert next commitment point: %v", err)
return
}
@ -2789,7 +2783,7 @@ func (f *fundingManager) handleFundingLocked(peer lnpeer.Peer,
f.barrierMtx.Lock()
chanBarrier, ok := f.newChanBarriers[chanID]
if ok {
fndgLog.Tracef("Closing chan barrier for ChanID(%v)",
log.Tracef("Closing chan barrier for ChanID(%v)",
chanID)
close(chanBarrier)
delete(f.newChanBarriers, chanID)
@ -2798,7 +2792,7 @@ func (f *fundingManager) handleFundingLocked(peer lnpeer.Peer,
}()
if err := peer.AddNewChannel(channel, f.quit); err != nil {
fndgLog.Errorf("Unable to add new channel %v with peer %x: %v",
log.Errorf("Unable to add new channel %v with peer %x: %v",
channel.FundingOutpoint,
peer.IdentityKey().SerializeCompressed(), err,
)
@ -2820,7 +2814,7 @@ type chanAnnouncement struct {
// identity pub keys of both parties to the channel, and the second segment is
// authenticated only by us and contains our directional routing policy for the
// channel.
func (f *fundingManager) newChanAnnouncement(localPubKey, remotePubKey,
func (f *Manager) newChanAnnouncement(localPubKey, remotePubKey,
localFundingKey, remoteFundingKey *btcec.PublicKey,
shortChanID lnwire.ShortChannelID, chanID lnwire.ChannelID,
fwdMinHTLC, fwdMaxHTLC lnwire.MilliSatoshi) (*chanAnnouncement, error) {
@ -2963,7 +2957,7 @@ func (f *fundingManager) newChanAnnouncement(localPubKey, remotePubKey,
// the network during its next trickle.
// This method is synchronous and will return when all the network requests
// finish, either successfully or with an error.
func (f *fundingManager) announceChannel(localIDKey, remoteIDKey, localFundingKey,
func (f *Manager) announceChannel(localIDKey, remoteIDKey, localFundingKey,
remoteFundingKey *btcec.PublicKey, shortChanID lnwire.ShortChannelID,
chanID lnwire.ChannelID) error {
@ -2979,7 +2973,7 @@ func (f *fundingManager) announceChannel(localIDKey, remoteIDKey, localFundingKe
0, 0,
)
if err != nil {
fndgLog.Errorf("can't generate channel announcement: %v", err)
log.Errorf("can't generate channel announcement: %v", err)
return err
}
@ -2993,10 +2987,10 @@ func (f *fundingManager) announceChannel(localIDKey, remoteIDKey, localFundingKe
if err != nil {
if routing.IsError(err, routing.ErrOutdated,
routing.ErrIgnored) {
fndgLog.Debugf("Router rejected "+
log.Debugf("Router rejected "+
"AnnounceSignatures: %v", err)
} else {
fndgLog.Errorf("Unable to send channel "+
log.Errorf("Unable to send channel "+
"proof: %v", err)
return err
}
@ -3012,7 +3006,7 @@ func (f *fundingManager) announceChannel(localIDKey, remoteIDKey, localFundingKe
// particular node, and this might be our first channel.
nodeAnn, err := f.cfg.CurrentNodeAnnouncement()
if err != nil {
fndgLog.Errorf("can't generate node announcement: %v", err)
log.Errorf("can't generate node announcement: %v", err)
return err
}
@ -3022,10 +3016,10 @@ func (f *fundingManager) announceChannel(localIDKey, remoteIDKey, localFundingKe
if err != nil {
if routing.IsError(err, routing.ErrOutdated,
routing.ErrIgnored) {
fndgLog.Debugf("Router rejected "+
log.Debugf("Router rejected "+
"NodeAnnouncement: %v", err)
} else {
fndgLog.Errorf("Unable to send node "+
log.Errorf("Unable to send node "+
"announcement: %v", err)
return err
}
@ -3038,14 +3032,11 @@ func (f *fundingManager) announceChannel(localIDKey, remoteIDKey, localFundingKe
return nil
}
// initFundingWorkflow sends a message to the funding manager instructing it
// InitFundingWorkflow sends a message to the funding manager instructing it
// to initiate a single funder workflow with the source peer.
// TODO(roasbeef): re-visit blocking nature..
func (f *fundingManager) initFundingWorkflow(peer lnpeer.Peer, req *openChanReq) {
f.fundingRequests <- &initFundingMsg{
peer: peer,
openChanReq: req,
}
func (f *Manager) InitFundingWorkflow(msg *InitFundingMsg) {
f.fundingRequests <- msg
}
// getUpfrontShutdownScript takes a user provided script and a getScript
@ -3095,15 +3086,15 @@ func getUpfrontShutdownScript(enableUpfrontShutdown bool, peer lnpeer.Peer,
// handleInitFundingMsg creates a channel reservation within the daemon's
// wallet, then sends a funding request to the remote peer kicking off the
// funding workflow.
func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) {
var (
peerKey = msg.peer.IdentityKey()
localAmt = msg.localFundingAmt
minHtlcIn = msg.minHtlcIn
remoteCsvDelay = msg.remoteCsvDelay
maxValue = msg.maxValueInFlight
maxHtlcs = msg.maxHtlcs
maxCSV = msg.maxLocalCsv
peerKey = msg.Peer.IdentityKey()
localAmt = msg.LocalFundingAmt
minHtlcIn = msg.MinHtlcIn
remoteCsvDelay = msg.RemoteCsvDelay
maxValue = msg.MaxValueInFlight
maxHtlcs = msg.MaxHtlcs
maxCSV = msg.MaxLocalCsv
)
// If no maximum CSV delay was set for this channel, we use our default
@ -3120,16 +3111,16 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
case chainreg.LitecoinChain:
ourDustLimit = chainreg.DefaultLitecoinDustLimit
}
fndgLog.Infof("Initiating fundingRequest(local_amt=%v "+
log.Infof("Initiating fundingRequest(local_amt=%v "+
"(subtract_fees=%v), push_amt=%v, chain_hash=%v, peer=%x, "+
"dust_limit=%v, min_confs=%v)", localAmt, msg.subtractFees,
msg.pushAmt, msg.chainHash, peerKey.SerializeCompressed(),
ourDustLimit, msg.minConfs)
"dust_limit=%v, min_confs=%v)", localAmt, msg.SubtractFees,
msg.PushAmt, msg.ChainHash, peerKey.SerializeCompressed(),
ourDustLimit, msg.MinConfs)
// We set the channel flags to indicate whether we want this channel to
// be announced to the network.
var channelFlags lnwire.FundingFlag
if !msg.openChanReq.private {
if !msg.Private {
// This channel will be announced.
channelFlags = lnwire.FFAnnounceChannel
}
@ -3138,15 +3129,15 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
// Otherwise we'll generate a fresh one as normal. This will be used
// to track this reservation throughout its lifetime.
var chanID [32]byte
if msg.pendingChanID == zeroID {
if msg.PendingChanID == zeroID {
chanID = f.nextPendingChanID()
} else {
// If the user specified their own pending channel ID, then
// we'll ensure it doesn't collide with any existing pending
// channel ID.
chanID = msg.pendingChanID
chanID = msg.PendingChanID
if _, err := f.getReservationCtx(peerKey, chanID); err == nil {
msg.err <- fmt.Errorf("pendingChannelID(%x) "+
msg.Err <- fmt.Errorf("pendingChannelID(%x) "+
"already present", chanID[:])
return
}
@ -3157,8 +3148,8 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
// address from the wallet if our node is configured to set shutdown
// address by default).
shutdown, err := getUpfrontShutdownScript(
f.cfg.EnableUpfrontShutdown, msg.peer,
msg.openChanReq.shutdownScript,
f.cfg.EnableUpfrontShutdown, msg.Peer,
msg.ShutdownScript,
func() (lnwire.DeliveryAddress, error) {
addr, err := f.cfg.Wallet.NewAddress(
lnwallet.WitnessPubKey, false,
@ -3170,7 +3161,7 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
},
)
if err != nil {
msg.err <- err
msg.Err <- err
return
}
@ -3182,7 +3173,7 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
// format we can use with this peer. This is dependent on *both* us and
// the remote peer are signaling the proper feature bit.
commitType := commitmentType(
msg.peer.LocalFeatures(), msg.peer.RemoteFeatures(),
msg.Peer.LocalFeatures(), msg.Peer.RemoteFeatures(),
)
// First, we'll query the fee estimator for a fee that should get the
@ -3191,7 +3182,7 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
// to execute a timely unilateral channel closure if needed.
commitFeePerKw, err := f.cfg.FeeEstimator.EstimateFeePerKW(3)
if err != nil {
msg.err <- err
msg.Err <- err
return
}
@ -3204,25 +3195,25 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
}
req := &lnwallet.InitFundingReserveMsg{
ChainHash: &msg.chainHash,
ChainHash: &msg.ChainHash,
PendingChanID: chanID,
NodeID: peerKey,
NodeAddr: msg.peer.Address(),
SubtractFees: msg.subtractFees,
NodeAddr: msg.Peer.Address(),
SubtractFees: msg.SubtractFees,
LocalFundingAmt: localAmt,
RemoteFundingAmt: 0,
CommitFeePerKw: commitFeePerKw,
FundingFeePerKw: msg.fundingFeePerKw,
PushMSat: msg.pushAmt,
FundingFeePerKw: msg.FundingFeePerKw,
PushMSat: msg.PushAmt,
Flags: channelFlags,
MinConfs: msg.minConfs,
MinConfs: msg.MinConfs,
CommitType: commitType,
ChanFunder: msg.chanFunder,
ChanFunder: msg.ChanFunder,
}
reservation, err := f.cfg.Wallet.InitChannelReservation(req)
if err != nil {
msg.err <- err
msg.Err <- err
return
}
@ -3235,7 +3226,7 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
// SubtractFees=true.
capacity := reservation.Capacity()
fndgLog.Infof("Target commit tx sat/kw for pendingID(%x): %v", chanID,
log.Infof("Target commit tx sat/kw for pendingID(%x): %v", chanID,
int64(commitFeePerKw))
// If the remote CSV delay was not set in the open channel request,
@ -3276,14 +3267,14 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
remoteMaxHtlcs: maxHtlcs,
maxLocalCsv: maxCSV,
reservation: reservation,
peer: msg.peer,
updates: msg.updates,
err: msg.err,
peer: msg.Peer,
updates: msg.Updates,
err: msg.Err,
}
f.activeReservations[peerIDKey][chanID] = resCtx
f.resMtx.Unlock()
// Update the timestamp once the initFundingMsg has been handled.
// Update the timestamp once the InitFundingMsg has been handled.
defer resCtx.updateTimestamp()
// Once the reservation has been created, and indexed, queue a funding
@ -3295,14 +3286,14 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
// remote party.
chanReserve := f.cfg.RequiredRemoteChanReserve(capacity, ourDustLimit)
fndgLog.Infof("Starting funding workflow with %v for pending_id(%x), "+
"committype=%v", msg.peer.Address(), chanID, commitType)
log.Infof("Starting funding workflow with %v for pending_id(%x), "+
"committype=%v", msg.Peer.Address(), chanID, commitType)
fundingOpen := lnwire.OpenChannel{
ChainHash: *f.cfg.Wallet.Cfg.NetParams.GenesisHash,
PendingChannelID: chanID,
FundingAmount: capacity,
PushAmount: msg.pushAmt,
PushAmount: msg.PushAmt,
DustLimit: ourContribution.DustLimit,
MaxValueInFlight: maxValue,
ChannelReserve: chanReserve,
@ -3319,19 +3310,19 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
ChannelFlags: channelFlags,
UpfrontShutdownScript: shutdown,
}
if err := msg.peer.SendMessage(true, &fundingOpen); err != nil {
if err := msg.Peer.SendMessage(true, &fundingOpen); err != nil {
e := fmt.Errorf("unable to send funding request message: %v",
err)
fndgLog.Errorf(e.Error())
log.Errorf(e.Error())
// Since we were unable to send the initial message to the peer
// and start the funding flow, we'll cancel this reservation.
_, err := f.cancelReservationCtx(peerKey, chanID, false)
if err != nil {
fndgLog.Errorf("unable to cancel reservation: %v", err)
log.Errorf("unable to cancel reservation: %v", err)
}
msg.err <- e
msg.Err <- e
return
}
}
@ -3339,7 +3330,7 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
// handleErrorMsg processes the error which was received from remote peer,
// depending on the type of error we should do different clean up steps and
// inform the user about it.
func (f *fundingManager) handleErrorMsg(peer lnpeer.Peer,
func (f *Manager) handleErrorMsg(peer lnpeer.Peer,
msg *lnwire.Error) {
chanID := msg.ChanID
@ -3350,7 +3341,7 @@ func (f *fundingManager) handleErrorMsg(peer lnpeer.Peer,
// exit early as this was an unwarranted error.
resCtx, err := f.cancelReservationCtx(peerKey, chanID, true)
if err != nil {
fndgLog.Warnf("Received error for non-existent funding "+
log.Warnf("Received error for non-existent funding "+
"flow: %v (%v)", err, msg.Error())
return
}
@ -3360,7 +3351,7 @@ func (f *fundingManager) handleErrorMsg(peer lnpeer.Peer,
fundingErr := fmt.Errorf("received funding error from %x: %v",
peerKey.SerializeCompressed(), msg.Error(),
)
fndgLog.Errorf(fundingErr.Error())
log.Errorf(fundingErr.Error())
// If this was a PSBT funding flow, the remote likely timed out because
// we waited too long. Return a nice error message to the user in that
@ -3376,7 +3367,7 @@ func (f *fundingManager) handleErrorMsg(peer lnpeer.Peer,
// pruneZombieReservations loops through all pending reservations and fails the
// funding flow for any reservations that have not been updated since the
// ReservationTimeout and are not locked waiting for the funding transaction.
func (f *fundingManager) pruneZombieReservations() {
func (f *Manager) pruneZombieReservations() {
zombieReservations := make(pendingChannels)
f.resMtx.RLock()
@ -3404,17 +3395,17 @@ func (f *fundingManager) pruneZombieReservations() {
err := fmt.Errorf("reservation timed out waiting for peer "+
"(peer_id:%x, chan_id:%x)", resCtx.peer.IdentityKey(),
pendingChanID[:])
fndgLog.Warnf(err.Error())
log.Warnf(err.Error())
f.failFundingFlow(resCtx.peer, pendingChanID, err)
}
}
// cancelReservationCtx does all needed work in order to securely cancel the
// reservation.
func (f *fundingManager) cancelReservationCtx(peerKey *btcec.PublicKey,
func (f *Manager) cancelReservationCtx(peerKey *btcec.PublicKey,
pendingChanID [32]byte, byRemote bool) (*reservationWithCtx, error) {
fndgLog.Infof("Cancelling funding reservation for node_key=%x, "+
log.Infof("Cancelling funding reservation for node_key=%x, "+
"chan_id=%x", peerKey.SerializeCompressed(), pendingChanID[:])
peerIDKey := newSerializedKey(peerKey)
@ -3459,7 +3450,7 @@ func (f *fundingManager) cancelReservationCtx(peerKey *btcec.PublicKey,
// deleteReservationCtx deletes the reservation uniquely identified by the
// target public key of the peer, and the specified pending channel ID.
func (f *fundingManager) deleteReservationCtx(peerKey *btcec.PublicKey,
func (f *Manager) deleteReservationCtx(peerKey *btcec.PublicKey,
pendingChanID [32]byte) {
// TODO(roasbeef): possibly cancel funding barrier in peer's
@ -3484,7 +3475,7 @@ func (f *fundingManager) deleteReservationCtx(peerKey *btcec.PublicKey,
// getReservationCtx returns the reservation context for a particular pending
// channel ID for a target peer.
func (f *fundingManager) getReservationCtx(peerKey *btcec.PublicKey,
func (f *Manager) getReservationCtx(peerKey *btcec.PublicKey,
pendingChanID [32]byte) (*reservationWithCtx, error) {
peerIDKey := newSerializedKey(peerKey)
@ -3505,7 +3496,7 @@ func (f *fundingManager) getReservationCtx(peerKey *btcec.PublicKey,
// of being funded. After the funding transaction has been confirmed, the
// channel will receive a new, permanent channel ID, and will no longer be
// considered pending.
func (f *fundingManager) IsPendingChannel(pendingChanID [32]byte,
func (f *Manager) IsPendingChannel(pendingChanID [32]byte,
peer lnpeer.Peer) bool {
peerIDKey := newSerializedKey(peer.IdentityKey())
@ -3526,7 +3517,7 @@ func copyPubKey(pub *btcec.PublicKey) *btcec.PublicKey {
// saveChannelOpeningState saves the channelOpeningState for the provided
// chanPoint to the channelOpeningStateBucket.
func (f *fundingManager) saveChannelOpeningState(chanPoint *wire.OutPoint,
func (f *Manager) saveChannelOpeningState(chanPoint *wire.OutPoint,
state channelOpeningState, shortChanID *lnwire.ShortChannelID) error {
return kvdb.Update(f.cfg.Wallet.Cfg.Database, func(tx kvdb.RwTx) error {
@ -3536,7 +3527,7 @@ func (f *fundingManager) saveChannelOpeningState(chanPoint *wire.OutPoint,
}
var outpointBytes bytes.Buffer
if err = writeOutpoint(&outpointBytes, chanPoint); err != nil {
if err = WriteOutpoint(&outpointBytes, chanPoint); err != nil {
return err
}
@ -3553,7 +3544,7 @@ func (f *fundingManager) saveChannelOpeningState(chanPoint *wire.OutPoint,
// getChannelOpeningState fetches the channelOpeningState for the provided
// chanPoint from the database, or returns ErrChannelNotFound if the channel
// is not found.
func (f *fundingManager) getChannelOpeningState(chanPoint *wire.OutPoint) (
func (f *Manager) getChannelOpeningState(chanPoint *wire.OutPoint) (
channelOpeningState, *lnwire.ShortChannelID, error) {
var state channelOpeningState
@ -3568,7 +3559,7 @@ func (f *fundingManager) getChannelOpeningState(chanPoint *wire.OutPoint) (
}
var outpointBytes bytes.Buffer
if err := writeOutpoint(&outpointBytes, chanPoint); err != nil {
if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
return err
}
@ -3589,7 +3580,7 @@ func (f *fundingManager) getChannelOpeningState(chanPoint *wire.OutPoint) (
}
// deleteChannelOpeningState removes any state for chanPoint from the database.
func (f *fundingManager) deleteChannelOpeningState(chanPoint *wire.OutPoint) error {
func (f *Manager) deleteChannelOpeningState(chanPoint *wire.OutPoint) error {
return kvdb.Update(f.cfg.Wallet.Cfg.Database, func(tx kvdb.RwTx) error {
bucket := tx.ReadWriteBucket(channelOpeningStateBucket)
if bucket == nil {
@ -3597,7 +3588,7 @@ func (f *fundingManager) deleteChannelOpeningState(chanPoint *wire.OutPoint) err
}
var outpointBytes bytes.Buffer
if err := writeOutpoint(&outpointBytes, chanPoint); err != nil {
if err := WriteOutpoint(&outpointBytes, chanPoint); err != nil {
return err
}

@ -1,6 +1,6 @@
// +build !rpctest
package lnd
package funding
import (
"bytes"
@ -59,6 +59,10 @@ const (
// A dummy value to use for the funding broadcast height.
fundingBroadcastHeight = 123
// defaultMaxLocalCSVDelay is the maximum delay we accept on our
// commitment output.
defaultMaxLocalCSVDelay = 10000
)
var (
@ -184,7 +188,7 @@ type testNode struct {
msgChan chan lnwire.Message
announceChan chan lnwire.Message
publTxChan chan *wire.MsgTx
fundingMgr *fundingManager
fundingMgr *Manager
newChannels chan *newChannelMsg
mockNotifier *mockNotifier
mockChanEvent *mockChanEvent
@ -346,7 +350,7 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey,
chainedAcceptor := chanacceptor.NewChainedAcceptor()
fundingCfg := fundingConfig{
fundingCfg := Config{
IDKey: privKey.PubKey(),
Wallet: lnw,
Notifier: chainNotifier,
@ -433,7 +437,7 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey,
},
ZombieSweeperInterval: 1 * time.Hour,
ReservationTimeout: 1 * time.Nanosecond,
MaxChanSize: MaxFundingAmount,
MaxChanSize: MaxBtcFundingAmount,
MaxLocalCSVDelay: defaultMaxLocalCSVDelay,
MaxPendingChannels: lncfg.DefaultMaxPendingChannels,
NotifyOpenChannelEvent: evt.NotifyOpenChannelEvent,
@ -446,7 +450,7 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey,
op(&fundingCfg)
}
f, err := newFundingManager(fundingCfg)
f, err := NewFundingManager(fundingCfg)
if err != nil {
t.Fatalf("failed creating fundingManager: %v", err)
}
@ -480,9 +484,7 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey,
func recreateAliceFundingManager(t *testing.T, alice *testNode) {
// Stop the old fundingManager before creating a new one.
close(alice.shutdownChannel)
if err := alice.fundingMgr.Stop(); err != nil {
t.Fatalf("unable to stop old fundingManager: %v", err)
}
alice.fundingMgr.Stop()
aliceMsgChan := make(chan lnwire.Message)
aliceAnnounceChan := make(chan lnwire.Message)
@ -493,7 +495,7 @@ func recreateAliceFundingManager(t *testing.T, alice *testNode) {
chainedAcceptor := chanacceptor.NewChainedAcceptor()
f, err := newFundingManager(fundingConfig{
f, err := NewFundingManager(Config{
IDKey: oldCfg.IDKey,
Wallet: oldCfg.Wallet,
Notifier: oldCfg.Notifier,
@ -558,7 +560,7 @@ func recreateAliceFundingManager(t *testing.T, alice *testNode) {
}
}
type cfgOption func(*fundingConfig)
type cfgOption func(*Config)
func setupFundingManagers(t *testing.T,
options ...cfgOption) (*testNode, *testNode) {
@ -620,12 +622,8 @@ func tearDownFundingManagers(t *testing.T, a, b *testNode) {
close(a.shutdownChannel)
close(b.shutdownChannel)
if err := a.fundingMgr.Stop(); err != nil {
t.Fatalf("unable to stop fundingManager: %v", err)
}
if err := b.fundingMgr.Stop(); err != nil {
t.Fatalf("unable to stop fundingManager: %v", err)
}
a.fundingMgr.Stop()
b.fundingMgr.Stop()
os.RemoveAll(a.testDir)
os.RemoveAll(b.testDir)
}
@ -656,25 +654,26 @@ func fundChannel(t *testing.T, alice, bob *testNode, localFundingAmt,
// Create a funding request and start the workflow.
errChan := make(chan error, 1)
initReq := &openChanReq{
targetPubkey: bob.privKey.PubKey(),
chainHash: *fundingNetParams.GenesisHash,
subtractFees: subtractFees,
localFundingAmt: localFundingAmt,
pushAmt: lnwire.NewMSatFromSatoshis(pushAmt),
fundingFeePerKw: 1000,
private: !announceChan,
updates: updateChan,
err: errChan,
initReq := &InitFundingMsg{
Peer: bob,
TargetPubkey: bob.privKey.PubKey(),
ChainHash: *fundingNetParams.GenesisHash,
SubtractFees: subtractFees,
LocalFundingAmt: localFundingAmt,
PushAmt: lnwire.NewMSatFromSatoshis(pushAmt),
FundingFeePerKw: 1000,
Private: !announceChan,
Updates: updateChan,
Err: errChan,
}
alice.fundingMgr.initFundingWorkflow(bob, initReq)
alice.fundingMgr.InitFundingWorkflow(initReq)
// Alice should have sent the OpenChannel message to Bob.
var aliceMsg lnwire.Message
select {
case aliceMsg = <-alice.msgChan:
case err := <-initReq.err:
case err := <-initReq.Err:
t.Fatalf("error init funding workflow: %v", err)
case <-time.After(time.Second * 5):
t.Fatalf("alice did not send OpenChannel message")
@ -1316,22 +1315,23 @@ func testLocalCSVLimit(t *testing.T, aliceMaxCSV, bobRequiredCSV uint16) {
// First, we will initiate an outgoing channel from Alice -> Bob.
errChan := make(chan error, 1)
updateChan := make(chan *lnrpc.OpenStatusUpdate)
initReq := &openChanReq{
targetPubkey: bob.privKey.PubKey(),
chainHash: *fundingNetParams.GenesisHash,
localFundingAmt: 200000,
fundingFeePerKw: 1000,
updates: updateChan,
err: errChan,
initReq := &InitFundingMsg{
Peer: bob,
TargetPubkey: bob.privKey.PubKey(),
ChainHash: *fundingNetParams.GenesisHash,
LocalFundingAmt: 200000,
FundingFeePerKw: 1000,
Updates: updateChan,
Err: errChan,
}
// Alice should have sent the OpenChannel message to Bob.
alice.fundingMgr.initFundingWorkflow(bob, initReq)
alice.fundingMgr.InitFundingWorkflow(initReq)
var aliceMsg lnwire.Message
select {
case aliceMsg = <-alice.msgChan:
case err := <-initReq.err:
case err := <-initReq.Err:
t.Fatalf("error init funding workflow: %v", err)
case <-time.After(time.Second * 5):
@ -1381,23 +1381,24 @@ func testLocalCSVLimit(t *testing.T, aliceMaxCSV, bobRequiredCSV uint16) {
// handle incoming channels, opening a channel from Bob->Alice.
errChan = make(chan error, 1)
updateChan = make(chan *lnrpc.OpenStatusUpdate)
initReq = &openChanReq{
targetPubkey: alice.privKey.PubKey(),
chainHash: *fundingNetParams.GenesisHash,
localFundingAmt: 200000,
fundingFeePerKw: 1000,
updates: updateChan,
err: errChan,
initReq = &InitFundingMsg{
Peer: alice,
TargetPubkey: alice.privKey.PubKey(),
ChainHash: *fundingNetParams.GenesisHash,
LocalFundingAmt: 200000,
FundingFeePerKw: 1000,
Updates: updateChan,
Err: errChan,
}
bob.fundingMgr.initFundingWorkflow(alice, initReq)
bob.fundingMgr.InitFundingWorkflow(initReq)
// Bob should have sent the OpenChannel message to Alice.
var bobMsg lnwire.Message
select {
case bobMsg = <-bob.msgChan:
case err := <-initReq.err:
case err := <-initReq.Err:
t.Fatalf("bob OpenChannel message failed: %v", err)
case <-time.After(time.Second * 5):
@ -1501,9 +1502,7 @@ func TestFundingManagerRestartBehavior(t *testing.T) {
// implementation, and expect it to retry sending the fundingLocked
// message. We'll explicitly shut down Alice's funding manager to
// prevent a race when overriding the sendMessage implementation.
if err := alice.fundingMgr.Stop(); err != nil {
t.Fatalf("unable to stop alice's funding manager: %v", err)
}
alice.fundingMgr.Stop()
bob.sendMessage = workingSendMessage
recreateAliceFundingManager(t, alice)
@ -1721,7 +1720,7 @@ func TestFundingManagerOfflinePeer(t *testing.T) {
// TestFundingManagerPeerTimeoutAfterInitFunding checks that the zombie sweeper
// will properly clean up a zombie reservation that times out after the
// initFundingMsg has been handled.
// InitFundingMsg has been handled.
func TestFundingManagerPeerTimeoutAfterInitFunding(t *testing.T) {
t.Parallel()
@ -1733,23 +1732,24 @@ func TestFundingManagerPeerTimeoutAfterInitFunding(t *testing.T) {
// Create a funding request and start the workflow.
errChan := make(chan error, 1)
initReq := &openChanReq{
targetPubkey: bob.privKey.PubKey(),
chainHash: *fundingNetParams.GenesisHash,
localFundingAmt: 500000,
pushAmt: lnwire.NewMSatFromSatoshis(0),
private: false,
updates: updateChan,
err: errChan,
initReq := &InitFundingMsg{
Peer: bob,
TargetPubkey: bob.privKey.PubKey(),
ChainHash: *fundingNetParams.GenesisHash,
LocalFundingAmt: 500000,
PushAmt: lnwire.NewMSatFromSatoshis(0),
Private: false,
Updates: updateChan,
Err: errChan,
}
alice.fundingMgr.initFundingWorkflow(bob, initReq)
alice.fundingMgr.InitFundingWorkflow(initReq)
// Alice should have sent the OpenChannel message to Bob.
var aliceMsg lnwire.Message
select {
case aliceMsg = <-alice.msgChan:
case err := <-initReq.err:
case err := <-initReq.Err:
t.Fatalf("error init funding workflow: %v", err)
case <-time.After(time.Second * 5):
t.Fatalf("alice did not send OpenChannel message")
@ -1795,23 +1795,24 @@ func TestFundingManagerPeerTimeoutAfterFundingOpen(t *testing.T) {
// Create a funding request and start the workflow.
errChan := make(chan error, 1)
initReq := &openChanReq{
targetPubkey: bob.privKey.PubKey(),
chainHash: *fundingNetParams.GenesisHash,
localFundingAmt: 500000,
pushAmt: lnwire.NewMSatFromSatoshis(0),
private: false,
updates: updateChan,
err: errChan,
initReq := &InitFundingMsg{
Peer: bob,
TargetPubkey: bob.privKey.PubKey(),
ChainHash: *fundingNetParams.GenesisHash,
LocalFundingAmt: 500000,
PushAmt: lnwire.NewMSatFromSatoshis(0),
Private: false,
Updates: updateChan,
Err: errChan,
}
alice.fundingMgr.initFundingWorkflow(bob, initReq)
alice.fundingMgr.InitFundingWorkflow(initReq)
// Alice should have sent the OpenChannel message to Bob.
var aliceMsg lnwire.Message
select {
case aliceMsg = <-alice.msgChan:
case err := <-initReq.err:
case err := <-initReq.Err:
t.Fatalf("error init funding workflow: %v", err)
case <-time.After(time.Second * 5):
t.Fatalf("alice did not send OpenChannel message")
@ -1866,23 +1867,24 @@ func TestFundingManagerPeerTimeoutAfterFundingAccept(t *testing.T) {
// Create a funding request and start the workflow.
errChan := make(chan error, 1)
initReq := &openChanReq{
targetPubkey: bob.privKey.PubKey(),
chainHash: *fundingNetParams.GenesisHash,
localFundingAmt: 500000,
pushAmt: lnwire.NewMSatFromSatoshis(0),
private: false,
updates: updateChan,
err: errChan,
initReq := &InitFundingMsg{
Peer: bob,
TargetPubkey: bob.privKey.PubKey(),
ChainHash: *fundingNetParams.GenesisHash,
LocalFundingAmt: 500000,
PushAmt: lnwire.NewMSatFromSatoshis(0),
Private: false,
Updates: updateChan,
Err: errChan,
}
alice.fundingMgr.initFundingWorkflow(bob, initReq)
alice.fundingMgr.InitFundingWorkflow(initReq)
// Alice should have sent the OpenChannel message to Bob.
var aliceMsg lnwire.Message
select {
case aliceMsg = <-alice.msgChan:
case err := <-initReq.err:
case err := <-initReq.Err:
t.Fatalf("error init funding workflow: %v", err)
case <-time.After(time.Second * 5):
t.Fatalf("alice did not send OpenChannel message")
@ -2590,26 +2592,27 @@ func TestFundingManagerCustomChannelParameters(t *testing.T) {
// Create a funding request with the custom parameters and start the
// workflow.
errChan := make(chan error, 1)
initReq := &openChanReq{
targetPubkey: bob.privKey.PubKey(),
chainHash: *fundingNetParams.GenesisHash,
localFundingAmt: localAmt,
pushAmt: lnwire.NewMSatFromSatoshis(pushAmt),
private: false,
maxValueInFlight: maxValueInFlight,
minHtlcIn: minHtlcIn,
remoteCsvDelay: csvDelay,
updates: updateChan,
err: errChan,
initReq := &InitFundingMsg{
Peer: bob,
TargetPubkey: bob.privKey.PubKey(),
ChainHash: *fundingNetParams.GenesisHash,
LocalFundingAmt: localAmt,
PushAmt: lnwire.NewMSatFromSatoshis(pushAmt),
Private: false,
MaxValueInFlight: maxValueInFlight,
MinHtlcIn: minHtlcIn,
RemoteCsvDelay: csvDelay,
Updates: updateChan,
Err: errChan,
}
alice.fundingMgr.initFundingWorkflow(bob, initReq)
alice.fundingMgr.InitFundingWorkflow(initReq)
// Alice should have sent the OpenChannel message to Bob.
var aliceMsg lnwire.Message
select {
case aliceMsg = <-alice.msgChan:
case err := <-initReq.err:
case err := <-initReq.Err:
t.Fatalf("error init funding workflow: %v", err)
case <-time.After(time.Second * 5):
t.Fatalf("alice did not send OpenChannel message")
@ -2864,25 +2867,26 @@ func TestFundingManagerMaxPendingChannels(t *testing.T) {
t.Parallel()
alice, bob := setupFundingManagers(
t, func(cfg *fundingConfig) {
t, func(cfg *Config) {
cfg.MaxPendingChannels = maxPending
},
)
defer tearDownFundingManagers(t, alice, bob)
// Create openChanReqs for maxPending+1 channels.
var initReqs []*openChanReq
// Create InitFundingMsg structs for maxPending+1 channels.
var initReqs []*InitFundingMsg
for i := 0; i < maxPending+1; i++ {
updateChan := make(chan *lnrpc.OpenStatusUpdate)
errChan := make(chan error, 1)
initReq := &openChanReq{
targetPubkey: bob.privKey.PubKey(),
chainHash: *fundingNetParams.GenesisHash,
localFundingAmt: 5000000,
pushAmt: lnwire.NewMSatFromSatoshis(0),
private: false,
updates: updateChan,
err: errChan,
initReq := &InitFundingMsg{
Peer: bob,
TargetPubkey: bob.privKey.PubKey(),
ChainHash: *fundingNetParams.GenesisHash,
LocalFundingAmt: 5000000,
PushAmt: lnwire.NewMSatFromSatoshis(0),
Private: false,
Updates: updateChan,
Err: errChan,
}
initReqs = append(initReqs, initReq)
}
@ -2891,13 +2895,13 @@ func TestFundingManagerMaxPendingChannels(t *testing.T) {
var accepts []*lnwire.AcceptChannel
var lastOpen *lnwire.OpenChannel
for i, initReq := range initReqs {
alice.fundingMgr.initFundingWorkflow(bob, initReq)
alice.fundingMgr.InitFundingWorkflow(initReq)
// Alice should have sent the OpenChannel message to Bob.
var aliceMsg lnwire.Message
select {
case aliceMsg = <-alice.msgChan:
case err := <-initReq.err:
case err := <-initReq.Err:
t.Fatalf("error init funding workflow: %v", err)
case <-time.After(time.Second * 5):
t.Fatalf("alice did not send OpenChannel message")
@ -2973,7 +2977,7 @@ func TestFundingManagerMaxPendingChannels(t *testing.T) {
// publish a funding tx to the network.
var pendingUpdate *lnrpc.OpenStatusUpdate
select {
case pendingUpdate = <-initReqs[i].updates:
case pendingUpdate = <-initReqs[i].Updates:
case <-time.After(time.Second * 5):
t.Fatalf("alice did not send OpenStatusUpdate_ChanPending")
}
@ -3036,7 +3040,7 @@ func TestFundingManagerRejectPush(t *testing.T) {
// Enable 'rejectpush' option and initialize funding managers.
alice, bob := setupFundingManagers(
t, func(cfg *fundingConfig) {
t, func(cfg *Config) {
cfg.RejectPush = true
},
)
@ -3045,23 +3049,24 @@ func TestFundingManagerRejectPush(t *testing.T) {
// Create a funding request and start the workflow.
updateChan := make(chan *lnrpc.OpenStatusUpdate)
errChan := make(chan error, 1)
initReq := &openChanReq{
targetPubkey: bob.privKey.PubKey(),
chainHash: *fundingNetParams.GenesisHash,
localFundingAmt: 500000,
pushAmt: lnwire.NewMSatFromSatoshis(10),
private: true,
updates: updateChan,
err: errChan,
initReq := &InitFundingMsg{
Peer: bob,
TargetPubkey: bob.privKey.PubKey(),
ChainHash: *fundingNetParams.GenesisHash,
LocalFundingAmt: 500000,
PushAmt: lnwire.NewMSatFromSatoshis(10),
Private: true,
Updates: updateChan,
Err: errChan,
}
alice.fundingMgr.initFundingWorkflow(bob, initReq)
alice.fundingMgr.InitFundingWorkflow(initReq)
// Alice should have sent the OpenChannel message to Bob.
var aliceMsg lnwire.Message
select {
case aliceMsg = <-alice.msgChan:
case err := <-initReq.err:
case err := <-initReq.Err:
t.Fatalf("error init funding workflow: %v", err)
case <-time.After(time.Second * 5):
t.Fatalf("alice did not send OpenChannel message")
@ -3102,23 +3107,24 @@ func TestFundingManagerMaxConfs(t *testing.T) {
// Create a funding request and start the workflow.
updateChan := make(chan *lnrpc.OpenStatusUpdate)
errChan := make(chan error, 1)
initReq := &openChanReq{
targetPubkey: bob.privKey.PubKey(),
chainHash: *fundingNetParams.GenesisHash,
localFundingAmt: 500000,
pushAmt: lnwire.NewMSatFromSatoshis(10),
private: false,
updates: updateChan,
err: errChan,
initReq := &InitFundingMsg{
Peer: bob,
TargetPubkey: bob.privKey.PubKey(),
ChainHash: *fundingNetParams.GenesisHash,
LocalFundingAmt: 500000,
PushAmt: lnwire.NewMSatFromSatoshis(10),
Private: false,
Updates: updateChan,
Err: errChan,
}
alice.fundingMgr.initFundingWorkflow(bob, initReq)
alice.fundingMgr.InitFundingWorkflow(initReq)
// Alice should have sent the OpenChannel message to Bob.
var aliceMsg lnwire.Message
select {
case aliceMsg = <-alice.msgChan:
case err := <-initReq.err:
case err := <-initReq.Err:
t.Fatalf("error init funding workflow: %v", err)
case <-time.After(time.Second * 5):
t.Fatalf("alice did not send OpenChannel message")
@ -3374,29 +3380,30 @@ func TestMaxChannelSizeConfig(t *testing.T) {
// Create a set of funding managers that will reject wumbo
// channels but set --maxchansize explicitly lower than soft-limit.
// Verify that wumbo rejecting funding managers will respect --maxchansize
// below 16777215 satoshi (MaxFundingAmount) limit.
alice, bob := setupFundingManagers(t, func(cfg *fundingConfig) {
// below 16777215 satoshi (MaxBtcFundingAmount) limit.
alice, bob := setupFundingManagers(t, func(cfg *Config) {
cfg.NoWumboChans = true
cfg.MaxChanSize = MaxFundingAmount - 1
cfg.MaxChanSize = MaxBtcFundingAmount - 1
})
// Attempt to create a channel above the limit
// imposed by --maxchansize, which should be rejected.
updateChan := make(chan *lnrpc.OpenStatusUpdate)
errChan := make(chan error, 1)
initReq := &openChanReq{
targetPubkey: bob.privKey.PubKey(),
chainHash: *fundingNetParams.GenesisHash,
localFundingAmt: MaxFundingAmount,
pushAmt: lnwire.NewMSatFromSatoshis(0),
private: false,
updates: updateChan,
err: errChan,
initReq := &InitFundingMsg{
Peer: bob,
TargetPubkey: bob.privKey.PubKey(),
ChainHash: *fundingNetParams.GenesisHash,
LocalFundingAmt: MaxBtcFundingAmount,
PushAmt: lnwire.NewMSatFromSatoshis(0),
Private: false,
Updates: updateChan,
Err: errChan,
}
// After processing the funding open message, bob should respond with
// an error rejecting the channel that exceeds size limit.
alice.fundingMgr.initFundingWorkflow(bob, initReq)
alice.fundingMgr.InitFundingWorkflow(initReq)
openChanMsg := expectOpenChannelMsg(t, alice.msgChan)
bob.fundingMgr.ProcessFundingMsg(openChanMsg, alice)
assertErrorSent(t, bob.msgChan)
@ -3405,13 +3412,16 @@ func TestMaxChannelSizeConfig(t *testing.T) {
// channels but set --maxchansize explicitly higher than soft-limit
// A --maxchansize greater than this limit should have no effect.
tearDownFundingManagers(t, alice, bob)
alice, bob = setupFundingManagers(t, func(cfg *fundingConfig) {
alice, bob = setupFundingManagers(t, func(cfg *Config) {
cfg.NoWumboChans = true
cfg.MaxChanSize = MaxFundingAmount + 1
cfg.MaxChanSize = MaxBtcFundingAmount + 1
})
// Reset the Peer to the newly created one.
initReq.Peer = bob
// We expect Bob to respond with an Accept channel message.
alice.fundingMgr.initFundingWorkflow(bob, initReq)
alice.fundingMgr.InitFundingWorkflow(initReq)
openChanMsg = expectOpenChannelMsg(t, alice.msgChan)
bob.fundingMgr.ProcessFundingMsg(openChanMsg, alice)
assertFundingMsgSent(t, bob.msgChan, "AcceptChannel")
@ -3420,18 +3430,21 @@ func TestMaxChannelSizeConfig(t *testing.T) {
// Create the funding managers, this time allowing
// wumbo channels but setting --maxchansize explicitly.
tearDownFundingManagers(t, alice, bob)
alice, bob = setupFundingManagers(t, func(cfg *fundingConfig) {
alice, bob = setupFundingManagers(t, func(cfg *Config) {
cfg.NoWumboChans = false
cfg.MaxChanSize = btcutil.Amount(100000000)
})
// Reset the Peer to the newly created one.
initReq.Peer = bob
// Attempt to create a channel above the limit
// imposed by --maxchansize, which should be rejected.
initReq.localFundingAmt = btcutil.SatoshiPerBitcoin + 1
initReq.LocalFundingAmt = btcutil.SatoshiPerBitcoin + 1
// After processing the funding open message, bob should respond with
// an error rejecting the channel that exceeds size limit.
alice.fundingMgr.initFundingWorkflow(bob, initReq)
alice.fundingMgr.InitFundingWorkflow(initReq)
openChanMsg = expectOpenChannelMsg(t, alice.msgChan)
bob.fundingMgr.ProcessFundingMsg(openChanMsg, alice)
assertErrorSent(t, bob.msgChan)
@ -3444,7 +3457,7 @@ func TestWumboChannelConfig(t *testing.T) {
// First we'll create a set of funding managers that will reject wumbo
// channels.
alice, bob := setupFundingManagers(t, func(cfg *fundingConfig) {
alice, bob := setupFundingManagers(t, func(cfg *Config) {
cfg.NoWumboChans = true
})
@ -3453,29 +3466,30 @@ func TestWumboChannelConfig(t *testing.T) {
// funding process w/o issue.
updateChan := make(chan *lnrpc.OpenStatusUpdate)
errChan := make(chan error, 1)
initReq := &openChanReq{
targetPubkey: bob.privKey.PubKey(),
chainHash: *fundingNetParams.GenesisHash,
localFundingAmt: MaxFundingAmount,
pushAmt: lnwire.NewMSatFromSatoshis(0),
private: false,
updates: updateChan,
err: errChan,
initReq := &InitFundingMsg{
Peer: bob,
TargetPubkey: bob.privKey.PubKey(),
ChainHash: *fundingNetParams.GenesisHash,
LocalFundingAmt: MaxBtcFundingAmount,
PushAmt: lnwire.NewMSatFromSatoshis(0),
Private: false,
Updates: updateChan,
Err: errChan,
}
// We expect Bob to respond with an Accept channel message.
alice.fundingMgr.initFundingWorkflow(bob, initReq)
alice.fundingMgr.InitFundingWorkflow(initReq)
openChanMsg := expectOpenChannelMsg(t, alice.msgChan)
bob.fundingMgr.ProcessFundingMsg(openChanMsg, alice)
assertFundingMsgSent(t, bob.msgChan, "AcceptChannel")
// We'll now attempt to create a channel above the wumbo mark, which
// should be rejected.
initReq.localFundingAmt = btcutil.SatoshiPerBitcoin
initReq.LocalFundingAmt = btcutil.SatoshiPerBitcoin
// After processing the funding open message, bob should respond with
// an error rejecting the channel.
alice.fundingMgr.initFundingWorkflow(bob, initReq)
alice.fundingMgr.InitFundingWorkflow(initReq)
openChanMsg = expectOpenChannelMsg(t, alice.msgChan)
bob.fundingMgr.ProcessFundingMsg(openChanMsg, alice)
assertErrorSent(t, bob.msgChan)
@ -3483,14 +3497,17 @@ func TestWumboChannelConfig(t *testing.T) {
// Next, we'll re-create the funding managers, but this time allowing
// wumbo channels explicitly.
tearDownFundingManagers(t, alice, bob)
alice, bob = setupFundingManagers(t, func(cfg *fundingConfig) {
alice, bob = setupFundingManagers(t, func(cfg *Config) {
cfg.NoWumboChans = false
cfg.MaxChanSize = MaxBtcFundingAmountWumbo
})
// Reset the Peer to the newly created one.
initReq.Peer = bob
// We should now be able to initiate a wumbo channel funding w/o any
// issues.
alice.fundingMgr.initFundingWorkflow(bob, initReq)
alice.fundingMgr.InitFundingWorkflow(initReq)
openChanMsg = expectOpenChannelMsg(t, alice.msgChan)
bob.fundingMgr.ProcessFundingMsg(openChanMsg, alice)
assertFundingMsgSent(t, bob.msgChan, "AcceptChannel")

@ -8,7 +8,7 @@ import (
"strings"
"github.com/btcsuite/btcutil"
"github.com/lightningnetwork/lnd"
"github.com/lightningnetwork/lnd/funding"
"github.com/lightningnetwork/lnd/lntest"
)
@ -49,7 +49,7 @@ func testMaxChannelSize(net *lntest.NetworkHarness, t *harnessTest) {
t.Fatalf("unable to connect peers: %v", err)
}
chanAmt := lnd.MaxBtcFundingAmountWumbo + 1
chanAmt := funding.MaxBtcFundingAmountWumbo + 1
_, err = net.OpenChannel(
ctxb, wumboNode, wumboNode2, lntest.OpenChannelParams{
Amt: chanAmt,
@ -97,7 +97,7 @@ func testMaxChannelSize(net *lntest.NetworkHarness, t *harnessTest) {
// to accept our wumbo channel funding.
wumboNode3, err := net.NewNode(
"wumbo3", []string{"--protocol.wumbo-channels",
fmt.Sprintf("--maxchansize=%v", int64(lnd.MaxBtcFundingAmountWumbo+1))},
fmt.Sprintf("--maxchansize=%v", int64(funding.MaxBtcFundingAmountWumbo+1))},
)
if err != nil {
t.Fatalf("unable to create new node: %v", err)

@ -6,7 +6,7 @@ import (
"strings"
"time"
"github.com/lightningnetwork/lnd"
"github.com/lightningnetwork/lnd/funding"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
"github.com/lightningnetwork/lnd/lntest"
@ -19,7 +19,7 @@ func testHtlcErrorPropagation(net *lntest.NetworkHarness, t *harnessTest) {
// In this test we wish to exercise the daemon's correct parsing,
// handling, and propagation of errors that occur while processing a
// multi-hop payment.
const chanAmt = lnd.MaxBtcFundingAmount
const chanAmt = funding.MaxBtcFundingAmount
// First establish a channel with a capacity of 0.5 BTC between Alice
// and Bob.
@ -102,7 +102,7 @@ func testHtlcErrorPropagation(net *lntest.NetworkHarness, t *harnessTest) {
t.Fatalf("unable to connect bob to carol: %v", err)
}
ctxt, _ = context.WithTimeout(ctxb, channelOpenTimeout)
const bobChanAmt = lnd.MaxBtcFundingAmount
const bobChanAmt = funding.MaxBtcFundingAmount
chanPointBob := openChannelAndAssert(
ctxt, t, net, net.Bob, carol,
lntest.OpenChannelParams{

@ -8,7 +8,7 @@ import (
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
"github.com/lightningnetwork/lnd"
"github.com/lightningnetwork/lnd/funding"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/walletrpc"
"github.com/lightningnetwork/lnd/lntest"
@ -20,7 +20,7 @@ import (
// multisig funding output.
func testPsbtChanFunding(net *lntest.NetworkHarness, t *harnessTest) {
ctxb := context.Background()
const chanSize = lnd.MaxBtcFundingAmount
const chanSize = funding.MaxBtcFundingAmount
// First, we'll create two new nodes that we'll use to open channels
// between for this test. Dave gets some coins that will be used to

@ -32,6 +32,7 @@ import (
"github.com/lightningnetwork/lnd"
"github.com/lightningnetwork/lnd/chainreg"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/funding"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/labels"
"github.com/lightningnetwork/lnd/lncfg"
@ -1250,7 +1251,7 @@ func basicChannelFundingTest(t *harnessTest, net *lntest.NetworkHarness,
alice *lntest.HarnessNode, bob *lntest.HarnessNode,
fundingShim *lnrpc.FundingShim) (*lnrpc.Channel, *lnrpc.Channel, func(), error) {
chanAmt := lnd.MaxBtcFundingAmount
chanAmt := funding.MaxBtcFundingAmount
pushAmt := btcutil.Amount(100000)
// Record nodes' channel balance before testing.
@ -1493,7 +1494,7 @@ func testUnconfirmedChannelFunding(net *lntest.NetworkHarness, t *harnessTest) {
ctxb := context.Background()
const (
chanAmt = lnd.MaxBtcFundingAmount
chanAmt = funding.MaxBtcFundingAmount
pushAmt = btcutil.Amount(100000)
)
@ -1945,7 +1946,7 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
defaultTimeLockDelta = chainreg.DefaultBitcoinTimeLockDelta
defaultMinHtlc = 1000
)
defaultMaxHtlc := calculateMaxHtlc(lnd.MaxBtcFundingAmount)
defaultMaxHtlc := calculateMaxHtlc(funding.MaxBtcFundingAmount)
// Launch notification clients for all nodes, such that we can
// get notified when they discover new channels and updates in the
@ -1955,7 +1956,7 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
bobSub := subscribeGraphNotifications(t, ctxb, net.Bob)
defer close(bobSub.quit)
chanAmt := lnd.MaxBtcFundingAmount
chanAmt := funding.MaxBtcFundingAmount
pushAmt := chanAmt / 2
// Create a channel Alice->Bob.
@ -2518,7 +2519,7 @@ func testOpenChannelAfterReorg(net *lntest.NetworkHarness, t *harnessTest) {
// Create a new channel that requires 1 confs before it's considered
// open, then broadcast the funding transaction
chanAmt := lnd.MaxBtcFundingAmount
chanAmt := funding.MaxBtcFundingAmount
pushAmt := btcutil.Amount(0)
ctxt, _ := context.WithTimeout(ctxb, channelOpenTimeout)
pendingUpdate, err := net.OpenPendingChannel(ctxt, net.Alice, net.Bob,
@ -2738,7 +2739,7 @@ func testDisconnectingTargetPeer(net *lntest.NetworkHarness, t *harnessTest) {
t.Fatalf("unable to send coins to alice: %v", err)
}
chanAmt := lnd.MaxBtcFundingAmount
chanAmt := funding.MaxBtcFundingAmount
pushAmt := btcutil.Amount(0)
// Create a new channel that requires 1 confs before it's considered
@ -2873,7 +2874,7 @@ func testDisconnectingTargetPeer(net *lntest.NetworkHarness, t *harnessTest) {
func testChannelFundingPersistence(net *lntest.NetworkHarness, t *harnessTest) {
ctxb := context.Background()
chanAmt := lnd.MaxBtcFundingAmount
chanAmt := funding.MaxBtcFundingAmount
pushAmt := btcutil.Amount(0)
// As we need to create a channel that requires more than 1
@ -3061,7 +3062,7 @@ func testChannelBalance(net *lntest.NetworkHarness, t *harnessTest) {
// Open a channel with 0.16 BTC between Alice and Bob, ensuring the
// channel has been opened properly.
amount := lnd.MaxBtcFundingAmount
amount := funding.MaxBtcFundingAmount
// Creates a helper closure to be used below which asserts the proper
// response to a channel balance RPC.
@ -6169,7 +6170,7 @@ func testSendToRouteErrorPropagation(net *lntest.NetworkHarness, t *harnessTest)
func testUnannouncedChannels(net *lntest.NetworkHarness, t *harnessTest) {
ctxb := context.Background()
amount := lnd.MaxBtcFundingAmount
amount := funding.MaxBtcFundingAmount
// Open a channel between Alice and Bob, ensuring the
// channel has been opened properly.
@ -7408,7 +7409,7 @@ func testBasicChannelCreationAndUpdates(net *lntest.NetworkHarness, t *harnessTe
ctxb := context.Background()
const (
numChannels = 2
amount = lnd.MaxBtcFundingAmount
amount = funding.MaxBtcFundingAmount
)
// Subscribe Bob and Alice to channel event notifications.
@ -7572,7 +7573,7 @@ func testMaxPendingChannels(net *lntest.NetworkHarness, t *harnessTest) {
ctxb := context.Background()
maxPendingChannels := lncfg.DefaultMaxPendingChannels + 1
amount := lnd.MaxBtcFundingAmount
amount := funding.MaxBtcFundingAmount
// Create a new node (Carol) with greater number of max pending
// channels.
@ -8183,7 +8184,7 @@ func testRevokedCloseRetribution(net *lntest.NetworkHarness, t *harnessTest) {
ctxb := context.Background()
const (
chanAmt = lnd.MaxBtcFundingAmount
chanAmt = funding.MaxBtcFundingAmount
paymentAmt = 10000
numInvoices = 6
)
@ -8452,7 +8453,7 @@ func testRevokedCloseRetributionZeroValueRemoteOutput(net *lntest.NetworkHarness
ctxb := context.Background()
const (
chanAmt = lnd.MaxBtcFundingAmount
chanAmt = funding.MaxBtcFundingAmount
paymentAmt = 10000
numInvoices = 6
)
@ -8701,7 +8702,7 @@ func testRevokedCloseRetributionRemoteHodl(net *lntest.NetworkHarness,
ctxb := context.Background()
const (
chanAmt = lnd.MaxBtcFundingAmount
chanAmt = funding.MaxBtcFundingAmount
pushAmt = 200000
paymentAmt = 10000
numInvoices = 6
@ -8747,7 +8748,7 @@ func testRevokedCloseRetributionRemoteHodl(net *lntest.NetworkHarness,
// In order to test Dave's response to an uncooperative channel closure
// by Carol, we'll first open up a channel between them with a
// lnd.MaxBtcFundingAmount (2^24) satoshis value.
// funding.MaxBtcFundingAmount (2^24) satoshis value.
ctxt, _ = context.WithTimeout(ctxb, channelOpenTimeout)
chanPoint := openChannelAndAssert(
ctxt, t, net, dave, carol,
@ -9165,7 +9166,7 @@ func testRevokedCloseRetributionAltruistWatchtowerCase(
ctxb := context.Background()
const (
chanAmt = lnd.MaxBtcFundingAmount
chanAmt = funding.MaxBtcFundingAmount
paymentAmt = 10000
numInvoices = 6
externalIP = "1.2.3.4"
@ -9739,7 +9740,7 @@ func assertDLPExecuted(net *lntest.NetworkHarness, t *harnessTest,
func testDataLossProtection(net *lntest.NetworkHarness, t *harnessTest) {
ctxb := context.Background()
const (
chanAmt = lnd.MaxBtcFundingAmount
chanAmt = funding.MaxBtcFundingAmount
paymentAmt = 10000
numInvoices = 6
)
@ -10329,7 +10330,7 @@ func subscribeGraphNotifications(t *harnessTest, ctxb context.Context,
func testGraphTopologyNotifications(net *lntest.NetworkHarness, t *harnessTest) {
ctxb := context.Background()
const chanAmt = lnd.MaxBtcFundingAmount
const chanAmt = funding.MaxBtcFundingAmount
// Let Alice subscribe to graph notifications.
graphSub := subscribeGraphNotifications(
@ -10656,7 +10657,7 @@ func testNodeAnnouncement(net *lntest.NetworkHarness, t *harnessTest) {
func testNodeSignVerify(net *lntest.NetworkHarness, t *harnessTest) {
ctxb := context.Background()
chanAmt := lnd.MaxBtcFundingAmount
chanAmt := funding.MaxBtcFundingAmount
pushAmt := btcutil.Amount(100000)
// Create a channel between alice and bob.
@ -13198,7 +13199,7 @@ func testAbandonChannel(net *lntest.NetworkHarness, t *harnessTest) {
// First establish a channel between Alice and Bob.
channelParam := lntest.OpenChannelParams{
Amt: lnd.MaxBtcFundingAmount,
Amt: funding.MaxBtcFundingAmount,
PushAmt: btcutil.Amount(100000),
}
@ -13991,7 +13992,7 @@ func testExternalFundingChanPoint(net *lntest.NetworkHarness, t *harnessTest) {
// flow. To start with, we'll create a pending channel with a shim for
// a transaction that will never be published.
const thawHeight uint32 = 10
const chanSize = lnd.MaxBtcFundingAmount
const chanSize = funding.MaxBtcFundingAmount
fundingShim1, chanPoint1, _ := deriveFundingShim(
net, t, carol, dave, chanSize, thawHeight, 1, false,
)

@ -5,7 +5,7 @@ import (
"strings"
"github.com/btcsuite/btcutil"
"github.com/lightningnetwork/lnd"
"github.com/lightningnetwork/lnd/funding"
"github.com/lightningnetwork/lnd/lntest"
)
@ -48,7 +48,7 @@ func testWumboChannels(net *lntest.NetworkHarness, t *harnessTest) {
t.Fatalf("unable to connect peers: %v", err)
}
chanAmt := lnd.MaxBtcFundingAmount + 1
chanAmt := funding.MaxBtcFundingAmount + 1
_, err = net.OpenChannel(
ctxb, wumboNode, miniNode, lntest.OpenChannelParams{
Amt: chanAmt,

3
log.go

@ -18,6 +18,7 @@ import (
"github.com/lightningnetwork/lnd/channelnotifier"
"github.com/lightningnetwork/lnd/contractcourt"
"github.com/lightningnetwork/lnd/discovery"
"github.com/lightningnetwork/lnd/funding"
"github.com/lightningnetwork/lnd/healthcheck"
"github.com/lightningnetwork/lnd/htlcswitch"
"github.com/lightningnetwork/lnd/invoices"
@ -81,7 +82,6 @@ var (
ltndLog = addLndPkgLogger("LTND")
rpcsLog = addLndPkgLogger("RPCS")
srvrLog = addLndPkgLogger("SRVR")
fndgLog = addLndPkgLogger("FNDG")
utxnLog = addLndPkgLogger("UTXN")
brarLog = addLndPkgLogger("BRAR")
atplLog = addLndPkgLogger("ATPL")
@ -135,6 +135,7 @@ func SetupLoggers(root *build.RotatingLogWriter) {
AddSubLogger(root, healthcheck.Subsystem, healthcheck.UseLogger)
AddSubLogger(root, chainreg.Subsystem, chainreg.UseLogger)
AddSubLogger(root, chanacceptor.Subsystem, chanacceptor.UseLogger)
AddSubLogger(root, funding.Subsystem, funding.UseLogger)
}
// AddSubLogger is a helper method to conveniently create and register the

@ -24,7 +24,7 @@ import (
"github.com/lightningnetwork/lnd/contractcourt"
"github.com/lightningnetwork/lnd/discovery"
"github.com/lightningnetwork/lnd/feature"
"github.com/lightningnetwork/lnd/fmgr"
"github.com/lightningnetwork/lnd/funding"
"github.com/lightningnetwork/lnd/htlcswitch"
"github.com/lightningnetwork/lnd/htlcswitch/hodl"
"github.com/lightningnetwork/lnd/htlcswitch/hop"
@ -273,8 +273,8 @@ type Config struct {
FetchLastChanUpdate func(lnwire.ShortChannelID) (*lnwire.ChannelUpdate,
error)
// FundingManager is an implementation of the fmgr.Manager interface.
FundingManager fmgr.Manager
// FundingManager is an implementation of the funding.Controller interface.
FundingManager funding.Controller
// Hodl is used when creating ChannelLinks to specify HodlFlags as
// breakpoints in dev builds.

@ -10,6 +10,7 @@ import (
"github.com/btcsuite/btcutil"
"github.com/lightningnetwork/lnd/autopilot"
"github.com/lightningnetwork/lnd/chainreg"
"github.com/lightningnetwork/lnd/funding"
"github.com/lightningnetwork/lnd/lncfg"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/tor"
@ -97,18 +98,18 @@ func (c *chanController) OpenChannel(target *btcec.PublicKey,
// Construct the open channel request and send it to the server to begin
// the funding workflow.
req := &openChanReq{
targetPubkey: target,
chainHash: *c.netParams.GenesisHash,
subtractFees: true,
localFundingAmt: amt,
pushAmt: 0,
minHtlcIn: c.chanMinHtlcIn,
fundingFeePerKw: feePerKw,
private: c.private,
remoteCsvDelay: 0,
minConfs: c.minConfs,
maxValueInFlight: 0,
req := &funding.InitFundingMsg{
TargetPubkey: target,
ChainHash: *c.netParams.GenesisHash,
SubtractFees: true,
LocalFundingAmt: amt,
PushAmt: 0,
MinHtlcIn: c.chanMinHtlcIn,
FundingFeePerKw: feePerKw,
Private: c.private,
RemoteCsvDelay: 0,
MinConfs: c.minConfs,
MaxValueInFlight: 0,
}
updateStream, errChan := c.server.OpenChannel(req)

@ -42,6 +42,7 @@ import (
"github.com/lightningnetwork/lnd/contractcourt"
"github.com/lightningnetwork/lnd/discovery"
"github.com/lightningnetwork/lnd/feature"
"github.com/lightningnetwork/lnd/funding"
"github.com/lightningnetwork/lnd/htlcswitch"
"github.com/lightningnetwork/lnd/htlcswitch/hop"
"github.com/lightningnetwork/lnd/input"
@ -1760,11 +1761,11 @@ func (r *rpcServer) canOpenChannel() error {
return nil
}
// praseOpenChannelReq parses an OpenChannelRequest message into the server's
// native openChanReq struct. The logic is abstracted so that it can be shared
// between OpenChannel and OpenChannelSync.
// praseOpenChannelReq parses an OpenChannelRequest message into an InitFundingMsg
// struct. The logic is abstracted so that it can be shared between OpenChannel
// and OpenChannelSync.
func (r *rpcServer) parseOpenChannelReq(in *lnrpc.OpenChannelRequest,
isSync bool) (*openChanReq, error) {
isSync bool) (*funding.InitFundingMsg, error) {
rpcsLog.Debugf("[openchannel] request to NodeKey(%x) "+
"allocation(us=%v, them=%v)", in.NodePubkey,
@ -1803,9 +1804,9 @@ func (r *rpcServer) parseOpenChannelReq(in *lnrpc.OpenChannelRequest,
// Restrict the size of the channel we'll actually open. At a later
// level, we'll ensure that the output we create after accounting for
// fees that a dust output isn't created.
if localFundingAmt < minChanFundingSize {
if localFundingAmt < funding.MinChanFundingSize {
return nil, fmt.Errorf("channel is too small, the minimum "+
"channel size is: %v SAT", int64(minChanFundingSize))
"channel size is: %v SAT", int64(funding.MinChanFundingSize))
}
// Prevent users from submitting a max-htlc value that would exceed the
@ -1891,20 +1892,20 @@ func (r *rpcServer) parseOpenChannelReq(in *lnrpc.OpenChannelRequest,
// Instruct the server to trigger the necessary events to attempt to
// open a new channel. A stream is returned in place, this stream will
// be used to consume updates of the state of the pending channel.
return &openChanReq{
targetPubkey: nodePubKey,
chainHash: *r.cfg.ActiveNetParams.GenesisHash,
localFundingAmt: localFundingAmt,
pushAmt: lnwire.NewMSatFromSatoshis(remoteInitialBalance),
minHtlcIn: minHtlcIn,
fundingFeePerKw: feeRate,
private: in.Private,
remoteCsvDelay: remoteCsvDelay,
minConfs: minConfs,
shutdownScript: script,
maxValueInFlight: maxValue,
maxHtlcs: maxHtlcs,
maxLocalCsv: uint16(in.MaxLocalCsv),
return &funding.InitFundingMsg{
TargetPubkey: nodePubKey,
ChainHash: *r.cfg.ActiveNetParams.GenesisHash,
LocalFundingAmt: localFundingAmt,
PushAmt: lnwire.NewMSatFromSatoshis(remoteInitialBalance),
MinHtlcIn: minHtlcIn,
FundingFeePerKw: feeRate,
Private: in.Private,
RemoteCsvDelay: remoteCsvDelay,
MinConfs: minConfs,
ShutdownScript: script,
MaxValueInFlight: maxValue,
MaxHtlcs: maxHtlcs,
MaxLocalCsv: uint16(in.MaxLocalCsv),
}, nil
}
@ -1935,8 +1936,8 @@ func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest,
// Map the channel point shim into a new
// chanfunding.CannedAssembler that the wallet will use
// to obtain the channel point details.
copy(req.pendingChanID[:], chanPointShim.PendingChanId)
req.chanFunder, err = newFundingShimAssembler(
copy(req.PendingChanID[:], chanPointShim.PendingChanId)
req.ChanFunder, err = newFundingShimAssembler(
chanPointShim, true, r.server.cc.KeyRing,
)
if err != nil {
@ -1953,9 +1954,9 @@ func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest,
// Instruct the wallet to use the new
// chanfunding.PsbtAssembler to construct the funding
// transaction.
copy(req.pendingChanID[:], psbtShim.PendingChanId)
req.chanFunder, err = newPsbtAssembler(
in, req.minConfs, psbtShim,
copy(req.PendingChanID[:], psbtShim.PendingChanId)
req.ChanFunder, err = newPsbtAssembler(
in, req.MinConfs, psbtShim,
&r.server.cc.Wallet.Cfg.NetParams,
)
if err != nil {
@ -1972,7 +1973,7 @@ out:
select {
case err := <-errChan:
rpcsLog.Errorf("unable to open channel to NodeKey(%x): %v",
req.targetPubkey.SerializeCompressed(), err)
req.TargetPubkey.SerializeCompressed(), err)
return err
case fundingUpdate := <-updateChan:
rpcsLog.Tracef("[openchannel] sending update: %v",
@ -2004,7 +2005,7 @@ out:
}
rpcsLog.Tracef("[openchannel] success NodeKey(%x), ChannelPoint(%v)",
req.targetPubkey.SerializeCompressed(), outpoint)
req.TargetPubkey.SerializeCompressed(), outpoint)
return nil
}
@ -2029,7 +2030,7 @@ func (r *rpcServer) OpenChannelSync(ctx context.Context,
// If an error occurs them immediately return the error to the client.
case err := <-errChan:
rpcsLog.Errorf("unable to open channel to NodeKey(%x): %v",
req.targetPubkey.SerializeCompressed(), err)
req.TargetPubkey.SerializeCompressed(), err)
return nil, err
// Otherwise, wait for the first channel update. The first update sent

115
server.go

@ -39,6 +39,7 @@ import (
"github.com/lightningnetwork/lnd/contractcourt"
"github.com/lightningnetwork/lnd/discovery"
"github.com/lightningnetwork/lnd/feature"
"github.com/lightningnetwork/lnd/funding"
"github.com/lightningnetwork/lnd/healthcheck"
"github.com/lightningnetwork/lnd/htlcswitch"
"github.com/lightningnetwork/lnd/htlcswitch/hop"
@ -51,7 +52,6 @@ import (
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
"github.com/lightningnetwork/lnd/lnwallet/chanfunding"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/nat"
"github.com/lightningnetwork/lnd/netann"
@ -114,6 +114,17 @@ var (
// validColorRegexp is a regexp that lets you check if a particular
// color string matches the standard hex color format #RRGGBB.
validColorRegexp = regexp.MustCompile("^#[A-Fa-f0-9]{6}$")
// MaxFundingAmount is a soft-limit of the maximum channel size
// currently accepted within the Lightning Protocol. This is
// defined in BOLT-0002, and serves as an initial precautionary limit
// while implementations are battle tested in the real world.
//
// At the moment, this value depends on which chain is active. It is set
// to the value under the Bitcoin chain as default.
//
// TODO(roasbeef): add command line param to modify
MaxFundingAmount = funding.MaxBtcFundingAmount
)
// errPeerAlreadyConnected is an error returned by the server when we're
@ -207,7 +218,7 @@ type server struct {
cc *chainreg.ChainControl
fundingMgr *fundingManager
fundingMgr *funding.Manager
localChanDB *channeldb.DB
@ -977,12 +988,12 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
// Litecoin, depending on the primary registered chain.
primaryChain := cfg.registeredChains.PrimaryChain()
chainCfg := cfg.Bitcoin
minRemoteDelay := minBtcRemoteDelay
maxRemoteDelay := maxBtcRemoteDelay
minRemoteDelay := funding.MinBtcRemoteDelay
maxRemoteDelay := funding.MaxBtcRemoteDelay
if primaryChain == chainreg.LitecoinChain {
chainCfg = cfg.Litecoin
minRemoteDelay = minLtcRemoteDelay
maxRemoteDelay = maxLtcRemoteDelay
minRemoteDelay = funding.MinLtcRemoteDelay
maxRemoteDelay = funding.MaxLtcRemoteDelay
}
var chanIDSeed [32]byte
@ -990,7 +1001,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
return nil, err
}
s.fundingMgr, err = newFundingManager(fundingConfig{
s.fundingMgr, err = funding.NewFundingManager(funding.Config{
NoWumboChans: !cfg.ProtocolOptions.Wumbo(),
IDKey: nodeKeyECDH.PubKey(),
Wallet: cc.Wallet,
@ -3472,63 +3483,6 @@ func (s *server) removePeer(p *peer.Brontide) {
s.peerNotifier.NotifyPeerOffline(pubKey)
}
// openChanReq is a message sent to the server in order to request the
// initiation of a channel funding workflow to the peer with either the
// specified relative peer ID, or a global lightning ID.
type openChanReq struct {
targetPubkey *btcec.PublicKey
chainHash chainhash.Hash
subtractFees bool
localFundingAmt btcutil.Amount
pushAmt lnwire.MilliSatoshi
fundingFeePerKw chainfee.SatPerKWeight
private bool
// minHtlcIn is the minimum incoming htlc that we accept.
minHtlcIn lnwire.MilliSatoshi
remoteCsvDelay uint16
// minConfs indicates the minimum number of confirmations that each
// output selected to fund the channel should satisfy.
minConfs int32
// shutdownScript is an optional upfront shutdown script for the channel.
// This value is optional, so may be nil.
shutdownScript lnwire.DeliveryAddress
// maxValueInFlight is the maximum amount of coins in millisatoshi that can
// be pending within the channel. It only applies to the remote party.
maxValueInFlight lnwire.MilliSatoshi
maxHtlcs uint16
// maxLocalCsv is the maximum local csv delay we will accept from our
// peer.
maxLocalCsv uint16
// TODO(roasbeef): add ability to specify channel constraints as well
// chanFunder is an optional channel funder that allows the caller to
// control exactly how the channel funding is carried out. If not
// specified, then the default chanfunding.WalletAssembler will be
// used.
chanFunder chanfunding.Assembler
// pendingChanID is not all zeroes (the default value), then this will
// be the pending channel ID used for the funding flow within the wire
// protocol.
pendingChanID [32]byte
updates chan *lnrpc.OpenStatusUpdate
err chan error
}
// ConnectToPeer requests that the server connect to a Lightning Network peer
// at the specified address. This function will *block* until either a
// connection is established, or the initial handshake process fails.
@ -3673,25 +3627,26 @@ func (s *server) DisconnectPeer(pubKey *btcec.PublicKey) error {
//
// NOTE: This function is safe for concurrent access.
func (s *server) OpenChannel(
req *openChanReq) (chan *lnrpc.OpenStatusUpdate, chan error) {
req *funding.InitFundingMsg) (chan *lnrpc.OpenStatusUpdate, chan error) {
// The updateChan will have a buffer of 2, since we expect a ChanPending
// + a ChanOpen update, and we want to make sure the funding process is
// not blocked if the caller is not reading the updates.
req.updates = make(chan *lnrpc.OpenStatusUpdate, 2)
req.err = make(chan error, 1)
req.Updates = make(chan *lnrpc.OpenStatusUpdate, 2)
req.Err = make(chan error, 1)
// First attempt to locate the target peer to open a channel with, if
// we're unable to locate the peer then this request will fail.
pubKeyBytes := req.targetPubkey.SerializeCompressed()
pubKeyBytes := req.TargetPubkey.SerializeCompressed()
s.mu.RLock()
peer, ok := s.peersByPub[string(pubKeyBytes)]
if !ok {
s.mu.RUnlock()
req.err <- fmt.Errorf("peer %x is not online", pubKeyBytes)
return req.updates, req.err
req.Err <- fmt.Errorf("peer %x is not online", pubKeyBytes)
return req.Updates, req.Err
}
req.Peer = peer
s.mu.RUnlock()
// We'll wait until the peer is active before beginning the channel
@ -3699,32 +3654,32 @@ func (s *server) OpenChannel(
select {
case <-peer.ActiveSignal():
case <-peer.QuitSignal():
req.err <- fmt.Errorf("peer %x disconnected", pubKeyBytes)
return req.updates, req.err
req.Err <- fmt.Errorf("peer %x disconnected", pubKeyBytes)
return req.Updates, req.Err
case <-s.quit:
req.err <- ErrServerShuttingDown
return req.updates, req.err
req.Err <- ErrServerShuttingDown
return req.Updates, req.Err
}
// If the fee rate wasn't specified, then we'll use a default
// confirmation target.
if req.fundingFeePerKw == 0 {
if req.FundingFeePerKw == 0 {
estimator := s.cc.FeeEstimator
feeRate, err := estimator.EstimateFeePerKW(6)
if err != nil {
req.err <- err
return req.updates, req.err
req.Err <- err
return req.Updates, req.Err
}
req.fundingFeePerKw = feeRate
req.FundingFeePerKw = feeRate
}
// Spawn a goroutine to send the funding workflow request to the funding
// manager. This allows the server to continue handling queries instead
// of blocking on this request which is exported as a synchronous
// request to the outside world.
go s.fundingMgr.initFundingWorkflow(peer, req)
go s.fundingMgr.InitFundingWorkflow(req)
return req.updates, req.err
return req.Updates, req.Err
}
// Peers returns a slice of all active peers.