mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-07-06 04:42:31 +00:00
[NOD-122] Fix timeout for get block template requests (#254)
* [NOD-122] Handle each message in rpcclient with a separate goroutine * [NOD-122] Stop listening to new blocks when not mining * [NOD-122] Made RPC logging in mining simulator more explicit + some styling enhencement
This commit is contained in:
parent
311c96122e
commit
a3735da12a
39
mining/simulator/client.go
Normal file
39
mining/simulator/client.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/daglabs/btcd/rpcclient"
|
||||||
|
"github.com/daglabs/btcd/util"
|
||||||
|
"github.com/daglabs/btcd/wire"
|
||||||
|
)
|
||||||
|
|
||||||
|
type simulatorClient struct {
|
||||||
|
*rpcclient.Client
|
||||||
|
onBlockAdded chan struct{}
|
||||||
|
notifyForNewBlocks bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSimulatorClient(address string, connCfg *rpcclient.ConnConfig) (*simulatorClient, error) {
|
||||||
|
client := &simulatorClient{
|
||||||
|
onBlockAdded: make(chan struct{}, 1),
|
||||||
|
}
|
||||||
|
notificationHandlers := &rpcclient.NotificationHandlers{
|
||||||
|
OnFilteredBlockAdded: func(height int32, header *wire.BlockHeader,
|
||||||
|
txs []*util.Tx) {
|
||||||
|
if client.notifyForNewBlocks {
|
||||||
|
client.onBlockAdded <- struct{}{}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
client.Client, err = rpcclient.New(connCfg, notificationHandlers)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Error connecting to address %s: %s", address, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = client.NotifyBlocks(); err != nil {
|
||||||
|
return nil, fmt.Errorf("Error while registering client %s for block notifications: %s", client.Host(), err)
|
||||||
|
}
|
||||||
|
return client, nil
|
||||||
|
}
|
@ -10,6 +10,7 @@ type config struct {
|
|||||||
AddressListPath string `long:"addresslist" description:"Path to a list of nodes' JSON-RPC endpoints" required:"true"`
|
AddressListPath string `long:"addresslist" description:"Path to a list of nodes' JSON-RPC endpoints" required:"true"`
|
||||||
CertificatePath string `long:"cert" description:"Path to certificate accepted by JSON-RPC endpoint"`
|
CertificatePath string `long:"cert" description:"Path to certificate accepted by JSON-RPC endpoint"`
|
||||||
DisableTLS bool `long:"notls" description:"Disable TLS"`
|
DisableTLS bool `long:"notls" description:"Disable TLS"`
|
||||||
|
Verbose bool `long:"verbose" short:"v" description:"Enable logging of RPC requests"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseConfig() (*config, error) {
|
func parseConfig() (*config, error) {
|
||||||
|
@ -6,15 +6,9 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/daglabs/btcd/dagconfig/daghash"
|
|
||||||
"github.com/daglabs/btcd/rpcclient"
|
"github.com/daglabs/btcd/rpcclient"
|
||||||
)
|
)
|
||||||
|
|
||||||
type simulatorClient struct {
|
|
||||||
*rpcclient.Client
|
|
||||||
onBlockAdded chan struct{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func connectToServers(cfg *config, addressList []string) ([]*simulatorClient, error) {
|
func connectToServers(cfg *config, addressList []string) ([]*simulatorClient, error) {
|
||||||
clients := make([]*simulatorClient, len(addressList))
|
clients := make([]*simulatorClient, len(addressList))
|
||||||
|
|
||||||
@ -28,12 +22,6 @@ func connectToServers(cfg *config, addressList []string) ([]*simulatorClient, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i, address := range addressList {
|
for i, address := range addressList {
|
||||||
onBlockAdded := make(chan struct{}, 1)
|
|
||||||
ntfnHandlers := &rpcclient.NotificationHandlers{
|
|
||||||
OnBlockAdded: func(hash *daghash.Hash, height int32, t time.Time) {
|
|
||||||
onBlockAdded <- struct{}{}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
connCfg := &rpcclient.ConnConfig{
|
connCfg := &rpcclient.ConnConfig{
|
||||||
Host: address,
|
Host: address,
|
||||||
Endpoint: "ws",
|
Endpoint: "ws",
|
||||||
@ -47,18 +35,10 @@ func connectToServers(cfg *config, addressList []string) ([]*simulatorClient, er
|
|||||||
connCfg.Certificates = cert
|
connCfg.Certificates = cert
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := rpcclient.New(connCfg, ntfnHandlers)
|
var err error
|
||||||
|
clients[i], err = newSimulatorClient(address, connCfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error connecting to address %s: %s", address, err)
|
return nil, err
|
||||||
}
|
|
||||||
|
|
||||||
if err := client.NotifyBlocks(); err != nil {
|
|
||||||
return nil, fmt.Errorf("Error while registering client %s for block notifications: %s", client.Host(), err)
|
|
||||||
}
|
|
||||||
|
|
||||||
clients[i] = &simulatorClient{
|
|
||||||
Client: client,
|
|
||||||
onBlockAdded: onBlockAdded,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Connected to server %s", address)
|
log.Printf("Connected to server %s", address)
|
||||||
|
24
mining/simulator/log.go
Normal file
24
mining/simulator/log.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btclog"
|
||||||
|
"github.com/daglabs/btcd/rpcclient"
|
||||||
|
)
|
||||||
|
|
||||||
|
type logWriter struct{}
|
||||||
|
|
||||||
|
func (logWriter) Write(p []byte) (n int, err error) {
|
||||||
|
log.Print(string(p))
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func enableRPCLogging() {
|
||||||
|
backendLog := btclog.NewBackend(logWriter{})
|
||||||
|
rpclog := backendLog.Logger("RPCC")
|
||||||
|
rpclog.SetLevel(btclog.LevelTrace)
|
||||||
|
rpcclient.UseLogger(rpclog)
|
||||||
|
|
||||||
|
log.SetFlags(log.LstdFlags | log.Lmicroseconds)
|
||||||
|
}
|
@ -2,21 +2,25 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/daglabs/btcd/signal"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
|
||||||
|
"github.com/daglabs/btcd/signal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
defer handlePanic()
|
defer handlePanic()
|
||||||
|
|
||||||
cfg, err := parseConfig()
|
cfg, err := parseConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Error parsing command-line arguments: %s", err)
|
fmt.Fprintf(os.Stderr, "Error parsing command-line arguments: %s", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cfg.Verbose {
|
||||||
|
enableRPCLogging()
|
||||||
|
}
|
||||||
|
|
||||||
addressList, err := getAddressList(cfg)
|
addressList, err := getAddressList(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("Couldn't load address list: %s", err))
|
panic(fmt.Errorf("Couldn't load address list: %s", err))
|
||||||
|
@ -79,6 +79,11 @@ func getBlockTemplate(client *simulatorClient, longPollID string) (*btcjson.GetB
|
|||||||
func templatesLoop(client *simulatorClient, newTemplateChan chan *btcjson.GetBlockTemplateResult, errChan chan error, stopChan chan struct{}) {
|
func templatesLoop(client *simulatorClient, newTemplateChan chan *btcjson.GetBlockTemplateResult, errChan chan error, stopChan chan struct{}) {
|
||||||
longPollID := ""
|
longPollID := ""
|
||||||
getBlockTemplateLongPoll := func() {
|
getBlockTemplateLongPoll := func() {
|
||||||
|
if longPollID != "" {
|
||||||
|
log.Printf("Requesting template with longPollID '%s' from %s", longPollID, client.Host())
|
||||||
|
} else {
|
||||||
|
log.Printf("Requesting template without longPollID from %s", client.Host())
|
||||||
|
}
|
||||||
template, err := getBlockTemplate(client, longPollID)
|
template, err := getBlockTemplate(client, longPollID)
|
||||||
if err == rpcclient.ErrResponseTimedOut {
|
if err == rpcclient.ErrResponseTimedOut {
|
||||||
log.Printf("Got timeout while requesting template '%s' from %s", longPollID, client.Host())
|
log.Printf("Got timeout while requesting template '%s' from %s", longPollID, client.Host())
|
||||||
@ -163,6 +168,7 @@ func mineLoop(clients []*simulatorClient) error {
|
|||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
currentClient := getRandomClient(clients)
|
currentClient := getRandomClient(clients)
|
||||||
|
currentClient.notifyForNewBlocks = true
|
||||||
log.Printf("Next block will be mined by: %s", currentClient.Host())
|
log.Printf("Next block will be mined by: %s", currentClient.Host())
|
||||||
mineNextBlock(currentClient, foundBlock, templateStopChan, errChan)
|
mineNextBlock(currentClient, foundBlock, templateStopChan, errChan)
|
||||||
block, ok := <-foundBlock
|
block, ok := <-foundBlock
|
||||||
@ -170,6 +176,7 @@ func mineLoop(clients []*simulatorClient) error {
|
|||||||
errChan <- nil
|
errChan <- nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
currentClient.notifyForNewBlocks = false
|
||||||
err := handleFoundBlock(currentClient, block, templateStopChan)
|
err := handleFoundBlock(currentClient, block, templateStopChan)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errChan <- err
|
errChan <- err
|
||||||
|
@ -431,7 +431,7 @@ out:
|
|||||||
}
|
}
|
||||||
break out
|
break out
|
||||||
}
|
}
|
||||||
c.handleMessage(msg)
|
go c.handleMessage(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the connection is closed.
|
// Ensure the connection is closed.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user