diff --git a/lnwallet/channel.go b/lnwallet/channel.go index 1f45805c..650de152 100644 --- a/lnwallet/channel.go +++ b/lnwallet/channel.go @@ -349,7 +349,7 @@ type commitment struct { // feePerKw is the fee per kw used to calculate this commitment // transaction's fee. - feePerKw btcutil.Amount + feePerKw SatPerKWeight // dustLimit is the limit on the commitment transaction such that no // output values should be below this amount. @@ -532,7 +532,7 @@ func (c *commitment) toDiskCommit(ourCommit bool) *channeldb.ChannelCommitment { LocalBalance: c.ourBalance, RemoteBalance: c.theirBalance, CommitFee: c.fee, - FeePerKw: c.feePerKw, + FeePerKw: btcutil.Amount(c.feePerKw), CommitTx: c.txn, CommitSig: c.sig, Htlcs: make([]channeldb.HTLC, 0, numHtlcs), @@ -596,7 +596,7 @@ func (c *commitment) toDiskCommit(ourCommit bool) *channeldb.ChannelCommitment { // commitment struct and updateLog. This function is used when we need to // restore commitment state written do disk back into memory once we need to // restart a channel session. -func (lc *LightningChannel) diskHtlcToPayDesc(feeRate btcutil.Amount, +func (lc *LightningChannel) diskHtlcToPayDesc(feeRate SatPerKWeight, commitHeight uint64, isPendingCommit bool, htlc *channeldb.HTLC, localCommitKeys, remoteCommitKeys *CommitmentKeyRing) (PaymentDescriptor, error) { @@ -673,7 +673,7 @@ func (lc *LightningChannel) diskHtlcToPayDesc(feeRate btcutil.Amount, // these payment descriptors can be re-inserted into the in-memory updateLog // for each side. func (lc *LightningChannel) extractPayDescs(commitHeight uint64, - isPendingCommit bool, feeRate btcutil.Amount, + isPendingCommit bool, feeRate SatPerKWeight, htlcs []channeldb.HTLC, localCommitKeys *CommitmentKeyRing, remoteCommitKeys *CommitmentKeyRing) ([]PaymentDescriptor, []PaymentDescriptor, error) { @@ -735,7 +735,7 @@ func (lc *LightningChannel) diskCommitToMemCommit(isLocal, isPendingCommit bool, // update log. incomingHtlcs, outgoingHtlcs, err := lc.extractPayDescs( diskCommit.CommitHeight, isPendingCommit, - diskCommit.FeePerKw, diskCommit.Htlcs, + SatPerKWeight(diskCommit.FeePerKw), diskCommit.Htlcs, localCommitKeys, remoteCommitKeys, ) if err != nil { @@ -756,7 +756,7 @@ func (lc *LightningChannel) diskCommitToMemCommit(isLocal, isPendingCommit bool, txn: diskCommit.CommitTx, sig: diskCommit.CommitSig, fee: diskCommit.CommitFee, - feePerKw: diskCommit.FeePerKw, + feePerKw: SatPerKWeight(diskCommit.FeePerKw), incomingHTLCs: incomingHtlcs, outgoingHTLCs: outgoingHtlcs, } @@ -1181,12 +1181,12 @@ type LightningChannel struct { // channel initiator) or received (if non-initiator) in an update fee // message, which haven't yet been included in a commitment. It will // be nil if no fee update is un-committed. - pendingFeeUpdate *btcutil.Amount + pendingFeeUpdate *SatPerKWeight // pendingAckFeeUpdate is set to the last committed fee update which is // not yet ACKed. This value will be nil if a fee update hasn't been // initiated. - pendingAckFeeUpdate *btcutil.Amount + pendingAckFeeUpdate *SatPerKWeight // LocalFundingKey is the public key under control by the wallet that // was used for the 2-of-2 funding output which created this channel. @@ -1355,7 +1355,7 @@ func (lc *LightningChannel) ResetState() { // if nothing happened. func (lc *LightningChannel) logUpdateToPayDesc(logUpdate *channeldb.LogUpdate, remoteUpdateLog *updateLog, commitHeight uint64, - feeRate btcutil.Amount, remoteCommitKeys *CommitmentKeyRing, + feeRate SatPerKWeight, remoteCommitKeys *CommitmentKeyRing, remoteDustLimit btcutil.Amount) (*PaymentDescriptor, error) { // Depending on the type of update message we'll map that to a distinct @@ -1626,14 +1626,14 @@ func (lc *LightningChannel) restoreStateLogs( // entry within the updateLog, so we'll just apply it and move // on. if feeUpdate, ok := logUpdate.UpdateMsg.(*lnwire.UpdateFee); ok { - newFeeRate := btcutil.Amount(feeUpdate.FeePerKw) + newFeeRate := SatPerKWeight(feeUpdate.FeePerKw) lc.pendingAckFeeUpdate = &newFeeRate continue } payDesc, err := lc.logUpdateToPayDesc( &logUpdate, lc.remoteUpdateLog, pendingHeight, - pendingCommit.FeePerKw, pendingRemoteKeys, + SatPerKWeight(pendingCommit.FeePerKw), pendingRemoteKeys, lc.channelState.RemoteChanCfg.DustLimit, ) if err != nil { @@ -1930,14 +1930,14 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64, // htlcTimeoutFee returns the fee in satoshis required for an HTLC timeout // transaction based on the current fee rate. -func htlcTimeoutFee(feePerKw btcutil.Amount) btcutil.Amount { - return (feePerKw * HtlcTimeoutWeight) / 1000 +func htlcTimeoutFee(feePerKw SatPerKWeight) btcutil.Amount { + return feePerKw.FeeForWeight(HtlcTimeoutWeight) } // htlcSuccessFee returns the fee in satoshis required for an HTLC success // transaction based on the current fee rate. -func htlcSuccessFee(feePerKw btcutil.Amount) btcutil.Amount { - return (feePerKw * HtlcSuccessWeight) / 1000 +func htlcSuccessFee(feePerKw SatPerKWeight) btcutil.Amount { + return feePerKw.FeeForWeight(HtlcSuccessWeight) } // htlcIsDust determines if an HTLC output is dust or not depending on two @@ -1946,8 +1946,8 @@ func htlcSuccessFee(feePerKw btcutil.Amount) btcutil.Amount { // require as we currently used second-level HTLC transactions as off-chain // covenants. Depending on the two bits, we'll either be using a timeout or // success transaction which have different weights. -func htlcIsDust(incoming, ourCommit bool, - feePerKw, htlcAmt, dustLimit btcutil.Amount) bool { +func htlcIsDust(incoming, ourCommit bool, feePerKw SatPerKWeight, + htlcAmt, dustLimit btcutil.Amount) bool { // First we'll determine the fee required for this HTLC based on if this is // an incoming HTLC or not, and also on whose commitment transaction it @@ -2135,7 +2135,7 @@ func (lc *LightningChannel) createCommitmentTx(c *commitment, // With the weight known, we can now calculate the commitment fee, // ensuring that we account for any dust outputs trimmed above. - commitFee := btcutil.Amount((int64(c.feePerKw) * totalCommitWeight) / 1000) + commitFee := c.feePerKw.FeeForWeight(totalCommitWeight) // Currently, within the protocol, the initiator always pays the fees. // So we'll subtract the fee amount from the balance of the current @@ -3049,7 +3049,7 @@ func (lc *LightningChannel) ChanSyncMsg() (*lnwire.ChannelReestablish, error) { // of the HTLCs will be set to the next commitment height. func (lc *LightningChannel) computeView(view *htlcView, remoteChain bool, updateState bool) (lnwire.MilliSatoshi, lnwire.MilliSatoshi, int64, - *htlcView, btcutil.Amount) { + *htlcView, SatPerKWeight) { commitChain := lc.localCommitChain dustLimit := lc.localChanCfg.DustLimit @@ -3176,7 +3176,7 @@ func (lc *LightningChannel) validateCommitmentSanity(theirLogCounter, // Calculate the commitment fee, and subtract it from the // initiator's balance. - commitFee := btcutil.Amount((int64(feePerKw) * commitWeight) / 1000) + commitFee := feePerKw.FeeForWeight(commitWeight) if lc.channelState.IsInitiator { ourBalance -= lnwire.NewMSatFromSatoshis(commitFee) } else { @@ -4229,7 +4229,7 @@ func NewUnilateralCloseSummary(chanState *channeldb.OpenChannel, signer Signer, // Next, we'll obtain HTLC resolutions for all the outgoing HTLC's we // had on their commitment transaction. htlcResolutions, err := extractHtlcResolutions( - remoteCommit.FeePerKw, false, signer, remoteCommit.Htlcs, + SatPerKWeight(remoteCommit.FeePerKw), false, signer, remoteCommit.Htlcs, keyRing, &chanState.LocalChanCfg, &chanState.RemoteChanCfg, *commitSpend.SpenderTxHash, pCache, ) @@ -4403,7 +4403,7 @@ type HtlcResolutions struct { // the remote party's commitment transaction. func newOutgoingHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelConfig, commitHash chainhash.Hash, htlc *channeldb.HTLC, keyRing *CommitmentKeyRing, - feePewKw, dustLimit btcutil.Amount, csvDelay uint32, localCommit bool, + feePerKw SatPerKWeight, dustLimit btcutil.Amount, csvDelay uint32, localCommit bool, ) (*OutgoingHtlcResolution, error) { op := wire.OutPoint{ @@ -4453,7 +4453,7 @@ func newOutgoingHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelCon // In order to properly reconstruct the HTLC transaction, we'll need to // re-calculate the fee required at this state, so we can add the // correct output value amount to the transaction. - htlcFee := htlcTimeoutFee(feePewKw) + htlcFee := htlcTimeoutFee(feePerKw) secondLevelOutputAmt := htlc.Amt.ToSatoshis() - htlcFee // With the fee calculated, re-construct the second level timeout @@ -4541,9 +4541,8 @@ func newOutgoingHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelCon // TODO(roasbeef) consolidate code with above func func newIncomingHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelConfig, commitHash chainhash.Hash, htlc *channeldb.HTLC, keyRing *CommitmentKeyRing, - feePewKw, dustLimit btcutil.Amount, csvDelay uint32, localCommit bool, - preimage [32]byte, -) (*IncomingHtlcResolution, error) { + feePerKw SatPerKWeight, dustLimit btcutil.Amount, csvDelay uint32, + localCommit bool, preimage [32]byte) (*IncomingHtlcResolution, error) { op := wire.OutPoint{ Hash: commitHash, @@ -4590,7 +4589,7 @@ func newIncomingHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelCon // First, we'll reconstruct the original HTLC success transaction, // taking into account the fee rate used. - htlcFee := htlcSuccessFee(feePewKw) + htlcFee := htlcSuccessFee(feePerKw) secondLevelOutputAmt := htlc.Amt.ToSatoshis() - htlcFee successTx, err := createHtlcSuccessTx( op, secondLevelOutputAmt, csvDelay, @@ -4672,7 +4671,7 @@ func newIncomingHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelCon // extractHtlcResolutions creates a series of outgoing HTLC resolutions, and // the local key used when generating the HTLC scrips. This function is to be // used in two cases: force close, or a unilateral close. -func extractHtlcResolutions(feePerKw btcutil.Amount, ourCommit bool, +func extractHtlcResolutions(feePerKw SatPerKWeight, ourCommit bool, signer Signer, htlcs []channeldb.HTLC, keyRing *CommitmentKeyRing, localChanCfg, remoteChanCfg *channeldb.ChannelConfig, commitHash chainhash.Hash, pCache PreimageCache) (*HtlcResolutions, error) { @@ -4872,8 +4871,9 @@ func (lc *LightningChannel) ForceClose() (*ForceCloseSummary, error) { // outgoing HTLC's that we'll need to claim as well. txHash := commitTx.TxHash() htlcResolutions, err := extractHtlcResolutions( - localCommitment.FeePerKw, true, lc.signer, localCommitment.Htlcs, - keyRing, lc.localChanCfg, lc.remoteChanCfg, txHash, lc.pCache) + SatPerKWeight(localCommitment.FeePerKw), true, lc.signer, + localCommitment.Htlcs, keyRing, lc.localChanCfg, + lc.remoteChanCfg, txHash, lc.pCache) if err != nil { return nil, err } @@ -5075,7 +5075,7 @@ func (lc *LightningChannel) availableBalance() (lnwire.MilliSatoshi, int64) { // If we are the channel initiator, we must remember to subtract the // commitment fee from our available balance. - commitFee := btcutil.Amount((int64(feePerKw) * commitWeight) / 1000) + commitFee := feePerKw.FeeForWeight(commitWeight) if lc.channelState.IsInitiator { ourBalance -= lnwire.NewMSatFromSatoshis(commitFee) } @@ -5095,7 +5095,7 @@ func (lc *LightningChannel) StateSnapshot() *channeldb.ChannelSnapshot { // validateFeeRate ensures that if the passed fee is applied to the channel, // and a new commitment is created (which evaluates this fee), then the // initiator of the channel does not dip below their reserve. -func (lc *LightningChannel) validateFeeRate(feePerKw btcutil.Amount) error { +func (lc *LightningChannel) validateFeeRate(feePerKw SatPerKWeight) error { // We'll ensure that we can accommodate this new fee change, yet still // be above our reserve balance. Otherwise, we'll reject the fee // update. @@ -5105,7 +5105,7 @@ func (lc *LightningChannel) validateFeeRate(feePerKw btcutil.Amount) error { // a commitment now, we'll compute our remaining balance if we apply // this new fee update. newFee := lnwire.NewMSatFromSatoshis( - btcutil.Amount((int64(feePerKw) * txWeight) / 1000), + feePerKw.FeeForWeight(txWeight), ) balanceAfterFee := availableBalance - newFee @@ -5128,7 +5128,7 @@ func (lc *LightningChannel) validateFeeRate(feePerKw btcutil.Amount) error { // UpdateFee initiates a fee update for this channel. Must only be called by // the channel initiator, and must be called before sending update_fee to // the remote. -func (lc *LightningChannel) UpdateFee(feePerKw btcutil.Amount) error { +func (lc *LightningChannel) UpdateFee(feePerKw SatPerKWeight) error { lc.Lock() defer lc.Unlock() @@ -5150,7 +5150,7 @@ func (lc *LightningChannel) UpdateFee(feePerKw btcutil.Amount) error { // ReceiveUpdateFee handles an updated fee sent from remote. This method will // return an error if called as channel initiator. -func (lc *LightningChannel) ReceiveUpdateFee(feePerKw btcutil.Amount) error { +func (lc *LightningChannel) ReceiveUpdateFee(feePerKw SatPerKWeight) error { lc.Lock() defer lc.Unlock() @@ -5301,8 +5301,8 @@ func CreateCooperativeCloseTx(fundingTxIn wire.TxIn, // CalcFee returns the commitment fee to use for the given // fee rate (fee-per-kw). -func (lc *LightningChannel) CalcFee(feeRate uint64) uint64 { - return (feeRate * uint64(CommitWeight)) / 1000 +func (lc *LightningChannel) CalcFee(feeRate SatPerKWeight) btcutil.Amount { + return feeRate.FeeForWeight(CommitWeight) } // RemoteNextRevocation returns the channelState's RemoteNextRevocation. @@ -5325,11 +5325,11 @@ func (lc *LightningChannel) IsInitiator() bool { // CommitFeeRate returns the current fee rate of the commitment transaction in // units of sat-per-kw. -func (lc *LightningChannel) CommitFeeRate() btcutil.Amount { +func (lc *LightningChannel) CommitFeeRate() SatPerKWeight { lc.RLock() defer lc.RUnlock() - return lc.channelState.LocalCommitment.FeePerKw + return SatPerKWeight(lc.channelState.LocalCommitment.FeePerKw) } // IsPending returns true if the channel's funding transaction has been fully