lnwallet: add CommitFee field to OpenChannel
In order to cleanly handle shutdowns and restarts during state machine operation, the fee for the current commitment transaction must be persisted. This allows the fee to be reapplied when the current state is reloaded.
This commit is contained in:
parent
7768415adc
commit
320bed7e6b
@ -68,7 +68,7 @@ var (
|
||||
updatePrefix = []byte("uup")
|
||||
satSentPrefix = []byte("ssp")
|
||||
satReceivedPrefix = []byte("srp")
|
||||
netFeesPrefix = []byte("ntp")
|
||||
commitFeePrefix = []byte("cfp")
|
||||
isPendingPrefix = []byte("pdg")
|
||||
openHeightPrefix = []byte("open-height-prefix")
|
||||
|
||||
@ -181,6 +181,13 @@ type OpenChannel struct {
|
||||
// channel directly spendable by the remote node.
|
||||
TheirBalance btcutil.Amount
|
||||
|
||||
// CommitFee is the amount calculated to be paid in fees for the
|
||||
// current set of commitment transactions. The fee amount is
|
||||
// persisted with the channel in order to allow the fee amount to be
|
||||
// removed and recalculated with each channel state update, including
|
||||
// updates that happen after a system restart.
|
||||
CommitFee btcutil.Amount
|
||||
|
||||
// OurCommitKey is the latest version of the commitment state,
|
||||
// broadcast able by us.
|
||||
OurCommitTx *wire.MsgTx
|
||||
@ -410,6 +417,7 @@ func (c *OpenChannel) UpdateCommitment(newCommitment *wire.MsgTx,
|
||||
c.TheirBalance = delta.RemoteBalance
|
||||
c.NumUpdates = delta.UpdateNum
|
||||
c.Htlcs = delta.Htlcs
|
||||
c.CommitFee = delta.CommitFee
|
||||
|
||||
// First we'll write out the current latest dynamic channel
|
||||
// state: the current channel balance, the number of updates,
|
||||
@ -424,6 +432,9 @@ func (c *OpenChannel) UpdateCommitment(newCommitment *wire.MsgTx,
|
||||
if err := putChanNumUpdates(chanBucket, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := putChanCommitFee(chanBucket, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := putChanCommitTxns(nodeChanBucket, c); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -492,6 +503,10 @@ type ChannelDelta struct {
|
||||
// update number.
|
||||
RemoteBalance btcutil.Amount
|
||||
|
||||
// CommitFee is the fee that has been subtracted from the channel
|
||||
// initiator's balance at this point in the commitment chain.
|
||||
CommitFee btcutil.Amount
|
||||
|
||||
// UpdateNum is the update number that this ChannelDelta represents the
|
||||
// total number of commitment updates to this point. This can be viewed
|
||||
// as sort of a "commitment height" as this number is monotonically
|
||||
@ -990,6 +1005,9 @@ func putOpenChannel(openChanBucket *bolt.Bucket, nodeChanBucket *bolt.Bucket,
|
||||
if err := putChanOpenHeight(openChanBucket, channel); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := putChanCommitFee(openChanBucket, channel); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Next, write out the fields of the channel update less frequently.
|
||||
if err := putChannelIDs(nodeChanBucket, channel); err != nil {
|
||||
@ -1080,6 +1098,9 @@ func fetchOpenChannel(openChanBucket *bolt.Bucket, nodeChanBucket *bolt.Bucket,
|
||||
if err := fetchChanOpenHeight(openChanBucket, channel); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = fetchChanCommitFee(openChanBucket, channel); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return channel, nil
|
||||
}
|
||||
@ -1113,6 +1134,9 @@ func deleteOpenChannel(openChanBucket *bolt.Bucket, nodeChanBucket *bolt.Bucket,
|
||||
if err := deleteChanOpenHeight(openChanBucket, channelID); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deleteChanCommitFee(openChanBucket, channelID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Finally, delete all the fields directly within the node's channel
|
||||
// bucket.
|
||||
@ -1591,6 +1615,46 @@ func deleteChanCommitKeys(nodeChanBucket *bolt.Bucket, chanID []byte) error {
|
||||
return nodeChanBucket.Delete(commitKey)
|
||||
}
|
||||
|
||||
func putChanCommitFee(openChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
||||
scratch := make([]byte, 8)
|
||||
byteOrder.PutUint64(scratch, uint64(channel.CommitFee))
|
||||
|
||||
var b bytes.Buffer
|
||||
if err := writeOutpoint(&b, channel.ChanID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
keyPrefix := make([]byte, 3+b.Len())
|
||||
copy(keyPrefix, commitFeePrefix)
|
||||
copy(keyPrefix[3:], b.Bytes())
|
||||
|
||||
return openChanBucket.Put(keyPrefix, scratch)
|
||||
}
|
||||
|
||||
func fetchChanCommitFee(openChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
||||
var b bytes.Buffer
|
||||
if err := writeOutpoint(&b, channel.ChanID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
keyPrefix := make([]byte, 3+b.Len())
|
||||
copy(keyPrefix, commitFeePrefix)
|
||||
copy(keyPrefix[3:], b.Bytes())
|
||||
|
||||
commitFeeBytes := openChanBucket.Get(keyPrefix)
|
||||
channel.CommitFee = btcutil.Amount(byteOrder.Uint64(commitFeeBytes))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func deleteChanCommitFee(openChanBucket *bolt.Bucket, chanID []byte) error {
|
||||
commitFeeKey := make([]byte, 3+len(chanID))
|
||||
copy(commitFeeKey, commitFeePrefix)
|
||||
copy(commitFeeKey[3:], chanID)
|
||||
|
||||
return openChanBucket.Delete(commitFeeKey)
|
||||
}
|
||||
|
||||
func fetchChanCommitKeys(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error {
|
||||
|
||||
// Construct the key which stores the commitment keys: ckk || channelID.
|
||||
@ -2119,6 +2183,11 @@ func serializeChannelDelta(w io.Writer, delta *ChannelDelta) error {
|
||||
}
|
||||
}
|
||||
|
||||
byteOrder.PutUint64(scratch[:], uint64(delta.CommitFee))
|
||||
if _, err := w.Write(scratch[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -2157,6 +2226,10 @@ func deserializeChannelDelta(r io.Reader) (*ChannelDelta, error) {
|
||||
|
||||
delta.Htlcs[i] = htlc
|
||||
}
|
||||
if _, err := r.Read(scratch[:]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
delta.CommitFee = btcutil.Amount(byteOrder.Uint64(scratch[:]))
|
||||
|
||||
return delta, nil
|
||||
}
|
||||
|
@ -232,6 +232,11 @@ type commitment struct {
|
||||
ourBalance btcutil.Amount
|
||||
theirBalance btcutil.Amount
|
||||
|
||||
// fee is the amount that will be paid as fees for this commitment
|
||||
// transaction. The fee is recorded here so that it can be added
|
||||
// back and recalculated for each new update to the channel state.
|
||||
fee btcutil.Amount
|
||||
|
||||
// htlcs is the set of HTLCs which remain unsettled within this
|
||||
// commitment.
|
||||
outgoingHTLCs []PaymentDescriptor
|
||||
@ -251,6 +256,7 @@ func (c *commitment) toChannelDelta(ourCommit bool) (*channeldb.ChannelDelta, er
|
||||
LocalBalance: c.ourBalance,
|
||||
RemoteBalance: c.theirBalance,
|
||||
UpdateNum: c.height,
|
||||
CommitFee: c.fee,
|
||||
Htlcs: make([]*channeldb.HTLC, 0, numHtlcs),
|
||||
}
|
||||
|
||||
@ -1181,6 +1187,8 @@ func (lc *LightningChannel) restoreStateLogs() error {
|
||||
lc.localCommitChain.tail().theirMessageIndex = theirCounter
|
||||
lc.remoteCommitChain.tail().ourMessageIndex = ourCounter
|
||||
lc.remoteCommitChain.tail().theirMessageIndex = theirCounter
|
||||
lc.localCommitChain.tail().fee = lc.channelState.CommitFee
|
||||
lc.remoteCommitChain.tail().fee = lc.channelState.CommitFee
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -1245,12 +1253,13 @@ func (lc *LightningChannel) fetchCommitmentView(remoteChain bool,
|
||||
|
||||
// TODO(roasbeef): don't assume view is always fetched from tip?
|
||||
var ourBalance, theirBalance btcutil.Amount
|
||||
if commitChain.tip() == nil {
|
||||
ourBalance = lc.channelState.OurBalance
|
||||
theirBalance = lc.channelState.TheirBalance
|
||||
} else {
|
||||
ourBalance = commitChain.tip().ourBalance
|
||||
theirBalance = commitChain.tip().theirBalance
|
||||
ourBalance = commitChain.tip().ourBalance
|
||||
theirBalance = commitChain.tip().theirBalance
|
||||
|
||||
if lc.channelState.IsInitiator {
|
||||
ourBalance = ourBalance + commitChain.tip().fee
|
||||
} else if !lc.channelState.IsInitiator {
|
||||
theirBalance = theirBalance + commitChain.tip().fee
|
||||
}
|
||||
|
||||
nextHeight := commitChain.tip().height + 1
|
||||
|
@ -215,6 +215,7 @@ func NewChannelReservation(capacity, fundingAmt btcutil.Amount, minFeeRate btcut
|
||||
TheirBalance: theirBalance,
|
||||
MinFeePerKb: minFeeRate,
|
||||
Db: wallet.ChannelDB,
|
||||
CommitFee: commitFee,
|
||||
},
|
||||
numConfsToOpen: numConfs,
|
||||
pushSat: pushSat,
|
||||
|
Loading…
Reference in New Issue
Block a user