From c7df82ab688a44564ae6add9e79169ee2f3c4352 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Sun, 30 Jul 2017 12:25:41 -0700 Subject: [PATCH] lnwallet: update the LightningChannel API usage for recent channels changes This commit updates much of the state interaction within the LightningChannel structure to account for the recent changes within the chanenldb involving the OpenChannel struct, namely the introduction of ChannelConfig and ChannelConstraints. --- lnwallet/channel.go | 213 +++++++++++++++++++++++++++----------------- 1 file changed, 130 insertions(+), 83 deletions(-) diff --git a/lnwallet/channel.go b/lnwallet/channel.go index 51bde351..6d1fb848 100644 --- a/lnwallet/channel.go +++ b/lnwallet/channel.go @@ -571,13 +571,21 @@ func compactLogs(ourLog, theirLog *updateLog, // // See the individual comments within the above methods for further details. type LightningChannel struct { - signer Signer + // signer is the main signer instances that will be responsible for + // signing any HTLC and commitment transaction generated by the state + // machine. + signer Signer + + // signDesc is the primary sign descriptor that is capable of signing + // the commitment transaction that spends the multi-sig output. signDesc *SignDescriptor channelEvents chainntnfs.ChainNotifier - sync.RWMutex - + // pendingACk denotes if we have an outstanding commitment transaction + // and are waiting for a revocation to be received. Until the + // revocation is received, we're unable to propose a new commitment + // state. pendingACK bool status channelState @@ -589,6 +597,10 @@ type LightningChannel struct { // Capcity is the total capacity of this channel. Capacity btcutil.Amount + // stateHintObsfucator is a 48-bit state hint that's used to obfsucate + // the current state number on the commitment transactions. + stateHintObsfucator [StateHintSize]byte + // currentHeight is the current height of our local commitment chain. // This is also the same as the number of updates to the channel we've // accepted. @@ -629,6 +641,10 @@ type LightningChannel struct { channelState *channeldb.OpenChannel + localChanCfg *channeldb.ChannelConfig + + remoteChanCfg *channeldb.ChannelConfig + // [local|remote]Log is a (mostly) append-only log storing all the HTLC // updates to this channel. The log is walked backwards as HTLC updates // are applied in order to re-construct a commitment transaction from a @@ -654,9 +670,7 @@ type LightningChannel struct { // way to lookup the original PaymentDescriptor. rHashMap map[PaymentHash][]*PaymentDescriptor - LocalDeliveryScript []byte RemoteDeliveryScript []byte - // FundingWitnessScript is the witness script for the 2-of-2 multi-sig // that opened the channel. FundingWitnessScript []byte @@ -697,6 +711,10 @@ type LightningChannel struct { // might be processed by this channel at the specific point of time. availableLocalBalance btcutil.Amount + sync.RWMutex + + wg sync.WaitGroup + shutdown int32 quit chan struct{} } @@ -709,28 +727,48 @@ type LightningChannel struct { func NewLightningChannel(signer Signer, events chainntnfs.ChainNotifier, fe FeeEstimator, state *channeldb.OpenChannel) (*LightningChannel, error) { + localKey := state.LocalChanCfg.MultiSigKey.SerializeCompressed() + remoteKey := state.RemoteChanCfg.MultiSigKey.SerializeCompressed() + multiSigScript, err := genMultiSigScript(localKey, remoteKey) + if err != nil { + return nil, err + } + + var stateHint [StateHintSize]byte + if state.IsInitiator { + stateHint = deriveStateHintObfuscator( + state.LocalChanCfg.PaymentBasePoint, + state.RemoteChanCfg.PaymentBasePoint, + ) + } else { + stateHint = deriveStateHintObfuscator( + state.RemoteChanCfg.PaymentBasePoint, + state.LocalChanCfg.PaymentBasePoint, + ) + } + lc := &LightningChannel{ signer: signer, channelEvents: events, feeEstimator: fe, + stateHintObsfucator: stateHint, currentHeight: state.NumUpdates, remoteCommitChain: newCommitmentChain(state.NumUpdates), localCommitChain: newCommitmentChain(state.NumUpdates), channelState: state, - revocationWindowEdge: state.NumUpdates, + localChanCfg: &state.LocalChanCfg, + remoteChanCfg: &state.RemoteChanCfg, localUpdateLog: newUpdateLog(), remoteUpdateLog: newUpdateLog(), rHashMap: make(map[PaymentHash][]*PaymentDescriptor), Capacity: state.Capacity, - LocalDeliveryScript: state.OurDeliveryScript, - RemoteDeliveryScript: state.TheirDeliveryScript, - FundingWitnessScript: state.FundingWitnessScript, + FundingWitnessScript: multiSigScript, ForceCloseSignal: make(chan struct{}), UnilateralClose: make(chan *UnilateralCloseSummary, 1), UnilateralCloseSignal: make(chan struct{}), ContractBreach: make(chan *BreachRetribution, 1), - LocalFundingKey: state.OurMultiSigKey, - RemoteFundingKey: state.TheirMultiSigKey, + LocalFundingKey: state.LocalChanCfg.MultiSigKey, + RemoteFundingKey: state.RemoteChanCfg.MultiSigKey, quit: make(chan struct{}), } @@ -738,15 +776,15 @@ func NewLightningChannel(signer Signer, events chainntnfs.ChainNotifier, // for each side. lc.localCommitChain.addCommitment(&commitment{ height: lc.currentHeight, - ourBalance: state.OurBalance, + ourBalance: state.LocalBalance, ourMessageIndex: 0, - theirBalance: state.TheirBalance, + theirBalance: state.RemoteBalance, theirMessageIndex: 0, fee: state.CommitFee, feePerKw: state.FeePerKw, }) walletLog.Debugf("ChannelPoint(%v), starting local commitment: %v", - state.ChanID, newLogClosure(func() string { + state.FundingOutpoint, newLogClosure(func() string { return spew.Sdump(lc.localCommitChain.tail()) }), ) @@ -760,9 +798,9 @@ func NewLightningChannel(signer Signer, events chainntnfs.ChainNotifier, return nil, err } remoteCommitment := &commitment{ - ourBalance: state.OurBalance, + ourBalance: state.LocalBalance, ourMessageIndex: 0, - theirBalance: state.TheirBalance, + theirBalance: state.RemoteBalance, theirMessageIndex: 0, fee: state.CommitFee, feePerKw: state.FeePerKw, @@ -774,7 +812,7 @@ func NewLightningChannel(signer Signer, events chainntnfs.ChainNotifier, } lc.remoteCommitChain.addCommitment(remoteCommitment) walletLog.Debugf("ChannelPoint(%v), starting remote commitment: %v", - state.ChanID, newLogClosure(func() string { + state.FundingOutpoint, newLogClosure(func() string { return spew.Sdump(lc.remoteCommitChain.tail()) }), ) @@ -788,15 +826,15 @@ func NewLightningChannel(signer Signer, events chainntnfs.ChainNotifier, // Create the sign descriptor which we'll be using very frequently to // request a signature for the 2-of-2 multi-sig from the signer in // order to complete channel state transitions. - fundingPkScript, err := witnessScriptHash(state.FundingWitnessScript) + fundingPkScript, err := witnessScriptHash(multiSigScript) if err != nil { return nil, err } - lc.fundingTxIn = wire.NewTxIn(state.FundingOutpoint, nil, nil) + lc.fundingTxIn = wire.NewTxIn(&state.FundingOutpoint, nil, nil) lc.fundingP2WSH = fundingPkScript lc.signDesc = &SignDescriptor{ - PubKey: lc.channelState.OurMultiSigKey, - WitnessScript: lc.channelState.FundingWitnessScript, + PubKey: lc.localChanCfg.MultiSigKey, + WitnessScript: multiSigScript, Output: &wire.TxOut{ PkScript: lc.fundingP2WSH, Value: int64(lc.channelState.Capacity), @@ -833,6 +871,7 @@ func NewLightningChannel(signer Signer, events chainntnfs.ChainNotifier, // Launch the close observer which will vigilantly watch the // network for any broadcasts the current or prior commitment // transactions, taking action accordingly. + lc.wg.Add(1) go lc.closeObserver(channelCloseNtfn) } @@ -989,8 +1028,10 @@ func newBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64, // // NOTE: This MUST be run as a goroutine. func (lc *LightningChannel) closeObserver(channelCloseNtfn *chainntnfs.SpendEvent) { + defer lc.wg.Done() + walletLog.Infof("Close observer for ChannelPoint(%v) active", - lc.channelState.ChanID) + lc.channelState.FundingOutpoint) var ( commitSpend *chainntnfs.SpendDetail @@ -1039,7 +1080,7 @@ func (lc *LightningChannel) closeObserver(channelCloseNtfn *chainntnfs.SpendEven // If this is our commitment transaction, then we can exit here as we // don't have any further processing we need to do (we can't cheat // ourselves :p). - commitmentHash := lc.channelState.OurCommitTx.TxHash() + commitmentHash := lc.channelState.CommitTx.TxHash() isOurCommitment := commitSpend.SpenderTxHash.IsEqual(&commitmentHash) if isOurCommitment { return @@ -1047,7 +1088,7 @@ func (lc *LightningChannel) closeObserver(channelCloseNtfn *chainntnfs.SpendEven // Decode the state hint encoded within the commitment transaction to // determine if this is a revoked state or not. - obsfucator := lc.channelState.StateHintObsfucator + obsfucator := lc.stateHintObsfucator broadcastStateNum := GetStateNumHint(commitTxBroadcast, obsfucator) currentStateNum := lc.currentHeight @@ -1067,23 +1108,23 @@ func (lc *LightningChannel) closeObserver(channelCloseNtfn *chainntnfs.SpendEven // their signature to us. case broadcastStateNum >= currentStateNum: walletLog.Infof("Unilateral close of ChannelPoint(%v) "+ - "detected", lc.channelState.ChanID) + "detected", lc.channelState.FundingOutpoint) // As we've detected that the channel has been closed, // immediately delete the state from disk, creating a close // summary for future usage by related sub-systems. // TODO(roasbeef): include HTLC's - // * and time-locked balance - closeSummary := &channeldb.ChannelCloseSummary{ - ChanPoint: *lc.channelState.ChanID, + // * and time-locked balance, NEED TO??? + closeSummary := channeldb.ChannelCloseSummary{ + ChanPoint: lc.channelState.FundingOutpoint, ClosingTXID: *commitSpend.SpenderTxHash, RemotePub: lc.channelState.IdentityPub, Capacity: lc.Capacity, - SettledBalance: lc.channelState.OurBalance, + SettledBalance: lc.channelState.LocalBalance, CloseType: channeldb.ForceClose, IsPending: true, } - if err := lc.DeleteState(closeSummary); err != nil { + if err := lc.DeleteState(&closeSummary); err != nil { walletLog.Errorf("unable to delete channel state: %v", err) } @@ -1104,7 +1145,7 @@ func (lc *LightningChannel) closeObserver(channelCloseNtfn *chainntnfs.SpendEven case broadcastStateNum < currentStateNum: walletLog.Warnf("Remote peer has breached the channel "+ "contract for ChannelPoint(%v). Revoked state #%v was "+ - "broadcast!!!", lc.channelState.ChanID, + "broadcast!!!", lc.channelState.FundingOutpoint, broadcastStateNum) // Create a new reach retribution struct which contains all the @@ -1455,7 +1496,7 @@ func (lc *LightningChannel) fetchCommitmentView(remoteChain bool, // Set the state hint of the commitment transaction to facilitate // quickly recovering the necessary penalty state in the case of an // uncooperative broadcast. - obsfucator := lc.channelState.StateHintObsfucator + obsfucator := lc.stateHintObsfucator stateNum := nextHeight if err := SetStateNumHint(commitTx, stateNum, obsfucator); err != nil { return nil, err @@ -1509,8 +1550,8 @@ func (lc *LightningChannel) evaluateHTLCView(view *htlcView, ourBalance, skipThem := make(map[uint64]struct{}) // First we run through non-add entries in both logs, populating the - // skip sets and mutating the current chain state (crediting balances, etc) to - // reflect the settle/timeout entry encountered. + // skip sets and mutating the current chain state (crediting balances, + // etc) to reflect the settle/timeout entry encountered. for _, entry := range view.ourUpdates { if entry.EntryType == Add { continue @@ -1552,8 +1593,8 @@ func (lc *LightningChannel) evaluateHTLCView(view *htlcView, ourBalance, } // Next we take a second pass through all the log entries, skipping any - // settled HTLCs, and debiting the chain state balance due to any - // newly added HTLCs. + // settled HTLCs, and debiting the chain state balance due to any newly + // added HTLCs. for _, entry := range view.ourUpdates { isAdd := entry.EntryType == Add if _, ok := skipUs[entry.Index]; !isAdd || ok { @@ -1719,13 +1760,16 @@ func (lc *LightningChannel) SignNextCommitment() ([]byte, error) { } walletLog.Tracef("ChannelPoint(%v): extending remote chain to height %v", - lc.channelState.ChanID, newCommitView.height) + lc.channelState.FundingOutpoint, newCommitView.height) + walletLog.Tracef("ChannelPoint(%v): remote chain: our_balance=%v, "+ - "their_balance=%v, commit_tx: %v", lc.channelState.ChanID, - newCommitView.ourBalance, newCommitView.theirBalance, + "their_balance=%v, commit_tx: %v", + lc.channelState.FundingOutpoint, newCommitView.ourBalance, + newCommitView.theirBalance, newLogClosure(func() string { return spew.Sdump(newCommitView.txn) - })) + }), + ) // Sign their version of the new commitment transaction. lc.signDesc.SigHashes = txscript.NewTxSigHashes(newCommitView.txn) @@ -1739,10 +1783,10 @@ func (lc *LightningChannel) SignNextCommitment() ([]byte, error) { lc.remoteCommitChain.addCommitment(newCommitView) // If we are the channel initiator then we would have signed any sent - // fee update at this point, so mark this update as pending ACK, and set - // pendingFeeUpdate to nil. We can do this since we know we won't sign - // any new commitment before receiving a revoke_and_ack, because of the - // revocation window of 1. + // fee update at this point, so mark this update as pending ACK, and + // set pendingFeeUpdate to nil. We can do this since we know we won't + // sign any new commitment before receiving a revoke_and_ack, because + // of the revocation window of 1. if lc.channelState.IsInitiator { lc.pendingAckFeeUpdate = lc.pendingFeeUpdate lc.pendingFeeUpdate = nil @@ -1879,10 +1923,10 @@ func (lc *LightningChannel) ReceiveNewCommitment(rawSig []byte) error { } walletLog.Tracef("ChannelPoint(%v): extending local chain to height %v", - lc.channelState.ChanID, localCommitmentView.height) + lc.channelState.FundingOutpoint, localCommitmentView.height) walletLog.Tracef("ChannelPoint(%v): local chain: our_balance=%v, "+ - "their_balance=%v, commit_tx: %v", lc.channelState.ChanID, + "their_balance=%v, commit_tx: %v", lc.channelState.FundingOutpoint, localCommitmentView.ourBalance, localCommitmentView.theirBalance, newLogClosure(func() string { return spew.Sdump(localCommitmentView.txn) @@ -1892,10 +1936,11 @@ func (lc *LightningChannel) ReceiveNewCommitment(rawSig []byte) error { // Construct the sighash of the commitment transaction corresponding to // this newly proposed state update. localCommitTx := localCommitmentView.txn - multiSigScript := lc.channelState.FundingWitnessScript + multiSigScript := lc.FundingWitnessScript hashCache := txscript.NewTxSigHashes(localCommitTx) 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 { // TODO(roasbeef): fetchview has already mutated the HTLCs... // * need to either roll-back, or make pure @@ -2011,8 +2056,9 @@ func (lc *LightningChannel) RevokeCurrentCommitment() (*lnwire.RevokeAndAck, err } walletLog.Tracef("ChannelPoint(%v): state transition accepted: "+ - "our_balance=%v, their_balance=%v", lc.channelState.ChanID, - tail.ourBalance, tail.theirBalance) + "our_balance=%v, their_balance=%v", + lc.channelState.FundingOutpoint, tail.ourBalance, + tail.theirBalance) // In the process of revoking our current commitment, we've also // implicitly ACK'd their set of pending changes that arrived before @@ -2020,12 +2066,15 @@ func (lc *LightningChannel) RevokeCurrentCommitment() (*lnwire.RevokeAndAck, err // ACK'd index within the log to right at this set of pending changes. lc.remoteUpdateLog.ackTransition() - revocationMsg.ChanID = lnwire.NewChanIDFromOutPoint(lc.channelState.ChanID) + revocationMsg.ChanID = lnwire.NewChanIDFromOutPoint( + &lc.channelState.FundingOutpoint, + ) + return revocationMsg, nil } // LocalAvailableBalance returns the amount of available money which might be -// procced by this channel at the specific point of time. +// proceed by this channel at the specific point of time. func (lc *LightningChannel) LocalAvailableBalance() btcutil.Amount { lc.Lock() defer lc.Unlock() @@ -2096,7 +2145,7 @@ func (lc *LightningChannel) ReceiveRevocation(revMsg *lnwire.RevokeAndAck) ([]*P lc.revocationWindow = append(lc.revocationWindow, revMsg) walletLog.Tracef("ChannelPoint(%v): remote party accepted state transition, "+ - "revoked height %v, now at %v", lc.channelState.ChanID, + "revoked height %v, now at %v", lc.channelState.FundingOutpoint, lc.remoteCommitChain.tail().height, lc.remoteCommitChain.tail().height+1) @@ -2220,9 +2269,6 @@ func (lc *LightningChannel) NextRevocationkey() (*btcec.PublicKey, error) { // AddHTLC adds an HTLC to the state machine's local update log. This method // should be called when preparing to send an outgoing HTLC. -// -// TODO(roasbeef): check for duplicates below? edge case during restart w/ HTLC -// persistence func (lc *LightningChannel) AddHTLC(htlc *lnwire.UpdateAddHTLC) (uint64, error) { lc.Lock() defer lc.Unlock() @@ -2415,7 +2461,7 @@ func (lc *LightningChannel) ChannelPoint() *wire.OutPoint { lc.RLock() defer lc.RUnlock() - return lc.channelState.ChanID + return &lc.channelState.FundingOutpoint } // ShortChanID returns the short channel ID for the channel. The short channel @@ -2519,13 +2565,13 @@ func (lc *LightningChannel) addHTLC(commitTx *wire.MsgTx, ourCommit bool, func (lc *LightningChannel) getSignedCommitTx() (*wire.MsgTx, error) { // Fetch the current commitment transaction, along with their signature // for the transaction. - commitTx := lc.channelState.OurCommitTx - theirSig := append(lc.channelState.OurCommitSig, byte(txscript.SigHashAll)) + commitTx := lc.channelState.CommitTx + theirSig := append(lc.channelState.CommitSig, byte(txscript.SigHashAll)) // With this, we then generate the full witness so the caller can // broadcast a fully signed transaction. - lc.signDesc.SigHashes = txscript.NewTxSigHashes(commitTx) - ourSigRaw, err := lc.signer.SignOutputRaw(commitTx, lc.signDesc) + lc.signDesc.SigHashes = txscript.NewTxSigHashes(&commitTx) + ourSigRaw, err := lc.signer.SignOutputRaw(&commitTx, lc.signDesc) if err != nil { return nil, err } @@ -2534,13 +2580,14 @@ func (lc *LightningChannel) getSignedCommitTx() (*wire.MsgTx, error) { // With the final signature generated, create the witness stack // required to spend from the multi-sig output. - ourKey := lc.channelState.OurMultiSigKey.SerializeCompressed() - theirKey := lc.channelState.TheirMultiSigKey.SerializeCompressed() + ourKey := lc.localChanCfg.MultiSigKey.SerializeCompressed() + theirKey := lc.remoteChanCfg.MultiSigKey.SerializeCompressed() commitTx.TxIn[0].Witness = SpendMultiSig(lc.FundingWitnessScript, ourKey, ourSig, theirKey, theirSig) - return commitTx, nil + return &commitTx, nil +} } // ForceCloseSummary describes the final commitment state before the channel is @@ -2656,7 +2703,7 @@ func (lc *LightningChannel) ForceClose() (*ForceCloseSummary, error) { WitnessScript: selfScript, Output: &wire.TxOut{ PkScript: delayScript, - Value: int64(lc.channelState.OurBalance), + Value: int64(lc.channelState.LocalBalance), }, HashType: txscript.SigHashAll, } @@ -2669,13 +2716,13 @@ func (lc *LightningChannel) ForceClose() (*ForceCloseSummary, error) { close(lc.ForceCloseSignal) return &ForceCloseSummary{ - ChanPoint: *lc.channelState.ChanID, - CloseTx: commitTx, + ChanPoint: lc.channelState.FundingOutpoint, SelfOutpoint: wire.OutPoint{ Hash: commitTx.TxHash(), Index: delayIndex, }, SelfOutputMaturity: csvTimeout, + CloseTx: commitTx, SelfOutputSignDesc: selfSignDesc, }, nil } @@ -2706,8 +2753,8 @@ func (lc *LightningChannel) CreateCloseProposal(feeRate uint64) ([]byte, uint64, // not to persist the adjusted balance, as the feeRate may change // during the channel closing process. proposedFee := uint64(btcutil.Amount(feeRate) * commitWeight / 1000) - ourBalance := lc.channelState.OurBalance - theirBalance := lc.channelState.TheirBalance + ourBalance := lc.channelState.LocalBalance + theirBalance := lc.channelState.RemoteBalance if lc.channelState.IsInitiator { ourBalance = ourBalance - btcutil.Amount(proposedFee) @@ -2716,9 +2763,9 @@ func (lc *LightningChannel) CreateCloseProposal(feeRate uint64) ([]byte, uint64, } closeTx := CreateCooperativeCloseTx(lc.fundingTxIn, - lc.channelState.OurDustLimit, lc.channelState.TheirDustLimit, - ourBalance, theirBalance, lc.channelState.OurDeliveryScript, - lc.channelState.TheirDeliveryScript, lc.channelState.IsInitiator) + lc.localChanCfg.DustLimit, lc.remoteChanCfg.DustLimit, + ourBalance, theirBalance, localDeliveryScript, + remoteDeliveryScript, lc.channelState.IsInitiator) // Ensure that the transaction doesn't explicitly violate any // consensus rules such as being too big, or having any value with a @@ -2766,8 +2813,8 @@ func (lc *LightningChannel) CompleteCooperativeClose(localSig, remoteSig []byte, // not to persist the adjusted balance, as the feeRate may change // during the channel closing process. proposedFee := uint64(btcutil.Amount(feeRate) * commitWeight / 1000) - ourBalance := lc.channelState.OurBalance - theirBalance := lc.channelState.TheirBalance + ourBalance := lc.channelState.LocalBalance + theirBalance := lc.channelState.RemoteBalance if lc.channelState.IsInitiator { ourBalance = ourBalance - btcutil.Amount(proposedFee) @@ -2779,9 +2826,9 @@ func (lc *LightningChannel) CompleteCooperativeClose(localSig, remoteSig []byte, // on this active channel back to both parties. In this current model, // the initiator pays full fees for the cooperative close transaction. closeTx := CreateCooperativeCloseTx(lc.fundingTxIn, - lc.channelState.OurDustLimit, lc.channelState.TheirDustLimit, - ourBalance, theirBalance, lc.channelState.OurDeliveryScript, - lc.channelState.TheirDeliveryScript, lc.channelState.IsInitiator) + lc.localChanCfg.DustLimit, lc.remoteChanCfg.DustLimit, + ourBalance, theirBalance, localDeliveryScript, + remoteDeliveryScript, lc.channelState.IsInitiator) // Ensure that the transaction doesn't explicitly validate any // consensus rules such as being too big, or having any value with a @@ -2794,8 +2841,8 @@ func (lc *LightningChannel) CompleteCooperativeClose(localSig, remoteSig []byte, // Finally, construct the witness stack minding the order of the // pubkeys+sigs on the stack. - ourKey := lc.channelState.OurMultiSigKey.SerializeCompressed() - theirKey := lc.channelState.TheirMultiSigKey.SerializeCompressed() + ourKey := lc.localChanCfg.MultiSigKey.SerializeCompressed() + theirKey := lc.remoteChanCfg.MultiSigKey.SerializeCompressed() witness := SpendMultiSig(lc.signDesc.WitnessScript, ourKey, localSig, theirKey, remoteSig) closeTx.TxIn[0].Witness = witness @@ -2844,9 +2891,9 @@ func (lc *LightningChannel) UpdateFee(feePerKw btcutil.Amount) error { defer lc.Unlock() // Only initiator can send fee update, so trying to send one as - // non-initiatior will fail. + // non-initiator will fail. if !lc.channelState.IsInitiator { - return fmt.Errorf("local fee update as non-initiatior") + return fmt.Errorf("local fee update as non-initiator") } lc.pendingFeeUpdate = &feePerKw @@ -2861,9 +2908,9 @@ func (lc *LightningChannel) ReceiveUpdateFee(feePerKw btcutil.Amount) error { defer lc.Unlock() // Only initiator can send fee update, and we must fail if we receive - // fee update as initiatior + // fee update as initiator if lc.channelState.IsInitiator { - return fmt.Errorf("received fee update as initiatior") + return fmt.Errorf("received fee update as initiator") } // TODO(halseth): should fail if fee update is unreasonable,