Merge branch 'master' into modernise-macos-toolchain

This commit is contained in:
Jack Grigg 2020-08-08 00:07:31 +01:00
commit 927a03465f
121 changed files with 3991 additions and 2450 deletions

2
.gitignore vendored
View File

@ -7,6 +7,7 @@ src/zcash-cli
src/zcash-gtest
src/zcash-tx
src/test/test_bitcoin
zcutil/bin/
*zcashTest.pk
*zcashTest.vk
@ -116,5 +117,6 @@ libzcashconsensus.pc
contrib/debian/files
contrib/debian/substvars
src/fuzzing/*/input
src/fuzzing/*/output
src/fuzz.cpp

214
Cargo.lock generated
View File

@ -32,6 +32,24 @@ dependencies = [
"opaque-debug",
]
[[package]]
name = "aho-corasick"
version = "0.7.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86"
dependencies = [
"memchr",
]
[[package]]
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
"winapi",
]
[[package]]
name = "arrayref"
version = "0.3.5"
@ -53,6 +71,12 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875"
[[package]]
name = "autocfg"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
[[package]]
name = "bellman"
version = "0.6.0"
@ -164,9 +188,20 @@ dependencies = [
[[package]]
name = "cfg-if"
version = "0.1.9"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "chrono"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c74d84029116787153e02106bf53e66828452a4b325cc8652b788b5967c0a0b6"
dependencies = [
"num-integer",
"num-traits",
"time",
]
[[package]]
name = "constant_time_eq"
@ -181,11 +216,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d818a4990769aac0c7ff1360e233ef3a41adcb009ebb2036bf6915eb0f6b23c"
dependencies = [
"cfg-if",
"crossbeam-channel",
"crossbeam-channel 0.3.9",
"crossbeam-deque",
"crossbeam-epoch",
"crossbeam-queue",
"crossbeam-utils",
"crossbeam-utils 0.6.6",
]
[[package]]
@ -194,7 +229,17 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8ec7fcd21571dc78f96cc96243cab8d8f035247c3efd16c687be154c3fa9efa"
dependencies = [
"crossbeam-utils",
"crossbeam-utils 0.6.6",
]
[[package]]
name = "crossbeam-channel"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ee0cc8804d5393478d743b035099520087a5186f3b93fa58cec08fa62407b6"
dependencies = [
"cfg-if",
"crossbeam-utils 0.7.2",
]
[[package]]
@ -204,7 +249,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71"
dependencies = [
"crossbeam-epoch",
"crossbeam-utils",
"crossbeam-utils 0.6.6",
]
[[package]]
@ -215,7 +260,7 @@ checksum = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9"
dependencies = [
"arrayvec",
"cfg-if",
"crossbeam-utils",
"crossbeam-utils 0.6.6",
"lazy_static",
"memoffset",
"scopeguard",
@ -227,7 +272,7 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
dependencies = [
"crossbeam-utils",
"crossbeam-utils 0.6.6",
]
[[package]]
@ -240,6 +285,17 @@ dependencies = [
"lazy_static",
]
[[package]]
name = "crossbeam-utils"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
dependencies = [
"autocfg 1.0.0",
"cfg-if",
"lazy_static",
]
[[package]]
name = "crunchy"
version = "0.1.6"
@ -418,9 +474,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.62"
version = "0.2.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
checksum = "a9f8082297d534141b30c8d39e9b1773713ab50fdbe4ff30f750d063b3bfd701"
[[package]]
name = "librustzcash"
@ -435,6 +491,10 @@ dependencies = [
"libc",
"pairing",
"rand_core",
"tracing",
"tracing-appender",
"tracing-core",
"tracing-subscriber",
"zcash_history",
"zcash_primitives",
"zcash_proofs",
@ -449,6 +509,21 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "matchers"
version = "0.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1"
dependencies = [
"regex-automata",
]
[[package]]
name = "memchr"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
[[package]]
name = "memoffset"
version = "0.5.1"
@ -470,7 +545,7 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9c3f34cdd24f334cb265d9bf8bfa8a241920d026916785747a92f0e55541a1a"
dependencies = [
"autocfg",
"autocfg 0.1.6",
"num-integer",
"num-traits",
]
@ -481,7 +556,7 @@ version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
dependencies = [
"autocfg",
"autocfg 0.1.6",
"num-traits",
]
@ -491,7 +566,7 @@ version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
dependencies = [
"autocfg",
"autocfg 0.1.6",
]
[[package]]
@ -595,6 +670,34 @@ dependencies = [
"rand_core",
]
[[package]]
name = "regex"
version = "1.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
"thread_local",
]
[[package]]
name = "regex-automata"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
dependencies = [
"byteorder",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
[[package]]
name = "rustc_version"
version = "0.2.3"
@ -657,6 +760,15 @@ dependencies = [
"opaque-debug",
]
[[package]]
name = "sharded-slab"
version = "0.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06d5a3f5166fb5b42a5439f2eee8b9de149e235961e3eb21c5808fc3ea17ff3e"
dependencies = [
"lazy_static",
]
[[package]]
name = "subtle"
version = "2.2.3"
@ -694,6 +806,82 @@ dependencies = [
"syn",
]
[[package]]
name = "thread_local"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
dependencies = [
"lazy_static",
]
[[package]]
name = "time"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "tracing"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0aae59226cf195d8e74d4b34beae1859257efb4e5fed3f147d2dc2c7d372178"
dependencies = [
"cfg-if",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-appender"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7aa52d56cc0d79ab604e8a022a1cebc4de33cf09dc9933c94353bea2e00d6e88"
dependencies = [
"chrono",
"crossbeam-channel 0.4.3",
"tracing-subscriber",
]
[[package]]
name = "tracing-attributes"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0693bf8d6f2bf22c690fc61a9d21ac69efdbb894a17ed596b9af0f01e64b84b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tracing-core"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d593f98af59ebc017c0648f0117525db358745a8894a8d684e185ba3f45954f9"
dependencies = [
"lazy_static",
]
[[package]]
name = "tracing-subscriber"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7b33f8b2ef2ab0c3778c12646d9c42a24f7772bee4cdafc72199644a9f58fdc"
dependencies = [
"ansi_term",
"chrono",
"lazy_static",
"matchers",
"regex",
"sharded-slab",
"tracing-core",
]
[[package]]
name = "typenum"
version = "1.11.2"

View File

@ -28,11 +28,19 @@ libc = "0.2"
pairing = "0.16"
lazy_static = "1"
rand_core = "0.5.1"
tracing = "0.1"
tracing-core = "0.1"
tracing-appender = "0.1"
zcash_history = "0.2"
zcash_primitives = "0.2"
zcash_proofs = "0.2"
ed25519-zebra = "2.0.0"
[dependencies.tracing-subscriber]
version = "0.2"
default-features = false
features = ["ansi", "chrono", "env-filter"]
[profile.release]
lto = true
panic = 'abort'

View File

@ -169,3 +169,7 @@ DISTCHECK_CONFIGURE_FLAGS = --enable-man
clean-local:
rm -rf test_bitcoin.coverage/ zcash-gtest.coverage/ total.coverage/
rm -rf afl-temp
distclean-local:
rm -f zcutil/bin/db_*
rmdir zcutil/bin 2>/dev/null || true

View File

@ -105,12 +105,6 @@ AC_ARG_ENABLE([mining],
[enable_mining=$enableval],
[enable_mining=yes])
AC_ARG_ENABLE([proton],
[AS_HELP_STRING([--enable-proton],
[enable Proton (AMQP messaging) (default is no)])],
[use_proton=$enableval],
[use_proton=no])
AC_ARG_ENABLE(tests,
AS_HELP_STRING([--disable-tests],[do not compile tests (default is to compile)]),
[use_tests=$enableval],
@ -666,31 +660,6 @@ if test x$enable_wallet != xno; then
BITCOIN_FIND_BDB62
fi
dnl Check Qpid Proton headers and library exist
if test x$use_proton = xyes; then
AC_CHECK_HEADERS([proton/connection.hpp],
[],
[AC_MSG_WARN([Proton headers not found, disabling Proton support])
use_proton=no])
AC_CHECK_LIB([qpid-proton-cpp-static], [main],
[PROTON_LIBS="-lqpid-proton-cpp-static"],
[AC_MSG_WARN([Proton qpid-proton-cpp-static library not found, disabling Proton support])
use_proton=no])
AC_CHECK_LIB([qpid-proton-core-static], [main],
[PROTON_LIBS+=" -lqpid-proton-core-static"],
[AC_MSG_WARN([Proton qpid-proton-core-static library not found, disabling Proton support])
use_proton=no])
AC_CHECK_LIB([qpid-proton-static], [main],
[PROTON_LIBS+=" -lqpid-proton-static"],
[AC_MSG_WARN([Proton qpid-proton-static library not found, disabling Proton support])
use_proton=no])
fi
if test x$use_proton = xyes; then
AC_DEFINE(ENABLE_PROTON, 1, [Define to 1 to enable Proton functions])
else
AC_DEFINE(ENABLE_PROTON, 0, [Define to 1 to enable Proton functions])
fi
if test x$build_bitcoin_utils$build_bitcoind$use_tests = xnonono; then
use_boost=no
else
@ -894,8 +863,6 @@ fi
AM_CONDITIONAL([ENABLE_ZMQ], [test "x$use_zmq" = "xyes"])
AM_CONDITIONAL([ENABLE_PROTON], [test "x$use_proton" = "xyes"])
AC_MSG_CHECKING([whether to build test_bitcoin])
if test x$use_tests = xyes; then
AC_MSG_RESULT([yes])
@ -968,7 +935,6 @@ AC_SUBST(EVENT_LIBS)
AC_SUBST(EVENT_PTHREADS_LIBS)
AC_SUBST(ZMQ_LIBS)
AC_SUBST(LIBZCASH_LIBS)
AC_SUBST(PROTON_LIBS)
AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile src/test/buildenv.py])
AC_CONFIG_FILES([qa/pull-tester/run-bitcoind-for-test.sh],[chmod +x qa/pull-tester/run-bitcoind-for-test.sh])
AC_CONFIG_FILES([qa/pull-tester/tests-config.sh],[chmod +x qa/pull-tester/tests-config.sh])
@ -1015,7 +981,6 @@ esac
echo
echo "Options used to compile and link:"
echo " with wallet = $enable_wallet"
echo " with proton = $use_proton"
echo " with zmq = $use_zmq"
echo " with test = $use_tests"
echo " sanitizers = $use_sanitizers"

View File

@ -1,48 +0,0 @@
#!/usr/bin/env python2
# Copyright (c) 2017-2019 The Zcash developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://www.opensource.org/licenses/mit-license.php .
# Requirements:
# pip install python-qpid-proton
import binascii
from proton.handlers import MessagingHandler
from proton.reactor import Container
port = 5672
class Server(MessagingHandler):
def __init__(self, url):
super(Server, self).__init__()
self.url = url
self.senders = {}
def on_start(self, event):
print "Listening on:", self.url
self.container = event.container
self.acceptor = event.container.listen(self.url)
def on_message(self, event):
m = event.message
topic = m.subject
body = m.body
sequence = str( m.properties['x-opt-sequence-number'] )
if topic == "hashablock":
print '- HASH BLOCK ('+sequence+') -'
print binascii.hexlify(body)
elif topic == "hashtx":
print '- HASH TX ('+sequence+') -'
print binascii.hexlify(body)
elif topic == "rawblock":
print '- RAW BLOCK HEADER ('+sequence+') -'
print binascii.hexlify(body[:80])
elif topic == "rawtx":
print '- RAW TX ('+sequence+') -'
print binascii.hexlify(body)
try:
Container(Server("127.0.0.1:%i" % port)).run()
except KeyboardInterrupt:
pass

View File

@ -1,7 +1,6 @@
buildbot-worker
pyblake2
pyflakes
python-qpid-proton
pyutil
pyzmq
requests

View File

@ -116,14 +116,19 @@ Files: depends/sources/google*.tar.gz
Copyright: 2008 Google Inc.
License: BSD-3clause-Google
Files: depends/sources/qpid-proton-*.tar.gz
Copyright: 2012-2017 The Apache Software Foundation
License: Apache-Qpid-Proton-with-BSD-Subcomponents
Files: depends/sources/utfcpp-*.tar.gz
Copyright: 2006 Nemanja Trifunovic
License: Boost-Software-License-1.0
Files: src/crypto/ctaes/*
Copyright: Copyright (c) 2016 Pieter Wuille
License: Expat
Files: src/secp256k1/*
Copyright: Copyright (c) 2013 Pieter Wuille
License: Expat
Comment: This copyright entry excludes files explicitly listed below.
Files: src/secp256k1/build-aux/m4/ax_jni_include_dir.m4
Copyright: 2008 Don Anderson <dda@sleepycat.com>
License: GNU-All-permissive-License
@ -1195,222 +1200,6 @@ Comment:
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
License: Apache-Qpid-Proton-with-BSD-Subcomponents
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
.
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
.
1. Definitions.
.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
.
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
.
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
.
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
.
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
.
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
.
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
.
END OF TERMS AND CONDITIONS
.
APPENDIX: How to apply the Apache License to your work.
.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
.
Copyright [yyyy] [name of copyright owner]
.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
.
http://www.apache.org/licenses/LICENSE-2.0
.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
.
.
PROTON SUBCOMPONENTS:
.
Proton includes freegetopt with a separate BSD license. Your use
of the source code for freegetopt is subject to the terms and
conditions of its license in examples/include/pncompat/internal/LICENSE.
.
The setup scripts for the python bindings include files derived by
PyZMQ and are licensed with a separate Modified BSD license. Use of
the source code in these setup files are subject to the terms and
conditions in the license:
proton-c/bindings/python/setuputils/PYZMQ_LICENSE.BSD.
License: GNU-All-permissive-License
Copying and distribution of this file, with or without modification, are
permitted in any medium without royalty provided the copyright notice

View File

@ -87,7 +87,7 @@ script: |
BASEPREFIX=`pwd`/depends
# Build dependencies for each host
for i in $HOSTS; do
NO_PROTON="x" make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}"
make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}"
done
# Faketime for binaries

View File

@ -4,7 +4,7 @@ SOURCES_PATH ?= $(BASEDIR)/sources
BASE_CACHE ?= $(BASEDIR)/built
SDK_PATH ?= $(BASEDIR)/SDKs
NO_WALLET ?=
PRIORITY_DOWNLOAD_PATH ?= https://download.z.cash/depends-sources
FALLBACK_DOWNLOAD_PATH ?= https://download.z.cash/depends-sources
BUILD ?= $(shell ./config.guess)
HOST ?= $(BUILD)
@ -78,10 +78,7 @@ include packages/packages.mk
wallet_packages_$(NO_WALLET) = $(wallet_packages)
NO_PROTON_$(WITH_PROTON) = 1
proton_packages_$(NO_PROTON_) = $(proton_packages)
packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(rust_packages) $(proton_packages_) $(wallet_packages_)
packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(rust_packages) $(wallet_packages_)
native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages)
all_packages = $(packages) $(native_packages)

View File

@ -36,7 +36,7 @@ The following can be set when running make: make FOO=bar
SOURCES_PATH: downloaded sources will be placed here
BASE_CACHE: built packages will be placed here
SDK_PATH: Path where sdk's can be found (used by OSX)
PRIORITY_DOWNLOAD_PATH: Try fetching source files from here before using their own URLs
FALLBACK_DOWNLOAD_PATH: If a source file can't be fetched, try here before giving up
NO_WALLET: Don't download/build/cache libs needed to enable the wallet
DEBUG: disable some optimizations and enable more runtime checking
LIBRUSTZCASH_OVERRIDE: Path to a local librustzcash repository

View File

@ -19,13 +19,15 @@ define int_get_all_dependencies
$(sort $(foreach dep,$(2),$(2) $(call int_get_all_dependencies,$(1),$($(dep)_dependencies))))
endef
define download_and_check_file
($(build_DOWNLOAD) "$(1)/$(2).temp" $(3) && echo "$(4) $(1)/$(2).temp" > $(1)/.$(2).hash && $(build_SHA256SUM) -c $(1)/.$(2).hash)
endef
define fetch_file
(test -f $$($(1)_source_dir)/$(4) || \
( mkdir -p $$($(1)_download_dir) && echo Fetching $(1)... && \
( $(build_DOWNLOAD) "$$($(1)_download_dir)/$(4).temp" "$(PRIORITY_DOWNLOAD_PATH)/$(4)" || \
$(build_DOWNLOAD) "$$($(1)_download_dir)/$(4).temp" "$(2)/$(3)" ) && \
echo "$(5) $$($(1)_download_dir)/$(4).temp" > $$($(1)_download_dir)/.$(4).hash && \
$(build_SHA256SUM) -c $$($(1)_download_dir)/.$(4).hash && \
( $(call download_and_check_file,$$($(1)_download_dir),$(4),"$(2)/$(3)",$(5)) || \
$(call download_and_check_file,$$($(1)_download_dir),$(4),"$(FALLBACK_DOWNLOAD_PATH)/$(4)",$(5)) ) && \
mv $$($(1)_download_dir)/$(4).temp $$($(1)_source_dir)/$(4) && \
rm -rf $$($(1)_download_dir) ))
endef

View File

@ -32,5 +32,11 @@ define $(package)_build_cmds
endef
define $(package)_stage_cmds
$(MAKE) DESTDIR=$($(package)_staging_dir) install_lib install_include
$(MAKE) DESTDIR=$($(package)_staging_dir) install
endef
define $(package)_postprocess_cmds
cd $(BASEDIR)/../zcutil && \
mkdir -p bin && \
mv -f $($(package)_staging_dir)$(host_prefix)/bin/db_* bin
endef

View File

@ -0,0 +1,15 @@
package=crate_aho_corasick
$(package)_crate_name=aho-corasick
$(package)_version=0.7.13
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86
$(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

View File

@ -0,0 +1,15 @@
package=crate_ansi_term
$(package)_crate_name=ansi_term
$(package)_version=0.12.1
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2
$(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

View File

@ -1,9 +1,9 @@
package=crate_autocfg
$(package)_crate_name=autocfg
$(package)_version=0.1.6
$(package)_version=1.0.0
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875
$(package)_sha256_hash=f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d
$(package)_crate_versioned_name=$($(package)_crate_name)
define $(package)_preprocess_cmds

View File

@ -0,0 +1,15 @@
package=crate_autocfg
$(package)_crate_name=autocfg
$(package)_version=0.1.6
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875
$(package)_crate_versioned_name=$($(package)_crate_name)-$($(package)_version)
define $(package)_preprocess_cmds
$(call generate_crate_checksum,$(package))
endef
define $(package)_stage_cmds
$(call vendor_crate_source,$(package))
endef

View File

@ -1,9 +1,9 @@
package=crate_cfg_if
$(package)_crate_name=cfg-if
$(package)_version=0.1.9
$(package)_version=0.1.10
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33
$(package)_sha256_hash=4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822
$(package)_crate_versioned_name=$($(package)_crate_name)
define $(package)_preprocess_cmds

View File

@ -0,0 +1,15 @@
package=crate_chrono
$(package)_crate_name=chrono
$(package)_version=0.4.13
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=c74d84029116787153e02106bf53e66828452a4b325cc8652b788b5967c0a0b6
$(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

View File

@ -1,9 +1,9 @@
package=crate_crossbeam_channel
$(package)_crate_name=crossbeam-channel
$(package)_version=0.3.9
$(package)_version=0.4.3
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=c8ec7fcd21571dc78f96cc96243cab8d8f035247c3efd16c687be154c3fa9efa
$(package)_sha256_hash=09ee0cc8804d5393478d743b035099520087a5186f3b93fa58cec08fa62407b6
$(package)_crate_versioned_name=$($(package)_crate_name)
define $(package)_preprocess_cmds

View File

@ -0,0 +1,15 @@
package=crate_crossbeam_channel
$(package)_crate_name=crossbeam-channel
$(package)_version=0.3.9
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=c8ec7fcd21571dc78f96cc96243cab8d8f035247c3efd16c687be154c3fa9efa
$(package)_crate_versioned_name=$($(package)_crate_name)-$($(package)_version)
define $(package)_preprocess_cmds
$(call generate_crate_checksum,$(package))
endef
define $(package)_stage_cmds
$(call vendor_crate_source,$(package))
endef

View File

@ -1,9 +1,9 @@
package=crate_crossbeam_utils
$(package)_crate_name=crossbeam-utils
$(package)_version=0.6.6
$(package)_version=0.7.2
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6
$(package)_sha256_hash=c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8
$(package)_crate_versioned_name=$($(package)_crate_name)
define $(package)_preprocess_cmds

View File

@ -0,0 +1,15 @@
package=crate_crossbeam_utils
$(package)_crate_name=crossbeam-utils
$(package)_version=0.6.6
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6
$(package)_crate_versioned_name=$($(package)_crate_name)-$($(package)_version)
define $(package)_preprocess_cmds
$(call generate_crate_checksum,$(package))
endef
define $(package)_stage_cmds
$(call vendor_crate_source,$(package))
endef

View File

@ -1,9 +1,9 @@
package=crate_libc
$(package)_crate_name=libc
$(package)_version=0.2.62
$(package)_version=0.2.72
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba
$(package)_sha256_hash=a9f8082297d534141b30c8d39e9b1773713ab50fdbe4ff30f750d063b3bfd701
$(package)_crate_versioned_name=$($(package)_crate_name)
define $(package)_preprocess_cmds

View File

@ -0,0 +1,15 @@
package=crate_matchers
$(package)_crate_name=matchers
$(package)_version=0.0.1
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1
$(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

View File

@ -0,0 +1,15 @@
package=crate_memchr
$(package)_crate_name=memchr
$(package)_version=2.3.3
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400
$(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

View File

@ -0,0 +1,15 @@
package=crate_regex
$(package)_crate_name=regex
$(package)_version=1.3.9
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6
$(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

View File

@ -0,0 +1,15 @@
package=crate_regex_automata
$(package)_crate_name=regex-automata
$(package)_version=0.1.9
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4
$(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

View File

@ -0,0 +1,15 @@
package=crate_regex_syntax
$(package)_crate_name=regex-syntax
$(package)_version=0.6.18
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8
$(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

View File

@ -0,0 +1,15 @@
package=crate_sharded_slab
$(package)_crate_name=sharded-slab
$(package)_version=0.0.9
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=06d5a3f5166fb5b42a5439f2eee8b9de149e235961e3eb21c5808fc3ea17ff3e
$(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

View File

@ -0,0 +1,15 @@
package=crate_thread_local
$(package)_crate_name=thread_local
$(package)_version=1.0.1
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14
$(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

View File

@ -0,0 +1,15 @@
package=crate_time
$(package)_crate_name=time
$(package)_version=0.1.43
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438
$(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

View File

@ -0,0 +1,15 @@
package=crate_tracing
$(package)_crate_name=tracing
$(package)_version=0.1.18
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=f0aae59226cf195d8e74d4b34beae1859257efb4e5fed3f147d2dc2c7d372178
$(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

View File

@ -0,0 +1,15 @@
package=crate_tracing_appender
$(package)_crate_name=tracing-appender
$(package)_version=0.1.1
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=7aa52d56cc0d79ab604e8a022a1cebc4de33cf09dc9933c94353bea2e00d6e88
$(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

View File

@ -0,0 +1,15 @@
package=crate_tracing_attributes
$(package)_crate_name=tracing-attributes
$(package)_version=0.1.9
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=f0693bf8d6f2bf22c690fc61a9d21ac69efdbb894a17ed596b9af0f01e64b84b
$(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

View File

@ -0,0 +1,15 @@
package=crate_tracing_core
$(package)_crate_name=tracing-core
$(package)_version=0.1.13
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=d593f98af59ebc017c0648f0117525db358745a8894a8d684e185ba3f45954f9
$(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

View File

@ -0,0 +1,15 @@
package=crate_tracing_subscriber
$(package)_crate_name=tracing-subscriber
$(package)_version=0.2.10
$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name)
$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate
$(package)_sha256_hash=f7b33f8b2ef2ab0c3778c12646d9c42a24f7772bee4cdafc72199644a9f58fdc
$(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

View File

@ -2,8 +2,11 @@ rust_crates := \
crate_aes \
crate_aesni \
crate_aes_soft \
crate_aho_corasick \
crate_ansi_term \
crate_arrayref \
crate_arrayvec \
crate_autocfg_0.1 \
crate_autocfg \
crate_bellman \
crate_bigint \
@ -17,11 +20,14 @@ rust_crates := \
crate_byteorder \
crate_c2_chacha \
crate_cfg_if \
crate_chrono \
crate_constant_time_eq \
crate_crossbeam_channel_0.3 \
crate_crossbeam_channel \
crate_crossbeam_deque \
crate_crossbeam_epoch \
crate_crossbeam_queue \
crate_crossbeam_utils_0.6 \
crate_crossbeam_utils \
crate_crossbeam \
crate_crunchy \
@ -45,6 +51,8 @@ rust_crates := \
crate_lazy_static \
crate_libc \
crate_log \
crate_matchers \
crate_memchr \
crate_memoffset \
crate_nodrop \
crate_num_bigint \
@ -61,6 +69,9 @@ rust_crates := \
crate_rand_hc \
crate_rand_xorshift \
crate_rand \
crate_regex_automata \
crate_regex_syntax \
crate_regex \
crate_rustc_version \
crate_scopeguard \
crate_semver_parser \
@ -68,10 +79,18 @@ rust_crates := \
crate_serde \
crate_serde_derive \
crate_sha2 \
crate_sharded_slab \
crate_subtle \
crate_syn \
crate_time \
crate_thiserror \
crate_thiserror_impl \
crate_thread_local \
crate_tracing_appender \
crate_tracing_attributes \
crate_tracing_core \
crate_tracing_subscriber \
crate_tracing \
crate_typenum \
crate_unicode_xid \
crate_wasi \
@ -83,7 +102,6 @@ rust_crates := \
crate_zcash_proofs \
crate_zeroize
rust_packages := rust $(rust_crates)
proton_packages := proton
zcash_packages := libsodium utfcpp
packages := boost openssl libevent zeromq $(zcash_packages) googletest
native_packages := native_ccache

View File

@ -1,24 +0,0 @@
package=proton
$(package)_version=0.30.0
$(package)_download_path=https://archive.apache.org/dist/qpid/proton/$($(package)_version)
$(package)_file_name=qpid-proton-$($(package)_version).tar.gz
$(package)_sha256_hash=e37fd8fb13391c3996f927839969a8f66edf35612392d0611eeac6e39e48dd33
$(package)_patches=minimal-build.patch
define $(package)_preprocess_cmds
patch -p1 < $($(package)_patch_dir)/minimal-build.patch && \
mkdir -p build/proton-c/src
endef
define $(package)_config_cmds
cd build; cmake .. -DCMAKE_CXX_STANDARD=11 -DCMAKE_INSTALL_PREFIX=/ -DSYSINSTALL_BINDINGS=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_PYTHON=OFF -DBUILD_RUBY=OFF -DBUILD_GO=OFF -DBUILD_STATIC_LIBS=ON -DLIB_SUFFIX= -DENABLE_JSONCPP=
endef
define $(package)_build_cmds
cd build; $(MAKE) VERBOSE=1
endef
define $(package)_stage_cmds
cd build; $(MAKE) VERBOSE=1 DESTDIR=$($(package)_staging_prefix_dir) install
endef

View File

@ -1,314 +0,0 @@
diff -ur a/c/CMakeLists.txt b/c/CMakeLists.txt
--- a/c/CMakeLists.txt 2019-12-09 07:17:00.000000000 -0700
+++ b/c/CMakeLists.txt 2020-01-08 16:15:26.837987469 -0700
@@ -428,18 +428,18 @@
# Can't use target_link_libraries() because cmake 2.8.12 doesn't allow object libraries as the first param
# otherwise for cmake 3.9 and on this would be:
# target_link_libraries (qpid-proton-core-objects ${SSL_LIB} ${SASL_LIB} ${TIME_LIB} ${PLATFORM_LIBS})
-target_compile_definitions(qpid-proton-core-objects PRIVATE $<TARGET_PROPERTY:qpid-proton-core,COMPILE_DEFINITIONS>)
-target_compile_options (qpid-proton-core-objects PRIVATE $<TARGET_PROPERTY:qpid-proton-core,COMPILE_OPTIONS>)
-target_include_directories(qpid-proton-core-objects PRIVATE $<TARGET_PROPERTY:qpid-proton-core,INCLUDE_DIRECTORIES>)
-
-add_library (qpid-proton-core SHARED $<TARGET_OBJECTS:qpid-proton-core-objects>)
-target_link_libraries (qpid-proton-core ${SSL_LIB} ${SASL_LIB} ${TIME_LIB} ${PLATFORM_LIBS})
-set_target_properties (qpid-proton-core
- PROPERTIES
- VERSION "${PN_LIB_CORE_VERSION}"
- SOVERSION "${PN_LIB_CORE_MAJOR_VERSION}"
- LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}"
-)
+#target_compile_definitions(qpid-proton-core-objects PRIVATE $<TARGET_PROPERTY:qpid-proton-core,COMPILE_DEFINITIONS>)
+#target_compile_options (qpid-proton-core-objects PRIVATE $<TARGET_PROPERTY:qpid-proton-core,COMPILE_OPTIONS>)
+#target_include_directories(qpid-proton-core-objects PRIVATE $<TARGET_PROPERTY:qpid-proton-core,INCLUDE_DIRECTORIES>)
+
+#add_library (qpid-proton-core SHARED $<TARGET_OBJECTS:qpid-proton-core-objects>)
+#target_link_libraries (qpid-proton-core ${SSL_LIB} ${SASL_LIB} ${TIME_LIB} ${PLATFORM_LIBS})
+#set_target_properties (qpid-proton-core
+# PROPERTIES
+# VERSION "${PN_LIB_CORE_VERSION}"
+# SOVERSION "${PN_LIB_CORE_MAJOR_VERSION}"
+# LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}"
+#)
if (BUILD_STATIC_LIBS)
add_library (qpid-proton-core-static STATIC ${qpid-proton-core-src})
@@ -454,14 +454,14 @@
${qpid-proton-include-extra}
)
-add_library (qpid-proton SHARED $<TARGET_OBJECTS:qpid-proton-core-objects> ${qpid-proton-noncore-src})
-target_link_libraries (qpid-proton LINK_PRIVATE ${SSL_LIB} ${SASL_LIB} ${TIME_LIB} ${PLATFORM_LIBS} ${PROACTOR_LIBS})
-set_target_properties (qpid-proton
- PROPERTIES
- VERSION "${PN_LIB_LEGACY_VERSION}"
- SOVERSION "${PN_LIB_LEGACY_MAJOR_VERSION}"
- LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}"
-)
+# add_library (qpid-proton SHARED $<TARGET_OBJECTS:qpid-proton-core-objects> ${qpid-proton-noncore-src})
+# target_link_libraries (qpid-proton LINK_PRIVATE ${SSL_LIB} ${SASL_LIB} ${TIME_LIB} ${PLATFORM_LIBS} ${PROACTOR_LIBS})
+# set_target_properties (qpid-proton
+# PROPERTIES
+# VERSION "${PN_LIB_LEGACY_VERSION}"
+# SOVERSION "${PN_LIB_LEGACY_MAJOR_VERSION}"
+# LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}"
+# )
if (BUILD_STATIC_LIBS)
add_library(qpid-proton-static STATIC ${qpid-proton-core-src} ${qpid-proton-noncore-src})
@@ -482,15 +482,15 @@
if (qpid-proton-proactor)
set(HAS_PROACTOR True)
- add_library (qpid-proton-proactor SHARED ${qpid-proton-proactor})
- target_link_libraries (qpid-proton-proactor LINK_PUBLIC qpid-proton-core)
- target_link_libraries (qpid-proton-proactor LINK_PRIVATE ${PLATFORM_LIBS} ${PROACTOR_LIBS})
- set_target_properties (qpid-proton-proactor
- PROPERTIES
- VERSION "${PN_LIB_PROACTOR_VERSION}"
- SOVERSION "${PN_LIB_PROACTOR_MAJOR_VERSION}"
- LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}"
- )
+ # add_library (qpid-proton-proactor SHARED ${qpid-proton-proactor})
+ # target_link_libraries (qpid-proton-proactor LINK_PUBLIC qpid-proton-core)
+ # target_link_libraries (qpid-proton-proactor LINK_PRIVATE ${PLATFORM_LIBS} ${PROACTOR_LIBS})
+ # set_target_properties (qpid-proton-proactor
+ # PROPERTIES
+ # VERSION "${PN_LIB_PROACTOR_VERSION}"
+ # SOVERSION "${PN_LIB_PROACTOR_MAJOR_VERSION}"
+ # LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}"
+ # )
if (BUILD_STATIC_LIBS)
add_library (qpid-proton-proactor-static STATIC ${qpid-proton-proactor})
endif(BUILD_STATIC_LIBS)
@@ -500,11 +500,11 @@
if (BUILD_STATIC_LIBS)
set(STATIC_LIBS qpid-proton-static qpid-proton-core-static)
endif()
-install(TARGETS qpid-proton qpid-proton-core ${STATIC_LIBS}
- EXPORT proton
- RUNTIME DESTINATION bin
- ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
- LIBRARY DESTINATION ${LIB_INSTALL_DIR})
+# install(TARGETS qpid-proton qpid-proton-core ${STATIC_LIBS}
+# EXPORT proton
+# RUNTIME DESTINATION bin
+# ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
+# LIBRARY DESTINATION ${LIB_INSTALL_DIR})
# Install windows pdb files
if (MSVC)
@@ -520,11 +520,11 @@
if (BUILD_STATIC_LIBS)
set(STATIC_LIBS qpid-proton-proactor-static)
endif()
- install(TARGETS qpid-proton-proactor ${STATIC_LIBS}
- EXPORT proton
- RUNTIME DESTINATION bin
- ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
- LIBRARY DESTINATION ${LIB_INSTALL_DIR})
+ # install(TARGETS qpid-proton-proactor ${STATIC_LIBS}
+ # EXPORT proton
+ # RUNTIME DESTINATION bin
+ # ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
+ # LIBRARY DESTINATION ${LIB_INSTALL_DIR})
# Install windows pdb files
if (MSVC)
@@ -576,10 +576,10 @@
${CMAKE_CURRENT_BINARY_DIR}/ProtonConfigVersion.cmake
DESTINATION ${LIB_INSTALL_DIR}/cmake/Proton)
-add_subdirectory(docs)
-add_subdirectory(examples)
-add_subdirectory(tests)
-add_subdirectory(tools)
+# add_subdirectory(docs)
+# add_subdirectory(examples)
+# add_subdirectory(tests)
+# add_subdirectory(tools)
install (DIRECTORY examples/
DESTINATION "${PROTON_SHARE}/examples/c"
diff -ur a/CMakeLists.txt b/CMakeLists.txt
--- a/CMakeLists.txt 2019-12-09 07:17:00.000000000 -0700
+++ b/CMakeLists.txt 2019-12-19 18:11:57.128248724 -0700
@@ -24,7 +24,7 @@
set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/tools/cmake/Modules")
set (CMAKE_THREAD_PREFER_PTHREAD TRUE)
-include (CTest)
+# include (CTest)
include (CheckLanguage)
include (CheckLibraryExists)
include (CheckSymbolExists)
@@ -33,13 +33,13 @@
find_package (OpenSSL)
find_package (Threads)
find_package (PythonInterp REQUIRED)
-find_package (SWIG)
+# find_package (SWIG)
find_package (CyrusSASL)
-enable_testing ()
+#enable_testing ()
# Set up runtime checks (valgrind, sanitizers etc.)
-include(tests/RuntimeCheck.cmake)
+# include(tests/RuntimeCheck.cmake)
## Variables used across components
@@ -260,7 +260,7 @@
set (SYSINSTALL_BINDINGS OFF CACHE BOOL "If SYSINSTALL_BINDINGS is OFF then proton bindings will be installed underneath ${BINDINGS_DIR} and each user will need to modify their interpreter configuration to load the appropriate binding. If SYSINSTALL_BINDINGS is ON, then each language interpreter will be queried for the appropriate directory and proton bindings will be installed and available system wide with no additional per user configuration.")
-set (BINDING_LANGS PYTHON RUBY)
+# set (BINDING_LANGS PYTHON RUBY)
foreach (LANG ${BINDING_LANGS})
set (SYSINSTALL_${LANG} OFF CACHE BOOL "Install ${LANG} bindings into interpreter specified location.")
@@ -315,7 +315,7 @@
endif()
# Prerequisites for Go
-find_program(GO_EXE go)
+# find_program(GO_EXE go)
mark_as_advanced(GO_EXE)
if (GO_EXE)
set (DEFAULT_GO ON)
diff -ur a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
--- a/cpp/CMakeLists.txt 2019-12-09 07:17:00.000000000 -0700
+++ b/cpp/CMakeLists.txt 2020-01-08 16:20:18.855394195 -0700
@@ -174,30 +174,30 @@
set (CMAKE_DEBUG_POSTFIX "d")
endif ()
-add_library(qpid-proton-cpp SHARED ${qpid-proton-cpp-source})
+# add_library(qpid-proton-cpp SHARED ${qpid-proton-cpp-source})
if(BUILD_STATIC_LIBS)
add_library(qpid-proton-cpp-static STATIC ${qpid-proton-cpp-source})
set(STATIC_LIBS qpid-proton-cpp-static)
endif(BUILD_STATIC_LIBS)
-target_link_libraries (qpid-proton-cpp LINK_PRIVATE ${PLATFORM_LIBS} qpid-proton-core qpid-proton-proactor ${CONNECT_CONFIG_LIBS})
+# target_link_libraries (qpid-proton-cpp LINK_PRIVATE ${PLATFORM_LIBS} qpid-proton-core qpid-proton-proactor ${CONNECT_CONFIG_LIBS})
-set_target_properties (
- qpid-proton-cpp
- PROPERTIES
- LINKER_LANGUAGE CXX
- VERSION "${PN_LIB_CPP_VERSION}"
- SOVERSION "${PN_LIB_CPP_MAJOR_VERSION}"
- LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}"
- )
+# set_target_properties (
+# qpid-proton-cpp
+# PROPERTIES
+# LINKER_LANGUAGE CXX
+# VERSION "${PN_LIB_CPP_VERSION}"
+# SOVERSION "${PN_LIB_CPP_MAJOR_VERSION}"
+# LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}"
+# )
## Install
-install(TARGETS qpid-proton-cpp ${STATIC_LIBS}
- EXPORT proton-cpp
- RUNTIME DESTINATION bin
- ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
- LIBRARY DESTINATION ${LIB_INSTALL_DIR})
+# install(TARGETS qpid-proton-cpp ${STATIC_LIBS}
+# EXPORT proton-cpp
+# RUNTIME DESTINATION bin
+# ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
+# LIBRARY DESTINATION ${LIB_INSTALL_DIR})
# Install windows qpid-proton-cpp pdb files
if (MSVC)
@@ -209,12 +209,12 @@
install (DIRECTORY "include/proton" DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING PATTERN "*.hpp")
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/config_presets.hpp" DESTINATION "${INCLUDE_INSTALL_DIR}/proton/internal")
-install (DIRECTORY "examples/"
- DESTINATION "${PROTON_SHARE}/examples/cpp"
- USE_SOURCE_PERMISSIONS
- PATTERN "ProtonCppConfig.cmake" EXCLUDE)
+# install (DIRECTORY "examples/"
+# DESTINATION "${PROTON_SHARE}/examples/cpp"
+# USE_SOURCE_PERMISSIONS
+# PATTERN "ProtonCppConfig.cmake" EXCLUDE)
-add_subdirectory(examples)
+# add_subdirectory(examples)
add_subdirectory(docs)
# Pkg config file
@@ -268,40 +268,40 @@
set(test_env ${test_env} "PATH=$<TARGET_FILE_DIR:qpid-proton>")
endif()
-macro(add_cpp_test test)
- add_executable (${test} src/${test}.cpp)
- target_link_libraries (${test} qpid-proton-cpp ${PLATFORM_LIBS})
- add_test (NAME cpp-${test}
- COMMAND ${PN_ENV_SCRIPT} -- ${test_env} ${TEST_EXE_PREFIX_CMD} $<TARGET_FILE:${test}> ${ARGN})
-endmacro(add_cpp_test)
-
-add_cpp_test(codec_test)
-add_cpp_test(connection_driver_test)
-add_cpp_test(interop_test ${CMAKE_SOURCE_DIR}/tests)
-add_cpp_test(message_test)
-add_cpp_test(map_test)
-add_cpp_test(scalar_test)
-add_cpp_test(value_test)
-add_cpp_test(container_test)
-add_cpp_test(reconnect_test)
-add_cpp_test(link_test)
-add_cpp_test(credit_test)
-if (ENABLE_JSONCPP)
- add_cpp_test(connect_config_test)
- target_link_libraries(connect_config_test qpid-proton-core) # For pn_sasl_enabled
- set_tests_properties(cpp-connect_config_test PROPERTIES WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
- # Test data and output directories for connect_config_test
- file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/testdata" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
-endif()
+# macro(add_cpp_test test)
+# add_executable (${test} src/${test}.cpp)
+# target_link_libraries (${test} qpid-proton-cpp ${PLATFORM_LIBS})
+# add_test (NAME cpp-${test}
+# COMMAND ${PN_ENV_SCRIPT} -- ${test_env} ${TEST_EXE_PREFIX_CMD} $<TARGET_FILE:${test}> ${ARGN})
+# endmacro(add_cpp_test)
+#
+# add_cpp_test(codec_test)
+# add_cpp_test(connection_driver_test)
+# add_cpp_test(interop_test ${CMAKE_SOURCE_DIR}/tests)
+# add_cpp_test(message_test)
+# add_cpp_test(map_test)
+# add_cpp_test(scalar_test)
+# add_cpp_test(value_test)
+# add_cpp_test(container_test)
+# add_cpp_test(reconnect_test)
+# add_cpp_test(link_test)
+# add_cpp_test(credit_test)
+# if (ENABLE_JSONCPP)
+# add_cpp_test(connect_config_test)
+# target_link_libraries(connect_config_test qpid-proton-core) # For pn_sasl_enabled
+# set_tests_properties(cpp-connect_config_test PROPERTIES WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+# # Test data and output directories for connect_config_test
+# file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/testdata" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
+# endif()
# TODO aconway 2018-10-31: Catch2 tests
# This is a simple example of a C++ test using the Catch2 framework.
# See c/tests/ for more interesting examples.
# Eventually all the C++ tests will migrate to Catch2.
-include_directories(${CMAKE_SOURCE_DIR}/tests/include)
-add_executable(cpp-test src/cpp-test.cpp src/url_test.cpp)
-target_link_libraries(cpp-test qpid-proton-cpp ${PLATFORM_LIBS})
+#include_directories(${CMAKE_SOURCE_DIR}/tests/include)
+#add_executable(cpp-test src/cpp-test.cpp src/url_test.cpp)
+#target_link_libraries(cpp-test qpid-proton-cpp ${PLATFORM_LIBS})
macro(add_catch_test tag)
add_test (

View File

@ -1,137 +0,0 @@
# Block and Transaction Broadcasting With AMQP 1.0 (Experimental Feature)
[AMQP](https://www.amqp.org/) is an enterprise-level message queuing
protocol for the reliable passing of real-time data and business
transactions between applications. AMQP supports both broker and
brokerless messaging. AMQP 1.0 is an open standard and has been
ratified as ISO/IEC 19464.
The Zcash daemon can be configured to act as a trusted "border
router", implementing the Zcash P2P protocol and relay, making
consensus decisions, maintaining the local blockchain database,
broadcasting locally generated transactions into the network, and
providing a queryable RPC interface to interact on a polled basis for
requesting blockchain related data. However, there exists only a
limited service to notify external software of events like the arrival
of new blocks or transactions.
The AMQP facility implements a notification interface through a set
of specific notifiers. Currently there are notifiers that publish
blocks and transactions. This read-only facility requires only the
connection of a corresponding AMQP subscriber port in receiving
software.
Currently the facility is not authenticated nor is there any two-way
protocol involvement. Therefore, subscribers should validate the
received data since it may be out of date, incomplete or even invalid.
Because AMQP is message oriented, subscribers receive transactions
and blocks all-at-once and do not need to implement any sort of
buffering or reassembly.
## Prerequisites
The AMQP feature in Zcash requires [Qpid Proton](https://qpid.apache.org/proton/)
version 0.17 or newer, which you will need to install if you are not
using the depends system. Typically, it is packaged by distributions as
something like *libqpid-proton*. The C++ wrapper for AMQP *is* required.
In order to run the example Python client scripts in contrib/ one must
also install *python-qpid-proton*, though this is not necessary for
daemon operation.
## Security WARNING
Enabling this feature even on the loopback interface only (e.g. binding
it to localhost or 127.0.0.1) will still expose it to the wilds of the
Internet, because of an attack vector called DNS rebinding. DNS
rebinding allows an attacker located remotely on the Internet to trick
applications that you're running on the same computer as Zcashd to
contact your supposedly localhost-only AMQP port, then, depending on the
program they may be able to attempt to attack it.
Do not enable this feature unless you are sure that you know what you
are doing, and that you have a strong reason for thinking that you are
not vulnerable to this type of attack.
## Enabling
By default, the AMQP feature is automatically compiled in if the
necessary prerequisites are found. To disable, use --disable-proton
during the *configure* step of building zcashd:
$ ./configure --disable-proton (other options)
To actually enable operation, one must set the appropriate options on
the commandline or in the configuration file.
## Usage
AMQP support is currently an experimental feature, so you must pass
the option:
-experimentalfeatures
Currently, the following notifications are supported:
-amqppubhashtx=address
-amqppubhashblock=address
-amqppubrawblock=address
-amqppubrawtx=address
The address must be a valid AMQP address, where the same address can be
used in more than notification. Note that SSL and SASL addresses are
not currently supported.
Launch zcashd like this:
$ zcashd -amqppubhashtx=amqp://127.0.0.1:5672
Or this:
$ zcashd -amqppubhashtx=amqp://127.0.0.1:5672 \
-amqppubrawtx=amqp://127.0.0.1:5672 \
-amqppubrawblock=amqp://127.0.0.1:5672 \
-amqppubhashblock=amqp://127.0.0.1:5672 \
-debug=amqp
The debug category `amqp` enables AMQP-related logging.
Each notification has a topic and body, where the header corresponds
to the notification type. For instance, for the notification `-amqpubhashtx`
the topic is `hashtx` (no null terminator) and the body is the hexadecimal
transaction hash (32 bytes). This transaction hash and the block hash
found in `hashblock` are in RPC byte order.
These options can also be provided in zcash.conf.
Please see `contrib/amqp/amqp_sub.py` for a working example of an
AMQP server listening for messages.
## Remarks
From the perspective of zcashd, the local end of an AMQP link is write-only.
No information is broadcast that wasn't already received from the public
P2P network.
No authentication or authorization is done on peers that zcashd connects
to; it is assumed that the AMQP link is exposed only to trusted entities,
using other means such as firewalling.
TLS support may be added once OpenSSL has been removed from the Zcash
project and alternative TLS implementations have been evaluated.
SASL support may be added in a future update for secure communication.
Note that when the block chain tip changes, a reorganisation may occur
and just the tip will be notified. It is up to the subscriber to
retrieve the chain from the last known block to the new tip.
At present, zcashd does not try to resend a notification if there was
a problem confirming receipt. Support for delivery guarantees such as
*at-least-once* and *exactly-once* will be added in in a future update.
Currently, zcashd appends an up-counting sequence number to each notification
which allows listeners to detect lost notifications.

View File

@ -4,6 +4,31 @@ release-notes at release time)
Notable changes
===============
New logging system
------------------
The `zcashd` logging system is now powered by the Rust `tracing` crate. This
has two main benefits:
- `tracing` supports the concept of "spans", which represent periods of time
with a beginning and end. These enable logging additional information about
temporality and causality of events. (Regular log lines, which represent
moments in time, are called `events` in `tracing`.)
- Spans and events are structured, and can record typed data in addition to text
messages. This structure can then be filtered dynamically.
The existing `-debug=target` config flags are mapped to `tracing` log filters,
and will continue to correctly enable additional logging when starting `zcashd`.
A new `setlogfilter` RPC method has been introduced that enables reconfiguring
the log filter at runtime. See `zcash-cli help setlogfilter` for its syntax.
As a minor note, `zcashd` no longer reopens the `debug.log` file on `SIGHUP`.
This behaviour was originally introduced in upstream Bitcoin Core to support log
rotation using external tools. `tracing` supports log rotation internally (which
is currently disabled), as well as a variety of interesting backends (such as
`journald` and OpenTelemetry integration); we are investigating how these might
be exposed in future releases.
Compatibility
-------------
macOS versions earlier than 10.12 are no longer supported.

View File

@ -114,10 +114,6 @@ if [ "x$ENABLE_ZMQ" = "x1" ]; then
testScripts+=('zmq_test.py')
fi
if [ "x$ENABLE_PROTON" = "x1" ]; then
testScripts+=('proton_test.py')
fi
extArg="-extended"
passOn=${@#$extArg}

View File

@ -11,7 +11,6 @@ EXEEXT="@EXEEXT@"
@BUILD_BITCOIN_UTILS_TRUE@ENABLE_UTILS=1
@BUILD_BITCOIND_TRUE@ENABLE_BITCOIND=1
@ENABLE_ZMQ_TRUE@ENABLE_ZMQ=1
@ENABLE_PROTON_TRUE@ENABLE_PROTON=1
REAL_BITCOIND="$BUILDDIR/src/zcashd${EXEEXT}"
REAL_BITCOINCLI="$BUILDDIR/src/zcash-cli${EXEEXT}"

View File

@ -1,117 +0,0 @@
#!/usr/bin/env python3
# Copyright (c) 2017 The Zcash developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://www.opensource.org/licenses/mit-license.php .
#
# Test Proton interface (provides AMQP 1.0 messaging support).
#
# Requirements:
# Python library for Qpid Proton:
# https://pypi.python.org/pypi/python-qpid-proton
# To install:
# pip install python-qpid-proton
#
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, bytes_to_hex_str, \
start_nodes
from proton.handlers import MessagingHandler
from proton.reactor import Container
import threading
class Server(MessagingHandler):
def __init__(self, url, limit):
super(Server, self).__init__()
self.url = url
self.counter = limit
self.blockhashes = []
self.txids = []
self.blockseq = -1
self.txidseq = -1
def on_start(self, event):
print("Proton listening on:", self.url)
self.container = event.container
self.acceptor = event.container.listen(self.url)
def on_message(self, event):
m = event.message
hash = bytes_to_hex_str(m.body)
sequence = m.properties['x-opt-sequence-number']
if m.subject == "hashtx":
self.txids.append(hash)
# Test that sequence id is incrementing
assert(sequence == 1 + self.txidseq)
self.txidseq = sequence
elif m.subject == "hashblock":
self.blockhashes.append(hash)
# Test that sequence id is incrementing
assert(sequence == 1 + self.blockseq)
self.blockseq = sequence
self.counter = self.counter - 1
if self.counter == 0:
self.container.stop()
class ProtonTest (BitcoinTestFramework):
port = 25672
numblocks = 10 # must be even, as two nodes generate equal number
assert(numblocks % 2 == 0)
def setup_nodes(self):
# Launch proton server in background thread
# It terminates after receiving numblocks * 2 messages (one for coinbase, one for block)
self.server = Server("127.0.0.1:%i" % self.port, self.numblocks * 2)
self.container = Container(self.server)
self.t1 = threading.Thread(target=self.container.run)
self.t1.start()
return start_nodes(4, self.options.tmpdir, extra_args=[
['-experimentalfeatures', '-debug=amqp', '-amqppubhashtx=amqp://127.0.0.1:'+str(self.port),
'-amqppubhashblock=amqp://127.0.0.1:'+str(self.port)],
[],
[],
[]
])
def run_test(self):
self.sync_all()
baseheight = self.nodes[0].getblockcount() # 200 blocks already mined
# generate some blocks
self.nodes[0].generate(self.numblocks//2)
self.sync_all()
self.nodes[1].generate(self.numblocks//2)
self.sync_all()
# wait for server to finish
self.t1.join()
# sequence numbers have already been checked in the server's message handler
# sanity check that we have the right number of block hashes and coinbase txids
assert_equal(len(self.server.blockhashes), self.numblocks)
assert_equal(len(self.server.txids), self.numblocks)
# verify that each block has the correct coinbase txid
for i in range(0, self.numblocks):
height = baseheight + i + 1
blockhash = self.nodes[0].getblockhash(height)
assert_equal(blockhash, self.server.blockhashes[i])
resp = self.nodes[0].getblock(blockhash)
coinbase = resp["tx"][0]
assert_equal(coinbase, self.server.txids[i])
if __name__ == '__main__':
ProtonTest().main()

View File

@ -149,7 +149,6 @@ def rust_test():
#
STAGES = [
'check-depends',
'rust-test',
'btest',
'gtest',
@ -162,7 +161,6 @@ STAGES = [
]
STAGE_COMMANDS = {
'check-depends': ['qa/zcash/test-depends-sources-mirror.py'],
'rust-test': rust_test,
'btest': [repofile('src/test/test_bitcoin'), '-p'],
'gtest': [repofile('src/zcash-gtest')],

View File

@ -4,220 +4,265 @@
# bdb 18.1.40 2020-09-01
#
bdb 18.1.40 2020-09-01
boost 1.71.0 2020-09-01
boost 1.72.0 2020-09-01
boost 1.73.0 2020-09-01
googletest 1.8.1 2020-09-01
googletest 1.10.0 2020-09-01
libevent 2.1.10 2020-09-01
libevent 2.1.11 2020-09-01
native_ccache 3.3.2 2020-09-01
native_ccache 3.3.3 2020-09-01
native_ccache 3.3.4 2020-09-01
native_ccache 3.3.5 2020-09-01
native_ccache 3.3.6 2020-09-01
native_ccache 3.4 2020-09-01
native_ccache 3.4.1 2020-09-01
native_ccache 3.4.2 2020-09-01
native_ccache 3.4.3 2020-09-01
native_ccache 3.5 2020-09-01
native_ccache 3.5.1 2020-09-01
native_ccache 3.6 2020-09-01
native_ccache 3.7 2020-09-01
native_ccache 3.7.1 2020-09-01
native_ccache 3.7.2 2020-09-01
native_ccache 3.7.3 2020-09-01
native_ccache 3.7.4 2020-09-01
native_ccache 3.7.5 2020-09-01
native_ccache 3.7.6 2020-09-01
native_ccache 3.7.7 2020-09-01
native_ccache 3.7.8 2020-09-01
native_ccache 3.7.9 2020-09-01
native_ccache 3.7.10 2020-09-01
openssl 1.1.1.b 2020-09-01
openssl 1.1.1.c 2020-09-01
openssl 1.1.1.d 2020-09-01
openssl 1.1.1.e 2020-09-01
openssl 1.1.1.f 2020-09-01
openssl 1.1.1.g 2020-09-01
proton 0.31.0 2020-09-01
rust 1.43.0 2020-09-01
rust 1.43.1 2020-09-01
rust 1.44.0 2020-09-01
rust 1.44.1 2020-09-01
zeromq 4.3.2 2020-09-01
leveldb 1.19 2020-09-01
leveldb 1.20 2020-09-01
utfcpp 3.1.1 2020-09-01
crate_aes 0.4.0 2020-09-01
crate_aesni 0.7.0 2020-09-01
crate_aes_soft 0.4.0 2020-09-01
crate_arrayvec 0.4.12 2020-09-01
crate_arrayvec 0.5.0 2020-09-01
crate_arrayvec 0.5.1 2020-09-01
crate_arrayref 0.3.6 2020-09-01
crate_autocfg 0.1.7 2020-09-01
crate_autocfg 1.0.0 2020-09-01
crate_bigint 4.4.2 2020-09-01
crate_bigint 4.4.3 2020-09-01
crate_blake2b_simd 0.5.9 2020-09-01
crate_blake2b_simd 0.5.10 2020-09-01
crate_blake2s_simd 0.5.9 2020-09-01
crate_blake2s_simd 0.5.10 2020-09-01
crate_bit_vec 0.5.0 2020-09-01
crate_bit_vec 0.5.1 2020-09-01
crate_bit_vec 0.6.0 2020-09-01
crate_bit_vec 0.6.1 2020-09-01
crate_bit_vec 0.6.2 2020-09-01
crate_block_cipher_trait 0.7.0 2020-09-01
crate_byteorder 1.3.3 2020-09-01
crate_byteorder 1.3.4 2020-09-01
crate_block_buffer 0.8.0 2020-09-01
crate_block_buffer 0.9.0 2020-09-01
crate_block_padding 0.1.5 2020-09-01
crate_block_padding 0.2.0 2020-09-01
crate_c2_chacha 0.2.3 2020-09-01
crate_c2_chacha 0.2.4 2020-09-01
crate_cfg_if 0.1.10 2020-09-01
crate_crunchy 0.2.1 2020-09-01
crate_crunchy 0.2.2 2020-09-01
crate_constant_time_eq 0.1.5 2020-09-01
crate_crossbeam 0.7.3 2020-09-01
crate_digest 0.9.0 2020-09-01
crate_crossbeam_channel 0.4.0 2020-09-01
crate_crossbeam_channel 0.4.1 2020-09-01
crate_crossbeam_channel 0.4.2 2020-09-01
crate_crossbeam_deque 0.7.2 2020-09-01
crate_crossbeam_deque 0.7.3 2020-09-01
crate_crossbeam_epoch 0.8.0 2020-09-01
crate_crossbeam_epoch 0.8.1 2020-09-01
crate_crossbeam_epoch 0.8.2 2020-09-01
crate_crossbeam_utils 0.7.0 2020-09-01
crate_crossbeam_utils 0.7.1 2020-09-01
crate_crossbeam_utils 0.7.2 2020-09-01
crate_crossbeam_queue 0.2.0 2020-09-01
crate_crossbeam_queue 0.2.1 2020-09-01
crate_crossbeam_queue 0.2.2 2020-09-01
crate_crossbeam_queue 0.2.3 2020-09-01
crate_crypto_api_chachapoly 0.3.0 2020-09-01
crate_crypto_api_chachapoly 0.4.0 2020-09-01
crate_crypto_api_chachapoly 0.4.1 2020-09-01
crate_crypto_api_chachapoly 0.4.2 2020-09-01
crate_directories 2.0.0 2020-09-01
crate_directories 2.0.1 2020-09-01
crate_directories 2.0.2 2020-09-01
crate_directories 3.0.0 2020-09-01
crate_getrandom 0.1.13 2020-09-01
crate_getrandom 0.1.14 2020-09-01
crate_hex 0.4.0 2020-09-01
crate_hex 0.4.1 2020-09-01
crate_hex 0.4.2 2020-09-01
crate_log 0.4.9 2020-09-01
crate_log 0.4.10 2020-09-01
crate_futures 0.2.0 2020-09-01
crate_futures 0.2.1 2020-09-01
crate_futures 0.3.0 2020-09-01
crate_futures 0.3.1 2020-09-01
crate_futures 0.3.2 2020-09-01
crate_futures 0.3.3 2020-09-01
crate_futures 0.3.4 2020-09-01
crate_futures 0.3.5 2020-09-01
crate_generic_array 0.13.0 2020-09-01
crate_generic_array 0.13.1 2020-09-01
crate_generic_array 0.13.2 2020-09-01
crate_generic_array 0.14.0 2020-09-01
crate_generic_array 0.14.1 2020-09-01
crate_generic_array 0.14.2 2020-09-01
crate_libc 0.2.63 2020-09-01
crate_libc 0.2.64 2020-09-01
crate_libc 0.2.65 2020-09-01
crate_libc 0.2.66 2020-09-01
crate_libc 0.2.67 2020-09-01
crate_libc 0.2.68 2020-09-01
crate_libc 0.2.69 2020-09-01
crate_libc 0.2.70 2020-09-01
crate_libc 0.2.71 2020-09-01
crate_nodrop 0.1.14 2020-09-01
crate_num_bigint 0.2.4 2020-09-01
crate_num_bigint 0.2.5 2020-09-01
crate_num_bigint 0.2.6 2020-09-01
crate_num_bigint 0.3.0 2020-09-01
crate_memoffset 0.5.2 2020-09-01
crate_memoffset 0.5.3 2020-09-01
crate_memoffset 0.5.4 2020-09-01
crate_ppv_lite86 0.2.6 2020-09-01
crate_ppv_lite86 0.2.7 2020-09-01
crate_ppv_lite86 0.2.8 2020-09-01
crate_proc_macro2 1.0.4 2020-09-01
crate_proc_macro2 1.0.5 2020-09-01
crate_proc_macro2 1.0.6 2020-09-01
crate_proc_macro2 1.0.7 2020-09-01
crate_proc_macro2 1.0.8 2020-09-01
crate_proc_macro2 1.0.9 2020-09-01
crate_proc_macro2 1.0.10 2020-09-01
crate_proc_macro2 1.0.11 2020-09-01
crate_proc_macro2 1.0.12 2020-09-01
crate_proc_macro2 1.0.13 2020-09-01
crate_proc_macro2 1.0.14 2020-09-01
crate_proc_macro2 1.0.15 2020-09-01
crate_proc_macro2 1.0.16 2020-09-01
crate_proc_macro2 1.0.17 2020-09-01
crate_proc_macro2 1.0.18 2020-09-01
crate_quote 1.0.3 2020-09-01
crate_quote 1.0.4 2020-09-01
crate_quote 1.0.5 2020-09-01
crate_quote 1.0.6 2020-09-01
crate_quote 1.0.7 2020-09-01
crate_num_cpus 1.11.0 2020-09-01
crate_num_cpus 1.11.1 2020-09-01
crate_num_cpus 1.12.0 2020-09-01
crate_num_cpus 1.13.0 2020-09-01
crate_num_integer 0.1.42 2020-09-01
crate_num_integer 0.1.43 2020-09-01
crate_num_traits 0.2.9 2020-09-01
crate_num_traits 0.2.10 2020-09-01
crate_num_traits 0.2.11 2020-09-01
crate_num_traits 0.2.12 2020-09-01
crate_opaque_debug 0.3.0 2020-09-01
crate_rand 0.7.1 2020-09-01
crate_rand 0.7.2 2020-09-01
crate_rand 0.7.3 2020-09-01
crate_typenum 1.12.0 2020-09-01
crate_rand_chacha 0.2.2 2020-09-01
crate_scopeguard 1.1.0 2020-09-01
crate_semver 0.10.0 2020-09-01
crate_semver_parser 0.9.0 2020-09-01
crate_sha2 0.8.1 2020-09-01
crate_sha2 0.8.2 2020-09-01
crate_sha2 0.9.0 2020-09-01
crate_sha2 0.9.1 2020-09-01
crate_syn 1.0.6 2020-09-01
crate_syn 1.0.7 2020-09-01
crate_syn 1.0.8 2020-09-01
crate_syn 1.0.9 2020-09-01
crate_syn 1.0.10 2020-09-01
crate_syn 1.0.11 2020-09-01
crate_syn 1.0.12 2020-09-01
crate_syn 1.0.13 2020-09-01
crate_syn 1.0.14 2020-09-01
crate_syn 1.0.15 2020-09-01
crate_syn 1.0.16 2020-09-01
crate_syn 1.0.17 2020-09-01
crate_syn 1.0.18 2020-09-01
crate_syn 1.0.19 2020-09-01
crate_syn 1.0.20 2020-09-01
crate_syn 1.0.21 2020-09-01
crate_syn 1.0.22 2020-09-01
crate_syn 1.0.23 2020-09-01
crate_syn 1.0.24 2020-09-01
crate_syn 1.0.25 2020-09-01
crate_syn 1.0.26 2020-09-01
crate_syn 1.0.27 2020-09-01
crate_syn 1.0.28 2020-09-01
crate_syn 1.0.29 2020-09-01
crate_syn 1.0.30 2020-09-01
crate_syn 1.0.31 2020-09-01
crate_syn 1.0.32 2020-09-01
crate_syn 1.0.33 2020-09-01
crate_unicode_xid 0.2.1 2020-09-01
bdb 18.1.40 2020-10-01
boost 1.71.0 2020-10-01
boost 1.72.0 2020-10-01
boost 1.73.0 2020-10-01
googletest 1.8.1 2020-10-01
googletest 1.10.0 2020-10-01
libevent 2.1.10 2020-10-01
libevent 2.1.11 2020-10-01
native_ccache 3.3.2 2020-10-01
native_ccache 3.3.3 2020-10-01
native_ccache 3.3.4 2020-10-01
native_ccache 3.3.5 2020-10-01
native_ccache 3.3.6 2020-10-01
native_ccache 3.4 2020-10-01
native_ccache 3.4.1 2020-10-01
native_ccache 3.4.2 2020-10-01
native_ccache 3.4.3 2020-10-01
native_ccache 3.5 2020-10-01
native_ccache 3.5.1 2020-10-01
native_ccache 3.6 2020-10-01
native_ccache 3.7 2020-10-01
native_ccache 3.7.1 2020-10-01
native_ccache 3.7.2 2020-10-01
native_ccache 3.7.3 2020-10-01
native_ccache 3.7.4 2020-10-01
native_ccache 3.7.5 2020-10-01
native_ccache 3.7.6 2020-10-01
native_ccache 3.7.7 2020-10-01
native_ccache 3.7.8 2020-10-01
native_ccache 3.7.9 2020-10-01
native_ccache 3.7.10 2020-10-01
openssl 1.1.1.b 2020-10-01
openssl 1.1.1.c 2020-10-01
openssl 1.1.1.d 2020-10-01
openssl 1.1.1.e 2020-10-01
openssl 1.1.1.f 2020-10-01
openssl 1.1.1.g 2020-10-01
proton 0.31.0 2020-10-01
rust 1.43.0 2020-10-01
rust 1.43.1 2020-10-01
rust 1.44.0 2020-10-01
rust 1.44.1 2020-10-01
zeromq 4.3.2 2020-10-01
leveldb 1.19 2020-10-01
leveldb 1.20 2020-10-01
utfcpp 3.1.1 2020-10-01
crate_aes 0.4.0 2020-10-01
crate_aesni 0.7.0 2020-10-01
crate_aes_soft 0.4.0 2020-10-01
crate_arrayvec 0.4.12 2020-10-01
crate_arrayvec 0.5.0 2020-10-01
crate_arrayvec 0.5.1 2020-10-01
crate_arrayref 0.3.6 2020-10-01
crate_autocfg_0.1 0.1.7 2020-10-01
crate_autocfg_0.1 1.0.0 2020-10-01
crate_bigint 4.4.2 2020-10-01
crate_bigint 4.4.3 2020-10-01
crate_blake2b_simd 0.5.9 2020-10-01
crate_blake2b_simd 0.5.10 2020-10-01
crate_blake2s_simd 0.5.9 2020-10-01
crate_blake2s_simd 0.5.10 2020-10-01
crate_bit_vec 0.5.0 2020-10-01
crate_bit_vec 0.5.1 2020-10-01
crate_bit_vec 0.6.0 2020-10-01
crate_bit_vec 0.6.1 2020-10-01
crate_bit_vec 0.6.2 2020-10-01
crate_block_cipher_trait 0.7.0 2020-10-01
crate_byteorder 1.3.3 2020-10-01
crate_byteorder 1.3.4 2020-10-01
crate_block_buffer 0.8.0 2020-10-01
crate_block_buffer 0.9.0 2020-10-01
crate_block_padding 0.1.5 2020-10-01
crate_block_padding 0.2.0 2020-10-01
crate_c2_chacha 0.2.3 2020-10-01
crate_c2_chacha 0.2.4 2020-10-01
crate_cfg_if 0.1.10 2020-10-01
crate_crunchy 0.2.1 2020-10-01
crate_crunchy 0.2.2 2020-10-01
crate_constant_time_eq 0.1.5 2020-10-01
crate_crossbeam 0.7.3 2020-10-01
crate_digest 0.9.0 2020-10-01
crate_crossbeam_channel_0.3 0.4.0 2020-10-01
crate_crossbeam_channel_0.3 0.4.1 2020-10-01
crate_crossbeam_channel_0.3 0.4.2 2020-10-01
crate_crossbeam_deque 0.7.2 2020-10-01
crate_crossbeam_deque 0.7.3 2020-10-01
crate_crossbeam_epoch 0.8.0 2020-10-01
crate_crossbeam_epoch 0.8.1 2020-10-01
crate_crossbeam_epoch 0.8.2 2020-10-01
crate_crossbeam_utils_0.6 0.7.0 2020-10-01
crate_crossbeam_utils_0.6 0.7.1 2020-10-01
crate_crossbeam_utils_0.6 0.7.2 2020-10-01
crate_crossbeam_queue 0.2.0 2020-10-01
crate_crossbeam_queue 0.2.1 2020-10-01
crate_crossbeam_queue 0.2.2 2020-10-01
crate_crossbeam_queue 0.2.3 2020-10-01
crate_crypto_api_chachapoly 0.3.0 2020-10-01
crate_crypto_api_chachapoly 0.4.0 2020-10-01
crate_crypto_api_chachapoly 0.4.1 2020-10-01
crate_crypto_api_chachapoly 0.4.2 2020-10-01
crate_directories 2.0.0 2020-10-01
crate_directories 2.0.1 2020-10-01
crate_directories 2.0.2 2020-10-01
crate_directories 3.0.0 2020-10-01
crate_getrandom 0.1.13 2020-10-01
crate_getrandom 0.1.14 2020-10-01
crate_hex 0.4.0 2020-10-01
crate_hex 0.4.1 2020-10-01
crate_hex 0.4.2 2020-10-01
crate_log 0.4.9 2020-10-01
crate_log 0.4.10 2020-10-01
crate_futures 0.2.0 2020-10-01
crate_futures 0.2.1 2020-10-01
crate_futures 0.3.0 2020-10-01
crate_futures 0.3.1 2020-10-01
crate_futures 0.3.2 2020-10-01
crate_futures 0.3.3 2020-10-01
crate_futures 0.3.4 2020-10-01
crate_futures 0.3.5 2020-10-01
crate_generic_array 0.13.0 2020-10-01
crate_generic_array 0.13.1 2020-10-01
crate_generic_array 0.13.2 2020-10-01
crate_generic_array 0.14.0 2020-10-01
crate_generic_array 0.14.1 2020-10-01
crate_generic_array 0.14.2 2020-10-01
crate_libc 0.2.63 2020-10-01
crate_libc 0.2.64 2020-10-01
crate_libc 0.2.65 2020-10-01
crate_libc 0.2.66 2020-10-01
crate_libc 0.2.67 2020-10-01
crate_libc 0.2.68 2020-10-01
crate_libc 0.2.69 2020-10-01
crate_libc 0.2.70 2020-10-01
crate_libc 0.2.71 2020-10-01
crate_nodrop 0.1.14 2020-10-01
crate_num_bigint 0.2.4 2020-10-01
crate_num_bigint 0.2.5 2020-10-01
crate_num_bigint 0.2.6 2020-10-01
crate_num_bigint 0.3.0 2020-10-01
crate_memoffset 0.5.2 2020-10-01
crate_memoffset 0.5.3 2020-10-01
crate_memoffset 0.5.4 2020-10-01
crate_ppv_lite86 0.2.6 2020-10-01
crate_ppv_lite86 0.2.7 2020-10-01
crate_ppv_lite86 0.2.8 2020-10-01
crate_proc_macro2 1.0.4 2020-10-01
crate_proc_macro2 1.0.5 2020-10-01
crate_proc_macro2 1.0.6 2020-10-01
crate_proc_macro2 1.0.7 2020-10-01
crate_proc_macro2 1.0.8 2020-10-01
crate_proc_macro2 1.0.9 2020-10-01
crate_proc_macro2 1.0.10 2020-10-01
crate_proc_macro2 1.0.11 2020-10-01
crate_proc_macro2 1.0.12 2020-10-01
crate_proc_macro2 1.0.13 2020-10-01
crate_proc_macro2 1.0.14 2020-10-01
crate_proc_macro2 1.0.15 2020-10-01
crate_proc_macro2 1.0.16 2020-10-01
crate_proc_macro2 1.0.17 2020-10-01
crate_proc_macro2 1.0.18 2020-10-01
crate_quote 1.0.3 2020-10-01
crate_quote 1.0.4 2020-10-01
crate_quote 1.0.5 2020-10-01
crate_quote 1.0.6 2020-10-01
crate_quote 1.0.7 2020-10-01
crate_num_cpus 1.11.0 2020-10-01
crate_num_cpus 1.11.1 2020-10-01
crate_num_cpus 1.12.0 2020-10-01
crate_num_cpus 1.13.0 2020-10-01
crate_num_integer 0.1.42 2020-10-01
crate_num_integer 0.1.43 2020-10-01
crate_num_traits 0.2.9 2020-10-01
crate_num_traits 0.2.10 2020-10-01
crate_num_traits 0.2.11 2020-10-01
crate_num_traits 0.2.12 2020-10-01
crate_opaque_debug 0.3.0 2020-10-01
crate_rand 0.7.1 2020-10-01
crate_rand 0.7.2 2020-10-01
crate_rand 0.7.3 2020-10-01
crate_typenum 1.12.0 2020-10-01
crate_rand_chacha 0.2.2 2020-10-01
crate_scopeguard 1.1.0 2020-10-01
crate_semver 0.10.0 2020-10-01
crate_semver_parser 0.9.0 2020-10-01
crate_sha2 0.8.1 2020-10-01
crate_sha2 0.8.2 2020-10-01
crate_sha2 0.9.0 2020-10-01
crate_sha2 0.9.1 2020-10-01
crate_syn 1.0.6 2020-10-01
crate_syn 1.0.7 2020-10-01
crate_syn 1.0.8 2020-10-01
crate_syn 1.0.9 2020-10-01
crate_syn 1.0.10 2020-10-01
crate_syn 1.0.11 2020-10-01
crate_syn 1.0.12 2020-10-01
crate_syn 1.0.13 2020-10-01
crate_syn 1.0.14 2020-10-01
crate_syn 1.0.15 2020-10-01
crate_syn 1.0.16 2020-10-01
crate_syn 1.0.17 2020-10-01
crate_syn 1.0.18 2020-10-01
crate_syn 1.0.19 2020-10-01
crate_syn 1.0.20 2020-10-01
crate_syn 1.0.21 2020-10-01
crate_syn 1.0.22 2020-10-01
crate_syn 1.0.23 2020-10-01
crate_syn 1.0.24 2020-10-01
crate_syn 1.0.25 2020-10-01
crate_syn 1.0.26 2020-10-01
crate_syn 1.0.27 2020-10-01
crate_syn 1.0.28 2020-10-01
crate_syn 1.0.29 2020-10-01
crate_syn 1.0.30 2020-10-01
crate_syn 1.0.31 2020-10-01
crate_syn 1.0.32 2020-10-01
crate_syn 1.0.33 2020-10-01
crate_unicode_xid 0.2.1 2020-10-01
libevent 2.1.12 2020-10-01
native_ccache 3.7.11 2020-10-01
crate_crossbeam_channel 0.4.3 2020-10-01
crate_crypto_api_chachapoly 0.4.3 2020-10-01
crate_directories 3.0.1 2020-10-01
crate_ed25519_zebra 2.1.0 2020-10-01
crate_ed25519_zebra 2.1.1 2020-10-01
crate_log 0.4.11 2020-10-01
crate_generic_array 0.14.3 2020-10-01
crate_libc 0.2.72 2020-10-01
crate_libc 0.2.73 2020-10-01
crate_libc 0.2.74 2020-10-01
crate_memoffset 0.5.5 2020-10-01
crate_proc_macro2 1.0.19 2020-10-01
crate_serde 1.0.114 2020-10-01
crate_serde_derive 1.0.114 2020-10-01
crate_syn 1.0.34 2020-10-01
crate_syn 1.0.35 2020-10-01
crate_syn 1.0.36 2020-10-01
crate_syn 1.0.37 2020-10-01
crate_winapi 0.3.9 2020-10-01
rust 1.45.0 2020-10-01
rust 1.45.1 2020-10-01
rust 1.45.2 2020-10-01
# The chrono crate depends on "time ^0.1.43", and is highly unlikely to
# upgrade to v0.2: https://github.com/chronotope/chrono/issues/400
crate_time 0.2.0 2021-02-01
crate_time 0.2.1 2021-02-01
crate_time 0.2.2 2021-02-01
crate_time 0.2.3 2021-02-01
crate_time 0.2.4 2021-02-01
crate_time 0.2.5 2021-02-01
crate_time 0.2.6 2021-02-01
crate_time 0.2.7 2021-02-01
crate_time 0.2.8 2021-02-01
crate_time 0.2.9 2021-02-01
crate_time 0.2.10 2021-02-01
crate_time 0.2.11 2021-02-01
crate_time 0.2.12 2021-02-01
crate_time 0.2.13 2021-02-01
crate_time 0.2.14 2021-02-01
crate_time 0.2.15 2021-02-01
crate_time 0.2.16 2021-02-01

View File

@ -25,6 +25,12 @@
# .mk files in depends/packages, this script will exit with
# a nonzero status. The latter case would suggest someone added a new dependency
# without adding a corresponding entry to get_dependency_list() below.
#
# To test the script itself, run it with --functionality-test as the only
# argument. This will exercise the full functionality of the script, but will
# only return a non-zero exit status when there's something wrong with the
# script itself, for example if a new file was added to depends/packages/ but
# wasn't added to this script.
import requests
import os
@ -67,10 +73,6 @@ def get_dependency_list():
GithubTagReleaseLister("openssl", "openssl", "^OpenSSL_(\d+)_(\d+)_(\d+)([a-z]+)?$",
{ "OpenSSL_1_1_1b": (1, 1, 1, 'b'), "OpenSSL_1_1_1-pre9": None }),
DependsVersionGetter("openssl")),
Dependency("proton",
GithubTagReleaseLister("apache", "qpid-proton", "^(\d+)\.(\d+)(?:\.(\d+))?$",
{ "0.27.0": (0, 27, 0), "0.10": (0, 10), "0.12.0-rc": None }),
DependsVersionGetter("proton")),
Dependency("rust",
GithubTagReleaseLister("rust-lang", "rust", "^(\d+)\.(\d+)(?:\.(\d+))?$",
{ "1.33.0": (1, 33, 0), "0.9": (0, 9) }),
@ -93,32 +95,53 @@ def get_dependency_list():
DependsVersionGetter("utfcpp"))
]
# Rust crates.
# Rust crates (filename portion: depends/packages/crate_<NAME>.mk).
crates = [
"aes", "aesni", "aes_soft", "arrayvec", "bellman",
"arrayref", "autocfg", "bigint", "blake2b_simd", "blake2s_simd",
"bit_vec", "block_cipher_trait", "byteorder",
"block_buffer", "block_padding", "c2_chacha", "cfg_if", "crunchy",
"byte_tools", "constant_time_eq", "crossbeam", "digest", "fpe",
"aes", "aesni", "aes_soft", "aho_corasick", "ansi_term",
"arrayvec", "arrayref", "autocfg", "autocfg_0.1",
"bellman", "bigint", "blake2b_simd", "blake2s_simd", "bit_vec",
"block_cipher_trait", "byteorder", "byte_tools", "block_buffer",
"block_padding", "c2_chacha", "cfg_if", "chrono", "crunchy",
"curve25519_dalek", "constant_time_eq", "crossbeam", "digest", "fpe",
"crossbeam_channel_0.3", "crossbeam_utils_0.6",
"crossbeam_channel", "crossbeam_deque", "crossbeam_epoch",
"crossbeam_utils", "crossbeam_queue", "crypto_api", "crypto_api_chachapoly",
"directories", "fake_simd", "ff", "ff_derive", "getrandom", "hex", "log",
"crossbeam_utils", "crossbeam_queue", "crypto_api",
"crypto_api_chachapoly", "directories", "ed25519_zebra", "fake_simd",
"ff", "ff_derive", "getrandom", "hex", "hex2", "log",
"futures_cpupool", "futures", "generic_array", "group",
"lazy_static", "libc", "nodrop", "num_bigint",
"memoffset", "ppv_lite86", "proc_macro2", "quote",
"num_cpus", "num_integer", "num_traits", "opaque_debug", "pairing",
"rand", "typenum",
"lazy_static", "libc", "matchers", "memchr", "memoffset", "nodrop", "num_bigint",
"ppv_lite86", "proc_macro2", "quote", "num_cpus", "num_integer",
"num_traits", "opaque_debug", "pairing", "rand", "typenum",
"rand_chacha", "rand_core", "rand_hc", "rand_xorshift",
"rustc_version", "scopeguard", "semver", "semver_parser", "sha2", "syn",
"regex", "regex_automata", "regex_syntax",
"rustc_version", "scopeguard", "semver", "semver_parser", "serde",
"serde_derive", "sha2", "sharded_slab", "subtle", "syn", "thiserror",
"thiserror_impl", "thread_local", "time", "tracing", "tracing_appender",
"tracing_attributes", "tracing_core", "tracing_subscriber",
"unicode_xid", "wasi",
"winapi_i686_pc_windows_gnu", "winapi", "winapi_x86_64_pc_windows_gnu",
"zcash_history", "zcash_primitives", "zcash_proofs"
"winapi_i686_pc_windows_gnu", "winapi",
"winapi_x86_64_pc_windows_gnu", "zcash_history", "zcash_primitives",
"zcash_proofs", "zeroize"
]
# Sometimes we need multiple versions of a crate, in which case there can't
# be a direct mapping between the filename portion and the crate name.
crate_name_exceptions = {
"autocfg_0.1": "autocfg",
"crossbeam_channel_0.3": "crossbeam_channel",
"crossbeam_utils_0.6": "crossbeam_utils",
"hex2": "hex"
}
for crate in crates:
if crate in crate_name_exceptions.keys():
crate_name = crate_name_exceptions[crate]
else:
crate_name = crate
dependencies.append(
Dependency("crate_" + crate,
RustCrateReleaseLister(crate),
RustCrateReleaseLister(crate_name),
DependsVersionGetter("crate_" + crate)
)
)
@ -269,7 +292,7 @@ class DependsVersionGetter:
self.name = name
def current_version(self):
mk_file_path = os.path.join(SOURCE_ROOT, "depends", "packages", safe(self.name) + ".mk")
mk_file_path = os.path.join(SOURCE_ROOT, "depends", "packages", safe_depends(self.name) + ".mk")
mk_file = open(mk_file_path, 'r').read()
regexp_whitelist = [
@ -346,6 +369,12 @@ def safe(string):
else:
raise RuntimeError("Potentially-dangerous string encountered.")
def safe_depends(string):
if re.match('^[a-zA-Z0-9._-]*$', string):
return string
else:
raise RuntimeError("Potentially-dangerous string encountered.")
def print_row(name, status, current_version, known_versions):
COL_FMT_LARGE = "{:<35}"
COL_FMT_SMALL = "{:<18}"
@ -388,42 +417,43 @@ def main():
for dependency in deps:
if dependency.name in unchecked_dependencies:
unchecked_dependencies.remove(dependency.name)
if len(sys.argv) == 2 and sys.argv[1] == "skipcheck":
print("Skipping the actual dependency update checks.")
if dependency.is_up_to_date():
print_row(
dependency.name,
"up to date",
str(dependency.current_version()),
"")
else:
if dependency.is_up_to_date():
print_row(
dependency.name,
"up to date",
str(dependency.current_version()),
"")
else:
# The status can either be POSTPONED or OUT OF DATE depending
# on whether or not all the new versions are whitelisted.
status_text = "POSTPONED"
newver_list = "["
for newver in dependency.released_versions_after_current_version():
if postponed.is_postponed(dependency.name, newver):
newver_list += str(newver) + " (postponed),"
else:
newver_list += str(newver) + ","
status_text = "OUT OF DATE"
status = 1
# The status can either be POSTPONED or OUT OF DATE depending
# on whether or not all the new versions are whitelisted.
status_text = "POSTPONED"
newver_list = "["
for newver in dependency.released_versions_after_current_version():
if postponed.is_postponed(dependency.name, newver):
newver_list += str(newver) + " (postponed),"
else:
newver_list += str(newver) + ","
status_text = "OUT OF DATE"
status = 1
newver_list = newver_list[:-1] + "]"
newver_list = newver_list[:-1] + "]"
print_row(
dependency.name,
status_text,
str(dependency.current_version()),
newver_list
)
print_row(
dependency.name,
status_text,
str(dependency.current_version()),
newver_list
)
if len(unchecked_dependencies) > 0:
unchecked_dependencies.sort()
print("WARNING: The following dependencies are not being checked for updates by this script: " + ', '.join(unchecked_dependencies))
sys.exit(2)
if len(sys.argv) == 2 and sys.argv[1] == "--functionality-test":
print("We're only testing this script's functionality. The exit status will only be nonzero if there's a problem with the script itself.")
sys.exit(0)
if status == 0:
print("Ready to release. All dependencies are up-to-date or postponed.")
elif status == 1:

View File

@ -29,6 +29,7 @@ endif
BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config
BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BDB_CPPFLAGS) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS)
BITCOIN_CONFIG_INCLUDES += -I$(srcdir)/rust/include
BITCOIN_INCLUDES += -I$(srcdir)/rust/include
BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include
BITCOIN_INCLUDES += -I$(srcdir)/univalue/include
@ -46,9 +47,6 @@ LIBZCASH=libzcash.a
if ENABLE_ZMQ
LIBBITCOIN_ZMQ=libbitcoin_zmq.a
endif
if ENABLE_PROTON
LIBBITCOIN_PROTON=libbitcoin_proton.a
endif
if BUILD_BITCOIN_LIBS
LIBZCASH_CONSENSUS=libzcashconsensus.la
endif
@ -115,7 +113,6 @@ EXTRA_LIBRARIES += \
$(LIBBITCOIN_CLI) \
$(LIBBITCOIN_WALLET) \
$(LIBBITCOIN_ZMQ) \
$(LIBBITCOIN_PROTON) \
$(LIBZCASH)
lib_LTLIBRARIES = $(LIBZCASH_CONSENSUS)
@ -155,11 +152,6 @@ BITCOIN_CORE_H = \
addrman.h \
alert.h \
amount.h \
amqp/amqpabstractnotifier.h \
amqp/amqpconfig.h \
amqp/amqpnotificationinterface.h \
amqp/amqppublishnotifier.h \
amqp/amqpsender.h \
arith_uint256.h \
asyncrpcoperation.h \
asyncrpcqueue.h \
@ -214,6 +206,7 @@ BITCOIN_CORE_H = \
prevector.h \
primitives/block.h \
primitives/transaction.h \
proof_verifier.h \
protocol.h \
pubkey.h \
random.h \
@ -339,15 +332,6 @@ libbitcoin_zmq_a_SOURCES = \
zmq/zmqpublishnotifier.cpp
endif
if ENABLE_PROTON
libbitcoin_proton_a_CPPFLAGS = $(BITCOIN_INCLUDES)
libbitcoin_proton_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
libbitcoin_proton_a_SOURCES = \
amqp/amqpabstractnotifier.cpp \
amqp/amqpnotificationinterface.cpp \
amqp/amqppublishnotifier.cpp
endif
# wallet: zcashd, but only linked when wallet enabled
libbitcoin_wallet_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
@ -375,6 +359,8 @@ libbitcoin_wallet_a_SOURCES = \
crypto_libbitcoin_crypto_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_CONFIG_INCLUDES)
crypto_libbitcoin_crypto_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
crypto_libbitcoin_crypto_a_SOURCES = \
crypto/aes.cpp \
crypto/aes.h \
crypto/common.h \
crypto/equihash.cpp \
crypto/equihash.h \
@ -427,6 +413,7 @@ libbitcoin_common_a_SOURCES = \
netbase.cpp \
primitives/block.cpp \
primitives/transaction.cpp \
proof_verifier.cpp \
protocol.cpp \
pubkey.cpp \
scheduler.cpp \
@ -497,7 +484,6 @@ zcashd_LDADD = \
$(LIBUNIVALUE) \
$(LIBBITCOIN_UTIL) \
$(LIBBITCOIN_ZMQ) \
$(LIBBITCOIN_PROTON) \
$(LIBBITCOIN_CRYPTO) \
$(LIBZCASH) \
$(LIBRUSTZCASH) \
@ -513,7 +499,6 @@ zcashd_LDADD += \
$(EVENT_PTHREADS_LIBS) \
$(EVENT_LIBS) \
$(ZMQ_LIBS) \
$(PROTON_LIBS) \
$(LIBBITCOIN_CRYPTO) \
$(LIBZCASH_LIBS)
@ -575,7 +560,6 @@ libzcash_a_SOURCES = \
zcash/address/zip32.cpp \
zcash/History.cpp \
zcash/JoinSplit.cpp \
zcash/Proof.cpp \
zcash/Note.cpp \
zcash/prf.cpp \
zcash/util.cpp
@ -615,11 +599,17 @@ libzcashconsensus_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
endif
#
CTAES_DIST = crypto/ctaes/bench.c
CTAES_DIST += crypto/ctaes/ctaes.c
CTAES_DIST += crypto/ctaes/ctaes.h
CTAES_DIST += crypto/ctaes/README.md
CTAES_DIST += crypto/ctaes/test.c
CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a *.gcda *.gcno */*.gcno wallet/*/*.gcno
DISTCLEANFILES = obj/build.h
EXTRA_DIST = leveldb rust
EXTRA_DIST = leveldb $(CTAES_DIST) rust
clean-local:
rm -f $(top_srcdir)/.cargo/config $(top_srcdir)/.cargo/.configured-for-*

View File

@ -61,21 +61,34 @@ endif
zcash_gtest_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
zcash_gtest_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
zcash_gtest_LDADD = -lgtest -lgmock $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
$(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1)
if ENABLE_ZMQ
zcash_gtest_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
endif
if ENABLE_WALLET
zcash_gtest_LDADD += $(LIBBITCOIN_WALLET)
endif
zcash_gtest_LDADD += $(LIBZCASH_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(LIBZCASH) $(LIBRUSTZCASH) $(LIBZCASH_LIBS)
if ENABLE_PROTON
zcash_gtest_LDADD += $(LIBBITCOIN_PROTON) $(PROTON_LIBS)
endif
zcash_gtest_LDADD = \
-lgtest -lgmock \
$(LIBBITCOIN_SERVER) \
$(LIBBITCOIN_CLI) \
$(LIBBITCOIN_WALLET) \
$(LIBBITCOIN_COMMON) \
$(LIBBITCOIN_UTIL) \
$(LIBBITCOIN_ZMQ) \
$(LIBBITCOIN_PROTON) \
$(LIBBITCOIN_CRYPTO) \
$(LIBUNIVALUE) \
$(LIBLEVELDB) \
$(LIBMEMENV) \
$(LIBSECP256K1)
zcash_gtest_LDADD += \
$(LIBZCASH_CONSENSUS) \
$(BOOST_LIBS) \
$(BOOST_UNIT_TEST_FRAMEWORK_LIB) \
$(BDB_LIBS) \
$(SSL_LIBS) \
$(CRYPTO_LIBS) \
$(EVENT_PTHREADS_LIBS) \
$(EVENT_LIBS) \
$(ZMQ_LIBS) \
$(LIBZCASH) \
$(LIBRUSTZCASH) \
$(LIBZCASH_LIBS)
zcash_gtest_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static

View File

@ -114,6 +114,7 @@ BITCOIN_TESTS += \
wallet/test/wallet_test_fixture.h \
wallet/test/accounting_tests.cpp \
wallet/test/wallet_tests.cpp \
wallet/test/crypto_tests.cpp \
wallet/test/rpc_wallet_tests.cpp
endif
@ -134,10 +135,6 @@ if ENABLE_ZMQ
test_test_bitcoin_LDADD += $(ZMQ_LIBS)
endif
if ENABLE_PROTON
test_test_bitcoin_LDADD += $(PROTON_LIBS)
endif
nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES)
$(BITCOIN_TESTS): $(GENERATED_TEST_FILES)

View File

@ -1,21 +0,0 @@
// Copyright (c) 2017 The Zcash developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
#include "amqpabstractnotifier.h"
#include "util.h"
AMQPAbstractNotifier::~AMQPAbstractNotifier()
{
}
bool AMQPAbstractNotifier::NotifyBlock(const CBlockIndex * /*CBlockIndex*/)
{
return true;
}
bool AMQPAbstractNotifier::NotifyTransaction(const CTransaction &/*transaction*/)
{
return true;
}

View File

@ -1,43 +0,0 @@
// Copyright (c) 2017 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_AMQP_AMQPABSTRACTNOTIFIER_H
#define ZCASH_AMQP_AMQPABSTRACTNOTIFIER_H
#include "amqpconfig.h"
class CBlockIndex;
class AMQPAbstractNotifier;
typedef AMQPAbstractNotifier* (*AMQPNotifierFactory)();
class AMQPAbstractNotifier
{
public:
AMQPAbstractNotifier() { }
virtual ~AMQPAbstractNotifier();
template <typename T>
static AMQPAbstractNotifier* Create()
{
return new T();
}
std::string GetType() const { return type; }
void SetType(const std::string &t) { type = t; }
std::string GetAddress() const { return address; }
void SetAddress(const std::string &a) { address = a; }
virtual bool Initialize() = 0;
virtual void Shutdown() = 0;
virtual bool NotifyBlock(const CBlockIndex *pindex);
virtual bool NotifyTransaction(const CTransaction &transaction);
protected:
std::string type;
std::string address;
};
#endif // ZCASH_AMQP_AMQPABSTRACTNOTIFIER_H

View File

@ -1,33 +0,0 @@
// Copyright (c) 2017 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_AMQP_AMQPCONFIG_H
#define ZCASH_AMQP_AMQPCONFIG_H
#if defined(HAVE_CONFIG_H)
#include "config/bitcoin-config.h"
#endif
#include <stdarg.h>
#include <string>
#if ENABLE_PROTON
#include <proton/connection.hpp>
#include <proton/connection_options.hpp>
#include <proton/container.hpp>
#include <proton/default_container.hpp>
#include <proton/message.hpp>
#include <proton/message_id.hpp>
#include <proton/messaging_handler.hpp>
#include <proton/thread_safe.hpp>
#include <proton/tracker.hpp>
#include <proton/transport.hpp>
#include <proton/types.hpp>
#include <proton/url.hpp>
#endif
#include "primitives/block.h"
#include "primitives/transaction.h"
#endif // ZCASH_AMQP_AMQPCONFIG_H

View File

@ -1,136 +0,0 @@
// Copyright (c) 2017 The Zcash developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
#include "amqpnotificationinterface.h"
#include "amqppublishnotifier.h"
#include "version.h"
#include "main.h"
#include "streams.h"
#include "util.h"
// AMQP 1.0 Support
//
// The boost::signals2 signals and slot system is thread safe, so CValidationInterface listeners
// can be invoked from any thread.
//
// Currently signals are fired from main.cpp so the callbacks should be invoked on the same thread.
// It should be safe to share objects responsible for sending, as they should not be run concurrently
// across different threads.
//
// Developers should be mindful of where notifications are fired to avoid potential race conditions.
// For example, different signals targeting the same address could be fired from different threads
// in different parts of the system around the same time.
//
// Like the ZMQ notification interface, if a notifier fails to send a message, the notifier is shut down.
//
AMQPNotificationInterface::AMQPNotificationInterface()
{
}
AMQPNotificationInterface::~AMQPNotificationInterface()
{
Shutdown();
for (std::list<AMQPAbstractNotifier*>::iterator i = notifiers.begin(); i != notifiers.end(); ++i) {
delete *i;
}
}
AMQPNotificationInterface* AMQPNotificationInterface::CreateWithArguments(const std::map<std::string, std::string> &args)
{
AMQPNotificationInterface* notificationInterface = nullptr;
std::map<std::string, AMQPNotifierFactory> factories;
std::list<AMQPAbstractNotifier*> notifiers;
factories["pubhashblock"] = AMQPAbstractNotifier::Create<AMQPPublishHashBlockNotifier>;
factories["pubhashtx"] = AMQPAbstractNotifier::Create<AMQPPublishHashTransactionNotifier>;
factories["pubrawblock"] = AMQPAbstractNotifier::Create<AMQPPublishRawBlockNotifier>;
factories["pubrawtx"] = AMQPAbstractNotifier::Create<AMQPPublishRawTransactionNotifier>;
for (std::map<std::string, AMQPNotifierFactory>::const_iterator i=factories.begin(); i!=factories.end(); ++i) {
std::map<std::string, std::string>::const_iterator j = args.find("-amqp" + i->first);
if (j!=args.end()) {
AMQPNotifierFactory factory = i->second;
std::string address = j->second;
AMQPAbstractNotifier *notifier = factory();
notifier->SetType(i->first);
notifier->SetAddress(address);
notifiers.push_back(notifier);
}
}
if (!notifiers.empty()) {
notificationInterface = new AMQPNotificationInterface();
notificationInterface->notifiers = notifiers;
if (!notificationInterface->Initialize()) {
delete notificationInterface;
notificationInterface = nullptr;
}
}
return notificationInterface;
}
// Called at startup to conditionally set up
bool AMQPNotificationInterface::Initialize()
{
LogPrint("amqp", "amqp: Initialize notification interface\n");
std::list<AMQPAbstractNotifier*>::iterator i = notifiers.begin();
for (; i != notifiers.end(); ++i) {
AMQPAbstractNotifier *notifier = *i;
if (notifier->Initialize()) {
LogPrint("amqp", "amqp: Notifier %s ready (address = %s)\n", notifier->GetType(), notifier->GetAddress());
} else {
LogPrint("amqp", "amqp: Notifier %s failed (address = %s)\n", notifier->GetType(), notifier->GetAddress());
break;
}
}
if (i != notifiers.end()) {
return false;
}
return true;
}
// Called during shutdown sequence
void AMQPNotificationInterface::Shutdown()
{
LogPrint("amqp", "amqp: Shutdown notification interface\n");
for (std::list<AMQPAbstractNotifier*>::iterator i = notifiers.begin(); i != notifiers.end(); ++i) {
AMQPAbstractNotifier *notifier = *i;
notifier->Shutdown();
}
}
void AMQPNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindex)
{
for (std::list<AMQPAbstractNotifier*>::iterator i = notifiers.begin(); i != notifiers.end(); ) {
AMQPAbstractNotifier *notifier = *i;
if (notifier->NotifyBlock(pindex)) {
i++;
} else {
notifier->Shutdown();
i = notifiers.erase(i);
}
}
}
void AMQPNotificationInterface::SyncTransaction(const CTransaction &tx, const CBlock *pblock, const int nHeight)
{
for (std::list<AMQPAbstractNotifier*>::iterator i = notifiers.begin(); i != notifiers.end(); ) {
AMQPAbstractNotifier *notifier = *i;
if (notifier->NotifyTransaction(tx)) {
i++;
} else {
notifier->Shutdown();
i = notifiers.erase(i);
}
}
}

View File

@ -1,36 +0,0 @@
// Copyright (c) 2017 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_AMQP_AMQPNOTIFICATIONINTERFACE_H
#define ZCASH_AMQP_AMQPNOTIFICATIONINTERFACE_H
#include "validationinterface.h"
#include <string>
#include <map>
class CBlockIndex;
class AMQPAbstractNotifier;
class AMQPNotificationInterface : public CValidationInterface
{
public:
virtual ~AMQPNotificationInterface();
static AMQPNotificationInterface* CreateWithArguments(const std::map<std::string, std::string> &args);
protected:
bool Initialize();
void Shutdown();
// CValidationInterface
void SyncTransaction(const CTransaction &tx, const CBlock *pblock, const int nHeight);
void UpdatedBlockTip(const CBlockIndex *pindex);
private:
AMQPNotificationInterface();
std::list<AMQPAbstractNotifier*> notifiers;
};
#endif // ZCASH_AMQP_AMQPNOTIFICATIONINTERFACE_H

View File

@ -1,179 +0,0 @@
// Copyright (c) 2017 The Zcash developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
#include "amqppublishnotifier.h"
#include "chainparams.h"
#include "main.h"
#include "util.h"
#include "amqpsender.h"
#include <memory>
#include <thread>
static std::multimap<std::string, AMQPAbstractPublishNotifier*> mapPublishNotifiers;
static const char *MSG_HASHBLOCK = "hashblock";
static const char *MSG_HASHTX = "hashtx";
static const char *MSG_RAWBLOCK = "rawblock";
static const char *MSG_RAWTX = "rawtx";
// Invoke this method from a new thread to run the proton container event loop.
void AMQPAbstractPublishNotifier::SpawnProtonContainer()
{
try {
proton::default_container(*handler_).run();
}
catch (const proton::error_condition &e) {
LogPrint("amqp", "amqp: container error: %s\n", e.what());
}
catch (const std::runtime_error &e) {
LogPrint("amqp", "amqp: runtime error: %s\n", e.what());
}
catch (const std::exception &e) {
LogPrint("amqp", "amqp: exception: %s\n", e.what());
}
catch (...) {
LogPrint("amqp", "amqp: unknown error\n");
}
handler_->terminate();
}
bool AMQPAbstractPublishNotifier::Initialize()
{
std::multimap<std::string, AMQPAbstractPublishNotifier*>::iterator i = mapPublishNotifiers.find(address);
if (i == mapPublishNotifiers.end()) {
try {
handler_ = std::make_shared<AMQPSender>(address);
thread_ = std::make_shared<std::thread>(&AMQPAbstractPublishNotifier::SpawnProtonContainer, this);
}
catch (std::exception &e) {
LogPrint("amqp", "amqp: initialization error: %s\n", e.what());
return false;
}
mapPublishNotifiers.insert(std::make_pair(address, this));
} else {
// copy the shared ptrs to the message handler and the thread where the proton container is running
handler_ = i->second->handler_;
thread_ = i->second->thread_;
mapPublishNotifiers.insert(std::make_pair(address, this));
}
return true;
}
void AMQPAbstractPublishNotifier::Shutdown()
{
LogPrint("amqp", "amqp: Shutdown notifier %s at %s\n", GetType(), GetAddress());
int count = mapPublishNotifiers.count(address);
// remove this notifier from the list of publishers using this address
typedef std::multimap<std::string, AMQPAbstractPublishNotifier*>::iterator iterator;
std::pair<iterator, iterator> iterpair = mapPublishNotifiers.equal_range(address);
for (iterator it = iterpair.first; it != iterpair.second; ++it) {
if (it->second == this) {
mapPublishNotifiers.erase(it);
break;
}
}
// terminate the connection if this is the last publisher using this address
if (count == 1) {
handler_->terminate();
if (thread_.get() != nullptr) {
if (thread_->joinable()) {
thread_->join();
}
}
}
}
bool AMQPAbstractPublishNotifier::SendMessage(const char *command, const void* data, size_t size)
{
try {
proton::binary content;
const char *p = (const char *)data;
content.assign(p, p + size);
proton::message message(content);
message.subject(std::string(command));
proton::message::property_map & props = message.properties();
props.put("x-opt-sequence-number", sequence_);
handler_->publish(message);
} catch (proton::error_condition &e) {
LogPrint("amqp", "amqp: error : %s\n", e.what());
return false;
}
catch (const std::runtime_error &e) {
LogPrint("amqp", "amqp: runtime error: %s\n", e.what());
return false;
}
catch (const std::exception &e) {
LogPrint("amqp", "amqp: exception: %s\n", e.what());
return false;
}
catch (...) {
LogPrint("amqp", "amqp: unknown error\n");
return false;
}
sequence_++;
return true;
}
bool AMQPPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex)
{
uint256 hash = pindex->GetBlockHash();
LogPrint("amqp", "amqp: Publish hashblock %s\n", hash.GetHex());
char data[32];
for (unsigned int i = 0; i < 32; i++)
data[31 - i] = hash.begin()[i];
return SendMessage(MSG_HASHBLOCK, data, 32);
}
bool AMQPPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &transaction)
{
uint256 hash = transaction.GetHash();
LogPrint("amqp", "amqp: Publish hashtx %s\n", hash.GetHex());
char data[32];
for (unsigned int i = 0; i < 32; i++)
data[31 - i] = hash.begin()[i];
return SendMessage(MSG_HASHTX, data, 32);
}
bool AMQPPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex)
{
LogPrint("amqp", "amqp: Publish rawblock %s\n", pindex->GetBlockHash().GetHex());
const Consensus::Params& consensusParams = Params().GetConsensus();
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
{
LOCK(cs_main);
CBlock block;
if(!ReadBlockFromDisk(block, pindex, consensusParams)) {
LogPrint("amqp", "amqp: Can't read block from disk");
return false;
}
ss << block;
}
return SendMessage(MSG_RAWBLOCK, &(*ss.begin()), ss.size());
}
bool AMQPPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &transaction)
{
uint256 hash = transaction.GetHash();
LogPrint("amqp", "amqp: Publish rawtx %s\n", hash.GetHex());
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << transaction;
return SendMessage(MSG_RAWTX, &(*ss.begin()), ss.size());
}

View File

@ -1,56 +0,0 @@
// Copyright (c) 2017 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_AMQP_AMQPPUBLISHNOTIFIER_H
#define ZCASH_AMQP_AMQPPUBLISHNOTIFIER_H
#include "amqpabstractnotifier.h"
#include "amqpconfig.h"
#include "amqpsender.h"
#include <memory>
#include <thread>
class CBlockIndex;
class AMQPAbstractPublishNotifier : public AMQPAbstractNotifier
{
private:
uint64_t sequence_; // memory only, per notifier instance: upcounting message sequence number
std::shared_ptr<std::thread> thread_; // proton container thread, may be shared between notifiers
std::shared_ptr<AMQPSender> handler_; // proton container message handler, may be shared between notifiers
public:
bool SendMessage(const char *command, const void* data, size_t size);
bool Initialize();
void Shutdown();
void SpawnProtonContainer();
};
class AMQPPublishHashBlockNotifier : public AMQPAbstractPublishNotifier
{
public:
bool NotifyBlock(const CBlockIndex *pindex);
};
class AMQPPublishHashTransactionNotifier : public AMQPAbstractPublishNotifier
{
public:
bool NotifyTransaction(const CTransaction &transaction);
};
class AMQPPublishRawBlockNotifier : public AMQPAbstractPublishNotifier
{
public:
bool NotifyBlock(const CBlockIndex *pindex);
};
class AMQPPublishRawTransactionNotifier : public AMQPAbstractPublishNotifier
{
public:
bool NotifyTransaction(const CTransaction &transaction);
};
#endif // ZCASH_AMQP_AMQPPUBLISHNOTIFIER_H

View File

@ -1,115 +0,0 @@
// Copyright (c) 2017 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_AMQP_AMQPSENDER_H
#define ZCASH_AMQP_AMQPSENDER_H
#include "amqpconfig.h"
#include <deque>
#include <memory>
#include <future>
#include <iostream>
class AMQPSender : public proton::messaging_handler {
private:
std::deque<proton::message> messages_;
proton::url url_;
proton::connection conn_;
proton::sender sender_;
std::mutex lock_;
std::atomic<bool> terminated_ = {false};
public:
AMQPSender(const std::string& url) : url_(url) {}
// Callback to initialize the container when run() is invoked
void on_container_start(proton::container& c) override {
proton::duration t(10000); // milliseconds
proton::connection_options opts = proton::connection_options().idle_timeout(t);
conn_ = c.connect(url_, opts);
sender_ = conn_.open_sender(url_.path());
}
// Remote end signals when the local end can send (i.e. has credit)
void on_sendable(proton::sender &s) override {
dispatch();
}
// Publish message by adding to queue and trying to dispatch it
void publish(const proton::message &m) {
add_message(m);
dispatch();
}
// Add message to queue
void add_message(const proton::message &m) {
std::lock_guard<std::mutex> guard(lock_);
messages_.push_back(m);
}
// Send messages in queue
void dispatch() {
std::lock_guard<std::mutex> guard(lock_);
if (isTerminated()) {
throw std::runtime_error("amqp connection was terminated");
}
if (!conn_.active()) {
throw std::runtime_error("amqp connection is not active");
}
while (messages_.size() > 0) {
if (sender_.credit()) {
const proton::message& m = messages_.front();
sender_.send(m);
messages_.pop_front();
} else {
break;
}
}
}
// Close connection to remote end. Container event-loop, by default, will auto-stop.
void terminate() {
std::lock_guard<std::mutex> guard(lock_);
conn_.close();
terminated_.store(true);
}
bool isTerminated() const {
return terminated_.load();
}
void on_transport_error(proton::transport &t) override {
t.connection().close();
throw t.error();
}
void on_connection_error(proton::connection &c) override {
c.close();
throw c.error();
}
void on_session_error(proton::session &s) override {
s.connection().close();
throw s.error();
}
void on_receiver_error(proton::receiver &r) override {
r.connection().close();
throw r.error();
}
void on_sender_error(proton::sender &s) override {
s.connection().close();
throw s.error();
}
};
#endif //ZCASH_AMQP_AMQPSENDER_H

View File

@ -7,7 +7,6 @@
#include "key.h"
#include "main.h"
#include "util.h"
#include "zcash/JoinSplit.hpp"
#include <boost/filesystem.hpp>

217
src/crypto/aes.cpp Normal file
View File

@ -0,0 +1,217 @@
// Copyright (c) 2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "aes.h"
#include "crypto/common.h"
#include <assert.h>
#include <string.h>
extern "C" {
#include "crypto/ctaes/ctaes.c"
}
AES128Encrypt::AES128Encrypt(const unsigned char key[16])
{
AES128_init(&ctx, key);
}
AES128Encrypt::~AES128Encrypt()
{
memset(&ctx, 0, sizeof(ctx));
}
void AES128Encrypt::Encrypt(unsigned char ciphertext[16], const unsigned char plaintext[16]) const
{
AES128_encrypt(&ctx, 1, ciphertext, plaintext);
}
AES128Decrypt::AES128Decrypt(const unsigned char key[16])
{
AES128_init(&ctx, key);
}
AES128Decrypt::~AES128Decrypt()
{
memset(&ctx, 0, sizeof(ctx));
}
void AES128Decrypt::Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const
{
AES128_decrypt(&ctx, 1, plaintext, ciphertext);
}
AES256Encrypt::AES256Encrypt(const unsigned char key[32])
{
AES256_init(&ctx, key);
}
AES256Encrypt::~AES256Encrypt()
{
memset(&ctx, 0, sizeof(ctx));
}
void AES256Encrypt::Encrypt(unsigned char ciphertext[16], const unsigned char plaintext[16]) const
{
AES256_encrypt(&ctx, 1, ciphertext, plaintext);
}
AES256Decrypt::AES256Decrypt(const unsigned char key[32])
{
AES256_init(&ctx, key);
}
AES256Decrypt::~AES256Decrypt()
{
memset(&ctx, 0, sizeof(ctx));
}
void AES256Decrypt::Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const
{
AES256_decrypt(&ctx, 1, plaintext, ciphertext);
}
template <typename T>
static int CBCEncrypt(const T& enc, const unsigned char iv[AES_BLOCKSIZE], const unsigned char* data, int size, bool pad, unsigned char* out)
{
int written = 0;
int padsize = size % AES_BLOCKSIZE;
unsigned char mixed[AES_BLOCKSIZE];
if (!data || !size || !out)
return 0;
if (!pad && padsize != 0)
return 0;
memcpy(mixed, iv, AES_BLOCKSIZE);
// Write all but the last block
while (written + AES_BLOCKSIZE <= size) {
for (int i = 0; i != AES_BLOCKSIZE; i++)
mixed[i] ^= *data++;
enc.Encrypt(out + written, mixed);
memcpy(mixed, out + written, AES_BLOCKSIZE);
written += AES_BLOCKSIZE;
}
if (pad) {
// For all that remains, pad each byte with the value of the remaining
// space. If there is none, pad by a full block.
for (int i = 0; i != padsize; i++)
mixed[i] ^= *data++;
for (int i = padsize; i != AES_BLOCKSIZE; i++)
mixed[i] ^= AES_BLOCKSIZE - padsize;
enc.Encrypt(out + written, mixed);
written += AES_BLOCKSIZE;
}
return written;
}
template <typename T>
static int CBCDecrypt(const T& dec, const unsigned char iv[AES_BLOCKSIZE], const unsigned char* data, int size, bool pad, unsigned char* out)
{
unsigned char padsize = 0;
int written = 0;
bool fail = false;
const unsigned char* prev = iv;
if (!data || !size || !out)
return 0;
if (size % AES_BLOCKSIZE != 0)
return 0;
// Decrypt all data. Padding will be checked in the output.
while (written != size) {
dec.Decrypt(out, data + written);
for (int i = 0; i != AES_BLOCKSIZE; i++)
*out++ ^= prev[i];
prev = data + written;
written += AES_BLOCKSIZE;
}
// When decrypting padding, attempt to run in constant-time
if (pad) {
// If used, padding size is the value of the last decrypted byte. For
// it to be valid, It must be between 1 and AES_BLOCKSIZE.
padsize = *--out;
fail = !padsize | (padsize > AES_BLOCKSIZE);
// If not well-formed, treat it as though there's no padding.
padsize *= !fail;
// All padding must equal the last byte otherwise it's not well-formed
for (int i = AES_BLOCKSIZE; i != 0; i--)
fail |= ((i > AES_BLOCKSIZE - padsize) & (*out-- != padsize));
written -= padsize;
}
return written * !fail;
}
AES256CBCEncrypt::AES256CBCEncrypt(const unsigned char key[AES256_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn)
: enc(key), pad(padIn)
{
memcpy(iv, ivIn, AES_BLOCKSIZE);
}
int AES256CBCEncrypt::Encrypt(const unsigned char* data, int size, unsigned char* out) const
{
return CBCEncrypt(enc, iv, data, size, pad, out);
}
AES256CBCEncrypt::~AES256CBCEncrypt()
{
memset(iv, 0, sizeof(iv));
}
AES256CBCDecrypt::AES256CBCDecrypt(const unsigned char key[AES256_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn)
: dec(key), pad(padIn)
{
memcpy(iv, ivIn, AES_BLOCKSIZE);
}
int AES256CBCDecrypt::Decrypt(const unsigned char* data, int size, unsigned char* out) const
{
return CBCDecrypt(dec, iv, data, size, pad, out);
}
AES256CBCDecrypt::~AES256CBCDecrypt()
{
memset(iv, 0, sizeof(iv));
}
AES128CBCEncrypt::AES128CBCEncrypt(const unsigned char key[AES128_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn)
: enc(key), pad(padIn)
{
memcpy(iv, ivIn, AES_BLOCKSIZE);
}
AES128CBCEncrypt::~AES128CBCEncrypt()
{
memset(iv, 0, AES_BLOCKSIZE);
}
int AES128CBCEncrypt::Encrypt(const unsigned char* data, int size, unsigned char* out) const
{
return CBCEncrypt(enc, iv, data, size, pad, out);
}
AES128CBCDecrypt::AES128CBCDecrypt(const unsigned char key[AES128_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn)
: dec(key), pad(padIn)
{
memcpy(iv, ivIn, AES_BLOCKSIZE);
}
AES128CBCDecrypt::~AES128CBCDecrypt()
{
memset(iv, 0, AES_BLOCKSIZE);
}
int AES128CBCDecrypt::Decrypt(const unsigned char* data, int size, unsigned char* out) const
{
return CBCDecrypt(dec, iv, data, size, pad, out);
}

118
src/crypto/aes.h Normal file
View File

@ -0,0 +1,118 @@
// Copyright (c) 2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
//
// C++ wrapper around ctaes, a constant-time AES implementation
#ifndef BITCOIN_CRYPTO_AES_H
#define BITCOIN_CRYPTO_AES_H
extern "C" {
#include "crypto/ctaes/ctaes.h"
}
static const int AES_BLOCKSIZE = 16;
static const int AES128_KEYSIZE = 16;
static const int AES256_KEYSIZE = 32;
/** An encryption class for AES-128. */
class AES128Encrypt
{
private:
AES128_ctx ctx;
public:
AES128Encrypt(const unsigned char key[16]);
~AES128Encrypt();
void Encrypt(unsigned char ciphertext[16], const unsigned char plaintext[16]) const;
};
/** A decryption class for AES-128. */
class AES128Decrypt
{
private:
AES128_ctx ctx;
public:
AES128Decrypt(const unsigned char key[16]);
~AES128Decrypt();
void Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const;
};
/** An encryption class for AES-256. */
class AES256Encrypt
{
private:
AES256_ctx ctx;
public:
AES256Encrypt(const unsigned char key[32]);
~AES256Encrypt();
void Encrypt(unsigned char ciphertext[16], const unsigned char plaintext[16]) const;
};
/** A decryption class for AES-256. */
class AES256Decrypt
{
private:
AES256_ctx ctx;
public:
AES256Decrypt(const unsigned char key[32]);
~AES256Decrypt();
void Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const;
};
class AES256CBCEncrypt
{
public:
AES256CBCEncrypt(const unsigned char key[AES256_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn);
~AES256CBCEncrypt();
int Encrypt(const unsigned char* data, int size, unsigned char* out) const;
private:
const AES256Encrypt enc;
const bool pad;
unsigned char iv[AES_BLOCKSIZE];
};
class AES256CBCDecrypt
{
public:
AES256CBCDecrypt(const unsigned char key[AES256_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn);
~AES256CBCDecrypt();
int Decrypt(const unsigned char* data, int size, unsigned char* out) const;
private:
const AES256Decrypt dec;
const bool pad;
unsigned char iv[AES_BLOCKSIZE];
};
class AES128CBCEncrypt
{
public:
AES128CBCEncrypt(const unsigned char key[AES128_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn);
~AES128CBCEncrypt();
int Encrypt(const unsigned char* data, int size, unsigned char* out) const;
private:
const AES128Encrypt enc;
const bool pad;
unsigned char iv[AES_BLOCKSIZE];
};
class AES128CBCDecrypt
{
public:
AES128CBCDecrypt(const unsigned char key[AES128_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn);
~AES128CBCDecrypt();
int Decrypt(const unsigned char* data, int size, unsigned char* out) const;
private:
const AES128Decrypt dec;
const bool pad;
unsigned char iv[AES_BLOCKSIZE];
};
#endif // BITCOIN_CRYPTO_AES_H

21
src/crypto/ctaes/COPYING Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Pieter Wuille
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,41 @@
ctaes
=====
Simple C module for constant-time AES encryption and decryption.
Features:
* Simple, pure C code without any dependencies.
* No tables or data-dependent branches whatsoever, but using bit sliced approach from https://eprint.iacr.org/2009/129.pdf.
* Very small object code: slightly over 4k of executable code when compiled with -Os.
* Slower than implementations based on precomputed tables or specialized instructions, but can do ~15 MB/s on modern CPUs.
Performance
-----------
Compiled with GCC 5.3.1 with -O3, on an Intel(R) Core(TM) i7-4800MQ CPU, numbers in CPU cycles:
| Algorithm | Key schedule | Encryption per byte | Decryption per byte |
| --------- | ------------:| -------------------:| -------------------:|
| AES-128 | 2.8k | 154 | 161 |
| AES-192 | 3.1k | 169 | 181 |
| AES-256 | 4.0k | 191 | 203 |
Build steps
-----------
Object code:
$ gcc -O3 ctaes.c -c -o ctaes.o
Tests:
$ gcc -O3 ctaes.c test.c -o test
Benchmark:
$ gcc -O3 ctaes.c bench.c -o bench
Review
------
Results of a formal review of the code can be found in http://bitcoin.sipa.be/ctaes/review.zip

170
src/crypto/ctaes/bench.c Normal file
View File

@ -0,0 +1,170 @@
#include <stdio.h>
#include <math.h>
#include "sys/time.h"
#include "ctaes.h"
static double gettimedouble(void) {
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_usec * 0.000001 + tv.tv_sec;
}
static void print_number(double x) {
double y = x;
int c = 0;
if (y < 0.0) {
y = -y;
}
while (y < 100.0) {
y *= 10.0;
c++;
}
printf("%.*f", c, x);
}
static void run_benchmark(char *name, void (*benchmark)(void*), void (*setup)(void*), void (*teardown)(void*), void* data, int count, int iter) {
int i;
double min = HUGE_VAL;
double sum = 0.0;
double max = 0.0;
for (i = 0; i < count; i++) {
double begin, total;
if (setup != NULL) {
setup(data);
}
begin = gettimedouble();
benchmark(data);
total = gettimedouble() - begin;
if (teardown != NULL) {
teardown(data);
}
if (total < min) {
min = total;
}
if (total > max) {
max = total;
}
sum += total;
}
printf("%s: min ", name);
print_number(min * 1000000000.0 / iter);
printf("ns / avg ");
print_number((sum / count) * 1000000000.0 / iter);
printf("ns / max ");
print_number(max * 1000000000.0 / iter);
printf("ns\n");
}
static void bench_AES128_init(void* data) {
AES128_ctx* ctx = (AES128_ctx*)data;
int i;
for (i = 0; i < 50000; i++) {
AES128_init(ctx, (unsigned char*)ctx);
}
}
static void bench_AES128_encrypt_setup(void* data) {
AES128_ctx* ctx = (AES128_ctx*)data;
static const unsigned char key[16] = {0};
AES128_init(ctx, key);
}
static void bench_AES128_encrypt(void* data) {
const AES128_ctx* ctx = (const AES128_ctx*)data;
unsigned char scratch[16] = {0};
int i;
for (i = 0; i < 4000000 / 16; i++) {
AES128_encrypt(ctx, 1, scratch, scratch);
}
}
static void bench_AES128_decrypt(void* data) {
const AES128_ctx* ctx = (const AES128_ctx*)data;
unsigned char scratch[16] = {0};
int i;
for (i = 0; i < 4000000 / 16; i++) {
AES128_decrypt(ctx, 1, scratch, scratch);
}
}
static void bench_AES192_init(void* data) {
AES192_ctx* ctx = (AES192_ctx*)data;
int i;
for (i = 0; i < 50000; i++) {
AES192_init(ctx, (unsigned char*)ctx);
}
}
static void bench_AES192_encrypt_setup(void* data) {
AES192_ctx* ctx = (AES192_ctx*)data;
static const unsigned char key[16] = {0};
AES192_init(ctx, key);
}
static void bench_AES192_encrypt(void* data) {
const AES192_ctx* ctx = (const AES192_ctx*)data;
unsigned char scratch[16] = {0};
int i;
for (i = 0; i < 4000000 / 16; i++) {
AES192_encrypt(ctx, 1, scratch, scratch);
}
}
static void bench_AES192_decrypt(void* data) {
const AES192_ctx* ctx = (const AES192_ctx*)data;
unsigned char scratch[16] = {0};
int i;
for (i = 0; i < 4000000 / 16; i++) {
AES192_decrypt(ctx, 1, scratch, scratch);
}
}
static void bench_AES256_init(void* data) {
AES256_ctx* ctx = (AES256_ctx*)data;
int i;
for (i = 0; i < 50000; i++) {
AES256_init(ctx, (unsigned char*)ctx);
}
}
static void bench_AES256_encrypt_setup(void* data) {
AES256_ctx* ctx = (AES256_ctx*)data;
static const unsigned char key[16] = {0};
AES256_init(ctx, key);
}
static void bench_AES256_encrypt(void* data) {
const AES256_ctx* ctx = (const AES256_ctx*)data;
unsigned char scratch[16] = {0};
int i;
for (i = 0; i < 4000000 / 16; i++) {
AES256_encrypt(ctx, 1, scratch, scratch);
}
}
static void bench_AES256_decrypt(void* data) {
const AES256_ctx* ctx = (const AES256_ctx*)data;
unsigned char scratch[16] = {0};
int i;
for (i = 0; i < 4000000 / 16; i++) {
AES256_decrypt(ctx, 1, scratch, scratch);
}
}
int main(void) {
AES128_ctx ctx128;
AES192_ctx ctx192;
AES256_ctx ctx256;
run_benchmark("aes128_init", bench_AES128_init, NULL, NULL, &ctx128, 20, 50000);
run_benchmark("aes128_encrypt_byte", bench_AES128_encrypt, bench_AES128_encrypt_setup, NULL, &ctx128, 20, 4000000);
run_benchmark("aes128_decrypt_byte", bench_AES128_decrypt, bench_AES128_encrypt_setup, NULL, &ctx128, 20, 4000000);
run_benchmark("aes192_init", bench_AES192_init, NULL, NULL, &ctx192, 20, 50000);
run_benchmark("aes192_encrypt_byte", bench_AES192_encrypt, bench_AES192_encrypt_setup, NULL, &ctx192, 20, 4000000);
run_benchmark("aes192_decrypt_byte", bench_AES192_decrypt, bench_AES192_encrypt_setup, NULL, &ctx192, 20, 4000000);
run_benchmark("aes256_init", bench_AES256_init, NULL, NULL, &ctx256, 20, 50000);
run_benchmark("aes256_encrypt_byte", bench_AES256_encrypt, bench_AES256_encrypt_setup, NULL, &ctx256, 20, 4000000);
run_benchmark("aes256_decrypt_byte", bench_AES256_decrypt, bench_AES256_encrypt_setup, NULL, &ctx256, 20, 4000000);
return 0;
}

556
src/crypto/ctaes/ctaes.c Normal file
View File

@ -0,0 +1,556 @@
/*********************************************************************
* Copyright (c) 2016 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
/* Constant time, unoptimized, concise, plain C, AES implementation
* Based On:
* Emilia Kasper and Peter Schwabe, Faster and Timing-Attack Resistant AES-GCM
* http://www.iacr.org/archive/ches2009/57470001/57470001.pdf
* But using 8 16-bit integers representing a single AES state rather than 8 128-bit
* integers representing 8 AES states.
*/
#include "ctaes.h"
/* Slice variable slice_i contains the i'th bit of the 16 state variables in this order:
* 0 1 2 3
* 4 5 6 7
* 8 9 10 11
* 12 13 14 15
*/
/** Convert a byte to sliced form, storing it corresponding to given row and column in s */
static void LoadByte(AES_state* s, unsigned char byte, int r, int c) {
int i;
for (i = 0; i < 8; i++) {
s->slice[i] |= (byte & 1) << (r * 4 + c);
byte >>= 1;
}
}
/** Load 16 bytes of data into 8 sliced integers */
static void LoadBytes(AES_state *s, const unsigned char* data16) {
int c;
for (c = 0; c < 4; c++) {
int r;
for (r = 0; r < 4; r++) {
LoadByte(s, *(data16++), r, c);
}
}
}
/** Convert 8 sliced integers into 16 bytes of data */
static void SaveBytes(unsigned char* data16, const AES_state *s) {
int c;
for (c = 0; c < 4; c++) {
int r;
for (r = 0; r < 4; r++) {
int b;
uint8_t v = 0;
for (b = 0; b < 8; b++) {
v |= ((s->slice[b] >> (r * 4 + c)) & 1) << b;
}
*(data16++) = v;
}
}
}
/* S-box implementation based on the gate logic from:
* Joan Boyar and Rene Peralta, A depth-16 circuit for the AES S-box.
* https://eprint.iacr.org/2011/332.pdf
*/
static void SubBytes(AES_state *s, int inv) {
/* Load the bit slices */
uint16_t U0 = s->slice[7], U1 = s->slice[6], U2 = s->slice[5], U3 = s->slice[4];
uint16_t U4 = s->slice[3], U5 = s->slice[2], U6 = s->slice[1], U7 = s->slice[0];
uint16_t T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16;
uint16_t T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, D;
uint16_t M1, M6, M11, M13, M15, M20, M21, M22, M23, M25, M37, M38, M39, M40;
uint16_t M41, M42, M43, M44, M45, M46, M47, M48, M49, M50, M51, M52, M53, M54;
uint16_t M55, M56, M57, M58, M59, M60, M61, M62, M63;
if (inv) {
uint16_t R5, R13, R17, R18, R19;
/* Undo linear postprocessing */
T23 = U0 ^ U3;
T22 = ~(U1 ^ U3);
T2 = ~(U0 ^ U1);
T1 = U3 ^ U4;
T24 = ~(U4 ^ U7);
R5 = U6 ^ U7;
T8 = ~(U1 ^ T23);
T19 = T22 ^ R5;
T9 = ~(U7 ^ T1);
T10 = T2 ^ T24;
T13 = T2 ^ R5;
T3 = T1 ^ R5;
T25 = ~(U2 ^ T1);
R13 = U1 ^ U6;
T17 = ~(U2 ^ T19);
T20 = T24 ^ R13;
T4 = U4 ^ T8;
R17 = ~(U2 ^ U5);
R18 = ~(U5 ^ U6);
R19 = ~(U2 ^ U4);
D = U0 ^ R17;
T6 = T22 ^ R17;
T16 = R13 ^ R19;
T27 = T1 ^ R18;
T15 = T10 ^ T27;
T14 = T10 ^ R18;
T26 = T3 ^ T16;
} else {
/* Linear preprocessing. */
T1 = U0 ^ U3;
T2 = U0 ^ U5;
T3 = U0 ^ U6;
T4 = U3 ^ U5;
T5 = U4 ^ U6;
T6 = T1 ^ T5;
T7 = U1 ^ U2;
T8 = U7 ^ T6;
T9 = U7 ^ T7;
T10 = T6 ^ T7;
T11 = U1 ^ U5;
T12 = U2 ^ U5;
T13 = T3 ^ T4;
T14 = T6 ^ T11;
T15 = T5 ^ T11;
T16 = T5 ^ T12;
T17 = T9 ^ T16;
T18 = U3 ^ U7;
T19 = T7 ^ T18;
T20 = T1 ^ T19;
T21 = U6 ^ U7;
T22 = T7 ^ T21;
T23 = T2 ^ T22;
T24 = T2 ^ T10;
T25 = T20 ^ T17;
T26 = T3 ^ T16;
T27 = T1 ^ T12;
D = U7;
}
/* Non-linear transformation (shared between the forward and backward case) */
M1 = T13 & T6;
M6 = T3 & T16;
M11 = T1 & T15;
M13 = (T4 & T27) ^ M11;
M15 = (T2 & T10) ^ M11;
M20 = T14 ^ M1 ^ (T23 & T8) ^ M13;
M21 = (T19 & D) ^ M1 ^ T24 ^ M15;
M22 = T26 ^ M6 ^ (T22 & T9) ^ M13;
M23 = (T20 & T17) ^ M6 ^ M15 ^ T25;
M25 = M22 & M20;
M37 = M21 ^ ((M20 ^ M21) & (M23 ^ M25));
M38 = M20 ^ M25 ^ (M21 | (M20 & M23));
M39 = M23 ^ ((M22 ^ M23) & (M21 ^ M25));
M40 = M22 ^ M25 ^ (M23 | (M21 & M22));
M41 = M38 ^ M40;
M42 = M37 ^ M39;
M43 = M37 ^ M38;
M44 = M39 ^ M40;
M45 = M42 ^ M41;
M46 = M44 & T6;
M47 = M40 & T8;
M48 = M39 & D;
M49 = M43 & T16;
M50 = M38 & T9;
M51 = M37 & T17;
M52 = M42 & T15;
M53 = M45 & T27;
M54 = M41 & T10;
M55 = M44 & T13;
M56 = M40 & T23;
M57 = M39 & T19;
M58 = M43 & T3;
M59 = M38 & T22;
M60 = M37 & T20;
M61 = M42 & T1;
M62 = M45 & T4;
M63 = M41 & T2;
if (inv){
/* Undo linear preprocessing */
uint16_t P0 = M52 ^ M61;
uint16_t P1 = M58 ^ M59;
uint16_t P2 = M54 ^ M62;
uint16_t P3 = M47 ^ M50;
uint16_t P4 = M48 ^ M56;
uint16_t P5 = M46 ^ M51;
uint16_t P6 = M49 ^ M60;
uint16_t P7 = P0 ^ P1;
uint16_t P8 = M50 ^ M53;
uint16_t P9 = M55 ^ M63;
uint16_t P10 = M57 ^ P4;
uint16_t P11 = P0 ^ P3;
uint16_t P12 = M46 ^ M48;
uint16_t P13 = M49 ^ M51;
uint16_t P14 = M49 ^ M62;
uint16_t P15 = M54 ^ M59;
uint16_t P16 = M57 ^ M61;
uint16_t P17 = M58 ^ P2;
uint16_t P18 = M63 ^ P5;
uint16_t P19 = P2 ^ P3;
uint16_t P20 = P4 ^ P6;
uint16_t P22 = P2 ^ P7;
uint16_t P23 = P7 ^ P8;
uint16_t P24 = P5 ^ P7;
uint16_t P25 = P6 ^ P10;
uint16_t P26 = P9 ^ P11;
uint16_t P27 = P10 ^ P18;
uint16_t P28 = P11 ^ P25;
uint16_t P29 = P15 ^ P20;
s->slice[7] = P13 ^ P22;
s->slice[6] = P26 ^ P29;
s->slice[5] = P17 ^ P28;
s->slice[4] = P12 ^ P22;
s->slice[3] = P23 ^ P27;
s->slice[2] = P19 ^ P24;
s->slice[1] = P14 ^ P23;
s->slice[0] = P9 ^ P16;
} else {
/* Linear postprocessing */
uint16_t L0 = M61 ^ M62;
uint16_t L1 = M50 ^ M56;
uint16_t L2 = M46 ^ M48;
uint16_t L3 = M47 ^ M55;
uint16_t L4 = M54 ^ M58;
uint16_t L5 = M49 ^ M61;
uint16_t L6 = M62 ^ L5;
uint16_t L7 = M46 ^ L3;
uint16_t L8 = M51 ^ M59;
uint16_t L9 = M52 ^ M53;
uint16_t L10 = M53 ^ L4;
uint16_t L11 = M60 ^ L2;
uint16_t L12 = M48 ^ M51;
uint16_t L13 = M50 ^ L0;
uint16_t L14 = M52 ^ M61;
uint16_t L15 = M55 ^ L1;
uint16_t L16 = M56 ^ L0;
uint16_t L17 = M57 ^ L1;
uint16_t L18 = M58 ^ L8;
uint16_t L19 = M63 ^ L4;
uint16_t L20 = L0 ^ L1;
uint16_t L21 = L1 ^ L7;
uint16_t L22 = L3 ^ L12;
uint16_t L23 = L18 ^ L2;
uint16_t L24 = L15 ^ L9;
uint16_t L25 = L6 ^ L10;
uint16_t L26 = L7 ^ L9;
uint16_t L27 = L8 ^ L10;
uint16_t L28 = L11 ^ L14;
uint16_t L29 = L11 ^ L17;
s->slice[7] = L6 ^ L24;
s->slice[6] = ~(L16 ^ L26);
s->slice[5] = ~(L19 ^ L28);
s->slice[4] = L6 ^ L21;
s->slice[3] = L20 ^ L22;
s->slice[2] = L25 ^ L29;
s->slice[1] = ~(L13 ^ L27);
s->slice[0] = ~(L6 ^ L23);
}
}
#define BIT_RANGE(from,to) (((1 << ((to) - (from))) - 1) << (from))
#define BIT_RANGE_LEFT(x,from,to,shift) (((x) & BIT_RANGE((from), (to))) << (shift))
#define BIT_RANGE_RIGHT(x,from,to,shift) (((x) & BIT_RANGE((from), (to))) >> (shift))
static void ShiftRows(AES_state* s) {
int i;
for (i = 0; i < 8; i++) {
uint16_t v = s->slice[i];
s->slice[i] =
(v & BIT_RANGE(0, 4)) |
BIT_RANGE_LEFT(v, 4, 5, 3) | BIT_RANGE_RIGHT(v, 5, 8, 1) |
BIT_RANGE_LEFT(v, 8, 10, 2) | BIT_RANGE_RIGHT(v, 10, 12, 2) |
BIT_RANGE_LEFT(v, 12, 15, 1) | BIT_RANGE_RIGHT(v, 15, 16, 3);
}
}
static void InvShiftRows(AES_state* s) {
int i;
for (i = 0; i < 8; i++) {
uint16_t v = s->slice[i];
s->slice[i] =
(v & BIT_RANGE(0, 4)) |
BIT_RANGE_LEFT(v, 4, 7, 1) | BIT_RANGE_RIGHT(v, 7, 8, 3) |
BIT_RANGE_LEFT(v, 8, 10, 2) | BIT_RANGE_RIGHT(v, 10, 12, 2) |
BIT_RANGE_LEFT(v, 12, 13, 3) | BIT_RANGE_RIGHT(v, 13, 16, 1);
}
}
#define ROT(x,b) (((x) >> ((b) * 4)) | ((x) << ((4-(b)) * 4)))
static void MixColumns(AES_state* s, int inv) {
/* The MixColumns transform treats the bytes of the columns of the state as
* coefficients of a 3rd degree polynomial over GF(2^8) and multiplies them
* by the fixed polynomial a(x) = {03}x^3 + {01}x^2 + {01}x + {02}, modulo
* x^4 + {01}.
*
* In the inverse transform, we multiply by the inverse of a(x),
* a^-1(x) = {0b}x^3 + {0d}x^2 + {09}x + {0e}. This is equal to
* a(x) * ({04}x^2 + {05}), so we can reuse the forward transform's code
* (found in OpenSSL's bsaes-x86_64.pl, attributed to Jussi Kivilinna)
*
* In the bitsliced representation, a multiplication of every column by x
* mod x^4 + 1 is simply a right rotation.
*/
/* Shared for both directions is a multiplication by a(x), which can be
* rewritten as (x^3 + x^2 + x) + {02}*(x^3 + {01}).
*
* First compute s into the s? variables, (x^3 + {01}) * s into the s?_01
* variables and (x^3 + x^2 + x)*s into the s?_123 variables.
*/
uint16_t s0 = s->slice[0], s1 = s->slice[1], s2 = s->slice[2], s3 = s->slice[3];
uint16_t s4 = s->slice[4], s5 = s->slice[5], s6 = s->slice[6], s7 = s->slice[7];
uint16_t s0_01 = s0 ^ ROT(s0, 1), s0_123 = ROT(s0_01, 1) ^ ROT(s0, 3);
uint16_t s1_01 = s1 ^ ROT(s1, 1), s1_123 = ROT(s1_01, 1) ^ ROT(s1, 3);
uint16_t s2_01 = s2 ^ ROT(s2, 1), s2_123 = ROT(s2_01, 1) ^ ROT(s2, 3);
uint16_t s3_01 = s3 ^ ROT(s3, 1), s3_123 = ROT(s3_01, 1) ^ ROT(s3, 3);
uint16_t s4_01 = s4 ^ ROT(s4, 1), s4_123 = ROT(s4_01, 1) ^ ROT(s4, 3);
uint16_t s5_01 = s5 ^ ROT(s5, 1), s5_123 = ROT(s5_01, 1) ^ ROT(s5, 3);
uint16_t s6_01 = s6 ^ ROT(s6, 1), s6_123 = ROT(s6_01, 1) ^ ROT(s6, 3);
uint16_t s7_01 = s7 ^ ROT(s7, 1), s7_123 = ROT(s7_01, 1) ^ ROT(s7, 3);
/* Now compute s = s?_123 + {02} * s?_01. */
s->slice[0] = s7_01 ^ s0_123;
s->slice[1] = s7_01 ^ s0_01 ^ s1_123;
s->slice[2] = s1_01 ^ s2_123;
s->slice[3] = s7_01 ^ s2_01 ^ s3_123;
s->slice[4] = s7_01 ^ s3_01 ^ s4_123;
s->slice[5] = s4_01 ^ s5_123;
s->slice[6] = s5_01 ^ s6_123;
s->slice[7] = s6_01 ^ s7_123;
if (inv) {
/* In the reverse direction, we further need to multiply by
* {04}x^2 + {05}, which can be written as {04} * (x^2 + {01}) + {01}.
*
* First compute (x^2 + {01}) * s into the t?_02 variables: */
uint16_t t0_02 = s->slice[0] ^ ROT(s->slice[0], 2);
uint16_t t1_02 = s->slice[1] ^ ROT(s->slice[1], 2);
uint16_t t2_02 = s->slice[2] ^ ROT(s->slice[2], 2);
uint16_t t3_02 = s->slice[3] ^ ROT(s->slice[3], 2);
uint16_t t4_02 = s->slice[4] ^ ROT(s->slice[4], 2);
uint16_t t5_02 = s->slice[5] ^ ROT(s->slice[5], 2);
uint16_t t6_02 = s->slice[6] ^ ROT(s->slice[6], 2);
uint16_t t7_02 = s->slice[7] ^ ROT(s->slice[7], 2);
/* And then update s += {04} * t?_02 */
s->slice[0] ^= t6_02;
s->slice[1] ^= t6_02 ^ t7_02;
s->slice[2] ^= t0_02 ^ t7_02;
s->slice[3] ^= t1_02 ^ t6_02;
s->slice[4] ^= t2_02 ^ t6_02 ^ t7_02;
s->slice[5] ^= t3_02 ^ t7_02;
s->slice[6] ^= t4_02;
s->slice[7] ^= t5_02;
}
}
static void AddRoundKey(AES_state* s, const AES_state* round) {
int b;
for (b = 0; b < 8; b++) {
s->slice[b] ^= round->slice[b];
}
}
/** column_0(s) = column_c(a) */
static void GetOneColumn(AES_state* s, const AES_state* a, int c) {
int b;
for (b = 0; b < 8; b++) {
s->slice[b] = (a->slice[b] >> c) & 0x1111;
}
}
/** column_c1(r) |= (column_0(s) ^= column_c2(a)) */
static void KeySetupColumnMix(AES_state* s, AES_state* r, const AES_state* a, int c1, int c2) {
int b;
for (b = 0; b < 8; b++) {
r->slice[b] |= ((s->slice[b] ^= ((a->slice[b] >> c2) & 0x1111)) & 0x1111) << c1;
}
}
/** Rotate the rows in s one position upwards, and xor in r */
static void KeySetupTransform(AES_state* s, const AES_state* r) {
int b;
for (b = 0; b < 8; b++) {
s->slice[b] = ((s->slice[b] >> 4) | (s->slice[b] << 12)) ^ r->slice[b];
}
}
/* Multiply the cells in s by x, as polynomials over GF(2) mod x^8 + x^4 + x^3 + x + 1 */
static void MultX(AES_state* s) {
uint16_t top = s->slice[7];
s->slice[7] = s->slice[6];
s->slice[6] = s->slice[5];
s->slice[5] = s->slice[4];
s->slice[4] = s->slice[3] ^ top;
s->slice[3] = s->slice[2] ^ top;
s->slice[2] = s->slice[1];
s->slice[1] = s->slice[0] ^ top;
s->slice[0] = top;
}
/** Expand the cipher key into the key schedule.
*
* state must be a pointer to an array of size nrounds + 1.
* key must be a pointer to 4 * nkeywords bytes.
*
* AES128 uses nkeywords = 4, nrounds = 10
* AES192 uses nkeywords = 6, nrounds = 12
* AES256 uses nkeywords = 8, nrounds = 14
*/
static void AES_setup(AES_state* rounds, const uint8_t* key, int nkeywords, int nrounds)
{
int i;
/* The one-byte round constant */
AES_state rcon = {{1,0,0,0,0,0,0,0}};
/* The number of the word being generated, modulo nkeywords */
int pos = 0;
/* The column representing the word currently being processed */
AES_state column;
for (i = 0; i < nrounds + 1; i++) {
int b;
for (b = 0; b < 8; b++) {
rounds[i].slice[b] = 0;
}
}
/* The first nkeywords round columns are just taken from the key directly. */
for (i = 0; i < nkeywords; i++) {
int r;
for (r = 0; r < 4; r++) {
LoadByte(&rounds[i >> 2], *(key++), r, i & 3);
}
}
GetOneColumn(&column, &rounds[(nkeywords - 1) >> 2], (nkeywords - 1) & 3);
for (i = nkeywords; i < 4 * (nrounds + 1); i++) {
/* Transform column */
if (pos == 0) {
SubBytes(&column, 0);
KeySetupTransform(&column, &rcon);
MultX(&rcon);
} else if (nkeywords > 6 && pos == 4) {
SubBytes(&column, 0);
}
if (++pos == nkeywords) pos = 0;
KeySetupColumnMix(&column, &rounds[i >> 2], &rounds[(i - nkeywords) >> 2], i & 3, (i - nkeywords) & 3);
}
}
static void AES_encrypt(const AES_state* rounds, int nrounds, unsigned char* cipher16, const unsigned char* plain16) {
AES_state s = {{0}};
int round;
LoadBytes(&s, plain16);
AddRoundKey(&s, rounds++);
for (round = 1; round < nrounds; round++) {
SubBytes(&s, 0);
ShiftRows(&s);
MixColumns(&s, 0);
AddRoundKey(&s, rounds++);
}
SubBytes(&s, 0);
ShiftRows(&s);
AddRoundKey(&s, rounds);
SaveBytes(cipher16, &s);
}
static void AES_decrypt(const AES_state* rounds, int nrounds, unsigned char* plain16, const unsigned char* cipher16) {
/* Most AES decryption implementations use the alternate scheme
* (the Equivalent Inverse Cipher), which allows for more code reuse between
* the encryption and decryption code, but requires separate setup for both.
*/
AES_state s = {{0}};
int round;
rounds += nrounds;
LoadBytes(&s, cipher16);
AddRoundKey(&s, rounds--);
for (round = 1; round < nrounds; round++) {
InvShiftRows(&s);
SubBytes(&s, 1);
AddRoundKey(&s, rounds--);
MixColumns(&s, 1);
}
InvShiftRows(&s);
SubBytes(&s, 1);
AddRoundKey(&s, rounds);
SaveBytes(plain16, &s);
}
void AES128_init(AES128_ctx* ctx, const unsigned char* key16) {
AES_setup(ctx->rk, key16, 4, 10);
}
void AES128_encrypt(const AES128_ctx* ctx, size_t blocks, unsigned char* cipher16, const unsigned char* plain16) {
while (blocks--) {
AES_encrypt(ctx->rk, 10, cipher16, plain16);
cipher16 += 16;
plain16 += 16;
}
}
void AES128_decrypt(const AES128_ctx* ctx, size_t blocks, unsigned char* plain16, const unsigned char* cipher16) {
while (blocks--) {
AES_decrypt(ctx->rk, 10, plain16, cipher16);
cipher16 += 16;
plain16 += 16;
}
}
void AES192_init(AES192_ctx* ctx, const unsigned char* key24) {
AES_setup(ctx->rk, key24, 6, 12);
}
void AES192_encrypt(const AES192_ctx* ctx, size_t blocks, unsigned char* cipher16, const unsigned char* plain16) {
while (blocks--) {
AES_encrypt(ctx->rk, 12, cipher16, plain16);
cipher16 += 16;
plain16 += 16;
}
}
void AES192_decrypt(const AES192_ctx* ctx, size_t blocks, unsigned char* plain16, const unsigned char* cipher16) {
while (blocks--) {
AES_decrypt(ctx->rk, 12, plain16, cipher16);
cipher16 += 16;
plain16 += 16;
}
}
void AES256_init(AES256_ctx* ctx, const unsigned char* key32) {
AES_setup(ctx->rk, key32, 8, 14);
}
void AES256_encrypt(const AES256_ctx* ctx, size_t blocks, unsigned char* cipher16, const unsigned char* plain16) {
while (blocks--) {
AES_encrypt(ctx->rk, 14, cipher16, plain16);
cipher16 += 16;
plain16 += 16;
}
}
void AES256_decrypt(const AES256_ctx* ctx, size_t blocks, unsigned char* plain16, const unsigned char* cipher16) {
while (blocks--) {
AES_decrypt(ctx->rk, 14, plain16, cipher16);
cipher16 += 16;
plain16 += 16;
}
}

41
src/crypto/ctaes/ctaes.h Normal file
View File

@ -0,0 +1,41 @@
/*********************************************************************
* Copyright (c) 2016 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
#ifndef _CTAES_H_
#define _CTAES_H_ 1
#include <stdint.h>
#include <stdlib.h>
typedef struct {
uint16_t slice[8];
} AES_state;
typedef struct {
AES_state rk[11];
} AES128_ctx;
typedef struct {
AES_state rk[13];
} AES192_ctx;
typedef struct {
AES_state rk[15];
} AES256_ctx;
void AES128_init(AES128_ctx* ctx, const unsigned char* key16);
void AES128_encrypt(const AES128_ctx* ctx, size_t blocks, unsigned char* cipher16, const unsigned char* plain16);
void AES128_decrypt(const AES128_ctx* ctx, size_t blocks, unsigned char* plain16, const unsigned char* cipher16);
void AES192_init(AES192_ctx* ctx, const unsigned char* key24);
void AES192_encrypt(const AES192_ctx* ctx, size_t blocks, unsigned char* cipher16, const unsigned char* plain16);
void AES192_decrypt(const AES192_ctx* ctx, size_t blocks, unsigned char* plain16, const unsigned char* cipher16);
void AES256_init(AES256_ctx* ctx, const unsigned char* key32);
void AES256_encrypt(const AES256_ctx* ctx, size_t blocks, unsigned char* cipher16, const unsigned char* plain16);
void AES256_decrypt(const AES256_ctx* ctx, size_t blocks, unsigned char* plain16, const unsigned char* cipher16);
#endif

110
src/crypto/ctaes/test.c Normal file
View File

@ -0,0 +1,110 @@
/*********************************************************************
* Copyright (c) 2016 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
#include "ctaes.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
typedef struct {
int keysize;
const char* key;
const char* plain;
const char* cipher;
} ctaes_test;
static const ctaes_test ctaes_tests[] = {
/* AES test vectors from FIPS 197. */
{128, "000102030405060708090a0b0c0d0e0f", "00112233445566778899aabbccddeeff", "69c4e0d86a7b0430d8cdb78070b4c55a"},
{192, "000102030405060708090a0b0c0d0e0f1011121314151617", "00112233445566778899aabbccddeeff", "dda97ca4864cdfe06eaf70a0ec0d7191"},
{256, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "00112233445566778899aabbccddeeff", "8ea2b7ca516745bfeafc49904b496089"},
/* AES-ECB test vectors from NIST sp800-38a. */
{128, "2b7e151628aed2a6abf7158809cf4f3c", "6bc1bee22e409f96e93d7e117393172a", "3ad77bb40d7a3660a89ecaf32466ef97"},
{128, "2b7e151628aed2a6abf7158809cf4f3c", "ae2d8a571e03ac9c9eb76fac45af8e51", "f5d3d58503b9699de785895a96fdbaaf"},
{128, "2b7e151628aed2a6abf7158809cf4f3c", "30c81c46a35ce411e5fbc1191a0a52ef", "43b1cd7f598ece23881b00e3ed030688"},
{128, "2b7e151628aed2a6abf7158809cf4f3c", "f69f2445df4f9b17ad2b417be66c3710", "7b0c785e27e8ad3f8223207104725dd4"},
{192, "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", "6bc1bee22e409f96e93d7e117393172a", "bd334f1d6e45f25ff712a214571fa5cc"},
{192, "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", "ae2d8a571e03ac9c9eb76fac45af8e51", "974104846d0ad3ad7734ecb3ecee4eef"},
{192, "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", "30c81c46a35ce411e5fbc1191a0a52ef", "ef7afd2270e2e60adce0ba2face6444e"},
{192, "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", "f69f2445df4f9b17ad2b417be66c3710", "9a4b41ba738d6c72fb16691603c18e0e"},
{256, "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "6bc1bee22e409f96e93d7e117393172a", "f3eed1bdb5d2a03c064b5a7e3db181f8"},
{256, "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "ae2d8a571e03ac9c9eb76fac45af8e51", "591ccb10d410ed26dc5ba74a31362870"},
{256, "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "30c81c46a35ce411e5fbc1191a0a52ef", "b6ed21b99ca6f4f9f153e7b1beafed1d"},
{256, "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "f69f2445df4f9b17ad2b417be66c3710", "23304b7a39f9f3ff067d8d8f9e24ecc7"}
};
static void from_hex(unsigned char* data, int len, const char* hex) {
int p;
for (p = 0; p < len; p++) {
int v = 0;
int n;
for (n = 0; n < 2; n++) {
assert((*hex >= '0' && *hex <= '9') || (*hex >= 'a' && *hex <= 'f'));
if (*hex >= '0' && *hex <= '9') {
v |= (*hex - '0') << (4 * (1 - n));
} else {
v |= (*hex - 'a' + 10) << (4 * (1 - n));
}
hex++;
}
*(data++) = v;
}
assert(*hex == 0);
}
int main(void) {
int i;
int fail = 0;
for (i = 0; i < sizeof(ctaes_tests) / sizeof(ctaes_tests[0]); i++) {
unsigned char key[32], plain[16], cipher[16], ciphered[16], deciphered[16];
const ctaes_test* test = &ctaes_tests[i];
assert(test->keysize == 128 || test->keysize == 192 || test->keysize == 256);
from_hex(plain, 16, test->plain);
from_hex(cipher, 16, test->cipher);
switch (test->keysize) {
case 128: {
AES128_ctx ctx;
from_hex(key, 16, test->key);
AES128_init(&ctx, key);
AES128_encrypt(&ctx, 1, ciphered, plain);
AES128_decrypt(&ctx, 1, deciphered, cipher);
break;
}
case 192: {
AES192_ctx ctx;
from_hex(key, 24, test->key);
AES192_init(&ctx, key);
AES192_encrypt(&ctx, 1, ciphered, plain);
AES192_decrypt(&ctx, 1, deciphered, cipher);
break;
}
case 256: {
AES256_ctx ctx;
from_hex(key, 32, test->key);
AES256_init(&ctx, key);
AES256_encrypt(&ctx, 1, ciphered, plain);
AES256_decrypt(&ctx, 1, deciphered, cipher);
break;
}
}
if (memcmp(cipher, ciphered, 16)) {
fprintf(stderr, "E(key=\"%s\", plain=\"%s\") != \"%s\"\n", test->key, test->plain, test->cipher);
fail++;
}
if (memcmp(plain, deciphered, 16)) {
fprintf(stderr, "D(key=\"%s\", cipher=\"%s\") != \"%s\"\n", test->key, test->cipher, test->plain);
fail++;
}
}
if (fail == 0) {
fprintf(stderr, "All tests successful\n");
} else {
fprintf(stderr, "%i tests failed\n", fail);
}
return (fail != 0);
}

View File

@ -1,5 +1,6 @@
#include "consensus/validation.h"
#include "chainparams.h"
#include "proof_verifier.h"
int main (int argc, char *argv[]) {
int retval = 0;
@ -18,7 +19,7 @@ int main (int argc, char *argv[]) {
// valid blocks with shielded transactions will generate a crash.
const CChainParams& chainparams = Params();
auto verifier = libzcash::ProofVerifier::Disabled();
auto verifier = ProofVerifier::Disabled();
CValidationState state;
// We don't check the PoW or Merkle tree root in order to reach more code.
if (!CheckBlock(block, state, chainparams, verifier, false, false)) {

View File

@ -2,7 +2,6 @@
#include "crypto/common.h"
#include "key.h"
#include "pubkey.h"
#include "zcash/JoinSplit.hpp"
#include "util.h"
#include "librustzcash.h"
@ -14,14 +13,10 @@ struct ECCryptoClosure
ECCryptoClosure instance_of_eccryptoclosure;
ZCJoinSplit* params;
int main(int argc, char **argv) {
assert(init_and_check_sodium() != -1);
ECC_Start();
params = ZCJoinSplit::Prepared();
boost::filesystem::path sapling_spend = ZC_GetParamsDir() / "sapling-spend.params";
boost::filesystem::path sapling_output = ZC_GetParamsDir() / "sapling-output.params";
boost::filesystem::path sprout_groth16 = ZC_GetParamsDir() / "sprout-groth16.params";

View File

@ -3,6 +3,7 @@
#include "consensus/validation.h"
#include "main.h"
#include "proof_verifier.h"
#include "utiltest.h"
#include "zcash/Proof.hpp"
@ -24,7 +25,7 @@ public:
};
TEST(CheckBlock, VersionTooLow) {
auto verifier = libzcash::ProofVerifier::Strict();
auto verifier = ProofVerifier::Strict();
CBlock block;
block.nVersion = 1;
@ -61,7 +62,7 @@ TEST(CheckBlock, BlockSproutRejectsBadVersion) {
MockCValidationState state;
CBlockIndex indexPrev {Params().GenesisBlock()};
auto verifier = libzcash::ProofVerifier::Strict();
auto verifier = ProofVerifier::Strict();
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-version-too-low", false)).Times(1);
EXPECT_FALSE(CheckBlock(block, state, Params(), verifier, false, false));

View File

@ -11,8 +11,6 @@
#include <librustzcash.h>
extern ZCJoinSplit* params;
TEST(ChecktransactionTests, CheckVpubNotBothNonzero) {
CMutableTransaction tx;
tx.nVersion = 2;
@ -831,7 +829,7 @@ TEST(ChecktransactionTests, SaplingSproutInputSumsTooLarge) {
std::array<size_t, ZC_NUM_JS_OUTPUTS> outputMap;
auto jsdesc = JSDescription::Randomized(
*params, joinSplitPubKey, rt,
joinSplitPubKey, rt,
inputs, outputs,
inputMap, outputMap,
0, 0, false);

View File

@ -11,8 +11,6 @@
#include "transaction_builder.h"
#include "utiltest.h"
extern ZCJoinSplit* params;
TEST(RecursiveDynamicUsageTests, TestTransactionTransparent)
{
auto consensusParams = RegtestActivateSapling();
@ -40,7 +38,7 @@ TEST(RecursiveDynamicUsageTests, TestTransactionJoinSplit)
auto sproutSk = libzcash::SproutSpendingKey::random();
auto wtx = GetValidSproutReceive(*params, sproutSk, 25000, true);
auto wtx = GetValidSproutReceive(sproutSk, 25000, true);
// 2 vin + 1 vJoinSplit + 1 vShieldedOutput
// 160 + 1856 + 976
EXPECT_EQ(2992, RecursiveDynamicUsage(wtx));

View File

@ -11,6 +11,7 @@
#include "version.h"
#include "serialize.h"
#include "primitives/transaction.h"
#include "proof_verifier.h"
#include "zcash/JoinSplit.hpp"
#include "zcash/Note.hpp"
#include "zcash/NoteEncryption.hpp"
@ -20,12 +21,9 @@
using namespace libzcash;
extern ZCJoinSplit* params;
// Make the Groth proof for a Sprout statement,
// and store the result in a JSDescription object.
JSDescription makeSproutProof(
ZCJoinSplit& js,
const std::array<JSInput, 2>& inputs,
const std::array<JSOutput, 2>& outputs,
const uint256& joinSplitPubKey,
@ -33,24 +31,23 @@ JSDescription makeSproutProof(
uint64_t vpub_new,
const uint256& rt
){
return JSDescription(js, joinSplitPubKey, rt, inputs, outputs, vpub_old, vpub_new);
return JSDescription(joinSplitPubKey, rt, inputs, outputs, vpub_old, vpub_new);
}
bool verifySproutProof(
ZCJoinSplit& js,
const JSDescription& jsdesc,
const uint256& joinSplitPubKey
)
{
auto verifier = libzcash::ProofVerifier::Strict();
return jsdesc.Verify(js, verifier, joinSplitPubKey);
auto verifier = ProofVerifier::Strict();
return verifier.VerifySprout(jsdesc, joinSplitPubKey);
}
void test_full_api(ZCJoinSplit* js)
void test_full_api()
{
// Create verification context.
auto verifier = libzcash::ProofVerifier::Strict();
auto verifier = ProofVerifier::Strict();
// The recipient's information.
SproutSpendingKey recipient_key = SproutSpendingKey::random();
@ -81,7 +78,6 @@ void test_full_api(ZCJoinSplit* js)
// Perform the proofs
jsdesc = makeSproutProof(
*js,
inputs,
outputs,
joinSplitPubKey,
@ -92,14 +88,14 @@ void test_full_api(ZCJoinSplit* js)
}
// Verify both PHGR and Groth Proof:
ASSERT_TRUE(verifySproutProof(*js, jsdesc, joinSplitPubKey));
ASSERT_TRUE(verifySproutProof(jsdesc, joinSplitPubKey));
{
SproutMerkleTree tree;
JSDescription jsdesc2;
// Recipient should decrypt
// Now the recipient should spend the money again
auto h_sig = js->h_sig(jsdesc.randomSeed, jsdesc.nullifiers, joinSplitPubKey);
auto h_sig = ZCJoinSplit::h_sig(jsdesc.randomSeed, jsdesc.nullifiers, joinSplitPubKey);
ZCNoteDecryption decryptor(recipient_key.receiving_key());
auto note_pt = SproutNotePlaintext::decrypt(
@ -143,7 +139,6 @@ void test_full_api(ZCJoinSplit* js)
// Perform the proofs
jsdesc2 = makeSproutProof(
*js,
inputs,
outputs,
joinSplitPubKey2,
@ -156,14 +151,13 @@ void test_full_api(ZCJoinSplit* js)
// Verify Groth Proof:
ASSERT_TRUE(verifySproutProof(*js, jsdesc2, joinSplitPubKey2));
ASSERT_TRUE(verifySproutProof(jsdesc2, joinSplitPubKey2));
}
}
// Invokes the API (but does not compute a proof)
// to test exceptions
void invokeAPI(
ZCJoinSplit* js,
const std::array<JSInput, 2>& inputs,
const std::array<JSOutput, 2>& outputs,
uint64_t vpub_old,
@ -181,7 +175,7 @@ void invokeAPI(
std::array<SproutNote, 2> output_notes;
// Groth
SproutProof proof = js->prove(
SproutProof proof = ZCJoinSplit::prove(
inputs,
outputs,
output_notes,
@ -200,7 +194,6 @@ void invokeAPI(
}
void invokeAPIFailure(
ZCJoinSplit* js,
const std::array<JSInput, 2>& inputs,
const std::array<JSOutput, 2>& outputs,
uint64_t vpub_old,
@ -210,7 +203,7 @@ void invokeAPIFailure(
)
{
try {
invokeAPI(js, inputs, outputs, vpub_old, vpub_new, rt);
invokeAPI(inputs, outputs, vpub_old, vpub_new, rt);
FAIL() << "It worked, when it shouldn't have!";
} catch(std::invalid_argument const & err) {
EXPECT_EQ(err.what(), reason);
@ -327,7 +320,7 @@ TEST(Joinsplit, FullApiTest)
increment_note_witnesses(note5.cm(), witnesses, tree);
// Should work
invokeAPI(params,
invokeAPI(
{
JSInput(),
JSInput()
@ -341,7 +334,7 @@ TEST(Joinsplit, FullApiTest)
tree.root());
// lhs > MAX_MONEY
invokeAPIFailure(params,
invokeAPIFailure(
{
JSInput(),
JSInput()
@ -356,7 +349,7 @@ TEST(Joinsplit, FullApiTest)
"nonsensical vpub_old value");
// rhs > MAX_MONEY
invokeAPIFailure(params,
invokeAPIFailure(
{
JSInput(),
JSInput()
@ -371,7 +364,7 @@ TEST(Joinsplit, FullApiTest)
"nonsensical vpub_new value");
// input witness for the wrong element
invokeAPIFailure(params,
invokeAPIFailure(
{
JSInput(witnesses[0], note1, sk),
JSInput()
@ -387,7 +380,7 @@ TEST(Joinsplit, FullApiTest)
// input witness doesn't match up with
// real root
invokeAPIFailure(params,
invokeAPIFailure(
{
JSInput(witnesses[1], note1, sk),
JSInput()
@ -402,7 +395,7 @@ TEST(Joinsplit, FullApiTest)
"joinsplit not anchored to the correct root");
// input is in the tree now! this should work
invokeAPI(params,
invokeAPI(
{
JSInput(witnesses[1], note1, sk),
JSInput()
@ -416,7 +409,7 @@ TEST(Joinsplit, FullApiTest)
tree.root());
// Wrong secret key
invokeAPIFailure(params,
invokeAPIFailure(
{
JSInput(witnesses[1], note1, SproutSpendingKey::random()),
JSInput()
@ -431,7 +424,7 @@ TEST(Joinsplit, FullApiTest)
"input note not authorized to spend with given key");
// Absurd input value
invokeAPIFailure(params,
invokeAPIFailure(
{
JSInput(witnesses[3], note3, sk),
JSInput()
@ -446,7 +439,7 @@ TEST(Joinsplit, FullApiTest)
"nonsensical input note value");
// Absurd total input value
invokeAPIFailure(params,
invokeAPIFailure(
{
JSInput(witnesses[4], note4, sk),
JSInput(witnesses[5], note5, sk)
@ -461,7 +454,7 @@ TEST(Joinsplit, FullApiTest)
"nonsensical left hand size of joinsplit balance");
// Absurd output value
invokeAPIFailure(params,
invokeAPIFailure(
{
JSInput(),
JSInput()
@ -476,7 +469,7 @@ TEST(Joinsplit, FullApiTest)
"nonsensical output value");
// Absurd total output value
invokeAPIFailure(params,
invokeAPIFailure(
{
JSInput(),
JSInput()
@ -491,7 +484,7 @@ TEST(Joinsplit, FullApiTest)
"nonsensical right hand side of joinsplit balance");
// Absurd total output value
invokeAPIFailure(params,
invokeAPIFailure(
{
JSInput(),
JSInput()
@ -506,7 +499,7 @@ TEST(Joinsplit, FullApiTest)
"invalid joinsplit balance");
}
test_full_api(params);
test_full_api();
}
TEST(Joinsplit, NotePlaintexts)

View File

@ -6,7 +6,6 @@
#include <array>
extern ZCJoinSplit* params;
extern int GenZero(int n);
extern int GenMax(int n);
@ -45,7 +44,7 @@ TEST(Transaction, JSDescriptionRandomized) {
{
auto jsdesc = JSDescription::Randomized(
*params, joinSplitPubKey, rt,
joinSplitPubKey, rt,
inputs, outputs,
inputMap, outputMap,
0, 0, false);
@ -61,7 +60,7 @@ TEST(Transaction, JSDescriptionRandomized) {
{
auto jsdesc = JSDescription::Randomized(
*params, joinSplitPubKey, rt,
joinSplitPubKey, rt,
inputs, outputs,
inputMap, outputMap,
0, 0, false, nullptr, GenZero);
@ -74,7 +73,7 @@ TEST(Transaction, JSDescriptionRandomized) {
{
auto jsdesc = JSDescription::Randomized(
*params, joinSplitPubKey, rt,
joinSplitPubKey, rt,
inputs, outputs,
inputMap, outputMap,
0, 0, false, nullptr, GenMax);

View File

@ -13,8 +13,6 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
extern ZCJoinSplit* params;
// Fake an empty view
class TransactionBuilderCoinsViewDB : public CCoinsView {
public:
@ -167,7 +165,7 @@ TEST(TransactionBuilder, SaplingToSprout) {
// - 0.0004 Sapling-ZEC in - 0.00025 Sprout-ZEC out
// - 0.00005 Sapling-ZEC change
// - 0.0001 t-ZEC fee
auto builder = TransactionBuilder(consensusParams, 2, nullptr, params);
auto builder = TransactionBuilder(consensusParams, 2, nullptr);
builder.AddSaplingSpend(expsk, testNote.note, testNote.tree.root(), testNote.tree.witness());
builder.AddSproutOutput(sproutAddr, 25000);
auto tx = builder.Build().GetTxOrThrow();
@ -199,8 +197,8 @@ TEST(TransactionBuilder, SproutToSproutAndSapling) {
auto sproutSk = libzcash::SproutSpendingKey::random();
auto sproutAddr = sproutSk.address();
auto wtx = GetValidSproutReceive(*params, sproutSk, 25000, true);
auto sproutNote = GetSproutNote(*params, sproutSk, wtx, 0, 1);
auto wtx = GetValidSproutReceive(sproutSk, 25000, true);
auto sproutNote = GetSproutNote(sproutSk, wtx, 0, 1);
SproutMerkleTree sproutTree;
for (int i = 0; i < ZC_NUM_JS_OUTPUTS; i++) {
@ -219,7 +217,7 @@ TEST(TransactionBuilder, SproutToSproutAndSapling) {
// - 0.00005 Sprout-ZEC change
// - 0.00005 Sapling-ZEC out
// - 0.00005 t-ZEC fee
auto builder = TransactionBuilder(consensusParams, 2, nullptr, params, &view);
auto builder = TransactionBuilder(consensusParams, 2, nullptr, &view);
builder.SetFee(5000);
builder.AddSproutInput(sproutSk, sproutNote, sproutWitness);
builder.AddSproutOutput(sproutAddr, 6000);
@ -250,16 +248,6 @@ TEST(TransactionBuilder, SproutToSproutAndSapling) {
RegtestDeactivateSapling();
}
TEST(TransactionBuilder, ThrowsOnSproutOutputWithoutParams)
{
auto consensusParams = Params().GetConsensus();
auto sk = libzcash::SproutSpendingKey::random();
auto addr = sk.address();
auto builder = TransactionBuilder(consensusParams, 1);
ASSERT_THROW(builder.AddSproutOutput(addr, 10), std::runtime_error);
}
TEST(TransactionBuilder, ThrowsOnTransparentInputWithoutKeyStore)
{
SelectParams(CBaseChainParams::REGTEST);

View File

@ -7,8 +7,6 @@
#include "transaction_builder.h"
#include "utiltest.h"
extern ZCJoinSplit* params;
extern bool ReceivedBlockTransactions(
const CBlock &block,
CValidationState& state,
@ -221,14 +219,14 @@ TEST(Validation, ReceivedBlockTransactions) {
// Create a fake genesis block
CBlock block1;
block1.vtx.push_back(GetValidSproutReceive(*params, sk, 5, true));
block1.vtx.push_back(GetValidSproutReceive(sk, 5, true));
block1.hashMerkleRoot = block1.BuildMerkleTree();
CBlockIndex fakeIndex1 {block1};
// Create a fake child block
CBlock block2;
block2.hashPrevBlock = block1.GetHash();
block2.vtx.push_back(GetValidSproutReceive(*params, sk, 10, true));
block2.vtx.push_back(GetValidSproutReceive(sk, 10, true));
block2.hashMerkleRoot = block2.BuildMerkleTree();
CBlockIndex fakeIndex2 {block2};
fakeIndex2.pprev = &fakeIndex1;

View File

@ -65,17 +65,13 @@
#include "zmq/zmqnotificationinterface.h"
#endif
#if ENABLE_PROTON
#include "amqp/amqpnotificationinterface.h"
#endif
#include "librustzcash.h"
using namespace std;
extern void ThreadSendAlert();
ZCJoinSplit* pzcashParams = NULL;
TracingHandle* pTracingHandle = nullptr;
bool fFeeEstimatesInitialized = false;
static const bool DEFAULT_PROXYRANDOMIZE = true;
@ -88,10 +84,6 @@ static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false;
static CZMQNotificationInterface* pzmqNotificationInterface = NULL;
#endif
#if ENABLE_PROTON
static AMQPNotificationInterface* pAMQPNotificationInterface = NULL;
#endif
#ifdef WIN32
// Win32 LevelDB doesn't use file descriptors, and the ones used for
// accessing block files don't count towards the fd_set size limit
@ -254,14 +246,6 @@ void Shutdown()
}
#endif
#if ENABLE_PROTON
if (pAMQPNotificationInterface) {
UnregisterValidationInterface(pAMQPNotificationInterface);
delete pAMQPNotificationInterface;
pAMQPNotificationInterface = NULL;
}
#endif
#ifndef WIN32
try {
boost::filesystem::remove(GetPidFile());
@ -274,11 +258,12 @@ void Shutdown()
delete pwalletMain;
pwalletMain = NULL;
#endif
delete pzcashParams;
pzcashParams = NULL;
globalVerifyHandle.reset();
ECC_Stop();
LogPrintf("%s: done\n", __func__);
if (pTracingHandle) {
tracing_free(pTracingHandle);
}
}
/**
@ -423,14 +408,6 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-zmqpubrawtx=<address>", _("Enable publish raw transaction in <address>"));
#endif
#if ENABLE_PROTON
strUsage += HelpMessageGroup(_("AMQP 1.0 notification options:"));
strUsage += HelpMessageOpt("-amqppubhashblock=<address>", _("Enable publish hash block in <address>"));
strUsage += HelpMessageOpt("-amqppubhashtx=<address>", _("Enable publish hash transaction in <address>"));
strUsage += HelpMessageOpt("-amqppubrawblock=<address>", _("Enable publish raw block in <address>"));
strUsage += HelpMessageOpt("-amqppubrawtx=<address>", _("Enable publish raw transaction in <address>"));
#endif
strUsage += HelpMessageGroup(_("Debugging/Testing options:"));
if (showDebug)
{
@ -719,8 +696,6 @@ static void ZC_LoadParams(
return;
}
pzcashParams = ZCJoinSplit::Prepared();
static_assert(
sizeof(boost::filesystem::path::value_type) == sizeof(codeunit),
"librustzcash not configured correctly");
@ -830,6 +805,23 @@ void InitLogging()
fLogTimestamps = GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS);
fLogIPs = GetBoolArg("-logips", DEFAULT_LOGIPS);
// Set up the initial filtering directive from the -debug flags.
std::string initialFilter = LogConfigFilter();
if (fPrintToConsole) {
pTracingHandle = tracing_init(nullptr, 0, initialFilter.c_str(), fLogTimestamps);
} else {
boost::filesystem::path pathDebug = GetDebugLogPath();
const boost::filesystem::path::string_type& pathDebugStr = pathDebug.native();
static_assert(sizeof(boost::filesystem::path::value_type) == sizeof(codeunit),
"native path has unexpected code unit size");
pTracingHandle = tracing_init(
reinterpret_cast<const codeunit*>(pathDebugStr.c_str()),
pathDebugStr.length(),
initialFilter.c_str(),
fLogTimestamps);
}
LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
LogPrintf("Zcash version %s (%s)\n", FormatFullVersion(), CLIENT_DATE);
}
@ -1174,12 +1166,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// if (GetBoolArg("-shrinkdebugfile", !fDebug))
// ShrinkDebugFile();
if (fPrintToDebugLog) {
if (!OpenDebugLog()) {
return InitError(strprintf("Could not open debug log file %s", GetDebugLogPath().string()));
}
}
LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION));
#ifdef ENABLE_WALLET
LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0));
@ -1365,21 +1351,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
}
#endif
#if ENABLE_PROTON
pAMQPNotificationInterface = AMQPNotificationInterface::CreateWithArguments(mapArgs);
if (pAMQPNotificationInterface) {
// AMQP support is currently an experimental feature, so fail if user configured AMQP notifications
// without enabling experimental features.
if (!GetBoolArg("-experimentalfeatures", false)) {
return InitError(_("AMQP support requires -experimentalfeatures."));
}
RegisterValidationInterface(pAMQPNotificationInterface);
}
#endif
// ********************************************************* Step 7: load block chain
fReindex = GetBoolArg("-reindex", false);

View File

@ -8,7 +8,7 @@
#include <string>
#include "zcash/JoinSplit.hpp"
#include <tracing.h>
class CScheduler;
class CWallet;
@ -18,7 +18,7 @@ namespace boost
class thread_group;
} // namespace boost
extern ZCJoinSplit* pzcashParams;
extern TracingHandle* pTracingHandle;
void StartShutdown();
bool ShutdownRequested();

View File

@ -1138,7 +1138,7 @@ bool ContextualCheckTransaction(
bool CheckTransaction(const CTransaction& tx, CValidationState &state,
libzcash::ProofVerifier& verifier)
ProofVerifier& verifier)
{
// Don't count coinbase transactions because mining skews the count
if (!tx.IsCoinBase()) {
@ -1150,7 +1150,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state,
} else {
// Ensure that zk-SNARKs verify
BOOST_FOREACH(const JSDescription &joinsplit, tx.vJoinSplit) {
if (!joinsplit.Verify(*pzcashParams, verifier, tx.joinSplitPubKey)) {
if (!verifier.VerifySprout(joinsplit, tx.joinSplitPubKey)) {
return state.DoS(100, error("CheckTransaction(): joinsplit does not verify"),
REJECT_INVALID, "bad-txns-joinsplit-verification-failed");
}
@ -1438,7 +1438,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
return false;
}
auto verifier = libzcash::ProofVerifier::Strict();
auto verifier = ProofVerifier::Strict();
if (!CheckTransaction(tx, state, verifier))
return error("AcceptToMemoryPool: CheckTransaction failed");
@ -2706,8 +2706,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
}
}
auto verifier = libzcash::ProofVerifier::Strict();
auto disabledVerifier = libzcash::ProofVerifier::Disabled();
auto verifier = ProofVerifier::Strict();
auto disabledVerifier = ProofVerifier::Disabled();
// Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in
if (!CheckBlock(block, state, chainparams, fExpensiveChecks ? verifier : disabledVerifier, !fJustCheck, !fJustCheck))
@ -3997,7 +3997,7 @@ bool CheckBlockHeader(
bool CheckBlock(const CBlock& block, CValidationState& state,
const CChainParams& chainparams,
libzcash::ProofVerifier& verifier,
ProofVerifier& verifier,
bool fCheckPOW, bool fCheckMerkleRoot)
{
// These are checks that are independent of context.
@ -4272,7 +4272,7 @@ static bool AcceptBlock(const CBlock& block, CValidationState& state, const CCha
}
// See method docstring for why this is always disabled
auto verifier = libzcash::ProofVerifier::Disabled();
auto verifier = ProofVerifier::Disabled();
if ((!CheckBlock(block, state, chainparams, verifier)) || !ContextualCheckBlock(block, state, chainparams, pindex->pprev)) {
if (state.IsInvalid() && !state.CorruptionPossible()) {
pindex->nStatus |= BLOCK_FAILED_VALID;
@ -4321,8 +4321,11 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned
bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, CDiskBlockPos* dbp)
{
auto span = TracingSpan("info", "main", "ProcessNewBlock");
auto spanGuard = span.Enter();
// Preliminary checks
auto verifier = libzcash::ProofVerifier::Disabled();
auto verifier = ProofVerifier::Disabled();
bool checked = CheckBlock(*pblock, state, chainparams, verifier);
{
@ -4360,7 +4363,7 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams,
indexDummy.pprev = pindexPrev;
indexDummy.nHeight = pindexPrev->nHeight + 1;
// JoinSplit proofs are verified in ConnectBlock
auto verifier = libzcash::ProofVerifier::Disabled();
auto verifier = ProofVerifier::Disabled();
// NOTE: CheckBlockHeader is called by CheckBlock
if (!ContextualCheckBlockHeader(block, state, chainparams, pindexPrev))
@ -4760,7 +4763,7 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview,
int nGoodTransactions = 0;
CValidationState state;
// No need to verify JoinSplits twice
auto verifier = libzcash::ProofVerifier::Disabled();
auto verifier = ProofVerifier::Disabled();
for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev)
{
boost::this_thread::interruption_point();

View File

@ -18,6 +18,7 @@
#include "net.h"
#include "primitives/block.h"
#include "primitives/transaction.h"
#include "proof_verifier.h"
#include "script/script.h"
#include "script/sigcache.h"
#include "script/standard.h"
@ -344,7 +345,7 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight);
/** Transaction validation functions */
/** Context-independent validity checks */
bool CheckTransaction(const CTransaction& tx, CValidationState& state, libzcash::ProofVerifier& verifier);
bool CheckTransaction(const CTransaction& tx, CValidationState& state, ProofVerifier& verifier);
bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidationState &state);
namespace Consensus {
@ -447,7 +448,7 @@ bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state,
bool fCheckPOW = true);
bool CheckBlock(const CBlock& block, CValidationState& state,
const CChainParams& chainparams,
libzcash::ProofVerifier& verifier,
ProofVerifier& verifier,
bool fCheckPOW = true, bool fCheckMerkleRoot = true);
/** Context-dependent validity checks.

View File

@ -994,6 +994,8 @@ void ThreadSocketHandler()
if (pnode->fDisconnect ||
(pnode->GetRefCount() <= 0 && pnode->vRecvMsg.empty() && pnode->nSendSize == 0 && pnode->ssSend.empty()))
{
auto spanGuard = pnode->span.Enter();
// remove from vNodes
vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
@ -1152,6 +1154,8 @@ void ThreadSocketHandler()
{
boost::this_thread::interruption_point();
auto spanGuard = pnode->span.Enter();
//
// Receive
//
@ -1557,6 +1561,8 @@ void ThreadMessageHandler()
if (pnode->fDisconnect)
continue;
auto spanGuard = pnode->span.Enter();
// Receive messages
{
TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
@ -1890,6 +1896,7 @@ void RelayTransaction(const CTransaction& tx, const CDataStream& ss)
if(!pnode->fRelayTxes)
continue;
LOCK(pnode->cs_filter);
auto spanGuard = pnode->span.Enter();
if (pnode->pfilter)
{
if (pnode->pfilter->IsRelevantAndUpdate(tx))
@ -2101,6 +2108,8 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa
nPingUsecTime = 0;
fPingQueued = false;
nMinPingUsecTime = std::numeric_limits<int64_t>::max();
span = TracingSpan("info", "net", "CNode");
auto spanGuard = span.Enter();
{
LOCK(cs_nLastNodeId);

View File

@ -30,6 +30,8 @@
#include <boost/foreach.hpp>
#include <boost/signals2/signal.hpp>
#include <tracing.h>
class CAddrMan;
class CBlockIndex;
class CScheduler;
@ -297,6 +299,8 @@ public:
CBloomFilter* pfilter;
int nRefCount;
NodeId id;
tracing::Span span;
protected:
// Denial-of-service detection/prevention

View File

@ -140,7 +140,7 @@ arith_uint256 GetBlockProof(const CBlockIndex& block)
// We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
// as it's too large for a arith_uint256. However, as 2**256 is at least as large
// as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
// or ~bnTarget / (nTarget+1) + 1.
// or ~bnTarget / (bnTarget+1) + 1.
return (~bnTarget / (bnTarget + 1)) + 1;
}

View File

@ -9,10 +9,7 @@
#include "tinyformat.h"
#include "utilstrencodings.h"
#include "librustzcash.h"
JSDescription::JSDescription(
ZCJoinSplit& params,
const uint256& joinSplitPubKey,
const uint256& anchor,
const std::array<libzcash::JSInput, ZC_NUM_JS_INPUTS>& inputs,
@ -25,7 +22,7 @@ JSDescription::JSDescription(
{
std::array<libzcash::SproutNote, ZC_NUM_JS_OUTPUTS> notes;
proof = params.prove(
proof = ZCJoinSplit::prove(
inputs,
outputs,
notes,
@ -45,7 +42,6 @@ JSDescription::JSDescription(
}
JSDescription JSDescription::Randomized(
ZCJoinSplit& params,
const uint256& joinSplitPubKey,
const uint256& anchor,
std::array<libzcash::JSInput, ZC_NUM_JS_INPUTS>& inputs,
@ -69,63 +65,12 @@ JSDescription JSDescription::Randomized(
MappedShuffle(outputs.begin(), outputMap.begin(), ZC_NUM_JS_OUTPUTS, gen);
return JSDescription(
params, joinSplitPubKey, anchor, inputs, outputs,
joinSplitPubKey, anchor, inputs, outputs,
vpub_old, vpub_new, computeProof,
esk // payment disclosure
);
}
class SproutProofVerifier : public boost::static_visitor<bool>
{
ZCJoinSplit& params;
libzcash::ProofVerifier& verifier;
const uint256& joinSplitPubKey;
const JSDescription& jsdesc;
public:
SproutProofVerifier(
ZCJoinSplit& params,
libzcash::ProofVerifier& verifier,
const uint256& joinSplitPubKey,
const JSDescription& jsdesc
) : params(params), jsdesc(jsdesc), verifier(verifier), joinSplitPubKey(joinSplitPubKey) {}
bool operator()(const libzcash::PHGRProof& proof) const
{
// We checkpoint after Sapling activation, so we can skip verification
// for all Sprout proofs.
return true;
}
bool operator()(const libzcash::GrothProof& proof) const
{
uint256 h_sig = ZCJoinSplit::h_sig(jsdesc.randomSeed, jsdesc.nullifiers, joinSplitPubKey);
return librustzcash_sprout_verify(
proof.begin(),
jsdesc.anchor.begin(),
h_sig.begin(),
jsdesc.macs[0].begin(),
jsdesc.macs[1].begin(),
jsdesc.nullifiers[0].begin(),
jsdesc.nullifiers[1].begin(),
jsdesc.commitments[0].begin(),
jsdesc.commitments[1].begin(),
jsdesc.vpub_old,
jsdesc.vpub_new
);
}
};
bool JSDescription::Verify(
ZCJoinSplit& params,
libzcash::ProofVerifier& verifier,
const uint256& joinSplitPubKey
) const {
auto pv = SproutProofVerifier(params, verifier, joinSplitPubKey, *this);
return boost::apply_visitor(pv, proof);
}
uint256 JSDescription::h_sig(const uint256& joinSplitPubKey) const
{
return ZCJoinSplit::h_sig(randomSeed, nullifiers, joinSplitPubKey);

View File

@ -235,7 +235,6 @@ public:
JSDescription(): vpub_old(0), vpub_new(0) { }
JSDescription(
ZCJoinSplit& params,
const uint256& joinSplitPubKey,
const uint256& rt,
const std::array<libzcash::JSInput, ZC_NUM_JS_INPUTS>& inputs,
@ -247,7 +246,6 @@ public:
);
static JSDescription Randomized(
ZCJoinSplit& params,
const uint256& joinSplitPubKey,
const uint256& rt,
std::array<libzcash::JSInput, ZC_NUM_JS_INPUTS>& inputs,
@ -261,13 +259,6 @@ public:
std::function<int(int)> gen = GetRandInt
);
// Verifies that the JoinSplit proof is correct.
bool Verify(
ZCJoinSplit& params,
libzcash::ProofVerifier& verifier,
const uint256& joinSplitPubKey
) const;
// Returns the calculated h_sig
uint256 h_sig(const uint256& joinSplitPubKey) const;

70
src/proof_verifier.cpp Normal file
View File

@ -0,0 +1,70 @@
// Copyright (c) 2016-2020 The Zcash developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
#include <proof_verifier.h>
#include <zcash/JoinSplit.hpp>
#include <boost/variant.hpp>
#include <librustzcash.h>
class SproutProofVerifier : public boost::static_visitor<bool>
{
ProofVerifier& verifier;
const uint256& joinSplitPubKey;
const JSDescription& jsdesc;
public:
SproutProofVerifier(
ProofVerifier& verifier,
const uint256& joinSplitPubKey,
const JSDescription& jsdesc
) : jsdesc(jsdesc), verifier(verifier), joinSplitPubKey(joinSplitPubKey) {}
bool operator()(const libzcash::PHGRProof& proof) const
{
// We checkpoint after Sapling activation, so we can skip verification
// for all Sprout proofs.
return true;
}
bool operator()(const libzcash::GrothProof& proof) const
{
uint256 h_sig = ZCJoinSplit::h_sig(jsdesc.randomSeed, jsdesc.nullifiers, joinSplitPubKey);
return librustzcash_sprout_verify(
proof.begin(),
jsdesc.anchor.begin(),
h_sig.begin(),
jsdesc.macs[0].begin(),
jsdesc.macs[1].begin(),
jsdesc.nullifiers[0].begin(),
jsdesc.nullifiers[1].begin(),
jsdesc.commitments[0].begin(),
jsdesc.commitments[1].begin(),
jsdesc.vpub_old,
jsdesc.vpub_new
);
}
};
ProofVerifier ProofVerifier::Strict() {
return ProofVerifier(true);
}
ProofVerifier ProofVerifier::Disabled() {
return ProofVerifier(false);
}
bool ProofVerifier::VerifySprout(
const JSDescription& jsdesc,
const uint256& joinSplitPubKey
) {
if (!perform_verification) {
return true;
}
auto pv = SproutProofVerifier(*this, joinSplitPubKey, jsdesc);
return boost::apply_visitor(pv, jsdesc.proof);
}

40
src/proof_verifier.h Normal file
View File

@ -0,0 +1,40 @@
// Copyright (c) 2016-2020 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_PROOF_VERIFIER_H
#define ZCASH_PROOF_VERIFIER_H
#include <primitives/transaction.h>
#include <uint256.h>
class ProofVerifier {
private:
bool perform_verification;
ProofVerifier(bool perform_verification) : perform_verification(perform_verification) { }
public:
// ProofVerifier should never be copied
ProofVerifier(const ProofVerifier&) = delete;
ProofVerifier& operator=(const ProofVerifier&) = delete;
ProofVerifier(ProofVerifier&&);
ProofVerifier& operator=(ProofVerifier&&);
// Creates a verification context that strictly verifies
// all proofs.
static ProofVerifier Strict();
// Creates a verification context that performs no
// verification, used when avoiding duplicate effort
// such as during reindexing.
static ProofVerifier Disabled();
// Verifies that the JoinSplit proof is correct.
bool VerifySprout(
const JSDescription& jsdesc,
const uint256& joinSplitPubKey
);
};
#endif // ZCASH_PROOF_VERIFIER_H

View File

@ -28,6 +28,8 @@
#include <boost/thread.hpp>
#include <boost/algorithm/string/case_conv.hpp> // for to_upper()
#include <tracing.h>
using namespace RPCServer;
using namespace std;
@ -239,6 +241,42 @@ UniValue help(const UniValue& params, bool fHelp)
}
UniValue setlogfilter(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() > 1) {
throw runtime_error(
"setlogfilter \"directives\"\n"
"\nSets the filter to be used for selecting events to log.\n"
"\nA filter is a comma-separated list of directives.\n"
"The syntax for each directive is:\n"
"\n target[span{field=value}]=level\n"
"\nThe default filter, derived from the -debug=target flags, is:\n"
+ strprintf("\n %s", LogConfigFilter()) + "\n"
"\nPassing a valid filter here will replace the existing filter.\n"
"Passing an empty string will reset the filter to the default.\n"
"\nArguments:\n"
"1. newFilterDirectives (string, required) The new log filter.\n"
"\nExamples:\n"
+ HelpExampleCli("setlogfilter", "\"main=info,rpc=info\"")
+ HelpExampleRpc("setlogfilter", "\"main=info,rpc=info\"")
);
}
auto newFilter = params[0].getValStr();
if (newFilter.empty()) {
newFilter = LogConfigFilter();
}
if (pTracingHandle) {
if (!tracing_reload(pTracingHandle, newFilter.c_str())) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Filter reload failed; check logs");
}
}
return NullUniValue;
}
UniValue stop(const UniValue& params, bool fHelp)
{
// Accept the deprecated and ignored 'detach' boolean argument
@ -260,6 +298,7 @@ static const CRPCCommand vRPCCommands[] =
// --------------------- ------------------------ ----------------------- ----------
/* Overall control/query calls */
{ "control", "help", &help, true },
{ "control", "setlogfilter", &setlogfilter, true },
{ "control", "stop", &stop, true },
};

View File

@ -1,6 +1,9 @@
#ifndef LIBRUSTZCASH_INCLUDE_H_
#define LIBRUSTZCASH_INCLUDE_H_
#include "rust/types.h"
#include <stddef.h>
#include <stdint.h>
#ifndef __cplusplus
@ -29,11 +32,6 @@ static_assert(alignof(HistoryEntry) == 1, "HistoryEntry struct alignment is not
#ifdef __cplusplus
extern "C" {
#endif
#ifdef WIN32
typedef uint16_t codeunit;
#else
typedef uint8_t codeunit;
#endif
void librustzcash_to_scalar(const unsigned char *input, unsigned char *result);

View File

@ -0,0 +1,16 @@
// 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 .
#ifndef RUST_TYPES_H_
#define RUST_TYPES_H_
#include <stdint.h>
#ifdef WIN32
typedef uint16_t codeunit;
#else
typedef uint8_t codeunit;
#endif
#endif // RUST_TYPES_H_

301
src/rust/include/tracing.h Normal file
View File

@ -0,0 +1,301 @@
// Copyright (c) 2020 Jack Grigg
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
#ifndef TRACING_INCLUDE_H_
#define TRACING_INCLUDE_H_
#include "rust/types.h"
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
#include <memory>
extern "C" {
#endif
struct TracingHandle;
typedef struct TracingHandle TracingHandle;
/// Initializes the tracing crate, returning a handle for the logging
/// component. The handle must be freed to close the logging component.
///
/// If log_path is NULL, logging is sent to standard output.
TracingHandle* tracing_init(
const codeunit* log_path,
size_t log_path_len,
const char* initial_filter,
bool log_timestamps);
/// Frees a tracing handle returned from `tracing_init`;
void tracing_free(TracingHandle* handle);
/// Reloads the tracing filter.
///
/// Returns `true` if the reload succeeded.
bool tracing_reload(TracingHandle* handle, const char* new_filter);
struct TracingCallsite;
typedef struct TracingCallsite TracingCallsite;
/// Creates a tracing callsite.
///
/// You should usually call the `TracingLog` macro (or one of the helper
/// macros such as `TracingInfo`) instead of calling this directly.
///
/// This MUST ONLY be called to assign a `static TracingCallsite*`, and all
/// string arguments MUST be static `const char*` constants, and MUST be valid
/// UTF-8.
TracingCallsite* tracing_callsite(
const char* name,
const char* target,
const char* level,
const char* file,
uint32_t line,
const char* const* fields,
size_t fields_len,
bool is_span);
struct TracingSpanHandle;
typedef struct TracingSpanHandle TracingSpanHandle;
struct TracingSpanGuard;
typedef struct TracingSpanGuard TracingSpanGuard;
/// Creates a span for a callsite.
///
/// The span must be freed when it goes out of scope.
TracingSpanHandle* tracing_span_create(const TracingCallsite* callsite);
/// Clones the given span.
///
/// Both spans need to be separately freed when they go out of scope.
TracingSpanHandle* tracing_span_clone(const TracingSpanHandle* span);
/// Frees a span.
void tracing_span_free(TracingSpanHandle* span);
/// Enters the given span, returning a guard.
///
/// `tracing_span_exit` must be called to drop this guard before the span
/// goes out of scope.
TracingSpanGuard* tracing_span_enter(const TracingSpanHandle* span);
/// Exits a span by dropping the given guard.
void tracing_span_exit(TracingSpanGuard* guard);
/// Logs a message for a callsite.
///
/// You should usually call the `TracingLog` macro (or one of the helper
/// macros such as `TracingInfo`) instead of calling this directly.
void tracing_log(
const TracingCallsite* callsite,
const char* const* field_values,
size_t fields_len);
#ifdef __cplusplus
}
#endif
//
// Helper macros
//
#define T_DOUBLEESCAPE(a) #a
#define T_ESCAPEQUOTE(a) T_DOUBLEESCAPE(a)
// Computes the length of the given array. This is COUNT_OF from Chromium.
#define T_ARRLEN(x) ((sizeof(x) / sizeof(0 [x])) / ((size_t)(!(sizeof(x) % sizeof(0 [x])))))
#ifdef __cplusplus
// Constructs a tracing callsite.
//
// The 'static constexpr' hack ensures that name, target, level, and fields are
// compile-time constants with static storage duration. The output of this macro
// MUST be stored as a static TracingCallsite*.
#define T_CALLSITE(name, target, level, fields, is_span) ([&] { \
static constexpr const char* _t_name = name; \
static constexpr const char* _t_target = target; \
static constexpr const char* _t_level = level; \
static constexpr const char* const* _t_fields = fields; \
return tracing_callsite( \
_t_name, \
_t_target, \
_t_level, \
__FILE__, \
__LINE__, \
_t_fields, \
T_ARRLEN(fields), \
is_span); \
}())
#else
// Constructs a tracing callsite.
//
// name, target, level, and fields MUST be static constants, and the output of
// this macro MUST be stored as a static TracingCallsite*.
#define T_CALLSITE(name, target, level, fields, is_span) \
tracing_callsite( \
name, \
target, \
level, \
__FILE__, \
__LINE__, \
fields, \
T_ARRLEN(fields), \
is_span)
#endif
//
// Spans
//
#ifdef __cplusplus
namespace tracing
{
class Span;
/// A guard representing a span which has been entered and is currently
/// executing.
///
/// When the guard is dropped, the span will be exited.
///
/// This is returned by the `Span::Enter` function.
class Entered
{
private:
friend class Span;
std::unique_ptr<TracingSpanGuard, decltype(&tracing_span_exit)> inner;
Entered(const TracingSpanHandle* span) : inner(tracing_span_enter(span), tracing_span_exit) {}
};
/// A handle representing a span, with the capability to enter the span if it
/// exists.
///
/// If the span was rejected by the current `Subscriber`'s filter, entering the
/// span will silently do nothing. Thus, the handle can be used in the same
/// manner regardless of whether or not the trace is currently being collected.
class Span
{
private:
std::unique_ptr<TracingSpanHandle, decltype(&tracing_span_free)> inner;
public:
/// Constructs a span that does nothing.
///
/// This constructor is present to enable spans to be stored in classes,
/// while also containing fields that are initialized within the class
/// constructor:
///
/// class Foo {
/// std::string name;
/// tracing::Span span;
///
/// Foo(std::string tag)
/// {
/// name = "Foo-" + tag;
/// span = TracingSpan("info", "main", "Foo", "name", name);
/// }
/// }
Span() : inner(nullptr, tracing_span_free) {}
/// Use the `TracingSpan` macro instead of calling this constructor directly.
Span(const TracingCallsite* callsite) : inner(tracing_span_create(callsite), tracing_span_free) {}
Span(Span& span) : inner(std::move(span.inner)) {}
Span(const Span& span) : inner(tracing_span_clone(span.inner.get()), tracing_span_free) {}
Span& operator=(Span& span)
{
if (this != &span) {
inner = std::move(span.inner);
}
return *this;
}
Span& operator=(const Span& span)
{
if (this != &span) {
inner.reset(tracing_span_clone(span.inner.get()));
}
return *this;
}
/// Enters this span, returning a guard that will exit the span when dropped.
///
/// If this span is enabled by the current subscriber, then this function
/// will call `Subscriber::enter` with the span's `Id`, and dropping the
/// guard will call `Subscriber::exit`. If the span is disabled, this does
/// nothing.
Entered Enter()
{
return Entered(inner.get());
}
};
} // namespace tracing
/// Expands to a `tracing::Span` object which is used to record a span.
/// The `Span::Enter` method on that object records that the span has been
/// entered, and returns a RAII guard object, which will exit the span when
/// dropped.
///
/// level, target, and name MUST be static constants, and MUST be valid UTF-8
/// strings.
#define TracingSpan(level, target, name) ([&] { \
static constexpr const char* const FIELDS[] = {}; \
static TracingCallsite* CALLSITE = \
T_CALLSITE(name, target, level, FIELDS, true); \
return tracing::Span(CALLSITE); \
}())
#endif
//
// Events
//
/// Constructs a new event.
///
/// level and target MUST be static constants, and MUST be valid UTF-8 strings.
#define TracingLog(level, target, message) \
do { \
static constexpr const char* const FIELDS[] = \
{"message"}; \
const char* T_VALUES[] = {message}; \
static TracingCallsite* CALLSITE = T_CALLSITE( \
"event " __FILE__ ":" T_ESCAPEQUOTE(__LINE__), \
target, level, FIELDS, false); \
tracing_log(CALLSITE, T_VALUES, T_ARRLEN(T_VALUES)); \
} while (0)
/// Constructs an event at the error level.
///
/// Arguments: (target, message)
///
/// target MUST be a static constant, and MUST be valid UTF-8 string.
#define TracingError(...) TracingLog("error", __VA_ARGS__)
/// Constructs an event at the warn level.
///
/// Arguments: (target, message)
///
/// target MUST be a static constant, and MUST be valid UTF-8 string.
#define TracingWarn(...) TracingLog("warn", __VA_ARGS__)
/// Constructs an event at the info level.
///
/// Arguments: (target, message)
///
/// target MUST be a static constant, and MUST be valid UTF-8 string.
#define TracingInfo(...) TracingLog("info", __VA_ARGS__)
/// Constructs an event at the debug level.
///
/// Arguments: (target, message)
///
/// target MUST be a static constant, and MUST be valid UTF-8 string.
#define TracingDebug(...) TracingLog("debug", __VA_ARGS__)
/// Constructs an event at the trace level.
///
/// Arguments: (target, message)
///
/// target MUST be a static constant, and MUST be valid UTF-8 string.
#define TracingTrace(...) TracingLog("trace", __VA_ARGS__)
#endif // TRACING_INCLUDE_H_

View File

@ -67,6 +67,8 @@ use zcash_proofs::{
use zcash_history::{Entry as MMREntry, NodeData as MMRNodeData, Tree as MMRTree};
mod tracing_ffi;
#[cfg(test)]
mod tests;

552
src/rust/src/tracing_ffi.rs Normal file
View File

@ -0,0 +1,552 @@
use libc::c_char;
use std::ffi::CStr;
use std::path::Path;
use std::slice;
use std::str;
use std::sync::atomic::{AtomicUsize, Ordering};
use tracing::{
callsite::{Callsite, Identifier},
field::{FieldSet, Value},
level_enabled,
metadata::Kind,
span::Entered,
subscriber::{Interest, Subscriber},
Event, Metadata, Span,
};
use tracing_appender::non_blocking::WorkerGuard;
use tracing_core::Once;
use tracing_subscriber::{
filter::EnvFilter,
layer::Layer,
reload::{self, Handle},
};
#[cfg(not(target_os = "windows"))]
use std::ffi::OsStr;
#[cfg(not(target_os = "windows"))]
use std::os::unix::ffi::OsStrExt;
#[cfg(target_os = "windows")]
use std::ffi::OsString;
#[cfg(target_os = "windows")]
use std::os::windows::ffi::OsStringExt;
trait ReloadHandle {
fn reload(&self, new_filter: EnvFilter) -> Result<(), reload::Error>;
}
impl<L, S> ReloadHandle for Handle<L, S>
where
L: From<EnvFilter> + Layer<S> + 'static,
S: Subscriber,
{
fn reload(&self, new_filter: EnvFilter) -> Result<(), reload::Error> {
self.reload(new_filter)
}
}
pub struct TracingHandle {
_file_guard: Option<WorkerGuard>,
reload_handle: Box<dyn ReloadHandle>,
}
#[no_mangle]
pub extern "C" fn tracing_init(
#[cfg(not(target_os = "windows"))] log_path: *const u8,
#[cfg(target_os = "windows")] log_path: *const u16,
log_path_len: usize,
initial_filter: *const c_char,
log_timestamps: bool,
) -> *mut TracingHandle {
let initial_filter = unsafe { CStr::from_ptr(initial_filter) }
.to_str()
.expect("initial filter should be a valid string");
if log_path.is_null() {
tracing_init_stdout(initial_filter, log_timestamps)
} else {
let log_path = unsafe { slice::from_raw_parts(log_path, log_path_len) };
#[cfg(not(target_os = "windows"))]
let log_path = Path::new(OsStr::from_bytes(log_path));
#[cfg(target_os = "windows")]
let log_path = Path::new(OsString::from_wide(log_path));
tracing_init_file(log_path, initial_filter, log_timestamps)
}
}
fn tracing_init_stdout(initial_filter: &str, log_timestamps: bool) -> *mut TracingHandle {
let builder = tracing_subscriber::fmt()
.with_ansi(true)
.with_env_filter(initial_filter);
let reload_handle = if log_timestamps {
let builder = builder.with_filter_reloading();
let reload_handle = builder.reload_handle();
builder.init();
Box::new(reload_handle) as Box<dyn ReloadHandle>
} else {
let builder = builder.without_time().with_filter_reloading();
let reload_handle = builder.reload_handle();
builder.init();
Box::new(reload_handle) as Box<dyn ReloadHandle>
};
Box::into_raw(Box::new(TracingHandle {
_file_guard: None,
reload_handle,
}))
}
fn tracing_init_file(
log_path: &Path,
initial_filter: &str,
log_timestamps: bool,
) -> *mut TracingHandle {
let file_appender =
tracing_appender::rolling::never(log_path.parent().unwrap(), log_path.file_name().unwrap());
let (non_blocking, file_guard) = tracing_appender::non_blocking(file_appender);
let builder = tracing_subscriber::fmt()
.with_ansi(false)
.with_env_filter(initial_filter)
.with_writer(non_blocking);
let reload_handle = if log_timestamps {
let builder = builder.with_filter_reloading();
let reload_handle = builder.reload_handle();
builder.init();
Box::new(reload_handle) as Box<dyn ReloadHandle>
} else {
let builder = builder.without_time().with_filter_reloading();
let reload_handle = builder.reload_handle();
builder.init();
Box::new(reload_handle) as Box<dyn ReloadHandle>
};
Box::into_raw(Box::new(TracingHandle {
_file_guard: Some(file_guard),
reload_handle,
}))
}
#[no_mangle]
pub extern "C" fn tracing_free(handle: *mut TracingHandle) {
drop(unsafe { Box::from_raw(handle) });
}
#[no_mangle]
pub extern "C" fn tracing_reload(handle: *mut TracingHandle, new_filter: *const c_char) -> bool {
let handle = unsafe { &mut *handle };
match unsafe { CStr::from_ptr(new_filter) }
.to_str()
.map(EnvFilter::new)
{
Err(e) => {
tracing::error!("New filter is not valid UTF-8: {}", e);
false
}
Ok(new_filter) => {
if let Err(e) = handle.reload_handle.reload(new_filter) {
tracing::error!("Filter reload failed: {}", e);
false
} else {
true
}
}
}
}
pub struct FfiCallsite {
interest: AtomicUsize,
meta: Option<Metadata<'static>>,
registration: Once,
fields: Vec<&'static str>,
}
impl FfiCallsite {
fn new(fields: Vec<&'static str>) -> Self {
FfiCallsite {
interest: AtomicUsize::new(0),
meta: None,
registration: Once::new(),
fields,
}
}
#[inline(always)]
fn is_enabled(&self) -> bool {
let interest = self.interest();
if interest.is_always() {
return true;
}
if interest.is_never() {
return false;
}
tracing::dispatcher::get_default(|current| current.enabled(self.metadata()))
}
#[inline(always)]
pub fn register(&'static self) {
self.registration
.call_once(|| tracing::callsite::register(self));
}
#[inline(always)]
fn interest(&self) -> Interest {
match self.interest.load(Ordering::Relaxed) {
0 => Interest::never(),
2 => Interest::always(),
_ => Interest::sometimes(),
}
}
}
impl Callsite for FfiCallsite {
fn set_interest(&self, interest: Interest) {
let interest = match () {
_ if interest.is_never() => 0,
_ if interest.is_always() => 2,
_ => 1,
};
self.interest.store(interest, Ordering::SeqCst);
}
#[inline(always)]
fn metadata(&self) -> &Metadata<'static> {
self.meta.as_ref().unwrap()
}
}
#[no_mangle]
pub extern "C" fn tracing_callsite(
name: *const c_char,
target: *const c_char,
level: *const c_char,
file: *const c_char,
line: u32,
fields: *const *const c_char,
fields_len: usize,
is_span: bool,
) -> *mut FfiCallsite {
let name = unsafe { CStr::from_ptr(name) }.to_str().unwrap();
let target = unsafe { CStr::from_ptr(target) }.to_str().unwrap();
let level = unsafe { CStr::from_ptr(level) }.to_str().unwrap();
let file = unsafe { CStr::from_ptr(file) }.to_str().unwrap();
let fields = unsafe { slice::from_raw_parts(fields, fields_len) };
let fields = fields
.iter()
.map(|&p| unsafe { CStr::from_ptr(p) })
.map(|cs| cs.to_str())
.collect::<Result<Vec<_>, _>>()
.unwrap();
let level = level.parse().unwrap();
// We immediately convert the new callsite into a pointer to erase lifetime
// information. The caller MUST ensure that the callsite is stored statically.
let site = Box::into_raw(Box::new(FfiCallsite::new(fields)));
let site_ref = unsafe { &*site };
let meta: Metadata<'static> = Metadata::new(
name,
target,
level,
Some(file),
Some(line),
None,
FieldSet::new(&site_ref.fields, Identifier(site_ref)),
if is_span { Kind::SPAN } else { Kind::EVENT },
);
unsafe { &mut *site }.meta = Some(meta);
site_ref.register();
site
}
macro_rules! repeat {
(1, $val:expr) => {
[$val]
};
(2, $val:expr) => {
[$val, $val]
};
(3, $val:expr) => {
[$val, $val, $val]
};
(4, $val:expr) => {
[$val, $val, $val, $val]
};
(5, $val:expr) => {
[$val, $val, $val, $val, $val]
};
(6, $val:expr) => {
[$val, $val, $val, $val, $val, $val]
};
(7, $val:expr) => {
[$val, $val, $val, $val, $val, $val, $val]
};
(8, $val:expr) => {
[$val, $val, $val, $val, $val, $val, $val, $val]
};
(9, $val:expr) => {
[$val, $val, $val, $val, $val, $val, $val, $val, $val]
};
(10, $val:expr) => {
[$val, $val, $val, $val, $val, $val, $val, $val, $val, $val]
};
(11, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
]
};
(12, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
]
};
(13, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
]
};
(14, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
]
};
(15, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val,
]
};
(16, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val, $val,
]
};
(17, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val, $val, $val,
]
};
(18, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val, $val, $val, $val,
]
};
(19, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val, $val, $val, $val, $val,
]
};
(20, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val, $val, $val, $val, $val, $val,
]
};
(21, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val, $val, $val, $val, $val, $val, $val,
]
};
(22, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val, $val, $val, $val, $val, $val, $val, $val,
]
};
(23, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val, $val, $val, $val, $val, $val, $val, $val, $val,
]
};
(24, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
]
};
(25, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
]
};
(26, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
]
};
(27, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
]
};
(28, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
]
};
(29, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val,
]
};
(30, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val, $val,
]
};
(31, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val, $val, $val,
]
};
(32, $val:expr) => {
[
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val, $val,
$val, $val, $val, $val,
]
};
}
#[no_mangle]
pub extern "C" fn tracing_span_create(callsite: *const FfiCallsite) -> *mut Span {
let callsite = unsafe { &*callsite };
let meta = callsite.metadata();
assert!(meta.is_span());
let span = if level_enabled!(*meta.level()) && callsite.is_enabled() {
Span::new(meta, &meta.fields().value_set(&[]))
} else {
Span::none()
};
Box::into_raw(Box::new(span))
}
#[no_mangle]
pub extern "C" fn tracing_span_clone(span: *const Span) -> *mut Span {
unsafe { span.as_ref() }
.map(|span| Box::into_raw(Box::new(span.clone())))
.unwrap_or(std::ptr::null_mut())
}
#[no_mangle]
pub extern "C" fn tracing_span_free(span: *mut Span) {
if !span.is_null() {
drop(unsafe { Box::from_raw(span) });
}
}
#[no_mangle]
pub extern "C" fn tracing_span_enter(span: *const Span) -> *mut Entered<'static> {
unsafe { span.as_ref() }
.map(|span| Box::into_raw(Box::new(span.enter())))
.unwrap_or(std::ptr::null_mut())
}
#[no_mangle]
pub extern "C" fn tracing_span_exit(guard: *mut Entered) {
if !guard.is_null() {
drop(unsafe { Box::from_raw(guard) });
}
}
#[no_mangle]
pub extern "C" fn tracing_log(
callsite: *const FfiCallsite,
field_values: *const *const c_char,
fields_len: usize,
) {
let callsite = unsafe { &*callsite };
let field_values = unsafe { slice::from_raw_parts(field_values, fields_len) };
let meta = callsite.metadata();
assert!(meta.is_event());
if level_enabled!(*meta.level()) && callsite.is_enabled() {
let mut fi = meta.fields().iter();
let mut vi = field_values
.iter()
.map(|&p| unsafe { CStr::from_ptr(p) })
.map(|cs| cs.to_string_lossy());
macro_rules! dispatch {
($n:tt) => {
Event::dispatch(
meta,
&meta.fields().value_set(&repeat!(
$n,
(
&fi.next().unwrap(),
Some(&vi.next().unwrap().as_ref() as &dyn Value)
)
)),
)
};
}
// https://github.com/tokio-rs/tracing/issues/782 might help improve things here.
match field_values.len() {
1 => dispatch!(1),
2 => dispatch!(2),
3 => dispatch!(3),
4 => dispatch!(4),
5 => dispatch!(5),
6 => dispatch!(6),
7 => dispatch!(7),
8 => dispatch!(8),
9 => dispatch!(9),
10 => dispatch!(10),
11 => dispatch!(11),
12 => dispatch!(12),
13 => dispatch!(13),
14 => dispatch!(14),
15 => dispatch!(15),
16 => dispatch!(16),
17 => dispatch!(17),
18 => dispatch!(18),
19 => dispatch!(19),
20 => dispatch!(20),
21 => dispatch!(21),
22 => dispatch!(22),
23 => dispatch!(23),
24 => dispatch!(24),
25 => dispatch!(25),
26 => dispatch!(26),
27 => dispatch!(27),
28 => dispatch!(28),
29 => dispatch!(29),
30 => dispatch!(30),
31 => dispatch!(31),
32 => dispatch!(32),
_ => unimplemented!(),
}
}
}

View File

@ -5,6 +5,7 @@
#include "clientversion.h"
#include "consensus/validation.h"
#include "main.h"
#include "proof_verifier.h"
#include "test/test_bitcoin.h"
#include "utiltime.h"
#include "zcash/Proof.hpp"
@ -57,7 +58,7 @@ BOOST_AUTO_TEST_CASE(May15)
// After May 15'th, big blocks are OK:
forkingBlock.nTime = tMay15; // Invalidates PoW
auto verifier = libzcash::ProofVerifier::Strict();
auto verifier = ProofVerifier::Strict();
BOOST_CHECK(CheckBlock(forkingBlock, state, Params(), verifier, false, false));
}

View File

@ -2,6 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
#include "crypto/aes.h"
#include "crypto/ripemd160.h"
#include "crypto/sha1.h"
#include "crypto/sha256.h"
@ -16,6 +17,8 @@
#include <boost/assign/list_of.hpp>
#include <boost/test/unit_test.hpp>
#include <openssl/aes.h>
#include <openssl/evp.h>
BOOST_FIXTURE_TEST_SUITE(crypto_tests, BasicTestingSetup)
@ -63,6 +66,127 @@ void TestHMACSHA512(const std::string &hexkey, const std::string &hexin, const s
TestVector(CHMAC_SHA512(&key[0], key.size()), ParseHex(hexin), ParseHex(hexout));
}
void TestAES128(const std::string &hexkey, const std::string &hexin, const std::string &hexout)
{
std::vector<unsigned char> key = ParseHex(hexkey);
std::vector<unsigned char> in = ParseHex(hexin);
std::vector<unsigned char> correctout = ParseHex(hexout);
std::vector<unsigned char> buf, buf2;
assert(key.size() == 16);
assert(in.size() == 16);
assert(correctout.size() == 16);
AES128Encrypt enc(&key[0]);
buf.resize(correctout.size());
buf2.resize(correctout.size());
enc.Encrypt(&buf[0], &in[0]);
BOOST_CHECK_EQUAL(HexStr(buf), HexStr(correctout));
AES128Decrypt dec(&key[0]);
dec.Decrypt(&buf2[0], &buf[0]);
BOOST_CHECK_EQUAL(HexStr(buf2), HexStr(in));
}
void TestAES256(const std::string &hexkey, const std::string &hexin, const std::string &hexout)
{
std::vector<unsigned char> key = ParseHex(hexkey);
std::vector<unsigned char> in = ParseHex(hexin);
std::vector<unsigned char> correctout = ParseHex(hexout);
std::vector<unsigned char> buf;
assert(key.size() == 32);
assert(in.size() == 16);
assert(correctout.size() == 16);
AES256Encrypt enc(&key[0]);
buf.resize(correctout.size());
enc.Encrypt(&buf[0], &in[0]);
BOOST_CHECK(buf == correctout);
AES256Decrypt dec(&key[0]);
dec.Decrypt(&buf[0], &buf[0]);
BOOST_CHECK(buf == in);
}
void TestAES128CBC(const std::string &hexkey, const std::string &hexiv, bool pad, const std::string &hexin, const std::string &hexout)
{
std::vector<unsigned char> key = ParseHex(hexkey);
std::vector<unsigned char> iv = ParseHex(hexiv);
std::vector<unsigned char> in = ParseHex(hexin);
std::vector<unsigned char> correctout = ParseHex(hexout);
std::vector<unsigned char> realout(in.size() + AES_BLOCKSIZE);
// Encrypt the plaintext and verify that it equals the cipher
AES128CBCEncrypt enc(&key[0], &iv[0], pad);
int size = enc.Encrypt(&in[0], in.size(), &realout[0]);
realout.resize(size);
BOOST_CHECK(realout.size() == correctout.size());
BOOST_CHECK_MESSAGE(realout == correctout, HexStr(realout) + std::string(" != ") + hexout);
// Decrypt the cipher and verify that it equals the plaintext
std::vector<unsigned char> decrypted(correctout.size());
AES128CBCDecrypt dec(&key[0], &iv[0], pad);
size = dec.Decrypt(&correctout[0], correctout.size(), &decrypted[0]);
decrypted.resize(size);
BOOST_CHECK(decrypted.size() == in.size());
BOOST_CHECK_MESSAGE(decrypted == in, HexStr(decrypted) + std::string(" != ") + hexin);
// Encrypt and re-decrypt substrings of the plaintext and verify that they equal each-other
for(std::vector<unsigned char>::iterator i(in.begin()); i != in.end(); ++i)
{
std::vector<unsigned char> sub(i, in.end());
std::vector<unsigned char> subout(sub.size() + AES_BLOCKSIZE);
int size = enc.Encrypt(&sub[0], sub.size(), &subout[0]);
if (size != 0)
{
subout.resize(size);
std::vector<unsigned char> subdecrypted(subout.size());
size = dec.Decrypt(&subout[0], subout.size(), &subdecrypted[0]);
subdecrypted.resize(size);
BOOST_CHECK(decrypted.size() == in.size());
BOOST_CHECK_MESSAGE(subdecrypted == sub, HexStr(subdecrypted) + std::string(" != ") + HexStr(sub));
}
}
}
void TestAES256CBC(const std::string &hexkey, const std::string &hexiv, bool pad, const std::string &hexin, const std::string &hexout)
{
std::vector<unsigned char> key = ParseHex(hexkey);
std::vector<unsigned char> iv = ParseHex(hexiv);
std::vector<unsigned char> in = ParseHex(hexin);
std::vector<unsigned char> correctout = ParseHex(hexout);
std::vector<unsigned char> realout(in.size() + AES_BLOCKSIZE);
// Encrypt the plaintext and verify that it equals the cipher
AES256CBCEncrypt enc(&key[0], &iv[0], pad);
int size = enc.Encrypt(&in[0], in.size(), &realout[0]);
realout.resize(size);
BOOST_CHECK(realout.size() == correctout.size());
BOOST_CHECK_MESSAGE(realout == correctout, HexStr(realout) + std::string(" != ") + hexout);
// Decrypt the cipher and verify that it equals the plaintext
std::vector<unsigned char> decrypted(correctout.size());
AES256CBCDecrypt dec(&key[0], &iv[0], pad);
size = dec.Decrypt(&correctout[0], correctout.size(), &decrypted[0]);
decrypted.resize(size);
BOOST_CHECK(decrypted.size() == in.size());
BOOST_CHECK_MESSAGE(decrypted == in, HexStr(decrypted) + std::string(" != ") + hexin);
// Encrypt and re-decrypt substrings of the plaintext and verify that they equal each-other
for(std::vector<unsigned char>::iterator i(in.begin()); i != in.end(); ++i)
{
std::vector<unsigned char> sub(i, in.end());
std::vector<unsigned char> subout(sub.size() + AES_BLOCKSIZE);
int size = enc.Encrypt(&sub[0], sub.size(), &subout[0]);
if (size != 0)
{
subout.resize(size);
std::vector<unsigned char> subdecrypted(subout.size());
size = dec.Decrypt(&subout[0], subout.size(), &subdecrypted[0]);
subdecrypted.resize(size);
BOOST_CHECK(decrypted.size() == in.size());
BOOST_CHECK_MESSAGE(subdecrypted == sub, HexStr(subdecrypted) + std::string(" != ") + HexStr(sub));
}
}
}
std::string LongTestString(void) {
std::string ret;
for (int i=0; i<200000; i++) {
@ -248,4 +372,71 @@ BOOST_AUTO_TEST_CASE(hmac_sha512_testvectors) {
"b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58");
}
BOOST_AUTO_TEST_CASE(aes_testvectors) {
// AES test vectors from FIPS 197.
TestAES128("000102030405060708090a0b0c0d0e0f", "00112233445566778899aabbccddeeff", "69c4e0d86a7b0430d8cdb78070b4c55a");
TestAES256("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "00112233445566778899aabbccddeeff", "8ea2b7ca516745bfeafc49904b496089");
// AES-ECB test vectors from NIST sp800-38a.
TestAES128("2b7e151628aed2a6abf7158809cf4f3c", "6bc1bee22e409f96e93d7e117393172a", "3ad77bb40d7a3660a89ecaf32466ef97");
TestAES128("2b7e151628aed2a6abf7158809cf4f3c", "ae2d8a571e03ac9c9eb76fac45af8e51", "f5d3d58503b9699de785895a96fdbaaf");
TestAES128("2b7e151628aed2a6abf7158809cf4f3c", "30c81c46a35ce411e5fbc1191a0a52ef", "43b1cd7f598ece23881b00e3ed030688");
TestAES128("2b7e151628aed2a6abf7158809cf4f3c", "f69f2445df4f9b17ad2b417be66c3710", "7b0c785e27e8ad3f8223207104725dd4");
TestAES256("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "6bc1bee22e409f96e93d7e117393172a", "f3eed1bdb5d2a03c064b5a7e3db181f8");
TestAES256("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "ae2d8a571e03ac9c9eb76fac45af8e51", "591ccb10d410ed26dc5ba74a31362870");
TestAES256("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "30c81c46a35ce411e5fbc1191a0a52ef", "b6ed21b99ca6f4f9f153e7b1beafed1d");
TestAES256("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "f69f2445df4f9b17ad2b417be66c3710", "23304b7a39f9f3ff067d8d8f9e24ecc7");
}
BOOST_AUTO_TEST_CASE(aes_cbc_testvectors) {
// NIST AES CBC 128-bit encryption test-vectors
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "000102030405060708090A0B0C0D0E0F", false, \
"6bc1bee22e409f96e93d7e117393172a", "7649abac8119b246cee98e9b12e9197d");
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "7649ABAC8119B246CEE98E9B12E9197D", false, \
"ae2d8a571e03ac9c9eb76fac45af8e51", "5086cb9b507219ee95db113a917678b2");
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "5086cb9b507219ee95db113a917678b2", false, \
"30c81c46a35ce411e5fbc1191a0a52ef", "73bed6b8e3c1743b7116e69e22229516");
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "73bed6b8e3c1743b7116e69e22229516", false, \
"f69f2445df4f9b17ad2b417be66c3710", "3ff1caa1681fac09120eca307586e1a7");
// The same vectors with padding enabled
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "000102030405060708090A0B0C0D0E0F", true, \
"6bc1bee22e409f96e93d7e117393172a", "7649abac8119b246cee98e9b12e9197d8964e0b149c10b7b682e6e39aaeb731c");
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "7649ABAC8119B246CEE98E9B12E9197D", true, \
"ae2d8a571e03ac9c9eb76fac45af8e51", "5086cb9b507219ee95db113a917678b255e21d7100b988ffec32feeafaf23538");
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "5086cb9b507219ee95db113a917678b2", true, \
"30c81c46a35ce411e5fbc1191a0a52ef", "73bed6b8e3c1743b7116e69e22229516f6eccda327bf8e5ec43718b0039adceb");
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "73bed6b8e3c1743b7116e69e22229516", true, \
"f69f2445df4f9b17ad2b417be66c3710", "3ff1caa1681fac09120eca307586e1a78cb82807230e1321d3fae00d18cc2012");
// NIST AES CBC 256-bit encryption test-vectors
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
"000102030405060708090A0B0C0D0E0F", false, "6bc1bee22e409f96e93d7e117393172a", \
"f58c4c04d6e5f1ba779eabfb5f7bfbd6");
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
"F58C4C04D6E5F1BA779EABFB5F7BFBD6", false, "ae2d8a571e03ac9c9eb76fac45af8e51", \
"9cfc4e967edb808d679f777bc6702c7d");
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
"9CFC4E967EDB808D679F777BC6702C7D", false, "30c81c46a35ce411e5fbc1191a0a52ef",
"39f23369a9d9bacfa530e26304231461");
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
"39F23369A9D9BACFA530E26304231461", false, "f69f2445df4f9b17ad2b417be66c3710", \
"b2eb05e2c39be9fcda6c19078c6a9d1b");
// The same vectors with padding enabled
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
"000102030405060708090A0B0C0D0E0F", true, "6bc1bee22e409f96e93d7e117393172a", \
"f58c4c04d6e5f1ba779eabfb5f7bfbd6485a5c81519cf378fa36d42b8547edc0");
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
"F58C4C04D6E5F1BA779EABFB5F7BFBD6", true, "ae2d8a571e03ac9c9eb76fac45af8e51", \
"9cfc4e967edb808d679f777bc6702c7d3a3aa5e0213db1a9901f9036cf5102d2");
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
"9CFC4E967EDB808D679F777BC6702C7D", true, "30c81c46a35ce411e5fbc1191a0a52ef",
"39f23369a9d9bacfa530e263042314612f8da707643c90a6f732b3de1d3f5cee");
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
"39F23369A9D9BACFA530E26304231461", true, "f69f2445df4f9b17ad2b417be66c3710", \
"b2eb05e2c39be9fcda6c19078c6a9d1b3f461796d6b0d6b2e0c2a72b4d80e644");
}
BOOST_AUTO_TEST_SUITE_END()

View File

@ -32,7 +32,8 @@
#include "librustzcash.h"
CClientUIInterface uiInterface; // Declared but not defined in ui_interface.h
ZCJoinSplit *pzcashParams;
TracingHandle* pTracingHandle = nullptr;
FastRandomContext insecure_rand_ctx(true);
extern bool fPrintToConsole;
@ -40,8 +41,6 @@ extern void noui_connect();
JoinSplitTestingSetup::JoinSplitTestingSetup(const std::string& chainName) : BasicTestingSetup(chainName)
{
pzcashParams = ZCJoinSplit::Prepared();
boost::filesystem::path sapling_spend = ZC_GetParamsDir() / "sapling-spend.params";
boost::filesystem::path sapling_output = ZC_GetParamsDir() / "sapling-output.params";
boost::filesystem::path sprout_groth16 = ZC_GetParamsDir() / "sprout-groth16.params";
@ -68,7 +67,6 @@ JoinSplitTestingSetup::JoinSplitTestingSetup(const std::string& chainName) : Bas
JoinSplitTestingSetup::~JoinSplitTestingSetup()
{
delete pzcashParams;
}
BasicTestingSetup::BasicTestingSetup(const std::string& chainName)

View File

@ -16,6 +16,7 @@
#include "keystore.h"
#include "main.h"
#include "policy/policy.h"
#include "proof_verifier.h"
#include "script/script.h"
#include "script/script_error.h"
#include "script/sign.h"
@ -108,7 +109,7 @@ BOOST_AUTO_TEST_CASE(tx_valid)
UniValue tests = read_json(std::string(json_tests::tx_valid, json_tests::tx_valid + sizeof(json_tests::tx_valid)));
std::string comment("");
auto verifier = libzcash::ProofVerifier::Strict();
auto verifier = ProofVerifier::Strict();
ScriptError err;
for (size_t idx = 0; idx < tests.size(); idx++) {
UniValue test = tests[idx];
@ -196,7 +197,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
UniValue tests = read_json(std::string(json_tests::tx_invalid, json_tests::tx_invalid + sizeof(json_tests::tx_invalid)));
std::string comment("");
auto verifier = libzcash::ProofVerifier::Strict();
auto verifier = ProofVerifier::Strict();
ScriptError err;
for (size_t idx = 0; idx < tests.size(); idx++) {
UniValue test = tests[idx];
@ -278,7 +279,7 @@ BOOST_AUTO_TEST_CASE(basic_transaction_tests)
CMutableTransaction tx;
stream >> tx;
CValidationState state;
auto verifier = libzcash::ProofVerifier::Strict();
auto verifier = ProofVerifier::Strict();
BOOST_CHECK_MESSAGE(CheckTransaction(tx, state, verifier) && state.IsValid(), "Simple deserialized transaction should be valid.");
// Check that duplicate txins fail
@ -369,11 +370,11 @@ BOOST_AUTO_TEST_CASE(test_basic_joinsplit_verification)
libzcash::JSOutput(addr, 50)
};
auto verifier = libzcash::ProofVerifier::Strict();
auto verifier = ProofVerifier::Strict();
{
JSDescription jsdesc(*pzcashParams, joinSplitPubKey, rt, inputs, outputs, 0, 0);
BOOST_CHECK(jsdesc.Verify(*pzcashParams, verifier, joinSplitPubKey));
JSDescription jsdesc(joinSplitPubKey, rt, inputs, outputs, 0, 0);
BOOST_CHECK(verifier.VerifySprout(jsdesc, joinSplitPubKey));
CDataStream ss(SER_DISK, CLIENT_VERSION);
auto os = WithVersion(&ss, SAPLING_TX_VERSION | 1 << 31);
@ -383,20 +384,20 @@ BOOST_AUTO_TEST_CASE(test_basic_joinsplit_verification)
os >> jsdesc_deserialized;
BOOST_CHECK(jsdesc_deserialized == jsdesc);
BOOST_CHECK(jsdesc_deserialized.Verify(*pzcashParams, verifier, joinSplitPubKey));
BOOST_CHECK(verifier.VerifySprout(jsdesc_deserialized, joinSplitPubKey));
}
{
// Ensure that the balance equation is working.
BOOST_CHECK_THROW(JSDescription(*pzcashParams, joinSplitPubKey, rt, inputs, outputs, 10, 0), std::invalid_argument);
BOOST_CHECK_THROW(JSDescription(*pzcashParams, joinSplitPubKey, rt, inputs, outputs, 0, 10), std::invalid_argument);
BOOST_CHECK_THROW(JSDescription(joinSplitPubKey, rt, inputs, outputs, 10, 0), std::invalid_argument);
BOOST_CHECK_THROW(JSDescription(joinSplitPubKey, rt, inputs, outputs, 0, 10), std::invalid_argument);
}
{
// Ensure that it won't verify if the root is changed.
auto test = JSDescription(*pzcashParams, joinSplitPubKey, rt, inputs, outputs, 0, 0);
auto test = JSDescription(joinSplitPubKey, rt, inputs, outputs, 0, 0);
test.anchor = GetRandHash();
BOOST_CHECK(!test.Verify(*pzcashParams, verifier, joinSplitPubKey));
BOOST_CHECK(!verifier.VerifySprout(test, joinSplitPubKey));
}
}
@ -460,7 +461,7 @@ void test_simple_sapling_invalidity(uint32_t consensusBranchId, CMutableTransact
void test_simple_joinsplit_invalidity(uint32_t consensusBranchId, CMutableTransaction tx)
{
auto verifier = libzcash::ProofVerifier::Strict();
auto verifier = ProofVerifier::Strict();
{
// Ensure that empty vin/vout remain invalid without
// joinsplits.

View File

@ -5,6 +5,7 @@
#include "transaction_builder.h"
#include "main.h"
#include "proof_verifier.h"
#include "pubkey.h"
#include "rpc/protocol.h"
#include "script/sign.h"
@ -99,13 +100,11 @@ TransactionBuilder::TransactionBuilder(
const Consensus::Params& consensusParams,
int nHeight,
CKeyStore* keystore,
ZCJoinSplit* sproutParams,
CCoinsViewCache* coinsView,
CCriticalSection* cs_coinsView) :
consensusParams(consensusParams),
nHeight(nHeight),
keystore(keystore),
sproutParams(sproutParams),
coinsView(coinsView),
cs_coinsView(cs_coinsView)
{
@ -179,10 +178,6 @@ void TransactionBuilder::AddSproutInput(
libzcash::SproutNote note,
SproutWitness witness)
{
if (sproutParams == nullptr) {
throw std::runtime_error("Cannot add Sprout inputs to a TransactionBuilder without Sprout params");
}
// Consistency check: all anchors must equal the first one
if (!jsInputs.empty()) {
if (jsInputs[0].witness.root() != witness.root()) {
@ -198,10 +193,6 @@ void TransactionBuilder::AddSproutOutput(
CAmount value,
std::array<unsigned char, ZC_MEMO_SIZE> memo)
{
if (sproutParams == nullptr) {
throw std::runtime_error("Cannot add Sprout outputs to a TransactionBuilder without Sprout params");
}
libzcash::JSOutput jsOutput(to, value);
jsOutput.memo = memo;
jsOutputs.push_back(jsOutput);
@ -724,7 +715,6 @@ void TransactionBuilder::CreateJSDescription(
// Generate the proof, this can take over a minute.
assert(mtx.fOverwintered && (mtx.nVersion >= SAPLING_TX_VERSION));
JSDescription jsdesc = JSDescription::Randomized(
*sproutParams,
mtx.joinSplitPubKey,
vjsin[0].witness.root(),
vjsin,
@ -737,8 +727,8 @@ void TransactionBuilder::CreateJSDescription(
&esk); // parameter expects pointer to esk, so pass in address
{
auto verifier = libzcash::ProofVerifier::Strict();
if (!jsdesc.Verify(*sproutParams, verifier, mtx.joinSplitPubKey)) {
auto verifier = ProofVerifier::Strict();
if (!verifier.VerifySprout(jsdesc, mtx.joinSplitPubKey)) {
throw std::runtime_error("error verifying joinsplit");
}
}

View File

@ -78,7 +78,6 @@ private:
Consensus::Params consensusParams;
int nHeight;
const CKeyStore* keystore;
ZCJoinSplit* sproutParams;
const CCoinsViewCache* coinsView;
CCriticalSection* cs_coinsView;
CMutableTransaction mtx;
@ -100,7 +99,6 @@ public:
const Consensus::Params& consensusParams,
int nHeight,
CKeyStore* keyStore = nullptr,
ZCJoinSplit* sproutParams = nullptr,
CCoinsViewCache* coinsView = nullptr,
CCriticalSection* cs_coinsView = nullptr);

Some files were not shown because too many files have changed in this diff Show More