multi: fix a variety of typos throughout the repo
This commit is contained in:
parent
49df1b0737
commit
40c7bac3aa
@ -12,7 +12,7 @@
|
|||||||
(https://godoc.org/github.com/lightningnetwork/lnd)
|
(https://godoc.org/github.com/lightningnetwork/lnd)
|
||||||
|
|
||||||
The Lightning Network Daemon (`lnd`) - is a complete implementation of a
|
The Lightning Network Daemon (`lnd`) - is a complete implementation of a
|
||||||
[Lightning Network](http://lightning.network) node and currently
|
[Lightning Network](https://lightning.network) node and currently
|
||||||
deployed on `testnet4` - the Bitcoin Test Network. It utilizes an
|
deployed on `testnet4` - the Bitcoin Test Network. It utilizes an
|
||||||
upcoming upgrade to Bitcoin: Segregated Witness (`segwit`). The
|
upcoming upgrade to Bitcoin: Segregated Witness (`segwit`). The
|
||||||
project's codebase uses the [btcsuite](https://github.com/btcsuite/) set
|
project's codebase uses the [btcsuite](https://github.com/btcsuite/) set
|
||||||
@ -56,7 +56,7 @@ said, `lnd` the current status of `lnd`'s BOLT compliance is:
|
|||||||
- [X] BOLT 8: Encrypted and Authenticated Transport
|
- [X] BOLT 8: Encrypted and Authenticated Transport
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
In order to build form source, the following build dependencies are
|
In order to build from source, the following build dependencies are
|
||||||
required:
|
required:
|
||||||
|
|
||||||
* **Go:** Installation instructions can be found [here](http://golang.org/doc/install).
|
* **Go:** Installation instructions can be found [here](http://golang.org/doc/install).
|
||||||
|
@ -14,14 +14,14 @@ import (
|
|||||||
"github.com/roasbeef/btcutil"
|
"github.com/roasbeef/btcutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// breachArbiter is a special sub-system which is responsible for watching and
|
// breachArbiter is a special subsystem which is responsible for watching and
|
||||||
// acting on the detection of any attempted uncooperative channel breaches by
|
// acting on the detection of any attempted uncooperative channel breaches by
|
||||||
// channel counter-parties. This file essentially acts as deterrence code for
|
// channel counterparties. This file essentially acts as deterrence code for
|
||||||
// those attempting to launch attacks against the daemon. In practice it's
|
// those attempting to launch attacks against the daemon. In practice it's
|
||||||
// expected that the logic in this file never gets executed, but it is
|
// expected that the logic in this file never gets executed, but it is
|
||||||
// important to have it in place just in case we encounter cheating channel
|
// important to have it in place just in case we encounter cheating channel
|
||||||
// counter-parties.
|
// counterparties.
|
||||||
// TODO(roasbeef): closures in config for sub-system pointers to decouple?
|
// TODO(roasbeef): closures in config for subsystem pointers to decouple?
|
||||||
type breachArbiter struct {
|
type breachArbiter struct {
|
||||||
wallet *lnwallet.LightningWallet
|
wallet *lnwallet.LightningWallet
|
||||||
db *channeldb.DB
|
db *channeldb.DB
|
||||||
@ -32,22 +32,22 @@ type breachArbiter struct {
|
|||||||
// observers we're currently managing. The key of the map is the
|
// observers we're currently managing. The key of the map is the
|
||||||
// funding outpoint of the channel, and the value is a channel which
|
// funding outpoint of the channel, and the value is a channel which
|
||||||
// will be closed once we detect that the channel has been
|
// will be closed once we detect that the channel has been
|
||||||
// cooperatively closed, there by killing the goroutine and freeing up
|
// cooperatively closed, thereby killing the goroutine and freeing up
|
||||||
// resource.
|
// resources.
|
||||||
breachObservers map[wire.OutPoint]chan struct{}
|
breachObservers map[wire.OutPoint]chan struct{}
|
||||||
|
|
||||||
// breachedContracts is a channel which is used internally within the
|
// breachedContracts is a channel which is used internally within the
|
||||||
// struct to send the necessary information required to punish a
|
// struct to send the necessary information required to punish a
|
||||||
// counter-party once a channel breach is detected. Breach observers
|
// counterparty once a channel breach is detected. Breach observers
|
||||||
// use this to communicate with the main contractObserver goroutine.
|
// use this to communicate with the main contractObserver goroutine.
|
||||||
breachedContracts chan *retributionInfo
|
breachedContracts chan *retributionInfo
|
||||||
|
|
||||||
// newContracts is a channel which is used by outside sub-systems to
|
// newContracts is a channel which is used by outside subsystems to
|
||||||
// notify the breachArbiter of a new contract (a channel) that should
|
// notify the breachArbiter of a new contract (a channel) that should
|
||||||
// be watched.
|
// be watched.
|
||||||
newContracts chan *lnwallet.LightningChannel
|
newContracts chan *lnwallet.LightningChannel
|
||||||
|
|
||||||
// settledContracts is a channel by outside sub-subsystems to notify
|
// settledContracts is a channel by outside subsystems to notify
|
||||||
// the breachArbiter that a channel has peacefully been closed. Once a
|
// the breachArbiter that a channel has peacefully been closed. Once a
|
||||||
// channel has been closed the arbiter no longer needs to watch for
|
// channel has been closed the arbiter no longer needs to watch for
|
||||||
// breach closes.
|
// breach closes.
|
||||||
@ -59,8 +59,8 @@ type breachArbiter struct {
|
|||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
// newBreachArbiter creates a new instance of a breachArbiter initialize with
|
// newBreachArbiter creates a new instance of a breachArbiter initialized with
|
||||||
// its dependant objects.
|
// its dependent objects.
|
||||||
func newBreachArbiter(wallet *lnwallet.LightningWallet, db *channeldb.DB,
|
func newBreachArbiter(wallet *lnwallet.LightningWallet, db *channeldb.DB,
|
||||||
notifier chainntnfs.ChainNotifier, h *htlcSwitch) *breachArbiter {
|
notifier chainntnfs.ChainNotifier, h *htlcSwitch) *breachArbiter {
|
||||||
|
|
||||||
@ -250,7 +250,7 @@ out:
|
|||||||
|
|
||||||
// exactRetribution is a goroutine which is executed once a contract breach has
|
// exactRetribution is a goroutine which is executed once a contract breach has
|
||||||
// been detected by a breachObserver. This function is responsible for
|
// been detected by a breachObserver. This function is responsible for
|
||||||
// punishing a counter-party for violating the channel contract by sweeping ALL
|
// punishing a counterparty for violating the channel contract by sweeping ALL
|
||||||
// the lingering funds within the channel into the daemon's wallet.
|
// the lingering funds within the channel into the daemon's wallet.
|
||||||
//
|
//
|
||||||
// NOTE: This MUST be run as a goroutine.
|
// NOTE: This MUST be run as a goroutine.
|
||||||
@ -259,7 +259,7 @@ func (b *breachArbiter) exactRetribution(confChan *chainntnfs.ConfirmationEvent,
|
|||||||
|
|
||||||
defer b.wg.Done()
|
defer b.wg.Done()
|
||||||
|
|
||||||
// TODO(roasbeef): state needs to be check-pointed here
|
// TODO(roasbeef): state needs to be checkpointed here
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case _, ok := <-confChan.Confirmed:
|
case _, ok := <-confChan.Confirmed:
|
||||||
@ -270,7 +270,7 @@ func (b *breachArbiter) exactRetribution(confChan *chainntnfs.ConfirmationEvent,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, if this is a real confirmation notification, then
|
// Otherwise, if this is a real confirmation notification, then
|
||||||
// we fall through to complete out duty.
|
// we fall through to complete our duty.
|
||||||
case <-b.quit:
|
case <-b.quit:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -291,7 +291,7 @@ func (b *breachArbiter) exactRetribution(confChan *chainntnfs.ConfirmationEvent,
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
// Finally, broadcast the transaction, finalizing the channels'
|
// Finally, broadcast the transaction, finalizing the channels'
|
||||||
// retribution against the cheating counter-party.
|
// retribution against the cheating counterparty.
|
||||||
if err := b.wallet.PublishTransaction(justiceTx); err != nil {
|
if err := b.wallet.PublishTransaction(justiceTx); err != nil {
|
||||||
brarLog.Errorf("unable to broadcast "+
|
brarLog.Errorf("unable to broadcast "+
|
||||||
"justice tx: %v", err)
|
"justice tx: %v", err)
|
||||||
@ -300,7 +300,7 @@ func (b *breachArbiter) exactRetribution(confChan *chainntnfs.ConfirmationEvent,
|
|||||||
|
|
||||||
// As a conclusionary step, we register for a notification to be
|
// As a conclusionary step, we register for a notification to be
|
||||||
// dispatched once the justice tx is confirmed. After confirmation we
|
// dispatched once the justice tx is confirmed. After confirmation we
|
||||||
// notify the caller that initiated the retribution work low that the
|
// notify the caller that initiated the retribution workflow that the
|
||||||
// deed has been done.
|
// deed has been done.
|
||||||
justiceTXID := justiceTx.TxHash()
|
justiceTXID := justiceTx.TxHash()
|
||||||
confChan, err = b.notifier.RegisterConfirmationsNtfn(&justiceTXID, 1)
|
confChan, err = b.notifier.RegisterConfirmationsNtfn(&justiceTXID, 1)
|
||||||
@ -316,7 +316,7 @@ func (b *breachArbiter) exactRetribution(confChan *chainntnfs.ConfirmationEvent,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(roasbeef): factor in HTLC's
|
// TODO(roasbeef): factor in HTLCs
|
||||||
revokedFunds := breachInfo.revokedOutput.amt
|
revokedFunds := breachInfo.revokedOutput.amt
|
||||||
totalFunds := revokedFunds + breachInfo.selfOutput.amt
|
totalFunds := revokedFunds + breachInfo.selfOutput.amt
|
||||||
|
|
||||||
@ -338,7 +338,7 @@ func (b *breachArbiter) exactRetribution(confChan *chainntnfs.ConfirmationEvent,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// breachObserver notifies the breachArbiter contract observer goroutine that a
|
// breachObserver notifies the breachArbiter contract observer goroutine that a
|
||||||
// channel's contract has been breached by the prior counter party. Once
|
// channel's contract has been breached by the prior counterparty. Once
|
||||||
// notified the breachArbiter will attempt to sweep ALL funds within the
|
// notified the breachArbiter will attempt to sweep ALL funds within the
|
||||||
// channel using the information provided within the BreachRetribution
|
// channel using the information provided within the BreachRetribution
|
||||||
// generated due to the breach of channel contract. The funds will be swept
|
// generated due to the breach of channel contract. The funds will be swept
|
||||||
@ -361,7 +361,7 @@ func (b *breachArbiter) breachObserver(contract *lnwallet.LightningChannel,
|
|||||||
|
|
||||||
// A read from this channel indicates that a channel breach has been
|
// A read from this channel indicates that a channel breach has been
|
||||||
// detected! So we notify the main coordination goroutine with the
|
// detected! So we notify the main coordination goroutine with the
|
||||||
// information needed to bring the counter-party to justice.
|
// information needed to bring the counterparty to justice.
|
||||||
case breachInfo := <-contract.ContractBreach:
|
case breachInfo := <-contract.ContractBreach:
|
||||||
brarLog.Warnf("REVOKED STATE #%v FOR ChannelPoint(%v) "+
|
brarLog.Warnf("REVOKED STATE #%v FOR ChannelPoint(%v) "+
|
||||||
"broadcast, REMOTE PEER IS DOING SOMETHING "+
|
"broadcast, REMOTE PEER IS DOING SOMETHING "+
|
||||||
@ -370,7 +370,7 @@ func (b *breachArbiter) breachObserver(contract *lnwallet.LightningChannel,
|
|||||||
|
|
||||||
// Immediately notify the HTLC switch that this link has been
|
// Immediately notify the HTLC switch that this link has been
|
||||||
// breached in order to ensure any incoming or outgoing
|
// breached in order to ensure any incoming or outgoing
|
||||||
// multi-hop HTLC's aren't sent over this link, nor any other
|
// multi-hop HTLCs aren't sent over this link, nor any other
|
||||||
// links associated with this peer.
|
// links associated with this peer.
|
||||||
b.htlcSwitch.CloseLink(chanPoint, CloseBreach)
|
b.htlcSwitch.CloseLink(chanPoint, CloseBreach)
|
||||||
if err := contract.DeleteState(); err != nil {
|
if err := contract.DeleteState(); err != nil {
|
||||||
@ -396,7 +396,7 @@ func (b *breachArbiter) breachObserver(contract *lnwallet.LightningChannel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Next we create the witness generation function that will be
|
// Next we create the witness generation function that will be
|
||||||
// used to sweep the cheating counter party's output by taking
|
// used to sweep the cheating counterparty's output by taking
|
||||||
// advantage of the revocation clause within the output's
|
// advantage of the revocation clause within the output's
|
||||||
// witness script.
|
// witness script.
|
||||||
remoteSignDesc := breachInfo.RemoteOutputSignDesc
|
remoteSignDesc := breachInfo.RemoteOutputSignDesc
|
||||||
@ -438,7 +438,7 @@ func (b *breachArbiter) breachObserver(contract *lnwallet.LightningChannel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// breachedOutput contains all the information needed to sweep a breached
|
// breachedOutput contains all the information needed to sweep a breached
|
||||||
// output. A breach output is an output that were now entitled to due to a
|
// output. A breached output is an output that we are now entitled to due to a
|
||||||
// revoked commitment transaction being broadcast.
|
// revoked commitment transaction being broadcast.
|
||||||
type breachedOutput struct {
|
type breachedOutput struct {
|
||||||
amt btcutil.Amount
|
amt btcutil.Amount
|
||||||
@ -450,7 +450,7 @@ type breachedOutput struct {
|
|||||||
|
|
||||||
// retributionInfo encapsulates all the data needed to sweep all the contested
|
// retributionInfo encapsulates all the data needed to sweep all the contested
|
||||||
// funds within a channel whose contract has been breached by the prior
|
// funds within a channel whose contract has been breached by the prior
|
||||||
// counter-party. This struct is used by the utxoNursery to create the justice
|
// counterparty. This struct is used by the utxoNursery to create the justice
|
||||||
// transaction which spends all outputs of the commitment transaction into an
|
// transaction which spends all outputs of the commitment transaction into an
|
||||||
// output controlled by the wallet.
|
// output controlled by the wallet.
|
||||||
type retributionInfo struct {
|
type retributionInfo struct {
|
||||||
@ -468,7 +468,7 @@ type retributionInfo struct {
|
|||||||
|
|
||||||
// createJusticeTx creates a transaction which exacts "justice" by sweeping ALL
|
// createJusticeTx creates a transaction which exacts "justice" by sweeping ALL
|
||||||
// the funds within the channel which we are now entitled to due to a breach of
|
// the funds within the channel which we are now entitled to due to a breach of
|
||||||
// the channel's contract by the counter-party. This function returns a *fully*
|
// the channel's contract by the counterparty. This function returns a *fully*
|
||||||
// signed transaction with the witness for each input fully in place.
|
// signed transaction with the witness for each input fully in place.
|
||||||
func (b *breachArbiter) createJusticeTx(r *retributionInfo) (*wire.MsgTx, error) {
|
func (b *breachArbiter) createJusticeTx(r *retributionInfo) (*wire.MsgTx, error) {
|
||||||
// First, we obtain a new public key script from the wallet which we'll
|
// First, we obtain a new public key script from the wallet which we'll
|
||||||
@ -480,13 +480,13 @@ func (b *breachArbiter) createJusticeTx(r *retributionInfo) (*wire.MsgTx, error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Before creating the actual TxOut, we'll need to calculate proper fee
|
// Before creating the actual TxOut, we'll need to calculate the proper fee
|
||||||
// to attach to the transaction to ensure a timely confirmation.
|
// to attach to the transaction to ensure a timely confirmation.
|
||||||
// TODO(roasbeef): remove hard-coded fee
|
// TODO(roasbeef): remove hard-coded fee
|
||||||
totalAmt := r.selfOutput.amt + r.revokedOutput.amt
|
totalAmt := r.selfOutput.amt + r.revokedOutput.amt
|
||||||
sweepedAmt := int64(totalAmt - 5000)
|
sweepedAmt := int64(totalAmt - 5000)
|
||||||
|
|
||||||
// With the fee calculate, we can now create the justice transaction
|
// With the fee calculated, we can now create the justice transaction
|
||||||
// using the information gathered above.
|
// using the information gathered above.
|
||||||
justiceTx := wire.NewMsgTx(2)
|
justiceTx := wire.NewMsgTx(2)
|
||||||
justiceTx.AddTxOut(&wire.TxOut{
|
justiceTx.AddTxOut(&wire.TxOut{
|
||||||
@ -504,9 +504,9 @@ func (b *breachArbiter) createJusticeTx(r *retributionInfo) (*wire.MsgTx, error)
|
|||||||
|
|
||||||
// Finally, using the witness generation functions attached to the
|
// Finally, using the witness generation functions attached to the
|
||||||
// retribution information, we'll populate the inputs with fully valid
|
// retribution information, we'll populate the inputs with fully valid
|
||||||
// witnesses for both commitment outputs, and all the pending HTLC's at
|
// witnesses for both commitment outputs, and all the pending HTLCs at
|
||||||
// this state in the channel's history.
|
// this state in the channel's history.
|
||||||
// TODO(roasbeef): handle the 2-layer HTLC's
|
// TODO(roasbeef): handle the 2-layer HTLCs
|
||||||
localWitness, err := r.selfOutput.witnessFunc(justiceTx, hashCache, 0)
|
localWitness, err := r.selfOutput.witnessFunc(justiceTx, hashCache, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -119,7 +119,7 @@ type SpendEvent struct {
|
|||||||
Spend chan *SpendDetail // MUST be buffered.
|
Spend chan *SpendDetail // MUST be buffered.
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlockEpoch represents meta-data concerning each new block connected to the
|
// BlockEpoch represents metadata concerning each new block connected to the
|
||||||
// main chain.
|
// main chain.
|
||||||
type BlockEpoch struct {
|
type BlockEpoch struct {
|
||||||
Height int32
|
Height int32
|
||||||
|
@ -20,7 +20,7 @@ var (
|
|||||||
// openChanBucket stores all the currently open channels. This bucket
|
// openChanBucket stores all the currently open channels. This bucket
|
||||||
// has a second, nested bucket which is keyed by a node's ID. Additionally,
|
// has a second, nested bucket which is keyed by a node's ID. Additionally,
|
||||||
// at the base level of this bucket several prefixed keys are stored which
|
// at the base level of this bucket several prefixed keys are stored which
|
||||||
// house channel meta-data such as total satoshis sent, number of updates
|
// house channel metadata such as total satoshis sent, number of updates
|
||||||
// etc. These fields are stored at this top level rather than within a
|
// etc. These fields are stored at this top level rather than within a
|
||||||
// node's channel bucket in order to facilitate sequential prefix scans
|
// node's channel bucket in order to facilitate sequential prefix scans
|
||||||
// to gather stats such as total satoshis received.
|
// to gather stats such as total satoshis received.
|
||||||
@ -41,7 +41,7 @@ var (
|
|||||||
|
|
||||||
// channelLogBucket is dedicated for storing the necessary delta state
|
// channelLogBucket is dedicated for storing the necessary delta state
|
||||||
// between channel updates required to re-construct a past state in
|
// between channel updates required to re-construct a past state in
|
||||||
// order to punish a counter party attempting a non-cooperative channel
|
// order to punish a counterparty attempting a non-cooperative channel
|
||||||
// closure. A channel log bucket is created for each node and is nested
|
// closure. A channel log bucket is created for each node and is nested
|
||||||
// within a node's ID bucket.
|
// within a node's ID bucket.
|
||||||
channelLogBucket = []byte("clb")
|
channelLogBucket = []byte("clb")
|
||||||
@ -81,7 +81,7 @@ var (
|
|||||||
// commitment transactions in addition to the csvDelay for both.
|
// commitment transactions in addition to the csvDelay for both.
|
||||||
commitTxnsKey = []byte("ctk")
|
commitTxnsKey = []byte("ctk")
|
||||||
|
|
||||||
// currentHtlcKey stores the set of fully locked-in HTLC's on our
|
// currentHtlcKey stores the set of fully locked-in HTLCs on our
|
||||||
// latest commitment state.
|
// latest commitment state.
|
||||||
currentHtlcKey = []byte("chk")
|
currentHtlcKey = []byte("chk")
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ var (
|
|||||||
fundingTxnKey = []byte("fsk")
|
fundingTxnKey = []byte("fsk")
|
||||||
|
|
||||||
// elkremStateKey stores their current revocation hash, and our elkrem
|
// elkremStateKey stores their current revocation hash, and our elkrem
|
||||||
// sender, and their elkrem reciever.
|
// sender, and their elkrem receiver.
|
||||||
elkremStateKey = []byte("esk")
|
elkremStateKey = []byte("esk")
|
||||||
|
|
||||||
// deliveryScriptsKey stores the scripts for the final delivery in the
|
// deliveryScriptsKey stores the scripts for the final delivery in the
|
||||||
@ -101,7 +101,7 @@ var (
|
|||||||
// ChannelType is an enum-like type that describes one of several possible
|
// ChannelType is an enum-like type that describes one of several possible
|
||||||
// channel types. Each open channel is associated with a particular type as the
|
// channel types. Each open channel is associated with a particular type as the
|
||||||
// channel type may determine how higher level operations are conducted such as
|
// channel type may determine how higher level operations are conducted such as
|
||||||
// fee negotiation, channel closing, the format of HTLC's, etc.
|
// fee negotiation, channel closing, the format of HTLCs, etc.
|
||||||
// TODO(roasbeef): split up per-chain?
|
// TODO(roasbeef): split up per-chain?
|
||||||
type ChannelType uint8
|
type ChannelType uint8
|
||||||
|
|
||||||
@ -221,7 +221,7 @@ type OpenChannel struct {
|
|||||||
RemoteCsvDelay uint32
|
RemoteCsvDelay uint32
|
||||||
|
|
||||||
// Current revocation for their commitment transaction. However, since
|
// Current revocation for their commitment transaction. However, since
|
||||||
// this the derived public key, we don't yet have the pre-image so we
|
// this the derived public key, we don't yet have the preimage so we
|
||||||
// aren't yet able to verify that it's actually in the hash chain.
|
// aren't yet able to verify that it's actually in the hash chain.
|
||||||
TheirCurrentRevocation *btcec.PublicKey
|
TheirCurrentRevocation *btcec.PublicKey
|
||||||
TheirCurrentRevocationHash [32]byte
|
TheirCurrentRevocationHash [32]byte
|
||||||
@ -251,7 +251,7 @@ type OpenChannel struct {
|
|||||||
// CreationTime is the time this channel was initially created.
|
// CreationTime is the time this channel was initially created.
|
||||||
CreationTime time.Time
|
CreationTime time.Time
|
||||||
|
|
||||||
// Htlcs is the list of active, uncleared HTLC's currently pending
|
// Htlcs is the list of active, uncleared HTLCs currently pending
|
||||||
// within the channel.
|
// within the channel.
|
||||||
Htlcs []*HTLC
|
Htlcs []*HTLC
|
||||||
|
|
||||||
@ -342,7 +342,7 @@ func (c *OpenChannel) FullSyncWithAddr(addr *net.TCPAddr) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Next, we need to establish a (possibly) new LinkNode
|
// Next, we need to establish a (possibly) new LinkNode
|
||||||
// relationship for this channel. The LinkNode meta-data contains
|
// relationship for this channel. The LinkNode metadata contains
|
||||||
// reachability, up-time, and service bits related information.
|
// reachability, up-time, and service bits related information.
|
||||||
// TODO(roasbeef): net info shuld be in lnwire.NetAddress
|
// TODO(roasbeef): net info shuld be in lnwire.NetAddress
|
||||||
linkNode := c.Db.NewLinkNode(wire.MainNet, c.IdentityPub, addr)
|
linkNode := c.Db.NewLinkNode(wire.MainNet, c.IdentityPub, addr)
|
||||||
@ -407,7 +407,7 @@ func (c *OpenChannel) UpdateCommitment(newCommitment *wire.MsgTx,
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTLC is the on-disk representation of a hash time-locked contract. HTLC's
|
// HTLC is the on-disk representation of a hash time-locked contract. HTLCs
|
||||||
// are contained within ChannelDeltas which encode the current state of the
|
// are contained within ChannelDeltas which encode the current state of the
|
||||||
// commitment between state updates.
|
// commitment between state updates.
|
||||||
type HTLC struct {
|
type HTLC struct {
|
||||||
@ -451,7 +451,7 @@ func (h *HTLC) Copy() HTLC {
|
|||||||
|
|
||||||
// ChannelDelta is a snapshot of the commitment state at a particular point in
|
// ChannelDelta is a snapshot of the commitment state at a particular point in
|
||||||
// the commitment chain. With each state transition, a snapshot of the current
|
// the commitment chain. With each state transition, a snapshot of the current
|
||||||
// state along with all non-settled HTLC's are recorded.
|
// state along with all non-settled HTLCs are recorded.
|
||||||
type ChannelDelta struct {
|
type ChannelDelta struct {
|
||||||
LocalBalance btcutil.Amount
|
LocalBalance btcutil.Amount
|
||||||
RemoteBalance btcutil.Amount
|
RemoteBalance btcutil.Amount
|
||||||
@ -514,7 +514,7 @@ func (c *OpenChannel) CommitmentHeight() (uint64, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
err := c.Db.View(func(tx *bolt.Tx) error {
|
err := c.Db.View(func(tx *bolt.Tx) error {
|
||||||
// Get the bucket dedicated to storing the meta-data for open
|
// Get the bucket dedicated to storing the metadata for open
|
||||||
// channels.
|
// channels.
|
||||||
openChanBucket := tx.Bucket(openChannelBucket)
|
openChanBucket := tx.Bucket(openChannelBucket)
|
||||||
if openChanBucket == nil {
|
if openChanBucket == nil {
|
||||||
@ -569,7 +569,7 @@ func (c *OpenChannel) FindPreviousState(updateNum uint64) (*ChannelDelta, error)
|
|||||||
// entails deleting all saved state within the database concerning this
|
// entails deleting all saved state within the database concerning this
|
||||||
// channel, as well as created a small channel summary for record keeping
|
// channel, as well as created a small channel summary for record keeping
|
||||||
// purposes.
|
// purposes.
|
||||||
// TODO(roasbeef): delete on-disk set of HTLC's
|
// TODO(roasbeef): delete on-disk set of HTLCs
|
||||||
func (c *OpenChannel) CloseChannel() error {
|
func (c *OpenChannel) CloseChannel() error {
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
if err := writeOutpoint(&b, c.ChanID); err != nil {
|
if err := writeOutpoint(&b, c.ChanID); err != nil {
|
||||||
@ -614,7 +614,7 @@ func (c *OpenChannel) CloseChannel() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now that the index to this channel has been deleted, purge
|
// Now that the index to this channel has been deleted, purge
|
||||||
// the remaining channel meta-data from the database.
|
// the remaining channel metadata from the database.
|
||||||
if err := deleteOpenChannel(chanBucket, nodeChanBucket,
|
if err := deleteOpenChannel(chanBucket, nodeChanBucket,
|
||||||
outPointBytes); err != nil {
|
outPointBytes); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -648,7 +648,7 @@ type ChannelSnapshot struct {
|
|||||||
|
|
||||||
// Snapshot returns a read-only snapshot of the current channel state. This
|
// Snapshot returns a read-only snapshot of the current channel state. This
|
||||||
// snapshot includes information concerning the current settled balance within
|
// snapshot includes information concerning the current settled balance within
|
||||||
// the channel, meta-data detailing total flows, and any outstanding HTLCs.
|
// the channel, metadata detailing total flows, and any outstanding HTLCs.
|
||||||
func (c *OpenChannel) Snapshot() *ChannelSnapshot {
|
func (c *OpenChannel) Snapshot() *ChannelSnapshot {
|
||||||
c.RLock()
|
c.RLock()
|
||||||
defer c.RUnlock()
|
defer c.RUnlock()
|
||||||
@ -664,7 +664,7 @@ func (c *OpenChannel) Snapshot() *ChannelSnapshot {
|
|||||||
TotalSatoshisReceived: c.TotalSatoshisReceived,
|
TotalSatoshisReceived: c.TotalSatoshisReceived,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy over the current set of HTLC's to ensure the caller can't
|
// Copy over the current set of HTLCs to ensure the caller can't
|
||||||
// mutate our internal state.
|
// mutate our internal state.
|
||||||
snapshot.Htlcs = make([]HTLC, len(c.Htlcs))
|
snapshot.Htlcs = make([]HTLC, len(c.Htlcs))
|
||||||
for i, h := range c.Htlcs {
|
for i, h := range c.Htlcs {
|
||||||
|
@ -378,8 +378,8 @@ func TestChannelStateTransition(t *testing.T) {
|
|||||||
t.Fatalf("unable to save and serialize channel state: %v", err)
|
t.Fatalf("unable to save and serialize channel state: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add some HTLC's which were added during this new state transition.
|
// Add some HTLCs which were added during this new state transition.
|
||||||
// Half of the HTLC's are incoming, while the other half are outgoing.
|
// Half of the HTLCs are incoming, while the other half are outgoing.
|
||||||
var htlcs []*HTLC
|
var htlcs []*HTLC
|
||||||
for i := uint32(0); i < 10; i++ {
|
for i := uint32(0); i < 10; i++ {
|
||||||
var incoming bool
|
var incoming bool
|
||||||
@ -397,7 +397,7 @@ func TestChannelStateTransition(t *testing.T) {
|
|||||||
htlcs = append(htlcs, htlc)
|
htlcs = append(htlcs, htlc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new channel delta which includes the above HTLC's, some
|
// Create a new channel delta which includes the above HTLCs, some
|
||||||
// balance updates, and an increment of the current commitment height.
|
// balance updates, and an increment of the current commitment height.
|
||||||
// Additionally, modify the signature and commitment transaction.
|
// Additionally, modify the signature and commitment transaction.
|
||||||
newSequence := uint32(129498)
|
newSequence := uint32(129498)
|
||||||
@ -416,7 +416,7 @@ func TestChannelStateTransition(t *testing.T) {
|
|||||||
t.Fatalf("unable to update commitment: %v", err)
|
t.Fatalf("unable to update commitment: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The balances, new update, the HTLC's and the changes to the fake
|
// The balances, new update, the HTLCs and the changes to the fake
|
||||||
// commitment transaction along with the modified signature should all
|
// commitment transaction along with the modified signature should all
|
||||||
// have been updated.
|
// have been updated.
|
||||||
updatedChannel, err := cdb.FetchOpenChannels(channel.IdentityPub)
|
updatedChannel, err := cdb.FetchOpenChannels(channel.IdentityPub)
|
||||||
|
@ -215,7 +215,7 @@ func fileExists(path string) bool {
|
|||||||
func (d *DB) FetchOpenChannels(nodeID *btcec.PublicKey) ([]*OpenChannel, error) {
|
func (d *DB) FetchOpenChannels(nodeID *btcec.PublicKey) ([]*OpenChannel, error) {
|
||||||
var channels []*OpenChannel
|
var channels []*OpenChannel
|
||||||
err := d.View(func(tx *bolt.Tx) error {
|
err := d.View(func(tx *bolt.Tx) error {
|
||||||
// Get the bucket dedicated to storing the meta-data for open
|
// Get the bucket dedicated to storing the metadata for open
|
||||||
// channels.
|
// channels.
|
||||||
openChanBucket := tx.Bucket(openChannelBucket)
|
openChanBucket := tx.Bucket(openChannelBucket)
|
||||||
if openChanBucket == nil {
|
if openChanBucket == nil {
|
||||||
@ -295,14 +295,14 @@ func (d *DB) FetchAllChannels() ([]*OpenChannel, error) {
|
|||||||
var channels []*OpenChannel
|
var channels []*OpenChannel
|
||||||
|
|
||||||
err := d.View(func(tx *bolt.Tx) error {
|
err := d.View(func(tx *bolt.Tx) error {
|
||||||
// Get the bucket dedicated to storing the meta-data for open
|
// Get the bucket dedicated to storing the metadata for open
|
||||||
// channels.
|
// channels.
|
||||||
openChanBucket := tx.Bucket(openChannelBucket)
|
openChanBucket := tx.Bucket(openChannelBucket)
|
||||||
if openChanBucket == nil {
|
if openChanBucket == nil {
|
||||||
return ErrNoActiveChannels
|
return ErrNoActiveChannels
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next, fetch the bucket dedicated to storing meta-data
|
// Next, fetch the bucket dedicated to storing metadata
|
||||||
// related to all nodes. All keys within this bucket are the
|
// related to all nodes. All keys within this bucket are the
|
||||||
// serialized public keys of all our direct counterparties.
|
// serialized public keys of all our direct counterparties.
|
||||||
nodeMetaBucket := tx.Bucket(nodeInfoBucket)
|
nodeMetaBucket := tx.Bucket(nodeInfoBucket)
|
||||||
|
@ -231,7 +231,7 @@ func (c *ChannelGraph) ForEachNode(cb func(*LightningNode) error) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SourceNode returns the source node of the graph. The source node is treated
|
// SourceNode returns the source node of the graph. The source node is treated
|
||||||
// as the center node within a star-graph. This method may be used to kick-off
|
// as the center node within a star-graph. This method may be used to kick off
|
||||||
// a path finding algorithm in order to explore the reachability of another
|
// a path finding algorithm in order to explore the reachability of another
|
||||||
// node based off the source node.
|
// node based off the source node.
|
||||||
func (c *ChannelGraph) SourceNode() (*LightningNode, error) {
|
func (c *ChannelGraph) SourceNode() (*LightningNode, error) {
|
||||||
@ -1013,7 +1013,7 @@ type ChannelEdge struct {
|
|||||||
FeeBaseMSat btcutil.Amount
|
FeeBaseMSat btcutil.Amount
|
||||||
|
|
||||||
// FeeProportionalMillionths is the rate that the node will charge for
|
// FeeProportionalMillionths is the rate that the node will charge for
|
||||||
// HTLC's for each millionth of a satoshi forwarded.
|
// HTLCs for each millionth of a satoshi forwarded.
|
||||||
FeeProportionalMillionths btcutil.Amount
|
FeeProportionalMillionths btcutil.Amount
|
||||||
|
|
||||||
// Capacity is the total capacity of the channel, this is determined by
|
// Capacity is the total capacity of the channel, this is determined by
|
||||||
|
@ -23,7 +23,7 @@ var (
|
|||||||
// invoiceBucket which indexes all invoices by their payment hash. The
|
// invoiceBucket which indexes all invoices by their payment hash. The
|
||||||
// payment hash is the sha256 of the invoice's payment preimage. This
|
// payment hash is the sha256 of the invoice's payment preimage. This
|
||||||
// index is used to detect duplicates, and also to provide a fast path
|
// index is used to detect duplicates, and also to provide a fast path
|
||||||
// for looking up incoming HTLC's to determine if we're able to settle
|
// for looking up incoming HTLCs to determine if we're able to settle
|
||||||
// them fully.
|
// them fully.
|
||||||
invoiceIndexBucket = []byte("paymenthashes")
|
invoiceIndexBucket = []byte("paymenthashes")
|
||||||
|
|
||||||
|
@ -12,20 +12,20 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// nodeInfoBucket stores meta-data pertaining to nodes that we've had
|
// nodeInfoBucket stores metadata pertaining to nodes that we've had
|
||||||
// direct channel-based correspondence with. This bucket allows one to
|
// direct channel-based correspondence with. This bucket allows one to
|
||||||
// query for all open channels pertaining to the node by exploring each
|
// query for all open channels pertaining to the node by exploring each
|
||||||
// node's sub-bucket within the openChanBucket.
|
// node's sub-bucket within the openChanBucket.
|
||||||
nodeInfoBucket = []byte("nib")
|
nodeInfoBucket = []byte("nib")
|
||||||
)
|
)
|
||||||
|
|
||||||
// LinkNode stores meta-data related to node's that we have/had a direct
|
// LinkNode stores metadata related to node's that we have/had a direct
|
||||||
// channel open with. Information such as the Bitcoin network the node
|
// channel open with. Information such as the Bitcoin network the node
|
||||||
// advertised, and its identity public key are also stored. Additionally, this
|
// advertised, and its identity public key are also stored. Additionally, this
|
||||||
// struct and the bucket its stored within have store data similar to that of
|
// struct and the bucket its stored within have store data similar to that of
|
||||||
// Bitcion's addrmanager. The TCP address information stored within the struct
|
// Bitcion's addrmanager. The TCP address information stored within the struct
|
||||||
// can be used to establish persistent connections will all channel
|
// can be used to establish persistent connections will all channel
|
||||||
// counter-parties on daemon startup.
|
// counterparties on daemon startup.
|
||||||
//
|
//
|
||||||
// TODO(roasbeef): also add current OnionKey plus rotation schedule?
|
// TODO(roasbeef): also add current OnionKey plus rotation schedule?
|
||||||
// TODO(roasbeef): add bitfield for supported services
|
// TODO(roasbeef): add bitfield for supported services
|
||||||
@ -123,7 +123,7 @@ func putLinkNode(nodeMetaBucket *bolt.Bucket, l *LinkNode) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally insert the link-node into the node meta-data bucket keyed
|
// Finally insert the link-node into the node metadata bucket keyed
|
||||||
// according to the its pubkey serialized in compressed form.
|
// according to the its pubkey serialized in compressed form.
|
||||||
nodePub := l.IdentityPub.SerializeCompressed()
|
nodePub := l.IdentityPub.SerializeCompressed()
|
||||||
return nodeMetaBucket.Put(nodePub, b.Bytes())
|
return nodeMetaBucket.Put(nodePub, b.Bytes())
|
||||||
@ -139,7 +139,7 @@ func (db *DB) FetchLinkNode(identity *btcec.PublicKey) (*LinkNode, error) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
err = db.View(func(tx *bolt.Tx) error {
|
err = db.View(func(tx *bolt.Tx) error {
|
||||||
// First fetch the bucket for storing node meta-data, bailing
|
// First fetch the bucket for storing node metadata, bailing
|
||||||
// out early if it hasn't been created yet.
|
// out early if it hasn't been created yet.
|
||||||
nodeMetaBucket := tx.Bucket(nodeInfoBucket)
|
nodeMetaBucket := tx.Bucket(nodeInfoBucket)
|
||||||
if nodeMetaBucket == nil {
|
if nodeMetaBucket == nil {
|
||||||
|
@ -69,7 +69,7 @@ type config struct {
|
|||||||
RawRPCCert string `long:"rawrpccert" description:"The raw bytes of btcd's PEM-encoded certificate chain which will be used to authenticate the RPC connection."`
|
RawRPCCert string `long:"rawrpccert" description:"The raw bytes of btcd's PEM-encoded certificate chain which will be used to authenticate the RPC connection."`
|
||||||
TestNet3 bool `long:"testnet" description:"Use the test network"`
|
TestNet3 bool `long:"testnet" description:"Use the test network"`
|
||||||
SimNet bool `long:"simnet" description:"Use the simulation test network"`
|
SimNet bool `long:"simnet" description:"Use the simulation test network"`
|
||||||
DebugHTLC bool `long:"debughtlc" description:"Activate the debug htlc mode. With the debug HTLC mode, all payments sent use a pre-determined R-Hash. Additionally, all HTLC's sent to a node with the debug HTLC R-Hash are immediately settled in the next available state transition."`
|
DebugHTLC bool `long:"debughtlc" description:"Activate the debug htlc mode. With the debug HTLC mode, all payments sent use a pre-determined R-Hash. Additionally, all HTLCs sent to a node with the debug HTLC R-Hash are immediately settled in the next available state transition."`
|
||||||
MaxPendingChannels int `long:"maxpendingchannels" description:"The maximum number of incoming pending channels permitted per peer."`
|
MaxPendingChannels int `long:"maxpendingchannels" description:"The maximum number of incoming pending channels permitted per peer."`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +145,7 @@ func loadConfig() (*config, error) {
|
|||||||
|
|
||||||
// Multiple networks can't be selected simultaneously.
|
// Multiple networks can't be selected simultaneously.
|
||||||
// Count number of network flags passed; assign active network params
|
// Count number of network flags passed; assign active network params
|
||||||
// while we're at it
|
// while we're at it.
|
||||||
numNets := 0
|
numNets := 0
|
||||||
if cfg.TestNet3 {
|
if cfg.TestNet3 {
|
||||||
numNets++
|
numNets++
|
||||||
@ -162,7 +162,7 @@ func loadConfig() (*config, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate profile port number
|
// Validate profile port number.
|
||||||
if cfg.Profile != "" {
|
if cfg.Profile != "" {
|
||||||
profilePort, err := strconv.Atoi(cfg.Profile)
|
profilePort, err := strconv.Atoi(cfg.Profile)
|
||||||
if err != nil || profilePort < 1024 || profilePort > 65535 {
|
if err != nil || profilePort < 1024 || profilePort > 65535 {
|
||||||
@ -213,7 +213,7 @@ func cleanAndExpandPath(path string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: The os.ExpandEnv doesn't work with Windows-style %VARIABLE%,
|
// NOTE: The os.ExpandEnv doesn't work with Windows-style %VARIABLE%,
|
||||||
// but they variables can still be expanded via POSIX-style $VARIABLE.
|
// but the variables can still be expanded via POSIX-style $VARIABLE.
|
||||||
return filepath.Clean(os.ExpandEnv(path))
|
return filepath.Clean(os.ExpandEnv(path))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,11 +7,11 @@
|
|||||||
4.2. [Testing](#Testing)<br />
|
4.2. [Testing](#Testing)<br />
|
||||||
4.3. [Code Documentation and Commenting](#CodeDocumentation)<br />
|
4.3. [Code Documentation and Commenting](#CodeDocumentation)<br />
|
||||||
4.4. [Model Git Commit Messages](#ModelGitCommitMessages)<br />
|
4.4. [Model Git Commit Messages](#ModelGitCommitMessages)<br />
|
||||||
4.5 [Code Spacing](#CodeSpacing)<br />
|
4.5. [Code Spacing](#CodeSpacing)<br />
|
||||||
5. [Code Approval Process](#CodeApproval)<br />
|
5. [Code Approval Process](#CodeApproval)<br />
|
||||||
5.1 [Code Review](#CodeReview)<br />
|
5.1. [Code Review](#CodeReview)<br />
|
||||||
5.2 [Rework Code (if needed)](#CodeRework)<br />
|
5.2. [Rework Code (if needed)](#CodeRework)<br />
|
||||||
5.3 [Acceptance](#CodeAcceptance)<br />
|
5.3. [Acceptance](#CodeAcceptance)<br />
|
||||||
6. [Contribution Standards](#Standards)<br />
|
6. [Contribution Standards](#Standards)<br />
|
||||||
6.1. [Contribution Checklist](#Checklist)<br />
|
6.1. [Contribution Checklist](#Checklist)<br />
|
||||||
6.2. [Licensing of Contributions](#Licensing)<br />
|
6.2. [Licensing of Contributions](#Licensing)<br />
|
||||||
@ -26,7 +26,7 @@ threat-modeling, and RPC systems. They also represent a radical shift to the
|
|||||||
current fiscal system and as a result provide an opportunity to help reshape
|
current fiscal system and as a result provide an opportunity to help reshape
|
||||||
the entire financial system. With the advent of the [Lightning Network
|
the entire financial system. With the advent of the [Lightning Network
|
||||||
(LN)](https://lightning.network/), new layers are being constructed upon the
|
(LN)](https://lightning.network/), new layers are being constructed upon the
|
||||||
base blockchain layer which have the potential to aleviate many of the
|
base blockchain layer which have the potential to alleviate many of the
|
||||||
limitations and constraints inherent in the design of blockchains. There are
|
limitations and constraints inherent in the design of blockchains. There are
|
||||||
few projects that offer this level of diversity and impact all in one code
|
few projects that offer this level of diversity and impact all in one code
|
||||||
base.
|
base.
|
||||||
@ -77,10 +77,10 @@ security and performance implications.
|
|||||||
- [Effective Go](http://golang.org/doc/effective_go.html) - The entire lnd
|
- [Effective Go](http://golang.org/doc/effective_go.html) - The entire lnd
|
||||||
project follows the guidelines in this document. For your code to be accepted,
|
project follows the guidelines in this document. For your code to be accepted,
|
||||||
it must follow the guidelines therein.
|
it must follow the guidelines therein.
|
||||||
- [Original Satoshi Whitepaper](http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&ved=0CCkQFjAA&url=http%3A%2F%2Fbitcoin.org%2Fbitcoin.pdf&ei=os3VUuH8G4SlsASV74GoAg&usg=AFQjCNEipPLigou_1MfB7DQjXCNdlylrBg&sig2=FaHDuT5z36GMWDEnybDJLg&bvm=bv.59378465,d.b2I) - This is the white paper that started it all. Having a solid
|
- [Original Satoshi Whitepaper](https://bitcoin.org/bitcoin.pdf) - This is the white paper that started it all. Having a solid
|
||||||
foundation to build on will make the code much more comprehensible.
|
foundation to build on will make the code much more comprehensible.
|
||||||
- [Lightning Network Whitepaper](https://lightning.network/lightning-network-paper.pdf) - This is the white paper that kicked off the Layer 2 revolution. Having a good graps of the concepts of Lightning will make the core logic within the daemon much more comprehensible: Bitcoin Script, off-chain blockchain protocols, payment channels, bi-directional payment channels, relative and absolute time-locks, commitment state revocations, and Segregated Witness.
|
- [Lightning Network Whitepaper](https://lightning.network/lightning-network-paper.pdf) - This is the white paper that kicked off the Layer 2 revolution. Having a good grasp of the concepts of Lightning will make the core logic within the daemon much more comprehensible: Bitcoin Script, off-chain blockchain protocols, payment channels, bi-directional payment channels, relative and absolute time-locks, commitment state revocations, and Segregated Witness.
|
||||||
- The original LN was written for a rather narrow audience, the paper may be a bit unapproachable to many. Thanks to the Bitcoin community, there exist many easily accessible suplemental resources which can help one see how all the pieces fit together from double-spend protection all the way up to commitment state transitions and Hash Time Locked Contracts (HTLC's):
|
- The original LN was written for a rather narrow audience, the paper may be a bit unapproachable to many. Thanks to the Bitcoin community, there exist many easily accessible supplemental resources which can help one see how all the pieces fit together from double-spend protection all the way up to commitment state transitions and Hash Time Locked Contracts (HTLCs):
|
||||||
- [Lightning Network Summary](https://lightning.network/lightning-network-summary.pdf)
|
- [Lightning Network Summary](https://lightning.network/lightning-network-summary.pdf)
|
||||||
- [Understanding the Lightning Network 3-Part series](https://bitcoinmagazine.com/articles/understanding-the-lightning-network-part-building-a-bidirectional-payment-channel-1464710791)
|
- [Understanding the Lightning Network 3-Part series](https://bitcoinmagazine.com/articles/understanding-the-lightning-network-part-building-a-bidirectional-payment-channel-1464710791)
|
||||||
- [Deployable Lightning](https://github.com/ElementsProject/lightning/blob/master/doc/deployable-lightning.pdf)
|
- [Deployable Lightning](https://github.com/ElementsProject/lightning/blob/master/doc/deployable-lightning.pdf)
|
||||||
@ -93,7 +93,7 @@ above may be a bit out of date. Many implementers are currently working on an
|
|||||||
initial [Version 1 Specification](https://medium.com/@lightningnetwork/lightning-network-meeting-on-interoperability-and-specifications-ea49e47696a4).
|
initial [Version 1 Specification](https://medium.com/@lightningnetwork/lightning-network-meeting-on-interoperability-and-specifications-ea49e47696a4).
|
||||||
Once the specification is finalized, it will be the most up-to-date
|
Once the specification is finalized, it will be the most up-to-date
|
||||||
comprehensive document explaining the Lightning Network. As a result, it will
|
comprehensive document explaining the Lightning Network. As a result, it will
|
||||||
be recommened for new comers to read first in order to get up to speed.
|
be recommened for newcomers to read first in order to get up to speed.
|
||||||
|
|
||||||
<a name="DevelopmentPractices" />
|
<a name="DevelopmentPractices" />
|
||||||
### 4. Development Practices
|
### 4. Development Practices
|
||||||
@ -103,7 +103,7 @@ they feel their feature or bug fix is ready for integration into the master
|
|||||||
branch.
|
branch.
|
||||||
|
|
||||||
<a name="ShareEarly" />
|
<a name="ShareEarly" />
|
||||||
### 4.1 Share Early, Share Often
|
### 4.1. Share Early, Share Often
|
||||||
|
|
||||||
We firmly believe in the share early, share often approach. The basic premise
|
We firmly believe in the share early, share often approach. The basic premise
|
||||||
of the approach is to announce your plans **before** you start work, and once
|
of the approach is to announce your plans **before** you start work, and once
|
||||||
@ -123,7 +123,7 @@ This approach has several benefits:
|
|||||||
spend rebasing and otherwise trying to keep up with the main code base
|
spend rebasing and otherwise trying to keep up with the main code base
|
||||||
|
|
||||||
<a name="Testing" />
|
<a name="Testing" />
|
||||||
### 4.2 Testing
|
### 4.2. Testing
|
||||||
|
|
||||||
One of the major design goals of all of lnd's packages and the daemon itself is
|
One of the major design goals of all of lnd's packages and the daemon itself is
|
||||||
to aim for a high degree of test coverage. This is financial software so bugs
|
to aim for a high degree of test coverage. This is financial software so bugs
|
||||||
@ -139,7 +139,7 @@ code works correctly when it is fed correct data as well as incorrect data
|
|||||||
|
|
||||||
|
|
||||||
Go provides an excellent test framework that makes writing test code and
|
Go provides an excellent test framework that makes writing test code and
|
||||||
checking coverage statistics straight forward. For more information about the
|
checking coverage statistics straightforward. For more information about the
|
||||||
test coverage tools, see the [golang cover blog post](http://blog.golang.org/cover).
|
test coverage tools, see the [golang cover blog post](http://blog.golang.org/cover).
|
||||||
|
|
||||||
A quick summary of test practices follows:
|
A quick summary of test practices follows:
|
||||||
@ -150,7 +150,7 @@ A quick summary of test practices follows:
|
|||||||
to both prove it has been resolved and to prevent future regressions
|
to both prove it has been resolved and to prevent future regressions
|
||||||
- Changes to publicly exported packages such as
|
- Changes to publicly exported packages such as
|
||||||
[brontide](https://github.com/lightningnetwork/lnd/tree/master/brontide) should
|
[brontide](https://github.com/lightningnetwork/lnd/tree/master/brontide) should
|
||||||
be accompanied by unittest excersising the new or changed behavior.
|
be accompanied by unit tests exercising the new or changed behavior.
|
||||||
- Changes to behavior within the daemon's interaction with the P2P protocol,
|
- Changes to behavior within the daemon's interaction with the P2P protocol,
|
||||||
or RPC's will need to be accompanied by integration tests which use the
|
or RPC's will need to be accompanied by integration tests which use the
|
||||||
[`networkHarness`framework](https://github.com/lightningnetwork/lnd/blob/master/networktest.go)
|
[`networkHarness`framework](https://github.com/lightningnetwork/lnd/blob/master/networktest.go)
|
||||||
@ -158,7 +158,7 @@ A quick summary of test practices follows:
|
|||||||
[`lnd_test.go`](https://github.com/lightningnetwork/lnd/blob/master/lnd_test.go#L181).
|
[`lnd_test.go`](https://github.com/lightningnetwork/lnd/blob/master/lnd_test.go#L181).
|
||||||
|
|
||||||
<a name="CodeDocumentation" />
|
<a name="CodeDocumentation" />
|
||||||
### 4.3 Code Documentation and Commenting
|
### 4.3. Code Documentation and Commenting
|
||||||
|
|
||||||
- At a minimum every function must be commented with its intended purpose and
|
- At a minimum every function must be commented with its intended purpose and
|
||||||
any assumptions that it makes
|
any assumptions that it makes
|
||||||
@ -181,10 +181,10 @@ func DeriveRevocationPubkey(commitPubKey *btcec.PublicKey,
|
|||||||
**RIGHT**
|
**RIGHT**
|
||||||
```go
|
```go
|
||||||
// DeriveRevocationPubkey derives the revocation public key given the
|
// DeriveRevocationPubkey derives the revocation public key given the
|
||||||
// counter-party's commitment key, and revocation pre-image derived via a
|
// counterparty's commitment key, and revocation preimage derived via a
|
||||||
// pseudo-random-function. In the event that we (for some reason) broadcast a
|
// pseudo-random-function. In the event that we (for some reason) broadcast a
|
||||||
// revoked commitment transaction, then if the other party knows the revocation
|
// revoked commitment transaction, then if the other party knows the revocation
|
||||||
// pre-image, then they'll be able to derive the corresponding private key to
|
// preimage, then they'll be able to derive the corresponding private key to
|
||||||
// this private key by exploiting the homomorphism in the elliptic curve group:
|
// this private key by exploiting the homomorphism in the elliptic curve group:
|
||||||
// * https://en.wikipedia.org/wiki/Group_homomorphism#Homomorphisms_of_abelian_groups
|
// * https://en.wikipedia.org/wiki/Group_homomorphism#Homomorphisms_of_abelian_groups
|
||||||
//
|
//
|
||||||
@ -194,7 +194,7 @@ func DeriveRevocationPubkey(commitPubKey *btcec.PublicKey,
|
|||||||
// := G*k + G*h
|
// := G*k + G*h
|
||||||
// := G * (k+h)
|
// := G * (k+h)
|
||||||
//
|
//
|
||||||
// Therefore, once we divulge the revocation pre-image, the remote peer is able to
|
// Therefore, once we divulge the revocation preimage, the remote peer is able to
|
||||||
// compute the proper private key for the revokeKey by computing:
|
// compute the proper private key for the revokeKey by computing:
|
||||||
// revokePriv := commitPriv + revokePreimge mod N
|
// revokePriv := commitPriv + revokePreimge mod N
|
||||||
//
|
//
|
||||||
@ -225,7 +225,7 @@ but it was left as a magic number to show how much of a difference a good
|
|||||||
comment can make.
|
comment can make.
|
||||||
|
|
||||||
<a name="ModelGitCommitMessages" />
|
<a name="ModelGitCommitMessages" />
|
||||||
### 4.4 Code Documentation and Commenting
|
### 4.4. Model Git Commit Messages
|
||||||
|
|
||||||
This project prefers to keep a clean commit history with well-formed commit
|
This project prefers to keep a clean commit history with well-formed commit
|
||||||
messages. This section illustrates a model commit message and provides a bit
|
messages. This section illustrates a model commit message and provides a bit
|
||||||
@ -273,20 +273,20 @@ a good thing.
|
|||||||
In addition to the Git commit message structure adhered to within the daemon
|
In addition to the Git commit message structure adhered to within the daemon
|
||||||
all short-[commit messages are to be prefixed according to the convention
|
all short-[commit messages are to be prefixed according to the convention
|
||||||
outlined in the Go project](https://golang.org/doc/contribute.html#change). All
|
outlined in the Go project](https://golang.org/doc/contribute.html#change). All
|
||||||
commits should begin with the sub-system or package primarliy affected by the
|
commits should begin with the subsystem or package primarily affected by the
|
||||||
change. In the case of a widespread change, the packages are to be delimited by
|
change. In the case of a widespread change, the packages are to be delimited by
|
||||||
either a '+' or a ','. This prefix seems minor but can be extremly helpful it
|
either a '+' or a ','. This prefix seems minor but can be extremly helpful in
|
||||||
determining the scope of a commit at a glance, or when bug hunting to find a
|
determining the scope of a commit at a glance, or when bug hunting to find a
|
||||||
commit which introduced a bug or regression.
|
commit which introduced a bug or regression.
|
||||||
|
|
||||||
<a name="CodeSpacing" />
|
<a name="CodeSpacing" />
|
||||||
### 4.5 Code Spacing
|
### 4.5. Code Spacing
|
||||||
|
|
||||||
Blocks of code within lnd should be segmented into logical stanzas of
|
Blocks of code within lnd should be segmented into logical stanzas of
|
||||||
operation. Such spacing makes the code easier to follow at a skim, and reduces
|
operation. Such spacing makes the code easier to follow at a skim, and reduces
|
||||||
uncessary line noise. Coupled commenting scheme specified above, proper spacing
|
unnecessary line noise. Coupled with the commenting scheme specified above,
|
||||||
allows readers to quickly scan code, extracting semantics quickly. Functions
|
proper spacing allows readers to quickly scan code, extracting semantics quickly.
|
||||||
should _not_ just be layed out as a bare contigious block of code.
|
Functions should _not_ just be layed out as a bare contiguous block of code.
|
||||||
|
|
||||||
- **Wrong**
|
- **Wrong**
|
||||||
```go
|
```go
|
||||||
@ -312,7 +312,7 @@ should _not_ just be layed out as a bare contigious block of code.
|
|||||||
|
|
||||||
// When initially generating the witnessScript, we sorted the serialized
|
// When initially generating the witnessScript, we sorted the serialized
|
||||||
// public keys in descending order. So we do a quick comparison in order
|
// public keys in descending order. So we do a quick comparison in order
|
||||||
// ensure the signatures appear on the Script Virtual Machine stack in
|
// to ensure the signatures appear on the Script Virtual Machine stack in
|
||||||
// the correct order.
|
// the correct order.
|
||||||
if bytes.Compare(pubA, pubB) == -1 {
|
if bytes.Compare(pubA, pubB) == -1 {
|
||||||
witness[1] = sigB
|
witness[1] = sigB
|
||||||
@ -322,7 +322,7 @@ should _not_ just be layed out as a bare contigious block of code.
|
|||||||
witness[2] = sigB
|
witness[2] = sigB
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, add the pre-image as the last witness element.
|
// Finally, add the preimage as the last witness element.
|
||||||
witness[3] = witnessScript
|
witness[3] = witnessScript
|
||||||
|
|
||||||
return witness
|
return witness
|
||||||
@ -335,7 +335,7 @@ This section describes the code approval process that is used for code
|
|||||||
contributions. This is how to get your changes into lnd.
|
contributions. This is how to get your changes into lnd.
|
||||||
|
|
||||||
<a name="CodeReview" />
|
<a name="CodeReview" />
|
||||||
### 5.1 Code Review
|
### 5.1. Code Review
|
||||||
|
|
||||||
All code which is submitted will need to be reviewed before inclusion into the
|
All code which is submitted will need to be reviewed before inclusion into the
|
||||||
master branch. This process is performed by the project maintainers and usually
|
master branch. This process is performed by the project maintainers and usually
|
||||||
@ -354,7 +354,7 @@ manageable, commits.
|
|||||||
|
|
||||||
Keeping the above in mind, most small changes will be reviewed within a few
|
Keeping the above in mind, most small changes will be reviewed within a few
|
||||||
days, while large or far reaching changes may take weeks. This is a good reason
|
days, while large or far reaching changes may take weeks. This is a good reason
|
||||||
to stick with the [Share Early, Share Often](#ShareOften) development practice
|
to stick with the [Share Early, Share Often](#ShareEarly) development practice
|
||||||
outlined above.
|
outlined above.
|
||||||
|
|
||||||
##### What is the review looking for?
|
##### What is the review looking for?
|
||||||
@ -370,7 +370,7 @@ checks which are generally performed as follows:
|
|||||||
consensus
|
consensus
|
||||||
|
|
||||||
<a name="CodeRework" />
|
<a name="CodeRework" />
|
||||||
### 5.2 Rework Code (if needed)
|
### 5.2. Rework Code (if needed)
|
||||||
|
|
||||||
After the code review, the change will be accepted immediately if no issues are
|
After the code review, the change will be accepted immediately if no issues are
|
||||||
found. If there are any concerns or questions, you will be provided with
|
found. If there are any concerns or questions, you will be provided with
|
||||||
@ -382,7 +382,7 @@ make the necessary changes.
|
|||||||
This process will continue until the code is finally accepted.
|
This process will continue until the code is finally accepted.
|
||||||
|
|
||||||
<a name="CodeAcceptance" />
|
<a name="CodeAcceptance" />
|
||||||
### 5.3 Acceptance
|
### 5.3. Acceptance
|
||||||
|
|
||||||
Once your code is accepted, it will be integrated with the master branch.
|
Once your code is accepted, it will be integrated with the master branch.
|
||||||
Typically it will be rebased and fast-forward merged to master as we prefer to
|
Typically it will be rebased and fast-forward merged to master as we prefer to
|
||||||
@ -421,7 +421,7 @@ All contributions must be licensed with the
|
|||||||
the same license as all of the code found within lnd.
|
the same license as all of the code found within lnd.
|
||||||
|
|
||||||
|
|
||||||
## Aknolwedgements
|
## Acknowledgements
|
||||||
This document was heavily inspired by a [similar document outlining the code
|
This document was heavily inspired by a [similar document outlining the code
|
||||||
contribution](https://github.com/btcsuite/btcd/blob/master/docs/code_contribution_guidelines.md)
|
contribution](https://github.com/btcsuite/btcd/blob/master/docs/code_contribution_guidelines.md)
|
||||||
guidelines for btcd.
|
guidelines for btcd.
|
||||||
|
@ -40,8 +40,8 @@ type reservationWithCtx struct {
|
|||||||
err chan error
|
err chan error
|
||||||
}
|
}
|
||||||
|
|
||||||
// initFundingMsg is sent by an outside sub-system 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
|
// order to kick off a funding workflow with a specified target peer. The
|
||||||
// original request which defines the parameters of the funding workflow are
|
// original request which defines the parameters of the funding workflow are
|
||||||
// embedded within this message giving the funding manager full context w.r.t
|
// embedded within this message giving the funding manager full context w.r.t
|
||||||
// the workflow.
|
// the workflow.
|
||||||
@ -92,7 +92,7 @@ type fundingOpenMsg struct {
|
|||||||
|
|
||||||
// fundingErrorMsg couples an lnwire.ErrorGeneric message
|
// fundingErrorMsg couples an lnwire.ErrorGeneric message
|
||||||
// with the peer who sent the message. This allows the funding
|
// with the peer who sent the message. This allows the funding
|
||||||
// manager properly process the error.
|
// manager to properly process the error.
|
||||||
type fundingErrorMsg struct {
|
type fundingErrorMsg struct {
|
||||||
err *lnwire.ErrorGeneric
|
err *lnwire.ErrorGeneric
|
||||||
peer *peer
|
peer *peer
|
||||||
@ -105,7 +105,7 @@ type pendingChannels map[uint64]*reservationWithCtx
|
|||||||
// fundingManager acts as an orchestrator/bridge between the wallet's
|
// fundingManager acts as an orchestrator/bridge between the wallet's
|
||||||
// 'ChannelReservation' workflow, and the wire protocol's funding initiation
|
// 'ChannelReservation' workflow, and the wire protocol's funding initiation
|
||||||
// messages. Any requests to initiate the funding workflow for a channel,
|
// messages. Any requests to initiate the funding workflow for a channel,
|
||||||
// either kicked-off locally, or remotely is handled by the funding manager.
|
// either kicked-off locally or remotely handled by the funding manager.
|
||||||
// Once a channel's funding workflow has been completed, any local callers, the
|
// Once a channel's funding workflow has been completed, any local callers, the
|
||||||
// local peer, and possibly the remote peer are notified of the completion of
|
// local peer, and possibly the remote peer are notified of the completion of
|
||||||
// the channel workflow. Additionally, any temporary or permanent access
|
// the channel workflow. Additionally, any temporary or permanent access
|
||||||
@ -135,7 +135,7 @@ type fundingManager struct {
|
|||||||
queries chan interface{}
|
queries chan interface{}
|
||||||
|
|
||||||
// fundingRequests is a channel used to receive channel initiation
|
// fundingRequests is a channel used to receive channel initiation
|
||||||
// requests from a local sub-system within the daemon.
|
// requests from a local subsystem within the daemon.
|
||||||
fundingRequests chan *initFundingMsg
|
fundingRequests chan *initFundingMsg
|
||||||
|
|
||||||
fakeProof *channelProof
|
fakeProof *channelProof
|
||||||
@ -187,7 +187,7 @@ func (f *fundingManager) Start() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start signals all helper goroutines to execute a graceful shutdown. This
|
// Stop signals all helper goroutines to execute a graceful shutdown. This
|
||||||
// method will block until all goroutines have exited.
|
// method will block until all goroutines have exited.
|
||||||
func (f *fundingManager) Stop() error {
|
func (f *fundingManager) Stop() error {
|
||||||
if atomic.AddInt32(&f.stopped, 1) != 1 {
|
if atomic.AddInt32(&f.stopped, 1) != 1 {
|
||||||
@ -388,7 +388,7 @@ func (f *fundingManager) handleFundingRequest(fmsg *fundingRequestMsg) {
|
|||||||
}
|
}
|
||||||
f.resMtx.Unlock()
|
f.resMtx.Unlock()
|
||||||
|
|
||||||
// With our portion of the reservation initialied, process the
|
// With our portion of the reservation initialized, process the
|
||||||
// initiators contribution to the channel.
|
// initiators contribution to the channel.
|
||||||
_, addrs, _, err := txscript.ExtractPkScriptAddrs(msg.DeliveryPkScript, activeNetParams.Params)
|
_, addrs, _, err := txscript.ExtractPkScriptAddrs(msg.DeliveryPkScript, activeNetParams.Params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -410,7 +410,7 @@ func (f *fundingManager) handleFundingRequest(fmsg *fundingRequestMsg) {
|
|||||||
|
|
||||||
fndgLog.Infof("Sending fundingResp for pendingID(%v)", msg.ChannelID)
|
fndgLog.Infof("Sending fundingResp for pendingID(%v)", msg.ChannelID)
|
||||||
|
|
||||||
// With the initiator's contribution recorded, response with our
|
// With the initiator's contribution recorded, respond with our
|
||||||
// contribution in the next message of the workflow.
|
// contribution in the next message of the workflow.
|
||||||
ourContribution := reservation.OurContribution()
|
ourContribution := reservation.OurContribution()
|
||||||
deliveryScript, err := txscript.PayToAddrScript(ourContribution.DeliveryAddress)
|
deliveryScript, err := txscript.PayToAddrScript(ourContribution.DeliveryAddress)
|
||||||
@ -443,7 +443,7 @@ func (f *fundingManager) handleFundingResponse(fmsg *fundingResponseMsg) {
|
|||||||
|
|
||||||
resCtx, err := f.getReservationCtx(peerID, chanID)
|
resCtx, err := f.getReservationCtx(peerID, chanID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fndgLog.Warnf("can' find reservation (peerID:%v, chanID:%v)",
|
fndgLog.Warnf("Can't find reservation (peerID:%v, chanID:%v)",
|
||||||
peerID, chanID)
|
peerID, chanID)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -518,7 +518,7 @@ func (f *fundingManager) processFundingComplete(msg *lnwire.SingleFundingComplet
|
|||||||
func (f *fundingManager) handleFundingComplete(fmsg *fundingCompleteMsg) {
|
func (f *fundingManager) handleFundingComplete(fmsg *fundingCompleteMsg) {
|
||||||
resCtx, err := f.getReservationCtx(fmsg.peer.id, fmsg.msg.ChannelID)
|
resCtx, err := f.getReservationCtx(fmsg.peer.id, fmsg.msg.ChannelID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fndgLog.Warnf("can' find reservation (peerID:%v, chanID:%v)",
|
fndgLog.Warnf("can't find reservation (peerID:%v, chanID:%v)",
|
||||||
fmsg.peer.id, fmsg.msg.ChannelID)
|
fmsg.peer.id, fmsg.msg.ChannelID)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -598,7 +598,7 @@ type chanAnnouncement struct {
|
|||||||
// announcement is two part: the first part authenticates the existence of the
|
// announcement is two part: the first part authenticates the existence of the
|
||||||
// channel and contains four signatures binding the funding pub keys and
|
// channel and contains four signatures binding the funding pub keys and
|
||||||
// identity pub keys of both parties to the channel, and the second segment is
|
// identity pub keys of both parties to the channel, and the second segment is
|
||||||
// authenticated only by us an contains our directional routing policy for the
|
// authenticated only by us and contains our directional routing policy for the
|
||||||
// channel.
|
// channel.
|
||||||
func newChanAnnouncement(localIdentity *btcec.PublicKey,
|
func newChanAnnouncement(localIdentity *btcec.PublicKey,
|
||||||
channel *lnwallet.LightningChannel, chanID lnwire.ChannelID,
|
channel *lnwallet.LightningChannel, chanID lnwire.ChannelID,
|
||||||
@ -680,14 +680,14 @@ func newChanAnnouncement(localIdentity *btcec.PublicKey,
|
|||||||
// funder workflow. Once this message is processed, the funding transaction is
|
// funder workflow. Once this message is processed, the funding transaction is
|
||||||
// broadcast. Once the funding transaction reaches a sufficient number of
|
// broadcast. Once the funding transaction reaches a sufficient number of
|
||||||
// confirmations, a message is sent to the responding peer along with a compact
|
// confirmations, a message is sent to the responding peer along with a compact
|
||||||
// encoding of the location of the channel within the block chain.
|
// encoding of the location of the channel within the blockchain.
|
||||||
func (f *fundingManager) handleFundingSignComplete(fmsg *fundingSignCompleteMsg) {
|
func (f *fundingManager) handleFundingSignComplete(fmsg *fundingSignCompleteMsg) {
|
||||||
chanID := fmsg.msg.ChannelID
|
chanID := fmsg.msg.ChannelID
|
||||||
peerID := fmsg.peer.id
|
peerID := fmsg.peer.id
|
||||||
|
|
||||||
resCtx, err := f.getReservationCtx(peerID, chanID)
|
resCtx, err := f.getReservationCtx(peerID, chanID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fndgLog.Warnf("can' find reservation (peerID:%v, chanID:%v)",
|
fndgLog.Warnf("can't find reservation (peerID:%v, chanID:%v)",
|
||||||
peerID, chanID)
|
peerID, chanID)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -709,7 +709,7 @@ func (f *fundingManager) handleFundingSignComplete(fmsg *fundingSignCompleteMsg)
|
|||||||
|
|
||||||
// Send an update to the upstream client that the negotiation process
|
// Send an update to the upstream client that the negotiation process
|
||||||
// is over.
|
// is over.
|
||||||
// TODO(roasbeef): add abstraction over updates to accomdate
|
// TODO(roasbeef): add abstraction over updates to accommodate
|
||||||
// long-polling, or SSE, etc.
|
// long-polling, or SSE, etc.
|
||||||
resCtx.updates <- &lnrpc.OpenStatusUpdate{
|
resCtx.updates <- &lnrpc.OpenStatusUpdate{
|
||||||
Update: &lnrpc.OpenStatusUpdate_ChanPending{
|
Update: &lnrpc.OpenStatusUpdate_ChanPending{
|
||||||
@ -788,7 +788,7 @@ func (f *fundingManager) handleFundingSignComplete(fmsg *fundingSignCompleteMsg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// announceChannel announces a newly created channel to the rest of the network
|
// announceChannel announces a newly created channel to the rest of the network
|
||||||
// by crafting the two authenticated announcement required for the peers on the
|
// by crafting the two authenticated announcements required for the peers on the
|
||||||
// network to recognize the legitimacy of the channel. The crafted
|
// network to recognize the legitimacy of the channel. The crafted
|
||||||
// announcements are then send to the channel router to handle broadcasting to
|
// announcements are then send to the channel router to handle broadcasting to
|
||||||
// the network during its next trickle.
|
// the network during its next trickle.
|
||||||
@ -807,7 +807,7 @@ func (f *fundingManager) announceChannel(s *server,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// processFundingOpenProof sends a message to the fundingManager allowing it
|
// processFundingOpenProof sends a message to the fundingManager allowing it
|
||||||
// to process the final message recieved when the daemon is on the responding
|
// to process the final message received when the daemon is on the responding
|
||||||
// side of a single funder channel workflow.
|
// side of a single funder channel workflow.
|
||||||
func (f *fundingManager) processFundingOpenProof(msg *lnwire.SingleFundingOpenProof, peer *peer) {
|
func (f *fundingManager) processFundingOpenProof(msg *lnwire.SingleFundingOpenProof, peer *peer) {
|
||||||
f.fundingMsgs <- &fundingOpenMsg{msg, peer}
|
f.fundingMsgs <- &fundingOpenMsg{msg, peer}
|
||||||
@ -821,7 +821,7 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) {
|
|||||||
|
|
||||||
resCtx, err := f.getReservationCtx(peerID, chanID)
|
resCtx, err := f.getReservationCtx(peerID, chanID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fndgLog.Warnf("can' find reservation (peerID:%v, chanID:%v)",
|
fndgLog.Warnf("can't find reservation (peerID:%v, chanID:%v)",
|
||||||
peerID, chanID)
|
peerID, chanID)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -829,7 +829,7 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) {
|
|||||||
// The channel initiator has claimed the channel is now open, so we'll
|
// The channel initiator has claimed the channel is now open, so we'll
|
||||||
// verify the contained SPV proof for validity.
|
// verify the contained SPV proof for validity.
|
||||||
// TODO(roasbeef): send off to the spv proof verifier, in the routing
|
// TODO(roasbeef): send off to the spv proof verifier, in the routing
|
||||||
// sub-module.
|
// submodule.
|
||||||
|
|
||||||
// Now that we've verified the initiator's proof, we'll commit the
|
// Now that we've verified the initiator's proof, we'll commit the
|
||||||
// channel state to disk, and notify the source peer of a newly opened
|
// channel state to disk, and notify the source peer of a newly opened
|
||||||
@ -858,10 +858,10 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) {
|
|||||||
|
|
||||||
// Send the newly opened channel to the breach arbiter to it can watch
|
// Send the newly opened channel to the breach arbiter to it can watch
|
||||||
// for uncooperative channel breaches, potentially punishing the
|
// for uncooperative channel breaches, potentially punishing the
|
||||||
// counter-party for attempting to cheat us.
|
// counterparty for attempting to cheat us.
|
||||||
f.breachAribter.newContracts <- openChan
|
f.breachAribter.newContracts <- openChan
|
||||||
|
|
||||||
// Finally, notify the target peer of the newly open channel.
|
// Finally, notify the target peer of the newly opened channel.
|
||||||
fmsg.peer.newChannels <- openChan
|
fmsg.peer.newChannels <- openChan
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -967,8 +967,8 @@ func (f *fundingManager) processErrorGeneric(err *lnwire.ErrorGeneric,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handleErrorGenericMsg process the error which was received from remote peer,
|
// handleErrorGenericMsg process the error which was received from remote peer,
|
||||||
// depends on the type of error we should do different clean up steps and
|
// depending on the type of error we should do different clean up steps and
|
||||||
// inform user about it.
|
// inform the user about it.
|
||||||
func (f *fundingManager) handleErrorGenericMsg(fmsg *fundingErrorMsg) {
|
func (f *fundingManager) handleErrorGenericMsg(fmsg *fundingErrorMsg) {
|
||||||
e := fmsg.err
|
e := fmsg.err
|
||||||
|
|
||||||
|
@ -26,11 +26,11 @@ const (
|
|||||||
htlcQueueSize = 50
|
htlcQueueSize = 50
|
||||||
)
|
)
|
||||||
|
|
||||||
// link represents a an active channel capable of forwarding HTLC's. Each
|
// link represents an active channel capable of forwarding HTLCs. Each
|
||||||
// active channel registered with the htlc switch creates a new link which will
|
// active channel registered with the htlc switch creates a new link which will
|
||||||
// be used for forwarding outgoing HTLC's. The link also has additional
|
// be used for forwarding outgoing HTLCs. The link also has additional
|
||||||
// meta-data such as the current available bandwidth of the link (in satoshis)
|
// metadata such as the current available bandwidth of the link (in satoshis)
|
||||||
// which aide the switch in optimally forwarding HTLC's.
|
// which aid the switch in optimally forwarding HTLCs.
|
||||||
type link struct {
|
type link struct {
|
||||||
capacity btcutil.Amount
|
capacity btcutil.Amount
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ type circuitKey [32]byte
|
|||||||
// link forwards an HTLC add request which initiates the creation of the
|
// link forwards an HTLC add request which initiates the creation of the
|
||||||
// circuit. The onion routing information contained within this message is
|
// circuit. The onion routing information contained within this message is
|
||||||
// used to identify the settle/clear ends of the circuit. A circuit may be
|
// used to identify the settle/clear ends of the circuit. A circuit may be
|
||||||
// re-used (not torndown) in the case that multiple HTLC's with the send RHash
|
// re-used (not torndown) in the case that multiple HTLCs with the send RHash
|
||||||
// are sent.
|
// are sent.
|
||||||
type paymentCircuit struct {
|
type paymentCircuit struct {
|
||||||
// TODO(roasbeef): add reference count so know when to delete?
|
// TODO(roasbeef): add reference count so know when to delete?
|
||||||
@ -99,14 +99,14 @@ type paymentCircuit struct {
|
|||||||
settle *link
|
settle *link
|
||||||
}
|
}
|
||||||
|
|
||||||
// htlcSwitch is a central messaging bus for all incoming/outgoing HTLC's.
|
// htlcSwitch is a central messaging bus for all incoming/outgoing HTLCs.
|
||||||
// Connected peers with active channels are treated as named interfaces which
|
// Connected peers with active channels are treated as named interfaces which
|
||||||
// refer to active channels as links. A link is the switch's message
|
// refer to active channels as links. A link is the switch's message
|
||||||
// communication point with the goroutine that manages an active channel. New
|
// communication point with the goroutine that manages an active channel. New
|
||||||
// links are registered each time a channel is created, and unregistered once
|
// links are registered each time a channel is created, and unregistered once
|
||||||
// the channel is closed. The switch manages the hand-off process for multi-hop
|
// the channel is closed. The switch manages the hand-off process for multi-hop
|
||||||
// HTLC's, forwarding HTLC's initiated from within the daemon, and additionally
|
// HTLCs, forwarding HTLCs initiated from within the daemon, and additionally
|
||||||
// splitting up incoming/outgoing HTLC's to a particular interface amongst many
|
// splitting up incoming/outgoing HTLCs to a particular interface amongst many
|
||||||
// links (payment fragmentation).
|
// links (payment fragmentation).
|
||||||
// TODO(roasbeef): active sphinx circuits need to be synced to disk
|
// TODO(roasbeef): active sphinx circuits need to be synced to disk
|
||||||
type htlcSwitch struct {
|
type htlcSwitch struct {
|
||||||
@ -145,8 +145,8 @@ type htlcSwitch struct {
|
|||||||
// the RPC system.
|
// the RPC system.
|
||||||
outgoingPayments chan *htlcPacket
|
outgoingPayments chan *htlcPacket
|
||||||
|
|
||||||
// htlcPlex is the channel in which all connected links use to
|
// htlcPlex is the channel which all connected links use to
|
||||||
// coordinate the setup/tear down of Sphinx (onion routing) payment
|
// coordinate the setup/teardown of Sphinx (onion routing) payment
|
||||||
// circuits. Active links forward any add/settle messages over this
|
// circuits. Active links forward any add/settle messages over this
|
||||||
// channel each state transition, sending new adds/settles which are
|
// channel each state transition, sending new adds/settles which are
|
||||||
// fully locked in.
|
// fully locked in.
|
||||||
@ -215,12 +215,12 @@ func (h *htlcSwitch) SendHTLC(htlcPkt *htlcPacket) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// htlcForwarder is responsible for optimally forwarding (and possibly
|
// htlcForwarder is responsible for optimally forwarding (and possibly
|
||||||
// fragmenting) incoming/outgoing HTLC's amongst all active interfaces and
|
// fragmenting) incoming/outgoing HTLCs amongst all active interfaces and
|
||||||
// their links. The duties of the forwarder are similar to that of a network
|
// their links. The duties of the forwarder are similar to that of a network
|
||||||
// switch, in that it facilitates multi-hop payments by acting as a central
|
// switch, in that it facilitates multi-hop payments by acting as a central
|
||||||
// messaging bus. The switch communicates will active links to create, manage,
|
// messaging bus. The switch communicates will active links to create, manage,
|
||||||
// and tear down active onion routed payments.Each active channel is modeled
|
// and tear down active onion routed payments. Each active channel is modeled
|
||||||
// as networked device with meta-data such as the available payment bandwidth,
|
// as networked device with metadata such as the available payment bandwidth,
|
||||||
// and total link capacity.
|
// and total link capacity.
|
||||||
func (h *htlcSwitch) htlcForwarder() {
|
func (h *htlcSwitch) htlcForwarder() {
|
||||||
// TODO(roasbeef): track pending payments here instead of within each peer?
|
// TODO(roasbeef): track pending payments here instead of within each peer?
|
||||||
@ -305,7 +305,7 @@ out:
|
|||||||
hswcLog.Errorf("unable to find dest end of "+
|
hswcLog.Errorf("unable to find dest end of "+
|
||||||
"circuit: %x", nextHop)
|
"circuit: %x", nextHop)
|
||||||
|
|
||||||
// We we're unable to locate the
|
// We were unable to locate the
|
||||||
// next-hop as encoded within the
|
// next-hop as encoded within the
|
||||||
// Sphinx packet. Therefore, we send a
|
// Sphinx packet. Therefore, we send a
|
||||||
// cancellation message back to the
|
// cancellation message back to the
|
||||||
@ -435,7 +435,7 @@ out:
|
|||||||
// route. In response, we'll terminate the payment
|
// route. In response, we'll terminate the payment
|
||||||
// circuit and propagate the error backwards.
|
// circuit and propagate the error backwards.
|
||||||
case *lnwire.CancelHTLC:
|
case *lnwire.CancelHTLC:
|
||||||
// In order to properly handle the error, well
|
// In order to properly handle the error, we'll
|
||||||
// need to look up the original circuit that
|
// need to look up the original circuit that
|
||||||
// the incoming HTLC created.
|
// the incoming HTLC created.
|
||||||
circuit, ok := h.paymentCircuits[pkt.payHash]
|
circuit, ok := h.paymentCircuits[pkt.payHash]
|
||||||
@ -446,7 +446,7 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Since an outgoing HTLC we sent on the clear
|
// Since an outgoing HTLC we sent on the clear
|
||||||
// link as he cancelled, we update the
|
// link has been cancelled, we update the
|
||||||
// bandwidth of the clear link, restoring the
|
// bandwidth of the clear link, restoring the
|
||||||
// value of the HTLC worth.
|
// value of the HTLC worth.
|
||||||
n := atomic.AddInt64(&circuit.clear.availableBandwidth,
|
n := atomic.AddInt64(&circuit.clear.availableBandwidth,
|
||||||
@ -472,7 +472,7 @@ out:
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
hswcLog.Infof("Sent %v satoshis, received %v satoshi in "+
|
hswcLog.Infof("Sent %v satoshis, received %v satoshis in "+
|
||||||
"the last 10 seconds (%v tx/sec)",
|
"the last 10 seconds (%v tx/sec)",
|
||||||
satSent.ToUnit(btcutil.AmountSatoshi),
|
satSent.ToUnit(btcutil.AmountSatoshi),
|
||||||
satRecv.ToUnit(btcutil.AmountSatoshi),
|
satRecv.ToUnit(btcutil.AmountSatoshi),
|
||||||
@ -487,8 +487,8 @@ out:
|
|||||||
h.wg.Done()
|
h.wg.Done()
|
||||||
}
|
}
|
||||||
|
|
||||||
// networkAdmin is responsible for handline requests to register, unregister,
|
// networkAdmin is responsible for handling requests to register, unregister,
|
||||||
// and close any link. In the event that a unregister requests leaves an
|
// and close any link. In the event that an unregister request leaves an
|
||||||
// interface with no active links, that interface is garbage collected.
|
// interface with no active links, that interface is garbage collected.
|
||||||
func (h *htlcSwitch) networkAdmin() {
|
func (h *htlcSwitch) networkAdmin() {
|
||||||
out:
|
out:
|
||||||
@ -540,7 +540,7 @@ func (h *htlcSwitch) handleRegisterLink(req *registerLinkMsg) {
|
|||||||
|
|
||||||
// Next, update the onion index which is used to look up the
|
// Next, update the onion index which is used to look up the
|
||||||
// settle/clear links during multi-hop payments and to dispatch
|
// settle/clear links during multi-hop payments and to dispatch
|
||||||
// outgoing payments initiated by a local sub-system.
|
// outgoing payments initiated by a local subsystem.
|
||||||
var onionId [ripemd160.Size]byte
|
var onionId [ripemd160.Size]byte
|
||||||
copy(onionId[:], btcutil.Hash160(req.peer.addr.IdentityKey.SerializeCompressed()))
|
copy(onionId[:], btcutil.Hash160(req.peer.addr.IdentityKey.SerializeCompressed()))
|
||||||
|
|
||||||
@ -614,8 +614,8 @@ func (h *htlcSwitch) handleUnregisterLink(req *unregisterLinkMsg) {
|
|||||||
hex.EncodeToString(chanInterface[:]))
|
hex.EncodeToString(chanInterface[:]))
|
||||||
|
|
||||||
// Delete the peer from the onion index so that the
|
// Delete the peer from the onion index so that the
|
||||||
// htlcForwarder knows not attempt to forward any further
|
// htlcForwarder knows not to attempt to forward any further
|
||||||
// HTLC's in this direction.
|
// HTLCs in this direction.
|
||||||
var onionId [ripemd160.Size]byte
|
var onionId [ripemd160.Size]byte
|
||||||
copy(onionId[:], btcutil.Hash160(req.remoteID))
|
copy(onionId[:], btcutil.Hash160(req.remoteID))
|
||||||
delete(h.onionIndex, onionId)
|
delete(h.onionIndex, onionId)
|
||||||
@ -655,7 +655,7 @@ func (h *htlcSwitch) handleCloseLink(req *closeLinkReq) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handleLinkUpdate processes the link info update message by adjusting the
|
// handleLinkUpdate processes the link info update message by adjusting the
|
||||||
// channels available bandwidth by the delta specified within the message.
|
// channel's available bandwidth by the delta specified within the message.
|
||||||
func (h *htlcSwitch) handleLinkUpdate(req *linkInfoUpdateMsg) {
|
func (h *htlcSwitch) handleLinkUpdate(req *linkInfoUpdateMsg) {
|
||||||
h.chanIndexMtx.RLock()
|
h.chanIndexMtx.RLock()
|
||||||
link := h.chanIndex[*req.targetLink]
|
link := h.chanIndex[*req.targetLink]
|
||||||
@ -708,9 +708,9 @@ type unregisterLinkMsg struct {
|
|||||||
done chan struct{}
|
done chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnregisterLink requets the htlcSwitch to register the new active link. An
|
// UnregisterLink requests the htlcSwitch to register the new active link. An
|
||||||
// unregistered link will no longer be considered a candidate to forward
|
// unregistered link will no longer be considered a candidate to forward
|
||||||
// HTLC's.
|
// HTLCs.
|
||||||
func (h *htlcSwitch) UnregisterLink(remotePub *btcec.PublicKey, chanPoint *wire.OutPoint) {
|
func (h *htlcSwitch) UnregisterLink(remotePub *btcec.PublicKey, chanPoint *wire.OutPoint) {
|
||||||
done := make(chan struct{}, 1)
|
done := make(chan struct{}, 1)
|
||||||
rawPub := remotePub.SerializeCompressed()
|
rawPub := remotePub.SerializeCompressed()
|
||||||
@ -725,7 +725,7 @@ func (h *htlcSwitch) UnregisterLink(remotePub *btcec.PublicKey, chanPoint *wire.
|
|||||||
<-done
|
<-done
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinkCloseType is a enum which signals the type of channel closure the switch
|
// LinkCloseType is an enum which signals the type of channel closure the switch
|
||||||
// should execute.
|
// should execute.
|
||||||
type LinkCloseType uint8
|
type LinkCloseType uint8
|
||||||
|
|
||||||
@ -734,7 +734,7 @@ const (
|
|||||||
// be attempted.
|
// be attempted.
|
||||||
CloseRegular LinkCloseType = iota
|
CloseRegular LinkCloseType = iota
|
||||||
|
|
||||||
// CloseBreach indicates that a channel breach has been dtected, and
|
// CloseBreach indicates that a channel breach has been detected, and
|
||||||
// the link should immediately be marked as unavailable.
|
// the link should immediately be marked as unavailable.
|
||||||
CloseBreach
|
CloseBreach
|
||||||
)
|
)
|
||||||
@ -750,7 +750,7 @@ type closeLinkReq struct {
|
|||||||
err chan error
|
err chan error
|
||||||
}
|
}
|
||||||
|
|
||||||
// CloseLink closes an active link targetted by it's channel point. Closing the
|
// CloseLink closes an active link targetted by its channel point. Closing the
|
||||||
// link initiates a cooperative channel closure iff forceClose is false. If
|
// link initiates a cooperative channel closure iff forceClose is false. If
|
||||||
// forceClose is true, then a unilateral channel closure is executed.
|
// forceClose is true, then a unilateral channel closure is executed.
|
||||||
// TODO(roasbeef): consolidate with UnregisterLink?
|
// TODO(roasbeef): consolidate with UnregisterLink?
|
||||||
@ -771,7 +771,7 @@ func (h *htlcSwitch) CloseLink(chanPoint *wire.OutPoint,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// linkInfoUpdateMsg encapsulates a request for the htlc switch to update the
|
// linkInfoUpdateMsg encapsulates a request for the htlc switch to update the
|
||||||
// meta-data related to the target link.
|
// metadata related to the target link.
|
||||||
type linkInfoUpdateMsg struct {
|
type linkInfoUpdateMsg struct {
|
||||||
targetLink *wire.OutPoint
|
targetLink *wire.OutPoint
|
||||||
|
|
||||||
|
@ -15,8 +15,8 @@ import (
|
|||||||
var (
|
var (
|
||||||
// debugPre is the default debug preimage which is inserted into the
|
// debugPre is the default debug preimage which is inserted into the
|
||||||
// invoice registry if the --debughtlc flag is activated on start up.
|
// invoice registry if the --debughtlc flag is activated on start up.
|
||||||
// All nodes initialize with the flag active will immediately settle
|
// All nodes initialized with the flag active will immediately settle
|
||||||
// any incoming HTLC whose rHash is corresponds with the debug
|
// any incoming HTLC whose rHash corresponds with the debug
|
||||||
// preimage.
|
// preimage.
|
||||||
debugPre, _ = chainhash.NewHash(bytes.Repeat([]byte{1}, 32))
|
debugPre, _ = chainhash.NewHash(bytes.Repeat([]byte{1}, 32))
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ type invoiceRegistry struct {
|
|||||||
nextClientID uint32
|
nextClientID uint32
|
||||||
notificationClients map[uint32]*invoiceSubscription
|
notificationClients map[uint32]*invoiceSubscription
|
||||||
|
|
||||||
// debugInvoices is a mp which stores special "debug" invoices which
|
// debugInvoices is a map which stores special "debug" invoices which
|
||||||
// should be only created/used when manual tests require an invoice
|
// should be only created/used when manual tests require an invoice
|
||||||
// that *all* nodes are able to fully settle.
|
// that *all* nodes are able to fully settle.
|
||||||
debugInvoices map[chainhash.Hash]*channeldb.Invoice
|
debugInvoices map[chainhash.Hash]*channeldb.Invoice
|
||||||
@ -43,7 +43,7 @@ type invoiceRegistry struct {
|
|||||||
|
|
||||||
// newInvoiceRegistry creates a new invoice registry. The invoice registry
|
// newInvoiceRegistry creates a new invoice registry. The invoice registry
|
||||||
// wraps the persistent on-disk invoice storage with an additional in-memory
|
// wraps the persistent on-disk invoice storage with an additional in-memory
|
||||||
// layer. The in-memory layer is in pace such that debug invoices can be added
|
// layer. The in-memory layer is in place such that debug invoices can be added
|
||||||
// which are volatile yet available system wide within the daemon.
|
// which are volatile yet available system wide within the daemon.
|
||||||
func newInvoiceRegistry(cdb *channeldb.DB) *invoiceRegistry {
|
func newInvoiceRegistry(cdb *channeldb.DB) *invoiceRegistry {
|
||||||
return &invoiceRegistry{
|
return &invoiceRegistry{
|
||||||
@ -54,8 +54,8 @@ func newInvoiceRegistry(cdb *channeldb.DB) *invoiceRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// addDebugInvoice adds a debug invoice for the specified amount, identified
|
// addDebugInvoice adds a debug invoice for the specified amount, identified
|
||||||
// by the passed preimage. Once this invoice is added, sub-systems within the
|
// by the passed preimage. Once this invoice is added, subsystems within the
|
||||||
// daemon add/forward HTLC's are able to obtain the proper preimage required
|
// daemon add/forward HTLCs are able to obtain the proper preimage required
|
||||||
// for redemption in the case that we're the final destination.
|
// for redemption in the case that we're the final destination.
|
||||||
func (i *invoiceRegistry) AddDebugInvoice(amt btcutil.Amount, preimage chainhash.Hash) {
|
func (i *invoiceRegistry) AddDebugInvoice(amt btcutil.Amount, preimage chainhash.Hash) {
|
||||||
paymentHash := chainhash.Hash(fastsha256.Sum256(preimage[:]))
|
paymentHash := chainhash.Hash(fastsha256.Sum256(preimage[:]))
|
||||||
@ -78,9 +78,9 @@ func (i *invoiceRegistry) AddDebugInvoice(amt btcutil.Amount, preimage chainhash
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AddInvoice adds a regular invoice for the specified amount, identified by
|
// AddInvoice adds a regular invoice for the specified amount, identified by
|
||||||
// the passed preimage. Additionally, any memo or recipt data provided will
|
// the passed preimage. Additionally, any memo or receipt data provided will
|
||||||
// also be stored on-disk. Once this invoice is added, sub-systems within the
|
// also be stored on-disk. Once this invoice is added, subsystems within the
|
||||||
// daemon add/forward HTLC's are able to obtain the proper preimage required
|
// daemon add/forward HTLCs are able to obtain the proper preimage required
|
||||||
// for redemption in the case that we're the final destination.
|
// for redemption in the case that we're the final destination.
|
||||||
func (i *invoiceRegistry) AddInvoice(invoice *channeldb.Invoice) error {
|
func (i *invoiceRegistry) AddInvoice(invoice *channeldb.Invoice) error {
|
||||||
ltndLog.Debugf("Adding invoice %v", newLogClosure(func() string {
|
ltndLog.Debugf("Adding invoice %v", newLogClosure(func() string {
|
||||||
@ -98,7 +98,7 @@ func (i *invoiceRegistry) AddInvoice(invoice *channeldb.Invoice) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// lookupInvoice looks up an invoice by it's payment hash (R-Hash), if found
|
// lookupInvoice looks up an invoice by its payment hash (R-Hash), if found
|
||||||
// then we're able to pull the funds pending within an HTLC.
|
// then we're able to pull the funds pending within an HTLC.
|
||||||
// TODO(roasbeef): ignore if settled?
|
// TODO(roasbeef): ignore if settled?
|
||||||
func (i *invoiceRegistry) LookupInvoice(rHash chainhash.Hash) (*channeldb.Invoice, error) {
|
func (i *invoiceRegistry) LookupInvoice(rHash chainhash.Hash) (*channeldb.Invoice, error) {
|
||||||
@ -119,7 +119,7 @@ func (i *invoiceRegistry) LookupInvoice(rHash chainhash.Hash) (*channeldb.Invoic
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SettleInvoice attempts to mark an invoice as settled. If the invoice is a
|
// SettleInvoice attempts to mark an invoice as settled. If the invoice is a
|
||||||
// dbueg invoice, then this method is a nooop as debug invoices are never fully
|
// debug invoice, then this method is a noop as debug invoices are never fully
|
||||||
// settled.
|
// settled.
|
||||||
func (i *invoiceRegistry) SettleInvoice(rHash chainhash.Hash) error {
|
func (i *invoiceRegistry) SettleInvoice(rHash chainhash.Hash) error {
|
||||||
ltndLog.Debugf("Settling invoice %x", rHash[:])
|
ltndLog.Debugf("Settling invoice %x", rHash[:])
|
||||||
@ -192,7 +192,7 @@ type invoiceSubscription struct {
|
|||||||
id uint32
|
id uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cancel unregisters the invoiceSubscription, freeing any previously allocate
|
// Cancel unregisters the invoiceSubscription, freeing any previously allocated
|
||||||
// resources.
|
// resources.
|
||||||
func (i *invoiceSubscription) Cancel() {
|
func (i *invoiceSubscription) Cancel() {
|
||||||
i.inv.clientMtx.Lock()
|
i.inv.clientMtx.Lock()
|
||||||
|
2
lnd.go
2
lnd.go
@ -60,7 +60,7 @@ func lndMain() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Open the channeldb, which is dedicated to storing channel, and
|
// Open the channeldb, which is dedicated to storing channel, and
|
||||||
// network related meta-data.
|
// network related metadata.
|
||||||
chanDB, err := channeldb.Open(cfg.DataDir)
|
chanDB, err := channeldb.Open(cfg.DataDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("unable to open channeldb: ", err)
|
fmt.Println("unable to open channeldb: ", err)
|
||||||
|
14
lnd_test.go
14
lnd_test.go
@ -33,7 +33,7 @@ import (
|
|||||||
|
|
||||||
// harnessTest wraps a regular testing.T providing enhanced error detection
|
// harnessTest wraps a regular testing.T providing enhanced error detection
|
||||||
// and propagation. All error will be augmented with a full stack-trace in
|
// and propagation. All error will be augmented with a full stack-trace in
|
||||||
// order to aide in debugging. Additionally, any panics caused by active
|
// order to aid in debugging. Additionally, any panics caused by active
|
||||||
// test cases will also be handled and represented as fatals.
|
// test cases will also be handled and represented as fatals.
|
||||||
type harnessTest struct {
|
type harnessTest struct {
|
||||||
t *testing.T
|
t *testing.T
|
||||||
@ -49,8 +49,8 @@ func newHarnessTest(t *testing.T) *harnessTest {
|
|||||||
return &harnessTest{t, nil}
|
return &harnessTest{t, nil}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fatalf causes the current active test-case to fail with a fatal error. All
|
// Fatalf causes the current active test case to fail with a fatal error. All
|
||||||
// integration tests should mark test failures soley with this method due to
|
// integration tests should mark test failures solely with this method due to
|
||||||
// the error stack traces it produces.
|
// the error stack traces it produces.
|
||||||
func (h *harnessTest) Fatalf(format string, a ...interface{}) {
|
func (h *harnessTest) Fatalf(format string, a ...interface{}) {
|
||||||
stacktrace := errors.Wrap(fmt.Sprintf(format, a...), 1).ErrorStack()
|
stacktrace := errors.Wrap(fmt.Sprintf(format, a...), 1).ErrorStack()
|
||||||
@ -63,7 +63,7 @@ func (h *harnessTest) Fatalf(format string, a ...interface{}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunTestCase executes a harness test-case. Any errors or panics will be
|
// RunTestCase executes a harness test case. Any errors or panics will be
|
||||||
// represented as fatal.
|
// represented as fatal.
|
||||||
func (h *harnessTest) RunTestCase(testCase *testCase, net *networkHarness) {
|
func (h *harnessTest) RunTestCase(testCase *testCase, net *networkHarness) {
|
||||||
h.testCase = testCase
|
h.testCase = testCase
|
||||||
@ -516,7 +516,7 @@ func testSingleHopInvoice(net *networkHarness, t *harnessTest) {
|
|||||||
|
|
||||||
// Now that the channel is open, create an invoice for Bob which
|
// Now that the channel is open, create an invoice for Bob which
|
||||||
// expects a payment of 1000 satoshis from Alice paid via a particular
|
// expects a payment of 1000 satoshis from Alice paid via a particular
|
||||||
// pre-image.
|
// preimage.
|
||||||
const paymentAmt = 1000
|
const paymentAmt = 1000
|
||||||
preimage := bytes.Repeat([]byte("A"), 32)
|
preimage := bytes.Repeat([]byte("A"), 32)
|
||||||
invoice := &lnrpc.Invoice{
|
invoice := &lnrpc.Invoice{
|
||||||
@ -628,7 +628,7 @@ func testListPayments(net *networkHarness, t *harnessTest) {
|
|||||||
|
|
||||||
// Now that the channel is open, create an invoice for Bob which
|
// Now that the channel is open, create an invoice for Bob which
|
||||||
// expects a payment of 1000 satoshis from Alice paid via a particular
|
// expects a payment of 1000 satoshis from Alice paid via a particular
|
||||||
// pre-image.
|
// preimage.
|
||||||
const paymentAmt = 1000
|
const paymentAmt = 1000
|
||||||
preimage := bytes.Repeat([]byte("B"), 32)
|
preimage := bytes.Repeat([]byte("B"), 32)
|
||||||
invoice := &lnrpc.Invoice{
|
invoice := &lnrpc.Invoice{
|
||||||
@ -870,7 +870,7 @@ func testMultiHopPayments(net *networkHarness, t *harnessTest) {
|
|||||||
|
|
||||||
select {
|
select {
|
||||||
case <-time.After(time.Second * 10):
|
case <-time.After(time.Second * 10):
|
||||||
t.Fatalf("HTLC's not cleared after 10 seconds")
|
t.Fatalf("HTLCs not cleared after 10 seconds")
|
||||||
case <-finClear:
|
case <-finClear:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ func (b *BtcWallet) GetBlock(blockHash *chainhash.Hash) (*wire.MsgBlock, error)
|
|||||||
return block, nil
|
return block, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBlockHash returns the hash of the block in the best block chain at the
|
// GetBlockHash returns the hash of the block in the best blockchain at the
|
||||||
// given height.
|
// given height.
|
||||||
//
|
//
|
||||||
// This method is a part of the lnwallet.BlockChainIO interface.
|
// This method is a part of the lnwallet.BlockChainIO interface.
|
||||||
|
@ -33,7 +33,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// MaxPendingPayments is the max number of pending HTLC's permitted on
|
// MaxPendingPayments is the max number of pending HTLCs permitted on
|
||||||
// a channel.
|
// a channel.
|
||||||
// TODO(roasbeef): make not random value + enforce
|
// TODO(roasbeef): make not random value + enforce
|
||||||
// * should be tuned to account for max tx "cost"
|
// * should be tuned to account for max tx "cost"
|
||||||
@ -66,7 +66,7 @@ const (
|
|||||||
channelClosing
|
channelClosing
|
||||||
|
|
||||||
// channelClosed represents a channel which has been fully closed. Note
|
// channelClosed represents a channel which has been fully closed. Note
|
||||||
// that before a channel can be closed, ALL pending HTLC's must be
|
// that before a channel can be closed, ALL pending HTLCs must be
|
||||||
// settled/removed.
|
// settled/removed.
|
||||||
channelClosed
|
channelClosed
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ const (
|
|||||||
channelDispute
|
channelDispute
|
||||||
|
|
||||||
// channelPendingPayment indicates that there a currently outstanding
|
// channelPendingPayment indicates that there a currently outstanding
|
||||||
// HTLC's within the channel.
|
// HTLCs within the channel.
|
||||||
channelPendingPayment
|
channelPendingPayment
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ const (
|
|||||||
|
|
||||||
// PaymentDescriptor represents a commitment state update which either adds,
|
// PaymentDescriptor represents a commitment state update which either adds,
|
||||||
// settles, or removes an HTLC. PaymentDescriptors encapsulate all necessary
|
// settles, or removes an HTLC. PaymentDescriptors encapsulate all necessary
|
||||||
// meta-data w.r.t to an HTLC, and additional data pairing a settle message to
|
// metadata w.r.t to an HTLC, and additional data pairing a settle message to
|
||||||
// the original added HTLC.
|
// the original added HTLC.
|
||||||
// TODO(roasbeef): LogEntry interface??
|
// TODO(roasbeef): LogEntry interface??
|
||||||
// * need to separate attrs for cancel/add/settle
|
// * need to separate attrs for cancel/add/settle
|
||||||
@ -197,7 +197,7 @@ type commitment struct {
|
|||||||
ourBalance btcutil.Amount
|
ourBalance btcutil.Amount
|
||||||
theirBalance btcutil.Amount
|
theirBalance btcutil.Amount
|
||||||
|
|
||||||
// htlcs is the set of HTLC's which remain unsettled within this
|
// htlcs is the set of HTLCs which remain unsettled within this
|
||||||
// commitment.
|
// commitment.
|
||||||
outgoingHTLCs []*PaymentDescriptor
|
outgoingHTLCs []*PaymentDescriptor
|
||||||
incomingHTLCs []*PaymentDescriptor
|
incomingHTLCs []*PaymentDescriptor
|
||||||
@ -377,7 +377,7 @@ type LightningChannel struct {
|
|||||||
|
|
||||||
// revocationWindow is a window of revocations sent to use by the
|
// revocationWindow is a window of revocations sent to use by the
|
||||||
// remote party, allowing us to create new commitment transactions
|
// remote party, allowing us to create new commitment transactions
|
||||||
// until depleted. The revocations don't contain a valid pre-image,
|
// until depleted. The revocations don't contain a valid preimage,
|
||||||
// only an additional key/hash allowing us to create a new commitment
|
// only an additional key/hash allowing us to create a new commitment
|
||||||
// transaction for the remote node that they are able to revoke. If
|
// transaction for the remote node that they are able to revoke. If
|
||||||
// this slice is empty, then we cannot make any new updates to their
|
// this slice is empty, then we cannot make any new updates to their
|
||||||
@ -430,7 +430,7 @@ type LightningChannel struct {
|
|||||||
// ContractBreach is a channel that is used to communicate the data
|
// ContractBreach is a channel that is used to communicate the data
|
||||||
// necessary to fully resolve the channel in the case that a contract
|
// necessary to fully resolve the channel in the case that a contract
|
||||||
// breach is detected. A contract breach occurs it is detected that the
|
// breach is detected. A contract breach occurs it is detected that the
|
||||||
// counter party has broadcast a prior *revoked* state.
|
// counterparty has broadcast a prior *revoked* state.
|
||||||
ContractBreach chan *BreachRetribution
|
ContractBreach chan *BreachRetribution
|
||||||
|
|
||||||
// LocalFundingKey is the public key under control by the wallet that
|
// LocalFundingKey is the public key under control by the wallet that
|
||||||
@ -540,7 +540,7 @@ func NewLightningChannel(signer Signer, bio BlockChainIO,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BreachRetribution contains all the data necessary to bring a channel
|
// BreachRetribution contains all the data necessary to bring a channel
|
||||||
// counter-party to justice claiming ALL lingering funds within the channel in
|
// counterparty to justice claiming ALL lingering funds within the channel in
|
||||||
// the scenario that they broadcast a revoked commitment transaction. A
|
// the scenario that they broadcast a revoked commitment transaction. A
|
||||||
// BreachRetribution is created by the closeObserver if it detects an
|
// BreachRetribution is created by the closeObserver if it detects an
|
||||||
// uncooperative close of the channel which uses a revoked commitment
|
// uncooperative close of the channel which uses a revoked commitment
|
||||||
@ -555,7 +555,7 @@ type BreachRetribution struct {
|
|||||||
// RevokedStateNum is the revoked state number which was broadcast.
|
// RevokedStateNum is the revoked state number which was broadcast.
|
||||||
RevokedStateNum uint64
|
RevokedStateNum uint64
|
||||||
|
|
||||||
// PendingHTLCs is a slice of the HTLC's which were pending at this
|
// PendingHTLCs is a slice of the HTLCs which were pending at this
|
||||||
// point within the channel's history transcript.
|
// point within the channel's history transcript.
|
||||||
PendingHTLCs []*channeldb.HTLC
|
PendingHTLCs []*channeldb.HTLC
|
||||||
|
|
||||||
@ -680,7 +680,7 @@ func newBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64,
|
|||||||
// the following three scenarios: a cooperative close, a unilateral close, and
|
// the following three scenarios: a cooperative close, a unilateral close, and
|
||||||
// a uncooperative contract breaching close. In the case of the last scenario a
|
// a uncooperative contract breaching close. In the case of the last scenario a
|
||||||
// BreachRetribution struct is created and sent over the ContractBreach channel
|
// BreachRetribution struct is created and sent over the ContractBreach channel
|
||||||
// notifying subscribers that the counter-party has violated the condition of
|
// notifying subscribers that the counterparty has violated the condition of
|
||||||
// the channel by broadcasting a revoked prior state.
|
// the channel by broadcasting a revoked prior state.
|
||||||
//
|
//
|
||||||
// NOTE: This MUST be run as a goroutine.
|
// NOTE: This MUST be run as a goroutine.
|
||||||
@ -772,7 +772,7 @@ func (lc *LightningChannel) closeObserver(channelCloseNtfn *chainntnfs.SpendEven
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// restoreStateLogs runs through the current locked-in HTLC's from the point of
|
// restoreStateLogs runs through the current locked-in HTLCs from the point of
|
||||||
// view of the channel and insert corresponding log entries (both local and
|
// view of the channel and insert corresponding log entries (both local and
|
||||||
// remote) for each HTLC read from disk. This method is required sync the
|
// remote) for each HTLC read from disk. This method is required sync the
|
||||||
// in-memory state of the state machine with that read from persistent storage.
|
// in-memory state of the state machine with that read from persistent storage.
|
||||||
@ -820,7 +820,7 @@ func (lc *LightningChannel) restoreStateLogs() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// htlcView represents the "active" HTLC's at a particular point within the
|
// htlcView represents the "active" HTLCs at a particular point within the
|
||||||
// history of the HTLC update log.
|
// history of the HTLC update log.
|
||||||
type htlcView struct {
|
type htlcView struct {
|
||||||
ourUpdates []*PaymentDescriptor
|
ourUpdates []*PaymentDescriptor
|
||||||
@ -890,7 +890,7 @@ func (lc *LightningChannel) fetchCommitmentView(remoteChain bool,
|
|||||||
|
|
||||||
nextHeight := commitChain.tip().height + 1
|
nextHeight := commitChain.tip().height + 1
|
||||||
|
|
||||||
// Run through all the HTLC's that will be covered by this transaction
|
// Run through all the HTLCs that will be covered by this transaction
|
||||||
// in order to update their commitment addition height, and to adjust
|
// in order to update their commitment addition height, and to adjust
|
||||||
// the balances on the commitment transaction accordingly.
|
// the balances on the commitment transaction accordingly.
|
||||||
// TODO(roasbeef): error if log empty?
|
// TODO(roasbeef): error if log empty?
|
||||||
@ -919,7 +919,7 @@ func (lc *LightningChannel) fetchCommitmentView(remoteChain bool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate a new commitment transaction with all the latest
|
// Generate a new commitment transaction with all the latest
|
||||||
// unsettled/un-timed out HTLC's.
|
// unsettled/un-timed out HTLCs.
|
||||||
ourCommitTx := !remoteChain
|
ourCommitTx := !remoteChain
|
||||||
commitTx, err := CreateCommitTx(lc.fundingTxIn, selfKey, remoteKey,
|
commitTx, err := CreateCommitTx(lc.fundingTxIn, selfKey, remoteKey,
|
||||||
revocationKey, delay, delayBalance, p2wkhBalance)
|
revocationKey, delay, delayBalance, p2wkhBalance)
|
||||||
@ -978,7 +978,7 @@ func (lc *LightningChannel) fetchCommitmentView(remoteChain bool,
|
|||||||
// evaluateHTLCView processes all update entries in both HTLC update logs,
|
// evaluateHTLCView processes all update entries in both HTLC update logs,
|
||||||
// producing a final view which is the result of properly applying all adds,
|
// producing a final view which is the result of properly applying all adds,
|
||||||
// settles, and timeouts found in both logs. The resulting view returned
|
// settles, and timeouts found in both logs. The resulting view returned
|
||||||
// reflects the current state of htlc's within the remote or local commitment
|
// reflects the current state of HTLCs within the remote or local commitment
|
||||||
// chain.
|
// chain.
|
||||||
func (lc *LightningChannel) evaluateHTLCView(view *htlcView, ourBalance,
|
func (lc *LightningChannel) evaluateHTLCView(view *htlcView, ourBalance,
|
||||||
theirBalance *btcutil.Amount, nextHeight uint64, remoteChain bool) *htlcView {
|
theirBalance *btcutil.Amount, nextHeight uint64, remoteChain bool) *htlcView {
|
||||||
@ -1025,8 +1025,8 @@ func (lc *LightningChannel) evaluateHTLCView(view *htlcView, ourBalance,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Next we take a second pass through all the log entries, skipping any
|
// Next we take a second pass through all the log entries, skipping any
|
||||||
// settled HTLC's, and debiting the chain state balance due to any
|
// settled HTLCs, and debiting the chain state balance due to any
|
||||||
// newly added HTLC's.
|
// newly added HTLCs.
|
||||||
for _, entry := range view.ourUpdates {
|
for _, entry := range view.ourUpdates {
|
||||||
isAdd := entry.EntryType == Add
|
isAdd := entry.EntryType == Add
|
||||||
if _, ok := skipUs[entry.Index]; !isAdd || ok {
|
if _, ok := skipUs[entry.Index]; !isAdd || ok {
|
||||||
@ -1108,7 +1108,7 @@ func processRemoveEntry(htlc *PaymentDescriptor, ourBalance,
|
|||||||
|
|
||||||
switch {
|
switch {
|
||||||
// If an incoming HTLC is being settled, then this means that we've
|
// If an incoming HTLC is being settled, then this means that we've
|
||||||
// received the preimage either from another sub-system, or the
|
// received the preimage either from another subsystem, or the
|
||||||
// upstream peer in the route. Therefore, we increase our balance by
|
// upstream peer in the route. Therefore, we increase our balance by
|
||||||
// the HTLC amount.
|
// the HTLC amount.
|
||||||
case isIncoming && htlc.EntryType == Settle:
|
case isIncoming && htlc.EntryType == Settle:
|
||||||
@ -1123,7 +1123,7 @@ func processRemoveEntry(htlc *PaymentDescriptor, ourBalance,
|
|||||||
// the value of the HTLC.
|
// the value of the HTLC.
|
||||||
case !isIncoming && htlc.EntryType == Settle:
|
case !isIncoming && htlc.EntryType == Settle:
|
||||||
*theirBalance += htlc.Amount
|
*theirBalance += htlc.Amount
|
||||||
// Otherwise, one of our outgoing HTLC's has been cancelled, so the
|
// Otherwise, one of our outgoing HTLCs has been cancelled, so the
|
||||||
// value of the HTLC should be returned to our settled balance.
|
// value of the HTLC should be returned to our settled balance.
|
||||||
case !isIncoming && htlc.EntryType == Cancel:
|
case !isIncoming && htlc.EntryType == Cancel:
|
||||||
*ourBalance += htlc.Amount
|
*ourBalance += htlc.Amount
|
||||||
@ -1164,7 +1164,7 @@ func (lc *LightningChannel) SignNextCommitment() ([]byte, uint32, error) {
|
|||||||
|
|
||||||
// Create a new commitment view which will calculate the evaluated
|
// Create a new commitment view which will calculate the evaluated
|
||||||
// state of the remote node's new commitment including our latest added
|
// state of the remote node's new commitment including our latest added
|
||||||
// HTLC's. The view includes the latest balances for both sides on the
|
// HTLCs. The view includes the latest balances for both sides on the
|
||||||
// remote node's chain, and also update the addition height of any new
|
// remote node's chain, and also update the addition height of any new
|
||||||
// HTLC log entries.
|
// HTLC log entries.
|
||||||
newCommitView, err := lc.fetchCommitmentView(true, lc.ourLogCounter,
|
newCommitView, err := lc.fetchCommitmentView(true, lc.ourLogCounter,
|
||||||
@ -1218,7 +1218,7 @@ func (lc *LightningChannel) validateCommitmentSanity(theirLogCounter,
|
|||||||
htlcCount++
|
htlcCount++
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run through all the HTLC's that will be covered by this transaction
|
// Run through all the HTLCs that will be covered by this transaction
|
||||||
// in order to calculate theirs count.
|
// in order to calculate theirs count.
|
||||||
htlcView := lc.fetchHTLCView(theirLogCounter, ourLogCounter)
|
htlcView := lc.fetchHTLCView(theirLogCounter, ourLogCounter)
|
||||||
|
|
||||||
@ -1305,7 +1305,7 @@ func (lc *LightningChannel) ReceiveNewCommitment(rawSig []byte,
|
|||||||
sigHash, err := txscript.CalcWitnessSigHash(multiSigScript, hashCache,
|
sigHash, err := txscript.CalcWitnessSigHash(multiSigScript, hashCache,
|
||||||
txscript.SigHashAll, localCommitTx, 0, int64(lc.channelState.Capacity))
|
txscript.SigHashAll, localCommitTx, 0, int64(lc.channelState.Capacity))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO(roasbeef): fetchview has already mutated the htlc's...
|
// TODO(roasbeef): fetchview has already mutated the HTLCs...
|
||||||
// * need to either roll-back, or make pure
|
// * need to either roll-back, or make pure
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1409,12 +1409,12 @@ func (lc *LightningChannel) RevokeCurrentCommitment() (*lnwire.CommitRevocation,
|
|||||||
// windows are extended, or in response to a state update that we initiate. If
|
// windows are extended, or in response to a state update that we initiate. If
|
||||||
// successful, then the remote commitment chain is advanced by a single
|
// successful, then the remote commitment chain is advanced by a single
|
||||||
// commitment, and a log compaction is attempted. In addition, a slice of
|
// commitment, and a log compaction is attempted. In addition, a slice of
|
||||||
// HTLC's which can be forwarded upstream are returned.
|
// HTLCs which can be forwarded upstream are returned.
|
||||||
func (lc *LightningChannel) ReceiveRevocation(revMsg *lnwire.CommitRevocation) ([]*PaymentDescriptor, error) {
|
func (lc *LightningChannel) ReceiveRevocation(revMsg *lnwire.CommitRevocation) ([]*PaymentDescriptor, error) {
|
||||||
lc.Lock()
|
lc.Lock()
|
||||||
defer lc.Unlock()
|
defer lc.Unlock()
|
||||||
|
|
||||||
// The revocation has a nil (zero) pre-image, then this should simply be
|
// The revocation has a nil (zero) preimage, then this should simply be
|
||||||
// added to the end of the revocation window for the remote node.
|
// added to the end of the revocation window for the remote node.
|
||||||
if bytes.Equal(zeroHash[:], revMsg.Revocation[:]) {
|
if bytes.Equal(zeroHash[:], revMsg.Revocation[:]) {
|
||||||
lc.revocationWindow = append(lc.revocationWindow, revMsg)
|
lc.revocationWindow = append(lc.revocationWindow, revMsg)
|
||||||
@ -1425,7 +1425,7 @@ func (lc *LightningChannel) ReceiveRevocation(revMsg *lnwire.CommitRevocation) (
|
|||||||
currentRevocationKey := lc.channelState.TheirCurrentRevocation
|
currentRevocationKey := lc.channelState.TheirCurrentRevocation
|
||||||
pendingRevocation := chainhash.Hash(revMsg.Revocation)
|
pendingRevocation := chainhash.Hash(revMsg.Revocation)
|
||||||
|
|
||||||
// Ensure the new pre-image fits in properly within the elkrem receiver
|
// Ensure the new preimage fits in properly within the elkrem receiver
|
||||||
// tree. If this fails, then all other checks are skipped.
|
// tree. If this fails, then all other checks are skipped.
|
||||||
// TODO(rosbeef): abstract into func
|
// TODO(rosbeef): abstract into func
|
||||||
remoteElkrem := lc.channelState.RemoteElkrem
|
remoteElkrem := lc.channelState.RemoteElkrem
|
||||||
@ -1434,15 +1434,15 @@ func (lc *LightningChannel) ReceiveRevocation(revMsg *lnwire.CommitRevocation) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify that the revocation public key we can derive using this
|
// Verify that the revocation public key we can derive using this
|
||||||
// pre-image and our private key is identical to the revocation key we
|
// preimage and our private key is identical to the revocation key we
|
||||||
// were given for their current (prior) commitment transaction.
|
// were given for their current (prior) commitment transaction.
|
||||||
revocationPub := DeriveRevocationPubkey(ourCommitKey, pendingRevocation[:])
|
revocationPub := DeriveRevocationPubkey(ourCommitKey, pendingRevocation[:])
|
||||||
if !revocationPub.IsEqual(currentRevocationKey) {
|
if !revocationPub.IsEqual(currentRevocationKey) {
|
||||||
return nil, fmt.Errorf("revocation key mismatch")
|
return nil, fmt.Errorf("revocation key mismatch")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Additionally, we need to ensure we were given the proper pre-image
|
// Additionally, we need to ensure we were given the proper preimage
|
||||||
// to the revocation hash used within any current HTLC's.
|
// to the revocation hash used within any current HTLCs.
|
||||||
if !bytes.Equal(lc.channelState.TheirCurrentRevocationHash[:], zeroHash[:]) {
|
if !bytes.Equal(lc.channelState.TheirCurrentRevocationHash[:], zeroHash[:]) {
|
||||||
revokeHash := fastsha256.Sum256(pendingRevocation[:])
|
revokeHash := fastsha256.Sum256(pendingRevocation[:])
|
||||||
// TODO(roasbeef): rename to drop the "Their"
|
// TODO(roasbeef): rename to drop the "Their"
|
||||||
@ -1497,7 +1497,7 @@ func (lc *LightningChannel) ReceiveRevocation(revMsg *lnwire.CommitRevocation) (
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(roasbeef): re-visit after adding persistence to HTLC's
|
// TODO(roasbeef): re-visit after adding persistence to HTLCs
|
||||||
// * either record add height, or set to N - 1
|
// * either record add height, or set to N - 1
|
||||||
uncomitted := (htlc.addCommitHeightRemote == 0 ||
|
uncomitted := (htlc.addCommitHeightRemote == 0 ||
|
||||||
htlc.addCommitHeightLocal == 0)
|
htlc.addCommitHeightLocal == 0)
|
||||||
@ -1524,9 +1524,9 @@ func (lc *LightningChannel) ReceiveRevocation(revMsg *lnwire.CommitRevocation) (
|
|||||||
return htlcsToForward, nil
|
return htlcsToForward, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// compactLogs performs garbage collection within the log removing HTLC's which
|
// compactLogs performs garbage collection within the log removing HTLCs which
|
||||||
// have been removed from the point-of-view of the tail of both chains. The
|
// have been removed from the point-of-view of the tail of both chains. The
|
||||||
// entries which timeout/settle HTLC's are also removed.
|
// entries which timeout/settle HTLCs are also removed.
|
||||||
func (lc *LightningChannel) compactLogs(ourLog, theirLog *list.List,
|
func (lc *LightningChannel) compactLogs(ourLog, theirLog *list.List,
|
||||||
localChainTail, remoteChainTail uint64) {
|
localChainTail, remoteChainTail uint64) {
|
||||||
|
|
||||||
@ -1654,7 +1654,7 @@ func (lc *LightningChannel) ReceiveHTLC(htlc *lnwire.HTLCAddRequest) (uint32, er
|
|||||||
|
|
||||||
// SettleHTLC attempts to settle an existing outstanding received HTLC. The
|
// SettleHTLC attempts to settle an existing outstanding received HTLC. The
|
||||||
// remote log index of the HTLC settled is returned in order to facilitate
|
// remote log index of the HTLC settled is returned in order to facilitate
|
||||||
// creating the corresponding wire message. In the case the supplied pre-image
|
// creating the corresponding wire message. In the case the supplied preimage
|
||||||
// is invalid, an error is returned.
|
// is invalid, an error is returned.
|
||||||
func (lc *LightningChannel) SettleHTLC(preimage [32]byte) (uint32, error) {
|
func (lc *LightningChannel) SettleHTLC(preimage [32]byte) (uint32, error) {
|
||||||
lc.Lock()
|
lc.Lock()
|
||||||
@ -1794,7 +1794,7 @@ func (lc *LightningChannel) ReceiveCancelHTLC(logIndex uint32) error {
|
|||||||
|
|
||||||
// ChannelPoint returns the outpoint of the original funding transaction which
|
// ChannelPoint returns the outpoint of the original funding transaction which
|
||||||
// created this active channel. This outpoint is used throughout various
|
// created this active channel. This outpoint is used throughout various
|
||||||
// sub-systems to uniquely identify an open channel.
|
// subsystems to uniquely identify an open channel.
|
||||||
func (lc *LightningChannel) ChannelPoint() *wire.OutPoint {
|
func (lc *LightningChannel) ChannelPoint() *wire.OutPoint {
|
||||||
return lc.channelState.ChanID
|
return lc.channelState.ChanID
|
||||||
}
|
}
|
||||||
@ -2119,7 +2119,7 @@ func (lc *LightningChannel) CompleteCooperativeClose(remoteSig []byte) (*wire.Ms
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DeleteState deletes all state concerning the channel from the underlying
|
// DeleteState deletes all state concerning the channel from the underlying
|
||||||
// database, only leaving a small summary describing meta-data of the
|
// database, only leaving a small summary describing metadata of the
|
||||||
// channel's lifetime.
|
// channel's lifetime.
|
||||||
func (lc *LightningChannel) DeleteState() error {
|
func (lc *LightningChannel) DeleteState() error {
|
||||||
return lc.channelState.CloseChannel()
|
return lc.channelState.CloseChannel()
|
||||||
@ -2138,7 +2138,7 @@ func (lc *LightningChannel) StateSnapshot() *channeldb.ChannelSnapshot {
|
|||||||
// funding output. The commitment transaction contains two outputs: one paying
|
// funding output. The commitment transaction contains two outputs: one paying
|
||||||
// to the "owner" of the commitment transaction which can be spent after a
|
// to the "owner" of the commitment transaction which can be spent after a
|
||||||
// relative block delay or revocation event, and the other paying the the
|
// relative block delay or revocation event, and the other paying the the
|
||||||
// counter-party within the channel, which can be spent immediately.
|
// counterparty within the channel, which can be spent immediately.
|
||||||
func CreateCommitTx(fundingOutput *wire.TxIn, selfKey, theirKey *btcec.PublicKey,
|
func CreateCommitTx(fundingOutput *wire.TxIn, selfKey, theirKey *btcec.PublicKey,
|
||||||
revokeKey *btcec.PublicKey, csvTimeout uint32, amountToSelf,
|
revokeKey *btcec.PublicKey, csvTimeout uint32, amountToSelf,
|
||||||
amountToThem btcutil.Amount) (*wire.MsgTx, error) {
|
amountToThem btcutil.Amount) (*wire.MsgTx, error) {
|
||||||
|
@ -398,7 +398,7 @@ func TestSimpleAddSettleWorkflow(t *testing.T) {
|
|||||||
t.Fatalf("alice unable to process bob's new commitment: %v", err)
|
t.Fatalf("alice unable to process bob's new commitment: %v", err)
|
||||||
}
|
}
|
||||||
// Alice then processes this revocation, sending her own recovation for
|
// Alice then processes this revocation, sending her own recovation for
|
||||||
// her prior commitment transaction. Alice shouldn't have any HTLC's to
|
// her prior commitment transaction. Alice shouldn't have any HTLCs to
|
||||||
// forward since she's sending an outgoing HTLC.
|
// forward since she's sending an outgoing HTLC.
|
||||||
if htlcs, err := aliceChannel.ReceiveRevocation(bobRevocation); err != nil {
|
if htlcs, err := aliceChannel.ReceiveRevocation(bobRevocation); err != nil {
|
||||||
t.Fatalf("alice unable to rocess bob's revocation: %v", err)
|
t.Fatalf("alice unable to rocess bob's revocation: %v", err)
|
||||||
@ -497,7 +497,7 @@ func TestSimpleAddSettleWorkflow(t *testing.T) {
|
|||||||
if htlcs, err := bobChannel.ReceiveRevocation(aliceRevocation2); err != nil {
|
if htlcs, err := bobChannel.ReceiveRevocation(aliceRevocation2); err != nil {
|
||||||
t.Fatalf("bob unable to process alice's revocation: %v", err)
|
t.Fatalf("bob unable to process alice's revocation: %v", err)
|
||||||
} else if len(htlcs) != 0 {
|
} else if len(htlcs) != 0 {
|
||||||
t.Fatalf("bob shouldn't forward any HTLC's after outgoing settle, "+
|
t.Fatalf("bob shouldn't forward any HTLCs after outgoing settle, "+
|
||||||
"instead can forward: %v", spew.Sdump(htlcs))
|
"instead can forward: %v", spew.Sdump(htlcs))
|
||||||
}
|
}
|
||||||
if htlcs, err := aliceChannel.ReceiveRevocation(bobRevocation2); err != nil {
|
if htlcs, err := aliceChannel.ReceiveRevocation(bobRevocation2); err != nil {
|
||||||
@ -566,7 +566,7 @@ func TestSimpleAddSettleWorkflow(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The logs of both sides should now be cleared since the entry adding
|
// The logs of both sides should now be cleared since the entry adding
|
||||||
// the HTLC should have been removed once both sides recieve the
|
// the HTLC should have been removed once both sides receive the
|
||||||
// revocation.
|
// revocation.
|
||||||
if aliceChannel.ourUpdateLog.Len() != 0 {
|
if aliceChannel.ourUpdateLog.Len() != 0 {
|
||||||
t.Fatalf("alice's local not updated, should be empty, has %v entries "+
|
t.Fatalf("alice's local not updated, should be empty, has %v entries "+
|
||||||
@ -977,7 +977,7 @@ func TestStateUpdatePersistence(t *testing.T) {
|
|||||||
|
|
||||||
const numHtlcs = 4
|
const numHtlcs = 4
|
||||||
|
|
||||||
// Alice adds 3 HTLC's to the update log, while Bob adds a single HTLC.
|
// Alice adds 3 HTLCs to the update log, while Bob adds a single HTLC.
|
||||||
var alicePreimage [32]byte
|
var alicePreimage [32]byte
|
||||||
copy(alicePreimage[:], bytes.Repeat([]byte{0xaa}, 32))
|
copy(alicePreimage[:], bytes.Repeat([]byte{0xaa}, 32))
|
||||||
var bobPreimage [32]byte
|
var bobPreimage [32]byte
|
||||||
@ -1002,9 +1002,9 @@ func TestStateUpdatePersistence(t *testing.T) {
|
|||||||
bobChannel.AddHTLC(bobh)
|
bobChannel.AddHTLC(bobh)
|
||||||
aliceChannel.ReceiveHTLC(bobh)
|
aliceChannel.ReceiveHTLC(bobh)
|
||||||
|
|
||||||
// Next, Alice initiates a state transition to lock in the above HTLC's.
|
// Next, Alice initiates a state transition to lock in the above HTLCs.
|
||||||
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
|
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
|
||||||
t.Fatalf("unable to lock in HTLC's: %v", err)
|
t.Fatalf("unable to lock in HTLCs: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The balances of both channels should be updated accordingly.
|
// The balances of both channels should be updated accordingly.
|
||||||
@ -1021,7 +1021,7 @@ func TestStateUpdatePersistence(t *testing.T) {
|
|||||||
bobBalance)
|
bobBalance)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The latest commitment from both sides should have all the HTLC's.
|
// The latest commitment from both sides should have all the HTLCs.
|
||||||
numAliceOutgoing := aliceChannel.localCommitChain.tail().outgoingHTLCs
|
numAliceOutgoing := aliceChannel.localCommitChain.tail().outgoingHTLCs
|
||||||
numAliceIncoming := aliceChannel.localCommitChain.tail().incomingHTLCs
|
numAliceIncoming := aliceChannel.localCommitChain.tail().incomingHTLCs
|
||||||
if len(numAliceOutgoing) != 3 {
|
if len(numAliceOutgoing) != 3 {
|
||||||
@ -1065,7 +1065,7 @@ func TestStateUpdatePersistence(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The state update logs of the new channels and the old channels
|
// The state update logs of the new channels and the old channels
|
||||||
// should now be identical other than the height the HTLC's were added.
|
// should now be identical other than the height the HTLCs were added.
|
||||||
if aliceChannel.ourLogCounter != aliceChannelNew.ourLogCounter {
|
if aliceChannel.ourLogCounter != aliceChannelNew.ourLogCounter {
|
||||||
t.Fatalf("alice log counter: expected %v, got %v",
|
t.Fatalf("alice log counter: expected %v, got %v",
|
||||||
aliceChannel.ourLogCounter, aliceChannelNew.ourLogCounter)
|
aliceChannel.ourLogCounter, aliceChannelNew.ourLogCounter)
|
||||||
@ -1101,7 +1101,7 @@ func TestStateUpdatePersistence(t *testing.T) {
|
|||||||
bobChannel.theirUpdateLog.Len(), bobChannelNew.theirUpdateLog.Len())
|
bobChannel.theirUpdateLog.Len(), bobChannelNew.theirUpdateLog.Len())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now settle all the HTLC's, then force a state update. The state
|
// Now settle all the HTLCs, then force a state update. The state
|
||||||
// update should suceed as both sides have identical.
|
// update should suceed as both sides have identical.
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
settleIndex, err := bobChannelNew.SettleHTLC(alicePreimage)
|
settleIndex, err := bobChannelNew.SettleHTLC(alicePreimage)
|
||||||
@ -1216,7 +1216,7 @@ func TestCancelHTLC(t *testing.T) {
|
|||||||
t.Fatalf("unable to create new commitment: %v", err)
|
t.Fatalf("unable to create new commitment: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now HTLC's should be present on the commitment transaction for
|
// Now HTLCs should be present on the commitment transaction for
|
||||||
// either side.
|
// either side.
|
||||||
if len(aliceChannel.localCommitChain.tip().outgoingHTLCs) != 0 ||
|
if len(aliceChannel.localCommitChain.tip().outgoingHTLCs) != 0 ||
|
||||||
len(aliceChannel.remoteCommitChain.tip().outgoingHTLCs) != 0 {
|
len(aliceChannel.remoteCommitChain.tip().outgoingHTLCs) != 0 {
|
||||||
|
@ -214,7 +214,7 @@ type BlockChainIO interface {
|
|||||||
// transaction ID.
|
// transaction ID.
|
||||||
GetTransaction(txid *chainhash.Hash) (*wire.MsgTx, error)
|
GetTransaction(txid *chainhash.Hash) (*wire.MsgTx, error)
|
||||||
|
|
||||||
// GetBlockHash returns the hash of the block in the best block chain
|
// GetBlockHash returns the hash of the block in the best blockchain
|
||||||
// at the given height.
|
// at the given height.
|
||||||
GetBlockHash(blockHeight int64) (*chainhash.Hash, error)
|
GetBlockHash(blockHeight int64) (*chainhash.Hash, error)
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ func SpendMultiSig(witnessScript, pubA, sigA, pubB, sigB []byte) [][]byte {
|
|||||||
witness[2] = sigB
|
witness[2] = sigB
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, add the pre-image as the last witness element.
|
// Finally, add the preimage as the last witness element.
|
||||||
witness[3] = witnessScript
|
witness[3] = witnessScript
|
||||||
|
|
||||||
return witness
|
return witness
|
||||||
@ -191,9 +191,9 @@ func senderHTLCScript(absoluteTimeout, relativeTimeout uint32, senderKey,
|
|||||||
|
|
||||||
// Alternatively, the receiver can place a 0 as the second item of the
|
// Alternatively, the receiver can place a 0 as the second item of the
|
||||||
// witness stack if they wish to claim the HTLC with the proper
|
// witness stack if they wish to claim the HTLC with the proper
|
||||||
// pre-image as normal. In order to prevent an over-sized pre-image
|
// preimage as normal. In order to prevent an over-sized preimage
|
||||||
// attack (which can create undesirable redemption asymmetries), we
|
// attack (which can create undesirable redemption asymmetries), we
|
||||||
// strongly require that all HTLC pre-images are exactly 32 bytes.
|
// strongly require that all HTLC preimages are exactly 32 bytes.
|
||||||
builder.AddOp(txscript.OP_ELSE)
|
builder.AddOp(txscript.OP_ELSE)
|
||||||
builder.AddOp(txscript.OP_SIZE)
|
builder.AddOp(txscript.OP_SIZE)
|
||||||
builder.AddInt64(32)
|
builder.AddInt64(32)
|
||||||
@ -218,7 +218,7 @@ func senderHTLCScript(absoluteTimeout, relativeTimeout uint32, senderKey,
|
|||||||
// In this case, the sender will need to wait for an absolute HTLC
|
// In this case, the sender will need to wait for an absolute HTLC
|
||||||
// timeout, then afterwards a relative timeout before we claim re-claim
|
// timeout, then afterwards a relative timeout before we claim re-claim
|
||||||
// the unsettled funds. This delay gives the other party a chance to
|
// the unsettled funds. This delay gives the other party a chance to
|
||||||
// present the pre-image to the revocation hash in the event that the
|
// present the preimage to the revocation hash in the event that the
|
||||||
// sender (at this time) broadcasts this commitment transaction after
|
// sender (at this time) broadcasts this commitment transaction after
|
||||||
// it has been revoked.
|
// it has been revoked.
|
||||||
builder.AddInt64(int64(absoluteTimeout))
|
builder.AddInt64(int64(absoluteTimeout))
|
||||||
@ -237,7 +237,7 @@ func senderHTLCScript(absoluteTimeout, relativeTimeout uint32, senderKey,
|
|||||||
// senderHtlcSpendRevoke constructs a valid witness allowing the receiver of an
|
// senderHtlcSpendRevoke constructs a valid witness allowing the receiver of an
|
||||||
// HTLC to claim the output with knowledge of the revocation preimage in the
|
// HTLC to claim the output with knowledge of the revocation preimage in the
|
||||||
// scenario that the sender of the HTLC broadcasts a previously revoked
|
// scenario that the sender of the HTLC broadcasts a previously revoked
|
||||||
// commitment transaction. A valid spend requires knowledge of the pre-image to
|
// commitment transaction. A valid spend requires knowledge of the preimage to
|
||||||
// the commitment transaction's revocation hash, and a valid signature under
|
// the commitment transaction's revocation hash, and a valid signature under
|
||||||
// the receiver's public key.
|
// the receiver's public key.
|
||||||
func senderHtlcSpendRevoke(commitScript []byte, outputAmt btcutil.Amount,
|
func senderHtlcSpendRevoke(commitScript []byte, outputAmt btcutil.Amount,
|
||||||
@ -268,7 +268,7 @@ func senderHtlcSpendRevoke(commitScript []byte, outputAmt btcutil.Amount,
|
|||||||
// senderHtlcSpendRedeem constructs a valid witness allowing the receiver of an
|
// senderHtlcSpendRedeem constructs a valid witness allowing the receiver of an
|
||||||
// HTLC to redeem the pending output in the scenario that the sender broadcasts
|
// HTLC to redeem the pending output in the scenario that the sender broadcasts
|
||||||
// their version of the commitment transaction. A valid spend requires
|
// their version of the commitment transaction. A valid spend requires
|
||||||
// knowledge of the payment pre-image, and a valid signature under the
|
// knowledge of the payment preimage, and a valid signature under the
|
||||||
// receivers public key.
|
// receivers public key.
|
||||||
func senderHtlcSpendRedeem(commitScript []byte, outputAmt btcutil.Amount,
|
func senderHtlcSpendRedeem(commitScript []byte, outputAmt btcutil.Amount,
|
||||||
reciverKey *btcec.PrivateKey, sweepTx *wire.MsgTx,
|
reciverKey *btcec.PrivateKey, sweepTx *wire.MsgTx,
|
||||||
@ -364,7 +364,7 @@ func senderHtlcSpendTimeout(commitScript []byte, outputAmt btcutil.Amount,
|
|||||||
// <sender key> OP_CHECKSIG
|
// <sender key> OP_CHECKSIG
|
||||||
// OP_ENDIF
|
// OP_ENDIF
|
||||||
// TODO(roasbeef): go back to revocation keys in the HTLC outputs?
|
// TODO(roasbeef): go back to revocation keys in the HTLC outputs?
|
||||||
// * also could combine pre-image with their key?
|
// * also could combine preimage with their key?
|
||||||
func receiverHTLCScript(absoluteTimeout, relativeTimeout uint32, senderKey,
|
func receiverHTLCScript(absoluteTimeout, relativeTimeout uint32, senderKey,
|
||||||
receiverKey *btcec.PublicKey, revokeHash, paymentHash []byte) ([]byte, error) {
|
receiverKey *btcec.PublicKey, revokeHash, paymentHash []byte) ([]byte, error) {
|
||||||
|
|
||||||
@ -380,7 +380,7 @@ func receiverHTLCScript(absoluteTimeout, relativeTimeout uint32, senderKey,
|
|||||||
// opportunity to re-claim the pending HTLC in the event that the
|
// opportunity to re-claim the pending HTLC in the event that the
|
||||||
// receiver (at this time) broadcasts this old commitment transaction
|
// receiver (at this time) broadcasts this old commitment transaction
|
||||||
// after it has been revoked. Additionally, we require that the
|
// after it has been revoked. Additionally, we require that the
|
||||||
// pre-image is exactly 32-bytes in order to avoid undesirable
|
// preimage is exactly 32-bytes in order to avoid undesirable
|
||||||
// redemption asymmetries in the multi-hop scenario.
|
// redemption asymmetries in the multi-hop scenario.
|
||||||
builder.AddOp(txscript.OP_SIZE)
|
builder.AddOp(txscript.OP_SIZE)
|
||||||
builder.AddInt64(32)
|
builder.AddInt64(32)
|
||||||
@ -549,7 +549,7 @@ func lockTimeToSequence(isSeconds bool, locktime uint32) uint32 {
|
|||||||
|
|
||||||
// commitScriptToSelf constructs the public key script for the output on the
|
// commitScriptToSelf constructs the public key script for the output on the
|
||||||
// commitment transaction paying to the "owner" of said commitment transaction.
|
// commitment transaction paying to the "owner" of said commitment transaction.
|
||||||
// If the other party learns of the pre-image to the revocation hash, then they
|
// If the other party learns of the preimage to the revocation hash, then they
|
||||||
// can claim all the settled funds in the channel, plus the unsettled funds.
|
// can claim all the settled funds in the channel, plus the unsettled funds.
|
||||||
//
|
//
|
||||||
// Possible Input Scripts:
|
// Possible Input Scripts:
|
||||||
@ -641,7 +641,7 @@ func CommitSpendTimeout(signer Signer, signDesc *SignDescriptor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CommitSpendRevoke constructs a valid witness allowing a node to sweep the
|
// CommitSpendRevoke constructs a valid witness allowing a node to sweep the
|
||||||
// settled output of a malicious counter-party who broadcasts a revoked
|
// settled output of a malicious counterparty who broadcasts a revoked
|
||||||
// commitment transaction.
|
// commitment transaction.
|
||||||
func CommitSpendRevoke(signer Signer, signDesc *SignDescriptor,
|
func CommitSpendRevoke(signer Signer, signDesc *SignDescriptor,
|
||||||
sweepTx *wire.MsgTx) (wire.TxWitness, error) {
|
sweepTx *wire.MsgTx) (wire.TxWitness, error) {
|
||||||
@ -662,7 +662,7 @@ func CommitSpendRevoke(signer Signer, signDesc *SignDescriptor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CommitSpendNoDelay constructs a valid witness allowing a node to spend their
|
// CommitSpendNoDelay constructs a valid witness allowing a node to spend their
|
||||||
// settled no-delay output on the counter-party's commitment transaction.
|
// settled no-delay output on the counterparty's commitment transaction.
|
||||||
func CommitSpendNoDelay(signer Signer, signDesc *SignDescriptor,
|
func CommitSpendNoDelay(signer Signer, signDesc *SignDescriptor,
|
||||||
sweepTx *wire.MsgTx) (wire.TxWitness, error) {
|
sweepTx *wire.MsgTx) (wire.TxWitness, error) {
|
||||||
|
|
||||||
@ -677,10 +677,10 @@ func CommitSpendNoDelay(signer Signer, signDesc *SignDescriptor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DeriveRevocationPubkey derives the revocation public key given the
|
// DeriveRevocationPubkey derives the revocation public key given the
|
||||||
// counter-party's commitment key, and revocation pre-image derived via a
|
// counterparty's commitment key, and revocation preimage derived via a
|
||||||
// pseudo-random-function. In the event that we (for some reason) broadcast a
|
// pseudo-random-function. In the event that we (for some reason) broadcast a
|
||||||
// revoked commitment transaction, then if the other party knows the revocation
|
// revoked commitment transaction, then if the other party knows the revocation
|
||||||
// pre-image, then they'll be able to derive the corresponding private key to
|
// preimage, then they'll be able to derive the corresponding private key to
|
||||||
// this private key by exploiting the homomorphism in the elliptic curve group:
|
// this private key by exploiting the homomorphism in the elliptic curve group:
|
||||||
// * https://en.wikipedia.org/wiki/Group_homomorphism#Homomorphisms_of_abelian_groups
|
// * https://en.wikipedia.org/wiki/Group_homomorphism#Homomorphisms_of_abelian_groups
|
||||||
//
|
//
|
||||||
@ -690,7 +690,7 @@ func CommitSpendNoDelay(signer Signer, signDesc *SignDescriptor,
|
|||||||
// := G*k + G*h
|
// := G*k + G*h
|
||||||
// := G * (k+h)
|
// := G * (k+h)
|
||||||
//
|
//
|
||||||
// Therefore, once we divulge the revocation pre-image, the remote peer is able to
|
// Therefore, once we divulge the revocation preimage, the remote peer is able to
|
||||||
// compute the proper private key for the revokeKey by computing:
|
// compute the proper private key for the revokeKey by computing:
|
||||||
// revokePriv := commitPriv + revokePreimge mod N
|
// revokePriv := commitPriv + revokePreimge mod N
|
||||||
//
|
//
|
||||||
@ -710,7 +710,7 @@ func DeriveRevocationPubkey(commitPubKey *btcec.PublicKey,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DeriveRevocationPrivKey derives the revocation private key given a node's
|
// DeriveRevocationPrivKey derives the revocation private key given a node's
|
||||||
// commitment private key, and the pre-image to a previously seen revocation
|
// commitment private key, and the preimage to a previously seen revocation
|
||||||
// hash. Using this derived private key, a node is able to claim the output
|
// hash. Using this derived private key, a node is able to claim the output
|
||||||
// within the commitment transaction of a node in the case that they broadcast
|
// within the commitment transaction of a node in the case that they broadcast
|
||||||
// a previously revoked commitment transaction.
|
// a previously revoked commitment transaction.
|
||||||
@ -722,12 +722,12 @@ func DeriveRevocationPubkey(commitPubKey *btcec.PublicKey,
|
|||||||
func DeriveRevocationPrivKey(commitPrivKey *btcec.PrivateKey,
|
func DeriveRevocationPrivKey(commitPrivKey *btcec.PrivateKey,
|
||||||
revokePreimage []byte) *btcec.PrivateKey {
|
revokePreimage []byte) *btcec.PrivateKey {
|
||||||
|
|
||||||
// Convert the revocation pre-image into a scalar value so we can
|
// Convert the revocation preimage into a scalar value so we can
|
||||||
// manipulate it within the curve's defined finite field.
|
// manipulate it within the curve's defined finite field.
|
||||||
revokeScalar := new(big.Int).SetBytes(revokePreimage)
|
revokeScalar := new(big.Int).SetBytes(revokePreimage)
|
||||||
|
|
||||||
// To derive the revocation private key, we simply add the revocation
|
// To derive the revocation private key, we simply add the revocation
|
||||||
// pre-image to the commitment private key.
|
// preimage to the commitment private key.
|
||||||
//
|
//
|
||||||
// This works since:
|
// This works since:
|
||||||
// P = G*a + G*b
|
// P = G*a + G*b
|
||||||
|
@ -215,10 +215,10 @@ func makeWitnessTestCase(t *testing.T, f func() (wire.TxWitness, error)) func()
|
|||||||
//
|
//
|
||||||
// The following cases are exercised by this test:
|
// The following cases are exercised by this test:
|
||||||
// sender script:
|
// sender script:
|
||||||
// * reciever spends
|
// * receiver spends
|
||||||
// * revoke w/ sig
|
// * revoke w/ sig
|
||||||
// * HTLC with invalid pre-image size
|
// * HTLC with invalid preimage size
|
||||||
// * HTLC with valid pre-image size + sig
|
// * HTLC with valid preimage size + sig
|
||||||
// * sender spends
|
// * sender spends
|
||||||
// * invalid lock-time for CLTV
|
// * invalid lock-time for CLTV
|
||||||
// * invalid sequence for CSV
|
// * invalid sequence for CSV
|
||||||
@ -235,14 +235,14 @@ func TestHTLCSenderSpendValidation(t *testing.T) {
|
|||||||
}
|
}
|
||||||
fakeFundingTxIn := wire.NewTxIn(fundingOut, nil, nil)
|
fakeFundingTxIn := wire.NewTxIn(fundingOut, nil, nil)
|
||||||
|
|
||||||
// Generate a payment and revocation pre-image to be used below.
|
// Generate a payment and revocation preimage to be used below.
|
||||||
revokePreimage := testHdSeed[:]
|
revokePreimage := testHdSeed[:]
|
||||||
revokeHash := fastsha256.Sum256(revokePreimage)
|
revokeHash := fastsha256.Sum256(revokePreimage)
|
||||||
paymentPreimage := revokeHash
|
paymentPreimage := revokeHash
|
||||||
paymentPreimage[0] ^= 1
|
paymentPreimage[0] ^= 1
|
||||||
paymentHash := fastsha256.Sum256(paymentPreimage[:])
|
paymentHash := fastsha256.Sum256(paymentPreimage[:])
|
||||||
|
|
||||||
// We'll also need some tests keys for alice and bob, and meta-data of
|
// We'll also need some tests keys for alice and bob, and metadata of
|
||||||
// the HTLC output.
|
// the HTLC output.
|
||||||
aliceKeyPriv, aliceKeyPub := btcec.PrivKeyFromBytes(btcec.S256(),
|
aliceKeyPriv, aliceKeyPub := btcec.PrivKeyFromBytes(btcec.S256(),
|
||||||
testWalletPrivKey)
|
testWalletPrivKey)
|
||||||
@ -302,18 +302,18 @@ func TestHTLCSenderSpendValidation(t *testing.T) {
|
|||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// HTLC with invalid pre-image size
|
// HTLC with invalid preimage size
|
||||||
makeWitnessTestCase(t, func() (wire.TxWitness, error) {
|
makeWitnessTestCase(t, func() (wire.TxWitness, error) {
|
||||||
return senderHtlcSpendRedeem(htlcScript, paymentAmt,
|
return senderHtlcSpendRedeem(htlcScript, paymentAmt,
|
||||||
bobKeyPriv, sweepTx,
|
bobKeyPriv, sweepTx,
|
||||||
// Invalid pre-image length
|
// Invalid preimage length
|
||||||
bytes.Repeat([]byte{1}, 45))
|
bytes.Repeat([]byte{1}, 45))
|
||||||
}),
|
}),
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// HTLC with valid pre-image size + sig
|
// HTLC with valid preimage size + sig
|
||||||
// TODO(roabeef): invalid pre-image
|
// TODO(roabeef): invalid preimage
|
||||||
makeWitnessTestCase(t, func() (wire.TxWitness, error) {
|
makeWitnessTestCase(t, func() (wire.TxWitness, error) {
|
||||||
return senderHtlcSpendRedeem(htlcScript, paymentAmt,
|
return senderHtlcSpendRedeem(htlcScript, paymentAmt,
|
||||||
bobKeyPriv, sweepTx,
|
bobKeyPriv, sweepTx,
|
||||||
@ -385,11 +385,11 @@ func TestHTLCSenderSpendValidation(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TestHTLCReceiverSpendValidation tests all possible valid+invalid redemption
|
// TestHTLCReceiverSpendValidation tests all possible valid+invalid redemption
|
||||||
// paths in the script used within the reciever's commitment transaction for an
|
// paths in the script used within the receiver's commitment transaction for an
|
||||||
// incoming HTLC.
|
// incoming HTLC.
|
||||||
//
|
//
|
||||||
// The following cases are exercised by this test:
|
// The following cases are exercised by this test:
|
||||||
// * reciever spends
|
// * receiver spends
|
||||||
// * HTLC redemption w/ invalid preimage size
|
// * HTLC redemption w/ invalid preimage size
|
||||||
// * HTLC redemption w/ invalid sequence
|
// * HTLC redemption w/ invalid sequence
|
||||||
// * HTLC redemption w/ valid preimage size
|
// * HTLC redemption w/ valid preimage size
|
||||||
@ -407,14 +407,14 @@ func TestHTLCReceiverSpendValidation(t *testing.T) {
|
|||||||
}
|
}
|
||||||
fakeFundingTxIn := wire.NewTxIn(fundingOut, nil, nil)
|
fakeFundingTxIn := wire.NewTxIn(fundingOut, nil, nil)
|
||||||
|
|
||||||
// Generate a payment and revocation pre-image to be used below.
|
// Generate a payment and revocation preimage to be used below.
|
||||||
revokePreimage := testHdSeed[:]
|
revokePreimage := testHdSeed[:]
|
||||||
revokeHash := fastsha256.Sum256(revokePreimage)
|
revokeHash := fastsha256.Sum256(revokePreimage)
|
||||||
paymentPreimage := revokeHash
|
paymentPreimage := revokeHash
|
||||||
paymentPreimage[0] ^= 1
|
paymentPreimage[0] ^= 1
|
||||||
paymentHash := fastsha256.Sum256(paymentPreimage[:])
|
paymentHash := fastsha256.Sum256(paymentPreimage[:])
|
||||||
|
|
||||||
// We'll also need some tests keys for alice and bob, and meta-data of
|
// We'll also need some tests keys for alice and bob, and metadata of
|
||||||
// the HTLC output.
|
// the HTLC output.
|
||||||
aliceKeyPriv, aliceKeyPub := btcec.PrivKeyFromBytes(btcec.S256(),
|
aliceKeyPriv, aliceKeyPub := btcec.PrivKeyFromBytes(btcec.S256(),
|
||||||
testWalletPrivKey)
|
testWalletPrivKey)
|
||||||
@ -438,15 +438,15 @@ func TestHTLCReceiverSpendValidation(t *testing.T) {
|
|||||||
// This will be Bob's commitment transaction. In this scenario Alice
|
// This will be Bob's commitment transaction. In this scenario Alice
|
||||||
// is sending an HTLC to a node she has a a path to (could be Bob,
|
// is sending an HTLC to a node she has a a path to (could be Bob,
|
||||||
// could be multiple hops down, it doesn't really matter).
|
// could be multiple hops down, it doesn't really matter).
|
||||||
recieverCommitTx := wire.NewMsgTx(2)
|
receiverCommitTx := wire.NewMsgTx(2)
|
||||||
recieverCommitTx.AddTxIn(fakeFundingTxIn)
|
receiverCommitTx.AddTxIn(fakeFundingTxIn)
|
||||||
recieverCommitTx.AddTxOut(&wire.TxOut{
|
receiverCommitTx.AddTxOut(&wire.TxOut{
|
||||||
Value: int64(paymentAmt),
|
Value: int64(paymentAmt),
|
||||||
PkScript: htlcWitnessScript,
|
PkScript: htlcWitnessScript,
|
||||||
})
|
})
|
||||||
|
|
||||||
prevOut := &wire.OutPoint{
|
prevOut := &wire.OutPoint{
|
||||||
Hash: recieverCommitTx.TxHash(),
|
Hash: receiverCommitTx.TxHash(),
|
||||||
Index: 0,
|
Index: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,10 +241,10 @@ type channelOpenMsg struct {
|
|||||||
// as a regular Bitcoin wallet which uses HD keys. The wallet is highly concurrent
|
// as a regular Bitcoin wallet which uses HD keys. The wallet is highly concurrent
|
||||||
// internally. All communication, and requests towards the wallet are
|
// internally. All communication, and requests towards the wallet are
|
||||||
// dispatched as messages over channels, ensuring thread safety across all
|
// dispatched as messages over channels, ensuring thread safety across all
|
||||||
// operations. Interaction has been designed independant of any peer-to-peer
|
// operations. Interaction has been designed independent of any peer-to-peer
|
||||||
// communication protocol, allowing the wallet to be self-contained and embeddable
|
// communication protocol, allowing the wallet to be self-contained and embeddable
|
||||||
// within future projects interacting with the Lightning Network.
|
// within future projects interacting with the Lightning Network.
|
||||||
// NOTE: At the moment the wallet requires a btcd full node, as it's dependant
|
// NOTE: At the moment the wallet requires a btcd full node, as it's dependent
|
||||||
// on btcd's websockets notifications as even triggers during the lifetime of
|
// on btcd's websockets notifications as even triggers during the lifetime of
|
||||||
// a channel. However, once the chainntnfs package is complete, the wallet
|
// a channel. However, once the chainntnfs package is complete, the wallet
|
||||||
// will be compatible with multiple RPC/notification services such as Electrum,
|
// will be compatible with multiple RPC/notification services such as Electrum,
|
||||||
@ -261,7 +261,7 @@ type LightningWallet struct {
|
|||||||
coinSelectMtx sync.RWMutex
|
coinSelectMtx sync.RWMutex
|
||||||
|
|
||||||
// A wrapper around a namespace within boltdb reserved for ln-based
|
// A wrapper around a namespace within boltdb reserved for ln-based
|
||||||
// wallet meta-data. See the 'channeldb' package for further
|
// wallet metadata. See the 'channeldb' package for further
|
||||||
// information.
|
// information.
|
||||||
ChannelDB *channeldb.DB
|
ChannelDB *channeldb.DB
|
||||||
|
|
||||||
@ -480,7 +480,7 @@ out:
|
|||||||
// same inputs in the funding transaction. If reservation initialization is
|
// same inputs in the funding transaction. If reservation initialization is
|
||||||
// successful, a ChannelReservation containing our completed contribution is
|
// successful, a ChannelReservation containing our completed contribution is
|
||||||
// returned. Our contribution contains all the items necessary to allow the
|
// returned. Our contribution contains all the items necessary to allow the
|
||||||
// counter party to build the funding transaction, and both versions of the
|
// counterparty to build the funding transaction, and both versions of the
|
||||||
// commitment transaction. Otherwise, an error occurred a nil pointer along with
|
// commitment transaction. Otherwise, an error occurred a nil pointer along with
|
||||||
// an error are returned.
|
// an error are returned.
|
||||||
//
|
//
|
||||||
@ -608,7 +608,7 @@ func (l *LightningWallet) handleFundingReserveRequest(req *initFundingReserveMsg
|
|||||||
|
|
||||||
// Funding reservation request successfully handled. The funding inputs
|
// Funding reservation request successfully handled. The funding inputs
|
||||||
// will be marked as unavailable until the reservation is either
|
// will be marked as unavailable until the reservation is either
|
||||||
// completed, or canceled.
|
// completed, or cancelled.
|
||||||
req.resp <- reservation
|
req.resp <- reservation
|
||||||
req.err <- nil
|
req.err <- nil
|
||||||
}
|
}
|
||||||
@ -754,7 +754,7 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) {
|
|||||||
pendingReservation.partialState.FundingOutpoint = fundingOutpoint
|
pendingReservation.partialState.FundingOutpoint = fundingOutpoint
|
||||||
|
|
||||||
// Initialize an empty sha-chain for them, tracking the current pending
|
// Initialize an empty sha-chain for them, tracking the current pending
|
||||||
// revocation hash (we don't yet know the pre-image so we can't add it
|
// revocation hash (we don't yet know the preimage so we can't add it
|
||||||
// to the chain).
|
// to the chain).
|
||||||
e := &elkrem.ElkremReceiver{}
|
e := &elkrem.ElkremReceiver{}
|
||||||
pendingReservation.partialState.RemoteElkrem = e
|
pendingReservation.partialState.RemoteElkrem = e
|
||||||
@ -921,7 +921,7 @@ func (l *LightningWallet) handleSingleContribution(req *addSingleContributionMsg
|
|||||||
ourRevokeKey := DeriveRevocationPubkey(theirCommitKey, firstPreimage[:])
|
ourRevokeKey := DeriveRevocationPubkey(theirCommitKey, firstPreimage[:])
|
||||||
|
|
||||||
// Initialize an empty sha-chain for them, tracking the current pending
|
// Initialize an empty sha-chain for them, tracking the current pending
|
||||||
// revocation hash (we don't yet know the pre-image so we can't add it
|
// revocation hash (we don't yet know the preimage so we can't add it
|
||||||
// to the chain).
|
// to the chain).
|
||||||
remoteElkrem := &elkrem.ElkremReceiver{}
|
remoteElkrem := &elkrem.ElkremReceiver{}
|
||||||
pendingReservation.partialState.RemoteElkrem = remoteElkrem
|
pendingReservation.partialState.RemoteElkrem = remoteElkrem
|
||||||
|
@ -23,7 +23,7 @@ type CommitRevocation struct {
|
|||||||
// CommitRevocation applies to.
|
// CommitRevocation applies to.
|
||||||
ChannelPoint *wire.OutPoint
|
ChannelPoint *wire.OutPoint
|
||||||
|
|
||||||
// Revocation is the pre-image to the revocation hash of the now prior
|
// Revocation is the preimage to the revocation hash of the now prior
|
||||||
// commitment transaction.
|
// commitment transaction.
|
||||||
//
|
//
|
||||||
// If the received revocation is the all zeroes hash ('0' * 32), then
|
// If the received revocation is the all zeroes hash ('0' * 32), then
|
||||||
@ -41,7 +41,7 @@ type CommitRevocation struct {
|
|||||||
|
|
||||||
// NextRevocationHash is the next revocation hash which should be added
|
// NextRevocationHash is the next revocation hash which should be added
|
||||||
// to the queue on unused revocation hashes for the remote peer. This
|
// to the queue on unused revocation hashes for the remote peer. This
|
||||||
// revocation hash will be used within any HTLC's included within this
|
// revocation hash will be used within any HTLCs included within this
|
||||||
// next commitment transaction.
|
// next commitment transaction.
|
||||||
NextRevocationHash [32]byte
|
NextRevocationHash [32]byte
|
||||||
}
|
}
|
||||||
|
@ -9,13 +9,13 @@ import (
|
|||||||
"github.com/roasbeef/btcutil"
|
"github.com/roasbeef/btcutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CommitSignature is sent by either side to stage any pending HTLC's in the
|
// CommitSignature is sent by either side to stage any pending HTLCs in the
|
||||||
// receiver's pending set which has not explicitly been rejected via an
|
// receiver's pending set which has not explicitly been rejected via an
|
||||||
// HTLCAddReject message. Implicitly, the new commitment transaction constructed
|
// HTLCAddReject message. Implicitly, the new commitment transaction constructed
|
||||||
// which has been signed by CommitSig includes all HTLC's in the remote node's
|
// which has been signed by CommitSig includes all HTLCs in the remote node's
|
||||||
// pending set. A CommitSignature message may be sent after a series of HTLCAdd
|
// pending set. A CommitSignature message may be sent after a series of HTLCAdd
|
||||||
// messages in order to batch add several HTLC's with a single signature
|
// messages in order to batch add several HTLCs with a single signature
|
||||||
// covering all implicitly accepted HTLC's.
|
// covering all implicitly accepted HTLCs.
|
||||||
type CommitSignature struct {
|
type CommitSignature struct {
|
||||||
// ChannelPoint uniquely identifies to which currently active channel this
|
// ChannelPoint uniquely identifies to which currently active channel this
|
||||||
// CommitSignature applies to.
|
// CommitSignature applies to.
|
||||||
@ -23,7 +23,7 @@ type CommitSignature struct {
|
|||||||
|
|
||||||
// LogIndex is the index into the receiver's HTLC log to which this
|
// LogIndex is the index into the receiver's HTLC log to which this
|
||||||
// commitment signature covers. In order to properly verify this
|
// commitment signature covers. In order to properly verify this
|
||||||
// signature, the receiver should include all the HTLC's within their
|
// signature, the receiver should include all the HTLCs within their
|
||||||
// log with an index less-than-or-equal to the listed log-index.
|
// log with an index less-than-or-equal to the listed log-index.
|
||||||
LogIndex uint64
|
LogIndex uint64
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
// HTLC to his remote commitment transaction. In addition to information
|
// HTLC to his remote commitment transaction. In addition to information
|
||||||
// detailing the value, and contract type of the HTLC, and onion blob is also
|
// detailing the value, and contract type of the HTLC, and onion blob is also
|
||||||
// included which allows Bob to derive the next hop in the route. The HTLC
|
// included which allows Bob to derive the next hop in the route. The HTLC
|
||||||
// added by this message is to be added to the remote node's "pending" HTLC's.
|
// added by this message is to be added to the remote node's "pending" HTLCs.
|
||||||
// A subsequent CommitSignature message will move the pending HTLC to the newly
|
// A subsequent CommitSignature message will move the pending HTLC to the newly
|
||||||
// created commitment transaction, marking them as "staged".
|
// created commitment transaction, marking them as "staged".
|
||||||
type HTLCAddRequest struct {
|
type HTLCAddRequest struct {
|
||||||
@ -40,8 +40,8 @@ type HTLCAddRequest struct {
|
|||||||
|
|
||||||
// RedemptionHashes are the hashes to be used within the HTLC script.
|
// RedemptionHashes are the hashes to be used within the HTLC script.
|
||||||
// An HTLC is only fufilled once Bob is provided with the required
|
// An HTLC is only fufilled once Bob is provided with the required
|
||||||
// number of pre-images for each of the listed hashes. For regular HTLC's
|
// number of preimages for each of the listed hashes. For regular HTLCs
|
||||||
// this slice only has one hash. However, for "multi-sig" HTLC's, the
|
// this slice only has one hash. However, for "multi-sig" HTLCs, the
|
||||||
// length of this slice should be N.
|
// length of this slice should be N.
|
||||||
RedemptionHashes [][32]byte
|
RedemptionHashes [][32]byte
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
// presented in order to support N-of-M HTLC contracts. A subsequent
|
// presented in order to support N-of-M HTLC contracts. A subsequent
|
||||||
// CommitSignature message will be sent by Alice to "lock-in" the removal of the
|
// CommitSignature message will be sent by Alice to "lock-in" the removal of the
|
||||||
// specified HTLC, possible containing a batch signature covering several settled
|
// specified HTLC, possible containing a batch signature covering several settled
|
||||||
// HTLC's.
|
// HTLCs.
|
||||||
type HTLCSettleRequest struct {
|
type HTLCSettleRequest struct {
|
||||||
// ChannelPoint references an active channel which holds the HTLC to be
|
// ChannelPoint references an active channel which holds the HTLC to be
|
||||||
// settled.
|
// settled.
|
||||||
|
@ -24,8 +24,8 @@ const MaxSliceLength = 65535
|
|||||||
// key script.
|
// key script.
|
||||||
type PkScript []byte
|
type PkScript []byte
|
||||||
|
|
||||||
// HTLCKey is an identifier used to uniquely identify any HTLC's transmitted
|
// HTLCKey is an identifier used to uniquely identify any HTLCs transmitted
|
||||||
// between Alice and Bob. In order to cancel, timeout, or settle HTLC's this
|
// between Alice and Bob. In order to cancel, timeout, or settle HTLCs this
|
||||||
// identifier should be used to allow either side to easily locate and modify
|
// identifier should be used to allow either side to easily locate and modify
|
||||||
// any staged or pending HTLCs.
|
// any staged or pending HTLCs.
|
||||||
// TODO(roasbeef): change to HTLCIdentifier?
|
// TODO(roasbeef): change to HTLCIdentifier?
|
||||||
@ -36,7 +36,7 @@ type HTLCKey int64
|
|||||||
// HTLC lists on either side will increment this height. As a result this value
|
// HTLC lists on either side will increment this height. As a result this value
|
||||||
// should always be monotonically increasing. Any CommitSignature or
|
// should always be monotonically increasing. Any CommitSignature or
|
||||||
// CommitRevocation messages will reference a value for the commitment height
|
// CommitRevocation messages will reference a value for the commitment height
|
||||||
// up to which it covers. HTLC's are only explicitly excluded by sending
|
// up to which it covers. HTLCs are only explicitly excluded by sending
|
||||||
// HTLCReject messages referencing a particular HTLCKey.
|
// HTLCReject messages referencing a particular HTLCKey.
|
||||||
type CommitHeight uint64
|
type CommitHeight uint64
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ type SingleFundingComplete struct {
|
|||||||
// RevocationKey is the initial key to be used for the revocation
|
// RevocationKey is the initial key to be used for the revocation
|
||||||
// clause within the self-output of the initiators's commitment
|
// clause within the self-output of the initiators's commitment
|
||||||
// transaction. Once an initial new state is created, the initiator
|
// transaction. Once an initial new state is created, the initiator
|
||||||
// will send a pre-image which will allow the initiator to sweep the
|
// will send a preimage which will allow the initiator to sweep the
|
||||||
// initiator's funds if the violate the contract.
|
// initiator's funds if the violate the contract.
|
||||||
RevocationKey *btcec.PublicKey
|
RevocationKey *btcec.PublicKey
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ type SingleFundingRequest struct {
|
|||||||
// ChannelType represents the type of channel this request would like
|
// ChannelType represents the type of channel this request would like
|
||||||
// to open. At this point, the only supported channels are type 0
|
// to open. At this point, the only supported channels are type 0
|
||||||
// channels, which are channels with regular commitment transactions
|
// channels, which are channels with regular commitment transactions
|
||||||
// utilizing HTLC's for payments.
|
// utilizing HTLCs for payments.
|
||||||
ChannelType uint8
|
ChannelType uint8
|
||||||
|
|
||||||
// CoinType represents which blockchain the channel will be opened
|
// CoinType represents which blockchain the channel will be opened
|
||||||
|
@ -33,7 +33,7 @@ type SingleFundingResponse struct {
|
|||||||
// RevocationKey is the initial key to be used for the revocation
|
// RevocationKey is the initial key to be used for the revocation
|
||||||
// clause within the self-output of the responder's commitment
|
// clause within the self-output of the responder's commitment
|
||||||
// transaction. Once an initial new state is created, the responder
|
// transaction. Once an initial new state is created, the responder
|
||||||
// will send a pre-image which will allow the initiator to sweep the
|
// will send a preimage which will allow the initiator to sweep the
|
||||||
// responder's funds if the violate the contract.
|
// responder's funds if the violate the contract.
|
||||||
RevocationKey *btcec.PublicKey
|
RevocationKey *btcec.PublicKey
|
||||||
|
|
||||||
|
2
log.go
2
log.go
@ -159,7 +159,7 @@ func setLogLevel(subsystemID string, logLevel string) {
|
|||||||
// level. It also dynamically creates the subsystem loggers as needed, so it
|
// level. It also dynamically creates the subsystem loggers as needed, so it
|
||||||
// can be used to initialize the logging system.
|
// can be used to initialize the logging system.
|
||||||
func setLogLevels(logLevel string) {
|
func setLogLevels(logLevel string) {
|
||||||
// Configure all sub-systems with the new logging level. Dynamically
|
// Configure all subsystems with the new logging level. Dynamically
|
||||||
// create loggers as needed.
|
// create loggers as needed.
|
||||||
for subsystemID := range subsystemLoggers {
|
for subsystemID := range subsystemLoggers {
|
||||||
setLogLevel(subsystemID, logLevel)
|
setLogLevel(subsystemID, logLevel)
|
||||||
|
44
peer.go
44
peer.go
@ -49,7 +49,7 @@ type outgoinMsg struct {
|
|||||||
sentChan chan struct{} // MUST be buffered.
|
sentChan chan struct{} // MUST be buffered.
|
||||||
}
|
}
|
||||||
|
|
||||||
// chanSnapshotReq is a message sent by outside sub-systems to a peer in order
|
// chanSnapshotReq is a message sent by outside subsystems to a peer in order
|
||||||
// to gain a snapshot of the peer's currently active channels.
|
// to gain a snapshot of the peer's currently active channels.
|
||||||
type chanSnapshotReq struct {
|
type chanSnapshotReq struct {
|
||||||
resp chan []*channeldb.ChannelSnapshot
|
resp chan []*channeldb.ChannelSnapshot
|
||||||
@ -351,7 +351,7 @@ func (p *peer) readNextMessage() (lnwire.Message, []byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// readHandler is responsible for reading messages off the wire in series, then
|
// readHandler is responsible for reading messages off the wire in series, then
|
||||||
// properly dispatching the handling of the message to the proper sub-system.
|
// properly dispatching the handling of the message to the proper subsystem.
|
||||||
//
|
//
|
||||||
// NOTE: This method MUST be run as a goroutine.
|
// NOTE: This method MUST be run as a goroutine.
|
||||||
func (p *peer) readHandler() {
|
func (p *peer) readHandler() {
|
||||||
@ -569,7 +569,7 @@ fin:
|
|||||||
peerLog.Tracef("writeHandler for peer %v done", p)
|
peerLog.Tracef("writeHandler for peer %v done", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
// queueHandler is responsible for accepting messages from outside sub-systems
|
// queueHandler is responsible for accepting messages from outside subsystems
|
||||||
// to be eventually sent out on the wire by the writeHandler.
|
// to be eventually sent out on the wire by the writeHandler.
|
||||||
//
|
//
|
||||||
// NOTE: This method MUST be run as a goroutine.
|
// NOTE: This method MUST be run as a goroutine.
|
||||||
@ -780,7 +780,7 @@ func (p *peer) executeCooperativeClose(channel *lnwallet.LightningChannel) (*cha
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handleLocalClose kicks-off the workflow to execute a cooperative or forced
|
// handleLocalClose kicks-off the workflow to execute a cooperative or forced
|
||||||
// unilateral closure of the channel initiated by a local sub-system.
|
// unilateral closure of the channel initiated by a local subsystem.
|
||||||
// TODO(roasbeef): if no more active channels with peer call Remove on connMgr
|
// TODO(roasbeef): if no more active channels with peer call Remove on connMgr
|
||||||
// with peerID
|
// with peerID
|
||||||
func (p *peer) handleLocalClose(req *closeLinkReq) {
|
func (p *peer) handleLocalClose(req *closeLinkReq) {
|
||||||
@ -803,7 +803,7 @@ func (p *peer) handleLocalClose(req *closeLinkReq) {
|
|||||||
"ChannelPoint(%v) with txid: %v", req.chanPoint,
|
"ChannelPoint(%v) with txid: %v", req.chanPoint,
|
||||||
closingTxid)
|
closingTxid)
|
||||||
|
|
||||||
// A type of CloseBreach indicates that the counter-party has breached
|
// A type of CloseBreach indicates that the counterparty has breached
|
||||||
// the cahnnel therefore we need to clean up our local state.
|
// the cahnnel therefore we need to clean up our local state.
|
||||||
case CloseBreach:
|
case CloseBreach:
|
||||||
peerLog.Infof("ChannelPoint(%v) has been breached, wiping "+
|
peerLog.Infof("ChannelPoint(%v) has been breached, wiping "+
|
||||||
@ -864,7 +864,7 @@ func (p *peer) handleLocalClose(req *closeLinkReq) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Respond to the local sub-system which requested the channel
|
// Respond to the local subsystem which requested the channel
|
||||||
// closure.
|
// closure.
|
||||||
req.updates <- &lnrpc.CloseStatusUpdate{
|
req.updates <- &lnrpc.CloseStatusUpdate{
|
||||||
Update: &lnrpc.CloseStatusUpdate_ChanClose{
|
Update: &lnrpc.CloseStatusUpdate_ChanClose{
|
||||||
@ -996,23 +996,23 @@ type pendingPayment struct {
|
|||||||
// save meta-state required for proper functioning.
|
// save meta-state required for proper functioning.
|
||||||
type commitmentState struct {
|
type commitmentState struct {
|
||||||
// htlcsToSettle is a list of preimages which allow us to settle one or
|
// htlcsToSettle is a list of preimages which allow us to settle one or
|
||||||
// many of the pending HTLC's we've received from the upstream peer.
|
// many of the pending HTLCs we've received from the upstream peer.
|
||||||
htlcsToSettle map[uint32]*channeldb.Invoice
|
htlcsToSettle map[uint32]*channeldb.Invoice
|
||||||
|
|
||||||
// htlcsToCancel is a set of HTLC's identified by their log index which
|
// htlcsToCancel is a set of HTLCs identified by their log index which
|
||||||
// are to be cancelled upon the next state transition.
|
// are to be cancelled upon the next state transition.
|
||||||
htlcsToCancel map[uint32]lnwire.CancelReason
|
htlcsToCancel map[uint32]lnwire.CancelReason
|
||||||
|
|
||||||
// cancelReasons stores the reason why a particular HTLC was cancelled.
|
// cancelReasons stores the reason why a particular HTLC was cancelled.
|
||||||
// The index of the HTLC within the log is mapped to the cancellation
|
// The index of the HTLC within the log is mapped to the cancellation
|
||||||
// reason. This value is used to thread the proper error through to the
|
// reason. This value is used to thread the proper error through to the
|
||||||
// htlcSwitch, or sub-system that initiated the HTLC.
|
// htlcSwitch, or subsystem that initiated the HTLC.
|
||||||
cancelReasons map[uint32]lnwire.CancelReason
|
cancelReasons map[uint32]lnwire.CancelReason
|
||||||
|
|
||||||
// TODO(roasbeef): use once trickle+batch logic is in
|
// TODO(roasbeef): use once trickle+batch logic is in
|
||||||
pendingBatch []*pendingPayment
|
pendingBatch []*pendingPayment
|
||||||
|
|
||||||
// clearedHTCLs is a map of outgoing HTLC's we've committed to in our
|
// clearedHTCLs is a map of outgoing HTLCs we've committed to in our
|
||||||
// chain which have not yet been settled by the upstream peer.
|
// chain which have not yet been settled by the upstream peer.
|
||||||
clearedHTCLs map[uint32]*pendingPayment
|
clearedHTCLs map[uint32]*pendingPayment
|
||||||
|
|
||||||
@ -1036,7 +1036,7 @@ type commitmentState struct {
|
|||||||
// within HTLC add messages.
|
// within HTLC add messages.
|
||||||
sphinx *sphinx.Router
|
sphinx *sphinx.Router
|
||||||
|
|
||||||
// pendingCircuits tracks the remote log index of the incoming HTLC's,
|
// pendingCircuits tracks the remote log index of the incoming HTLCs,
|
||||||
// mapped to the processed Sphinx packet contained within the HTLC.
|
// mapped to the processed Sphinx packet contained within the HTLC.
|
||||||
// This map is used as a staging area between when an HTLC is added to
|
// This map is used as a staging area between when an HTLC is added to
|
||||||
// the log, and when it's locked into the commitment state of both
|
// the log, and when it's locked into the commitment state of both
|
||||||
@ -1054,7 +1054,7 @@ type commitmentState struct {
|
|||||||
// from several possible downstream channels managed by the htlcSwitch. In the
|
// from several possible downstream channels managed by the htlcSwitch. In the
|
||||||
// event that an htlc needs to be forwarded, then send-only htlcPlex chan is
|
// event that an htlc needs to be forwarded, then send-only htlcPlex chan is
|
||||||
// used which sends htlc packets to the switch for forwarding. Additionally,
|
// used which sends htlc packets to the switch for forwarding. Additionally,
|
||||||
// the htlcManager handles acting upon all timeouts for any active HTLC's,
|
// the htlcManager handles acting upon all timeouts for any active HTLCs,
|
||||||
// manages the channel's revocation window, and also the htlc trickle
|
// manages the channel's revocation window, and also the htlc trickle
|
||||||
// queue+timer for this active channels.
|
// queue+timer for this active channels.
|
||||||
func (p *peer) htlcManager(channel *lnwallet.LightningChannel,
|
func (p *peer) htlcManager(channel *lnwallet.LightningChannel,
|
||||||
@ -1091,7 +1091,7 @@ func (p *peer) htlcManager(channel *lnwallet.LightningChannel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO(roasbeef): check to see if able to settle any currently pending
|
// TODO(roasbeef): check to see if able to settle any currently pending
|
||||||
// HTLC's
|
// HTLCs
|
||||||
// * also need signals when new invoices are added by the invoiceRegistry
|
// * also need signals when new invoices are added by the invoiceRegistry
|
||||||
|
|
||||||
batchTimer := time.Tick(10 * time.Millisecond)
|
batchTimer := time.Tick(10 * time.Millisecond)
|
||||||
@ -1178,8 +1178,8 @@ out:
|
|||||||
|
|
||||||
// handleDownStreamPkt processes an HTLC packet sent from the downstream HTLC
|
// handleDownStreamPkt processes an HTLC packet sent from the downstream HTLC
|
||||||
// Switch. Possible messages sent by the switch include requests to forward new
|
// Switch. Possible messages sent by the switch include requests to forward new
|
||||||
// HTLC's, timeout previously cleared HTLC's, and finally to settle currently
|
// HTLCs, timeout previously cleared HTLCs, and finally to settle currently
|
||||||
// cleared HTLC's with the upstream peer.
|
// cleared HTLCs with the upstream peer.
|
||||||
func (p *peer) handleDownStreamPkt(state *commitmentState, pkt *htlcPacket) {
|
func (p *peer) handleDownStreamPkt(state *commitmentState, pkt *htlcPacket) {
|
||||||
var isSettle bool
|
var isSettle bool
|
||||||
switch htlc := pkt.msg.(type) {
|
switch htlc := pkt.msg.(type) {
|
||||||
@ -1262,7 +1262,7 @@ func (p *peer) handleDownStreamPkt(state *commitmentState, pkt *htlcPacket) {
|
|||||||
|
|
||||||
// If this newly added update exceeds the max batch size for adds, or
|
// If this newly added update exceeds the max batch size for adds, or
|
||||||
// this is a settle request, then initiate an update.
|
// this is a settle request, then initiate an update.
|
||||||
// TODO(roasbeef): enforce max HTLC's in flight limit
|
// TODO(roasbeef): enforce max HTLCs in flight limit
|
||||||
if len(state.pendingBatch) >= 10 || isSettle {
|
if len(state.pendingBatch) >= 10 || isSettle {
|
||||||
if sent, err := p.updateCommitTx(state); err != nil {
|
if sent, err := p.updateCommitTx(state); err != nil {
|
||||||
peerLog.Errorf("unable to update "+
|
peerLog.Errorf("unable to update "+
|
||||||
@ -1297,7 +1297,7 @@ func (p *peer) handleUpstreamMsg(state *commitmentState, msg lnwire.Message) {
|
|||||||
|
|
||||||
// We just received an add request from an upstream peer, so we
|
// We just received an add request from an upstream peer, so we
|
||||||
// add it to our state machine, then add the HTLC to our
|
// add it to our state machine, then add the HTLC to our
|
||||||
// "settle" list in the event that we know the pre-image
|
// "settle" list in the event that we know the preimage
|
||||||
index, err := state.channel.ReceiveHTLC(htlcPkt)
|
index, err := state.channel.ReceiveHTLC(htlcPkt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
peerLog.Errorf("Receiving HTLC rejected: %v", err)
|
peerLog.Errorf("Receiving HTLC rejected: %v", err)
|
||||||
@ -1377,7 +1377,7 @@ func (p *peer) handleUpstreamMsg(state *commitmentState, msg lnwire.Message) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(roasbeef): add pre-image to DB in order to swipe
|
// TODO(roasbeef): add preimage to DB in order to swipe
|
||||||
// repeated r-values
|
// repeated r-values
|
||||||
case *lnwire.CancelHTLC:
|
case *lnwire.CancelHTLC:
|
||||||
idx := uint32(htlcPkt.HTLCKey)
|
idx := uint32(htlcPkt.HTLCKey)
|
||||||
@ -1433,7 +1433,7 @@ func (p *peer) handleUpstreamMsg(state *commitmentState, msg lnwire.Message) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// If any of the htlc's eligible for forwarding are pending
|
// If any of the HTLCs eligible for forwarding are pending
|
||||||
// settling or timing out previous outgoing payments, then we
|
// settling or timing out previous outgoing payments, then we
|
||||||
// can them from the pending set, and signal the requester (if
|
// can them from the pending set, and signal the requester (if
|
||||||
// existing) that the payment has been fully fulfilled.
|
// existing) that the payment has been fully fulfilled.
|
||||||
@ -1522,7 +1522,7 @@ func (p *peer) handleUpstreamMsg(state *commitmentState, msg lnwire.Message) {
|
|||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for _, htlc := range htlcsToForward {
|
for _, htlc := range htlcsToForward {
|
||||||
// We don't need to forward any HTLC's that we
|
// We don't need to forward any HTLCs that we
|
||||||
// just settled or cancelled above.
|
// just settled or cancelled above.
|
||||||
// TODO(roasbeef): key by index instead?
|
// TODO(roasbeef): key by index instead?
|
||||||
if _, ok := settledPayments[htlc.RHash]; ok {
|
if _, ok := settledPayments[htlc.RHash]; ok {
|
||||||
@ -1614,7 +1614,7 @@ func (p *peer) updateCommitTx(state *commitmentState) (bool, error) {
|
|||||||
}
|
}
|
||||||
p.queueMsg(commitSig, nil)
|
p.queueMsg(commitSig, nil)
|
||||||
|
|
||||||
// Move all pending updates to the map of cleared HTLC's, clearing out
|
// Move all pending updates to the map of cleared HTLCs, clearing out
|
||||||
// the set of pending updates.
|
// the set of pending updates.
|
||||||
for _, update := range state.pendingBatch {
|
for _, update := range state.pendingBatch {
|
||||||
// TODO(roasbeef): add parsed next-hop info to pending batch
|
// TODO(roasbeef): add parsed next-hop info to pending batch
|
||||||
@ -1629,7 +1629,7 @@ func (p *peer) updateCommitTx(state *commitmentState) (bool, error) {
|
|||||||
|
|
||||||
// logEntryToHtlcPkt converts a particular Lightning Commitment Protocol (LCP)
|
// logEntryToHtlcPkt converts a particular Lightning Commitment Protocol (LCP)
|
||||||
// log entry the corresponding htlcPacket with src/dest set along with the
|
// log entry the corresponding htlcPacket with src/dest set along with the
|
||||||
// proper wire message. This helper method is provided in order to aide an
|
// proper wire message. This helper method is provided in order to aid an
|
||||||
// htlcManager in forwarding packets to the htlcSwitch.
|
// htlcManager in forwarding packets to the htlcSwitch.
|
||||||
func logEntryToHtlcPkt(chanPoint wire.OutPoint,
|
func logEntryToHtlcPkt(chanPoint wire.OutPoint,
|
||||||
pd *lnwallet.PaymentDescriptor,
|
pd *lnwallet.PaymentDescriptor,
|
||||||
|
@ -30,7 +30,7 @@ type Route struct {
|
|||||||
// route. This is the CLTV value that should be extended to the first
|
// route. This is the CLTV value that should be extended to the first
|
||||||
// hop in the route. All other hops will decrement the time-lock as
|
// hop in the route. All other hops will decrement the time-lock as
|
||||||
// advertised, leaving enough time for all hops to wait for or present
|
// advertised, leaving enough time for all hops to wait for or present
|
||||||
// the payment pre-image to complete the payment.
|
// the payment preimage to complete the payment.
|
||||||
TotalTimeLock uint32
|
TotalTimeLock uint32
|
||||||
|
|
||||||
// TotalFees is the sum of the fees paid at each hop within the final
|
// TotalFees is the sum of the fees paid at each hop within the final
|
||||||
|
@ -609,7 +609,7 @@ func (r *ChannelRouter) processNetworkAnnouncement(msg lnwire.Message) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// syncRequest represents a request from an outside sub-system to the wallet to
|
// syncRequest represents a request from an outside subsystem to the wallet to
|
||||||
// sync a new node to the latest graph state.
|
// sync a new node to the latest graph state.
|
||||||
type syncRequest struct {
|
type syncRequest struct {
|
||||||
node *btcec.PublicKey
|
node *btcec.PublicKey
|
||||||
|
12
rpcserver.go
12
rpcserver.go
@ -467,7 +467,7 @@ func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Respond to the local sub-system which requested the
|
// Respond to the local subsystem which requested the
|
||||||
// channel closure.
|
// channel closure.
|
||||||
updateChan <- &lnrpc.CloseStatusUpdate{
|
updateChan <- &lnrpc.CloseStatusUpdate{
|
||||||
Update: &lnrpc.CloseStatusUpdate_ChanClose{
|
Update: &lnrpc.CloseStatusUpdate_ChanClose{
|
||||||
@ -886,7 +886,7 @@ func (r *rpcServer) SendPayment(paymentStream lnrpc.Lightning_SendPaymentServer)
|
|||||||
|
|
||||||
}
|
}
|
||||||
// If we're in debug HTLC mode, then all outgoing
|
// If we're in debug HTLC mode, then all outgoing
|
||||||
// HTLC's will pay to the same debug rHash. Otherwise,
|
// HTLCs will pay to the same debug rHash. Otherwise,
|
||||||
// we pay to the rHash specified within the RPC
|
// we pay to the rHash specified within the RPC
|
||||||
// request.
|
// request.
|
||||||
var rHash [32]byte
|
var rHash [32]byte
|
||||||
@ -969,7 +969,7 @@ func (r *rpcServer) SendPaymentSync(ctx context.Context,
|
|||||||
// Otherwise, the payment conditions have been manually specified in
|
// Otherwise, the payment conditions have been manually specified in
|
||||||
// the proto.
|
// the proto.
|
||||||
} else {
|
} else {
|
||||||
// If we're in debug HTLC mode, then all outgoing HTLC's will pay to
|
// If we're in debug HTLC mode, then all outgoing HTLCs will pay to
|
||||||
// the same debug rHash. Otherwise, we pay to the rHash specified
|
// the same debug rHash. Otherwise, we pay to the rHash specified
|
||||||
// within the RPC request.
|
// within the RPC request.
|
||||||
if cfg.DebugHTLC && nextPayment.PaymentHashString == "" {
|
if cfg.DebugHTLC && nextPayment.PaymentHashString == "" {
|
||||||
@ -1044,8 +1044,8 @@ func (r *rpcServer) constructPaymentRoute(destNode *btcec.PublicKey,
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Craft an HTLC packet to send to the routing sub-system. The
|
// Craft an HTLC packet to send to the routing subsystem. The
|
||||||
// meta-data within this packet will be used to route the payment
|
// metadata within this packet will be used to route the payment
|
||||||
// through the network.
|
// through the network.
|
||||||
htlcAdd := &lnwire.HTLCAddRequest{
|
htlcAdd := &lnwire.HTLCAddRequest{
|
||||||
Amount: route.TotalAmount,
|
Amount: route.TotalAmount,
|
||||||
@ -1190,7 +1190,7 @@ func (r *rpcServer) AddInvoice(ctx context.Context,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next, generate the payment hash itself from the pre-image. This will
|
// Next, generate the payment hash itself from the preimage. This will
|
||||||
// be used by clients to query for the state of a particular invoice.
|
// be used by clients to query for the state of a particular invoice.
|
||||||
rHash := fastsha256.Sum256(paymentPreimage[:])
|
rHash := fastsha256.Sum256(paymentPreimage[:])
|
||||||
|
|
||||||
|
10
server.go
10
server.go
@ -135,7 +135,7 @@ func newServer(listenAddrs []string, notifier chainntnfs.ChainNotifier,
|
|||||||
|
|
||||||
// If the debug HTLC flag is on, then we invoice a "master debug"
|
// If the debug HTLC flag is on, then we invoice a "master debug"
|
||||||
// invoice which all outgoing payments will be sent and all incoming
|
// invoice which all outgoing payments will be sent and all incoming
|
||||||
// HTLC's with the debug R-Hash immediately settled.
|
// HTLCs with the debug R-Hash immediately settled.
|
||||||
if cfg.DebugHTLC {
|
if cfg.DebugHTLC {
|
||||||
kiloCoin := btcutil.Amount(btcutil.SatoshiPerBitcoin * 1000)
|
kiloCoin := btcutil.Amount(btcutil.SatoshiPerBitcoin * 1000)
|
||||||
s.invoices.AddDebugInvoice(kiloCoin, *debugPre)
|
s.invoices.AddDebugInvoice(kiloCoin, *debugPre)
|
||||||
@ -198,7 +198,7 @@ func newServer(listenAddrs []string, notifier chainntnfs.ChainNotifier,
|
|||||||
|
|
||||||
// In order to promote liveness of our active channels, instruct the
|
// In order to promote liveness of our active channels, instruct the
|
||||||
// connection manager to attempt to establish and maintain persistent
|
// connection manager to attempt to establish and maintain persistent
|
||||||
// connections to all our direct channel counter parties.
|
// connections to all our direct channel counterparties.
|
||||||
linkNodes, err := s.chanDB.FetchAllLinkNodes()
|
linkNodes, err := s.chanDB.FetchAllLinkNodes()
|
||||||
if err != nil && err != channeldb.ErrLinkNodesNotFound {
|
if err != nil && err != channeldb.ErrLinkNodesNotFound {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -240,7 +240,7 @@ func (s *server) Start() error {
|
|||||||
// goroutines can be notified when a funding transaction reaches a
|
// goroutines can be notified when a funding transaction reaches a
|
||||||
// sufficient number of confirmations, or when the input for the
|
// sufficient number of confirmations, or when the input for the
|
||||||
// funding transaction is spent in an attempt at an uncooperative close
|
// funding transaction is spent in an attempt at an uncooperative close
|
||||||
// by the counter party.
|
// by the counterparty.
|
||||||
if err := s.chainNotifier.Start(); err != nil {
|
if err := s.chainNotifier.Start(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -302,7 +302,7 @@ func (s *server) WaitForShutdown() {
|
|||||||
s.wg.Wait()
|
s.wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
// broadcastReq is a message sent to the server by a related sub-system when it
|
// broadcastReq is a message sent to the server by a related subsystem when it
|
||||||
// wishes to broadcast one or more messages to all connected peers. Thi
|
// wishes to broadcast one or more messages to all connected peers. Thi
|
||||||
type broadcastReq struct {
|
type broadcastReq struct {
|
||||||
ignore *btcec.PublicKey
|
ignore *btcec.PublicKey
|
||||||
@ -338,7 +338,7 @@ func (s *server) broadcastMessage(skip *btcec.PublicKey, msgs ...lnwire.Message)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendReq is message sent to the server by a related sub-system which it
|
// sendReq is message sent to the server by a related subsystem which it
|
||||||
// wishes to send a set of messages to a specified peer.
|
// wishes to send a set of messages to a specified peer.
|
||||||
type sendReq struct {
|
type sendReq struct {
|
||||||
target *btcec.PublicKey
|
target *btcec.PublicKey
|
||||||
|
@ -36,13 +36,13 @@ type HyperShaChain struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewHyperShaChain
|
// NewHyperShaChain
|
||||||
// * used to track their pre-images
|
// * used to track their preimages
|
||||||
func New() *HyperShaChain {
|
func New() *HyperShaChain {
|
||||||
return &HyperShaChain{lastChainIndex: 0, numValid: 0}
|
return &HyperShaChain{lastChainIndex: 0, numValid: 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHyperShaChainFromSeed...
|
// NewHyperShaChainFromSeed...
|
||||||
// * used to derive your own pre-images
|
// * used to derive your own preimages
|
||||||
func NewFromSeed(seed *[32]byte, deriveTo uint64) (*HyperShaChain, error) {
|
func NewFromSeed(seed *[32]byte, deriveTo uint64) (*HyperShaChain, error) {
|
||||||
var shaSeed [32]byte
|
var shaSeed [32]byte
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ func (h *HyperShaChain) CurrentRevocationHash() []byte {
|
|||||||
// LocatePreImage...
|
// LocatePreImage...
|
||||||
// Alice just broadcasted an old commitment tx, we need the revocation hash to
|
// Alice just broadcasted an old commitment tx, we need the revocation hash to
|
||||||
// claim the funds so we don't get cheated. However, we aren't storing all the
|
// claim the funds so we don't get cheated. However, we aren't storing all the
|
||||||
// pre-images in memory. So which shachain index # did she broadcast?
|
// preimages in memory. So which shachain index # did she broadcast?
|
||||||
func (h *HyperShaChain) LocatePreImage(outputScript []byte) (uint64, *[32]byte) {
|
func (h *HyperShaChain) LocatePreImage(outputScript []byte) (uint64, *[32]byte) {
|
||||||
// TODO(roasbeef): parallel goroutine divide and conquer?
|
// TODO(roasbeef): parallel goroutine divide and conquer?
|
||||||
// * need to know which side it is? also proper keys?
|
// * need to know which side it is? also proper keys?
|
||||||
|
Loading…
Reference in New Issue
Block a user