From c8430665f714db7aff020cc2fc3af61ecadca870 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 15 Feb 2022 11:26:50 -0500 Subject: [PATCH 1/3] WIP RPC that doesn't quite work yet --- src/rpc/blockchain.cpp | 36 +++++++++++++++++++++++++++++ src/rpc/client.cpp | 1 + src/zcash/IncrementalMerkleTree.hpp | 2 +- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 5f3a54d2f..24412762a 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -856,6 +856,41 @@ UniValue gettxoutsetinfo(const UniValue& params, bool fHelp, const CPubKey& mypk return ret; } +UniValue getblockmerkletree(const UniValue& params, bool fHelp, const CPubKey& mypk) +{ + if (fHelp || params.size() != 1 ) + throw runtime_error( + "getblockmerkletree height\n" + "\nGet full merkletree for a given Hush or HSC block height.\n" + "\nArguments:\n" + "1. height (int, required) block height\n" + "\nResult:\n" + "\"hex\" (string) the merkle tree hex encoded\n" + + HelpExampleCli("getblockmerkletree", "290000") + + HelpExampleRpc("getblockmerkletree", "290000") + ); + + CBlockIndex* phushblockindex; + uint256 blockRoot; + SaplingMerkleTree tree; + + int nHeight = params[0].get_int(); + if ( (nHeight < 1) || (nHeight > chainActive.LastTip()->GetHeight()) ) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid Hush or HSC block height parameter"); + } + + phushblockindex = chainActive[nHeight]; + blockRoot = phushblockindex->pprev->hashFinalSaplingRoot; + if( pcoinsTip->GetSaplingAnchorAt(blockRoot, tree) ) { + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << tree.path(); + std::vector merklepath(ss.begin(), ss.end()); + //TODO: this returns the same, wrong data for all heights + return HexStr(merklepath); + } else { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Could not find merkletree"); + } +} UniValue kvsearch(const UniValue& params, bool fHelp, const CPubKey& mypk) { @@ -1877,6 +1912,7 @@ static const CRPCCommand commands[] = { "blockchain", "getblockcount", &getblockcount, true }, { "blockchain", "getblock", &getblock, true }, { "blockchain", "getblockhash", &getblockhash, true }, + { "blockchain", "getblockmerkletree", &getblockmerkletree, true }, { "blockchain", "getblockheader", &getblockheader, true }, { "blockchain", "getchaintips", &getchaintips, true }, { "blockchain", "getchaintxstats", &getchaintxstats, true }, diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 916273043..e427ec3ff 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -63,6 +63,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "getbalance", 1 }, { "getbalance", 2 }, { "getblockhash", 0 }, + { "getblockmerkletree", 0 }, { "move", 2 }, { "move", 3 }, { "sendfrom", 2 }, diff --git a/src/zcash/IncrementalMerkleTree.hpp b/src/zcash/IncrementalMerkleTree.hpp index 03fa51fda..e0a05f6c6 100644 --- a/src/zcash/IncrementalMerkleTree.hpp +++ b/src/zcash/IncrementalMerkleTree.hpp @@ -108,6 +108,7 @@ public: IncrementalWitness witness() const { return IncrementalWitness(*this); } + MerklePath path(std::deque filler_hashes = std::deque()) const; ADD_SERIALIZE_METHODS; @@ -135,7 +136,6 @@ private: // Collapsed "left" subtrees ordered toward the root of the tree. std::vector> parents; - MerklePath path(std::deque filler_hashes = std::deque()) const; Hash root(size_t depth, std::deque filler_hashes = std::deque()) const; bool is_complete(size_t depth = Depth) const; size_t next_depth(size_t skip) const; From ce5c8a54e458def4b698b95f810e088e1e508d7d Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 16 Feb 2022 09:10:11 -0500 Subject: [PATCH 2/3] Make it work correctly --- src/rpc/blockchain.cpp | 8 +++----- src/zcash/IncrementalMerkleTree.hpp | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 24412762a..90b8e7201 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -880,13 +880,11 @@ UniValue getblockmerkletree(const UniValue& params, bool fHelp, const CPubKey& m } phushblockindex = chainActive[nHeight]; - blockRoot = phushblockindex->pprev->hashFinalSaplingRoot; + blockRoot = phushblockindex->hashFinalSaplingRoot; if( pcoinsTip->GetSaplingAnchorAt(blockRoot, tree) ) { CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << tree.path(); - std::vector merklepath(ss.begin(), ss.end()); - //TODO: this returns the same, wrong data for all heights - return HexStr(merklepath); + ss << tree; + return HexStr(ss.begin(), ss.end()); } else { throw JSONRPCError(RPC_INVALID_PARAMETER, "Could not find merkletree"); } diff --git a/src/zcash/IncrementalMerkleTree.hpp b/src/zcash/IncrementalMerkleTree.hpp index e0a05f6c6..03fa51fda 100644 --- a/src/zcash/IncrementalMerkleTree.hpp +++ b/src/zcash/IncrementalMerkleTree.hpp @@ -108,7 +108,6 @@ public: IncrementalWitness witness() const { return IncrementalWitness(*this); } - MerklePath path(std::deque filler_hashes = std::deque()) const; ADD_SERIALIZE_METHODS; @@ -136,6 +135,7 @@ private: // Collapsed "left" subtrees ordered toward the root of the tree. std::vector> parents; + MerklePath path(std::deque filler_hashes = std::deque()) const; Hash root(size_t depth, std::deque filler_hashes = std::deque()) const; bool is_complete(size_t depth = Depth) const; size_t next_depth(size_t skip) const; From c3623047f7eba7b6bd63ea4a21f4f74ea27d71f5 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 16 Feb 2022 10:57:52 -0500 Subject: [PATCH 3/3] Script to generate SDL checkpoint data via getblockmerkletree --- contrib/sdl_checkpoints.pl | 44 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100755 contrib/sdl_checkpoints.pl diff --git a/contrib/sdl_checkpoints.pl b/contrib/sdl_checkpoints.pl new file mode 100755 index 000000000..e140fb0ec --- /dev/null +++ b/contrib/sdl_checkpoints.pl @@ -0,0 +1,44 @@ +#!/usr/bin/perl +# Copyright (c) 2016-2022 The Hush developers +# Distributed under the GPLv3 software license, see the accompanying +# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html + +# This script is used to generate the data used by the silentdragonlite-cli checkpoints.rs file +# https://git.hush.is/hush/silentdragonlite-cli/src/branch/master/lib/src/lightclient/checkpoints.rs#L24 + +use warnings; +use strict; +my $hush = "./src/hush-cli"; +my $gethash = "$hush getblockhash"; +my $gettree = "$hush getblockmerkletree"; +my $start = shift || 300000; +my $end = shift || 840000; +my $stride = shift || 10000; + +my $blocks = qx{$hush getblockcount}; +if($?) { + print "ERROR, is hushd running? exiting...\n"; + exit 1; +} + +if ($end > $blocks) { + print "The block $end is beyond how many blocks this node knows about, exiting...\n"; + exit 1; +} + +if ($start < 1) { + print "Invalid start block $start, exiting...\n"; + exit 1; +} + +my $block = $start; +while (1) { + last if $block > $end; + my $blockhash = qx{$gethash $block}; + my $merkle = qx{$gettree $block}; + chomp $merkle; + chomp $blockhash; + print qq{($block,"$blockhash",\n\t"$merkle"\n),\n}; + + $block += $stride; +}