Fix finalorchardroot serialization

Previously, `finalorchardroot` and `orchard.anchor` were serialized differently
in the RPC API, which made it difficult to correlate them. This changes the
serialization for `finalorchardroot` to match `orchard.anchor`.
This commit is contained in:
Greg Pfeil 2022-09-09 11:48:37 -06:00
parent 4f4ef5537b
commit bdde47fb5d
5 changed files with 27 additions and 8 deletions

View File

@ -19,3 +19,13 @@ has a memory limit of 100 MiB.
- (counter) `zcashd.wallet.batchscanner.outputs.scanned`
- (gauge) `zcashd.wallet.batchscanner.size.transactions`
- (gauge) `zcashd.wallet.batchscanner.usage.bytes`
RPC Interface
-------------
- The `finalorchardroot` field in the `getblock` result and the
`orchard.commitments.finalRoot` field in the `z_gettreestate` result have
been changed to match the byte ordering used for the `orchard.anchor`
field in the `getrawtransaction` result. These previously produced different
hash values from the `orchard.anchor` field due to having been byte-flipped
in their internal representation in zcashd.

View File

@ -57,7 +57,7 @@ class Zip221Test(BitcoinTestFramework):
if height >= 35:
orchard_root = hex_str_to_bytes(
self.nodes[0].getblock(str(height))["finalorchardroot"])[::-1]
self.nodes[0].getblock(str(height))["finalorchardroot"])
v2_data = (orchard_root, 0)
else:
v2_data = None

View File

@ -19,7 +19,7 @@ from decimal import Decimal
SPROUT_TREE_EMPTY_ROOT = "59d2cde5e65c1414c32ba54f0fe4bdb3d67618125286e6a191317917c812c6d7"
SAPLING_TREE_EMPTY_ROOT = "3e49b5f954aa9d3545bc6c37744661eea48d7c34e3000d82b7f0010c30f4c2fb"
ORCHARD_TREE_EMPTY_ROOT = "2fd8e51a03d9bbe2dd809831b1497aeb68a6e37ddf707ced4aa2d8dff13529ae"
ORCHARD_TREE_EMPTY_ROOT = "ae2935f1dfd8a24aed7c70df7de3a668eb7a49b1319880dde2bbd9031ae5d82f"
NULL_FIELD = "0000000000000000000000000000000000000000000000000000000000000000"
# Verify block header field 'hashFinalOrchardRoot' (returned in rpc as 'finalorchardroot')

View File

@ -19,7 +19,7 @@ from decimal import Decimal
SPROUT_TREE_EMPTY_ROOT = "59d2cde5e65c1414c32ba54f0fe4bdb3d67618125286e6a191317917c812c6d7"
SAPLING_TREE_EMPTY_ROOT = "3e49b5f954aa9d3545bc6c37744661eea48d7c34e3000d82b7f0010c30f4c2fb"
ORCHARD_TREE_EMPTY_ROOT = "2fd8e51a03d9bbe2dd809831b1497aeb68a6e37ddf707ced4aa2d8dff13529ae"
ORCHARD_TREE_EMPTY_ROOT = "ae2935f1dfd8a24aed7c70df7de3a668eb7a49b1319880dde2bbd9031ae5d82f"
NULL_FIELD = "0000000000000000000000000000000000000000000000000000000000000000"
# Verify block header field 'hashFinalSaplingRoot' (returned in rpc as 'finalsaplingroot')

View File

@ -241,7 +241,8 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx
result.pushKV("authdataroot", blockindex->hashAuthDataRoot.GetHex());
result.pushKV("finalsaplingroot", blockindex->hashFinalSaplingRoot.GetHex());
if (nu5Active) {
result.pushKV("finalorchardroot", blockindex->hashFinalOrchardRoot.GetHex());
auto finalOrchardRootBytes = blockindex->hashFinalOrchardRoot;
result.pushKV("finalorchardroot", HexStr(finalOrchardRootBytes.begin(), finalOrchardRootBytes.end()));
}
result.pushKV("chainhistoryroot", blockindex->hashChainHistoryRoot.GetHex());
UniValue txs(UniValue::VARR);
@ -716,9 +717,13 @@ UniValue getblock(const UniValue& params, bool fHelp)
" \"version\" : n, (numeric) The block version\n"
" \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
" \"finalsaplingroot\" : \"xxxx\", (string) The root of the Sapling commitment tree after applying this block\n"
" \"finalorchardroot\" : \"xxxx\", (string) The root of the Orchard commitment tree after applying this block.\n"
" Omitted for blocks prior to NU5 activation. This will be the null\n"
" hash if this block has never been connected to a main chain.\n"
" \"finalorchardroot\" : \"xxxx\", (string, optional) The root of the Orchard commitment tree after\n"
" applying this block. Omitted for blocks prior to NU5 activation. This\n"
" will be the null hash if this block has never been connected to a\n"
" main chain.\n"
" NB: The serialized representation of this field returned by this method\n"
" was byte-flipped relative to its representation in the `getrawtransaction`\n"
" output in prior releases up to v5.2.0. This has now been rectified.\n"
" \"tx\" : [ (array of string) The transaction ids\n"
" \"transactionid\" (string) The transaction id\n"
" ,...\n"
@ -1247,6 +1252,9 @@ UniValue z_gettreestate(const UniValue& params, bool fHelp)
" \"skipHash\": \"hash\", (string) hash of most recent block with more information\n"
" \"commitments\": {\n"
" \"finalRoot\": \"hex\", (string)\n"
" NB: The serialized representation of this field returned by this method\n"
" was byte-flipped relative to its representation in the `getrawtransaction`\n"
" output in prior releases up to v5.2.0. This has now been rectified.\n"
" \"finalState\": \"hex\" (string)\n"
" }\n"
" },\n"
@ -1345,7 +1353,8 @@ UniValue z_gettreestate(const UniValue& params, bool fHelp)
if (nu5_activation_height.has_value()) {
UniValue orchard_result(UniValue::VOBJ);
UniValue orchard_commitments(UniValue::VOBJ);
orchard_commitments.pushKV("finalRoot", pindex->hashFinalOrchardRoot.GetHex());
auto finalOrchardRootBytes = pindex->hashFinalOrchardRoot;
orchard_commitments.pushKV("finalRoot", HexStr(finalOrchardRootBytes.begin(), finalOrchardRootBytes.end()));
bool need_skiphash = false;
OrchardMerkleFrontier tree;
if (pcoinsTip->GetOrchardAnchorAt(pindex->hashFinalOrchardRoot, tree)) {