func (s *rpcServer) Stop() error {
	if !atomic.CompareAndSwapUint32(&s.stopped, 0, 1) {
		return nil
	}
	var returnErr error
	rpcLog.Info("Trader server stopping")
	if err := s.server.sidecarAcceptor.Stop(); err != nil {
		rpcLog.Errorf("Error stopping sidecar acceptor: %v", err)
		returnErr = err
	}
	if err := s.server.fundingManager.Stop(); err != nil {
		rpcLog.Errorf("Error stopping funding manager: %v", err)
	}
	s.accountManager.Stop()
	s.orderManager.Stop()
	if err := s.auctioneer.Stop(); err != nil {
		rpcLog.Errorf("Error closing server stream: %v", err)
	}
	close(s.quit)
	s.wg.Wait()
	s.blockNtfnCancel()
	rpcLog.Info("Stopped trader server")
	return returnErr
}
Stop stops the server.
package pool
import (
	"bytes"
	"context"
	"encoding/hex"
	"errors"
	"fmt"
	"sync"
	"sync/atomic"
	"time"
	"github.com/btcsuite/btcd/btcec"
	"github.com/btcsuite/btcd/chaincfg/chainhash"
	"github.com/btcsuite/btcd/txscript"
	"github.com/btcsuite/btcd/wire"
	"github.com/btcsuite/btcutil"
	"github.com/davecgh/go-spew/spew"
	"github.com/lightninglabs/lndclient"
	"github.com/lightninglabs/pool/account"
	"github.com/lightninglabs/pool/auctioneer"
	"github.com/lightninglabs/pool/auctioneerrpc"
	"github.com/lightninglabs/pool/chaninfo"
	"github.com/lightninglabs/pool/clientdb"
	"github.com/lightninglabs/pool/event"
	"github.com/lightninglabs/pool/funding"
	"github.com/lightninglabs/pool/order"
	"github.com/lightninglabs/pool/poolrpc"
	"github.com/lightninglabs/pool/poolscript"
	"github.com/lightninglabs/pool/sidecar"
	"github.com/lightninglabs/pool/terms"
	"github.com/lightningnetwork/lnd/chanbackup"
	lndFunding "github.com/lightningnetwork/lnd/funding"
	"github.com/lightningnetwork/lnd/input"
	"github.com/lightningnetwork/lnd/lnrpc"
	"github.com/lightningnetwork/lnd/lnwallet/chainfee"
	"github.com/lightningnetwork/lnd/lnwire"
)
const (
	getInfoTimeout = 5 * time.Second
)
type rpcServer struct {
	started uint32  
	stopped uint32  
	bestHeight uint32
	poolrpc.UnimplementedTraderServer
	server         *Server
	lndServices    *lndclient.LndServices
	lndClient      lnrpc.LightningClient
	auctioneer     *auctioneer.Client
	accountManager *account.Manager
	orderManager   *order.Manager
	quit            chan struct{}
	wg              sync.WaitGroup
	blockNtfnCancel func()
	recoveryMutex   sync.Mutex
	recoveryPending bool
	wumboSupported bool
}
type accountStore struct {
	*clientdb.DB
}
var _ account.Store = (*accountStore)(nil)
func (s *accountStore) PendingBatch() error {
	_, err := s.DB.PendingBatchSnapshot()
	return err
}
func newRPCServer(server *Server) *rpcServer {
	accountStore := &accountStore{server.db}
	lndServices := &server.lndServices.LndServices
	return &rpcServer{
		server:      server,
		lndServices: lndServices,
		lndClient:   server.lndClient,
		auctioneer:  server.AuctioneerClient,
		accountManager: account.NewManager(&account.ManagerConfig{
			Store:          accountStore,
			Auctioneer:     server.AuctioneerClient,
			Wallet:         lndServices.WalletKit,
			Signer:         lndServices.Signer,
			ChainNotifier:  lndServices.ChainNotifier,
			TxSource:       lndServices.Client,
			TxFeeEstimator: lndServices.Client,
			TxLabelPrefix:  server.cfg.TxLabelPrefix,
		}),
		orderManager: order.NewManager(&order.ManagerConfig{
			Store:     server.db,
			AcctStore: accountStore,
			Lightning: lndServices.Client,
			Wallet:    lndServices.WalletKit,
			Signer:    lndServices.Signer,
		}),
		quit: make(chan struct{}),
	}
}
func (s *rpcServer) Start() error {
	if !atomic.CompareAndSwapUint32(&s.started, 0, 1) {
		return nil
	}
	rpcLog.Infof("Starting trader server")
	ctx := context.Background()
	lndCtx, lndCancel := context.WithTimeout(ctx, getInfoTimeout)
	defer lndCancel()
	info, err := s.lndClient.GetInfo(lndCtx, &lnrpc.GetInfoRequest{})
	if err != nil {
		return fmt.Errorf("error in GetInfo: %v", err)
	}
	_, s.wumboSupported = info.Features[uint32(lnwire.WumboChannelsRequired)]
	if !s.wumboSupported {
		_, s.wumboSupported = info.Features[uint32(lnwire.WumboChannelsOptional)]
	}
	rpcLog.Infof("Connected to lnd node %v with pubkey %v", info.Alias,
		info.IdentityPubkey)
	var blockCtx context.Context
	blockCtx, s.blockNtfnCancel = context.WithCancel(ctx)
	chainNotifier := s.lndServices.ChainNotifier
	blockChan, blockErrChan, err := chainNotifier.RegisterBlockEpochNtfn(
		blockCtx,
	)
	if err != nil {
		return err
	}
	var height int32
	select {
	case height = <-blockChan:
	case err := <-blockErrChan:
		return fmt.Errorf("unable to receive first block "+
			"notification: %v", err)
	case <-ctx.Done():
		return nil
	}
	s.updateHeight(height)
	if err := s.auctioneer.Start(); err != nil {
		return fmt.Errorf("unable to start auctioneer client: %v", err)
	}
	if err := s.accountManager.Start(); err != nil {
		return fmt.Errorf("unable to start account manager: %v", err)
	}
	if err := s.orderManager.Start(); err != nil {
		return fmt.Errorf("unable to start order manager: %v", err)
	}
	if err := s.server.fundingManager.Start(); err != nil {
		return fmt.Errorf("unable to start funding manager: %v", err)
	}
	if err := s.server.sidecarAcceptor.Start(blockErrChan); err != nil {
		return fmt.Errorf("unable to start sidecar acceptor: %v", err)
	}
	s.wg.Add(1)
	go s.serverHandler(blockChan, blockErrChan)
	rpcLog.Infof("Trader server is now active")
	return nil
}