github.com/decred/dcrlnd@v0.7.6/lntest/spv.go (about)

     1  //go:build spv
     2  // +build spv
     3  
     4  package lntest
     5  
     6  import (
     7  	"context"
     8  	"testing"
     9  
    10  	pb "decred.org/dcrwallet/v4/rpc/walletrpc"
    11  	rpctest "github.com/decred/dcrtest/dcrdtest"
    12  )
    13  
    14  // SpvBackendConfig is an implementation of the BackendConfig interface
    15  // backed by a btcd node.
    16  type SpvBackendConfig struct {
    17  	// connectAddr is the address that SPV clients may use to connect to
    18  	// this node via the p2p interface.
    19  	connectAddr string
    20  
    21  	// harness is this backend's node.
    22  	harness *rpctest.Harness
    23  
    24  	// miner is the backing miner used during tests.
    25  	miner *rpctest.Harness
    26  }
    27  
    28  // GenArgs returns the arguments needed to be passed to LND at startup for
    29  // using this node as a chain backend.
    30  func (b SpvBackendConfig) GenArgs() []string {
    31  	return []string{
    32  		"--dcrwallet.spv",
    33  		"--dcrwallet.spvconnect=" + b.harness.P2PAddress(),
    34  	}
    35  }
    36  
    37  func (b SpvBackendConfig) StartWalletSync(loader pb.WalletLoaderServiceClient, password []byte) error {
    38  	req := &pb.SpvSyncRequest{
    39  		SpvConnect:        []string{b.connectAddr},
    40  		DiscoverAccounts:  true,
    41  		PrivatePassphrase: password,
    42  	}
    43  
    44  	stream, err := loader.SpvSync(context.Background(), req)
    45  	if err != nil {
    46  		return err
    47  	}
    48  
    49  	syncDone := make(chan error)
    50  	go func() {
    51  		for {
    52  			resp, err := stream.Recv()
    53  			if err != nil {
    54  				syncDone <- err
    55  				return
    56  			}
    57  			if resp.Synced {
    58  				close(syncDone)
    59  				break
    60  			}
    61  		}
    62  
    63  		// After sync is complete, just drain the notifications until
    64  		// the connection is closed.
    65  		for {
    66  			_, err := stream.Recv()
    67  			if err != nil {
    68  				return
    69  			}
    70  		}
    71  	}()
    72  
    73  	return <-syncDone
    74  }
    75  
    76  // ConnectMiner connects the backend to the underlying miner.
    77  func (b SpvBackendConfig) ConnectMiner() error {
    78  	return rpctest.ConnectNode(context.Background(), b.harness, b.miner)
    79  }
    80  
    81  // DisconnectMiner disconnects the backend to the underlying miner.
    82  func (b SpvBackendConfig) DisconnectMiner() error {
    83  	return rpctest.RemoveNode(context.Background(), b.harness, b.miner)
    84  }
    85  
    86  // Name returns the name of the backend type.
    87  func (b SpvBackendConfig) Name() string {
    88  	return "spv"
    89  }
    90  
    91  // NewBackend starts a new rpctest.Harness and returns a SpvBackendConfig for
    92  // that node.
    93  func NewBackend(t *testing.T, miner *rpctest.Harness) (*SpvBackendConfig, func() error, error) {
    94  	chainBackend, cleanUp, err := newBackend(t, miner)
    95  	if err != nil {
    96  		return nil, nil, err
    97  	}
    98  
    99  	bd := &SpvBackendConfig{
   100  		connectAddr: chainBackend.P2PAddress(),
   101  		harness:     chainBackend,
   102  		miner:       miner,
   103  	}
   104  	return bd, cleanUp, nil
   105  }