From 49b9db1a6418ba2034af58ec6ce4b96e0d3df464 Mon Sep 17 00:00:00 2001 From: jholdstock Date: Wed, 23 Aug 2023 16:33:53 +0100 Subject: [PATCH] rpc: Fix block connected handler. Fix a bug where it appeared as though a notification handler was being attached to the dcrd RPC client, but actually no notifications were received until the client was disconnected a new one was created. Now, rather than delaying attaching the notification handler, it is attached immediately upon client creation and vspd does not start handling the received notifications until it is ready. --- cmd/vspd/vspd.go | 17 ++++++++++------- rpc/dcrd.go | 22 ++++++++++------------ 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/cmd/vspd/vspd.go b/cmd/vspd/vspd.go index fc5111c..903b2ac 100644 --- a/cmd/vspd/vspd.go +++ b/cmd/vspd/vspd.go @@ -42,6 +42,8 @@ type vspd struct { db *database.VspDatabase dcrd rpc.DcrdConnect wallets rpc.WalletConnect + + blockNotifChan chan *wire.BlockHeader } // newVspd creates the essential resources required by vspd - a database, logger @@ -56,9 +58,12 @@ func newVspd(cfg *config) (*vspd, error) { log := cfg.logger("VSP") rpcLog := cfg.logger("RPC") + // Create a channel to receive blockConnected notifications from dcrd. + blockNotifChan := make(chan *wire.BlockHeader) + // Create RPC client for local dcrd instance (used for broadcasting and // checking the status of fee transactions). - dcrd := rpc.SetupDcrd(cfg.DcrdUser, cfg.DcrdPass, cfg.DcrdHost, cfg.dcrdCert, cfg.netParams.Params, rpcLog) + dcrd := rpc.SetupDcrd(cfg.DcrdUser, cfg.DcrdPass, cfg.DcrdHost, cfg.dcrdCert, cfg.netParams.Params, rpcLog, blockNotifChan) // Create RPC client for remote dcrwallet instances (used for voting). wallets := rpc.SetupWallet(cfg.walletUsers, cfg.walletPasswords, cfg.walletHosts, cfg.walletCerts, cfg.netParams.Params, rpcLog) @@ -69,6 +74,8 @@ func newVspd(cfg *config) (*vspd, error) { db: db, dcrd: dcrd, wallets: wallets, + + blockNotifChan: blockNotifChan, } return v, nil @@ -162,8 +169,7 @@ func (v *vspd) run() int { return 1 } - // Create a channel to receive blockConnected notifications from dcrd. - notifChan := make(chan *wire.BlockHeader) + // Start handling blockConnected notifications from dcrd. shutdownWg.Add(1) go func() { for { @@ -171,16 +177,13 @@ func (v *vspd) run() int { case <-shutdownCtx.Done(): shutdownWg.Done() return - case header := <-notifChan: + case header := <-v.blockNotifChan: v.log.Debugf("Block notification %d (%s)", header.Height, header.BlockHash().String()) v.blockConnected() } } }() - // Attach notification listener to dcrd client. - v.dcrd.BlockConnectedHandler(notifChan) - // Loop forever attempting ensuring a dcrd connection is available, so // notifications are received. shutdownWg.Add(1) diff --git a/rpc/dcrd.go b/rpc/dcrd.go index 93fa73a..667b282 100644 --- a/rpc/dcrd.go +++ b/rpc/dcrd.go @@ -46,24 +46,22 @@ type DcrdConnect struct { log slog.Logger } -func SetupDcrd(user, pass, addr string, cert []byte, params *chaincfg.Params, log slog.Logger) DcrdConnect { +func SetupDcrd(user, pass, addr string, cert []byte, params *chaincfg.Params, log slog.Logger, + blockConnectedChan chan *wire.BlockHeader) DcrdConnect { + client := setup(user, pass, addr, cert, log) + + client.notifier = &blockConnectedHandler{ + blockConnected: blockConnectedChan, + log: log, + } + return DcrdConnect{ - client: setup(user, pass, addr, cert, log), + client: client, params: params, log: log, } } -// BlockConnectedHandler attaches a blockconnected notification handler to the -// dcrd client. Every time a notification is received, the header of the -// connected block is sent to the provided channel. -func (d *DcrdConnect) BlockConnectedHandler(blockConnected chan *wire.BlockHeader) { - d.client.notifier = &blockConnectedHandler{ - blockConnected: blockConnected, - log: d.log, - } -} - func (d *DcrdConnect) Close() { d.client.Close() d.log.Debug("dcrd client closed")