While removing the globals from background.go it also made sense to clean up the use of dcrd RPC clients. Previously two seperate clients were maintained, one for making RPC calls and one for receiving notifications. These clients have been unified.
62 lines
1.4 KiB
Go
62 lines
1.4 KiB
Go
package rpc
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/decred/dcrd/wire"
|
|
)
|
|
|
|
type blockConnectedHandler struct {
|
|
blockConnected chan *wire.BlockHeader
|
|
}
|
|
|
|
// Notify is called every time a notification is received from dcrd client.
|
|
// A wsrpc.Client will never call Notify concurrently. Notify should not return
|
|
// an error because that will cause the client to close and no further
|
|
// notifications will be received until a new connection is established.
|
|
func (n *blockConnectedHandler) Notify(method string, msg json.RawMessage) error {
|
|
if method != "blockconnected" {
|
|
return nil
|
|
}
|
|
|
|
header, err := parseBlockConnected(msg)
|
|
if err != nil {
|
|
log.Errorf("Failed to parse dcrd block notification: %v", err)
|
|
return nil
|
|
}
|
|
|
|
n.blockConnected <- header
|
|
|
|
return nil
|
|
}
|
|
|
|
func (n *blockConnectedHandler) Close() error {
|
|
return nil
|
|
}
|
|
|
|
// parseBlockConnected extracts the block header from a
|
|
// blockconnected JSON-RPC notification.
|
|
func parseBlockConnected(msg json.RawMessage) (*wire.BlockHeader, error) {
|
|
var notif []string
|
|
err := json.Unmarshal(msg, ¬if)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("json unmarshal error: %w", err)
|
|
}
|
|
|
|
if len(notif) == 0 {
|
|
return nil, errors.New("notification is empty")
|
|
}
|
|
|
|
var header wire.BlockHeader
|
|
err = header.Deserialize(hex.NewDecoder(bytes.NewReader([]byte(notif[0]))))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error creating block header from bytes: %w", err)
|
|
}
|
|
|
|
return &header, nil
|
|
}
|