multi: Return total chain work in RPC results.

This modifies the getblock and getblockheader RPC results to include the
total number of hashes expected to produce the chain up to the requested
block in hex and updates the JSON-RPC API documentation accordingly.
This commit is contained in:
Dave Collins 2018-10-14 23:45:48 -05:00
parent 3a2bdcc332
commit 6d647094ee
No known key found for this signature in database
GPG Key ID: B8904D9D9C93D1F2
4 changed files with 20 additions and 4 deletions

View File

@ -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"`
}

View File

@ -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.<br />2. `verbose`: `(boolean, optional, default=true)` specifies the block is returned as a JSON object instead of hex-encoded string.<br />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)`<br />`hash`: `(string)` the hash of the block (same as provided).<br />`confirmations`: `(numeric)` the number of confirmations.<br />`size`: `(numeric)` the size of the block.<br />`height`: `(numeric)` the height of the block in the block chain.<br />`version`: `(numeric)` the block version.<br />`merkleroot`: `(string)` root hash of the merkle tree.<br />`stakeroot`: `(string)` root hash of the stake tree.<br />`tx`: `(json array of string)` the transaction hashes.<br />`stx`: `(json array of string)` the stake transaction hashes.<br />`time`: `(numeric)` the block time in seconds since 1 Jan 1970 GMT.<br />`nonce`: `(numeric)` the block nonce.<br />`votebits`: `(numeric)` the block voting results.<br />`finalstate`: `(string)` the final lottery state.<br />`voters`: `(numeric)` the number of votes.<br />`freshstake`: `(numeric)` the number of ticket purchases.<br />`revocations`: `(numeric)` the number of ticket revocations.<br />`poolsize`: `(numeric)` the total number of valid spendble tickets as of the block.<br />`bits`: `(numeric)` the bits which represent the block difficulty.<br />`sbits`: `(numeric)` the bits which represent the stake difficulty.<br />`difficulty`: `(numeric)` the proof-of-work difficulty as a multiple of the minimum difficulty.<br />`extradata`: `(string)` extra data for the block including the extra nonce used by proof-of-work miners.<br />`stakeversion`: `(string)` block stake version.<br />`previousblockhash`: `(string)` the hash of the previous block.<br />`nextblockhash`: `(string)` the hash of the next block (only if there is one).<br /><br />`{"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)`<br />`hash`: `(string)` the hash of the block (same as provided).<br />`confirmations`: `(numeric)` the number of confirmations.<br />`size`: `(numeric)` the size of the block.<br />`height`: `(numeric)` the height of the block in the block chain.<br />`version`: `(numeric)` the block version.<br />`merkleroot`: `(string)` root hash of the merkle tree.<br />`stakeroot`: `(string)` root hash of the stake tree.<br />`tx`: `(json array of string)` the transaction hashes.<br />`stx`: `(json array of string)` the stake transaction hashes.<br />`time`: `(numeric)` the block time in seconds since 1 Jan 1970 GMT.<br />`nonce`: `(numeric)` the block nonce.<br />`votebits`: `(numeric)` the block voting results.<br />`finalstate`: `(string)` the final lottery state.<br />`voters`: `(numeric)` the number of votes.<br />`freshstake`: `(numeric)` the number of ticket purchases.<br />`revocations`: `(numeric)` the number of ticket revocations.<br />`poolsize`: `(numeric)` the total number of valid spendble tickets as of the block.<br />`bits`: `(numeric)` the bits which represent the block difficulty.<br />`sbits`: `(numeric)` the bits which represent the stake difficulty.<br />`difficulty`: `(numeric)` the proof-of-work difficulty as a multiple of the minimum difficulty.<br />`chainwork`: `(string)` the total number of hashes expected to produce the chain up to the block in hex.<br />`extradata`: `(string)` extra data for the block including the extra nonce used by proof-of-work miners.<br />`stakeversion`: `(string)` block stake version.<br />`previousblockhash`: `(string)` the hash of the previous block.<br />`nextblockhash`: `(string)` the hash of the next block (only if there is one).<br /><br />`{"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.<br/> `"01000000b926d1870d6f88760a8b10db0d4439e5cd74f3827fd4b6827443000000000000`<br />`35cade3c4cd99e7547d1dffe8474855dd363dff69b395428810466c985d067c800000000`<br />`000000000000000000000000000000000000000000000000000000000100000000000000`<br />`0000000000000000ffff011b00c2eb0b00000000020000007e01000080d8b856bac0f231`<br />`c84e3a6b6ad536d301000000000000000000000000000000000000000000000000000000`<br />`010100000001000000000000000000000000000000000000000000000000000000000000`<br />`0000ffffffff00ffffffff03fa1a981200000000000017a914f5916158e3e2c4551c1796`<br />`708db8367207ed13bb8700000000000000000000266a2402000000000000000000000000`<br />`000000000000000000000000000000ffa310d9a6a9588edea1906f0000000000001976a9`<br />`148ffe7a49ecf0f4858e7a52155302177398d2296988ac000000000000000001d8bc2882`<br />`0000000000000000ffffffff0800002f646372642f00"`<br />|
|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)<br />
***
@ -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.<br />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)`<br />`hash`: `(string)` the hash of the block (same as provided).<br />`confirmations`: `(numeric)` the number of confirmations.<br />`version`: `(numeric)` the block version.<br />`merkleroot`: `(string)` root hash of the merkle tree.<br />`stakeroot`: `(string)` root hash of the stake tree.<br />`votebits`: `(numeric)` the block voting results.<br />`finalstate`: `(string)` the final lottery state.<br />`voters`: `(numeric)` the number of votes.<br />`freshstake`: `(numeric)` the number of ticket purchases.<br />`revocations`: `(numeric)` the number of ticket revocations.<br />`poolsize`: `(numeric)` the total number of valid spendble tickets as of the block.<br />`bits`: `(numeric)` the bits which represent the block difficulty.<br />`sbits`: `(numeric)` the bits which represent the stake difficulty.<br />`height`: `(numeric)` the height of the block in the block chain.<br />`size`: `(numeric)` the size of the block.<br />`time`: `(numeric)` the block time in seconds since 1 Jan 1970 GMT.<br />`nonce`: `(numeric)` the block nonce.<br />`extradata`: `(string)` extra data for the block including the extra nonce used by proof-of-work miners.<br />`stakeversion`: `(string)` block stake version.<br />`difficulty`: `(numeric)` the proof-of-work difficulty as a multiple of the minimum difficulty.<br />`previousblockhash`: `(string)` the hash of the previous block.<br />`nextblockhash`: `(string)` the hash of the next block (only if there is one).<br /><br />`{"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)`<br />`hash`: `(string)` the hash of the block (same as provided).<br />`confirmations`: `(numeric)` the number of confirmations.<br />`version`: `(numeric)` the block version.<br />`merkleroot`: `(string)` root hash of the merkle tree.<br />`stakeroot`: `(string)` root hash of the stake tree.<br />`votebits`: `(numeric)` the block voting results.<br />`finalstate`: `(string)` the final lottery state.<br />`voters`: `(numeric)` the number of votes.<br />`freshstake`: `(numeric)` the number of ticket purchases.<br />`revocations`: `(numeric)` the number of ticket revocations.<br />`poolsize`: `(numeric)` the total number of valid spendble tickets as of the block.<br />`bits`: `(numeric)` the bits which represent the block difficulty.<br />`sbits`: `(numeric)` the bits which represent the stake difficulty.<br />`height`: `(numeric)` the height of the block in the block chain.<br />`size`: `(numeric)` the size of the block.<br />`time`: `(numeric)` the block time in seconds since 1 Jan 1970 GMT.<br />`nonce`: `(numeric)` the block nonce.<br />`extradata`: `(string)` extra data for the block including the extra nonce used by proof-of-work miners.<br />`stakeversion`: `(string)` block stake version.<br />`difficulty`: `(numeric)` the proof-of-work difficulty as a multiple of the minimum difficulty.<br />`chainwork`: `(string)` the total number of hashes expected to produce the chain up to the block in hex.<br />`previousblockhash`: `(string)` the hash of the previous block.<br />`nextblockhash`: `(string)` the hash of the next block (only if there is one).<br /><br />`{"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.<br />`"0100000094f455952f88b4ff019c6673f3f01541b76e700e0c8a2ab9da00000000000000`<br />`266b9d4672f099e2b36c7adcede6564ee7326ac02b757b065e4a7c69efa44925825ccc8e`<br />`9602af73d03e54ea1ac717f712c869440a1762375f64b9fe3ae2409f01008b736885bab7`<br />`0500000047a60000b494111a6688f80402000000a0860100600c000000a081585ab58b03`<br />`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)<br />
***

View File

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

View File

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