Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor GetBlockVerboseTx to reflect correct getblock RPC call parameters. #1529

Merged
merged 4 commits into from
Mar 9, 2020
Merged

Refactor GetBlockVerboseTx to reflect correct getblock RPC call parameters. #1529

merged 4 commits into from
Mar 9, 2020

Conversation

jalavosus
Copy link
Contributor

Currently, rpcclient.GetBlockVerboseTx(...) does not return raw transaction data. This is due to how GetBlockCmd is implemented in btcjson; in upstream/master, getblock sends two boolean parameters (verbose and verbosetx), which throws an error.

According to the bitcoin JSON RPC documentation, getblock accepts two parameters: blockhash (as a string) and verbosity (as an integer). verbosity can be any of 0, 1, or 2, with 0 being the default.

getblock "blockhash" ( verbosity ) 

If verbosity is 0, returns a string that is serialized, hex-encoded data for block 'hash'.
If verbosity is 1, returns an Object with information about block .
If verbosity is 2, returns an Object with information about block  and information about each transaction. 

Arguments:
1. "blockhash"          (string, required) The block hash
2. verbosity              (numeric, optional, default=1) 0 for hex encoded data, 1 for a json object, and 2 for json object with transaction data

This pull request aims to correctly implement verbosity as a parameter to getblock by refactoring GetBlockCmd (in btcjson/chainsvrcmds.go) to have two fields: Hash and Verbosity, with Verbosity being an optional int pointer.

In order to implement correct behavior, three primary changes are necessary: the above refactor, an additional type specific to getblock verbosity=2, and a new Future type to enable proper (and error-free) unmarshalling of verbosity=2 data.

The new type (GetBlockVerboseTxResult) is almost entirely the same as GetBlockVerboseResult, but with the minor modification of changing the Tx field from a []string to a []TxRawResult so as to enable proper unmarshalling.

The new Future type (FutureGetBlockVerboseTxResult) returns a GetBlockVerboseTxResult rather than a GetBlockVerboseResult so that data can be properly returned to the user without error.

@jalavosus jalavosus changed the title Fix getblock Refactor GetBlockVerboseTx to reflect correct getblock RPC call parameters. Jan 31, 2020
@jalavosus
Copy link
Contributor Author

Additional data from the RPC documentation:

Result (for verbosity = 0):
"data"             (string) A string that is serialized, hex-encoded data for block 'hash'.

Result (for verbosity = 1):
{
  "hash" : "hash",     (string) the block hash (same as provided)
  "confirmations" : n,   (numeric) The number of confirmations, or -1 if the block is not on the main chain
  "size" : n,            (numeric) The block size
  "strippedsize" : n,    (numeric) The block size excluding witness data
  "weight" : n           (numeric) The block weight as defined in BIP 141
  "height" : n,          (numeric) The block height or index
  "version" : n,         (numeric) The block version
  "versionHex" : "00000000", (string) The block version formatted in hexadecimal
  "merkleroot" : "xxxx", (string) The merkle root
  "tx" : [               (array of string) The transaction ids
     "transactionid"     (string) The transaction id
     ,...
  ],
  "time" : ttt,          (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)
  "mediantime" : ttt,    (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)
  "nonce" : n,           (numeric) The nonce
  "bits" : "1d00ffff", (string) The bits
  "difficulty" : x.xxx,  (numeric) The difficulty
  "chainwork" : "xxxx",  (string) Expected number of hashes required to produce the chain up to this block (in hex)
  "nTx" : n,             (numeric) The number of transactions in the block.
  "previousblockhash" : "hash",  (string) The hash of the previous block
  "nextblockhash" : "hash"       (string) The hash of the next block
}

Result (for verbosity = 2):
{
  ...,                     Same output as verbosity = 1.
  "tx" : [               (array of Objects) The transactions in the format of the getrawtransaction RPC. Different from verbosity = 1 "tx" result.
         ,...
  ],
  ,...                     Same output as verbosity = 1.
}

@jalavosus
Copy link
Contributor Author

This is a duplicate of #1528, due to me using master in #1528 as opposed to a proper feature branch.

Copy link
Collaborator

@jakesylvestre jakesylvestre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're still referring to c.Verbose here, a type which you deleted

See the CI output for details

@jalavosus
Copy link
Contributor Author

@jakesyl thanks for the heads up, I'll fix that in another commit.

@jakesylvestre
Copy link
Collaborator

jakesylvestre commented Mar 4, 2020

@jcvernaleo (as per #1530)

  • high priority
  • outdated (or just incomplete, needs a quick fix to run on CI)

@jalavosus
Copy link
Contributor Author

jalavosus commented Mar 5, 2020

@jakesyl @jcvernaleo Please review this when you get the chance, and sorry about all the tiny commits -- it's been a long night.

Edit: Did a force push to my branch with a squash + rebase to upstream.

… bitcoin json RPC verbosity format for getblock,

which uses 0, 1, or 2 as parameters rather than a boolean true or false.
…getblock "hash" verbosity=1,

and a second type for getblock "hash" verbosity=2. This is necessary due to how getblock returns
a block's transaction data based on the provided verbosity parameter.

If verbosity=1, then getblock.Tx is an array of a block's transaction ids (txids) as strings.
If verbosity=2, then getblock.Tx is an array of raw transaction data.
…rboseResult, and FutureGetBlockVerboseTxResult.

Due to differences in how getblock returns data based on the provided verbosity parameter, it's necessary
to have two separate return types based on verbosity. This necessitates a separate unmarshalling function
(represented throughout rpcclient/chain.go as Result.Receive()) to ensure that data is correctly unmarshalled
and returned to the user.
Copy link
Member

@jcvernaleo jcvernaleo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great. Could you squash it to one commit and then I'll merge it.

@jcvernaleo
Copy link
Member

Does #1232 still block this? I don't think so but I might have missed it.

@jakesylvestre
Copy link
Collaborator

jakesylvestre commented Mar 7, 2020

Nope, read the test output wrong

@jakesylvestre jakesylvestre merged commit c4f3999 into btcsuite:master Mar 9, 2020
@jcvernaleo
Copy link
Member

For future PRs, could we try to stick to squash and rebase first so we can stick with a linear history?

@jakesylvestre
Copy link
Collaborator

@jcvernaleo my bad - I hit "Squash and Merge" and no clue what happened, haven't merged any non-squashed since

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants