Skip to content

Add support for getblock with verbosity 3 - #1339

Merged
NicolasDorier merged 6 commits into
MetacoSA:masterfrom
Carti-it:RPClient-1
Sep 21, 2026
Merged

NicolasDorier merged 6 commits into
MetacoSA:masterfrom
Carti-it:RPClient-1

Conversation

@Carti-it

@Carti-it Carti-it commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

This verbosity 3 option was introduced in Bitcoin Core 23.01 and its release notes mentions:

The getblock RPC command now supports verbosity level 3 containing transaction inputs' prevout information. The existing /rest/block/ REST endpoint is modified to contain this information too. Every vin field will contain an additional prevout subfield describing the spent output. prevout contains the following keys:

  • generated - true if the spent coins was a coinbase.
  • height
  • value
  • scriptPubKey

The PR can be reviewed one commit at a time with whitespace off (https://github.com/MetacoSA/NBitcoin/pull/1339/changes?w=1)

Footnotes

  1. It was released in 2022. ↩

}
}

private void AssertJsonEquals(string json1, string json2)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not in use

Comment thread NBitcoin/RPC/RPCClient.cs
Comment on lines -2008 to -2013
private Transaction ParseTxHex(string hex)
{
var tx = Network.Consensus.ConsensusFactory.CreateTransaction();
tx.ReadWrite(Encoders.Hex.DecodeData(hex), Network);
return tx;
}

@Carti-it Carti-it Sep 19, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

There is Transaction.Parse that should be IMO used as the one implementation to use everywhere.

edit: This change is not strictly necessary in this PR but I find it useful.

@Carti-it Carti-it changed the title RPCClient: Use standard method for transaction parsing Add support for getblock with verbosity 3 Sep 19, 2026
var node = builder.CreateNode();
await node.StartAsync();
var cli = node.CreateRPCClient();
using var builder = NodeBuilderEx.Create();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

4f5d4ad removes unnecessary indentation

Assert.Null(prevOutInfo);
}

// Assert the prevOut for our transaction.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

See the JSON that explains this part:

{
  "hash": "254a23cf90f22d5538b85d952f7b2c841527183ed6d042bbece39e7833ed7be6",
  "confirmations": 1,
  "height": 104,
  "version": 536870912,
  "versionHex": "20000000",
  "merkleroot": "749942a42e5b19d99532f77fedccf9f009fea9d2f8bd636cc7ee946e7ef00eb0",
  "time": 1789849953,
  "mediantime": 1789849952,
  "nonce": 1,
  "bits": "207fffff",
  "target": "7fffff0000000000000000000000000000000000000000000000000000000000",
  "difficulty": 4.656542373906925E-10,
  "chainwork": "00000000000000000000000000000000000000000000000000000000000000d2",
  "nTx": 2,
  "previousblockhash": "63c4865f8bf6a614f8fef5f24ccc93adc34066131da8e54312568b81fcdb4894",
  "strippedsize": 326,
  "size": 471,
  "weight": 1449,
  "coinbase_tx": {
    "version": 2,
    "locktime": 103,
    "sequence": 4294967294,
    "coinbase": "016800",
    "witness": "0000000000000000000000000000000000000000000000000000000000000000"
  },
  "tx": [
    {
      "txid": "fa503bcd5edb6b278e09c914fd98d67faed7e73405aa7f6741dee7ba36303cfa",
      "hash": "cfcd7b6008f932c2492561afd3b2f761eed10b427778b214411b66c7c745b614",
      "version": 2,
      "size": 168,
      "vsize": 141,
      "weight": 564,
      "locktime": 103,
      "vin": [
        {
          "coinbase": "016800",
          "txinwitness": [
            "0000000000000000000000000000000000000000000000000000000000000000"
          ],
          "sequence": 4294967294
        }
      ],
      "vout": [
        {
          "value": 50.0000282,
          "n": 0,
          "scriptPubKey": {
            "asm": "0 75b801f675adb64974d64c774f9079e9beda2687",
            "desc": "addr(bcrt1qwkuqran44kmyjaxkf3m5lyreaxld5f58zgjsd9)#76m7ed6x",
            "hex": "001475b801f675adb64974d64c774f9079e9beda2687",
            "address": "bcrt1qwkuqran44kmyjaxkf3m5lyreaxld5f58zgjsd9",
            "type": "witness_v0_keyhash"
          }
        },
        {
          "value": 0.0,
          "n": 1,
          "scriptPubKey": {
            "asm": "OP_RETURN aa21a9ed32525b54d20bae9a46130d47b653d9f2e85d0910291ae976fc0f09fd8f3a5504",
            "desc": "raw(6a24aa21a9ed32525b54d20bae9a46130d47b653d9f2e85d0910291ae976fc0f09fd8f3a5504)#mrv873td",
            "hex": "6a24aa21a9ed32525b54d20bae9a46130d47b653d9f2e85d0910291ae976fc0f09fd8f3a5504",
            "type": "nulldata"
          }
        }
      ],
      "hex": "020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03016800feffffff0204fd052a0100000016001475b801f675adb64974d64c774f9079e9beda26870000000000000000266a24aa21a9ed32525b54d20bae9a46130d47b653d9f2e85d0910291ae976fc0f09fd8f3a55040120000000000000000000000000000000000000000000000000000000000000000067000000"
    },
    {
      "txid": "f2595f028a06067fac620bb5588b48a67fdc63a1f625d86bcc91392f1bb9a094",
      "hash": "a60efd5d8bc7a2cc9854a5c87135f925b6b64d8e246e40135cedebdaaff6c763",
      "version": 2,
      "size": 222,
      "vsize": 141,
      "weight": 561,
      "locktime": 103,
      "vin": [
        {
          "txid": "228899f8ef8b677368a42e2e12e3d1759fef92e0011f7bbf257c9aed19ecd0c4",
          "vout": 0,
          "scriptSig": {
            "asm": "",
            "hex": ""
          },
          "txinwitness": [
            "3044022022766071aaba9d5b93977b3fde1a8243a52a0e0840da404427c53995a401d9fd02201fffb974906cdd99e3bc750290968c5a8c0176079cea0a01482585fea06a7b6401",
            "0386018cb0053876a9f47ffc8fa11e62063497c407bdd96ccf3c9e730dfb14e813"
          ],
          "prevout": {
            "generated": true,
            "height": 3,
            "value": 50.0,
            "scriptPubKey": {
              "asm": "0 75b801f675adb64974d64c774f9079e9beda2687",
              "desc": "addr(bcrt1qwkuqran44kmyjaxkf3m5lyreaxld5f58zgjsd9)#76m7ed6x",
              "hex": "001475b801f675adb64974d64c774f9079e9beda2687",
              "address": "bcrt1qwkuqran44kmyjaxkf3m5lyreaxld5f58zgjsd9",
              "type": "witness_v0_keyhash"
            }
          },
          "sequence": 4294967293
        }
      ],
      "vout": [
        {
          "value": 48.9999718,
          "n": 0,
          "scriptPubKey": {
            "asm": "0 da8b839488b686e06a845290b0b2a5818a9b46b8",
            "desc": "addr(bcrt1qm29c89ygk6rwq65y22gtpv49sx9fk34cltzahq)#nj8nx6rc",
            "hex": "0014da8b839488b686e06a845290b0b2a5818a9b46b8",
            "address": "bcrt1qm29c89ygk6rwq65y22gtpv49sx9fk34cltzahq",
            "type": "witness_v0_keyhash"
          }
        },
        {
          "value": 1.0,
          "n": 1,
          "scriptPubKey": {
            "asm": "0 75b801f675adb64974d64c774f9079e9beda2687",
            "desc": "addr(bcrt1qwkuqran44kmyjaxkf3m5lyreaxld5f58zgjsd9)#76m7ed6x",
            "hex": "001475b801f675adb64974d64c774f9079e9beda2687",
            "address": "bcrt1qwkuqran44kmyjaxkf3m5lyreaxld5f58zgjsd9",
            "type": "witness_v0_keyhash"
          }
        }
      ],
      "fee": 2.82E-05,
      "hex": "02000000000101c4d0ec19ed9a7c25bf7b1f01e092ef9f75d1e3122e2ea46873678beff89988220000000000fdffffff02fc05102401000000160014da8b839488b686e06a845290b0b2a5818a9b46b800e1f5050000000016001475b801f675adb64974d64c774f9079e9beda268702473044022022766071aaba9d5b93977b3fde1a8243a52a0e0840da404427c53995a401d9fd02201fffb974906cdd99e3bc750290968c5a8c0176079cea0a01482585fea06a7b6401210386018cb0053876a9f47ffc8fa11e62063497c407bdd96ccf3c9e730dfb14e81367000000"
    }
  ]
}

@NicolasDorier NicolasDorier left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

NBitcoin/RPC/RPCClient.cs:1552 parses generated from the height field:

var generated = prevOutJson.Value<bool>("height");

Any non-zero height is converted to true, so almost every ordinary transaction output is incorrectly reported as coinbase-generated. The current test masks this because it spends a coinbase output at height 1. Please read the generated field instead and add coverage that spends a non-coinbase output and asserts Generated == false.

@Carti-it

Copy link
Copy Markdown
Contributor Author

NBitcoin/RPC/RPCClient.cs:1552 parses generated from the height field:

var generated = prevOutJson.Value<bool>("height");

Any non-zero height is converted to true, so almost every ordinary transaction output is incorrectly reported as coinbase-generated. The current test masks this because it spends a coinbase output at height 1. Please read the generated field instead and add coverage that spends a non-coinbase output and asserts Generated == false.

Thank you for the review. I fixed it as suggested in e9534c7.

@NicolasDorier
NicolasDorier merged commit db3d9fc into MetacoSA:master Sep 21, 2026
6 checks passed
@Carti-it
Carti-it deleted the RPClient-1 branch September 21, 2026 07:40
@Carti-it

Copy link
Copy Markdown
Contributor Author

@NicolasDorier Would you mind releasing a new version of NBitcoin with this patch? It would allow me to use this work in WalletWasabi/WalletWasabi#14949.

@NicolasDorier

Copy link
Copy Markdown
Collaborator

@Carti-it just pushed 10.0.0.13

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants