Merge remote-tracking branch 'upstream/master' into zip-207
This commit is contained in:
commit
436dee90de
|
@ -1,5 +1,10 @@
|
|||
[source.crates-io]
|
||||
replace-with = "vendored-sources"
|
||||
|
||||
[source."https://github.com/ebfull/ed25519-zebra"]
|
||||
git = "https://github.com/ebfull/ed25519-zebra"
|
||||
rev = "8c97acde89b6446f7f2505069fc7b9ac3a541417"
|
||||
replace-with = "vendored-sources"
|
||||
|
||||
[source.vendored-sources]
|
||||
# The directory for this source is set to RUST_VENDORED_SOURCES by src/Makefile.am
|
||||
|
|
|
@ -261,6 +261,19 @@ dependencies = [
|
|||
"crypto_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "curve25519-dalek"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d85653f070353a16313d0046f173f70d1aadd5b42600a14de626f0dfb3473a5"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"digest",
|
||||
"rand_core",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.8.1"
|
||||
|
@ -280,6 +293,19 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ed25519-zebra"
|
||||
version = "0.4.1"
|
||||
source = "git+https://github.com/ebfull/ed25519-zebra?rev=8c97acde89b6446f7f2505069fc7b9ac3a541417#8c97acde89b6446f7f2505069fc7b9ac3a541417"
|
||||
dependencies = [
|
||||
"curve25519-dalek",
|
||||
"hex 0.4.2",
|
||||
"rand_core",
|
||||
"serde",
|
||||
"sha2",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fake-simd"
|
||||
version = "0.1.2"
|
||||
|
@ -377,6 +403,12 @@ version = "0.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
|
@ -396,6 +428,7 @@ dependencies = [
|
|||
"bellman",
|
||||
"blake2b_simd",
|
||||
"blake2s_simd",
|
||||
"ed25519-zebra",
|
||||
"ff",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
|
@ -591,6 +624,26 @@ version = "0.7.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.113"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6135c78461981c79497158ef777264c51d9d0f4f3fc3a4d22b915900e42dac6a"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.113"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93c5eaa17d0954cb481cdcfffe9d84fcfa7a1a9f2349271e678677be4c26ae31"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.8.0"
|
||||
|
@ -604,16 +657,42 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.5"
|
||||
name = "subtle"
|
||||
version = "2.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
|
||||
checksum = "502d53007c02d7605a05df1c1a73ee436952781653da5d0bf57ad608f66932c1"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.11.2"
|
||||
|
@ -678,7 +757,7 @@ dependencies = [
|
|||
"crypto_api_chachapoly",
|
||||
"ff",
|
||||
"fpe",
|
||||
"hex",
|
||||
"hex 0.3.2",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"pairing",
|
||||
|
@ -702,3 +781,9 @@ dependencies = [
|
|||
"rand_core",
|
||||
"zcash_primitives",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8"
|
||||
|
|
|
@ -31,6 +31,7 @@ rand_core = "0.5.1"
|
|||
zcash_history = "0.2"
|
||||
zcash_primitives = "0.2"
|
||||
zcash_proofs = "0.2"
|
||||
ed25519-zebra = { git = "https://github.com/ebfull/ed25519-zebra", rev = "8c97acde89b6446f7f2505069fc7b9ac3a541417" }
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package=crate_curve25519_dalek
|
||||
$(package)_crate_name=curve25519-dalek
|
||||
$(package)_version=2.1.0
|
||||
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
|
||||
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
|
||||
$(package)_sha256_hash=5d85653f070353a16313d0046f173f70d1aadd5b42600a14de626f0dfb3473a5
|
||||
$(package)_crate_versioned_name=$($(package)_crate_name)
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
$(call generate_crate_checksum,$(package))
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
$(call vendor_crate_source,$(package))
|
||||
endef
|
|
@ -0,0 +1,16 @@
|
|||
package=crate_ed25519_zebra
|
||||
$(package)_crate_name=ed25519-zebra
|
||||
$(package)_download_path=https://github.com/ebfull/$($(package)_crate_name)/archive/
|
||||
$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz
|
||||
$(package)_download_file=$($(package)_git_commit).tar.gz
|
||||
$(package)_sha256_hash=e0b432e0161abe9cb27cf96dd42c1486d32297e2fdbf725b70e7ae1f5b53d052
|
||||
$(package)_git_commit=8c97acde89b6446f7f2505069fc7b9ac3a541417
|
||||
$(package)_crate_versioned_name=$($(package)_crate_name)
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
$(call generate_unpackaged_crate_checksum,$(package))
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
$(call vendor_crate_source,$(package))
|
||||
endef
|
|
@ -4,7 +4,7 @@ $(package)_version=0.3.2
|
|||
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
|
||||
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
|
||||
$(package)_sha256_hash=805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77
|
||||
$(package)_crate_versioned_name=$($(package)_crate_name)
|
||||
$(package)_crate_versioned_name="$($(package)_crate_name) 0.3.2"
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
$(call generate_crate_checksum,$(package))
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package=crate_hex2
|
||||
$(package)_crate_name=hex
|
||||
$(package)_version=0.4.2
|
||||
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
|
||||
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
|
||||
$(package)_sha256_hash=644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35
|
||||
$(package)_crate_versioned_name="$($(package)_crate_name) 0.4.2"
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
$(call generate_crate_checksum,$(package))
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
$(call vendor_crate_source,$(package))
|
||||
endef
|
|
@ -0,0 +1,15 @@
|
|||
package=crate_serde
|
||||
$(package)_crate_name=serde
|
||||
$(package)_version=1.0.113
|
||||
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
|
||||
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
|
||||
$(package)_sha256_hash=6135c78461981c79497158ef777264c51d9d0f4f3fc3a4d22b915900e42dac6a
|
||||
$(package)_crate_versioned_name=$($(package)_crate_name)
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
$(call generate_crate_checksum,$(package))
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
$(call vendor_crate_source,$(package))
|
||||
endef
|
|
@ -0,0 +1,15 @@
|
|||
package=crate_serde_derive
|
||||
$(package)_crate_name=serde_derive
|
||||
$(package)_version=1.0.113
|
||||
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
|
||||
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
|
||||
$(package)_sha256_hash=93c5eaa17d0954cb481cdcfffe9d84fcfa7a1a9f2349271e678677be4c26ae31
|
||||
$(package)_crate_versioned_name=$($(package)_crate_name)
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
$(call generate_crate_checksum,$(package))
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
$(call vendor_crate_source,$(package))
|
||||
endef
|
|
@ -0,0 +1,15 @@
|
|||
package=crate_subtle
|
||||
$(package)_crate_name=subtle
|
||||
$(package)_version=2.2.3
|
||||
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
|
||||
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
|
||||
$(package)_sha256_hash=502d53007c02d7605a05df1c1a73ee436952781653da5d0bf57ad608f66932c1
|
||||
$(package)_crate_versioned_name=$($(package)_crate_name)
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
$(call generate_crate_checksum,$(package))
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
$(call vendor_crate_source,$(package))
|
||||
endef
|
|
@ -1,9 +1,9 @@
|
|||
package=crate_syn
|
||||
$(package)_crate_name=syn
|
||||
$(package)_version=1.0.5
|
||||
$(package)_version=1.0.11
|
||||
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
|
||||
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
|
||||
$(package)_sha256_hash=66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf
|
||||
$(package)_sha256_hash=dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238
|
||||
$(package)_crate_versioned_name=$($(package)_crate_name)
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package=crate_thiserror
|
||||
$(package)_crate_name=thiserror
|
||||
$(package)_version=1.0.20
|
||||
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
|
||||
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
|
||||
$(package)_sha256_hash=7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08
|
||||
$(package)_crate_versioned_name=$($(package)_crate_name)
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
$(call generate_crate_checksum,$(package))
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
$(call vendor_crate_source,$(package))
|
||||
endef
|
|
@ -0,0 +1,15 @@
|
|||
package=crate_thiserror_impl
|
||||
$(package)_crate_name=thiserror-impl
|
||||
$(package)_version=1.0.20
|
||||
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
|
||||
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
|
||||
$(package)_sha256_hash=bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793
|
||||
$(package)_crate_versioned_name=$($(package)_crate_name)
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
$(call generate_crate_checksum,$(package))
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
$(call vendor_crate_source,$(package))
|
||||
endef
|
|
@ -0,0 +1,15 @@
|
|||
package=crate_zeroize
|
||||
$(package)_crate_name=zeroize
|
||||
$(package)_version=1.1.0
|
||||
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
|
||||
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
|
||||
$(package)_sha256_hash=3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8
|
||||
$(package)_crate_versioned_name=$($(package)_crate_name)
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
$(call generate_crate_checksum,$(package))
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
$(call vendor_crate_source,$(package))
|
||||
endef
|
|
@ -27,8 +27,10 @@ rust_crates := \
|
|||
crate_crunchy \
|
||||
crate_crypto_api_chachapoly \
|
||||
crate_crypto_api \
|
||||
crate_curve25519_dalek \
|
||||
crate_digest \
|
||||
crate_directories \
|
||||
crate_ed25519_zebra \
|
||||
crate_fake_simd \
|
||||
crate_ff_derive \
|
||||
crate_ff \
|
||||
|
@ -39,6 +41,7 @@ rust_crates := \
|
|||
crate_getrandom \
|
||||
crate_group \
|
||||
crate_hex \
|
||||
crate_hex2 \
|
||||
crate_lazy_static \
|
||||
crate_libc \
|
||||
crate_log \
|
||||
|
@ -62,8 +65,13 @@ rust_crates := \
|
|||
crate_scopeguard \
|
||||
crate_semver_parser \
|
||||
crate_semver \
|
||||
crate_serde \
|
||||
crate_serde_derive \
|
||||
crate_sha2 \
|
||||
crate_subtle \
|
||||
crate_syn \
|
||||
crate_thiserror \
|
||||
crate_thiserror_impl \
|
||||
crate_typenum \
|
||||
crate_unicode_xid \
|
||||
crate_wasi \
|
||||
|
@ -72,7 +80,8 @@ rust_crates := \
|
|||
crate_winapi_x86_64_pc_windows_gnu \
|
||||
crate_zcash_history \
|
||||
crate_zcash_primitives \
|
||||
crate_zcash_proofs
|
||||
crate_zcash_proofs \
|
||||
crate_zeroize
|
||||
rust_packages := rust $(rust_crates)
|
||||
proton_packages := proton
|
||||
zcash_packages := libsodium utfcpp
|
||||
|
|
|
@ -89,6 +89,7 @@ testScripts=(
|
|||
'upgrade_golden.py'
|
||||
'post_heartwood_rollback.py'
|
||||
'feature_logging.py'
|
||||
'remove_sprout_shielding.py'
|
||||
);
|
||||
testScriptsExt=(
|
||||
'getblocktemplate_longpoll.py'
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2020 The Zcash developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
||||
|
||||
from decimal import Decimal
|
||||
from test_framework.authproxy import JSONRPCException
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
initialize_chain,
|
||||
start_nodes, get_coinbase_address,
|
||||
wait_and_assert_operationid_status,
|
||||
nuparams, BLOSSOM_BRANCH_ID, HEARTWOOD_BRANCH_ID, CANOPY_BRANCH_ID
|
||||
)
|
||||
|
||||
import logging
|
||||
|
||||
HAS_CANOPY = ['-nurejectoldversions=false',
|
||||
nuparams(BLOSSOM_BRANCH_ID, 205),
|
||||
nuparams(HEARTWOOD_BRANCH_ID, 210),
|
||||
nuparams(CANOPY_BRANCH_ID, 220),
|
||||
]
|
||||
class RemoveSproutShieldingTest (BitcoinTestFramework):
|
||||
|
||||
def setup_chain(self):
|
||||
print("Initializing test directory "+self.options.tmpdir)
|
||||
initialize_chain(self.options.tmpdir)
|
||||
|
||||
def setup_nodes(self):
|
||||
return start_nodes(4, self.options.tmpdir, extra_args=[HAS_CANOPY]*4)
|
||||
|
||||
def run_test (self):
|
||||
|
||||
# Generate blocks up to Heartwood activation
|
||||
logging.info("Generating initial blocks. Current height is 200, advance to 210 (activate Heartwood but not Canopy)")
|
||||
self.nodes[0].generate(10)
|
||||
self.sync_all()
|
||||
|
||||
# Shield coinbase to Sprout on node 0. Should pass
|
||||
sprout_addr = self.nodes[0].z_getnewaddress('sprout')
|
||||
myopid = self.nodes[0].z_shieldcoinbase(get_coinbase_address(self.nodes[0]), sprout_addr, 0)['opid']
|
||||
wait_and_assert_operationid_status(self.nodes[0], myopid)
|
||||
print("taddr -> Sprout z_shieldcoinbase tx accepted before Canopy on node 0")
|
||||
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
assert_equal(self.nodes[0].z_getbalance(sprout_addr), Decimal('10'))
|
||||
|
||||
# Fund taddr_0 from shielded coinbase on node 0
|
||||
taddr_0 = self.nodes[0].getnewaddress()
|
||||
for _ in range(3):
|
||||
recipients = [{"address": taddr_0, "amount": Decimal('1')}]
|
||||
myopid = self.nodes[0].z_sendmany(sprout_addr, recipients, 1, 0)
|
||||
wait_and_assert_operationid_status(self.nodes[0], myopid)
|
||||
self.sync_all()
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
# Create taddr -> Sprout transaction and mine on node 0 before it is Canopy-aware. Should pass
|
||||
sendmany_tx_0 = self.nodes[0].z_sendmany(taddr_0, [{"address": self.nodes[1].z_getnewaddress('sprout'), "amount": 1}])
|
||||
wait_and_assert_operationid_status(self.nodes[0], sendmany_tx_0)
|
||||
print("taddr -> Sprout z_sendmany tx accepted before Canopy on node 0")
|
||||
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
# Create mergetoaddress taddr -> Sprout transaction and mine on node 0 before it is Canopy-aware. Should pass
|
||||
merge_tx_0 = self.nodes[0].z_mergetoaddress(["ANY_TADDR"], self.nodes[1].z_getnewaddress('sprout'))
|
||||
wait_and_assert_operationid_status(self.nodes[0], merge_tx_0['opid'])
|
||||
print("taddr -> Sprout z_mergetoaddress tx accepted before Canopy on node 0")
|
||||
|
||||
# Mine to one block before Canopy activation on node 0; adding value
|
||||
# to the Sprout pool will fail now since the transaction must be
|
||||
# included in the next (or later) block, after Canopy has activated.
|
||||
self.nodes[0].generate(4)
|
||||
self.sync_all()
|
||||
|
||||
# Shield coinbase to Sprout on node 0. Should fail
|
||||
errorString = ''
|
||||
try:
|
||||
sprout_addr = self.nodes[0].z_getnewaddress('sprout')
|
||||
self.nodes[0].z_shieldcoinbase(get_coinbase_address(self.nodes[0]), sprout_addr, 0)
|
||||
except JSONRPCException as e:
|
||||
errorString = e.error['message']
|
||||
assert("Sprout shielding is not supported after Canopy" in errorString)
|
||||
print("taddr -> Sprout z_shieldcoinbase tx rejected at Canopy activation on node 0")
|
||||
|
||||
# Create taddr -> Sprout z_sendmany transaction on node 0. Should fail
|
||||
errorString = ''
|
||||
try:
|
||||
sprout_addr = self.nodes[1].z_getnewaddress('sprout')
|
||||
self.nodes[0].z_sendmany(taddr_0, [{"address": sprout_addr, "amount": 1}])
|
||||
except JSONRPCException as e:
|
||||
errorString = e.error['message']
|
||||
assert("Sprout shielding is not supported after Canopy" in errorString)
|
||||
print("taddr -> Sprout z_sendmany tx rejected at Canopy activation on node 0")
|
||||
|
||||
# Create z_mergetoaddress [taddr, Sprout] -> Sprout transaction on node 0. Should fail
|
||||
errorString = ''
|
||||
try:
|
||||
self.nodes[0].z_mergetoaddress(["ANY_TADDR", "ANY_SPROUT"], self.nodes[1].z_getnewaddress('sprout'))
|
||||
except JSONRPCException as e:
|
||||
errorString = e.error['message']
|
||||
assert("Sprout shielding is not supported after Canopy" in errorString)
|
||||
print("[taddr, Sprout] -> Sprout z_mergetoaddress tx rejected at Canopy activation on node 0")
|
||||
|
||||
# Create z_mergetoaddress Sprout -> Sprout transaction on node 0. Should pass
|
||||
merge_tx_1 = self.nodes[0].z_mergetoaddress(["ANY_SPROUT"], self.nodes[1].z_getnewaddress('sprout'))
|
||||
wait_and_assert_operationid_status(self.nodes[0], merge_tx_1['opid'])
|
||||
print("Sprout -> Sprout z_mergetoaddress tx accepted at Canopy activation on node 0")
|
||||
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
# Shield coinbase to Sapling on node 0. Should pass
|
||||
sapling_addr = self.nodes[0].z_getnewaddress('sapling')
|
||||
myopid = self.nodes[0].z_shieldcoinbase(get_coinbase_address(self.nodes[0]), sapling_addr, 0)['opid']
|
||||
wait_and_assert_operationid_status(self.nodes[0], myopid)
|
||||
print("taddr -> Sapling z_shieldcoinbase tx accepted after Canopy on node 0")
|
||||
|
||||
if __name__ == '__main__':
|
||||
RemoveSproutShieldingTest().main()
|
|
@ -1097,7 +1097,7 @@ TEST(ChecktransactionTests, BadTxReceivedOverNetwork)
|
|||
}
|
||||
}
|
||||
|
||||
TEST(CheckTransaction, InvalidShieldedCoinbase) {
|
||||
TEST(ChecktransactionTests, InvalidShieldedCoinbase) {
|
||||
RegtestActivateSapling();
|
||||
|
||||
CMutableTransaction mtx = GetValidTransaction();
|
||||
|
@ -1128,7 +1128,7 @@ TEST(CheckTransaction, InvalidShieldedCoinbase) {
|
|||
RegtestDeactivateHeartwood();
|
||||
}
|
||||
|
||||
TEST(CheckTransaction, HeartwoodAcceptsShieldedCoinbase) {
|
||||
TEST(ChecktransactionTests, HeartwoodAcceptsShieldedCoinbase) {
|
||||
RegtestActivateHeartwood(false, Consensus::NetworkUpgrade::ALWAYS_ACTIVE);
|
||||
auto chainparams = Params();
|
||||
|
||||
|
@ -1211,7 +1211,7 @@ TEST(CheckTransaction, HeartwoodAcceptsShieldedCoinbase) {
|
|||
// Check that the consensus rules relevant to valueBalance, vShieldedOutput, and
|
||||
// bindingSig from https://zips.z.cash/protocol/protocol.pdf#txnencoding are
|
||||
// applied to coinbase transactions.
|
||||
TEST(CheckTransaction, HeartwoodEnforcesSaplingRulesOnShieldedCoinbase) {
|
||||
TEST(ChecktransactionTests, HeartwoodEnforcesSaplingRulesOnShieldedCoinbase) {
|
||||
RegtestActivateHeartwood(false, Consensus::NetworkUpgrade::ALWAYS_ACTIVE);
|
||||
auto chainparams = Params();
|
||||
|
||||
|
@ -1284,3 +1284,60 @@ TEST(CheckTransaction, HeartwoodEnforcesSaplingRulesOnShieldedCoinbase) {
|
|||
|
||||
RegtestDeactivateHeartwood();
|
||||
}
|
||||
|
||||
|
||||
TEST(ChecktransactionTests, CanopyRejectsNonzeroVPubOld) {
|
||||
|
||||
RegtestActivateSapling();
|
||||
|
||||
CMutableTransaction mtx = GetValidTransaction(NetworkUpgradeInfo[Consensus::UPGRADE_SAPLING].nBranchId);
|
||||
|
||||
// Make a JoinSplit with nonzero vpub_old
|
||||
mtx.vJoinSplit.resize(1);
|
||||
mtx.vJoinSplit[0].vpub_old = 1;
|
||||
mtx.vJoinSplit[0].vpub_new = 0;
|
||||
mtx.vJoinSplit[0].proof = libzcash::GrothProof();
|
||||
CreateJoinSplitSignature(mtx, NetworkUpgradeInfo[Consensus::UPGRADE_SAPLING].nBranchId);
|
||||
|
||||
CTransaction tx(mtx);
|
||||
|
||||
// Before Canopy, nonzero vpub_old is accepted in both non-contextual and contextual checks
|
||||
MockCValidationState state;
|
||||
EXPECT_TRUE(CheckTransactionWithoutProofVerification(tx, state));
|
||||
EXPECT_TRUE(ContextualCheckTransaction(tx, state, Params(), 1, true));
|
||||
|
||||
RegtestActivateCanopy(false, Consensus::NetworkUpgrade::ALWAYS_ACTIVE);
|
||||
|
||||
// After Canopy, nonzero vpub_old is accepted in non-contextual checks but rejected in contextual checks
|
||||
EXPECT_TRUE(CheckTransactionWithoutProofVerification(tx, state));
|
||||
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-vpub_old-nonzero", false)).Times(1);
|
||||
EXPECT_FALSE(ContextualCheckTransaction(tx, state, Params(), 10, true));
|
||||
|
||||
RegtestDeactivateCanopy();
|
||||
|
||||
}
|
||||
|
||||
TEST(ChecktransactionTests, CanopyAcceptsZeroVPubOld) {
|
||||
|
||||
CMutableTransaction mtx = GetValidTransaction(NetworkUpgradeInfo[Consensus::UPGRADE_SAPLING].nBranchId);
|
||||
|
||||
// Make a JoinSplit with zero vpub_old
|
||||
mtx.vJoinSplit.resize(1);
|
||||
mtx.vJoinSplit[0].vpub_old = 0;
|
||||
mtx.vJoinSplit[0].vpub_new = 1;
|
||||
mtx.vJoinSplit[0].proof = libzcash::GrothProof();
|
||||
CreateJoinSplitSignature(mtx, NetworkUpgradeInfo[Consensus::UPGRADE_CANOPY].nBranchId);
|
||||
|
||||
CTransaction tx(mtx);
|
||||
|
||||
// After Canopy, zero value vpub_old (i.e. unshielding) is accepted in both non-contextual and contextual checks
|
||||
MockCValidationState state;
|
||||
|
||||
RegtestActivateCanopy(false, Consensus::NetworkUpgrade::ALWAYS_ACTIVE);
|
||||
|
||||
EXPECT_TRUE(CheckTransactionWithoutProofVerification(tx, state));
|
||||
EXPECT_TRUE(ContextualCheckTransaction(tx, state, Params(), 10, true));
|
||||
|
||||
RegtestDeactivateCanopy();
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
39
src/main.cpp
39
src/main.cpp
|
@ -988,6 +988,15 @@ bool ContextualCheckTransaction(
|
|||
}
|
||||
}
|
||||
|
||||
// Rules that apply to Canopy or later:
|
||||
if (canopyActive) {
|
||||
for (const JSDescription& joinsplit : tx.vJoinSplit) {
|
||||
if (joinsplit.vpub_old > 0) {
|
||||
return state.DoS(DOS_LEVEL_BLOCK, error("ContextualCheckTransaction(): joinsplit.vpub_old nonzero"), REJECT_INVALID, "bad-txns-vpub_old-nonzero");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto consensusBranchId = CurrentEpochBranchId(nHeight, chainparams.GetConsensus());
|
||||
auto prevConsensusBranchId = PrevEpochBranchId(consensusBranchId, chainparams.GetConsensus());
|
||||
uint256 dataToBeSigned;
|
||||
|
@ -1010,25 +1019,39 @@ bool ContextualCheckTransaction(
|
|||
}
|
||||
}
|
||||
|
||||
int (*ed25519_verifier)(
|
||||
const unsigned char *,
|
||||
const unsigned char *,
|
||||
unsigned long long ,
|
||||
const unsigned char *
|
||||
) = &crypto_sign_verify_detached;
|
||||
|
||||
// Switch from using the libsodium ed25519 verifier to using the
|
||||
// ed25519-zebra Rust crate, which implements an ed25519 verifier that is
|
||||
// compliant with ZIP 215.
|
||||
if (canopyActive) {
|
||||
ed25519_verifier = &librustzcash_zebra_crypto_sign_verify_detached;
|
||||
}
|
||||
|
||||
if (!tx.vJoinSplit.empty())
|
||||
{
|
||||
BOOST_STATIC_ASSERT(crypto_sign_PUBLICKEYBYTES == 32);
|
||||
|
||||
// We rely on libsodium to check that the signature is canonical.
|
||||
// https://github.com/jedisct1/libsodium/commit/62911edb7ff2275cccd74bf1c8aefcc4d76924e0
|
||||
if (crypto_sign_verify_detached(&tx.joinSplitSig[0],
|
||||
dataToBeSigned.begin(), 32,
|
||||
tx.joinSplitPubKey.begin()
|
||||
) != 0) {
|
||||
if (ed25519_verifier(&tx.joinSplitSig[0],
|
||||
dataToBeSigned.begin(), 32,
|
||||
tx.joinSplitPubKey.begin()
|
||||
) != 0) {
|
||||
// Check whether the failure was caused by an outdated consensus
|
||||
// branch ID; if so, inform the node that they need to upgrade. We
|
||||
// only check the previous epoch's branch ID, on the assumption that
|
||||
// users creating transactions will notice their transactions
|
||||
// failing before a second network upgrade occurs.
|
||||
if (crypto_sign_verify_detached(&tx.joinSplitSig[0],
|
||||
prevDataToBeSigned.begin(), 32,
|
||||
tx.joinSplitPubKey.begin()
|
||||
) == 0) {
|
||||
if (ed25519_verifier(&tx.joinSplitSig[0],
|
||||
prevDataToBeSigned.begin(), 32,
|
||||
tx.joinSplitPubKey.begin()
|
||||
) == 0) {
|
||||
return state.DoS(
|
||||
dosLevelPotentiallyRelaxing, false, REJECT_INVALID, strprintf(
|
||||
"old-consensus-branch-id (Expected %s, found %s)",
|
||||
|
|
|
@ -351,6 +351,13 @@ extern "C" {
|
|||
const unsigned char *n_ptr,
|
||||
unsigned char *h_ret
|
||||
);
|
||||
|
||||
int librustzcash_zebra_crypto_sign_verify_detached(
|
||||
const unsigned char *sig,
|
||||
const unsigned char *m,
|
||||
unsigned long long mlen,
|
||||
const unsigned char *pk
|
||||
);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1340,3 +1340,43 @@ pub extern "system" fn librustzcash_mmr_hash_node(
|
|||
|
||||
0
|
||||
}
|
||||
|
||||
// The `librustzcash_zebra_crypto_sign_verify_detached` API attempts to
|
||||
// mimic the `crypto_sign_verify_detached` API in libsodium, but uses
|
||||
// the ed25519-zebra crate internally instead.
|
||||
const LIBSODIUM_OK: isize = 0;
|
||||
const LIBSODIUM_ERROR: isize = -1;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn librustzcash_zebra_crypto_sign_verify_detached(
|
||||
sig: *const [u8; 64],
|
||||
m: *const u8,
|
||||
mlen: u64,
|
||||
pk: *const [u8; 32],
|
||||
) -> isize {
|
||||
use ed25519_zebra::{Signature, VerificationKey};
|
||||
use std::convert::TryFrom;
|
||||
|
||||
let sig = Signature::from(*unsafe {
|
||||
match sig.as_ref() {
|
||||
Some(sig) => sig,
|
||||
None => return LIBSODIUM_ERROR,
|
||||
}
|
||||
});
|
||||
|
||||
let pk = match VerificationKey::try_from(*match unsafe { pk.as_ref() } {
|
||||
Some(pk) => pk,
|
||||
None => return LIBSODIUM_ERROR,
|
||||
}) {
|
||||
Ok(pk) => pk,
|
||||
Err(_) => return LIBSODIUM_ERROR,
|
||||
};
|
||||
|
||||
let m = unsafe { slice::from_raw_parts(m, mlen as usize) };
|
||||
|
||||
if pk.verify(&sig, m).is_err() {
|
||||
LIBSODIUM_ERROR
|
||||
} else {
|
||||
LIBSODIUM_OK
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3017,7 +3017,14 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp)
|
|||
CAmount vpub_old(0);
|
||||
CAmount vpub_new(0);
|
||||
|
||||
int nextBlockHeight = chainActive.Height() + 1;
|
||||
|
||||
const bool canopyActive = Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_CANOPY);
|
||||
|
||||
if (params[3].get_real() != 0.0)
|
||||
if (canopyActive) {
|
||||
throw JSONRPCError(RPC_VERIFY_REJECTED, "Sprout shielding is not supported after Canopy");
|
||||
}
|
||||
vpub_old = AmountFromValue(params[3]);
|
||||
|
||||
if (params[4].get_real() != 0.0)
|
||||
|
@ -4063,6 +4070,15 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
|
|||
RPC_INVALID_PARAMETER,
|
||||
"Cannot send between Sprout and Sapling addresses using z_sendmany");
|
||||
}
|
||||
|
||||
int nextBlockHeight = chainActive.Height() + 1;
|
||||
|
||||
if (fromTaddr && toSprout) {
|
||||
const bool canopyActive = Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_CANOPY);
|
||||
if (canopyActive) {
|
||||
throw JSONRPCError(RPC_VERIFY_REJECTED, "Sprout shielding is not supported after Canopy");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ")+address );
|
||||
}
|
||||
|
@ -4424,6 +4440,18 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp)
|
|||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress );
|
||||
}
|
||||
|
||||
int nextBlockHeight = chainActive.Height() + 1;
|
||||
const bool canopyActive = Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_CANOPY);
|
||||
|
||||
if (canopyActive) {
|
||||
auto decodeAddr = DecodePaymentAddress(destaddress);
|
||||
bool isToSproutZaddr = (boost::get<libzcash::SproutPaymentAddress>(&decodeAddr) != nullptr);
|
||||
|
||||
if (isToSproutZaddr) {
|
||||
throw JSONRPCError(RPC_VERIFY_REJECTED, "Sprout shielding is not supported after Canopy activation");
|
||||
}
|
||||
}
|
||||
|
||||
// Convert fee from currency format to zatoshis
|
||||
CAmount nFee = SHIELD_COINBASE_DEFAULT_MINERS_FEE;
|
||||
if (params.size() > 2) {
|
||||
|
@ -4442,7 +4470,6 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp)
|
|||
}
|
||||
}
|
||||
|
||||
int nextBlockHeight = chainActive.Height() + 1;
|
||||
const bool saplingActive = Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_SAPLING);
|
||||
|
||||
// We cannot create shielded transactions before Sapling activates.
|
||||
|
@ -4644,6 +4671,8 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
|||
// Keep track of addresses to spot duplicates
|
||||
std::set<std::string> setAddress;
|
||||
|
||||
bool isFromNonSprout = false;
|
||||
|
||||
// Sources
|
||||
for (const UniValue& o : addresses.getValues()) {
|
||||
if (!o.isStr())
|
||||
|
@ -4653,18 +4682,24 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
|||
|
||||
if (address == "ANY_TADDR") {
|
||||
useAnyUTXO = true;
|
||||
isFromNonSprout = true;
|
||||
} else if (address == "ANY_SPROUT") {
|
||||
useAnySprout = true;
|
||||
} else if (address == "ANY_SAPLING") {
|
||||
useAnySapling = true;
|
||||
isFromNonSprout = true;
|
||||
} else {
|
||||
CTxDestination taddr = DecodeDestination(address);
|
||||
if (IsValidDestination(taddr)) {
|
||||
taddrs.insert(taddr);
|
||||
isFromNonSprout = true;
|
||||
} else {
|
||||
auto zaddr = DecodePaymentAddress(address);
|
||||
if (IsValidPaymentAddress(zaddr)) {
|
||||
zaddrs.insert(zaddr);
|
||||
if (boost::get<libzcash::SaplingPaymentAddress>(&zaddr) != nullptr) {
|
||||
isFromNonSprout = true;
|
||||
}
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Unknown address format: ") + address);
|
||||
}
|
||||
|
@ -4686,6 +4721,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
|||
const int nextBlockHeight = chainActive.Height() + 1;
|
||||
const bool overwinterActive = Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_OVERWINTER);
|
||||
const bool saplingActive = Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_SAPLING);
|
||||
const bool canopyActive = Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_CANOPY);
|
||||
|
||||
// Validate the destination address
|
||||
auto destaddress = params[1].get_str();
|
||||
|
@ -4709,6 +4745,11 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
|||
}
|
||||
}
|
||||
|
||||
if (canopyActive && isFromNonSprout && isToSproutZaddr) {
|
||||
// Value can be moved within Sprout, but not into Sprout.
|
||||
throw JSONRPCError(RPC_VERIFY_REJECTED, "Sprout shielding is not supported after Canopy");
|
||||
}
|
||||
|
||||
// Convert fee from currency format to zatoshis
|
||||
CAmount nFee = SHIELD_COINBASE_DEFAULT_MINERS_FEE;
|
||||
if (params.size() > 2) {
|
||||
|
|
Loading…
Reference in New Issue