Skip to content

Commit 09c3fea

Browse files
author
Larry Ruane
committed
use getblock verbose=3 instead of two getblock calls
If available, use `getblock verbose=3`. If not available, use the old way, which requires making two `getblock` RPCs. This is only a performance improvement.
1 parent 283cc64 commit 09c3fea

File tree

1 file changed

+39
-21
lines changed

1 file changed

+39
-21
lines changed

common/common.go

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ type (
154154
ZcashRpcReplyGetblock1 struct {
155155
Hash string
156156
Tx []string
157+
Hex string
157158
Trees struct {
158159
Sapling struct {
159160
Size uint32
@@ -311,21 +312,38 @@ func getBlockFromRPC(height int) (*walletrpc.CompactBlock, error) {
311312
}
312313
params := make([]json.RawMessage, 2)
313314
params[0] = heightJSON
314-
// Fetch the block using the verbose option ("1") because it provides
315-
// both the list of txids, which we're not yet able to compute for
316-
// Orchard (V5) transactions, and the block hash (block ID), which
317-
// we need to fetch the raw data format of the same block. Don't fetch
315+
316+
// We're not (yet) able to compute v5 transactions IDs (from the raw
317+
// serialized transaction), so we get this from zcashd 'getblock'.
318+
//
319+
// First try verbose=3, which returns a JSON object with exactly
320+
// what's needed: the block raw hex and the list of txids.
321+
//
322+
// If unsuccessful (zcashd isn't upgraded),
323+
// fetch the block using the verbose option ("1") because it provides
324+
// both the list of txids and the block hash (block ID), which we then
325+
// use to fetch the raw data format of the same block. Don't fetch
318326
// by height in case a reorg occurs between the two getblock calls;
319327
// using block hash ensures that we're fetching the same block.
320-
params[1] = json.RawMessage("1")
328+
params[1] = json.RawMessage("3")
321329
result, rpcErr := RawRequest("getblock", params)
322330
if rpcErr != nil {
323331
// Check to see if we are requesting a height the zcashd doesn't have yet
324332
if (strings.Split(rpcErr.Error(), ":"))[0] == "-8" {
325333
return nil, nil
326334
}
327-
return nil, fmt.Errorf("error requesting verbose block: %w", rpcErr)
335+
// zcashd must not be upgraded to support verbose=3
336+
params[1] = json.RawMessage("1")
337+
result, rpcErr = RawRequest("getblock", params)
338+
if rpcErr != nil {
339+
// Check to see if we are requesting a height the zcashd doesn't have yet
340+
if (strings.Split(rpcErr.Error(), ":"))[0] == "-8" {
341+
return nil, nil
342+
}
343+
return nil, fmt.Errorf("error requesting verbose block: %w", rpcErr)
344+
}
328345
}
346+
// This type works for both the verbose=1 or 3 reply.
329347
var block1 ZcashRpcReplyGetblock1
330348
err = json.Unmarshal(result, &block1)
331349
if err != nil {
@@ -335,26 +353,26 @@ func getBlockFromRPC(height int) (*walletrpc.CompactBlock, error) {
335353
if err != nil {
336354
Log.Fatal("getBlockFromRPC bad block hash", block1.Hash)
337355
}
338-
params[0] = blockHash
339-
params[1] = json.RawMessage("0") // non-verbose (raw hex)
340-
result, rpcErr = RawRequest("getblock", params)
356+
if block1.Hex == "" {
357+
// the getblock verbose=3 attempt must have failed, get the raw hex now
358+
params[0] = blockHash
359+
params[1] = json.RawMessage("0") // non-verbose (raw hex, non-JSON)
360+
result, rpcErr = RawRequest("getblock", params)
341361

342-
// For some reason, the error responses are not JSON
343-
if rpcErr != nil {
344-
return nil, fmt.Errorf("error requesting block: %w", rpcErr)
345-
}
362+
// For some reason, the error responses are not JSON
363+
if rpcErr != nil {
364+
return nil, fmt.Errorf("error requesting block: %w", rpcErr)
365+
}
346366

347-
var blockDataHex string
348-
err = json.Unmarshal(result, &blockDataHex)
349-
if err != nil {
350-
return nil, fmt.Errorf("error reading JSON response: %w", err)
367+
err = json.Unmarshal(result, &block1.Hex)
368+
if err != nil {
369+
return nil, fmt.Errorf("error reading JSON response: %w", err)
370+
}
351371
}
352-
353-
blockData, err := hex.DecodeString(blockDataHex)
372+
blockData, err := hex.DecodeString(block1.Hex)
354373
if err != nil {
355-
return nil, fmt.Errorf("error decoding getblock output: %w", err)
374+
return nil, fmt.Errorf("error decoding block hex: %w", err)
356375
}
357-
358376
block := parser.NewBlock()
359377
rest, err := block.ParseFromSlice(blockData)
360378
if err != nil {

0 commit comments

Comments
 (0)