Merge remote-tracking branch 'upstream/master' into feature/wallet_orchard
This commit is contained in:
commit
9202b127d0
|
@ -36,7 +36,7 @@ Please provide a general summary of the issue you're experiencing
|
||||||
Tell us what should happen
|
Tell us what should happen
|
||||||
|
|
||||||
### Actual behaviour + errors
|
### Actual behaviour + errors
|
||||||
Tell us what happens instead including any noticable error output (any messages
|
Tell us what happens instead including any noticeable error output (any messages
|
||||||
displayed on-screen when e.g. a crash occurred)
|
displayed on-screen when e.g. a crash occurred)
|
||||||
|
|
||||||
### The version of Zcash you were using:
|
### The version of Zcash you were using:
|
||||||
|
|
|
@ -5,7 +5,7 @@ where possible.
|
||||||
|
|
||||||
## Adding new dependencies in online-Rust mode
|
## Adding new dependencies in online-Rust mode
|
||||||
|
|
||||||
The `zcashd` build system pins all dependencies, and in order to faciliate
|
The `zcashd` build system pins all dependencies, and in order to facilitate
|
||||||
deterministic builds, `cargo` is configured to run in offline mode with vendored
|
deterministic builds, `cargo` is configured to run in offline mode with vendored
|
||||||
crates. This means that if, for example, you add the `foobar` crate to
|
crates. This means that if, for example, you add the `foobar` crate to
|
||||||
`Cargo.toml`, you will likely see an error similar to this:
|
`Cargo.toml`, you will likely see an error similar to this:
|
||||||
|
|
|
@ -32,7 +32,7 @@ Check that dependencies are up-to-date or have been postponed:
|
||||||
$ ./qa/zcash/updatecheck.py
|
$ ./qa/zcash/updatecheck.py
|
||||||
```
|
```
|
||||||
|
|
||||||
If you are missing the `.updatecheck-token` file requried to run this script,
|
If you are missing the `.updatecheck-token` file required to run this script,
|
||||||
please ask Taylor or another Zcash developer for a copy, or create an
|
please ask Taylor or another Zcash developer for a copy, or create an
|
||||||
unprivileged personal access token for a github account and save it to the
|
unprivileged personal access token for a github account and save it to the
|
||||||
file in the format `username:hex-token`.
|
file in the format `username:hex-token`.
|
||||||
|
|
|
@ -43,7 +43,7 @@ class FinalSaplingRootTest(BitcoinTestFramework):
|
||||||
self.nodes[0].generate(200)
|
self.nodes[0].generate(200)
|
||||||
self.sync_all()
|
self.sync_all()
|
||||||
|
|
||||||
# Verfify genesis block contains null field for what is now called the final sapling root field.
|
# Verify genesis block contains null field for what is now called the final sapling root field.
|
||||||
blk = self.nodes[0].getblock("0")
|
blk = self.nodes[0].getblock("0")
|
||||||
assert_equal(blk["finalsaplingroot"], NULL_FIELD)
|
assert_equal(blk["finalsaplingroot"], NULL_FIELD)
|
||||||
treestate = self.nodes[0].z_gettreestate("0")
|
treestate = self.nodes[0].z_gettreestate("0")
|
||||||
|
|
|
@ -73,7 +73,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||||
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
|
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
|
||||||
fee = rawtxfund['fee']
|
fee = rawtxfund['fee']
|
||||||
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
|
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
|
||||||
assert_equal(len(dec_tx['vin']) > 0, True) #test if we have enought inputs
|
assert_equal(len(dec_tx['vin']) > 0, True) #test if we have enough inputs
|
||||||
|
|
||||||
##############################
|
##############################
|
||||||
# simple test with two coins #
|
# simple test with two coins #
|
||||||
|
|
|
@ -75,7 +75,7 @@ class MerkleBlockTest(BitcoinTestFramework):
|
||||||
txid_spent = txin_spent["txid"]
|
txid_spent = txin_spent["txid"]
|
||||||
txid_unspent = txid1 if txin_spent["txid"] != txid1 else txid2
|
txid_unspent = txid1 if txin_spent["txid"] != txid1 else txid2
|
||||||
|
|
||||||
# We cant find the block from a fully-spent tx
|
# We can't find the block from a fully-spent tx
|
||||||
assert_raises(JSONRPCException, self.nodes[2].gettxoutproof, [txid_spent])
|
assert_raises(JSONRPCException, self.nodes[2].gettxoutproof, [txid_spent])
|
||||||
# ...but we can if we specify the block
|
# ...but we can if we specify the block
|
||||||
assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid_spent], blockhash)), [txid_spent])
|
assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid_spent], blockhash)), [txid_spent])
|
||||||
|
|
|
@ -27,7 +27,7 @@ class NodeHandlingTest (BitcoinTestFramework):
|
||||||
###########################
|
###########################
|
||||||
assert_equal(len(self.nodes[2].getpeerinfo()), 4) #we should have 4 nodes at this point
|
assert_equal(len(self.nodes[2].getpeerinfo()), 4) #we should have 4 nodes at this point
|
||||||
self.nodes[2].setban("127.0.0.1", "add")
|
self.nodes[2].setban("127.0.0.1", "add")
|
||||||
time.sleep(3) #wait till the nodes are disconected
|
time.sleep(3) #wait till the nodes are disconnected
|
||||||
assert_equal(len(self.nodes[2].getpeerinfo()), 0) #all nodes must be disconnected at this point
|
assert_equal(len(self.nodes[2].getpeerinfo()), 0) #all nodes must be disconnected at this point
|
||||||
assert_equal(len(self.nodes[2].listbanned()), 1)
|
assert_equal(len(self.nodes[2].listbanned()), 1)
|
||||||
self.nodes[2].clearbanned()
|
self.nodes[2].clearbanned()
|
||||||
|
|
|
@ -159,7 +159,7 @@ class FullBlockTest(ComparisonTestFramework):
|
||||||
yield test
|
yield test
|
||||||
|
|
||||||
|
|
||||||
# Start by bulding a couple of blocks on top (which output is spent is in parentheses):
|
# Start by building a couple of blocks on top (which output is spent is in parentheses):
|
||||||
# genesis -> b1 (0) -> b2 (1)
|
# genesis -> b1 (0) -> b2 (1)
|
||||||
out0 = get_spendable_output()
|
out0 = get_spendable_output()
|
||||||
block(1, spend=out0)
|
block(1, spend=out0)
|
||||||
|
|
|
@ -152,7 +152,7 @@ class PruneTest(BitcoinTestFramework):
|
||||||
print("Invalidating block at height:",invalidheight,badhash)
|
print("Invalidating block at height:",invalidheight,badhash)
|
||||||
self.nodes[1].invalidateblock(badhash)
|
self.nodes[1].invalidateblock(badhash)
|
||||||
|
|
||||||
# We've now switched to our previously mined-24 block fork on node 1, but thats not what we want
|
# We've now switched to our previously mined-24 block fork on node 1, but that's not what we want
|
||||||
# So invalidate that fork as well, until we're on the same chain as node 0/2 (but at an ancestor 288 blocks ago)
|
# So invalidate that fork as well, until we're on the same chain as node 0/2 (but at an ancestor 288 blocks ago)
|
||||||
mainchainhash = self.nodes[0].getblockhash(invalidheight - 1)
|
mainchainhash = self.nodes[0].getblockhash(invalidheight - 1)
|
||||||
curhash = self.nodes[1].getblockhash(invalidheight - 1)
|
curhash = self.nodes[1].getblockhash(invalidheight - 1)
|
||||||
|
@ -210,7 +210,7 @@ class PruneTest(BitcoinTestFramework):
|
||||||
goalbesthash = self.mainchainhash2
|
goalbesthash = self.mainchainhash2
|
||||||
|
|
||||||
# As of 0.10 the current block download logic is not able to reorg to the original chain created in
|
# As of 0.10 the current block download logic is not able to reorg to the original chain created in
|
||||||
# create_chain_with_stale_blocks because it doesn't know of any peer thats on that chain from which to
|
# create_chain_with_stale_blocks because it doesn't know of any peer that's on that chain from which to
|
||||||
# redownload its missing blocks.
|
# redownload its missing blocks.
|
||||||
# Invalidate the reorg_test chain in node 0 as well, it can successfully switch to the original chain
|
# Invalidate the reorg_test chain in node 0 as well, it can successfully switch to the original chain
|
||||||
# because it has all the block data.
|
# because it has all the block data.
|
||||||
|
|
|
@ -29,7 +29,7 @@ def satoshi_round(amount):
|
||||||
def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee_increment):
|
def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee_increment):
|
||||||
'''
|
'''
|
||||||
Create and send a transaction with a random fee.
|
Create and send a transaction with a random fee.
|
||||||
The transaction pays to a trival P2SH script, and assumes that its inputs
|
The transaction pays to a trivial P2SH script, and assumes that its inputs
|
||||||
are of the same form.
|
are of the same form.
|
||||||
The function takes a list of confirmed outputs and unconfirmed outputs
|
The function takes a list of confirmed outputs and unconfirmed outputs
|
||||||
and attempts to use the confirmed list first for its inputs.
|
and attempts to use the confirmed list first for its inputs.
|
||||||
|
|
|
@ -44,7 +44,7 @@ class UpgradeGoldenTest(BitcoinTestFramework):
|
||||||
logging.info("Initializing the network in "+self.options.tmpdir)
|
logging.info("Initializing the network in "+self.options.tmpdir)
|
||||||
|
|
||||||
# Node 0 will always be running with the most recent network upgrade version.
|
# Node 0 will always be running with the most recent network upgrade version.
|
||||||
# The remaining nodes start with the nework upgrade versions in order that they
|
# The remaining nodes start with the network upgrade versions in order that they
|
||||||
# are specified in the upgrades list.
|
# are specified in the upgrades list.
|
||||||
upgrade_args = [self.upgrades[-1].extra_args] + [u.extra_args for u in self.upgrades]
|
upgrade_args = [self.upgrades[-1].extra_args] + [u.extra_args for u in self.upgrades]
|
||||||
self.nodes = start_nodes(len(self.upgrades) + 1, self.options.tmpdir, extra_args=upgrade_args)
|
self.nodes = start_nodes(len(self.upgrades) + 1, self.options.tmpdir, extra_args=upgrade_args)
|
||||||
|
|
|
@ -70,7 +70,7 @@ class WalletImportExportTest (BitcoinTestFramework):
|
||||||
assert_true(sapling_address0 in sapling_keys1)
|
assert_true(sapling_address0 in sapling_keys1)
|
||||||
assert_true(sapling_address2 in sapling_keys1)
|
assert_true(sapling_address2 in sapling_keys1)
|
||||||
|
|
||||||
# make sure we have perserved the metadata
|
# make sure we have preserved the metadata
|
||||||
for sapling_key0 in sapling_keys0.splitlines():
|
for sapling_key0 in sapling_keys0.splitlines():
|
||||||
assert_true(sapling_key0 in sapling_keys1)
|
assert_true(sapling_key0 in sapling_keys1)
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ class WalletPersistenceTest (BitcoinTestFramework):
|
||||||
# Verify Sapling address is persisted in wallet
|
# Verify Sapling address is persisted in wallet
|
||||||
sapling_addr = self.nodes[0].z_getnewaddress('sapling')
|
sapling_addr = self.nodes[0].z_getnewaddress('sapling')
|
||||||
|
|
||||||
# Make sure the node has the addresss
|
# Make sure the node has the address
|
||||||
addresses = self.nodes[0].z_listaddresses()
|
addresses = self.nodes[0].z_listaddresses()
|
||||||
assert_true(sapling_addr in addresses, "Should contain address before restart")
|
assert_true(sapling_addr in addresses, "Should contain address before restart")
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ class ZapWalletTXesTest (BitcoinTestFramework):
|
||||||
print(e)
|
print(e)
|
||||||
aException = True
|
aException = True
|
||||||
|
|
||||||
assert_equal(aException, True) # there must be a expection because the unconfirmed wallettx0 must be gone by now
|
assert_equal(aException, True) # there must be an exception because the unconfirmed wallet tx0 must be gone by now
|
||||||
|
|
||||||
tx0 = self.nodes[0].gettransaction(txid0)
|
tx0 = self.nodes[0].gettransaction(txid0)
|
||||||
assert_equal(tx0['txid'], txid0) # tx0 (confirmed) must still be available because it was confirmed
|
assert_equal(tx0['txid'], txid0) # tx0 (confirmed) must still be available because it was confirmed
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
# Name : checksec.sh
|
# Name : checksec.sh
|
||||||
# Version : 1.7.0
|
# Version : 1.7.0
|
||||||
# Author : Brian Davis
|
# Author : Brian Davis
|
||||||
# Date : Feburary 2014
|
# Date : February 2014
|
||||||
# Download: https://github.com/slimm609/checksec.sh
|
# Download: https://github.com/slimm609/checksec.sh
|
||||||
#
|
#
|
||||||
# --- Modified Version ---
|
# --- Modified Version ---
|
||||||
|
@ -298,9 +298,9 @@ echo_message() {
|
||||||
# check selinux status
|
# check selinux status
|
||||||
getsestatus() {
|
getsestatus() {
|
||||||
local status
|
local status
|
||||||
${debug} && echo -e "\n***fuction getsestatus"
|
${debug} && echo -e "\n***function getsestatus"
|
||||||
if (command_exists getenforce); then
|
if (command_exists getenforce); then
|
||||||
${debug} && echo "***fuction getsestatus->getenforce"
|
${debug} && echo "***function getsestatus->getenforce"
|
||||||
sestatus=$(getenforce)
|
sestatus=$(getenforce)
|
||||||
if [[ "${sestatus}" == "Disabled" ]]; then
|
if [[ "${sestatus}" == "Disabled" ]]; then
|
||||||
status=0
|
status=0
|
||||||
|
@ -310,7 +310,7 @@ getsestatus() {
|
||||||
status=2
|
status=2
|
||||||
fi
|
fi
|
||||||
elif (command_exists sestatus); then
|
elif (command_exists sestatus); then
|
||||||
${debug} && echo "***fuction getsestatus->sestatus"
|
${debug} && echo "***function getsestatus->sestatus"
|
||||||
sestatus=$(sestatus | grep "SELinux status" | awk '{ print $3}')
|
sestatus=$(sestatus | grep "SELinux status" | awk '{ print $3}')
|
||||||
if [[ "${sestatus}" == "disabled" ]]; then
|
if [[ "${sestatus}" == "disabled" ]]; then
|
||||||
status=0
|
status=0
|
||||||
|
@ -328,7 +328,7 @@ return ${status}
|
||||||
|
|
||||||
# check if directory exists
|
# check if directory exists
|
||||||
dir_exists () {
|
dir_exists () {
|
||||||
${debug} && echo "fuction dir_exists"
|
${debug} && echo "function dir_exists"
|
||||||
if [[ -d "${1}" ]] ; then
|
if [[ -d "${1}" ]] ; then
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
|
@ -842,7 +842,7 @@ kernelcheck() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo_message " Kernel heap randomization: " "" "" ""
|
echo_message " Kernel heap randomization: " "" "" ""
|
||||||
# NOTE: y means it turns off kernel heap randomization for backwards compatability (libc5)
|
# NOTE: y means it turns off kernel heap randomization for backwards compatibility (libc5)
|
||||||
if ${kconfig} | grep -qi 'CONFIG_COMPAT_BRK=y'; then
|
if ${kconfig} | grep -qi 'CONFIG_COMPAT_BRK=y'; then
|
||||||
echo_message "\033[31mDisabled\033[m\n" "Disabled," " kernel_heap_randomization='no'" ', "kernel_heap_randomization":"no"'
|
echo_message "\033[31mDisabled\033[m\n" "Disabled," " kernel_heap_randomization='no'" ', "kernel_heap_randomization":"no"'
|
||||||
else
|
else
|
||||||
|
@ -1123,7 +1123,7 @@ kernelcheck() {
|
||||||
sestatus=$?
|
sestatus=$?
|
||||||
if [[ ${sestatus} == 0 ]]; then
|
if [[ ${sestatus} == 0 ]]; then
|
||||||
echo_message "\033[31mDisabled\033[m\n" "Disabled,," " <selinux enabled='no'" '"selinux":{ "enabled":"no"'
|
echo_message "\033[31mDisabled\033[m\n" "Disabled,," " <selinux enabled='no'" '"selinux":{ "enabled":"no"'
|
||||||
echo_message "\n SELinux infomation available here: \n" "" "" ""
|
echo_message "\n SELinux information available here: \n" "" "" ""
|
||||||
echo_message " https://selinuxproject.org/\n" "" "" ""
|
echo_message " https://selinuxproject.org/\n" "" "" ""
|
||||||
elif [[ ${sestatus} == 1 ]]; then
|
elif [[ ${sestatus} == 1 ]]; then
|
||||||
echo_message "\033[33mPermissive\033[m\n" "Permissive," " <selinux enabled='yes' mode='permissive'" '"selinux":{ "enabled":"yes", "mode":"permissive"'
|
echo_message "\033[33mPermissive\033[m\n" "Permissive," " <selinux enabled='yes' mode='permissive'" '"selinux":{ "enabled":"yes", "mode":"permissive"'
|
||||||
|
@ -1132,7 +1132,7 @@ kernelcheck() {
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo_message "\033[31mNo SELinux\033[m\n" "Disabled,," " <selinux enabled='no'" '"selinux":{ "enabled":"no"'
|
echo_message "\033[31mNo SELinux\033[m\n" "Disabled,," " <selinux enabled='no'" '"selinux":{ "enabled":"no"'
|
||||||
echo_message "\n SELinux infomation available here: \n" "" "" ""
|
echo_message "\n SELinux information available here: \n" "" "" ""
|
||||||
echo_message " https://selinuxproject.org/\n" "" "" ""
|
echo_message " https://selinuxproject.org/\n" "" "" ""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -393,6 +393,7 @@ libbitcoin_common_a_SOURCES = \
|
||||||
netbase.cpp \
|
netbase.cpp \
|
||||||
primitives/block.cpp \
|
primitives/block.cpp \
|
||||||
primitives/transaction.cpp \
|
primitives/transaction.cpp \
|
||||||
|
primitives/tx_version_info.cpp \
|
||||||
proof_verifier.cpp \
|
proof_verifier.cpp \
|
||||||
protocol.cpp \
|
protocol.cpp \
|
||||||
pubkey.cpp \
|
pubkey.cpp \
|
||||||
|
@ -558,6 +559,7 @@ libzcash_script_la_SOURCES = \
|
||||||
crypto/sha512.cpp \
|
crypto/sha512.cpp \
|
||||||
hash.cpp \
|
hash.cpp \
|
||||||
primitives/transaction.cpp \
|
primitives/transaction.cpp \
|
||||||
|
primitives/tx_version_info.cpp \
|
||||||
pubkey.cpp \
|
pubkey.cpp \
|
||||||
script/zcash_script.cpp \
|
script/zcash_script.cpp \
|
||||||
script/interpreter.cpp \
|
script/interpreter.cpp \
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
|
|
||||||
/* These architectures support quering the cycle counter
|
/* These architectures support querying the cycle counter
|
||||||
* from user space, no need for any syscall overhead.
|
* from user space, no need for any syscall overhead.
|
||||||
*/
|
*/
|
||||||
void perf_init(void) { }
|
void perf_init(void) { }
|
||||||
|
|
|
@ -46,7 +46,7 @@ bool CCoins::Spend(uint32_t nPos)
|
||||||
}
|
}
|
||||||
bool CCoinsView::GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const { return false; }
|
bool CCoinsView::GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const { return false; }
|
||||||
bool CCoinsView::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const { return false; }
|
bool CCoinsView::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const { return false; }
|
||||||
bool CCoinsView::GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleTree &tree) const { return false; }
|
bool CCoinsView::GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const { return false; }
|
||||||
bool CCoinsView::GetNullifier(const uint256 &nullifier, ShieldedType type) const { return false; }
|
bool CCoinsView::GetNullifier(const uint256 &nullifier, ShieldedType type) const { return false; }
|
||||||
bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; }
|
bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; }
|
||||||
bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; }
|
bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; }
|
||||||
|
@ -75,7 +75,7 @@ CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { }
|
||||||
|
|
||||||
bool CCoinsViewBacked::GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const { return base->GetSproutAnchorAt(rt, tree); }
|
bool CCoinsViewBacked::GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const { return base->GetSproutAnchorAt(rt, tree); }
|
||||||
bool CCoinsViewBacked::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const { return base->GetSaplingAnchorAt(rt, tree); }
|
bool CCoinsViewBacked::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const { return base->GetSaplingAnchorAt(rt, tree); }
|
||||||
bool CCoinsViewBacked::GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleTree &tree) const { return base->GetOrchardAnchorAt(rt, tree); }
|
bool CCoinsViewBacked::GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const { return base->GetOrchardAnchorAt(rt, tree); }
|
||||||
bool CCoinsViewBacked::GetNullifier(const uint256 &nullifier, ShieldedType type) const { return base->GetNullifier(nullifier, type); }
|
bool CCoinsViewBacked::GetNullifier(const uint256 &nullifier, ShieldedType type) const { return base->GetNullifier(nullifier, type); }
|
||||||
bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) const { return base->GetCoins(txid, coins); }
|
bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) const { return base->GetCoins(txid, coins); }
|
||||||
bool CCoinsViewBacked::HaveCoins(const uint256 &txid) const { return base->HaveCoins(txid); }
|
bool CCoinsViewBacked::HaveCoins(const uint256 &txid) const { return base->HaveCoins(txid); }
|
||||||
|
@ -191,7 +191,7 @@ bool CCoinsViewCache::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &t
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCoinsViewCache::GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleTree &tree) const {
|
bool CCoinsViewCache::GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const {
|
||||||
CAnchorsOrchardMap::const_iterator it = cacheOrchardAnchors.find(rt);
|
CAnchorsOrchardMap::const_iterator it = cacheOrchardAnchors.find(rt);
|
||||||
if (it != cacheOrchardAnchors.end()) {
|
if (it != cacheOrchardAnchors.end()) {
|
||||||
if (it->second.entered) {
|
if (it->second.entered) {
|
||||||
|
@ -321,9 +321,9 @@ template<> void CCoinsViewCache::PushAnchor(const SaplingMerkleTree &tree)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> void CCoinsViewCache::PushAnchor(const OrchardMerkleTree &tree)
|
template<> void CCoinsViewCache::PushAnchor(const OrchardMerkleFrontier &tree)
|
||||||
{
|
{
|
||||||
AbstractPushAnchor<OrchardMerkleTree, CAnchorsOrchardMap, CAnchorsOrchardMap::iterator, CAnchorsOrchardCacheEntry>(
|
AbstractPushAnchor<OrchardMerkleFrontier, CAnchorsOrchardMap, CAnchorsOrchardMap::iterator, CAnchorsOrchardCacheEntry>(
|
||||||
tree,
|
tree,
|
||||||
ORCHARD,
|
ORCHARD,
|
||||||
cacheOrchardAnchors,
|
cacheOrchardAnchors,
|
||||||
|
@ -352,7 +352,7 @@ void CCoinsViewCache::BringBestAnchorIntoCache(
|
||||||
template<>
|
template<>
|
||||||
void CCoinsViewCache::BringBestAnchorIntoCache(
|
void CCoinsViewCache::BringBestAnchorIntoCache(
|
||||||
const uint256 ¤tRoot,
|
const uint256 ¤tRoot,
|
||||||
OrchardMerkleTree &tree
|
OrchardMerkleFrontier &tree
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
assert(GetOrchardAnchorAt(currentRoot, tree));
|
assert(GetOrchardAnchorAt(currentRoot, tree));
|
||||||
|
@ -1069,7 +1069,7 @@ std::optional<UnsatisfiedShieldedReq> CCoinsViewCache::HaveShieldedRequirements(
|
||||||
|
|
||||||
std::optional<uint256> root = tx.GetOrchardBundle().GetAnchor();
|
std::optional<uint256> root = tx.GetOrchardBundle().GetAnchor();
|
||||||
if (root) {
|
if (root) {
|
||||||
OrchardMerkleTree tree;
|
OrchardMerkleFrontier tree;
|
||||||
if (!GetOrchardAnchorAt(root.value(), tree)) {
|
if (!GetOrchardAnchorAt(root.value(), tree)) {
|
||||||
auto txid = tx.GetHash().ToString();
|
auto txid = tx.GetHash().ToString();
|
||||||
auto anchor = root.value().ToString();
|
auto anchor = root.value().ToString();
|
||||||
|
|
|
@ -304,7 +304,7 @@ struct CAnchorsSaplingCacheEntry
|
||||||
struct CAnchorsOrchardCacheEntry
|
struct CAnchorsOrchardCacheEntry
|
||||||
{
|
{
|
||||||
bool entered; // This will be false if the anchor is removed from the cache
|
bool entered; // This will be false if the anchor is removed from the cache
|
||||||
OrchardMerkleTree tree; // The tree itself
|
OrchardMerkleFrontier tree; // The tree itself
|
||||||
unsigned char flags;
|
unsigned char flags;
|
||||||
|
|
||||||
enum Flags {
|
enum Flags {
|
||||||
|
@ -368,7 +368,7 @@ public:
|
||||||
virtual bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
|
virtual bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
|
||||||
|
|
||||||
//! Retrieve the tree (Orchard) at a particular anchored root in the chain
|
//! Retrieve the tree (Orchard) at a particular anchored root in the chain
|
||||||
virtual bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleTree &tree) const;
|
virtual bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const;
|
||||||
|
|
||||||
//! Determine whether a nullifier is spent or not
|
//! Determine whether a nullifier is spent or not
|
||||||
virtual bool GetNullifier(const uint256 &nullifier, ShieldedType type) const;
|
virtual bool GetNullifier(const uint256 &nullifier, ShieldedType type) const;
|
||||||
|
@ -428,7 +428,7 @@ public:
|
||||||
CCoinsViewBacked(CCoinsView *viewIn);
|
CCoinsViewBacked(CCoinsView *viewIn);
|
||||||
bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const;
|
bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const;
|
||||||
bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
|
bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
|
||||||
bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleTree &tree) const;
|
bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const;
|
||||||
bool GetNullifier(const uint256 &nullifier, ShieldedType type) const;
|
bool GetNullifier(const uint256 &nullifier, ShieldedType type) const;
|
||||||
bool GetCoins(const uint256 &txid, CCoins &coins) const;
|
bool GetCoins(const uint256 &txid, CCoins &coins) const;
|
||||||
bool HaveCoins(const uint256 &txid) const;
|
bool HaveCoins(const uint256 &txid) const;
|
||||||
|
@ -521,7 +521,7 @@ public:
|
||||||
// Standard CCoinsView methods
|
// Standard CCoinsView methods
|
||||||
bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const;
|
bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const;
|
||||||
bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
|
bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
|
||||||
bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleTree &tree) const;
|
bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const;
|
||||||
bool GetNullifier(const uint256 &nullifier, ShieldedType type) const;
|
bool GetNullifier(const uint256 &nullifier, ShieldedType type) const;
|
||||||
bool GetCoins(const uint256 &txid, CCoins &coins) const;
|
bool GetCoins(const uint256 &txid, CCoins &coins) const;
|
||||||
bool HaveCoins(const uint256 &txid) const;
|
bool HaveCoins(const uint256 &txid) const;
|
||||||
|
|
|
@ -293,13 +293,13 @@ TEST(orchardMerkleTree, emptyroot) {
|
||||||
// an integer, which is converted to little-endian internally.
|
// an integer, which is converted to little-endian internally.
|
||||||
uint256 expected = uint256S("2fd8e51a03d9bbe2dd809831b1497aeb68a6e37ddf707ced4aa2d8dff13529ae");
|
uint256 expected = uint256S("2fd8e51a03d9bbe2dd809831b1497aeb68a6e37ddf707ced4aa2d8dff13529ae");
|
||||||
|
|
||||||
ASSERT_EQ(OrchardMerkleTree::empty_root(), expected);
|
ASSERT_EQ(OrchardMerkleFrontier::empty_root(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(orchardMerkleTree, appendBundle) {
|
TEST(orchardMerkleTree, appendBundle) {
|
||||||
OrchardMerkleTree newTree;
|
OrchardMerkleFrontier newTree;
|
||||||
|
|
||||||
ASSERT_EQ(newTree.root(), OrchardMerkleTree::empty_root());
|
ASSERT_EQ(newTree.root(), OrchardMerkleFrontier::empty_root());
|
||||||
|
|
||||||
for (int i = 0; i < 1; i++) {
|
for (int i = 0; i < 1; i++) {
|
||||||
CDataStream ssBundleData(merkle_roots_orchard[i].bundle, SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream ssBundleData(merkle_roots_orchard[i].bundle, SER_NETWORK, PROTOCOL_VERSION);
|
||||||
|
|
|
@ -1453,7 +1453,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||||
// cache size calculations
|
// cache size calculations
|
||||||
int64_t nTotalCache = (GetArg("-dbcache", nDefaultDbCache) << 20);
|
int64_t nTotalCache = (GetArg("-dbcache", nDefaultDbCache) << 20);
|
||||||
nTotalCache = std::max(nTotalCache, nMinDbCache << 20); // total cache cannot be less than nMinDbCache
|
nTotalCache = std::max(nTotalCache, nMinDbCache << 20); // total cache cannot be less than nMinDbCache
|
||||||
nTotalCache = std::min(nTotalCache, nMaxDbCache << 20); // total cache cannot be greated than nMaxDbcache
|
nTotalCache = std::min(nTotalCache, nMaxDbCache << 20); // total cache cannot be greater than nMaxDbcache
|
||||||
int64_t nBlockTreeDBCache = nTotalCache / 8;
|
int64_t nBlockTreeDBCache = nTotalCache / 8;
|
||||||
if (nBlockTreeDBCache > (1 << 21) && !GetBoolArg("-txindex", DEFAULT_TXINDEX))
|
if (nBlockTreeDBCache > (1 << 21) && !GetBoolArg("-txindex", DEFAULT_TXINDEX))
|
||||||
nBlockTreeDBCache = (1 << 21); // block tree db cache shouldn't be larger than 2 MiB
|
nBlockTreeDBCache = (1 << 21); // block tree db cache shouldn't be larger than 2 MiB
|
||||||
|
|
|
@ -3125,7 +3125,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||||
SaplingMerkleTree sapling_tree;
|
SaplingMerkleTree sapling_tree;
|
||||||
assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree));
|
assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree));
|
||||||
|
|
||||||
OrchardMerkleTree orchard_tree;
|
OrchardMerkleFrontier orchard_tree;
|
||||||
assert(view.GetOrchardAnchorAt(view.GetBestAnchor(ORCHARD), orchard_tree));
|
assert(view.GetOrchardAnchorAt(view.GetBestAnchor(ORCHARD), orchard_tree));
|
||||||
|
|
||||||
// Grab the consensus branch ID for this block and its parent
|
// Grab the consensus branch ID for this block and its parent
|
||||||
|
@ -6181,7 +6181,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
||||||
if ((mi->second->nVersion <= 4) != (inv.type == MSG_TX)) {
|
if ((mi->second->nVersion <= 4) != (inv.type == MSG_TX)) {
|
||||||
Misbehaving(pfrom->GetId(), 100);
|
Misbehaving(pfrom->GetId(), 100);
|
||||||
LogPrint("net", "Wrong INV message type used for v%d tx", mi->second->nVersion);
|
LogPrint("net", "Wrong INV message type used for v%d tx", mi->second->nVersion);
|
||||||
// Break so that this inv mesage will be erased from the queue
|
// Break so that this inv message will be erased from the queue
|
||||||
// (otherwise the peer would repeatedly hit this case until its
|
// (otherwise the peer would repeatedly hit this case until its
|
||||||
// Misbehaving level rises above -banscore, no matter what the
|
// Misbehaving level rises above -banscore, no matter what the
|
||||||
// user set it to).
|
// user set it to).
|
||||||
|
@ -6202,7 +6202,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
||||||
if ((txinfo.tx->nVersion <= 4) != (inv.type == MSG_TX)) {
|
if ((txinfo.tx->nVersion <= 4) != (inv.type == MSG_TX)) {
|
||||||
Misbehaving(pfrom->GetId(), 100);
|
Misbehaving(pfrom->GetId(), 100);
|
||||||
LogPrint("net", "Wrong INV message type used for v%d tx", txinfo.tx->nVersion);
|
LogPrint("net", "Wrong INV message type used for v%d tx", txinfo.tx->nVersion);
|
||||||
// Break so that this inv mesage will be erased from the queue.
|
// Break so that this inv message will be erased from the queue.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Ensure we only reply with a transaction if it is exactly what
|
// Ensure we only reply with a transaction if it is exactly what
|
||||||
|
@ -7201,7 +7201,7 @@ bool static ProcessMessage(const CChainParams& chainparams, CNode* pfrom, string
|
||||||
LogPrint("net", "Reject %s\n", SanitizeString(ss.str()));
|
LogPrint("net", "Reject %s\n", SanitizeString(ss.str()));
|
||||||
} catch (const std::ios_base::failure&) {
|
} catch (const std::ios_base::failure&) {
|
||||||
// Avoid feedback loops by preventing reject messages from triggering a new reject message.
|
// Avoid feedback loops by preventing reject messages from triggering a new reject message.
|
||||||
LogPrint("net", "Unparseable reject message received\n");
|
LogPrint("net", "Unparsable reject message received\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,7 @@ void WeightedTxTree::remove(const uint256& txId)
|
||||||
size_t removeIndex = txIdToIndexMap[txId];
|
size_t removeIndex = txIdToIndexMap[txId];
|
||||||
|
|
||||||
// We reduce the size at the start of this method to avoid saying size - 1
|
// We reduce the size at the start of this method to avoid saying size - 1
|
||||||
// when refering to the last element of the array below
|
// when referring to the last element of the array below
|
||||||
size -= 1;
|
size -= 1;
|
||||||
|
|
||||||
TxWeight lastChildWeight = txIdAndWeights[size].txWeight;
|
TxWeight lastChildWeight = txIdAndWeights[size].txWeight;
|
||||||
|
|
|
@ -331,7 +331,7 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const MinerAddre
|
||||||
|
|
||||||
// Largest block you're willing to create:
|
// Largest block you're willing to create:
|
||||||
unsigned int nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE);
|
unsigned int nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE);
|
||||||
// Limit to betweeen 1K and MAX_BLOCK_SIZE-1K for sanity:
|
// Limit to between 1K and MAX_BLOCK_SIZE-1K for sanity:
|
||||||
nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize));
|
nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize));
|
||||||
|
|
||||||
// How much of the block should be dedicated to high-priority transactions,
|
// How much of the block should be dedicated to high-priority transactions,
|
||||||
|
|
|
@ -690,7 +690,7 @@ public:
|
||||||
static bool BannedSetIsDirty();
|
static bool BannedSetIsDirty();
|
||||||
//!set the "dirty" flag for the banlist
|
//!set the "dirty" flag for the banlist
|
||||||
static void SetBannedSetDirty(bool dirty=true);
|
static void SetBannedSetDirty(bool dirty=true);
|
||||||
//!clean unused entires (if bantime has expired)
|
//!clean unused entries (if bantime has expired)
|
||||||
static void SweepBanned();
|
static void SweepBanned();
|
||||||
|
|
||||||
void copyStats(CNodeStats &stats);
|
void copyStats(CNodeStats &stats);
|
||||||
|
|
|
@ -93,13 +93,13 @@ private:
|
||||||
// Count the total # of txs in each bucket
|
// Count the total # of txs in each bucket
|
||||||
// Track the historical moving average of this total over blocks
|
// Track the historical moving average of this total over blocks
|
||||||
std::vector<double> txCtAvg;
|
std::vector<double> txCtAvg;
|
||||||
// and calcuate the total for the current block to update the moving average
|
// and calculate the total for the current block to update the moving average
|
||||||
std::vector<int> curBlockTxCt;
|
std::vector<int> curBlockTxCt;
|
||||||
|
|
||||||
// Count the total # of txs confirmed within Y blocks in each bucket
|
// Count the total # of txs confirmed within Y blocks in each bucket
|
||||||
// Track the historical moving average of theses totals over blocks
|
// Track the historical moving average of these totals over blocks
|
||||||
std::vector<std::vector<double> > confAvg; // confAvg[Y][X]
|
std::vector<std::vector<double> > confAvg; // confAvg[Y][X]
|
||||||
// and calcuate the totals for the current block to update the moving averages
|
// and calculate the totals for the current block to update the moving averages
|
||||||
std::vector<std::vector<int> > curBlockConf; // curBlockConf[Y][X]
|
std::vector<std::vector<int> > curBlockConf; // curBlockConf[Y][X]
|
||||||
|
|
||||||
// Sum the total priority/fee of all txs in each bucket
|
// Sum the total priority/fee of all txs in each bucket
|
||||||
|
|
|
@ -374,7 +374,7 @@ struct equi {
|
||||||
struct collisiondata {
|
struct collisiondata {
|
||||||
#ifdef XBITMAP
|
#ifdef XBITMAP
|
||||||
#if NSLOTS > 64
|
#if NSLOTS > 64
|
||||||
#error cant use XBITMAP with more than 64 slots
|
#error can't use XBITMAP with more than 64 slots
|
||||||
#endif
|
#endif
|
||||||
u64 xhashmap[NRESTS];
|
u64 xhashmap[NRESTS];
|
||||||
u64 xmap;
|
u64 xmap;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include <amount.h>
|
#include <amount.h>
|
||||||
#include <rust/orchard.h>
|
#include <rust/orchard.h>
|
||||||
|
|
||||||
class OrchardMerkleTree;
|
class OrchardMerkleFrontier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Orchard component of a transaction.
|
* The Orchard component of a transaction.
|
||||||
|
@ -22,7 +22,7 @@ private:
|
||||||
/// Memory is allocated by Rust.
|
/// Memory is allocated by Rust.
|
||||||
std::unique_ptr<OrchardBundlePtr, decltype(&orchard_bundle_free)> inner;
|
std::unique_ptr<OrchardBundlePtr, decltype(&orchard_bundle_free)> inner;
|
||||||
|
|
||||||
friend class OrchardMerkleTree;
|
friend class OrchardMerkleFrontier;
|
||||||
public:
|
public:
|
||||||
OrchardBundle() : inner(nullptr, orchard_bundle_free) {}
|
OrchardBundle() : inner(nullptr, orchard_bundle_free) {}
|
||||||
|
|
||||||
|
|
|
@ -425,45 +425,3 @@ std::string CTransaction::ToString() const
|
||||||
str += " " + vout[i].ToString() + "\n";
|
str += " " + vout[i].ToString() + "\n";
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the most recent supported transaction version and version group id,
|
|
||||||
* as of the specified activation height and active features.
|
|
||||||
*/
|
|
||||||
TxVersionInfo CurrentTxVersionInfo(
|
|
||||||
const Consensus::Params& consensus,
|
|
||||||
int nHeight,
|
|
||||||
bool requireSprout)
|
|
||||||
{
|
|
||||||
if (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_ZFUTURE)) {
|
|
||||||
return {
|
|
||||||
.fOverwintered = true,
|
|
||||||
.nVersionGroupId = ZFUTURE_VERSION_GROUP_ID,
|
|
||||||
.nVersion = ZFUTURE_TX_VERSION
|
|
||||||
};
|
|
||||||
} else if (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_NU5) && !requireSprout) {
|
|
||||||
return {
|
|
||||||
.fOverwintered = true,
|
|
||||||
.nVersionGroupId = ZIP225_VERSION_GROUP_ID,
|
|
||||||
.nVersion = ZIP225_TX_VERSION
|
|
||||||
};
|
|
||||||
} else if (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_SAPLING)) {
|
|
||||||
return {
|
|
||||||
.fOverwintered = true,
|
|
||||||
.nVersionGroupId = SAPLING_VERSION_GROUP_ID,
|
|
||||||
.nVersion = SAPLING_TX_VERSION
|
|
||||||
};
|
|
||||||
} else if (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_OVERWINTER)) {
|
|
||||||
return {
|
|
||||||
.fOverwintered = true,
|
|
||||||
.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID,
|
|
||||||
.nVersion = OVERWINTER_TX_VERSION
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
.fOverwintered = false,
|
|
||||||
.nVersionGroupId = 0,
|
|
||||||
.nVersion = CTransaction::SPROUT_MIN_CURRENT_VERSION
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
// Copyright (c) 2021 The Zcash developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
||||||
|
|
||||||
|
#include "primitives/transaction.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the most recent supported transaction version and version group id,
|
||||||
|
* as of the specified activation height and active features.
|
||||||
|
*/
|
||||||
|
TxVersionInfo CurrentTxVersionInfo(
|
||||||
|
const Consensus::Params& consensus,
|
||||||
|
int nHeight,
|
||||||
|
bool requireSprout)
|
||||||
|
{
|
||||||
|
if (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_ZFUTURE)) {
|
||||||
|
return {
|
||||||
|
.fOverwintered = true,
|
||||||
|
.nVersionGroupId = ZFUTURE_VERSION_GROUP_ID,
|
||||||
|
.nVersion = ZFUTURE_TX_VERSION
|
||||||
|
};
|
||||||
|
} else if (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_NU5) && !requireSprout) {
|
||||||
|
return {
|
||||||
|
.fOverwintered = true,
|
||||||
|
.nVersionGroupId = ZIP225_VERSION_GROUP_ID,
|
||||||
|
.nVersion = ZIP225_TX_VERSION
|
||||||
|
};
|
||||||
|
} else if (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_SAPLING)) {
|
||||||
|
return {
|
||||||
|
.fOverwintered = true,
|
||||||
|
.nVersionGroupId = SAPLING_VERSION_GROUP_ID,
|
||||||
|
.nVersion = SAPLING_TX_VERSION
|
||||||
|
};
|
||||||
|
} else if (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_OVERWINTER)) {
|
||||||
|
return {
|
||||||
|
.fOverwintered = true,
|
||||||
|
.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID,
|
||||||
|
.nVersion = OVERWINTER_TX_VERSION
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
.fOverwintered = false,
|
||||||
|
.nVersionGroupId = 0,
|
||||||
|
.nVersion = CTransaction::SPROUT_MIN_CURRENT_VERSION
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -56,7 +56,7 @@
|
||||||
-------------
|
-------------
|
||||||
Clang -std=c++2a enables it. GCC has it enabled without -std=c++2a
|
Clang -std=c++2a enables it. GCC has it enabled without -std=c++2a
|
||||||
but warns "__VA_OPT__ is not available until C++2a" if another -std
|
but warns "__VA_OPT__ is not available until C++2a" if another -std
|
||||||
flag is supplied along with -pedantic (dont know how to supress it).
|
flag is supplied along with -pedantic (dont know how to suppress it).
|
||||||
MSVC TBD
|
MSVC TBD
|
||||||
|
|
||||||
Credits
|
Credits
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
// Copyright (c) 2021 The Zcash developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
||||||
|
|
||||||
|
#ifndef ZCASH_RUST_INCLUDE_RUST_ORCHARD_INCREMENTAL_MERKLE_TREE_H
|
||||||
|
#define ZCASH_RUST_INCLUDE_RUST_ORCHARD_INCREMENTAL_MERKLE_TREE_H
|
||||||
|
|
||||||
|
#include "rust/streams.h"
|
||||||
|
#include "rust/orchard.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SINSEMILLA_DIGEST_LEN 32U
|
||||||
|
|
||||||
|
/// Pointer to an Orchard incremental merkle tree frontier
|
||||||
|
struct OrchardMerkleFrontierPtr;
|
||||||
|
typedef struct OrchardMerkleFrontierPtr OrchardMerkleFrontierPtr;
|
||||||
|
|
||||||
|
// Create an empty Orchard Merkle frontier.
|
||||||
|
//
|
||||||
|
// Memory allocated to the resulting value must be manually freed.
|
||||||
|
OrchardMerkleFrontierPtr* orchard_merkle_frontier_empty();
|
||||||
|
|
||||||
|
// Clones the given Orchard Merkle frontier and returns
|
||||||
|
// a pointer to the newly created tree. Both the original
|
||||||
|
// tree's memory and the newly allocated one need to be freed
|
||||||
|
// independently.
|
||||||
|
OrchardMerkleFrontierPtr* orchard_merkle_frontier_clone(
|
||||||
|
const OrchardMerkleFrontierPtr* tree_ptr);
|
||||||
|
|
||||||
|
// Free the memory allocated for the given Orchard Merkle frontier.
|
||||||
|
void orchard_merkle_frontier_free(
|
||||||
|
OrchardMerkleFrontierPtr* tree_ptr);
|
||||||
|
|
||||||
|
// Parses an Orchard Merkle frontier from a stream. If parsing
|
||||||
|
// fails, this will return the null pointer.
|
||||||
|
//
|
||||||
|
// Memory allocated to the resulting value must be manually freed.
|
||||||
|
OrchardMerkleFrontierPtr* orchard_merkle_frontier_parse(
|
||||||
|
void* stream,
|
||||||
|
read_callback_t read_cb);
|
||||||
|
|
||||||
|
// Serializes an Orchard Merkle frontier to a stream.
|
||||||
|
//
|
||||||
|
// Returns `false` if an error occurs while writing to the stream.
|
||||||
|
bool orchard_merkle_frontier_serialize(
|
||||||
|
const OrchardMerkleFrontierPtr* tree_ptr,
|
||||||
|
void* stream,
|
||||||
|
write_callback_t write_cb);
|
||||||
|
|
||||||
|
// For each action in the provided bundle, append its
|
||||||
|
// commitment to the frontier.
|
||||||
|
//
|
||||||
|
// Returns `true` if the append succeeds, `false` if the
|
||||||
|
// tree is full.
|
||||||
|
bool orchard_merkle_frontier_append_bundle(
|
||||||
|
OrchardMerkleFrontierPtr* tree_ptr,
|
||||||
|
const OrchardBundlePtr* bundle);
|
||||||
|
|
||||||
|
// Computes the root of the provided orchard Merkle frontier
|
||||||
|
void orchard_merkle_frontier_root(
|
||||||
|
const OrchardMerkleFrontierPtr* tree_ptr,
|
||||||
|
unsigned char* digest_ret);
|
||||||
|
|
||||||
|
// The total number of leaves that have been appended to obtain
|
||||||
|
// the current state of the frontier. Subtract 1 from this value
|
||||||
|
// to obtain the position of the most recently appended leaf.
|
||||||
|
size_t orchard_merkle_frontier_num_leaves(
|
||||||
|
const OrchardMerkleFrontierPtr* tree_ptr);
|
||||||
|
|
||||||
|
// Estimate the amount of memory consumed by the merkle frontier.
|
||||||
|
size_t orchard_merkle_frontier_dynamic_mem_usage(
|
||||||
|
const OrchardMerkleFrontierPtr* tree_ptr);
|
||||||
|
|
||||||
|
// Computes the empty leaf value for the incremental Merkle tree.
|
||||||
|
void orchard_merkle_tree_empty_root(
|
||||||
|
unsigned char* digest_ret);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // ZCASH_RUST_INCLUDE_RUST_ORCHARD_INCREMENTAL_MERKLE_TREE_H
|
|
@ -1,149 +0,0 @@
|
||||||
// Copyright (c) 2021 The Zcash developers
|
|
||||||
// Distributed under the MIT software license, see the accompanying
|
|
||||||
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
|
||||||
|
|
||||||
#ifndef ZCASH_RUST_INCLUDE_RUST_ORCHARD_INCREMENTAL_SINSEMILLA_TREE_H
|
|
||||||
#define ZCASH_RUST_INCLUDE_RUST_ORCHARD_INCREMENTAL_SINSEMILLA_TREE_H
|
|
||||||
|
|
||||||
#include "rust/streams.h"
|
|
||||||
#include "rust/orchard.h"
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SINSEMILLA_DIGEST_LEN 32U
|
|
||||||
|
|
||||||
/// Pointer to an Orchard incremental merkle tree frontier
|
|
||||||
struct OrchardMerkleFrontierPtr;
|
|
||||||
typedef struct OrchardMerkleFrontierPtr OrchardMerkleFrontierPtr;
|
|
||||||
|
|
||||||
// Create an empty Orchard Merkle frontier.
|
|
||||||
//
|
|
||||||
// Memory allocated to the resulting value must be manually freed.
|
|
||||||
OrchardMerkleFrontierPtr* orchard_merkle_frontier_empty();
|
|
||||||
|
|
||||||
// Clones the given Orchard Merkle frontier and returns
|
|
||||||
// a pointer to the newly created tree. Both the original
|
|
||||||
// tree's memory and the newly allocated one need to be freed
|
|
||||||
// independently.
|
|
||||||
OrchardMerkleFrontierPtr* orchard_merkle_frontier_clone(
|
|
||||||
const OrchardMerkleFrontierPtr* tree_ptr);
|
|
||||||
|
|
||||||
// Free the memory allocated for the given Orchard Merkle frontier.
|
|
||||||
void orchard_merkle_frontier_free(
|
|
||||||
OrchardMerkleFrontierPtr* tree_ptr);
|
|
||||||
|
|
||||||
// Parses an Orchard Merkle frontier from a stream. If parsing
|
|
||||||
// fails, this will return the null pointer.
|
|
||||||
//
|
|
||||||
// Memory allocated to the resulting value must be manually freed.
|
|
||||||
OrchardMerkleFrontierPtr* orchard_merkle_frontier_parse(
|
|
||||||
void* stream,
|
|
||||||
read_callback_t read_cb);
|
|
||||||
|
|
||||||
// Serializes an Orchard Merkle frontier to a stream.
|
|
||||||
//
|
|
||||||
// Returns `false` if an error occurs while writing to the stream.
|
|
||||||
bool orchard_merkle_frontier_serialize(
|
|
||||||
const OrchardMerkleFrontierPtr* tree_ptr,
|
|
||||||
void* stream,
|
|
||||||
write_callback_t write_cb);
|
|
||||||
|
|
||||||
// For each action in the provided bundle, append its
|
|
||||||
// commitment to the frontier.
|
|
||||||
//
|
|
||||||
// Returns `true` if the append succeeds, `false` if the
|
|
||||||
// tree is full.
|
|
||||||
bool orchard_merkle_frontier_append_bundle(
|
|
||||||
OrchardMerkleFrontierPtr* tree_ptr,
|
|
||||||
const OrchardBundlePtr* bundle);
|
|
||||||
|
|
||||||
// Computes the root of the provided orchard Merkle frontier
|
|
||||||
void orchard_merkle_frontier_root(
|
|
||||||
const OrchardMerkleFrontierPtr* tree_ptr,
|
|
||||||
unsigned char* digest_ret);
|
|
||||||
|
|
||||||
// The total number of leaves that have been appended to obtain
|
|
||||||
// the current state of the frontier. Subtract 1 from this value
|
|
||||||
// to obtain the position of the most recently appended leaf.
|
|
||||||
size_t orchard_merkle_frontier_num_leaves(
|
|
||||||
const OrchardMerkleFrontierPtr* tree_ptr);
|
|
||||||
|
|
||||||
// Estimate the amount of memory consumed by the merkle frontier.
|
|
||||||
size_t orchard_merkle_frontier_dynamic_mem_usage(
|
|
||||||
const OrchardMerkleFrontierPtr* tree_ptr);
|
|
||||||
|
|
||||||
/// Pointer to an Orchard incremental Sinsemilla tree
|
|
||||||
struct IncrementalSinsemillaTreePtr;
|
|
||||||
typedef struct IncrementalSinsemillaTreePtr IncrementalSinsemillaTreePtr;
|
|
||||||
|
|
||||||
// Create an empty incremental Sinsemilla tree.
|
|
||||||
//
|
|
||||||
// Memory allocated to the resulting value must be manually freed.
|
|
||||||
IncrementalSinsemillaTreePtr* incremental_sinsemilla_tree_empty();
|
|
||||||
|
|
||||||
// Clones the given incremental Sinsemilla tree and returns
|
|
||||||
// a pointer to the newly created tree. Both the original
|
|
||||||
// tree's memory and the newly allocated one need to be freed
|
|
||||||
// independently.
|
|
||||||
IncrementalSinsemillaTreePtr* incremental_sinsemilla_tree_clone(
|
|
||||||
const IncrementalSinsemillaTreePtr* tree_ptr);
|
|
||||||
|
|
||||||
// Free the memory allocated for the given incremental Sinsemilla tree.
|
|
||||||
void incremental_sinsemilla_tree_free(
|
|
||||||
IncrementalSinsemillaTreePtr* tree_ptr);
|
|
||||||
|
|
||||||
// Parses an incremental Sinsemilla tree from a stream. If parsing
|
|
||||||
// fails, this will return the null pointer.
|
|
||||||
//
|
|
||||||
// Memory allocated to the resulting value must be manually freed.
|
|
||||||
IncrementalSinsemillaTreePtr* incremental_sinsemilla_tree_parse(
|
|
||||||
void* stream,
|
|
||||||
read_callback_t read_cb);
|
|
||||||
|
|
||||||
// Serializes an incremental Sinsemilla tree to a stream.
|
|
||||||
//
|
|
||||||
// Returns false if an error occurs while writing to the stream.
|
|
||||||
bool incremental_sinsemilla_tree_serialize(
|
|
||||||
const IncrementalSinsemillaTreePtr* tree_ptr,
|
|
||||||
void* stream,
|
|
||||||
write_callback_t write_cb);
|
|
||||||
|
|
||||||
// For each action in the provided bundle, append its
|
|
||||||
// commitment to the incremental Merkle tree.
|
|
||||||
//
|
|
||||||
// Returns `true` if the append succeeds, `false` if the
|
|
||||||
// tree is full.
|
|
||||||
bool incremental_sinsemilla_tree_append_bundle(
|
|
||||||
IncrementalSinsemillaTreePtr* tree_ptr,
|
|
||||||
const OrchardBundlePtr* bundle);
|
|
||||||
|
|
||||||
// Save the current state of the incremental merkle tree
|
|
||||||
// as a point to which the tree can be rewound.
|
|
||||||
void incremental_sinsemilla_tree_checkpoint(
|
|
||||||
IncrementalSinsemillaTreePtr* tree_ptr);
|
|
||||||
|
|
||||||
// Rewind the incremental merkle tree to the latest checkpoint.
|
|
||||||
//
|
|
||||||
// Returns `true` if the rewind succeeds, `false` if the attempted
|
|
||||||
// rewind would require the destruction of witness data.
|
|
||||||
bool incremental_sinsemilla_tree_rewind(
|
|
||||||
IncrementalSinsemillaTreePtr* tree_ptr);
|
|
||||||
|
|
||||||
// Computes the root of the provided incremental Sinsemilla tree.
|
|
||||||
void incremental_sinsemilla_tree_root(
|
|
||||||
const IncrementalSinsemillaTreePtr* tree_ptr,
|
|
||||||
unsigned char* digest_ret);
|
|
||||||
|
|
||||||
// Computes the empty leaf value for the incremental Sinsemilla tree.
|
|
||||||
void incremental_sinsemilla_tree_empty_root(
|
|
||||||
unsigned char* digest_ret);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // ZCASH_RUST_INCLUDE_RUST_ORCHARD_INCREMENTAL_SINSEMILLA_TREE_H
|
|
|
@ -1,21 +1,17 @@
|
||||||
use incrementalmerkletree::{
|
use incrementalmerkletree::{bridgetree, Altitude, Frontier, Hashable};
|
||||||
bridgetree::{self, BridgeTree},
|
|
||||||
Altitude, Frontier, Hashable, Tree,
|
|
||||||
};
|
|
||||||
use std::mem::size_of_val;
|
use std::mem::size_of_val;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
use orchard::{bundle::Authorized, tree::MerkleHashOrchard};
|
use orchard::{bundle::Authorized, tree::MerkleHashOrchard};
|
||||||
|
use tracing::error;
|
||||||
use zcash_primitives::{
|
use zcash_primitives::{
|
||||||
merkle_tree::incremental::{read_frontier_v1, read_tree, write_frontier_v1, write_tree},
|
merkle_tree::incremental::{read_frontier_v1, write_frontier_v1},
|
||||||
transaction::components::Amount,
|
transaction::components::Amount,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::orchard_ffi::{error, CppStreamReader, CppStreamWriter, ReadCb, StreamObj, WriteCb};
|
use crate::streams_ffi::{CppStreamReader, CppStreamWriter, ReadCb, StreamObj, WriteCb};
|
||||||
|
|
||||||
pub const MERKLE_DEPTH: u8 = 32;
|
pub const MERKLE_DEPTH: u8 = 32;
|
||||||
pub const MAX_CHECKPOINTS: usize = 100;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Operations on Merkle frontiers.
|
// Operations on Merkle frontiers.
|
||||||
|
@ -148,139 +144,8 @@ pub extern "C" fn orchard_merkle_frontier_dynamic_mem_usage(
|
||||||
size_of_val(tree) + tree.dynamic_memory_usage()
|
size_of_val(tree) + tree.dynamic_memory_usage()
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Operations on incremental merkle trees with interstitial
|
|
||||||
// witnesses.
|
|
||||||
//
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn incremental_sinsemilla_tree_empty(
|
pub extern "C" fn orchard_merkle_tree_empty_root(root_ret: *mut [u8; 32]) {
|
||||||
) -> *mut BridgeTree<MerkleHashOrchard, MERKLE_DEPTH> {
|
|
||||||
let empty_tree = BridgeTree::<MerkleHashOrchard, MERKLE_DEPTH>::new(MAX_CHECKPOINTS);
|
|
||||||
Box::into_raw(Box::new(empty_tree))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn incremental_sinsemilla_tree_clone(
|
|
||||||
tree: *const BridgeTree<MerkleHashOrchard, MERKLE_DEPTH>,
|
|
||||||
) -> *mut BridgeTree<MerkleHashOrchard, MERKLE_DEPTH> {
|
|
||||||
unsafe { tree.as_ref() }
|
|
||||||
.map(|tree| Box::into_raw(Box::new(tree.clone())))
|
|
||||||
.unwrap_or(std::ptr::null_mut())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn incremental_sinsemilla_tree_free(
|
|
||||||
tree: *mut BridgeTree<MerkleHashOrchard, MERKLE_DEPTH>,
|
|
||||||
) {
|
|
||||||
if !tree.is_null() {
|
|
||||||
drop(unsafe { Box::from_raw(tree) });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn incremental_sinsemilla_tree_parse(
|
|
||||||
stream: Option<StreamObj>,
|
|
||||||
read_cb: Option<ReadCb>,
|
|
||||||
) -> *mut BridgeTree<MerkleHashOrchard, MERKLE_DEPTH> {
|
|
||||||
let reader = CppStreamReader::from_raw_parts(stream, read_cb.unwrap());
|
|
||||||
|
|
||||||
match read_tree(reader) {
|
|
||||||
Ok(parsed) => Box::into_raw(Box::new(parsed)),
|
|
||||||
Err(e) => {
|
|
||||||
error!("Failed to parse Orchard bundle: {}", e);
|
|
||||||
ptr::null_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn incremental_sinsemilla_tree_serialize(
|
|
||||||
tree: *const BridgeTree<MerkleHashOrchard, MERKLE_DEPTH>,
|
|
||||||
stream: Option<StreamObj>,
|
|
||||||
write_cb: Option<WriteCb>,
|
|
||||||
) -> bool {
|
|
||||||
let tree = unsafe {
|
|
||||||
tree.as_ref()
|
|
||||||
.expect("Orchard note commitment tree pointer may not be null.")
|
|
||||||
};
|
|
||||||
|
|
||||||
let writer = CppStreamWriter::from_raw_parts(stream, write_cb.unwrap());
|
|
||||||
match write_tree(writer, tree) {
|
|
||||||
Ok(()) => true,
|
|
||||||
Err(e) => {
|
|
||||||
error!("{}", e);
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn incremental_sinsemilla_tree_append_bundle(
|
|
||||||
tree: *mut BridgeTree<MerkleHashOrchard, MERKLE_DEPTH>,
|
|
||||||
bundle: *const orchard::Bundle<Authorized, Amount>,
|
|
||||||
) -> bool {
|
|
||||||
let tree = unsafe {
|
|
||||||
tree.as_mut()
|
|
||||||
.expect("Orchard note commitment tree pointer may not be null.")
|
|
||||||
};
|
|
||||||
if let Some(bundle) = unsafe { bundle.as_ref() } {
|
|
||||||
for action in bundle.actions().iter() {
|
|
||||||
if !tree.append(&MerkleHashOrchard::from_cmx(action.cmx())) {
|
|
||||||
error!("Orchard note commitment tree is full.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn incremental_sinsemilla_tree_checkpoint(
|
|
||||||
tree: *mut BridgeTree<MerkleHashOrchard, MERKLE_DEPTH>,
|
|
||||||
) {
|
|
||||||
let tree = unsafe {
|
|
||||||
tree.as_mut()
|
|
||||||
.expect("Orchard note commitment tree pointer may not be null.")
|
|
||||||
};
|
|
||||||
|
|
||||||
tree.checkpoint()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn incremental_sinsemilla_tree_rewind(
|
|
||||||
tree: *mut BridgeTree<MerkleHashOrchard, MERKLE_DEPTH>,
|
|
||||||
) -> bool {
|
|
||||||
let tree = unsafe {
|
|
||||||
tree.as_mut()
|
|
||||||
.expect("Orchard note commitment tree pointer may not be null.")
|
|
||||||
};
|
|
||||||
|
|
||||||
tree.rewind()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn incremental_sinsemilla_tree_root(
|
|
||||||
tree: *const BridgeTree<MerkleHashOrchard, MERKLE_DEPTH>,
|
|
||||||
root_ret: *mut [u8; 32],
|
|
||||||
) {
|
|
||||||
let tree = unsafe {
|
|
||||||
tree.as_ref()
|
|
||||||
.expect("Orchard note commitment tree pointer may not be null.")
|
|
||||||
};
|
|
||||||
|
|
||||||
let root_ret = unsafe {
|
|
||||||
root_ret
|
|
||||||
.as_mut()
|
|
||||||
.expect("Cannot return to the null pointer.")
|
|
||||||
};
|
|
||||||
|
|
||||||
*root_ret = tree.root().to_bytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn incremental_sinsemilla_tree_empty_root(root_ret: *mut [u8; 32]) {
|
|
||||||
let root_ret = unsafe {
|
let root_ret = unsafe {
|
||||||
root_ret
|
root_ret
|
||||||
.as_mut()
|
.as_mut()
|
|
@ -19,8 +19,6 @@ use zcash_primitives::transaction::{
|
||||||
|
|
||||||
use crate::streams_ffi::{CppStreamReader, CppStreamWriter, ReadCb, StreamObj, WriteCb};
|
use crate::streams_ffi::{CppStreamReader, CppStreamWriter, ReadCb, StreamObj, WriteCb};
|
||||||
|
|
||||||
mod incremental_sinsemilla_tree_ffi;
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn orchard_bundle_clone(
|
pub extern "C" fn orchard_bundle_clone(
|
||||||
bundle: *const Bundle<Authorized, Amount>,
|
bundle: *const Bundle<Authorized, Amount>,
|
||||||
|
|
|
@ -70,6 +70,7 @@ mod tracing_ffi;
|
||||||
|
|
||||||
mod address_ffi;
|
mod address_ffi;
|
||||||
mod history_ffi;
|
mod history_ffi;
|
||||||
|
mod incremental_merkle_tree_ffi;
|
||||||
mod orchard_ffi;
|
mod orchard_ffi;
|
||||||
mod transaction_ffi;
|
mod transaction_ffi;
|
||||||
mod zip339_ffi;
|
mod zip339_ffi;
|
||||||
|
|
|
@ -69,6 +69,22 @@ struct ECCryptoClosure
|
||||||
};
|
};
|
||||||
|
|
||||||
ECCryptoClosure instance_of_eccryptoclosure;
|
ECCryptoClosure instance_of_eccryptoclosure;
|
||||||
|
|
||||||
|
// Copy of GetLegacySigOpCount from main.cpp commit c4b2ef7c4.
|
||||||
|
// Replace with the copy from src/consensus/tx_verify.{cpp,h} after backporting that refactor.
|
||||||
|
unsigned int GetLegacySigOpCount(const CTransaction& tx)
|
||||||
|
{
|
||||||
|
unsigned int nSigOps = 0;
|
||||||
|
for (const CTxIn& txin : tx.vin)
|
||||||
|
{
|
||||||
|
nSigOps += txin.scriptSig.GetSigOpCount(false);
|
||||||
|
}
|
||||||
|
for (const CTxOut& txout : tx.vout)
|
||||||
|
{
|
||||||
|
nSigOps += txout.scriptPubKey.GetSigOpCount(false);
|
||||||
|
}
|
||||||
|
return nSigOps;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PrecomputedTransaction {
|
struct PrecomputedTransaction {
|
||||||
|
@ -92,7 +108,7 @@ void* zcash_script_new_precomputed_tx(
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regardless of the verification result, the tx did not error.
|
// Deserializing the tx did not error.
|
||||||
set_error(err, zcash_script_ERR_OK);
|
set_error(err, zcash_script_ERR_OK);
|
||||||
auto preTx = new PrecomputedTransaction(tx);
|
auto preTx = new PrecomputedTransaction(tx);
|
||||||
return preTx;
|
return preTx;
|
||||||
|
@ -166,6 +182,42 @@ int zcash_script_verify(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int zcash_script_legacy_sigop_count_precomputed(
|
||||||
|
const void* pre_preTx,
|
||||||
|
zcash_script_error* err)
|
||||||
|
{
|
||||||
|
const PrecomputedTransaction* preTx = static_cast<const PrecomputedTransaction*>(pre_preTx);
|
||||||
|
|
||||||
|
// The current implementation of this method never errors.
|
||||||
|
set_error(err, zcash_script_ERR_OK);
|
||||||
|
|
||||||
|
return GetLegacySigOpCount(preTx->tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int zcash_script_legacy_sigop_count(
|
||||||
|
const unsigned char *txTo,
|
||||||
|
unsigned int txToLen,
|
||||||
|
zcash_script_error* err)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
TxInputStream stream(SER_NETWORK, PROTOCOL_VERSION, txTo, txToLen);
|
||||||
|
CTransaction tx;
|
||||||
|
stream >> tx;
|
||||||
|
if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) {
|
||||||
|
set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH);
|
||||||
|
return UINT_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deserializing the tx did not error.
|
||||||
|
set_error(err, zcash_script_ERR_OK);
|
||||||
|
|
||||||
|
return GetLegacySigOpCount(tx);
|
||||||
|
} catch (const std::exception&) {
|
||||||
|
set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing
|
||||||
|
return UINT_MAX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int zcash_script_version()
|
unsigned int zcash_script_version()
|
||||||
{
|
{
|
||||||
// Just use the API version for now
|
// Just use the API version for now
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ZCASH_SCRIPT_API_VER 1
|
#define ZCASH_SCRIPT_API_VER 2
|
||||||
|
|
||||||
typedef enum zcash_script_error_t
|
typedef enum zcash_script_error_t
|
||||||
{
|
{
|
||||||
|
@ -99,6 +99,28 @@ EXPORT_SYMBOL int zcash_script_verify(
|
||||||
uint32_t consensusBranchId,
|
uint32_t consensusBranchId,
|
||||||
zcash_script_error* err);
|
zcash_script_error* err);
|
||||||
|
|
||||||
|
/// Returns the number of transparent signature operations in the
|
||||||
|
/// transparent inputs and outputs of the precomputed transaction
|
||||||
|
/// pointed to by preTx.
|
||||||
|
///
|
||||||
|
/// Returns UINT_MAX on error, so that invalid transactions don't pass the Zcash consensus rules.
|
||||||
|
/// If not NULL, err will contain an error/success code for the operation.
|
||||||
|
EXPORT_SYMBOL unsigned int zcash_script_legacy_sigop_count_precomputed(
|
||||||
|
const void* preTx,
|
||||||
|
zcash_script_error* err);
|
||||||
|
|
||||||
|
/// Returns the number of transparent signature operations in the
|
||||||
|
/// transparent inputs and outputs of the serialized transaction
|
||||||
|
/// pointed to by txTo.
|
||||||
|
///
|
||||||
|
/// Returns UINT_MAX on error.
|
||||||
|
/// If not NULL, err will contain an error/success code for the operation.
|
||||||
|
EXPORT_SYMBOL unsigned int zcash_script_legacy_sigop_count(
|
||||||
|
const unsigned char *txTo,
|
||||||
|
unsigned int txToLen,
|
||||||
|
zcash_script_error* err);
|
||||||
|
|
||||||
|
/// Returns the current version of the zcash_script library.
|
||||||
EXPORT_SYMBOL unsigned int zcash_script_version();
|
EXPORT_SYMBOL unsigned int zcash_script_version();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -21,7 +21,7 @@ void memory_cleanse(void *ptr, size_t len)
|
||||||
|
|
||||||
/* In order to prevent the compiler from optimizing out the memset, this uses an
|
/* In order to prevent the compiler from optimizing out the memset, this uses an
|
||||||
* unremovable (see https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile )
|
* unremovable (see https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile )
|
||||||
* asm block that the compiler must assume could access arbitary memory, including
|
* asm block that the compiler must assume could access arbitrary memory, including
|
||||||
* the zero bytes written by std::memset.
|
* the zero bytes written by std::memset.
|
||||||
*
|
*
|
||||||
* Quoting Adam Langley <agl@google.com> in commit ad1907fe73334d6c696c8539646c21b11178f20f
|
* Quoting Adam Langley <agl@google.com> in commit ad1907fe73334d6c696c8539646c21b11178f20f
|
||||||
|
|
|
@ -392,7 +392,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
|
||||||
size_t percent23 = (addrman.size() * 23) / 100;
|
size_t percent23 = (addrman.size() * 23) / 100;
|
||||||
BOOST_CHECK(vAddr.size() == percent23);
|
BOOST_CHECK(vAddr.size() == percent23);
|
||||||
BOOST_CHECK(vAddr.size() == 461);
|
BOOST_CHECK(vAddr.size() == 461);
|
||||||
// (Addrman.size() < number of addresses added) due to address collisons.
|
// (Addrman.size() < number of addresses added) due to address collisions.
|
||||||
BOOST_CHECK(addrman.size() == 2007);
|
BOOST_CHECK(addrman.size() == 2007);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ help_text="""Test framework for bitcoin utils.
|
||||||
|
|
||||||
Runs automatically during `make check`.
|
Runs automatically during `make check`.
|
||||||
|
|
||||||
Can also be run manually from the src directory by specifiying the source directory:
|
Can also be run manually from the src directory by specifying the source directory:
|
||||||
|
|
||||||
test/bitcoin-util-test.py --srcdir='srcdir' [--verbose]
|
test/bitcoin-util-test.py --srcdir='srcdir' [--verbose]
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -302,7 +302,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_UniqueCheck)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Test that blocks which might allocate lots of memory free their memory agressively.
|
// Test that blocks which might allocate lots of memory free their memory aggressively.
|
||||||
//
|
//
|
||||||
// This test attempts to catch a pathological case where by lazily freeing
|
// This test attempts to catch a pathological case where by lazily freeing
|
||||||
// checks might mean leaving a check un-swapped out, and decreasing by 1 each
|
// checks might mean leaving a check un-swapped out, and decreasing by 1 each
|
||||||
|
|
|
@ -32,7 +32,7 @@ class CCoinsViewTest : public CCoinsView
|
||||||
std::map<uint256, CCoins> map_;
|
std::map<uint256, CCoins> map_;
|
||||||
std::map<uint256, SproutMerkleTree> mapSproutAnchors_;
|
std::map<uint256, SproutMerkleTree> mapSproutAnchors_;
|
||||||
std::map<uint256, SaplingMerkleTree> mapSaplingAnchors_;
|
std::map<uint256, SaplingMerkleTree> mapSaplingAnchors_;
|
||||||
std::map<uint256, OrchardMerkleTree> mapOrchardAnchors_;
|
std::map<uint256, OrchardMerkleFrontier> mapOrchardAnchors_;
|
||||||
std::map<uint256, bool> mapSproutNullifiers_;
|
std::map<uint256, bool> mapSproutNullifiers_;
|
||||||
std::map<uint256, bool> mapSaplingNullifiers_;
|
std::map<uint256, bool> mapSaplingNullifiers_;
|
||||||
std::map<uint256, bool> mapOrchardNullifiers_;
|
std::map<uint256, bool> mapOrchardNullifiers_;
|
||||||
|
@ -41,7 +41,7 @@ public:
|
||||||
CCoinsViewTest() {
|
CCoinsViewTest() {
|
||||||
hashBestSproutAnchor_ = SproutMerkleTree::empty_root();
|
hashBestSproutAnchor_ = SproutMerkleTree::empty_root();
|
||||||
hashBestSaplingAnchor_ = SaplingMerkleTree::empty_root();
|
hashBestSaplingAnchor_ = SaplingMerkleTree::empty_root();
|
||||||
hashBestOrchardAnchor_ = OrchardMerkleTree::empty_root();
|
hashBestOrchardAnchor_ = OrchardMerkleFrontier::empty_root();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetSproutAnchorAt(const uint256& rt, SproutMerkleTree &tree) const {
|
bool GetSproutAnchorAt(const uint256& rt, SproutMerkleTree &tree) const {
|
||||||
|
@ -76,14 +76,14 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetOrchardAnchorAt(const uint256& rt, OrchardMerkleTree &tree) const {
|
bool GetOrchardAnchorAt(const uint256& rt, OrchardMerkleFrontier &tree) const {
|
||||||
if (rt == OrchardMerkleTree::empty_root()) {
|
if (rt == OrchardMerkleFrontier::empty_root()) {
|
||||||
OrchardMerkleTree new_tree;
|
OrchardMerkleFrontier new_tree;
|
||||||
tree = new_tree;
|
tree = new_tree;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<uint256, OrchardMerkleTree>::const_iterator it = mapOrchardAnchors_.find(rt);
|
std::map<uint256, OrchardMerkleFrontier>::const_iterator it = mapOrchardAnchors_.find(rt);
|
||||||
if (it == mapOrchardAnchors_.end()) {
|
if (it == mapOrchardAnchors_.end()) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -217,7 +217,7 @@ public:
|
||||||
|
|
||||||
BatchWriteAnchors<SproutMerkleTree, CAnchorsSproutMap, CAnchorsSproutCacheEntry>(mapSproutAnchors, mapSproutAnchors_);
|
BatchWriteAnchors<SproutMerkleTree, CAnchorsSproutMap, CAnchorsSproutCacheEntry>(mapSproutAnchors, mapSproutAnchors_);
|
||||||
BatchWriteAnchors<SaplingMerkleTree, CAnchorsSaplingMap, CAnchorsSaplingCacheEntry>(mapSaplingAnchors, mapSaplingAnchors_);
|
BatchWriteAnchors<SaplingMerkleTree, CAnchorsSaplingMap, CAnchorsSaplingCacheEntry>(mapSaplingAnchors, mapSaplingAnchors_);
|
||||||
BatchWriteAnchors<OrchardMerkleTree, CAnchorsOrchardMap, CAnchorsOrchardCacheEntry>(mapOrchardAnchors, mapOrchardAnchors_);
|
BatchWriteAnchors<OrchardMerkleFrontier, CAnchorsOrchardMap, CAnchorsOrchardCacheEntry>(mapOrchardAnchors, mapOrchardAnchors_);
|
||||||
|
|
||||||
BatchWriteNullifiers(mapSproutNullifiers, mapSproutNullifiers_);
|
BatchWriteNullifiers(mapSproutNullifiers, mapSproutNullifiers_);
|
||||||
BatchWriteNullifiers(mapSaplingNullifiers, mapSaplingNullifiers_);
|
BatchWriteNullifiers(mapSaplingNullifiers, mapSaplingNullifiers_);
|
||||||
|
|
|
@ -665,7 +665,7 @@
|
||||||
["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", ""],
|
["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", ""],
|
||||||
|
|
||||||
["While not really correctly DER encoded, the empty signature is allowed by"],
|
["While not really correctly DER encoded, the empty signature is allowed by"],
|
||||||
["STRICTENC to provide a compact way to provide a delibrately invalid signature."],
|
["STRICTENC to provide a compact way to provide a deliberately invalid signature."],
|
||||||
["0", "0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 CHECKSIG NOT", "STRICTENC"],
|
["0", "0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 CHECKSIG NOT", "STRICTENC"],
|
||||||
["0 0", "1 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 1 CHECKMULTISIG NOT", "STRICTENC"],
|
["0 0", "1 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 1 CHECKMULTISIG NOT", "STRICTENC"],
|
||||||
|
|
||||||
|
|
|
@ -158,7 +158,7 @@
|
||||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]],
|
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]],
|
||||||
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000fe64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
|
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000fe64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||||
|
|
||||||
["By-time locks, with argument just beyond tx nLockTime (but within numerical boundries)"],
|
["By-time locks, with argument just beyond tx nLockTime (but within numerical boundaries)"],
|
||||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000001 NOP2 1"]],
|
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000001 NOP2 1"]],
|
||||||
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
|
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]],
|
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]],
|
||||||
|
|
|
@ -102,7 +102,7 @@
|
||||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
|
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
|
||||||
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
|
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||||
|
|
||||||
["By-time locks, with argument just beyond tx nLockTime (but within numerical boundries)"],
|
["By-time locks, with argument just beyond tx nLockTime (but within numerical boundaries)"],
|
||||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]],
|
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]],
|
||||||
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
|
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]],
|
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]],
|
||||||
|
|
|
@ -47,7 +47,7 @@ BOOST_AUTO_TEST_CASE(limitedmap_test)
|
||||||
// make sure the item is present
|
// make sure the item is present
|
||||||
BOOST_CHECK(map.count(i) == 1);
|
BOOST_CHECK(map.count(i) == 1);
|
||||||
|
|
||||||
// use the iterator to check for the expected key adn value
|
// use the iterator to check for the expected key and value
|
||||||
BOOST_CHECK(it->first == i);
|
BOOST_CHECK(it->first == i);
|
||||||
BOOST_CHECK(it->second == i + 1);
|
BOOST_CHECK(it->second == i + 1);
|
||||||
|
|
||||||
|
|
|
@ -221,7 +221,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||||
equi eq(1);
|
equi eq(1);
|
||||||
eq.setstate(curr_state.state);
|
eq.setstate(curr_state.state);
|
||||||
|
|
||||||
// Intialization done, start algo driver.
|
// Initialization done, start algo driver.
|
||||||
eq.digit0(0);
|
eq.digit0(0);
|
||||||
eq.xfull = eq.bfull = eq.hfull = 0;
|
eq.xfull = eq.bfull = eq.hfull = 0;
|
||||||
eq.showbsizes(0);
|
eq.showbsizes(0);
|
||||||
|
|
|
@ -360,7 +360,7 @@ static std::map<std::string,std::string> ParseTorReplyMapping(const std::string
|
||||||
|
|
||||||
/** Read full contents of a file and return them in a std::string.
|
/** Read full contents of a file and return them in a std::string.
|
||||||
* Returns a pair <status, string>.
|
* Returns a pair <status, string>.
|
||||||
* If an error occured, status will be false, otherwise status will be true and the data will be returned in string.
|
* If an error occurred, status will be false, otherwise status will be true and the data will be returned in string.
|
||||||
*
|
*
|
||||||
* @param maxsize Puts a maximum size limit on the file that is read. If the file is larger than this, truncated data
|
* @param maxsize Puts a maximum size limit on the file that is read. If the file is larger than this, truncated data
|
||||||
* (with len > maxsize) will be returned.
|
* (with len > maxsize) will be returned.
|
||||||
|
|
10
src/txdb.cpp
10
src/txdb.cpp
|
@ -81,9 +81,9 @@ bool CCoinsViewDB::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree
|
||||||
return read;
|
return read;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCoinsViewDB::GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleTree &tree) const {
|
bool CCoinsViewDB::GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const {
|
||||||
if (rt == OrchardMerkleTree::empty_root()) {
|
if (rt == OrchardMerkleFrontier::empty_root()) {
|
||||||
OrchardMerkleTree new_tree;
|
OrchardMerkleFrontier new_tree;
|
||||||
tree = new_tree;
|
tree = new_tree;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -141,7 +141,7 @@ uint256 CCoinsViewDB::GetBestAnchor(ShieldedType type) const {
|
||||||
break;
|
break;
|
||||||
case ORCHARD:
|
case ORCHARD:
|
||||||
if (!db.Read(DB_BEST_ORCHARD_ANCHOR, hashBestAnchor))
|
if (!db.Read(DB_BEST_ORCHARD_ANCHOR, hashBestAnchor))
|
||||||
return OrchardMerkleTree::empty_root();
|
return OrchardMerkleFrontier::empty_root();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw runtime_error("Unknown shielded type");
|
throw runtime_error("Unknown shielded type");
|
||||||
|
@ -291,7 +291,7 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins,
|
||||||
|
|
||||||
::BatchWriteAnchors<CAnchorsSproutMap, CAnchorsSproutMap::iterator, CAnchorsSproutCacheEntry, SproutMerkleTree>(batch, mapSproutAnchors, DB_SPROUT_ANCHOR);
|
::BatchWriteAnchors<CAnchorsSproutMap, CAnchorsSproutMap::iterator, CAnchorsSproutCacheEntry, SproutMerkleTree>(batch, mapSproutAnchors, DB_SPROUT_ANCHOR);
|
||||||
::BatchWriteAnchors<CAnchorsSaplingMap, CAnchorsSaplingMap::iterator, CAnchorsSaplingCacheEntry, SaplingMerkleTree>(batch, mapSaplingAnchors, DB_SAPLING_ANCHOR);
|
::BatchWriteAnchors<CAnchorsSaplingMap, CAnchorsSaplingMap::iterator, CAnchorsSaplingCacheEntry, SaplingMerkleTree>(batch, mapSaplingAnchors, DB_SAPLING_ANCHOR);
|
||||||
::BatchWriteAnchors<CAnchorsOrchardMap, CAnchorsOrchardMap::iterator, CAnchorsOrchardCacheEntry, OrchardMerkleTree>(batch, mapOrchardAnchors, DB_ORCHARD_ANCHOR);
|
::BatchWriteAnchors<CAnchorsOrchardMap, CAnchorsOrchardMap::iterator, CAnchorsOrchardCacheEntry, OrchardMerkleFrontier>(batch, mapOrchardAnchors, DB_ORCHARD_ANCHOR);
|
||||||
|
|
||||||
::BatchWriteNullifiers(batch, mapSproutNullifiers, DB_NULLIFIER);
|
::BatchWriteNullifiers(batch, mapSproutNullifiers, DB_NULLIFIER);
|
||||||
::BatchWriteNullifiers(batch, mapSaplingNullifiers, DB_SAPLING_NULLIFIER);
|
::BatchWriteNullifiers(batch, mapSaplingNullifiers, DB_SAPLING_NULLIFIER);
|
||||||
|
|
|
@ -83,7 +83,7 @@ public:
|
||||||
|
|
||||||
bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const;
|
bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const;
|
||||||
bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
|
bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
|
||||||
bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleTree &tree) const;
|
bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const;
|
||||||
bool GetNullifier(const uint256 &nf, ShieldedType type) const;
|
bool GetNullifier(const uint256 &nf, ShieldedType type) const;
|
||||||
bool GetCoins(const uint256 &txid, CCoins &coins) const;
|
bool GetCoins(const uint256 &txid, CCoins &coins) const;
|
||||||
bool HaveCoins(const uint256 &txid) const;
|
bool HaveCoins(const uint256 &txid) const;
|
||||||
|
|
|
@ -1232,7 +1232,7 @@ TEST(WalletTests, CachedWitnessesEmptyChain) {
|
||||||
EXPECT_TRUE((bool) sproutWitnesses[1]);
|
EXPECT_TRUE((bool) sproutWitnesses[1]);
|
||||||
EXPECT_TRUE((bool) saplingWitnesses[0]);
|
EXPECT_TRUE((bool) saplingWitnesses[0]);
|
||||||
|
|
||||||
// Until #1302 is implemented, this should triggger an assertion
|
// Until #1302 is implemented, this should trigger an assertion
|
||||||
EXPECT_DEATH(wallet.DecrementNoteWitnesses(&index),
|
EXPECT_DEATH(wallet.DecrementNoteWitnesses(&index),
|
||||||
".*nWitnessCacheSize > 0.*");
|
".*nWitnessCacheSize > 0.*");
|
||||||
}
|
}
|
||||||
|
|
|
@ -2271,7 +2271,7 @@ UniValue z_listunspent(const UniValue& params, bool fHelp)
|
||||||
" \"spendable\" : true|false, (boolean) true if note can be spent by wallet, false if address is watchonly\n"
|
" \"spendable\" : true|false, (boolean) true if note can be spent by wallet, false if address is watchonly\n"
|
||||||
" \"address\" : \"address\", (string) the shielded address\n"
|
" \"address\" : \"address\", (string) the shielded address\n"
|
||||||
" \"amount\": xxxxx, (numeric) the amount of value in the note\n"
|
" \"amount\": xxxxx, (numeric) the amount of value in the note\n"
|
||||||
" \"memo\": xxxxx, (string) hexademical string representation of memo field\n"
|
" \"memo\": xxxxx, (string) hexadecimal string representation of memo field\n"
|
||||||
" \"change\": true|false, (boolean) true if the address that received the note is also one of the sending addresses\n"
|
" \"change\": true|false, (boolean) true if the address that received the note is also one of the sending addresses\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
" ,...\n"
|
" ,...\n"
|
||||||
|
@ -3424,7 +3424,7 @@ UniValue z_viewtransaction(const UniValue& params, bool fHelp)
|
||||||
" \"outgoing\" : true|false (boolean, sapling) True if the output is not for an address in the wallet\n"
|
" \"outgoing\" : true|false (boolean, sapling) True if the output is not for an address in the wallet\n"
|
||||||
" \"value\" : x.xxx (numeric) The amount in " + CURRENCY_UNIT + "\n"
|
" \"value\" : x.xxx (numeric) The amount in " + CURRENCY_UNIT + "\n"
|
||||||
" \"valueZat\" : xxxx (numeric) The amount in zatoshis\n"
|
" \"valueZat\" : xxxx (numeric) The amount in zatoshis\n"
|
||||||
" \"memo\" : \"hexmemo\", (string) Hexademical string representation of the memo field\n"
|
" \"memo\" : \"hexmemo\", (string) hexadecimal string representation of the memo field\n"
|
||||||
" \"memoStr\" : \"memo\", (string) Only returned if memo contains valid UTF-8 text.\n"
|
" \"memoStr\" : \"memo\", (string) Only returned if memo contains valid UTF-8 text.\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
" ,...\n"
|
" ,...\n"
|
||||||
|
|
|
@ -886,7 +886,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test Aysnc RPC queue and operations.
|
* Test Async RPC queue and operations.
|
||||||
*/
|
*/
|
||||||
BOOST_AUTO_TEST_CASE(rpc_wallet_async_operations)
|
BOOST_AUTO_TEST_CASE(rpc_wallet_async_operations)
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include "zcash/util.h"
|
#include "zcash/util.h"
|
||||||
|
|
||||||
#include <primitives/orchard.h>
|
#include <primitives/orchard.h>
|
||||||
#include <rust/orchard/incremental_sinsemilla_tree.h>
|
#include <rust/orchard/incremental_merkle_tree.h>
|
||||||
|
|
||||||
namespace libzcash {
|
namespace libzcash {
|
||||||
|
|
||||||
|
@ -259,28 +259,28 @@ typedef libzcash::IncrementalMerkleTree<INCREMENTAL_MERKLE_TREE_DEPTH_TESTING, l
|
||||||
typedef libzcash::IncrementalWitness<SAPLING_INCREMENTAL_MERKLE_TREE_DEPTH, libzcash::PedersenHash> SaplingWitness;
|
typedef libzcash::IncrementalWitness<SAPLING_INCREMENTAL_MERKLE_TREE_DEPTH, libzcash::PedersenHash> SaplingWitness;
|
||||||
typedef libzcash::IncrementalWitness<INCREMENTAL_MERKLE_TREE_DEPTH_TESTING, libzcash::PedersenHash> SaplingTestingWitness;
|
typedef libzcash::IncrementalWitness<INCREMENTAL_MERKLE_TREE_DEPTH_TESTING, libzcash::PedersenHash> SaplingTestingWitness;
|
||||||
|
|
||||||
class OrchardMerkleTree
|
class OrchardMerkleFrontier
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/// An incremental Sinsemilla tree; this pointer may never be null.
|
/// An incremental Sinsemilla tree; this pointer may never be null.
|
||||||
/// Memory is allocated by Rust.
|
/// Memory is allocated by Rust.
|
||||||
std::unique_ptr<OrchardMerkleFrontierPtr, decltype(&orchard_merkle_frontier_free)> inner;
|
std::unique_ptr<OrchardMerkleFrontierPtr, decltype(&orchard_merkle_frontier_free)> inner;
|
||||||
public:
|
public:
|
||||||
OrchardMerkleTree() : inner(orchard_merkle_frontier_empty(), orchard_merkle_frontier_free) {}
|
OrchardMerkleFrontier() : inner(orchard_merkle_frontier_empty(), orchard_merkle_frontier_free) {}
|
||||||
|
|
||||||
OrchardMerkleTree(OrchardMerkleTree&& frontier) : inner(std::move(frontier.inner)) {}
|
OrchardMerkleFrontier(OrchardMerkleFrontier&& frontier) : inner(std::move(frontier.inner)) {}
|
||||||
|
|
||||||
OrchardMerkleTree(const OrchardMerkleTree& frontier) :
|
OrchardMerkleFrontier(const OrchardMerkleFrontier& frontier) :
|
||||||
inner(orchard_merkle_frontier_clone(frontier.inner.get()), orchard_merkle_frontier_free) {}
|
inner(orchard_merkle_frontier_clone(frontier.inner.get()), orchard_merkle_frontier_free) {}
|
||||||
|
|
||||||
OrchardMerkleTree& operator=(OrchardMerkleTree&& frontier)
|
OrchardMerkleFrontier& operator=(OrchardMerkleFrontier&& frontier)
|
||||||
{
|
{
|
||||||
if (this != &frontier) {
|
if (this != &frontier) {
|
||||||
inner = std::move(frontier.inner);
|
inner = std::move(frontier.inner);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
OrchardMerkleTree& operator=(const OrchardMerkleTree& frontier)
|
OrchardMerkleFrontier& operator=(const OrchardMerkleFrontier& frontier)
|
||||||
{
|
{
|
||||||
if (this != &frontier) {
|
if (this != &frontier) {
|
||||||
inner.reset(orchard_merkle_frontier_clone(frontier.inner.get()));
|
inner.reset(orchard_merkle_frontier_clone(frontier.inner.get()));
|
||||||
|
@ -323,7 +323,7 @@ public:
|
||||||
|
|
||||||
static uint256 empty_root() {
|
static uint256 empty_root() {
|
||||||
uint256 value;
|
uint256 value;
|
||||||
incremental_sinsemilla_tree_empty_root(value.begin());
|
orchard_merkle_tree_empty_root(value.begin());
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -447,7 +447,7 @@ class FakeCoinsViewDB : public CCoinsView {
|
||||||
uint256 hash;
|
uint256 hash;
|
||||||
SproutMerkleTree sproutTree;
|
SproutMerkleTree sproutTree;
|
||||||
SaplingMerkleTree saplingTree;
|
SaplingMerkleTree saplingTree;
|
||||||
OrchardMerkleTree orchardTree;
|
OrchardMerkleFrontier orchardTree;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FakeCoinsViewDB(std::string dbName, uint256& hash) : db(GetDataDir() / dbName, 100, false, false), hash(hash) {}
|
FakeCoinsViewDB(std::string dbName, uint256& hash) : db(GetDataDir() / dbName, 100, false, false), hash(hash) {}
|
||||||
|
@ -468,7 +468,7 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleTree &tree) const {
|
bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const {
|
||||||
if (rt == orchardTree.root()) {
|
if (rt == orchardTree.root()) {
|
||||||
tree = orchardTree;
|
tree = orchardTree;
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue