@@ -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