rpcserver: Return template errors from getwork RPC.
This modifies the RPC server getwork method to return an error in the case of a failed background template. Callers generally expect an error as opposed to long blocking behavior in the case there is a temporary reason block templates are unable to be generated. Also, correct the offsets in the comments regarding the serialized locations of the fields while here.
This commit is contained in:
parent
659b7fed1f
commit
bccbb9a722
@ -3660,11 +3660,20 @@ func getWorkTemplateKey(header *wire.BlockHeader) [merkleRootPairSize]byte {
|
||||
//
|
||||
// This function MUST be called with the RPC workstate locked.
|
||||
func handleGetWorkRequest(s *Server) (interface{}, error) {
|
||||
// Return an error immediately in the case of a failed background template.
|
||||
//
|
||||
// The only time this is expected is due to imposition of certain additional
|
||||
// time-based rules such as when the maximum allowed difficulty on testnet
|
||||
// is reached and not enough time has passed since the last block.
|
||||
bt := s.cfg.BlockTemplater
|
||||
if _, err := bt.CurrentTemplate(); err != nil {
|
||||
return nil, rpcMiscError(fmt.Sprintf("no work is available: %v", err))
|
||||
}
|
||||
|
||||
// Prune old templates and wait for updated templates when the current best
|
||||
// chain changes.
|
||||
state := s.workState
|
||||
best := s.cfg.Chain.BestSnapshot()
|
||||
bt := s.cfg.BlockTemplater
|
||||
var template *mining.BlockTemplate
|
||||
if state.prevHash == nil || *state.prevHash != best.Hash {
|
||||
// Prune old templates from the pool when the best block changes.
|
||||
@ -3726,10 +3735,10 @@ func handleGetWorkRequest(s *Server) (interface{}, error) {
|
||||
// retuned as part of the data below.
|
||||
//
|
||||
// For reference (0-index based, end value is exclusive):
|
||||
// data[115:119] --> Bits
|
||||
// data[135:139] --> Timestamp
|
||||
// data[139:143] --> Nonce
|
||||
// data[143:151] --> ExtraNonce
|
||||
// data[116:120] --> Bits
|
||||
// data[136:140] --> Timestamp
|
||||
// data[140:144] --> Nonce
|
||||
// data[144:152] --> ExtraNonce
|
||||
data := make([]byte, 0, getworkDataLen)
|
||||
buf := bytes.NewBuffer(data)
|
||||
err = headerCopy.Serialize(buf)
|
||||
|
||||
@ -5756,7 +5756,7 @@ func TestHandleGetWork(t *testing.T) {
|
||||
return templater
|
||||
}(),
|
||||
wantErr: true,
|
||||
errCode: dcrjson.ErrRPCInternal.Code,
|
||||
errCode: dcrjson.ErrRPCMisc,
|
||||
}, {
|
||||
name: "handleGetWork: no work during chain reorg",
|
||||
handler: handleGetWork,
|
||||
|
||||
@ -15,6 +15,7 @@ import (
|
||||
|
||||
"github.com/decred/dcrd/blockchain/standalone/v2"
|
||||
"github.com/decred/dcrd/chaincfg/chainhash"
|
||||
dcrdtypes "github.com/decred/dcrd/rpc/jsonrpc/types/v4"
|
||||
"github.com/decred/dcrd/rpcclient/v8"
|
||||
"github.com/decred/dcrd/wire"
|
||||
)
|
||||
@ -110,10 +111,14 @@ func waitPredicate(pred func() bool, timeout time.Duration) error {
|
||||
// This is only applicable for tests that run on simnet or other networks that
|
||||
// have a target block per count of 1 second.
|
||||
func AdjustedSimnetMiner(ctx context.Context, client *rpcclient.Client, nb uint32) ([]*chainhash.Hash, error) {
|
||||
|
||||
hashes := make([]*chainhash.Hash, nb)
|
||||
|
||||
prevWork, err := client.GetWork(ctx)
|
||||
// Fetch the current template. This might fail if there aren't enough
|
||||
// tickets in the mempool yet, so perform a few tries.
|
||||
var prevWork *dcrdtypes.GetWorkResult
|
||||
err := waitPredicate(func() bool {
|
||||
var err error
|
||||
prevWork, err = client.GetWork(ctx)
|
||||
return err == nil
|
||||
}, time.Second*10)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -135,6 +140,7 @@ func AdjustedSimnetMiner(ctx context.Context, client *rpcclient.Client, nb uint3
|
||||
return work.Data != prevWork.Data
|
||||
}, time.Second)
|
||||
|
||||
hashes := make([]*chainhash.Hash, nb)
|
||||
for i := uint32(0); i < nb; i++ {
|
||||
work, err := client.GetWork(ctx)
|
||||
if err != nil {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user