Skip to content

Commit 8ed37f6

Browse files
committed
Merge #19077: wallet: Add sqlite as an alternative wallet database and use it for new descriptor wallets
c4a29d0 Update wallet_multiwallet.py for descriptor and sqlite wallets (Russell Yanofsky) 310b0fd Run dumpwallet for legacy wallets only in wallet_backup.py (Andrew Chow) 6c6639a Include sqlite3 in documentation (Andrew Chow) f023b7c wallet: Enforce sqlite serialized threading mode (Andrew Chow) 6173269 Set and check the sqlite user version (Andrew Chow) 9d3d2d2 Use network magic as sqlite wallet application ID (Andrew Chow) 9af5de3 Use SQLite for descriptor wallets (Andrew Chow) 9b78f3c walletutil: Wallets can also be sqlite (Andrew Chow) ac38a87 Determine wallet file type based on file magic (Andrew Chow) 6045f77 Implement SQLiteDatabase::MakeBatch (Andrew Chow) 727e6b2 Implement SQLiteDatabase::Verify (Andrew Chow) b4df8fd Implement SQLiteDatabase::Rewrite (Andrew Chow) 010e365 Implement SQLiteDatabase::TxnBegin, TxnCommit, and TxnAbort (Andrew Chow) ac5c161 Implement SQLiteDatabase::Backup (Andrew Chow) f6f9cd6 Implement SQLiteBatch::StartCursor, ReadAtCursor, and CloseCursor (Andrew Chow) bf90e03 Implement SQLiteBatch::ReadKey, WriteKey, EraseKey, and HasKey (Andrew Chow) 7aa4562 Add SetupSQLStatements (Andrew Chow) 6636a26 Implement SQLiteBatch::Close (Andrew Chow) 9382535 Implement SQLiteDatabase::Close (Andrew Chow) a0de833 Implement SQLiteDatabase::Open (Andrew Chow) 3bfa0fe Initialize and Shutdown sqlite3 globals (Andrew Chow) 5a488b3 Constructors, destructors, and relevant private fields for SQLiteDatabase/Batch (Andrew Chow) ca8b7e0 Implement SQLiteDatabaseVersion (Andrew Chow) 7577b6e Add SQLiteDatabase and SQLiteBatch dummy classes (Andrew Chow) e87df82 Add sqlite to travis and depends (Andrew Chow) 54729f3 Add libsqlite3 (Andrew Chow) Pull request description: This PR adds a new class `SQLiteDatabase` which is a subclass of `WalletDatabase`. This provides access to a SQLite database that is used to store the wallet records. To keep compatibility with BDB and to complexity of the change down, we don't make use of many SQLite's features. We use it strictly as a key-value store. We create a table `main` which has two columns, `key` and `value` both with the type `blob`. For new descriptor wallets, we will create a `SQLiteDatabase` instead of a `BerkeleyDatabase`. There is no requirement that all SQLite wallets are descriptor wallets, nor is there a requirement that all descriptor wallets be SQLite wallets. This allows for existing descriptor wallets to work as well as keeping open the option to migrate existing wallets to SQLite. We keep the name `wallet.dat` for SQLite wallets. We are able to determine which database type to use by searching for specific magic bytes in the `wallet.dat` file. SQLite begins it's files with a null terminated string `SQLite format 3`. BDB has `0x00053162` at byte 12 (note that the byte order of this integer depends on the system endianness). So when we see that there is a `wallet.dat` file that we want to open, we check for the magic bytes to determine which database system to use. I decided to keep the `wallet.dat` naming to keep things like backup script to continue to function as they won't need to be modified to look for a different file name. It also simplifies a couple of things in the implementation and the tests as `wallet.dat` is something that is specifically being looked for. If we don't want this behavior, then I do have another branch which creates `wallet.sqlite` files instead, but I find that this direction is easier. ACKs for top commit: Sjors: re-utACK c4a29d0 promag: Tested ACK c4a29d0. fjahr: reACK c4a29d0 S3RK: Re-review ACK c4a29d0 meshcollider: re-utACK c4a29d0 hebasto: re-ACK c4a29d0, only rebased since my [previous](bitcoin/bitcoin#19077 (review)) review, verified with `git range-diff master d18892dcc c4a29d0`. ryanofsky: Code review ACK c4a29d0. I am honestly confused about reasons for locking into `wallet.dat` again when it's so easy now to use a clean format. I assume I'm just very dense, or there's some unstated reason, because the only thing that's been brought up are unrealistic compatibility scenarios (all require actively creating a wallet with non-default descriptor+sqlite option, then trying to using the descriptor+sqlite wallets with old software or scripts and ignoring the results) that we didn't pay attention to with previous PRs like #11687, which did not require any active interfaction. jonatack: ACK c4a29d0, debug builds and test runs after rebase to latest master @ c2c4dba, some manual testing creating, using, unloading and reloading a few different new sqlite descriptor wallets over several node restarts/shutdowns. Tree-SHA512: 19145732e5001484947352d3175a660b5102bc6e833f227a55bd41b9b2f4d92737bbed7cead64b75b509decf9e1408cd81c185ab1fb4b90561aee427c4f9751c
2 parents f2e6d14 + c4a29d0 commit 8ed37f6

34 files changed

+934
-80
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ jobs:
132132
- berkeley-db4
133133
- miniupnpc
134134
- qrencode
135+
- sqlite
135136
- ccache
136137
- zeromq
137138
env: >-

build_msvc/vcpkg.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99
"boost-signals2",
1010
"boost-test",
1111
"boost-thread",
12+
"sqlite3",
1213
"double-conversion",
1314
{
1415
"name": "libevent",
1516
"features": ["thread"]
1617
},
1718
"zeromq"
1819
]
19-
}
20+
}

ci/test/00_setup_env_native_asan.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
export LC_ALL=C.UTF-8
88

99
export CONTAINER_NAME=ci_native_asan
10-
export PACKAGES="clang llvm python3-zmq qtbase5-dev qttools5-dev-tools libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libqrencode-dev"
10+
export PACKAGES="clang llvm python3-zmq qtbase5-dev qttools5-dev-tools libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libqrencode-dev libsqlite3-dev"
1111
export DOCKER_NAME_TAG=ubuntu:20.04
1212
export NO_DEPENDS=1
1313
export GOAL="install"

ci/test/00_setup_env_native_msan.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export BDB_PREFIX="${BASE_ROOT_DIR}/db4"
1515

1616
export CONTAINER_NAME="ci_native_msan"
1717
export PACKAGES="clang-9 llvm-9 cmake"
18-
export DEP_OPTS="NO_WALLET=1 NO_QT=1 CC='clang' CXX='clang++' CFLAGS='${MSAN_FLAGS}' CXXFLAGS='${MSAN_AND_LIBCXX_FLAGS}' boost_cxxflags='-std=c++11 -fvisibility=hidden -fPIC ${MSAN_AND_LIBCXX_FLAGS}' zeromq_cxxflags='-std=c++11 ${MSAN_AND_LIBCXX_FLAGS}'"
18+
export DEP_OPTS="NO_BDB=1 NO_QT=1 CC='clang' CXX='clang++' CFLAGS='${MSAN_FLAGS}' CXXFLAGS='${MSAN_AND_LIBCXX_FLAGS}' boost_cxxflags='-std=c++11 -fvisibility=hidden -fPIC ${MSAN_AND_LIBCXX_FLAGS}' zeromq_cxxflags='-std=c++11 ${MSAN_AND_LIBCXX_FLAGS}'"
1919
export GOAL="install"
2020
export BITCOIN_CONFIG="--enable-wallet --with-sanitizers=memory --with-asm=no --prefix=${BASE_ROOT_DIR}/depends/x86_64-pc-linux-gnu/ CC=clang CXX=clang++ CFLAGS='${MSAN_FLAGS}' CXXFLAGS='${MSAN_AND_LIBCXX_FLAGS}' BDB_LIBS='-L${BDB_PREFIX}/lib -ldb_cxx-4.8' BDB_CFLAGS='-I${BDB_PREFIX}/include'"
2121
export USE_MEMORY_SANITIZER="true"

ci/test/00_setup_env_native_valgrind.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
export LC_ALL=C.UTF-8
88

99
export CONTAINER_NAME=ci_native_valgrind
10-
export PACKAGES="valgrind clang llvm python3-zmq libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev"
10+
export PACKAGES="valgrind clang llvm python3-zmq libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libsqlite3-dev"
1111
export USE_VALGRIND=1
1212
export NO_DEPENDS=1
1313
export TEST_RUNNER_EXTRA="--exclude rpc_bind" # Excluded for now, see https://github.com/bitcoin/bitcoin/issues/17765#issuecomment-602068547

configure.ac

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,6 +1222,9 @@ if test x$enable_wallet != xno; then
12221222
if test x$suppress_external_warnings != xno ; then
12231223
BDB_CPPFLAGS=SUPPRESS_WARNINGS($BDB_CPPFLAGS)
12241224
fi
1225+
1226+
dnl Check for sqlite3
1227+
PKG_CHECK_MODULES([SQLITE], [sqlite3 >= 3.7.17], , [AC_MSG_ERROR([sqlite3 not found.])])
12251228
fi
12261229

12271230
dnl Check for libminiupnpc (optional)
@@ -1643,6 +1646,7 @@ AC_SUBST(LIBTOOL_APP_LDFLAGS)
16431646
AC_SUBST(USE_UPNP)
16441647
AC_SUBST(USE_QRCODE)
16451648
AC_SUBST(BOOST_LIBS)
1649+
AC_SUBST(SQLITE_LIBS)
16461650
AC_SUBST(TESTDEFS)
16471651
AC_SUBST(MINIUPNPC_CPPFLAGS)
16481652
AC_SUBST(MINIUPNPC_LIBS)

contrib/gitian-descriptors/gitian-linux.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ script: |
7878
echo "REAL=\`which -a ${i}-${prog}-8 | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog}
7979
echo "export LD_PRELOAD='/usr/\$LIB/faketime/libfaketime.so.1'" >> ${WRAP_DIR}/${i}-${prog}
8080
echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog}
81-
echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog}
81+
echo "\$REAL \"\$@\"" >> $WRAP_DIR/${i}-${prog}
8282
chmod +x ${WRAP_DIR}/${i}-${prog}
8383
fi
8484
done

contrib/gitian-descriptors/gitian-win.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ script: |
8181
echo "REAL=\`which -a ${i}-${prog}-posix | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog}
8282
echo "export LD_PRELOAD='/usr/\$LIB/faketime/libfaketime.so.1'" >> ${WRAP_DIR}/${i}-${prog}
8383
echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog}
84-
echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog}
84+
echo "\$REAL \"\$@\"" >> $WRAP_DIR/${i}-${prog}
8585
chmod +x ${WRAP_DIR}/${i}-${prog}
8686
done
8787
done

depends/Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,10 @@ qrencode_packages_$(NO_QR) = $(qrencode_packages)
134134

135135
qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages) $(qt_$(host_arch)_$(host_os)_packages) $(qrencode_packages_)
136136

137-
wallet_packages_$(NO_WALLET) = $(wallet_packages)
137+
bdb_packages_$(NO_BDB) = $(bdb_packages)
138+
sqlite_packages_$(NO_SQLITE) = $(sqlite_packages)
139+
wallet_packages_$(NO_WALLET) = $(bdb_packages_) $(sqlite_packages_)
140+
138141
upnp_packages_$(NO_UPNP) = $(upnp_packages)
139142
zmq_packages_$(NO_ZMQ) = $(zmq_packages)
140143
multiprocess_packages_$(MULTIPROCESS) = $(multiprocess_packages)

depends/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ The following can be set when running make: `make FOO=bar`
9999
<dd>Don't download/build/cache packages needed for enabling zeromq</dd>
100100
<dt>NO_WALLET</dt>
101101
<dd>Don't download/build/cache libs needed to enable the wallet</dd>
102+
<dt>NO_BDB</dt>
103+
<dd>Don't download/build/cache BerkeleyDB</dd>
104+
<dt>NO_SQLITE</dt>
105+
<dd>Don't download/build/cache SQLite</dd>
102106
<dt>NO_UPNP</dt>
103107
<dd>Don't download/build/cache packages needed for enabling upnp</dd>
104108
<dt>MULTIPROCESS</dt>

0 commit comments

Comments
 (0)