Make Orchard `finalState` serialization format match Sapling.

For consistency, we serialize the `finalState` field in the
same (sparse) encoding as Sapling and Sprout use. In the future
we may want to update this to the dense encoding that
incrementalmerkletree::bridgetree::Frontier uses, but that's not
necessary for the moment.
This commit is contained in:
Kris Nuttycombe 2022-04-08 12:48:03 -06:00
parent a4aba7cb91
commit f86a65d7cb
8 changed files with 70 additions and 18 deletions

View File

@ -6,7 +6,7 @@ replace-with = "vendored-sources"
[source."https://github.com/zcash/librustzcash.git"]
git = "https://github.com/zcash/librustzcash.git"
rev = "43c18d000fcbe45363b2d53585d5102841eff99e"
rev = "d5c5f048947d211c2fbef23ce986b329b91d1aa5"
replace-with = "vendored-sources"
[source."https://github.com/nuttycom/hdwallet.git"]

16
Cargo.lock generated
View File

@ -562,7 +562,7 @@ checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d"
[[package]]
name = "equihash"
version = "0.1.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=43c18d000fcbe45363b2d53585d5102841eff99e#43c18d000fcbe45363b2d53585d5102841eff99e"
source = "git+https://github.com/zcash/librustzcash.git?rev=d5c5f048947d211c2fbef23ce986b329b91d1aa5#d5c5f048947d211c2fbef23ce986b329b91d1aa5"
dependencies = [
"blake2b_simd",
"byteorder",
@ -571,7 +571,7 @@ dependencies = [
[[package]]
name = "f4jumble"
version = "0.0.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=43c18d000fcbe45363b2d53585d5102841eff99e#43c18d000fcbe45363b2d53585d5102841eff99e"
source = "git+https://github.com/zcash/librustzcash.git?rev=d5c5f048947d211c2fbef23ce986b329b91d1aa5#d5c5f048947d211c2fbef23ce986b329b91d1aa5"
dependencies = [
"blake2b_simd",
]
@ -2240,7 +2240,7 @@ dependencies = [
[[package]]
name = "zcash_address"
version = "0.0.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=43c18d000fcbe45363b2d53585d5102841eff99e#43c18d000fcbe45363b2d53585d5102841eff99e"
source = "git+https://github.com/zcash/librustzcash.git?rev=d5c5f048947d211c2fbef23ce986b329b91d1aa5#d5c5f048947d211c2fbef23ce986b329b91d1aa5"
dependencies = [
"bech32",
"bs58",
@ -2251,7 +2251,7 @@ dependencies = [
[[package]]
name = "zcash_encoding"
version = "0.0.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=43c18d000fcbe45363b2d53585d5102841eff99e#43c18d000fcbe45363b2d53585d5102841eff99e"
source = "git+https://github.com/zcash/librustzcash.git?rev=d5c5f048947d211c2fbef23ce986b329b91d1aa5#d5c5f048947d211c2fbef23ce986b329b91d1aa5"
dependencies = [
"byteorder",
"nonempty",
@ -2260,7 +2260,7 @@ dependencies = [
[[package]]
name = "zcash_history"
version = "0.2.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=43c18d000fcbe45363b2d53585d5102841eff99e#43c18d000fcbe45363b2d53585d5102841eff99e"
source = "git+https://github.com/zcash/librustzcash.git?rev=d5c5f048947d211c2fbef23ce986b329b91d1aa5#d5c5f048947d211c2fbef23ce986b329b91d1aa5"
dependencies = [
"bigint",
"blake2b_simd",
@ -2270,7 +2270,7 @@ dependencies = [
[[package]]
name = "zcash_note_encryption"
version = "0.1.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=43c18d000fcbe45363b2d53585d5102841eff99e#43c18d000fcbe45363b2d53585d5102841eff99e"
source = "git+https://github.com/zcash/librustzcash.git?rev=d5c5f048947d211c2fbef23ce986b329b91d1aa5#d5c5f048947d211c2fbef23ce986b329b91d1aa5"
dependencies = [
"chacha20",
"chacha20poly1305",
@ -2281,7 +2281,7 @@ dependencies = [
[[package]]
name = "zcash_primitives"
version = "0.5.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=43c18d000fcbe45363b2d53585d5102841eff99e#43c18d000fcbe45363b2d53585d5102841eff99e"
source = "git+https://github.com/zcash/librustzcash.git?rev=d5c5f048947d211c2fbef23ce986b329b91d1aa5#d5c5f048947d211c2fbef23ce986b329b91d1aa5"
dependencies = [
"aes",
"bip0039",
@ -2317,7 +2317,7 @@ dependencies = [
[[package]]
name = "zcash_proofs"
version = "0.5.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=43c18d000fcbe45363b2d53585d5102841eff99e#43c18d000fcbe45363b2d53585d5102841eff99e"
source = "git+https://github.com/zcash/librustzcash.git?rev=d5c5f048947d211c2fbef23ce986b329b91d1aa5#d5c5f048947d211c2fbef23ce986b329b91d1aa5"
dependencies = [
"bellman",
"blake2b_simd",

View File

@ -87,9 +87,9 @@ codegen-units = 1
[patch.crates-io]
hdwallet = { git = "https://github.com/nuttycom/hdwallet", rev = "9b4c1bdbe0517e3a7a8f285d6048a37d472ba3bc" }
zcash_address = { git = "https://github.com/zcash/librustzcash.git", rev = "43c18d000fcbe45363b2d53585d5102841eff99e" }
zcash_encoding = { git = "https://github.com/zcash/librustzcash.git", rev = "43c18d000fcbe45363b2d53585d5102841eff99e" }
zcash_history = { git = "https://github.com/zcash/librustzcash.git", rev = "43c18d000fcbe45363b2d53585d5102841eff99e" }
zcash_note_encryption = { git = "https://github.com/zcash/librustzcash.git", rev = "43c18d000fcbe45363b2d53585d5102841eff99e" }
zcash_primitives = { git = "https://github.com/zcash/librustzcash.git", rev = "43c18d000fcbe45363b2d53585d5102841eff99e" }
zcash_proofs = { git = "https://github.com/zcash/librustzcash.git", rev = "43c18d000fcbe45363b2d53585d5102841eff99e" }
zcash_address = { git = "https://github.com/zcash/librustzcash.git", rev = "d5c5f048947d211c2fbef23ce986b329b91d1aa5" }
zcash_encoding = { git = "https://github.com/zcash/librustzcash.git", rev = "d5c5f048947d211c2fbef23ce986b329b91d1aa5" }
zcash_history = { git = "https://github.com/zcash/librustzcash.git", rev = "d5c5f048947d211c2fbef23ce986b329b91d1aa5" }
zcash_note_encryption = { git = "https://github.com/zcash/librustzcash.git", rev = "d5c5f048947d211c2fbef23ce986b329b91d1aa5" }
zcash_primitives = { git = "https://github.com/zcash/librustzcash.git", rev = "d5c5f048947d211c2fbef23ce986b329b91d1aa5" }
zcash_proofs = { git = "https://github.com/zcash/librustzcash.git", rev = "d5c5f048947d211c2fbef23ce986b329b91d1aa5" }

View File

@ -224,7 +224,7 @@ class FinalSaplingRootTest(BitcoinTestFramework):
assert "skipHash" not in treestate["orchard"]
assert_equal(new_treestate["orchard"]["commitments"]["finalRoot"], ORCHARD_TREE_EMPTY_ROOT)
assert_equal(new_treestate["orchard"]["commitments"]["finalState"], "00")
assert_equal(new_treestate["orchard"]["commitments"]["finalState"], "000000")
pass

View File

@ -1343,7 +1343,7 @@ UniValue z_gettreestate(const UniValue& params, bool fHelp)
OrchardMerkleFrontier tree;
if (pcoinsTip->GetOrchardAnchorAt(pindex->hashFinalOrchardRoot, tree)) {
CDataStream s(SER_NETWORK, PROTOCOL_VERSION);
s << tree;
s << OrchardMerkleFrontierLegacySer(tree);
orchard_commitments.pushKV("finalState", HexStr(s.begin(), s.end()));
} else {
// Set skipHash to the most recent block that has a finalState.

View File

@ -52,6 +52,15 @@ bool orchard_merkle_frontier_serialize(
void* stream,
write_callback_t write_cb);
// Serializes an Orchard Merkle frontier to a stream using the
// zcash_primitives::merkle_tree::CommitmentTree sparse encoding.
//
// Returns `false` if an error occurs while writing to the stream.
bool orchard_merkle_frontier_serialize_legacy(
const OrchardMerkleFrontierPtr* tree_ptr,
void* stream,
write_callback_t write_cb);
// For each action in the provided bundle, append its
// commitment to the frontier.
//

View File

@ -5,7 +5,10 @@ use std::ptr;
use orchard::{bundle::Authorized, tree::MerkleHashOrchard};
use tracing::error;
use zcash_primitives::{
merkle_tree::incremental::{read_frontier_v1, write_frontier_v1},
merkle_tree::{
incremental::{read_frontier_v1, write_frontier_v1},
CommitmentTree,
},
transaction::components::Amount,
};
@ -80,6 +83,29 @@ pub extern "C" fn orchard_merkle_frontier_serialize(
}
}
#[no_mangle]
pub extern "C" fn orchard_merkle_frontier_serialize_legacy(
frontier: *const bridgetree::Frontier<MerkleHashOrchard, MERKLE_DEPTH>,
stream: Option<StreamObj>,
write_cb: Option<WriteCb>,
) -> bool {
let frontier = unsafe {
frontier
.as_ref()
.expect("Orchard note commitment tree pointer may not be null.")
};
let writer = CppStreamWriter::from_raw_parts(stream, write_cb.unwrap());
let commitment_tree = CommitmentTree::from_frontier(frontier);
match commitment_tree.write(writer) {
Ok(()) => true,
Err(e) => {
error!("{}", e);
false
}
}
}
#[no_mangle]
pub extern "C" fn orchard_merkle_frontier_append_bundle(
tree: *mut bridgetree::Frontier<MerkleHashOrchard, MERKLE_DEPTH>,

View File

@ -260,6 +260,7 @@ typedef libzcash::IncrementalWitness<SAPLING_INCREMENTAL_MERKLE_TREE_DEPTH, libz
typedef libzcash::IncrementalWitness<INCREMENTAL_MERKLE_TREE_DEPTH_TESTING, libzcash::PedersenHash> SaplingTestingWitness;
class OrchardWallet;
class OrchardMerkleFrontierLegacySer;
class OrchardMerkleFrontier
{
@ -269,6 +270,7 @@ private:
std::unique_ptr<OrchardMerkleFrontierPtr, decltype(&orchard_merkle_frontier_free)> inner;
friend class OrchardWallet;
friend class OrchardMerkleFrontierLegacySer;
public:
OrchardMerkleFrontier() : inner(orchard_merkle_frontier_empty(), orchard_merkle_frontier_free) {}
@ -332,4 +334,19 @@ public:
}
};
class OrchardMerkleFrontierLegacySer {
private:
const OrchardMerkleFrontier& frontier;
public:
OrchardMerkleFrontierLegacySer(const OrchardMerkleFrontier& frontier): frontier(frontier) {}
template<typename Stream>
void Serialize(Stream& s) const {
RustStream rs(s);
if (!orchard_merkle_frontier_serialize_legacy(frontier.inner.get(), &rs, RustStream<Stream>::write_callback)) {
throw std::ios_base::failure("Failed to serialize Orchard merkle frontier in legacy format.");
}
}
};
#endif /* ZC_INCREMENTALMERKLETREE_H_ */