Compare commits

...

87 Commits

Author SHA1 Message Date
luigi1111 2222bea92f Merge pull request #7902
0ae1cd2 v0.17: Fix Boost-1.77: Add missing algorithm header to i18n.cpp (mj-xmr)
2021-08-29 12:30:57 -04:00
luigi1111 f12e75b5e4 Merge pull request #7888
3c15eb8 python-rpc: add missing python api for new freeze/thaw/frozen RPC (moneromooo-monero)
2021-08-29 12:29:57 -04:00
mj-xmr 0ae1cd2413 v0.17: Fix Boost-1.77: Add missing algorithm header to i18n.cpp 2021-08-28 15:32:50 +02:00
luigi1111 317eceb725 Merge pull request #7894
c0ce4d5 Wallet2: fix optimize-coinbase for p2pool payouts (SChernykh)
2021-08-26 21:14:12 -04:00
luigi1111 d98787eb1b Merge pull request #7825
ccfed60 cmake: test is a reserved keyword (selsta)
f0fa959 cmake: fix ccache detection (anon)
8dbe2e5 Daemon: Update average block size table (rbrunner7)
94bad34 wallet2: Don't auto lock device on process parsed blocks (tobtoht)
3c23aca ledger: don't lock for software device (tobtoht)
49beb8d ledger: use software device if we have view key (tobtoht)
d188b5f wallet_api: getPassword (tobtoht)
a395f36 depends, docker: fix bintray links (selsta)
0fecd7e blocks: fix cmake syntax (selsta)
76824bf Stop adding more outputs than bulletproof allows (Alex Opie)
67ba733 unit_tests: fix wipeable_string parse_hexstr test with latest gtest (xiphon)
402ba04 cmake: use CMAKE_CURRENT_LIST_DIR in FindLibUSB (selsta)
1565bcb epee: include public openssl header in cmake (selsta)
2e9af2a cmake: treat warnings as error in compiler flag tests (selsta)
db564ef wallet_api: fix typo in exportKeyImages (selsta)
8507917 depends: add getmonero package mirror (selsta)
8716d2a cmake: fix non portable code (selsta)
2021-08-26 21:10:56 -04:00
luigi1111 ca1b1b7332 Merge pull request #7822
99bee1c Apply gamma distr from chain tip when selecting decoys (j-berman)
2021-08-26 21:08:56 -04:00
luigi1111 27c5013acd Merge pull request #7805
1e037d3 build: prepare v0.17.2.3 (selsta)
2021-08-26 21:08:04 -04:00
SChernykh c0ce4d5089 Wallet2: fix optimize-coinbase for p2pool payouts
RefreshOptimizeCoinbase was an optimization to speed up scanning of coinbase transactions before RingCT (tx version 2) where they split miner reward into multiple denominations, all to the same wallet.

When RingCT was introduced, all coinbase transactions became 1 output only, so this optimization does nothing now.

With p2pool, this optimization will skip scanning p2pool payouts because they use more than 1 output in coinbase transaction.

Fix it by applying this optimization only to pre-RingCT transactions (version < 2).
2021-08-26 11:51:07 +02:00
moneromooo-monero 3c15eb8e81 python-rpc: add missing python api for new freeze/thaw/frozen RPC 2021-08-24 00:25:10 +02:00
luigi1111 c61c09a567 Merge pull request #7882
e48fae3 epee: link with Boost_SYSTEM_LIBRARY (selsta)
2021-08-20 16:51:39 -04:00
luigi1111 b864817629 Merge pull request #7879
be6c61e wallet_api: add make_uri (tobtoht)
2021-08-20 16:50:54 -04:00
luigi1111 a520234c51 Merge pull request #7848
adcf440 Make sure node returns to wallet that real output is unlocked (j-berman)
2021-08-20 16:49:19 -04:00
luigi1111 715ebcb744 Merge pull request #7846
2285c66 Protect client from divide by 0 caused by integer truncation (j-berman)
2021-08-20 16:48:14 -04:00
luigi1111 4073599aaf Merge pull request #7838
6ec9fd6 support freeze, thaw, and frozen in wallet rpc (woodser)
2021-08-20 16:43:18 -04:00
j-berman 2285c66ef1 Protect client from divide by 0 caused by integer truncation 2021-08-19 15:00:59 -07:00
j-berman 99bee1ccf0 Apply gamma distr from chain tip when selecting decoys
- matches the paper by Miller et al to apply the gamma from chain tip, rather than after unlock time
- if the gamma produces an output more recent than the unlock time, the algo packs that output into one of the first 50 spendable blocks, respecting the block density factor
2021-08-19 14:59:12 -07:00
selsta e48fae3177 epee: link with Boost_SYSTEM_LIBRARY 2021-08-19 19:06:05 +02:00
tobtoht be6c61e2ee wallet_api: add make_uri 2021-08-19 15:52:01 +02:00
selsta 1e037d372a build: prepare v0.17.2.3 2021-08-19 15:00:42 +02:00
woodser 6ec9fd6c08 support freeze, thaw, and frozen in wallet rpc 2021-08-12 09:13:09 -04:00
selsta ccfed6008a cmake: test is a reserved keyword 2021-08-12 04:52:51 +02:00
anon f0fa959383 cmake: fix ccache detection 2021-08-12 04:52:36 +02:00
rbrunner7 8dbe2e57ac Daemon: Update average block size table 2021-08-12 04:42:46 +02:00
luigi1111 64c320130f Merge pull request #7839
925c6b6 provide key images of spent outputs in wallet rpc (woodser)
2021-08-11 22:41:04 -04:00
luigi1111 8f95eaa0b0 Merge pull request #7817
1510b1e unit_tests: fix broken tests (anon)
2021-08-11 22:39:42 -04:00
luigi1111 9f93fe1539 Merge pull request #7810
8eb2b79 p2p: remove blocked addresses/hosts from peerlist (moneromooo-monero)
2021-08-11 22:36:50 -04:00
luigi1111 db6688f584 Merge pull request #7801
07d82af Fixed json serialization of rct::RCTTypeNull (SChernykh)
2021-08-11 22:33:04 -04:00
luigi1111 f00db20a5f Merge pull request #7792
9b84043 fix #7784 - deinit wallet in wallet dtor (Dusan Klinec)
2021-08-11 22:30:53 -04:00
j-berman adcf440dcd Make sure node returns to wallet that real output is unlocked 2021-08-11 07:26:56 -07:00
woodser 925c6b60e3 provide key images of spent outputs in wallet rpc 2021-08-07 09:36:45 -04:00
tobtoht 94bad34c26 wallet2: Don't auto lock device on process parsed blocks 2021-08-07 03:04:24 +02:00
tobtoht 3c23aca26b ledger: don't lock for software device 2021-08-07 03:04:15 +02:00
tobtoht 49beb8da17 ledger: use software device if we have view key 2021-08-07 03:04:04 +02:00
tobtoht d188b5f51f wallet_api: getPassword 2021-08-07 03:03:40 +02:00
moneromooo-monero 8eb2b79bad p2p: remove blocked addresses/hosts from peerlist 2021-08-05 19:05:02 +00:00
luigi1111 3eb8f1458b Merge pull request #7791
7e3f211 wallet: rephrase error message on invalid device address (Dusan Klinec)
2021-08-02 18:53:40 -04:00
selsta a395f363e7 depends, docker: fix bintray links 2021-08-01 18:16:09 +02:00
selsta 0fecd7eb86 blocks: fix cmake syntax 2021-08-01 15:47:11 +02:00
Alex Opie 76824bf827 Stop adding more outputs than bulletproof allows
If more outputs are requested, they are split across
multiple transactions.

#7322
2021-08-01 15:47:11 +02:00
xiphon 67ba733de1 unit_tests: fix wipeable_string parse_hexstr test with latest gtest
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=973196
2021-08-01 15:47:11 +02:00
selsta 402ba046e0 cmake: use CMAKE_CURRENT_LIST_DIR in FindLibUSB 2021-08-01 15:47:11 +02:00
selsta 1565bcb1fb epee: include public openssl header in cmake 2021-08-01 15:47:08 +02:00
selsta 2e9af2a1c8 cmake: treat warnings as error in compiler flag tests 2021-08-01 15:47:05 +02:00
selsta db564efe0b wallet_api: fix typo in exportKeyImages 2021-08-01 15:47:05 +02:00
selsta 85079173db depends: add getmonero package mirror 2021-08-01 15:47:05 +02:00
selsta 8716d2ad9d cmake: fix non portable code 2021-08-01 15:47:05 +02:00
luigi1111 5a34eae063 Merge pull request #7815
7128f73 cmake: don't forbid undefined symbols on openbsd (selsta)
2021-07-28 14:02:43 -04:00
anon 1510b1e550 unit_tests: fix broken tests
boosted_tcp_server: check condition before sleep too
cryptonote_protocol_handler: each instance of BlockchainLMDB requires separate thread due to private thread local fields
2021-07-28 13:38:23 +00:00
selsta 7128f73ec2 cmake: don't forbid undefined symbols on openbsd 2021-07-28 01:23:03 +02:00
luigi1111 8b63bb3c75 Merge pull request #7789
2161bd0 device: set correct ledger min version (selsta)
2021-07-27 17:05:11 -04:00
luigi1111 56ce7fca6f Merge pull request #7781
4f7c38a device_trezor_base: fix typo (anon)
2021-07-27 17:03:46 -04:00
luigi1111 bc252794f0 Merge pull request #7693
ec6ff0d cmake: export all symbols (anon)
ceb8e7c cmake: fix undefined symbols and multiple definitions (anon)
72af8a5 cmake: forbid undefined symbols (anon)
2021-07-27 16:52:59 -04:00
SChernykh 07d82af979 Fixed json serialization of rct::RCTTypeNull
rct::RCTTypeNull doesn't have these fields (ecdhInfo, outPk, txnFee).
2021-07-18 17:19:32 +02:00
Dusan Klinec 9b840439b9 fix #7784 - deinit wallet in wallet dtor 2021-07-14 15:08:06 +02:00
Dusan Klinec 7e3f211791 wallet: rephrase error message on invalid device address 2021-07-14 15:05:28 +02:00
selsta 2161bd0f3a device: set correct ledger min version 2021-07-14 08:31:11 +02:00
anon ec6ff0d002 cmake: export all symbols 2021-07-13 08:01:26 +02:00
anon ceb8e7c508 cmake: fix undefined symbols and multiple definitions 2021-07-13 08:01:23 +02:00
anon 72af8a5fce cmake: forbid undefined symbols 2021-07-13 08:01:09 +02:00
anon 4f7c38a444 device_trezor_base: fix typo 2021-07-10 23:52:15 +00:00
luigi1111 7d2e717ee8 Merge pull request #7734
a2d8f87 randomx: bump submodule to v1.1.9 (selsta)
2021-06-16 14:40:45 -05:00
luigi1111 83e378740a Merge pull request #7736
c28d2f7 Fix boost 1.76.0 compatibility (loqs)
2021-06-01 22:12:42 -05:00
loqs c28d2f7c11 Fix boost 1.76.0 compatibility
Add missing header boost/mpl/contains.hpp
monero-project/monero/issues/7728
2021-05-24 05:32:24 +02:00
selsta a2d8f876ca randomx: bump submodule to v1.1.9 2021-05-22 23:13:23 +02:00
luigi1111 3701257d61 Merge pull request #7695
1d6f211 workflows: fix windows build (selsta)
2021-05-12 17:00:58 -05:00
luigi1111 90703ba8bd Merge pull request #7687
cb9a2e4 add -framework AppKit for Apple (woodser)
2021-05-12 16:57:02 -05:00
luigi1111 a080c0be9c Merge pull request #7678
dedcd63 wallet_api: import / export output function (tobtoht)
6e22710 expose set_offline to wallet api (benevanoff)
02e9a41 wallet_api: add isDeterministic() (tobtoht)
def5819 wallet_api: add seed_offset param to seed() (tobtoht)
73959c6 wallet_api: store fee for incoming txs in history (Ben Evanoff)
712f362 wallet api: allow wallet to fetch all key images via api (benevanoff)
153d08d Allow tx note edits via TransactionHistory object in wallet/api (dsc)
2abd7b1 wallet_api: TransactionHistory - fill unconfirmed out payments dests (xiphon)
9a50bef Extend TransactionInfo with coinbase and description attributes in wallet/api (dsc)
22bb6a6 Allow AddressBook description edits via wallet/api interface (dsc)
2021-05-12 16:55:38 -05:00
luigi1111 de7565069e Merge pull request #7680
70c5c81 wallet2: Fix rescan_bc keep_ki option (Nathan Dorfman)
2021-05-12 15:29:31 -05:00
selsta 1d6f2114b8 workflows: fix windows build 2021-04-27 14:45:22 +02:00
woodser cb9a2e4471 add -framework AppKit for Apple 2021-04-26 18:30:32 -04:00
Nathan Dorfman 70c5c81670 wallet2: Fix rescan_bc keep_ki option 2021-04-22 16:15:01 -06:00
luigi1111 d59cd3d222 Merge pull request #7657
6305b90 ITS#9496 fix mdb_env_open bug from #8704 (Howard Chu)
2021-04-22 01:44:50 -04:00
tobtoht dedcd6304c wallet_api: import / export output function 2021-04-22 04:33:11 +02:00
benevanoff 6e22710f0e expose set_offline to wallet api 2021-04-22 04:33:03 +02:00
tobtoht 02e9a41cbe wallet_api: add isDeterministic() 2021-04-22 04:32:50 +02:00
tobtoht def58196da wallet_api: add seed_offset param to seed() 2021-04-22 04:32:41 +02:00
Ben Evanoff 73959c623c wallet_api: store fee for incoming txs in history 2021-04-22 04:32:32 +02:00
benevanoff 712f362150 wallet api: allow wallet to fetch all key images via api 2021-04-22 04:32:24 +02:00
dsc 153d08d026 Allow tx note edits via TransactionHistory object in wallet/api 2021-04-22 04:32:14 +02:00
xiphon 2abd7b174b wallet_api: TransactionHistory - fill unconfirmed out payments dests 2021-04-22 04:32:06 +02:00
dsc 9a50bef3cd Extend TransactionInfo with coinbase and description attributes in wallet/api 2021-04-22 04:31:44 +02:00
dsc 22bb6a654d Allow AddressBook description edits via wallet/api interface 2021-04-22 04:31:36 +02:00
luigi1111 38958f722b Merge pull request #7655
9fc9c7d gitian: remove osslsigncode (selsta)
2021-04-16 12:53:55 -05:00
luigi1111 36a68b0cba Merge pull request #7654
df03288 unit_tests: fix boost 1.58 compatibility (anon)
2021-04-16 12:53:28 -05:00
Howard Chu 6305b90596 ITS#9496 fix mdb_env_open bug from #8704
Broken in 9c6eb75c65
2021-04-09 14:25:51 +01:00
selsta 9fc9c7d695 gitian: remove osslsigncode
Unused and archive is offline
2021-04-08 17:13:57 +02:00
anon df032882a8 unit_tests: fix boost 1.58 compatibility 2021-04-08 11:45:26 +00:00
59 changed files with 838 additions and 176 deletions
+1 -1
View File
@@ -23,7 +23,7 @@ jobs:
- uses: actions/checkout@v1
with:
submodules: recursive
- uses: eine/setup-msys2@v1
- uses: msys2/setup-msys2@v2
with:
update: true
install: mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-protobuf-c mingw-w64-x86_64-libusb git
+73 -5
View File
@@ -71,16 +71,18 @@ function (die msg)
endfunction ()
function (add_c_flag_if_supported flag var)
string(REPLACE "-" "_" supported ${flag}_c)
check_c_compiler_flag(${flag} ${supported})
set(TMP "-Werror ${flag}")
string(REGEX REPLACE "[- ]" "_" supported ${TMP}_c)
check_c_compiler_flag(${TMP} ${supported})
if(${${supported}})
set(${var} "${${var}} ${flag}" PARENT_SCOPE)
endif()
endfunction()
function (add_cxx_flag_if_supported flag var)
string(REPLACE "-" "_" supported ${flag}_cxx)
check_cxx_compiler_flag(${flag} ${supported})
set(TMP "-Werror ${flag}")
string(REGEX REPLACE "[- ]" "_" supported ${TMP}_cxx)
check_cxx_compiler_flag(${TMP} ${supported})
if(${${supported}})
set(${var} "${${var}} ${flag}" PARENT_SCOPE)
endif()
@@ -111,6 +113,66 @@ function (add_definition_if_library_exists library function header var)
endif()
endfunction()
# Function to forbid undefined symbols and also verify
# 1) Test project with all types of libraries and without undefined symbols can compile successfully
# 2) Test project with all types of libraries and undefined symbols can not compile successfully
function(forbid_undefined_symbols)
unset(TMP)
# https://www.unix.com/man-page/linux/1/ld, --no-undefined, Report unresolved symbol references from regular object files.
add_linker_flag_if_supported(-Wl,--no-undefined TMP)
# https://www.unix.com/man-page/osx/1/ld/, -undefined, Specifies how undefined symbols are to be treated.
add_linker_flag_if_supported(-Wl,-undefined,error TMP)
string(APPEND CMAKE_SHARED_LINKER_FLAGS ${TMP})
string(APPEND CMAKE_MODULE_LINKER_FLAGS ${TMP})
set(CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} PARENT_SCOPE)
set(CMAKE_MODULE_LINKER_FLAGS ${CMAKE_MODULE_LINKER_FLAGS} PARENT_SCOPE)
set(TEST_PROJECT "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeTmp/test_project")
foreach(EXPECT IN ITEMS TRUE FALSE)
file(REMOVE_RECURSE "${TEST_PROJECT}")
file(MAKE_DIRECTORY "${TEST_PROJECT}")
file(WRITE "${TEST_PROJECT}/CMakeLists.txt"
[=[
cmake_minimum_required(VERSION 3.1)
project(test)
option(EXPECT_SUCCESS "" ON)
file(WRITE "${CMAKE_SOURCE_DIR}/incorrect_source.cpp" "void undefined_symbol(); void symbol() { undefined_symbol(); }")
if (EXPECT_SUCCESS)
file(APPEND "${CMAKE_SOURCE_DIR}/incorrect_source.cpp" " void undefined_symbol() {}; ")
endif()
add_library(l0 SHARED incorrect_source.cpp)
add_library(l1 MODULE incorrect_source.cpp)
add_library(l2 STATIC incorrect_source.cpp)
add_library(l3 OBJECT incorrect_source.cpp)
]=]
)
try_compile(SUCCESS "${TEST_PROJECT}/build" "${TEST_PROJECT}" test
CMAKE_FLAGS
"-DCMAKE_SHARED_LINKER_FLAGS=${CMAKE_SHARED_LINKER_FLAGS}"
"-DCMAKE_MODULE_LINKER_FLAGS=${CMAKE_MODULE_LINKER_FLAGS}"
"-DEXPECT_SUCCESS=${EXPECT}"
)
if (NOT ${SUCCESS} STREQUAL ${EXPECT})
message(FATAL_ERROR "Undefined symbols test failure: expect(${EXPECT}), success(${SUCCESS})")
endif()
file(REMOVE_RECURSE "${TEST_PROJECT}")
endforeach()
endfunction()
if (NOT (CMAKE_SYSTEM_NAME MATCHES "kOpenBSD.*|OpenBSD.*"))
forbid_undefined_symbols()
endif()
if (MINGW)
function(export_all_symbols)
unset(TMP)
add_linker_flag_if_supported(-Wl,--export-all-symbols TMP)
string(APPEND CMAKE_SHARED_LINKER_FLAGS ${TMP})
string(APPEND CMAKE_MODULE_LINKER_FLAGS ${TMP})
set(CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} PARENT_SCOPE)
set(CMAKE_MODULE_LINKER_FLAGS ${CMAKE_MODULE_LINKER_FLAGS} PARENT_SCOPE)
endfunction()
export_all_symbols()
endif()
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
message(STATUS "Setting default build type: ${CMAKE_BUILD_TYPE}")
@@ -449,6 +511,10 @@ if(STATIC AND NOT IOS)
endif()
endif()
if (WIN32)
list(APPEND OPENSSL_LIBRARIES ws2_32 crypt32)
endif()
find_package(HIDAPI)
add_definition_if_library_exists(c memset_s "string.h" HAVE_MEMSET_S)
@@ -931,10 +997,12 @@ list(APPEND EXTRA_LIBRARIES ${CMAKE_DL_LIBS})
if (HIDAPI_FOUND OR LibUSB_COMPILE_TEST_PASSED)
if (APPLE)
if(DEPENDS)
list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework IOKit")
list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework AppKit -framework IOKit")
else()
find_library(COREFOUNDATION CoreFoundation)
find_library(APPKIT AppKit)
find_library(IOKIT IOKit)
list(APPEND EXTRA_LIBRARIES ${APPKIT})
list(APPEND EXTRA_LIBRARIES ${IOKIT})
list(APPEND EXTRA_LIBRARIES ${COREFOUNDATION})
endif()
+1 -1
View File
@@ -46,7 +46,7 @@ ARG BOOST_VERSION=1_70_0
ARG BOOST_VERSION_DOT=1.70.0
ARG BOOST_HASH=430ae8354789de4fd19ee52f3b1f739e1fba576f0aded0897c3c2bc00fb38778
RUN set -ex \
&& curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \
&& curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2 \
&& echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \
&& tar -xvf boost_${BOOST_VERSION}.tar.bz2 \
&& cd boost_${BOOST_VERSION} \
+5 -5
View File
@@ -134,8 +134,8 @@ Dates are provided in the format YYYY-MM-DD.
| 1788000 | 2019-03-09 | v10 | v0.14.0.0 | v0.14.1.2 | New PoW based on Cryptonight-R, new block weight algorithm, slightly more efficient RingCT format
| 1788720 | 2019-03-10 | v11 | v0.14.0.0 | v0.14.1.2 | forbid old RingCT transaction format
| 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.2.0 | New CLSAG transaction format
| 2210720 | 2020-10-18 | v14 | v0.17.1.1 | v0.17.2.0 | forbid old MLSAG transaction format
| 2210000 | 2020-10-17 | v13 | v0.17.0.0 | v0.17.2.3 | New CLSAG transaction format
| 2210720 | 2020-10-18 | v14 | v0.17.1.1 | v0.17.2.3 | forbid old MLSAG 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.
@@ -295,7 +295,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 tags/v0.17.2.0
git checkout tags/v0.17.2.3
```
* Build:
@@ -412,10 +412,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.17.2.0'. 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.17.2.3'. If you don't care about the version and just want binaries from master, skip this step:
```bash
git checkout v0.17.2.0
git checkout v0.17.2.3
```
* If you are on a 64-bit system, run:
+13 -6
View File
@@ -42,12 +42,19 @@
find_program(CCACHE_FOUND ccache)
if (CCACHE_FOUND)
# Try to compile a test program with ccache, in order to verify if it really works. (needed on exotic setups)
# Create a temporary file with a simple program.
set(TEMP_CPP_FILE "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeTmp/test-program.cpp")
file(WRITE "${TEMP_CPP_FILE}" "int main() { return 0; }")
# And run the found ccache on it.
execute_process(COMMAND "${CCACHE_FOUND}" "${CMAKE_CXX_COMPILER}" "${TEMP_CPP_FILE}" RESULT_VARIABLE RET)
if (${RET} EQUAL 0)
set(TEST_PROJECT "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeTmp")
file(WRITE "${TEST_PROJECT}/CMakeLists.txt" [=[
cmake_minimum_required(VERSION 3.1)
project(test)
option (CCACHE "")
file(WRITE "${CMAKE_SOURCE_DIR}/test.cpp" "int main() { return 0; }")
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE}")
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CCACHE}")
add_executable(main test.cpp)
]=])
try_compile(RET "${TEST_PROJECT}/build" "${TEST_PROJECT}" "test" CMAKE_FLAGS -DCCACHE="${CCACHE_FOUND}")
unset(TEST_PROJECT)
if (${RET})
# Success
message(STATUS "Found usable ccache: ${CCACHE_FOUND}")
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_FOUND}")
+1 -1
View File
@@ -134,7 +134,7 @@ if ( LibUSB_FOUND )
try_compile(LibUSB_COMPILE_TEST_PASSED
${CMAKE_BINARY_DIR}
"${CMAKE_SOURCE_DIR}/cmake/test-libusb-version.c"
"${CMAKE_CURRENT_LIST_DIR}/test-libusb-version.c"
CMAKE_FLAGS
"-DINCLUDE_DIRECTORIES=${LibUSB_INCLUDE_DIRS}"
"-DLINK_DIRECTORIES=${LibUSB_LIBRARIES}"
+1 -1
View File
@@ -3,7 +3,7 @@
SOURCES_PATH ?= $(BASEDIR)/sources
BASE_CACHE ?= $(BASEDIR)/built
SDK_PATH ?= $(BASEDIR)/SDKs
FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources
FALLBACK_DOWNLOAD_PATH ?= https://downloads.getmonero.org/depends-sources
BUILD = $(shell ./config.guess)
HOST ?= $(BUILD)
+1 -1
View File
@@ -32,7 +32,7 @@ endef
define fetch_file
( test -f $$($(1)_source_dir)/$(4) || \
( $(call fetch_file_inner,$(1),$(2),$(3),$(4),$(5)) || \
$(call fetch_file_inner,$(1),$(FALLBACK_DOWNLOAD_PATH),$(3),$(4),$(5))))
$(call fetch_file_inner,$(1),$(FALLBACK_DOWNLOAD_PATH),$(4),$(4),$(5))))
endef
define int_get_build_recipe_hash
+1 -1
View File
@@ -1,6 +1,6 @@
package=boost
$(package)_version=1_64_0
$(package)_download_path=https://dl.bintray.com/boostorg/release/1.64.0/source/
$(package)_download_path=https://downloads.sourceforge.net/project/boost/boost/1.64.0/
$(package)_file_name=$(package)_$($(package)_version).tar.bz2
$(package)_sha256_hash=7bcc5caace97baa948931d712ea5f37038dbb1c5d89b43ad4def4ed7cb683332
$(package)_dependencies=libiconv
+2 -1
View File
@@ -1,7 +1,8 @@
package=eudev
$(package)_version=v3.2.6
$(package)_download_path=https://github.com/gentoo/eudev/archive/
$(package)_file_name=$($(package)_version).tar.gz
$(package)_download_file=$($(package)_version).tar.gz
$(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_sha256_hash=a96ecb8637667897b8bd4dee4c22c7c5f08b327be45186e912ce6bc768385852
define $(package)_set_vars
+2 -1
View File
@@ -1,7 +1,8 @@
package=gtest
$(package)_version=1.8.1
$(package)_download_path=https://github.com/google/googletest/archive/
$(package)_file_name=release-$($(package)_version).tar.gz
$(package)_download_file=release-$($(package)_version).tar.gz
$(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_sha256_hash=9bf1fe5182a604b4135edc1a425ae356c9ad15e9b23f9f12a02e80184c3a249c
$(package)_cxxflags=-std=c++11
$(package)_cxxflags_linux=-fPIC
+2 -1
View File
@@ -1,7 +1,8 @@
package=native_cctools
$(package)_version=807d6fd1be5d2224872e381870c0a75387fe05e6
$(package)_download_path=https://github.com/theuni/cctools-port/archive
$(package)_file_name=$($(package)_version).tar.gz
$(package)_download_file=$($(package)_version).tar.gz
$(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_sha256_hash=a09c9ba4684670a0375e42d9d67e7f12c1f62581a27f28f7c825d6d7032ccc6a
$(package)_build_subdir=cctools
$(package)_clang_version=3.7.1
@@ -236,6 +236,7 @@ namespace net_utils
virtual address_type get_type_id() const = 0;
virtual zone get_zone() const = 0;
virtual bool is_blockable() const = 0;
virtual std::uint16_t port() const = 0;
};
template<typename T>
@@ -266,6 +267,7 @@ namespace net_utils
virtual address_type get_type_id() const override { return value.get_type_id(); }
virtual zone get_zone() const override { return value.get_zone(); }
virtual bool is_blockable() const override { return value.is_blockable(); }
virtual std::uint16_t port() const override { return value.port(); }
};
std::shared_ptr<interface> self;
@@ -312,6 +314,7 @@ namespace net_utils
address_type get_type_id() const { return self ? self->get_type_id() : address_type::invalid; }
zone get_zone() const { return self ? self->get_zone() : zone::invalid; }
bool is_blockable() const { return self ? self->is_blockable() : false; }
std::uint16_t port() const { return self ? self->port() : 0; }
template<typename Type> const Type &as() const { return as_mutable<const Type>(); }
BEGIN_KV_SERIALIZE_MAP()
@@ -40,6 +40,8 @@
#include "span.h"
#include "int-util.h"
#include <boost/mpl/contains.hpp>
namespace epee
{
namespace serialization
+11 -2
View File
@@ -27,7 +27,7 @@
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
add_library(epee STATIC byte_slice.cpp byte_stream.cpp hex.cpp abstract_http_client.cpp http_auth.cpp mlog.cpp net_helper.cpp net_utils_base.cpp string_tools.cpp
add_library(epee byte_slice.cpp byte_stream.cpp hex.cpp abstract_http_client.cpp http_auth.cpp mlog.cpp net_helper.cpp net_utils_base.cpp string_tools.cpp
wipeable_string.cpp levin_base.cpp memwipe.c connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp net_ssl.cpp
int-util.cpp)
@@ -60,14 +60,23 @@ target_link_libraries(epee
${Boost_CHRONO_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
${Boost_THREAD_LIBRARY}
PRIVATE
${Boost_REGEX_LIBRARY}
${Boost_SYSTEM_LIBRARY}
${OPENSSL_LIBRARIES}
PRIVATE
${EXTRA_LIBRARIES})
if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
target_link_libraries(epee_readline
PUBLIC
easylogging
${Boost_SYSTEM_LIBRARY}
PRIVATE
${GNU_READLINE_LIBRARY})
endif()
target_include_directories(epee
PUBLIC
"${EPEE_INCLUDE_DIR_BASE}"
"${OPENSSL_INCLUDE_DIR}")
-4
View File
@@ -94,10 +94,6 @@ def build():
os.chdir('builder')
os.makedirs('inputs', exist_ok=True)
subprocess.check_call(['wget', '-N', '-P', 'inputs', 'https://downloads.sourceforge.net/project/osslsigncode/osslsigncode/osslsigncode-1.7.1.tar.gz'])
subprocess.check_call(['wget', '-N', '-P', 'inputs', 'https://bitcoincore.org/cfields/osslsigncode-Backports-to-1.7.1.patch'])
subprocess.check_output(["echo 'a8c4e9cafba922f89de0df1f2152e7be286aba73f78505169bc351a7938dd911 inputs/osslsigncode-Backports-to-1.7.1.patch' | sha256sum -c"], shell=True)
subprocess.check_output(["echo 'f9a8cdb38b9c309326764ebc937cba1523a3a751a7ab05df3ecc99d18ae466c9 inputs/osslsigncode-1.7.1.tar.gz' | sha256sum -c"], shell=True)
subprocess.check_call(['make', '-C', 'inputs/monero/contrib/depends', 'download', 'SOURCES_PATH=' + os.getcwd() + '/cache/common'])
rebuild()
+3 -3
View File
@@ -4882,9 +4882,6 @@ mdb_env_open2(MDB_env *env, int prev)
#endif
env->me_maxpg = env->me_mapsize / env->me_psize;
if (env->me_txns)
env->me_txns->mti_txnid = meta.mm_txnid;
#if MDB_DEBUG
{
MDB_meta *meta = mdb_env_pick_meta(env);
@@ -4984,6 +4981,9 @@ static int ESECT
mdb_env_share_locks(MDB_env *env, int *excl)
{
int rc = 0;
MDB_meta *meta = mdb_env_pick_meta(env);
env->me_txns->mti_txnid = meta->mm_txnid;
#ifdef _WIN32
{
+21 -9
View File
@@ -28,20 +28,32 @@
set(GENERATED_SOURCES "")
set(GENERATOR "${CMAKE_CURRENT_BINARY_DIR}/blocks_generator.cmake")
file(GENERATE OUTPUT ${GENERATOR} CONTENT [=[
file(READ "${INPUT_DAT_FILE}" DATA HEX)
string(REGEX REPLACE "[0-9a-fA-F][0-9a-fA-F]" "0x\\0," DATA "${DATA}")
file(WRITE "${OUTPUT_C_SOURCE}" "
#include <stddef.h>
const unsigned char ${BLOB_NAME}[]={
${DATA}
};
const size_t ${BLOB_NAME}_len = sizeof(${BLOB_NAME});
"
)
]=])
foreach(BLOB_NAME checkpoints testnet_blocks stagenet_blocks)
set(OUTPUT_C_SOURCE "generated_${BLOB_NAME}.c")
list(APPEND GENERATED_SOURCES ${OUTPUT_C_SOURCE})
set(INPUT_DAT_FILE "${BLOB_NAME}.dat")
add_custom_command(
OUTPUT ${OUTPUT_C_SOURCE}
MAIN_DEPENDENCY ${INPUT_DAT_FILE}
COMMAND
cd ${CMAKE_CURRENT_BINARY_DIR} &&
echo "'#include\t<stddef.h>'" > ${OUTPUT_C_SOURCE} &&
echo "'const\tunsigned\tchar\t${BLOB_NAME}[]={'" >> ${OUTPUT_C_SOURCE} &&
od -v -An -tx1 ${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_DAT_FILE} | sed -e "'s/[0-9a-fA-F]\\{1,\\}/0x&,/g'" -e "'$$s/.$$//'" >> ${OUTPUT_C_SOURCE} &&
echo "'};'" >> ${OUTPUT_C_SOURCE} &&
echo "'const\tsize_t\t${BLOB_NAME}_len\t=\tsizeof(${BLOB_NAME});'" >> ${OUTPUT_C_SOURCE}
OUTPUT ${OUTPUT_C_SOURCE}
MAIN_DEPENDENCY ${INPUT_DAT_FILE}
DEPENDS ${GENERATOR}
COMMAND ${CMAKE_COMMAND}
"-DINPUT_DAT_FILE=${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_DAT_FILE}"
"-DBLOB_NAME=${BLOB_NAME}"
"-DOUTPUT_C_SOURCE=${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_C_SOURCE}"
-P "${GENERATOR}"
)
endforeach()
Binary file not shown.
+1
View File
@@ -247,6 +247,7 @@ namespace cryptonote
ADD_CHECKPOINT2(2257500, "99643c32f27b157c6952a67af7dbe07ca819e71df386fa9379a344686d2950cf", "0x11c2f448d4f8830");
ADD_CHECKPOINT2(2265000, "727a6228a71f5b35c899553ee19d60bfc10c126a009ffd633afb30666e8edbe6", "0x121a33e656ecad4");
ADD_CHECKPOINT2(2325000, "f61261994b368700f0cbbfb4477433fa36a3c7537908ab2d1a06ac2987cc8b01", "0x154bceeffaff847");
ADD_CHECKPOINT2(2430000, "5f7f4273eb6be024df3c4311a8d28482220a253190efa1719f35b7782587740c", "0x1c3f14ba9b0bebc");
return true;
}
+1
View File
@@ -34,6 +34,7 @@
#include "file_io_utils.h"
#include "common/i18n.h"
#include "translation_files.h"
#include <algorithm>
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "i18n"
+6 -2
View File
@@ -1355,8 +1355,12 @@ std::string get_nix_version_display_string()
100743, 92152, 57565, 22533, 37564, 21823, 19980, 18277, 18402, 14344,
12142, 15842, 13677, 17631, 18294, 22270, 41422, 39296, 36688, 33512,
33831, 27582, 22276, 27516, 27317, 25505, 24426, 20566, 23045, 26766,
28185, 26169, 27011,
28642 // Blocks 1,990,000 to 1,999,999 in December 2019
28185, 26169, 27011, 28642, 34994, 34442, 30682, 34357, 31640, 41167,
41301, 48616, 51075, 55061, 49909, 44606, 47091, 53828, 42520, 39023,
55245, 56145, 51119, 60398, 71821, 48142, 60310, 56041, 54176, 66220,
56336, 55248, 56656, 63305, 54029, 77136, 71902, 71618, 83587, 81068,
69062, 54848, 53681, 53555,
50616 // Blocks 2,400,000 to 2,409,999 in July 2021
};
const uint64_t block_range_size = 10000;
+9
View File
@@ -36,6 +36,14 @@ if(APPLE)
endif()
endif()
monero_add_library(cryptonote_format_utils_basic
cryptonote_format_utils_basic.cpp
)
target_link_libraries(cryptonote_format_utils_basic
PUBLIC
cncrypto
)
set(cryptonote_basic_sources
account.cpp
connection_context.cpp
@@ -72,6 +80,7 @@ target_link_libraries(cryptonote_basic
common
cncrypto
checkpoints
cryptonote_format_utils_basic
device
${Boost_DATE_TIME_LIBRARY}
${Boost_PROGRAM_OPTIONS_LIBRARY}
@@ -139,22 +139,6 @@ namespace cryptonote
return h;
}
//---------------------------------------------------------------
void get_transaction_prefix_hash(const transaction_prefix& tx, crypto::hash& h)
{
std::ostringstream s;
binary_archive<true> a(s);
::serialization::serialize(a, const_cast<transaction_prefix&>(tx));
crypto::cn_fast_hash(s.str().data(), s.str().size(), h);
}
//---------------------------------------------------------------
crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx)
{
crypto::hash h = null_hash;
get_transaction_prefix_hash(tx, h);
return h;
}
//---------------------------------------------------------------
bool expand_transaction_1(transaction &tx, bool base_only)
{
if (tx.version >= 2 && !is_coinbase(tx))
@@ -0,0 +1,49 @@
// Copyright (c) 2014-2021, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
#include "cryptonote_format_utils.h"
namespace cryptonote
{
void get_transaction_prefix_hash(const transaction_prefix& tx, crypto::hash& h)
{
std::ostringstream s;
binary_archive<true> a(s);
::serialization::serialize(a, const_cast<transaction_prefix&>(tx));
crypto::cn_fast_hash(s.str().data(), s.str().size(), h);
}
crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx)
{
crypto::hash h = crypto::null_hash;
get_transaction_prefix_hash(tx, h);
return h;
}
}
+1 -1
View File
@@ -5390,7 +5390,7 @@ void Blockchain::cancel()
}
#if defined(PER_BLOCK_CHECKPOINT)
static const char expected_block_hashes_hash[] = "b198c2514bed71ca0a43cba6590090068daf6d207b351d8a4c7d0f0f791c095f";
static const char expected_block_hashes_hash[] = "ff99bc76e59e0d6268e2d8ed54a2206d828de643fcb13be8d296611fc051a540";
void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback& get_checkpoints)
{
if (get_checkpoints == nullptr || !m_fast_sync)
+1
View File
@@ -71,6 +71,7 @@ target_link_libraries(device
PUBLIC
${HIDAPI_LIBRARIES}
cncrypto
cryptonote_format_utils_basic
ringct_basic
wallet-crypto
${OPENSSL_CRYPTO_LIBRARIES}
+14 -5
View File
@@ -529,9 +529,7 @@ namespace hw {
}
bool device_ledger::init(void) {
#ifdef DEBUG_HWDEVICE
this->controle_device = &hw::get_device("default");
#endif
this->release();
hw_device.init();
MDEBUG( "Device "<<this->id <<" HIDUSB inited");
@@ -697,7 +695,6 @@ namespace hw {
/* ======================================================================= */
bool device_ledger::derive_subaddress_public_key(const crypto::public_key &pub, const crypto::key_derivation &derivation, const std::size_t output_index, crypto::public_key &derived_pub){
AUTO_LOCK_CMD();
#ifdef DEBUG_HWDEVICE
const crypto::public_key pub_x = pub;
crypto::key_derivation derivation_x;
@@ -721,7 +718,7 @@ namespace hw {
MDEBUG( "derive_subaddress_public_key : PARSE mode with known viewkey");
crypto::derive_subaddress_public_key(pub, derivation, output_index,derived_pub);
} else {
AUTO_LOCK_CMD();
int offset = set_command_header_noopt(INS_DERIVE_SUBADDRESS_PUBLIC_KEY);
//pub
memmove(this->buffer_send+offset, pub.data, 32);
@@ -750,6 +747,12 @@ namespace hw {
}
crypto::public_key device_ledger::get_subaddress_spend_public_key(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) {
if (has_view_key) {
cryptonote::account_keys keys_{keys};
keys_.m_view_secret_key = this->viewkey;
return this->controle_device->get_subaddress_spend_public_key(keys_, index);
}
AUTO_LOCK_CMD();
crypto::public_key D;
@@ -801,6 +804,12 @@ namespace hw {
}
cryptonote::account_public_address device_ledger::get_subaddress(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) {
if (has_view_key) {
cryptonote::account_keys keys_{keys};
keys_.m_view_secret_key = this->viewkey;
return this->controle_device->get_subaddress(keys_, index);
}
AUTO_LOCK_CMD();
cryptonote::account_public_address address;
@@ -1049,7 +1058,6 @@ namespace hw {
}
bool device_ledger::generate_key_derivation(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_derivation &derivation) {
AUTO_LOCK_CMD();
bool r = false;
#ifdef DEBUG_HWDEVICE
@@ -1070,6 +1078,7 @@ namespace hw {
assert(is_fake_view_key(sec));
r = crypto::generate_key_derivation(pub, this->viewkey, derivation);
} else {
AUTO_LOCK_CMD();
int offset = set_command_header_noopt(INS_GEN_KEY_DERIVATION);
//pub
memmove(this->buffer_send+offset, pub.data, 32);
+3 -6
View File
@@ -44,8 +44,8 @@ namespace hw {
/* Minimal supported version */
#define MINIMAL_APP_VERSION_MAJOR 1
#define MINIMAL_APP_VERSION_MINOR 6
#define MINIMAL_APP_VERSION_MICRO 0
#define MINIMAL_APP_VERSION_MINOR 7
#define MINIMAL_APP_VERSION_MICRO 6
#define VERSION(M,m,u) ((M)<<16|(m)<<8|(u))
#define VERSION_MAJOR(v) (((v)>>16)&0xFF)
@@ -192,11 +192,8 @@ namespace hw {
// To speed up blockchain parsing the view key maybe handle here.
crypto::secret_key viewkey;
bool has_view_key;
//extra debug
#ifdef DEBUG_HWDEVICE
device *controle_device;
#endif
public:
device_ledger();
+1 -1
View File
@@ -510,7 +510,7 @@ namespace trezor {
const auto data_cleaner = epee::misc_utils::create_scope_leave_handler([&]() {
if (m.has_passphrase())
memwipe(&(m.mutable_passphrase())[0], m.mutable_passphrase()->size());
memwipe(&(*m.mutable_passphrase())[0], m.mutable_passphrase()->size());
});
resp = call_raw(&m);
+18 -3
View File
@@ -269,9 +269,17 @@ namespace nodetool
peerlist_entry pe{};
pe.adr = addr;
zone.second.m_peerlist.remove_from_peer_white(pe);
zone.second.m_peerlist.remove_from_peer_gray(pe);
zone.second.m_peerlist.remove_from_peer_anchor(addr);
if (addr.port() == 0)
{
zone.second.m_peerlist.evict_host_from_peerlist(true, pe);
zone.second.m_peerlist.evict_host_from_peerlist(false, pe);
}
else
{
zone.second.m_peerlist.remove_from_peer_white(pe);
zone.second.m_peerlist.remove_from_peer_gray(pe);
zone.second.m_peerlist.remove_from_peer_anchor(addr);
}
for (const auto &c: conns)
zone.second.m_net_server.get_config_object().close(c);
@@ -331,6 +339,13 @@ namespace nodetool
for (const auto &c: conns)
zone.second.m_net_server.get_config_object().close(c);
for (int i = 0; i < 2; ++i)
zone.second.m_peerlist.filter(i == 0, [&subnet](const peerlist_entry &pe){
if (pe.adr.get_type_id() != epee::net_utils::ipv4_network_address::get_type_id())
return false;
return subnet.matches(pe.adr.as<const epee::net_utils::ipv4_network_address>());
});
conns.clear();
}
+2 -10
View File
@@ -289,17 +289,9 @@ namespace nodetool
copy_peers(peers.anchor, m_peers_anchor.get<by_addr>());
}
void peerlist_manager::evict_host_from_white_peerlist(const peerlist_entry& pr)
void peerlist_manager::evict_host_from_peerlist(bool use_white, const peerlist_entry& pr)
{
peers_indexed::index<by_time>::type& sorted_index=m_peers_white.get<by_time>();
auto i = sorted_index.begin();
while (i != sorted_index.end())
{
if (i->adr.is_same_host(pr.adr))
i = sorted_index.erase(i);
else
++i;
}
filter(use_white, [&pr](const peerlist_entry& pe){ return pe.adr.is_same_host(pr.adr); });
}
}
+24 -2
View File
@@ -109,7 +109,7 @@ namespace nodetool
bool get_white_peer_by_index(peerlist_entry& p, size_t i);
bool get_gray_peer_by_index(peerlist_entry& p, size_t i);
template<typename F> bool foreach(bool white, const F &f);
void evict_host_from_white_peerlist(const peerlist_entry& pr);
void evict_host_from_peerlist(bool white, const peerlist_entry& pr);
bool append_with_peer_white(const peerlist_entry& pr);
bool append_with_peer_gray(const peerlist_entry& pr);
bool append_with_peer_anchor(const anchor_peerlist_entry& ple);
@@ -120,6 +120,7 @@ namespace nodetool
bool get_and_empty_anchor_peerlist(std::vector<anchor_peerlist_entry>& apl);
bool remove_from_peer_anchor(const epee::net_utils::network_address& addr);
bool remove_from_peer_white(const peerlist_entry& pe);
template<typename F> size_t filter(bool white, const F &f); // f returns true: drop, false: keep
private:
struct by_time{};
@@ -346,7 +347,7 @@ namespace nodetool
if(by_addr_it_wt == m_peers_white.get<by_addr>().end())
{
//put new record into white list
evict_host_from_white_peerlist(ple);
evict_host_from_peerlist(true, ple);
m_peers_white.insert(ple);
trim_white_peerlist();
}else
@@ -519,5 +520,26 @@ namespace nodetool
CATCH_ENTRY_L0("peerlist_manager::remove_from_peer_anchor()", false);
}
//--------------------------------------------------------------------------------------------------
template<typename F> size_t peerlist_manager::filter(bool white, const F &f)
{
size_t filtered = 0;
TRY_ENTRY();
CRITICAL_REGION_LOCAL(m_peerlist_lock);
peers_indexed::index<by_addr>::type& sorted_index = white ? m_peers_gray.get<by_addr>() : m_peers_white.get<by_addr>();
auto i = sorted_index.begin();
while (i != sorted_index.end())
{
if (f(*i))
{
i = sorted_index.erase(i);
++filtered;
}
else
++i;
}
CATCH_ENTRY_L0("peerlist_manager::filter()", filtered);
return filtered;
}
//--------------------------------------------------------------------------------------------------
}
+12 -6
View File
@@ -1091,9 +1091,12 @@ void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const rct::rctSig&
};
INSERT_INTO_JSON_OBJECT(dest, type, sig.type);
INSERT_INTO_JSON_OBJECT(dest, encrypted, sig.ecdhInfo);
INSERT_INTO_JSON_OBJECT(dest, commitments, transform(sig.outPk, just_mask));
INSERT_INTO_JSON_OBJECT(dest, fee, sig.txnFee);
if (sig.type != rct::RCTTypeNull)
{
INSERT_INTO_JSON_OBJECT(dest, encrypted, sig.ecdhInfo);
INSERT_INTO_JSON_OBJECT(dest, commitments, transform(sig.outPk, just_mask));
INSERT_INTO_JSON_OBJECT(dest, fee, sig.txnFee);
}
// prunable
if (!sig.p.bulletproofs.empty() || !sig.p.rangeSigs.empty() || !sig.p.MGs.empty() || !sig.get_pseudo_outs().empty())
@@ -1122,9 +1125,12 @@ void fromJsonValue(const rapidjson::Value& val, rct::rctSig& sig)
}
GET_FROM_JSON_OBJECT(val, sig.type, type);
GET_FROM_JSON_OBJECT(val, sig.ecdhInfo, encrypted);
GET_FROM_JSON_OBJECT(val, sig.outPk, commitments);
GET_FROM_JSON_OBJECT(val, sig.txnFee, fee);
if (sig.type != rct::RCTTypeNull)
{
GET_FROM_JSON_OBJECT(val, sig.ecdhInfo, encrypted);
GET_FROM_JSON_OBJECT(val, sig.outPk, commitments);
GET_FROM_JSON_OBJECT(val, sig.txnFee, fee);
}
// prunable
const auto prunable = val.FindMember("prunable");
+1 -1
View File
@@ -5800,7 +5800,7 @@ bool simple_wallet::refresh_main(uint64_t start_height, enum ResetType reset, bo
if (reset != ResetNone)
{
if (reset == ResetSoftKeepKI)
height_pre = m_wallet->hash_m_transfers(-1, transfer_hash_pre);
height_pre = m_wallet->hash_m_transfers(boost::none, transfer_hash_pre);
m_wallet->rescan_blockchain(reset == ResetHard, false, reset == ResetSoftKeepKI);
}
+1 -1
View File
@@ -1,5 +1,5 @@
#define DEF_MONERO_VERSION_TAG "@VERSIONTAG@"
#define DEF_MONERO_VERSION "0.17.2.0"
#define DEF_MONERO_VERSION "0.17.2.3"
#define DEF_MONERO_RELEASE_NAME "Oxygen Orion"
#define DEF_MONERO_VERSION_FULL DEF_MONERO_VERSION "-" DEF_MONERO_VERSION_TAG
#define DEF_MONERO_VERSION_IS_RELEASE @VERSION_IS_RELEASE@
+3
View File
@@ -71,10 +71,13 @@ target_link_libraries(wallet_api
mnemonics
${LMDB_LIBRARY}
${Boost_CHRONO_LIBRARY}
${Boost_LOCALE_LIBRARY}
${ICU_LIBRARIES}
${Boost_SERIALIZATION_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY}
${Boost_THREAD_LIBRARY}
${CMAKE_THREAD_LIBS_INIT}
${Boost_REGEX_LIBRARY}
PRIVATE
${EXTRA_LIBRARIES})
+19
View File
@@ -70,6 +70,25 @@ bool AddressBookImpl::addRow(const std::string &dst_addr , const std::string &pa
return r;
}
bool AddressBookImpl::setDescription(std::size_t index, const std::string &description)
{
clearStatus();
const auto ab = m_wallet->m_wallet->get_address_book();
if (index >= ab.size()){
return false;
}
tools::wallet2::address_book_row entry = ab[index];
entry.m_description = description;
bool r = m_wallet->m_wallet->set_address_book_row(index, entry.m_address, NULL, entry.m_description, entry.m_is_subaddress);
if (r)
refresh();
else
m_errorCode = General_Error;
return r;
}
void AddressBookImpl::refresh()
{
LOG_PRINT_L2("Refreshing addressbook");
+1
View File
@@ -45,6 +45,7 @@ public:
void refresh() override;
std::vector<AddressBookRow*> getAll() const override;
bool addRow(const std::string &dst_addr , const std::string &payment_id, const std::string &description) override;
bool setDescription(std::size_t index, const std::string &description) override;
bool deleteRow(std::size_t rowId) override;
// Error codes. See AddressBook:ErrorCode enum in wallet2_api.h
+22
View File
@@ -92,6 +92,17 @@ std::vector<TransactionInfo *> TransactionHistoryImpl::getAll() const
return m_history;
}
void TransactionHistoryImpl::setTxNote(const std::string &txid, const std::string &note)
{
cryptonote::blobdata txid_data;
if(!epee::string_tools::parse_hexstr_to_binbuff(txid, txid_data) || txid_data.size() != sizeof(crypto::hash))
return;
const crypto::hash htxid = *reinterpret_cast<const crypto::hash*>(txid_data.data());
m_wallet->m_wallet->set_tx_note(htxid, note);
refresh();
}
void TransactionHistoryImpl::refresh()
{
// multithreaded access:
@@ -126,10 +137,13 @@ void TransactionHistoryImpl::refresh()
payment_id = payment_id.substr(0,16);
TransactionInfoImpl * ti = new TransactionInfoImpl();
ti->m_paymentid = payment_id;
ti->m_coinbase = pd.m_coinbase;
ti->m_amount = pd.m_amount;
ti->m_fee = pd.m_fee;
ti->m_direction = TransactionInfo::Direction_In;
ti->m_hash = string_tools::pod_to_hex(pd.m_tx_hash);
ti->m_blockheight = pd.m_block_height;
ti->m_description = m_wallet->m_wallet->get_tx_note(pd.m_tx_hash);
ti->m_subaddrIndex = { pd.m_subaddr_index.minor };
ti->m_subaddrAccount = pd.m_subaddr_index.major;
ti->m_label = m_wallet->m_wallet->get_subaddress_label(pd.m_subaddr_index);
@@ -173,6 +187,7 @@ void TransactionHistoryImpl::refresh()
ti->m_direction = TransactionInfo::Direction_Out;
ti->m_hash = string_tools::pod_to_hex(hash);
ti->m_blockheight = pd.m_block_height;
ti->m_description = m_wallet->m_wallet->get_tx_note(hash);
ti->m_subaddrIndex = pd.m_subaddr_indices;
ti->m_subaddrAccount = pd.m_subaddr_account;
ti->m_label = pd.m_subaddr_indices.size() == 1 ? m_wallet->m_wallet->get_subaddress_label({pd.m_subaddr_account, *pd.m_subaddr_indices.begin()}) : "";
@@ -183,6 +198,7 @@ void TransactionHistoryImpl::refresh()
for (const auto &d: pd.m_dests) {
ti->m_transfers.push_back({d.amount, d.address(m_wallet->m_wallet->nettype(), pd.m_payment_id)});
}
m_history.push_back(ti);
}
@@ -207,11 +223,16 @@ void TransactionHistoryImpl::refresh()
ti->m_failed = is_failed;
ti->m_pending = true;
ti->m_hash = string_tools::pod_to_hex(hash);
ti->m_description = m_wallet->m_wallet->get_tx_note(hash);
ti->m_subaddrIndex = pd.m_subaddr_indices;
ti->m_subaddrAccount = pd.m_subaddr_account;
ti->m_label = pd.m_subaddr_indices.size() == 1 ? m_wallet->m_wallet->get_subaddress_label({pd.m_subaddr_account, *pd.m_subaddr_indices.begin()}) : "";
ti->m_timestamp = pd.m_timestamp;
ti->m_confirmations = 0;
for (const auto &d : pd.m_dests)
{
ti->m_transfers.push_back({d.amount, d.address(m_wallet->m_wallet->nettype(), pd.m_payment_id)});
}
m_history.push_back(ti);
}
@@ -230,6 +251,7 @@ void TransactionHistoryImpl::refresh()
ti->m_direction = TransactionInfo::Direction_In;
ti->m_hash = string_tools::pod_to_hex(pd.m_tx_hash);
ti->m_blockheight = pd.m_block_height;
ti->m_description = m_wallet->m_wallet->get_tx_note(pd.m_tx_hash);
ti->m_pending = true;
ti->m_subaddrIndex = { pd.m_subaddr_index.minor };
ti->m_subaddrAccount = pd.m_subaddr_index.major;
+1
View File
@@ -45,6 +45,7 @@ public:
virtual TransactionInfo * transaction(const std::string &id) const;
virtual std::vector<TransactionInfo*> getAll() const;
virtual void refresh();
virtual void setTxNote(const std::string &txid, const std::string &note);
private:
+11
View File
@@ -45,6 +45,7 @@ TransactionInfoImpl::TransactionInfoImpl()
: m_direction(Direction_Out)
, m_pending(false)
, m_failed(false)
, m_coinbase(false)
, m_amount(0)
, m_fee(0)
, m_blockheight(0)
@@ -77,6 +78,11 @@ bool TransactionInfoImpl::isFailed() const
return m_failed;
}
bool TransactionInfoImpl::isCoinbase() const
{
return m_coinbase;
}
uint64_t TransactionInfoImpl::amount() const
{
return m_amount;
@@ -92,6 +98,11 @@ uint64_t TransactionInfoImpl::blockHeight() const
return m_blockheight;
}
std::string TransactionInfoImpl::description() const
{
return m_description;
}
std::set<uint32_t> TransactionInfoImpl::subaddrIndex() const
{
return m_subaddrIndex;
+4
View File
@@ -46,10 +46,12 @@ public:
//! true if hold
virtual bool isPending() const override;
virtual bool isFailed() const override;
virtual bool isCoinbase() const override;
virtual uint64_t amount() const override;
//! always 0 for incoming txes
virtual uint64_t fee() const override;
virtual uint64_t blockHeight() const override;
virtual std::string description() const override;
virtual std::set<uint32_t> subaddrIndex() const override;
virtual uint32_t subaddrAccount() const override;
virtual std::string label() const override;
@@ -65,9 +67,11 @@ private:
int m_direction;
bool m_pending;
bool m_failed;
bool m_coinbase;
uint64_t m_amount;
uint64_t m_fee;
uint64_t m_blockheight;
std::string m_description;
std::set<uint32_t> m_subaddrIndex; // always unique index for incoming transfers; can be multiple indices for outgoing transfers
uint32_t m_subaddrAccount;
std::string m_label;
+85 -4
View File
@@ -791,11 +791,11 @@ bool WalletImpl::close(bool store)
return result;
}
std::string WalletImpl::seed() const
std::string WalletImpl::seed(const std::string& seed_offset) const
{
epee::wipeable_string seed;
if (m_wallet)
m_wallet->get_seed(seed);
m_wallet->get_seed(seed, seed_offset);
return std::string(seed.data(), seed.size()); // TODO
}
@@ -839,6 +839,11 @@ bool WalletImpl::setPassword(const std::string &password)
return status() == Status_Ok;
}
const std::string& WalletImpl::getPassword() const
{
return m_password;
}
bool WalletImpl::setDevicePin(const std::string &pin)
{
clearStatus();
@@ -1168,7 +1173,7 @@ bool WalletImpl::submitTransaction(const string &fileName) {
return true;
}
bool WalletImpl::exportKeyImages(const string &filename)
bool WalletImpl::exportKeyImages(const string &filename, bool all)
{
if (m_wallet->watch_only())
{
@@ -1178,7 +1183,7 @@ bool WalletImpl::exportKeyImages(const string &filename)
try
{
if (!m_wallet->export_key_images(filename))
if (!m_wallet->export_key_images(filename, all))
{
setStatusError(tr("failed to save file ") + filename);
return false;
@@ -1216,6 +1221,68 @@ bool WalletImpl::importKeyImages(const string &filename)
return true;
}
bool WalletImpl::exportOutputs(const string &filename, bool all)
{
if (m_wallet->key_on_device())
{
setStatusError(string(tr("Not supported on HW wallets.")) + filename);
return false;
}
try
{
std::string data = m_wallet->export_outputs_to_str(all);
bool r = m_wallet->save_to_file(filename, data);
if (!r)
{
LOG_ERROR("Failed to save file " << filename);
setStatusError(string(tr("Failed to save file: ")) + filename);
return false;
}
}
catch (const std::exception &e)
{
LOG_ERROR("Error exporting outputs: " << e.what());
setStatusError(string(tr("Error exporting outputs: ")) + e.what());
return false;
}
LOG_PRINT_L2("Outputs exported to " << filename);
return true;
}
bool WalletImpl::importOutputs(const string &filename)
{
if (m_wallet->key_on_device())
{
setStatusError(string(tr("Not supported on HW wallets.")) + filename);
return false;
}
std::string data;
bool r = m_wallet->load_from_file(filename, data);
if (!r)
{
LOG_ERROR("Failed to read file: " << filename);
setStatusError(string(tr("Failed to read file: ")) + filename);
return false;
}
try
{
size_t n_outputs = m_wallet->import_outputs_from_str(data);
LOG_PRINT_L2(std::to_string(n_outputs) << " outputs imported");
}
catch (const std::exception &e)
{
LOG_ERROR("Failed to import outputs: " << e.what());
setStatusError(string(tr("Failed to import outputs: ")) + e.what());
return false;
}
return true;
}
void WalletImpl::addSubaddressAccount(const std::string& label)
{
m_wallet->add_subaddress_account(label);
@@ -2104,6 +2171,11 @@ bool WalletImpl::watchOnly() const
return m_wallet->watch_only();
}
bool WalletImpl::isDeterministic() const
{
return m_wallet->is_deterministic();
}
void WalletImpl::clearStatus() const
{
boost::lock_guard<boost::mutex> l(m_statusMutex);
@@ -2283,6 +2355,11 @@ bool WalletImpl::parse_uri(const std::string &uri, std::string &address, std::st
return m_wallet->parse_uri(uri, address, payment_id, amount, tx_description, recipient_name, unknown_parameters, error);
}
std::string WalletImpl::make_uri(const std::string &address, const std::string &payment_id, uint64_t amount, const std::string &tx_description, const std::string &recipient_name, std::string &error) const
{
return m_wallet->make_uri(address, payment_id, amount, tx_description, recipient_name, error);
}
std::string WalletImpl::getDefaultDataDir() const
{
return tools::get_default_data_dir();
@@ -2305,6 +2382,10 @@ bool WalletImpl::rescanSpent()
return true;
}
void WalletImpl::setOffline(bool offline)
{
m_wallet->set_offline(offline);
}
void WalletImpl::hardForkInfo(uint8_t &version, uint64_t &earliest_height) const
{
+9 -2
View File
@@ -81,7 +81,7 @@ public:
const std::string &device_name);
Device getDeviceType() const override;
bool close(bool store = true);
std::string seed() const override;
std::string seed(const std::string& seed_offset = "") const override;
std::string getSeedLanguage() const override;
void setSeedLanguage(const std::string &arg) override;
// void setListener(Listener *) {}
@@ -89,6 +89,7 @@ public:
std::string errorString() const override;
void statusWithErrorString(int& status, std::string& errorString) const override;
bool setPassword(const std::string &password) override;
const std::string& getPassword() const override;
bool setDevicePin(const std::string &password) override;
bool setDevicePassphrase(const std::string &password) override;
std::string address(uint32_t accountIndex = 0, uint32_t addressIndex = 0) const override;
@@ -129,6 +130,7 @@ public:
void setRecoveringFromDevice(bool recoveringFromDevice) override;
void setSubaddressLookahead(uint32_t major, uint32_t minor) override;
bool watchOnly() const override;
bool isDeterministic() const override;
bool rescanSpent() override;
NetworkType nettype() const override {return static_cast<NetworkType>(m_wallet->nettype());}
void hardForkInfo(uint8_t &version, uint64_t &earliest_height) const override;
@@ -164,8 +166,10 @@ public:
virtual PendingTransaction * createSweepUnmixableTransaction() override;
bool submitTransaction(const std::string &fileName) override;
virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) override;
bool exportKeyImages(const std::string &filename) override;
bool exportKeyImages(const std::string &filename, bool all = false) override;
bool importKeyImages(const std::string &filename) override;
bool exportOutputs(const std::string &filename, bool all = false) override;
bool importOutputs(const std::string &filename) override;
virtual void disposeTransaction(PendingTransaction * t) override;
virtual uint64_t estimateTransactionFee(const std::vector<std::pair<std::string, uint64_t>> &destinations,
@@ -181,6 +185,8 @@ public:
virtual bool setCacheAttribute(const std::string &key, const std::string &val) override;
virtual std::string getCacheAttribute(const std::string &key) const override;
virtual void setOffline(bool offline) override;
virtual bool setUserNote(const std::string &txid, const std::string &note) override;
virtual std::string getUserNote(const std::string &txid) const override;
virtual std::string getTxKey(const std::string &txid) const override;
@@ -198,6 +204,7 @@ public:
virtual void startRefresh() override;
virtual void pauseRefresh() override;
virtual bool parse_uri(const std::string &uri, std::string &address, std::string &payment_id, uint64_t &amount, std::string &tx_description, std::string &recipient_name, std::vector<std::string> &unknown_parameters, std::string &error) override;
virtual std::string make_uri(const std::string &address, const std::string &payment_id, uint64_t amount, const std::string &tx_description, const std::string &recipient_name, std::string &error) const override;
virtual std::string getDefaultDataDir() const override;
virtual bool lightWalletLogin(bool &isNewWallet) const override;
virtual bool lightWalletImportWalletRequest(std::string &payment_id, uint64_t &fee, bool &new_request, bool &request_fulfilled, std::string &payment_address, std::string &status) override;
+34 -2
View File
@@ -182,9 +182,11 @@ struct TransactionInfo
virtual int direction() const = 0;
virtual bool isPending() const = 0;
virtual bool isFailed() const = 0;
virtual bool isCoinbase() const = 0;
virtual uint64_t amount() const = 0;
virtual uint64_t fee() const = 0;
virtual uint64_t blockHeight() const = 0;
virtual std::string description() const = 0;
virtual std::set<uint32_t> subaddrIndex() const = 0;
virtual uint32_t subaddrAccount() const = 0;
virtual std::string label() const = 0;
@@ -208,6 +210,7 @@ struct TransactionHistory
virtual TransactionInfo * transaction(const std::string &id) const = 0;
virtual std::vector<TransactionInfo*> getAll() const = 0;
virtual void refresh() = 0;
virtual void setTxNote(const std::string &txid, const std::string &note) = 0;
};
/**
@@ -250,6 +253,7 @@ struct AddressBook
virtual std::vector<AddressBookRow*> getAll() const = 0;
virtual bool addRow(const std::string &dst_addr , const std::string &payment_id, const std::string &description) = 0;
virtual bool deleteRow(std::size_t rowId) = 0;
virtual bool setDescription(std::size_t index, const std::string &description) = 0;
virtual void refresh() = 0;
virtual std::string errorString() const = 0;
virtual int errorCode() const = 0;
@@ -442,7 +446,7 @@ struct Wallet
};
virtual ~Wallet() = 0;
virtual std::string seed() const = 0;
virtual std::string seed(const std::string& seed_offset = "") const = 0;
virtual std::string getSeedLanguage() const = 0;
virtual void setSeedLanguage(const std::string &arg) = 0;
//! returns wallet status (Status_Ok | Status_Error)
@@ -452,6 +456,7 @@ struct Wallet
//! returns both error and error string atomically. suggested to use in instead of status() and errorString()
virtual void statusWithErrorString(int& status, std::string& errorString) const = 0;
virtual bool setPassword(const std::string &password) = 0;
virtual const std::string& getPassword() const = 0;
virtual bool setDevicePin(const std::string &pin) { (void)pin; return false; };
virtual bool setDevicePassphrase(const std::string &passphrase) { (void)passphrase; return false; };
virtual std::string address(uint32_t accountIndex = 0, uint32_t addressIndex = 0) const = 0;
@@ -622,6 +627,12 @@ struct Wallet
*/
virtual bool watchOnly() const = 0;
/**
* @brief isDeterministic - checks if wallet keys are deterministic
* @return - true if deterministic
*/
virtual bool isDeterministic() const = 0;
/**
* @brief blockChainHeight - returns current blockchain height
* @return
@@ -897,9 +908,10 @@ struct Wallet
/*!
* \brief exportKeyImages - exports key images to file
* \param filename
* \param all - export all key images or only those that have not yet been exported
* \return - true on success
*/
virtual bool exportKeyImages(const std::string &filename) = 0;
virtual bool exportKeyImages(const std::string &filename, bool all = false) = 0;
/*!
* \brief importKeyImages - imports key images from file
@@ -908,6 +920,19 @@ struct Wallet
*/
virtual bool importKeyImages(const std::string &filename) = 0;
/*!
* \brief importOutputs - exports outputs to file
* \param filename
* \return - true on success
*/
virtual bool exportOutputs(const std::string &filename, bool all = false) = 0;
/*!
* \brief importOutputs - imports outputs from file
* \param filename
* \return - true on success
*/
virtual bool importOutputs(const std::string &filename) = 0;
virtual TransactionHistory * history() = 0;
virtual AddressBook * addressBook() = 0;
@@ -995,6 +1020,7 @@ struct Wallet
virtual bool verifyMessageWithPublicKey(const std::string &message, const std::string &publicKey, const std::string &signature) const = 0;
virtual bool parse_uri(const std::string &uri, std::string &address, std::string &payment_id, uint64_t &amount, std::string &tx_description, std::string &recipient_name, std::vector<std::string> &unknown_parameters, std::string &error) = 0;
virtual std::string make_uri(const std::string &address, const std::string &payment_id, uint64_t amount, const std::string &tx_description, const std::string &recipient_name, std::string &error) const = 0;
virtual std::string getDefaultDataDir() const = 0;
@@ -1003,6 +1029,12 @@ struct Wallet
* \return true on success
*/
virtual bool rescanSpent() = 0;
/*
* \brief setOffline - toggle set offline on/off
* \param offline - true/false
*/
virtual void setOffline(bool offline) = 0;
//! blackballs a set of outputs
virtual bool blackballOutputs(const std::vector<std::string> &outputs, bool add) = 0;
+113 -39
View File
@@ -142,6 +142,9 @@ using namespace cryptonote;
#define IGNORE_LONG_PAYMENT_ID_FROM_BLOCK_VERSION 12
#define DEFAULT_UNLOCK_TIME (CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE * DIFFICULTY_TARGET_V2)
#define RECENT_SPEND_WINDOW (50 * DIFFICULTY_TARGET_V2)
static const std::string MULTISIG_SIGNATURE_MAGIC = "SigMultisigPkV1";
static const std::string MULTISIG_EXTRA_INFO_MAGIC = "MultisigxV1";
@@ -1022,7 +1025,13 @@ gamma_picker::gamma_picker(const std::vector<uint64_t> &rct_offsets, double shap
end = rct_offsets.data() + rct_offsets.size() - CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE;
num_rct_outputs = *(end - 1);
THROW_WALLET_EXCEPTION_IF(num_rct_outputs == 0, error::wallet_internal_error, "No rct outputs");
THROW_WALLET_EXCEPTION_IF(outputs_to_consider == 0, error::wallet_internal_error, "No rct outputs to consider");
average_output_time = DIFFICULTY_TARGET_V2 * blocks_to_consider / outputs_to_consider; // this assumes constant target over the whole rct range
if (average_output_time == 0) {
// TODO: apply this to all cases; do so alongside a hard fork, where all clients will update at the same time, preventing anonymity puddle formation
average_output_time = DIFFICULTY_TARGET_V2 * blocks_to_consider / static_cast<double>(outputs_to_consider);
}
THROW_WALLET_EXCEPTION_IF(average_output_time == 0, error::wallet_internal_error, "Average seconds per output cannot be 0.");
};
gamma_picker::gamma_picker(const std::vector<uint64_t> &rct_offsets): gamma_picker(rct_offsets, GAMMA_SHAPE, GAMMA_SCALE) {}
@@ -1031,6 +1040,34 @@ uint64_t gamma_picker::pick()
{
double x = gamma(engine);
x = exp(x);
if (x > DEFAULT_UNLOCK_TIME)
{
// We are trying to select an output from the chain that appeared 'x' seconds before the
// current chain tip, where 'x' is selected from the gamma distribution recommended in Miller et al.
// (https://arxiv.org/pdf/1704.04299/).
// Our method is to get the average time delta between outputs in the recent past, estimate the number of
// outputs 'n' that would have appeared between 'chain_tip - x' and 'chain_tip', select the real output at
// 'current_num_outputs - n', then randomly select an output from the block where that output appears.
// Source code to paper: https://github.com/maltemoeser/moneropaper
//
// Due to the 'default spendable age' mechanic in Monero, 'current_num_outputs' only contains
// currently *unlocked* outputs, which means the earliest output that can be selected is not at the chain tip!
// Therefore, we must offset 'x' so it matches up with the timing of the outputs being considered. We do
// this by saying if 'x` equals the expected age of the first unlocked output (compared to the current
// chain tip - i.e. DEFAULT_UNLOCK_TIME), then select the first unlocked output.
x -= DEFAULT_UNLOCK_TIME;
}
else
{
// If the spent time suggested by the gamma is less than the unlock time, that means the gamma is suggesting an output
// that is no longer feasible to be spent (possible since the gamma was constructed when consensus rules did not enforce the
// lock time). The assumption made in this code is that an output expected spent quicker than the unlock time would likely
// be spent within RECENT_SPEND_WINDOW after allowed. So it returns an output that falls between 0 and the RECENT_SPEND_WINDOW.
// The RECENT_SPEND_WINDOW was determined with empirical analysis of observed data.
x = crypto::rand_idx(static_cast<uint64_t>(RECENT_SPEND_WINDOW));
}
uint64_t output_index = x / average_output_time;
if (output_index >= num_rct_outputs)
return std::numeric_limits<uint64_t>::max(); // bad pick
@@ -1215,6 +1252,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std
wallet2::~wallet2()
{
deinit();
}
bool wallet2::has_testnet_option(const boost::program_options::variables_map& vm)
@@ -1858,7 +1896,7 @@ void wallet2::cache_tx_data(const cryptonote::transaction& tx, const crypto::has
const bool is_miner = tx.vin.size() == 1 && tx.vin[0].type() == typeid(cryptonote::txin_gen);
if (!is_miner || m_refresh_type != RefreshType::RefreshNoCoinbase)
{
const size_t rec_size = is_miner && m_refresh_type == RefreshType::RefreshOptimizeCoinbase ? 1 : tx.vout.size();
const size_t rec_size = (is_miner && m_refresh_type == RefreshType::RefreshOptimizeCoinbase && tx.version < 2) ? 1 : tx.vout.size();
if (!tx.vout.empty())
{
// if tx.vout is not empty, we loop through all tx pubkeys
@@ -2007,7 +2045,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
{
// assume coinbase isn't for us
}
else if (miner_tx && m_refresh_type == RefreshOptimizeCoinbase)
else if (miner_tx && m_refresh_type == RefreshOptimizeCoinbase && tx.version < 2)
{
check_acc_out_precomp_once(tx.vout[0], derivation, additional_derivations, 0, is_out_data_ptr, tx_scan_info[0], output_found[0]);
THROW_WALLET_EXCEPTION_IF(tx_scan_info[0].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
@@ -2734,9 +2772,8 @@ void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector<cry
{
if (tx_cache_data[i].empty())
continue;
tpool.submit(&waiter, [&hwdev, &gender, &tx_cache_data, i]() {
tpool.submit(&waiter, [&gender, &tx_cache_data, i]() {
auto &slot = tx_cache_data[i];
boost::unique_lock<hw::device> hwdev_lock(hwdev);
for (auto &iod: slot.primary)
gender(iod);
for (auto &iod: slot.additional)
@@ -2779,8 +2816,9 @@ void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector<cry
if (m_refresh_type != RefreshType::RefreshNoCoinbase)
{
THROW_WALLET_EXCEPTION_IF(txidx >= tx_cache_data.size(), error::wallet_internal_error, "txidx out of range");
const size_t n_vouts = m_refresh_type == RefreshType::RefreshOptimizeCoinbase ? 1 : parsed_blocks[i].block.miner_tx.vout.size();
tpool.submit(&waiter, [&, i, n_vouts, txidx](){ geniod(parsed_blocks[i].block.miner_tx, n_vouts, txidx); }, true);
const cryptonote::transaction& tx = parsed_blocks[i].block.miner_tx;
const size_t n_vouts = (m_refresh_type == RefreshType::RefreshOptimizeCoinbase && tx.version < 2) ? 1 : tx.vout.size();
tpool.submit(&waiter, [&, i, n_vouts, txidx](){ geniod(tx, n_vouts, txidx); }, true);
}
++txidx;
for (size_t j = 0; j < parsed_blocks[i].txes.size(); ++j)
@@ -3692,9 +3730,11 @@ void wallet2::detach_blockchain(uint64_t height, std::map<std::pair<uint64_t, ui
//----------------------------------------------------------------------------------------------------
bool wallet2::deinit()
{
m_is_initialized=false;
unlock_keys_file();
m_account.deinit();
if(m_is_initialized) {
m_is_initialized = false;
unlock_keys_file();
m_account.deinit();
}
return true;
}
//----------------------------------------------------------------------------------------------------
@@ -4364,7 +4404,7 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st
account_public_address device_account_public_address;
THROW_WALLET_EXCEPTION_IF(!hwdev.get_public_address(device_account_public_address), error::wallet_internal_error, "Cannot get a device address");
THROW_WALLET_EXCEPTION_IF(device_account_public_address != m_account.get_keys().m_account_address, error::wallet_internal_error, "Device wallet does not match wallet address. "
THROW_WALLET_EXCEPTION_IF(device_account_public_address != m_account.get_keys().m_account_address, error::wallet_internal_error, "Device wallet does not match wallet address. If the device uses the passphrase feature, please check whether the passphrase was entered correctly (it may have been misspelled - different passphrases generate different wallets, passphrase is case-sensitive). "
"Device address: " + cryptonote::get_account_address_as_str(m_nettype, false, device_account_public_address) +
", wallet address: " + m_account.get_public_address_str(m_nettype));
LOG_PRINT_L0("Device inited...");
@@ -8583,7 +8623,8 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
if (req.outputs[i].index == td.m_global_output_index)
if (daemon_resp.outs[i].key == boost::get<txout_to_key>(td.m_tx.vout[td.m_internal_output_index].target).key)
if (daemon_resp.outs[i].mask == mask)
real_out_found = true;
if (daemon_resp.outs[i].unlocked)
real_out_found = true;
}
THROW_WALLET_EXCEPTION_IF(!real_out_found, error::wallet_internal_error,
"Daemon response did not include the requested real output");
@@ -9768,13 +9809,18 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
TX() : weight(0), needed_fee(0) {}
void add(const cryptonote::tx_destination_entry &de, uint64_t amount, unsigned int original_output_index, bool merge_destinations) {
/* Add an output to the transaction.
* Returns True if the output was added, False if there are no more available output slots.
*/
bool add(const cryptonote::tx_destination_entry &de, uint64_t amount, unsigned int original_output_index, bool merge_destinations, size_t max_dsts) {
if (merge_destinations)
{
std::vector<cryptonote::tx_destination_entry>::iterator i;
i = std::find_if(dsts.begin(), dsts.end(), [&](const cryptonote::tx_destination_entry &d) { return !memcmp (&d.addr, &de.addr, sizeof(de.addr)); });
if (i == dsts.end())
{
if (dsts.size() >= max_dsts)
return false;
dsts.push_back(de);
i = dsts.end() - 1;
i->amount = 0;
@@ -9787,12 +9833,15 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
std::string("original_output_index too large: ") + std::to_string(original_output_index) + " > " + std::to_string(dsts.size()));
if (original_output_index == dsts.size())
{
if (dsts.size() >= max_dsts)
return false;
dsts.push_back(de);
dsts.back().amount = 0;
}
THROW_WALLET_EXCEPTION_IF(memcmp(&dsts[original_output_index].addr, &de.addr, sizeof(de.addr)), error::wallet_internal_error, "Mismatched destination address");
dsts[original_output_index].amount += amount;
}
return true;
}
};
std::vector<TX> txes;
@@ -10062,6 +10111,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
// clear any fake outs we'd already gathered, since we'll need a new set
outs.clear();
bool out_slots_exhausted = false;
if (adding_fee)
{
LOG_PRINT_L2("We need more fee, adding it to fee");
@@ -10074,20 +10124,32 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
// we can fully pay that destination
LOG_PRINT_L2("We can fully pay " << get_account_address_as_str(m_nettype, dsts[0].is_subaddress, dsts[0].addr) <<
" for " << print_money(dsts[0].amount));
tx.add(dsts[0], dsts[0].amount, original_output_index, m_merge_destinations);
if (!tx.add(dsts[0], dsts[0].amount, original_output_index, m_merge_destinations, BULLETPROOF_MAX_OUTPUTS-1))
{
LOG_PRINT_L2("Didn't pay: ran out of output slots");
out_slots_exhausted = true;
break;
}
available_amount -= dsts[0].amount;
dsts[0].amount = 0;
pop_index(dsts, 0);
++original_output_index;
}
if (available_amount > 0 && !dsts.empty() && estimate_tx_weight(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size()+1, extra.size(), bulletproof, clsag) < TX_WEIGHT_TARGET(upper_transaction_weight_limit)) {
if (!out_slots_exhausted && available_amount > 0 && !dsts.empty() && estimate_tx_weight(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size()+1, extra.size(), bulletproof, clsag) < TX_WEIGHT_TARGET(upper_transaction_weight_limit)) {
// we can partially fill that destination
LOG_PRINT_L2("We can partially pay " << get_account_address_as_str(m_nettype, dsts[0].is_subaddress, dsts[0].addr) <<
" for " << print_money(available_amount) << "/" << print_money(dsts[0].amount));
tx.add(dsts[0], available_amount, original_output_index, m_merge_destinations);
dsts[0].amount -= available_amount;
available_amount = 0;
if (tx.add(dsts[0], available_amount, original_output_index, m_merge_destinations, BULLETPROOF_MAX_OUTPUTS-1))
{
dsts[0].amount -= available_amount;
available_amount = 0;
}
else
{
LOG_PRINT_L2("Didn't pay: ran out of output slots");
out_slots_exhausted = true;
}
}
}
@@ -10095,8 +10157,15 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
LOG_PRINT_L2("Considering whether to create a tx now, " << tx.selected_transfers.size() << " inputs, tx limit "
<< upper_transaction_weight_limit);
bool try_tx = false;
// If the new transaction is full, create it and start a new one
if (out_slots_exhausted)
{
LOG_PRINT_L2("Transaction is full, will create it and start a new tx");
try_tx = true;
}
// if we have preferred picks, but haven't yet used all of them, continue
if (preferred_inputs.empty())
else if (preferred_inputs.empty())
{
if (adding_fee)
{
@@ -14100,15 +14169,15 @@ void wallet2::hash_m_transfer(const transfer_details & transfer, crypto::hash &h
KECCAK_CTX state;
keccak_init(&state);
keccak_update(&state, (const uint8_t *) transfer.m_txid.data, sizeof(transfer.m_txid.data));
keccak_update(&state, (const uint8_t *) transfer.m_internal_output_index, sizeof(transfer.m_internal_output_index));
keccak_update(&state, (const uint8_t *) transfer.m_global_output_index, sizeof(transfer.m_global_output_index));
keccak_update(&state, (const uint8_t *) transfer.m_amount, sizeof(transfer.m_amount));
keccak_update(&state, (const uint8_t *) &transfer.m_internal_output_index, sizeof(transfer.m_internal_output_index));
keccak_update(&state, (const uint8_t *) &transfer.m_global_output_index, sizeof(transfer.m_global_output_index));
keccak_update(&state, (const uint8_t *) &transfer.m_amount, sizeof(transfer.m_amount));
keccak_finish(&state, (uint8_t *) hash.data);
}
//----------------------------------------------------------------------------------------------------
uint64_t wallet2::hash_m_transfers(int64_t transfer_height, crypto::hash &hash) const
uint64_t wallet2::hash_m_transfers(boost::optional<uint64_t> transfer_height, crypto::hash &hash) const
{
CHECK_AND_ASSERT_THROW_MES(transfer_height > (int64_t)m_transfers.size(), "Hash height is greater than number of transfers");
CHECK_AND_ASSERT_THROW_MES(!transfer_height || *transfer_height <= m_transfers.size(), "Hash height is greater than number of transfers");
KECCAK_CTX state;
crypto::hash tmp_hash{};
@@ -14116,12 +14185,12 @@ uint64_t wallet2::hash_m_transfers(int64_t transfer_height, crypto::hash &hash)
keccak_init(&state);
for(const transfer_details & transfer : m_transfers){
if (transfer_height >= 0 && current_height >= (uint64_t)transfer_height){
if (transfer_height && current_height >= *transfer_height){
break;
}
hash_m_transfer(transfer, tmp_hash);
keccak_update(&state, (const uint8_t *) transfer.m_block_height, sizeof(transfer.m_block_height));
keccak_update(&state, (const uint8_t *) &transfer.m_block_height, sizeof(transfer.m_block_height));
keccak_update(&state, (const uint8_t *) tmp_hash.data, sizeof(tmp_hash.data));
current_height += 1;
}
@@ -14133,23 +14202,28 @@ uint64_t wallet2::hash_m_transfers(int64_t transfer_height, crypto::hash &hash)
void wallet2::finish_rescan_bc_keep_key_images(uint64_t transfer_height, const crypto::hash &hash)
{
// Compute hash of m_transfers, if differs there had to be BC reorg.
crypto::hash new_transfers_hash{};
hash_m_transfers((int64_t) transfer_height, new_transfers_hash);
if (transfer_height <= m_transfers.size()) {
crypto::hash new_transfers_hash{};
hash_m_transfers(transfer_height, new_transfers_hash);
if (new_transfers_hash != hash)
{
// Soft-Reset to avoid inconsistency in case of BC reorg.
clear_soft(false); // keep_key_images works only with soft reset.
THROW_WALLET_EXCEPTION_IF(true, error::wallet_internal_error, "Transfers changed during rescan, soft or hard rescan is needed");
if (new_transfers_hash == hash) {
// Restore key images in m_transfers from m_key_images
for(auto it = m_key_images.begin(); it != m_key_images.end(); it++)
{
THROW_WALLET_EXCEPTION_IF(it->second >= m_transfers.size(),
error::wallet_internal_error,
"Key images cache contains illegal transfer offset");
m_transfers[it->second].m_key_image = it->first;
m_transfers[it->second].m_key_image_known = true;
}
return;
}
}
// Restore key images in m_transfers from m_key_images
for(auto it = m_key_images.begin(); it != m_key_images.end(); it++)
{
THROW_WALLET_EXCEPTION_IF(it->second >= m_transfers.size(), error::wallet_internal_error, "Key images cache contains illegal transfer offset");
m_transfers[it->second].m_key_image = it->first;
m_transfers[it->second].m_key_image_known = true;
}
// Soft-Reset to avoid inconsistency in case of BC reorg.
clear_soft(false); // keep_key_images works only with soft reset.
THROW_WALLET_EXCEPTION_IF(true, error::wallet_internal_error, "Transfers changed during rescan, soft or hard rescan is needed");
}
//----------------------------------------------------------------------------------------------------
uint64_t wallet2::get_bytes_sent() const
+1 -1
View File
@@ -1542,7 +1542,7 @@ private:
bool is_tx_spendtime_unlocked(uint64_t unlock_time, uint64_t block_height);
void hash_m_transfer(const transfer_details & transfer, crypto::hash &hash) const;
uint64_t hash_m_transfers(int64_t transfer_height, crypto::hash &hash) const;
uint64_t hash_m_transfers(boost::optional<uint64_t> transfer_height, crypto::hash &hash) const;
void finish_rescan_bc_keep_key_images(uint64_t transfer_height, const crypto::hash &hash);
void enable_dns(bool enable) { m_use_dns = enable; }
void set_offline(bool offline = true);
+102 -7
View File
@@ -762,6 +762,90 @@ namespace tools
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server::on_freeze(const wallet_rpc::COMMAND_RPC_FREEZE::request& req, wallet_rpc::COMMAND_RPC_FREEZE::response& res, epee::json_rpc::error& er, const connection_context *ctx)
{
if (!m_wallet) return not_open(er);
try
{
if (req.key_image.empty())
{
er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
er.message = std::string("Must specify key image to freeze");
return false;
}
crypto::key_image ki;
if (!epee::string_tools::hex_to_pod(req.key_image, ki))
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE;
er.message = "failed to parse key image";
return false;
}
m_wallet->freeze(ki);
}
catch (const std::exception& e)
{
handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
return false;
}
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server::on_thaw(const wallet_rpc::COMMAND_RPC_THAW::request& req, wallet_rpc::COMMAND_RPC_THAW::response& res, epee::json_rpc::error& er, const connection_context *ctx)
{
if (!m_wallet) return not_open(er);
try
{
if (req.key_image.empty())
{
er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
er.message = std::string("Must specify key image to thaw");
return false;
}
crypto::key_image ki;
if (!epee::string_tools::hex_to_pod(req.key_image, ki))
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE;
er.message = "failed to parse key image";
return false;
}
m_wallet->thaw(ki);
}
catch (const std::exception& e)
{
handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
return false;
}
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server::on_frozen(const wallet_rpc::COMMAND_RPC_FROZEN::request& req, wallet_rpc::COMMAND_RPC_FROZEN::response& res, epee::json_rpc::error& er, const connection_context *ctx)
{
if (!m_wallet) return not_open(er);
try
{
if (req.key_image.empty())
{
er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
er.message = std::string("Must specify key image to check if frozen");
return false;
}
crypto::key_image ki;
if (!epee::string_tools::hex_to_pod(req.key_image, ki))
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE;
er.message = "failed to parse key image";
return false;
}
res.frozen = m_wallet->frozen(ki);
}
catch (const std::exception& e)
{
handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
return false;
}
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server::validate_transfer(const std::list<wallet_rpc::transfer_destination>& destinations, const std::string& payment_id, std::vector<cryptonote::tx_destination_entry>& dsts, std::vector<uint8_t>& extra, bool at_least_one_destination, epee::json_rpc::error& er)
{
crypto::hash8 integrated_payment_id = crypto::null_hash8;
@@ -877,10 +961,10 @@ namespace tools
return amount;
}
//------------------------------------------------------------------------------------------------------------------------------
template<typename Ts, typename Tu>
template<typename Ts, typename Tu, typename Tk>
bool wallet_rpc_server::fill_response(std::vector<tools::wallet2::pending_tx> &ptx_vector,
bool get_tx_key, Ts& tx_key, Tu &amount, Tu &fee, Tu &weight, std::string &multisig_txset, std::string &unsigned_txset, bool do_not_relay,
Ts &tx_hash, bool get_tx_hex, Ts &tx_blob, bool get_tx_metadata, Ts &tx_metadata, epee::json_rpc::error &er)
Ts &tx_hash, bool get_tx_hex, Ts &tx_blob, bool get_tx_metadata, Ts &tx_metadata, Tk &spent_key_images, epee::json_rpc::error &er)
{
for (const auto & ptx : ptx_vector)
{
@@ -895,6 +979,17 @@ namespace tools
fill(amount, total_amount(ptx));
fill(fee, ptx.fee);
fill(weight, cryptonote::get_transaction_weight(ptx.tx));
// add spent key images
tools::wallet_rpc::key_image_list key_image_list;
bool all_are_txin_to_key = std::all_of(ptx.tx.vin.begin(), ptx.tx.vin.end(), [&](const cryptonote::txin_v& s_e) -> bool
{
CHECKED_GET_SPECIFIC_VARIANT(s_e, const cryptonote::txin_to_key, in, false);
key_image_list.key_images.push_back(epee::string_tools::pod_to_hex(in.k_image));
return true;
});
THROW_WALLET_EXCEPTION_IF(!all_are_txin_to_key, error::unexpected_txin_type, ptx.tx);
fill(spent_key_images, key_image_list);
}
if (m_wallet->multisig())
@@ -981,7 +1076,7 @@ namespace tools
}
return fill_response(ptx_vector, req.get_tx_key, res.tx_key, res.amount, res.fee, res.weight, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
res.tx_hash, req.get_tx_hex, res.tx_blob, req.get_tx_metadata, res.tx_metadata, er);
res.tx_hash, req.get_tx_hex, res.tx_blob, req.get_tx_metadata, res.tx_metadata, res.spent_key_images, er);
}
catch (const std::exception& e)
{
@@ -1027,7 +1122,7 @@ namespace tools
}
return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_list, res.weight_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, er);
res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, res.spent_key_images_list, er);
}
catch (const std::exception& e)
{
@@ -1390,7 +1485,7 @@ namespace tools
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_unmixable_sweep_transactions();
return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_list, res.weight_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, er);
res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, res.spent_key_images_list, er);
}
catch (const std::exception& e)
{
@@ -1448,7 +1543,7 @@ namespace tools
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_all(req.below_amount, dsts[0].addr, dsts[0].is_subaddress, req.outputs, mixin, req.unlock_time, priority, extra, req.account_index, subaddr_indices);
return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_list, res.weight_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, er);
res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, res.spent_key_images_list, er);
}
catch (const std::exception& e)
{
@@ -1523,7 +1618,7 @@ namespace tools
}
return fill_response(ptx_vector, req.get_tx_key, res.tx_key, res.amount, res.fee, res.weight, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
res.tx_hash, req.get_tx_hex, res.tx_blob, req.get_tx_metadata, res.tx_metadata, er);
res.tx_hash, req.get_tx_hex, res.tx_blob, req.get_tx_metadata, res.tx_metadata, res.spent_key_images, er);
}
catch (const std::exception& e)
{
+8 -2
View File
@@ -84,6 +84,9 @@ namespace tools
MAP_JON_RPC_WE("set_account_tag_description", on_set_account_tag_description, wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION)
MAP_JON_RPC_WE("get_height", on_getheight, wallet_rpc::COMMAND_RPC_GET_HEIGHT)
MAP_JON_RPC_WE("getheight", on_getheight, wallet_rpc::COMMAND_RPC_GET_HEIGHT)
MAP_JON_RPC_WE("freeze", on_freeze, wallet_rpc::COMMAND_RPC_FREEZE)
MAP_JON_RPC_WE("thaw", on_thaw, wallet_rpc::COMMAND_RPC_THAW)
MAP_JON_RPC_WE("frozen", on_frozen, wallet_rpc::COMMAND_RPC_FROZEN)
MAP_JON_RPC_WE("transfer", on_transfer, wallet_rpc::COMMAND_RPC_TRANSFER)
MAP_JON_RPC_WE("transfer_split", on_transfer_split, wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT)
MAP_JON_RPC_WE("sign_transfer", on_sign_transfer, wallet_rpc::COMMAND_RPC_SIGN_TRANSFER)
@@ -173,6 +176,9 @@ namespace tools
bool on_untag_accounts(const wallet_rpc::COMMAND_RPC_UNTAG_ACCOUNTS::request& req, wallet_rpc::COMMAND_RPC_UNTAG_ACCOUNTS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_set_account_tag_description(const wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION::request& req, wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_getheight(const wallet_rpc::COMMAND_RPC_GET_HEIGHT::request& req, wallet_rpc::COMMAND_RPC_GET_HEIGHT::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_freeze(const wallet_rpc::COMMAND_RPC_FREEZE::request& req, wallet_rpc::COMMAND_RPC_FREEZE::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_thaw(const wallet_rpc::COMMAND_RPC_THAW::request& req, wallet_rpc::COMMAND_RPC_THAW::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_frozen(const wallet_rpc::COMMAND_RPC_FROZEN::request& req, wallet_rpc::COMMAND_RPC_FROZEN::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_transfer(const wallet_rpc::COMMAND_RPC_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_TRANSFER::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_transfer_split(const wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT::request& req, wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_sign_transfer(const wallet_rpc::COMMAND_RPC_SIGN_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_SIGN_TRANSFER::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
@@ -255,10 +261,10 @@ namespace tools
bool not_open(epee::json_rpc::error& er);
void handle_rpc_exception(const std::exception_ptr& e, epee::json_rpc::error& er, int default_error_code);
template<typename Ts, typename Tu>
template<typename Ts, typename Tu, typename Tk>
bool fill_response(std::vector<tools::wallet2::pending_tx> &ptx_vector,
bool get_tx_key, Ts& tx_key, Tu &amount, Tu &fee, Tu &weight, std::string &multisig_txset, std::string &unsigned_txset, bool do_not_relay,
Ts &tx_hash, bool get_tx_hex, Ts &tx_blob, bool get_tx_metadata, Ts &tx_metadata, epee::json_rpc::error &er);
Ts &tx_hash, bool get_tx_hex, Ts &tx_blob, bool get_tx_metadata, Ts &tx_metadata, Tk &spent_key_images, epee::json_rpc::error &er);
bool validate_transfer(const std::list<wallet_rpc::transfer_destination>& destinations, const std::string& payment_id, std::vector<cryptonote::tx_destination_entry>& dsts, std::vector<uint8_t>& extra, bool at_least_one_destination, epee::json_rpc::error& er);
+83 -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 20
#define WALLET_RPC_VERSION_MINOR 22
#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
@@ -456,6 +456,78 @@ namespace wallet_rpc
END_KV_SERIALIZE_MAP()
};
struct COMMAND_RPC_FREEZE
{
struct request_t
{
std::string key_image;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(key_image)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;
struct response_t
{
BEGIN_KV_SERIALIZE_MAP()
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<response_t> response;
};
struct COMMAND_RPC_THAW
{
struct request_t
{
std::string key_image;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(key_image)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;
struct response_t
{
BEGIN_KV_SERIALIZE_MAP()
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<response_t> response;
};
struct COMMAND_RPC_FROZEN
{
struct request_t
{
std::string key_image;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(key_image)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;
struct response_t
{
bool frozen;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(frozen)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<response_t> response;
};
struct key_image_list
{
std::list<std::string> key_images;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(key_images)
END_KV_SERIALIZE_MAP()
};
struct COMMAND_RPC_TRANSFER
{
struct request_t
@@ -499,6 +571,7 @@ namespace wallet_rpc
std::string tx_metadata;
std::string multisig_txset;
std::string unsigned_txset;
key_image_list spent_key_images;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(tx_hash)
@@ -510,6 +583,7 @@ namespace wallet_rpc
KV_SERIALIZE(tx_metadata)
KV_SERIALIZE(multisig_txset)
KV_SERIALIZE(unsigned_txset)
KV_SERIALIZE(spent_key_images)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<response_t> response;
@@ -567,6 +641,7 @@ namespace wallet_rpc
std::list<std::string> tx_metadata_list;
std::string multisig_txset;
std::string unsigned_txset;
std::list<key_image_list> spent_key_images_list;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(tx_hash_list)
@@ -578,6 +653,7 @@ namespace wallet_rpc
KV_SERIALIZE(tx_metadata_list)
KV_SERIALIZE(multisig_txset)
KV_SERIALIZE(unsigned_txset)
KV_SERIALIZE(spent_key_images_list)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<response_t> response;
@@ -742,6 +818,7 @@ namespace wallet_rpc
std::list<std::string> tx_metadata_list;
std::string multisig_txset;
std::string unsigned_txset;
std::list<key_image_list> spent_key_images_list;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(tx_hash_list)
@@ -753,6 +830,7 @@ namespace wallet_rpc
KV_SERIALIZE(tx_metadata_list)
KV_SERIALIZE(multisig_txset)
KV_SERIALIZE(unsigned_txset)
KV_SERIALIZE(spent_key_images_list)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<response_t> response;
@@ -816,6 +894,7 @@ namespace wallet_rpc
std::list<std::string> tx_metadata_list;
std::string multisig_txset;
std::string unsigned_txset;
std::list<key_image_list> spent_key_images_list;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(tx_hash_list)
@@ -827,6 +906,7 @@ namespace wallet_rpc
KV_SERIALIZE(tx_metadata_list)
KV_SERIALIZE(multisig_txset)
KV_SERIALIZE(unsigned_txset)
KV_SERIALIZE(spent_key_images_list)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<response_t> response;
@@ -875,6 +955,7 @@ namespace wallet_rpc
std::string tx_metadata;
std::string multisig_txset;
std::string unsigned_txset;
key_image_list spent_key_images;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(tx_hash)
@@ -886,6 +967,7 @@ namespace wallet_rpc
KV_SERIALIZE(tx_metadata)
KV_SERIALIZE(multisig_txset)
KV_SERIALIZE(unsigned_txset)
KV_SERIALIZE(spent_key_images)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<response_t> response;
+2 -4
View File
@@ -111,8 +111,7 @@ TEST(boosted_tcp_server, worker_threads_are_exception_resistant)
{
boost::unique_lock<boost::mutex> lock(mtx);
ASSERT_NE(boost::cv_status::timeout, cond.wait_for(lock, boost::chrono::seconds(5)));
ASSERT_EQ(4, counter);
ASSERT_TRUE(cond.wait_for(lock, boost::chrono::seconds(5), [&counter]{ return counter == 4; }));
}
// Check if threads are alive
@@ -125,8 +124,7 @@ TEST(boosted_tcp_server, worker_threads_are_exception_resistant)
{
boost::unique_lock<boost::mutex> lock(mtx);
ASSERT_NE(boost::cv_status::timeout, cond.wait_for(lock, boost::chrono::seconds(5)));
ASSERT_EQ(4, counter);
ASSERT_TRUE(cond.wait_for(lock, boost::chrono::seconds(5), [&counter]{ return counter == 4; }));
}
srv.send_stop_signal();
+1
View File
@@ -1503,6 +1503,7 @@ TEST(NetUtils, NetworkAddress)
constexpr static epee::net_utils::address_type get_type_id() noexcept { return epee::net_utils::address_type(-1); }
constexpr static epee::net_utils::zone get_zone() noexcept { return epee::net_utils::zone::invalid; }
constexpr static bool is_blockable() noexcept { return false; }
constexpr static uint16_t port() { return 0; }
};
const epee::net_utils::network_address empty;
+7 -5
View File
@@ -352,7 +352,7 @@ TEST(cryptonote_protocol_handler, race_condition)
acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
acceptor.bind(endpoint, ec);
EXPECT_EQ(ec.value(), 0);
acceptor.listen(boost::asio::socket_base::max_listen_connections, ec);
acceptor.listen(boost::asio::socket_base::max_connections, ec);
EXPECT_EQ(ec.value(), 0);
out->socket().open(endpoint.protocol(), ec);
EXPECT_EQ(ec.value(), 0);
@@ -803,9 +803,11 @@ TEST(cryptonote_protocol_handler, race_condition)
workers_t workers;
} check;
check.work = std::make_shared<work_t>(check.io_context);
check.workers.emplace_back([&check]{
check.io_context.run();
});
while (check.workers.size() < 2) {
check.workers.emplace_back([&check]{
check.io_context.run();
});
}
while (daemon.main.conn.size() < 1) {
daemon.main.conn.emplace_back(new connection_t(check.io_context, daemon.main.shared_state, {}, {}));
daemon.alt.conn.emplace_back(new connection_t(io_context, daemon.alt.shared_state, {}, {}));
@@ -864,7 +866,7 @@ TEST(cryptonote_protocol_handler, race_condition)
}
}
while (daemon.main.conn.size() < 2) {
daemon.main.conn.emplace_back(new connection_t(io_context, daemon.main.shared_state, {}, {}));
daemon.main.conn.emplace_back(new connection_t(check.io_context, daemon.main.shared_state, {}, {}));
daemon.alt.conn.emplace_back(new connection_t(io_context, daemon.alt.shared_state, {}, {}));
create_conn_pair(daemon.main.conn.back(), daemon.alt.conn.back());
conduct_handshake(daemon.alt.net_node, daemon.alt.conn.back());
+9 -9
View File
@@ -189,20 +189,20 @@ TEST(wipeable_string, parse_hexstr)
{
boost::optional<epee::wipeable_string> s;
ASSERT_EQ(boost::none, epee::wipeable_string("x").parse_hexstr());
ASSERT_EQ(boost::none, epee::wipeable_string("x0000000000000000").parse_hexstr());
ASSERT_EQ(boost::none, epee::wipeable_string("0000000000000000x").parse_hexstr());
ASSERT_EQ(boost::none, epee::wipeable_string("0").parse_hexstr());
ASSERT_EQ(boost::none, epee::wipeable_string("000").parse_hexstr());
ASSERT_TRUE(boost::none == epee::wipeable_string("x").parse_hexstr());
ASSERT_TRUE(boost::none == epee::wipeable_string("x0000000000000000").parse_hexstr());
ASSERT_TRUE(boost::none == epee::wipeable_string("0000000000000000x").parse_hexstr());
ASSERT_TRUE(boost::none == epee::wipeable_string("0").parse_hexstr());
ASSERT_TRUE(boost::none == epee::wipeable_string("000").parse_hexstr());
ASSERT_TRUE((s = epee::wipeable_string("").parse_hexstr()) != boost::none);
ASSERT_EQ(*s, "");
ASSERT_TRUE(*s == "");
ASSERT_TRUE((s = epee::wipeable_string("00").parse_hexstr()) != boost::none);
ASSERT_EQ(*s, epee::wipeable_string("", 1));
ASSERT_TRUE(*s == epee::wipeable_string("", 1));
ASSERT_TRUE((s = epee::wipeable_string("41").parse_hexstr()) != boost::none);
ASSERT_EQ(*s, epee::wipeable_string("A"));
ASSERT_TRUE(*s == epee::wipeable_string("A"));
ASSERT_TRUE((s = epee::wipeable_string("414243").parse_hexstr()) != boost::none);
ASSERT_EQ(*s, epee::wipeable_string("ABC"));
ASSERT_TRUE(*s == epee::wipeable_string("ABC"));
}
TEST(wipeable_string, to_hex)
+1 -1
View File
@@ -44,7 +44,7 @@ ARG BOOST_VERSION=1_68_0
ARG BOOST_VERSION_DOT=1.68.0
ARG BOOST_HASH=7f6130bc3cf65f56a618888ce9d5ea704fa10b462be126ad053e80e553d6d8b7
RUN set -ex \
&& curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \
&& curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2 \
&& echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \
&& tar -xvf boost_${BOOST_VERSION}.tar.bz2 \
&& rm -f boost_${BOOST_VERSION}.tar.bz2 \
+1 -1
View File
@@ -44,7 +44,7 @@ ARG BOOST_VERSION=1_68_0
ARG BOOST_VERSION_DOT=1.68.0
ARG BOOST_HASH=7f6130bc3cf65f56a618888ce9d5ea704fa10b462be126ad053e80e553d6d8b7
RUN set -ex \
&& curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \
&& curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2 \
&& echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \
&& tar -xvf boost_${BOOST_VERSION}.tar.bz2 \
&& rm -f boost_${BOOST_VERSION}.tar.bz2 \
+33
View File
@@ -1088,3 +1088,36 @@ class Wallet(object):
'id': '0'
}
return self.rpc.send_json_rpc_request(get_version)
def freeze(self, key_image):
freeze = {
'method': 'freeze',
'jsonrpc': '2.0',
'params' : {
'key_image': key_image,
},
'id': '0'
}
return self.rpc.send_json_rpc_request(freeze)
def thaw(self, key_image):
thaw = {
'method': 'thaw',
'jsonrpc': '2.0',
'params' : {
'key_image': key_image,
},
'id': '0'
}
return self.rpc.send_json_rpc_request(thaw)
def frozen(self, key_image):
frozen = {
'method': 'frozen',
'jsonrpc': '2.0',
'params' : {
'key_image': key_image,
},
'id': '0'
}
return self.rpc.send_json_rpc_request(frozen)