Repository: decred/dcrd
Pull request #2640 (2021-04-27 17:39:02)

rpcserver: Allow gettreasurybalance empty blk str.
When an empty string is provided for the optional block hash argument
to `gettreasurybalance`, this should be treated as if it were omitted rather
than the zero hash, which is an invalid block.

This changes `handleGetTreasuryBalance` to treat `""` like `nil`. This change
is consistent with how `handleGetTreasurySpendVotes` handles its optional
block argument.

The tests for both `gettreasurybalance` and `gettreasuryspendvotes` are
updated to ensure this behavior (existing for `gettreasuryspendvotes`).

`gettreasuryspendvotes` handles it like this already:

```
$ dcrctl gettreasuryspendvotes "" '["47de5efe98f073b6f33fbffb1743bacb850fbd8be5723195a744086061f5f0f2"]'
{
  "hash": "0000001c3a63d55611a2b11340d02456e9d1b28195a5effd978c653b3d5668f7",
  "height": 671777,
  "votes": [
    {
      "hash": "47de5efe98f073b6f33fbffb1743bacb850fbd8be5723195a744086061f5f0f2",
      "expiry": 560882,
      "votestart": 560640,
      "voteend": 560880,
      "yesvotes": 380,
      "novotes": 65
    }
  ]
}
```

but `gettreasurybalance` did not:

```
$ dcrctl gettreasurybalance "" true
-5: Block not found: 0000000000000000000000000000000000000000000000000000000000000000
```

With this PR (on release-v1.6):

```
$ dcrctl gettreasurybalance "" true
{
  "hash": "0000000dc2f6babad37f7cb808672fceaad630564618bd61167226522cd86aab",
  "height": 671793,
  "balance": 1427848700668,
  "updates": [
    9561569
  ]
}
```

chappjc: Squashed.  Note that I only tested this backported to release-v1.6 (without the tests delta since the tests appear to be missing on release-v1.6).
davecgh: > Squashed. Note that I only tested this backported to release-v1.6 (without the tests diff since the tests appear to be missing on release-v1.6).

Thanks for the heads up.  I tested it with master.

Patch:
diff --git a/internal/rpcserver/rpcserver.go b/internal/rpcserver/rpcserver.go
index b5c026b9..de46c3c0 100644
--- a/internal/rpcserver/rpcserver.go
+++ b/internal/rpcserver/rpcserver.go
@@ -3031,7 +3031,7 @@ func handleGetTreasuryBalance(_ context.Context, s *Server, cmd interface{}) (in
 	// Either parse the provided hash or use the current best tip hash when none
 	// is provided.
 	var hash chainhash.Hash
-	if c.Hash == nil {
+	if c.Hash == nil || *c.Hash == "" {
 		hash = s.cfg.Chain.BestSnapshot().Hash
 	} else {
 		parsedHash, err := chainhash.NewHashFromStr(*c.Hash)


Test patch:
diff --git a/internal/rpcserver/rpcserverhandlers_test.go b/internal/rpcserver/rpcserverhandlers_test.go
index ad4e6d93..0e54b926 100644
--- a/internal/rpcserver/rpcserverhandlers_test.go
+++ b/internal/rpcserver/rpcserverhandlers_test.go
@@ -4819,6 +4819,19 @@ func TestHandleGetTreasuryBalance(t *testing.T) {
 			Balance: balance,
 			Updates: updates,
 		},
+	}, {
+		name:    "handleGetTreasuryBalance: ok empty block hash with verbose",
+		handler: handleGetTreasuryBalance,
+		cmd: &types.GetTreasuryBalanceCmd{
+			Hash:    dcrjson.String(""),
+			Verbose: dcrjson.Bool(true),
+		},
+		result: types.GetTreasuryBalanceResult{
+			Hash:    blkHashString,
+			Height:  blkHeight,
+			Balance: balance,
+			Updates: updates,
+		},
 	}, {
 		name:    "handleGetTreasuryBalance: ok with block hash",
 		handler: handleGetTreasuryBalance,
@@ -6461,6 +6474,26 @@ func TestHandleTSpendVotes(t *testing.T) {
 				NoVotes:   50,
 			}},
 		},
+	}, {
+		name:            "tspendVotes: empty block hash string counts mempool tspend votes up to tip",
+		mockTxMempooler: mempoolTSpends,
+		mockChain:       chainVotes,
+		handler:         handleGetTreasurySpendVotes,
+		cmd: &types.GetTreasurySpendVotesCmd{
+			Block: dcrjson.String(""),
+		},
+		result: types.GetTreasurySpendVotesResult{
+			Hash:   bestHash,
+			Height: 432100,
+			Votes: []types.TreasurySpendVotes{{
+				Hash:      tspendHash.String(),
+				Expiry:    432290,
+				VoteStart: 428832,
+				VoteEnd:   432288,
+				YesVotes:  100,
+				NoVotes:   50,
+			}},
+		},
 	}, {
 		name:            "tspendVotes: requesting block in the past does not count votes",
 		mockTxMempooler: mempoolTSpends,