Browse Source

Merge pull request #5235

9eb5a5f build: pad header for osx libs (Cory Fields)
9ed8979 build: fix static dll link for mingw (Cory Fields)
19df238 build: shared lib build should work reasonably well now (Cory Fields)
269efa3 build: add quick consensus lib tests (Cory Fields)
cdd36c6 build: add --with-libs so that libs are optional (Cory Fields)
2cf5f16 build: add libbitcoinconsensus files and hook up the lib build (Cory Fields)
ee64c53 build: remove internal/protected build attribute checks (Cory Fields)
f36a40f build: check visibility attributes (Cory Fields)
811a765 build: mingw needs libssp for hardening with dlls (Cory Fields)
e0077de build: make a distinction between static app ldflags and static lib ldflags (Cory Fields)
0.10
Wladimir J. van der Laan 10 years ago
parent
commit
9842ed465b
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 5
      .gitignore
  2. 217
      build-aux/m4/ax_gcc_func_attribute.m4
  3. 46
      configure.ac
  4. 43
      src/Makefile.am
  5. 2
      src/Makefile.qt.include
  6. 2
      src/Makefile.qttest.include
  7. 4
      src/Makefile.test.include
  8. 91
      src/script/bitcoinconsensus.cpp
  9. 67
      src/script/bitcoinconsensus.h
  10. 13
      src/test/script_tests.cpp

5
.gitignore vendored

@ -45,6 +45,7 @@ src/qt/test/moc*.cpp
.deps .deps
.dirstamp .dirstamp
.libs
.*.swp .*.swp
*.*~* *.*~*
*.bak *.bak
@ -66,6 +67,10 @@ src/qt/test/moc*.cpp
*.json.h *.json.h
*.raw.h *.raw.h
#libtool object files
*.lo
*.la
# Compilation and Qt preprocessor part # Compilation and Qt preprocessor part
*.qm *.qm
Makefile Makefile

217
build-aux/m4/ax_gcc_func_attribute.m4

@ -0,0 +1,217 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_gcc_func_attribute.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_GCC_FUNC_ATTRIBUTE(ATTRIBUTE)
#
# DESCRIPTION
#
# This macro checks if the compiler supports one of GCC's function
# attributes; many other compilers also provide function attributes with
# the same syntax. Compiler warnings are used to detect supported
# attributes as unsupported ones are ignored by default so quieting
# warnings when using this macro will yield false positives.
#
# The ATTRIBUTE parameter holds the name of the attribute to be checked.
#
# If ATTRIBUTE is supported define HAVE_FUNC_ATTRIBUTE_<ATTRIBUTE>.
#
# The macro caches its result in the ax_cv_have_func_attribute_<attribute>
# variable.
#
# The macro currently supports the following function attributes:
#
# alias
# aligned
# alloc_size
# always_inline
# artificial
# cold
# const
# constructor
# deprecated
# destructor
# dllexport
# dllimport
# error
# externally_visible
# flatten
# format
# format_arg
# gnu_inline
# hot
# ifunc
# leaf
# malloc
# noclone
# noinline
# nonnull
# noreturn
# nothrow
# optimize
# pure
# unused
# used
# visibility
# warning
# warn_unused_result
# weak
# weakref
#
# Unsuppored function attributes will be tested with a prototype returning
# an int and not accepting any arguments and the result of the check might
# be wrong or meaningless so use with care.
#
# LICENSE
#
# Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 2
AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [
AS_VAR_PUSHDEF([ac_var], [ax_cv_have_func_attribute_$1])
AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([
m4_case([$1],
[alias], [
int foo( void ) { return 0; }
int bar( void ) __attribute__(($1("foo")));
],
[aligned], [
int foo( void ) __attribute__(($1(32)));
],
[alloc_size], [
void *foo(int a) __attribute__(($1(1)));
],
[always_inline], [
inline __attribute__(($1)) int foo( void ) { return 0; }
],
[artificial], [
inline __attribute__(($1)) int foo( void ) { return 0; }
],
[cold], [
int foo( void ) __attribute__(($1));
],
[const], [
int foo( void ) __attribute__(($1));
],
[constructor], [
int foo( void ) __attribute__(($1));
],
[deprecated], [
int foo( void ) __attribute__(($1("")));
],
[destructor], [
int foo( void ) __attribute__(($1));
],
[dllexport], [
__attribute__(($1)) int foo( void ) { return 0; }
],
[dllimport], [
int foo( void ) __attribute__(($1));
],
[error], [
int foo( void ) __attribute__(($1("")));
],
[externally_visible], [
int foo( void ) __attribute__(($1));
],
[flatten], [
int foo( void ) __attribute__(($1));
],
[format], [
int foo(const char *p, ...) __attribute__(($1(printf, 1, 2)));
],
[format_arg], [
char *foo(const char *p) __attribute__(($1(1)));
],
[gnu_inline], [
inline __attribute__(($1)) int foo( void ) { return 0; }
],
[hot], [
int foo( void ) __attribute__(($1));
],
[ifunc], [
int my_foo( void ) { return 0; }
static int (*resolve_foo(void))(void) { return my_foo; }
int foo( void ) __attribute__(($1("resolve_foo")));
],
[leaf], [
__attribute__(($1)) int foo( void ) { return 0; }
],
[malloc], [
void *foo( void ) __attribute__(($1));
],
[noclone], [
int foo( void ) __attribute__(($1));
],
[noinline], [
__attribute__(($1)) int foo( void ) { return 0; }
],
[nonnull], [
int foo(char *p) __attribute__(($1(1)));
],
[noreturn], [
void foo( void ) __attribute__(($1));
],
[nothrow], [
int foo( void ) __attribute__(($1));
],
[optimize], [
__attribute__(($1(3))) int foo( void ) { return 0; }
],
[pure], [
int foo( void ) __attribute__(($1));
],
[unused], [
int foo( void ) __attribute__(($1));
],
[used], [
int foo( void ) __attribute__(($1));
],
[visibility], [
int foo_def( void ) __attribute__(($1("default")));
int foo_hid( void ) __attribute__(($1("hidden")));
],
[warning], [
int foo( void ) __attribute__(($1("")));
],
[warn_unused_result], [
int foo( void ) __attribute__(($1));
],
[weak], [
int foo( void ) __attribute__(($1));
],
[weakref], [
static int foo( void ) { return 0; }
static int bar( void ) __attribute__(($1("foo")));
],
[
m4_warn([syntax], [Unsupported attribute $1, the test may fail])
int foo( void ) __attribute__(($1));
]
)], [])
],
dnl GCC doesn't exit with an error if an unknown attribute is
dnl provided but only outputs a warning, so accept the attribute
dnl only if no warning were issued.
[AS_IF([test -s conftest.err],
[AS_VAR_SET([ac_var], [no])],
[AS_VAR_SET([ac_var], [yes])])],
[AS_VAR_SET([ac_var], [no])])
])
AS_IF([test yes = AS_VAR_GET([ac_var])],
[AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_FUNC_ATTRIBUTE_$1), 1,
[Define to 1 if the system has the `$1' function attribute])], [])
AS_VAR_POPDEF([ac_var])
])

46
configure.ac

@ -49,7 +49,7 @@ case $host in
;; ;;
esac esac
dnl Libtool init checks. dnl Libtool init checks.
LT_INIT([disable-shared]) LT_INIT([pic-only])
dnl Check/return PATH for base programs. dnl Check/return PATH for base programs.
AC_PATH_TOOL(AR, ar) AC_PATH_TOOL(AR, ar)
@ -201,12 +201,9 @@ case $host in
AC_CHECK_LIB([iphlpapi], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([iphlpapi], [main],, AC_MSG_ERROR(lib missing))
AC_CHECK_LIB([crypt32], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([crypt32], [main],, AC_MSG_ERROR(lib missing))
AX_CHECK_LINK_FLAG([[-static-libgcc]],[LDFLAGS="$LDFLAGS -static-libgcc"])
AX_CHECK_LINK_FLAG([[-static-libstdc++]],[LDFLAGS="$LDFLAGS -static-libstdc++"])
# -static is interpreted by libtool, where it has a different meaning. # -static is interpreted by libtool, where it has a different meaning.
# In libtool-speak, it's -all-static. # In libtool-speak, it's -all-static.
AX_CHECK_LINK_FLAG([[-static]],[LDFLAGS="$LDFLAGS -static"; LIBTOOL_LDFLAGS="$LIBTOOL_LDFLAGS -all-static"]) AX_CHECK_LINK_FLAG([[-static]],[LIBTOOL_APP_LDFLAGS="$LIBTOOL_APP_LDFLAGS -all-static"])
AC_PATH_PROG([MAKENSIS], [makensis], none) AC_PATH_PROG([MAKENSIS], [makensis], none)
if test x$MAKENSIS = xnone; then if test x$MAKENSIS = xnone; then
@ -229,6 +226,15 @@ case $host in
*) AC_MSG_ERROR("Could not determine win32/win64 for installer") ;; *) AC_MSG_ERROR("Could not determine win32/win64 for installer") ;;
esac esac
AC_SUBST(WINDOWS_BITS) AC_SUBST(WINDOWS_BITS)
dnl libtool insists upon adding -nostdlib and a list of objects/libs to link against.
dnl That breaks our ability to build dll's with static libgcc/libstdc++/libssp. Override
dnl its command here, with the predeps/postdeps removed, and -static inserted. Postdeps are
dnl also overridden to prevent their insertion later.
dnl This should only affect dll's.
archive_cmds_CXX="\$CC -shared \$libobjs \$deplibs \$compiler_flags -static -o \$output_objdir/\$soname \${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker \$lib"
postdeps_CXX=
;; ;;
*darwin*) *darwin*)
TARGET_OS=darwin TARGET_OS=darwin
@ -279,6 +285,7 @@ case $host in
esac esac
fi fi
AX_CHECK_LINK_FLAG([[-Wl,-headerpad_max_install_names]], [LDFLAGS="$LDFLAGS -Wl,-headerpad_max_install_names"])
CPPFLAGS="$CPPFLAGS -DMAC_OSX" CPPFLAGS="$CPPFLAGS -DMAC_OSX"
;; ;;
*linux*) *linux*)
@ -349,6 +356,10 @@ fi
AX_CHECK_LINK_FLAG([[-Wl,--large-address-aware]], [LDFLAGS="$LDFLAGS -Wl,--large-address-aware"]) AX_CHECK_LINK_FLAG([[-Wl,--large-address-aware]], [LDFLAGS="$LDFLAGS -Wl,--large-address-aware"])
AX_GCC_FUNC_ATTRIBUTE([visibility])
AX_GCC_FUNC_ATTRIBUTE([dllexport])
AX_GCC_FUNC_ATTRIBUTE([dllimport])
if test x$use_glibc_compat != xno; then if test x$use_glibc_compat != xno; then
#__fdelt_chk's params and return type have changed from long unsigned int to long int. #__fdelt_chk's params and return type have changed from long unsigned int to long int.
@ -389,6 +400,12 @@ if test x$use_hardening != xno; then
AX_CHECK_LINK_FLAG([[-pie]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -pie"]) AX_CHECK_LINK_FLAG([[-pie]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -pie"])
fi fi
case $host in
*mingw*)
AC_CHECK_LIB([ssp], [main],, AC_MSG_ERROR(lib missing))
;;
esac
CXXFLAGS="$CXXFLAGS $HARDENED_CXXFLAGS" CXXFLAGS="$CXXFLAGS $HARDENED_CXXFLAGS"
CPPFLAGS="$CPPFLAGS $HARDENED_CPPFLAGS" CPPFLAGS="$CPPFLAGS $HARDENED_CPPFLAGS"
LDFLAGS="$LDFLAGS $HARDENED_LDFLAGS" LDFLAGS="$LDFLAGS $HARDENED_LDFLAGS"
@ -603,6 +620,12 @@ AC_ARG_WITH([utils],
[build_bitcoin_utils=$withval], [build_bitcoin_utils=$withval],
[build_bitcoin_utils=yes]) [build_bitcoin_utils=yes])
AC_ARG_WITH([libs],
[AS_HELP_STRING([--with-libs],
[build libraries (default=yes)])],
[build_bitcoin_libs=$withval],
[build_bitcoin_libs=yes])
AC_ARG_WITH([daemon], AC_ARG_WITH([daemon],
[AS_HELP_STRING([--with-daemon], [AS_HELP_STRING([--with-daemon],
[build bitcoind daemon (default=yes)])], [build bitcoind daemon (default=yes)])],
@ -653,6 +676,13 @@ AC_MSG_CHECKING([whether to build utils (bitcoin-cli bitcoin-tx)])
AM_CONDITIONAL([BUILD_BITCOIN_UTILS], [test x$build_bitcoin_utils = xyes]) AM_CONDITIONAL([BUILD_BITCOIN_UTILS], [test x$build_bitcoin_utils = xyes])
AC_MSG_RESULT($build_bitcoin_utils) AC_MSG_RESULT($build_bitcoin_utils)
AC_MSG_CHECKING([whether to build libraries])
AM_CONDITIONAL([BUILD_BITCOIN_LIBS], [test x$build_bitcoin_libs = xyes])
if test x$build_bitcoin_libs = xyes; then
AC_DEFINE(HAVE_CONSENSUS_LIB, 1, [Define this symbol if the consensus lib has been built])
fi
AC_MSG_RESULT($build_bitcoin_libs)
dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus
BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt4]) BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt4])
@ -769,8 +799,8 @@ else
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
fi fi
if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests = xnononono; then if test x$build_bitcoin_utils$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_tests = xnononono; then
AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-daemon --with-gui or --enable-tests]) AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-gui or --enable-tests])
fi fi
AM_CONDITIONAL([TARGET_DARWIN], [test x$TARGET_OS = xdarwin]) AM_CONDITIONAL([TARGET_DARWIN], [test x$TARGET_OS = xdarwin])
@ -801,7 +831,7 @@ AC_SUBST(CLIENT_VERSION_IS_RELEASE, _CLIENT_VERSION_IS_RELEASE)
AC_SUBST(COPYRIGHT_YEAR, _COPYRIGHT_YEAR) AC_SUBST(COPYRIGHT_YEAR, _COPYRIGHT_YEAR)
AC_SUBST(RELDFLAGS) AC_SUBST(RELDFLAGS)
AC_SUBST(LIBTOOL_LDFLAGS) AC_SUBST(LIBTOOL_APP_LDFLAGS)
AC_SUBST(USE_UPNP) AC_SUBST(USE_UPNP)
AC_SUBST(USE_QRCODE) AC_SUBST(USE_QRCODE)
AC_SUBST(BOOST_LIBS) AC_SUBST(BOOST_LIBS)

43
src/Makefile.am

@ -49,6 +49,13 @@ BITCOIN_INCLUDES += $(BDB_CPPFLAGS)
noinst_LIBRARIES += libbitcoin_wallet.a noinst_LIBRARIES += libbitcoin_wallet.a
endif endif
if BUILD_BITCOIN_LIBS
lib_LTLIBRARIES = libbitcoinconsensus.la
LIBBITCOIN_CONSENSUS=libbitcoinconsensus.la
else
LIBBITCOIN_CONSENSUS=
endif
bin_PROGRAMS = bin_PROGRAMS =
TESTS = TESTS =
@ -295,7 +302,7 @@ endif
bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS)
bitcoind_CPPFLAGS = $(BITCOIN_INCLUDES) bitcoind_CPPFLAGS = $(BITCOIN_INCLUDES)
bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
# bitcoin-cli binary # # bitcoin-cli binary #
bitcoin_cli_LDADD = \ bitcoin_cli_LDADD = \
@ -324,12 +331,42 @@ bitcoin_tx_LDADD = \
bitcoin_tx_SOURCES = bitcoin-tx.cpp bitcoin_tx_SOURCES = bitcoin-tx.cpp
bitcoin_tx_CPPFLAGS = $(BITCOIN_INCLUDES) bitcoin_tx_CPPFLAGS = $(BITCOIN_INCLUDES)
# #
bitcoin_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) bitcoin_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
if TARGET_WINDOWS if TARGET_WINDOWS
bitcoin_cli_SOURCES += bitcoin-cli-res.rc bitcoin_cli_SOURCES += bitcoin-cli-res.rc
endif endif
bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
if BUILD_BITCOIN_LIBS
include_HEADERS = script/bitcoinconsensus.h
libbitcoinconsensus_la_SOURCES = \
core/transaction.cpp \
crypto/sha1.cpp \
crypto/sha2.cpp \
crypto/ripemd160.cpp \
eccryptoverify.cpp \
ecwrapper.cpp \
hash.cpp \
pubkey.cpp \
script/script.cpp \
script/interpreter.cpp \
script/bitcoinconsensus.cpp \
uint256.cpp \
utilstrencodings.cpp
if GLIBC_BACK_COMPAT
libbitcoinconsensus_la_SOURCES += compat/glibc_compat.cpp
libbitcoinconsensus_la_SOURCES += compat/glibcxx_compat.cpp
endif
libbitcoinconsensus_la_LDFLAGS = -no-undefined $(RELDFLAGS)
libbitcoinconsensus_la_LIBADD = $(CRYPTO_LIBS)
libbitcoinconsensus_la_CPPFLAGS = $(CRYPTO_CFLAGS) -I$(builddir)/obj -DBUILD_BITCOIN_INTERNAL
if USE_LIBSECP256K1
libbitcoinconsensus_la_LIBADD += secp256k1/libsecp256k1.la
endif
endif
CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a *.gcda *.gcno CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a *.gcda *.gcno

2
src/Makefile.qt.include

@ -361,7 +361,7 @@ qt_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET)
endif endif
qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \ qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
$(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1)
qt_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) qt_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
qt_bitcoin_qt_LIBTOOLFLAGS = --tag CXX qt_bitcoin_qt_LIBTOOLFLAGS = --tag CXX
#locale/foo.ts -> locale/foo.qm #locale/foo.ts -> locale/foo.qm

2
src/Makefile.qttest.include

@ -33,7 +33,7 @@ endif
qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) \ qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) \
$(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \ $(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
$(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1)
qt_test_test_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) qt_test_test_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
CLEAN_BITCOIN_QT_TEST = $(TEST_QT_MOC_CPP) qt/test/*.gcda qt/test/*.gcno CLEAN_BITCOIN_QT_TEST = $(TEST_QT_MOC_CPP) qt/test/*.gcda qt/test/*.gcno

4
src/Makefile.test.include

@ -85,8 +85,8 @@ if ENABLE_WALLET
test_test_bitcoin_LDADD += $(LIBBITCOIN_WALLET) test_test_bitcoin_LDADD += $(LIBBITCOIN_WALLET)
endif endif
test_test_bitcoin_LDADD += $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS)
test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static-libtool-libs
nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES) nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES)

91
src/script/bitcoinconsensus.cpp

@ -0,0 +1,91 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "bitcoinconsensus.h"
#include "core/transaction.h"
#include "script/interpreter.h"
#include "version.h"
namespace {
/** A class that deserializes a single CTransaction one time. */
class TxInputStream
{
public:
TxInputStream(int nTypeIn, int nVersionIn, const unsigned char *txTo, size_t txToLen) :
m_type(nTypeIn),
m_version(nVersionIn),
m_data(txTo),
m_remaining(txToLen)
{}
TxInputStream& read(char* pch, size_t nSize)
{
if (nSize > m_remaining)
throw std::ios_base::failure(std::string(__func__) + ": end of data");
if (pch == NULL)
throw std::ios_base::failure(std::string(__func__) + ": bad destination buffer");
if (m_data == NULL)
throw std::ios_base::failure(std::string(__func__) + ": bad source buffer");
memcpy(pch, m_data, nSize);
m_remaining -= nSize;
m_data += nSize;
return *this;
}
template<typename T>
TxInputStream& operator>>(T& obj)
{
::Unserialize(*this, obj, m_type, m_version);
return *this;
}
private:
const int m_type;
const int m_version;
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;
}
} // anon namespace
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)
{
try {
TxInputStream stream(SER_NETWORK, PROTOCOL_VERSION, txTo, txToLen);
CTransaction tx;
stream >> tx;
if (nIn >= tx.vin.size())
return set_error(err, bitcoinconsensus_ERR_TX_INDEX);
if (tx.GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION) != 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);
return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), flags, SignatureChecker(tx, nIn), NULL);
} catch (std::exception &e) {
return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing
}
}
unsigned int bitcoinconsensus_version()
{
// Just use the API version for now
return BITCOINCONSENSUS_API_VER;
}

67
src/script/bitcoinconsensus.h

@ -0,0 +1,67 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_BITCOINCONSENSUS_H
#define BITCOIN_BITCOINCONSENSUS_H
#if defined(BUILD_BITCOIN_INTERNAL) && defined(HAVE_CONFIG_H)
#include "config/bitcoin-config.h"
#if defined(_WIN32)
#if defined(DLL_EXPORT)
#if defined(HAVE_FUNC_ATTRIBUTE_DLLEXPORT)
#define EXPORT_SYMBOL __declspec(dllexport)
#else
#define EXPORT_SYMBOL
#endif
#endif
#elif defined(HAVE_FUNC_ATTRIBUTE_VISIBILITY)
#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 0
typedef enum bitcoinconsensus_error_t
{
bitcoinconsensus_ERR_OK = 0,
bitcoinconsensus_ERR_TX_INDEX,
bitcoinconsensus_ERR_TX_SIZE_MISMATCH,
bitcoinconsensus_ERR_TX_DESERIALIZE,
} bitcoinconsensus_error;
/** Script verification flags */
enum
{
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NONE = 0,
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts
};
/// 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 NULL, 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 unsigned int bitcoinconsensus_version();
#ifdef __cplusplus
} // extern "C"
#endif
#undef EXPORT_SYMBOL
#endif // BITCOIN_BITCOINCONSENSUS_H

13
src/test/script_tests.cpp

@ -14,6 +14,10 @@
#include "script/sign.h" #include "script/sign.h"
#include "util.h" #include "util.h"
#if defined(HAVE_CONSENSUS_LIB)
#include "script/bitcoinconsensus.h"
#endif
#include <fstream> #include <fstream>
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
@ -94,8 +98,15 @@ CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMu
void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, bool expect, const std::string& message) void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, bool expect, const std::string& message)
{ {
ScriptError err; ScriptError err;
BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, SignatureChecker(BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey)), 0), &err) == expect, message); CMutableTransaction tx = BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey));
CMutableTransaction tx2 = tx;
BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, SignatureChecker(tx, 0), &err) == expect, message);
BOOST_CHECK_MESSAGE(expect == (err == SCRIPT_ERR_OK), std::string(ScriptErrorString(err)) + ": " + message); BOOST_CHECK_MESSAGE(expect == (err == SCRIPT_ERR_OK), std::string(ScriptErrorString(err)) + ": " + message);
#if defined(HAVE_CONSENSUS_LIB)
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
stream << tx2;
BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(begin_ptr(scriptPubKey), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect,message);
#endif
} }
void static NegateSignatureS(std::vector<unsigned char>& vchSig) { void static NegateSignatureS(std::vector<unsigned char>& vchSig) {

Loading…
Cancel
Save