From 6e54aba7ac81d8a9763c9e98808980168edc2ad4 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Mon, 21 Aug 2017 23:20:29 -0700 Subject: [PATCH] lnwallet: convert channel state machine accounting to milli-satoshi --- lnwallet/channel.go | 111 ++++++++++++----------- lnwallet/channel_test.go | 191 +++++++++++++++++++++------------------ 2 files changed, 160 insertions(+), 142 deletions(-) diff --git a/lnwallet/channel.go b/lnwallet/channel.go index e6f6a089..7456b335 100644 --- a/lnwallet/channel.go +++ b/lnwallet/channel.go @@ -149,8 +149,8 @@ type PaymentDescriptor struct { // expires. Timeout uint32 - // Amount is the HTLC amount in satoshis. - Amount btcutil.Amount + // Amount is the HTLC amount in milli-satoshis. + Amount lnwire.MilliSatoshi // Index is the log entry number that his HTLC update has within the // log. Depending on if IsIncoming is true, this is either an entry the @@ -260,8 +260,8 @@ type commitment struct { // within the commitment chain. This balance is computed by properly // evaluating all the add/remove/settle log entries before the listed // indexes. - ourBalance btcutil.Amount - theirBalance btcutil.Amount + ourBalance lnwire.MilliSatoshi + theirBalance lnwire.MilliSatoshi // 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 @@ -360,7 +360,7 @@ func (c *commitment) populateHtlcIndexes(ourCommitTx bool, // indexes within the commitment view for a particular HTLC. populateIndex := func(htlc *PaymentDescriptor, incoming bool) error { isDust := htlcIsDust(incoming, ourCommitTx, c.feePerKw, - htlc.Amount, dustLimit) + htlc.Amount.ToSatoshis(), dustLimit) var err error switch { @@ -822,7 +822,7 @@ type LightningChannel struct { // availableLocalBalance represent the amount of available money which // might be processed by this channel at the specific point of time. - availableLocalBalance btcutil.Amount + availableLocalBalance lnwire.MilliSatoshi sync.RWMutex @@ -1198,7 +1198,7 @@ func newBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64, DoubleTweak: commitmentSecret, WitnessScript: htlcScript, Output: &wire.TxOut{ - Value: int64(htlc.Amt), + Value: int64(htlc.Amt.ToSatoshis()), }, HashType: txscript.SigHashAll, }, @@ -1228,7 +1228,7 @@ func newBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64, WitnessScript: localPkScript, Output: &wire.TxOut{ PkScript: localWitnessHash, - Value: int64(revokedSnapshot.LocalBalance), + Value: int64(revokedSnapshot.LocalBalance.ToSatoshis()), }, HashType: txscript.SigHashAll, }, @@ -1239,7 +1239,7 @@ func newBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64, WitnessScript: remotePkScript, Output: &wire.TxOut{ PkScript: remoteWitnessHash, - Value: int64(revokedSnapshot.RemoteBalance), + Value: int64(revokedSnapshot.RemoteBalance.ToSatoshis()), }, HashType: txscript.SigHashAll, }, @@ -1350,7 +1350,7 @@ func (lc *LightningChannel) closeObserver(channelCloseNtfn *chainntnfs.SpendEven ClosingTXID: *commitSpend.SpenderTxHash, RemotePub: lc.channelState.IdentityPub, Capacity: lc.Capacity, - SettledBalance: lc.channelState.LocalBalance, + SettledBalance: lc.channelState.LocalBalance.ToSatoshis(), CloseType: channeldb.ForceClose, IsPending: true, } @@ -1412,7 +1412,7 @@ func (lc *LightningChannel) closeObserver(channelCloseNtfn *chainntnfs.SpendEven SingleTweak: SingleTweakBytes(commitPoint, localPayBase), WitnessScript: selfP2WKH, Output: &wire.TxOut{ - Value: int64(lc.channelState.LocalBalance), + Value: int64(lc.channelState.LocalBalance.ToSatoshis()), PkScript: selfP2WKH, }, HashType: txscript.SigHashAll, @@ -1599,9 +1599,9 @@ func (lc *LightningChannel) restoreStateLogs() error { // dust with a special output index in the on-disk state // snapshot. isDustLocal := htlcIsDust(htlc.Incoming, true, feeRate, - htlc.Amt, localChanCfg.DustLimit) + htlc.Amt.ToSatoshis(), localChanCfg.DustLimit) isDustRemote := htlcIsDust(htlc.Incoming, false, feeRate, - htlc.Amt, remoteChanCfg.DustLimit) + htlc.Amt.ToSatoshis(), remoteChanCfg.DustLimit) if !isDustLocal { ourP2WSH, ourWitnessScript, err = lc.genHtlcScript( htlc.Incoming, true, htlc.RefundTimeout, htlc.RHash, @@ -1723,9 +1723,9 @@ func (lc *LightningChannel) fetchCommitmentView(remoteChain bool, // re-applied in case fee estimation parameters have changed or the // number of outstanding HTLCs has changed. if lc.channelState.IsInitiator { - ourBalance = ourBalance + commitChain.tip().fee + ourBalance += lnwire.NewMSatFromSatoshis(commitChain.tip().fee) } else if !lc.channelState.IsInitiator { - theirBalance = theirBalance + commitChain.tip().fee + theirBalance += lnwire.NewMSatFromSatoshis(commitChain.tip().fee) } nextHeight := commitChain.tip().height + 1 @@ -1783,8 +1783,8 @@ func (lc *LightningChannel) fetchCommitmentView(remoteChain bool, } numHTLCs := int64(0) for _, htlc := range filteredHTLCView.ourUpdates { - if htlcIsDust(false, ourCommitTx, feePerKw, htlc.Amount, - dustLimit) { + if htlcIsDust(false, ourCommitTx, feePerKw, + htlc.Amount.ToSatoshis(), dustLimit) { continue } @@ -1792,8 +1792,8 @@ func (lc *LightningChannel) fetchCommitmentView(remoteChain bool, numHTLCs++ } for _, htlc := range filteredHTLCView.theirUpdates { - if htlcIsDust(true, ourCommitTx, feePerKw, htlc.Amount, - dustLimit) { + if htlcIsDust(true, ourCommitTx, feePerKw, + htlc.Amount.ToSatoshis(), dustLimit) { continue } @@ -1815,9 +1815,9 @@ func (lc *LightningChannel) fetchCommitmentView(remoteChain bool, // So we'll subtract the fee amount from the balance of the current // initiator. if lc.channelState.IsInitiator { - ourBalance -= commitFee + ourBalance -= lnwire.NewMSatFromSatoshis(commitFee) } else if !lc.channelState.IsInitiator { - theirBalance -= commitFee + theirBalance -= lnwire.NewMSatFromSatoshis(commitFee) } var ( @@ -1842,8 +1842,8 @@ func (lc *LightningChannel) fetchCommitmentView(remoteChain bool, ) delay = uint32(lc.remoteChanCfg.CsvDelay) - delayBalance = theirBalance - p2wkhBalance = ourBalance + delayBalance = theirBalance.ToSatoshis() + p2wkhBalance = ourBalance.ToSatoshis() } else { delayKey = TweakPubKey(lc.localChanCfg.DelayBasePoint, commitPoint) @@ -1855,8 +1855,8 @@ func (lc *LightningChannel) fetchCommitmentView(remoteChain bool, ) delay = uint32(lc.localChanCfg.CsvDelay) - delayBalance = ourBalance - p2wkhBalance = theirBalance + delayBalance = ourBalance.ToSatoshis() + p2wkhBalance = theirBalance.ToSatoshis() } // TODO(roasbeef); create all keys unconditionally within commitment @@ -1878,8 +1878,8 @@ func (lc *LightningChannel) fetchCommitmentView(remoteChain bool, localKey := TweakPubKey(lc.localChanCfg.PaymentBasePoint, commitPoint) remoteKey := TweakPubKey(lc.remoteChanCfg.PaymentBasePoint, commitPoint) for _, htlc := range filteredHTLCView.ourUpdates { - if htlcIsDust(false, !remoteChain, feePerKw, htlc.Amount, - dustLimit) { + if htlcIsDust(false, !remoteChain, feePerKw, + htlc.Amount.ToSatoshis(), dustLimit) { continue } @@ -1890,8 +1890,8 @@ func (lc *LightningChannel) fetchCommitmentView(remoteChain bool, } } for _, htlc := range filteredHTLCView.theirUpdates { - if htlcIsDust(true, !remoteChain, feePerKw, htlc.Amount, - dustLimit) { + if htlcIsDust(true, !remoteChain, feePerKw, + htlc.Amount.ToSatoshis(), dustLimit) { continue } @@ -1953,7 +1953,7 @@ func (lc *LightningChannel) fetchCommitmentView(remoteChain bool, // reflects the current state of HTLCs within the remote or local commitment // chain. func (lc *LightningChannel) evaluateHTLCView(view *htlcView, ourBalance, - theirBalance *btcutil.Amount, nextHeight uint64, remoteChain bool) *htlcView { + theirBalance *lnwire.MilliSatoshi, nextHeight uint64, remoteChain bool) *htlcView { newView := &htlcView{} @@ -1977,7 +1977,7 @@ func (lc *LightningChannel) evaluateHTLCView(view *htlcView, ourBalance, // number of satoshis we've received within the channel. if entry.EntryType == Settle && !remoteChain && entry.removeCommitHeightLocal == 0 { - lc.channelState.TotalSatoshisReceived += uint64(entry.Amount) + lc.channelState.TotalMSatReceived += entry.Amount } addEntry := lc.remoteUpdateLog.lookup(entry.ParentIndex) @@ -1997,7 +1997,7 @@ func (lc *LightningChannel) evaluateHTLCView(view *htlcView, ourBalance, // channel. if entry.EntryType == Settle && !remoteChain && entry.removeCommitHeightLocal == 0 { - lc.channelState.TotalSatoshisSent += uint64(entry.Amount) + lc.channelState.TotalMSatSent += entry.Amount } addEntry := lc.localUpdateLog.lookup(entry.ParentIndex) @@ -2038,7 +2038,7 @@ func (lc *LightningChannel) evaluateHTLCView(view *htlcView, ourBalance, // If the HTLC hasn't yet been committed in either chain, then the height it // was committed is updated. Keeping track of this inclusion height allows us to // later compact the log once the change is fully committed in both chains. -func processAddEntry(htlc *PaymentDescriptor, ourBalance, theirBalance *btcutil.Amount, +func processAddEntry(htlc *PaymentDescriptor, ourBalance, theirBalance *lnwire.MilliSatoshi, nextHeight uint64, remoteChain bool, isIncoming bool) { // If we're evaluating this entry for the remote chain (to create/view @@ -2074,7 +2074,7 @@ func processAddEntry(htlc *PaymentDescriptor, ourBalance, theirBalance *btcutil. // previously added HTLC. If the removal entry has already been processed, it // is skipped. func processRemoveEntry(htlc *PaymentDescriptor, ourBalance, - theirBalance *btcutil.Amount, nextHeight uint64, + theirBalance *lnwire.MilliSatoshi, nextHeight uint64, remoteChain bool, isIncoming bool) { var removeHeight *uint64 @@ -2162,7 +2162,8 @@ func genRemoteHtlcSigJobs(commitPoint *btcec.PublicKey, // dust output after taking into account second-level HTLC fees, then a // sigJob will be generated and appended to the current batch. for _, htlc := range remoteCommitView.incomingHTLCs { - if htlcIsDust(true, false, feePerKw, htlc.Amount, dustLimit) { + if htlcIsDust(true, false, feePerKw, htlc.Amount.ToSatoshis(), + dustLimit) { continue } @@ -2178,7 +2179,7 @@ func genRemoteHtlcSigJobs(commitPoint *btcec.PublicKey, // transaction needs to account for fees, so we'll compute the // required fee and output now. htlcFee := htlcTimeoutFee(feePerKw) - outputAmt := htlc.Amount - htlcFee + outputAmt := htlc.Amount.ToSatoshis() - htlcFee // With the fee calculate, we can properly create the HTLC // timeout transaction using the HTLC amount minus the fee. @@ -2201,7 +2202,7 @@ func genRemoteHtlcSigJobs(commitPoint *btcec.PublicKey, SingleTweak: commitTweak, WitnessScript: htlc.theirWitnessScript, Output: &wire.TxOut{ - Value: int64(htlc.Amount), + Value: int64(htlc.Amount.ToSatoshis()), }, HashType: txscript.SigHashAll, SigHashes: txscript.NewTxSigHashes(sigJob.tx), @@ -2212,7 +2213,8 @@ func genRemoteHtlcSigJobs(commitPoint *btcec.PublicKey, sigBatch = append(sigBatch, sigJob) } for _, htlc := range remoteCommitView.outgoingHTLCs { - if htlcIsDust(false, false, feePerKw, htlc.Amount, dustLimit) { + if htlcIsDust(false, false, feePerKw, htlc.Amount.ToSatoshis(), + dustLimit) { continue } @@ -2226,7 +2228,7 @@ func genRemoteHtlcSigJobs(commitPoint *btcec.PublicKey, // transaction needs to account for fees, so we'll compute the // required fee and output now. htlcFee := htlcSuccessFee(feePerKw) - outputAmt := htlc.Amount - htlcFee + outputAmt := htlc.Amount.ToSatoshis() - htlcFee // With the proper output amount calculated, we can now // generate the success transaction using the remote party's @@ -2250,7 +2252,7 @@ func genRemoteHtlcSigJobs(commitPoint *btcec.PublicKey, SingleTweak: commitTweak, WitnessScript: htlc.theirWitnessScript, Output: &wire.TxOut{ - Value: int64(htlc.Amount), + Value: int64(htlc.Amount.ToSatoshis()), }, HashType: txscript.SigHashAll, SigHashes: txscript.NewTxSigHashes(sigJob.tx), @@ -2526,7 +2528,7 @@ func genHtlcSigValidationJobs(localCommitmentView *commitment, } htlcFee := htlcSuccessFee(feePerKw) - outputAmt := htlc.Amount - htlcFee + outputAmt := htlc.Amount.ToSatoshis() - htlcFee successTx, err := createHtlcSuccessTx(op, outputAmt, uint32(localChanCfg.CsvDelay), @@ -2539,7 +2541,8 @@ func genHtlcSigValidationJobs(localCommitmentView *commitment, sigHash, err := txscript.CalcWitnessSigHash( htlc.ourWitnessScript, hashCache, txscript.SigHashAll, successTx, 0, - int64(htlc.Amount)) + int64(htlc.Amount.ToSatoshis()), + ) if err != nil { return nil, err } @@ -2565,7 +2568,7 @@ func genHtlcSigValidationJobs(localCommitmentView *commitment, } htlcFee := htlcTimeoutFee(feePerKw) - outputAmt := htlc.Amount - htlcFee + outputAmt := htlc.Amount.ToSatoshis() - htlcFee timeoutTx, err := createHtlcTimeoutTx(op, outputAmt, htlc.Timeout, @@ -2580,7 +2583,7 @@ func genHtlcSigValidationJobs(localCommitmentView *commitment, sigHash, err := txscript.CalcWitnessSigHash( htlc.ourWitnessScript, hashCache, txscript.SigHashAll, timeoutTx, 0, - int64(htlc.Amount), + int64(htlc.Amount.ToSatoshis()), ) if err != nil { return nil, err @@ -2838,7 +2841,7 @@ func (lc *LightningChannel) RevokeCurrentCommitment() (*lnwire.RevokeAndAck, err // LocalAvailableBalance returns the amount of available money which might be // proceed by this channel at the specific point of time. -func (lc *LightningChannel) LocalAvailableBalance() btcutil.Amount { +func (lc *LightningChannel) LocalAvailableBalance() lnwire.MilliSatoshi { lc.Lock() defer lc.Unlock() @@ -3388,7 +3391,7 @@ func newHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelConfig, // re-calculate the fee required at this state, so we can add the // correct output value amount to the transaction. htlcFee := htlcTimeoutFee(feePewKw) - secondLevelOutputAmt := htlc.Amt - htlcFee + secondLevelOutputAmt := htlc.Amt.ToSatoshis() - htlcFee // With the fee calculated, re-construct the second level timeout // transaction. @@ -3413,7 +3416,7 @@ func newHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelConfig, SingleTweak: commitTweak, WitnessScript: htlcCreationScript, Output: &wire.TxOut{ - Value: int64(htlc.Amt), + Value: int64(htlc.Amt.ToSatoshis()), }, HashType: txscript.SigHashAll, SigHashes: txscript.NewTxSigHashes(timeoutTx), @@ -3488,8 +3491,8 @@ func extractHtlcResolutions(feePerKw btcutil.Amount, ourCommit bool, // We'll also skip any HTLC's which were dust on the commitment // transaction, as these don't have a corresponding output // within the commitment transaction. - if htlcIsDust(htlc.Incoming, ourCommit, feePerKw, htlc.Amt, - dustLimit) { + if htlcIsDust(htlc.Incoming, ourCommit, feePerKw, + htlc.Amt.ToSatoshis(), dustLimit) { continue } @@ -3625,7 +3628,7 @@ func (lc *LightningChannel) ForceClose() (*ForceCloseSummary, error) { WitnessScript: selfScript, Output: &wire.TxOut{ PkScript: delayScript, - Value: int64(lc.channelState.LocalBalance), + Value: int64(lc.channelState.LocalBalance.ToSatoshis()), }, HashType: txscript.SigHashAll, } @@ -3686,8 +3689,8 @@ func (lc *LightningChannel) CreateCloseProposal(proposedFee uint64, // Subtract the proposed fee from the appropriate balance, taking care // not to persist the adjusted balance, as the feeRate may change // during the channel closing process. - ourBalance := lc.channelState.LocalBalance - theirBalance := lc.channelState.RemoteBalance + ourBalance := lc.channelState.LocalBalance.ToSatoshis() + theirBalance := lc.channelState.RemoteBalance.ToSatoshis() if lc.channelState.IsInitiator { ourBalance = ourBalance - btcutil.Amount(proposedFee) @@ -3747,8 +3750,8 @@ func (lc *LightningChannel) CompleteCooperativeClose(localSig, remoteSig, // Subtract the proposed fee from the appropriate balance, taking care // not to persist the adjusted balance, as the feeRate may change // during the channel closing process. - ourBalance := lc.channelState.LocalBalance - theirBalance := lc.channelState.RemoteBalance + ourBalance := lc.channelState.LocalBalance.ToSatoshis() + theirBalance := lc.channelState.RemoteBalance.ToSatoshis() if lc.channelState.IsInitiator { ourBalance = ourBalance - btcutil.Amount(proposedFee) diff --git a/lnwallet/channel_test.go b/lnwallet/channel_test.go index dc4cd912..8ba3e0a0 100644 --- a/lnwallet/channel_test.go +++ b/lnwallet/channel_test.go @@ -224,9 +224,9 @@ func createTestChannels(revocationWindow int) (*LightningChannel, *LightningChan aliceCfg := channeldb.ChannelConfig{ ChannelConstraints: channeldb.ChannelConstraints{ DustLimit: aliceDustLimit, - MaxPendingAmount: btcutil.Amount(rand.Int63()), + MaxPendingAmount: lnwire.MilliSatoshi(rand.Int63()), ChanReserve: btcutil.Amount(rand.Int63()), - MinHTLC: btcutil.Amount(rand.Int63()), + MinHTLC: lnwire.MilliSatoshi(rand.Int63()), MaxAcceptedHtlcs: uint16(rand.Int31()), }, CsvDelay: uint16(csvTimeoutAlice), @@ -238,9 +238,9 @@ func createTestChannels(revocationWindow int) (*LightningChannel, *LightningChan bobCfg := channeldb.ChannelConfig{ ChannelConstraints: channeldb.ChannelConstraints{ DustLimit: bobDustLimit, - MaxPendingAmount: btcutil.Amount(rand.Int63()), + MaxPendingAmount: lnwire.MilliSatoshi(rand.Int63()), ChanReserve: btcutil.Amount(rand.Int63()), - MinHTLC: btcutil.Amount(rand.Int63()), + MinHTLC: lnwire.MilliSatoshi(rand.Int63()), MaxAcceptedHtlcs: uint16(rand.Int31()), }, CsvDelay: uint16(csvTimeoutBob), @@ -301,8 +301,8 @@ func createTestChannels(revocationWindow int) (*LightningChannel, *LightningChan FeePerKw: feePerKw, IsInitiator: true, Capacity: channelCapacity, - LocalBalance: channelBal - commitFee, - RemoteBalance: channelBal, + LocalBalance: lnwire.NewMSatFromSatoshis(channelBal - commitFee), + RemoteBalance: lnwire.NewMSatFromSatoshis(channelBal), CommitTx: *aliceCommitTx, CommitSig: bytes.Repeat([]byte{1}, 71), RemoteCurrentRevocation: bobCommitPoint, @@ -320,8 +320,8 @@ func createTestChannels(revocationWindow int) (*LightningChannel, *LightningChan ChanType: channeldb.SingleFunder, IsInitiator: false, Capacity: channelCapacity, - LocalBalance: channelBal, - RemoteBalance: channelBal - commitFee, + LocalBalance: lnwire.NewMSatFromSatoshis(channelBal), + RemoteBalance: lnwire.NewMSatFromSatoshis(channelBal - commitFee), CommitTx: *bobCommitTx, CommitSig: bytes.Repeat([]byte{1}, 71), RemoteCurrentRevocation: aliceCommitPoint, @@ -378,7 +378,7 @@ func calcStaticFee(numHTLCs int) btcutil.Amount { // createHTLC is a utility function for generating an HTLC with a given // preimage and a given amount. -func createHTLC(data int, amount btcutil.Amount) (*lnwire.UpdateAddHTLC, [32]byte) { +func createHTLC(data int, amount lnwire.MilliSatoshi) (*lnwire.UpdateAddHTLC, [32]byte) { preimage := bytes.Repeat([]byte{byte(data)}, 32) paymentHash := sha256.Sum256(preimage) @@ -417,7 +417,7 @@ func TestSimpleAddSettleWorkflow(t *testing.T) { paymentHash := sha256.Sum256(paymentPreimage) htlc := &lnwire.UpdateAddHTLC{ PaymentHash: paymentHash, - Amount: btcutil.SatoshiPerBitcoin, + Amount: lnwire.NewMSatFromSatoshis(btcutil.SatoshiPerBitcoin), Expiry: uint32(5), } @@ -501,24 +501,24 @@ func TestSimpleAddSettleWorkflow(t *testing.T) { // At this point, both sides should have the proper number of satoshis // sent, and commitment height updated within their local channel // state. - aliceSent := uint64(0) - bobSent := uint64(0) + aliceSent := lnwire.MilliSatoshi(0) + bobSent := lnwire.MilliSatoshi(0) - if aliceChannel.channelState.TotalSatoshisSent != aliceSent { - t.Fatalf("alice has incorrect satoshis sent: %v vs %v", - aliceChannel.channelState.TotalSatoshisSent, aliceSent) + if aliceChannel.channelState.TotalMSatSent != aliceSent { + t.Fatalf("alice has incorrect milli-satoshis sent: %v vs %v", + aliceChannel.channelState.TotalMSatSent, aliceSent) } - if aliceChannel.channelState.TotalSatoshisReceived != bobSent { - t.Fatalf("alice has incorrect satoshis received %v vs %v", - aliceChannel.channelState.TotalSatoshisReceived, bobSent) + if aliceChannel.channelState.TotalMSatReceived != bobSent { + t.Fatalf("alice has incorrect milli-satoshis received %v vs %v", + aliceChannel.channelState.TotalMSatReceived, bobSent) } - if bobChannel.channelState.TotalSatoshisSent != bobSent { - t.Fatalf("bob has incorrect satoshis sent %v vs %v", - bobChannel.channelState.TotalSatoshisSent, bobSent) + if bobChannel.channelState.TotalMSatSent != bobSent { + t.Fatalf("bob has incorrect milli-satoshis sent %v vs %v", + bobChannel.channelState.TotalMSatSent, bobSent) } - if bobChannel.channelState.TotalSatoshisReceived != aliceSent { - t.Fatalf("bob has incorrect satoshis received %v vs %v", - bobChannel.channelState.TotalSatoshisReceived, aliceSent) + if bobChannel.channelState.TotalMSatReceived != aliceSent { + t.Fatalf("bob has incorrect milli-satoshis received %v vs %v", + bobChannel.channelState.TotalMSatReceived, aliceSent) } if bobChannel.currentHeight != 1 { t.Fatalf("bob has incorrect commitment height, %v vs %v", @@ -585,27 +585,27 @@ func TestSimpleAddSettleWorkflow(t *testing.T) { } // At this point, Bob should have 6 BTC settled, with Alice still having - // 4 BTC. Alice's channel should show 1 BTC sent and Bob's channel should - // show 1 BTC received. They should also be at commitment height two, - // with the revocation window extended by by 1 (5). - satoshisTransferred := uint64(100000000) - if aliceChannel.channelState.TotalSatoshisSent != satoshisTransferred { + // 4 BTC. Alice's channel should show 1 BTC sent and Bob's channel + // should show 1 BTC received. They should also be at commitment height + // two, with the revocation window extended by by 1 (5). + mSatTransferred := lnwire.NewMSatFromSatoshis(btcutil.SatoshiPerBitcoin) + if aliceChannel.channelState.TotalMSatSent != mSatTransferred { t.Fatalf("alice satoshis sent incorrect %v vs %v expected", - aliceChannel.channelState.TotalSatoshisSent, - satoshisTransferred) + aliceChannel.channelState.TotalMSatSent, + mSatTransferred) } - if aliceChannel.channelState.TotalSatoshisReceived != 0 { + if aliceChannel.channelState.TotalMSatReceived != 0 { t.Fatalf("alice satoshis received incorrect %v vs %v expected", - aliceChannel.channelState.TotalSatoshisSent, 0) + aliceChannel.channelState.TotalMSatReceived, 0) } - if bobChannel.channelState.TotalSatoshisReceived != satoshisTransferred { + if bobChannel.channelState.TotalMSatReceived != mSatTransferred { t.Fatalf("bob satoshis received incorrect %v vs %v expected", - bobChannel.channelState.TotalSatoshisReceived, - satoshisTransferred) + bobChannel.channelState.TotalMSatReceived, + mSatTransferred) } - if bobChannel.channelState.TotalSatoshisSent != 0 { + if bobChannel.channelState.TotalMSatSent != 0 { t.Fatalf("bob satoshis sent incorrect %v vs %v expected", - bobChannel.channelState.TotalSatoshisReceived, 0) + bobChannel.channelState.TotalMSatSent, 0) } if bobChannel.currentHeight != 2 { t.Fatalf("bob has incorrect commitment height, %v vs %v", @@ -680,7 +680,7 @@ func TestCheckCommitTxSize(t *testing.T) { // Adding HTLCs and check that size stays in allowable estimation // error window. for i := 1; i <= 10; i++ { - htlc, _ := createHTLC(i, btcutil.Amount(1e7)) + htlc, _ := createHTLC(i, lnwire.MilliSatoshi(1e7)) if _, err := aliceChannel.AddHTLC(htlc); err != nil { t.Fatalf("alice unable to add htlc: %v", err) @@ -699,7 +699,7 @@ func TestCheckCommitTxSize(t *testing.T) { // Settle HTLCs and check that estimation is counting cost of settle // HTLCs properly. for i := 10; i >= 1; i-- { - _, preimage := createHTLC(i, btcutil.Amount(1e7)) + _, preimage := createHTLC(i, lnwire.MilliSatoshi(1e7)) settleIndex, err := bobChannel.SettleHTLC(preimage) if err != nil { @@ -797,7 +797,7 @@ func TestForceClose(t *testing.T) { } defer cleanUp() - htlcAmount := btcutil.Amount(500) + htlcAmount := lnwire.NewMSatFromSatoshis(500) aliceAmount := aliceChannel.channelState.LocalBalance bobAmount := bobChannel.channelState.LocalBalance @@ -818,10 +818,12 @@ func TestForceClose(t *testing.T) { if !closeSummary.SelfOutputSignDesc.PubKey.IsEqual(aliceDelayPoint) { t.Fatalf("alice incorrect pubkey in SelfOutputSignDesc") } - if closeSummary.SelfOutputSignDesc.Output.Value != int64(aliceAmount) { + if closeSummary.SelfOutputSignDesc.Output.Value != + int64(aliceAmount.ToSatoshis()) { + t.Fatalf("alice incorrect output value in SelfOutputSignDesc, "+ "expected %v, got %v", - aliceChannel.channelState.LocalBalance, + aliceChannel.channelState.LocalBalance.ToSatoshis(), closeSummary.SelfOutputSignDesc.Output.Value) } if closeSummary.SelfOutputMaturity != @@ -850,10 +852,12 @@ func TestForceClose(t *testing.T) { if !closeSummary.SelfOutputSignDesc.PubKey.IsEqual(bobDelayPoint) { t.Fatalf("bob incorrect pubkey in SelfOutputSignDesc") } - if closeSummary.SelfOutputSignDesc.Output.Value != int64(bobAmount) { + if closeSummary.SelfOutputSignDesc.Output.Value != + int64(bobAmount.ToSatoshis()) { + t.Fatalf("bob incorrect output value in SelfOutputSignDesc, "+ "expected %v, got %v", - int64(bobAmount), + bobAmount.ToSatoshis(), int64(closeSummary.SelfOutputSignDesc.Output.Value)) } if closeSummary.SelfOutputMaturity != @@ -922,10 +926,10 @@ func TestForceClose(t *testing.T) { t.Fatalf("alice incorrect pubkey in SelfOutputSignDesc") } if closeSummary.SelfOutputSignDesc.Output.Value != - int64(aliceAmount) { + int64(aliceAmount.ToSatoshis()) { t.Fatalf("alice incorrect output value in SelfOutputSignDesc, "+ "expected %v, got %v", - aliceChannel.channelState.LocalBalance, + aliceChannel.channelState.LocalBalance.ToSatoshis(), closeSummary.SelfOutputSignDesc.Output.Value) } @@ -978,7 +982,7 @@ func TestDustHTLCFees(t *testing.T) { aliceStartingBalance := aliceChannel.channelState.LocalBalance // This HTLC amount should be lower than the dust limits of both nodes. - htlcAmount := btcutil.Amount(100) + htlcAmount := lnwire.NewMSatFromSatoshis(100) htlc, _ := createHTLC(0, htlcAmount) if _, err := aliceChannel.AddHTLC(htlc); err != nil { t.Fatalf("alice unable to add htlc: %v", err) @@ -996,16 +1000,16 @@ func TestDustHTLCFees(t *testing.T) { // sides. totalSatoshisAlice := (aliceChannel.channelState.LocalBalance + aliceChannel.channelState.RemoteBalance + - aliceChannel.channelState.CommitFee) - if totalSatoshisAlice+htlcAmount != aliceChannel.Capacity { + lnwire.NewMSatFromSatoshis(aliceChannel.channelState.CommitFee)) + if totalSatoshisAlice+htlcAmount != lnwire.NewMSatFromSatoshis(aliceChannel.Capacity) { t.Fatalf("alice's funds leaked: total satoshis are %v, but channel "+ "capacity is %v", int64(totalSatoshisAlice), int64(aliceChannel.Capacity)) } totalSatoshisBob := (bobChannel.channelState.LocalBalance + bobChannel.channelState.RemoteBalance + - bobChannel.channelState.CommitFee) - if totalSatoshisBob+htlcAmount != bobChannel.Capacity { + lnwire.NewMSatFromSatoshis(bobChannel.channelState.CommitFee)) + if totalSatoshisBob+htlcAmount != lnwire.NewMSatFromSatoshis(bobChannel.Capacity) { t.Fatalf("bob's funds leaked: total satoshis are %v, but channel "+ "capacity is %v", int64(totalSatoshisBob), int64(bobChannel.Capacity)) @@ -1054,8 +1058,9 @@ func TestHTLCDustLimit(t *testing.T) { // The amount of the HTLC should be above Alice's dust limit and below // Bob's dust limit. - htlcAmount := (btcutil.Amount(500) + + htlcSat := (btcutil.Amount(500) + htlcTimeoutFee(aliceChannel.channelState.FeePerKw)) + htlcAmount := lnwire.NewMSatFromSatoshis(htlcSat) htlc, preimage := createHTLC(0, htlcAmount) if _, err := aliceChannel.AddHTLC(htlc); err != nil { @@ -1109,9 +1114,9 @@ func TestHTLCDustLimit(t *testing.T) { t.Fatalf("incorrect # of outputs: expected %v, got %v", 2, len(commitment.txn.TxOut)) } - if aliceChannel.channelState.TotalSatoshisSent != uint64(htlcAmount) { + if aliceChannel.channelState.TotalMSatSent != htlcAmount { t.Fatalf("alice satoshis sent incorrect: expected %v, got %v", - htlcAmount, aliceChannel.channelState.TotalSatoshisSent) + htlcAmount, aliceChannel.channelState.TotalMSatSent) } } @@ -1136,9 +1141,11 @@ func TestChannelBalanceDustLimit(t *testing.T) { // once fees have been subtracted, but smaller than Bob's dust limit. defaultFee := calcStaticFee(0) dustLimit := aliceChannel.channelState.LocalChanCfg.DustLimit - aliceBalance := aliceChannel.channelState.LocalBalance - htlcAmount := aliceBalance - (defaultFee + dustLimit + 100) - htlcAmount += htlcSuccessFee(aliceChannel.channelState.FeePerKw) + aliceBalance := aliceChannel.channelState.LocalBalance.ToSatoshis() + htlcSat := aliceBalance - (defaultFee + dustLimit + 100) + htlcSat += htlcSuccessFee(aliceChannel.channelState.FeePerKw) + + htlcAmount := lnwire.NewMSatFromSatoshis(htlcSat) htlc, preimage := createHTLC(0, htlcAmount) if _, err := aliceChannel.AddHTLC(htlc); err != nil { @@ -1171,9 +1178,9 @@ func TestChannelBalanceDustLimit(t *testing.T) { t.Fatalf("incorrect # of outputs: expected %v, got %v", 1, len(commitment.txn.TxOut)) } - if aliceChannel.channelState.TotalSatoshisSent != uint64(htlcAmount) { + if aliceChannel.channelState.TotalMSatSent != htlcAmount { t.Fatalf("alice satoshis sent incorrect: expected %v, got %v", - htlcAmount, aliceChannel.channelState.TotalSatoshisSent) + htlcAmount, aliceChannel.channelState.TotalMSatSent) } } @@ -1197,7 +1204,7 @@ func TestStateUpdatePersistence(t *testing.T) { } const numHtlcs = 4 - const htlcAmt = 20000 + htlcAmt := lnwire.NewMSatFromSatoshis(20000) // Alice adds 3 HTLCs to the update log, while Bob adds a single HTLC. var alicePreimage [32]byte @@ -1429,21 +1436,21 @@ func TestStateUpdatePersistence(t *testing.T) { // The amounts transferred should been updated as per the amounts in // the HTLCs - if aliceChannelNew.channelState.TotalSatoshisSent != htlcAmt*3 { + if aliceChannelNew.channelState.TotalMSatSent != htlcAmt*3 { t.Fatalf("expected %v alice satoshis sent, got %v", - htlcAmt*3, aliceChannelNew.channelState.TotalSatoshisSent) + htlcAmt*3, aliceChannelNew.channelState.TotalMSatSent) } - if aliceChannelNew.channelState.TotalSatoshisReceived != htlcAmt { + if aliceChannelNew.channelState.TotalMSatReceived != htlcAmt { t.Fatalf("expected %v alice satoshis received, got %v", - htlcAmt, aliceChannelNew.channelState.TotalSatoshisReceived) + htlcAmt, aliceChannelNew.channelState.TotalMSatReceived) } - if bobChannelNew.channelState.TotalSatoshisSent != htlcAmt { + if bobChannelNew.channelState.TotalMSatSent != htlcAmt { t.Fatalf("expected %v bob satoshis sent, got %v", - htlcAmt, bobChannel.channelState.TotalSatoshisSent) + htlcAmt, bobChannel.channelState.TotalMSatSent) } - if bobChannelNew.channelState.TotalSatoshisReceived != htlcAmt*3 { + if bobChannelNew.channelState.TotalMSatReceived != htlcAmt*3 { t.Fatalf("expected %v bob satoshis sent, got %v", - htlcAmt*3, bobChannel.channelState.TotalSatoshisSent) + htlcAmt*3, bobChannel.channelState.TotalMSatReceived) } } @@ -1461,7 +1468,7 @@ func TestCancelHTLC(t *testing.T) { // Add a new HTLC from Alice to Bob, then trigger a new state // transition in order to include it in the latest state. - const htlcAmt = btcutil.SatoshiPerBitcoin + htlcAmt := lnwire.NewMSatFromSatoshis(btcutil.SatoshiPerBitcoin) var preImage [32]byte copy(preImage[:], bytes.Repeat([]byte{0xaa}, 32)) @@ -1486,9 +1493,10 @@ func TestCancelHTLC(t *testing.T) { // of the new HTLC. aliceExpectedBalance := btcutil.Amount(btcutil.SatoshiPerBitcoin*4) - calcStaticFee(1) - if aliceChannel.channelState.LocalBalance != aliceExpectedBalance { + if aliceChannel.channelState.LocalBalance.ToSatoshis() != aliceExpectedBalance { t.Fatalf("Alice's balance is wrong: expected %v, got %v", - aliceExpectedBalance, aliceChannel.channelState.LocalBalance) + aliceExpectedBalance, + aliceChannel.channelState.LocalBalance.ToSatoshis()) } // Now, with the HTLC committed on both sides, trigger a cancellation @@ -1527,22 +1535,28 @@ func TestCancelHTLC(t *testing.T) { } expectedBalance := btcutil.Amount(btcutil.SatoshiPerBitcoin * 5) - if aliceChannel.channelState.LocalBalance != expectedBalance-calcStaticFee(0) { + if aliceChannel.channelState.LocalBalance.ToSatoshis() != + expectedBalance-calcStaticFee(0) { + t.Fatalf("balance is wrong: expected %v, got %v", - aliceChannel.channelState.LocalBalance, expectedBalance- - calcStaticFee(0)) + aliceChannel.channelState.LocalBalance.ToSatoshis(), + expectedBalance-calcStaticFee(0)) } - if aliceChannel.channelState.RemoteBalance != expectedBalance { + if aliceChannel.channelState.RemoteBalance.ToSatoshis() != expectedBalance { t.Fatalf("balance is wrong: expected %v, got %v", - aliceChannel.channelState.RemoteBalance, expectedBalance) + aliceChannel.channelState.RemoteBalance.ToSatoshis(), + expectedBalance) } - if bobChannel.channelState.LocalBalance != expectedBalance { + if bobChannel.channelState.LocalBalance.ToSatoshis() != expectedBalance { t.Fatalf("balance is wrong: expected %v, got %v", - bobChannel.channelState.LocalBalance, expectedBalance) + bobChannel.channelState.LocalBalance.ToSatoshis(), + expectedBalance) } - if bobChannel.channelState.RemoteBalance != expectedBalance-calcStaticFee(0) { + if bobChannel.channelState.RemoteBalance.ToSatoshis() != + expectedBalance-calcStaticFee(0) { + t.Fatalf("balance is wrong: expected %v, got %v", - bobChannel.channelState.RemoteBalance, + bobChannel.channelState.RemoteBalance.ToSatoshis(), expectedBalance-calcStaticFee(0)) } } @@ -1574,7 +1588,7 @@ func TestCooperativeCloseDustAdherence(t *testing.T) { bobChannel.status = channelOpen } - setBalances := func(aliceBalance, bobBalance btcutil.Amount) { + setBalances := func(aliceBalance, bobBalance lnwire.MilliSatoshi) { aliceChannel.channelState.LocalBalance = aliceBalance aliceChannel.channelState.RemoteBalance = bobBalance bobChannel.channelState.LocalBalance = bobBalance @@ -1626,8 +1640,8 @@ func TestCooperativeCloseDustAdherence(t *testing.T) { // Next we'll modify the current balances and dust limits such that // Bob's current balance is above _below_ his dust limit. - aliceBal := btcutil.Amount(btcutil.SatoshiPerBitcoin) - bobBal := btcutil.Amount(250) + aliceBal := lnwire.NewMSatFromSatoshis(btcutil.SatoshiPerBitcoin) + bobBal := lnwire.NewMSatFromSatoshis(250) setBalances(aliceBal, bobBal) // Attempt another cooperative channel closure. It should succeed @@ -1659,9 +1673,10 @@ func TestCooperativeCloseDustAdherence(t *testing.T) { t.Fatalf("close tx has wrong number of outputs: expected %v "+ "got %v", 1, len(closeTx.TxOut)) } - if closeTx.TxOut[0].Value != int64(aliceBal-calcStaticFee(0)) { + if closeTx.TxOut[0].Value != int64(aliceBal.ToSatoshis()-calcStaticFee(0)) { t.Fatalf("alice's balance is incorrect: expected %v, got %v", - int64(aliceBal-calcStaticFee(0)), closeTx.TxOut[0].Value) + int64(aliceBal.ToSatoshis()-calcStaticFee(0)), + closeTx.TxOut[0].Value) } // Finally, we'll modify the current balances and dust limits such that @@ -1698,9 +1713,9 @@ func TestCooperativeCloseDustAdherence(t *testing.T) { t.Fatalf("close tx has wrong number of outputs: expected %v "+ "got %v", 1, len(closeTx.TxOut)) } - if closeTx.TxOut[0].Value != int64(aliceBal) { + if closeTx.TxOut[0].Value != int64(aliceBal.ToSatoshis()) { t.Fatalf("bob's balance is incorrect: expected %v, got %v", - aliceBal, closeTx.TxOut[0].Value) + aliceBal.ToSatoshis(), closeTx.TxOut[0].Value) } }