Auto merge of #3170 - ebfull:sapling-merkle-tree, r=ebfull

Sapling merkle tree implementation

Closes #3056.

Please also review https://github.com/zcash/librustzcash/pull/8

This PR:

1. Introduces ZCSaplingIncrementalMerkleTree using Pedersen hashes.
2. Adds support for Sapling anchors into consensus rules. (Adds commitments, checks anchors are correct, handles block (dis)connects, etc.)
3. Handles mempool eviction for obsolete anchors.
4. Enforces correctness of block's Sapling root field
5. Changes miner to correctly apply the Sapling root to the block header
6. Handles mempool consistency checks for anchors
This commit is contained in:
Homu
2018-05-07 20:37:46 -07:00
37 changed files with 1166 additions and 309 deletions

View File

@@ -429,7 +429,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
auto it = intermediates.find(prevJoinSplit.anchor);
if (it != intermediates.end()) {
tree = it->second;
} else if (!pcoinsTip->GetAnchorAt(prevJoinSplit.anchor, tree)) {
} else if (!pcoinsTip->GetSproutAnchorAt(prevJoinSplit.anchor, tree)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Could not find previous JoinSplit anchor");
}
@@ -693,7 +693,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(MergeToAddressJSInf
uint256 anchor;
{
LOCK(cs_main);
anchor = pcoinsTip->GetBestAnchor(); // As there are no inputs, ask the wallet for the best anchor
anchor = pcoinsTip->GetBestAnchor(SPROUT); // As there are no inputs, ask the wallet for the best anchor
}
return perform_joinsplit(info, witnesses, anchor);
}

View File

@@ -545,7 +545,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
auto it = intermediates.find(prevJoinSplit.anchor);
if (it != intermediates.end()) {
tree = it->second;
} else if (!pcoinsTip->GetAnchorAt(prevJoinSplit.anchor, tree)) {
} else if (!pcoinsTip->GetSproutAnchorAt(prevJoinSplit.anchor, tree)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Could not find previous JoinSplit anchor");
}
@@ -914,7 +914,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info
uint256 anchor;
{
LOCK(cs_main);
anchor = pcoinsTip->GetBestAnchor(); // As there are no inputs, ask the wallet for the best anchor
anchor = pcoinsTip->GetBestAnchor(SPROUT); // As there are no inputs, ask the wallet for the best anchor
}
return perform_joinsplit(info, witnesses, anchor);
}

View File

@@ -314,7 +314,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf
{
LOCK(cs_main);
consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
anchor = pcoinsTip->GetBestAnchor();
anchor = pcoinsTip->GetBestAnchor(SPROUT);
}

View File

@@ -1765,7 +1765,7 @@ void CWallet::WitnessNoteCommitment(std::vector<uint256> commitments,
// Consistency check: we should be able to find the current tree
// in our CCoins view.
ZCIncrementalMerkleTree dummy_tree;
assert(pcoinsTip->GetAnchorAt(current_anchor, dummy_tree));
assert(pcoinsTip->GetSproutAnchorAt(current_anchor, dummy_tree));
pindex = chainActive.Next(pindex);
}
@@ -1819,7 +1819,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
ZCIncrementalMerkleTree tree;
// This should never fail: we should always be able to get the tree
// state on the path to the tip of our chain
assert(pcoinsTip->GetAnchorAt(pindex->hashAnchor, tree));
assert(pcoinsTip->GetSproutAnchorAt(pindex->hashSproutAnchor, tree));
// Increment note witness caches
IncrementNoteWitnesses(pindex, &block, tree);