github.com/decred/dcrlnd@v0.7.6/lnrpc/initchainsyncrpc/initchainctrl_service.go (about)

     1  package initchainsyncrpc
     2  
     3  import (
     4  	"fmt"
     5  	"time"
     6  
     7  	"github.com/decred/dcrlnd/lnwallet"
     8  )
     9  
    10  // Server implements the initial chain sync gRPC service server.
    11  type Server struct {
    12  	chainCtrl        lnwallet.WalletController
    13  	chainCtrlSetChan chan struct{}
    14  }
    15  
    16  // A compile time check to ensure that Server fully implements the
    17  // InitialChainSync gRPC service.
    18  var _ InitialChainSyncServer = (*Server)(nil)
    19  
    20  // NewInitCHainSyncService initializes a new InitChainSyncService.
    21  func New() *Server {
    22  	return &Server{
    23  		chainCtrlSetChan: make(chan struct{}),
    24  	}
    25  }
    26  
    27  // SetChainControl sets the internal chain/wallet controller. MUST only be
    28  // called once.
    29  func (s *Server) SetChainControl(cc lnwallet.WalletController) {
    30  	s.chainCtrl = cc
    31  	close(s.chainCtrlSetChan)
    32  }
    33  
    34  func (s *Server) SubscribeChainSync(sub *ChainSyncSubscription, svr InitialChainSync_SubscribeChainSyncServer) error {
    35  	// Wait until the chain control is set.
    36  	ccSet := false
    37  	for !ccSet {
    38  		select {
    39  		case <-s.chainCtrlSetChan:
    40  			ccSet = true
    41  		case <-svr.Context().Done():
    42  			return svr.Context().Err()
    43  		}
    44  	}
    45  
    46  	var synced = false
    47  	delay := time.Millisecond
    48  	for !synced {
    49  		select {
    50  		case <-svr.Context().Done():
    51  			return svr.Context().Err()
    52  		case <-s.chainCtrl.InitialSyncChannel():
    53  			synced = true
    54  		case <-time.After(delay):
    55  		}
    56  
    57  		height, hash, ts, err := s.chainCtrl.BestBlock()
    58  		if err != nil {
    59  			return fmt.Errorf("unable to fetch current best block: %v", err)
    60  		}
    61  		updt := &ChainSyncUpdate{
    62  			BlockHeight:    height,
    63  			BlockHash:      hash[:],
    64  			BlockTimestamp: ts,
    65  			Synced:         synced,
    66  		}
    67  		if err := svr.Send(updt); err != nil {
    68  			return err
    69  		}
    70  
    71  		delay = 5 * time.Second
    72  	}
    73  	return nil
    74  }