Skip to content

Commit

Permalink
rpc: Fix block connected handler.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jholdstock committed Aug 24, 2023
1 parent bac0dce commit 49b9db1
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 19 deletions.
17 changes: 10 additions & 7 deletions cmd/vspd/vspd.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -69,6 +74,8 @@ func newVspd(cfg *config) (*vspd, error) {
db: db,
dcrd: dcrd,
wallets: wallets,

blockNotifChan: blockNotifChan,
}

return v, nil
Expand Down Expand Up @@ -162,25 +169,21 @@ 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 {
select {
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)
Expand Down
22 changes: 10 additions & 12 deletions rpc/dcrd.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down

0 comments on commit 49b9db1

Please sign in to comment.