diff --git a/dcrjson/chainsvrresults.go b/dcrjson/chainsvrresults.go index d7b594d6..d3fa6202 100644 --- a/dcrjson/chainsvrresults.go +++ b/dcrjson/chainsvrresults.go @@ -85,6 +85,7 @@ type GetBlockVerboseResult struct { ExtraData string `json:"extradata"` StakeVersion uint32 `json:"stakeversion"` Difficulty float64 `json:"difficulty"` + ChainWork string `json:"chainwork"` PreviousHash string `json:"previousblockhash"` NextHash string `json:"nextblockhash,omitempty"` } @@ -137,6 +138,7 @@ type GetBlockHeaderVerboseResult struct { ExtraData string `json:"extradata"` StakeVersion uint32 `json:"stakeversion"` Difficulty float64 `json:"difficulty"` + ChainWork string `json:"chainwork"` PreviousHash string `json:"previousblockhash,omitempty"` NextHash string `json:"nextblockhash,omitempty"` } diff --git a/docs/json_rpc_api.md b/docs/json_rpc_api.md index 315430c3..850d1704 100644 --- a/docs/json_rpc_api.md +++ b/docs/json_rpc_api.md @@ -280,9 +280,9 @@ the method name for further details such as parameter and return information. |Parameters|1. `block hash`: `(string, required)` the hash of the block.
2. `verbose`: `(boolean, optional, default=true)` specifies the block is returned as a JSON object instead of hex-encoded string.
3. `verbosetx`: `(boolean, optional, default=false)` specifies that each transaction is returned as a JSON object and only applies if the `verbose` flag is true.| |Description|Returns information about a block given its hash.| |Returns (verbose=false)|`"data" (string) hex-encoded bytes of the serialized block`| -|Returns (verbose=true, verbosetx=false)|`(json object)`
`hash`: `(string)` the hash of the block (same as provided).
`confirmations`: `(numeric)` the number of confirmations.
`size`: `(numeric)` the size of the block.
`height`: `(numeric)` the height of the block in the block chain.
`version`: `(numeric)` the block version.
`merkleroot`: `(string)` root hash of the merkle tree.
`stakeroot`: `(string)` root hash of the stake tree.
`tx`: `(json array of string)` the transaction hashes.
`stx`: `(json array of string)` the stake transaction hashes.
`time`: `(numeric)` the block time in seconds since 1 Jan 1970 GMT.
`nonce`: `(numeric)` the block nonce.
`votebits`: `(numeric)` the block voting results.
`finalstate`: `(string)` the final lottery state.
`voters`: `(numeric)` the number of votes.
`freshstake`: `(numeric)` the number of ticket purchases.
`revocations`: `(numeric)` the number of ticket revocations.
`poolsize`: `(numeric)` the total number of valid spendble tickets as of the block.
`bits`: `(numeric)` the bits which represent the block difficulty.
`sbits`: `(numeric)` the bits which represent the stake difficulty.
`difficulty`: `(numeric)` the proof-of-work difficulty as a multiple of the minimum difficulty.
`extradata`: `(string)` extra data for the block including the extra nonce used by proof-of-work miners.
`stakeversion`: `(string)` block stake version.
`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, "extradata": "data", "stakeversion": n, previousblockhash": "hash", "nextblockhash": "hash"}`| +|Returns (verbose=true, verbosetx=false)|`(json object)`
`hash`: `(string)` the hash of the block (same as provided).
`confirmations`: `(numeric)` the number of confirmations.
`size`: `(numeric)` the size of the block.
`height`: `(numeric)` the height of the block in the block chain.
`version`: `(numeric)` the block version.
`merkleroot`: `(string)` root hash of the merkle tree.
`stakeroot`: `(string)` root hash of the stake tree.
`tx`: `(json array of string)` the transaction hashes.
`stx`: `(json array of string)` the stake transaction hashes.
`time`: `(numeric)` the block time in seconds since 1 Jan 1970 GMT.
`nonce`: `(numeric)` the block nonce.
`votebits`: `(numeric)` the block voting results.
`finalstate`: `(string)` the final lottery state.
`voters`: `(numeric)` the number of votes.
`freshstake`: `(numeric)` the number of ticket purchases.
`revocations`: `(numeric)` the number of ticket revocations.
`poolsize`: `(numeric)` the total number of valid spendble tickets as of the block.
`bits`: `(numeric)` the bits which represent the block difficulty.
`sbits`: `(numeric)` the bits which represent the stake difficulty.
`difficulty`: `(numeric)` the proof-of-work difficulty as a multiple of the minimum difficulty.
`chainwork`: `(string)` the total number of hashes expected to produce the chain up to the block in hex.
`extradata`: `(string)` extra data for the block including the extra nonce used by proof-of-work miners.
`stakeversion`: `(string)` block stake version.
`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"}`| |Example Return (verbose=false)|Newlines added for display purposes. The actual return does not contain newlines.
`"01000000b926d1870d6f88760a8b10db0d4439e5cd74f3827fd4b6827443000000000000`
`35cade3c4cd99e7547d1dffe8474855dd363dff69b395428810466c985d067c800000000`
`000000000000000000000000000000000000000000000000000000000100000000000000`
`0000000000000000ffff011b00c2eb0b00000000020000007e01000080d8b856bac0f231`
`c84e3a6b6ad536d301000000000000000000000000000000000000000000000000000000`
`010100000001000000000000000000000000000000000000000000000000000000000000`
`0000ffffffff00ffffffff03fa1a981200000000000017a914f5916158e3e2c4551c1796`
`708db8367207ed13bb8700000000000000000000266a2402000000000000000000000000`
`000000000000000000000000000000ffa310d9a6a9588edea1906f0000000000001976a9`
`148ffe7a49ecf0f4858e7a52155302177398d2296988ac000000000000000001d8bc2882`
`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, "extradata": "c84e3a6b6ad536d3010000000000000000000000000000000000000000000000", "stakeversion": 0, "previousblockhash": "000000000000437482b6d47f82f374cde539440ddb108b0a76886f0d87d126b9", "nextblockhash": "00000000000108ac3e3f51a0f4424dd757a3b0485da0ec96592f637f27bd1cf5"}`| +|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"}`| [Return to Overview](#MethodOverview)
*** @@ -318,10 +318,10 @@ the method name for further details such as parameter and return information. |Parameters|1. `block hash`: `(string, required)` the hash of the block.
2. `verbose`: `(boolean, optional, default=true)` specifies the block header is returned as a JSON object instead of a hex-encoded string.| |Description|Returns hex-encoded bytes of the serialized block header.| |Returns (verbose=false)|`"data" (string) hex-encoded bytes of the serialized block`| -|Returns (verbose=true)|`(json object)`
`hash`: `(string)` the hash of the block (same as provided).
`confirmations`: `(numeric)` the number of confirmations.
`version`: `(numeric)` the block version.
`merkleroot`: `(string)` root hash of the merkle tree.
`stakeroot`: `(string)` root hash of the stake tree.
`votebits`: `(numeric)` the block voting results.
`finalstate`: `(string)` the final lottery state.
`voters`: `(numeric)` the number of votes.
`freshstake`: `(numeric)` the number of ticket purchases.
`revocations`: `(numeric)` the number of ticket revocations.
`poolsize`: `(numeric)` the total number of valid spendble tickets as of the block.
`bits`: `(numeric)` the bits which represent the block difficulty.
`sbits`: `(numeric)` the bits which represent the stake difficulty.
`height`: `(numeric)` the height of the block in the block chain.
`size`: `(numeric)` the size of the block.
`time`: `(numeric)` the block time in seconds since 1 Jan 1970 GMT.
`nonce`: `(numeric)` the block nonce.
`extradata`: `(string)` extra data for the block including the extra nonce used by proof-of-work miners.
`stakeversion`: `(string)` block stake version.
`difficulty`: `(numeric)` the proof-of-work difficulty as a multiple of the minimum difficulty.
`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, "previousblockhash": "hash", "nextblockhash": "hash"}` +|Returns (verbose=true)|`(json object)`
`hash`: `(string)` the hash of the block (same as provided).
`confirmations`: `(numeric)` the number of confirmations.
`version`: `(numeric)` the block version.
`merkleroot`: `(string)` root hash of the merkle tree.
`stakeroot`: `(string)` root hash of the stake tree.
`votebits`: `(numeric)` the block voting results.
`finalstate`: `(string)` the final lottery state.
`voters`: `(numeric)` the number of votes.
`freshstake`: `(numeric)` the number of ticket purchases.
`revocations`: `(numeric)` the number of ticket revocations.
`poolsize`: `(numeric)` the total number of valid spendble tickets as of the block.
`bits`: `(numeric)` the bits which represent the block difficulty.
`sbits`: `(numeric)` the bits which represent the stake difficulty.
`height`: `(numeric)` the height of the block in the block chain.
`size`: `(numeric)` the size of the block.
`time`: `(numeric)` the block time in seconds since 1 Jan 1970 GMT.
`nonce`: `(numeric)` the block nonce.
`extradata`: `(string)` extra data for the block including the extra nonce used by proof-of-work miners.
`stakeversion`: `(string)` block stake version.
`difficulty`: `(numeric)` the proof-of-work difficulty as a multiple of the minimum difficulty.
`chainwork`: `(string)` the total number of hashes expected to produce the chain up to the block in hex.
`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"}` | |Example Return (verbose=false)|Newlines added for display purposes. The actual return does not contain newlines.
`"0100000094f455952f88b4ff019c6673f3f01541b76e700e0c8a2ab9da00000000000000`
`266b9d4672f099e2b36c7adcede6564ee7326ac02b757b065e4a7c69efa44925825ccc8e`
`9602af73d03e54ea1ac717f712c869440a1762375f64b9fe3ae2409f01008b736885bab7`
`0500000047a60000b494111a6688f80402000000a0860100600c000000a081585ab58b03`
`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, "previousblockhash": "00000000000000dab92a8a0c0e706eb74115f0f373669c01ffb4882f9555f494", "nextblockhash": "0000000000000578b08f22fd2bdf5f7fe5b0af1bb4928de5053a3f906b3c8f6b"}`| +|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"}`| [Return to Overview](#MethodOverview)
*** diff --git a/rpcserver.go b/rpcserver.go index c760c4a2..d6508762 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1808,6 +1808,11 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i return hex.EncodeToString(blkBytes), nil } + chainWork, err := s.chain.ChainWork(hash) + if err != nil { + return nil, rpcInternalError(err.Error(), "Failed to retrieve work") + } + best := s.chain.BestSnapshot() // Get next block hash unless there are none. @@ -1849,6 +1854,7 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i Bits: strconv.FormatInt(int64(blockHeader.Bits), 16), SBits: sbitsFloat, Difficulty: getDifficultyRatio(blockHeader.Bits), + ChainWork: fmt.Sprintf("%064x", chainWork), ExtraData: hex.EncodeToString(blockHeader.ExtraData[:]), NextHash: nextHashString, } @@ -2031,6 +2037,11 @@ func handleGetBlockHeader(s *rpcServer, cmd interface{}, closeChan <-chan struct // The verbose flag is set, so generate the JSON object and return it. + chainWork, err := s.chain.ChainWork(hash) + if err != nil { + return nil, rpcInternalError(err.Error(), "Failed to retrieve work") + } + best := s.chain.BestSnapshot() // Get next block hash unless there are none. @@ -2071,6 +2082,7 @@ func handleGetBlockHeader(s *rpcServer, cmd interface{}, closeChan <-chan struct ExtraData: hex.EncodeToString(blockHeader.ExtraData[:]), StakeVersion: blockHeader.StakeVersion, Difficulty: getDifficultyRatio(blockHeader.Bits), + ChainWork: fmt.Sprintf("%064x", chainWork), PreviousHash: blockHeader.PrevBlock.String(), NextHash: nextHashString, } diff --git a/rpcserverhelp.go b/rpcserverhelp.go index 61452d82..fdd5c6f1 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -304,6 +304,7 @@ var helpDescsEnUS = map[string]string{ "getblockverboseresult-nonce": "The block nonce", "getblockverboseresult-bits": "The bits which represent the block difficulty", "getblockverboseresult-difficulty": "The proof-of-work difficulty as a multiple of the minimum difficulty", + "getblockverboseresult-chainwork": "The total number of hashes expected to produce the chain up to the block in hex", "getblockverboseresult-previousblockhash": "The hash of the previous block", "getblockverboseresult-nextblockhash": "The hash of the next block (only if there is one)", "getblockverboseresult-sbits": "The stake difficulty of theblock", @@ -346,6 +347,7 @@ var helpDescsEnUS = map[string]string{ "getblockheaderverboseresult-nonce": "The block nonce", "getblockheaderverboseresult-bits": "The bits which represent the block difficulty", "getblockheaderverboseresult-difficulty": "The proof-of-work difficulty as a multiple of the minimum difficulty", + "getblockheaderverboseresult-chainwork": "The total number of hashes expected to produce the chain up to the block in hex", "getblockheaderverboseresult-previousblockhash": "The hash of the previous block", "getblockheaderverboseresult-nextblockhash": "The hash of the next block (only if there is one)", "getblockheaderverboseresult-size": "The size of the block in bytes",