Repository: lightningnetwork/lnd
Pull request #4591 (2020-09-03 16:28:57)

lnd: Call loader.UnloadWallet on shutdown
This is required to make restart work for LndMobile builds.
Not calling `UnloadWallet` would make `UnlockWallet` stall forever on the second run as the file is already opened.

This was pretty much a non-issue for the normal UNIX daemon build, as sending `stopDaemon` or `SIGINT` would close down the process and Go's runtime would presumably handle any open files.
But on mobile builds, this is not the case, thus we have to explicitly close it down.  

Right now I'm just grabbing the loader all the way to `Main` and `defer`-ing the call so that it will execute once we get a `shutdownChan` signal, I'm unsure if this is the best approach.
N.B: wallet has to be opened for the main RPC server to function properly.

This is a part of an on-going work to address mobile restarting problems #4492.

hsjoberg: Now passing `UnloadWallet` function pointer instead of `Loader` instance.
Also rebased.

Patch:
diff --git a/channeldb/channel.go b/channeldb/channel.go
index 35a0700d4..0a5e47b2c 100644
--- a/channeldb/channel.go
+++ b/channeldb/channel.go
@@ -206,7 +206,8 @@ const (
 
 	// AnchorOutputsBit indicates that the channel makes use of anchor
 	// outputs to bump the commitment transaction's effective feerate. This
-	// channel type also uses a delayed to_remote output script.
+	// channel type also uses a delayed to_remote output script. If bit is
+	// set, we'll find the size of the anchor outputs in the database.
 	AnchorOutputsBit ChannelType = 1 << 3
 
 	// FrozenBit indicates that the channel is a frozen channel, meaning
diff --git a/htlcswitch/mock.go b/htlcswitch/mock.go
index 69277bc31..7c169ac76 100644
--- a/htlcswitch/mock.go
+++ b/htlcswitch/mock.go
@@ -15,6 +15,8 @@ import (
 	"time"
 
 	"github.com/btcsuite/btcd/btcec"
+	"github.com/btcsuite/btcd/chaincfg/chainhash"
+	"github.com/btcsuite/btcd/txscript"
 	"github.com/btcsuite/btcd/wire"
 	"github.com/go-errors/errors"
 	sphinx "github.com/lightningnetwork/lightning-onion"
@@ -23,9 +25,9 @@ import (
 	"github.com/lightningnetwork/lnd/clock"
 	"github.com/lightningnetwork/lnd/contractcourt"
 	"github.com/lightningnetwork/lnd/htlcswitch/hop"
+	"github.com/lightningnetwork/lnd/input"
 	"github.com/lightningnetwork/lnd/invoices"
 	"github.com/lightningnetwork/lnd/lnpeer"
-	"github.com/lightningnetwork/lnd/lntest/mock"
 	"github.com/lightningnetwork/lnd/lntypes"
 	"github.com/lightningnetwork/lnd/lnwallet/chainfee"
 	"github.com/lightningnetwork/lnd/lnwire"
@@ -170,11 +172,7 @@ func initSwitchWithDB(startingHeight uint32, db *channeldb.DB) (*Switch, error)
 		FetchLastChannelUpdate: func(lnwire.ShortChannelID) (*lnwire.ChannelUpdate, error) {
 			return nil, nil
 		},
-		Notifier: &mock.ChainNotifier{
-			SpendChan: make(chan *chainntnfs.SpendDetail),
-			EpochChan: make(chan *chainntnfs.BlockEpoch),
-			ConfChan:  make(chan *chainntnfs.TxConfirmation),
-		},
+		Notifier:       &mockNotifier{},
 		FwdEventTicker: ticker.NewForce(DefaultFwdEventInterval),
 		LogEventTicker: ticker.NewForce(DefaultLogInterval),
 		AckEventTicker: ticker.NewForce(DefaultAckInterval),
@@ -857,6 +855,103 @@ func (i *mockInvoiceRegistry) HodlUnsubscribeAll(subscriber chan<- interface{})
 
 var _ InvoiceDatabase = (*mockInvoiceRegistry)(nil)
 
+type mockSigner struct {
+	key *btcec.PrivateKey
+}
+
+func (m *mockSigner) SignOutputRaw(tx *wire.MsgTx,
+	signDesc *input.SignDescriptor) (input.Signature, error) {
+
+	amt := signDesc.Output.Value
+	witnessScript := signDesc.WitnessScript
+	privKey := m.key
+
+	if !privKey.PubKey().IsEqual(signDesc.KeyDesc.PubKey) {
+		return nil, fmt.Errorf("incorrect key passed")
+	}
+
+	switch {
+	case signDesc.SingleTweak != nil:
+		privKey = input.TweakPrivKey(privKey,
+			signDesc.SingleTweak)
+	case signDesc.DoubleTweak != nil:
+		privKey = input.DeriveRevocationPrivKey(privKey,
+			signDesc.DoubleTweak)
+	}
+
+	sig, err := txscript.RawTxInWitnessSignature(tx, signDesc.SigHashes,
+		signDesc.InputIndex, amt, witnessScript, signDesc.HashType,
+		privKey)
+	if err != nil {
+		return nil, err
+	}
+
+	return btcec.ParseDERSignature(sig[:len(sig)-1], btcec.S256())
+}
+func (m *mockSigner) ComputeInputScript(tx *wire.MsgTx, signDesc *input.SignDescriptor) (*input.Script, error) {
+
+	// TODO(roasbeef): expose tweaked signer from lnwallet so don't need to
+	// duplicate this code?
+
+	privKey := m.key
+
+	switch {
+	case signDesc.SingleTweak != nil:
+		privKey = input.TweakPrivKey(privKey,
+			signDesc.SingleTweak)
+	case signDesc.DoubleTweak != nil:
+		privKey = input.DeriveRevocationPrivKey(privKey,
+			signDesc.DoubleTweak)
+	}
+
+	witnessScript, err := txscript.WitnessSignature(tx, signDesc.SigHashes,
+		signDesc.InputIndex, signDesc.Output.Value, signDesc.Output.PkScript,
+		signDesc.HashType, privKey, true)
+	if err != nil {
+		return nil, err
+	}
+
+	return &input.Script{
+		Witness: witnessScript,
+	}, nil
+}
+
+type mockNotifier struct {
+	epochChan chan *chainntnfs.BlockEpoch
+}
+
+func (m *mockNotifier) RegisterConfirmationsNtfn(txid *chainhash.Hash, _ []byte,
+	numConfs uint32, heightHint uint32) (*chainntnfs.ConfirmationEvent, error) {
+	return nil, nil
+}
+func (m *mockNotifier) RegisterBlockEpochNtfn(
+	bestBlock *chainntnfs.BlockEpoch) (*chainntnfs.BlockEpochEvent, error) {
+	return &chainntnfs.BlockEpochEvent{
+		Epochs: m.epochChan,
+		Cancel: func() {},
+	}, nil
+}
+
+func (m *mockNotifier) Start() error {
+	return nil
+}
+
+func (m *mockNotifier) Started() bool {
+	return true
+}
+
+func (m *mockNotifier) Stop() error {
+	return nil
+}
+
+func (m *mockNotifier) RegisterSpendNtfn(outpoint *wire.OutPoint, _ []byte,
+	heightHint uint32) (*chainntnfs.SpendEvent, error) {
+
+	return &chainntnfs.SpendEvent{
+		Spend: make(chan *chainntnfs.SpendDetail),
+	}, nil
+}
+
 type mockCircuitMap struct {
 	lookup chan *PaymentCircuit
 }
diff --git a/lnd.go b/lnd.go
index d5bc77687..a7dbb69bc 100644
--- a/lnd.go
+++ b/lnd.go
@@ -387,6 +387,11 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
 		walletInitParams = *params
 		privateWalletPw = walletInitParams.Password
 		publicWalletPw = walletInitParams.Password
+		defer func() {
+			if err := walletInitParams.UnloadWallet(); err != nil {
+				ltndLog.Errorf("Could not unload wallet: %v", err)
+			}
+		}()
 
 		if walletInitParams.RecoveryWindow > 0 {
 			ltndLog.Infof("Wallet recovery mode enabled with "+
@@ -944,6 +949,10 @@ type WalletUnlockParams struct {
 	// ChansToRestore a set of static channel backups that should be
 	// restored before the main server instance starts up.
 	ChansToRestore walletunlocker.ChannelsToRecover
+
+	// UnloadWallet is a function for unloading the wallet, which should
+	// be called on shutdown.
+	UnloadWallet func() error
 }
 
 // waitForWalletPassword will spin up gRPC and REST endpoints for the
@@ -1105,6 +1114,7 @@ func waitForWalletPassword(cfg *Config, restEndpoints []net.Addr,
 			RecoveryWindow: recoveryWindow,
 			Wallet:         newWallet,
 			ChansToRestore: initMsg.ChanBackups,
+			UnloadWallet:   loader.UnloadWallet,
 		}, nil
 
 	// The wallet has already been created in the past, and is simply being
@@ -1115,6 +1125,7 @@ func waitForWalletPassword(cfg *Config, restEndpoints []net.Addr,
 			RecoveryWindow: unlockMsg.RecoveryWindow,
 			Wallet:         unlockMsg.Wallet,
 			ChansToRestore: unlockMsg.ChanBackups,
+			UnloadWallet:   unlockMsg.UnloadWallet,
 		}, nil
 
 	case <-signal.ShutdownChannel():
diff --git a/lnwallet/channel.go b/lnwallet/channel.go
index ccdf55308..94e268054 100644
--- a/lnwallet/channel.go
+++ b/lnwallet/channel.go
@@ -6179,15 +6179,20 @@ func (lc *LightningChannel) CreateCloseProposal(proposedFee btcutil.Amount,
 		return nil, nil, 0, ErrChanClosing
 	}
 
-	// Get the final balances after subtracting the proposed fee, taking
-	// care not to persist the adjusted balance, as the feeRate may change
+	// Subtract the proposed fee from the appropriate balance, taking care
+	// not to persist the adjusted balance, as the feeRate may change
 	// during the channel closing process.
-	ourBalance, theirBalance, err := CoopCloseBalance(
-		lc.channelState.ChanType, lc.channelState.IsInitiator,
-		proposedFee, lc.channelState.LocalCommitment,
-	)
-	if err != nil {
-		return nil, nil, 0, err
+	localCommit := lc.channelState.LocalCommitment
+	ourBalance := localCommit.LocalBalance.ToSatoshis()
+	theirBalance := localCommit.RemoteBalance.ToSatoshis()
+
+	// We'll make sure we account for the complete balance by adding the
+	// current dangling commitment fee to the balance of the initiator.
+	commitFee := localCommit.CommitFee
+	if lc.channelState.IsInitiator {
+		ourBalance = ourBalance - proposedFee + commitFee
+	} else {
+		theirBalance = theirBalance - proposedFee + commitFee
 	}
 
 	closeTx := CreateCooperativeCloseTx(
@@ -6243,13 +6248,20 @@ func (lc *LightningChannel) CompleteCooperativeClose(
 		return nil, 0, ErrChanClosing
 	}
 
-	// Get the final balances after subtracting the proposed fee.
-	ourBalance, theirBalance, err := CoopCloseBalance(
-		lc.channelState.ChanType, lc.channelState.IsInitiator,
-		proposedFee, lc.channelState.LocalCommitment,
-	)
-	if err != nil {
-		return nil, 0, err
+	// Subtract the proposed fee from the appropriate balance, taking care
+	// not to persist the adjusted balance, as the feeRate may change
+	// during the channel closing process.
+	localCommit := lc.channelState.LocalCommitment
+	ourBalance := localCommit.LocalBalance.ToSatoshis()
+	theirBalance := localCommit.RemoteBalance.ToSatoshis()
+
+	// We'll make sure we account for the complete balance by adding the
+	// current dangling commitment fee to the balance of the initiator.
+	commitFee := localCommit.CommitFee
+	if lc.channelState.IsInitiator {
+		ourBalance = ourBalance - proposedFee + commitFee
+	} else {
+		theirBalance = theirBalance - proposedFee + commitFee
 	}
 
 	// Create the transaction used to return the current settled balance
diff --git a/lnwallet/commitment.go b/lnwallet/commitment.go
index 44b3c81c4..d70f3ca0e 100644
--- a/lnwallet/commitment.go
+++ b/lnwallet/commitment.go
@@ -663,47 +663,6 @@ func CreateCommitTx(chanType channeldb.ChannelType,
 	return commitTx, nil
 }
 
-// CoopCloseBalance returns the final balances that should be used to create
-// the cooperative close tx, given the channel type and transaction fee.
-func CoopCloseBalance(chanType channeldb.ChannelType, isInitiator bool,
-	coopCloseFee btcutil.Amount, localCommit channeldb.ChannelCommitment) (
-	btcutil.Amount, btcutil.Amount, error) {
-
-	// Get both parties' balances from the latest commitment.
-	ourBalance := localCommit.LocalBalance.ToSatoshis()
-	theirBalance := localCommit.RemoteBalance.ToSatoshis()
-
-	// We'll make sure we account for the complete balance by adding the
-	// current dangling commitment fee to the balance of the initiator.
-	initiatorDelta := localCommit.CommitFee
-
-	// Since the initiator's balance also is stored after subtracting the
-	// anchor values, add that back in case this was an anchor commitment.
-	if chanType.HasAnchors() {
-		initiatorDelta += 2 * anchorSize
-	}
-
-	// The initiator will pay the full coop close fee, subtract that value
-	// from their balance.
-	initiatorDelta -= coopCloseFee
-
-	if isInitiator {
-		ourBalance += initiatorDelta
-	} else {
-		theirBalance += initiatorDelta
-	}
-
-	// During fee negotiation it should always be verified that the
-	// initiator can pay the proposed fee, but we do a sanity check just to
-	// be sure here.
-	if ourBalance < 0 || theirBalance < 0 {
-		return 0, 0, fmt.Errorf("initiator cannot afford proposed " +
-			"coop close fee")
-	}
-
-	return ourBalance, theirBalance, nil
-}
-
 // genHtlcScript generates the proper P2WSH public key scripts for the HTLC
 // output modified by two-bits denoting if this is an incoming HTLC, and if the
 // HTLC is being applied to their commitment transaction or ours.
diff --git a/lnwire/features.go b/lnwire/features.go
index 5584191b0..6cc899463 100644
--- a/lnwire/features.go
+++ b/lnwire/features.go
@@ -112,12 +112,12 @@ const (
 	// AnchorsRequired is a required feature bit that signals that the node
 	// requires channels to be made using commitments having anchor
 	// outputs.
-	AnchorsRequired FeatureBit = 20
+	AnchorsRequired FeatureBit = 1336
 
 	// AnchorsRequired is an optional feature bit that signals that the
 	// node supports channels to be made using commitments having anchor
 	// outputs.
-	AnchorsOptional FeatureBit = 21
+	AnchorsOptional FeatureBit = 1337
 
 	// maxAllowedSize is a maximum allowed size of feature vector.
 	//
diff --git a/mock.go b/mock.go
new file mode 100644
index 000000000..94b9f318c
--- /dev/null
+++ b/mock.go
@@ -0,0 +1,400 @@
+package lnd
+
+import (
+	"encoding/hex"
+	"fmt"
+	"sync"
+	"sync/atomic"
+	"time"
+
+	"github.com/btcsuite/btcd/btcec"
+	"github.com/btcsuite/btcd/chaincfg"
+	"github.com/btcsuite/btcd/chaincfg/chainhash"
+	"github.com/btcsuite/btcd/txscript"
+	"github.com/btcsuite/btcd/wire"
+	"github.com/btcsuite/btcutil"
+	"github.com/btcsuite/btcwallet/wallet/txauthor"
+	"github.com/btcsuite/btcwallet/wtxmgr"
+
+	"github.com/lightningnetwork/lnd/chainntnfs"
+	"github.com/lightningnetwork/lnd/input"
+	"github.com/lightningnetwork/lnd/keychain"
+	"github.com/lightningnetwork/lnd/lnwallet"
+	"github.com/lightningnetwork/lnd/lnwallet/chainfee"
+)
+
+var (
+	coinPkScript, _ = hex.DecodeString("001431df1bde03c074d0cf21ea2529427e1499b8f1de")
+)
+
+// The block height returned by the mock BlockChainIO's GetBestBlock.
+const fundingBroadcastHeight = 123
+
+type mockSigner struct {
+	key *btcec.PrivateKey
+}
+
+func (m *mockSigner) SignOutputRaw(tx *wire.MsgTx,
+	signDesc *input.SignDescriptor) (input.Signature, error) {
+	amt := signDesc.Output.Value
+	witnessScript := signDesc.WitnessScript
+	privKey := m.key
+
+	if !privKey.PubKey().IsEqual(signDesc.KeyDesc.PubKey) {
+		return nil, fmt.Errorf("incorrect key passed")
+	}
+
+	switch {
+	case signDesc.SingleTweak != nil:
+		privKey = input.TweakPrivKey(privKey,
+			signDesc.SingleTweak)
+	case signDesc.DoubleTweak != nil:
+		privKey = input.DeriveRevocationPrivKey(privKey,
+			signDesc.DoubleTweak)
+	}
+
+	sig, err := txscript.RawTxInWitnessSignature(tx, signDesc.SigHashes,
+		signDesc.InputIndex, amt, witnessScript, signDesc.HashType,
+		privKey)
+	if err != nil {
+		return nil, err
+	}
+
+	return btcec.ParseDERSignature(sig[:len(sig)-1], btcec.S256())
+}
+
+func (m *mockSigner) ComputeInputScript(tx *wire.MsgTx,
+	signDesc *input.SignDescriptor) (*input.Script, error) {
+
+	// TODO(roasbeef): expose tweaked signer from lnwallet so don't need to
+	// duplicate this code?
+
+	privKey := m.key
+
+	switch {
+	case signDesc.SingleTweak != nil:
+		privKey = input.TweakPrivKey(privKey,
+			signDesc.SingleTweak)
+	case signDesc.DoubleTweak != nil:
+		privKey = input.DeriveRevocationPrivKey(privKey,
+			signDesc.DoubleTweak)
+	}
+
+	witnessScript, err := txscript.WitnessSignature(tx, signDesc.SigHashes,
+		signDesc.InputIndex, signDesc.Output.Value, signDesc.Output.PkScript,
+		signDesc.HashType, privKey, true)
+	if err != nil {
+		return nil, err
+	}
+
+	return &input.Script{
+		Witness: witnessScript,
+	}, nil
+}
+
+type mockNotfier struct {
+	confChannel chan *chainntnfs.TxConfirmation
+}
+
+func (m *mockNotfier) RegisterConfirmationsNtfn(txid *chainhash.Hash,
+	_ []byte, numConfs, heightHint uint32) (*chainntnfs.ConfirmationEvent, error) {
+	return &chainntnfs.ConfirmationEvent{
+		Confirmed: m.confChannel,
+	}, nil
+}
+func (m *mockNotfier) RegisterBlockEpochNtfn(
+	bestBlock *chainntnfs.BlockEpoch) (*chainntnfs.BlockEpochEvent, error) {
+	return &chainntnfs.BlockEpochEvent{
+		Epochs: make(chan *chainntnfs.BlockEpoch),
+		Cancel: func() {},
+	}, nil
+}
+
+func (m *mockNotfier) Start() error {
+	return nil
+}
+
+func (m *mockNotfier) Started() bool {
+	return true
+}
+
+func (m *mockNotfier) Stop() error {
+	return nil
+}
+func (m *mockNotfier) RegisterSpendNtfn(outpoint *wire.OutPoint, _ []byte,
+	heightHint uint32) (*chainntnfs.SpendEvent, error) {
+	return &chainntnfs.SpendEvent{
+		Spend:  make(chan *chainntnfs.SpendDetail),
+		Cancel: func() {},
+	}, nil
+}
+
+// mockSpendNotifier extends the mockNotifier so that spend notifications can be
+// triggered and delivered to subscribers.
+type mockSpendNotifier struct {
+	*mockNotfier
+	spendMap map[wire.OutPoint][]chan *chainntnfs.SpendDetail
+	spends   map[wire.OutPoint]*chainntnfs.SpendDetail
+	mtx      sync.Mutex
+}
+
+func makeMockSpendNotifier() *mockSpendNotifier {
+	return &mockSpendNotifier{
+		mockNotfier: &mockNotfier{
+			confChannel: make(chan *chainntnfs.TxConfirmation),
+		},
+		spendMap: make(map[wire.OutPoint][]chan *chainntnfs.SpendDetail),
+		spends:   make(map[wire.OutPoint]*chainntnfs.SpendDetail),
+	}
+}
+
+func (m *mockSpendNotifier) RegisterSpendNtfn(outpoint *wire.OutPoint,
+	_ []byte, heightHint uint32) (*chainntnfs.SpendEvent, error) {
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+
+	spendChan := make(chan *chainntnfs.SpendDetail, 1)
+	if detail, ok := m.spends[*outpoint]; ok {
+		// Deliver spend immediately if details are already known.
+		spendChan <- &chainntnfs.SpendDetail{
+			SpentOutPoint:     detail.SpentOutPoint,
+			SpendingHeight:    detail.SpendingHeight,
+			SpendingTx:        detail.SpendingTx,
+			SpenderTxHash:     detail.SpenderTxHash,
+			SpenderInputIndex: detail.SpenderInputIndex,
+		}
+	} else {
+		// Otherwise, queue the notification for delivery if the spend
+		// is ever received.
+		m.spendMap[*outpoint] = append(m.spendMap[*outpoint], spendChan)
+	}
+
+	return &chainntnfs.SpendEvent{
+		Spend: spendChan,
+		Cancel: func() {
+		},
+	}, nil
+}
+
+// Spend dispatches SpendDetails to all subscribers of the outpoint. The details
+// will include the transaction and height provided by the caller.
+func (m *mockSpendNotifier) Spend(outpoint *wire.OutPoint, height int32,
+	txn *wire.MsgTx) {
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+
+	txnHash := txn.TxHash()
+	details := &chainntnfs.SpendDetail{
+		SpentOutPoint:     outpoint,
+		SpendingHeight:    height,
+		SpendingTx:        txn,
+		SpenderTxHash:     &txnHash,
+		SpenderInputIndex: outpoint.Index,
+	}
+
+	// Cache details in case of late registration.
+	if _, ok := m.spends[*outpoint]; !ok {
+		m.spends[*outpoint] = details
+	}
+
+	// Deliver any backlogged spend notifications.
+	if spendChans, ok := m.spendMap[*outpoint]; ok {
+		delete(m.spendMap, *outpoint)
+		for _, spendChan := range spendChans {
+			spendChan <- &chainntnfs.SpendDetail{
+				SpentOutPoint:     details.SpentOutPoint,
+				SpendingHeight:    details.SpendingHeight,
+				SpendingTx:        details.SpendingTx,
+				SpenderTxHash:     details.SpenderTxHash,
+				SpenderInputIndex: details.SpenderInputIndex,
+			}
+		}
+	}
+}
+
+type mockChainIO struct {
+	bestHeight int32
+}
+
+var _ lnwallet.BlockChainIO = (*mockChainIO)(nil)
+
+func (m *mockChainIO) GetBestBlock() (*chainhash.Hash, int32, error) {
+	return chaincfg.TestNet3Params.GenesisHash, m.bestHeight, nil
+}
+
+func (*mockChainIO) GetUtxo(op *wire.OutPoint, _ []byte,
+	heightHint uint32, _ <-chan struct{}) (*wire.TxOut, error) {
+	return nil, nil
+}
+
+func (*mockChainIO) GetBlockHash(blockHeight int64) (*chainhash.Hash, error) {
+	return nil, nil
+}
+
+func (*mockChainIO) GetBlock(blockHash *chainhash.Hash) (*wire.MsgBlock, error) {
+	return nil, nil
+}
+
+// mockWalletController is used by the LightningWallet, and let us mock the
+// interaction with the bitcoin network.
+type mockWalletController struct {
+	rootKey               *btcec.PrivateKey
+	publishedTransactions chan *wire.MsgTx
+	index                 uint32
+	utxos                 []*lnwallet.Utxo
+}
+
+// BackEnd returns "mock" to signify a mock wallet controller.
+func (*mockWalletController) BackEnd() string {
+	return "mock"
+}
+
+// FetchInputInfo will be called to get info about the inputs to the funding
+// transaction.
+func (*mockWalletController) FetchInputInfo(
+	prevOut *wire.OutPoint) (*lnwallet.Utxo, error) {
+	utxo := &lnwallet.Utxo{
+		AddressType:   lnwallet.WitnessPubKey,
+		Value:         10 * btcutil.SatoshiPerBitcoin,
+		PkScript:      []byte("dummy"),
+		Confirmations: 1,
+		OutPoint:      *prevOut,
+	}
+	return utxo, nil
+}
+func (*mockWalletController) ConfirmedBalance(confs int32) (btcutil.Amount, error) {
+	return 0, nil
+}
+
+// NewAddress is called to get new addresses for delivery, change etc.
+func (m *mockWalletController) NewAddress(addrType lnwallet.AddressType,
+	change bool) (btcutil.Address, error) {
+	addr, _ := btcutil.NewAddressPubKey(
+		m.rootKey.PubKey().SerializeCompressed(), &chaincfg.MainNetParams)
+	return addr, nil
+}
+func (*mockWalletController) LastUnusedAddress(addrType lnwallet.AddressType) (
+	btcutil.Address, error) {
+	return nil, nil
+}
+
+func (*mockWalletController) IsOurAddress(a btcutil.Address) bool {
+	return false
+}
+
+func (*mockWalletController) SendOutputs(outputs []*wire.TxOut,
+	_ chainfee.SatPerKWeight, _ string) (*wire.MsgTx, error) {
+
+	return nil, nil
+}
+
+func (*mockWalletController) CreateSimpleTx(outputs []*wire.TxOut,
+	_ chainfee.SatPerKWeight, _ bool) (*txauthor.AuthoredTx, error) {
+
+	return nil, nil
+}
+
+// ListUnspentWitness is called by the wallet when doing coin selection. We just
+// need one unspent for the funding transaction.
+func (m *mockWalletController) ListUnspentWitness(minconfirms,
+	maxconfirms int32) ([]*lnwallet.Utxo, error) {
+
+	// If the mock already has a list of utxos, return it.
+	if m.utxos != nil {
+		return m.utxos, nil
+	}
+
+	// Otherwise create one to return.
+	utxo := &lnwallet.Utxo{
+		AddressType: lnwallet.WitnessPubKey,
+		Value:       btcutil.Amount(10 * btcutil.SatoshiPerBitcoin),
+		PkScript:    coinPkScript,
+		OutPoint: wire.OutPoint{
+			Hash:  chainhash.Hash{},
+			Index: m.index,
+		},
+	}
+	atomic.AddUint32(&m.index, 1)
+	var ret []*lnwallet.Utxo
+	ret = append(ret, utxo)
+	return ret, nil
+}
+func (*mockWalletController) ListTransactionDetails(_, _ int32) ([]*lnwallet.TransactionDetail, error) {
+	return nil, nil
+}
+func (*mockWalletController) LockOutpoint(o wire.OutPoint)   {}
+func (*mockWalletController) UnlockOutpoint(o wire.OutPoint) {}
+
+func (*mockWalletController) LeaseOutput(wtxmgr.LockID, wire.OutPoint) (time.Time, error) {
+	return time.Now(), nil
+}
+func (*mockWalletController) ReleaseOutput(wtxmgr.LockID, wire.OutPoint) error {
+	return nil
+}
+
+func (m *mockWalletController) PublishTransaction(tx *wire.MsgTx, _ string) error {
+	m.publishedTransactions <- tx
+	return nil
+}
+
+func (m *mockWalletController) LabelTransaction(_ chainhash.Hash, _ string,
+	_ bool) error {
+
+	return nil
+}
+
+func (*mockWalletController) SubscribeTransactions() (lnwallet.TransactionSubscription, error) {
+	return nil, nil
+}
+func (*mockWalletController) IsSynced() (bool, int64, error) {
+	return true, int64(0), nil
+}
+func (*mockWalletController) GetRecoveryInfo() (bool, float64, error) {
+	return true, float64(1), nil
+}
+func (*mockWalletController) Start() error {
+	return nil
+}
+func (*mockWalletController) Stop() error {
+	return nil
+}
+
+type mockSecretKeyRing struct {
+	rootKey *btcec.PrivateKey
+}
+
+func (m *mockSecretKeyRing) DeriveNextKey(keyFam keychain.KeyFamily) (keychain.KeyDescriptor, error) {
+	return keychain.KeyDescriptor{
+		PubKey: m.rootKey.PubKey(),
+	}, nil
+}
+
+func (m *mockSecretKeyRing) DeriveKey(keyLoc keychain.KeyLocator) (keychain.KeyDescriptor, error) {
+	return keychain.KeyDescriptor{
+		PubKey: m.rootKey.PubKey(),
+	}, nil
+}
+
+func (m *mockSecretKeyRing) DerivePrivKey(keyDesc keychain.KeyDescriptor) (*btcec.PrivateKey, error) {
+	return m.rootKey, nil
+}
+
+func (m *mockSecretKeyRing) ECDH(_ keychain.KeyDescriptor,
+	pubKey *btcec.PublicKey) ([32]byte, error) {
+
+	return [32]byte{}, nil
+}
+
+func (m *mockSecretKeyRing) SignDigest(_ keychain.KeyDescriptor,
+	digest [32]byte) (*btcec.Signature, error) {
+
+	return m.rootKey.Sign(digest[:])
+}
+
+func (m *mockSecretKeyRing) SignDigestCompact(_ keychain.KeyDescriptor,
+	digest [32]byte) ([]byte, error) {
+
+	return btcec.SignCompact(btcec.S256(), m.rootKey, digest[:], true)
+}
+
+var _ keychain.SecretKeyRing = (*mockSecretKeyRing)(nil)
diff --git a/peer/brontide.go b/peer/brontide.go
index 11e04928b..cc637207c 100644
--- a/peer/brontide.go
+++ b/peer/brontide.go
@@ -2785,11 +2785,11 @@ func (p *Brontide) handleCloseMsg(msg *closeMsg) {
 func (p *Brontide) HandleLocalCloseChanReqs(req *htlcswitch.ChanClose) {
 	select {
 	case p.localCloseChanReqs <- req:
-		peerLog.Infof("Local close channel request delivered to "+
-			"peer: %x", p.PubKey())
+		peerLog.Infof("Local close channel request delivered to peer: %v",
+			p.PubKey())
 	case <-p.quit:
-		peerLog.Infof("Unable to deliver local close channel request "+
-			"to peer %x", p.PubKey())
+		peerLog.Infof("Unable to deliver local close channel request to peer "+
+			"%x", p.PubKey())
 	}
 }
 
diff --git a/walletunlocker/service.go b/walletunlocker/service.go
index 90e84bae8..39a667010 100644
--- a/walletunlocker/service.go
+++ b/walletunlocker/service.go
@@ -81,6 +81,10 @@ type WalletUnlockMsg struct {
 	// ChanBackups a set of static channel backups that should be received
 	// after the wallet has been unlocked.
 	ChanBackups ChannelsToRecover
+
+	// UnloadWallet is a function for unloading the wallet, which should
+	// be called on shutdown.
+	UnloadWallet func() error
 }
 
 // UnlockerService implements the WalletUnlocker service used to provide lnd
@@ -346,6 +350,7 @@ func (u *UnlockerService) UnlockWallet(ctx context.Context,
 		Passphrase:     password,
 		RecoveryWindow: recoveryWindow,
 		Wallet:         unlockedWallet,
+		UnloadWallet:   loader.UnloadWallet,
 	}
 
 	// Before we return the unlock payload, we'll check if we can extract


Test patch:
diff --git a/breacharbiter_test.go b/breacharbiter_test.go
index 03c1cdb6f..01d9daf75 100644
--- a/breacharbiter_test.go
+++ b/breacharbiter_test.go
@@ -29,7 +29,6 @@ import (
 	"github.com/lightningnetwork/lnd/htlcswitch"
 	"github.com/lightningnetwork/lnd/input"
 	"github.com/lightningnetwork/lnd/keychain"
-	"github.com/lightningnetwork/lnd/lntest/mock"
 	"github.com/lightningnetwork/lnd/lntest/wait"
 	"github.com/lightningnetwork/lnd/lnwallet"
 	"github.com/lightningnetwork/lnd/lnwallet/chainfee"
@@ -1434,8 +1433,8 @@ func testBreachSpends(t *testing.T, test breachTest) {
 
 	// Notify that the breaching transaction is confirmed, to trigger the
 	// retribution logic.
-	notifier := brar.cfg.Notifier.(*mock.SpendNotifier)
-	notifier.ConfChan <- &chainntnfs.TxConfirmation{}
+	notifier := brar.cfg.Notifier.(*mockSpendNotifier)
+	notifier.confChannel <- &chainntnfs.TxConfirmation{}
 
 	// The breach arbiter should attempt to sweep all outputs on the
 	// breached commitment. We'll pretend that the HTLC output has been
@@ -1511,7 +1510,7 @@ func testBreachSpends(t *testing.T, test breachTest) {
 
 	// Deliver confirmation of sweep if the test expects it.
 	if test.sendFinalConf {
-		notifier.ConfChan <- &chainntnfs.TxConfirmation{}
+		notifier.confChannel <- &chainntnfs.TxConfirmation{}
 	}
 
 	// Assert that the channel is fully resolved.
@@ -1671,10 +1670,10 @@ func createTestArbiter(t *testing.T, contractBreaches chan *ContractBreachEvent,
 
 	aliceKeyPriv, _ := btcec.PrivKeyFromBytes(btcec.S256(),
 		alicesPrivKey)
-	signer := &mock.SingleSigner{Privkey: aliceKeyPriv}
+	signer := &mockSigner{key: aliceKeyPriv}
 
 	// Assemble our test arbiter.
-	notifier := mock.MakeMockSpendNotifier()
+	notifier := makeMockSpendNotifier()
 	ba := newBreachArbiter(&BreachConfig{
 		CloseLink:          func(_ *wire.OutPoint, _ htlcswitch.ChannelCloseType) {},
 		DB:                 db,
@@ -1898,8 +1897,8 @@ func createInitChannels(revocationWindow int) (*lnwallet.LightningChannel, *lnwa
 		Packager:                channeldb.NewChannelPackager(shortChanID),
 	}
 
-	aliceSigner := &mock.SingleSigner{Privkey: aliceKeyPriv}
-	bobSigner := &mock.SingleSigner{Privkey: bobKeyPriv}
+	aliceSigner := &mockSigner{aliceKeyPriv}
+	bobSigner := &mockSigner{bobKeyPriv}
 
 	alicePool := lnwallet.NewSigPool(1, aliceSigner)
 	channelAlice, err := lnwallet.NewLightningChannel(
diff --git a/contractcourt/chain_arbitrator_test.go b/contractcourt/chain_arbitrator_test.go
index e197c0b09..60c7eebe7 100644
--- a/contractcourt/chain_arbitrator_test.go
+++ b/contractcourt/chain_arbitrator_test.go
@@ -8,10 +8,8 @@ import (
 
 	"github.com/btcsuite/btcd/chaincfg/chainhash"
 	"github.com/btcsuite/btcd/wire"
-	"github.com/lightningnetwork/lnd/chainntnfs"
 	"github.com/lightningnetwork/lnd/channeldb"
 	"github.com/lightningnetwork/lnd/clock"
-	"github.com/lightningnetwork/lnd/lntest/mock"
 	"github.com/lightningnetwork/lnd/lnwallet"
 )
 
@@ -82,12 +80,8 @@ func TestChainArbitratorRepublishCloses(t *testing.T) {
 	published := make(map[chainhash.Hash]int)
 
 	chainArbCfg := ChainArbitratorConfig{
-		ChainIO: &mock.ChainIO{},
-		Notifier: &mock.ChainNotifier{
-			SpendChan: make(chan *chainntnfs.SpendDetail),
-			EpochChan: make(chan *chainntnfs.BlockEpoch),
-			ConfChan:  make(chan *chainntnfs.TxConfirmation),
-		},
+		ChainIO:  &mockChainIO{},
+		Notifier: &mockNotifier{},
 		PublishTx: func(tx *wire.MsgTx, _ string) error {
 			published[tx.TxHash()]++
 			return nil
@@ -178,12 +172,8 @@ func TestResolveContract(t *testing.T) {
 	// chain arbitrator that should pick up these new channels and launch
 	// resolver for them.
 	chainArbCfg := ChainArbitratorConfig{
-		ChainIO: &mock.ChainIO{},
-		Notifier: &mock.ChainNotifier{
-			SpendChan: make(chan *chainntnfs.SpendDetail),
-			EpochChan: make(chan *chainntnfs.BlockEpoch),
-			ConfChan:  make(chan *chainntnfs.TxConfirmation),
-		},
+		ChainIO:  &mockChainIO{},
+		Notifier: &mockNotifier{},
 		PublishTx: func(tx *wire.MsgTx, _ string) error {
 			return nil
 		},
diff --git a/contractcourt/chain_watcher_test.go b/contractcourt/chain_watcher_test.go
index 50e73ec52..62c768717 100644
--- a/contractcourt/chain_watcher_test.go
+++ b/contractcourt/chain_watcher_test.go
@@ -7,15 +7,58 @@ import (
 	"testing"
 	"time"
 
+	"github.com/btcsuite/btcd/chaincfg/chainhash"
 	"github.com/btcsuite/btcd/wire"
 	"github.com/lightningnetwork/lnd/chainntnfs"
 	"github.com/lightningnetwork/lnd/channeldb"
 	"github.com/lightningnetwork/lnd/input"
-	"github.com/lightningnetwork/lnd/lntest/mock"
 	"github.com/lightningnetwork/lnd/lnwallet"
 	"github.com/lightningnetwork/lnd/lnwire"
 )
 
+type mockNotifier struct {
+	spendChan chan *chainntnfs.SpendDetail
+	epochChan chan *chainntnfs.BlockEpoch
+	confChan  chan *chainntnfs.TxConfirmation
+}
+
+func (m *mockNotifier) RegisterConfirmationsNtfn(txid *chainhash.Hash, _ []byte, numConfs,
+	heightHint uint32) (*chainntnfs.ConfirmationEvent, error) {
+	return &chainntnfs.ConfirmationEvent{
+		Confirmed: m.confChan,
+		Cancel:    func() {},
+	}, nil
+}
+
+func (m *mockNotifier) RegisterBlockEpochNtfn(
+	bestBlock *chainntnfs.BlockEpoch) (*chainntnfs.BlockEpochEvent, error) {
+
+	return &chainntnfs.BlockEpochEvent{
+		Epochs: m.epochChan,
+		Cancel: func() {},
+	}, nil
+}
+
+func (m *mockNotifier) Start() error {
+	return nil
+}
+
+func (m *mockNotifier) Started() bool {
+	return true
+}
+
+func (m *mockNotifier) Stop() error {
+	return nil
+}
+func (m *mockNotifier) RegisterSpendNtfn(outpoint *wire.OutPoint, _ []byte,
+	heightHint uint32) (*chainntnfs.SpendEvent, error) {
+
+	return &chainntnfs.SpendEvent{
+		Spend:  m.spendChan,
+		Cancel: func() {},
+	}, nil
+}
+
 // TestChainWatcherRemoteUnilateralClose tests that the chain watcher is able
 // to properly detect a normal unilateral close by the remote node using their
 // lowest commitment.
@@ -34,10 +77,8 @@ func TestChainWatcherRemoteUnilateralClose(t *testing.T) {
 
 	// With the channels created, we'll now create a chain watcher instance
 	// which will be watching for any closes of Alice's channel.
-	aliceNotifier := &mock.ChainNotifier{
-		SpendChan: make(chan *chainntnfs.SpendDetail),
-		EpochChan: make(chan *chainntnfs.BlockEpoch),
-		ConfChan:  make(chan *chainntnfs.TxConfirmation),
+	aliceNotifier := &mockNotifier{
+		spendChan: make(chan *chainntnfs.SpendDetail),
 	}
 	aliceChainWatcher, err := newChainWatcher(chainWatcherConfig{
 		chanState:           aliceChannel.State(),
@@ -66,7 +107,7 @@ func TestChainWatcherRemoteUnilateralClose(t *testing.T) {
 		SpenderTxHash: &bobTxHash,
 		SpendingTx:    bobCommit,
 	}
-	aliceNotifier.SpendChan <- bobSpend
+	aliceNotifier.spendChan <- bobSpend
 
 	// We should get a new spend event over the remote unilateral close
 	// event channel.
@@ -125,10 +166,8 @@ func TestChainWatcherRemoteUnilateralClosePendingCommit(t *testing.T) {
 
 	// With the channels created, we'll now create a chain watcher instance
 	// which will be watching for any closes of Alice's channel.
-	aliceNotifier := &mock.ChainNotifier{
-		SpendChan: make(chan *chainntnfs.SpendDetail),
-		EpochChan: make(chan *chainntnfs.BlockEpoch),
-		ConfChan:  make(chan *chainntnfs.TxConfirmation),
+	aliceNotifier := &mockNotifier{
+		spendChan: make(chan *chainntnfs.SpendDetail),
 	}
 	aliceChainWatcher, err := newChainWatcher(chainWatcherConfig{
 		chanState:           aliceChannel.State(),
@@ -177,7 +216,7 @@ func TestChainWatcherRemoteUnilateralClosePendingCommit(t *testing.T) {
 		SpenderTxHash: &bobTxHash,
 		SpendingTx:    bobCommit,
 	}
-	aliceNotifier.SpendChan <- bobSpend
+	aliceNotifier.spendChan <- bobSpend
 
 	// We should get a new spend event over the remote unilateral close
 	// event channel.
@@ -253,10 +292,8 @@ func TestChainWatcherDataLossProtect(t *testing.T) {
 		// With the channels created, we'll now create a chain watcher
 		// instance which will be watching for any closes of Alice's
 		// channel.
-		aliceNotifier := &mock.ChainNotifier{
-			SpendChan: make(chan *chainntnfs.SpendDetail),
-			EpochChan: make(chan *chainntnfs.BlockEpoch),
-			ConfChan:  make(chan *chainntnfs.TxConfirmation),
+		aliceNotifier := &mockNotifier{
+			spendChan: make(chan *chainntnfs.SpendDetail),
 		}
 		aliceChainWatcher, err := newChainWatcher(chainWatcherConfig{
 			chanState: aliceChannel.State(),
@@ -313,7 +350,7 @@ func TestChainWatcherDataLossProtect(t *testing.T) {
 			SpenderTxHash: &bobTxHash,
 			SpendingTx:    bobCommit,
 		}
-		aliceNotifier.SpendChan <- bobSpend
+		aliceNotifier.spendChan <- bobSpend
 
 		// We should get a new uni close resolution that indicates we
 		// processed the DLP scenario.
@@ -424,10 +461,8 @@ func TestChainWatcherLocalForceCloseDetect(t *testing.T) {
 		// With the channels created, we'll now create a chain watcher
 		// instance which will be watching for any closes of Alice's
 		// channel.
-		aliceNotifier := &mock.ChainNotifier{
-			SpendChan: make(chan *chainntnfs.SpendDetail),
-			EpochChan: make(chan *chainntnfs.BlockEpoch),
-			ConfChan:  make(chan *chainntnfs.TxConfirmation),
+		aliceNotifier := &mockNotifier{
+			spendChan: make(chan *chainntnfs.SpendDetail),
 		}
 		aliceChainWatcher, err := newChainWatcher(chainWatcherConfig{
 			chanState:           aliceChannel.State(),
@@ -482,7 +517,7 @@ func TestChainWatcherLocalForceCloseDetect(t *testing.T) {
 			SpenderTxHash: &aliceTxHash,
 			SpendingTx:    aliceCommit,
 		}
-		aliceNotifier.SpendChan <- aliceSpend
+		aliceNotifier.spendChan <- aliceSpend
 
 		// We should get a local force close event from Alice as she
 		// should be able to detect the close based on the commitment
diff --git a/contractcourt/channel_arbitrator_test.go b/contractcourt/channel_arbitrator_test.go
index 1cdb81421..ce0963ece 100644
--- a/contractcourt/channel_arbitrator_test.go
+++ b/contractcourt/channel_arbitrator_test.go
@@ -19,7 +19,6 @@ import (
 	"github.com/lightningnetwork/lnd/channeldb/kvdb"
 	"github.com/lightningnetwork/lnd/clock"
 	"github.com/lightningnetwork/lnd/input"
-	"github.com/lightningnetwork/lnd/lntest/mock"
 	"github.com/lightningnetwork/lnd/lnwallet"
 	"github.com/lightningnetwork/lnd/lnwire"
 )
@@ -335,10 +334,10 @@ func createTestChannelArbitrator(t *testing.T, log ArbitratorLog,
 		},
 		OutgoingBroadcastDelta: 5,
 		IncomingBroadcastDelta: 5,
-		Notifier: &mock.ChainNotifier{
-			EpochChan: make(chan *chainntnfs.BlockEpoch),
-			SpendChan: make(chan *chainntnfs.SpendDetail),
-			ConfChan:  make(chan *chainntnfs.TxConfirmation),
+		Notifier: &mockNotifier{
+			epochChan: make(chan *chainntnfs.BlockEpoch),
+			spendChan: make(chan *chainntnfs.SpendDetail),
+			confChan:  make(chan *chainntnfs.TxConfirmation),
 		},
 		IncubateOutputs: func(wire.OutPoint,
 			*lnwallet.OutgoingHtlcResolution,
@@ -879,7 +878,7 @@ func TestChannelArbitratorLocalForceClosePendingHtlc(t *testing.T) {
 	// We'll grab the old notifier here as our resolvers are still holding
 	// a reference to this instance, and a new one will be created when we
 	// restart the channel arb below.
-	oldNotifier := chanArb.cfg.Notifier.(*mock.ChainNotifier)
+	oldNotifier := chanArb.cfg.Notifier.(*mockNotifier)
 
 	// At this point, in order to simulate a restart, we'll re-create the
 	// channel arbitrator. We do this to ensure that all information
@@ -928,7 +927,7 @@ func TestChannelArbitratorLocalForceClosePendingHtlc(t *testing.T) {
 	}
 
 	// Send a notification that the expiry height has been reached.
-	oldNotifier.EpochChan <- &chainntnfs.BlockEpoch{Height: 10}
+	oldNotifier.epochChan <- &chainntnfs.BlockEpoch{Height: 10}
 
 	// htlcOutgoingContestResolver is now transforming into a
 	// htlcTimeoutResolver and should send the contract off for incubation.
@@ -940,7 +939,7 @@ func TestChannelArbitratorLocalForceClosePendingHtlc(t *testing.T) {
 
 	// Notify resolver that the HTLC output of the commitment has been
 	// spent.
-	oldNotifier.SpendChan <- &chainntnfs.SpendDetail{SpendingTx: closeTx}
+	oldNotifier.spendChan <- &chainntnfs.SpendDetail{SpendingTx: closeTx}
 
 	// Finally, we should also receive a resolution message instructing the
 	// switch to cancel back the HTLC.
@@ -968,7 +967,7 @@ func TestChannelArbitratorLocalForceClosePendingHtlc(t *testing.T) {
 	}
 
 	// Notify resolver that the second level transaction is spent.
-	oldNotifier.SpendChan <- &chainntnfs.SpendDetail{SpendingTx: closeTx}
+	oldNotifier.spendChan <- &chainntnfs.SpendDetail{SpendingTx: closeTx}
 
 	// At this point channel should be marked as resolved.
 	chanArbCtxNew.AssertStateTransitions(StateFullyResolved)
diff --git a/contractcourt/commit_sweep_resolver_test.go b/contractcourt/commit_sweep_resolver_test.go
index eb54dbf32..578b5c45d 100644
--- a/contractcourt/commit_sweep_resolver_test.go
+++ b/contractcourt/commit_sweep_resolver_test.go
@@ -10,7 +10,6 @@ import (
 	"github.com/lightningnetwork/lnd/channeldb"
 	"github.com/lightningnetwork/lnd/channeldb/kvdb"
 	"github.com/lightningnetwork/lnd/input"
-	"github.com/lightningnetwork/lnd/lntest/mock"
 	"github.com/lightningnetwork/lnd/lnwallet"
 	"github.com/lightningnetwork/lnd/lnwallet/chainfee"
 	"github.com/lightningnetwork/lnd/sweep"
@@ -18,7 +17,7 @@ import (
 
 type commitSweepResolverTestContext struct {
 	resolver           *commitSweepResolver
-	notifier           *mock.ChainNotifier
+	notifier           *mockNotifier
 	sweeper            *mockSweeper
 	resolverResultChan chan resolveResult
 	t                  *testing.T
@@ -27,10 +26,10 @@ type commitSweepResolverTestContext struct {
 func newCommitSweepResolverTestContext(t *testing.T,
 	resolution *lnwallet.CommitOutputResolution) *commitSweepResolverTestContext {
 
-	notifier := &mock.ChainNotifier{
-		EpochChan: make(chan *chainntnfs.BlockEpoch),
-		SpendChan: make(chan *chainntnfs.SpendDetail),
-		ConfChan:  make(chan *chainntnfs.TxConfirmation),
+	notifier := &mockNotifier{
+		epochChan: make(chan *chainntnfs.BlockEpoch),
+		spendChan: make(chan *chainntnfs.SpendDetail),
+		confChan:  make(chan *chainntnfs.TxConfirmation),
 	}
 
 	sweeper := newMockSweeper()
@@ -84,7 +83,7 @@ func (i *commitSweepResolverTestContext) resolve() {
 }
 
 func (i *commitSweepResolverTestContext) notifyEpoch(height int32) {
-	i.notifier.EpochChan <- &chainntnfs.BlockEpoch{
+	i.notifier.epochChan <- &chainntnfs.BlockEpoch{
 		Height: height,
 	}
 }
@@ -190,7 +189,7 @@ func TestCommitSweepResolverNoDelay(t *testing.T) {
 
 	spendTx := &wire.MsgTx{}
 	spendHash := spendTx.TxHash()
-	ctx.notifier.ConfChan <- &chainntnfs.TxConfirmation{
+	ctx.notifier.confChan <- &chainntnfs.TxConfirmation{
 		Tx: spendTx,
 	}
 
@@ -268,7 +267,7 @@ func testCommitSweepResolverDelay(t *testing.T, sweepErr error) {
 
 	ctx.resolve()
 
-	ctx.notifier.ConfChan <- &chainntnfs.TxConfirmation{
+	ctx.notifier.confChan <- &chainntnfs.TxConfirmation{
 		BlockHeight: testInitialBlockHeight - 1,
 	}
 
diff --git a/contractcourt/htlc_incoming_resolver_test.go b/contractcourt/htlc_incoming_resolver_test.go
index 4ada27ffb..55bc33b5e 100644
--- a/contractcourt/htlc_incoming_resolver_test.go
+++ b/contractcourt/htlc_incoming_resolver_test.go
@@ -12,7 +12,6 @@ import (
 	"github.com/lightningnetwork/lnd/channeldb/kvdb"
 	"github.com/lightningnetwork/lnd/htlcswitch/hop"
 	"github.com/lightningnetwork/lnd/invoices"
-	"github.com/lightningnetwork/lnd/lntest/mock"
 	"github.com/lightningnetwork/lnd/lntypes"
 	"github.com/lightningnetwork/lnd/lnwallet"
 	"github.com/lightningnetwork/lnd/lnwire"
@@ -296,7 +295,7 @@ type incomingResolverTestContext struct {
 	registry       *mockRegistry
 	witnessBeacon  *mockWitnessBeacon
 	resolver       *htlcIncomingContestResolver
-	notifier       *mock.ChainNotifier
+	notifier       *mockNotifier
 	onionProcessor *mockOnionProcessor
 	resolveErr     chan error
 	nextResolver   ContractResolver
@@ -304,10 +303,10 @@ type incomingResolverTestContext struct {
 }
 
 func newIncomingResolverTestContext(t *testing.T, isExit bool) *incomingResolverTestContext {
-	notifier := &mock.ChainNotifier{
-		EpochChan: make(chan *chainntnfs.BlockEpoch),
-		SpendChan: make(chan *chainntnfs.SpendDetail),
-		ConfChan:  make(chan *chainntnfs.TxConfirmation),
+	notifier := &mockNotifier{
+		epochChan: make(chan *chainntnfs.BlockEpoch),
+		spendChan: make(chan *chainntnfs.SpendDetail),
+		confChan:  make(chan *chainntnfs.TxConfirmation),
 	}
 	witnessBeacon := newMockWitnessBeacon()
 	registry := &mockRegistry{
@@ -378,7 +377,7 @@ func (i *incomingResolverTestContext) resolve() {
 }
 
 func (i *incomingResolverTestContext) notifyEpoch(height int32) {
-	i.notifier.EpochChan <- &chainntnfs.BlockEpoch{
+	i.notifier.epochChan <- &chainntnfs.BlockEpoch{
 		Height: height,
 	}
 }
diff --git a/contractcourt/htlc_outgoing_contest_resolver_test.go b/contractcourt/htlc_outgoing_contest_resolver_test.go
index 987c1a7a8..10d8fbc1c 100644
--- a/contractcourt/htlc_outgoing_contest_resolver_test.go
+++ b/contractcourt/htlc_outgoing_contest_resolver_test.go
@@ -9,7 +9,6 @@ import (
 	"github.com/lightningnetwork/lnd/channeldb"
 	"github.com/lightningnetwork/lnd/channeldb/kvdb"
 	"github.com/lightningnetwork/lnd/input"
-	"github.com/lightningnetwork/lnd/lntest/mock"
 	"github.com/lightningnetwork/lnd/lntypes"
 	"github.com/lightningnetwork/lnd/lnwallet"
 	"github.com/lightningnetwork/lnd/lnwire"
@@ -81,7 +80,7 @@ func TestHtlcOutgoingResolverRemoteClaim(t *testing.T) {
 
 	spendHash := spendTx.TxHash()
 
-	ctx.notifier.SpendChan <- &chainntnfs.SpendDetail{
+	ctx.notifier.spendChan <- &chainntnfs.SpendDetail{
 		SpendingTx:    spendTx,
 		SpenderTxHash: &spendHash,
 	}
@@ -115,7 +114,7 @@ type resolveResult struct {
 
 type outgoingResolverTestContext struct {
 	resolver           *htlcOutgoingContestResolver
-	notifier           *mock.ChainNotifier
+	notifier           *mockNotifier
 	preimageDB         *mockWitnessBeacon
 	resolverResultChan chan resolveResult
 	resolutionChan     chan ResolutionMsg
@@ -123,10 +122,10 @@ type outgoingResolverTestContext struct {
 }
 
 func newOutgoingResolverTestContext(t *testing.T) *outgoingResolverTestContext {
-	notifier := &mock.ChainNotifier{
-		EpochChan: make(chan *chainntnfs.BlockEpoch),
-		SpendChan: make(chan *chainntnfs.SpendDetail),
-		ConfChan:  make(chan *chainntnfs.TxConfirmation),
+	notifier := &mockNotifier{
+		epochChan: make(chan *chainntnfs.BlockEpoch),
+		spendChan: make(chan *chainntnfs.SpendDetail),
+		confChan:  make(chan *chainntnfs.TxConfirmation),
 	}
 
 	checkPointChan := make(chan struct{}, 1)
@@ -213,7 +212,7 @@ func (i *outgoingResolverTestContext) resolve() {
 }
 
 func (i *outgoingResolverTestContext) notifyEpoch(height int32) {
-	i.notifier.EpochChan <- &chainntnfs.BlockEpoch{
+	i.notifier.epochChan <- &chainntnfs.BlockEpoch{
 		Height: height,
 	}
 }
diff --git a/contractcourt/htlc_success_resolver_test.go b/contractcourt/htlc_success_resolver_test.go
index 6e44c22c7..0c700969f 100644
--- a/contractcourt/htlc_success_resolver_test.go
+++ b/contractcourt/htlc_success_resolver_test.go
@@ -8,7 +8,6 @@ import (
 	"github.com/lightningnetwork/lnd/chainntnfs"
 	"github.com/lightningnetwork/lnd/channeldb"
 	"github.com/lightningnetwork/lnd/channeldb/kvdb"
-	"github.com/lightningnetwork/lnd/lntest/mock"
 	"github.com/lightningnetwork/lnd/lnwallet"
 	"github.com/lightningnetwork/lnd/lnwire"
 )
@@ -17,16 +16,16 @@ var testHtlcAmt = lnwire.MilliSatoshi(200000)
 
 type htlcSuccessResolverTestContext struct {
 	resolver           *htlcSuccessResolver
-	notifier           *mock.ChainNotifier
+	notifier           *mockNotifier
 	resolverResultChan chan resolveResult
 	t                  *testing.T
 }
 
 func newHtlcSuccessResolverTextContext(t *testing.T) *htlcSuccessResolverTestContext {
-	notifier := &mock.ChainNotifier{
-		EpochChan: make(chan *chainntnfs.BlockEpoch),
-		SpendChan: make(chan *chainntnfs.SpendDetail),
-		ConfChan:  make(chan *chainntnfs.TxConfirmation),
+	notifier := &mockNotifier{
+		epochChan: make(chan *chainntnfs.BlockEpoch),
+		spendChan: make(chan *chainntnfs.SpendDetail),
+		confChan:  make(chan *chainntnfs.TxConfirmation),
 	}
 
 	checkPointChan := make(chan struct{}, 1)
@@ -117,7 +116,7 @@ func TestSingleStageSuccess(t *testing.T) {
 	// We send a confirmation for our sweep tx to indicate that our sweep
 	// succeeded.
 	resolve := func(ctx *htlcSuccessResolverTestContext) {
-		ctx.notifier.ConfChan <- &chainntnfs.TxConfirmation{
+		ctx.notifier.confChan <- &chainntnfs.TxConfirmation{
 			Tx:          ctx.resolver.sweepTx,
 			BlockHeight: testInitialBlockHeight - 1,
 		}
@@ -166,7 +165,7 @@ func TestSecondStageResolution(t *testing.T) {
 
 	// We send a spend notification for our output to resolve our htlc.
 	resolve := func(ctx *htlcSuccessResolverTestContext) {
-		ctx.notifier.SpendChan <- &chainntnfs.SpendDetail{
+		ctx.notifier.spendChan <- &chainntnfs.SpendDetail{
 			SpendingTx:    sweepTx,
 			SpenderTxHash: &sweepHash,
 		}
diff --git a/contractcourt/htlc_timeout_resolver_test.go b/contractcourt/htlc_timeout_resolver_test.go
index 6e41ad791..fdf0bba53 100644
--- a/contractcourt/htlc_timeout_resolver_test.go
+++ b/contractcourt/htlc_timeout_resolver_test.go
@@ -7,6 +7,7 @@ import (
 	"testing"
 	"time"
 
+	"github.com/btcsuite/btcd/btcec"
 	"github.com/btcsuite/btcd/txscript"
 	"github.com/btcsuite/btcd/wire"
 	"github.com/btcsuite/btcutil"
@@ -14,11 +15,33 @@ import (
 	"github.com/lightningnetwork/lnd/channeldb"
 	"github.com/lightningnetwork/lnd/channeldb/kvdb"
 	"github.com/lightningnetwork/lnd/input"
-	"github.com/lightningnetwork/lnd/lntest/mock"
 	"github.com/lightningnetwork/lnd/lntypes"
 	"github.com/lightningnetwork/lnd/lnwallet"
 )
 
+type dummySignature struct{}
+
+func (s *dummySignature) Serialize() []byte {
+	return []byte{}
+}
+
+func (s *dummySignature) Verify(_ []byte, _ *btcec.PublicKey) bool {
+	return true
+}
+
+type mockSigner struct {
+}
+
+func (m *mockSigner) SignOutputRaw(tx *wire.MsgTx,
+	signDesc *input.SignDescriptor) (input.Signature, error) {
+	return &dummySignature{}, nil
+}
+
+func (m *mockSigner) ComputeInputScript(tx *wire.MsgTx,
+	signDesc *input.SignDescriptor) (*input.Script, error) {
+	return nil, nil
+}
+
 type mockWitnessBeacon struct {
 	preImageUpdates chan lntypes.Preimage
 	newPreimages    chan []lntypes.Preimage
@@ -70,7 +93,7 @@ func TestHtlcTimeoutResolver(t *testing.T) {
 
 	copy(fakePreimage[:], fakePreimageBytes)
 
-	signer := &mock.DummySigner{}
+	signer := &mockSigner{}
 	sweepTx := &wire.MsgTx{
 		TxIn: []*wire.TxIn{
 			{
@@ -141,7 +164,7 @@ func TestHtlcTimeoutResolver(t *testing.T) {
 			timeout:      true,
 			txToBroadcast: func() (*wire.MsgTx, error) {
 				witness, err := input.SenderHtlcSpendTimeout(
-					&mock.DummySignature{}, txscript.SigHashAll,
+					&dummySignature{}, txscript.SigHashAll,
 					signer, fakeSignDesc, sweepTx,
 				)
 				if err != nil {
@@ -166,7 +189,7 @@ func TestHtlcTimeoutResolver(t *testing.T) {
 			timeout:      false,
 			txToBroadcast: func() (*wire.MsgTx, error) {
 				witness, err := input.ReceiverHtlcSpendRedeem(
-					&mock.DummySignature{}, txscript.SigHashAll,
+					&dummySignature{}, txscript.SigHashAll,
 					fakePreimageBytes, signer, fakeSignDesc,
 					sweepTx,
 				)
@@ -203,10 +226,10 @@ func TestHtlcTimeoutResolver(t *testing.T) {
 		},
 	}
 
-	notifier := &mock.ChainNotifier{
-		EpochChan: make(chan *chainntnfs.BlockEpoch),
-		SpendChan: make(chan *chainntnfs.SpendDetail),
-		ConfChan:  make(chan *chainntnfs.TxConfirmation),
+	notifier := &mockNotifier{
+		epochChan: make(chan *chainntnfs.BlockEpoch),
+		spendChan: make(chan *chainntnfs.SpendDetail),
+		confChan:  make(chan *chainntnfs.TxConfirmation),
 	}
 	witnessBeacon := newMockWitnessBeacon()
 
@@ -331,7 +354,7 @@ func TestHtlcTimeoutResolver(t *testing.T) {
 		spendTxHash := spendingTx.TxHash()
 
 		select {
-		case notifier.SpendChan <- &chainntnfs.SpendDetail{
+		case notifier.spendChan <- &chainntnfs.SpendDetail{
 			SpendingTx:    spendingTx,
 			SpenderTxHash: &spendTxHash,
 		}:
@@ -388,7 +411,7 @@ func TestHtlcTimeoutResolver(t *testing.T) {
 			// only if this is a local commitment transaction.
 			if !testCase.remoteCommit {
 				select {
-				case notifier.SpendChan <- &chainntnfs.SpendDetail{
+				case notifier.spendChan <- &chainntnfs.SpendDetail{
 					SpendingTx:    spendingTx,
 					SpenderTxHash: &spendTxHash,
 				}:
diff --git a/discovery/gossiper_test.go b/discovery/gossiper_test.go
index 9dfad6bad..5281d4aa0 100644
--- a/discovery/gossiper_test.go
+++ b/discovery/gossiper_test.go
@@ -23,8 +23,8 @@ import (
 	"github.com/go-errors/errors"
 	"github.com/lightningnetwork/lnd/chainntnfs"
 	"github.com/lightningnetwork/lnd/channeldb"
+	"github.com/lightningnetwork/lnd/input"
 	"github.com/lightningnetwork/lnd/lnpeer"
-	"github.com/lightningnetwork/lnd/lntest/mock"
 	"github.com/lightningnetwork/lnd/lntest/wait"
 	"github.com/lightningnetwork/lnd/lnwire"
 	"github.com/lightningnetwork/lnd/netann"
@@ -92,6 +92,26 @@ func makeTestDB() (*channeldb.DB, func(), error) {
 	return cdb, cleanUp, nil
 }
 
+type mockSigner struct {
+	privKey *btcec.PrivateKey
+}
+
+func (n *mockSigner) SignMessage(pubKey *btcec.PublicKey,
+	msg []byte) (input.Signature, error) {
+
+	if !pubKey.IsEqual(n.privKey.PubKey()) {
+		return nil, fmt.Errorf("unknown public key")
+	}
+
+	digest := chainhash.DoubleHashB(msg)
+	sign, err := n.privKey.Sign(digest)
+	if err != nil {
+		return nil, fmt.Errorf("can't sign the message: %v", err)
+	}
+
+	return sign, nil
+}
+
 type mockGraphSource struct {
 	bestHeight uint32
 
@@ -535,7 +555,7 @@ func createNodeAnnouncement(priv *btcec.PrivateKey,
 		a.ExtraOpaqueData = extraBytes[0]
 	}
 
-	signer := mock.SingleSigner{Privkey: priv}
+	signer := mockSigner{priv}
 	sig, err := netann.SignAnnouncement(&signer, priv.PubKey(), a)
 	if err != nil {
 		return nil, err
@@ -587,7 +607,7 @@ func createUpdateAnnouncement(blockHeight uint32,
 
 func signUpdate(nodeKey *btcec.PrivateKey, a *lnwire.ChannelUpdate) error {
 	pub := nodeKey.PubKey()
-	signer := mock.SingleSigner{Privkey: nodeKey}
+	signer := mockSigner{nodeKey}
 	sig, err := netann.SignAnnouncement(&signer, pub, a)
 	if err != nil {
 		return err
@@ -629,7 +649,7 @@ func createRemoteChannelAnnouncement(blockHeight uint32,
 	a := createAnnouncementWithoutProof(blockHeight, extraBytes...)
 
 	pub := nodeKeyPriv1.PubKey()
-	signer := mock.SingleSigner{Privkey: nodeKeyPriv1}
+	signer := mockSigner{nodeKeyPriv1}
 	sig, err := netann.SignAnnouncement(&signer, pub, a)
 	if err != nil {
 		return nil, err
@@ -640,7 +660,7 @@ func createRemoteChannelAnnouncement(blockHeight uint32,
 	}
 
 	pub = nodeKeyPriv2.PubKey()
-	signer = mock.SingleSigner{Privkey: nodeKeyPriv2}
+	signer = mockSigner{nodeKeyPriv2}
 	sig, err = netann.SignAnnouncement(&signer, pub, a)
 	if err != nil {
 		return nil, err
@@ -651,7 +671,7 @@ func createRemoteChannelAnnouncement(blockHeight uint32,
 	}
 
 	pub = bitcoinKeyPriv1.PubKey()
-	signer = mock.SingleSigner{Privkey: bitcoinKeyPriv1}
+	signer = mockSigner{bitcoinKeyPriv1}
 	sig, err = netann.SignAnnouncement(&signer, pub, a)
 	if err != nil {
 		return nil, err
@@ -662,7 +682,7 @@ func createRemoteChannelAnnouncement(blockHeight uint32,
 	}
 
 	pub = bitcoinKeyPriv2.PubKey()
-	signer = mock.SingleSigner{Privkey: bitcoinKeyPriv2}
+	signer = mockSigner{bitcoinKeyPriv2}
 	sig, err = netann.SignAnnouncement(&signer, pub, a)
 	if err != nil {
 		return nil, err
@@ -741,7 +761,7 @@ func createTestCtx(startHeight uint32) (*testCtx, func(), error) {
 		RotateTicker:         ticker.NewForce(DefaultSyncerRotationInterval),
 		HistoricalSyncTicker: ticker.NewForce(DefaultHistoricalSyncInterval),
 		NumActiveSyncers:     3,
-		AnnSigner:            &mock.SingleSigner{Privkey: nodeKeyPriv1},
+		AnnSigner:            &mockSigner{nodeKeyPriv1},
 		SubBatchDelay:        time.Second * 5,
 		MinimumBatchSize:     10,
 	}, nodeKeyPub1)
diff --git a/fundingmanager_test.go b/fundingmanager_test.go
index 59faf4480..0bc0e304d 100644
--- a/fundingmanager_test.go
+++ b/fundingmanager_test.go
@@ -33,7 +33,6 @@ import (
 	"github.com/lightningnetwork/lnd/keychain"
 	"github.com/lightningnetwork/lnd/lnpeer"
 	"github.com/lightningnetwork/lnd/lnrpc"
-	"github.com/lightningnetwork/lnd/lntest/mock"
 	"github.com/lightningnetwork/lnd/lnwallet"
 	"github.com/lightningnetwork/lnd/lnwallet/chainfee"
 	"github.com/lightningnetwork/lnd/lnwire"
@@ -55,9 +54,6 @@ const (
 	// maxPending is the maximum number of channels we allow opening to the
 	// same peer in the max pending channels test.
 	maxPending = 4
-
-	// A dummy value to use for the funding broadcast height.
-	fundingBroadcastHeight = 123
 )
 
 var (
@@ -302,14 +298,14 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey,
 	publTxChan := make(chan *wire.MsgTx, 1)
 	shutdownChan := make(chan struct{})
 
-	wc := &mock.WalletController{
-		RootKey: alicePrivKey,
+	wc := &mockWalletController{
+		rootKey: alicePrivKey,
 	}
-	signer := &mock.SingleSigner{
-		Privkey: alicePrivKey,
+	signer := &mockSigner{
+		key: alicePrivKey,
 	}
-	bio := &mock.ChainIO{
-		BestHeight: fundingBroadcastHeight,
+	bio := &mockChainIO{
+		bestHeight: fundingBroadcastHeight,
 	}
 
 	// The mock channel event notifier will receive events for each pending
@@ -329,8 +325,8 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey,
 		return nil, err
 	}
 
-	keyRing := &mock.SecretKeyRing{
-		RootKey: alicePrivKey,
+	keyRing := &mockSecretKeyRing{
+		rootKey: alicePrivKey,
 	}
 
 	lnw, err := createTestWallet(
@@ -3017,7 +3013,7 @@ func TestFundingManagerFundAll(t *testing.T) {
 			Value: btcutil.Amount(
 				0.05 * btcutil.SatoshiPerBitcoin,
 			),
-			PkScript: mock.CoinPkScript,
+			PkScript: coinPkScript,
 			OutPoint: wire.OutPoint{
 				Hash:  chainhash.Hash{},
 				Index: 0,
@@ -3028,7 +3024,7 @@ func TestFundingManagerFundAll(t *testing.T) {
 			Value: btcutil.Amount(
 				0.06 * btcutil.SatoshiPerBitcoin,
 			),
-			PkScript: mock.CoinPkScript,
+			PkScript: coinPkScript,
 			OutPoint: wire.OutPoint{
 				Hash:  chainhash.Hash{},
 				Index: 1,
@@ -3062,7 +3058,7 @@ func TestFundingManagerFundAll(t *testing.T) {
 		alice, bob := setupFundingManagers(t)
 		defer tearDownFundingManagers(t, alice, bob)
 
-		alice.fundingMgr.cfg.Wallet.WalletController.(*mock.WalletController).Utxos = allCoins
+		alice.fundingMgr.cfg.Wallet.WalletController.(*mockWalletController).utxos = allCoins
 
 		// We will consume the channel updates as we go, so no
 		// buffering is needed.
diff --git a/htlcswitch/decayedlog_test.go b/htlcswitch/decayedlog_test.go
index 961eade48..7ebe1f10b 100644
--- a/htlcswitch/decayedlog_test.go
+++ b/htlcswitch/decayedlog_test.go
@@ -10,7 +10,6 @@ import (
 
 	sphinx "github.com/lightningnetwork/lightning-onion"
 	"github.com/lightningnetwork/lnd/chainntnfs"
-	"github.com/lightningnetwork/lnd/lntest/mock"
 )
 
 const (
@@ -29,18 +28,16 @@ func tempDecayedLogPath(t *testing.T) string {
 }
 
 // startup sets up the DecayedLog and possibly the garbage collector.
-func startup(dbPath string, notifier bool) (sphinx.ReplayLog,
-	*mock.ChainNotifier, *sphinx.HashPrefix, error) {
+func startup(dbPath string, notifier bool) (sphinx.ReplayLog, *mockNotifier,
+	*sphinx.HashPrefix, error) {
 
 	var log sphinx.ReplayLog
-	var chainNotifier *mock.ChainNotifier
+	var chainNotifier *mockNotifier
 	if notifier {
 
 		// Create the MockNotifier which triggers the garbage collector
-		chainNotifier = &mock.ChainNotifier{
-			SpendChan: make(chan *chainntnfs.SpendDetail),
-			EpochChan: make(chan *chainntnfs.BlockEpoch, 1),
-			ConfChan:  make(chan *chainntnfs.TxConfirmation),
+		chainNotifier = &mockNotifier{
+			epochChan: make(chan *chainntnfs.BlockEpoch, 1),
 		}
 
 		// Initialize the DecayedLog object
@@ -102,7 +99,7 @@ func TestDecayedLogGarbageCollector(t *testing.T) {
 	// should remove the entry by block 100001.
 
 	// Send block 100000
-	notifier.EpochChan <- &chainntnfs.BlockEpoch{
+	notifier.epochChan <- &chainntnfs.BlockEpoch{
 		Height: 100000,
 	}
 
@@ -117,7 +114,7 @@ func TestDecayedLogGarbageCollector(t *testing.T) {
 	}
 
 	// Send block 100001 (expiry block)
-	notifier.EpochChan <- &chainntnfs.BlockEpoch{
+	notifier.epochChan <- &chainntnfs.BlockEpoch{
 		Height: 100001,
 	}
 
@@ -178,7 +175,7 @@ func TestDecayedLogPersistentGarbageCollector(t *testing.T) {
 
 	// Send a block notification to the garbage collector that expires
 	// the stored CLTV.
-	notifier2.EpochChan <- &chainntnfs.BlockEpoch{
+	notifier2.epochChan <- &chainntnfs.BlockEpoch{
 		Height: int32(100001),
 	}
 
diff --git a/htlcswitch/test_utils.go b/htlcswitch/test_utils.go
index 37925ef9f..ae64cf1bd 100644
--- a/htlcswitch/test_utils.go
+++ b/htlcswitch/test_utils.go
@@ -29,7 +29,6 @@ import (
 	"github.com/lightningnetwork/lnd/input"
 	"github.com/lightningnetwork/lnd/keychain"
 	"github.com/lightningnetwork/lnd/lnpeer"
-	"github.com/lightningnetwork/lnd/lntest/mock"
 	"github.com/lightningnetwork/lnd/lntest/wait"
 	"github.com/lightningnetwork/lnd/lntypes"
 	"github.com/lightningnetwork/lnd/lnwallet"
@@ -377,8 +376,8 @@ func createTestChannel(alicePrivKey, bobPrivKey []byte,
 		os.RemoveAll(alicePath)
 	}
 
-	aliceSigner := &mock.SingleSigner{Privkey: aliceKeyPriv}
-	bobSigner := &mock.SingleSigner{Privkey: bobKeyPriv}
+	aliceSigner := &mockSigner{aliceKeyPriv}
+	bobSigner := &mockSigner{bobKeyPriv}
 
 	alicePool := lnwallet.NewSigPool(runtime.NumCPU(), aliceSigner)
 	channelAlice, err := lnwallet.NewLightningChannel(
diff --git a/lntest/mock/chainio.go b/lntest/mock/chainio.go
deleted file mode 100644
index 1f07056f0..000000000
--- a/lntest/mock/chainio.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package mock
-
-import (
-	"github.com/btcsuite/btcd/chaincfg"
-	"github.com/btcsuite/btcd/chaincfg/chainhash"
-	"github.com/btcsuite/btcd/wire"
-)
-
-// ChainIO is a mock implementation of the BlockChainIO interface.
-type ChainIO struct {
-	BestHeight int32
-}
-
-// GetBestBlock currently returns dummy values.
-func (c *ChainIO) GetBestBlock() (*chainhash.Hash, int32, error) {
-	return chaincfg.TestNet3Params.GenesisHash, c.BestHeight, nil
-}
-
-// GetUtxo currently returns dummy values.
-func (c *ChainIO) GetUtxo(op *wire.OutPoint, _ []byte,
-	heightHint uint32, _ <-chan struct{}) (*wire.TxOut, error) {
-
-	return nil, nil
-}
-
-// GetBlockHash currently returns dummy values.
-func (c *ChainIO) GetBlockHash(blockHeight int64) (*chainhash.Hash, error) {
-	return nil, nil
-}
-
-// GetBlock currently returns dummy values.
-func (c *ChainIO) GetBlock(blockHash *chainhash.Hash) (*wire.MsgBlock, error) {
-	return nil, nil
-}
diff --git a/lntest/mock/chainnotifier.go b/lntest/mock/chainnotifier.go
deleted file mode 100644
index 185d15cd2..000000000
--- a/lntest/mock/chainnotifier.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package mock
-
-import (
-	"github.com/btcsuite/btcd/chaincfg/chainhash"
-	"github.com/btcsuite/btcd/wire"
-
-	"github.com/lightningnetwork/lnd/chainntnfs"
-)
-
-// ChainNotifier is a mock implementation of the ChainNotifier interface.
-type ChainNotifier struct {
-	SpendChan chan *chainntnfs.SpendDetail
-	EpochChan chan *chainntnfs.BlockEpoch
-	ConfChan  chan *chainntnfs.TxConfirmation
-}
-
-// RegisterConfirmationsNtfn returns a ConfirmationEvent that contains a channel
-// that the tx confirmation will go over.
-func (c *ChainNotifier) RegisterConfirmationsNtfn(txid *chainhash.Hash,
-	pkScript []byte, numConfs, heightHint uint32) (*chainntnfs.ConfirmationEvent,
-	error) {
-
-	return &chainntnfs.ConfirmationEvent{
-		Confirmed: c.ConfChan,
-		Cancel:    func() {},
-	}, nil
-}
-
-// RegisterSpendNtfn returns a SpendEvent that contains a channel that the spend
-// details will go over.
-func (c *ChainNotifier) RegisterSpendNtfn(outpoint *wire.OutPoint,
-	pkScript []byte, heightHint uint32) (*chainntnfs.SpendEvent, error) {
-
-	return &chainntnfs.SpendEvent{
-		Spend:  c.SpendChan,
-		Cancel: func() {},
-	}, nil
-}
-
-// RegisterBlockEpochNtfn returns a BlockEpochEvent that contains a channel that
-// block epochs will go over.
-func (c *ChainNotifier) RegisterBlockEpochNtfn(blockEpoch *chainntnfs.BlockEpoch) (
-	*chainntnfs.BlockEpochEvent, error) {
-
-	return &chainntnfs.BlockEpochEvent{
-		Epochs: c.EpochChan,
-		Cancel: func() {},
-	}, nil
-}
-
-// Start currently returns a dummy value.
-func (c *ChainNotifier) Start() error {
-	return nil
-}
-
-// Started currently returns a dummy value.
-func (c *ChainNotifier) Started() bool {
-	return true
-}
-
-// Stop currently returns a dummy value.
-func (c *ChainNotifier) Stop() error {
-	return nil
-}
diff --git a/lntest/mock/secretkeyring.go b/lntest/mock/secretkeyring.go
deleted file mode 100644
index 1c2da65f0..000000000
--- a/lntest/mock/secretkeyring.go
+++ /dev/null
@@ -1,56 +0,0 @@
-package mock
-
-import (
-	"github.com/btcsuite/btcd/btcec"
-
-	"github.com/lightningnetwork/lnd/keychain"
-)
-
-// SecretKeyRing is a mock implementation of the SecretKeyRing interface.
-type SecretKeyRing struct {
-	RootKey *btcec.PrivateKey
-}
-
-// DeriveNextKey currently returns dummy values.
-func (s *SecretKeyRing) DeriveNextKey(keyFam keychain.KeyFamily) (
-	keychain.KeyDescriptor, error) {
-
-	return keychain.KeyDescriptor{
-		PubKey: s.RootKey.PubKey(),
-	}, nil
-}
-
-// DeriveKey currently returns dummy values.
-func (s *SecretKeyRing) DeriveKey(keyLoc keychain.KeyLocator) (keychain.KeyDescriptor,
-	error) {
-	return keychain.KeyDescriptor{
-		PubKey: s.RootKey.PubKey(),
-	}, nil
-}
-
-// DerivePrivKey currently returns dummy values.
-func (s *SecretKeyRing) DerivePrivKey(keyDesc keychain.KeyDescriptor) (*btcec.PrivateKey,
-	error) {
-	return s.RootKey, nil
-}
-
-// ECDH currently returns dummy values.
-func (s *SecretKeyRing) ECDH(_ keychain.KeyDescriptor, pubKey *btcec.PublicKey) ([32]byte,
-	error) {
-
-	return [32]byte{}, nil
-}
-
-// SignDigest signs the passed digest and ignores the KeyDescriptor.
-func (s *SecretKeyRing) SignDigest(_ keychain.KeyDescriptor,
-	digest [32]byte) (*btcec.Signature, error) {
-
-	return s.RootKey.Sign(digest[:])
-}
-
-// SignDigestCompact signs the passed digest.
-func (s *SecretKeyRing) SignDigestCompact(_ keychain.KeyDescriptor,
-	digest [32]byte) ([]byte, error) {
-
-	return btcec.SignCompact(btcec.S256(), s.RootKey, digest[:], true)
-}
diff --git a/lntest/mock/signer.go b/lntest/mock/signer.go
deleted file mode 100644
index c94d4eeb2..000000000
--- a/lntest/mock/signer.go
+++ /dev/null
@@ -1,127 +0,0 @@
-package mock
-
-import (
-	"fmt"
-
-	"github.com/btcsuite/btcd/btcec"
-	"github.com/btcsuite/btcd/chaincfg/chainhash"
-	"github.com/btcsuite/btcd/txscript"
-	"github.com/btcsuite/btcd/wire"
-
-	"github.com/lightningnetwork/lnd/input"
-)
-
-// DummySignature is a dummy Signature implementation.
-type DummySignature struct{}
-
-// Serialize returns an empty byte slice.
-func (d *DummySignature) Serialize() []byte {
-	return []byte{}
-}
-
-// Verify always returns true.
-func (d *DummySignature) Verify(_ []byte, _ *btcec.PublicKey) bool {
-	return true
-}
-
-// DummySigner is an implementation of the Signer interface that returns
-// dummy values when called.
-type DummySigner struct{}
-
-// SignOutputRaw returns a dummy signature.
-func (d *DummySigner) SignOutputRaw(tx *wire.MsgTx,
-	signDesc *input.SignDescriptor) (input.Signature, error) {
-
-	return &DummySignature{}, nil
-}
-
-// ComputeInputScript returns nil for both values.
-func (d *DummySigner) ComputeInputScript(tx *wire.MsgTx,
-	signDesc *input.SignDescriptor) (*input.Script, error) {
-
-	return &input.Script{}, nil
-}
-
-// SingleSigner is an implementation of the Signer interface that signs
-// everything with a single private key.
-type SingleSigner struct {
-	Privkey *btcec.PrivateKey
-}
-
-// SignOutputRaw generates a signature for the passed transaction using the
-// stored private key.
-func (s *SingleSigner) SignOutputRaw(tx *wire.MsgTx,
-	signDesc *input.SignDescriptor) (input.Signature, error) {
-
-	amt := signDesc.Output.Value
-	witnessScript := signDesc.WitnessScript
-	privKey := s.Privkey
-
-	if !privKey.PubKey().IsEqual(signDesc.KeyDesc.PubKey) {
-		return nil, fmt.Errorf("incorrect key passed")
-	}
-
-	switch {
-	case signDesc.SingleTweak != nil:
-		privKey = input.TweakPrivKey(privKey,
-			signDesc.SingleTweak)
-	case signDesc.DoubleTweak != nil:
-		privKey = input.DeriveRevocationPrivKey(privKey,
-			signDesc.DoubleTweak)
-	}
-
-	sig, err := txscript.RawTxInWitnessSignature(tx, signDesc.SigHashes,
-		signDesc.InputIndex, amt, witnessScript, signDesc.HashType,
-		privKey)
-	if err != nil {
-		return nil, err
-	}
-
-	return btcec.ParseDERSignature(sig[:len(sig)-1], btcec.S256())
-}
-
-// ComputeInputScript computes an input script with the stored private key
-// given a transaction and a SignDescriptor.
-func (s *SingleSigner) ComputeInputScript(tx *wire.MsgTx,
-	signDesc *input.SignDescriptor) (*input.Script, error) {
-
-	privKey := s.Privkey
-
-	switch {
-	case signDesc.SingleTweak != nil:
-		privKey = input.TweakPrivKey(privKey,
-			signDesc.SingleTweak)
-	case signDesc.DoubleTweak != nil:
-		privKey = input.DeriveRevocationPrivKey(privKey,
-			signDesc.DoubleTweak)
-	}
-
-	witnessScript, err := txscript.WitnessSignature(tx, signDesc.SigHashes,
-		signDesc.InputIndex, signDesc.Output.Value, signDesc.Output.PkScript,
-		signDesc.HashType, privKey, true)
-	if err != nil {
-		return nil, err
-	}
-
-	return &input.Script{
-		Witness: witnessScript,
-	}, nil
-}
-
-// SignMessage takes a public key and a message and only signs the message
-// with the stored private key if the public key matches the private key.
-func (s *SingleSigner) SignMessage(pubKey *btcec.PublicKey,
-	msg []byte) (input.Signature, error) {
-
-	if !pubKey.IsEqual(s.Privkey.PubKey()) {
-		return nil, fmt.Errorf("unknown public key")
-	}
-
-	digest := chainhash.DoubleHashB(msg)
-	sign, err := s.Privkey.Sign(digest)
-	if err != nil {
-		return nil, fmt.Errorf("can't sign the message: %v", err)
-	}
-
-	return sign, nil
-}
diff --git a/lntest/mock/spendnotifier.go b/lntest/mock/spendnotifier.go
deleted file mode 100644
index 7d51b458d..000000000
--- a/lntest/mock/spendnotifier.go
+++ /dev/null
@@ -1,97 +0,0 @@
-package mock
-
-import (
-	"sync"
-
-	"github.com/btcsuite/btcd/wire"
-
-	"github.com/lightningnetwork/lnd/chainntnfs"
-)
-
-// SpendNotifier extends the mock.ChainNotifier so that spend
-// notifications can be triggered and delivered to subscribers.
-type SpendNotifier struct {
-	*ChainNotifier
-	spendMap map[wire.OutPoint][]chan *chainntnfs.SpendDetail
-	spends   map[wire.OutPoint]*chainntnfs.SpendDetail
-	mtx      sync.Mutex
-}
-
-// MakeMockSpendNotifier creates a SpendNotifier.
-func MakeMockSpendNotifier() *SpendNotifier {
-	return &SpendNotifier{
-		ChainNotifier: &ChainNotifier{
-			SpendChan: make(chan *chainntnfs.SpendDetail),
-			EpochChan: make(chan *chainntnfs.BlockEpoch),
-			ConfChan:  make(chan *chainntnfs.TxConfirmation),
-		},
-		spendMap: make(map[wire.OutPoint][]chan *chainntnfs.SpendDetail),
-		spends:   make(map[wire.OutPoint]*chainntnfs.SpendDetail),
-	}
-}
-
-// RegisterSpendNtfn registers a spend notification for a specified outpoint.
-func (s *SpendNotifier) RegisterSpendNtfn(outpoint *wire.OutPoint,
-	_ []byte, heightHint uint32) (*chainntnfs.SpendEvent, error) {
-
-	s.mtx.Lock()
-	defer s.mtx.Unlock()
-
-	spendChan := make(chan *chainntnfs.SpendDetail, 1)
-	if detail, ok := s.spends[*outpoint]; ok {
-		// Deliver spend immediately if details are already known.
-		spendChan <- &chainntnfs.SpendDetail{
-			SpentOutPoint:     detail.SpentOutPoint,
-			SpendingHeight:    detail.SpendingHeight,
-			SpendingTx:        detail.SpendingTx,
-			SpenderTxHash:     detail.SpenderTxHash,
-			SpenderInputIndex: detail.SpenderInputIndex,
-		}
-	} else {
-		// Otherwise, queue the notification for delivery if the spend
-		// is ever received.
-		s.spendMap[*outpoint] = append(s.spendMap[*outpoint], spendChan)
-	}
-
-	return &chainntnfs.SpendEvent{
-		Spend:  spendChan,
-		Cancel: func() {},
-	}, nil
-}
-
-// Spend dispatches SpendDetails to all subscribers of the outpoint. The details
-// will includethe transaction and height provided by the caller.
-func (s *SpendNotifier) Spend(outpoint *wire.OutPoint, height int32,
-	txn *wire.MsgTx) {
-
-	s.mtx.Lock()
-	defer s.mtx.Unlock()
-
-	txnHash := txn.TxHash()
-	details := &chainntnfs.SpendDetail{
-		SpentOutPoint:     outpoint,
-		SpendingHeight:    height,
-		SpendingTx:        txn,
-		SpenderTxHash:     &txnHash,
-		SpenderInputIndex: outpoint.Index,
-	}
-
-	// Cache details in case of late registration.
-	if _, ok := s.spends[*outpoint]; !ok {
-		s.spends[*outpoint] = details
-	}
-
-	// Deliver any backlogged spend notifications.
-	if spendChans, ok := s.spendMap[*outpoint]; ok {
-		delete(s.spendMap, *outpoint)
-		for _, spendChan := range spendChans {
-			spendChan <- &chainntnfs.SpendDetail{
-				SpentOutPoint:     details.SpentOutPoint,
-				SpendingHeight:    details.SpendingHeight,
-				SpendingTx:        details.SpendingTx,
-				SpenderTxHash:     details.SpenderTxHash,
-				SpenderInputIndex: details.SpenderInputIndex,
-			}
-		}
-	}
-}
diff --git a/lntest/mock/walletcontroller.go b/lntest/mock/walletcontroller.go
deleted file mode 100644
index 5aea2135c..000000000
--- a/lntest/mock/walletcontroller.go
+++ /dev/null
@@ -1,182 +0,0 @@
-package mock
-
-import (
-	"encoding/hex"
-	"sync/atomic"
-	"time"
-
-	"github.com/btcsuite/btcd/btcec"
-	"github.com/btcsuite/btcd/chaincfg"
-	"github.com/btcsuite/btcd/chaincfg/chainhash"
-	"github.com/btcsuite/btcd/wire"
-	"github.com/btcsuite/btcutil"
-	"github.com/btcsuite/btcwallet/wallet/txauthor"
-	"github.com/btcsuite/btcwallet/wtxmgr"
-
-	"github.com/lightningnetwork/lnd/lnwallet"
-	"github.com/lightningnetwork/lnd/lnwallet/chainfee"
-)
-
-var (
-	CoinPkScript, _ = hex.DecodeString("001431df1bde03c074d0cf21ea2529427e1499b8f1de")
-)
-
-// WalletController is a mock implementation of the WalletController
-// interface. It let's us mock the interaction with the bitcoin network.
-type WalletController struct {
-	RootKey               *btcec.PrivateKey
-	PublishedTransactions chan *wire.MsgTx
-	index                 uint32
-	Utxos                 []*lnwallet.Utxo
-}
-
-// BackEnd returns "mock" to signify a mock wallet controller.
-func (w *WalletController) BackEnd() string {
-	return "mock"
-}
-
-// FetchInputInfo will be called to get info about the inputs to the funding
-// transaction.
-func (w *WalletController) FetchInputInfo(
-	prevOut *wire.OutPoint) (*lnwallet.Utxo, error) {
-
-	utxo := &lnwallet.Utxo{
-		AddressType:   lnwallet.WitnessPubKey,
-		Value:         10 * btcutil.SatoshiPerBitcoin,
-		PkScript:      []byte("dummy"),
-		Confirmations: 1,
-		OutPoint:      *prevOut,
-	}
-	return utxo, nil
-}
-
-// ConfirmedBalance currently returns dummy values.
-func (w *WalletController) ConfirmedBalance(confs int32) (btcutil.Amount, error) {
-	return 0, nil
-}
-
-// NewAddress is called to get new addresses for delivery, change etc.
-func (w *WalletController) NewAddress(addrType lnwallet.AddressType,
-	change bool) (btcutil.Address, error) {
-
-	addr, _ := btcutil.NewAddressPubKey(
-		w.RootKey.PubKey().SerializeCompressed(), &chaincfg.MainNetParams,
-	)
-	return addr, nil
-}
-
-// LastUnusedAddress currently returns dummy values.
-func (w *WalletController) LastUnusedAddress(addrType lnwallet.AddressType) (
-	btcutil.Address, error) {
-	return nil, nil
-}
-
-// IsOurAddress currently returns a dummy value.
-func (w *WalletController) IsOurAddress(a btcutil.Address) bool {
-	return false
-}
-
-// SendOutputs currently returns dummy values.
-func (w *WalletController) SendOutputs(outputs []*wire.TxOut,
-	_ chainfee.SatPerKWeight, _ string) (*wire.MsgTx, error) {
-
-	return nil, nil
-}
-
-// CreateSimpleTx currently returns dummy values.
-func (w *WalletController) CreateSimpleTx(outputs []*wire.TxOut,
-	_ chainfee.SatPerKWeight, _ bool) (*txauthor.AuthoredTx, error) {
-
-	return nil, nil
-}
-
-// ListUnspentWitness is called by the wallet when doing coin selection. We just
-// need one unspent for the funding transaction.
-func (w *WalletController) ListUnspentWitness(minconfirms,
-	maxconfirms int32) ([]*lnwallet.Utxo, error) {
-
-	// If the mock already has a list of utxos, return it.
-	if w.Utxos != nil {
-		return w.Utxos, nil
-	}
-
-	// Otherwise create one to return.
-	utxo := &lnwallet.Utxo{
-		AddressType: lnwallet.WitnessPubKey,
-		Value:       btcutil.Amount(10 * btcutil.SatoshiPerBitcoin),
-		PkScript:    CoinPkScript,
-		OutPoint: wire.OutPoint{
-			Hash:  chainhash.Hash{},
-			Index: w.index,
-		},
-	}
-	atomic.AddUint32(&w.index, 1)
-	var ret []*lnwallet.Utxo
-	ret = append(ret, utxo)
-	return ret, nil
-}
-
-// ListTransactionDetails currently returns dummy values.
-func (w *WalletController) ListTransactionDetails(_,
-	_ int32) ([]*lnwallet.TransactionDetail, error) {
-
-	return nil, nil
-}
-
-// LockOutpoint currently does nothing.
-func (w *WalletController) LockOutpoint(o wire.OutPoint) {}
-
-// UnlockOutpoint currently does nothing.
-func (w *WalletController) UnlockOutpoint(o wire.OutPoint) {}
-
-// LeaseOutput returns the current time and a nil error.
-func (w *WalletController) LeaseOutput(wtxmgr.LockID, wire.OutPoint) (time.Time,
-	error) {
-
-	return time.Now(), nil
-}
-
-// ReleaseOutput currently does nothing.
-func (w *WalletController) ReleaseOutput(wtxmgr.LockID, wire.OutPoint) error {
-	return nil
-}
-
-// PublishTransaction sends a transaction to the PublishedTransactions chan.
-func (w *WalletController) PublishTransaction(tx *wire.MsgTx, _ string) error {
-	w.PublishedTransactions <- tx
-	return nil
-}
-
-// LabelTransaction currently does nothing.
-func (w *WalletController) LabelTransaction(_ chainhash.Hash, _ string,
-	_ bool) error {
-
-	return nil
-}
-
-// SubscribeTransactions currently does nothing.
-func (w *WalletController) SubscribeTransactions() (lnwallet.TransactionSubscription,
-	error) {
-
-	return nil, nil
-}
-
-// IsSynced currently returns dummy values.
-func (w *WalletController) IsSynced() (bool, int64, error) {
-	return true, int64(0), nil
-}
-
-// GetRecoveryInfo currently returns dummy values.
-func (w *WalletController) GetRecoveryInfo() (bool, float64, error) {
-	return true, float64(1), nil
-}
-
-// Start currently does nothing.
-func (w *WalletController) Start() error {
-	return nil
-}
-
-// Stop currently does nothing.
-func (w *WalletController) Stop() error {
-	return nil
-}
diff --git a/lnwallet/channel_test.go b/lnwallet/channel_test.go
index 190e31c12..f076ae3a0 100644
--- a/lnwallet/channel_test.go
+++ b/lnwallet/channel_test.go
@@ -683,37 +683,14 @@ func testCommitHTLCSigTieBreak(t *testing.T, restart bool) {
 	}
 }
 
-// TestCooperativeChannelClosure checks that the coop close process finishes
-// with an agreement from both parties, and that the final balances of the
-// close tx check out.
 func TestCooperativeChannelClosure(t *testing.T) {
-	t.Run("tweakless", func(t *testing.T) {
-		testCoopClose(t, &coopCloseTestCase{
-			chanType: channeldb.SingleFunderTweaklessBit,
-		})
-	})
-	t.Run("anchors", func(t *testing.T) {
-		testCoopClose(t, &coopCloseTestCase{
-			chanType: channeldb.SingleFunderTweaklessBit |
-				channeldb.AnchorOutputsBit,
-			anchorAmt: anchorSize * 2,
-		})
-	})
-}
-
-type coopCloseTestCase struct {
-	chanType  channeldb.ChannelType
-	anchorAmt btcutil.Amount
-}
-
-func testCoopClose(t *testing.T, testCase *coopCloseTestCase) {
 	t.Parallel()
 
 	// Create a test channel which will be used for the duration of this
 	// unittest. The channel will be funded evenly with Alice having 5 BTC,
 	// and Bob having 5 BTC.
 	aliceChannel, bobChannel, cleanUp, err := CreateTestChannels(
-		testCase.chanType,
+		channeldb.SingleFunderTweaklessBit,
 	)
 	if err != nil {
 		t.Fatalf("unable to create test channels: %v", err)
@@ -730,7 +707,7 @@ func testCoopClose(t *testing.T, testCase *coopCloseTestCase) {
 		bobChannel.channelState.LocalCommitment.FeePerKw,
 	)
 
-	// We'll start with both Alice and Bob creating a new close proposal
+	// We'll store with both Alice and Bob creating a new close proposal
 	// with the same fee.
 	aliceFee := aliceChannel.CalcFee(aliceFeeRate)
 	aliceSig, _, _, err := aliceChannel.CreateCloseProposal(
@@ -751,7 +728,7 @@ func testCoopClose(t *testing.T, testCase *coopCloseTestCase) {
 	// With the proposals created, both sides should be able to properly
 	// process the other party's signature. This indicates that the
 	// transaction is well formed, and the signatures verify.
-	aliceCloseTx, bobTxBalance, err := bobChannel.CompleteCooperativeClose(
+	aliceCloseTx, _, err := bobChannel.CompleteCooperativeClose(
 		bobSig, aliceSig, bobDeliveryScript, aliceDeliveryScript,
 		bobFee,
 	)
@@ -760,7 +737,7 @@ func testCoopClose(t *testing.T, testCase *coopCloseTestCase) {
 	}
 	bobCloseSha := aliceCloseTx.TxHash()
 
-	bobCloseTx, aliceTxBalance, err := aliceChannel.CompleteCooperativeClose(
+	bobCloseTx, _, err := aliceChannel.CompleteCooperativeClose(
 		aliceSig, bobSig, aliceDeliveryScript, bobDeliveryScript,
 		aliceFee,
 	)
@@ -772,32 +749,6 @@ func testCoopClose(t *testing.T, testCase *coopCloseTestCase) {
 	if bobCloseSha != aliceCloseSha {
 		t.Fatalf("alice and bob close transactions don't match: %v", err)
 	}
-
-	// Finally, make sure the final balances are correct from both's
-	// perspective.
-	aliceBalance := aliceChannel.channelState.LocalCommitment.
-		LocalBalance.ToSatoshis()
-
-	// The commit balance have had the initiator's (Alice) commitfee and
-	// any anchors subtracted, so add that back to the final expected
-	// balance. Alice also pays the coop close fee, so that must be
-	// subtracted.
-	commitFee := aliceChannel.channelState.LocalCommitment.CommitFee
-	expBalanceAlice := aliceBalance + commitFee +
-		testCase.anchorAmt - bobFee
-	if aliceTxBalance != expBalanceAlice {
-		t.Fatalf("expected balance %v got %v", expBalanceAlice,
-			aliceTxBalance)
-	}
-
-	// Bob is not the initiator, so his final balance should simply be
-	// equal to the latest commitment balance.
-	expBalanceBob := bobChannel.channelState.LocalCommitment.
-		LocalBalance.ToSatoshis()
-	if bobTxBalance != expBalanceBob {
-		t.Fatalf("expected bob's balance to be %v got %v",
-			expBalanceBob, bobTxBalance)
-	}
 }
 
 // TestForceClose checks that the resulting ForceCloseSummary is correct when a
@@ -2230,11 +2181,11 @@ func TestCooperativeCloseDustAdherence(t *testing.T) {
 			"got %v", 2, len(closeTx.TxOut))
 	}
 
-	// We'll reset the channel states before proceeding to our next test.
+	// We'll reset the channel states before proceeding to our nest test.
 	resetChannelState()
 
 	// Next we'll modify the current balances and dust limits such that
-	// Bob's current balance is _below_ his dust limit.
+	// Bob's current balance is above _below_ his dust limit.
 	aliceBal := lnwire.NewMSatFromSatoshis(btcutil.SatoshiPerBitcoin)
 	bobBal := lnwire.NewMSatFromSatoshis(250)
 	setBalances(aliceBal, bobBal)
@@ -2277,24 +2228,9 @@ func TestCooperativeCloseDustAdherence(t *testing.T) {
 			int64(closeTx.TxOut[0].Value))
 	}
 
-	// We'll modify the current balances and dust limits such that
-	// Alice's current balance is too low to pay the proposed fee.
-	setBalances(bobBal, aliceBal)
-	resetChannelState()
-
-	// Attempting to close with this fee now should fail, since Alice
-	// cannot afford it.
-	_, _, _, err = aliceChannel.CreateCloseProposal(
-		aliceFee, aliceDeliveryScript, bobDeliveryScript,
-	)
-	if err == nil {
-		t.Fatalf("expected error")
-	}
-
 	// Finally, we'll modify the current balances and dust limits such that
-	// Alice's balance after paying the coop fee is _below_ her dust limit.
-	lowBalance := lnwire.NewMSatFromSatoshis(aliceFee) + 1000
-	setBalances(lowBalance, aliceBal)
+	// Alice's current balance is _below_ his her limit.
+	setBalances(bobBal, aliceBal)
 	resetChannelState()
 
 	// Our final attempt at another cooperative channel closure. It should
diff --git a/peer/brontide_test.go b/peer/brontide_test.go
index 6150fe276..78800b115 100644
--- a/peer/brontide_test.go
+++ b/peer/brontide_test.go
@@ -12,7 +12,6 @@ import (
 	"github.com/lightningnetwork/lnd/chainntnfs"
 	"github.com/lightningnetwork/lnd/channeldb"
 	"github.com/lightningnetwork/lnd/htlcswitch"
-	"github.com/lightningnetwork/lnd/lntest/mock"
 	"github.com/lightningnetwork/lnd/lnwallet/chancloser"
 	"github.com/lightningnetwork/lnd/lnwire"
 )
@@ -34,10 +33,8 @@ var (
 func TestPeerChannelClosureAcceptFeeResponder(t *testing.T) {
 	t.Parallel()
 
-	notifier := &mock.ChainNotifier{
-		SpendChan: make(chan *chainntnfs.SpendDetail),
-		EpochChan: make(chan *chainntnfs.BlockEpoch),
-		ConfChan:  make(chan *chainntnfs.TxConfirmation),
+	notifier := &mockNotifier{
+		confChannel: make(chan *chainntnfs.TxConfirmation),
 	}
 	broadcastTxChan := make(chan *wire.MsgTx)
 
@@ -129,7 +126,7 @@ func TestPeerChannelClosureAcceptFeeResponder(t *testing.T) {
 	}
 
 	// Alice should be waiting in a goroutine for a confirmation.
-	notifier.ConfChan <- &chainntnfs.TxConfirmation{}
+	notifier.confChannel <- &chainntnfs.TxConfirmation{}
 }
 
 // TestPeerChannelClosureAcceptFeeInitiator tests the shutdown initiator's
@@ -137,10 +134,8 @@ func TestPeerChannelClosureAcceptFeeResponder(t *testing.T) {
 func TestPeerChannelClosureAcceptFeeInitiator(t *testing.T) {
 	t.Parallel()
 
-	notifier := &mock.ChainNotifier{
-		SpendChan: make(chan *chainntnfs.SpendDetail),
-		EpochChan: make(chan *chainntnfs.BlockEpoch),
-		ConfChan:  make(chan *chainntnfs.TxConfirmation),
+	notifier := &mockNotifier{
+		confChannel: make(chan *chainntnfs.TxConfirmation),
 	}
 	broadcastTxChan := make(chan *wire.MsgTx)
 
@@ -250,7 +245,7 @@ func TestPeerChannelClosureAcceptFeeInitiator(t *testing.T) {
 	}
 
 	// Alice should be waiting on a single confirmation for the coop close tx.
-	notifier.ConfChan <- &chainntnfs.TxConfirmation{}
+	notifier.confChannel <- &chainntnfs.TxConfirmation{}
 }
 
 // TestPeerChannelClosureFeeNegotiationsResponder tests the shutdown
@@ -259,10 +254,8 @@ func TestPeerChannelClosureAcceptFeeInitiator(t *testing.T) {
 func TestPeerChannelClosureFeeNegotiationsResponder(t *testing.T) {
 	t.Parallel()
 
-	notifier := &mock.ChainNotifier{
-		SpendChan: make(chan *chainntnfs.SpendDetail),
-		EpochChan: make(chan *chainntnfs.BlockEpoch),
-		ConfChan:  make(chan *chainntnfs.TxConfirmation),
+	notifier := &mockNotifier{
+		confChannel: make(chan *chainntnfs.TxConfirmation),
 	}
 	broadcastTxChan := make(chan *wire.MsgTx)
 
@@ -444,7 +437,7 @@ func TestPeerChannelClosureFeeNegotiationsResponder(t *testing.T) {
 	}
 
 	// Alice should be waiting on a single confirmation for the coop close tx.
-	notifier.ConfChan <- &chainntnfs.TxConfirmation{}
+	notifier.confChannel <- &chainntnfs.TxConfirmation{}
 }
 
 // TestPeerChannelClosureFeeNegotiationsInitiator tests the shutdown
@@ -453,10 +446,8 @@ func TestPeerChannelClosureFeeNegotiationsResponder(t *testing.T) {
 func TestPeerChannelClosureFeeNegotiationsInitiator(t *testing.T) {
 	t.Parallel()
 
-	notifier := &mock.ChainNotifier{
-		SpendChan: make(chan *chainntnfs.SpendDetail),
-		EpochChan: make(chan *chainntnfs.BlockEpoch),
-		ConfChan:  make(chan *chainntnfs.TxConfirmation),
+	notifier := &mockNotifier{
+		confChannel: make(chan *chainntnfs.TxConfirmation),
 	}
 	broadcastTxChan := make(chan *wire.MsgTx)
 
@@ -651,7 +642,7 @@ func TestPeerChannelClosureFeeNegotiationsInitiator(t *testing.T) {
 	}
 
 	// Alice should be waiting on a single confirmation for the coop close tx.
-	notifier.ConfChan <- &chainntnfs.TxConfirmation{}
+	notifier.confChannel <- &chainntnfs.TxConfirmation{}
 }
 
 // TestChooseDeliveryScript tests that chooseDeliveryScript correctly errors
@@ -788,10 +779,8 @@ func TestCustomShutdownScript(t *testing.T) {
 		test := test
 
 		t.Run(test.name, func(t *testing.T) {
-			notifier := &mock.ChainNotifier{
-				SpendChan: make(chan *chainntnfs.SpendDetail),
-				EpochChan: make(chan *chainntnfs.BlockEpoch),
-				ConfChan:  make(chan *chainntnfs.TxConfirmation),
+			notifier := &mockNotifier{
+				confChannel: make(chan *chainntnfs.TxConfirmation),
 			}
 			broadcastTxChan := make(chan *wire.MsgTx)
 
diff --git a/peer/test_utils.go b/peer/test_utils.go
index 08c4557de..df74eda11 100644
--- a/peer/test_utils.go
+++ b/peer/test_utils.go
@@ -4,6 +4,7 @@ import (
 	"bytes"
 	crand "crypto/rand"
 	"encoding/binary"
+	"fmt"
 	"io"
 	"io/ioutil"
 	"math/rand"
@@ -12,15 +13,18 @@ import (
 	"time"
 
 	"github.com/btcsuite/btcd/btcec"
+	"github.com/btcsuite/btcd/chaincfg"
 	"github.com/btcsuite/btcd/chaincfg/chainhash"
+	"github.com/btcsuite/btcd/txscript"
 	"github.com/btcsuite/btcd/wire"
 	"github.com/btcsuite/btcutil"
+	"github.com/btcsuite/btcwallet/wallet/txauthor"
+	"github.com/btcsuite/btcwallet/wtxmgr"
 	"github.com/lightningnetwork/lnd/chainntnfs"
 	"github.com/lightningnetwork/lnd/channeldb"
 	"github.com/lightningnetwork/lnd/htlcswitch"
 	"github.com/lightningnetwork/lnd/input"
 	"github.com/lightningnetwork/lnd/keychain"
-	"github.com/lightningnetwork/lnd/lntest/mock"
 	"github.com/lightningnetwork/lnd/lnwallet"
 	"github.com/lightningnetwork/lnd/lnwallet/chainfee"
 	"github.com/lightningnetwork/lnd/lnwire"
@@ -99,6 +103,252 @@ var (
 // call the setup code with no custom values on the channels set up.
 var noUpdate = func(a, b *channeldb.OpenChannel) {}
 
+type mockSigner struct {
+	key *btcec.PrivateKey
+}
+
+func (m *mockSigner) SignOutputRaw(tx *wire.MsgTx,
+	signDesc *input.SignDescriptor) (input.Signature, error) {
+	amt := signDesc.Output.Value
+	witnessScript := signDesc.WitnessScript
+	privKey := m.key
+
+	if !privKey.PubKey().IsEqual(signDesc.KeyDesc.PubKey) {
+		return nil, fmt.Errorf("incorrect key passed")
+	}
+
+	switch {
+	case signDesc.SingleTweak != nil:
+		privKey = input.TweakPrivKey(privKey,
+			signDesc.SingleTweak)
+	case signDesc.DoubleTweak != nil:
+		privKey = input.DeriveRevocationPrivKey(privKey,
+			signDesc.DoubleTweak)
+	}
+
+	sig, err := txscript.RawTxInWitnessSignature(tx, signDesc.SigHashes,
+		signDesc.InputIndex, amt, witnessScript, signDesc.HashType,
+		privKey)
+	if err != nil {
+		return nil, err
+	}
+
+	return btcec.ParseDERSignature(sig[:len(sig)-1], btcec.S256())
+}
+
+func (m *mockSigner) ComputeInputScript(tx *wire.MsgTx,
+	signDesc *input.SignDescriptor) (*input.Script, error) {
+
+	// TODO(roasbeef): expose tweaked signer from lnwallet so don't need to
+	// duplicate this code?
+
+	privKey := m.key
+
+	switch {
+	case signDesc.SingleTweak != nil:
+		privKey = input.TweakPrivKey(privKey,
+			signDesc.SingleTweak)
+	case signDesc.DoubleTweak != nil:
+		privKey = input.DeriveRevocationPrivKey(privKey,
+			signDesc.DoubleTweak)
+	}
+
+	witnessScript, err := txscript.WitnessSignature(tx, signDesc.SigHashes,
+		signDesc.InputIndex, signDesc.Output.Value, signDesc.Output.PkScript,
+		signDesc.HashType, privKey, true)
+	if err != nil {
+		return nil, err
+	}
+
+	return &input.Script{
+		Witness: witnessScript,
+	}, nil
+}
+
+var _ input.Signer = (*mockSigner)(nil)
+
+type mockChainIO struct {
+	bestHeight int32
+}
+
+func (m *mockChainIO) GetBestBlock() (*chainhash.Hash, int32, error) {
+	return nil, m.bestHeight, nil
+}
+
+func (*mockChainIO) GetUtxo(op *wire.OutPoint, _ []byte,
+	heightHint uint32, _ <-chan struct{}) (*wire.TxOut, error) {
+	return nil, nil
+}
+
+func (*mockChainIO) GetBlockHash(blockHeight int64) (*chainhash.Hash, error) {
+	return nil, nil
+}
+
+func (*mockChainIO) GetBlock(blockHash *chainhash.Hash) (*wire.MsgBlock, error) {
+	return nil, nil
+}
+
+var _ lnwallet.BlockChainIO = (*mockChainIO)(nil)
+
+type mockWalletController struct {
+	rootKey       *btcec.PrivateKey
+	publishedTxns chan *wire.MsgTx
+}
+
+func (*mockWalletController) FetchInputInfo(prevOut *wire.OutPoint) (
+	*lnwallet.Utxo, error) {
+
+	return nil, nil
+}
+
+func (*mockWalletController) ConfirmedBalance(confs int32) (btcutil.Amount,
+	error) {
+
+	return 0, nil
+}
+
+func (m *mockWalletController) NewAddress(addrType lnwallet.AddressType,
+	change bool) (btcutil.Address, error) {
+
+	addr, _ := btcutil.NewAddressPubKey(
+		m.rootKey.PubKey().SerializeCompressed(), &chaincfg.MainNetParams,
+	)
+	return addr, nil
+}
+
+func (*mockWalletController) LastUnusedAddress(addrType lnwallet.AddressType) (
+	btcutil.Address, error) {
+
+	return nil, nil
+}
+
+func (*mockWalletController) IsOurAddress(a btcutil.Address) bool {
+	return false
+}
+
+func (*mockWalletController) SendOutputs(outputs []*wire.TxOut,
+	feeRate chainfee.SatPerKWeight, label string) (*wire.MsgTx, error) {
+
+	return nil, nil
+}
+
+func (*mockWalletController) CreateSimpleTx(outputs []*wire.TxOut,
+	feeRate chainfee.SatPerKWeight, dryRun bool) (*txauthor.AuthoredTx, error) {
+
+	return nil, nil
+}
+
+func (*mockWalletController) ListUnspentWitness(minconfirms,
+	maxconfirms int32) ([]*lnwallet.Utxo, error) {
+
+	return nil, nil
+}
+
+func (*mockWalletController) ListTransactionDetails(startHeight,
+	endHeight int32) ([]*lnwallet.TransactionDetail, error) {
+
+	return nil, nil
+}
+
+func (*mockWalletController) LockOutpoint(o wire.OutPoint) {}
+
+func (*mockWalletController) UnlockOutpoint(o wire.OutPoint) {}
+
+func (m *mockWalletController) PublishTransaction(tx *wire.MsgTx,
+	label string) error {
+	m.publishedTxns <- tx
+	return nil
+}
+
+func (*mockWalletController) LabelTransaction(hash chainhash.Hash,
+	label string, overwrite bool) error {
+
+	return nil
+}
+
+func (*mockWalletController) SubscribeTransactions() (
+	lnwallet.TransactionSubscription, error) {
+
+	return nil, nil
+}
+
+func (*mockWalletController) IsSynced() (bool, int64, error) {
+	return false, 0, nil
+}
+
+func (*mockWalletController) Start() error {
+	return nil
+}
+
+func (*mockWalletController) Stop() error {
+	return nil
+}
+
+func (*mockWalletController) BackEnd() string {
+	return ""
+}
+
+func (*mockWalletController) LeaseOutput(wtxmgr.LockID,
+	wire.OutPoint) (time.Time, error) {
+
+	return time.Now(), nil
+}
+
+func (*mockWalletController) ReleaseOutput(wtxmgr.LockID, wire.OutPoint) error {
+	return nil
+}
+
+func (*mockWalletController) GetRecoveryInfo() (bool, float64, error) {
+	return false, 0, nil
+}
+
+var _ lnwallet.WalletController = (*mockWalletController)(nil)
+
+type mockNotifier struct {
+	confChannel chan *chainntnfs.TxConfirmation
+}
+
+func (m *mockNotifier) RegisterConfirmationsNtfn(txid *chainhash.Hash,
+	_ []byte, numConfs, heightHint uint32) (*chainntnfs.ConfirmationEvent,
+	error) {
+
+	return &chainntnfs.ConfirmationEvent{
+		Confirmed: m.confChannel,
+	}, nil
+}
+
+func (m *mockNotifier) RegisterSpendNtfn(outpoint *wire.OutPoint, _ []byte,
+	heightHint uint32) (*chainntnfs.SpendEvent, error) {
+
+	return &chainntnfs.SpendEvent{
+		Spend:  make(chan *chainntnfs.SpendDetail),
+		Cancel: func() {},
+	}, nil
+}
+
+func (m *mockNotifier) RegisterBlockEpochNtfn(
+	bestBlock *chainntnfs.BlockEpoch) (*chainntnfs.BlockEpochEvent, error) {
+
+	return &chainntnfs.BlockEpochEvent{
+		Epochs: make(chan *chainntnfs.BlockEpoch),
+		Cancel: func() {},
+	}, nil
+}
+
+func (m *mockNotifier) Start() error {
+	return nil
+}
+
+func (m *mockNotifier) Stop() error {
+	return nil
+}
+
+func (m *mockNotifier) Started() bool {
+	return true
+}
+
+var _ chainntnfs.ChainNotifier = (*mockNotifier)(nil)
+
 // createTestPeer creates a channel between two nodes, and returns a peer for
 // one of the nodes, together with the channel seen from both nodes. It takes
 // an updateChan function which can be used to modify the default values on
@@ -325,8 +575,8 @@ func createTestPeer(notifier chainntnfs.ChainNotifier,
 		os.RemoveAll(alicePath)
 	}
 
-	aliceSigner := &mock.SingleSigner{Privkey: aliceKeyPriv}
-	bobSigner := &mock.SingleSigner{Privkey: bobKeyPriv}
+	aliceSigner := &mockSigner{aliceKeyPriv}
+	bobSigner := &mockSigner{bobKeyPriv}
 
 	alicePool := lnwallet.NewSigPool(1, aliceSigner)
 	channelAlice, err := lnwallet.NewLightningChannel(
@@ -346,13 +596,13 @@ func createTestPeer(notifier chainntnfs.ChainNotifier,
 	}
 	_ = bobPool.Start()
 
-	chainIO := &mock.ChainIO{
-		BestHeight: broadcastHeight,
+	chainIO := &mockChainIO{
+		bestHeight: broadcastHeight,
 	}
 	wallet := &lnwallet.LightningWallet{
-		WalletController: &mock.WalletController{
-			RootKey:               aliceKeyPriv,
-			PublishedTransactions: publTx,
+		WalletController: &mockWalletController{
+			rootKey:       aliceKeyPriv,
+			publishedTxns: publTx,
 		},
 	}
 
diff --git a/sweep/sweeper_test.go b/sweep/sweeper_test.go
index d7b6ab131..eaffec404 100644
--- a/sweep/sweeper_test.go
+++ b/sweep/sweeper_test.go
@@ -14,7 +14,6 @@ import (
 	"github.com/lightningnetwork/lnd/build"
 	"github.com/lightningnetwork/lnd/input"
 	"github.com/lightningnetwork/lnd/keychain"
-	"github.com/lightningnetwork/lnd/lntest/mock"
 	"github.com/lightningnetwork/lnd/lnwallet"
 	"github.com/lightningnetwork/lnd/lnwallet/chainfee"
 )
@@ -129,7 +128,7 @@ func createSweeperTestContext(t *testing.T) *sweeperTestContext {
 			return c
 		},
 		Store:  store,
-		Signer: &mock.DummySigner{},
+		Signer: &mockSigner{},
 		GenSweepScript: func() ([]byte, error) {
 			script := []byte{outputScriptCount}
 			outputScriptCount++
diff --git a/sweep/test_utils.go b/sweep/test_utils.go
index 2fd916c8e..5b83d730e 100644
--- a/sweep/test_utils.go
+++ b/sweep/test_utils.go
@@ -6,9 +6,11 @@ import (
 	"testing"
 	"time"
 
+	"github.com/btcsuite/btcd/btcec"
 	"github.com/btcsuite/btcd/chaincfg/chainhash"
 	"github.com/btcsuite/btcd/wire"
 	"github.com/lightningnetwork/lnd/chainntnfs"
+	"github.com/lightningnetwork/lnd/input"
 )
 
 var (
@@ -17,6 +19,31 @@ var (
 	mockChainHeight    = int32(100)
 )
 
+type dummySignature struct{}
+
+func (s *dummySignature) Serialize() []byte {
+	return []byte{}
+}
+
+func (s *dummySignature) Verify(_ []byte, _ *btcec.PublicKey) bool {
+	return true
+}
+
+type mockSigner struct {
+}
+
+func (m *mockSigner) SignOutputRaw(tx *wire.MsgTx,
+	signDesc *input.SignDescriptor) (input.Signature, error) {
+
+	return &dummySignature{}, nil
+}
+
+func (m *mockSigner) ComputeInputScript(tx *wire.MsgTx,
+	signDesc *input.SignDescriptor) (*input.Script, error) {
+
+	return &input.Script{}, nil
+}
+
 // MockNotifier simulates the chain notifier for test purposes. This type is
 // exported because it is used in nursery tests.
 type MockNotifier struct {
diff --git a/sweep/walletsweep_test.go b/sweep/walletsweep_test.go
index 4e0987579..acd99c6a5 100644
--- a/sweep/walletsweep_test.go
+++ b/sweep/walletsweep_test.go
@@ -9,7 +9,6 @@ import (
 	"github.com/btcsuite/btcd/txscript"
 	"github.com/btcsuite/btcd/wire"
 	"github.com/btcsuite/btcutil"
-	"github.com/lightningnetwork/lnd/lntest/mock"
 	"github.com/lightningnetwork/lnd/lnwallet"
 	"github.com/lightningnetwork/lnd/lnwallet/chainfee"
 )
@@ -336,7 +335,7 @@ func TestCraftSweepAllTx(t *testing.T) {
 
 	// First, we'll make a mock signer along with a fee estimator, We'll
 	// use zero fees to we can assert a precise output value.
-	signer := &mock.DummySigner{}
+	signer := &mockSigner{}
 	feeEstimator := newMockFeeEstimator(0, 0)
 
 	// For our UTXO source, we'll pass in all the UTXOs that we know of,
diff --git a/utxonursery_test.go b/utxonursery_test.go
index 5675c9ea0..4f9fdab93 100644
--- a/utxonursery_test.go
+++ b/utxonursery_test.go
@@ -20,7 +20,6 @@ import (
 	"github.com/btcsuite/btcutil"
 	"github.com/lightningnetwork/lnd/channeldb"
 	"github.com/lightningnetwork/lnd/input"
-	"github.com/lightningnetwork/lnd/lntest/mock"
 	"github.com/lightningnetwork/lnd/lnwallet"
 	"github.com/lightningnetwork/lnd/sweep"
 )
@@ -399,7 +398,7 @@ func TestBabyOutputSerialization(t *testing.T) {
 type nurseryTestContext struct {
 	nursery     *utxoNursery
 	notifier    *sweep.MockNotifier
-	chainIO     *mock.ChainIO
+	chainIO     *mockChainIO
 	publishChan chan wire.MsgTx
 	store       *nurseryStoreInterceptor
 	restart     func() bool
@@ -442,8 +441,8 @@ func createNurseryTestContext(t *testing.T,
 
 	timeoutChan := make(chan chan time.Time)
 
-	chainIO := &mock.ChainIO{
-		BestHeight: 0,
+	chainIO := &mockChainIO{
+		bestHeight: 0,
 	}
 
 	sweeper := newMockSweeper(t)
@@ -523,7 +522,7 @@ func createNurseryTestContext(t *testing.T,
 func (ctx *nurseryTestContext) notifyEpoch(height int32) {
 	ctx.t.Helper()
 
-	ctx.chainIO.BestHeight = height
+	ctx.chainIO.bestHeight = height
 	ctx.notifier.NotifyEpoch(height)
 }