You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
277 lines
8.9 KiB
277 lines
8.9 KiB
From 7dea5ad88e709689e3a40f1de239e238749f9e55 Mon Sep 17 00:00:00 2001
|
|
From: Matt Whitlock <bitcoin@mattwhitlock.name>
|
|
Date: Sun, 17 Sep 2023 10:29:27 -0400
|
|
Subject: [PATCH] support linking against system-installed leveldb and
|
|
libsecp256k1
|
|
|
|
- Abort if runtime leveldb != compiled-against leveldb.
|
|
|
|
Originally based on 22.0-fix_build_without_leveldb.patch.
|
|
---
|
|
configure.ac | 71 +++++++++++++++++++++++++++++++++++++--
|
|
src/Makefile.am | 13 ++++++-
|
|
src/Makefile.test.include | 2 ++
|
|
src/dbwrapper.cpp | 27 ++++++++++++++-
|
|
src/dbwrapper.h | 8 +++++
|
|
src/kernel/checks.cpp | 7 ++++
|
|
6 files changed, 124 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index c6dc5a6875..3507a81b7a 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -1358,6 +1358,22 @@ if test "$enable_fuzz_binary" = "yes"; then
|
|
CHECK_RUNTIME_LIB
|
|
fi
|
|
|
|
+dnl Check for libsecp256k1, only if explicitly requested
|
|
+AC_ARG_WITH([system-libsecp256k1],
|
|
+ [AS_HELP_STRING([--with-system-libsecp256k1],
|
|
+ [Build with system libsecp256k1 (default is no; DANGEROUS; NOT SUPPORTED)])],
|
|
+ [system_libsecp256k1=$withval],
|
|
+ [system_libsecp256k1=no])
|
|
+AS_IF([test x$system_libsecp256k1 != xno],[
|
|
+ PKG_CHECK_MODULES([libsecp256k1],[libsecp256k1],,[true])
|
|
+],[
|
|
+ libsecp256k1_CFLAGS='-I$(srcdir)/secp256k1/include'
|
|
+ libsecp256k1_LIBS='secp256k1/libsecp256k1.la'
|
|
+])
|
|
+AM_CONDITIONAL([EMBEDDED_LIBSECP256K1],[test x$system_libsecp256k1 = xno])
|
|
+AC_SUBST(libsecp256k1_CFLAGS)
|
|
+AC_SUBST(libsecp256k1_LIBS)
|
|
+
|
|
if test "$enable_wallet" != "no"; then
|
|
dnl Check for libdb_cxx only if wallet enabled
|
|
if test "$use_bdb" != "no"; then
|
|
@@ -1415,6 +1431,55 @@ if test "$build_bitcoind$bitcoin_enable_qt$use_bench$use_tests" = "nononono"; th
|
|
use_zmq=no
|
|
fi
|
|
|
|
+dnl Check for leveldb, only if explicitly requested
|
|
+AC_ARG_WITH([system-leveldb],
|
|
+ [AS_HELP_STRING([--with-system-leveldb],
|
|
+ [Build with system LevelDB (default is no; DANGEROUS; NOT SUPPORTED)])],
|
|
+ [system_leveldb=$withval],
|
|
+ [system_leveldb=no])
|
|
+AC_ARG_VAR([leveldb_CFLAGS],[C compiler flags for system-leveldb])
|
|
+AC_ARG_VAR([leveldb_LIBS],[linker flags for system-leveldb])
|
|
+AS_IF([test x$system_leveldb != xno],[
|
|
+ TEMP_CPPFLAGS="$CPPFLAGS"
|
|
+ TEMP_LIBS="$LIBS"
|
|
+ CPPFLAGS="$leveldb_CFLAGS"
|
|
+ LIBS="$leveldb_LIBS"
|
|
+ AC_SEARCH_LIBS([leveldb_open],[leveldb],[leveldb_LIBS="$LIBS"],
|
|
+ [AC_MSG_ERROR([leveldb library not found; using --with-system-leveldb is not supported anyway])])
|
|
+ AC_CHECK_HEADER([leveldb/filter_policy.h],[],
|
|
+ [AC_MSG_ERROR([LevelDB headers not found; using --with-system-leveldb is not supported anyway])])
|
|
+ AC_CHECK_HEADER([leveldb/helpers/memenv.h],[],
|
|
+ [AC_MSG_ERROR([LevelDB headers not found; using --with-system-leveldb is not supported anyway])])
|
|
+
|
|
+ AC_MSG_CHECKING([for library containing leveldb::NewMemEnv])
|
|
+ for searchlib in "" "-lmemenv" ERR; do
|
|
+ if test "x$searchlib" = "xERR"; then
|
|
+ AC_MSG_RESULT([no])
|
|
+ AC_MSG_ERROR([LevelDB's memenv helper not found; using --with-system-leveldb is not supported anyway])
|
|
+ fi
|
|
+ LIBS="$searchlib $leveldb_LIBS"
|
|
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([
|
|
+ #include <leveldb/env.h>
|
|
+ #include <leveldb/helpers/memenv.h>
|
|
+ ],[
|
|
+ leveldb::Env *myenv = leveldb::NewMemEnv(leveldb::Env::Default());
|
|
+ delete myenv;
|
|
+ ])
|
|
+ ],[
|
|
+ AC_MSG_RESULT([$searchlib])
|
|
+ break
|
|
+ ])
|
|
+ done
|
|
+ leveldb_LIBS="$LIBS"
|
|
+ LIBS="$TEMP_LIBS"
|
|
+ CPPFLAGS="$TEMP_CPPFLAGS"
|
|
+],[
|
|
+ AC_DEFINE([EMBEDDED_LEVELDB],[1],[Define to use the bundled LevelDB sources])
|
|
+])
|
|
+AM_CONDITIONAL([EMBEDDED_LEVELDB],[test x$system_leveldb = xno])
|
|
+AC_SUBST(leveldb_CFLAGS)
|
|
+AC_SUBST(leveldb_LIBS)
|
|
+
|
|
dnl Check for libminiupnpc (optional)
|
|
if test "$use_upnp" != "no"; then
|
|
TEMP_CPPFLAGS="$CPPFLAGS"
|
|
@@ -1989,8 +2054,10 @@ CPPFLAGS_TEMP="$CPPFLAGS"
|
|
unset CPPFLAGS
|
|
CPPFLAGS="$CPPFLAGS_TEMP"
|
|
|
|
-ac_configure_args="${ac_configure_args} --disable-shared --with-pic --enable-benchmark=no --enable-module-recovery --disable-module-ecdh"
|
|
-AC_CONFIG_SUBDIRS([src/secp256k1])
|
|
+AM_COND_IF([EMBEDDED_LIBSECP256K1],[
|
|
+ ac_configure_args="${ac_configure_args} --disable-shared --with-pic --enable-benchmark=no --enable-module-recovery --disable-module-ecdh"
|
|
+ AC_CONFIG_SUBDIRS([src/secp256k1])
|
|
+])
|
|
|
|
AC_OUTPUT
|
|
|
|
diff --git a/src/Makefile.am b/src/Makefile.am
|
|
index 1d7004ac86..2fb8d3e2eb 100644
|
|
--- a/src/Makefile.am
|
|
+++ b/src/Makefile.am
|
|
@@ -24,7 +24,7 @@ check_PROGRAMS =
|
|
TESTS =
|
|
BENCHMARKS =
|
|
|
|
-BITCOIN_INCLUDES=-I$(builddir) -I$(srcdir)/$(MINISKETCH_INCLUDE_DIR_INT) -I$(srcdir)/secp256k1/include -I$(srcdir)/$(UNIVALUE_INCLUDE_DIR_INT) $(LEVELDB_CPPFLAGS)
|
|
+BITCOIN_INCLUDES=-I$(builddir) -I$(srcdir)/$(MINISKETCH_INCLUDE_DIR_INT) $(libsecp256k1_CFLAGS) -I$(srcdir)/$(UNIVALUE_INCLUDE_DIR_INT) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS)
|
|
|
|
LIBBITCOIN_NODE=libbitcoin_node.a
|
|
LIBBITCOIN_COMMON=libbitcoin_common.a
|
|
@@ -33,7 +33,11 @@ LIBBITCOIN_CLI=libbitcoin_cli.a
|
|
LIBBITCOIN_UTIL=libbitcoin_util.a
|
|
LIBBITCOIN_CRYPTO_BASE=crypto/libbitcoin_crypto_base.la
|
|
LIBBITCOINQT=qt/libbitcoinqt.a
|
|
+if EMBEDDED_LIBSECP256K1
|
|
LIBSECP256K1=secp256k1/libsecp256k1.la
|
|
+else
|
|
+LIBSECP256K1=$(libsecp256k1_LIBS)
|
|
+endif
|
|
|
|
if ENABLE_ZMQ
|
|
LIBBITCOIN_ZMQ=libbitcoin_zmq.a
|
|
@@ -68,8 +72,10 @@ LIBBITCOIN_CRYPTO += $(LIBBITCOIN_CRYPTO_ARM_SHANI)
|
|
endif
|
|
noinst_LTLIBRARIES += $(LIBBITCOIN_CRYPTO)
|
|
|
|
+if EMBEDDED_LIBSECP256K1
|
|
$(LIBSECP256K1): $(wildcard secp256k1/src/*.h) $(wildcard secp256k1/src/*.c) $(wildcard secp256k1/include/*)
|
|
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F)
|
|
+endif
|
|
|
|
# Make is not made aware of per-object dependencies to avoid limiting building parallelization
|
|
# But to build the less dependent modules first, we manually select their order here:
|
|
@@ -1104,8 +1110,13 @@ endif
|
|
|
|
include Makefile.minisketch.include
|
|
|
|
+if EMBEDDED_LEVELDB
|
|
include Makefile.crc32c.include
|
|
include Makefile.leveldb.include
|
|
+else
|
|
+LEVELDB_CPPFLAGS = $(leveldb_CFLAGS)
|
|
+LIBLEVELDB = $(leveldb_LIBS)
|
|
+endif
|
|
|
|
include Makefile.test_util.include
|
|
include Makefile.test_fuzz.include
|
|
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
|
|
index 15d5a17cec..9a7397f20f 100644
|
|
--- a/src/Makefile.test.include
|
|
+++ b/src/Makefile.test.include
|
|
@@ -384,7 +384,9 @@ if ENABLE_BENCH
|
|
$(BENCH_BINARY) -sanity-check -priority-level=high
|
|
endif
|
|
endif
|
|
+if EMBEDDED_LIBSECP256K1
|
|
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check
|
|
+endif
|
|
|
|
if ENABLE_TESTS
|
|
UNIVALUE_TESTS = univalue/test/object univalue/test/unitester
|
|
diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp
|
|
index 2aade14ef4..279037ef01 100644
|
|
--- a/src/dbwrapper.cpp
|
|
+++ b/src/dbwrapper.cpp
|
|
@@ -20,13 +20,38 @@
|
|
#include <leveldb/db.h>
|
|
#include <leveldb/env.h>
|
|
#include <leveldb/filter_policy.h>
|
|
-#include <leveldb/helpers/memenv/memenv.h>
|
|
+#if EMBEDDED_LEVELDB
|
|
+# include <leveldb/helpers/memenv/memenv.h>
|
|
+#else
|
|
+# include <leveldb/helpers/memenv.h>
|
|
+#endif
|
|
#include <leveldb/iterator.h>
|
|
#include <leveldb/options.h>
|
|
#include <leveldb/status.h>
|
|
#include <memory>
|
|
#include <optional>
|
|
|
|
+#if !EMBEDDED_LEVELDB
|
|
+#include <node/interface_ui.h>
|
|
+#include <util/translation.h>
|
|
+#include <leveldb/c.h>
|
|
+bool dbwrapper_SanityCheck()
|
|
+{
|
|
+ unsigned long header_version = (leveldb::kMajorVersion << 16) | leveldb::kMinorVersion;
|
|
+ unsigned long library_version = (leveldb_major_version() << 16) | leveldb_minor_version();
|
|
+
|
|
+ if (header_version != library_version) {
|
|
+ InitError(Untranslated(strprintf("Compiled with LevelDB %d.%d, but linked with LevelDB %d.%d (incompatible).",
|
|
+ leveldb::kMajorVersion, leveldb::kMinorVersion,
|
|
+ leveldb_major_version(), leveldb_minor_version()
|
|
+ )));
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+}
|
|
+#endif
|
|
+
|
|
class CBitcoinLevelDBLogger : public leveldb::Logger {
|
|
public:
|
|
// This code is adapted from posix_logger.h, which is why it is using vsprintf.
|
|
diff --git a/src/dbwrapper.h b/src/dbwrapper.h
|
|
index 35782edca6..0e306d7d9c 100644
|
|
--- a/src/dbwrapper.h
|
|
+++ b/src/dbwrapper.h
|
|
@@ -5,6 +5,10 @@
|
|
#ifndef BITCOIN_DBWRAPPER_H
|
|
#define BITCOIN_DBWRAPPER_H
|
|
|
|
+#if defined(HAVE_CONFIG_H)
|
|
+#include <config/bitcoin-config.h>
|
|
+#endif
|
|
+
|
|
#include <clientversion.h>
|
|
#include <logging.h>
|
|
#include <serialize.h>
|
|
@@ -54,6 +58,10 @@ struct DBParams {
|
|
DBOptions options{};
|
|
};
|
|
|
|
+#if !EMBEDDED_LEVELDB
|
|
+bool dbwrapper_SanityCheck();
|
|
+#endif
|
|
+
|
|
class dbwrapper_error : public std::runtime_error
|
|
{
|
|
public:
|
|
diff --git a/src/kernel/checks.cpp b/src/kernel/checks.cpp
|
|
index 4c303c172c..a8867c3aa5 100644
|
|
--- a/src/kernel/checks.cpp
|
|
+++ b/src/kernel/checks.cpp
|
|
@@ -4,6 +4,7 @@
|
|
|
|
#include <kernel/checks.h>
|
|
|
|
+#include <dbwrapper.h>
|
|
#include <key.h>
|
|
#include <random.h>
|
|
#include <util/time.h>
|
|
@@ -15,6 +16,12 @@ namespace kernel {
|
|
|
|
std::optional<bilingual_str> SanityChecks(const Context&)
|
|
{
|
|
+#if !EMBEDDED_LEVELDB
|
|
+ if (!dbwrapper_SanityCheck()) {
|
|
+ return Untranslated("Database sanity check failure. Aborting.");
|
|
+ }
|
|
+#endif
|
|
+
|
|
if (!ECC_InitSanityCheck()) {
|
|
return Untranslated("Elliptic curve cryptography sanity check failure. Aborting.");
|
|
}
|
|
--
|
|
2.42.0
|
|
|