mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-25 02:33:24 -03:00
remove libbitcoinconsensus
This was deprecated in v27.0, for removal in v28.0. See discussion in PR #29189.
This commit is contained in:
parent
9a459e3ab9
commit
80f8b92f4f
17 changed files with 10 additions and 694 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -136,7 +136,6 @@ test/lint/test_runner/target/
|
||||||
|
|
||||||
/doc/doxygen/
|
/doc/doxygen/
|
||||||
|
|
||||||
libbitcoinconsensus.pc
|
|
||||||
contrib/devtools/split-debug.sh
|
contrib/devtools/split-debug.sh
|
||||||
|
|
||||||
# Output from running db4 installation
|
# Output from running db4 installation
|
||||||
|
|
|
@ -14,11 +14,6 @@ endif
|
||||||
.PHONY: deploy FORCE
|
.PHONY: deploy FORCE
|
||||||
.INTERMEDIATE: $(COVERAGE_INFO)
|
.INTERMEDIATE: $(COVERAGE_INFO)
|
||||||
|
|
||||||
if BUILD_BITCOIN_LIBS
|
|
||||||
pkgconfigdir = $(libdir)/pkgconfig
|
|
||||||
pkgconfig_DATA = libbitcoinconsensus.pc
|
|
||||||
endif
|
|
||||||
|
|
||||||
BITCOIND_BIN=$(top_builddir)/src/$(BITCOIN_DAEMON_NAME)$(EXEEXT)
|
BITCOIND_BIN=$(top_builddir)/src/$(BITCOIN_DAEMON_NAME)$(EXEEXT)
|
||||||
BITCOIN_QT_BIN=$(top_builddir)/src/qt/$(BITCOIN_GUI_NAME)$(EXEEXT)
|
BITCOIN_QT_BIN=$(top_builddir)/src/qt/$(BITCOIN_GUI_NAME)$(EXEEXT)
|
||||||
BITCOIN_TEST_BIN=$(top_builddir)/src/test/$(BITCOIN_TEST_NAME)$(EXEEXT)
|
BITCOIN_TEST_BIN=$(top_builddir)/src/test/$(BITCOIN_TEST_NAME)$(EXEEXT)
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
<ClCompile Include="..\..\src\primitives\block.cpp" />
|
<ClCompile Include="..\..\src\primitives\block.cpp" />
|
||||||
<ClCompile Include="..\..\src\primitives\transaction.cpp" />
|
<ClCompile Include="..\..\src\primitives\transaction.cpp" />
|
||||||
<ClCompile Include="..\..\src\pubkey.cpp" />
|
<ClCompile Include="..\..\src\pubkey.cpp" />
|
||||||
<ClCompile Include="..\..\src\script\bitcoinconsensus.cpp" />
|
|
||||||
<ClCompile Include="..\..\src\script\interpreter.cpp" />
|
<ClCompile Include="..\..\src\script\interpreter.cpp" />
|
||||||
<ClCompile Include="..\..\src\script\script.cpp" />
|
<ClCompile Include="..\..\src\script\script.cpp" />
|
||||||
<ClCompile Include="..\..\src\script\script_error.cpp" />
|
<ClCompile Include="..\..\src\script\script_error.cpp" />
|
||||||
|
|
|
@ -16,5 +16,5 @@ export RUN_UNIT_TESTS_SEQUENTIAL="true"
|
||||||
export RUN_UNIT_TESTS="false"
|
export RUN_UNIT_TESTS="false"
|
||||||
export GOAL="install"
|
export GOAL="install"
|
||||||
export DOWNLOAD_PREVIOUS_RELEASES="true"
|
export DOWNLOAD_PREVIOUS_RELEASES="true"
|
||||||
export BITCOIN_CONFIG="--enable-zmq --with-libs=no --with-gui=qt5 --enable-reduce-exports --enable-debug \
|
export BITCOIN_CONFIG="--enable-zmq --with-gui=qt5 --enable-reduce-exports --enable-debug \
|
||||||
CFLAGS=\"-g0 -O2 -funsigned-char\" CPPFLAGS='-DBOOST_MULTI_INDEX_ENABLE_SAFE_MODE' CXXFLAGS=\"-g0 -O2 -funsigned-char\""
|
CFLAGS=\"-g0 -O2 -funsigned-char\" CPPFLAGS='-DBOOST_MULTI_INDEX_ENABLE_SAFE_MODE' CXXFLAGS=\"-g0 -O2 -funsigned-char\""
|
||||||
|
|
26
configure.ac
26
configure.ac
|
@ -626,15 +626,9 @@ AC_ARG_ENABLE([experimental-util-chainstate],
|
||||||
[build_bitcoin_chainstate=$enableval],
|
[build_bitcoin_chainstate=$enableval],
|
||||||
[build_bitcoin_chainstate=no])
|
[build_bitcoin_chainstate=no])
|
||||||
|
|
||||||
AC_ARG_WITH([libs],
|
|
||||||
[AS_HELP_STRING([--with-libs],
|
|
||||||
[build libraries (default=yes)])],
|
|
||||||
[build_bitcoin_libs=$withval],
|
|
||||||
[build_bitcoin_libs=yes])
|
|
||||||
|
|
||||||
AC_ARG_WITH([experimental-kernel-lib],
|
AC_ARG_WITH([experimental-kernel-lib],
|
||||||
[AS_HELP_STRING([--with-experimental-kernel-lib],
|
[AS_HELP_STRING([--with-experimental-kernel-lib],
|
||||||
[build experimental bitcoinkernel library (default is to build if we're building libraries and the experimental build-chainstate executable)])],
|
[build experimental bitcoinkernel library (default is to build if we're building the experimental build-chainstate executable)])],
|
||||||
[build_experimental_kernel_lib=$withval],
|
[build_experimental_kernel_lib=$withval],
|
||||||
[build_experimental_kernel_lib=auto])
|
[build_experimental_kernel_lib=auto])
|
||||||
|
|
||||||
|
@ -1262,7 +1256,6 @@ if test "$enable_fuzz" = "yes"; then
|
||||||
build_bitcoin_chainstate=no
|
build_bitcoin_chainstate=no
|
||||||
build_bitcoin_wallet=no
|
build_bitcoin_wallet=no
|
||||||
build_bitcoind=no
|
build_bitcoind=no
|
||||||
build_bitcoin_libs=no
|
|
||||||
bitcoin_enable_qt=no
|
bitcoin_enable_qt=no
|
||||||
bitcoin_enable_qt_test=no
|
bitcoin_enable_qt_test=no
|
||||||
bitcoin_enable_qt_dbus=no
|
bitcoin_enable_qt_dbus=no
|
||||||
|
@ -1421,7 +1414,7 @@ if test "$use_boost" = "yes"; then
|
||||||
dnl Check for Boost headers
|
dnl Check for Boost headers
|
||||||
AX_BOOST_BASE([1.73.0],[],[AC_MSG_ERROR([Boost is not available!])])
|
AX_BOOST_BASE([1.73.0],[],[AC_MSG_ERROR([Boost is not available!])])
|
||||||
if test "$want_boost" = "no"; then
|
if test "$want_boost" = "no"; then
|
||||||
AC_MSG_ERROR([only libbitcoinconsensus can be built without Boost])
|
AC_MSG_ERROR([Boost is required])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl we don't use multi_index serialization
|
dnl we don't use multi_index serialization
|
||||||
|
@ -1635,18 +1628,8 @@ fi
|
||||||
AM_CONDITIONAL([BUILD_BITCOIN_CHAINSTATE], [test $build_bitcoin_chainstate = "yes"])
|
AM_CONDITIONAL([BUILD_BITCOIN_CHAINSTATE], [test $build_bitcoin_chainstate = "yes"])
|
||||||
AC_MSG_RESULT($build_bitcoin_chainstate)
|
AC_MSG_RESULT($build_bitcoin_chainstate)
|
||||||
|
|
||||||
AC_MSG_CHECKING([whether to build libraries])
|
|
||||||
AM_CONDITIONAL([BUILD_BITCOIN_LIBS], [test $build_bitcoin_libs = "yes"])
|
|
||||||
|
|
||||||
if test "$build_bitcoin_libs" = "yes"; then
|
|
||||||
AC_DEFINE([HAVE_CONSENSUS_LIB], [1], [Define this symbol if the consensus lib has been built])
|
|
||||||
AC_CONFIG_FILES([libbitcoinconsensus.pc:libbitcoinconsensus.pc.in])
|
|
||||||
fi
|
|
||||||
|
|
||||||
AM_CONDITIONAL([BUILD_BITCOIN_KERNEL_LIB], [test "$build_experimental_kernel_lib" != "no" && ( test "$build_experimental_kernel_lib" = "yes" || test "$build_bitcoin_chainstate" = "yes" )])
|
AM_CONDITIONAL([BUILD_BITCOIN_KERNEL_LIB], [test "$build_experimental_kernel_lib" != "no" && ( test "$build_experimental_kernel_lib" = "yes" || test "$build_bitcoin_chainstate" = "yes" )])
|
||||||
|
|
||||||
AC_MSG_RESULT($build_bitcoin_libs)
|
|
||||||
|
|
||||||
AC_LANG_POP
|
AC_LANG_POP
|
||||||
|
|
||||||
if test "$use_ccache" != "no"; then
|
if test "$use_ccache" != "no"; then
|
||||||
|
@ -1780,8 +1763,8 @@ else
|
||||||
AC_MSG_RESULT([no])
|
AC_MSG_RESULT([no])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$build_bitcoin_wallet$build_bitcoin_cli$build_bitcoin_tx$build_bitcoin_util$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$enable_fuzz_binary$use_bench$use_tests" = "nononononononononono"; then
|
if test "$build_bitcoin_wallet$build_bitcoin_cli$build_bitcoin_tx$build_bitcoin_util$build_bitcoind$bitcoin_enable_qt$enable_fuzz_binary$use_bench$use_tests" = "nonononononononono"; then
|
||||||
AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-gui --enable-fuzz(-binary) --enable-bench or --enable-tests])
|
AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-daemon --with-gui --enable-fuzz(-binary) --enable-bench or --enable-tests])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AM_CONDITIONAL([TARGET_DARWIN], [test "$TARGET_OS" = "darwin"])
|
AM_CONDITIONAL([TARGET_DARWIN], [test "$TARGET_OS" = "darwin"])
|
||||||
|
@ -1941,7 +1924,6 @@ echo
|
||||||
echo "Options used to compile and link:"
|
echo "Options used to compile and link:"
|
||||||
echo " external signer = $use_external_signer"
|
echo " external signer = $use_external_signer"
|
||||||
echo " multiprocess = $build_multiprocess"
|
echo " multiprocess = $build_multiprocess"
|
||||||
echo " with libs = $build_bitcoin_libs"
|
|
||||||
echo " with wallet = $enable_wallet"
|
echo " with wallet = $enable_wallet"
|
||||||
if test "$enable_wallet" != "no"; then
|
if test "$enable_wallet" != "no"; then
|
||||||
echo " with sqlite = $use_sqlite"
|
echo " with sqlite = $use_sqlite"
|
||||||
|
|
|
@ -59,7 +59,6 @@ The Bitcoin repo's [root README](/README.md) contains relevant information on th
|
||||||
- [Translation Strings Policy](translation_strings_policy.md)
|
- [Translation Strings Policy](translation_strings_policy.md)
|
||||||
- [JSON-RPC Interface](JSON-RPC-interface.md)
|
- [JSON-RPC Interface](JSON-RPC-interface.md)
|
||||||
- [Unauthenticated REST Interface](REST-interface.md)
|
- [Unauthenticated REST Interface](REST-interface.md)
|
||||||
- [Shared Libraries](shared-libraries.md)
|
|
||||||
- [BIPS](bips.md)
|
- [BIPS](bips.md)
|
||||||
- [Dnsseed Policy](dnsseed-policy.md)
|
- [Dnsseed Policy](dnsseed-policy.md)
|
||||||
- [Benchmarking](benchmarking.md)
|
- [Benchmarking](benchmarking.md)
|
||||||
|
|
|
@ -4,10 +4,9 @@
|
||||||
|--------------------------|-------------|
|
|--------------------------|-------------|
|
||||||
| *libbitcoin_cli* | RPC client functionality used by *bitcoin-cli* executable |
|
| *libbitcoin_cli* | RPC client functionality used by *bitcoin-cli* executable |
|
||||||
| *libbitcoin_common* | Home for common functionality shared by different executables and libraries. Similar to *libbitcoin_util*, but higher-level (see [Dependencies](#dependencies)). |
|
| *libbitcoin_common* | Home for common functionality shared by different executables and libraries. Similar to *libbitcoin_util*, but higher-level (see [Dependencies](#dependencies)). |
|
||||||
| *libbitcoin_consensus* | Stable, backwards-compatible consensus functionality used by *libbitcoin_node* and *libbitcoin_wallet* and also exposed as a [shared library](../shared-libraries.md). |
|
| *libbitcoin_consensus* | Stable, backwards-compatible consensus functionality used by *libbitcoin_node* and *libbitcoin_wallet*. |
|
||||||
| *libbitcoinconsensus* | Shared library build of static *libbitcoin_consensus* library |
|
| *libbitcoin_kernel* | Consensus engine and support library used for validation by *libbitcoin_node*. |
|
||||||
| *libbitcoin_kernel* | Consensus engine and support library used for validation by *libbitcoin_node* and also exposed as a [shared library](../shared-libraries.md). |
|
| *libbitcoinqt* | GUI functionality used by *bitcoin-qt* and *bitcoin-gui* executables. |
|
||||||
| *libbitcoinqt* | GUI functionality used by *bitcoin-qt* and *bitcoin-gui* executables |
|
|
||||||
| *libbitcoin_ipc* | IPC functionality used by *bitcoin-node*, *bitcoin-wallet*, *bitcoin-gui* executables to communicate when [`--enable-multiprocess`](multiprocess.md) is used. |
|
| *libbitcoin_ipc* | IPC functionality used by *bitcoin-node*, *bitcoin-wallet*, *bitcoin-gui* executables to communicate when [`--enable-multiprocess`](multiprocess.md) is used. |
|
||||||
| *libbitcoin_node* | P2P and RPC server functionality used by *bitcoind* and *bitcoin-qt* executables. |
|
| *libbitcoin_node* | P2P and RPC server functionality used by *bitcoind* and *bitcoin-qt* executables. |
|
||||||
| *libbitcoin_util* | Home for common functionality shared by different executables and libraries. Similar to *libbitcoin_common*, but lower-level (see [Dependencies](#dependencies)). |
|
| *libbitcoin_util* | Home for common functionality shared by different executables and libraries. Similar to *libbitcoin_common*, but lower-level (see [Dependencies](#dependencies)). |
|
||||||
|
@ -17,7 +16,7 @@
|
||||||
|
|
||||||
## Conventions
|
## Conventions
|
||||||
|
|
||||||
- Most libraries are internal libraries and have APIs which are completely unstable! There are few or no restrictions on backwards compatibility or rules about external dependencies. Exceptions are *libbitcoin_consensus* and *libbitcoin_kernel* which have external interfaces documented at [../shared-libraries.md](../shared-libraries.md).
|
- Most libraries are internal libraries and have APIs which are completely unstable! There are few or no restrictions on backwards compatibility or rules about external dependencies. An exception is *libbitcoin_kernel*, which, at some future point, will have a documented external interface.
|
||||||
|
|
||||||
- Generally each library should have a corresponding source directory and namespace. Source code organization is a work in progress, so it is true that some namespaces are applied inconsistently, and if you look at [`libbitcoin_*_SOURCES`](../../src/Makefile.am) lists you can see that many libraries pull in files from outside their source directory. But when working with libraries, it is good to follow a consistent pattern like:
|
- Generally each library should have a corresponding source directory and namespace. Source code organization is a work in progress, so it is true that some namespaces are applied inconsistently, and if you look at [`libbitcoin_*_SOURCES`](../../src/Makefile.am) lists you can see that many libraries pull in files from outside their source directory. But when working with libraries, it is good to follow a consistent pattern like:
|
||||||
|
|
||||||
|
|
|
@ -1,78 +0,0 @@
|
||||||
Shared Libraries
|
|
||||||
================
|
|
||||||
|
|
||||||
## bitcoinconsensus
|
|
||||||
***This library is deprecated and will be removed in v28***
|
|
||||||
|
|
||||||
The purpose of this library is to make the verification functionality that is critical to Bitcoin's consensus available to other applications, e.g. to language bindings.
|
|
||||||
|
|
||||||
### API
|
|
||||||
|
|
||||||
The interface is defined in the C header `bitcoinconsensus.h` located in `src/script/bitcoinconsensus.h`.
|
|
||||||
|
|
||||||
#### Version
|
|
||||||
|
|
||||||
`bitcoinconsensus_version` returns an `unsigned int` with the API version *(currently `2`)*.
|
|
||||||
|
|
||||||
#### Script Validation
|
|
||||||
|
|
||||||
`bitcoinconsensus_verify_script`, `bitcoinconsensus_verify_script_with_amount` and `bitcoinconsensus_verify_script_with_spent_outputs` return an `int` with the status of the verification. It will be `1` if the input script correctly spends the previous output `scriptPubKey`.
|
|
||||||
|
|
||||||
##### Parameters
|
|
||||||
###### bitcoinconsensus_verify_script
|
|
||||||
- `const unsigned char *scriptPubKey` - The previous output script that encumbers spending.
|
|
||||||
- `unsigned int scriptPubKeyLen` - The number of bytes for the `scriptPubKey`.
|
|
||||||
- `const unsigned char *txTo` - The transaction with the input that is spending the previous output.
|
|
||||||
- `unsigned int txToLen` - The number of bytes for the `txTo`.
|
|
||||||
- `unsigned int nIn` - The index of the input in `txTo` that spends the `scriptPubKey`.
|
|
||||||
- `unsigned int flags` - The script validation flags *(see below)*.
|
|
||||||
- `bitcoinconsensus_error* err` - Will have the error/success code for the operation *(see below)*.
|
|
||||||
|
|
||||||
###### bitcoinconsensus_verify_script_with_amount
|
|
||||||
- `const unsigned char *scriptPubKey` - The previous output script that encumbers spending.
|
|
||||||
- `unsigned int scriptPubKeyLen` - The number of bytes for the `scriptPubKey`.
|
|
||||||
- `int64_t amount` - The amount spent in the input
|
|
||||||
- `const unsigned char *txTo` - The transaction with the input that is spending the previous output.
|
|
||||||
- `unsigned int txToLen` - The number of bytes for the `txTo`.
|
|
||||||
- `unsigned int nIn` - The index of the input in `txTo` that spends the `scriptPubKey`.
|
|
||||||
- `unsigned int flags` - The script validation flags *(see below)*.
|
|
||||||
- `bitcoinconsensus_error* err` - Will have the error/success code for the operation *(see below)*.
|
|
||||||
|
|
||||||
###### bitcoinconsensus_verify_script_with_spent_outputs
|
|
||||||
- `const unsigned char *scriptPubKey` - The previous output script that encumbers spending.
|
|
||||||
- `unsigned int scriptPubKeyLen` - The number of bytes for the `scriptPubKey`.
|
|
||||||
- `int64_t amount` - The amount spent in the input
|
|
||||||
- `const unsigned char *txTo` - The transaction with the input that is spending the previous output.
|
|
||||||
- `unsigned int txToLen` - The number of bytes for the `txTo`.
|
|
||||||
- `UTXO *spentOutputs` - Previous outputs spent in the transaction. `UTXO` is a struct composed by `const unsigned char *scriptPubKey`, `unsigned int scriptPubKeySize` (the number of bytes for the `scriptPubKey`) and `unsigned int value`.
|
|
||||||
- `unsigned int spentOutputsLen` - The number of bytes for the `spentOutputs`.
|
|
||||||
- `unsigned int nIn` - The index of the input in `txTo` that spends the `scriptPubKey`.
|
|
||||||
- `unsigned int flags` - The script validation flags *(see below)*.
|
|
||||||
- `bitcoinconsensus_error* err` - Will have the error/success code for the operation *(see below)*.
|
|
||||||
|
|
||||||
##### Script Flags
|
|
||||||
- `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NONE`
|
|
||||||
- `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH` - Evaluate P2SH ([BIP16](https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki)) subscripts
|
|
||||||
- `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG` - Enforce strict DER ([BIP66](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki)) compliance
|
|
||||||
- `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NULLDUMMY` - Enforce NULLDUMMY ([BIP147](https://github.com/bitcoin/bips/blob/master/bip-0147.mediawiki))
|
|
||||||
- `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY` - Enable CHECKLOCKTIMEVERIFY ([BIP65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki))
|
|
||||||
- `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKSEQUENCEVERIFY` - Enable CHECKSEQUENCEVERIFY ([BIP112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki))
|
|
||||||
- `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS` - Enable WITNESS ([BIP141](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki))
|
|
||||||
- `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_TAPROOT` - Enable TAPROOT ([BIP340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki), [BIP341](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki), [BIP342](https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki))
|
|
||||||
|
|
||||||
##### Errors
|
|
||||||
- `bitcoinconsensus_ERR_OK` - No errors with input parameters *(see the return value of `bitcoinconsensus_verify_script` for the verification status)*
|
|
||||||
- `bitcoinconsensus_ERR_TX_INDEX` - An invalid index for `txTo`
|
|
||||||
- `bitcoinconsensus_ERR_TX_SIZE_MISMATCH` - `txToLen` did not match with the size of `txTo`
|
|
||||||
- `bitcoinconsensus_ERR_DESERIALIZE` - An error deserializing `txTo`
|
|
||||||
- `bitcoinconsensus_ERR_AMOUNT_REQUIRED` - Input amount is required if WITNESS is used
|
|
||||||
- `bitcoinconsensus_ERR_INVALID_FLAGS` - Script verification `flags` are invalid (i.e. not part of the libconsensus interface)
|
|
||||||
- `bitcoinconsensus_ERR_SPENT_OUTPUTS_REQUIRED` - Spent outputs are required if TAPROOT is used
|
|
||||||
- `bitcoinconsensus_ERR_SPENT_OUTPUTS_MISMATCH` - Spent outputs size doesn't match tx inputs size
|
|
||||||
|
|
||||||
### Example Implementations
|
|
||||||
- [NBitcoin](https://github.com/MetacoSA/NBitcoin/blob/5e1055cd7c4186dee4227c344af8892aea54faec/NBitcoin/Script.cs#L979-#L1031) (.NET Bindings)
|
|
||||||
- [node-libbitcoinconsensus](https://github.com/bitpay/node-libbitcoinconsensus) (Node.js Bindings)
|
|
||||||
- [java-libbitcoinconsensus](https://github.com/dexX7/java-libbitcoinconsensus) (Java Bindings)
|
|
||||||
- [bitcoinconsensus-php](https://github.com/Bit-Wasp/bitcoinconsensus-php) (PHP Bindings)
|
|
||||||
- [rust-bitcoinconsensus](https://github.com/rust-bitcoin/rust-bitcoinconsensus) (Rust Bindings)
|
|
|
@ -1,10 +0,0 @@
|
||||||
prefix=@prefix@
|
|
||||||
exec_prefix=@exec_prefix@
|
|
||||||
libdir=@libdir@
|
|
||||||
includedir=@includedir@
|
|
||||||
|
|
||||||
Name: @PACKAGE_NAME@ consensus library
|
|
||||||
Description: Library for the Bitcoin consensus protocol.
|
|
||||||
Version: @PACKAGE_VERSION@
|
|
||||||
Libs: -L${libdir} -lbitcoinconsensus
|
|
||||||
Cflags: -I${includedir}
|
|
|
@ -39,9 +39,6 @@ LIBSECP256K1=secp256k1/libsecp256k1.la
|
||||||
if ENABLE_ZMQ
|
if ENABLE_ZMQ
|
||||||
LIBBITCOIN_ZMQ=libbitcoin_zmq.a
|
LIBBITCOIN_ZMQ=libbitcoin_zmq.a
|
||||||
endif
|
endif
|
||||||
if BUILD_BITCOIN_LIBS
|
|
||||||
LIBBITCOINCONSENSUS=libbitcoinconsensus.la
|
|
||||||
endif
|
|
||||||
if BUILD_BITCOIN_KERNEL_LIB
|
if BUILD_BITCOIN_KERNEL_LIB
|
||||||
LIBBITCOINKERNEL=libbitcoinkernel.la
|
LIBBITCOINKERNEL=libbitcoinkernel.la
|
||||||
endif
|
endif
|
||||||
|
@ -648,7 +645,6 @@ libbitcoin_consensus_a_SOURCES = \
|
||||||
primitives/transaction.h \
|
primitives/transaction.h \
|
||||||
pubkey.cpp \
|
pubkey.cpp \
|
||||||
pubkey.h \
|
pubkey.h \
|
||||||
script/bitcoinconsensus.cpp \
|
|
||||||
script/interpreter.cpp \
|
script/interpreter.cpp \
|
||||||
script/interpreter.h \
|
script/interpreter.h \
|
||||||
script/script.cpp \
|
script/script.cpp \
|
||||||
|
@ -1007,21 +1003,6 @@ libbitcoinkernel_la-clientversion.l$(OBJEXT): obj/build.h
|
||||||
endif # BUILD_BITCOIN_KERNEL_LIB
|
endif # BUILD_BITCOIN_KERNEL_LIB
|
||||||
#
|
#
|
||||||
|
|
||||||
# bitcoinconsensus library #
|
|
||||||
if BUILD_BITCOIN_LIBS
|
|
||||||
lib_LTLIBRARIES += $(LIBBITCOINCONSENSUS)
|
|
||||||
|
|
||||||
include_HEADERS = script/bitcoinconsensus.h
|
|
||||||
libbitcoinconsensus_la_SOURCES = support/cleanse.cpp $(crypto_libbitcoin_crypto_base_la_SOURCES) $(libbitcoin_consensus_a_SOURCES)
|
|
||||||
|
|
||||||
libbitcoinconsensus_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(RELDFLAGS)
|
|
||||||
libbitcoinconsensus_la_LIBADD = $(LIBSECP256K1)
|
|
||||||
libbitcoinconsensus_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(builddir)/obj -I$(srcdir)/secp256k1/include -DBUILD_BITCOIN_INTERNAL -DDISABLE_OPTIMIZED_SHA256
|
|
||||||
libbitcoinconsensus_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
|
||||||
|
|
||||||
endif
|
|
||||||
#
|
|
||||||
|
|
||||||
CTAES_DIST = crypto/ctaes/bench.c
|
CTAES_DIST = crypto/ctaes/bench.c
|
||||||
CTAES_DIST += crypto/ctaes/ctaes.c
|
CTAES_DIST += crypto/ctaes/ctaes.c
|
||||||
CTAES_DIST += crypto/ctaes/ctaes.h
|
CTAES_DIST += crypto/ctaes/ctaes.h
|
||||||
|
|
|
@ -362,7 +362,6 @@ test_fuzz_fuzz_SOURCES = \
|
||||||
test/fuzz/rpc.cpp \
|
test/fuzz/rpc.cpp \
|
||||||
test/fuzz/script.cpp \
|
test/fuzz/script.cpp \
|
||||||
test/fuzz/script_assets_test_minimizer.cpp \
|
test/fuzz/script_assets_test_minimizer.cpp \
|
||||||
test/fuzz/script_bitcoin_consensus.cpp \
|
|
||||||
test/fuzz/script_descriptor_cache.cpp \
|
test/fuzz/script_descriptor_cache.cpp \
|
||||||
test/fuzz/script_flags.cpp \
|
test/fuzz/script_flags.cpp \
|
||||||
test/fuzz/script_format.cpp \
|
test/fuzz/script_format.cpp \
|
||||||
|
|
|
@ -2,15 +2,8 @@
|
||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#if defined(HAVE_CONFIG_H)
|
|
||||||
#include <config/bitcoin-config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <bench/bench.h>
|
#include <bench/bench.h>
|
||||||
#include <key.h>
|
#include <key.h>
|
||||||
#if defined(HAVE_CONSENSUS_LIB)
|
|
||||||
#include <script/bitcoinconsensus.h>
|
|
||||||
#endif
|
|
||||||
#include <script/script.h>
|
#include <script/script.h>
|
||||||
#include <script/interpreter.h>
|
#include <script/interpreter.h>
|
||||||
#include <streams.h>
|
#include <streams.h>
|
||||||
|
@ -63,17 +56,6 @@ static void VerifyScriptBench(benchmark::Bench& bench)
|
||||||
&err);
|
&err);
|
||||||
assert(err == SCRIPT_ERR_OK);
|
assert(err == SCRIPT_ERR_OK);
|
||||||
assert(success);
|
assert(success);
|
||||||
|
|
||||||
#if defined(HAVE_CONSENSUS_LIB)
|
|
||||||
DataStream stream;
|
|
||||||
stream << TX_WITH_WITNESS(txSpend);
|
|
||||||
int csuccess = bitcoinconsensus_verify_script_with_amount(
|
|
||||||
txCredit.vout[0].scriptPubKey.data(),
|
|
||||||
txCredit.vout[0].scriptPubKey.size(),
|
|
||||||
txCredit.vout[0].nValue,
|
|
||||||
(const unsigned char*)stream.data(), stream.size(), 0, flags, nullptr);
|
|
||||||
assert(csuccess == 1);
|
|
||||||
#endif
|
|
||||||
});
|
});
|
||||||
ECC_Stop();
|
ECC_Stop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,157 +0,0 @@
|
||||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
|
||||||
// Copyright (c) 2009-2022 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 <script/bitcoinconsensus.h>
|
|
||||||
|
|
||||||
#include <primitives/transaction.h>
|
|
||||||
#include <pubkey.h>
|
|
||||||
#include <script/interpreter.h>
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
/** A class that deserializes a single CTransaction one time. */
|
|
||||||
class TxInputStream
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
TxInputStream(const unsigned char *txTo, size_t txToLen) :
|
|
||||||
m_data(txTo),
|
|
||||||
m_remaining(txToLen)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void read(Span<std::byte> dst)
|
|
||||||
{
|
|
||||||
if (dst.size() > m_remaining) {
|
|
||||||
throw std::ios_base::failure(std::string(__func__) + ": end of data");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dst.data() == nullptr) {
|
|
||||||
throw std::ios_base::failure(std::string(__func__) + ": bad destination buffer");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_data == nullptr) {
|
|
||||||
throw std::ios_base::failure(std::string(__func__) + ": bad source buffer");
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(dst.data(), m_data, dst.size());
|
|
||||||
m_remaining -= dst.size();
|
|
||||||
m_data += dst.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
TxInputStream& operator>>(T&& obj)
|
|
||||||
{
|
|
||||||
::Unserialize(*this, obj);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const unsigned char* m_data;
|
|
||||||
size_t m_remaining;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline int set_error(bitcoinconsensus_error* ret, bitcoinconsensus_error serror)
|
|
||||||
{
|
|
||||||
if (ret)
|
|
||||||
*ret = serror;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
/** Check that all specified flags are part of the libconsensus interface. */
|
|
||||||
static bool verify_flags(unsigned int flags)
|
|
||||||
{
|
|
||||||
return (flags & ~(bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL)) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, CAmount amount,
|
|
||||||
const unsigned char *txTo , unsigned int txToLen,
|
|
||||||
const UTXO *spentOutputs, unsigned int spentOutputsLen,
|
|
||||||
unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err)
|
|
||||||
{
|
|
||||||
if (!verify_flags(flags)) {
|
|
||||||
return set_error(err, bitcoinconsensus_ERR_INVALID_FLAGS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_TAPROOT && spentOutputs == nullptr) {
|
|
||||||
return set_error(err, bitcoinconsensus_ERR_SPENT_OUTPUTS_REQUIRED);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
TxInputStream stream(txTo, txToLen);
|
|
||||||
CTransaction tx(deserialize, TX_WITH_WITNESS, stream);
|
|
||||||
|
|
||||||
std::vector<CTxOut> spent_outputs;
|
|
||||||
if (spentOutputs != nullptr) {
|
|
||||||
if (spentOutputsLen != tx.vin.size()) {
|
|
||||||
return set_error(err, bitcoinconsensus_ERR_SPENT_OUTPUTS_MISMATCH);
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < spentOutputsLen; i++) {
|
|
||||||
CScript spk = CScript(spentOutputs[i].scriptPubKey, spentOutputs[i].scriptPubKey + spentOutputs[i].scriptPubKeySize);
|
|
||||||
const CAmount& value = spentOutputs[i].value;
|
|
||||||
CTxOut tx_out = CTxOut(value, spk);
|
|
||||||
spent_outputs.push_back(tx_out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nIn >= tx.vin.size())
|
|
||||||
return set_error(err, bitcoinconsensus_ERR_TX_INDEX);
|
|
||||||
if (GetSerializeSize(TX_WITH_WITNESS(tx)) != txToLen)
|
|
||||||
return set_error(err, bitcoinconsensus_ERR_TX_SIZE_MISMATCH);
|
|
||||||
|
|
||||||
// Regardless of the verification result, the tx did not error.
|
|
||||||
set_error(err, bitcoinconsensus_ERR_OK);
|
|
||||||
|
|
||||||
PrecomputedTransactionData txdata(tx);
|
|
||||||
|
|
||||||
if (spentOutputs != nullptr && flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_TAPROOT) {
|
|
||||||
txdata.Init(tx, std::move(spent_outputs));
|
|
||||||
}
|
|
||||||
|
|
||||||
return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), &tx.vin[nIn].scriptWitness, flags, TransactionSignatureChecker(&tx, nIn, amount, txdata, MissingDataBehavior::FAIL), nullptr);
|
|
||||||
} catch (const std::exception&) {
|
|
||||||
return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int bitcoinconsensus_verify_script_with_spent_outputs(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, int64_t amount,
|
|
||||||
const unsigned char *txTo , unsigned int txToLen,
|
|
||||||
const UTXO *spentOutputs, unsigned int spentOutputsLen,
|
|
||||||
unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err)
|
|
||||||
{
|
|
||||||
CAmount am(amount);
|
|
||||||
return ::verify_script(scriptPubKey, scriptPubKeyLen, am, txTo, txToLen, spentOutputs, spentOutputsLen, nIn, flags, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
int bitcoinconsensus_verify_script_with_amount(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, int64_t amount,
|
|
||||||
const unsigned char *txTo , unsigned int txToLen,
|
|
||||||
unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err)
|
|
||||||
{
|
|
||||||
CAmount am(amount);
|
|
||||||
UTXO *spentOutputs = nullptr;
|
|
||||||
unsigned int spentOutputsLen = 0;
|
|
||||||
return ::verify_script(scriptPubKey, scriptPubKeyLen, am, txTo, txToLen, spentOutputs, spentOutputsLen, nIn, flags, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen,
|
|
||||||
const unsigned char *txTo , unsigned int txToLen,
|
|
||||||
unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err)
|
|
||||||
{
|
|
||||||
if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) {
|
|
||||||
return set_error(err, bitcoinconsensus_ERR_AMOUNT_REQUIRED);
|
|
||||||
}
|
|
||||||
|
|
||||||
CAmount am(0);
|
|
||||||
UTXO *spentOutputs = nullptr;
|
|
||||||
unsigned int spentOutputsLen = 0;
|
|
||||||
return ::verify_script(scriptPubKey, scriptPubKeyLen, am, txTo, txToLen, spentOutputs, spentOutputsLen, nIn, flags, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int bitcoinconsensus_version()
|
|
||||||
{
|
|
||||||
// Just use the API version for now
|
|
||||||
return BITCOINCONSENSUS_API_VER;
|
|
||||||
}
|
|
|
@ -1,96 +0,0 @@
|
||||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
|
||||||
// Copyright (c) 2009-2021 The Bitcoin Core developers
|
|
||||||
// Distributed under the MIT software license, see the accompanying
|
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
||||||
|
|
||||||
#ifndef BITCOIN_SCRIPT_BITCOINCONSENSUS_H
|
|
||||||
#define BITCOIN_SCRIPT_BITCOINCONSENSUS_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#if defined(BUILD_BITCOIN_INTERNAL) && defined(HAVE_CONFIG_H)
|
|
||||||
#include <config/bitcoin-config.h>
|
|
||||||
#if defined(_WIN32)
|
|
||||||
#if defined(HAVE_DLLEXPORT_ATTRIBUTE)
|
|
||||||
#define EXPORT_SYMBOL __declspec(dllexport)
|
|
||||||
#else
|
|
||||||
#define EXPORT_SYMBOL
|
|
||||||
#endif
|
|
||||||
#elif defined(HAVE_DEFAULT_VISIBILITY_ATTRIBUTE)
|
|
||||||
#define EXPORT_SYMBOL __attribute__ ((visibility ("default")))
|
|
||||||
#endif
|
|
||||||
#elif defined(MSC_VER) && !defined(STATIC_LIBBITCOINCONSENSUS)
|
|
||||||
#define EXPORT_SYMBOL __declspec(dllimport)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef EXPORT_SYMBOL
|
|
||||||
#define EXPORT_SYMBOL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define BITCOINCONSENSUS_API_VER 2
|
|
||||||
|
|
||||||
typedef enum bitcoinconsensus_error_t
|
|
||||||
{
|
|
||||||
bitcoinconsensus_ERR_OK = 0,
|
|
||||||
bitcoinconsensus_ERR_TX_INDEX,
|
|
||||||
bitcoinconsensus_ERR_TX_SIZE_MISMATCH,
|
|
||||||
bitcoinconsensus_ERR_TX_DESERIALIZE,
|
|
||||||
bitcoinconsensus_ERR_AMOUNT_REQUIRED,
|
|
||||||
bitcoinconsensus_ERR_INVALID_FLAGS,
|
|
||||||
bitcoinconsensus_ERR_SPENT_OUTPUTS_REQUIRED,
|
|
||||||
bitcoinconsensus_ERR_SPENT_OUTPUTS_MISMATCH
|
|
||||||
} bitcoinconsensus_error;
|
|
||||||
|
|
||||||
/** Script verification flags */
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NONE = 0,
|
|
||||||
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts
|
|
||||||
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG = (1U << 2), // enforce strict DER (BIP66) compliance
|
|
||||||
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NULLDUMMY = (1U << 4), // enforce NULLDUMMY (BIP147)
|
|
||||||
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), // enable CHECKLOCKTIMEVERIFY (BIP65)
|
|
||||||
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKSEQUENCEVERIFY = (1U << 10), // enable CHECKSEQUENCEVERIFY (BIP112)
|
|
||||||
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS = (1U << 11), // enable WITNESS (BIP141)
|
|
||||||
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_TAPROOT = (1U << 17), // enable TAPROOT (BIPs 341 & 342)
|
|
||||||
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL = bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH | bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG |
|
|
||||||
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NULLDUMMY | bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY |
|
|
||||||
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKSEQUENCEVERIFY | bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS |
|
|
||||||
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_TAPROOT
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const unsigned char *scriptPubKey;
|
|
||||||
unsigned int scriptPubKeySize;
|
|
||||||
int64_t value;
|
|
||||||
} UTXO;
|
|
||||||
|
|
||||||
/// Returns 1 if the input nIn of the serialized transaction pointed to by
|
|
||||||
/// txTo correctly spends the scriptPubKey pointed to by scriptPubKey under
|
|
||||||
/// the additional constraints specified by flags.
|
|
||||||
/// If not nullptr, err will contain an error/success code for the operation
|
|
||||||
EXPORT_SYMBOL int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen,
|
|
||||||
const unsigned char *txTo , unsigned int txToLen,
|
|
||||||
unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err);
|
|
||||||
|
|
||||||
EXPORT_SYMBOL int bitcoinconsensus_verify_script_with_amount(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, int64_t amount,
|
|
||||||
const unsigned char *txTo , unsigned int txToLen,
|
|
||||||
unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err);
|
|
||||||
|
|
||||||
EXPORT_SYMBOL int bitcoinconsensus_verify_script_with_spent_outputs(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, int64_t amount,
|
|
||||||
const unsigned char *txTo , unsigned int txToLen,
|
|
||||||
const UTXO *spentOutputs, unsigned int spentOutputsLen,
|
|
||||||
unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err);
|
|
||||||
|
|
||||||
EXPORT_SYMBOL unsigned int bitcoinconsensus_version();
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} // extern "C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef EXPORT_SYMBOL
|
|
||||||
|
|
||||||
#endif // BITCOIN_SCRIPT_BITCOINCONSENSUS_H
|
|
|
@ -1,50 +0,0 @@
|
||||||
// Copyright (c) 2020 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 <script/bitcoinconsensus.h>
|
|
||||||
#include <script/interpreter.h>
|
|
||||||
#include <test/fuzz/FuzzedDataProvider.h>
|
|
||||||
#include <test/fuzz/fuzz.h>
|
|
||||||
#include <test/fuzz/util.h>
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
FUZZ_TARGET(script_bitcoin_consensus)
|
|
||||||
{
|
|
||||||
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
|
||||||
const std::vector<uint8_t> random_bytes_1 = ConsumeRandomLengthByteVector(fuzzed_data_provider);
|
|
||||||
const std::vector<uint8_t> random_bytes_2 = ConsumeRandomLengthByteVector(fuzzed_data_provider);
|
|
||||||
const CAmount money = ConsumeMoney(fuzzed_data_provider);
|
|
||||||
bitcoinconsensus_error err;
|
|
||||||
bitcoinconsensus_error* err_p = fuzzed_data_provider.ConsumeBool() ? &err : nullptr;
|
|
||||||
const unsigned int n_in = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
|
|
||||||
const unsigned int flags = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
|
|
||||||
assert(bitcoinconsensus_version() == BITCOINCONSENSUS_API_VER);
|
|
||||||
if ((flags & SCRIPT_VERIFY_WITNESS) != 0 && (flags & SCRIPT_VERIFY_P2SH) == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
(void)bitcoinconsensus_verify_script(random_bytes_1.data(), random_bytes_1.size(), random_bytes_2.data(), random_bytes_2.size(), n_in, flags, err_p);
|
|
||||||
(void)bitcoinconsensus_verify_script_with_amount(random_bytes_1.data(), random_bytes_1.size(), money, random_bytes_2.data(), random_bytes_2.size(), n_in, flags, err_p);
|
|
||||||
|
|
||||||
std::vector<UTXO> spent_outputs;
|
|
||||||
std::vector<std::vector<unsigned char>> spent_spks;
|
|
||||||
if (n_in <= 24386) {
|
|
||||||
spent_outputs.reserve(n_in);
|
|
||||||
spent_spks.reserve(n_in);
|
|
||||||
for (size_t i = 0; i < n_in; ++i) {
|
|
||||||
spent_spks.push_back(ConsumeRandomLengthByteVector(fuzzed_data_provider));
|
|
||||||
const CAmount value{ConsumeMoney(fuzzed_data_provider)};
|
|
||||||
const auto spk_size{static_cast<unsigned>(spent_spks.back().size())};
|
|
||||||
spent_outputs.push_back({.scriptPubKey = spent_spks.back().data(), .scriptPubKeySize = spk_size, .value = value});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto spent_outs_size{static_cast<unsigned>(spent_outputs.size())};
|
|
||||||
|
|
||||||
(void)bitcoinconsensus_verify_script_with_spent_outputs(
|
|
||||||
random_bytes_1.data(), random_bytes_1.size(), money, random_bytes_2.data(), random_bytes_2.size(),
|
|
||||||
spent_outputs.data(), spent_outs_size, n_in, flags, err_p);
|
|
||||||
}
|
|
|
@ -2,10 +2,6 @@
|
||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#if defined(HAVE_CONFIG_H)
|
|
||||||
#include <config/bitcoin-config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <test/data/script_tests.json.h>
|
#include <test/data/script_tests.json.h>
|
||||||
#include <test/data/bip341_wallet_vectors.json.h>
|
#include <test/data/bip341_wallet_vectors.json.h>
|
||||||
|
|
||||||
|
@ -27,10 +23,6 @@
|
||||||
#include <util/fs.h>
|
#include <util/fs.h>
|
||||||
#include <util/strencodings.h>
|
#include <util/strencodings.h>
|
||||||
|
|
||||||
#if defined(HAVE_CONSENSUS_LIB)
|
|
||||||
#include <script/bitcoinconsensus.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -143,21 +135,6 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScript
|
||||||
if (combined_flags & SCRIPT_VERIFY_WITNESS && ~combined_flags & SCRIPT_VERIFY_P2SH) continue;
|
if (combined_flags & SCRIPT_VERIFY_WITNESS && ~combined_flags & SCRIPT_VERIFY_P2SH) continue;
|
||||||
BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, &scriptWitness, combined_flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err) == expect, message + strprintf(" (with flags %x)", combined_flags));
|
BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, &scriptWitness, combined_flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err) == expect, message + strprintf(" (with flags %x)", combined_flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_CONSENSUS_LIB)
|
|
||||||
DataStream stream;
|
|
||||||
stream << TX_WITH_WITNESS(tx2);
|
|
||||||
uint32_t libconsensus_flags{flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL};
|
|
||||||
if (libconsensus_flags == flags) {
|
|
||||||
int expectedSuccessCode = expect ? 1 : 0;
|
|
||||||
if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) {
|
|
||||||
BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), txCredit.vout[0].nValue, UCharCast(stream.data()), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message);
|
|
||||||
} else {
|
|
||||||
BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), 0, UCharCast(stream.data()), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message);
|
|
||||||
BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void static NegateSignatureS(std::vector<unsigned char>& vchSig) {
|
void static NegateSignatureS(std::vector<unsigned char>& vchSig) {
|
||||||
|
@ -1498,179 +1475,6 @@ static CScriptWitness ScriptWitnessFromJSON(const UniValue& univalue)
|
||||||
return scriptwitness;
|
return scriptwitness;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_CONSENSUS_LIB)
|
|
||||||
|
|
||||||
/* Test simple (successful) usage of bitcoinconsensus_verify_script */
|
|
||||||
BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_returns_true)
|
|
||||||
{
|
|
||||||
unsigned int libconsensus_flags = 0;
|
|
||||||
int nIn = 0;
|
|
||||||
|
|
||||||
CScript scriptPubKey;
|
|
||||||
CScript scriptSig;
|
|
||||||
CScriptWitness wit;
|
|
||||||
|
|
||||||
scriptPubKey << OP_1;
|
|
||||||
CTransaction creditTx{BuildCreditingTransaction(scriptPubKey, 1)};
|
|
||||||
CTransaction spendTx{BuildSpendingTransaction(scriptSig, wit, creditTx)};
|
|
||||||
|
|
||||||
DataStream stream;
|
|
||||||
stream << TX_WITH_WITNESS(spendTx);
|
|
||||||
|
|
||||||
bitcoinconsensus_error err;
|
|
||||||
int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
|
|
||||||
BOOST_CHECK_EQUAL(result, 1);
|
|
||||||
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Test bitcoinconsensus_verify_script returns invalid tx index err*/
|
|
||||||
BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_index_err)
|
|
||||||
{
|
|
||||||
unsigned int libconsensus_flags = 0;
|
|
||||||
int nIn = 3;
|
|
||||||
|
|
||||||
CScript scriptPubKey;
|
|
||||||
CScript scriptSig;
|
|
||||||
CScriptWitness wit;
|
|
||||||
|
|
||||||
scriptPubKey << OP_EQUAL;
|
|
||||||
CTransaction creditTx{BuildCreditingTransaction(scriptPubKey, 1)};
|
|
||||||
CTransaction spendTx{BuildSpendingTransaction(scriptSig, wit, creditTx)};
|
|
||||||
|
|
||||||
DataStream stream;
|
|
||||||
stream << TX_WITH_WITNESS(spendTx);
|
|
||||||
|
|
||||||
bitcoinconsensus_error err;
|
|
||||||
int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
|
|
||||||
BOOST_CHECK_EQUAL(result, 0);
|
|
||||||
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_INDEX);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Test bitcoinconsensus_verify_script returns tx size mismatch err*/
|
|
||||||
BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_size)
|
|
||||||
{
|
|
||||||
unsigned int libconsensus_flags = 0;
|
|
||||||
int nIn = 0;
|
|
||||||
|
|
||||||
CScript scriptPubKey;
|
|
||||||
CScript scriptSig;
|
|
||||||
CScriptWitness wit;
|
|
||||||
|
|
||||||
scriptPubKey << OP_EQUAL;
|
|
||||||
CTransaction creditTx{BuildCreditingTransaction(scriptPubKey, 1)};
|
|
||||||
CTransaction spendTx{BuildSpendingTransaction(scriptSig, wit, creditTx)};
|
|
||||||
|
|
||||||
DataStream stream;
|
|
||||||
stream << TX_WITH_WITNESS(spendTx);
|
|
||||||
|
|
||||||
bitcoinconsensus_error err;
|
|
||||||
int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size() * 2, nIn, libconsensus_flags, &err);
|
|
||||||
BOOST_CHECK_EQUAL(result, 0);
|
|
||||||
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_SIZE_MISMATCH);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Test bitcoinconsensus_verify_script returns invalid tx serialization error */
|
|
||||||
BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_serialization)
|
|
||||||
{
|
|
||||||
unsigned int libconsensus_flags = 0;
|
|
||||||
int nIn = 0;
|
|
||||||
|
|
||||||
CScript scriptPubKey;
|
|
||||||
CScript scriptSig;
|
|
||||||
CScriptWitness wit;
|
|
||||||
|
|
||||||
scriptPubKey << OP_EQUAL;
|
|
||||||
CTransaction creditTx{BuildCreditingTransaction(scriptPubKey, 1)};
|
|
||||||
CTransaction spendTx{BuildSpendingTransaction(scriptSig, wit, creditTx)};
|
|
||||||
|
|
||||||
DataStream stream;
|
|
||||||
stream << 0xffffffff;
|
|
||||||
|
|
||||||
bitcoinconsensus_error err;
|
|
||||||
int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
|
|
||||||
BOOST_CHECK_EQUAL(result, 0);
|
|
||||||
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_DESERIALIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Test bitcoinconsensus_verify_script returns amount required error */
|
|
||||||
BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_amount_required_err)
|
|
||||||
{
|
|
||||||
unsigned int libconsensus_flags = bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS;
|
|
||||||
int nIn = 0;
|
|
||||||
|
|
||||||
CScript scriptPubKey;
|
|
||||||
CScript scriptSig;
|
|
||||||
CScriptWitness wit;
|
|
||||||
|
|
||||||
scriptPubKey << OP_EQUAL;
|
|
||||||
CTransaction creditTx{BuildCreditingTransaction(scriptPubKey, 1)};
|
|
||||||
CTransaction spendTx{BuildSpendingTransaction(scriptSig, wit, creditTx)};
|
|
||||||
|
|
||||||
DataStream stream;
|
|
||||||
stream << TX_WITH_WITNESS(spendTx);
|
|
||||||
|
|
||||||
bitcoinconsensus_error err;
|
|
||||||
int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
|
|
||||||
BOOST_CHECK_EQUAL(result, 0);
|
|
||||||
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_AMOUNT_REQUIRED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Test bitcoinconsensus_verify_script returns invalid flags err */
|
|
||||||
BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_invalid_flags)
|
|
||||||
{
|
|
||||||
unsigned int libconsensus_flags = 1 << 3;
|
|
||||||
int nIn = 0;
|
|
||||||
|
|
||||||
CScript scriptPubKey;
|
|
||||||
CScript scriptSig;
|
|
||||||
CScriptWitness wit;
|
|
||||||
|
|
||||||
scriptPubKey << OP_EQUAL;
|
|
||||||
CTransaction creditTx{BuildCreditingTransaction(scriptPubKey, 1)};
|
|
||||||
CTransaction spendTx{BuildSpendingTransaction(scriptSig, wit, creditTx)};
|
|
||||||
|
|
||||||
DataStream stream;
|
|
||||||
stream << TX_WITH_WITNESS(spendTx);
|
|
||||||
|
|
||||||
bitcoinconsensus_error err;
|
|
||||||
int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
|
|
||||||
BOOST_CHECK_EQUAL(result, 0);
|
|
||||||
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_INVALID_FLAGS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Test bitcoinconsensus_verify_script returns spent outputs required err */
|
|
||||||
BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_spent_outputs_required_err)
|
|
||||||
{
|
|
||||||
unsigned int libconsensus_flags{bitcoinconsensus_SCRIPT_FLAGS_VERIFY_TAPROOT};
|
|
||||||
const int nIn{0};
|
|
||||||
|
|
||||||
CScript scriptPubKey;
|
|
||||||
CScript scriptSig;
|
|
||||||
CScriptWitness wit;
|
|
||||||
|
|
||||||
scriptPubKey << OP_EQUAL;
|
|
||||||
CTransaction creditTx{BuildCreditingTransaction(scriptPubKey, 1)};
|
|
||||||
CTransaction spendTx{BuildSpendingTransaction(scriptSig, wit, creditTx)};
|
|
||||||
|
|
||||||
DataStream stream;
|
|
||||||
stream << TX_WITH_WITNESS(spendTx);
|
|
||||||
|
|
||||||
bitcoinconsensus_error err;
|
|
||||||
int result{bitcoinconsensus_verify_script_with_spent_outputs(scriptPubKey.data(), scriptPubKey.size(), creditTx.vout[0].nValue, UCharCast(stream.data()), stream.size(), nullptr, 0, nIn, libconsensus_flags, &err)};
|
|
||||||
BOOST_CHECK_EQUAL(result, 0);
|
|
||||||
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_SPENT_OUTPUTS_REQUIRED);
|
|
||||||
|
|
||||||
result = bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), creditTx.vout[0].nValue, UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
|
|
||||||
BOOST_CHECK_EQUAL(result, 0);
|
|
||||||
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_SPENT_OUTPUTS_REQUIRED);
|
|
||||||
|
|
||||||
result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
|
|
||||||
BOOST_CHECK_EQUAL(result, 0);
|
|
||||||
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_SPENT_OUTPUTS_REQUIRED);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // defined(HAVE_CONSENSUS_LIB)
|
|
||||||
|
|
||||||
static std::vector<unsigned int> AllConsensusFlags()
|
static std::vector<unsigned int> AllConsensusFlags()
|
||||||
{
|
{
|
||||||
std::vector<unsigned int> ret;
|
std::vector<unsigned int> ret;
|
||||||
|
@ -1718,28 +1522,12 @@ static void AssetTest(const UniValue& test)
|
||||||
txdata.Init(tx, std::vector<CTxOut>(prevouts));
|
txdata.Init(tx, std::vector<CTxOut>(prevouts));
|
||||||
CachingTransactionSignatureChecker txcheck(&tx, idx, prevouts[idx].nValue, true, txdata);
|
CachingTransactionSignatureChecker txcheck(&tx, idx, prevouts[idx].nValue, true, txdata);
|
||||||
|
|
||||||
#if defined(HAVE_CONSENSUS_LIB)
|
|
||||||
DataStream stream;
|
|
||||||
stream << TX_WITH_WITNESS(tx);
|
|
||||||
std::vector<UTXO> utxos;
|
|
||||||
utxos.resize(prevouts.size());
|
|
||||||
for (size_t i = 0; i < prevouts.size(); i++) {
|
|
||||||
utxos[i].scriptPubKey = prevouts[i].scriptPubKey.data();
|
|
||||||
utxos[i].scriptPubKeySize = prevouts[i].scriptPubKey.size();
|
|
||||||
utxos[i].value = prevouts[i].nValue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (const auto flags : ALL_CONSENSUS_FLAGS) {
|
for (const auto flags : ALL_CONSENSUS_FLAGS) {
|
||||||
// "final": true tests are valid for all flags. Others are only valid with flags that are
|
// "final": true tests are valid for all flags. Others are only valid with flags that are
|
||||||
// a subset of test_flags.
|
// a subset of test_flags.
|
||||||
if (fin || ((flags & test_flags) == flags)) {
|
if (fin || ((flags & test_flags) == flags)) {
|
||||||
bool ret = VerifyScript(tx.vin[idx].scriptSig, prevouts[idx].scriptPubKey, &tx.vin[idx].scriptWitness, flags, txcheck, nullptr);
|
bool ret = VerifyScript(tx.vin[idx].scriptSig, prevouts[idx].scriptPubKey, &tx.vin[idx].scriptWitness, flags, txcheck, nullptr);
|
||||||
BOOST_CHECK(ret);
|
BOOST_CHECK(ret);
|
||||||
#if defined(HAVE_CONSENSUS_LIB)
|
|
||||||
int lib_ret = bitcoinconsensus_verify_script_with_spent_outputs(prevouts[idx].scriptPubKey.data(), prevouts[idx].scriptPubKey.size(), prevouts[idx].nValue, UCharCast(stream.data()), stream.size(), utxos.data(), utxos.size(), idx, flags, nullptr);
|
|
||||||
BOOST_CHECK(lib_ret == 1);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1752,27 +1540,11 @@ static void AssetTest(const UniValue& test)
|
||||||
txdata.Init(tx, std::vector<CTxOut>(prevouts));
|
txdata.Init(tx, std::vector<CTxOut>(prevouts));
|
||||||
CachingTransactionSignatureChecker txcheck(&tx, idx, prevouts[idx].nValue, true, txdata);
|
CachingTransactionSignatureChecker txcheck(&tx, idx, prevouts[idx].nValue, true, txdata);
|
||||||
|
|
||||||
#if defined(HAVE_CONSENSUS_LIB)
|
|
||||||
DataStream stream;
|
|
||||||
stream << TX_WITH_WITNESS(tx);
|
|
||||||
std::vector<UTXO> utxos;
|
|
||||||
utxos.resize(prevouts.size());
|
|
||||||
for (size_t i = 0; i < prevouts.size(); i++) {
|
|
||||||
utxos[i].scriptPubKey = prevouts[i].scriptPubKey.data();
|
|
||||||
utxos[i].scriptPubKeySize = prevouts[i].scriptPubKey.size();
|
|
||||||
utxos[i].value = prevouts[i].nValue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (const auto flags : ALL_CONSENSUS_FLAGS) {
|
for (const auto flags : ALL_CONSENSUS_FLAGS) {
|
||||||
// If a test is supposed to fail with test_flags, it should also fail with any superset thereof.
|
// If a test is supposed to fail with test_flags, it should also fail with any superset thereof.
|
||||||
if ((flags & test_flags) == test_flags) {
|
if ((flags & test_flags) == test_flags) {
|
||||||
bool ret = VerifyScript(tx.vin[idx].scriptSig, prevouts[idx].scriptPubKey, &tx.vin[idx].scriptWitness, flags, txcheck, nullptr);
|
bool ret = VerifyScript(tx.vin[idx].scriptSig, prevouts[idx].scriptPubKey, &tx.vin[idx].scriptWitness, flags, txcheck, nullptr);
|
||||||
BOOST_CHECK(!ret);
|
BOOST_CHECK(!ret);
|
||||||
#if defined(HAVE_CONSENSUS_LIB)
|
|
||||||
int lib_ret = bitcoinconsensus_verify_script_with_spent_outputs(prevouts[idx].scriptPubKey.data(), prevouts[idx].scriptPubKey.size(), prevouts[idx].nValue, UCharCast(stream.data()), stream.size(), utxos.data(), utxos.size(), idx, flags, nullptr);
|
|
||||||
BOOST_CHECK(lib_ret == 0);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -476,7 +476,7 @@ enum class CoinsCacheSizeState
|
||||||
* current best chain.
|
* current best chain.
|
||||||
*
|
*
|
||||||
* Eventually, the API here is targeted at being exposed externally as a
|
* Eventually, the API here is targeted at being exposed externally as a
|
||||||
* consumable libconsensus library, so any functions added must only call
|
* consumable library, so any functions added must only call
|
||||||
* other class member functions, pure functions in other parts of the consensus
|
* other class member functions, pure functions in other parts of the consensus
|
||||||
* library, callbacks via the validation interface, or read/write-to-disk
|
* library, callbacks via the validation interface, or read/write-to-disk
|
||||||
* functions (eventually this will also be via callbacks).
|
* functions (eventually this will also be via callbacks).
|
||||||
|
|
Loading…
Add table
Reference in a new issue