From b3bb65ea43ba3d48605c1aadd082f6945b2dd5bf Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Sat, 30 Jun 2018 17:13:14 -0500 Subject: [PATCH 1/4] rpc: restore proper debug HTLC usage In this commit, we fix a slight regression that happened when the sendtoroute RPC call was implemented. As a result of the refactoring, the debughtlc mode silently broke. In this commit, we fix this by checking against the zero hash, rather than the length of the payment hash, as since we use a fixed sized byte slice, it will always be zero. --- rpcserver.go | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/rpcserver.go b/rpcserver.go index 99de1e34e..98241511f 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -11,11 +11,11 @@ import ( "math" "sort" "strings" + "sync" "time" "gopkg.in/macaroon-bakery.v2/bakery" - "sync" "sync/atomic" "github.com/coreos/bbolt" @@ -51,6 +51,8 @@ const ( ) var ( + zeroHash [32]byte + // maxPaymentMSat is the maximum allowed payment currently permitted as // defined in BOLT-002. This value depends on which chain is active. // It is set to the value under the Bitcoin chain as default. @@ -2061,9 +2063,10 @@ func extractPaymentIntent(rpcPayReq *rpcPaymentRequest) (rpcPaymentIntent, error payIntent.cltvDelta = uint16(rpcPayReq.FinalCltvDelta) - // If the user is manually specifying payment details, then the - // payment hash may be encoded as a string. - if rpcPayReq.PaymentHashString != "" { + // If the user is manually specifying payment details, then the payment + // hash may be encoded as a string. + switch { + case rpcPayReq.PaymentHashString != "": paymentHash, err := hex.DecodeString( rpcPayReq.PaymentHashString, ) @@ -2072,15 +2075,15 @@ func extractPaymentIntent(rpcPayReq *rpcPaymentRequest) (rpcPaymentIntent, error } copy(payIntent.rHash[:], paymentHash) - } else { - copy(payIntent.rHash[:], rpcPayReq.PaymentHash) - } // 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 within // the RPC request. - if cfg.DebugHTLC && len(payIntent.rHash) == 0 { + case cfg.DebugHTLC && bytes.Equal(payIntent.rHash[:], zeroHash[:]): copy(payIntent.rHash[:], debugHash[:]) + + default: + copy(payIntent.rHash[:], rpcPayReq.PaymentHash) } // Currently, within the bootstrap phase of the network, we limit the From 39c1f46f857aeb34a6ca9bc61cea044f166927f7 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Sat, 30 Jun 2018 17:14:22 -0500 Subject: [PATCH 2/4] routing: new newLogClosure to delay spew evaluation until log print time In this commit, we update the generateSphinxPacket to use newLogClosure to delay the spew evaluation until log print time. Before this commit, even if we weren't on the trace logging level, the spew call would always be evaluated. --- routing/router.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/routing/router.go b/routing/router.go index 4f3a5bfb6..d03f16348 100644 --- a/routing/router.go +++ b/routing/router.go @@ -1458,7 +1458,10 @@ func generateSphinxPacket(route *Route, paymentHash []byte) ([]byte, hopPayloads := route.ToHopPayloads() log.Tracef("Constructed per-hop payloads for payment_hash=%x: %v", - paymentHash[:], spew.Sdump(hopPayloads)) + paymentHash[:], newLogClosure(func() string { + return spew.Sdump(hopPayloads) + }), + ) sessionKey, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { @@ -1467,8 +1470,9 @@ func generateSphinxPacket(route *Route, paymentHash []byte) ([]byte, // Next generate the onion routing packet which allows us to perform // privacy preserving source routing across the network. - sphinxPacket, err := sphinx.NewOnionPacket(nodes, sessionKey, - hopPayloads, paymentHash) + sphinxPacket, err := sphinx.NewOnionPacket( + nodes, sessionKey, hopPayloads, paymentHash, + ) if err != nil { return nil, nil, err } From 3ad15c5f42be825860be19dda2a99d3a028dc5f3 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Sat, 30 Jun 2018 17:14:59 -0500 Subject: [PATCH 3/4] hltcswitch: use a logClosure to delay spew evaluation until log print time --- htlcswitch/link.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/htlcswitch/link.go b/htlcswitch/link.go index b60b43f1d..d02c4672f 100644 --- a/htlcswitch/link.go +++ b/htlcswitch/link.go @@ -1566,8 +1566,13 @@ func (l *channelLink) updateCommitTx() error { if err == lnwallet.ErrNoWindow { l.tracef("revocation window exhausted, unable to send: %v, "+ "dangling_opens=%v, dangling_closes%v", - l.batchCounter, spew.Sdump(l.openedCircuits), - spew.Sdump(l.closedCircuits)) + l.batchCounter, newLogClosure(func() string { + return spew.Sdump(l.openedCircuits) + }), + newLogClosure(func() string { + return spew.Sdump(l.closedCircuits) + }), + ) return nil } else if err != nil { return err From d889644f521494aed45e62475641ea43844c95e6 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Sat, 30 Jun 2018 17:15:24 -0500 Subject: [PATCH 4/4] htlcswitch: use Batch for calls within ackSettleFail --- htlcswitch/switch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htlcswitch/switch.go b/htlcswitch/switch.go index 122402386..30f4e28f8 100644 --- a/htlcswitch/switch.go +++ b/htlcswitch/switch.go @@ -1251,7 +1251,7 @@ func (s *Switch) closeCircuit(pkt *htlcPacket) (*PaymentCircuit, error) { // we're the originator of the payment, so the link stops attempting to // re-broadcast. func (s *Switch) ackSettleFail(settleFailRef channeldb.SettleFailRef) error { - return s.cfg.DB.Update(func(tx *bolt.Tx) error { + return s.cfg.DB.Batch(func(tx *bolt.Tx) error { return s.cfg.SwitchPackager.AckSettleFails(tx, settleFailRef) }) }