func (a *SidecarAcceptor) subscribe() {
	defer a.wg.Done()
	for {
		select {
		case serverMsg, ok := <-a.client.FromServerChan:
			if !ok {
				return
			}
			if err := a.handleServerMessage(serverMsg); err != nil {
				sdcrLog.Errorf("Error while handling server "+
					"message: %v", err)
			}
		case <-a.quit:
			return
		}
	}
}
subscribe subscribes to auction messages coming in from the server. Since we
are only on the receiving end of a sidecar order if we receive a message here
we only have to do three things during the match making process: Connect out
to the maker and register the funding shim in the prepare step and wait for
the incoming channel in the sign step. The rest is just cleanup of pending
states.
package pool
import (
	"bytes"
	"context"
	"fmt"
	"sync"
	"github.com/btcsuite/btcd/btcec"
	"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/clientdb"
	"github.com/lightninglabs/pool/funding"
	"github.com/lightninglabs/pool/order"
	"github.com/lightninglabs/pool/sidecar"
	"github.com/lightningnetwork/lnd/keychain"
	"github.com/lightningnetwork/lnd/subscribe"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)
type SidecarAcceptor struct {
	cfg *SidecarAcceptorConfig
	client                *auctioneer.Client
	pendingOpenChanClient *subscribe.Client
	pendingSidecarOrders    map[order.Nonce]*sidecar.Ticket
	pendingSidecarOrdersMtx sync.Mutex
	pendingBatch            *order.Batch
	sync.Mutex
	negotiators map[[64]byte]*SidecarNegotiator
	quit chan struct{}
	wg   sync.WaitGroup
}
type SidecarAcceptorConfig struct {
	SidecarDB sidecar.Store
	AcctDB account.Store
	Signer lndclient.SignerClient
	Wallet lndclient.WalletKitClient
	BaseClient funding.BaseClient
	Acceptor *ChannelAcceptor
	NodePubKey *btcec.PublicKey
	ClientCfg auctioneer.Config
	PrepareOrder orderPreparer
	FundingManager *funding.Manager
	FetchSidecarBid func(*sidecar.Ticket) (*order.Bid, error)
}
func NewSidecarAcceptor(cfg *SidecarAcceptorConfig) *SidecarAcceptor {
	cfg.ClientCfg.ConnectSidecar = true
	return &SidecarAcceptor{
		cfg:                  cfg,
		pendingSidecarOrders: make(map[order.Nonce]*sidecar.Ticket),
		quit:                 make(chan struct{}),
		negotiators:          make(map[[64]byte]*SidecarNegotiator),
	}
}
func (a *SidecarAcceptor) Start(errChan chan error) error {
	var err error
	a.client, err = auctioneer.NewClient(&a.cfg.ClientCfg)
	if err != nil {
		return fmt.Errorf("error creating auctioneer client: %v", err)
	}
	if err := a.client.Start(); err != nil {
		return fmt.Errorf("error starting auctioneer client: %v", err)
	}
	if err := a.cfg.Acceptor.Start(errChan); err != nil {
		return fmt.Errorf("error starting channel acceptor: %v", err)
	}
	a.pendingOpenChanClient, err = a.cfg.FundingManager.SubscribePendingOpenChan()
	if err != nil {
		return fmt.Errorf("error subscribing to pending open channel "+
			"events: %v", err)
	}
	tickets, err := a.cfg.SidecarDB.Sidecars()
	if err != nil {
		return fmt.Errorf("error reading sidecar tickets: %v", err)
	}
	for _, ticket := range tickets {
		switch {
		case ticket.Offer.Auto && !ticket.State.IsTerminal():
			acct, err := a.cfg.AcctDB.Account(ticket.Offer.SignPubKey)
			switch {
			case err == clientdb.ErrAccountNotFound:
				autoAcceptor := NewSidecarNegotiator(AutoAcceptorConfig{
					Provider: false,
					StartingPkt: &SidecarPacket{
						CurrentState:   ticket.State,
						ReceiverTicket: ticket,
						ProviderTicket: ticket,
					},
					Driver:  a,
					MailBox: a,
				})
				if err := autoAcceptor.Start(); err != nil {
					return err
				}
				streamID, err := deriveRecipientStreamID(ticket)
				if err != nil {
					return fmt.Errorf("unable to derive "+
						"stream IDs: %v", err)
				}
				a.Lock()
				a.negotiators[streamID] = autoAcceptor
				a.Unlock()
			case err == nil:
				ticketBid, err := a.cfg.FetchSidecarBid(ticket)
				if err != nil {
					return fmt.Errorf("unable to fetch "+
						"sidecar bid: %w", err)
				}
				state := ticket.State
				if state == sidecar.StateOffered {
					state = sidecar.StateCreated
				}
				autoAcceptor := NewSidecarNegotiator(AutoAcceptorConfig{
					Provider:    true,
					ProviderBid: ticketBid,
					StartingPkt: &SidecarPacket{
						CurrentState:   state,
						ReceiverTicket: ticket,
						ProviderTicket: ticket,
					},
					ProviderAccount: acct,
					Driver:          a,
					MailBox:         a,
				})
				if err := autoAcceptor.Start(); err != nil {
					return err
				}
				streamID, err := deriveRecipientStreamID(ticket)
				if err != nil {
					return fmt.Errorf("unable to derive "+
						"stream IDs: %v", err)
				}
				a.Lock()
				a.negotiators[streamID] = autoAcceptor
				a.Unlock()
			default:
				return fmt.Errorf("unable to fetch account "+
					"for sidecar: %w", err)
			}
			continue
		case ticket.State != sidecar.StateExpectingChannel:
			continue
		case ticket.Recipient == nil:
			continue
		}
		r := ticket.Recipient
		if !r.NodePubKey.IsEqual(a.cfg.NodePubKey) {
			continue
		}
		ctxb := context.Background()
		if err := a.ExpectChannel(ctxb, ticket); err != nil {
			return fmt.Errorf("error subscribing to batch "+
				"updates for sidecar ticket: %v", err)
		}
	}
	a.wg.Add(1)
	go a.subscribe()
	return nil
}