From ec0d5d12b1b7b315f7c677dade8a477922b73070 Mon Sep 17 00:00:00 2001 From: Jonathan Chappelow Date: Tue, 18 Jul 2023 17:29:49 -0500 Subject: [PATCH 1/3] jsonrpc/types: Add powhash to verbose block output. --- rpc/jsonrpc/types/chainsvrresults.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rpc/jsonrpc/types/chainsvrresults.go b/rpc/jsonrpc/types/chainsvrresults.go index 1a0896b12b..2db1120453 100644 --- a/rpc/jsonrpc/types/chainsvrresults.go +++ b/rpc/jsonrpc/types/chainsvrresults.go @@ -1,5 +1,5 @@ // Copyright (c) 2014 The btcsuite developers -// Copyright (c) 2015-2022 The Decred developers +// Copyright (c) 2015-2023 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -62,6 +62,7 @@ type GetAddedNodeInfoResult struct { // hex-encoded string. Contains Decred additions. type GetBlockVerboseResult struct { Hash string `json:"hash"` + PoWHash string `json:"powhash"` Confirmations int64 `json:"confirmations"` Size int32 `json:"size"` Height int64 `json:"height"` @@ -137,6 +138,7 @@ type GetBlockChainInfoResult struct { // returns a hex-encoded string. type GetBlockHeaderVerboseResult struct { Hash string `json:"hash"` + PowHash string `json:"powhash"` Confirmations int64 `json:"confirmations"` Version int32 `json:"version"` MerkleRoot string `json:"merkleroot"` From ec33d6e60a00e8148b8ff0a85ca9feb4a572bf7d Mon Sep 17 00:00:00 2001 From: Jonathan Chappelow Date: Tue, 18 Jul 2023 17:31:53 -0500 Subject: [PATCH 2/3] rpc: Add PoWHash to getblock/getblockheader (verbose) results. --- internal/rpcserver/rpcserver.go | 24 +++++++++++++++++++- internal/rpcserver/rpcserverhandlers_test.go | 6 +++++ internal/rpcserver/rpcserverhelp.go | 4 +++- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/internal/rpcserver/rpcserver.go b/internal/rpcserver/rpcserver.go index 8de7bb7167..f44d4ff2ba 100644 --- a/internal/rpcserver/rpcserver.go +++ b/internal/rpcserver/rpcserver.go @@ -61,7 +61,7 @@ import ( // API version constants const ( jsonrpcSemverMajor = 8 - jsonrpcSemverMinor = 0 + jsonrpcSemverMinor = 1 jsonrpcSemverPatch = 0 ) @@ -1969,8 +1969,19 @@ func handleGetBlock(_ context.Context, s *Server, cmd interface{}) (interface{}, return nil, rpcInternalError(err.Error(), "Unable to retrieve median block time") } + isBlake3PowActive, err := s.isBlake3PowAgendaActive(&blockHeader.PrevBlock) + if err != nil { + return nil, err + } + powHashFn := blockHeader.PowHashV1 + if isBlake3PowActive { + powHashFn = blockHeader.PowHashV2 + } + powHash := powHashFn() + blockReply := types.GetBlockVerboseResult{ Hash: c.Hash, + PoWHash: powHash.String(), Version: blockHeader.Version, MerkleRoot: blockHeader.MerkleRoot.String(), StakeRoot: blockHeader.StakeRoot.String(), @@ -2249,8 +2260,19 @@ func handleGetBlockHeader(_ context.Context, s *Server, cmd interface{}) (interf return nil, rpcInternalError(err.Error(), "Unable to retrieve median block time") } + isBlake3PowActive, err := s.isBlake3PowAgendaActive(&blockHeader.PrevBlock) + if err != nil { + return nil, err + } + powHashFn := blockHeader.PowHashV1 + if isBlake3PowActive { + powHashFn = blockHeader.PowHashV2 + } + powHash := powHashFn() + blockHeaderReply := types.GetBlockHeaderVerboseResult{ Hash: c.Hash, + PowHash: powHash.String(), Confirmations: confirmations, Version: blockHeader.Version, MerkleRoot: blockHeader.MerkleRoot.String(), diff --git a/internal/rpcserver/rpcserverhandlers_test.go b/internal/rpcserver/rpcserverhandlers_test.go index 7e7ac83068..1fc559c549 100644 --- a/internal/rpcserver/rpcserverhandlers_test.go +++ b/internal/rpcserver/rpcserverhandlers_test.go @@ -3763,6 +3763,8 @@ func TestHandleGetBlock(t *testing.T) { blk := dcrutil.NewBlock(&block432100) blkHash := blk.Hash() blkHashString := blkHash.String() + powHash := blkHeader.PowHashV1() // pre-DCP0011 activation + powHashString := powHash.String() blkBytes, err := blk.Bytes() if err != nil { t.Fatalf("error serializing block: %+v", err) @@ -3827,6 +3829,7 @@ func TestHandleGetBlock(t *testing.T) { }(), result: types.GetBlockVerboseResult{ Hash: blkHashString, + PoWHash: powHashString, Version: blkHeader.Version, MerkleRoot: blkHeader.MerkleRoot.String(), StakeRoot: blkHeader.StakeRoot.String(), @@ -3882,6 +3885,7 @@ func TestHandleGetBlock(t *testing.T) { }(), result: types.GetBlockVerboseResult{ Hash: blkHashString, + PoWHash: powHashString, Version: blkHeader.Version, MerkleRoot: blkHeader.MerkleRoot.String(), StakeRoot: blkHeader.StakeRoot.String(), @@ -4032,6 +4036,7 @@ func TestHandleGetBlockHeader(t *testing.T) { t.Fatalf("error serializing block header: %+v", err) } blkHeaderHexString := hex.EncodeToString(blkHeaderBytes) + powHashString := blkHeader.PowHashV1().String() // pre-DCP0011 block blk := dcrutil.NewBlock(&block432100) blkHash := blk.Hash() blkHashString := blkHash.String() @@ -4065,6 +4070,7 @@ func TestHandleGetBlockHeader(t *testing.T) { }(), result: types.GetBlockHeaderVerboseResult{ Hash: blkHashString, + PowHash: powHashString, Confirmations: confirmations, Version: blkHeader.Version, MerkleRoot: blkHeader.MerkleRoot.String(), diff --git a/internal/rpcserver/rpcserverhelp.go b/internal/rpcserver/rpcserverhelp.go index 158b68eee0..807219f689 100644 --- a/internal/rpcserver/rpcserverhelp.go +++ b/internal/rpcserver/rpcserverhelp.go @@ -1,5 +1,5 @@ // Copyright (c) 2015 The btcsuite developers -// Copyright (c) 2015-2022 The Decred developers +// Copyright (c) 2015-2023 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -276,6 +276,7 @@ var helpDescsEnUS = map[string]string{ // GetBlockVerboseResult help. "getblockverboseresult-hash": "The hash of the block (same as provided)", + "getblockverboseresult-powhash": "The Proof-of-Work hash of the block (same as hash prior to DCP0011 activation)", "getblockverboseresult-confirmations": "The number of confirmations", "getblockverboseresult-size": "The size of the block", "getblockverboseresult-height": "The height of the block in the block chain", @@ -323,6 +324,7 @@ var helpDescsEnUS = map[string]string{ // GetBlockHeaderVerboseResult help. "getblockheaderverboseresult-hash": "The hash of the block (same as provided)", + "getblockheaderverboseresult-powhash": "The Proof-of-Work hash of the block (same as hash prior to DCP0011 activation)", "getblockheaderverboseresult-confirmations": "The number of confirmations", "getblockheaderverboseresult-height": "The height of the block in the block chain", "getblockheaderverboseresult-version": "The block version", From 75d0b8ec2214e56232ac972814fb6c9de869e8a8 Mon Sep 17 00:00:00 2001 From: Jonathan Chappelow Date: Tue, 18 Jul 2023 17:36:59 -0500 Subject: [PATCH 3/3] docs: Update JSON-RPC API for powhash. --- docs/json_rpc_api.mediawiki | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/json_rpc_api.mediawiki b/docs/json_rpc_api.mediawiki index c98a9a943d..ac60cd4720 100644 --- a/docs/json_rpc_api.mediawiki +++ b/docs/json_rpc_api.mediawiki @@ -989,6 +989,7 @@ of the best block. | (json object) : hash: (string) the hash of the block (same as provided). +: powhash: (string) the Proof-of-Work hash of the block (same as hash prior to DCP0011 activation). : confirmations: (numeric) the number of confirmations. : size: (numeric) the size of the block. : height: (numeric) the height of the block in the block chain. @@ -1015,7 +1016,7 @@ of the best block. : previousblockhash: (string) the hash of the previous block. : nextblockhash: (string) the hash of the next block (only if there is one). -{"hash": "blockhash", "confirmations": n, "size": n, "height": n, "version": n, "merkleroot": "hash", "stakeroot": "hash", "tx": ["transactionhash", ...], "stx": ["transactionhash", ...], "time": n, "nonce": n, "votebits": n, "finalstate": "state", "voters": n, "freshstake": n, "revocations": n, "poolsize": n, "bits": n, "sbits": n.nn, "difficulty": n.nn, "chainwork": "workhex", "extradata": "data", "stakeversion": n, previousblockhash": "hash", "nextblockhash": "hash"} +{"hash": "blockhash", "powhash": "hash", "confirmations": n, "size": n, "height": n, "version": n, "merkleroot": "hash", "stakeroot": "hash", "tx": ["transactionhash", ...], "stx": ["transactionhash", ...], "time": n, "nonce": n, "votebits": n, "finalstate": "state", "voters": n, "freshstake": n, "revocations": n, "poolsize": n, "bits": n, "sbits": n.nn, "difficulty": n.nn, "chainwork": "workhex", "extradata": "data", "stakeversion": n, previousblockhash": "hash", "nextblockhash": "hash"} |- !Example Return (verbose=false) | @@ -1033,7 +1034,7 @@ of the best block. : 0000000000000000ffffffff0800002f646372642f00" |- !Example Return (verbose=true, verbosetx=false) -|"hash": "000000000000c41019872ff7db8fd2e9bfa05f42d3f8fee8e895e8c1e5b8dcba", "confirmations": 283285,"size": 382, "height": 2, "version": 1, "merkleroot": "c867d085c96604812854399bf6df63d35d857484fedfd147759ed94c3cdeca35", "stakeroot": "000000000000000000000000000000000000000000000000000000000000000", tx": ["ba8d2fcb5c705a1e5cbeda0db9dd30a521e360efd3aef75e862b2b69e0a673af", ...], "time": 1454954624, "nonce": 837992634, "votebits": 1, "finalstate": "000000000000", "voters": 0, "freshstake": 0, "revocations": 0, "poolsize": 0, "bits": "1d00ffff", "sbits": 2, "difficulty": 32767.74999809, "chainwork": "00000000000000000000000000000000000000000000000000018000c0006000", "extradata": "c84e3a6b6ad536d3010000000000000000000000000000000000000000000000", "stakeversion": 0, "previousblockhash": "000000000000437482b6d47f82f374cde539440ddb108b0a76886f0d87d126b9", "nextblockhash": "00000000000108ac3e3f51a0f4424dd757a3b0485da0ec96592f637f27bd1cf5"} +|"hash": "000000000000c41019872ff7db8fd2e9bfa05f42d3f8fee8e895e8c1e5b8dcba", "powhash": "000000000000c41019872ff7db8fd2e9bfa05f42d3f8fee8e895e8c1e5b8dcba", "confirmations": 283285,"size": 382, "height": 2, "version": 1, "merkleroot": "c867d085c96604812854399bf6df63d35d857484fedfd147759ed94c3cdeca35", "stakeroot": "000000000000000000000000000000000000000000000000000000000000000", tx": ["ba8d2fcb5c705a1e5cbeda0db9dd30a521e360efd3aef75e862b2b69e0a673af", ...], "time": 1454954624, "nonce": 837992634, "votebits": 1, "finalstate": "000000000000", "voters": 0, "freshstake": 0, "revocations": 0, "poolsize": 0, "bits": "1d00ffff", "sbits": 2, "difficulty": 32767.74999809, "chainwork": "00000000000000000000000000000000000000000000000000018000c0006000", "extradata": "c84e3a6b6ad536d3010000000000000000000000000000000000000000000000", "stakeversion": 0, "previousblockhash": "000000000000437482b6d47f82f374cde539440ddb108b0a76886f0d87d126b9", "nextblockhash": "00000000000108ac3e3f51a0f4424dd757a3b0485da0ec96592f637f27bd1cf5"} |} ---- @@ -1136,6 +1137,7 @@ of the best block. !Returns (verbose=true) |(json object) : hash: (string) the hash of the block (same as provided). +: powhash: (string) the Proof-of-Work hash of the block (same as hash prior to DCP0011 activation). : confirmations: (numeric) the number of confirmations. : version: (numeric) the block version. : merkleroot: (string) root hash of the merkle tree. @@ -1160,7 +1162,7 @@ of the best block. : previousblockhash: (string) the hash of the previous block. : nextblockhash: (string) the hash of the next block (only if there is one). -{"hash": "blockhash", "confirmations": n, "version": n, "merkleroot": "hash", "stakeroot": "hash", "votebits": n, "finalstate": "state", "voters": n, "freshstake": n, "revocations": n, "poolsize": n, "bits": n, "sbits": n.nn, "height": n, "size": n, "time": n, "nonce": n, "extradata": "data", "stakeversion": n, "difficulty": n.nn, "chainwork": "workhex", "previousblockhash": "hash", "nextblockhash": "hash"} +{"hash": "blockhash", "powhash": "hash", "confirmations": n, "version": n, "merkleroot": "hash", "stakeroot": "hash", "votebits": n, "finalstate": "state", "voters": n, "freshstake": n, "revocations": n, "poolsize": n, "bits": n, "sbits": n.nn, "height": n, "size": n, "time": n, "nonce": n, "extradata": "data", "stakeversion": n, "difficulty": n.nn, "chainwork": "workhex", "previousblockhash": "hash", "nextblockhash": "hash"} |- !Example Return (verbose=false) | @@ -1172,7 +1174,7 @@ of the best block. : 360000000024680140d1ec18000000000000000000000000000000000000000000000000" |- !Example Return (verbose=true) -|{"hash": "00000000000004289d9a7b0f7a332fb60a1c221faae89a107ce3ab93eead2f93", "confirmations": 183291, "version": 1, "merkleroot": "2549a4ef697c4a5e067b752bc06a32e74e56e6eddc7a6cb3e299f072469d6b26", "stakeroot":"9f40e23afeb9645f3762170a4469c812f717c71aea543ed073af02968ecc5c82", "votebits": 1, "finalstate": "8b736885bab7", "voters": 5, "freshstake": 0, "revocations": 0, "poolsize": 42567, "bits": "1a1194b4", "sbits": 86.73331302, "height": 100000, "size": 3168, "time": 1484890112, "nonce": 59487578, "stakeversion": 0, "difficulty": 954273.50809769, "chainwork": "00000000000000000000000000000000000000000000001060ad4432c4d6eff1", "previousblockhash": "00000000000000dab92a8a0c0e706eb74115f0f373669c01ffb4882f9555f494", "nextblockhash": "0000000000000578b08f22fd2bdf5f7fe5b0af1bb4928de5053a3f906b3c8f6b"} +|{"hash": "00000000000004289d9a7b0f7a332fb60a1c221faae89a107ce3ab93eead2f93", "powhash": "00000000000004289d9a7b0f7a332fb60a1c221faae89a107ce3ab93eead2f93", "confirmations": 183291, "version": 1, "merkleroot": "2549a4ef697c4a5e067b752bc06a32e74e56e6eddc7a6cb3e299f072469d6b26", "stakeroot":"9f40e23afeb9645f3762170a4469c812f717c71aea543ed073af02968ecc5c82", "votebits": 1, "finalstate": "8b736885bab7", "voters": 5, "freshstake": 0, "revocations": 0, "poolsize": 42567, "bits": "1a1194b4", "sbits": 86.73331302, "height": 100000, "size": 3168, "time": 1484890112, "nonce": 59487578, "stakeversion": 0, "difficulty": 954273.50809769, "chainwork": "00000000000000000000000000000000000000000000001060ad4432c4d6eff1", "previousblockhash": "00000000000000dab92a8a0c0e706eb74115f0f373669c01ffb4882f9555f494", "nextblockhash": "0000000000000578b08f22fd2bdf5f7fe5b0af1bb4928de5053a3f906b3c8f6b"} |} ----