diff --git a/breacharbiter_test.go b/breacharbiter_test.go index 01d9daf7..03c1cdb6 100644 --- a/breacharbiter_test.go +++ b/breacharbiter_test.go @@ -29,6 +29,7 @@ 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" @@ -1433,8 +1434,8 @@ func testBreachSpends(t *testing.T, test breachTest) { // Notify that the breaching transaction is confirmed, to trigger the // retribution logic. - notifier := brar.cfg.Notifier.(*mockSpendNotifier) - notifier.confChannel <- &chainntnfs.TxConfirmation{} + notifier := brar.cfg.Notifier.(*mock.SpendNotifier) + notifier.ConfChan <- &chainntnfs.TxConfirmation{} // The breach arbiter should attempt to sweep all outputs on the // breached commitment. We'll pretend that the HTLC output has been @@ -1510,7 +1511,7 @@ func testBreachSpends(t *testing.T, test breachTest) { // Deliver confirmation of sweep if the test expects it. if test.sendFinalConf { - notifier.confChannel <- &chainntnfs.TxConfirmation{} + notifier.ConfChan <- &chainntnfs.TxConfirmation{} } // Assert that the channel is fully resolved. @@ -1670,10 +1671,10 @@ func createTestArbiter(t *testing.T, contractBreaches chan *ContractBreachEvent, aliceKeyPriv, _ := btcec.PrivKeyFromBytes(btcec.S256(), alicesPrivKey) - signer := &mockSigner{key: aliceKeyPriv} + signer := &mock.SingleSigner{Privkey: aliceKeyPriv} // Assemble our test arbiter. - notifier := makeMockSpendNotifier() + notifier := mock.MakeMockSpendNotifier() ba := newBreachArbiter(&BreachConfig{ CloseLink: func(_ *wire.OutPoint, _ htlcswitch.ChannelCloseType) {}, DB: db, @@ -1897,8 +1898,8 @@ func createInitChannels(revocationWindow int) (*lnwallet.LightningChannel, *lnwa Packager: channeldb.NewChannelPackager(shortChanID), } - aliceSigner := &mockSigner{aliceKeyPriv} - bobSigner := &mockSigner{bobKeyPriv} + aliceSigner := &mock.SingleSigner{Privkey: aliceKeyPriv} + bobSigner := &mock.SingleSigner{Privkey: 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 60c7eebe..e197c0b0 100644 --- a/contractcourt/chain_arbitrator_test.go +++ b/contractcourt/chain_arbitrator_test.go @@ -8,8 +8,10 @@ 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" ) @@ -80,8 +82,12 @@ func TestChainArbitratorRepublishCloses(t *testing.T) { published := make(map[chainhash.Hash]int) chainArbCfg := ChainArbitratorConfig{ - ChainIO: &mockChainIO{}, - Notifier: &mockNotifier{}, + ChainIO: &mock.ChainIO{}, + Notifier: &mock.ChainNotifier{ + SpendChan: make(chan *chainntnfs.SpendDetail), + EpochChan: make(chan *chainntnfs.BlockEpoch), + ConfChan: make(chan *chainntnfs.TxConfirmation), + }, PublishTx: func(tx *wire.MsgTx, _ string) error { published[tx.TxHash()]++ return nil @@ -172,8 +178,12 @@ func TestResolveContract(t *testing.T) { // chain arbitrator that should pick up these new channels and launch // resolver for them. chainArbCfg := ChainArbitratorConfig{ - ChainIO: &mockChainIO{}, - Notifier: &mockNotifier{}, + ChainIO: &mock.ChainIO{}, + Notifier: &mock.ChainNotifier{ + SpendChan: make(chan *chainntnfs.SpendDetail), + EpochChan: make(chan *chainntnfs.BlockEpoch), + ConfChan: make(chan *chainntnfs.TxConfirmation), + }, PublishTx: func(tx *wire.MsgTx, _ string) error { return nil }, diff --git a/contractcourt/chain_watcher_test.go b/contractcourt/chain_watcher_test.go index 62c76871..50e73ec5 100644 --- a/contractcourt/chain_watcher_test.go +++ b/contractcourt/chain_watcher_test.go @@ -7,58 +7,15 @@ 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. @@ -77,8 +34,10 @@ 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 := &mockNotifier{ - spendChan: make(chan *chainntnfs.SpendDetail), + aliceNotifier := &mock.ChainNotifier{ + SpendChan: make(chan *chainntnfs.SpendDetail), + EpochChan: make(chan *chainntnfs.BlockEpoch), + ConfChan: make(chan *chainntnfs.TxConfirmation), } aliceChainWatcher, err := newChainWatcher(chainWatcherConfig{ chanState: aliceChannel.State(), @@ -107,7 +66,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. @@ -166,8 +125,10 @@ 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 := &mockNotifier{ - spendChan: make(chan *chainntnfs.SpendDetail), + aliceNotifier := &mock.ChainNotifier{ + SpendChan: make(chan *chainntnfs.SpendDetail), + EpochChan: make(chan *chainntnfs.BlockEpoch), + ConfChan: make(chan *chainntnfs.TxConfirmation), } aliceChainWatcher, err := newChainWatcher(chainWatcherConfig{ chanState: aliceChannel.State(), @@ -216,7 +177,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. @@ -292,8 +253,10 @@ 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 := &mockNotifier{ - spendChan: make(chan *chainntnfs.SpendDetail), + aliceNotifier := &mock.ChainNotifier{ + SpendChan: make(chan *chainntnfs.SpendDetail), + EpochChan: make(chan *chainntnfs.BlockEpoch), + ConfChan: make(chan *chainntnfs.TxConfirmation), } aliceChainWatcher, err := newChainWatcher(chainWatcherConfig{ chanState: aliceChannel.State(), @@ -350,7 +313,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. @@ -461,8 +424,10 @@ 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 := &mockNotifier{ - spendChan: make(chan *chainntnfs.SpendDetail), + aliceNotifier := &mock.ChainNotifier{ + SpendChan: make(chan *chainntnfs.SpendDetail), + EpochChan: make(chan *chainntnfs.BlockEpoch), + ConfChan: make(chan *chainntnfs.TxConfirmation), } aliceChainWatcher, err := newChainWatcher(chainWatcherConfig{ chanState: aliceChannel.State(), @@ -517,7 +482,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 ce0963ec..1cdb8142 100644 --- a/contractcourt/channel_arbitrator_test.go +++ b/contractcourt/channel_arbitrator_test.go @@ -19,6 +19,7 @@ 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" ) @@ -334,10 +335,10 @@ func createTestChannelArbitrator(t *testing.T, log ArbitratorLog, }, OutgoingBroadcastDelta: 5, IncomingBroadcastDelta: 5, - Notifier: &mockNotifier{ - epochChan: make(chan *chainntnfs.BlockEpoch), - spendChan: make(chan *chainntnfs.SpendDetail), - confChan: make(chan *chainntnfs.TxConfirmation), + Notifier: &mock.ChainNotifier{ + EpochChan: make(chan *chainntnfs.BlockEpoch), + SpendChan: make(chan *chainntnfs.SpendDetail), + ConfChan: make(chan *chainntnfs.TxConfirmation), }, IncubateOutputs: func(wire.OutPoint, *lnwallet.OutgoingHtlcResolution, @@ -878,7 +879,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.(*mockNotifier) + oldNotifier := chanArb.cfg.Notifier.(*mock.ChainNotifier) // At this point, in order to simulate a restart, we'll re-create the // channel arbitrator. We do this to ensure that all information @@ -927,7 +928,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. @@ -939,7 +940,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. @@ -967,7 +968,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 578b5c45..eb54dbf3 100644 --- a/contractcourt/commit_sweep_resolver_test.go +++ b/contractcourt/commit_sweep_resolver_test.go @@ -10,6 +10,7 @@ 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" @@ -17,7 +18,7 @@ import ( type commitSweepResolverTestContext struct { resolver *commitSweepResolver - notifier *mockNotifier + notifier *mock.ChainNotifier sweeper *mockSweeper resolverResultChan chan resolveResult t *testing.T @@ -26,10 +27,10 @@ type commitSweepResolverTestContext struct { func newCommitSweepResolverTestContext(t *testing.T, resolution *lnwallet.CommitOutputResolution) *commitSweepResolverTestContext { - notifier := &mockNotifier{ - epochChan: make(chan *chainntnfs.BlockEpoch), - spendChan: make(chan *chainntnfs.SpendDetail), - confChan: make(chan *chainntnfs.TxConfirmation), + notifier := &mock.ChainNotifier{ + EpochChan: make(chan *chainntnfs.BlockEpoch), + SpendChan: make(chan *chainntnfs.SpendDetail), + ConfChan: make(chan *chainntnfs.TxConfirmation), } sweeper := newMockSweeper() @@ -83,7 +84,7 @@ func (i *commitSweepResolverTestContext) resolve() { } func (i *commitSweepResolverTestContext) notifyEpoch(height int32) { - i.notifier.epochChan <- &chainntnfs.BlockEpoch{ + i.notifier.EpochChan <- &chainntnfs.BlockEpoch{ Height: height, } } @@ -189,7 +190,7 @@ func TestCommitSweepResolverNoDelay(t *testing.T) { spendTx := &wire.MsgTx{} spendHash := spendTx.TxHash() - ctx.notifier.confChan <- &chainntnfs.TxConfirmation{ + ctx.notifier.ConfChan <- &chainntnfs.TxConfirmation{ Tx: spendTx, } @@ -267,7 +268,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 55bc33b5..4ada27ff 100644 --- a/contractcourt/htlc_incoming_resolver_test.go +++ b/contractcourt/htlc_incoming_resolver_test.go @@ -12,6 +12,7 @@ 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" @@ -295,7 +296,7 @@ type incomingResolverTestContext struct { registry *mockRegistry witnessBeacon *mockWitnessBeacon resolver *htlcIncomingContestResolver - notifier *mockNotifier + notifier *mock.ChainNotifier onionProcessor *mockOnionProcessor resolveErr chan error nextResolver ContractResolver @@ -303,10 +304,10 @@ type incomingResolverTestContext struct { } func newIncomingResolverTestContext(t *testing.T, isExit bool) *incomingResolverTestContext { - notifier := &mockNotifier{ - epochChan: make(chan *chainntnfs.BlockEpoch), - spendChan: make(chan *chainntnfs.SpendDetail), - confChan: make(chan *chainntnfs.TxConfirmation), + notifier := &mock.ChainNotifier{ + EpochChan: make(chan *chainntnfs.BlockEpoch), + SpendChan: make(chan *chainntnfs.SpendDetail), + ConfChan: make(chan *chainntnfs.TxConfirmation), } witnessBeacon := newMockWitnessBeacon() registry := &mockRegistry{ @@ -377,7 +378,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 10d8fbc1..987c1a7a 100644 --- a/contractcourt/htlc_outgoing_contest_resolver_test.go +++ b/contractcourt/htlc_outgoing_contest_resolver_test.go @@ -9,6 +9,7 @@ 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" @@ -80,7 +81,7 @@ func TestHtlcOutgoingResolverRemoteClaim(t *testing.T) { spendHash := spendTx.TxHash() - ctx.notifier.spendChan <- &chainntnfs.SpendDetail{ + ctx.notifier.SpendChan <- &chainntnfs.SpendDetail{ SpendingTx: spendTx, SpenderTxHash: &spendHash, } @@ -114,7 +115,7 @@ type resolveResult struct { type outgoingResolverTestContext struct { resolver *htlcOutgoingContestResolver - notifier *mockNotifier + notifier *mock.ChainNotifier preimageDB *mockWitnessBeacon resolverResultChan chan resolveResult resolutionChan chan ResolutionMsg @@ -122,10 +123,10 @@ type outgoingResolverTestContext struct { } func newOutgoingResolverTestContext(t *testing.T) *outgoingResolverTestContext { - notifier := &mockNotifier{ - epochChan: make(chan *chainntnfs.BlockEpoch), - spendChan: make(chan *chainntnfs.SpendDetail), - confChan: make(chan *chainntnfs.TxConfirmation), + notifier := &mock.ChainNotifier{ + EpochChan: make(chan *chainntnfs.BlockEpoch), + SpendChan: make(chan *chainntnfs.SpendDetail), + ConfChan: make(chan *chainntnfs.TxConfirmation), } checkPointChan := make(chan struct{}, 1) @@ -212,7 +213,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 0c700969..6e44c22c 100644 --- a/contractcourt/htlc_success_resolver_test.go +++ b/contractcourt/htlc_success_resolver_test.go @@ -8,6 +8,7 @@ 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" ) @@ -16,16 +17,16 @@ var testHtlcAmt = lnwire.MilliSatoshi(200000) type htlcSuccessResolverTestContext struct { resolver *htlcSuccessResolver - notifier *mockNotifier + notifier *mock.ChainNotifier resolverResultChan chan resolveResult t *testing.T } func newHtlcSuccessResolverTextContext(t *testing.T) *htlcSuccessResolverTestContext { - notifier := &mockNotifier{ - epochChan: make(chan *chainntnfs.BlockEpoch), - spendChan: make(chan *chainntnfs.SpendDetail), - confChan: make(chan *chainntnfs.TxConfirmation), + notifier := &mock.ChainNotifier{ + EpochChan: make(chan *chainntnfs.BlockEpoch), + SpendChan: make(chan *chainntnfs.SpendDetail), + ConfChan: make(chan *chainntnfs.TxConfirmation), } checkPointChan := make(chan struct{}, 1) @@ -116,7 +117,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, } @@ -165,7 +166,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 fdf0bba5..6e41ad79 100644 --- a/contractcourt/htlc_timeout_resolver_test.go +++ b/contractcourt/htlc_timeout_resolver_test.go @@ -7,7 +7,6 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" @@ -15,33 +14,11 @@ 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 @@ -93,7 +70,7 @@ func TestHtlcTimeoutResolver(t *testing.T) { copy(fakePreimage[:], fakePreimageBytes) - signer := &mockSigner{} + signer := &mock.DummySigner{} sweepTx := &wire.MsgTx{ TxIn: []*wire.TxIn{ { @@ -164,7 +141,7 @@ func TestHtlcTimeoutResolver(t *testing.T) { timeout: true, txToBroadcast: func() (*wire.MsgTx, error) { witness, err := input.SenderHtlcSpendTimeout( - &dummySignature{}, txscript.SigHashAll, + &mock.DummySignature{}, txscript.SigHashAll, signer, fakeSignDesc, sweepTx, ) if err != nil { @@ -189,7 +166,7 @@ func TestHtlcTimeoutResolver(t *testing.T) { timeout: false, txToBroadcast: func() (*wire.MsgTx, error) { witness, err := input.ReceiverHtlcSpendRedeem( - &dummySignature{}, txscript.SigHashAll, + &mock.DummySignature{}, txscript.SigHashAll, fakePreimageBytes, signer, fakeSignDesc, sweepTx, ) @@ -226,10 +203,10 @@ func TestHtlcTimeoutResolver(t *testing.T) { }, } - notifier := &mockNotifier{ - epochChan: make(chan *chainntnfs.BlockEpoch), - spendChan: make(chan *chainntnfs.SpendDetail), - confChan: make(chan *chainntnfs.TxConfirmation), + notifier := &mock.ChainNotifier{ + EpochChan: make(chan *chainntnfs.BlockEpoch), + SpendChan: make(chan *chainntnfs.SpendDetail), + ConfChan: make(chan *chainntnfs.TxConfirmation), } witnessBeacon := newMockWitnessBeacon() @@ -354,7 +331,7 @@ func TestHtlcTimeoutResolver(t *testing.T) { spendTxHash := spendingTx.TxHash() select { - case notifier.spendChan <- &chainntnfs.SpendDetail{ + case notifier.SpendChan <- &chainntnfs.SpendDetail{ SpendingTx: spendingTx, SpenderTxHash: &spendTxHash, }: @@ -411,7 +388,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 5281d4aa..9dfad6ba 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,26 +92,6 @@ 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 @@ -555,7 +535,7 @@ func createNodeAnnouncement(priv *btcec.PrivateKey, a.ExtraOpaqueData = extraBytes[0] } - signer := mockSigner{priv} + signer := mock.SingleSigner{Privkey: priv} sig, err := netann.SignAnnouncement(&signer, priv.PubKey(), a) if err != nil { return nil, err @@ -607,7 +587,7 @@ func createUpdateAnnouncement(blockHeight uint32, func signUpdate(nodeKey *btcec.PrivateKey, a *lnwire.ChannelUpdate) error { pub := nodeKey.PubKey() - signer := mockSigner{nodeKey} + signer := mock.SingleSigner{Privkey: nodeKey} sig, err := netann.SignAnnouncement(&signer, pub, a) if err != nil { return err @@ -649,7 +629,7 @@ func createRemoteChannelAnnouncement(blockHeight uint32, a := createAnnouncementWithoutProof(blockHeight, extraBytes...) pub := nodeKeyPriv1.PubKey() - signer := mockSigner{nodeKeyPriv1} + signer := mock.SingleSigner{Privkey: nodeKeyPriv1} sig, err := netann.SignAnnouncement(&signer, pub, a) if err != nil { return nil, err @@ -660,7 +640,7 @@ func createRemoteChannelAnnouncement(blockHeight uint32, } pub = nodeKeyPriv2.PubKey() - signer = mockSigner{nodeKeyPriv2} + signer = mock.SingleSigner{Privkey: nodeKeyPriv2} sig, err = netann.SignAnnouncement(&signer, pub, a) if err != nil { return nil, err @@ -671,7 +651,7 @@ func createRemoteChannelAnnouncement(blockHeight uint32, } pub = bitcoinKeyPriv1.PubKey() - signer = mockSigner{bitcoinKeyPriv1} + signer = mock.SingleSigner{Privkey: bitcoinKeyPriv1} sig, err = netann.SignAnnouncement(&signer, pub, a) if err != nil { return nil, err @@ -682,7 +662,7 @@ func createRemoteChannelAnnouncement(blockHeight uint32, } pub = bitcoinKeyPriv2.PubKey() - signer = mockSigner{bitcoinKeyPriv2} + signer = mock.SingleSigner{Privkey: bitcoinKeyPriv2} sig, err = netann.SignAnnouncement(&signer, pub, a) if err != nil { return nil, err @@ -761,7 +741,7 @@ func createTestCtx(startHeight uint32) (*testCtx, func(), error) { RotateTicker: ticker.NewForce(DefaultSyncerRotationInterval), HistoricalSyncTicker: ticker.NewForce(DefaultHistoricalSyncInterval), NumActiveSyncers: 3, - AnnSigner: &mockSigner{nodeKeyPriv1}, + AnnSigner: &mock.SingleSigner{Privkey: nodeKeyPriv1}, SubBatchDelay: time.Second * 5, MinimumBatchSize: 10, }, nodeKeyPub1) diff --git a/fundingmanager_test.go b/fundingmanager_test.go index 0bc0e304..59faf448 100644 --- a/fundingmanager_test.go +++ b/fundingmanager_test.go @@ -33,6 +33,7 @@ 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" @@ -54,6 +55,9 @@ 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 ( @@ -298,14 +302,14 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey, publTxChan := make(chan *wire.MsgTx, 1) shutdownChan := make(chan struct{}) - wc := &mockWalletController{ - rootKey: alicePrivKey, + wc := &mock.WalletController{ + RootKey: alicePrivKey, } - signer := &mockSigner{ - key: alicePrivKey, + signer := &mock.SingleSigner{ + Privkey: alicePrivKey, } - bio := &mockChainIO{ - bestHeight: fundingBroadcastHeight, + bio := &mock.ChainIO{ + BestHeight: fundingBroadcastHeight, } // The mock channel event notifier will receive events for each pending @@ -325,8 +329,8 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey, return nil, err } - keyRing := &mockSecretKeyRing{ - rootKey: alicePrivKey, + keyRing := &mock.SecretKeyRing{ + RootKey: alicePrivKey, } lnw, err := createTestWallet( @@ -3013,7 +3017,7 @@ func TestFundingManagerFundAll(t *testing.T) { Value: btcutil.Amount( 0.05 * btcutil.SatoshiPerBitcoin, ), - PkScript: coinPkScript, + PkScript: mock.CoinPkScript, OutPoint: wire.OutPoint{ Hash: chainhash.Hash{}, Index: 0, @@ -3024,7 +3028,7 @@ func TestFundingManagerFundAll(t *testing.T) { Value: btcutil.Amount( 0.06 * btcutil.SatoshiPerBitcoin, ), - PkScript: coinPkScript, + PkScript: mock.CoinPkScript, OutPoint: wire.OutPoint{ Hash: chainhash.Hash{}, Index: 1, @@ -3058,7 +3062,7 @@ func TestFundingManagerFundAll(t *testing.T) { alice, bob := setupFundingManagers(t) defer tearDownFundingManagers(t, alice, bob) - alice.fundingMgr.cfg.Wallet.WalletController.(*mockWalletController).utxos = allCoins + alice.fundingMgr.cfg.Wallet.WalletController.(*mock.WalletController).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 7ebe1f10..961eade4 100644 --- a/htlcswitch/decayedlog_test.go +++ b/htlcswitch/decayedlog_test.go @@ -10,6 +10,7 @@ import ( sphinx "github.com/lightningnetwork/lightning-onion" "github.com/lightningnetwork/lnd/chainntnfs" + "github.com/lightningnetwork/lnd/lntest/mock" ) const ( @@ -28,16 +29,18 @@ func tempDecayedLogPath(t *testing.T) string { } // startup sets up the DecayedLog and possibly the garbage collector. -func startup(dbPath string, notifier bool) (sphinx.ReplayLog, *mockNotifier, - *sphinx.HashPrefix, error) { +func startup(dbPath string, notifier bool) (sphinx.ReplayLog, + *mock.ChainNotifier, *sphinx.HashPrefix, error) { var log sphinx.ReplayLog - var chainNotifier *mockNotifier + var chainNotifier *mock.ChainNotifier if notifier { // Create the MockNotifier which triggers the garbage collector - chainNotifier = &mockNotifier{ - epochChan: make(chan *chainntnfs.BlockEpoch, 1), + chainNotifier = &mock.ChainNotifier{ + SpendChan: make(chan *chainntnfs.SpendDetail), + EpochChan: make(chan *chainntnfs.BlockEpoch, 1), + ConfChan: make(chan *chainntnfs.TxConfirmation), } // Initialize the DecayedLog object @@ -99,7 +102,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, } @@ -114,7 +117,7 @@ func TestDecayedLogGarbageCollector(t *testing.T) { } // Send block 100001 (expiry block) - notifier.epochChan <- &chainntnfs.BlockEpoch{ + notifier.EpochChan <- &chainntnfs.BlockEpoch{ Height: 100001, } @@ -175,7 +178,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/mock.go b/htlcswitch/mock.go index 7c169ac7..69277bc3 100644 --- a/htlcswitch/mock.go +++ b/htlcswitch/mock.go @@ -15,8 +15,6 @@ 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" @@ -25,9 +23,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" @@ -172,7 +170,11 @@ func initSwitchWithDB(startingHeight uint32, db *channeldb.DB) (*Switch, error) FetchLastChannelUpdate: func(lnwire.ShortChannelID) (*lnwire.ChannelUpdate, error) { return nil, nil }, - Notifier: &mockNotifier{}, + Notifier: &mock.ChainNotifier{ + SpendChan: make(chan *chainntnfs.SpendDetail), + EpochChan: make(chan *chainntnfs.BlockEpoch), + ConfChan: make(chan *chainntnfs.TxConfirmation), + }, FwdEventTicker: ticker.NewForce(DefaultFwdEventInterval), LogEventTicker: ticker.NewForce(DefaultLogInterval), AckEventTicker: ticker.NewForce(DefaultAckInterval), @@ -855,103 +857,6 @@ 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/htlcswitch/test_utils.go b/htlcswitch/test_utils.go index ae64cf1b..37925ef9 100644 --- a/htlcswitch/test_utils.go +++ b/htlcswitch/test_utils.go @@ -29,6 +29,7 @@ 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" @@ -376,8 +377,8 @@ func createTestChannel(alicePrivKey, bobPrivKey []byte, os.RemoveAll(alicePath) } - aliceSigner := &mockSigner{aliceKeyPriv} - bobSigner := &mockSigner{bobKeyPriv} + aliceSigner := &mock.SingleSigner{Privkey: aliceKeyPriv} + bobSigner := &mock.SingleSigner{Privkey: bobKeyPriv} alicePool := lnwallet.NewSigPool(runtime.NumCPU(), aliceSigner) channelAlice, err := lnwallet.NewLightningChannel( diff --git a/lntest/mock/chainio.go b/lntest/mock/chainio.go new file mode 100644 index 00000000..1f07056f --- /dev/null +++ b/lntest/mock/chainio.go @@ -0,0 +1,34 @@ +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 new file mode 100644 index 00000000..185d15cd --- /dev/null +++ b/lntest/mock/chainnotifier.go @@ -0,0 +1,64 @@ +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 new file mode 100644 index 00000000..1c2da65f --- /dev/null +++ b/lntest/mock/secretkeyring.go @@ -0,0 +1,56 @@ +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 new file mode 100644 index 00000000..c94d4eeb --- /dev/null +++ b/lntest/mock/signer.go @@ -0,0 +1,127 @@ +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 new file mode 100644 index 00000000..7d51b458 --- /dev/null +++ b/lntest/mock/spendnotifier.go @@ -0,0 +1,97 @@ +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 new file mode 100644 index 00000000..5aea2135 --- /dev/null +++ b/lntest/mock/walletcontroller.go @@ -0,0 +1,182 @@ +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/mock.go b/mock.go deleted file mode 100644 index 94b9f318..00000000 --- a/mock.go +++ /dev/null @@ -1,400 +0,0 @@ -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_test.go b/peer/brontide_test.go index 78800b11..6150fe27 100644 --- a/peer/brontide_test.go +++ b/peer/brontide_test.go @@ -12,6 +12,7 @@ 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" ) @@ -33,8 +34,10 @@ var ( func TestPeerChannelClosureAcceptFeeResponder(t *testing.T) { t.Parallel() - notifier := &mockNotifier{ - confChannel: make(chan *chainntnfs.TxConfirmation), + notifier := &mock.ChainNotifier{ + SpendChan: make(chan *chainntnfs.SpendDetail), + EpochChan: make(chan *chainntnfs.BlockEpoch), + ConfChan: make(chan *chainntnfs.TxConfirmation), } broadcastTxChan := make(chan *wire.MsgTx) @@ -126,7 +129,7 @@ func TestPeerChannelClosureAcceptFeeResponder(t *testing.T) { } // Alice should be waiting in a goroutine for a confirmation. - notifier.confChannel <- &chainntnfs.TxConfirmation{} + notifier.ConfChan <- &chainntnfs.TxConfirmation{} } // TestPeerChannelClosureAcceptFeeInitiator tests the shutdown initiator's @@ -134,8 +137,10 @@ func TestPeerChannelClosureAcceptFeeResponder(t *testing.T) { func TestPeerChannelClosureAcceptFeeInitiator(t *testing.T) { t.Parallel() - notifier := &mockNotifier{ - confChannel: make(chan *chainntnfs.TxConfirmation), + notifier := &mock.ChainNotifier{ + SpendChan: make(chan *chainntnfs.SpendDetail), + EpochChan: make(chan *chainntnfs.BlockEpoch), + ConfChan: make(chan *chainntnfs.TxConfirmation), } broadcastTxChan := make(chan *wire.MsgTx) @@ -245,7 +250,7 @@ func TestPeerChannelClosureAcceptFeeInitiator(t *testing.T) { } // Alice should be waiting on a single confirmation for the coop close tx. - notifier.confChannel <- &chainntnfs.TxConfirmation{} + notifier.ConfChan <- &chainntnfs.TxConfirmation{} } // TestPeerChannelClosureFeeNegotiationsResponder tests the shutdown @@ -254,8 +259,10 @@ func TestPeerChannelClosureAcceptFeeInitiator(t *testing.T) { func TestPeerChannelClosureFeeNegotiationsResponder(t *testing.T) { t.Parallel() - notifier := &mockNotifier{ - confChannel: make(chan *chainntnfs.TxConfirmation), + notifier := &mock.ChainNotifier{ + SpendChan: make(chan *chainntnfs.SpendDetail), + EpochChan: make(chan *chainntnfs.BlockEpoch), + ConfChan: make(chan *chainntnfs.TxConfirmation), } broadcastTxChan := make(chan *wire.MsgTx) @@ -437,7 +444,7 @@ func TestPeerChannelClosureFeeNegotiationsResponder(t *testing.T) { } // Alice should be waiting on a single confirmation for the coop close tx. - notifier.confChannel <- &chainntnfs.TxConfirmation{} + notifier.ConfChan <- &chainntnfs.TxConfirmation{} } // TestPeerChannelClosureFeeNegotiationsInitiator tests the shutdown @@ -446,8 +453,10 @@ func TestPeerChannelClosureFeeNegotiationsResponder(t *testing.T) { func TestPeerChannelClosureFeeNegotiationsInitiator(t *testing.T) { t.Parallel() - notifier := &mockNotifier{ - confChannel: make(chan *chainntnfs.TxConfirmation), + notifier := &mock.ChainNotifier{ + SpendChan: make(chan *chainntnfs.SpendDetail), + EpochChan: make(chan *chainntnfs.BlockEpoch), + ConfChan: make(chan *chainntnfs.TxConfirmation), } broadcastTxChan := make(chan *wire.MsgTx) @@ -642,7 +651,7 @@ func TestPeerChannelClosureFeeNegotiationsInitiator(t *testing.T) { } // Alice should be waiting on a single confirmation for the coop close tx. - notifier.confChannel <- &chainntnfs.TxConfirmation{} + notifier.ConfChan <- &chainntnfs.TxConfirmation{} } // TestChooseDeliveryScript tests that chooseDeliveryScript correctly errors @@ -779,8 +788,10 @@ func TestCustomShutdownScript(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { - notifier := &mockNotifier{ - confChannel: make(chan *chainntnfs.TxConfirmation), + notifier := &mock.ChainNotifier{ + SpendChan: make(chan *chainntnfs.SpendDetail), + EpochChan: make(chan *chainntnfs.BlockEpoch), + ConfChan: make(chan *chainntnfs.TxConfirmation), } broadcastTxChan := make(chan *wire.MsgTx) diff --git a/peer/test_utils.go b/peer/test_utils.go index df74eda1..08c4557d 100644 --- a/peer/test_utils.go +++ b/peer/test_utils.go @@ -4,7 +4,6 @@ import ( "bytes" crand "crypto/rand" "encoding/binary" - "fmt" "io" "io/ioutil" "math/rand" @@ -13,18 +12,15 @@ 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" @@ -103,252 +99,6 @@ 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 @@ -575,8 +325,8 @@ func createTestPeer(notifier chainntnfs.ChainNotifier, os.RemoveAll(alicePath) } - aliceSigner := &mockSigner{aliceKeyPriv} - bobSigner := &mockSigner{bobKeyPriv} + aliceSigner := &mock.SingleSigner{Privkey: aliceKeyPriv} + bobSigner := &mock.SingleSigner{Privkey: bobKeyPriv} alicePool := lnwallet.NewSigPool(1, aliceSigner) channelAlice, err := lnwallet.NewLightningChannel( @@ -596,13 +346,13 @@ func createTestPeer(notifier chainntnfs.ChainNotifier, } _ = bobPool.Start() - chainIO := &mockChainIO{ - bestHeight: broadcastHeight, + chainIO := &mock.ChainIO{ + BestHeight: broadcastHeight, } wallet := &lnwallet.LightningWallet{ - WalletController: &mockWalletController{ - rootKey: aliceKeyPriv, - publishedTxns: publTx, + WalletController: &mock.WalletController{ + RootKey: aliceKeyPriv, + PublishedTransactions: publTx, }, } diff --git a/sweep/sweeper_test.go b/sweep/sweeper_test.go index eaffec40..d7b6ab13 100644 --- a/sweep/sweeper_test.go +++ b/sweep/sweeper_test.go @@ -14,6 +14,7 @@ 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" ) @@ -128,7 +129,7 @@ func createSweeperTestContext(t *testing.T) *sweeperTestContext { return c }, Store: store, - Signer: &mockSigner{}, + Signer: &mock.DummySigner{}, GenSweepScript: func() ([]byte, error) { script := []byte{outputScriptCount} outputScriptCount++ diff --git a/sweep/test_utils.go b/sweep/test_utils.go index 5b83d730..2fd916c8 100644 --- a/sweep/test_utils.go +++ b/sweep/test_utils.go @@ -6,11 +6,9 @@ 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 ( @@ -19,31 +17,6 @@ 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 acd99c6a..4e098757 100644 --- a/sweep/walletsweep_test.go +++ b/sweep/walletsweep_test.go @@ -9,6 +9,7 @@ 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" ) @@ -335,7 +336,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 := &mockSigner{} + signer := &mock.DummySigner{} 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 4f9fdab9..5675c9ea 100644 --- a/utxonursery_test.go +++ b/utxonursery_test.go @@ -20,6 +20,7 @@ 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" ) @@ -398,7 +399,7 @@ func TestBabyOutputSerialization(t *testing.T) { type nurseryTestContext struct { nursery *utxoNursery notifier *sweep.MockNotifier - chainIO *mockChainIO + chainIO *mock.ChainIO publishChan chan wire.MsgTx store *nurseryStoreInterceptor restart func() bool @@ -441,8 +442,8 @@ func createNurseryTestContext(t *testing.T, timeoutChan := make(chan chan time.Time) - chainIO := &mockChainIO{ - bestHeight: 0, + chainIO := &mock.ChainIO{ + BestHeight: 0, } sweeper := newMockSweeper(t) @@ -522,7 +523,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) }