Repository: lightningnetwork/lnd
Pull request #3509 (2019-09-16 11:23:06)

lnwallet: fix goroutines in tests
This PR fixes a test in `lnwallet` where some of the error conditions could never be recorded, because they were happening inside a goroutine. 

`T.Fatal()` is a convenience function that combines `T.Log()` and `T.FailNow()`. 

From the godoc of `T.FailNow()`: 

> FailNow must be called from the goroutine running the test or benchmark function, not from other goroutines created during the test. Calling FailNow does not stop those other goroutines.

To see this in action, take a look at `main_test.go` in my [example repo](https://github.com/alrs/fatalfail/).


Patch:
diff --git a/.golangci.yml b/.golangci.yml
index e00edaa19..0ab310bdd 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -6,10 +6,6 @@ run:
   # worker.
   concurrency: 1
 
-  # Skip autogenerated files for mobile.
-  skip-files:
-    - "mobile\\/.*generated\\.go"
-
   build-tags:
     - autopilotrpc
     - chainrpc
diff --git a/Makefile b/Makefile
index 7ae8f24b5..b9b00c714 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ MOBILE_PKG := $(PKG)/mobile
 
 BTCD_PKG := github.com/btcsuite/btcd
 GOVERALLS_PKG := github.com/mattn/goveralls
-LINT_PKG := github.com/golangci/golangci-lint/cmd/golangci-lint
+LINT_PKG := github.com/golangci/golangci-lint/cmd/golangci-lint@v1.18.0
 GOACC_PKG := github.com/ory/go-acc
 
 GO_BIN := ${GOPATH}/bin
@@ -30,10 +30,8 @@ BTCD_COMMIT := $(shell cat go.mod | \
 		awk -F " " '{ print $$2 }' | \
 		awk -F "/" '{ print $$1 }')
 
-LINT_COMMIT := v1.18.0
 GOACC_COMMIT := ddc355013f90fea78d83d3a6c71f1d37ac07ecd5
 
-DEPGET := cd /tmp && GO111MODULE=on go get -v
 GOBUILD := GO111MODULE=on go build -v -trimpath
 GOINSTALL := GO111MODULE=on go install -v -trimpath
 GOTEST := GO111MODULE=on go test -v
@@ -51,7 +49,7 @@ include make/testing_flags.mk
 
 DEV_TAGS := $(if ${tags},$(DEV_TAGS) ${tags},$(DEV_TAGS))
 
-LINT = $(LINT_BIN) run -v
+LINT = $(LINT_BIN) run
 
 GREEN := "\\033[0;32m"
 NC := "\\033[0m"
@@ -73,15 +71,21 @@ $(GOVERALLS_BIN):
 
 $(LINT_BIN):
 	@$(call print, "Fetching linter")
-	$(DEPGET) $(LINT_PKG)@$(LINT_COMMIT)
+	# Switch to tmp directory to prevent lnd go.mod from being modified.
+	# Hopefully someday a flag for go get will be added for this.
+	cd /tmp
+	GO111MODULE=on go get $(LINT_PKG)
 
 $(GOACC_BIN):
 	@$(call print, "Fetching go-acc")
-	$(DEPGET) $(GOACC_PKG)@$(GOACC_COMMIT)
+	go get -u -v $(GOACC_PKG)@$(GOACC_COMMIT)
+	$(GOINSTALL) $(GOACC_PKG)
 
 btcd:
 	@$(call print, "Installing btcd.")
-	$(DEPGET) $(BTCD_PKG)@$(BTCD_COMMIT)
+	GO111MODULE=on go get -v $(BTCD_PKG)@$(BTCD_COMMIT)
+	$(GOINSTALL) $(BTCD_PKG)
+	$(GOINSTALL) $(BTCD_PKG)/cmd/btcctl
 
 # ============
 # INSTALLATION
diff --git a/chainntnfs/btcdnotify/btcd.go b/chainntnfs/btcdnotify/btcd.go
index c393300b1..cdd1e7789 100644
--- a/chainntnfs/btcdnotify/btcd.go
+++ b/chainntnfs/btcdnotify/btcd.go
@@ -139,24 +139,17 @@ func (b *BtcdNotifier) Start() error {
 		return nil
 	}
 
-	// Start our concurrent queues before starting the chain connection, to
-	// ensure onBlockConnected and onRedeemingTx callbacks won't be
-	// blocked.
-	b.chainUpdates.Start()
-	b.txUpdates.Start()
-
 	// Connect to btcd, and register for notifications on connected, and
 	// disconnected blocks.
 	if err := b.chainConn.Connect(20); err != nil {
-		b.txUpdates.Stop()
-		b.chainUpdates.Stop()
+		return err
+	}
+	if err := b.chainConn.NotifyBlocks(); err != nil {
 		return err
 	}
 
 	currentHash, currentHeight, err := b.chainConn.GetBestBlock()
 	if err != nil {
-		b.txUpdates.Stop()
-		b.chainUpdates.Stop()
 		return err
 	}
 
@@ -170,11 +163,8 @@ func (b *BtcdNotifier) Start() error {
 		Hash:   currentHash,
 	}
 
-	if err := b.chainConn.NotifyBlocks(); err != nil {
-		b.txUpdates.Stop()
-		b.chainUpdates.Stop()
-		return err
-	}
+	b.chainUpdates.Start()
+	b.txUpdates.Start()
 
 	b.wg.Add(1)
 	go b.notificationDispatcher()
@@ -218,14 +208,10 @@ func (b *BtcdNotifier) Stop() error {
 func (b *BtcdNotifier) onBlockConnected(hash *chainhash.Hash, height int32, t time.Time) {
 	// Append this new chain update to the end of the queue of new chain
 	// updates.
-	select {
-	case b.chainUpdates.ChanIn() <- &chainUpdate{
+	b.chainUpdates.ChanIn() <- &chainUpdate{
 		blockHash:   hash,
 		blockHeight: height,
 		connect:     true,
-	}:
-	case <-b.quit:
-		return
 	}
 }
 
@@ -250,14 +236,10 @@ type filteredBlock struct {
 func (b *BtcdNotifier) onBlockDisconnected(hash *chainhash.Hash, height int32, t time.Time) {
 	// Append this new chain update to the end of the queue of new chain
 	// updates.
-	select {
-	case b.chainUpdates.ChanIn() <- &chainUpdate{
+	b.chainUpdates.ChanIn() <- &chainUpdate{
 		blockHash:   hash,
 		blockHeight: height,
 		connect:     false,
-	}:
-	case <-b.quit:
-		return
 	}
 }
 
@@ -265,11 +247,7 @@ func (b *BtcdNotifier) onBlockDisconnected(hash *chainhash.Hash, height int32, t
 func (b *BtcdNotifier) onRedeemingTx(tx *btcutil.Tx, details *btcjson.BlockDetails) {
 	// Append this new transaction update to the end of the queue of new
 	// chain updates.
-	select {
-	case b.txUpdates.ChanIn() <- &txUpdate{tx, details}:
-	case <-b.quit:
-		return
-	}
+	b.txUpdates.ChanIn() <- &txUpdate{tx, details}
 }
 
 // notificationDispatcher is the primary goroutine which handles client
diff --git a/chainntnfs/neutrinonotify/neutrino.go b/chainntnfs/neutrinonotify/neutrino.go
index d06c0996d..c7d2e1ad6 100644
--- a/chainntnfs/neutrinonotify/neutrino.go
+++ b/chainntnfs/neutrinonotify/neutrino.go
@@ -116,20 +116,12 @@ func (n *NeutrinoNotifier) Start() error {
 		return nil
 	}
 
-	// Start our concurrent queues before starting the rescan, to ensure
-	// onFilteredBlockConnected and onRelavantTx callbacks won't be
-	// blocked.
-	n.chainUpdates.Start()
-	n.txUpdates.Start()
-
 	// First, we'll obtain the latest block height of the p2p node. We'll
 	// start the auto-rescan from this point. Once a caller actually wishes
 	// to register a chain view, the rescan state will be rewound
 	// accordingly.
 	startingPoint, err := n.p2pNode.BestBlock()
 	if err != nil {
-		n.txUpdates.Stop()
-		n.chainUpdates.Stop()
 		return err
 	}
 	n.bestBlock.Hash = &startingPoint.Hash
@@ -168,6 +160,9 @@ func (n *NeutrinoNotifier) Start() error {
 	)
 	n.rescanErr = n.chainView.Start()
 
+	n.chainUpdates.Start()
+	n.txUpdates.Start()
+
 	n.wg.Add(1)
 	go n.notificationDispatcher()
 
diff --git a/channeldb/invoices.go b/channeldb/invoices.go
index 3f3dbfd9a..f7912987f 100644
--- a/channeldb/invoices.go
+++ b/channeldb/invoices.go
@@ -272,7 +272,7 @@ type InvoiceHTLC struct {
 
 	// State indicates the state the invoice htlc is currently in. A
 	// cancelled htlc isn't just removed from the invoice htlcs map, because
-	// we need AcceptHeight to properly cancel the htlc back.
+	// we need AcceptedHeight to properly cancel the htlc back.
 	State HtlcState
 }
 
@@ -1224,9 +1224,9 @@ func (d *DB) updateInvoice(hash lntypes.Hash, invoices, settleIndex *bbolt.Bucke
 			if !ok {
 				return nil, fmt.Errorf("unknown htlc %v", key)
 			}
-			if htlc.State != HtlcStateAccepted {
-				return nil, fmt.Errorf("can only cancel " +
-					"accepted htlcs")
+			if htlc.State == HtlcStateSettled {
+				return nil, fmt.Errorf("cannot cancel a " +
+					"settled htlc")
 			}
 
 			htlc.State = HtlcStateCancelled
diff --git a/cmd/lncli/wtclient.go b/cmd/lncli/wtclient_active.go
similarity index 99%
rename from cmd/lncli/wtclient.go
rename to cmd/lncli/wtclient_active.go
index bcc0a4eb7..c58f38084 100644
--- a/cmd/lncli/wtclient.go
+++ b/cmd/lncli/wtclient_active.go
@@ -1,3 +1,5 @@
+// +build wtclientrpc
+
 package main
 
 import (
diff --git a/cmd/lncli/wtclient_default.go b/cmd/lncli/wtclient_default.go
new file mode 100644
index 000000000..d1e3c1dd8
--- /dev/null
+++ b/cmd/lncli/wtclient_default.go
@@ -0,0 +1,10 @@
+// +build !wtclientrpc
+
+package main
+
+import "github.com/urfave/cli"
+
+// wtclientCommands will return nil for non-wtclientrpc builds.
+func wtclientCommands() []cli.Command {
+	return nil
+}
diff --git a/cmd/lncli/wtclient_types.go b/cmd/lncli/wtclient_types.go
index 4192bef02..7dcf5bf53 100644
--- a/cmd/lncli/wtclient_types.go
+++ b/cmd/lncli/wtclient_types.go
@@ -1,3 +1,5 @@
+// +build wtclientrpc
+
 package main
 
 import (
diff --git a/contractcourt/channel_arbitrator.go b/contractcourt/channel_arbitrator.go
index fbad14651..93f369258 100644
--- a/contractcourt/channel_arbitrator.go
+++ b/contractcourt/channel_arbitrator.go
@@ -357,9 +357,6 @@ func (c *ChannelArbitrator) Start() error {
 			case channeldb.CooperativeClose:
 				trigger = coopCloseTrigger
 
-			case channeldb.BreachClose:
-				trigger = breachCloseTrigger
-
 			case channeldb.LocalForceClose:
 				trigger = localCloseTrigger
 
@@ -421,6 +418,8 @@ func (c *ChannelArbitrator) Start() error {
 		}
 	}
 
+	// TODO(roasbeef): cancel if breached
+
 	c.wg.Add(1)
 	go c.channelAttendant(bestHeight)
 	return nil
@@ -650,11 +649,6 @@ const (
 	// coopCloseTrigger is a transition trigger driven by a cooperative
 	// close transaction being confirmed.
 	coopCloseTrigger
-
-	// breachCloseTrigger is a transition trigger driven by a remote breach
-	// being confirmed. In this case the channel arbitrator won't have to
-	// do anything, so we'll just clean up and exit gracefully.
-	breachCloseTrigger
 )
 
 // String returns a human readable string describing the passed
@@ -676,9 +670,6 @@ func (t transitionTrigger) String() string {
 	case coopCloseTrigger:
 		return "coopCloseTrigger"
 
-	case breachCloseTrigger:
-		return "breachCloseTrigger"
-
 	default:
 		return "unknown trigger"
 	}
@@ -757,9 +748,8 @@ func (c *ChannelArbitrator) stateStep(
 
 		// If the trigger is a cooperative close being confirmed, then
 		// we can go straight to StateFullyResolved, as there won't be
-		// any contracts to resolve. The same is true in the case of a
-		// breach.
-		case coopCloseTrigger, breachCloseTrigger:
+		// any contracts to resolve.
+		case coopCloseTrigger:
 			nextState = StateFullyResolved
 
 		// Otherwise, if this state advance was triggered by a
@@ -783,7 +773,7 @@ func (c *ChannelArbitrator) stateStep(
 		// StateBroadcastCommit via a user or chain trigger. On restart,
 		// this state may be reexecuted after closing the channel, but
 		// failing to commit to StateContractClosed or
-		// StateFullyResolved. In that case, one of the four close
+		// StateFullyResolved. In that case, one of the three close
 		// triggers will be presented, signifying that we should skip
 		// rebroadcasting, and go straight to resolving the on-chain
 		// contract or marking the channel resolved.
@@ -795,7 +785,7 @@ func (c *ChannelArbitrator) stateStep(
 				c.cfg.ChanPoint, trigger, StateContractClosed)
 			return StateContractClosed, closeTx, nil
 
-		case coopCloseTrigger, breachCloseTrigger:
+		case coopCloseTrigger:
 			log.Infof("ChannelArbitrator(%v): detected %s "+
 				"close after closing channel, fast-forwarding "+
 				"to %s to resolve contract",
@@ -871,9 +861,7 @@ func (c *ChannelArbitrator) stateStep(
 				c.cfg.ChanPoint, trigger)
 			nextState = StateContractClosed
 
-		// If a coop close or breach was confirmed, jump straight to
-		// the fully resolved state.
-		case coopCloseTrigger, breachCloseTrigger:
+		case coopCloseTrigger:
 			log.Infof("ChannelArbitrator(%v): trigger %v, "+
 				" going to StateFullyResolved",
 				c.cfg.ChanPoint, trigger)
@@ -1328,15 +1316,6 @@ func (c *ChannelArbitrator) checkCommitChainActions(height uint32,
 	// either learn of it eventually from the outgoing HTLC, or the sender
 	// will timeout the HTLC.
 	for _, htlc := range htlcs.incomingHTLCs {
-		// If the HTLC is dust, there is no action to be taken.
-		if htlc.OutputIndex < 0 {
-			log.Debugf("ChannelArbitrator(%v): no resolution "+
-				"needed for incoming dust htlc=%x",
-				c.cfg.ChanPoint, htlc.RHash[:])
-
-			continue
-		}
-
 		log.Tracef("ChannelArbitrator(%v): watching chain to decide "+
 			"action for incoming htlc=%x", c.cfg.ChanPoint,
 			htlc.RHash[:])
@@ -1892,8 +1871,8 @@ func (c *ChannelArbitrator) resolveContract(currentContract ContractResolver) {
 				}
 
 				log.Errorf("ChannelArbitrator(%v): unable to "+
-					"progress %T: %v",
-					c.cfg.ChanPoint, currentContract, err)
+					"progress resolver: %v",
+					c.cfg.ChanPoint, err)
 				return
 			}
 
@@ -2038,7 +2017,7 @@ func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
 				uint32(bestHeight), chainTrigger, nil,
 			)
 			if err != nil {
-				log.Errorf("Unable to advance state: %v", err)
+				log.Errorf("unable to advance state: %v", err)
 			}
 
 			// If as a result of this trigger, the contract is
@@ -2093,7 +2072,7 @@ func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
 				closeInfo.ChannelCloseSummary,
 			)
 			if err != nil {
-				log.Errorf("Unable to mark channel closed: "+
+				log.Errorf("unable to mark channel closed: "+
 					"%v", err)
 				return
 			}
@@ -2104,7 +2083,7 @@ func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
 				closeInfo.CloseHeight, coopCloseTrigger, nil,
 			)
 			if err != nil {
-				log.Errorf("Unable to advance state: %v", err)
+				log.Errorf("unable to advance state: %v", err)
 				return
 			}
 
@@ -2135,7 +2114,7 @@ func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
 			// actions on restart.
 			err := c.log.LogContractResolutions(contractRes)
 			if err != nil {
-				log.Errorf("Unable to write resolutions: %v",
+				log.Errorf("unable to write resolutions: %v",
 					err)
 				return
 			}
@@ -2143,8 +2122,7 @@ func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
 				&closeInfo.CommitSet,
 			)
 			if err != nil {
-				log.Errorf("Unable to write commit set: %v",
-					err)
+				log.Errorf("unable to write commit set: %v", err)
 				return
 			}
 
@@ -2162,7 +2140,7 @@ func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
 				closeInfo.ChannelCloseSummary,
 			)
 			if err != nil {
-				log.Errorf("Unable to mark "+
+				log.Errorf("unable to mark "+
 					"channel closed: %v", err)
 				return
 			}
@@ -2174,7 +2152,7 @@ func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
 				localCloseTrigger, &closeInfo.CommitSet,
 			)
 			if err != nil {
-				log.Errorf("Unable to advance state: %v", err)
+				log.Errorf("unable to advance state: %v", err)
 			}
 
 		// The remote party has broadcast the commitment on-chain.
@@ -2201,7 +2179,7 @@ func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
 			// actions on restart.
 			err := c.log.LogContractResolutions(contractRes)
 			if err != nil {
-				log.Errorf("Unable to write resolutions: %v",
+				log.Errorf("unable to write resolutions: %v",
 					err)
 				return
 			}
@@ -2209,8 +2187,7 @@ func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
 				&uniClosure.CommitSet,
 			)
 			if err != nil {
-				log.Errorf("Unable to write commit set: %v",
-					err)
+				log.Errorf("unable to write commit set: %v", err)
 				return
 			}
 
@@ -2227,7 +2204,7 @@ func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
 			closeSummary := &uniClosure.ChannelCloseSummary
 			err = c.cfg.MarkChannelClosed(closeSummary)
 			if err != nil {
-				log.Errorf("Unable to mark channel closed: %v",
+				log.Errorf("unable to mark channel closed: %v",
 					err)
 				return
 			}
@@ -2239,24 +2216,7 @@ func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
 				remoteCloseTrigger, &uniClosure.CommitSet,
 			)
 			if err != nil {
-				log.Errorf("Unable to advance state: %v", err)
-			}
-
-		// The remote has breached the channel. As this is handled by
-		// the ChainWatcher and BreachArbiter, we don't have to do
-		// anything in particular, so just advance our state and
-		// gracefully exit.
-		case <-c.cfg.ChainEvents.ContractBreach:
-			log.Infof("ChannelArbitrator(%v): remote party has "+
-				"breached channel!", c.cfg.ChanPoint)
-
-			// We'll advance our state machine until it reaches a
-			// terminal state.
-			_, _, err := c.advanceState(
-				uint32(bestHeight), breachCloseTrigger, nil,
-			)
-			if err != nil {
-				log.Errorf("Unable to advance state: %v", err)
+				log.Errorf("unable to advance state: %v", err)
 			}
 
 		// A new contract has just been resolved, we'll now check our
@@ -2270,7 +2230,7 @@ func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
 				uint32(bestHeight), chainTrigger, nil,
 			)
 			if err != nil {
-				log.Errorf("Unable to advance state: %v", err)
+				log.Errorf("unable to advance state: %v", err)
 			}
 
 			// If we don't have anything further to do after
@@ -2304,7 +2264,7 @@ func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
 				uint32(bestHeight), userTrigger, nil,
 			)
 			if err != nil {
-				log.Errorf("Unable to advance state: %v", err)
+				log.Errorf("unable to advance state: %v", err)
 			}
 
 			select {
diff --git a/discovery/gossiper.go b/discovery/gossiper.go
index b943cfe31..7db498e69 100644
--- a/discovery/gossiper.go
+++ b/discovery/gossiper.go
@@ -147,12 +147,6 @@ type Config struct {
 	// notification for when it reconnects.
 	NotifyWhenOffline func(peerPubKey [33]byte) <-chan struct{}
 
-	// SelfNodeAnnouncement is a function that fetches our own current node
-	// announcement, for use when determining whether we should update our
-	// peers about our presence on the network. If the refresh is true, a
-	// new and updated announcement will be returned.
-	SelfNodeAnnouncement func(refresh bool) (lnwire.NodeAnnouncement, error)
-
 	// ProofMatureDelta the number of confirmations which is needed before
 	// exchange the channel announcement proofs.
 	ProofMatureDelta uint32
@@ -162,17 +156,9 @@ type Config struct {
 	// the last trickle tick.
 	TrickleDelay time.Duration
 
-	// RetransmitTicker is a ticker that ticks with a period which
-	// indicates that we should check if we need re-broadcast any of our
-	// personal channels.
-	RetransmitTicker ticker.Ticker
-
-	// RebroadcastInterval is the maximum time we wait between sending out
-	// channel updates for our active channels and our own node
-	// announcement. We do this to ensure our active presence on the
-	// network is known, and we are not being considered a zombie node or
-	// having zombie channels.
-	RebroadcastInterval time.Duration
+	// RetransmitDelay is the period of a timer which indicates that we
+	// should check if we need re-broadcast any of our personal channels.
+	RetransmitDelay time.Duration
 
 	// WaitingProofStore is a persistent storage of partial channel proof
 	// announcement messages. We use it to buffer half of the material
@@ -895,16 +881,16 @@ func (d *AuthenticatedGossiper) networkHandler() {
 	announcements := deDupedAnnouncements{}
 	announcements.Reset()
 
-	d.cfg.RetransmitTicker.Resume()
-	defer d.cfg.RetransmitTicker.Stop()
+	retransmitTimer := time.NewTicker(d.cfg.RetransmitDelay)
+	defer retransmitTimer.Stop()
 
 	trickleTimer := time.NewTicker(d.cfg.TrickleDelay)
 	defer trickleTimer.Stop()
 
-	// To start, we'll first check to see if there are any stale channel or
-	// node announcements that we need to re-transmit.
-	if err := d.retransmitStaleAnns(time.Now()); err != nil {
-		log.Errorf("Unable to rebroadcast stale announcements: %v", err)
+	// To start, we'll first check to see if there are any stale channels
+	// that we need to re-transmit.
+	if err := d.retransmitStaleChannels(); err != nil {
+		log.Errorf("Unable to rebroadcast stale channels: %v", err)
 	}
 
 	// We'll use this validation to ensure that we process jobs in their
@@ -1115,14 +1101,13 @@ func (d *AuthenticatedGossiper) networkHandler() {
 
 		// The retransmission timer has ticked which indicates that we
 		// should check if we need to prune or re-broadcast any of our
-		// personal channels or node announcement. This addresses the
-		// case of "zombie" channels and channel advertisements that
-		// have been dropped, or not properly propagated through the
-		// network.
-		case tick := <-d.cfg.RetransmitTicker.Ticks():
-			if err := d.retransmitStaleAnns(tick); err != nil {
+		// personal channels. This addresses the case of "zombie"
+		// channels and channel advertisements that have been dropped,
+		// or not properly propagated through the network.
+		case <-retransmitTimer.C:
+			if err := d.retransmitStaleChannels(); err != nil {
 				log.Errorf("unable to rebroadcast stale "+
-					"announcements: %v", err)
+					"channels: %v", err)
 			}
 
 		// The gossiper has been signalled to exit, to we exit our
@@ -1170,23 +1155,18 @@ func (d *AuthenticatedGossiper) isRecentlyRejectedMsg(msg lnwire.Message) bool {
 	}
 }
 
-// retransmitStaleAnns examines all outgoing channels that the source node is
-// known to maintain to check to see if any of them are "stale". A channel is
-// stale iff, the last timestamp of its rebroadcast is older than the
-// RebroadcastInterval. We also check if a refreshed node announcement should
-// be resent.
-func (d *AuthenticatedGossiper) retransmitStaleAnns(now time.Time) error {
+// retransmitStaleChannels examines all outgoing channels that the source node
+// is known to maintain to check to see if any of them are "stale". A channel
+// is stale iff, the last timestamp of its rebroadcast is older then
+// broadcastInterval.
+func (d *AuthenticatedGossiper) retransmitStaleChannels() error {
 	// Iterate over all of our channels and check if any of them fall
 	// within the prune interval or re-broadcast interval.
 	type updateTuple struct {
 		info *channeldb.ChannelEdgeInfo
 		edge *channeldb.ChannelEdgePolicy
 	}
-
-	var (
-		havePublicChannels bool
-		edgesToUpdate      []updateTuple
-	)
+	var edgesToUpdate []updateTuple
 	err := d.cfg.Router.ForAllOutgoingChannels(func(
 		info *channeldb.ChannelEdgeInfo,
 		edge *channeldb.ChannelEdgePolicy) error {
@@ -1202,11 +1182,6 @@ func (d *AuthenticatedGossiper) retransmitStaleAnns(now time.Time) error {
 			return nil
 		}
 
-		// We make a note that we have at least one public channel. We
-		// use this to determine whether we should send a node
-		// announcement below.
-		havePublicChannels = true
-
 		// If this edge has a ChannelUpdate that was created before the
 		// introduction of the MaxHTLC field, then we'll update this
 		// edge to propagate this information in the network.
@@ -1218,12 +1193,14 @@ func (d *AuthenticatedGossiper) retransmitStaleAnns(now time.Time) error {
 			return nil
 		}
 
-		timeElapsed := now.Sub(edge.LastUpdate)
+		const broadcastInterval = time.Hour * 24
 
-		// If it's been longer than RebroadcastInterval since we've
-		// re-broadcasted the channel, add the channel to the set of
-		// edges we need to update.
-		if timeElapsed >= d.cfg.RebroadcastInterval {
+		timeElapsed := time.Since(edge.LastUpdate)
+
+		// If it's been a full day since we've re-broadcasted the
+		// channel, add the channel to the set of edges we need to
+		// update.
+		if timeElapsed >= broadcastInterval {
 			edgesToUpdate = append(edgesToUpdate, updateTuple{
 				info: info,
 				edge: edge,
@@ -1257,51 +1234,13 @@ func (d *AuthenticatedGossiper) retransmitStaleAnns(now time.Time) error {
 		signedUpdates = append(signedUpdates, chanUpdate)
 	}
 
-	// If we don't have any public channels, we return as we don't want to
-	// broadcast anything that would reveal our existence.
-	if !havePublicChannels {
-		return nil
-	}
-
-	// We'll also check that our NodeAnnouncement is not too old.
-	currentNodeAnn, err := d.cfg.SelfNodeAnnouncement(false)
-	if err != nil {
-		return fmt.Errorf("unable to get current node announment: %v",
-			err)
-	}
-
-	timestamp := time.Unix(int64(currentNodeAnn.Timestamp), 0)
-	timeElapsed := now.Sub(timestamp)
-
-	// If it's been a full day since we've re-broadcasted the
-	// node announcement, refresh it and resend it.
-	nodeAnnStr := ""
-	if timeElapsed >= d.cfg.RebroadcastInterval {
-		newNodeAnn, err := d.cfg.SelfNodeAnnouncement(true)
-		if err != nil {
-			return fmt.Errorf("unable to get refreshed node "+
-				"announcement: %v", err)
-		}
-
-		signedUpdates = append(signedUpdates, &newNodeAnn)
-		nodeAnnStr = " and our refreshed node announcement"
-
-		// Before broadcasting the refreshed node announcement, add it
-		// to our own graph.
-		if err := d.addNode(&newNodeAnn); err != nil {
-			log.Errorf("Unable to add refreshed node announcement "+
-				"to graph: %v", err)
-		}
-	}
-
-	// If we don't have any updates to re-broadcast, then we'll exit
+	// If we don't have any channels to re-broadcast, then we'll exit
 	// early.
 	if len(signedUpdates) == 0 {
 		return nil
 	}
 
-	log.Infof("Retransmitting %v outgoing channels%v",
-		len(edgesToUpdate), nodeAnnStr)
+	log.Infof("Retransmitting %v outgoing channels", len(edgesToUpdate))
 
 	// With all the wire announcements properly crafted, we'll broadcast
 	// our known outgoing channels to all our immediate peers.
@@ -1515,33 +1454,6 @@ func (d *AuthenticatedGossiper) processRejectedEdge(
 	return announcements, nil
 }
 
-// addNode processes the given node announcement, and adds it to our channel
-// graph.
-func (d *AuthenticatedGossiper) addNode(msg *lnwire.NodeAnnouncement) error {
-	if err := routing.ValidateNodeAnn(msg); err != nil {
-		return fmt.Errorf("unable to validate node announcement: %v",
-			err)
-	}
-
-	timestamp := time.Unix(int64(msg.Timestamp), 0)
-	features := lnwire.NewFeatureVector(
-		msg.Features, lnwire.GlobalFeatures,
-	)
-	node := &channeldb.LightningNode{
-		HaveNodeAnnouncement: true,
-		LastUpdate:           timestamp,
-		Addresses:            msg.Addresses,
-		PubKeyBytes:          msg.NodeID,
-		Alias:                msg.Alias.String(),
-		AuthSigBytes:         msg.Signature.ToSignatureBytes(),
-		Features:             features,
-		Color:                msg.RGBColor,
-		ExtraOpaqueData:      msg.ExtraOpaqueData,
-	}
-
-	return d.cfg.Router.AddNode(node)
-}
-
 // processNetworkAnnouncement processes a new network relate authenticated
 // channel or node announcement or announcements proofs. If the announcement
 // didn't affect the internal state due to either being out of date, invalid,
@@ -1575,7 +1487,30 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(
 			return nil
 		}
 
-		if err := d.addNode(msg); err != nil {
+		if err := routing.ValidateNodeAnn(msg); err != nil {
+			err := fmt.Errorf("unable to validate "+
+				"node announcement: %v", err)
+			log.Error(err)
+			nMsg.err <- err
+			return nil
+		}
+
+		features := lnwire.NewFeatureVector(
+			msg.Features, lnwire.GlobalFeatures,
+		)
+		node := &channeldb.LightningNode{
+			HaveNodeAnnouncement: true,
+			LastUpdate:           timestamp,
+			Addresses:            msg.Addresses,
+			PubKeyBytes:          msg.NodeID,
+			Alias:                msg.Alias.String(),
+			AuthSigBytes:         msg.Signature.ToSignatureBytes(),
+			Features:             features,
+			Color:                msg.RGBColor,
+			ExtraOpaqueData:      msg.ExtraOpaqueData,
+		}
+
+		if err := d.cfg.Router.AddNode(node); err != nil {
 			if routing.IsError(err, routing.ErrOutdated,
 				routing.ErrIgnored) {
 
@@ -1591,10 +1526,10 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(
 		// In order to ensure we don't leak unadvertised nodes, we'll
 		// make a quick check to ensure this node intends to publicly
 		// advertise itself to the network.
-		isPublic, err := d.cfg.Router.IsPublicNode(msg.NodeID)
+		isPublic, err := d.cfg.Router.IsPublicNode(node.PubKeyBytes)
 		if err != nil {
 			log.Errorf("Unable to determine if node %x is "+
-				"advertised: %v", msg.NodeID, err)
+				"advertised: %v", node.PubKeyBytes, err)
 			nMsg.err <- err
 			return nil
 		}
diff --git a/go.mod b/go.mod
index 488a13566..46a9c7a08 100644
--- a/go.mod
+++ b/go.mod
@@ -33,7 +33,7 @@ require (
 	github.com/juju/utils v0.0.0-20180820210520-bf9cc5bdd62d // indirect
 	github.com/juju/version v0.0.0-20180108022336-b64dbd566305 // indirect
 	github.com/kkdai/bstream v0.0.0-20181106074824-b3251f7901ec
-	github.com/lightninglabs/neutrino v0.0.0-20190919020618-7cf83626779e
+	github.com/lightninglabs/neutrino v0.0.0-20190906012717-f087198de655
 	github.com/lightningnetwork/lightning-onion v0.0.0-20190909101754-850081b08b6a
 	github.com/lightningnetwork/lnd/queue v1.0.1
 	github.com/lightningnetwork/lnd/ticker v1.0.0
diff --git a/go.sum b/go.sum
index 963208956..e76a5b4c9 100644
--- a/go.sum
+++ b/go.sum
@@ -127,8 +127,6 @@ github.com/lightninglabs/gozmq v0.0.0-20190710231225-cea2a031735d h1:tt8hwvxl6fk
 github.com/lightninglabs/gozmq v0.0.0-20190710231225-cea2a031735d/go.mod h1:vxmQPeIQxPf6Jf9rM8R+B4rKBqLA2AjttNxkFBL2Plk=
 github.com/lightninglabs/neutrino v0.0.0-20190906012717-f087198de655 h1:/EpOX/6QvD5CdoAfMt1yvZeUPjJ8sCiHv6CRNG2lEuY=
 github.com/lightninglabs/neutrino v0.0.0-20190906012717-f087198de655/go.mod h1:awTrhbCWjWNH4yVwZ4IE7nZbvpQ27e7OyD+jao7wRxA=
-github.com/lightninglabs/neutrino v0.0.0-20190919020618-7cf83626779e h1:1xvNaf+0HrwjzuqqI7b0jZFTHb+MpEup4tpG44xhrmE=
-github.com/lightninglabs/neutrino v0.0.0-20190919020618-7cf83626779e/go.mod h1:awTrhbCWjWNH4yVwZ4IE7nZbvpQ27e7OyD+jao7wRxA=
 github.com/lightningnetwork/lightning-onion v0.0.0-20190909101754-850081b08b6a h1:GoWPN4i4jTKRxhVNh9a2vvBBO1Y2seiJB+SopUYoKyo=
 github.com/lightningnetwork/lightning-onion v0.0.0-20190909101754-850081b08b6a/go.mod h1:rigfi6Af/KqsF7Za0hOgcyq2PNH4AN70AaMRxcJkff4=
 github.com/ltcsuite/ltcd v0.0.0-20190101042124-f37f8bf35796 h1:sjOGyegMIhvgfq5oaue6Td+hxZuf3tDC8lAPrFldqFw=
diff --git a/htlcswitch/link.go b/htlcswitch/link.go
index c904aa3e2..1c462577e 100644
--- a/htlcswitch/link.go
+++ b/htlcswitch/link.go
@@ -364,9 +364,9 @@ type channelLink struct {
 	// registry.
 	hodlQueue *queue.ConcurrentQueue
 
-	// hodlMap stores related htlc data for a circuit key. It allows
+	// hodlMap stores a list of htlc data structs per hash. It allows
 	// resolving those htlcs when we receive a message on hodlQueue.
-	hodlMap map[channeldb.CircuitKey]hodlHtlc
+	hodlMap map[lntypes.Hash][]hodlHtlc
 
 	wg   sync.WaitGroup
 	quit chan struct{}
@@ -391,7 +391,7 @@ func NewChannelLink(cfg ChannelLinkConfig,
 		logCommitTimer: time.NewTimer(300 * time.Millisecond),
 		overflowQueue:  newPacketQueue(input.MaxHTLCNumber / 2),
 		htlcUpdates:    make(chan *contractcourt.ContractUpdate),
-		hodlMap:        make(map[channeldb.CircuitKey]hodlHtlc),
+		hodlMap:        make(map[lntypes.Hash][]hodlHtlc),
 		hodlQueue:      queue.NewConcurrentQueue(10),
 		quit:           make(chan struct{}),
 	}
@@ -1151,21 +1151,10 @@ func (l *channelLink) processHodlQueue(firstHodlEvent invoices.HodlEvent) error
 	hodlEvent := firstHodlEvent
 loop:
 	for {
-		// Lookup all hodl htlcs that can be failed or settled with this event.
-		// The hodl htlc must be present in the map.
-		circuitKey := hodlEvent.CircuitKey
-		hodlHtlc, ok := l.hodlMap[circuitKey]
-		if !ok {
-			return fmt.Errorf("hodl htlc not found: %v", circuitKey)
-		}
-
-		if err := l.processHodlEvent(hodlEvent, hodlHtlc); err != nil {
+		if err := l.processHodlMapEvent(hodlEvent); err != nil {
 			return err
 		}
 
-		// Clean up hodl map.
-		delete(l.hodlMap, circuitKey)
-
 		select {
 		case item := <-l.hodlQueue.ChanOut():
 			hodlEvent = item.(invoices.HodlEvent)
@@ -1182,37 +1171,73 @@ loop:
 	return nil
 }
 
+// processHodlMapEvent resolves stored hodl htlcs based using the information in
+// hodlEvent.
+func (l *channelLink) processHodlMapEvent(hodlEvent invoices.HodlEvent) error {
+	// Lookup all hodl htlcs that can be failed or settled with this event.
+	// The hodl htlc must be present in the map.
+	hash := hodlEvent.Hash
+	hodlHtlcs, ok := l.hodlMap[hash]
+	if !ok {
+		return fmt.Errorf("hodl htlc not found: %v", hash)
+	}
+
+	if err := l.processHodlEvent(hodlEvent, hodlHtlcs...); err != nil {
+		return err
+	}
+
+	// Clean up hodl map.
+	delete(l.hodlMap, hash)
+
+	return nil
+}
+
 // processHodlEvent applies a received hodl event to the provided htlc. When
 // this function returns without an error, the commit tx should be updated.
 func (l *channelLink) processHodlEvent(hodlEvent invoices.HodlEvent,
-	htlc hodlHtlc) error {
-
-	l.batchCounter++
+	htlcs ...hodlHtlc) error {
 
-	circuitKey := hodlEvent.CircuitKey
+	hash := hodlEvent.Hash
 
 	// Determine required action for the resolution.
+	var hodlAction func(htlc hodlHtlc) error
 	if hodlEvent.Preimage != nil {
-		l.debugf("Received hodl settle event for %v", circuitKey)
+		l.debugf("Received hodl settle event for %v", hash)
 
-		return l.settleHTLC(
-			*hodlEvent.Preimage, htlc.pd.HtlcIndex,
-			htlc.pd.SourceRef,
-		)
+		hodlAction = func(htlc hodlHtlc) error {
+			return l.settleHTLC(
+				*hodlEvent.Preimage, htlc.pd.HtlcIndex,
+				htlc.pd.SourceRef,
+			)
+		}
+	} else {
+		l.debugf("Received hodl cancel event for %v", hash)
+
+		hodlAction = func(htlc hodlHtlc) error {
+			// In case of a cancel, always return
+			// incorrect_or_unknown_payment_details in order to
+			// avoid leaking info.
+			failure := lnwire.NewFailIncorrectDetails(
+				htlc.pd.Amount,
+			)
+
+			l.sendHTLCError(
+				htlc.pd.HtlcIndex, failure, htlc.obfuscator,
+				htlc.pd.SourceRef,
+			)
+			return nil
+		}
 	}
 
-	l.debugf("Received hodl cancel event for %v", circuitKey)
+	// Apply action for all htlcs matching this hash.
+	for _, htlc := range htlcs {
+		if err := hodlAction(htlc); err != nil {
+			return err
+		}
 
-	// In case of a cancel, always return
-	// incorrect_or_unknown_payment_details in order to avoid leaking info.
-	failure := lnwire.NewFailIncorrectDetails(
-		htlc.pd.Amount, uint32(hodlEvent.AcceptHeight),
-	)
+		l.batchCounter++
+	}
 
-	l.sendHTLCError(
-		htlc.pd.HtlcIndex, failure, htlc.obfuscator,
-		htlc.pd.SourceRef,
-	)
 	return nil
 }
 
@@ -2867,7 +2892,7 @@ func (l *channelLink) processExitHop(pd *lnwallet.PaymentDescriptor,
 
 	// Cancel htlc if we don't have an invoice for it.
 	case channeldb.ErrInvoiceNotFound:
-		failure := lnwire.NewFailIncorrectDetails(pd.Amount, heightNow)
+		failure := lnwire.NewFailIncorrectDetails(pd.Amount)
 		l.sendHTLCError(pd.HtlcIndex, failure, obfuscator, pd.SourceRef)
 
 		return true, nil
@@ -2888,7 +2913,8 @@ func (l *channelLink) processExitHop(pd *lnwallet.PaymentDescriptor,
 
 	if event == nil {
 		// Save payment descriptor for future reference.
-		l.hodlMap[circuitKey] = htlc
+		hodlHtlcs := l.hodlMap[invoiceHash]
+		l.hodlMap[invoiceHash] = append(hodlHtlcs, htlc)
 
 		return false, nil
 	}
diff --git a/invoices/invoiceregistry.go b/invoices/invoiceregistry.go
index 7efb92443..602014d40 100644
--- a/invoices/invoiceregistry.go
+++ b/invoices/invoiceregistry.go
@@ -36,12 +36,8 @@ type HodlEvent struct {
 	// Preimage is the htlc preimage. Its value is nil in case of a cancel.
 	Preimage *lntypes.Preimage
 
-	// CircuitKey is the key of the htlc for which we have a resolution
-	// decision.
-	CircuitKey channeldb.CircuitKey
-
-	// AcceptHeight is the original height at which the htlc was accepted.
-	AcceptHeight int32
+	// Hash is the htlc hash.
+	Hash lntypes.Hash
 }
 
 // InvoiceRegistry is a central registry of all the outstanding invoices
@@ -64,13 +60,13 @@ type InvoiceRegistry struct {
 	// new single invoice subscriptions are carried.
 	invoiceEvents chan interface{}
 
-	// subscriptions is a map from a circuit key to a list of subscribers.
+	// subscriptions is a map from a payment hash to a list of subscribers.
 	// It is used for efficient notification of links.
-	hodlSubscriptions map[channeldb.CircuitKey]map[chan<- interface{}]struct{}
+	hodlSubscriptions map[lntypes.Hash]map[chan<- interface{}]struct{}
 
-	// reverseSubscriptions tracks circuit keys subscribed to per
-	// subscriber. This is used to unsubscribe from all hashes efficiently.
-	hodlReverseSubscriptions map[chan<- interface{}]map[channeldb.CircuitKey]struct{}
+	// reverseSubscriptions tracks hashes subscribed to per subscriber. This
+	// is used to unsubscribe from all hashes efficiently.
+	hodlReverseSubscriptions map[chan<- interface{}]map[lntypes.Hash]struct{}
 
 	// finalCltvRejectDelta defines the number of blocks before the expiry
 	// of the htlc where we no longer settle it as an exit hop and instead
@@ -96,8 +92,8 @@ func NewRegistry(cdb *channeldb.DB, finalCltvRejectDelta int32) *InvoiceRegistry
 		newSubscriptions:          make(chan *InvoiceSubscription),
 		subscriptionCancels:       make(chan uint32),
 		invoiceEvents:             make(chan interface{}, 100),
-		hodlSubscriptions:         make(map[channeldb.CircuitKey]map[chan<- interface{}]struct{}),
-		hodlReverseSubscriptions:  make(map[chan<- interface{}]map[channeldb.CircuitKey]struct{}),
+		hodlSubscriptions:         make(map[lntypes.Hash]map[chan<- interface{}]struct{}),
+		hodlReverseSubscriptions:  make(map[chan<- interface{}]map[lntypes.Hash]struct{}),
 		finalCltvRejectDelta:      finalCltvRejectDelta,
 		quit:                      make(chan struct{}),
 	}
@@ -555,33 +551,24 @@ func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash,
 	// If it isn't recorded, cancel htlc.
 	if !ok {
 		return &HodlEvent{
-			CircuitKey:   circuitKey,
-			AcceptHeight: currentHeight,
+			Hash: rHash,
 		}, nil
 	}
 
-	// Determine accepted height of this htlc. If the htlc reached the
-	// invoice database (possibly in a previous call to the invoice
-	// registry), we'll take the original accepted height as it was recorded
-	// in the database.
-	acceptHeight := int32(invoiceHtlc.AcceptHeight)
-
 	switch invoiceHtlc.State {
 	case channeldb.HtlcStateCancelled:
 		return &HodlEvent{
-			CircuitKey:   circuitKey,
-			AcceptHeight: acceptHeight,
+			Hash: rHash,
 		}, nil
 
 	case channeldb.HtlcStateSettled:
 		return &HodlEvent{
-			CircuitKey:   circuitKey,
-			Preimage:     &invoice.Terms.PaymentPreimage,
-			AcceptHeight: acceptHeight,
+			Hash:     rHash,
+			Preimage: &invoice.Terms.PaymentPreimage,
 		}, nil
 
 	case channeldb.HtlcStateAccepted:
-		i.hodlSubscribe(hodlChan, circuitKey)
+		i.hodlSubscribe(hodlChan, rHash)
 		return nil, nil
 
 	default:
@@ -622,23 +609,10 @@ func (i *InvoiceRegistry) SettleHodlInvoice(preimage lntypes.Preimage) error {
 	log.Debugf("Invoice(%v): settled with preimage %v", hash,
 		invoice.Terms.PaymentPreimage)
 
-	// In the callback, we marked the invoice as settled. UpdateInvoice will
-	// have seen this and should have moved all htlcs that were accepted to
-	// the settled state. In the loop below, we go through all of these and
-	// notify links and resolvers that are waiting for resolution. Any htlcs
-	// that were already settled before, will be notified again. This isn't
-	// necessary but doesn't hurt either.
-	for key, htlc := range invoice.Htlcs {
-		if htlc.State != channeldb.HtlcStateSettled {
-			continue
-		}
-
-		i.notifyHodlSubscribers(HodlEvent{
-			CircuitKey:   key,
-			Preimage:     &preimage,
-			AcceptHeight: int32(htlc.AcceptHeight),
-		})
-	}
+	i.notifyHodlSubscribers(HodlEvent{
+		Hash:     hash,
+		Preimage: &preimage,
+	})
 	i.notifyClients(hash, invoice, invoice.Terms.State)
 
 	return nil
@@ -666,21 +640,7 @@ func (i *InvoiceRegistry) CancelInvoice(payHash lntypes.Hash) error {
 		canceledHtlcs := make(
 			map[channeldb.CircuitKey]*channeldb.HtlcAcceptDesc,
 		)
-		for key, htlc := range invoice.Htlcs {
-			switch htlc.State {
-
-			// If we get here, there shouldn't be any settled htlcs.
-			case channeldb.HtlcStateSettled:
-				return nil, errors.New("cannot cancel " +
-					"invoice with settled htlc(s)")
-
-			// Don't cancel htlcs that were already cancelled,
-			// because it would incorrectly modify the invoice paid
-			// amt.
-			case channeldb.HtlcStateCancelled:
-				continue
-			}
-
+		for key := range invoice.Htlcs {
 			canceledHtlcs[key] = nil
 		}
 
@@ -704,22 +664,9 @@ func (i *InvoiceRegistry) CancelInvoice(payHash lntypes.Hash) error {
 	}
 
 	log.Debugf("Invoice(%v): canceled", payHash)
-
-	// In the callback, some htlcs may have been moved to the canceled
-	// state. We now go through all of these and notify links and resolvers
-	// that are waiting for resolution. Any htlcs that were already canceled
-	// before, will be notified again. This isn't necessary but doesn't hurt
-	// either.
-	for key, htlc := range invoice.Htlcs {
-		if htlc.State != channeldb.HtlcStateCancelled {
-			continue
-		}
-
-		i.notifyHodlSubscribers(HodlEvent{
-			CircuitKey:   key,
-			AcceptHeight: int32(htlc.AcceptHeight),
-		})
-	}
+	i.notifyHodlSubscribers(HodlEvent{
+		Hash: payHash,
+	})
 	i.notifyClients(payHash, invoice, channeldb.ContractCanceled)
 
 	return nil
@@ -986,7 +933,7 @@ func (i *InvoiceRegistry) SubscribeSingleInvoice(
 
 // notifyHodlSubscribers sends out the hodl event to all current subscribers.
 func (i *InvoiceRegistry) notifyHodlSubscribers(hodlEvent HodlEvent) {
-	subscribers, ok := i.hodlSubscriptions[hodlEvent.CircuitKey]
+	subscribers, ok := i.hodlSubscriptions[hodlEvent.Hash]
 	if !ok {
 		return
 	}
@@ -1001,34 +948,31 @@ func (i *InvoiceRegistry) notifyHodlSubscribers(hodlEvent HodlEvent) {
 			return
 		}
 
-		delete(
-			i.hodlReverseSubscriptions[subscriber],
-			hodlEvent.CircuitKey,
-		)
+		delete(i.hodlReverseSubscriptions[subscriber], hodlEvent.Hash)
 	}
 
-	delete(i.hodlSubscriptions, hodlEvent.CircuitKey)
+	delete(i.hodlSubscriptions, hodlEvent.Hash)
 }
 
 // hodlSubscribe adds a new invoice subscription.
 func (i *InvoiceRegistry) hodlSubscribe(subscriber chan<- interface{},
-	circuitKey channeldb.CircuitKey) {
+	hash lntypes.Hash) {
 
-	log.Debugf("Hodl subscribe for %v", circuitKey)
+	log.Debugf("Hodl subscribe for %v", hash)
 
-	subscriptions, ok := i.hodlSubscriptions[circuitKey]
+	subscriptions, ok := i.hodlSubscriptions[hash]
 	if !ok {
 		subscriptions = make(map[chan<- interface{}]struct{})
-		i.hodlSubscriptions[circuitKey] = subscriptions
+		i.hodlSubscriptions[hash] = subscriptions
 	}
 	subscriptions[subscriber] = struct{}{}
 
 	reverseSubscriptions, ok := i.hodlReverseSubscriptions[subscriber]
 	if !ok {
-		reverseSubscriptions = make(map[channeldb.CircuitKey]struct{})
+		reverseSubscriptions = make(map[lntypes.Hash]struct{})
 		i.hodlReverseSubscriptions[subscriber] = reverseSubscriptions
 	}
-	reverseSubscriptions[circuitKey] = struct{}{}
+	reverseSubscriptions[hash] = struct{}{}
 }
 
 // HodlUnsubscribeAll cancels the subscription.
diff --git a/lnrpc/chainrpc/chainnotifier_server.go b/lnrpc/chainrpc/chainnotifer_server.go
similarity index 100%
rename from lnrpc/chainrpc/chainnotifier_server.go
rename to lnrpc/chainrpc/chainnotifer_server.go
diff --git a/lnrpc/routerrpc/router.pb.go b/lnrpc/routerrpc/router.pb.go
index fdb45dfb2..86a69c2ca 100644
--- a/lnrpc/routerrpc/router.pb.go
+++ b/lnrpc/routerrpc/router.pb.go
@@ -646,9 +646,7 @@ type Failure struct {
 	//*
 	//The position in the path of the intermediate or final node that generated
 	//the failure message. Position zero is the sender node.
-	FailureSourceIndex uint32 `protobuf:"varint,8,opt,name=failure_source_index,json=failureSourceIndex,proto3" json:"failure_source_index,omitempty"`
-	/// A failure type-dependent block height.
-	Height               uint32   `protobuf:"varint,9,opt,name=height,proto3" json:"height,omitempty"`
+	FailureSourceIndex   uint32   `protobuf:"varint,8,opt,name=failure_source_index,json=failureSourceIndex,proto3" json:"failure_source_index,omitempty"`
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 	XXX_unrecognized     []byte   `json:"-"`
 	XXX_sizecache        int32    `json:"-"`
@@ -728,13 +726,6 @@ func (m *Failure) GetFailureSourceIndex() uint32 {
 	return 0
 }
 
-func (m *Failure) GetHeight() uint32 {
-	if m != nil {
-		return m.Height
-	}
-	return 0
-}
-
 type ChannelUpdate struct {
 	//*
 	//The signature that validates the announced data and proves the ownership
@@ -1221,118 +1212,117 @@ func init() {
 func init() { proto.RegisterFile("routerrpc/router.proto", fileDescriptor_7a0613f69d37b0a5) }
 
 var fileDescriptor_7a0613f69d37b0a5 = []byte{
-	// 1769 bytes of a gzipped FileDescriptorProto
+	// 1759 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x57, 0x41, 0x73, 0x22, 0xb9,
 	0x15, 0x5e, 0x0c, 0x18, 0x78, 0x80, 0xdd, 0x96, 0x3d, 0x76, 0x0f, 0x1e, 0xef, 0x7a, 0xd9, 0xcd,
 	0xac, 0x6b, 0x6a, 0x63, 0x6f, 0x9c, 0xda, 0xad, 0xa9, 0x3d, 0x24, 0xc5, 0x80, 0x58, 0xf7, 0x0c,
 	0x74, 0x7b, 0x05, 0xcc, 0xee, 0x24, 0x07, 0x95, 0x0c, 0xb2, 0xe9, 0x72, 0xd3, 0xcd, 0x74, 0x0b,
-	0x67, 0x9c, 0x43, 0x2e, 0xa9, 0x1c, 0x73, 0xcf, 0xbf, 0xc8, 0x6f, 0xca, 0x25, 0xf9, 0x05, 0x39,
-	0xa6, 0x2a, 0x25, 0xa9, 0x1b, 0x1a, 0x8c, 0x27, 0x39, 0xd1, 0xfa, 0xde, 0xa7, 0x27, 0xe9, 0x3d,
-	0xbd, 0x4f, 0x0f, 0xd8, 0x0f, 0x83, 0x99, 0xe0, 0x61, 0x38, 0x1d, 0x9e, 0xe9, 0xaf, 0xd3, 0x69,
-	0x18, 0x88, 0x00, 0x95, 0xe6, 0x78, 0xad, 0x14, 0x4e, 0x87, 0x1a, 0xad, 0xff, 0x27, 0x0b, 0xa8,
-	0xc7, 0xfd, 0xd1, 0x25, 0xbb, 0x9f, 0x70, 0x5f, 0x10, 0xfe, 0x7e, 0xc6, 0x23, 0x81, 0x10, 0xe4,
-	0x46, 0x3c, 0x12, 0x66, 0xe6, 0x38, 0x73, 0x52, 0x21, 0xea, 0x1b, 0x19, 0x90, 0x65, 0x13, 0x61,
-	0x6e, 0x1c, 0x67, 0x4e, 0xb2, 0x44, 0x7e, 0xa2, 0xcf, 0xa1, 0x32, 0xd5, 0xf3, 0xe8, 0x98, 0x45,
-	0x63, 0x33, 0xab, 0xd8, 0xe5, 0x18, 0xbb, 0x60, 0xd1, 0x18, 0x9d, 0x80, 0x71, 0xed, 0xfa, 0xcc,
-	0xa3, 0x43, 0x4f, 0xdc, 0xd1, 0x11, 0xf7, 0x04, 0x33, 0x73, 0xc7, 0x99, 0x93, 0x3c, 0xd9, 0x52,
-	0x78, 0xd3, 0x13, 0x77, 0x2d, 0x89, 0xa2, 0xaf, 0x60, 0x3b, 0x71, 0x16, 0xea, 0x5d, 0x98, 0xf9,
-	0xe3, 0xcc, 0x49, 0x89, 0x6c, 0x4d, 0x97, 0xf7, 0xf6, 0x15, 0x6c, 0x0b, 0x77, 0xc2, 0x83, 0x99,
-	0xa0, 0x11, 0x1f, 0x06, 0xfe, 0x28, 0x32, 0x37, 0xb5, 0xc7, 0x18, 0xee, 0x69, 0x14, 0xd5, 0xa1,
-	0x7a, 0xcd, 0x39, 0xf5, 0xdc, 0x89, 0x2b, 0x68, 0xc4, 0x84, 0x59, 0x50, 0x5b, 0x2f, 0x5f, 0x73,
-	0xde, 0x91, 0x58, 0x8f, 0x09, 0xb9, 0xbf, 0x60, 0x26, 0x6e, 0x02, 0xd7, 0xbf, 0xa1, 0xc3, 0x31,
-	0xf3, 0xa9, 0x3b, 0x32, 0x8b, 0xc7, 0x99, 0x93, 0x1c, 0xd9, 0x4a, 0xf0, 0xe6, 0x98, 0xf9, 0xd6,
-	0x08, 0x1d, 0x01, 0xa8, 0x33, 0x28, 0x77, 0x66, 0x49, 0xad, 0x58, 0x92, 0x88, 0xf2, 0x85, 0xce,
-	0xa1, 0xac, 0x02, 0x4c, 0xc7, 0xae, 0x2f, 0x22, 0x13, 0x8e, 0xb3, 0x27, 0xe5, 0x73, 0xe3, 0xd4,
-	0xf3, 0x65, 0xac, 0x89, 0xb4, 0x5c, 0xb8, 0xbe, 0x20, 0x69, 0x12, 0xc2, 0x50, 0x94, 0x91, 0xa5,
-	0xc2, 0xbb, 0x33, 0xcb, 0x6a, 0xc2, 0x8b, 0xd3, 0x79, 0x96, 0x4e, 0x1f, 0xa6, 0xe5, 0xb4, 0xc5,
-	0x23, 0xd1, 0xf7, 0xee, 0xb0, 0x2f, 0xc2, 0x7b, 0x52, 0x18, 0xe9, 0x51, 0xed, 0x7b, 0xa8, 0xa4,
-	0x0d, 0x32, 0x51, 0xb7, 0xfc, 0x5e, 0xe5, 0x2e, 0x47, 0xe4, 0x27, 0xda, 0x83, 0xfc, 0x1d, 0xf3,
-	0x66, 0x5c, 0x25, 0xaf, 0x42, 0xf4, 0xe0, 0xfb, 0x8d, 0x97, 0x99, 0xfa, 0x4b, 0xd8, 0xed, 0x87,
-	0x6c, 0x78, 0xbb, 0x92, 0xff, 0xd5, 0xcc, 0x66, 0x1e, 0x64, 0xb6, 0xfe, 0x27, 0xa8, 0xc6, 0x93,
-	0x7a, 0x82, 0x89, 0x59, 0x84, 0x7e, 0x09, 0xf9, 0x48, 0x30, 0xc1, 0x15, 0x79, 0xeb, 0xfc, 0x20,
-	0x75, 0x94, 0x14, 0x91, 0x13, 0xcd, 0x42, 0x35, 0x28, 0x4e, 0x43, 0xee, 0x4e, 0xd8, 0x4d, 0xb2,
-	0xad, 0xf9, 0x18, 0xd5, 0x21, 0xaf, 0x26, 0xab, 0x1b, 0x55, 0x3e, 0xaf, 0xa4, 0xc3, 0x48, 0xb4,
-	0xa9, 0xfe, 0x1b, 0xd8, 0x56, 0xe3, 0x36, 0xe7, 0x1f, 0xbb, 0xb5, 0x07, 0x50, 0x60, 0x13, 0x9d,
-	0x7e, 0x7d, 0x73, 0x37, 0xd9, 0x44, 0x66, 0xbe, 0x3e, 0x02, 0x63, 0x31, 0x3f, 0x9a, 0x06, 0x7e,
-	0xc4, 0xe5, 0x6d, 0x90, 0xce, 0xe5, 0x65, 0x90, 0x37, 0x67, 0x22, 0x67, 0x65, 0xd4, 0xac, 0xad,
-	0x18, 0x6f, 0x73, 0xde, 0x8d, 0x98, 0x40, 0xcf, 0xf5, 0x25, 0xa4, 0x5e, 0x30, 0xbc, 0x95, 0xd7,
-	0x9a, 0xdd, 0xc7, 0xee, 0xab, 0x12, 0xee, 0x04, 0xc3, 0xdb, 0x96, 0x04, 0xeb, 0xbf, 0xd7, 0xe5,
-	0xd5, 0x0f, 0xf4, 0xde, 0xff, 0xef, 0xf0, 0x2e, 0x42, 0xb0, 0xf1, 0x78, 0x08, 0x28, 0xec, 0x2e,
-	0x39, 0x8f, 0x4f, 0x91, 0x8e, 0x6c, 0x66, 0x25, 0xb2, 0x5f, 0x43, 0xe1, 0x9a, 0xb9, 0xde, 0x2c,
-	0x4c, 0x1c, 0xa3, 0x54, 0x9a, 0xda, 0xda, 0x42, 0x12, 0x4a, 0xfd, 0x1f, 0x05, 0x28, 0xc4, 0x20,
-	0x3a, 0x87, 0xdc, 0x30, 0x18, 0x25, 0xd9, 0xfd, 0xf4, 0xe1, 0xb4, 0xe4, 0xb7, 0x19, 0x8c, 0x38,
-	0x51, 0x5c, 0xf4, 0x5b, 0xd8, 0x92, 0x45, 0xe5, 0x73, 0x8f, 0xce, 0xa6, 0x23, 0x36, 0x4f, 0xa8,
-	0x99, 0x9a, 0xdd, 0xd4, 0x84, 0x81, 0xb2, 0x93, 0xea, 0x30, 0x3d, 0x44, 0x87, 0x50, 0x1a, 0x0b,
-	0x6f, 0xa8, 0x33, 0x91, 0x53, 0x17, 0xba, 0x28, 0x01, 0x95, 0x83, 0x3a, 0x54, 0x03, 0xdf, 0x0d,
-	0x7c, 0x1a, 0x8d, 0x19, 0x3d, 0xff, 0xf6, 0x3b, 0xa5, 0x17, 0x15, 0x52, 0x56, 0x60, 0x6f, 0xcc,
-	0xce, 0xbf, 0xfd, 0x0e, 0x7d, 0x06, 0x65, 0x55, 0xb5, 0xfc, 0xc3, 0xd4, 0x0d, 0xef, 0x95, 0x50,
-	0x54, 0x89, 0x2a, 0x64, 0xac, 0x10, 0x59, 0x1a, 0xd7, 0x1e, 0xbb, 0x89, 0x94, 0x38, 0x54, 0x89,
-	0x1e, 0xa0, 0x6f, 0x60, 0x2f, 0x8e, 0x01, 0x8d, 0x82, 0x59, 0x38, 0xe4, 0xd4, 0xf5, 0x47, 0xfc,
-	0x83, 0x92, 0x86, 0x2a, 0x41, 0xb1, 0xad, 0xa7, 0x4c, 0x96, 0xb4, 0xa0, 0x7d, 0xd8, 0x1c, 0x73,
-	0xf7, 0x66, 0xac, 0xa5, 0xa1, 0x4a, 0xe2, 0x51, 0xfd, 0x6f, 0x79, 0x28, 0xa7, 0x02, 0x83, 0x2a,
-	0x50, 0x24, 0xb8, 0x87, 0xc9, 0x5b, 0xdc, 0x32, 0x3e, 0x41, 0x27, 0xf0, 0xa5, 0x65, 0x37, 0x1d,
-	0x42, 0x70, 0xb3, 0x4f, 0x1d, 0x42, 0x07, 0xf6, 0x1b, 0xdb, 0xf9, 0xc9, 0xa6, 0x97, 0x8d, 0x77,
-	0x5d, 0x6c, 0xf7, 0x69, 0x0b, 0xf7, 0x1b, 0x56, 0xa7, 0x67, 0x64, 0xd0, 0x33, 0x30, 0x17, 0xcc,
-	0xc4, 0xdc, 0xe8, 0x3a, 0x03, 0xbb, 0x6f, 0x6c, 0xa0, 0xcf, 0xe0, 0xb0, 0x6d, 0xd9, 0x8d, 0x0e,
-	0x5d, 0x70, 0x9a, 0x9d, 0xfe, 0x5b, 0x8a, 0x7f, 0xbe, 0xb4, 0xc8, 0x3b, 0x23, 0xbb, 0x8e, 0x70,
-	0xd1, 0xef, 0x34, 0x13, 0x0f, 0x39, 0xf4, 0x14, 0x9e, 0x68, 0x82, 0x9e, 0x42, 0xfb, 0x8e, 0x43,
-	0x7b, 0x8e, 0x63, 0x1b, 0x79, 0xb4, 0x03, 0x55, 0xcb, 0x7e, 0xdb, 0xe8, 0x58, 0x2d, 0x4a, 0x70,
-	0xa3, 0xd3, 0x35, 0x36, 0xd1, 0x2e, 0x6c, 0xaf, 0xf2, 0x0a, 0xd2, 0x45, 0xc2, 0x73, 0x6c, 0xcb,
-	0xb1, 0xe9, 0x5b, 0x4c, 0x7a, 0x96, 0x63, 0x1b, 0x45, 0xb4, 0x0f, 0x68, 0xd9, 0x74, 0xd1, 0x6d,
-	0x34, 0x8d, 0x12, 0x7a, 0x02, 0x3b, 0xcb, 0xf8, 0x1b, 0xfc, 0xce, 0x00, 0x64, 0xc2, 0x9e, 0xde,
-	0x18, 0x7d, 0x85, 0x3b, 0xce, 0x4f, 0xb4, 0x6b, 0xd9, 0x56, 0x77, 0xd0, 0x35, 0xca, 0x68, 0x0f,
-	0x8c, 0x36, 0xc6, 0xd4, 0xb2, 0x7b, 0x83, 0x76, 0xdb, 0x6a, 0x5a, 0xd8, 0xee, 0x1b, 0x15, 0xbd,
-	0xf2, 0xba, 0x83, 0x57, 0xe5, 0x84, 0xe6, 0x45, 0xc3, 0xb6, 0x71, 0x87, 0xb6, 0xac, 0x5e, 0xe3,
-	0x55, 0x07, 0xb7, 0x8c, 0x2d, 0x74, 0x04, 0x4f, 0xfb, 0xb8, 0x7b, 0xe9, 0x90, 0x06, 0x79, 0x47,
-	0x13, 0x7b, 0xbb, 0x61, 0x75, 0x06, 0x04, 0x1b, 0xdb, 0xe8, 0x73, 0x38, 0x22, 0xf8, 0xc7, 0x81,
-	0x45, 0x70, 0x8b, 0xda, 0x4e, 0x0b, 0xd3, 0x36, 0x6e, 0xf4, 0x07, 0x04, 0xd3, 0xae, 0xd5, 0xeb,
-	0x59, 0xf6, 0x0f, 0x86, 0x81, 0xbe, 0x84, 0xe3, 0x39, 0x65, 0xee, 0x60, 0x85, 0xb5, 0x23, 0xcf,
-	0x97, 0xa4, 0xd4, 0xc6, 0x3f, 0xf7, 0xe9, 0x25, 0xc6, 0xc4, 0x40, 0xa8, 0x06, 0xfb, 0x8b, 0xe5,
-	0xf5, 0x02, 0xf1, 0xda, 0xbb, 0xd2, 0x76, 0x89, 0x49, 0xb7, 0x61, 0xcb, 0x04, 0x2f, 0xd9, 0xf6,
-	0xe4, 0xb6, 0x17, 0xb6, 0xd5, 0x6d, 0x3f, 0x41, 0x7b, 0xb0, 0x9d, 0xac, 0x96, 0x80, 0xff, 0x2c,
-	0xa0, 0x03, 0x40, 0x03, 0x9b, 0xe0, 0x46, 0x4b, 0x1e, 0x7e, 0x6e, 0xf8, 0x57, 0xe1, 0x75, 0xae,
-	0xb8, 0x61, 0x64, 0xeb, 0x7f, 0xcf, 0x42, 0x75, 0xa9, 0x06, 0xd1, 0x33, 0x28, 0x45, 0xee, 0x8d,
-	0xcf, 0x84, 0x54, 0x09, 0x2d, 0x20, 0x0b, 0x40, 0xbd, 0x83, 0x63, 0xe6, 0xfa, 0x5a, 0xb9, 0xb4,
-	0x72, 0x97, 0x14, 0xa2, 0x74, 0xeb, 0x00, 0x0a, 0xc9, 0x3b, 0x9a, 0x55, 0xf5, 0xba, 0x39, 0xd4,
-	0xef, 0xe7, 0x33, 0x28, 0x49, 0x69, 0x8c, 0x04, 0x9b, 0x4c, 0x55, 0x29, 0x57, 0xc9, 0x02, 0x40,
-	0x5f, 0x40, 0x75, 0xc2, 0xa3, 0x88, 0xdd, 0x70, 0xaa, 0xcb, 0x11, 0x14, 0xa3, 0x12, 0x83, 0x6d,
-	0x55, 0x95, 0x5f, 0x40, 0x22, 0x0f, 0x31, 0x29, 0xaf, 0x49, 0x31, 0xa8, 0x49, 0xab, 0xca, 0x2c,
-	0x58, 0x5c, 0xf5, 0x69, 0x65, 0x16, 0x0c, 0xbd, 0x80, 0x1d, 0x2d, 0x2d, 0xae, 0xef, 0x4e, 0x66,
-	0x13, 0x2d, 0x31, 0x05, 0xb5, 0xe5, 0x6d, 0x25, 0x31, 0x1a, 0x57, 0x4a, 0xf3, 0x14, 0x8a, 0x57,
-	0x2c, 0xe2, 0xf2, 0x51, 0x88, 0x25, 0xa0, 0x20, 0xc7, 0x6d, 0xce, 0xa5, 0x49, 0x3e, 0x15, 0xa1,
-	0x14, 0x37, 0x5d, 0xf9, 0x85, 0x6b, 0xce, 0x89, 0x8c, 0xe3, 0x7c, 0x05, 0xf6, 0x61, 0xb1, 0x42,
-	0x39, 0xb5, 0x82, 0xc6, 0xd5, 0x0a, 0x2f, 0x60, 0x87, 0x7f, 0x10, 0x21, 0xa3, 0xc1, 0x94, 0xbd,
-	0x9f, 0x71, 0x3a, 0x62, 0x82, 0x99, 0x15, 0x15, 0xdc, 0x6d, 0x65, 0x70, 0x14, 0xde, 0x62, 0x82,
-	0xd5, 0x9f, 0x41, 0x8d, 0xf0, 0x88, 0x8b, 0xae, 0x1b, 0x45, 0x6e, 0xe0, 0x37, 0x03, 0x5f, 0x84,
-	0x81, 0x17, 0xbf, 0x2d, 0xf5, 0x23, 0x38, 0x5c, 0x6b, 0xd5, 0x8f, 0x83, 0x9c, 0xfc, 0xe3, 0x8c,
-	0x87, 0xf7, 0xeb, 0x27, 0xdf, 0xc3, 0xe1, 0x5a, 0x6b, 0xfc, 0xb2, 0x7c, 0x0d, 0x79, 0x3f, 0x18,
-	0xf1, 0xc8, 0xcc, 0xa8, 0x6e, 0x65, 0x3f, 0x25, 0xe3, 0x76, 0x30, 0xe2, 0x17, 0x6e, 0x24, 0x82,
-	0xf0, 0x9e, 0x68, 0x92, 0x64, 0x4f, 0x99, 0x1b, 0x46, 0xe6, 0xc6, 0x03, 0xf6, 0x25, 0x73, 0xc3,
-	0x39, 0x5b, 0x91, 0xea, 0x7f, 0xce, 0x40, 0x39, 0xe5, 0x44, 0x0a, 0xea, 0x74, 0x76, 0x95, 0x34,
-	0x32, 0x15, 0x12, 0x8f, 0xd0, 0x73, 0xd8, 0xf2, 0x58, 0x24, 0xa8, 0xd4, 0x60, 0x2a, 0x53, 0x1a,
-	0x3f, 0xbc, 0x2b, 0x28, 0x3a, 0x05, 0x14, 0x88, 0x31, 0x0f, 0x69, 0x34, 0x1b, 0x0e, 0x79, 0x14,
-	0xd1, 0x69, 0x18, 0x5c, 0xa9, 0x3b, 0xb9, 0x41, 0xd6, 0x58, 0x5e, 0xe7, 0x8a, 0x39, 0x23, 0x5f,
-	0xff, 0x77, 0x06, 0xca, 0xa9, 0xcd, 0xc9, 0x5b, 0x2b, 0x0f, 0x43, 0xaf, 0xc3, 0x60, 0x92, 0xd4,
-	0xc2, 0x1c, 0x40, 0x26, 0x14, 0xd4, 0x40, 0x04, 0x71, 0x21, 0x24, 0xc3, 0xe5, 0xdb, 0x9e, 0x55,
-	0x1b, 0x4c, 0xdd, 0xf6, 0x73, 0xd8, 0x9b, 0xb8, 0x3e, 0x9d, 0x72, 0x9f, 0x79, 0xee, 0x1f, 0x39,
-	0x4d, 0x3a, 0x94, 0x9c, 0x22, 0xae, 0xb5, 0xa1, 0x3a, 0x54, 0x96, 0x4e, 0x92, 0x57, 0x27, 0x59,
-	0xc2, 0xd0, 0x4b, 0x38, 0x50, 0x51, 0x60, 0x42, 0xf0, 0xc9, 0x54, 0x24, 0x07, 0xbc, 0x9e, 0x79,
-	0xaa, 0x06, 0x8a, 0xe4, 0x31, 0xf3, 0x8b, 0xbf, 0x66, 0xa0, 0x92, 0xee, 0xd2, 0x50, 0x15, 0x4a,
-	0x96, 0x4d, 0xdb, 0x1d, 0xeb, 0x87, 0x8b, 0xbe, 0xf1, 0x89, 0x1c, 0xf6, 0x06, 0xcd, 0x26, 0xc6,
-	0x2d, 0xdc, 0x32, 0x32, 0x08, 0xc1, 0x96, 0x14, 0x12, 0xdc, 0xa2, 0x7d, 0xab, 0x8b, 0x9d, 0x81,
-	0x7c, 0x83, 0x76, 0x61, 0x3b, 0xc6, 0x6c, 0x87, 0x12, 0x67, 0xd0, 0xc7, 0x46, 0x16, 0x19, 0x50,
-	0x89, 0x41, 0x4c, 0x88, 0x43, 0x8c, 0x9c, 0x14, 0xce, 0x18, 0x79, 0xf8, 0x9e, 0x25, 0xcf, 0x5d,
-	0xfe, 0xfc, 0x2f, 0x39, 0xd8, 0x54, 0x5d, 0x4d, 0x88, 0x2e, 0xa0, 0x9c, 0x6a, 0x85, 0xd1, 0xd1,
-	0x47, 0x5b, 0xe4, 0x9a, 0xb9, 0xbe, 0xed, 0x9c, 0x45, 0xdf, 0x64, 0xd0, 0x6b, 0xa8, 0xa4, 0x9b,
-	0x5d, 0x94, 0x6e, 0x62, 0xd6, 0x74, 0xc1, 0x1f, 0xf5, 0xf5, 0x06, 0x0c, 0x1c, 0x09, 0x77, 0x22,
-	0x9b, 0x96, 0xb8, 0x8d, 0x44, 0xb5, 0x14, 0x7f, 0xa5, 0x37, 0xad, 0x1d, 0xae, 0xb5, 0xc5, 0x75,
-	0xd5, 0xd1, 0x47, 0x8c, 0x1b, 0xb9, 0x07, 0x47, 0x5c, 0xee, 0x1e, 0x6b, 0x9f, 0x3e, 0x66, 0x8e,
-	0xbd, 0x8d, 0x60, 0x77, 0x8d, 0x02, 0xa0, 0x5f, 0xa4, 0x77, 0xf0, 0xa8, 0x7e, 0xd4, 0x9e, 0xff,
-	0x2f, 0xda, 0x62, 0x95, 0x35, 0x52, 0xb1, 0xb4, 0xca, 0xe3, 0x42, 0xb3, 0xb4, 0xca, 0x47, 0x14,
-	0xe7, 0xd5, 0xaf, 0x7e, 0x77, 0x76, 0xe3, 0x8a, 0xf1, 0xec, 0xea, 0x74, 0x18, 0x4c, 0xce, 0x3c,
-	0xd9, 0x52, 0xf9, 0xae, 0x7f, 0xe3, 0x73, 0xf1, 0x87, 0x20, 0xbc, 0x3d, 0xf3, 0xfc, 0xd1, 0x99,
-	0x6a, 0x8c, 0xcf, 0xe6, 0xee, 0xae, 0x36, 0xd5, 0x3f, 0xdb, 0x5f, 0xff, 0x37, 0x00, 0x00, 0xff,
-	0xff, 0x3c, 0xe4, 0x5c, 0x67, 0x09, 0x0f, 0x00, 0x00,
+	0x67, 0x9c, 0x43, 0x2e, 0xa9, 0x1c, 0x73, 0xcf, 0xbf, 0xc8, 0xef, 0xc8, 0x1f, 0x49, 0x7e, 0x41,
+	0x8e, 0xa9, 0x4a, 0x49, 0xea, 0x86, 0x06, 0xe3, 0x49, 0x4e, 0xb4, 0xbe, 0xf7, 0xe9, 0x49, 0x7a,
+	0x4f, 0xef, 0xd3, 0x03, 0xf6, 0xc3, 0x60, 0x26, 0x78, 0x18, 0x4e, 0x87, 0x67, 0xfa, 0xeb, 0x74,
+	0x1a, 0x06, 0x22, 0x40, 0xa5, 0x39, 0x5e, 0x2b, 0x85, 0xd3, 0xa1, 0x46, 0xeb, 0xff, 0xc9, 0x02,
+	0xea, 0x71, 0x7f, 0x74, 0xc9, 0xee, 0x27, 0xdc, 0x17, 0x84, 0xbf, 0x9f, 0xf1, 0x48, 0x20, 0x04,
+	0xb9, 0x11, 0x8f, 0x84, 0x99, 0x39, 0xce, 0x9c, 0x54, 0x88, 0xfa, 0x46, 0x06, 0x64, 0xd9, 0x44,
+	0x98, 0x1b, 0xc7, 0x99, 0x93, 0x2c, 0x91, 0x9f, 0xe8, 0x73, 0xa8, 0x4c, 0xf5, 0x3c, 0x3a, 0x66,
+	0xd1, 0xd8, 0xcc, 0x2a, 0x76, 0x39, 0xc6, 0x2e, 0x58, 0x34, 0x46, 0x27, 0x60, 0x5c, 0xbb, 0x3e,
+	0xf3, 0xe8, 0xd0, 0x13, 0x77, 0x74, 0xc4, 0x3d, 0xc1, 0xcc, 0xdc, 0x71, 0xe6, 0x24, 0x4f, 0xb6,
+	0x14, 0xde, 0xf4, 0xc4, 0x5d, 0x4b, 0xa2, 0xe8, 0x2b, 0xd8, 0x4e, 0x9c, 0x85, 0x7a, 0x17, 0x66,
+	0xfe, 0x38, 0x73, 0x52, 0x22, 0x5b, 0xd3, 0xe5, 0xbd, 0x7d, 0x05, 0xdb, 0xc2, 0x9d, 0xf0, 0x60,
+	0x26, 0x68, 0xc4, 0x87, 0x81, 0x3f, 0x8a, 0xcc, 0x4d, 0xed, 0x31, 0x86, 0x7b, 0x1a, 0x45, 0x75,
+	0xa8, 0x5e, 0x73, 0x4e, 0x3d, 0x77, 0xe2, 0x0a, 0x1a, 0x31, 0x61, 0x16, 0xd4, 0xd6, 0xcb, 0xd7,
+	0x9c, 0x77, 0x24, 0xd6, 0x63, 0x42, 0xee, 0x2f, 0x98, 0x89, 0x9b, 0xc0, 0xf5, 0x6f, 0xe8, 0x70,
+	0xcc, 0x7c, 0xea, 0x8e, 0xcc, 0xe2, 0x71, 0xe6, 0x24, 0x47, 0xb6, 0x12, 0xbc, 0x39, 0x66, 0xbe,
+	0x35, 0x42, 0x47, 0x00, 0xea, 0x0c, 0xca, 0x9d, 0x59, 0x52, 0x2b, 0x96, 0x24, 0xa2, 0x7c, 0xa1,
+	0x73, 0x28, 0xab, 0x00, 0xd3, 0xb1, 0xeb, 0x8b, 0xc8, 0x84, 0xe3, 0xec, 0x49, 0xf9, 0xdc, 0x38,
+	0xf5, 0x7c, 0x19, 0x6b, 0x22, 0x2d, 0x17, 0xae, 0x2f, 0x48, 0x9a, 0x84, 0x30, 0x14, 0x65, 0x64,
+	0xa9, 0xf0, 0xee, 0xcc, 0xb2, 0x9a, 0xf0, 0xe2, 0x74, 0x9e, 0xa5, 0xd3, 0x87, 0x69, 0x39, 0x6d,
+	0xf1, 0x48, 0xf4, 0xbd, 0x3b, 0xec, 0x8b, 0xf0, 0x9e, 0x14, 0x46, 0x7a, 0x54, 0xfb, 0x1e, 0x2a,
+	0x69, 0x83, 0x4c, 0xd4, 0x2d, 0xbf, 0x57, 0xb9, 0xcb, 0x11, 0xf9, 0x89, 0xf6, 0x20, 0x7f, 0xc7,
+	0xbc, 0x19, 0x57, 0xc9, 0xab, 0x10, 0x3d, 0xf8, 0x7e, 0xe3, 0x65, 0xa6, 0xfe, 0x12, 0x76, 0xfb,
+	0x21, 0x1b, 0xde, 0xae, 0xe4, 0x7f, 0x35, 0xb3, 0x99, 0x07, 0x99, 0xad, 0xff, 0x09, 0xaa, 0xf1,
+	0xa4, 0x9e, 0x60, 0x62, 0x16, 0xa1, 0x5f, 0x42, 0x3e, 0x12, 0x4c, 0x70, 0x45, 0xde, 0x3a, 0x3f,
+	0x48, 0x1d, 0x25, 0x45, 0xe4, 0x44, 0xb3, 0x50, 0x0d, 0x8a, 0xd3, 0x90, 0xbb, 0x13, 0x76, 0x93,
+	0x6c, 0x6b, 0x3e, 0x46, 0x75, 0xc8, 0xab, 0xc9, 0xea, 0x46, 0x95, 0xcf, 0x2b, 0xe9, 0x30, 0x12,
+	0x6d, 0xaa, 0xff, 0x06, 0xb6, 0xd5, 0xb8, 0xcd, 0xf9, 0xc7, 0x6e, 0xed, 0x01, 0x14, 0xd8, 0x44,
+	0xa7, 0x5f, 0xdf, 0xdc, 0x4d, 0x36, 0x91, 0x99, 0xaf, 0x8f, 0xc0, 0x58, 0xcc, 0x8f, 0xa6, 0x81,
+	0x1f, 0x71, 0x79, 0x1b, 0xa4, 0x73, 0x79, 0x19, 0xe4, 0xcd, 0x99, 0xc8, 0x59, 0x19, 0x35, 0x6b,
+	0x2b, 0xc6, 0xdb, 0x9c, 0x77, 0x23, 0x26, 0xd0, 0x73, 0x7d, 0x09, 0xa9, 0x17, 0x0c, 0x6f, 0xe5,
+	0xb5, 0x66, 0xf7, 0xb1, 0xfb, 0xaa, 0x84, 0x3b, 0xc1, 0xf0, 0xb6, 0x25, 0xc1, 0xfa, 0xef, 0x75,
+	0x79, 0xf5, 0x03, 0xbd, 0xf7, 0xff, 0x3b, 0xbc, 0x8b, 0x10, 0x6c, 0x3c, 0x1e, 0x02, 0x0a, 0xbb,
+	0x4b, 0xce, 0xe3, 0x53, 0xa4, 0x23, 0x9b, 0x59, 0x89, 0xec, 0xd7, 0x50, 0xb8, 0x66, 0xae, 0x37,
+	0x0b, 0x13, 0xc7, 0x28, 0x95, 0xa6, 0xb6, 0xb6, 0x90, 0x84, 0x52, 0xff, 0x47, 0x01, 0x0a, 0x31,
+	0x88, 0xce, 0x21, 0x37, 0x0c, 0x46, 0x49, 0x76, 0x3f, 0x7d, 0x38, 0x2d, 0xf9, 0x6d, 0x06, 0x23,
+	0x4e, 0x14, 0x17, 0xfd, 0x16, 0xb6, 0x64, 0x51, 0xf9, 0xdc, 0xa3, 0xb3, 0xe9, 0x88, 0xcd, 0x13,
+	0x6a, 0xa6, 0x66, 0x37, 0x35, 0x61, 0xa0, 0xec, 0xa4, 0x3a, 0x4c, 0x0f, 0xd1, 0x21, 0x94, 0xc6,
+	0xc2, 0x1b, 0xea, 0x4c, 0xe4, 0xd4, 0x85, 0x2e, 0x4a, 0x40, 0xe5, 0xa0, 0x0e, 0xd5, 0xc0, 0x77,
+	0x03, 0x9f, 0x46, 0x63, 0x46, 0xcf, 0xbf, 0xfd, 0x4e, 0xe9, 0x45, 0x85, 0x94, 0x15, 0xd8, 0x1b,
+	0xb3, 0xf3, 0x6f, 0xbf, 0x43, 0x9f, 0x41, 0x59, 0x55, 0x2d, 0xff, 0x30, 0x75, 0xc3, 0x7b, 0x25,
+	0x14, 0x55, 0xa2, 0x0a, 0x19, 0x2b, 0x44, 0x96, 0xc6, 0xb5, 0xc7, 0x6e, 0x22, 0x25, 0x0e, 0x55,
+	0xa2, 0x07, 0xe8, 0x1b, 0xd8, 0x8b, 0x63, 0x40, 0xa3, 0x60, 0x16, 0x0e, 0x39, 0x75, 0xfd, 0x11,
+	0xff, 0xa0, 0xa4, 0xa1, 0x4a, 0x50, 0x6c, 0xeb, 0x29, 0x93, 0x25, 0x2d, 0xf5, 0xbf, 0xe5, 0xa1,
+	0x9c, 0x0a, 0x00, 0xaa, 0x40, 0x91, 0xe0, 0x1e, 0x26, 0x6f, 0x71, 0xcb, 0xf8, 0x04, 0x9d, 0xc0,
+	0x97, 0x96, 0xdd, 0x74, 0x08, 0xc1, 0xcd, 0x3e, 0x75, 0x08, 0x1d, 0xd8, 0x6f, 0x6c, 0xe7, 0x27,
+	0x9b, 0x5e, 0x36, 0xde, 0x75, 0xb1, 0xdd, 0xa7, 0x2d, 0xdc, 0x6f, 0x58, 0x9d, 0x9e, 0x91, 0x41,
+	0xcf, 0xc0, 0x5c, 0x30, 0x13, 0x73, 0xa3, 0xeb, 0x0c, 0xec, 0xbe, 0xb1, 0x81, 0x3e, 0x83, 0xc3,
+	0xb6, 0x65, 0x37, 0x3a, 0x74, 0xc1, 0x69, 0x76, 0xfa, 0x6f, 0x29, 0xfe, 0xf9, 0xd2, 0x22, 0xef,
+	0x8c, 0xec, 0x3a, 0xc2, 0x45, 0xbf, 0xd3, 0x4c, 0x3c, 0xe4, 0xd0, 0x53, 0x78, 0xa2, 0x09, 0x7a,
+	0x0a, 0xed, 0x3b, 0x0e, 0xed, 0x39, 0x8e, 0x6d, 0xe4, 0xd1, 0x0e, 0x54, 0x2d, 0xfb, 0x6d, 0xa3,
+	0x63, 0xb5, 0x28, 0xc1, 0x8d, 0x4e, 0xd7, 0xd8, 0x44, 0xbb, 0xb0, 0xbd, 0xca, 0x2b, 0x48, 0x17,
+	0x09, 0xcf, 0xb1, 0x2d, 0xc7, 0xa6, 0x6f, 0x31, 0xe9, 0x59, 0x8e, 0x6d, 0x14, 0xd1, 0x3e, 0xa0,
+	0x65, 0xd3, 0x45, 0xb7, 0xd1, 0x34, 0x4a, 0xe8, 0x09, 0xec, 0x2c, 0xe3, 0x6f, 0xf0, 0x3b, 0x03,
+	0x90, 0x09, 0x7b, 0x7a, 0x63, 0xf4, 0x15, 0xee, 0x38, 0x3f, 0xd1, 0xae, 0x65, 0x5b, 0xdd, 0x41,
+	0xd7, 0x28, 0xa3, 0x3d, 0x30, 0xda, 0x18, 0x53, 0xcb, 0xee, 0x0d, 0xda, 0x6d, 0xab, 0x69, 0x61,
+	0xbb, 0x6f, 0x54, 0xf4, 0xca, 0xeb, 0x0e, 0x5e, 0x95, 0x13, 0x9a, 0x17, 0x0d, 0xdb, 0xc6, 0x1d,
+	0xda, 0xb2, 0x7a, 0x8d, 0x57, 0x1d, 0xdc, 0x32, 0xb6, 0xd0, 0x11, 0x3c, 0xed, 0xe3, 0xee, 0xa5,
+	0x43, 0x1a, 0xe4, 0x1d, 0x4d, 0xec, 0xed, 0x86, 0xd5, 0x19, 0x10, 0x6c, 0x6c, 0xa3, 0xcf, 0xe1,
+	0x88, 0xe0, 0x1f, 0x07, 0x16, 0xc1, 0x2d, 0x6a, 0x3b, 0x2d, 0x4c, 0xdb, 0xb8, 0xd1, 0x1f, 0x10,
+	0x4c, 0xbb, 0x56, 0xaf, 0x67, 0xd9, 0x3f, 0x18, 0x06, 0xfa, 0x12, 0x8e, 0xe7, 0x94, 0xb9, 0x83,
+	0x15, 0xd6, 0x8e, 0x3c, 0x5f, 0x92, 0x52, 0x1b, 0xff, 0xdc, 0xa7, 0x97, 0x18, 0x13, 0x03, 0xa1,
+	0x1a, 0xec, 0x2f, 0x96, 0xd7, 0x0b, 0xc4, 0x6b, 0xef, 0x4a, 0xdb, 0x25, 0x26, 0xdd, 0x86, 0x2d,
+	0x13, 0xbc, 0x64, 0xdb, 0x93, 0xdb, 0x5e, 0xd8, 0x56, 0xb7, 0xfd, 0x04, 0xed, 0xc1, 0x76, 0xb2,
+	0x5a, 0x02, 0xfe, 0xb3, 0x80, 0x0e, 0x00, 0x0d, 0x6c, 0x82, 0x1b, 0x2d, 0x79, 0xf8, 0xb9, 0xe1,
+	0x5f, 0x85, 0xd7, 0xb9, 0xe2, 0x86, 0x91, 0xad, 0xff, 0x3d, 0x0b, 0xd5, 0xa5, 0x5a, 0x43, 0xcf,
+	0xa0, 0x14, 0xb9, 0x37, 0x3e, 0x13, 0x52, 0x0d, 0xb4, 0x50, 0x2c, 0x00, 0xf5, 0xde, 0x8d, 0x99,
+	0xeb, 0x6b, 0x85, 0xd2, 0x0a, 0x5d, 0x52, 0x88, 0xd2, 0xa7, 0x03, 0x28, 0x24, 0xef, 0x65, 0x56,
+	0xd5, 0xe5, 0xe6, 0x50, 0xbf, 0x93, 0xcf, 0xa0, 0x24, 0x25, 0x30, 0x12, 0x6c, 0x32, 0x55, 0x25,
+	0x5b, 0x25, 0x0b, 0x00, 0x7d, 0x01, 0xd5, 0x09, 0x8f, 0x22, 0x76, 0xc3, 0xa9, 0x2e, 0x3b, 0x50,
+	0x8c, 0x4a, 0x0c, 0xb6, 0x55, 0xf5, 0x7d, 0x01, 0x89, 0x0c, 0xc4, 0xa4, 0xbc, 0x26, 0xc5, 0xa0,
+	0x26, 0xad, 0x2a, 0xb0, 0x60, 0x71, 0x75, 0xa7, 0x15, 0x58, 0x30, 0xf4, 0x02, 0x76, 0xb4, 0x84,
+	0xb8, 0xbe, 0x3b, 0x99, 0x4d, 0xb4, 0x94, 0x14, 0xd4, 0x96, 0xb7, 0x95, 0x94, 0x68, 0x5c, 0x29,
+	0xca, 0x53, 0x28, 0x5e, 0xb1, 0x88, 0x4b, 0xf1, 0x8f, 0x4b, 0xbd, 0x20, 0xc7, 0x6d, 0xce, 0xa5,
+	0x49, 0x3e, 0x09, 0xa1, 0x14, 0xb1, 0x92, 0x36, 0x5d, 0x73, 0x4e, 0x64, 0x1c, 0xe7, 0x2b, 0xb0,
+	0x0f, 0x8b, 0x15, 0xca, 0xa9, 0x15, 0x34, 0xae, 0x56, 0x78, 0x01, 0x3b, 0xfc, 0x83, 0x08, 0x19,
+	0x0d, 0xa6, 0xec, 0xfd, 0x8c, 0xd3, 0x11, 0x13, 0xcc, 0xac, 0xa8, 0xe0, 0x6e, 0x2b, 0x83, 0xa3,
+	0xf0, 0x16, 0x13, 0xac, 0xfe, 0x0c, 0x6a, 0x84, 0x47, 0x5c, 0x74, 0xdd, 0x28, 0x72, 0x03, 0xbf,
+	0x19, 0xf8, 0x22, 0x0c, 0xbc, 0xf8, 0x0d, 0xa9, 0x1f, 0xc1, 0xe1, 0x5a, 0xab, 0x7e, 0x04, 0xe4,
+	0xe4, 0x1f, 0x67, 0x3c, 0xbc, 0x5f, 0x3f, 0xf9, 0x1e, 0x0e, 0xd7, 0x5a, 0xe3, 0x17, 0xe4, 0x6b,
+	0xc8, 0xfb, 0xc1, 0x88, 0x47, 0x66, 0x46, 0x75, 0x25, 0xfb, 0x29, 0xb9, 0xb6, 0x83, 0x11, 0xbf,
+	0x70, 0x23, 0x11, 0x84, 0xf7, 0x44, 0x93, 0x24, 0x7b, 0xca, 0xdc, 0x30, 0x32, 0x37, 0x1e, 0xb0,
+	0x2f, 0x99, 0x1b, 0xce, 0xd9, 0x8a, 0x54, 0xff, 0x73, 0x06, 0xca, 0x29, 0x27, 0x68, 0x1f, 0x36,
+	0xa7, 0xb3, 0xab, 0xa4, 0x61, 0xa9, 0x90, 0x78, 0x84, 0x9e, 0xc3, 0x96, 0xc7, 0x22, 0x41, 0xa5,
+	0xd6, 0x52, 0x99, 0xd2, 0xf8, 0x81, 0x5d, 0x41, 0xd1, 0x29, 0xa0, 0x40, 0x8c, 0x79, 0x48, 0xa3,
+	0xd9, 0x70, 0xc8, 0xa3, 0x88, 0x4e, 0xc3, 0xe0, 0x4a, 0xdd, 0xc9, 0x0d, 0xb2, 0xc6, 0xf2, 0x3a,
+	0x57, 0xcc, 0x19, 0xf9, 0xfa, 0xbf, 0x33, 0x50, 0x4e, 0x6d, 0x4e, 0xde, 0x5a, 0x79, 0x18, 0x7a,
+	0x1d, 0x06, 0x93, 0xa4, 0x16, 0xe6, 0x00, 0x32, 0xa1, 0xa0, 0x06, 0x22, 0x88, 0x0b, 0x21, 0x19,
+	0x2e, 0xdf, 0xf6, 0xac, 0xda, 0x60, 0xea, 0xb6, 0x9f, 0xc3, 0xde, 0xc4, 0xf5, 0xe9, 0x94, 0xfb,
+	0xcc, 0x73, 0xff, 0xc8, 0x69, 0xd2, 0x89, 0xe4, 0x14, 0x71, 0xad, 0x0d, 0xd5, 0xa1, 0xb2, 0x74,
+	0x92, 0xbc, 0x3a, 0xc9, 0x12, 0x86, 0x5e, 0xc2, 0x81, 0x8a, 0x02, 0x13, 0x82, 0x4f, 0xa6, 0x22,
+	0x39, 0xe0, 0xf5, 0xcc, 0x53, 0x35, 0x50, 0x24, 0x8f, 0x99, 0x5f, 0xfc, 0x35, 0x03, 0x95, 0x74,
+	0x37, 0x86, 0xaa, 0x50, 0xb2, 0x6c, 0xda, 0xee, 0x58, 0x3f, 0x5c, 0xf4, 0x8d, 0x4f, 0xe4, 0xb0,
+	0x37, 0x68, 0x36, 0x31, 0x6e, 0xe1, 0x96, 0x91, 0x41, 0x08, 0xb6, 0xa4, 0x90, 0xe0, 0x16, 0xed,
+	0x5b, 0x5d, 0xec, 0x0c, 0xe4, 0x1b, 0xb4, 0x0b, 0xdb, 0x31, 0x66, 0x3b, 0x94, 0x38, 0x83, 0x3e,
+	0x36, 0xb2, 0xc8, 0x80, 0x4a, 0x0c, 0x62, 0x42, 0x1c, 0x62, 0xe4, 0xa4, 0x70, 0xc6, 0xc8, 0xc3,
+	0xf7, 0x2c, 0x79, 0xee, 0xf2, 0xe7, 0x7f, 0xc9, 0xc1, 0xa6, 0xea, 0x5e, 0x42, 0x74, 0x01, 0xe5,
+	0x54, 0xcb, 0x8b, 0x8e, 0x3e, 0xda, 0x0a, 0xd7, 0xcc, 0xf5, 0xed, 0xe5, 0x2c, 0xfa, 0x26, 0x83,
+	0x5e, 0x43, 0x25, 0xdd, 0xd4, 0xa2, 0x74, 0xb3, 0xb2, 0xa6, 0xdb, 0xfd, 0xa8, 0xaf, 0x37, 0x60,
+	0xe0, 0x48, 0xb8, 0x13, 0xd9, 0x9c, 0xc4, 0xed, 0x22, 0xaa, 0xa5, 0xf8, 0x2b, 0x3d, 0x68, 0xed,
+	0x70, 0xad, 0x2d, 0xae, 0xab, 0x8e, 0x3e, 0x62, 0xdc, 0xb0, 0x3d, 0x38, 0xe2, 0x72, 0x97, 0x58,
+	0xfb, 0xf4, 0x31, 0x73, 0xec, 0x6d, 0x04, 0xbb, 0x6b, 0x14, 0x00, 0xfd, 0x22, 0xbd, 0x83, 0x47,
+	0xf5, 0xa3, 0xf6, 0xfc, 0x7f, 0xd1, 0x16, 0xab, 0xac, 0x91, 0x8a, 0xa5, 0x55, 0x1e, 0x17, 0x9a,
+	0xa5, 0x55, 0x3e, 0xa2, 0x38, 0xaf, 0x7e, 0xf5, 0xbb, 0xb3, 0x1b, 0x57, 0x8c, 0x67, 0x57, 0xa7,
+	0xc3, 0x60, 0x72, 0xe6, 0xb9, 0x37, 0x63, 0xe1, 0xbb, 0xfe, 0x8d, 0xcf, 0xc5, 0x1f, 0x82, 0xf0,
+	0xf6, 0xcc, 0xf3, 0x47, 0x67, 0xaa, 0x01, 0x3e, 0x9b, 0xbb, 0xbb, 0xda, 0x54, 0xff, 0x60, 0x7f,
+	0xfd, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd5, 0x11, 0xe6, 0x51, 0xf1, 0x0e, 0x00, 0x00,
 }
 
 // Reference imports to suppress errors if they are not otherwise used.
diff --git a/lnrpc/routerrpc/router.proto b/lnrpc/routerrpc/router.proto
index 7299a02b7..d09b6867b 100644
--- a/lnrpc/routerrpc/router.proto
+++ b/lnrpc/routerrpc/router.proto
@@ -239,9 +239,6 @@ message Failure {
     the failure message. Position zero is the sender node.
     **/
     uint32 failure_source_index = 8;
-
-    /// A failure type-dependent block height.
-    uint32 height = 9;
 }
 
 
diff --git a/lnrpc/routerrpc/router_server.go b/lnrpc/routerrpc/router_server.go
index cea63be98..f2fe0c686 100644
--- a/lnrpc/routerrpc/router_server.go
+++ b/lnrpc/routerrpc/router_server.go
@@ -324,7 +324,6 @@ func marshallError(sendError error) (*Failure, error) {
 
 	case *lnwire.FailIncorrectDetails:
 		response.Code = Failure_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS
-		response.Height = onionErr.Height()
 
 	case *lnwire.FailIncorrectPaymentAmount:
 		response.Code = Failure_INCORRECT_PAYMENT_AMOUNT
diff --git a/lnrpc/wtclientrpc/config.go b/lnrpc/wtclientrpc/config_active.go
similarity index 97%
rename from lnrpc/wtclientrpc/config.go
rename to lnrpc/wtclientrpc/config_active.go
index a008ca0d3..7a50efefb 100644
--- a/lnrpc/wtclientrpc/config.go
+++ b/lnrpc/wtclientrpc/config_active.go
@@ -1,3 +1,5 @@
+// +build wtclientrpc
+
 package wtclientrpc
 
 import (
diff --git a/lnrpc/wtclientrpc/config_default.go b/lnrpc/wtclientrpc/config_default.go
new file mode 100644
index 000000000..a23813cba
--- /dev/null
+++ b/lnrpc/wtclientrpc/config_default.go
@@ -0,0 +1,6 @@
+// +build !wtclientrpc
+
+package wtclientrpc
+
+// Config is empty for non-wtclientrpc builds.
+type Config struct{}
diff --git a/lnwallet/channel.go b/lnwallet/channel.go
index 99f3e6409..b6e6edfff 100644
--- a/lnwallet/channel.go
+++ b/lnwallet/channel.go
@@ -3279,9 +3279,8 @@ func (lc *LightningChannel) ProcessChanSyncMsg(
 			msg.RemoteCommitTailHeight, localTailHeight)
 
 		if isRestoredChan {
-			walletLog.Warnf("ChannelPoint(%v): detected restored "+
-				"triggering DLP",
-				lc.channelState.FundingOutpoint)
+			walletLog.Warnf("ChannelPoint(%v): detected restored " +
+				"triggering DLP")
 		}
 
 		// We must check that we had recovery options to ensure the
diff --git a/lnwallet/reservation.go b/lnwallet/reservation.go
index 98c88d724..555d0ded7 100644
--- a/lnwallet/reservation.go
+++ b/lnwallet/reservation.go
@@ -288,8 +288,8 @@ func (r *ChannelReservation) CommitConstraints(c *channeldb.ChannelConstraints)
 		return ErrCsvDelayTooLarge(c.CsvDelay, maxDelay)
 	}
 
-	// The channel reserve should always be greater or equal to the dust
-	// limit. The reservation request should be denied if otherwise.
+	// The dust limit should always be greater or equal to the channel
+	// reserve. The reservation request should be denied if otherwise.
 	if c.DustLimit > c.ChanReserve {
 		return ErrChanReserveTooSmall(c.ChanReserve, c.DustLimit)
 	}
diff --git a/lnwire/onion_error.go b/lnwire/onion_error.go
index 43a3d3266..51f3bc581 100644
--- a/lnwire/onion_error.go
+++ b/lnwire/onion_error.go
@@ -333,19 +333,13 @@ func (f *FailIncorrectPaymentAmount) Error() string {
 type FailIncorrectDetails struct {
 	// amount is the value of the extended HTLC.
 	amount MilliSatoshi
-
-	// height is the block height when the htlc was received.
-	height uint32
 }
 
 // NewFailIncorrectDetails makes a new instance of the FailIncorrectDetails
-// error bound to the specified HTLC amount and acceptance height.
-func NewFailIncorrectDetails(amt MilliSatoshi,
-	height uint32) *FailIncorrectDetails {
-
+// error bound to the specified HTLC amount.
+func NewFailIncorrectDetails(amt MilliSatoshi) *FailIncorrectDetails {
 	return &FailIncorrectDetails{
 		amount: amt,
-		height: height,
 	}
 }
 
@@ -354,11 +348,6 @@ func (f *FailIncorrectDetails) Amount() MilliSatoshi {
 	return f.amount
 }
 
-// Height is the block height when the htlc was received.
-func (f *FailIncorrectDetails) Height() uint32 {
-	return f.height
-}
-
 // Code returns the failure unique code.
 //
 // NOTE: Part of the FailureMessage interface.
@@ -371,8 +360,7 @@ func (f *FailIncorrectDetails) Code() FailCode {
 // NOTE: Implements the error interface.
 func (f *FailIncorrectDetails) Error() string {
 	return fmt.Sprintf(
-		"%v(amt=%v, height=%v)", CodeIncorrectOrUnknownPaymentDetails,
-		f.amount, f.height,
+		"%v(amt=%v)", CodeIncorrectOrUnknownPaymentDetails, f.amount,
 	)
 }
 
@@ -393,17 +381,6 @@ func (f *FailIncorrectDetails) Decode(r io.Reader, pver uint32) error {
 		return err
 	}
 
-	// At a later stage, the height field was also tacked on. We need to
-	// check for io.EOF here as well.
-	err = ReadElement(r, &f.height)
-	switch {
-	case err == io.EOF:
-		return nil
-
-	case err != nil:
-		return err
-	}
-
 	return nil
 }
 
@@ -411,7 +388,7 @@ func (f *FailIncorrectDetails) Decode(r io.Reader, pver uint32) error {
 //
 // NOTE: Part of the Serializable interface.
 func (f *FailIncorrectDetails) Encode(w io.Writer, pver uint32) error {
-	return WriteElements(w, f.amount, f.height)
+	return WriteElement(w, f.amount)
 }
 
 // FailFinalExpiryTooSoon is returned if the cltv_expiry is too low, the final
diff --git a/server.go b/server.go
index a002aab93..c47be8322 100644
--- a/server.go
+++ b/server.go
@@ -710,20 +710,16 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB,
 	}
 
 	s.authGossiper = discovery.New(discovery.Config{
-		Router:            s.chanRouter,
-		Notifier:          s.cc.chainNotifier,
-		ChainHash:         *activeNetParams.GenesisHash,
-		Broadcast:         s.BroadcastMessage,
-		ChanSeries:        chanSeries,
-		NotifyWhenOnline:  s.NotifyWhenOnline,
-		NotifyWhenOffline: s.NotifyWhenOffline,
-		SelfNodeAnnouncement: func(refresh bool) (lnwire.NodeAnnouncement, error) {
-			return s.genNodeAnnouncement(refresh)
-		},
+		Router:                  s.chanRouter,
+		Notifier:                s.cc.chainNotifier,
+		ChainHash:               *activeNetParams.GenesisHash,
+		Broadcast:               s.BroadcastMessage,
+		ChanSeries:              chanSeries,
+		NotifyWhenOnline:        s.NotifyWhenOnline,
+		NotifyWhenOffline:       s.NotifyWhenOffline,
 		ProofMatureDelta:        0,
 		TrickleDelay:            time.Millisecond * time.Duration(cfg.TrickleDelay),
-		RetransmitTicker:        ticker.New(time.Minute * 30),
-		RebroadcastInterval:     time.Hour * 24,
+		RetransmitDelay:         time.Minute * 30,
 		WaitingProofStore:       waitingProofStore,
 		MessageStore:            gossipMessageStore,
 		AnnSigner:               s.nodeSigner,


Test patch:
diff --git a/contractcourt/channel_arbitrator_test.go b/contractcourt/channel_arbitrator_test.go
index b785b02ae..65bfde650 100644
--- a/contractcourt/channel_arbitrator_test.go
+++ b/contractcourt/channel_arbitrator_test.go
@@ -1,7 +1,6 @@
 package contractcourt
 
 import (
-	"errors"
 	"fmt"
 	"sync"
 	"testing"
@@ -355,7 +354,7 @@ func TestChannelArbitratorRemoteForceClose(t *testing.T) {
 		t, log.newStates, StateContractClosed, StateFullyResolved,
 	)
 
-	// It should also mark the channel as resolved.
+	// It should alos mark the channel as resolved.
 	select {
 	case <-resolved:
 		// Expected.
@@ -470,49 +469,6 @@ func TestChannelArbitratorLocalForceClose(t *testing.T) {
 	}
 }
 
-// TestChannelArbitratorBreachClose tests that the ChannelArbitrator goes
-// through the expected states in case we notice a breach in the chain, and
-// gracefully exits.
-func TestChannelArbitratorBreachClose(t *testing.T) {
-	log := &mockArbitratorLog{
-		state:     StateDefault,
-		newStates: make(chan ArbitratorState, 5),
-	}
-
-	chanArb, resolved, _, _, err := createTestChannelArbitrator(log)
-	if err != nil {
-		t.Fatalf("unable to create ChannelArbitrator: %v", err)
-	}
-
-	if err := chanArb.Start(); err != nil {
-		t.Fatalf("unable to start ChannelArbitrator: %v", err)
-	}
-	defer func() {
-		if err := chanArb.Stop(); err != nil {
-			t.Fatal(err)
-		}
-	}()
-
-	// It should start out in the default state.
-	assertState(t, chanArb, StateDefault)
-
-	// Send a breach close event.
-	chanArb.cfg.ChainEvents.ContractBreach <- &lnwallet.BreachRetribution{}
-
-	// It should transition StateDefault -> StateFullyResolved.
-	assertStateTransitions(
-		t, log.newStates, StateFullyResolved,
-	)
-
-	// It should also mark the channel as resolved.
-	select {
-	case <-resolved:
-		// Expected.
-	case <-time.After(5 * time.Second):
-		t.Fatalf("contract was not resolved")
-	}
-}
-
 // TestChannelArbitratorLocalForceClosePendingHtlc tests that the
 // ChannelArbitrator goes through the expected states in case we request it to
 // force close a channel that still has an HTLC pending.
@@ -540,8 +496,6 @@ func TestChannelArbitratorLocalForceClosePendingHtlc(t *testing.T) {
 
 		return nil
 	}
-	chanArb.cfg.PreimageDB = newMockWitnessBeacon()
-	chanArb.cfg.Registry = &mockRegistry{}
 
 	if err := chanArb.Start(); err != nil {
 		t.Fatalf("unable to start ChannelArbitrator: %v", err)
@@ -558,33 +512,16 @@ func TestChannelArbitratorLocalForceClosePendingHtlc(t *testing.T) {
 	chanArb.UpdateContractSignals(signals)
 
 	// Add HTLC to channel arbitrator.
+	htlcIndex := uint64(99)
 	htlc := channeldb.HTLC{
 		Incoming:  false,
 		Amt:       10000,
-		HtlcIndex: 99,
-	}
-
-	outgoingDustHtlc := channeldb.HTLC{
-		Incoming:    false,
-		Amt:         100,
-		HtlcIndex:   100,
-		OutputIndex: -1,
-	}
-
-	incomingDustHtlc := channeldb.HTLC{
-		Incoming:    true,
-		Amt:         105,
-		HtlcIndex:   101,
-		OutputIndex: -1,
-	}
-
-	htlcSet := []channeldb.HTLC{
-		htlc, outgoingDustHtlc, incomingDustHtlc,
+		HtlcIndex: htlcIndex,
 	}
 
 	htlcUpdates <- &ContractUpdate{
 		HtlcKey: LocalHtlcSet,
-		Htlcs:   htlcSet,
+		Htlcs:   []channeldb.HTLC{htlc},
 	}
 
 	errChan := make(chan error, 1)
@@ -670,7 +607,7 @@ func TestChannelArbitratorLocalForceClosePendingHtlc(t *testing.T) {
 		CommitSet: CommitSet{
 			ConfCommitKey: &LocalHtlcSet,
 			HtlcSets: map[HtlcSetKey][]channeldb.HTLC{
-				LocalHtlcSet: htlcSet,
+				LocalHtlcSet: {htlc},
 			},
 		},
 	}
@@ -680,22 +617,6 @@ func TestChannelArbitratorLocalForceClosePendingHtlc(t *testing.T) {
 		StateWaitingFullResolution,
 	)
 
-	// We expect an immediate resolution message for the outgoing dust htlc.
-	// It is not resolvable on-chain.
-	select {
-	case msgs := <-resolutions:
-		if len(msgs) != 1 {
-			t.Fatalf("expected 1 message, instead got %v", len(msgs))
-		}
-
-		if msgs[0].HtlcIndex != outgoingDustHtlc.HtlcIndex {
-			t.Fatalf("wrong htlc index: expected %v, got %v",
-				outgoingDustHtlc.HtlcIndex, msgs[0].HtlcIndex)
-		}
-	case <-time.After(5 * time.Second):
-		t.Fatalf("resolution msgs not sent")
-	}
-
 	// htlcOutgoingContestResolver is now active and waiting for the HTLC to
 	// expire. It should not yet have passed it on for incubation.
 	select {
@@ -728,9 +649,9 @@ func TestChannelArbitratorLocalForceClosePendingHtlc(t *testing.T) {
 			t.Fatalf("expected 1 message, instead got %v", len(msgs))
 		}
 
-		if msgs[0].HtlcIndex != htlc.HtlcIndex {
+		if msgs[0].HtlcIndex != htlcIndex {
 			t.Fatalf("wrong htlc index: expected %v, got %v",
-				htlc.HtlcIndex, msgs[0].HtlcIndex)
+				htlcIndex, msgs[0].HtlcIndex)
 		}
 	case <-time.After(5 * time.Second):
 		t.Fatalf("resolution msgs not sent")
@@ -1108,122 +1029,6 @@ func TestChannelArbitratorPersistence(t *testing.T) {
 	}
 }
 
-// TestChannelArbitratorForceCloseBreachedChannel tests that the channel
-// arbitrator is able to handle a channel in the process of being force closed
-// is breached by the remote node. In these cases we expect the
-// ChannelArbitrator to gracefully exit, as the breach is handled by other
-// subsystems.
-func TestChannelArbitratorForceCloseBreachedChannel(t *testing.T) {
-	log := &mockArbitratorLog{
-		state:     StateDefault,
-		newStates: make(chan ArbitratorState, 5),
-	}
-
-	chanArb, _, _, _, err := createTestChannelArbitrator(log)
-	if err != nil {
-		t.Fatalf("unable to create ChannelArbitrator: %v", err)
-	}
-
-	if err := chanArb.Start(); err != nil {
-		t.Fatalf("unable to start ChannelArbitrator: %v", err)
-	}
-
-	// It should start in StateDefault.
-	assertState(t, chanArb, StateDefault)
-
-	// We start by attempting a local force close. We'll return an
-	// unexpected publication error, causing the state machine to halt.
-	expErr := errors.New("intentional publication error")
-	stateChan := make(chan ArbitratorState)
-	chanArb.cfg.PublishTx = func(*wire.MsgTx) error {
-		// When the force close tx is being broadcasted, check that the
-		// state is correct at that point.
-		select {
-		case stateChan <- chanArb.state:
-		case <-chanArb.quit:
-			return fmt.Errorf("exiting")
-		}
-		return expErr
-	}
-
-	errChan := make(chan error, 1)
-	respChan := make(chan *wire.MsgTx, 1)
-
-	// With the channel found, and the request crafted, we'll send over a
-	// force close request to the arbitrator that watches this channel.
-	chanArb.forceCloseReqs <- &forceCloseReq{
-		errResp: errChan,
-		closeTx: respChan,
-	}
-
-	// It should transition to StateBroadcastCommit.
-	assertStateTransitions(t, log.newStates, StateBroadcastCommit)
-
-	// We expect it to be in state StateBroadcastCommit when attempting
-	// the force close.
-	select {
-	case state := <-stateChan:
-		if state != StateBroadcastCommit {
-			t.Fatalf("state during PublishTx was %v", state)
-		}
-	case <-time.After(15 * time.Second):
-		t.Fatalf("no state update received")
-	}
-
-	// Make sure we get the expected error.
-	select {
-	case err := <-errChan:
-		if err != expErr {
-			t.Fatalf("unexpected error force closing channel: %v",
-				err)
-		}
-	case <-time.After(5 * time.Second):
-		t.Fatalf("no response received")
-	}
-
-	// Stop the channel abitrator.
-	if err := chanArb.Stop(); err != nil {
-		t.Fatal(err)
-	}
-
-	// We mimic that the channel is breached while the channel arbitrator
-	// is down. This means that on restart it will be started with a
-	// pending close channel, of type BreachClose.
-	chanArb, resolved, _, _, err := createTestChannelArbitrator(log)
-	if err != nil {
-		t.Fatalf("unable to create ChannelArbitrator: %v", err)
-	}
-
-	chanArb.cfg.IsPendingClose = true
-	chanArb.cfg.ClosingHeight = 100
-	chanArb.cfg.CloseType = channeldb.BreachClose
-
-	// Start the channel abitrator again, and make sure it goes straight to
-	// state fully resolved, as in case of breach there is nothing to
-	// handle.
-	if err := chanArb.Start(); err != nil {
-		t.Fatalf("unable to start ChannelArbitrator: %v", err)
-	}
-	defer func() {
-		if err := chanArb.Stop(); err != nil {
-			t.Fatal(err)
-		}
-	}()
-
-	// Finally it should advance to StateFullyResolved.
-	assertStateTransitions(
-		t, log.newStates, StateFullyResolved,
-	)
-
-	// It should also mark the channel as resolved.
-	select {
-	case <-resolved:
-		// Expected.
-	case <-time.After(5 * time.Second):
-		t.Fatalf("contract was not resolved")
-	}
-}
-
 // TestChannelArbitratorCommitFailure tests that the channel arbitrator is able
 // to recover from a failed CommitState call at restart.
 func TestChannelArbitratorCommitFailure(t *testing.T) {
diff --git a/contractcourt/htlc_incoming_resolver_test.go b/contractcourt/htlc_incoming_resolver_test.go
index 43d01817b..5f6234288 100644
--- a/contractcourt/htlc_incoming_resolver_test.go
+++ b/contractcourt/htlc_incoming_resolver_test.go
@@ -18,9 +18,8 @@ const (
 )
 
 var (
-	testResPreimage   = lntypes.Preimage{1, 2, 3}
-	testResHash       = testResPreimage.Hash()
-	testResCircuitKey = channeldb.CircuitKey{}
+	testResPreimage = lntypes.Preimage{1, 2, 3}
+	testResHash     = testResPreimage.Hash()
 )
 
 // TestHtlcIncomingResolverFwdPreimageKnown tests resolution of a forwarded htlc
@@ -93,8 +92,8 @@ func TestHtlcIncomingResolverExitSettle(t *testing.T) {
 
 	ctx := newIncomingResolverTestContext(t)
 	ctx.registry.notifyEvent = &invoices.HodlEvent{
-		CircuitKey: testResCircuitKey,
-		Preimage:   &testResPreimage,
+		Hash:     testResHash,
+		Preimage: &testResPreimage,
 	}
 	ctx.resolve()
 
@@ -117,7 +116,7 @@ func TestHtlcIncomingResolverExitCancel(t *testing.T) {
 
 	ctx := newIncomingResolverTestContext(t)
 	ctx.registry.notifyEvent = &invoices.HodlEvent{
-		CircuitKey: testResCircuitKey,
+		Hash: testResHash,
 	}
 	ctx.resolve()
 	ctx.waitForResult(false)
@@ -134,8 +133,8 @@ func TestHtlcIncomingResolverExitSettleHodl(t *testing.T) {
 
 	notifyData := <-ctx.registry.notifyChan
 	notifyData.hodlChan <- invoices.HodlEvent{
-		CircuitKey: testResCircuitKey,
-		Preimage:   &testResPreimage,
+		Hash:     testResHash,
+		Preimage: &testResPreimage,
 	}
 
 	ctx.waitForResult(true)
@@ -163,7 +162,7 @@ func TestHtlcIncomingResolverExitCancelHodl(t *testing.T) {
 	ctx.resolve()
 	notifyData := <-ctx.registry.notifyChan
 	notifyData.hodlChan <- invoices.HodlEvent{
-		CircuitKey: testResCircuitKey,
+		Hash: testResHash,
 	}
 	ctx.waitForResult(false)
 }
diff --git a/discovery/gossiper_test.go b/discovery/gossiper_test.go
index 5f224d581..2a92c26e9 100644
--- a/discovery/gossiper_test.go
+++ b/discovery/gossiper_test.go
@@ -58,11 +58,6 @@ var (
 	trickleDelay     = time.Millisecond * 100
 	retransmitDelay  = time.Hour * 1
 	proofMatureDelta uint32
-
-	// The test timestamp + rebroadcast interval makes sure messages won't
-	// be rebroadcasted automaticallty during the tests.
-	testTimestamp       = uint32(1234567890)
-	rebroadcastInterval = time.Hour * 1000000
 )
 
 // makeTestDB creates a new instance of the ChannelDB for testing purposes. A
@@ -168,6 +163,10 @@ func (r *mockGraphSource) UpdateEdge(edge *channeldb.ChannelEdgePolicy) error {
 	return nil
 }
 
+func (r *mockGraphSource) SelfEdges() ([]*channeldb.ChannelEdgePolicy, error) {
+	return nil, nil
+}
+
 func (r *mockGraphSource) CurrentBlockHeight() (uint32, error) {
 	return r.bestHeight, nil
 }
@@ -472,7 +471,7 @@ type annBatch struct {
 func createAnnouncements(blockHeight uint32) (*annBatch, error) {
 	var err error
 	var batch annBatch
-	timestamp := testTimestamp
+	timestamp := uint32(123456)
 
 	batch.nodeAnn1, err = createNodeAnnouncement(nodeKeyPriv1, timestamp)
 	if err != nil {
@@ -740,15 +739,9 @@ func createTestCtx(startHeight uint32) (*testCtx, func(), error) {
 			c := make(chan struct{})
 			return c
 		},
-		SelfNodeAnnouncement: func(bool) (lnwire.NodeAnnouncement, error) {
-			return lnwire.NodeAnnouncement{
-				Timestamp: testTimestamp,
-			}, nil
-		},
 		Router:               router,
 		TrickleDelay:         trickleDelay,
-		RetransmitTicker:     ticker.NewForce(retransmitDelay),
-		RebroadcastInterval:  rebroadcastInterval,
+		RetransmitDelay:      retransmitDelay,
 		ProofMatureDelta:     proofMatureDelta,
 		WaitingProofStore:    waitingProofStore,
 		MessageStore:         newMockMessageStore(),
@@ -787,7 +780,8 @@ func createTestCtx(startHeight uint32) (*testCtx, func(), error) {
 func TestProcessAnnouncement(t *testing.T) {
 	t.Parallel()
 
-	timestamp := testTimestamp
+	timestamp := uint32(123456)
+
 	ctx, cleanup, err := createTestCtx(0)
 	if err != nil {
 		t.Fatalf("can't create context: %v", err)
@@ -895,7 +889,7 @@ func TestProcessAnnouncement(t *testing.T) {
 func TestPrematureAnnouncement(t *testing.T) {
 	t.Parallel()
 
-	timestamp := testTimestamp
+	timestamp := uint32(123456)
 
 	ctx, cleanup, err := createTestCtx(0)
 	if err != nil {
@@ -1497,11 +1491,9 @@ func TestSignatureAnnouncementRetryAtStartup(t *testing.T) {
 		Broadcast:            ctx.gossiper.cfg.Broadcast,
 		NotifyWhenOnline:     ctx.gossiper.reliableSender.cfg.NotifyWhenOnline,
 		NotifyWhenOffline:    ctx.gossiper.reliableSender.cfg.NotifyWhenOffline,
-		SelfNodeAnnouncement: ctx.gossiper.cfg.SelfNodeAnnouncement,
 		Router:               ctx.gossiper.cfg.Router,
 		TrickleDelay:         trickleDelay,
-		RetransmitTicker:     ticker.NewForce(retransmitDelay),
-		RebroadcastInterval:  rebroadcastInterval,
+		RetransmitDelay:      retransmitDelay,
 		ProofMatureDelta:     proofMatureDelta,
 		WaitingProofStore:    ctx.gossiper.cfg.WaitingProofStore,
 		MessageStore:         ctx.gossiper.cfg.MessageStore,
@@ -1665,7 +1657,6 @@ func TestSignatureAnnouncementFullProofWhenRemoteProof(t *testing.T) {
 		t.Fatal("channel update announcement was broadcast")
 	case <-time.After(2 * trickleDelay):
 	}
-
 	select {
 	case msg := <-sentToPeer:
 		assertMessage(t, batch.chanUpdAnn1, msg)
@@ -1806,7 +1797,7 @@ func TestSignatureAnnouncementFullProofWhenRemoteProof(t *testing.T) {
 func TestDeDuplicatedAnnouncements(t *testing.T) {
 	t.Parallel()
 
-	timestamp := testTimestamp
+	timestamp := uint32(123456)
 	announcements := deDupedAnnouncements{}
 	announcements.Reset()
 
@@ -2676,7 +2667,6 @@ func TestExtraDataChannelAnnouncementValidation(t *testing.T) {
 func TestExtraDataChannelUpdateValidation(t *testing.T) {
 	t.Parallel()
 
-	timestamp := testTimestamp
 	ctx, cleanup, err := createTestCtx(0)
 	if err != nil {
 		t.Fatalf("can't create context: %v", err)
@@ -2684,6 +2674,7 @@ func TestExtraDataChannelUpdateValidation(t *testing.T) {
 	defer cleanup()
 
 	remotePeer := &mockPeer{nodeKeyPriv1.PubKey(), nil, nil}
+	timestamp := uint32(123456)
 
 	// In this scenario, we'll create two announcements, one regular
 	// channel announcement, and another channel update announcement, that
@@ -2750,7 +2741,7 @@ func TestExtraDataNodeAnnouncementValidation(t *testing.T) {
 	defer cleanup()
 
 	remotePeer := &mockPeer{nodeKeyPriv1.PubKey(), nil, nil}
-	timestamp := testTimestamp
+	timestamp := uint32(123456)
 
 	// We'll create a node announcement that includes a set of opaque data
 	// which we don't know of, but will store anyway in order to ensure
@@ -2772,171 +2763,6 @@ func TestExtraDataNodeAnnouncementValidation(t *testing.T) {
 	}
 }
 
-// assertBroadcast checks that num messages are being broadcasted from the
-// gossiper. The broadcasted messages are returned.
-func assertBroadcast(t *testing.T, ctx *testCtx, num int) []lnwire.Message {
-	t.Helper()
-
-	var msgs []lnwire.Message
-	for i := 0; i < num; i++ {
-		select {
-		case msg := <-ctx.broadcastedMessage:
-			msgs = append(msgs, msg.msg)
-		case <-time.After(time.Second):
-			t.Fatalf("expected %d messages to be broadcast, only "+
-				"got %d", num, i)
-		}
-	}
-
-	// No more messages should be broadcast.
-	select {
-	case msg := <-ctx.broadcastedMessage:
-		t.Fatalf("unexpected message was broadcast: %T", msg.msg)
-	case <-time.After(2 * trickleDelay):
-	}
-
-	return msgs
-}
-
-// assertProcessAnnouncemnt is a helper method that checks that the result of
-// processing an announcement is successful.
-func assertProcessAnnouncement(t *testing.T, result chan error) {
-	t.Helper()
-
-	select {
-	case err := <-result:
-		if err != nil {
-			t.Fatalf("unable to process :%v", err)
-		}
-	case <-time.After(2 * time.Second):
-		t.Fatal("did not process announcement")
-	}
-}
-
-// TestRetransmit checks that the expected announcements are retransmitted when
-// the retransmit ticker ticks.
-func TestRetransmit(t *testing.T) {
-	t.Parallel()
-
-	ctx, cleanup, err := createTestCtx(proofMatureDelta)
-	if err != nil {
-		t.Fatalf("can't create context: %v", err)
-	}
-	defer cleanup()
-
-	batch, err := createAnnouncements(0)
-	if err != nil {
-		t.Fatalf("can't generate announcements: %v", err)
-	}
-
-	localKey, err := btcec.ParsePubKey(batch.nodeAnn1.NodeID[:], btcec.S256())
-	if err != nil {
-		t.Fatalf("unable to parse pubkey: %v", err)
-	}
-	remoteKey, err := btcec.ParsePubKey(batch.nodeAnn2.NodeID[:], btcec.S256())
-	if err != nil {
-		t.Fatalf("unable to parse pubkey: %v", err)
-	}
-	remotePeer := &mockPeer{remoteKey, nil, nil}
-
-	// Process a local channel annoucement, channel update and node
-	// announcement. No messages should be broadcasted yet, since no proof
-	// has been exchanged.
-	assertProcessAnnouncement(
-		t, ctx.gossiper.ProcessLocalAnnouncement(
-			batch.localChanAnn, localKey,
-		),
-	)
-	assertBroadcast(t, ctx, 0)
-
-	assertProcessAnnouncement(
-		t, ctx.gossiper.ProcessLocalAnnouncement(
-			batch.chanUpdAnn1, localKey,
-		),
-	)
-	assertBroadcast(t, ctx, 0)
-
-	assertProcessAnnouncement(
-		t, ctx.gossiper.ProcessLocalAnnouncement(
-			batch.nodeAnn1, localKey,
-		),
-	)
-	assertBroadcast(t, ctx, 0)
-
-	// Add the remote channel update to the gossiper. Similarly, nothing
-	// should be broadcasted.
-	assertProcessAnnouncement(
-		t, ctx.gossiper.ProcessRemoteAnnouncement(
-			batch.chanUpdAnn2, remotePeer,
-		),
-	)
-	assertBroadcast(t, ctx, 0)
-
-	// Now add the local and remote proof to the gossiper, which should
-	// trigger a broadcast of the announcements.
-	assertProcessAnnouncement(
-		t, ctx.gossiper.ProcessLocalAnnouncement(
-			batch.localProofAnn, localKey,
-		),
-	)
-	assertBroadcast(t, ctx, 0)
-
-	assertProcessAnnouncement(
-		t, ctx.gossiper.ProcessRemoteAnnouncement(
-			batch.remoteProofAnn, remotePeer,
-		),
-	)
-
-	// checkAnncouncments make sure the expected number of channel
-	// announcements + channel updates + node announcements are broadcast.
-	checkAnnouncements := func(t *testing.T, chanAnns, chanUpds,
-		nodeAnns int) {
-
-		t.Helper()
-
-		num := chanAnns + chanUpds + nodeAnns
-		anns := assertBroadcast(t, ctx, num)
-
-		// Count the received announcements.
-		var chanAnn, chanUpd, nodeAnn int
-		for _, msg := range anns {
-			switch msg.(type) {
-			case *lnwire.ChannelAnnouncement:
-				chanAnn++
-			case *lnwire.ChannelUpdate:
-				chanUpd++
-			case *lnwire.NodeAnnouncement:
-				nodeAnn++
-			}
-		}
-
-		if chanAnn != chanAnns || chanUpd != chanUpds ||
-			nodeAnn != nodeAnns {
-			t.Fatalf("unexpected number of announcements: "+
-				"chanAnn=%d, chanUpd=%d, nodeAnn=%d",
-				chanAnn, chanUpd, nodeAnn)
-		}
-	}
-
-	// All announcements should be broadcast, including the remote channel
-	// update.
-	checkAnnouncements(t, 1, 2, 1)
-
-	// Now let the retransmit ticker tick, which should trigger updates to
-	// be rebroadcast.
-	now := time.Unix(int64(testTimestamp), 0)
-	future := now.Add(rebroadcastInterval + 10*time.Second)
-	select {
-	case ctx.gossiper.cfg.RetransmitTicker.(*ticker.Force).Force <- future:
-	case <-time.After(2 * time.Second):
-		t.Fatalf("unable to force tick")
-	}
-
-	// The channel announcement + local channel update + node announcement
-	// should be re-broadcast.
-	checkAnnouncements(t, 1, 1, 1)
-}
-
 // TestNodeAnnouncementNoChannels tests that NodeAnnouncements for nodes with
 // no existing channels in the graph do not get forwarded.
 func TestNodeAnnouncementNoChannels(t *testing.T) {
diff --git a/htlcswitch/switch_test.go b/htlcswitch/switch_test.go
index b0a53eb3a..59f6fae9a 100644
--- a/htlcswitch/switch_test.go
+++ b/htlcswitch/switch_test.go
@@ -1803,7 +1803,7 @@ func TestSwitchSendPayment(t *testing.T) {
 	// the add htlc request with error and sent the htlc fail request
 	// back. This request should be forwarded back to alice channel link.
 	obfuscator := NewMockObfuscator()
-	failure := lnwire.NewFailIncorrectDetails(update.Amount, 100)
+	failure := lnwire.NewFailIncorrectDetails(update.Amount)
 	reason, err := obfuscator.EncryptFirstHop(failure)
 	if err != nil {
 		t.Fatalf("unable obfuscate failure: %v", err)
diff --git a/invoices/invoiceregistry_test.go b/invoices/invoiceregistry_test.go
index 8145d3fe0..ee457c5d1 100644
--- a/invoices/invoiceregistry_test.go
+++ b/invoices/invoiceregistry_test.go
@@ -23,8 +23,6 @@ var (
 
 	testHtlcExpiry = uint32(5)
 
-	testInvoiceCltvDelta = uint32(4)
-
 	testFinalCltvRejectDelta = int32(4)
 
 	testCurrentHeight = int32(1)
@@ -123,23 +121,6 @@ func TestSettleInvoice(t *testing.T) {
 
 	hodlChan := make(chan interface{}, 1)
 
-	// Try to settle invoice with an htlc that expires too soon.
-	event, err := registry.NotifyExitHopHtlc(
-		hash, testInvoice.Terms.Value,
-		uint32(testCurrentHeight)+testInvoiceCltvDelta-1,
-		testCurrentHeight, getCircuitKey(10), hodlChan, nil,
-	)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if event.Preimage != nil {
-		t.Fatal("expected cancel event")
-	}
-	if event.AcceptHeight != testCurrentHeight {
-		t.Fatalf("expected acceptHeight %v, but got %v",
-			testCurrentHeight, event.AcceptHeight)
-	}
-
 	// Settle invoice with a slightly higher amount.
 	amtPaid := lnwire.MilliSatoshi(100500)
 	_, err = registry.NotifyExitHopHtlc(
@@ -178,7 +159,7 @@ func TestSettleInvoice(t *testing.T) {
 
 	// Try to settle again with the same htlc id. We need this idempotent
 	// behaviour after a restart.
-	event, err = registry.NotifyExitHopHtlc(
+	event, err := registry.NotifyExitHopHtlc(
 		hash, amtPaid, testHtlcExpiry, testCurrentHeight,
 		getCircuitKey(0), hodlChan, nil,
 	)
@@ -328,7 +309,7 @@ func TestCancelInvoice(t *testing.T) {
 	}
 
 	// Notify arrival of a new htlc paying to this invoice. This should
-	// result in a cancel event.
+	// succeed.
 	hodlChan := make(chan interface{})
 	event, err := registry.NotifyExitHopHtlc(
 		hash, amt, testHtlcExpiry, testCurrentHeight,
@@ -341,15 +322,10 @@ func TestCancelInvoice(t *testing.T) {
 	if event.Preimage != nil {
 		t.Fatal("expected cancel hodl event")
 	}
-	if event.AcceptHeight != testCurrentHeight {
-		t.Fatalf("expected acceptHeight %v, but got %v",
-			testCurrentHeight, event.AcceptHeight)
-	}
 }
 
-// TestSettleHoldInvoice tests settling of a hold invoice and related
-// notifications.
-func TestSettleHoldInvoice(t *testing.T) {
+// TestHoldInvoice tests settling of a hold invoice and related notifications.
+func TestHoldInvoice(t *testing.T) {
 	defer timeout(t)()
 
 	cdb, cleanup, err := newDB()
@@ -486,10 +462,6 @@ func TestSettleHoldInvoice(t *testing.T) {
 	if *hodlEvent.Preimage != preimage {
 		t.Fatal("unexpected preimage in hodl event")
 	}
-	if hodlEvent.AcceptHeight != testCurrentHeight {
-		t.Fatalf("expected acceptHeight %v, but got %v",
-			testCurrentHeight, event.AcceptHeight)
-	}
 
 	// We expect a settled notification to be sent out for both all and
 	// single invoice subscribers.
@@ -522,85 +494,6 @@ func TestSettleHoldInvoice(t *testing.T) {
 	}
 }
 
-// TestCancelHoldInvoice tests canceling of a hold invoice and related
-// notifications.
-func TestCancelHoldInvoice(t *testing.T) {
-	defer timeout(t)()
-
-	cdb, cleanup, err := newDB()
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer cleanup()
-
-	// Instantiate and start the invoice registry.
-	registry := NewRegistry(cdb, testFinalCltvRejectDelta)
-
-	err = registry.Start()
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer registry.Stop()
-
-	// Add the invoice.
-	invoice := &channeldb.Invoice{
-		Terms: channeldb.ContractTerm{
-			PaymentPreimage: channeldb.UnknownPreimage,
-			Value:           lnwire.MilliSatoshi(100000),
-		},
-	}
-
-	_, err = registry.AddInvoice(invoice, hash)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	amtPaid := lnwire.MilliSatoshi(100000)
-	hodlChan := make(chan interface{}, 1)
-
-	// NotifyExitHopHtlc without a preimage present in the invoice registry
-	// should be possible.
-	event, err := registry.NotifyExitHopHtlc(
-		hash, amtPaid, testHtlcExpiry, testCurrentHeight,
-		getCircuitKey(0), hodlChan, nil,
-	)
-	if err != nil {
-		t.Fatalf("expected settle to succeed but got %v", err)
-	}
-	if event != nil {
-		t.Fatalf("expected htlc to be held")
-	}
-
-	// Cancel invoice.
-	err = registry.CancelInvoice(hash)
-	if err != nil {
-		t.Fatal("cancel invoice failed")
-	}
-
-	hodlEvent := (<-hodlChan).(HodlEvent)
-	if hodlEvent.Preimage != nil {
-		t.Fatal("expected cancel hodl event")
-	}
-
-	// Offering the same htlc again at a higher height should still result
-	// in a rejection. The accept height is expected to be the original
-	// accept height.
-	event, err = registry.NotifyExitHopHtlc(
-		hash, amtPaid, testHtlcExpiry, testCurrentHeight+1,
-		getCircuitKey(0), hodlChan, nil,
-	)
-	if err != nil {
-		t.Fatalf("expected settle to succeed but got %v", err)
-	}
-	if event.Preimage != nil {
-		t.Fatalf("expected htlc to be canceled")
-	}
-	if event.AcceptHeight != testCurrentHeight {
-		t.Fatalf("expected acceptHeight %v, but got %v",
-			testCurrentHeight, event.AcceptHeight)
-	}
-}
-
 func newDB() (*channeldb.DB, func(), error) {
 	// First, create a temporary directory to be used for the duration of
 	// this test.
diff --git a/lnwallet/interface_test.go b/lnwallet/interface_test.go
index e7f53d1d1..8a2793904 100644
--- a/lnwallet/interface_test.go
+++ b/lnwallet/interface_test.go
@@ -1269,7 +1269,7 @@ func testTransactionSubscriptions(miner *rpctest.Harness,
 		outputAmt = btcutil.SatoshiPerBitcoin
 		numTxns   = 3
 	)
-	unconfirmedNtfns := make(chan struct{})
+	errCh1 := make(chan error, 1)
 	switch alice.BackEnd() {
 	case "neutrino":
 		// Neutrino doesn't listen for unconfirmed transactions.
@@ -1278,23 +1278,25 @@ func testTransactionSubscriptions(miner *rpctest.Harness,
 			for i := 0; i < numTxns; i++ {
 				txDetail := <-txClient.UnconfirmedTransactions()
 				if txDetail.NumConfirmations != 0 {
-					t.Fatalf("incorrect number of confs, "+
+					errCh1 <- fmt.Errorf("incorrect number of confs, "+
 						"expected %v got %v", 0,
 						txDetail.NumConfirmations)
+					return
 				}
 				if txDetail.Value != outputAmt {
-					t.Fatalf("incorrect output amt, "+
+					errCh1 <- fmt.Errorf("incorrect output amt, "+
 						"expected %v got %v", outputAmt,
 						txDetail.Value)
+					return
 				}
 				if txDetail.BlockHash != nil {
-					t.Fatalf("block hash should be nil, "+
+					errCh1 <- fmt.Errorf("block hash should be nil, "+
 						"is instead %v",
 						txDetail.BlockHash)
+					return
 				}
 			}
-
-			close(unconfirmedNtfns)
+			errCh1 <- nil
 		}()
 	}
 
@@ -1333,24 +1335,29 @@ func testTransactionSubscriptions(miner *rpctest.Harness,
 		select {
 		case <-time.After(time.Second * 10):
 			t.Fatalf("transactions not received after 10 seconds")
-		case <-unconfirmedNtfns: // Fall through on success
+		case err := <-errCh1:
+			if err != nil {
+				t.Fatal(err)
+			}
 		}
 	}
 
-	confirmedNtfns := make(chan struct{})
+	errCh2 := make(chan error, 1)
 	go func() {
 		for i := 0; i < numTxns; i++ {
 			txDetail := <-txClient.ConfirmedTransactions()
 			if txDetail.NumConfirmations != 1 {
-				t.Fatalf("incorrect number of confs for %s, expected %v got %v",
+				errCh2 <- fmt.Errorf("incorrect number of confs for %s, expected %v got %v",
 					txDetail.Hash, 1, txDetail.NumConfirmations)
+				return
 			}
 			if txDetail.Value != outputAmt {
-				t.Fatalf("incorrect output amt, expected %v got %v in txid %s",
+				errCh2 <- fmt.Errorf("incorrect output amt, expected %v got %v in txid %s",
 					outputAmt, txDetail.Value, txDetail.Hash)
+				return
 			}
 		}
-		close(confirmedNtfns)
+		errCh2 <- nil
 	}()
 
 	// Next mine a single block, all the transactions generated above
@@ -1364,7 +1371,10 @@ func testTransactionSubscriptions(miner *rpctest.Harness,
 	select {
 	case <-time.After(time.Second * 5):
 		t.Fatalf("transactions not received after 5 seconds")
-	case <-confirmedNtfns: // Fall through on success
+	case err := <-errCh2:
+		if err != nil {
+			t.Fatal(err)
+		}
 	}
 
 	// We'll also ensure that the client is able to send our new
diff --git a/lnwire/onion_error_test.go b/lnwire/onion_error_test.go
index 8420be1f7..21fe3fcd4 100644
--- a/lnwire/onion_error_test.go
+++ b/lnwire/onion_error_test.go
@@ -4,7 +4,6 @@ import (
 	"bufio"
 	"bytes"
 	"encoding/binary"
-	"io"
 	"reflect"
 	"testing"
 
@@ -37,7 +36,7 @@ var onionFailures = []FailureMessage{
 	&FailIncorrectPaymentAmount{},
 	&FailFinalExpiryTooSoon{},
 
-	NewFailIncorrectDetails(99, 100),
+	NewFailIncorrectDetails(99),
 	NewInvalidOnionVersion(testOnionHash),
 	NewInvalidOnionHmac(testOnionHash),
 	NewInvalidOnionKey(testOnionHash),
@@ -175,7 +174,10 @@ func TestWriteOnionErrorChanUpdate(t *testing.T) {
 func TestFailIncorrectDetailsOptionalAmount(t *testing.T) {
 	t.Parallel()
 
-	onionError := &mockFailIncorrectDetailsNoAmt{}
+	// Creation an error that is a non-pointer will allow us to skip the
+	// type assertion for the Serializable interface. As a result, the
+	// amount body won't be written.
+	onionError := &FailIncorrectDetails{}
 
 	var b bytes.Buffer
 	if err := EncodeFailure(&b, onionError, 0); err != nil {
@@ -187,89 +189,8 @@ func TestFailIncorrectDetailsOptionalAmount(t *testing.T) {
 		t.Fatalf("unable to decode error: %v", err)
 	}
 
-	invalidDetailsErr, ok := onionError2.(*FailIncorrectDetails)
-	if !ok {
-		t.Fatalf("expected FailIncorrectDetails, but got %T",
-			onionError2)
+	if !reflect.DeepEqual(onionError, onionError2) {
+		t.Fatalf("expected %v, got %v", spew.Sdump(onionError),
+			spew.Sdump(onionError2))
 	}
-
-	if invalidDetailsErr.amount != 0 {
-		t.Fatalf("expected amount to be zero")
-	}
-	if invalidDetailsErr.height != 0 {
-		t.Fatalf("height incorrect")
-	}
-}
-
-type mockFailIncorrectDetailsNoAmt struct {
-}
-
-func (f *mockFailIncorrectDetailsNoAmt) Code() FailCode {
-	return CodeIncorrectOrUnknownPaymentDetails
-}
-
-func (f *mockFailIncorrectDetailsNoAmt) Error() string {
-	return ""
-}
-
-func (f *mockFailIncorrectDetailsNoAmt) Decode(r io.Reader, pver uint32) error {
-	return nil
-}
-
-func (f *mockFailIncorrectDetailsNoAmt) Encode(w io.Writer, pver uint32) error {
-	return nil
-}
-
-// TestFailIncorrectDetailsOptionalHeight tests that we're able to decode an
-// FailIncorrectDetails error that doesn't have the optional height. This
-// ensures we're able to decode FailIncorrectDetails messages from older nodes.
-func TestFailIncorrectDetailsOptionalHeight(t *testing.T) {
-	t.Parallel()
-
-	onionError := &mockFailIncorrectDetailsNoHeight{
-		amount: uint64(123),
-	}
-
-	var b bytes.Buffer
-	if err := EncodeFailure(&b, onionError, 0); err != nil {
-		t.Fatalf("unable to encode failure: %v", err)
-	}
-
-	onionError2, err := DecodeFailure(bytes.NewReader(b.Bytes()), 0)
-	if err != nil {
-		t.Fatalf("unable to decode error: %v", err)
-	}
-
-	invalidDetailsErr, ok := onionError2.(*FailIncorrectDetails)
-	if !ok {
-		t.Fatalf("expected FailIncorrectDetails, but got %T",
-			onionError2)
-	}
-
-	if invalidDetailsErr.amount != 123 {
-		t.Fatalf("amount incorrect")
-	}
-	if invalidDetailsErr.height != 0 {
-		t.Fatalf("height incorrect")
-	}
-}
-
-type mockFailIncorrectDetailsNoHeight struct {
-	amount uint64
-}
-
-func (f *mockFailIncorrectDetailsNoHeight) Code() FailCode {
-	return CodeIncorrectOrUnknownPaymentDetails
-}
-
-func (f *mockFailIncorrectDetailsNoHeight) Error() string {
-	return ""
-}
-
-func (f *mockFailIncorrectDetailsNoHeight) Decode(r io.Reader, pver uint32) error {
-	return nil
-}
-
-func (f *mockFailIncorrectDetailsNoHeight) Encode(w io.Writer, pver uint32) error {
-	return WriteElement(w, f.amount)
 }
diff --git a/routing/missioncontrol_store_test.go b/routing/missioncontrol_store_test.go
index 9d070f4de..86111d0bd 100644
--- a/routing/missioncontrol_store_test.go
+++ b/routing/missioncontrol_store_test.go
@@ -61,7 +61,7 @@ func TestMissionControlStore(t *testing.T) {
 
 	result1 := paymentResult{
 		route:            &testRoute,
-		failure:          lnwire.NewFailIncorrectDetails(100, 1000),
+		failure:          lnwire.NewFailIncorrectDetails(100),
 		failureSourceIdx: &failureSourceIdx,
 		id:               99,
 		timeReply:        testTime,
diff --git a/routing/result_interpretation_test.go b/routing/result_interpretation_test.go
index 8c4498b06..7d95ad641 100644
--- a/routing/result_interpretation_test.go
+++ b/routing/result_interpretation_test.go
@@ -103,7 +103,7 @@ var resultTestCases = []resultTestCase{
 		name:          "fail incorrect details",
 		route:         &routeTwoHop,
 		failureSrcIdx: 2,
-		failure:       lnwire.NewFailIncorrectDetails(97, 0),
+		failure:       lnwire.NewFailIncorrectDetails(97),
 
 		expectedResult: &interpretedResult{
 			pairResults: map[DirectedNodePair]pairResult{