Skip to content

Commit

Permalink
pool: Handle (nil,nil) response from dcrd.GetTxOut
Browse files Browse the repository at this point in the history
  • Loading branch information
jholdstock authored Dec 22, 2023
1 parent 8ebd1cb commit eb166a7
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 4 deletions.
6 changes: 4 additions & 2 deletions pool/hub.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,11 @@ type WalletConnection interface {
Rescan(ctx context.Context, in *walletrpc.RescanRequest, opts ...grpc.CallOption) (walletrpc.WalletService_RescanClient, error)
}

// NodeConnection defines the functionality needed by a mining node
// connection for the pool.
// NodeConnection defines the functionality needed by a mining node connection
// for the pool. Typically a dcrd client but can be stubbed for testing.
type NodeConnection interface {
// GetTxOut fetches the output referenced by the provided txHash and index.
// WARNING: dcrd can return (nil, nil).
GetTxOut(context.Context, *chainhash.Hash, uint32, int8, bool) (*chainjson.GetTxOutResult, error)
CreateRawTransaction(context.Context, []chainjson.TransactionInput, map[stdaddr.Address]dcrutil.Amount, *int64, *int64) (*wire.MsgTx, error)
GetWorkSubmit(context.Context, string) (bool, error)
Expand Down
10 changes: 8 additions & 2 deletions pool/paymentmgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ const (
// pool. Typically a dcrd client but can be stubbed for testing.
type txCreator interface {
// GetTxOut fetches the output referenced by the provided txHash and index.
// WARNING: dcrd can return (nil, nil).
GetTxOut(context.Context, *chainhash.Hash, uint32, int8, bool) (*chainjson.GetTxOutResult, error)
// CreateRawTransaction generates a transaction from the provided
// inputs and payouts.
Expand Down Expand Up @@ -641,8 +642,13 @@ func (pm *PaymentMgr) generatePayoutTxDetails(ctx context.Context, txC txCreator
// the current height.
txOutResult, err := txC.GetTxOut(ctx, txHash, coinbaseIndex, wire.TxTreeRegular, false)
if err != nil {
desc := fmt.Sprintf("%s: unable to find tx output: %v",
funcName, err)
desc := fmt.Sprintf("%s: unable to find tx output %s:%d: %v",
funcName, txHash, coinbaseIndex, err)
return nil, nil, nil, 0, errs.PoolError(errs.TxOut, desc)
}
if txOutResult == nil {
desc := fmt.Sprintf("%s: unable to find tx output %s:%d",
funcName, txHash, coinbaseIndex)
return nil, nil, nil, 0, errs.PoolError(errs.TxOut, desc)
}
if txOutResult.Confirmations < int64(pm.cfg.ActiveNet.CoinbaseMaturity+1) {
Expand Down
15 changes: 15 additions & 0 deletions pool/paymentmgr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,21 @@ func testPaymentMgrPayment(t *testing.T) {
t.Fatalf("expected a fetch txOut error, got %v", err)
}

// Ensure a (nil, nil) response from dcrd is handled gracefully.
// generatePayoutTxDetails should return a TxOut error rather than
// generating a panic.
txC = &txCreatorImpl{
getTxOut: func(ctx context.Context, txHash *chainhash.Hash, index uint32, tree int8, mempool bool) (*chainjson.GetTxOutResult, error) {
return nil, nil
},
}
_, _, _, _, err = mgr.generatePayoutTxDetails(ctx, txC, poolFeeAddrs,
mPmts, coinbaseIndex)
if !errors.Is(err, errs.TxOut) {
cancel()
t.Fatalf("expected a fetch txOut error, got %v", err)
}

// Ensure generating payout tx details returns an error if the returned
// output is not spendable.
txC = &txCreatorImpl{
Expand Down

0 comments on commit eb166a7

Please sign in to comment.