Compare commits

...

13 Commits

Author SHA1 Message Date
luigi1111 66184f3085 Merge pull request #8597
853171b build: prepare v0.18.1.2 (selsta)
2022-09-27 17:31:52 -05:00
selsta 853171bbf0 build: prepare v0.18.1.2 2022-09-26 22:41:36 +02:00
luigi1111 1f27fdf6a5 Merge pull request #8588
802c4bb Move update_checkpoints() to a later stage (SChernykh)
2022-09-26 15:00:59 -05:00
luigi1111 0bef4265ac Merge pull request #8585
5ffa31c wallet2: fail to establish daemon cxn == 'Disconnected' cxn status (j-berman)
2022-09-26 14:57:58 -05:00
luigi1111 a7b0c93c7d Merge pull request #8582
1cd21bf add an option to force-update multisig key exchange under some circumstances (koe)
2022-09-26 14:55:28 -05:00
luigi1111 9885b8b0f2 Merge pull request #8579
7d358cd repo: remove ldns leftovers (selsta)
09402d0 depends: remove unused Qt package (selsta)
2022-09-26 14:54:58 -05:00
luigi1111 fdb31856dd Merge pull request #8577
6adf03c Second thread pool for IO (SChernykh)
2022-09-26 14:51:54 -05:00
SChernykh 802c4bb0e4 Move update_checkpoints() to a later stage
update_checkpoints() makes a few DNS requests and can take up to 20-30 seconds to complete (3-6 seconds on average). It is currently called from core::handle_incoming_block() which holds m_incoming_tx_lock, so it blocks all incoming transactions and blocks processing while update_checkpoints() is running. This PR moves it to until after a new block has been processed and relayed, to avoid full monerod locking.
2022-09-22 13:06:39 +02:00
j-berman 5ffa31c48e wallet2: fail to establish daemon cxn == "Disconnected" cxn status 2022-09-21 20:12:16 -06:00
koe 1cd21bfba5 add an option to force-update multisig key exchange under some circumstances 2022-09-21 12:51:19 -05:00
selsta 7d358cdb1f repo: remove ldns leftovers 2022-09-20 20:22:31 +02:00
selsta 09402d0edb depends: remove unused Qt package 2022-09-20 20:21:48 +02:00
SChernykh 6adf03cdc5 Second thread pool for IO 2022-09-20 10:22:12 +02:00
45 changed files with 296 additions and 499 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ jobs:
key: ccache-${{ runner.os }}-build-${{ github.sha }}
restore-keys: ccache-${{ runner.os }}-build-
- name: install dependencies
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install boost hidapi openssl zmq libpgm miniupnpc ldns expat libunwind-headers protobuf ccache
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install boost hidapi openssl zmq libpgm miniupnpc expat libunwind-headers protobuf ccache
- name: build
run: |
${{env.CCACHE_SETTINGS}}
+2 -2
View File
@@ -36,13 +36,13 @@ jobs:
packages: "python3 gperf g++-aarch64-linux-gnu"
- name: "i686 Win"
host: "i686-w64-mingw32"
packages: "python3 g++-mingw-w64-i686 qttools5-dev-tools"
packages: "python3 g++-mingw-w64-i686"
- name: "i686 Linux"
host: "i686-pc-linux-gnu"
packages: "gperf cmake g++-multilib python3-zmq"
- name: "Win64"
host: "x86_64-w64-mingw32"
packages: "cmake python3 g++-mingw-w64-x86-64 qttools5-dev-tools"
packages: "cmake python3 g++-mingw-w64-x86-64"
- name: "x86_64 Linux"
host: "x86_64-unknown-linux-gnu"
packages: "gperf cmake python3-zmq libdbus-1-dev libharfbuzz-dev"
+9 -10
View File
@@ -138,8 +138,8 @@ Dates are provided in the format YYYY-MM-DD.
| 1978433 | 2019-11-30 | v12 | v0.15.0.0 | v0.16.0.0 | New PoW based on RandomX, only allow >= 2 outputs, change to the block median used to calculate penalty, v1 coinbases are forbidden, rct sigs in coinbase forbidden, 10 block lock time for incoming outputs
| 2210000 | 2020-10-17 | v13 | v0.17.0.0 | v0.17.3.2 | New CLSAG transaction format
| 2210720 | 2020-10-18 | v14 | v0.17.1.1 | v0.17.3.2 | forbid old MLSAG transaction format
| 2688888 | 2022-08-13 | v15 | v0.18.0.0 | v0.18.1.1 | ringsize = 16, bulletproofs+, view tags, adjusted dynamic block weight algorithm
| 2689608 | 2022-08-14 | v16 | v0.18.0.0 | v0.18.1.1 | forbid old v14 transaction format
| 2688888 | 2022-08-13 | v15 | v0.18.0.0 | v0.18.1.2 | ringsize = 16, bulletproofs+, view tags, adjusted dynamic block weight algorithm
| 2689608 | 2022-08-14 | v16 | v0.18.0.0 | v0.18.1.2 | forbid old v14 transaction format
| XXXXXXX | XXX-XX-XX | XXX | vX.XX.X.X | vX.XX.X.X | XXX |
X's indicate that these details have not been determined as of commit date.
@@ -178,7 +178,6 @@ library archives (`.a`).
| libunwind | any | NO | `libunwind8-dev` | `libunwind` | `libunwind-devel` | `libunwind-devel` | YES | Stack traces |
| liblzma | any | NO | `liblzma-dev` | `xz` | `liblzma-devel` | `xz-devel` | YES | For libunwind |
| libreadline | 6.3.0 | NO | `libreadline6-dev` | `readline` | `readline-devel` | `readline-devel` | YES | Input editing |
| ldns | 1.6.17 | NO | `libldns-dev` | `ldns` | `libldns-devel` | `ldns-devel` | YES | SSL toolkit |
| expat | 1.1 | NO | `libexpat1-dev` | `expat` | `expat-devel` | `expat-devel` | YES | XML parsing |
| GTest | 1.5 | YES | `libgtest-dev`[1] | `gtest` | `gtest-devel` | `gtest-devel` | YES | Test suite |
| ccache | any | NO | `ccache` | `ccache` | `ccache` | `ccache` | YES | Compil. cache |
@@ -205,23 +204,23 @@ then:
Install all dependencies at once on Debian/Ubuntu:
```
sudo apt update && sudo apt install build-essential cmake pkg-config libssl-dev libzmq3-dev libunbound-dev libsodium-dev libunwind8-dev liblzma-dev libreadline6-dev libldns-dev libexpat1-dev libpgm-dev qttools5-dev-tools libhidapi-dev libusb-1.0-0-dev libprotobuf-dev protobuf-compiler libudev-dev libboost-chrono-dev libboost-date-time-dev libboost-filesystem-dev libboost-locale-dev libboost-program-options-dev libboost-regex-dev libboost-serialization-dev libboost-system-dev libboost-thread-dev python3 ccache doxygen graphviz
sudo apt update && sudo apt install build-essential cmake pkg-config libssl-dev libzmq3-dev libunbound-dev libsodium-dev libunwind8-dev liblzma-dev libreadline6-dev libexpat1-dev libpgm-dev qttools5-dev-tools libhidapi-dev libusb-1.0-0-dev libprotobuf-dev protobuf-compiler libudev-dev libboost-chrono-dev libboost-date-time-dev libboost-filesystem-dev libboost-locale-dev libboost-program-options-dev libboost-regex-dev libboost-serialization-dev libboost-system-dev libboost-thread-dev python3 ccache doxygen graphviz
```
Install all dependencies at once on Arch:
```
sudo pacman -Syu --needed base-devel cmake boost openssl zeromq libpgm unbound libsodium libunwind xz readline ldns expat gtest python3 ccache doxygen graphviz qt5-tools hidapi libusb protobuf systemd
sudo pacman -Syu --needed base-devel cmake boost openssl zeromq libpgm unbound libsodium libunwind xz readline expat gtest python3 ccache doxygen graphviz qt5-tools hidapi libusb protobuf systemd
```
Install all dependencies at once on Fedora:
```
sudo dnf install gcc gcc-c++ cmake pkgconf boost-devel openssl-devel zeromq-devel openpgm-devel unbound-devel libsodium-devel libunwind-devel xz-devel readline-devel ldns-devel expat-devel gtest-devel ccache doxygen graphviz qt5-linguist hidapi-devel libusbx-devel protobuf-devel protobuf-compiler systemd-devel
sudo dnf install gcc gcc-c++ cmake pkgconf boost-devel openssl-devel zeromq-devel openpgm-devel unbound-devel libsodium-devel libunwind-devel xz-devel readline-devel expat-devel gtest-devel ccache doxygen graphviz qt5-linguist hidapi-devel libusbx-devel protobuf-devel protobuf-compiler systemd-devel
```
Install all dependencies at once on openSUSE:
```
sudo zypper ref && sudo zypper in cppzmq-devel ldns-devel libboost_chrono-devel libboost_date_time-devel libboost_filesystem-devel libboost_locale-devel libboost_program_options-devel libboost_regex-devel libboost_serialization-devel libboost_system-devel libboost_thread-devel libexpat-devel libminiupnpc-devel libsodium-devel libunwind-devel unbound-devel cmake doxygen ccache fdupes gcc-c++ libevent-devel libopenssl-devel pkgconf-pkg-config readline-devel xz-devel libqt5-qttools-devel patterns-devel-C-C++-devel_C_C++
sudo zypper ref && sudo zypper in cppzmq-devel libboost_chrono-devel libboost_date_time-devel libboost_filesystem-devel libboost_locale-devel libboost_program_options-devel libboost_regex-devel libboost_serialization-devel libboost_system-devel libboost_thread-devel libexpat-devel libminiupnpc-devel libsodium-devel libunwind-devel unbound-devel cmake doxygen ccache fdupes gcc-c++ libevent-devel libopenssl-devel pkgconf-pkg-config readline-devel xz-devel libqt5-qttools-devel patterns-devel-C-C++-devel_C_C++
```
Install all dependencies at once on macOS with the provided Brewfile:
@@ -345,7 +344,7 @@ Tested on a Raspberry Pi Zero with a clean install of minimal Raspbian Stretch (
```bash
git clone https://github.com/monero-project/monero.git
cd monero
git checkout v0.18.1.1
git checkout v0.18.1.2
```
* Build:
@@ -464,10 +463,10 @@ application.
cd monero
```
* If you would like a specific [version/tag](https://github.com/monero-project/monero/tags), do a git checkout for that version. eg. 'v0.18.1.1'. If you don't care about the version and just want binaries from master, skip this step:
* If you would like a specific [version/tag](https://github.com/monero-project/monero/tags), do a git checkout for that version. eg. 'v0.18.1.2'. If you don't care about the version and just want binaries from master, skip this step:
```bash
git checkout v0.18.1.1
git checkout v0.18.1.2
```
* If you are on a 64-bit system, run:
-1
View File
@@ -25,7 +25,6 @@ brew "unbound"
brew "libsodium"
brew "miniupnpc"
brew "readline"
brew "ldns"
brew "expat"
brew "ccache"
brew "doxygen"
+1 -2
View File
@@ -110,8 +110,7 @@ $(host_arch)_$(host_os)_id_string+=$(shell $(host_CXX) --version 2>/dev/null)
$(host_arch)_$(host_os)_id_string+=$(shell $(host_RANLIB) --version 2>/dev/null)
$(host_arch)_$(host_os)_id_string+=$(shell $(host_STRIP) --version 2>/dev/null)
qt_packages_$(NO_QT) = $(qt_packages)
packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(qt_packages_)
packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages)
native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages)
all_packages = $(packages) $(native_packages)
-15
View File
@@ -7,27 +7,12 @@ ac_tool_prefix=${host_alias}-
if test -z $with_boost; then
with_boost=$depends_prefix
fi
if test -z $with_qt_plugindir; then
with_qt_plugindir=$depends_prefix/plugins
fi
if test -z $with_qt_translationdir; then
with_qt_translationdir=$depends_prefix/translations
fi
if test x@host_os@ = xdarwin; then
BREW=no
PORT=no
fi
if test x@host_os@ = xmingw32; then
if test -z $with_qt_incdir; then
with_qt_incdir=$depends_prefix/include
fi
if test -z $with_qt_libdir; then
with_qt_libdir=$depends_prefix/lib
fi
fi
PATH=$depends_prefix/native/bin:$PATH
PKG_CONFIG="`which pkg-config` --static"
-34
View File
@@ -1,34 +0,0 @@
package=ldns
$(package)_version=1.7.1
$(package)_download_path=https://www.nlnetlabs.nl/downloads/$(package)/
$(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_sha256_hash=8ac84c16bdca60e710eea75782356f3ac3b55680d40e1530d7cea474ac208229
$(package)_dependencies=openssl
define $(package)_set_vars
$(package)_config_opts=--disable-shared --enable-static --with-drill
$(package)_config_opts+=--with-ssl=$(host_prefix)
$(package)_config_opts_release=--disable-debug-mode
$(package)_config_opts_linux=--with-pic
endef
define $(package)_preprocess_cmds
cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub .
endef
define $(package)_config_cmds
$($(package)_autoconf)
endef
define $(package)_build_cmds
$(MAKE)
endef
define $(package)_stage_cmds
$(MAKE) DESTDIR=$($(package)_staging_dir) install-h install-lib
endef
define $(package)_postprocess_cmds
rm lib/*.la
endef
+1 -2
View File
@@ -1,4 +1,4 @@
packages:=boost openssl zeromq libiconv expat ldns unbound
packages:=boost openssl zeromq libiconv expat unbound
# ccache is useless in gitian builds
ifneq ($(GITIAN),1)
@@ -20,7 +20,6 @@ freebsd_packages = ncurses readline sodium
linux_packages = eudev ncurses readline sodium $(hardware_packages)
linux_native_packages = $(hardware_native_packages)
qt_packages = qt
ifeq ($(build_tests),ON)
packages += gtest
-175
View File
@@ -1,175 +0,0 @@
PACKAGE=qt
$(package)_version=5.15.1
$(package)_download_path=https://download.qt.io/official_releases/qt/5.15/$($(package)_version)/submodules
$(package)_suffix=everywhere-src-$($(package)_version).tar.xz
$(package)_file_name=qtbase-$($(package)_suffix)
$(package)_sha256_hash=33960404d579675b7210de103ed06a72613bfc4305443e278e2d32a3eb1f3d8c
$(package)_build_subdir=qtbase
$(package)_qt_libs=corelib
$(package)_patches=fix_qt_pkgconfig.patch fix_no_printer.patch fix_rcc_determinism.patch no-xlib.patch
$(package)_qttranslations_file_name=qttranslations-$($(package)_suffix)
$(package)_qttranslations_sha256_hash=46e0c0e3a511fbcc803a4146204062e47f6ed43b34d98a3c27372a03b8746bd8
$(package)_qttools_file_name=qttools-$($(package)_suffix)
$(package)_qttools_sha256_hash=c98ee5f0f980bf68cbf0c94d62434816a92441733de50bd9adbe9b9055f03498
$(package)_extra_sources = $($(package)_qttranslations_file_name)
$(package)_extra_sources += $($(package)_qttools_file_name)
define $(package)_set_vars
$(package)_config_opts_release = -release
$(package)_config_opts_debug = -debug
$(package)_config_opts += -bindir $(build_prefix)/bin
$(package)_config_opts += -c++std c++11
$(package)_config_opts += -confirm-license
$(package)_config_opts += -dbus-runtime
$(package)_config_opts += -hostprefix $(build_prefix)
$(package)_config_opts += -no-compile-examples
$(package)_config_opts += -no-cups
$(package)_config_opts += -no-egl
$(package)_config_opts += -no-eglfs
$(package)_config_opts += -no-evdev
$(package)_config_opts += -no-gui
$(package)_config_opts += -no-freetype
$(package)_config_opts += -no-gif
$(package)_config_opts += -no-glib
$(package)_config_opts += -no-icu
$(package)_config_opts += -no-ico
$(package)_config_opts += -no-iconv
$(package)_config_opts += -no-kms
$(package)_config_opts += -no-linuxfb
$(package)_config_opts += -no-libjpeg
$(package)_config_opts += -no-libudev
$(package)_config_opts += -no-mtdev
$(package)_config_opts += -no-openvg
$(package)_config_opts += -no-reduce-relocations
$(package)_config_opts += -no-sql-db2
$(package)_config_opts += -no-sql-ibase
$(package)_config_opts += -no-sql-oci
$(package)_config_opts += -no-sql-tds
$(package)_config_opts += -no-sql-mysql
$(package)_config_opts += -no-sql-odbc
$(package)_config_opts += -no-sql-psql
$(package)_config_opts += -no-sql-sqlite
$(package)_config_opts += -no-sql-sqlite2
$(package)_config_opts += -no-use-gold-linker
$(package)_config_opts += -nomake examples
$(package)_config_opts += -nomake tests
$(package)_config_opts += -opensource
$(package)_config_opts += -no-openssl
$(package)_config_opts += -optimized-qmake
$(package)_config_opts += -pch
$(package)_config_opts += -pkg-config
$(package)_config_opts += -prefix $(host_prefix)
$(package)_config_opts += -no-libpng
$(package)_config_opts += -qt-pcre
$(package)_config_opts += -qt-harfbuzz
$(package)_config_opts += -no-zlib
$(package)_config_opts += -static
$(package)_config_opts += -silent
$(package)_config_opts += -v
$(package)_config_opts += -no-feature-bearermanagement
$(package)_config_opts += -no-feature-colordialog
$(package)_config_opts += -no-feature-dial
$(package)_config_opts += -no-feature-filesystemwatcher
$(package)_config_opts += -no-feature-fontcombobox
$(package)_config_opts += -no-feature-ftp
$(package)_config_opts += -no-feature-image_heuristic_mask
$(package)_config_opts += -no-feature-keysequenceedit
$(package)_config_opts += -no-feature-lcdnumber
$(package)_config_opts += -no-feature-pdf
$(package)_config_opts += -no-feature-printdialog
$(package)_config_opts += -no-feature-printer
$(package)_config_opts += -no-feature-printpreviewdialog
$(package)_config_opts += -no-feature-printpreviewwidget
$(package)_config_opts += -no-feature-sessionmanager
$(package)_config_opts += -no-feature-sql
$(package)_config_opts += -no-feature-statemachine
$(package)_config_opts += -no-feature-syntaxhighlighter
$(package)_config_opts += -no-feature-textbrowser
$(package)_config_opts += -no-feature-textodfwriter
$(package)_config_opts += -no-feature-topleveldomain
$(package)_config_opts += -no-feature-udpsocket
$(package)_config_opts += -no-feature-undocommand
$(package)_config_opts += -no-feature-undogroup
$(package)_config_opts += -no-feature-undostack
$(package)_config_opts += -no-feature-undoview
$(package)_config_opts += -no-feature-vnc
$(package)_config_opts += -no-feature-wizard
$(package)_config_opts_linux = -no-fontconfig
$(package)_config_opts_linux += -no-opengl
$(package)_config_opts_linux += -no-xcb
$(package)_config_opts_linux += -no-feature-xlib
endef
define $(package)_fetch_cmds
$(call fetch_file,$(package),$($(package)_download_path),$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \
$(call fetch_file,$(package),$($(package)_download_path),$($(package)_qttranslations_file_name),$($(package)_qttranslations_file_name),$($(package)_qttranslations_sha256_hash)) && \
$(call fetch_file,$(package),$($(package)_download_path),$($(package)_qttools_file_name),$($(package)_qttools_file_name),$($(package)_qttools_sha256_hash))
endef
define $(package)_extract_cmds
mkdir -p $($(package)_extract_dir) && \
echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \
echo "$($(package)_qttranslations_sha256_hash) $($(package)_source_dir)/$($(package)_qttranslations_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \
echo "$($(package)_qttools_sha256_hash) $($(package)_source_dir)/$($(package)_qttools_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \
$(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \
mkdir qtbase && \
tar --strip-components=1 -xf $($(package)_source) -C qtbase && \
mkdir qttranslations && \
tar --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttranslations_file_name) -C qttranslations && \
mkdir qttools && \
tar --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttools_file_name) -C qttools
endef
define $(package)_preprocess_cmds
sed -i.old "s|FT_Get_Font_Format|FT_Get_X11_Font_Format|" qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp && \
sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \
sed -i.old "/updateqm.depends =/d" qttranslations/translations/translations.pro && \
sed -i.old "s/src_plugins.depends = src_sql src_network/src_plugins.depends = src_network/" qtbase/src/src.pro && \
cp -r qtbase/mkspecs/linux-arm-gnueabi-g++ qtbase/mkspecs/bitcoin-linux-g++ && \
sed -i.old "s/arm-linux-gnueabi-/$(host)-/g" qtbase/mkspecs/bitcoin-linux-g++/qmake.conf && \
patch -p1 -i $($(package)_patch_dir)/fix_qt_pkgconfig.patch && \
patch -p1 -i $($(package)_patch_dir)/fix_no_printer.patch && \
echo "!host_build: QMAKE_CFLAGS += $($(package)_cflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \
echo "!host_build: QMAKE_CXXFLAGS += $($(package)_cxxflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \
echo "!host_build: QMAKE_LFLAGS += $($(package)_ldflags)" >> qtbase/mkspecs/common/gcc-base.conf && \
patch -p1 -i $($(package)_patch_dir)/no-xlib.patch && \
echo "QMAKE_LINK_OBJECT_MAX = 10" >> qtbase/mkspecs/win32-g++/qmake.conf && \
echo "QMAKE_LINK_OBJECT_SCRIPT = object_script" >> qtbase/mkspecs/win32-g++/qmake.conf && \
sed -i.old "s|QMAKE_CFLAGS += |!host_build: QMAKE_CFLAGS = $($(package)_cflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \
sed -i.old "s|QMAKE_CXXFLAGS += |!host_build: QMAKE_CXXFLAGS = $($(package)_cxxflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \
sed -i.old "0,/^QMAKE_LFLAGS_/s|^QMAKE_LFLAGS_|!host_build: QMAKE_LFLAGS = $($(package)_ldflags)\n&|" qtbase/mkspecs/win32-g++/qmake.conf && \
sed -i.old "s/LIBRARY_PATH/(CROSS_)?\0/g" qtbase/mkspecs/features/toolchain.prf
endef
define $(package)_config_cmds
export PKG_CONFIG_SYSROOT_DIR=/ && \
export PKG_CONFIG_LIBDIR=$(host_prefix)/lib/pkgconfig && \
export PKG_CONFIG_PATH=$(host_prefix)/share/pkgconfig && \
./configure $($(package)_config_opts) && \
echo "CONFIG += force_bootstrap" >> mkspecs/qconfig.pri && \
$(MAKE) sub-src-clean && \
cd ../qttranslations && ../qtbase/bin/qmake qttranslations.pro -o Makefile && \
cd translations && ../../qtbase/bin/qmake translations.pro -o Makefile && cd ../.. &&\
cd qttools/src/linguist/lrelease/ && ../../../../qtbase/bin/qmake lrelease.pro -o Makefile
endef
define $(package)_build_cmds
$(MAKE) -C src $(addprefix sub-,$($(package)_qt_libs)) && \
$(MAKE) -C ../qttools/src/linguist/lrelease && \
$(MAKE) -C ../qttranslations
endef
define $(package)_stage_cmds
$(MAKE) -C src INSTALL_ROOT=$($(package)_staging_dir) $(addsuffix -install_subtargets,$(addprefix sub-,$($(package)_qt_libs))) && cd .. &&\
$(MAKE) -C qttools/src/linguist/lrelease INSTALL_ROOT=$($(package)_staging_dir) install_target && \
$(MAKE) -C qttranslations INSTALL_ROOT=$($(package)_staging_dir) install_subtargets
endef
define $(package)_postprocess_cmds
rm -rf native/mkspecs/ native/lib/ lib/cmake/ && \
rm -f lib/lib*.la lib/*.prl plugins/*/*.prl
endef
+1 -1
View File
@@ -3,7 +3,7 @@ $(package)_version=1.15.0
$(package)_download_path=https://www.nlnetlabs.nl/downloads/$(package)/
$(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_sha256_hash=a480dc6c8937447b98d161fe911ffc76cfaffa2da18788781314e81339f1126f
$(package)_dependencies=openssl expat ldns
$(package)_dependencies=openssl expat
$(package)_patches=disable-glibc-reallocarray.patch
@@ -1,19 +0,0 @@
--- x/qtbase/src/plugins/platforms/cocoa/qprintengine_mac_p.h
+++ y/qtbase/src/plugins/platforms/cocoa/qprintengine_mac_p.h
@@ -52,6 +52,7 @@
//
#include <QtCore/qglobal.h>
+#include <qpa/qplatformprintdevice.h>
#ifndef QT_NO_PRINTER
--- x/qtbase/src/plugins/plugins.pro
+++ y/qtbase/src/plugins/plugins.pro
@@ -9,6 +9,3 @@ qtHaveModule(gui) {
!android:qtConfig(library): SUBDIRS *= generic
}
qtHaveModule(widgets): SUBDIRS += styles
-
-!winrt:qtHaveModule(printsupport): \
- SUBDIRS += printsupport
@@ -1,11 +0,0 @@
--- old/qtbase/mkspecs/features/qt_module.prf
+++ new/qtbase/mkspecs/features/qt_module.prf
@@ -269,7 +269,7 @@ load(qt_installs)
load(qt_targets)
# this builds on top of qt_common
-!internal_module:if(unix|mingw):!if(darwin:debug_and_release:CONFIG(debug, debug|release)) {
+if(unix|mingw):!if(darwin:debug_and_release:CONFIG(debug, debug|release)) {
CONFIG += create_pc
QMAKE_PKGCONFIG_DESTDIR = pkgconfig
host_build: \
@@ -1,15 +0,0 @@
--- old/qtbase/src/tools/rcc/rcc.cpp
+++ new/qtbase/src/tools/rcc/rcc.cpp
@@ -207,7 +207,11 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib)
if (lib.formatVersion() >= 2) {
// last modified time stamp
const QDateTime lastModified = m_fileInfo.lastModified();
- lib.writeNumber8(quint64(lastModified.isValid() ? lastModified.toMSecsSinceEpoch() : 0));
+ quint64 lastmod = quint64(lastModified.isValid() ? lastModified.toMSecsSinceEpoch() : 0);
+ static const quint64 sourceDate = 1000 * qgetenv("QT_RCC_SOURCE_DATE_OVERRIDE").toULongLong();
+ if (sourceDate != 0)
+ lastmod = sourceDate;
+ lib.writeNumber8(lastmod);
if (text || pass1)
lib.writeChar('\n');
}
-69
View File
@@ -1,69 +0,0 @@
From 9563cef873ae82e06f60708d706d054717e801ce Mon Sep 17 00:00:00 2001
From: Carl Dong <contact@carldong.me>
Date: Thu, 18 Jul 2019 17:22:05 -0400
Subject: [PATCH] Wrap xlib related code blocks in #if's
They are not necessary to compile QT.
---
qtbase/src/plugins/platforms/xcb/qxcbcursor.cpp | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/qtbase/src/plugins/platforms/xcb/qxcbcursor.cpp b/qtbase/src/plugins/platforms/xcb/qxcbcursor.cpp
index 7c62c2e2b3..c05c6c0a07 100644
--- a/qtbase/src/plugins/platforms/xcb/qxcbcursor.cpp
+++ b/qtbase/src/plugins/platforms/xcb/qxcbcursor.cpp
@@ -49,7 +49,9 @@
#include <QtGui/QWindow>
#include <QtGui/QBitmap>
#include <QtGui/private/qguiapplication_p.h>
+#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library)
#include <X11/cursorfont.h>
+#endif
#include <xcb/xfixes.h>
#include <xcb/xcb_image.h>
@@ -391,6 +393,7 @@ void QXcbCursor::changeCursor(QCursor *cursor, QWindow *window)
xcb_flush(xcb_connection());
}
+#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library)
static int cursorIdForShape(int cshape)
{
int cursorId = 0;
@@ -444,6 +447,7 @@ static int cursorIdForShape(int cshape)
}
return cursorId;
}
+#endif
xcb_cursor_t QXcbCursor::createNonStandardCursor(int cshape)
{
@@ -556,7 +560,9 @@ static xcb_cursor_t loadCursor(void *dpy, int cshape)
xcb_cursor_t QXcbCursor::createFontCursor(int cshape)
{
xcb_connection_t *conn = xcb_connection();
+#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library)
int cursorId = cursorIdForShape(cshape);
+#endif
xcb_cursor_t cursor = XCB_NONE;
// Try Xcursor first
@@ -586,6 +592,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape)
// Non-standard X11 cursors are created from bitmaps
cursor = createNonStandardCursor(cshape);
+#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library)
// Create a glpyh cursor if everything else failed
if (!cursor && cursorId) {
cursor = xcb_generate_id(conn);
@@ -593,6 +600,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape)
cursorId, cursorId + 1,
0xFFFF, 0xFFFF, 0xFFFF, 0, 0, 0);
}
+#endif
if (cursor && cshape >= 0 && cshape < Qt::LastCursor && connection()->hasXFixes()) {
const char *name = cursorNames[cshape].front();
---
2.22.0
-2
View File
@@ -27,8 +27,6 @@ SET(Terminfo_LIBRARY @prefix@/lib/libtinfo.a)
SET(UNBOUND_INCLUDE_DIR @prefix@/include)
SET(UNBOUND_LIBRARIES @prefix@/lib/libunbound.a)
SET(LRELEASE_PATH @prefix@/native/bin CACHE FILEPATH "path to lrelease" FORCE)
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Android")
SET(LIBUNWIND_INCLUDE_DIR @prefix@/include)
SET(LIBUNWIND_LIBRARIES @prefix@/lib/libunwind.a)
+1 -1
View File
@@ -57,7 +57,7 @@ The dockrun.sh script will do everything to build the binaries. Just specify the
version to build as its only argument, e.g.
```bash
VERSION=v0.18.1.1
VERSION=v0.18.1.2
./dockrun.sh $VERSION
```
+1 -1
View File
@@ -133,7 +133,7 @@ Common setup part:
su - gitianuser
GH_USER=YOUR_GITHUB_USER_NAME
VERSION=v0.18.1.1
VERSION=v0.18.1.2
```
Where `GH_USER` is your GitHub user name and `VERSION` is the version tag you want to build.
Binary file not shown.
+1
View File
@@ -242,6 +242,7 @@ namespace cryptonote
ADD_CHECKPOINT2(2661600, "41c9060e8426012238e8a26da26fcb90797436896cc70886a894c2c560bcccf2", "0x2e0d87526ff161f");
ADD_CHECKPOINT2(2677000, "1b9fee6246eeb176bd17d637bf252e9af54a4218675f01b4449cc0901867f9eb", "0x2f165bc1a5163ba");
ADD_CHECKPOINT2(2706000, "d8eb144c5e1fe6b329ecc900ec95e7792fccff84175fb23a25ed59d7299a511c", "0x310f7d89372f705");
ADD_CHECKPOINT2(2720000, "b19fb41dff15bd1016afbee9f8469f05aab715c9e5d1b974466a11fd58ecbb86", "0x3216b5851ddbb61");
return true;
}
+1 -1
View File
@@ -521,7 +521,7 @@ bool load_txt_records_from_dns(std::vector<std::string> &good_records, const std
// send all requests in parallel
std::deque<bool> avail(dns_urls.size(), false), valid(dns_urls.size(), false);
tools::threadpool& tpool = tools::threadpool::getInstance();
tools::threadpool& tpool = tools::threadpool::getInstanceForIO();
tools::threadpool::waiter waiter(tpool);
for (size_t n = 0; n < dns_urls.size(); ++n)
{
+5 -1
View File
@@ -42,10 +42,14 @@ namespace tools
class threadpool
{
public:
static threadpool& getInstance() {
static threadpool& getInstanceForCompute() {
static threadpool instance;
return instance;
}
static threadpool& getInstanceForIO() {
static threadpool instance(8);
return instance;
}
static threadpool *getNewForUnitTests(unsigned max_threads = 0) {
return new threadpool(max_threads);
}
+3 -3
View File
@@ -3434,7 +3434,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
std::vector < uint64_t > results;
results.resize(tx.vin.size(), 0);
tools::threadpool& tpool = tools::threadpool::getInstance();
tools::threadpool& tpool = tools::threadpool::getInstanceForCompute();
tools::threadpool::waiter waiter(tpool);
int threads = tpool.get_max_concurrency();
@@ -5137,7 +5137,7 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
return true;
bool blocks_exist = false;
tools::threadpool& tpool = tools::threadpool::getInstance();
tools::threadpool& tpool = tools::threadpool::getInstanceForCompute();
unsigned threads = tpool.get_max_concurrency();
blocks.resize(blocks_entry.size());
@@ -5604,7 +5604,7 @@ void Blockchain::cancel()
}
#if defined(PER_BLOCK_CHECKPOINT)
static const char expected_block_hashes_hash[] = "a913c311ed4cbe42c5b36c13215021dd50705b17d03ddc2e637ab7e85b22ac89";
static const char expected_block_hashes_hash[] = "52105e0e45013e4c6705d5b7902268f5989b6eea71f5a04160176297a79f4b32";
void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback& get_checkpoints)
{
if (get_checkpoints == nullptr || !m_fast_sync)
+1 -5
View File
@@ -1013,7 +1013,7 @@ namespace cryptonote
CRITICAL_REGION_LOCAL(m_incoming_tx_lock);
tools::threadpool& tpool = tools::threadpool::getInstance();
tools::threadpool& tpool = tools::threadpool::getInstanceForCompute();
tools::threadpool::waiter waiter(tpool);
epee::span<tx_blob_entry>::const_iterator it = tx_blobs.begin();
for (size_t i = 0; i < tx_blobs.size(); i++, ++it) {
@@ -1656,10 +1656,6 @@ namespace cryptonote
if (((size_t)-1) <= 0xffffffff && block_blob.size() >= 0x3fffffff)
MWARNING("This block's size is " << block_blob.size() << ", closing on the 32 bit limit");
// load json & DNS checkpoints every 10min/hour respectively,
// and verify them with respect to what blocks we already have
CHECK_AND_ASSERT_MES(update_checkpoints(), false, "One or more checkpoints loaded from json or dns conflicted with existing checkpoints.");
block lb;
if (!b)
{
@@ -537,6 +537,10 @@ namespace cryptonote
MLOG_PEER_STATE("requesting chain");
}
// load json & DNS checkpoints every 10min/hour respectively,
// and verify them with respect to what blocks we already have
CHECK_AND_ASSERT_MES(m_core.update_checkpoints(), 1, "One or more checkpoints loaded from json or dns conflicted with existing checkpoints.");
return 1;
}
//------------------------------------------------------------------------------------------------------------------------
@@ -819,6 +823,10 @@ namespace cryptonote
post_notify<NOTIFY_REQUEST_CHAIN>(r, context);
MLOG_PEER_STATE("requesting chain");
}
// load json & DNS checkpoints every 10min/hour respectively,
// and verify them with respect to what blocks we already have
CHECK_AND_ASSERT_MES(m_core.update_checkpoints(), 1, "One or more checkpoints loaded from json or dns conflicted with existing checkpoints.");
}
}
else
+9 -3
View File
@@ -50,7 +50,6 @@
using namespace std;
using namespace epee;
using namespace cryptonote;
using boost::lexical_cast;
namespace po = boost::program_options;
#undef MONERO_DEFAULT_LOG_CATEGORY
@@ -84,6 +83,9 @@ static bool generate_multisig(uint32_t threshold, uint32_t total, const std::str
try
{
if (total == 0)
throw std::runtime_error("Signer group of size 0 is not allowed.");
// create M wallets first
std::vector<boost::shared_ptr<tools::wallet2>> wallets(total);
for (size_t n = 0; n < total; ++n)
@@ -118,13 +120,17 @@ static bool generate_multisig(uint32_t threshold, uint32_t total, const std::str
ss << " " << name << std::endl;
}
//exchange keys unless exchange_multisig_keys returns no extra info
while (!kex_msgs_intermediate[0].empty())
// exchange keys until the wallets are done
bool ready{false};
wallets[0]->multisig(&ready);
while (!ready)
{
for (size_t n = 0; n < total; ++n)
{
kex_msgs_intermediate[n] = wallets[n]->exchange_multisig_keys(pwd_container->password(), kex_msgs_intermediate);
}
wallets[0]->multisig(&ready);
}
std::string address = wallets[0]->get_account().get_public_address_str(wallets[0]->nettype());
+4 -3
View File
@@ -175,19 +175,20 @@ namespace multisig
// only mutate account if update succeeds
multisig_account temp_account{*this};
temp_account.set_multisig_config(threshold, std::move(signers));
temp_account.kex_update_impl(expanded_msgs_rnd1);
temp_account.kex_update_impl(expanded_msgs_rnd1, false);
*this = std::move(temp_account);
}
//----------------------------------------------------------------------------------------------------------------------
// multisig_account: EXTERNAL
//----------------------------------------------------------------------------------------------------------------------
void multisig_account::kex_update(const std::vector<multisig_kex_msg> &expanded_msgs)
void multisig_account::kex_update(const std::vector<multisig_kex_msg> &expanded_msgs,
const bool force_update_use_with_caution /*= false*/)
{
CHECK_AND_ASSERT_THROW_MES(account_is_active(), "multisig account: tried to update kex, but kex isn't initialized yet.");
CHECK_AND_ASSERT_THROW_MES(!multisig_is_ready(), "multisig account: tried to update kex, but kex is already complete.");
multisig_account temp_account{*this};
temp_account.kex_update_impl(expanded_msgs);
temp_account.kex_update_impl(expanded_msgs, force_update_use_with_caution);
*this = std::move(temp_account);
}
//----------------------------------------------------------------------------------------------------------------------
+10 -2
View File
@@ -169,12 +169,20 @@ namespace multisig
* - The main interface for multisig key exchange, this handles all the work of processing input messages,
* creating new messages for new rounds, and finalizing the multisig shared public key when kex is complete.
* param: expanded_msgs - kex messages corresponding to the account's 'in progress' round
* param: force_update_use_with_caution - try to force the account to update with messages from an incomplete signer set.
* - If this is the post-kex verification round, only require one input message.
* - Force updating here should only be done if we can safely assume an honest signer subgroup of size 'threshold'
* will complete the account.
* - If this is an intermediate round, only require messages from 'num signers - 1 - (round - 1)' other signers.
* - If force updating with maliciously-crafted messages, the resulting account will be invalid (either unable
* to complete signatures, or a 'hostage' to the malicious signer [i.e. can't sign without his participation]).
*/
void kex_update(const std::vector<multisig_kex_msg> &expanded_msgs);
void kex_update(const std::vector<multisig_kex_msg> &expanded_msgs,
const bool force_update_use_with_caution = false);
private:
// implementation of kex_update() (non-transactional)
void kex_update_impl(const std::vector<multisig_kex_msg> &expanded_msgs);
void kex_update_impl(const std::vector<multisig_kex_msg> &expanded_msgs, const bool incomplete_signer_set);
/**
* brief: initialize_kex_update - Helper for kex_update_impl()
* - Collect the local signer's shared keys to ignore in incoming messages, build the aggregate ancillary key
+106 -45
View File
@@ -181,7 +181,8 @@ namespace multisig
* Key aggregation via aggregation coefficients prevents key cancellation attacks.
* See: https://www.getmonero.org/resources/research-lab/pubs/MRL-0009.pdf
* param: final_keys - address components (public keys) obtained from other participants (not shared with local)
* param: privkeys_inout - private keys of address components known by local; each key will be multiplied by an aggregation coefficient (return by reference)
* param: privkeys_inout - private keys of address components known by local; each key will be multiplied by an aggregation
* coefficient (return by reference)
* return: final multisig public spend key for the account
*/
//----------------------------------------------------------------------------------------------------------------------
@@ -199,7 +200,8 @@ namespace multisig
for (std::size_t multisig_keys_index{0}; multisig_keys_index < privkeys_inout.size(); ++multisig_keys_index)
{
crypto::public_key pubkey;
CHECK_AND_ASSERT_THROW_MES(crypto::secret_key_to_public_key(privkeys_inout[multisig_keys_index], pubkey), "Failed to derive public key");
CHECK_AND_ASSERT_THROW_MES(crypto::secret_key_to_public_key(privkeys_inout[multisig_keys_index], pubkey),
"Failed to derive public key");
own_keys_mapping[pubkey] = multisig_keys_index;
@@ -307,8 +309,7 @@ namespace multisig
* INTERNAL
*
* brief: multisig_kex_msgs_sanitize_pubkeys - Sanitize multisig kex messages.
* - Removes duplicates from msg pubkeys, ignores pubkeys equal to the local account's signing key,
* ignores messages signed by the local account, ignores keys found in input 'exclusion set',
* - Removes duplicates from msg pubkeys, ignores keys found in input 'exclusion set',
* constructs map of pubkey:origins.
* - Requires that all input msgs have the same round number.
*
@@ -316,15 +317,13 @@ namespace multisig
*
* - If the messages' round numbers are all '1', then only the message signing pubkey is considered
* 'recommended'. Furthermore, the 'exclusion set' is ignored.
* param: own_pubkey - local account's signing key (key used to sign multisig messages)
* param: expanded_msgs - set of multisig kex messages to process
* param: exclude_pubkeys - pubkeys to exclude from output set
* outparam: sanitized_pubkeys_out - processed pubkeys obtained from msgs, mapped to their origins
* return: round number shared by all input msgs
*/
//----------------------------------------------------------------------------------------------------------------------
static std::uint32_t multisig_kex_msgs_sanitize_pubkeys(const crypto::public_key &own_pubkey,
const std::vector<multisig_kex_msg> &expanded_msgs,
static std::uint32_t multisig_kex_msgs_sanitize_pubkeys(const std::vector<multisig_kex_msg> &expanded_msgs,
const std::vector<crypto::public_key> &exclude_pubkeys,
multisig_keyset_map_memsafe_t &sanitized_pubkeys_out)
{
@@ -339,10 +338,6 @@ namespace multisig
// - origins = all the signing pubkeys that recommended a given msg pubkey
for (const auto &expanded_msg : expanded_msgs)
{
// ignore messages from self
if (expanded_msg.get_signing_pubkey() == own_pubkey)
continue;
// in round 1, only the signing pubkey is treated as a msg pubkey
if (round == 1)
{
@@ -355,10 +350,6 @@ namespace multisig
// copy all pubkeys from message into list
for (const auto &pubkey : expanded_msg.get_msg_pubkeys())
{
// ignore own pubkey
if (pubkey == own_pubkey)
continue;
// ignore pubkeys in 'ignore' set
if (std::find(exclude_pubkeys.begin(), exclude_pubkeys.end(), pubkey) != exclude_pubkeys.end())
continue;
@@ -375,6 +366,31 @@ namespace multisig
/**
* INTERNAL
*
* brief: remove_key_from_mapped_sets - Remove a specified key from the mapped sets in a multisig keyset map.
* param: key_to_remove - specified key to remove
* inoutparam: keyset_inout - keyset to update
*/
//----------------------------------------------------------------------------------------------------------------------
static void remove_key_from_mapped_sets(const crypto::public_key &key_to_remove,
multisig_keyset_map_memsafe_t &keyset_inout)
{
// remove specified key from each mapped set
for (auto keyset_it = keyset_inout.begin(); keyset_it != keyset_inout.end();)
{
// remove specified key from this set
keyset_it->second.erase(key_to_remove);
// remove empty keyset positions or increment iterator
if (keyset_it->second.size() == 0)
keyset_it = keyset_inout.erase(keyset_it);
else
++keyset_it;
}
}
//----------------------------------------------------------------------------------------------------------------------
/**
* INTERNAL
*
* brief: evaluate_multisig_kex_round_msgs - Evaluate pubkeys from a kex round in order to prepare for the next round.
* - Sanitizes input msgs.
* - Require uniqueness in: 'exclude_pubkeys'.
@@ -392,6 +408,8 @@ namespace multisig
* param: signers - expected participants in multisig kex
* param: expanded_msgs - set of multisig kex messages to process
* param: exclude_pubkeys - derivations held by the local account corresponding to round 'expected_round'
* param: incomplete_signer_set - only require the minimum number of signers to complete this round
* minimum = num_signers - (round num - 1) (including local signer)
* return: fully sanitized and validated pubkey:origins map for building the account's next kex round message
*/
//----------------------------------------------------------------------------------------------------------------------
@@ -400,7 +418,8 @@ namespace multisig
const std::uint32_t expected_round,
const std::vector<crypto::public_key> &signers,
const std::vector<multisig_kex_msg> &expanded_msgs,
const std::vector<crypto::public_key> &exclude_pubkeys)
const std::vector<crypto::public_key> &exclude_pubkeys,
const bool incomplete_signer_set)
{
// exclude_pubkeys should all be unique
for (auto it = exclude_pubkeys.begin(); it != exclude_pubkeys.end(); ++it)
@@ -410,21 +429,31 @@ namespace multisig
}
// sanitize input messages
multisig_keyset_map_memsafe_t pubkey_origins_map;
const std::uint32_t round = multisig_kex_msgs_sanitize_pubkeys(base_pubkey, expanded_msgs, exclude_pubkeys, pubkey_origins_map);
multisig_keyset_map_memsafe_t pubkey_origins_map; //map: [pubkey : [origins]]
const std::uint32_t round = multisig_kex_msgs_sanitize_pubkeys(expanded_msgs, exclude_pubkeys, pubkey_origins_map);
CHECK_AND_ASSERT_THROW_MES(round == expected_round,
"Kex messages were for round [" << round << "], but expected round is [" << expected_round << "]");
// remove the local signer from each origins set in the sanitized pubkey map
// note: intermediate kex rounds only need keys from other signers to make progress (keys from self are useless)
remove_key_from_mapped_sets(base_pubkey, pubkey_origins_map);
// evaluate pubkeys collected
std::unordered_map<crypto::public_key, std::unordered_set<crypto::public_key>> origin_pubkeys_map;
std::unordered_map<crypto::public_key, std::unordered_set<crypto::public_key>> origin_pubkeys_map; //map: [origin: [pubkeys]]
// 1. each pubkey should be recommended by a precise number of signers
const std::size_t num_recommendations_per_pubkey_required{
incomplete_signer_set
? 1
: round
};
for (const auto &pubkey_and_origins : pubkey_origins_map)
{
// expected amount = round_num
// With each successive round, pubkeys are shared by incrementally larger groups,
// starting at 1 in round 1 (i.e. the local multisig key to start kex with).
CHECK_AND_ASSERT_THROW_MES(pubkey_and_origins.second.size() == round,
CHECK_AND_ASSERT_THROW_MES(pubkey_and_origins.second.size() >= num_recommendations_per_pubkey_required,
"A pubkey recommended by multisig kex messages had an unexpected number of recommendations.");
// map (sanitized) pubkeys back to origins
@@ -433,8 +462,18 @@ namespace multisig
}
// 2. the number of unique signers recommending pubkeys should equal the number of signers passed in (minus the local signer)
CHECK_AND_ASSERT_THROW_MES(origin_pubkeys_map.size() == signers.size() - 1,
"Number of unique other signers does not equal number of other signers that recommended pubkeys.");
// - if an incomplete set is allowed, then we need at least one signer to represent each subgroup in this round that
// doesn't include the local signer
const std::size_t num_signers_required{
incomplete_signer_set
? signers.size() - 1 - (round - 1)
: signers.size() - 1
};
CHECK_AND_ASSERT_THROW_MES(origin_pubkeys_map.size() >= num_signers_required,
"Number of unique other signers recommending pubkeys does not equal number of required other signers "
"(kex round: " << round << ", num signers found: " << origin_pubkeys_map.size() << ", num signers required: " <<
num_signers_required << ").");
// 3. each origin should recommend a precise number of pubkeys
@@ -461,19 +500,20 @@ namespace multisig
// other signers: (N - 2) choose (msg_round_num - 1)
// - Each signer recommends keys they share with other signers.
// - In each round, a signer shares a key with 'round num - 1' other signers.
// - Since 'origins pubkey map' excludes keys shared with the local account,
// only keys shared with participants 'other than local and self' will be in the map (e.g. N - 2 signers).
// - So other signers will recommend (N - 2) choose (msg_round_num - 1) pubkeys (after removing keys shared with local).
// - Each origin should have a shared key with each group of size 'round - 1'.
// Note: Keys shared with local are ignored to facilitate kex round boosting, where one or more signers may
// - In each round, every group of size 'round num' will have a key. From a single signer's perspective,
// they will share a key with every group of size 'round num - 1' of other signers.
// - Since 'origins pubkey map' excludes keys shared with the local account, only keys shared with participants
// 'other than local and self' will be in the map (e.g. N - 2 signers).
// - Other signers will recommend (N - 2) choose (msg_round_num - 1) pubkeys (after removing keys shared with local).
// Note: Keys shared with local are filtered out to facilitate kex round boosting, where one or more signers may
// have boosted the local signer (implying they didn't have access to the local signer's previous round msg).
const std::uint32_t expected_recommendations_others = n_choose_k_f(signers.size() - 2, round - 1);
// local: (N - 1) choose (msg_round_num - 1)
const std::uint32_t expected_recommendations_self = n_choose_k_f(signers.size() - 1, round - 1);
// note: expected_recommendations_others would be 0 in the last round of 1-of-N, but we return early for that case
// note: expected_recommendations_others would be 0 in the last round of 1-of-N, but we don't call this function for
// that case
CHECK_AND_ASSERT_THROW_MES(expected_recommendations_self > 0 && expected_recommendations_others > 0,
"Bad num signers or round num (possibly numerical limits exceeded).");
@@ -485,7 +525,7 @@ namespace multisig
for (const auto &origin_and_pubkeys : origin_pubkeys_map)
{
CHECK_AND_ASSERT_THROW_MES(origin_and_pubkeys.second.size() == expected_recommendations_others,
"A pubkey recommended by multisig kex messages had an unexpected number of recommendations.");
"A multisig signer recommended an unexpected number of pubkeys.");
// 2 (continued). only expected signers should be recommending keys
CHECK_AND_ASSERT_THROW_MES(std::find(signers.begin(), signers.end(), origin_and_pubkeys.first) != signers.end(),
@@ -507,6 +547,7 @@ namespace multisig
* param: expected_round - expected kex round of input messages
* param: signers - expected participants in multisig kex
* param: expanded_msgs - set of multisig kex messages to process
* param: incomplete_signer_set - only require the minimum amount of messages to complete this round (1 message)
* return: sanitized and validated pubkey:origins map
*/
//----------------------------------------------------------------------------------------------------------------------
@@ -514,15 +555,20 @@ namespace multisig
const crypto::public_key &base_pubkey,
const std::uint32_t expected_round,
const std::vector<crypto::public_key> &signers,
const std::vector<multisig_kex_msg> &expanded_msgs)
const std::vector<multisig_kex_msg> &expanded_msgs,
const bool incomplete_signer_set)
{
// sanitize input messages
const std::vector<crypto::public_key> dummy;
multisig_keyset_map_memsafe_t pubkey_origins_map;
const std::uint32_t round = multisig_kex_msgs_sanitize_pubkeys(base_pubkey, expanded_msgs, dummy, pubkey_origins_map);
multisig_keyset_map_memsafe_t pubkey_origins_map; //map: [pubkey : [origins]]
const std::uint32_t round = multisig_kex_msgs_sanitize_pubkeys(expanded_msgs, dummy, pubkey_origins_map);
CHECK_AND_ASSERT_THROW_MES(round == expected_round,
"Kex messages were for round [" << round << "], but expected round is [" << expected_round << "]");
// note: do NOT remove the local signer from the pubkey origins map, since the post-kex round can be force-updated with
// just the local signer's post-kex message (if the local signer were removed, then the post-kex message's pubkeys
// would be completely lost)
// evaluate pubkeys collected
// 1) there should only be two pubkeys
@@ -533,17 +579,26 @@ namespace multisig
CHECK_AND_ASSERT_THROW_MES(pubkey_origins_map.begin()->second == (++(pubkey_origins_map.begin()))->second,
"Multisig post-kex round messages from other signers did not all recommend the same pubkey pair.");
// 3) all signers should be present in the recommendation list
// 3) all signers should be present in the recommendation list (unless an incomplete list is permitted)
auto origins = pubkey_origins_map.begin()->second;
origins.insert(base_pubkey); //add self
origins.insert(base_pubkey); //add self if missing
CHECK_AND_ASSERT_THROW_MES(origins.size() == signers.size(),
"Multisig post-kex round message origins don't line up with multisig signer set.");
const std::size_t num_signers_required{
incomplete_signer_set
? 1
: signers.size()
};
for (const crypto::public_key &signer : signers)
CHECK_AND_ASSERT_THROW_MES(origins.size() >= num_signers_required,
"Multisig post-kex round message origins don't line up with multisig signer set "
"(num signers found: " << origins.size() << ", num signers required: " << num_signers_required << ").");
for (const crypto::public_key &origin : origins)
{
CHECK_AND_ASSERT_THROW_MES(origins.find(signer) != origins.end(),
"Could not find an expected signer in multisig post-kex round messages (all signers expected).");
// note: if num_signers_required == signers.size(), then this test will ensure all signers are present in 'origins',
// which contains only unique pubkeys
CHECK_AND_ASSERT_THROW_MES(std::find(signers.begin(), signers.end(), origin) != signers.end(),
"An unknown origin recommended a multisig post-kex verification messsage.");
}
return pubkey_origins_map;
@@ -564,6 +619,7 @@ namespace multisig
* param: expanded_msgs - set of multisig kex messages to process
* param: exclude_pubkeys - keys held by the local account corresponding to round 'current_round'
* - If 'current_round' is the final round, these are the local account's shares of the final aggregate key.
* param: incomplete_signer_set - allow messages from an incomplete signer set
* outparam: keys_to_origins_map_out - map between round keys and identity keys
* - If in the final round, these are key shares recommended by other signers for the final aggregate key.
* - Otherwise, these are the local account's DH derivations for the next round.
@@ -578,6 +634,7 @@ namespace multisig
const std::vector<crypto::public_key> &signers,
const std::vector<multisig_kex_msg> &expanded_msgs,
const std::vector<crypto::public_key> &exclude_pubkeys,
const bool incomplete_signer_set,
multisig_keyset_map_memsafe_t &keys_to_origins_map_out)
{
check_multisig_config(current_round, threshold, signers.size());
@@ -598,7 +655,8 @@ namespace multisig
current_round,
signers,
expanded_msgs,
exclude_pubkeys);
exclude_pubkeys,
incomplete_signer_set);
}
else //(current_round == kex_rounds_required + 1)
{
@@ -606,7 +664,8 @@ namespace multisig
evaluated_pubkeys = evaluate_multisig_post_kex_round_msgs(base_pubkey,
current_round,
signers,
expanded_msgs);
expanded_msgs,
incomplete_signer_set);
}
// prepare keys-to-origins map for updating the multisig account
@@ -693,9 +752,9 @@ namespace multisig
{
// post-kex verification round: check that the multisig pubkey and common pubkey were recommended by other signers
CHECK_AND_ASSERT_THROW_MES(result_keys_to_origins_map.count(m_multisig_pubkey) > 0,
"Multisig post-kex round: expected multisig pubkey wasn't found in other signers' messages.");
"Multisig post-kex round: expected multisig pubkey wasn't found in input messages.");
CHECK_AND_ASSERT_THROW_MES(result_keys_to_origins_map.count(m_common_pubkey) > 0,
"Multisig post-kex round: expected common pubkey wasn't found in other signers' messages.");
"Multisig post-kex round: expected common pubkey wasn't found in input messages.");
// save keys that should be recommended to other signers
// - for convenience, re-recommend the post-kex verification message once an account is complete
@@ -790,7 +849,8 @@ namespace multisig
//----------------------------------------------------------------------------------------------------------------------
// multisig_account: INTERNAL
//----------------------------------------------------------------------------------------------------------------------
void multisig_account::kex_update_impl(const std::vector<multisig_kex_msg> &expanded_msgs)
void multisig_account::kex_update_impl(const std::vector<multisig_kex_msg> &expanded_msgs,
const bool incomplete_signer_set)
{
// check messages are for the expected kex round
check_messages_round(expanded_msgs, m_kex_rounds_complete + 1);
@@ -816,6 +876,7 @@ namespace multisig
m_signers,
expanded_msgs,
exclude_pubkeys,
incomplete_signer_set,
result_keys_to_origins_map);
// finish account update
+3 -3
View File
@@ -1333,7 +1333,7 @@ namespace rct {
try
{
if (semantics) {
tools::threadpool& tpool = tools::threadpool::getInstance();
tools::threadpool& tpool = tools::threadpool::getInstanceForCompute();
tools::threadpool::waiter waiter(tpool);
std::deque<bool> results(rv.outPk.size(), false);
DP("range proofs verified?");
@@ -1383,7 +1383,7 @@ namespace rct {
{
PERF_TIMER(verRctSemanticsSimple);
tools::threadpool& tpool = tools::threadpool::getInstance();
tools::threadpool& tpool = tools::threadpool::getInstanceForCompute();
tools::threadpool::waiter waiter(tpool);
std::deque<bool> results;
std::vector<const Bulletproof*> bp_proofs;
@@ -1536,7 +1536,7 @@ namespace rct {
const size_t threads = std::max(rv.outPk.size(), rv.mixRing.size());
std::deque<bool> results(threads);
tools::threadpool& tpool = tools::threadpool::getInstance();
tools::threadpool& tpool = tools::threadpool::getInstanceForCompute();
tools::threadpool::waiter waiter(tpool);
const keyV &pseudoOuts = bulletproof || bulletproof_plus ? rv.p.pseudoOuts : rv.pseudoOuts;
+18 -12
View File
@@ -243,7 +243,7 @@ namespace
const char* USAGE_IMPORT_OUTPUTS("import_outputs <filename>");
const char* USAGE_SHOW_TRANSFER("show_transfer <txid>");
const char* USAGE_MAKE_MULTISIG("make_multisig <threshold> <string1> [<string>...]");
const char* USAGE_EXCHANGE_MULTISIG_KEYS("exchange_multisig_keys <string> [<string>...]");
const char* USAGE_EXCHANGE_MULTISIG_KEYS("exchange_multisig_keys [force-update-use-with-caution] <string> [<string>...]");
const char* USAGE_EXPORT_MULTISIG_INFO("export_multisig_info <filename>");
const char* USAGE_IMPORT_MULTISIG_INFO("import_multisig_info <filename> [<filename>...]");
const char* USAGE_SIGN_MULTISIG("sign_multisig <filename>");
@@ -1138,11 +1138,22 @@ bool simple_wallet::make_multisig_main(const std::vector<std::string> &args, boo
bool simple_wallet::exchange_multisig_keys(const std::vector<std::string> &args)
{
CHECK_MULTISIG_ENABLED();
exchange_multisig_keys_main(args, false);
bool force_update_use_with_caution = false;
auto local_args = args;
if (args.size() >= 1 && local_args[0] == "force-update-use-with-caution")
{
force_update_use_with_caution = true;
local_args.erase(local_args.begin());
}
exchange_multisig_keys_main(local_args, force_update_use_with_caution, false);
return true;
}
bool simple_wallet::exchange_multisig_keys_main(const std::vector<std::string> &args, bool called_by_mms) {
bool simple_wallet::exchange_multisig_keys_main(const std::vector<std::string> &args,
const bool force_update_use_with_caution,
const bool called_by_mms) {
CHECK_MULTISIG_ENABLED();
bool ready;
if (m_wallet->key_on_device())
@@ -1168,15 +1179,9 @@ bool simple_wallet::exchange_multisig_keys_main(const std::vector<std::string> &
return false;
}
if (args.size() < 1)
{
PRINT_USAGE(USAGE_EXCHANGE_MULTISIG_KEYS);
return false;
}
try
{
std::string multisig_extra_info = m_wallet->exchange_multisig_keys(orig_pwd_container->password(), args);
std::string multisig_extra_info = m_wallet->exchange_multisig_keys(orig_pwd_container->password(), args, force_update_use_with_caution);
bool ready;
m_wallet->multisig(&ready);
if (!ready)
@@ -4787,7 +4792,7 @@ bool simple_wallet::try_connect_to_daemon(bool silent, uint32_t* version)
uint32_t version_ = 0;
if (!version)
version = &version_;
bool wallet_is_outdated, daemon_is_outdated = false;
bool wallet_is_outdated = false, daemon_is_outdated = false;
if (!m_wallet->check_connection(version, NULL, 200000, &wallet_is_outdated, &daemon_is_outdated))
{
if (!silent)
@@ -11176,7 +11181,8 @@ void simple_wallet::mms_next(const std::vector<std::string> &args)
mms::message m = ms.get_message_by_id(data.message_ids[i]);
sig_args[i] = m.content;
}
command_successful = exchange_multisig_keys_main(sig_args, true);
// todo: update mms to enable 'key exchange force updating'
command_successful = exchange_multisig_keys_main(sig_args, false, true);
break;
}
+1 -1
View File
@@ -235,7 +235,7 @@ namespace cryptonote
bool make_multisig(const std::vector<std::string>& args);
bool make_multisig_main(const std::vector<std::string>& args, bool called_by_mms);
bool exchange_multisig_keys(const std::vector<std::string> &args);
bool exchange_multisig_keys_main(const std::vector<std::string> &args, bool called_by_mms);
bool exchange_multisig_keys_main(const std::vector<std::string> &args, const bool force_update_use_with_caution, const bool called_by_mms);
bool export_multisig(const std::vector<std::string>& args);
bool export_multisig_main(const std::vector<std::string>& args, bool called_by_mms);
bool import_multisig(const std::vector<std::string>& args);
+1 -1
View File
@@ -1,5 +1,5 @@
#define DEF_MONERO_VERSION_TAG "@VERSIONTAG@"
#define DEF_MONERO_VERSION "0.18.1.1"
#define DEF_MONERO_VERSION "0.18.1.2"
#define DEF_MONERO_RELEASE_NAME "Fluorine Fermi"
#define DEF_MONERO_VERSION_FULL DEF_MONERO_VERSION "-" DEF_MONERO_VERSION_TAG
#define DEF_MONERO_VERSION_IS_RELEASE @VERSION_IS_RELEASE@
+5 -5
View File
@@ -63,8 +63,8 @@ namespace {
static const int MAX_REFRESH_INTERVAL_MILLIS = 1000 * 60 * 1;
// Default refresh interval when connected to remote node
static const int DEFAULT_REMOTE_NODE_REFRESH_INTERVAL_MILLIS = 1000 * 10;
// Connection timeout 30 sec
static const int DEFAULT_CONNECTION_TIMEOUT_MILLIS = 1000 * 30;
// Connection timeout 20 sec
static const int DEFAULT_CONNECTION_TIMEOUT_MILLIS = 1000 * 20;
std::string get_default_ringdb_path(cryptonote::network_type nettype)
{
@@ -1396,12 +1396,12 @@ string WalletImpl::makeMultisig(const vector<string>& info, const uint32_t thres
return string();
}
std::string WalletImpl::exchangeMultisigKeys(const std::vector<std::string> &info) {
std::string WalletImpl::exchangeMultisigKeys(const std::vector<std::string> &info, const bool force_update_use_with_caution /*= false*/) {
try {
clearStatus();
checkMultisigWalletNotReady(m_wallet);
return m_wallet->exchange_multisig_keys(epee::wipeable_string(m_password), info);
return m_wallet->exchange_multisig_keys(epee::wipeable_string(m_password), info, force_update_use_with_caution);
} catch (const exception& e) {
LOG_ERROR("Error on exchanging multisig keys: " << e.what());
setStatusError(string(tr("Failed to exchange multisig keys: ")) + e.what());
@@ -2173,7 +2173,7 @@ bool WalletImpl::connectToDaemon()
Wallet::ConnectionStatus WalletImpl::connected() const
{
uint32_t version = 0;
bool wallet_is_outdated, daemon_is_outdated = false;
bool wallet_is_outdated = false, daemon_is_outdated = false;
m_is_connected = m_wallet->check_connection(&version, NULL, DEFAULT_CONNECTION_TIMEOUT_MILLIS, &wallet_is_outdated, &daemon_is_outdated);
if (!m_is_connected)
{
+1 -1
View File
@@ -146,7 +146,7 @@ public:
MultisigState multisig() const override;
std::string getMultisigInfo() const override;
std::string makeMultisig(const std::vector<std::string>& info, uint32_t threshold) override;
std::string exchangeMultisigKeys(const std::vector<std::string> &info) override;
std::string exchangeMultisigKeys(const std::vector<std::string> &info, const bool force_update_use_with_caution = false) override;
bool exportMultisigImages(std::string& images) override;
size_t importMultisigImages(const std::vector<std::string>& images) override;
bool hasMultisigPartialKeyImages() const override;
+2 -1
View File
@@ -796,9 +796,10 @@ struct Wallet
/**
* @brief exchange_multisig_keys - provides additional key exchange round for arbitrary multisig schemes (like N-1/N, M/N)
* @param info - base58 encoded key derivations returned by makeMultisig or exchangeMultisigKeys function call
* @param force_update_use_with_caution - force multisig account to update even if not all signers contribute round messages
* @return new info string if more rounds required or an empty string if wallet creation is done
*/
virtual std::string exchangeMultisigKeys(const std::vector<std::string> &info) = 0;
virtual std::string exchangeMultisigKeys(const std::vector<std::string> &info, const bool force_update_use_with_caution) = 0;
/**
* @brief exportMultisigImages - exports transfers' key images
* @param images - output paramter for hex encoded array of images
+24 -14
View File
@@ -1346,6 +1346,7 @@ bool wallet2::set_daemon(std::string daemon_address, boost::optional<epee::net_u
}
m_rpc_payment_state.expected_spent = 0;
m_rpc_payment_state.discrepancy = 0;
m_rpc_version = 0;
m_node_rpc_proxy.invalidate();
}
@@ -2724,7 +2725,7 @@ void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector<cry
THROW_WALLET_EXCEPTION_IF(blocks.size() != parsed_blocks.size(), error::wallet_internal_error, "size mismatch");
THROW_WALLET_EXCEPTION_IF(!m_blockchain.is_in_bounds(current_index), error::out_of_hashchain_bounds_error);
tools::threadpool& tpool = tools::threadpool::getInstance();
tools::threadpool& tpool = tools::threadpool::getInstanceForCompute();
tools::threadpool::waiter waiter(tpool);
size_t num_txes = 0;
@@ -2967,7 +2968,7 @@ void wallet2::pull_and_parse_next_blocks(uint64_t start_height, uint64_t &blocks
pull_blocks(start_height, blocks_start_height, short_chain_history, blocks, o_indices, current_height);
THROW_WALLET_EXCEPTION_IF(blocks.size() != o_indices.size(), error::wallet_internal_error, "Mismatched sizes of blocks and o_indices");
tools::threadpool& tpool = tools::threadpool::getInstance();
tools::threadpool& tpool = tools::threadpool::getInstanceForCompute();
tools::threadpool::waiter waiter(tpool);
parsed_blocks.resize(blocks.size());
for (size_t i = 0; i < blocks.size(); ++i)
@@ -3464,7 +3465,7 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo
size_t try_count = 0;
crypto::hash last_tx_hash_id = m_transfers.size() ? m_transfers.back().m_txid : null_hash;
std::list<crypto::hash> short_chain_history;
tools::threadpool& tpool = tools::threadpool::getInstance();
tools::threadpool& tpool = tools::threadpool::getInstanceForCompute();
tools::threadpool::waiter waiter(tpool);
uint64_t blocks_start_height;
std::vector<cryptonote::block_complete_entry> blocks;
@@ -5126,12 +5127,11 @@ std::string wallet2::make_multisig(const epee::wipeable_string &password,
}
//----------------------------------------------------------------------------------------------------
std::string wallet2::exchange_multisig_keys(const epee::wipeable_string &password,
const std::vector<std::string> &kex_messages)
const std::vector<std::string> &kex_messages,
const bool force_update_use_with_caution /*= false*/)
{
bool ready{false};
CHECK_AND_ASSERT_THROW_MES(multisig(&ready), "The wallet is not multisig");
CHECK_AND_ASSERT_THROW_MES(!ready, "Multisig wallet creation process has already been finished");
CHECK_AND_ASSERT_THROW_MES(kex_messages.size() > 0, "No key exchange messages passed in.");
// decrypt account keys
epee::misc_utils::auto_scope_leave_caller keys_reencryptor;
@@ -5150,13 +5150,6 @@ std::string wallet2::exchange_multisig_keys(const epee::wipeable_string &passwor
);
}
// open kex messages
std::vector<multisig::multisig_kex_msg> expanded_msgs;
expanded_msgs.reserve(kex_messages.size());
for (const auto &msg : kex_messages)
expanded_msgs.emplace_back(msg);
// reconstruct multisig account
multisig::multisig_keyset_map_memsafe_t kex_origins_map;
@@ -5177,8 +5170,25 @@ std::string wallet2::exchange_multisig_keys(const epee::wipeable_string &passwor
""
};
// KLUDGE: early return if there are no kex messages and main kex is complete (will return the post-kex verification round
// message) (it's a kludge because this behavior would be more appropriate for a standalone wallet method)
if (kex_messages.size() == 0)
{
CHECK_AND_ASSERT_THROW_MES(multisig_account.main_kex_rounds_done(),
"Exchange multisig keys: there are no kex messages but the main kex rounds are not done.");
return multisig_account.get_next_kex_round_msg();
}
// open kex messages
std::vector<multisig::multisig_kex_msg> expanded_msgs;
expanded_msgs.reserve(kex_messages.size());
for (const auto &msg : kex_messages)
expanded_msgs.emplace_back(msg);
// update multisig kex
multisig_account.kex_update(expanded_msgs);
multisig_account.kex_update(expanded_msgs, force_update_use_with_caution);
// update wallet state
+2 -1
View File
@@ -886,7 +886,8 @@ private:
* to other participants
*/
std::string exchange_multisig_keys(const epee::wipeable_string &password,
const std::vector<std::string> &kex_messages);
const std::vector<std::string> &kex_messages,
const bool force_update_use_with_caution = false);
/*!
* \brief Get initial message to start multisig key exchange (before 'make_multisig()' is called)
* \return string to send to other participants
+1 -1
View File
@@ -144,7 +144,7 @@ bool wallet2::search_for_rpc_payment(uint64_t credits_target, uint32_t n_threads
n_threads = boost::thread::hardware_concurrency();
std::vector<crypto::hash> hash(n_threads);
tools::threadpool& tpool = tools::threadpool::getInstance();
tools::threadpool& tpool = tools::threadpool::getInstanceForCompute();
tools::threadpool::waiter waiter(tpool);
const uint32_t local_nonce = nonce += n_threads; // wrapping's OK
+1 -8
View File
@@ -4146,13 +4146,6 @@ namespace tools
er.message = "This wallet is not multisig";
return false;
}
if (ready)
{
er.code = WALLET_RPC_ERROR_CODE_ALREADY_MULTISIG;
er.message = "This wallet is multisig, and already finalized";
return false;
}
CHECK_MULTISIG_ENABLED();
if (req.multisig_info.size() + 1 < total)
@@ -4164,7 +4157,7 @@ namespace tools
try
{
res.multisig_info = m_wallet->exchange_multisig_keys(req.password, req.multisig_info);
res.multisig_info = m_wallet->exchange_multisig_keys(req.password, req.multisig_info, req.force_update_use_with_caution);
m_wallet->multisig(&ready);
if (ready)
{
+3 -1
View File
@@ -47,7 +47,7 @@
// advance which version they will stop working with
// Don't go over 32767 for any of these
#define WALLET_RPC_VERSION_MAJOR 1
#define WALLET_RPC_VERSION_MINOR 25
#define WALLET_RPC_VERSION_MINOR 26
#define MAKE_WALLET_RPC_VERSION(major,minor) (((major)<<16)|(minor))
#define WALLET_RPC_VERSION MAKE_WALLET_RPC_VERSION(WALLET_RPC_VERSION_MAJOR, WALLET_RPC_VERSION_MINOR)
namespace tools
@@ -2535,10 +2535,12 @@ namespace wallet_rpc
{
std::string password;
std::vector<std::string> multisig_info;
bool force_update_use_with_caution;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(password)
KV_SERIALIZE(multisig_info)
KV_SERIALIZE_OPT(force_update_use_with_caution, false)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;
+1
View File
@@ -90,6 +90,7 @@ namespace tests
bool get_test_drop_download_height() {return true;}
bool prepare_handle_incoming_blocks(const std::vector<cryptonote::block_complete_entry> &blocks_entry, std::vector<cryptonote::block> &blocks) { return true; }
bool cleanup_handle_incoming_blocks(bool force_sync = false) { return true; }
bool update_checkpoints(const bool skip_dns = false) { return true; }
uint64_t get_target_blockchain_height() const { return 1; }
size_t get_block_sync_size(uint64_t height) const { return BLOCKS_SYNCHRONIZING_DEFAULT_COUNT; }
virtual void on_transactions_relayed(epee::span<const cryptonote::blobdata> tx_blobs, cryptonote::relay_method tx_relay) {}
+1 -1
View File
@@ -778,7 +778,7 @@ inline bool do_replay_events_get_core(std::vector<test_event_entry>& events, cry
t_test_class validator;
bool ret = replay_events_through_core<t_test_class>(c, events, validator);
tools::threadpool::getInstance().recycle();
tools::threadpool::getInstanceForCompute().recycle();
// c.deinit();
return ret;
}
+64 -24
View File
@@ -95,9 +95,47 @@ static std::vector<std::string> exchange_round(std::vector<tools::wallet2>& wall
std::vector<std::string> new_infos;
new_infos.reserve(infos.size());
for (size_t i = 0; i < wallets.size(); ++i)
new_infos.push_back(wallets[i].exchange_multisig_keys("", infos));
return new_infos;
}
static std::vector<std::string> exchange_round_force_update(std::vector<tools::wallet2>& wallets,
const std::vector<std::string>& infos,
const std::size_t round_in_progress)
{
EXPECT_TRUE(wallets.size() == infos.size());
std::vector<std::string> new_infos;
std::vector<std::string> temp_force_update_infos;
new_infos.reserve(infos.size());
// when force-updating, we only need at most 'num_signers - 1 - (round - 1)' messages from other signers
size_t num_other_messages_required{wallets.size() - 1 - (round_in_progress - 1)};
if (num_other_messages_required > wallets.size())
num_other_messages_required = 0; //overflow case for post-kex verification round of 1-of-N
for (size_t i = 0; i < wallets.size(); ++i)
{
new_infos.push_back(wallets[i].exchange_multisig_keys("", infos));
temp_force_update_infos.clear();
temp_force_update_infos.reserve(num_other_messages_required + 1);
temp_force_update_infos.push_back(infos[i]); //always include the local signer's message for this round
size_t infos_collected{0};
for (size_t wallet_index = 0; wallet_index < wallets.size(); ++wallet_index)
{
// skip the local signer's message
if (wallet_index == i)
continue;
temp_force_update_infos.push_back(infos[wallet_index]);
++infos_collected;
if (infos_collected == num_other_messages_required)
break;
}
new_infos.push_back(wallets[i].exchange_multisig_keys("", temp_force_update_infos, true));
}
return new_infos;
@@ -105,7 +143,7 @@ static std::vector<std::string> exchange_round(std::vector<tools::wallet2>& wall
static void check_results(const std::vector<std::string> &intermediate_infos,
std::vector<tools::wallet2>& wallets,
std::uint32_t M)
const std::uint32_t M)
{
// check results
std::unordered_set<crypto::secret_key> unique_privkeys;
@@ -167,8 +205,9 @@ static void check_results(const std::vector<std::string> &intermediate_infos,
wallets[0].encrypt_keys("");
}
static void make_wallets(std::vector<tools::wallet2>& wallets, unsigned int M)
static void make_wallets(const unsigned int M, const unsigned int N, const bool force_update)
{
std::vector<tools::wallet2> wallets(N);
ASSERT_TRUE(wallets.size() > 1 && wallets.size() <= KEYS_COUNT);
ASSERT_TRUE(M <= wallets.size());
std::uint32_t total_rounds_required = multisig::multisig_setup_rounds_required(wallets.size(), M);
@@ -207,9 +246,12 @@ static void make_wallets(std::vector<tools::wallet2>& wallets, unsigned int M)
wallets[0].multisig(&ready);
while (!ready)
{
intermediate_infos = exchange_round(wallets, intermediate_infos);
wallets[0].multisig(&ready);
if (force_update)
intermediate_infos = exchange_round_force_update(wallets, intermediate_infos, rounds_complete + 1);
else
intermediate_infos = exchange_round(wallets, intermediate_infos);
wallets[0].multisig(&ready);
++rounds_complete;
}
@@ -220,38 +262,38 @@ static void make_wallets(std::vector<tools::wallet2>& wallets, unsigned int M)
TEST(multisig, make_1_2)
{
std::vector<tools::wallet2> wallets(2);
make_wallets(wallets, 1);
make_wallets(1, 2, false);
make_wallets(1, 2, true);
}
TEST(multisig, make_1_3)
{
std::vector<tools::wallet2> wallets(3);
make_wallets(wallets, 1);
make_wallets(1, 3, false);
make_wallets(1, 3, true);
}
TEST(multisig, make_2_2)
{
std::vector<tools::wallet2> wallets(2);
make_wallets(wallets, 2);
make_wallets(2, 2, false);
make_wallets(2, 2, true);
}
TEST(multisig, make_3_3)
{
std::vector<tools::wallet2> wallets(3);
make_wallets(wallets, 3);
make_wallets(3, 3, false);
make_wallets(3, 3, true);
}
TEST(multisig, make_2_3)
{
std::vector<tools::wallet2> wallets(3);
make_wallets(wallets, 2);
make_wallets(2, 3, false);
make_wallets(2, 3, true);
}
TEST(multisig, make_2_4)
{
std::vector<tools::wallet2> wallets(4);
make_wallets(wallets, 2);
make_wallets(2, 4, false);
make_wallets(2, 4, true);
}
TEST(multisig, multisig_kex_msg)
@@ -272,9 +314,7 @@ TEST(multisig, multisig_kex_msg)
signing_skey = rct::rct2sk(rct::skGen());
}
crypto::secret_key ancillary_skey = rct::rct2sk(rct::skGen());
while (ancillary_skey == crypto::null_skey)
ancillary_skey = rct::rct2sk(rct::skGen());
const crypto::secret_key ancillary_skey{rct::rct2sk(rct::skGen())};
// misc. edge cases
EXPECT_NO_THROW((multisig_kex_msg{}));
@@ -312,8 +352,8 @@ TEST(multisig, multisig_kex_msg)
// test that keys can be recovered if stored in a message and the message's reverse
// round 1
multisig_kex_msg msg_rnd1{1, signing_skey, std::vector<crypto::public_key>{pubkey1}, ancillary_skey};
multisig_kex_msg msg_rnd1_reverse{msg_rnd1.get_msg()};
const multisig_kex_msg msg_rnd1{1, signing_skey, std::vector<crypto::public_key>{pubkey1}, ancillary_skey};
const multisig_kex_msg msg_rnd1_reverse{msg_rnd1.get_msg()};
EXPECT_EQ(msg_rnd1.get_round(), 1);
EXPECT_EQ(msg_rnd1.get_round(), msg_rnd1_reverse.get_round());
EXPECT_EQ(msg_rnd1.get_signing_pubkey(), signing_pubkey);
@@ -324,8 +364,8 @@ TEST(multisig, multisig_kex_msg)
EXPECT_EQ(msg_rnd1.get_msg_privkey(), msg_rnd1_reverse.get_msg_privkey());
// round 2
multisig_kex_msg msg_rnd2{2, signing_skey, std::vector<crypto::public_key>{pubkey1, pubkey2}, ancillary_skey};
multisig_kex_msg msg_rnd2_reverse{msg_rnd2.get_msg()};
const multisig_kex_msg msg_rnd2{2, signing_skey, std::vector<crypto::public_key>{pubkey1, pubkey2}, ancillary_skey};
const multisig_kex_msg msg_rnd2_reverse{msg_rnd2.get_msg()};
EXPECT_EQ(msg_rnd2.get_round(), 2);
EXPECT_EQ(msg_rnd2.get_round(), msg_rnd2_reverse.get_round());
EXPECT_EQ(msg_rnd2.get_signing_pubkey(), signing_pubkey);
+1
View File
@@ -72,6 +72,7 @@ public:
bool get_test_drop_download_height() const {return true;}
bool prepare_handle_incoming_blocks(const std::vector<cryptonote::block_complete_entry> &blocks_entry, std::vector<cryptonote::block> &blocks) { return true; }
bool cleanup_handle_incoming_blocks(bool force_sync = false) { return true; }
bool update_checkpoints(const bool skip_dns = false) { return true; }
uint64_t get_target_blockchain_height() const { return 1; }
size_t get_block_sync_size(uint64_t height) const { return BLOCKS_SYNCHRONIZING_DEFAULT_COUNT; }
virtual void on_transactions_relayed(epee::span<const cryptonote::blobdata> tx_blobs, cryptonote::relay_method tx_relay) {}
+2 -1
View File
@@ -524,12 +524,13 @@ class Wallet(object):
}
return self.rpc.send_json_rpc_request(finalize_multisig)
def exchange_multisig_keys(self, multisig_info, password = ''):
def exchange_multisig_keys(self, multisig_info, password = '', force_update_use_with_caution = False):
exchange_multisig_keys = {
'method': 'exchange_multisig_keys',
'params' : {
'multisig_info': multisig_info,
'password': password,
'force_update_use_with_caution': force_update_use_with_caution,
},
'jsonrpc': '2.0',
'id': '0'