mirror of
https://codeberg.org/nahuhh/wownero
synced 2026-03-05 06:07:35 -05:00
Compare commits
134 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e921c3b8a3 | ||
|
|
f626f0a412 | ||
|
|
d9c70f5a08 | ||
|
|
8d7701a67d | ||
|
|
2a8a05af56 | ||
|
|
bb88fdfcdd | ||
|
|
1a86d67ef4 | ||
|
|
2c26e205bd | ||
|
|
48b8b5287b | ||
|
|
a1fde20408 | ||
|
|
6824ad23f6 | ||
|
|
dee8d4a2e2 | ||
|
|
272ddf78bf | ||
|
|
becc181499 | ||
|
|
ef8637a396 | ||
|
|
085d0f1994 | ||
|
|
710430ea51 | ||
|
|
e292b49308 | ||
|
|
e815479531 | ||
|
|
b0ef1ce118 | ||
|
|
ed71a89138 | ||
|
|
90f8943da6 | ||
|
|
a2dc960250 | ||
|
|
a03e5c3905 | ||
|
|
e2d02caf67 | ||
|
|
a985911453 | ||
|
|
f1ca5b5fd1 | ||
|
|
eb2a7342b8 | ||
|
|
a21819cc22 | ||
|
|
3341cded57 | ||
|
|
4578688c7b | ||
|
|
62ae03bfd3 | ||
|
|
f8d0f857f6 | ||
|
|
e44d831d7f | ||
|
|
12ad6748a4 | ||
|
|
b1710a4fcc | ||
|
|
65764dce8c | ||
|
|
c8b4cdffdc | ||
|
|
a0e4d6b4c2 | ||
|
|
b878068e84 | ||
|
|
143ac20baf | ||
|
|
215fccb71c | ||
|
|
4f1fc36c9b | ||
|
|
0a6465ebcc | ||
|
|
6573d10b5b | ||
|
|
2482733bc7 | ||
|
|
f2b4a3be47 | ||
|
|
a8eb29dbe7 | ||
|
|
6b28de1cdc | ||
|
|
e78ef8a3a7 | ||
|
|
7e6109d02a | ||
|
|
6fe4ceaf09 | ||
|
|
bcdc98a8b0 | ||
|
|
6c97d87295 | ||
|
|
d10480a12f | ||
|
|
79a4abdc18 | ||
|
|
864255d783 | ||
|
|
4ac984bc56 | ||
|
|
9be78e756b | ||
|
|
bd011fcae9 | ||
|
|
399593a320 | ||
|
|
d0bacf4f77 | ||
|
|
f25a655cff | ||
|
|
ddfefa5dd5 | ||
|
|
22e71f9449 | ||
|
|
15b7b9d05b | ||
|
|
5022273035 | ||
|
|
c36f266520 | ||
|
|
e9e18bdf56 | ||
|
|
83b5e5ada1 | ||
|
|
2944371b43 | ||
|
|
b06dd76792 | ||
|
|
8695701058 | ||
|
|
99682fb3a7 | ||
|
|
e84d5ba8c0 | ||
|
|
200586592c | ||
|
|
b2d752b298 | ||
|
|
3d25c90053 | ||
|
|
fd18ad1e60 | ||
|
|
d2a170f6e4 | ||
|
|
60ff2f668e | ||
|
|
45a63f10ba | ||
|
|
a21f06b933 | ||
|
|
1080a90d23 | ||
|
|
ccc2396d92 | ||
|
|
136be529d6 | ||
|
|
b5fb9aea88 | ||
|
|
dfa32f3330 | ||
|
|
6aaee726f1 | ||
|
|
a636325df3 | ||
|
|
47f78dc11a | ||
|
|
2d3fa0f1c9 | ||
|
|
7d1b51ebf7 | ||
|
|
dd4556c5e1 | ||
|
|
e52d622592 | ||
|
|
6cbf952315 | ||
|
|
a2013707e2 | ||
|
|
37e2666915 | ||
|
|
5c42087ec3 | ||
|
|
4f53308b8a | ||
|
|
1812ba449b | ||
|
|
930e6e32a0 | ||
|
|
773072bcd7 | ||
|
|
22a97e4192 | ||
|
|
095be4ff65 | ||
|
|
179db40a4a | ||
|
|
540548a0b7 | ||
|
|
4f6d49eff6 | ||
|
|
0c28ca0f4d | ||
|
|
36285ab082 | ||
|
|
327ea9032a | ||
|
|
5c29f2b10c | ||
|
|
84f49bed65 | ||
|
|
970ec88436 | ||
|
|
35b1f07d86 | ||
|
|
b895d04401 | ||
|
|
e082e0bc1a | ||
|
|
250a681db6 | ||
|
|
8635db2b19 | ||
|
|
0992c28663 | ||
|
|
32ea1c1423 | ||
|
|
53df650a78 | ||
|
|
9a4ddf9a1c | ||
|
|
3d7cf87092 | ||
|
|
a9534ceb46 | ||
|
|
d4675d8527 | ||
|
|
9ef26ac926 | ||
|
|
2581457497 | ||
|
|
e64ad1e325 | ||
|
|
3817d559d6 | ||
|
|
365c3b9517 | ||
|
|
d7f76002aa | ||
|
|
6526020b08 | ||
|
|
ddef0b1b8b |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -151,7 +151,7 @@ jobs:
|
||||
- name: install monero dependencies
|
||||
run: ${{env.APT_INSTALL_LINUX}}
|
||||
- name: install Python dependencies
|
||||
run: pip install requests psutil monotonic zmq deepdiff
|
||||
run: pip install requests psutil monotonic zmq
|
||||
- name: tests
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: ON
|
||||
|
||||
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -14,6 +14,6 @@
|
||||
branch = monero
|
||||
[submodule "external/randomwow"]
|
||||
path = external/randomwow
|
||||
url = https://codeberg.org/wownero/RandomWOW
|
||||
branch = 1.2.1-wow
|
||||
url = https://git.wownero.com/wownero/RandomWOW
|
||||
branch = 1.1.10-wow
|
||||
|
||||
|
||||
@@ -413,7 +413,7 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
else()
|
||||
set(DEFAULT_BUILD_DEBUG_UTILITIES OFF)
|
||||
endif()
|
||||
option(BUILD_DEBUG_UTILITIES "Build debug utilities." DEFAULT_BUILD_DEBUG_UTILITIES)
|
||||
option(BUILD_DEBUG_UTILITIES "Build debug utilities." ${DEFAULT_BUILD_DEBUG_UTILITIES})
|
||||
|
||||
if(OSSFUZZ)
|
||||
message(STATUS "Using OSS-Fuzz fuzzing system")
|
||||
@@ -778,7 +778,7 @@ else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARCH_FLAG}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_FLAG}")
|
||||
|
||||
set(WARNINGS "-Wall -Wextra -Wpointer-arith -Wundef -Wvla -Wwrite-strings -Wno-error=extra -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-error=unused-variable -Wno-error=undef -Wno-error=uninitialized")
|
||||
set(WARNINGS "-Wpointer-arith -Wundef -Wvla -Wwrite-strings -Wno-deprecated-declarations -Wno-unused-parameter -Wno-error=unused-variable -Wno-error=undef -Wno-error=uninitialized")
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
if(ARM)
|
||||
set(WARNINGS "${WARNINGS} -Wno-error=inline-asm")
|
||||
@@ -1076,38 +1076,26 @@ if(STATIC)
|
||||
set(Boost_USE_STATIC_LIBS ON)
|
||||
set(Boost_USE_STATIC_RUNTIME ON)
|
||||
endif()
|
||||
|
||||
# Find Boost headers
|
||||
set(BOOST_MIN_VER 1.62)
|
||||
find_package(Boost ${BOOST_MIN_VER} QUIET REQUIRED)
|
||||
|
||||
if(NOT Boost_FOUND)
|
||||
die("Could not find Boost libraries, please make sure you have installed Boost or libboost-all-dev (>=${BOOST_MIN_VER}) or the equivalent")
|
||||
elseif(Boost_FOUND)
|
||||
message(STATUS "Found Boost Version: ${Boost_VERSION_STRING}")
|
||||
|
||||
set(BOOST_COMPONENTS filesystem thread date_time chrono serialization program_options locale)
|
||||
|
||||
# Boost System is header-only since 1.69
|
||||
if (Boost_VERSION_STRING VERSION_LESS 1.69.0)
|
||||
list(APPEND BOOST_COMPONENTS system)
|
||||
endif()
|
||||
|
||||
# Boost Regex is header-only since 1.77
|
||||
if (Boost_VERSION_STRING VERSION_LESS 1.77.0)
|
||||
list(APPEND BOOST_COMPONENTS regex)
|
||||
endif()
|
||||
|
||||
message(STATUS "Boost components: ${BOOST_COMPONENTS}")
|
||||
|
||||
# Find required Boost libraries
|
||||
find_package(Boost ${BOOST_MIN_VER} QUIET REQUIRED COMPONENTS ${BOOST_COMPONENTS})
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_LIB_SUFFIXES})
|
||||
endif()
|
||||
|
||||
find_package(Boost 1.58 QUIET REQUIRED COMPONENTS system filesystem thread date_time chrono regex serialization program_options locale)
|
||||
add_definitions(-DBOOST_ASIO_ENABLE_SEQUENTIAL_STRAND_ALLOCATION)
|
||||
add_definitions(-DBOOST_NO_AUTO_PTR)
|
||||
add_definitions(-DBOOST_UUID_DISABLE_ALIGNMENT) # This restores UUID's std::has_unique_object_representations property
|
||||
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_LIB_SUFFIXES})
|
||||
if(NOT Boost_FOUND)
|
||||
die("Could not find Boost libraries, please make sure you have installed Boost or libboost-all-dev (>=1.58) or the equivalent")
|
||||
elseif(Boost_FOUND)
|
||||
message(STATUS "Found Boost Version: ${Boost_VERSION}")
|
||||
if (Boost_VERSION VERSION_LESS 10 AND Boost_VERSION VERSION_LESS 1.62.0 AND NOT (OPENSSL_VERSION VERSION_LESS 1.1))
|
||||
set(BOOST_BEFORE_1_62 true)
|
||||
endif()
|
||||
if (NOT Boost_VERSION VERSION_LESS 10 AND Boost_VERSION VERSION_LESS 106200 AND NOT (OPENSSL_VERSION VERSION_LESS 1.1))
|
||||
set(BOOST_BEFORE_1_62 true)
|
||||
endif()
|
||||
if (BOOST_BEFORE_1_62)
|
||||
message(FATAL_ERROR "Boost ${Boost_VERSION} (older than 1.62) is too old to link with OpenSSL ${OPENSSL_VERSION} (1.1 or newer) found at ${OPENSSL_INCLUDE_DIR} and ${OPENSSL_LIBRARIES}. "
|
||||
"Update Boost or install OpenSSL 1.0 and set path to it when running cmake: "
|
||||
"cmake -DOPENSSL_ROOT_DIR='/usr/include/openssl-1.0'")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
|
||||
if(MINGW)
|
||||
@@ -1129,7 +1117,8 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "(SunOS|Solaris)")
|
||||
set(EXTRA_LIBRARIES socket nsl resolv)
|
||||
elseif(NOT MSVC AND NOT DEPENDS)
|
||||
find_library(RT rt)
|
||||
set(EXTRA_LIBRARIES ${RT})
|
||||
find_library(Z z)
|
||||
set(EXTRA_LIBRARIES ${RT} ${Z})
|
||||
endif()
|
||||
|
||||
list(APPEND EXTRA_LIBRARIES ${CMAKE_DL_LIBS})
|
||||
@@ -1152,7 +1141,9 @@ if (HIDAPI_FOUND OR LibUSB_COMPILE_TEST_PASSED)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
option(USE_READLINE "Build with GNU readline support." ON)
|
||||
if(NOT OPENBSD)
|
||||
option(USE_READLINE "Build with GNU readline support." ON)
|
||||
endif()
|
||||
if(USE_READLINE AND NOT DEPENDS)
|
||||
find_package(Readline)
|
||||
if(READLINE_FOUND AND GNU_READLINE_FOUND)
|
||||
@@ -1201,7 +1192,6 @@ endif()
|
||||
if(NOT ZMQ_LIB)
|
||||
message(FATAL_ERROR "Could not find required libzmq")
|
||||
endif()
|
||||
include_directories(${ZMQ_INCLUDE_PATH})
|
||||
if(PGM_LIBRARY)
|
||||
set(ZMQ_LIB "${ZMQ_LIB};${PGM_LIBRARY}")
|
||||
endif()
|
||||
@@ -1215,15 +1205,7 @@ if(PROTOLIB_LIBRARY)
|
||||
set(ZMQ_LIB "${ZMQ_LIB};${PROTOLIB_LIBRARY}")
|
||||
endif()
|
||||
if(SODIUM_LIBRARY)
|
||||
message(STATUS "ZMQ_LIB: ${ZMQ_LIB};${SODIUM_LIBRARY}")
|
||||
set(ZMQ_LIB "${ZMQ_LIB};${SODIUM_LIBRARY}")
|
||||
find_path(SODIUM_INCLUDE_PATH sodium/crypto_verify_32.h)
|
||||
if (SODIUM_INCLUDE_PATH)
|
||||
message(STATUS "SODIUM_INCLUDE_PATH: ${SODIUM_INCLUDE_PATH}")
|
||||
include_directories(${SODIUM_INCLUDE_PATH})
|
||||
else()
|
||||
message(FATAL_ERROR "Could not find required sodium/crypto_verify_32.h")
|
||||
endif()
|
||||
endif()
|
||||
if(BSD_LIBRARY)
|
||||
set(ZMQ_LIB "${ZMQ_LIB};${BSD_LIBRARY}")
|
||||
|
||||
4
Makefile
4
Makefile
@@ -48,7 +48,7 @@ all: release-all
|
||||
|
||||
depends:
|
||||
cd contrib/depends && $(MAKE) HOST=$(target) && cd ../.. && mkdir -p build/$(target)/release
|
||||
cd build/$(target)/release && USE_DEVICE_TREZOR_MANDATORY=1 cmake -DCMAKE_TOOLCHAIN_FILE=$(CURDIR)/contrib/depends/$(target)/share/toolchain.cmake ../../.. && $(MAKE)
|
||||
cd build/$(target)/release && cmake -DCMAKE_TOOLCHAIN_FILE=$(CURDIR)/contrib/depends/$(target)/share/toolchain.cmake ../../.. && $(MAKE)
|
||||
|
||||
cmake-debug:
|
||||
mkdir -p $(builddir)/debug
|
||||
@@ -104,7 +104,7 @@ release-all:
|
||||
|
||||
release-static:
|
||||
mkdir -p $(builddir)/release
|
||||
cd $(builddir)/release && cmake -D BUILD_TESTS=OFF -D USE_DEVICE_TREZOR=OFF -D STATIC=ON -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release $(topdir) && $(MAKE)
|
||||
cd $(builddir)/release && cmake -D BUILD_TESTS=OFF -D USE_DEVICE_TREZOR=OFF -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release $(topdir) && $(MAKE)
|
||||
|
||||
coverage:
|
||||
mkdir -p $(builddir)/debug
|
||||
|
||||
78
README.md
78
README.md
@@ -1,12 +1,7 @@
|
||||
# ~~Mo~~Wownero - Such privacy! Many coins! Wow!
|
||||
# ~~Mo~~Wownero - Such privacy! Many coins! Wow! 🐕
|
||||
|
||||
[<img src="https://suchwow.xyz/data/suchwow/image/to23moqn.jpeg">](https://suchwow.xyz/s/oh-really-9eda16b2/item)
|
||||
|
||||
## Introduction
|
||||
|
||||
Wownero is a Doge-inspired, CPU-mineable, solo-mining only, privacy-respecting memecoin. It was fairly launched on April Fools' Day in 2018. It is a software fork of Monero, but with a lite version of RandomX, larger ring size, and a fixed supply of 184 million coins emitted over 50 years. Wownero has no trusted setup, premine, or dev tax. Besides betting on online snail racing, the main use case of Wownero is micro-tipping meme creators with sound magic internet money. As a 100% community-driven, free and open source software, Wownero does not depend on billionaire shills or lame ass "influencers."
|
||||
|
||||
Unlike Opposing Projects.
|
||||
Copyright (c) 2014-2023 The Monero Project.
|
||||
Portions Copyright (c) 2012-2013 The Cryptonote developers.
|
||||
|
||||
## Resources
|
||||
|
||||
@@ -15,30 +10,33 @@ Unlike Opposing Projects.
|
||||
- Twitter: [@w0wn3r0](https://twitter.com/w0wn3r0)
|
||||
- Reddit: [/r/wownero](https://www.reddit.com/r/wownero)
|
||||
- Mail: [wownero@wownero.org](mailto:wownero@wownero.org)
|
||||
- Git: [codeberg.org/wownero/wownero](https://codeberg.org/wownero/wownero)
|
||||
- Git: [git.wownero.com/wownero/wownero](https://git.wownero.com/wownero/wownero)
|
||||
- Wownero Funding System: [funding.wownero.com](https://funding.wownero.com)
|
||||
- Wownero Forum: [forum.wownero.com](https://forum.wownero.com)
|
||||
- Discord: [discord.gg/ykZyAzJhDK](https://discord.com/invite/ykZyAzJhDK)
|
||||
- Telegram: [t.me/wownero](https://t.me/wownero)
|
||||
- Public Node Status: [monero.fail](https://monero.fail/?chain=wownero&network=mainnet)
|
||||
- Wowlet Desktop Wallet: [git.wownero.com/wowlet/wowlet](https://git.wownero.com/wowlet/wowlet/releases)
|
||||
- Stack Wallet iOS & Android Mobile Wallet: [stackwallet.com](https://stackwallet.com)
|
||||
- Wonerujo Android Mobile Wallet: [google store](https://play.google.com/store/apps/details?id=com.m2049r.wowwallet)
|
||||
- Elite Wallet Android Mobile Wallet: [github](https://github.com/Elite-Labs/EliteWallet)
|
||||
- Public Node Status: [monero.fail](https://monero.fail/?crypto=wownero)
|
||||
- Wownero Memes: [suchwow.xyz](https://suchwow.xyz/posts/top)
|
||||
- Market Info: [coinmarketcap.com](https://coinmarketcap.com/currencies/wownero), [coingecko.com](https://www.coingecko.com/en/coins/wownero/usd)
|
||||
|
||||
## Exchanges
|
||||
|
||||
- [NonKYC](https://nonkyc.io/market/WOW_BTC)
|
||||
- [AltQuick](https://altquick.com/market/Wownero)
|
||||
- [Majestic Bank](https://majesticbank.sc)
|
||||
- [TradeOgre](https://tradeogre.com/exchange/BTC-WOW)
|
||||
|
||||
## Wallets
|
||||
### Blockchain Explorers
|
||||
|
||||
- Wonero CLI Wallet: [codeberg.org/wownero/wownero](https://codeberg.org/wownero/wownero/releases)
|
||||
- Wowlet Desktop Wallet: [codeberg.org/wownero/wowlet](https://codeberg.org/wownero/wowlet/releases)
|
||||
- Stack Wallet iOS & Android Mobile Wallet: [stackwallet.com](https://stackwallet.com)
|
||||
- Cake Wallet [cakewallet.com](https://cakewallet.com)
|
||||
- https://explore.wownero.com
|
||||
- https://muchwow.lol
|
||||
|
||||
## Blockchain Explorers
|
||||
## Introduction
|
||||
|
||||
- https://explorer.suchwow.xyz
|
||||
Wownero is a privacy-centric memecoin that was fairly launched on April 1, 2018 with no pre-mine, stealth-mine or ICO. Wownero has a maximum supply of around 184 million WOW with a slow and steady emission over 50 years. It is a fork of Monero, but with its own genesis block, so there is no degradation of privacy due to ring signatures using different participants for the same tx outputs on opposing forks.
|
||||
|
||||
## Supporting the project
|
||||
|
||||
@@ -47,8 +45,11 @@ Wownero is a 100% community-sponsored endeavor. Supporting services are also gra
|
||||
[<img src="https://git.wownero.com/wownero/meta/raw/branch/master/images/macstadium.png"
|
||||
alt="MacStadium"
|
||||
height="100">](https://www.macstadium.com)
|
||||
[<img src="https://git.wownero.com/wownero/meta/raw/branch/master/images/jetbrains.png"
|
||||
alt="JetBrains"
|
||||
height="100">](https://www.jetbrains.com)
|
||||
|
||||
Developers are volunteers doing this mostly for shits and giggles. If you would like to support our shenanigans and stimulant addictions, please consider donating to the dev slush fund.
|
||||
Developers are volunteers doing this mostly for shits and giggles. If you would like to support our shenanigans and stimulant addictions, please consider donating to [WFS proposals](https://funding.wownero.com/proposals) or the dev slush fund.
|
||||
|
||||
### Donation Addresses
|
||||
|
||||
@@ -62,13 +63,19 @@ XMR: `44SQVPGLufPasUcuUQSZiF5c9BFzjcP8ucDxzzFDgLf1VkCEFaidJ3u2AhSKMhPLKA3jc2iS8w
|
||||
|
||||
BTC: `bc1qcw9zglp3fxyl25zswemw7jczlqryms2lsmu464`
|
||||
|
||||
### Open Collective
|
||||
|
||||
Open Collective is an online funding platform for open source software and collaborative communities. The platform brings together legal entities that act as a “Fiscal Host”, “Collectives” (unincorporated, community-based projects), and individuals interested in supporting projects with donations. Fiscal hosts hold donations for collectives in trust and handle all the taxes and legal stuff.
|
||||
|
||||
Wownero is hosted by Open Collective Europe, a Brussels-based non-profit that hosts many other collectives, such as Manjaro, EndeavourOS, Xfce, and peertube.social. If you would like donate to the Wownero Project using this method, you can check out our [Wownero - Open Collective](https://opencollective.com/wownero) page.
|
||||
|
||||
## Release staging and Contributing
|
||||
|
||||
**Anyone is welcome to contribute to Wownero's codebase!**
|
||||
|
||||
If you have a fix or code change, feel free to submit it as a pull request. Ahead of a scheduled software upgrade, a development branch will be created with the new release version tag. Pull requests that address bugs should be made to Master. Pull requests that require review and testing (generally, optimizations and new features) should be made to the development branch. All pull requests will be considered safe until the US dollar valuation of 1 Wownero equals $1000. After this valuation has been reached, more research will be needed to introduce experimental cryptography and/or code into the codebase.
|
||||
|
||||
Things to Do, Work in Progress, and Help Wanted tasks are tracked in the [Meta](https://codeberg.org/wownero/meta/issues) repo.
|
||||
Things to Do, Work in Progress, and Help Wanted tasks are tracked in the [Meta](https://git.wownero.com/wownero/meta/issues) repo.
|
||||
|
||||
Join `#wownero` on IRC OFTC to participate in development conversation.
|
||||
|
||||
@@ -77,7 +84,7 @@ Join `#wownero` on IRC OFTC to participate in development conversation.
|
||||
Wownero uses a fixed-schedule software upgrade (hard fork) mechanism to implement new features. This means that users of Wownero (end users and service providers) should run current versions and upgrade their software on a regular schedule. The required software for these upgrades will be available prior to the scheduled date. Please check the repository prior to this date for the proper Wownero software version. Below is the historical schedule and the projected schedule for the next upgrade.
|
||||
Dates are provided in the format YYYY-MM-DD.
|
||||
|
||||
| Software upgrade block height | Date | Release Name | Minimum Wownero version | Recommended Wownero version | Details |
|
||||
| Software upgrade block height | Date | Release Name | Minimum Wownero version | Recommended Wownero version | Details |
|
||||
|-------------------------------|------------| ----------------- |-------------------------|-----------------------------| ---------------------------------------------------------------------------------- |
|
||||
| 1 | 2018-04-01 | Awesome Akita | v0.1.0.0 | v0.1.0.0 | Cryptonight variant 1, ringsize >= 8, sorted inputs
|
||||
| 69,69 | 2018-04-24 | Busty Brazzers | v0.2.0.0 | v0.2.0.0 | Bulletproofs, LWMA difficulty algorithm, ringsize >= 10, reduce unlock to 4
|
||||
@@ -89,12 +96,14 @@ Dates are provided in the format YYYY-MM-DD.
|
||||
| - | 2020-06-28 | Hallucinogenic Hypnotoad | v0.8.0.0 | v0.8.0.2 | Dandelion++ support
|
||||
| 253,999 | 2020-10-09 | Illiterate Illuminati | v0.9.0.0 | v0.9.3.3 | Dynamic coinbase unlock (up to 1 mo.), Deterministic unlock times, Enforce maximum coinbase amount, show_qr_code wallet command, CLSAG
|
||||
| 331,170 | 2021-07-04 | Junkie Jeff | v0.10.0.0 | v0.10.2.0 | Bulletproofs+, Miner Block Header Signing, Vote by Block, Change coinbase unlock time to 1 day, Reset difficulty and switch back to Monero's difficulty algorithm
|
||||
| 514,000 | 2023-04-01 | Kunty Karen | v0.11.0.0 | v0.11.3.0 | View tags, fee changes, adjusted dynamic block weight algorithm, multisig security fixes, RPC broadcast node donation sub-address, Limit tx_extra max size to ~1kb, 12-hour difficulty adjustment window
|
||||
| 514,000 | 2023-04-01 | Kunty Karen | v0.11.0.0 | v0.11.0.3 | View tags, fee changes, adjusted dynamic block weight algorithm, multisig security fixes, RPC broadcast node donation sub-address, Limit tx_extra max size to ~1kb, 12-hour difficulty adjustment window
|
||||
|
||||
X's indicate that these details have not been determined as of commit date.
|
||||
|
||||
\* indicates estimate as of commit date
|
||||
|
||||
## Installing from a package
|
||||
|
||||
Packages are available for
|
||||
|
||||
* Arch Linux/Manjaro
|
||||
@@ -122,22 +131,21 @@ Packaging for your favorite distribution would be a welcome contribution!
|
||||
|
||||
* Docker
|
||||
|
||||
git clone https://codeberg.org/wownero/wownero && cd wownero
|
||||
git clone https://git.wownero.com/wownero/wownero && cd wownero
|
||||
docker build -t git-wow:master -m 4g .
|
||||
docker run -it -p 34567:34567 -p 34568:34568 -w /home/wownero/build/release/bin git-wow:master bash
|
||||
|
||||
* Arch Linux/Manjaro
|
||||
|
||||
sudo pacman -Syu --needed base-devel cmake boost openssl zeromq libpgm unbound libsodium libunwind xz readline expat gtest python3 ccache doxygen graphviz qt5-tools hidapi libusb protobuf systemd gcc13
|
||||
git clone https://codeberg.org/wownero/wownero && cd wownero
|
||||
export CC=gcc-13 CXX=g++-13
|
||||
sudo pacman -Syu && sudo pacman -S base-devel cmake boost openssl zeromq libpgm unbound libsodium git libusb systemd
|
||||
git clone https://git.wownero.com/wownero/wownero && cd wownero
|
||||
make -j2
|
||||
|
||||
* Debian/Ubuntu
|
||||
|
||||
sudo apt update && sudo apt install build-essential cmake pkg-config libssl-dev libzmq3-dev libunbound-dev libsodium-dev libunwind8-dev liblzma-dev libreadline6-dev libexpat1-dev libpgm-dev qttools5-dev-tools libhidapi-dev libusb-1.0-0-dev libprotobuf-dev protobuf-compiler libudev-dev libboost-chrono-dev libboost-date-time-dev libboost-filesystem-dev libboost-locale-dev libboost-program-options-dev libboost-regex-dev libboost-serialization-dev libboost-system-dev libboost-thread-dev python3 ccache doxygen graphviz gcc-13 g++-13
|
||||
git clone https://codeberg.org/wownero/wownero && cd wownero
|
||||
CC="gcc-13" CXX="g++-13" make -j2
|
||||
sudo apt update && sudo apt install build-essential cmake pkg-config libboost-all-dev libssl-dev libzmq3-dev libunbound-dev libsodium-dev libunwind8-dev liblzma-dev libreadline6-dev libldns-dev libexpat1-dev libpgm-dev libhidapi-dev libusb-1.0-0-dev libprotobuf-dev protobuf-compiler libudev-dev git -y
|
||||
git clone https://git.wownero.com/wownero/wownero && cd wownero
|
||||
make -j2
|
||||
|
||||
|
||||
## Running Binaries
|
||||
@@ -160,7 +168,7 @@ To run in background:
|
||||
|
||||
To run as a systemd service, copy
|
||||
[wownerod.service](utils/systemd/wownerod.service) to `/etc/systemd/system/` and
|
||||
[wow.conf](utils/conf/wow.conf) to `/etc/`. The [example
|
||||
[wow.conf](wow.conf) to `/etc/`. The [example
|
||||
service](utils/systemd/wownerod.service) assumes that the user `wownero` exists
|
||||
and its home is the data directory specified in the [example
|
||||
config](wow.conf).
|
||||
@@ -188,7 +196,7 @@ HiddenServiceVersion 3
|
||||
save and close nano
|
||||
|
||||
* `sudo /etc/init.d/tor restart && sudo systemctl enable tor`
|
||||
* copy [wow.conf](utils/conf/wow.conf) file and save it in same directory as `wownerod`.
|
||||
* copy [wow.conf](https://git.wownero.com/wownero/wownero/raw/branch/master/wow.conf) file and save it in same directory as `wownerod`.
|
||||
* start wownerod like this:
|
||||
|
||||
```
|
||||
@@ -196,16 +204,14 @@ save and close nano
|
||||
```
|
||||
|
||||
* `sudo cat /var/lib/tor/wownero/hostname`
|
||||
|
||||
Copy your onion address and share node with others [here](https://monero.fail/?crypto=wownero).
|
||||
copy your onion address and share node with others [here](https://monero.fail/?crypto=wownero) and [here](https://forum.wownero.com/t/wownero-tor-onion-sites/623)
|
||||
|
||||
To share your node over p2p, uncomment first line of wownerod.conf and add your onion address.
|
||||
|
||||
More information on running Tor and i2p nodes is available [here](https://forum.wownero.com/t/how-to-setup-a-full-node-with-tor-i2p/588)
|
||||
|
||||
### Access remote Tor node from CLI wallet
|
||||
|
||||
```
|
||||
./wownero-wallet-cli --proxy 127.0.0.1:9050 --daemon-address iy6ry6uudpzvbd72zsipepukp6nsazjdu72n52vg3isfnxqn342flzad.onion:34568
|
||||
```
|
||||
|
||||
Copyright (c) 2014-2024 The Monero Project.
|
||||
Portions Copyright (c) 2012-2013 The Cryptonote developers.
|
||||
|
||||
@@ -145,7 +145,7 @@ $(1)_build_env+=PATH="$(build_prefix)/bin:$(PATH)"
|
||||
$(1)_stage_env+=PATH="$(build_prefix)/bin:$(PATH)"
|
||||
$(1)_autoconf=./configure --host=$($($(1)_type)_host) --prefix=$($($(1)_type)_prefix) $$($(1)_config_opts) CC="$$($(1)_cc)" CXX="$$($(1)_cxx)"
|
||||
|
||||
ifeq ($(filter $(1),libusb unbound),)
|
||||
ifneq ($(1),libusb)
|
||||
$(1)_autoconf += --disable-dependency-tracking
|
||||
endif
|
||||
ifneq ($($(1)_nm),)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package=expat
|
||||
$(package)_version=2.6.0
|
||||
$(package)_download_path=https://github.com/libexpat/libexpat/releases/download/R_$(subst .,_,$($(package)_version))/
|
||||
$(package)_version=2.4.1
|
||||
$(package)_download_path=https://github.com/libexpat/libexpat/releases/download/R_2_4_1
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.bz2
|
||||
$(package)_sha256_hash=ff60e6a6b6ce570ae012dc7b73169c7fdf4b6bf08c12ed0ec6f55736b78d85ba
|
||||
$(package)_sha256_hash=2f9b6a580b94577b150a7d5617ad4643a4301a6616ff459307df3e225bcfbf40
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_opts=--disable-shared --without-docbook --without-tests --without-examples
|
||||
$(package)_config_opts+=--enable-option-checking --without-xmlwf --with-pic
|
||||
$(package)_config_opts=--enable-static
|
||||
$(package)_config_opts=--disable-shared
|
||||
$(package)_config_opts+=--prefix=$(host_prefix)
|
||||
endef
|
||||
|
||||
@@ -23,6 +23,6 @@ define $(package)_stage_cmds
|
||||
endef
|
||||
|
||||
define $(package)_postprocess_cmds
|
||||
rm -rf share lib/cmake lib/*.la
|
||||
rm lib/*.la
|
||||
endef
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
package=native_biplist
|
||||
$(package)_version=0.9
|
||||
$(package)_download_path=https://pypi.python.org/packages/source/b/biplist
|
||||
$(package)_file_name=biplist-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=b57cadfd26e4754efdf89e9e37de87885f9b5c847b2615688ca04adfaf6ca604
|
||||
$(package)_install_libdir=$(build_prefix)/lib/python/dist-packages
|
||||
$(package)_patches=sorted_list.patch
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
patch -p1 < $($(package)_patch_dir)/sorted_list.patch
|
||||
endef
|
||||
|
||||
define $(package)_build_cmds
|
||||
python setup.py build
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
mkdir -p $($(package)_install_libdir) && \
|
||||
python setup.py install --root=$($(package)_staging_dir) --prefix=$(build_prefix) --install-lib=$($(package)_install_libdir)
|
||||
endef
|
||||
@@ -1,26 +0,0 @@
|
||||
package=native_cdrkit
|
||||
$(package)_version=1.1.11
|
||||
$(package)_download_path=https://distro.ibiblio.org/fatdog/source/600/c
|
||||
$(package)_file_name=cdrkit-$($(package)_version).tar.bz2
|
||||
$(package)_sha256_hash=b50d64c214a65b1a79afe3a964c691931a4233e2ba605d793eb85d0ac3652564
|
||||
$(package)_patches=cdrkit-deterministic.patch
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
patch -p1 < $($(package)_patch_dir)/cdrkit-deterministic.patch
|
||||
endef
|
||||
|
||||
define $(package)_config_cmds
|
||||
cmake -DCMAKE_INSTALL_PREFIX=$(build_prefix)
|
||||
endef
|
||||
|
||||
define $(package)_build_cmds
|
||||
$(MAKE) genisoimage
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
$(MAKE) DESTDIR=$($(package)_staging_dir) -C genisoimage install
|
||||
endef
|
||||
|
||||
define $(package)_postprocess_cmds
|
||||
rm bin/isovfy bin/isoinfo bin/isodump bin/isodebug bin/devdump
|
||||
endef
|
||||
@@ -1,23 +0,0 @@
|
||||
package=native_cmake
|
||||
$(package)_version=3.14.0
|
||||
$(package)_version_dot=v3.14
|
||||
$(package)_download_path=https://cmake.org/files/$($(package)_version_dot)/
|
||||
$(package)_file_name=cmake-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=aa76ba67b3c2af1946701f847073f4652af5cbd9f141f221c97af99127e75502
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_opts=
|
||||
endef
|
||||
|
||||
define $(package)_config_cmds
|
||||
./bootstrap &&\
|
||||
./configure $($(package)_config_opts)
|
||||
endef
|
||||
|
||||
define $(package)_build_cmd
|
||||
$(MAKE)
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
$(MAKE) DESTDIR=$($(package)_staging_dir) install
|
||||
endef
|
||||
@@ -1,17 +0,0 @@
|
||||
package=native_ds_store
|
||||
$(package)_version=1.1.0
|
||||
$(package)_download_path=https://github.com/al45tair/ds_store/archive/
|
||||
$(package)_download_file=v$($(package)_version).tar.gz
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=a9f4c0755c6be7224ff7029e188dd262e830bb81e801424841db9eb0780ec8ed
|
||||
$(package)_install_libdir=$(build_prefix)/lib/python/dist-packages
|
||||
$(package)_dependencies=native_biplist
|
||||
|
||||
define $(package)_build_cmds
|
||||
python setup.py build
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
mkdir -p $($(package)_install_libdir) && \
|
||||
python setup.py install --root=$($(package)_staging_dir) --prefix=$(build_prefix) --install-lib=$($(package)_install_libdir)
|
||||
endef
|
||||
@@ -1,22 +0,0 @@
|
||||
package=native_libdmg-hfsplus
|
||||
$(package)_version=0.1
|
||||
$(package)_download_path=https://github.com/theuni/libdmg-hfsplus/archive
|
||||
$(package)_file_name=libdmg-hfsplus-v$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=6569a02eb31c2827080d7d59001869ea14484c281efab0ae7f2b86af5c3120b3
|
||||
$(package)_build_subdir=build
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
mkdir build
|
||||
endef
|
||||
|
||||
define $(package)_config_cmds
|
||||
cmake -DCMAKE_INSTALL_PREFIX:PATH=$(build_prefix)/bin ..
|
||||
endef
|
||||
|
||||
define $(package)_build_cmds
|
||||
$(MAKE) -C dmg
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
$(MAKE) DESTDIR=$($(package)_staging_dir) -C dmg install
|
||||
endef
|
||||
@@ -1,21 +0,0 @@
|
||||
package=native_mac_alias
|
||||
$(package)_version=1.1.0
|
||||
$(package)_download_path=https://github.com/al45tair/mac_alias/archive/
|
||||
$(package)_download_file=v$($(package)_version).tar.gz
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=b10cb44ecb64fc25283fae7a9cf365d2829377d84e37b9c21100aca8757509be
|
||||
$(package)_install_libdir=$(build_prefix)/lib/python/dist-packages
|
||||
$(package)_patches=python3.patch
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
patch -p1 < $($(package)_patch_dir)/python3.patch
|
||||
endef
|
||||
|
||||
define $(package)_build_cmds
|
||||
python setup.py build
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
mkdir -p $($(package)_install_libdir) && \
|
||||
python setup.py install --root=$($(package)_staging_dir) --prefix=$(build_prefix) --install-lib=$($(package)_install_libdir)
|
||||
endef
|
||||
@@ -1,19 +1,20 @@
|
||||
package=openssl
|
||||
$(package)_version=3.0.13
|
||||
$(package)_version=1.1.1t
|
||||
$(package)_download_path=https://www.openssl.org/source
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=88525753f79d3bec27d2fa7c66aa0b92b3aa9498dafd93d7cfa4b3780cdae313
|
||||
$(package)_sha256_hash=8dee9b24bdb1dcbf0c3d1e9b02fb8f6bf22165e807f45adeb7c9677536859d3b
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_env=AR="$($(package)_ar)" ARFLAGS=$($(package)_arflags) RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)"
|
||||
$(package)_config_env_android=ANDROID_NDK_ROOT="$(host_prefix)/native" PATH="$(host_prefix)/native/bin" CC=clang AR=ar RANLIB=ranlib
|
||||
$(package)_build_env_android=ANDROID_NDK_ROOT="$(host_prefix)/native"
|
||||
$(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl --libdir=$(host_prefix)/lib
|
||||
$(package)_config_env_android=ANDROID_NDK_HOME="$(host_prefix)/native" PATH="$(host_prefix)/native/bin" CC=clang AR=ar RANLIB=ranlib
|
||||
$(package)_build_env_android=ANDROID_NDK_HOME="$(host_prefix)/native"
|
||||
$(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl
|
||||
$(package)_config_opts+=no-capieng
|
||||
$(package)_config_opts+=no-dso
|
||||
$(package)_config_opts+=no-dtls1
|
||||
$(package)_config_opts+=no-ec_nistp_64_gcc_128
|
||||
$(package)_config_opts+=no-gost
|
||||
$(package)_config_opts+=no-heartbeats
|
||||
$(package)_config_opts+=no-md2
|
||||
$(package)_config_opts+=no-rc5
|
||||
$(package)_config_opts+=no-rdrand
|
||||
@@ -21,8 +22,8 @@ $(package)_config_opts+=no-rfc3779
|
||||
$(package)_config_opts+=no-sctp
|
||||
$(package)_config_opts+=no-shared
|
||||
$(package)_config_opts+=no-ssl-trace
|
||||
$(package)_config_opts+=no-ssl2
|
||||
$(package)_config_opts+=no-ssl3
|
||||
$(package)_config_opts+=no-tests
|
||||
$(package)_config_opts+=no-unit-test
|
||||
$(package)_config_opts+=no-weak-ssl-ciphers
|
||||
$(package)_config_opts+=no-zlib
|
||||
@@ -48,7 +49,7 @@ $(package)_config_opts_x86_64_freebsd=BSD-x86_64
|
||||
endef
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
sed -i.old 's|crypto ssl apps util tools fuzz providers doc|crypto ssl util tools providers|' build.info
|
||||
sed -i.old 's|"engines", "apps", "test", "util", "tools", "fuzz"|"engines", "tools"|' Configure
|
||||
endef
|
||||
|
||||
define $(package)_config_cmds
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
package=unbound
|
||||
$(package)_version=1.19.1
|
||||
$(package)_version=1.15.0
|
||||
$(package)_download_path=https://www.nlnetlabs.nl/downloads/$(package)/
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=bc1d576f3dd846a0739adc41ffaa702404c6767d2b6082deb9f2f97cbb24a3a9
|
||||
$(package)_sha256_hash=a480dc6c8937447b98d161fe911ffc76cfaffa2da18788781314e81339f1126f
|
||||
$(package)_dependencies=openssl expat
|
||||
$(package)_patches=disable-glibc-reallocarray.patch
|
||||
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_opts=--disable-shared --enable-static --without-pyunbound --prefix=$(host_prefix)
|
||||
$(package)_config_opts+=--with-libexpat=$(host_prefix) --with-ssl=$(host_prefix) --with-libevent=no
|
||||
$(package)_config_opts+=--without-pythonmodule --disable-flto --with-pthreads --with-libunbound-only
|
||||
$(package)_config_opts=--disable-shared --enable-static --without-pyunbound --prefix=$(host_prefix) --with-libexpat=$(host_prefix) --with-ssl=$(host_prefix) --with-libevent=no --without-pythonmodule --disable-flto --with-pthreads --with-libunbound-only
|
||||
$(package)_config_opts_linux=--with-pic
|
||||
$(package)_config_opts_w64=--enable-static-exe --sysconfdir=/etc --prefix=$(host_prefix) --target=$(host_prefix)
|
||||
$(package)_config_opts_x86_64_darwin=ac_cv_func_SHA384_Init=yes
|
||||
$(package)_build_opts_mingw32=LDFLAGS="$($(package)_ldflags) -lpthread"
|
||||
$(package)_cflags_mingw32+="-D_WIN32_WINNT=0x600"
|
||||
endef
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
@@ -34,3 +30,6 @@ endef
|
||||
define $(package)_stage_cmds
|
||||
$(MAKE) DESTDIR=$($(package)_staging_dir) install
|
||||
endef
|
||||
|
||||
define $(package)_postprocess_cmds
|
||||
endef
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
This file is part of MXE. See LICENSE.md for licensing information.
|
||||
|
||||
Contains ad hoc patches for cross building.
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tony Theodore <tonyt@logyst.com>
|
||||
Date: Fri, 12 Aug 2016 02:01:20 +1000
|
||||
Subject: [PATCH 1/3] fix windres invocation options
|
||||
|
||||
windres doesn't recognise various gcc flags like -mms-bitfields,
|
||||
-fopenmp, -mthreads etc. (basically not `-D` or `-I`)
|
||||
|
||||
diff --git a/Modules/Platform/Windows-windres.cmake b/Modules/Platform/Windows-windres.cmake
|
||||
index 1111111..2222222 100644
|
||||
--- a/Modules/Platform/Windows-windres.cmake
|
||||
+++ b/Modules/Platform/Windows-windres.cmake
|
||||
@@ -1 +1 @@
|
||||
-set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> -O coff <DEFINES> <INCLUDES> <FLAGS> <SOURCE> <OBJECT>")
|
||||
+set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> -O coff <DEFINES> <INCLUDES> <SOURCE> <OBJECT>")
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tony Theodore <tonyt@logyst.com>
|
||||
Date: Tue, 25 Jul 2017 20:34:56 +1000
|
||||
Subject: [PATCH 2/3] add option to disable -isystem
|
||||
|
||||
taken from (not accepted):
|
||||
https://gitlab.kitware.com/cmake/cmake/merge_requests/895
|
||||
|
||||
see also:
|
||||
https://gitlab.kitware.com/cmake/cmake/issues/16291
|
||||
https://gitlab.kitware.com/cmake/cmake/issues/16919
|
||||
|
||||
diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake
|
||||
index 1111111..2222222 100644
|
||||
--- a/Modules/Compiler/GNU.cmake
|
||||
+++ b/Modules/Compiler/GNU.cmake
|
||||
@@ -42,7 +42,7 @@ macro(__compiler_gnu lang)
|
||||
string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -O2 -g -DNDEBUG")
|
||||
set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
|
||||
set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
|
||||
- if(NOT APPLE OR NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 4) # work around #4462
|
||||
+ if(NOT APPLE OR NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 4 AND (NOT MXE_DISABLE_INCLUDE_SYSTEM_FLAG)) # work around #4462
|
||||
set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tony Theodore <tonyt@logyst.com>
|
||||
Date: Tue, 15 Aug 2017 15:25:06 +1000
|
||||
Subject: [PATCH 3/3] add CPACK_NSIS_EXECUTABLE variable
|
||||
|
||||
|
||||
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
|
||||
index 1111111..2222222 100644
|
||||
--- a/Source/CPack/cmCPackNSISGenerator.cxx
|
||||
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
|
||||
@@ -384,7 +384,9 @@ int cmCPackNSISGenerator::InitializeInternal()
|
||||
}
|
||||
#endif
|
||||
|
||||
- nsisPath = cmSystemTools::FindProgram("makensis", path, false);
|
||||
+ this->SetOptionIfNotSet("CPACK_NSIS_EXECUTABLE", "makensis");
|
||||
+ nsisPath = cmSystemTools::FindProgram(
|
||||
+ this->GetOption("CPACK_NSIS_EXECUTABLE"), path, false);
|
||||
|
||||
if (nsisPath.empty()) {
|
||||
cmCPackLogger(
|
||||
@@ -1,29 +0,0 @@
|
||||
--- a/biplist/__init__.py 2014-10-26 19:03:11.000000000 +0000
|
||||
+++ b/biplist/__init__.py 2016-07-19 19:30:17.663521999 +0000
|
||||
@@ -541,7 +541,7 @@
|
||||
return HashableWrapper(n)
|
||||
elif isinstance(root, dict):
|
||||
n = {}
|
||||
- for key, value in iteritems(root):
|
||||
+ for key, value in sorted(iteritems(root)):
|
||||
n[self.wrapRoot(key)] = self.wrapRoot(value)
|
||||
return HashableWrapper(n)
|
||||
elif isinstance(root, list):
|
||||
@@ -616,7 +616,7 @@
|
||||
elif isinstance(obj, dict):
|
||||
size = proc_size(len(obj))
|
||||
self.incrementByteCount('dictBytes', incr=1+size)
|
||||
- for key, value in iteritems(obj):
|
||||
+ for key, value in sorted(iteritems(obj)):
|
||||
check_key(key)
|
||||
self.computeOffsets(key, asReference=True)
|
||||
self.computeOffsets(value, asReference=True)
|
||||
@@ -714,7 +714,7 @@
|
||||
keys = []
|
||||
values = []
|
||||
objectsToWrite = []
|
||||
- for key, value in iteritems(obj):
|
||||
+ for key, value in sorted(iteritems(obj)):
|
||||
keys.append(key)
|
||||
values.append(value)
|
||||
for key in keys:
|
||||
@@ -1,86 +0,0 @@
|
||||
--- cdrkit-1.1.11.old/genisoimage/tree.c 2008-10-21 19:57:47.000000000 -0400
|
||||
+++ cdrkit-1.1.11/genisoimage/tree.c 2013-12-06 00:23:18.489622668 -0500
|
||||
@@ -1139,8 +1139,9 @@
|
||||
scan_directory_tree(struct directory *this_dir, char *path,
|
||||
struct directory_entry *de)
|
||||
{
|
||||
- DIR *current_dir;
|
||||
+ int current_file;
|
||||
char whole_path[PATH_MAX];
|
||||
+ struct dirent **d_list;
|
||||
struct dirent *d_entry;
|
||||
struct directory *parent;
|
||||
int dflag;
|
||||
@@ -1164,7 +1165,8 @@
|
||||
this_dir->dir_flags |= DIR_WAS_SCANNED;
|
||||
|
||||
errno = 0; /* Paranoia */
|
||||
- current_dir = opendir(path);
|
||||
+ //current_dir = opendir(path);
|
||||
+ current_file = scandir(path, &d_list, NULL, alphasort);
|
||||
d_entry = NULL;
|
||||
|
||||
/*
|
||||
@@ -1173,12 +1175,12 @@
|
||||
*/
|
||||
old_path = path;
|
||||
|
||||
- if (current_dir) {
|
||||
+ if (current_file >= 0) {
|
||||
errno = 0;
|
||||
- d_entry = readdir(current_dir);
|
||||
+ d_entry = d_list[0];
|
||||
}
|
||||
|
||||
- if (!current_dir || !d_entry) {
|
||||
+ if (current_file < 0 || !d_entry) {
|
||||
int ret = 1;
|
||||
|
||||
#ifdef USE_LIBSCHILY
|
||||
@@ -1191,8 +1193,8 @@
|
||||
de->isorec.flags[0] &= ~ISO_DIRECTORY;
|
||||
ret = 0;
|
||||
}
|
||||
- if (current_dir)
|
||||
- closedir(current_dir);
|
||||
+ if(d_list)
|
||||
+ free(d_list);
|
||||
return (ret);
|
||||
}
|
||||
#ifdef ABORT_DEEP_ISO_ONLY
|
||||
@@ -1208,7 +1210,7 @@
|
||||
errmsgno(EX_BAD, "use Rock Ridge extensions via -R or -r,\n");
|
||||
errmsgno(EX_BAD, "or allow deep ISO9660 directory nesting via -D.\n");
|
||||
}
|
||||
- closedir(current_dir);
|
||||
+ free(d_list);
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
@@ -1250,13 +1252,13 @@
|
||||
* The first time through, skip this, since we already asked
|
||||
* for the first entry when we opened the directory.
|
||||
*/
|
||||
- if (dflag)
|
||||
- d_entry = readdir(current_dir);
|
||||
+ if (dflag && current_file >= 0)
|
||||
+ d_entry = d_list[current_file];
|
||||
dflag++;
|
||||
|
||||
- if (!d_entry)
|
||||
+ if (current_file < 0)
|
||||
break;
|
||||
-
|
||||
+ current_file--;
|
||||
/* OK, got a valid entry */
|
||||
|
||||
/* If we do not want all files, then pitch the backups. */
|
||||
@@ -1348,7 +1350,7 @@
|
||||
insert_file_entry(this_dir, whole_path, d_entry->d_name);
|
||||
#endif /* APPLE_HYB */
|
||||
}
|
||||
- closedir(current_dir);
|
||||
+ free(d_list);
|
||||
|
||||
#ifdef APPLE_HYB
|
||||
/*
|
||||
@@ -1,72 +0,0 @@
|
||||
diff -dur a/mac_alias/alias.py b/mac_alias/alias.py
|
||||
--- a/mac_alias/alias.py 2015-10-19 12:12:48.000000000 +0200
|
||||
+++ b/mac_alias/alias.py 2016-04-03 12:13:12.037159417 +0200
|
||||
@@ -243,10 +243,10 @@
|
||||
alias = Alias()
|
||||
alias.appinfo = appinfo
|
||||
|
||||
- alias.volume = VolumeInfo (volname.replace('/',':'),
|
||||
+ alias.volume = VolumeInfo (volname.decode().replace('/',':'),
|
||||
voldate, fstype, disktype,
|
||||
volattrs, volfsid)
|
||||
- alias.target = TargetInfo (kind, filename.replace('/',':'),
|
||||
+ alias.target = TargetInfo (kind, filename.decode().replace('/',':'),
|
||||
folder_cnid, cnid,
|
||||
crdate, creator_code, type_code)
|
||||
alias.target.levels_from = levels_from
|
||||
@@ -261,9 +261,9 @@
|
||||
b.read(1)
|
||||
|
||||
if tag == TAG_CARBON_FOLDER_NAME:
|
||||
- alias.target.folder_name = value.replace('/',':')
|
||||
+ alias.target.folder_name = value.decode().replace('/',':')
|
||||
elif tag == TAG_CNID_PATH:
|
||||
- alias.target.cnid_path = struct.unpack(b'>%uI' % (length // 4),
|
||||
+ alias.target.cnid_path = struct.unpack('>%uI' % (length // 4),
|
||||
value)
|
||||
elif tag == TAG_CARBON_PATH:
|
||||
alias.target.carbon_path = value
|
||||
@@ -298,9 +298,9 @@
|
||||
alias.target.creation_date \
|
||||
= mac_epoch + datetime.timedelta(seconds=seconds)
|
||||
elif tag == TAG_POSIX_PATH:
|
||||
- alias.target.posix_path = value
|
||||
+ alias.target.posix_path = value.decode()
|
||||
elif tag == TAG_POSIX_PATH_TO_MOUNTPOINT:
|
||||
- alias.volume.posix_path = value
|
||||
+ alias.volume.posix_path = value.decode()
|
||||
elif tag == TAG_RECURSIVE_ALIAS_OF_DISK_IMAGE:
|
||||
alias.volume.disk_image_alias = Alias.from_bytes(value)
|
||||
elif tag == TAG_USER_HOME_LENGTH_PREFIX:
|
||||
@@ -422,13 +422,13 @@
|
||||
# (so doing so is ridiculous, and nothing could rely on it).
|
||||
b.write(struct.pack(b'>h28pI2shI64pII4s4shhI2s10s',
|
||||
self.target.kind,
|
||||
- carbon_volname, voldate,
|
||||
+ carbon_volname, int(voldate),
|
||||
self.volume.fs_type,
|
||||
self.volume.disk_type,
|
||||
self.target.folder_cnid,
|
||||
carbon_filename,
|
||||
self.target.cnid,
|
||||
- crdate,
|
||||
+ int(crdate),
|
||||
self.target.creator_code,
|
||||
self.target.type_code,
|
||||
self.target.levels_from,
|
||||
@@ -449,12 +449,12 @@
|
||||
|
||||
b.write(struct.pack(b'>hhQhhQ',
|
||||
TAG_HIGH_RES_VOLUME_CREATION_DATE,
|
||||
- 8, long(voldate * 65536),
|
||||
+ 8, int(voldate * 65536),
|
||||
TAG_HIGH_RES_CREATION_DATE,
|
||||
- 8, long(crdate * 65536)))
|
||||
+ 8, int(crdate * 65536)))
|
||||
|
||||
if self.target.cnid_path:
|
||||
- cnid_path = struct.pack(b'>%uI' % len(self.target.cnid_path),
|
||||
+ cnid_path = struct.pack('>%uI' % len(self.target.cnid_path),
|
||||
*self.target.cnid_path)
|
||||
b.write(struct.pack(b'>hh', TAG_CNID_PATH,
|
||||
len(cnid_path)))
|
||||
@@ -144,11 +144,8 @@ elseif(ARCHITECTURE STREQUAL "aarch64")
|
||||
endif()
|
||||
|
||||
if(ARCHITECTURE STREQUAL "riscv64")
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(BUILD_TAG "linux-riscv64")
|
||||
endif()
|
||||
set(ARCH_ID "riscv64")
|
||||
set(ARCH "rv64gc")
|
||||
set(NO_AES ON)
|
||||
set(ARCH "rv64imafdc")
|
||||
endif()
|
||||
|
||||
if(ARCHITECTURE STREQUAL "i686")
|
||||
|
||||
@@ -74,7 +74,6 @@ namespace epee
|
||||
public:
|
||||
using char_type = std::uint8_t;
|
||||
using Ch = char_type;
|
||||
using value_type = char_type;
|
||||
|
||||
//! Increase internal buffer by at least `byte_stream_increase` bytes.
|
||||
byte_stream() noexcept
|
||||
@@ -87,7 +86,6 @@ namespace epee
|
||||
~byte_stream() noexcept = default;
|
||||
byte_stream& operator=(byte_stream&& rhs) noexcept;
|
||||
|
||||
std::uint8_t* data() noexcept { return buffer_.get(); }
|
||||
const std::uint8_t* data() const noexcept { return buffer_.get(); }
|
||||
std::uint8_t* tellp() const noexcept { return next_write_; }
|
||||
std::size_t available() const noexcept { return end_ - next_write_; }
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
|
||||
#include <string>
|
||||
#include <ctime>
|
||||
#include <cstdint>
|
||||
|
||||
namespace epee
|
||||
{
|
||||
|
||||
@@ -583,8 +583,11 @@ namespace net_utils
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if (ec.value())
|
||||
terminate();
|
||||
else {
|
||||
cancel_timer();
|
||||
on_interrupted();
|
||||
}
|
||||
};
|
||||
m_strand.post(
|
||||
|
||||
@@ -171,13 +171,6 @@
|
||||
epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(rsp), response_info.m_body); \
|
||||
return true; \
|
||||
} \
|
||||
epee::serialization::storage_entry params_; \
|
||||
params_ = epee::serialization::storage_entry(epee::serialization::section()); \
|
||||
if(!ps.get_value("params", params_, nullptr)) \
|
||||
{ \
|
||||
epee::serialization::section params_section; \
|
||||
ps.set_value("params", std::move(params_section), nullptr); \
|
||||
} \
|
||||
if(false) return true; //just a stub to have "else if"
|
||||
|
||||
|
||||
|
||||
@@ -98,18 +98,16 @@ public: \
|
||||
#define KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, val_name) \
|
||||
epee::serialization::selector<is_store>::serialize_t_val_as_blob(this_ref.varialble, stg, hparent_section, val_name);
|
||||
|
||||
#define KV_SERIALIZE_VAL_POD_AS_BLOB_N(variable, val_name) \
|
||||
static_assert(std::is_trivially_copyable<decltype(this_ref.variable)>(), "t_type must be a trivially copyable type."); \
|
||||
static_assert(std::is_standard_layout<decltype(this_ref.variable)>(), "t_type must be a standard layout type."); \
|
||||
KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(variable, val_name)
|
||||
#define KV_SERIALIZE_VAL_POD_AS_BLOB_N(varialble, val_name) \
|
||||
static_assert(std::is_pod<decltype(this_ref.varialble)>::value, "t_type must be a POD type."); \
|
||||
KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, val_name)
|
||||
|
||||
#define KV_SERIALIZE_VAL_POD_AS_BLOB_OPT_N(variable, val_name, default_value) \
|
||||
#define KV_SERIALIZE_VAL_POD_AS_BLOB_OPT_N(varialble, val_name, default_value) \
|
||||
do { \
|
||||
static_assert(std::is_trivially_copyable<decltype(this_ref.variable)>(), "t_type must be a trivially copyable type."); \
|
||||
static_assert(std::is_standard_layout<decltype(this_ref.variable)>(), "t_type must be a standard layout type."); \
|
||||
bool ret = KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(variable, val_name) \
|
||||
static_assert(std::is_pod<decltype(this_ref.varialble)>::value, "t_type must be a POD type."); \
|
||||
bool ret = KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, val_name); \
|
||||
if (!ret) \
|
||||
epee::serialize_default(this_ref.variable, default_value); \
|
||||
epee::serialize_default(this_ref.varialble, default_value); \
|
||||
} while(0);
|
||||
|
||||
#define KV_SERIALIZE_CONTAINER_POD_AS_BLOB_N(varialble, val_name) \
|
||||
@@ -120,7 +118,7 @@ public: \
|
||||
#define KV_SERIALIZE(varialble) KV_SERIALIZE_N(varialble, #varialble)
|
||||
#define KV_SERIALIZE_VAL_POD_AS_BLOB(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_N(varialble, #varialble)
|
||||
#define KV_SERIALIZE_VAL_POD_AS_BLOB_OPT(varialble, def) KV_SERIALIZE_VAL_POD_AS_BLOB_OPT_N(varialble, #varialble, def)
|
||||
#define KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, #varialble) //skip is_trivially_copyable and is_standard_layout compile time check
|
||||
#define KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, #varialble) //skip is_pod compile time check
|
||||
#define KV_SERIALIZE_CONTAINER_POD_AS_BLOB(varialble) KV_SERIALIZE_CONTAINER_POD_AS_BLOB_N(varialble, #varialble)
|
||||
#define KV_SERIALIZE_OPT(variable,default_value) KV_SERIALIZE_OPT_N(variable, #variable, default_value)
|
||||
|
||||
|
||||
@@ -133,37 +133,26 @@ namespace epee
|
||||
return {src.data(), src.size()};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr bool has_padding() noexcept
|
||||
{
|
||||
return !std::is_standard_layout<T>() || alignof(T) != 1;
|
||||
}
|
||||
|
||||
//! \return Cast data from `src` as `span<const std::uint8_t>`.
|
||||
template<typename T>
|
||||
span<const std::uint8_t> to_byte_span(const span<const T> src) noexcept
|
||||
{
|
||||
static_assert(!std::is_empty<T>(), "empty value types will not work -> sizeof == 1");
|
||||
static_assert(std::is_standard_layout<T>(), "type must have standard layout");
|
||||
static_assert(std::is_trivially_copyable<T>(), "type must be trivially copyable");
|
||||
static_assert(alignof(T) == 1, "type may have padding");
|
||||
static_assert(!has_padding<T>(), "source type may have padding");
|
||||
return {reinterpret_cast<const std::uint8_t*>(src.data()), src.size_bytes()};
|
||||
}
|
||||
|
||||
//! \return `span<std::uint8_t>` from a STL compatible `src`.
|
||||
template<typename T>
|
||||
constexpr span<std::uint8_t> to_mut_byte_span(T& src)
|
||||
{
|
||||
using value_type = typename T::value_type;
|
||||
static_assert(!std::is_empty<value_type>(), "empty value types will not work -> sizeof == 1");
|
||||
static_assert(std::is_standard_layout<value_type>(), "value type must have standard layout");
|
||||
static_assert(std::is_trivially_copyable<value_type>(), "value type must be trivially copyable");
|
||||
static_assert(alignof(value_type) == 1, "value type may have padding");
|
||||
return {reinterpret_cast<std::uint8_t*>(src.data()), src.size() * sizeof(value_type)};
|
||||
}
|
||||
|
||||
//! \return `span<const std::uint8_t>` which represents the bytes at `&src`.
|
||||
template<typename T>
|
||||
span<const std::uint8_t> as_byte_span(const T& src) noexcept
|
||||
{
|
||||
static_assert(!std::is_empty<T>(), "empty types will not work -> sizeof == 1");
|
||||
static_assert(std::is_standard_layout<T>(), "type must have standard layout");
|
||||
static_assert(std::is_trivially_copyable<T>(), "type must be trivially copyable");
|
||||
static_assert(alignof(T) == 1, "type may have padding");
|
||||
static_assert(!has_padding<T>(), "source type may have padding");
|
||||
return {reinterpret_cast<const std::uint8_t*>(std::addressof(src)), sizeof(T)};
|
||||
}
|
||||
|
||||
@@ -172,9 +161,7 @@ namespace epee
|
||||
span<std::uint8_t> as_mut_byte_span(T& src) noexcept
|
||||
{
|
||||
static_assert(!std::is_empty<T>(), "empty types will not work -> sizeof == 1");
|
||||
static_assert(std::is_standard_layout<T>(), "type must have standard layout");
|
||||
static_assert(std::is_trivially_copyable<T>(), "type must be trivially copyable");
|
||||
static_assert(alignof(T) == 1, "type may have padding");
|
||||
static_assert(!has_padding<T>(), "source type may have padding");
|
||||
return {reinterpret_cast<std::uint8_t*>(std::addressof(src)), sizeof(T)};
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
|
||||
#include <boost/utility/string_ref_fwd.hpp>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
namespace epee
|
||||
{
|
||||
|
||||
@@ -33,9 +33,6 @@
|
||||
#include "portable_storage_base.h"
|
||||
#include "portable_storage_bin_utils.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "serialization"
|
||||
|
||||
#ifdef EPEE_PORTABLE_STORAGE_RECURSION_LIMIT
|
||||
#define EPEE_PORTABLE_STORAGE_RECURSION_LIMIT_INTERNAL EPEE_PORTABLE_STORAGE_RECURSION_LIMIT
|
||||
#else
|
||||
|
||||
@@ -31,9 +31,6 @@
|
||||
#include "parserse_base_utils.h"
|
||||
#include "file_io_utils.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "serialization"
|
||||
|
||||
#define EPEE_JSON_RECURSION_LIMIT_INTERNAL 100
|
||||
|
||||
namespace epee
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#include "misc_log_ex.h"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/numeric/conversion/bounds.hpp>
|
||||
#include <typeinfo>
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include "mlocker.h"
|
||||
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
@@ -70,17 +69,23 @@ namespace string_tools
|
||||
#ifdef _WIN32
|
||||
std::string get_current_module_path();
|
||||
#endif
|
||||
void set_module_name_and_folder(const std::string& path_to_process_);
|
||||
bool set_module_name_and_folder(const std::string& path_to_process_);
|
||||
bool trim_left(std::string& str);
|
||||
bool trim_right(std::string& str);
|
||||
//----------------------------------------------------------------------------
|
||||
inline std::string& trim(std::string& str)
|
||||
{
|
||||
boost::trim(str);
|
||||
trim_left(str);
|
||||
trim_right(str);
|
||||
return str;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
inline std::string trim(const std::string& str)
|
||||
inline std::string trim(const std::string& str_)
|
||||
{
|
||||
return boost::trim_copy(str);
|
||||
std::string str = str_;
|
||||
trim_left(str);
|
||||
trim_right(str);
|
||||
return str;
|
||||
}
|
||||
std::string pad_string(std::string s, size_t n, char c = ' ', bool prepend = false);
|
||||
|
||||
@@ -89,7 +94,6 @@ namespace string_tools
|
||||
std::string pod_to_hex(const t_pod_type& s)
|
||||
{
|
||||
static_assert(std::is_standard_layout<t_pod_type>(), "expected standard layout type");
|
||||
static_assert(alignof(t_pod_type) == 1, "type may have padding");
|
||||
return to_hex::string(as_byte_span(s));
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -97,8 +101,6 @@ namespace string_tools
|
||||
bool hex_to_pod(const boost::string_ref hex_str, t_pod_type& s)
|
||||
{
|
||||
static_assert(std::is_standard_layout<t_pod_type>(), "expected standard layout type");
|
||||
static_assert(alignof(t_pod_type) == 1, "type may have padding");
|
||||
static_assert(std::is_trivially_copyable<t_pod_type>(), "type must be trivially copyable");
|
||||
return from_hex::to_buffer(as_mut_byte_span(s), hex_str);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -152,11 +152,7 @@ namespace epee
|
||||
{
|
||||
std::size_t space_needed = 0;
|
||||
for (const auto& source : sources)
|
||||
{
|
||||
if (std::numeric_limits<std::size_t>::max() - space_needed < source.size())
|
||||
throw std::bad_alloc{};
|
||||
space_needed += source.size();
|
||||
}
|
||||
|
||||
if (space_needed)
|
||||
{
|
||||
@@ -166,9 +162,9 @@ namespace epee
|
||||
|
||||
for (const auto& source : sources)
|
||||
{
|
||||
assert(source.size() <= out.size()); // see check above
|
||||
std::memcpy(out.data(), source.data(), source.size());
|
||||
out.remove_prefix(source.size());
|
||||
if (out.remove_prefix(source.size()) < source.size())
|
||||
throw std::bad_alloc{}; // size_t overflow on space_needed
|
||||
}
|
||||
storage_ = std::move(storage);
|
||||
}
|
||||
|
||||
@@ -176,12 +176,11 @@ void mlog_configure(const std::string &filename_base, bool console, const std::s
|
||||
std::vector<boost::filesystem::path> found_files;
|
||||
const boost::filesystem::directory_iterator end_itr;
|
||||
const boost::filesystem::path filename_base_path(filename_base);
|
||||
const std::string filename_base_name = filename_base_path.filename().string();
|
||||
const boost::filesystem::path parent_path = filename_base_path.has_parent_path() ? filename_base_path.parent_path() : ".";
|
||||
for (boost::filesystem::directory_iterator iter(parent_path); iter != end_itr; ++iter)
|
||||
{
|
||||
const std::string filename = iter->path().filename().string();
|
||||
if (filename.size() >= filename_base_name.size() && std::memcmp(filename.data(), filename_base_name.data(), filename_base_name.size()) == 0)
|
||||
const std::string filename = iter->path().string();
|
||||
if (filename.size() >= filename_base.size() && std::memcmp(filename.data(), filename_base.data(), filename_base.size()) == 0)
|
||||
{
|
||||
found_files.push_back(iter->path());
|
||||
}
|
||||
|
||||
@@ -496,13 +496,6 @@ void ssl_options_t::configure(
|
||||
const std::string& host) const
|
||||
{
|
||||
socket.next_layer().set_option(boost::asio::ip::tcp::no_delay(true));
|
||||
{
|
||||
// in case server is doing "virtual" domains, set hostname
|
||||
SSL* const ssl_ctx = socket.native_handle();
|
||||
if (type == boost::asio::ssl::stream_base::client && !host.empty() && ssl_ctx)
|
||||
SSL_set_tlsext_host_name(ssl_ctx, host.c_str());
|
||||
}
|
||||
|
||||
|
||||
/* Using system-wide CA store for client verification is funky - there is
|
||||
no expected hostname for server to verify against. If server doesn't have
|
||||
@@ -520,7 +513,11 @@ void ssl_options_t::configure(
|
||||
{
|
||||
socket.set_verify_mode(boost::asio::ssl::verify_peer | boost::asio::ssl::verify_fail_if_no_peer_cert);
|
||||
|
||||
|
||||
// in case server is doing "virtual" domains, set hostname
|
||||
SSL* const ssl_ctx = socket.native_handle();
|
||||
if (type == boost::asio::ssl::stream_base::client && !host.empty() && ssl_ctx)
|
||||
SSL_set_tlsext_host_name(ssl_ctx, host.c_str());
|
||||
|
||||
socket.set_verify_callback([&](const bool preverified, boost::asio::ssl::verify_context &ctx)
|
||||
{
|
||||
// preverified means it passed system or user CA check. System CA is never loaded
|
||||
|
||||
@@ -38,12 +38,9 @@
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <system_error>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include "misc_log_ex.h"
|
||||
#include "storages/parserse_base_utils.h"
|
||||
#include "hex.h"
|
||||
@@ -160,20 +157,46 @@ namespace string_tools
|
||||
return pname;
|
||||
}
|
||||
#endif
|
||||
|
||||
void set_module_name_and_folder(const std::string& path_to_process_)
|
||||
{
|
||||
boost::filesystem::path path_to_process = path_to_process_;
|
||||
|
||||
|
||||
bool set_module_name_and_folder(const std::string& path_to_process_)
|
||||
{
|
||||
std::string path_to_process = path_to_process_;
|
||||
#ifdef _WIN32
|
||||
path_to_process = get_current_module_path();
|
||||
#endif
|
||||
std::string::size_type a = path_to_process.rfind( '\\' );
|
||||
if(a == std::string::npos )
|
||||
{
|
||||
a = path_to_process.rfind( '/' );
|
||||
}
|
||||
if ( a != std::string::npos )
|
||||
{
|
||||
get_current_module_name() = path_to_process.substr(a+1, path_to_process.size());
|
||||
get_current_module_folder() = path_to_process.substr(0, a);
|
||||
return true;
|
||||
}else
|
||||
return false;
|
||||
|
||||
get_current_module_name() = path_to_process.filename().string();
|
||||
get_current_module_folder() = path_to_process.parent_path().string();
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool trim_left(std::string& str)
|
||||
{
|
||||
for(std::string::iterator it = str.begin(); it!= str.end() && isspace(static_cast<unsigned char>(*it));)
|
||||
str.erase(str.begin());
|
||||
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
bool trim_right(std::string& str)
|
||||
{
|
||||
|
||||
for(std::string::reverse_iterator it = str.rbegin(); it!= str.rend() && isspace(static_cast<unsigned char>(*it));)
|
||||
str.erase( --((it++).base()));
|
||||
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
std::string pad_string(std::string s, size_t n, char c, bool prepend)
|
||||
{
|
||||
if (s.size() < n)
|
||||
@@ -186,22 +209,28 @@ namespace string_tools
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string get_extension(const std::string& str)
|
||||
{
|
||||
std::string ext_with_dot = boost::filesystem::path(str).extension().string();
|
||||
|
||||
if (ext_with_dot.empty())
|
||||
return {};
|
||||
|
||||
return ext_with_dot.erase(0, 1);
|
||||
}
|
||||
|
||||
std::string get_extension(const std::string& str)
|
||||
{
|
||||
std::string res;
|
||||
std::string::size_type pos = str.rfind('.');
|
||||
if(std::string::npos == pos)
|
||||
return res;
|
||||
|
||||
res = str.substr(pos+1, str.size()-pos);
|
||||
return res;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cut_off_extension(const std::string& str)
|
||||
{
|
||||
return boost::filesystem::path(str).replace_extension("").string();
|
||||
}
|
||||
std::string cut_off_extension(const std::string& str)
|
||||
{
|
||||
std::string res;
|
||||
std::string::size_type pos = str.rfind('.');
|
||||
if(std::string::npos == pos)
|
||||
return str;
|
||||
|
||||
res = str.substr(0, pos);
|
||||
return res;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
#ifdef _WIN32
|
||||
std::wstring utf8_to_utf16(const std::string& str)
|
||||
{
|
||||
|
||||
@@ -57,7 +57,7 @@ The dockrun.sh script will do everything to build the binaries. Just specify the
|
||||
version to build as its only argument, e.g.
|
||||
|
||||
```bash
|
||||
VERSION=v0.18.3.4
|
||||
VERSION=v0.18.2.0
|
||||
./dockrun.sh $VERSION
|
||||
```
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ Common setup part:
|
||||
su - gitianuser
|
||||
|
||||
GH_USER=YOUR_GITHUB_USER_NAME
|
||||
VERSION=v0.18.3.4
|
||||
VERSION=v0.18.2.0
|
||||
```
|
||||
|
||||
Where `GH_USER` is your GitHub user name and `VERSION` is the version tag you want to build.
|
||||
|
||||
@@ -41,10 +41,10 @@ RUN useradd -ms /bin/bash -U ubuntu -G docker
|
||||
USER ubuntu:docker
|
||||
WORKDIR $WORKDIR
|
||||
|
||||
RUN git clone https://codeberg.org/wownero/gitian.sigs.git sigs; \
|
||||
RUN git clone https://git.wownero.com/wownero/gitian.sigs.git sigs; \
|
||||
git clone https://github.com/devrandom/gitian-builder.git builder; \
|
||||
cd builder; git checkout c0f77ca018cb5332bfd595e0aff0468f77542c23; mkdir -p inputs var; cd inputs; \
|
||||
git clone https://codeberg.org/wownero/wownero
|
||||
git clone https://git.wownero.com/wownero/wownero
|
||||
|
||||
CMD ["sleep", "infinity"]
|
||||
EOF
|
||||
@@ -109,7 +109,7 @@ if [ "$check" != "sign" ]; then
|
||||
fi
|
||||
|
||||
if [ ! -d sigs ]; then
|
||||
git clone https://codeberg.org/wownero/gitian.sigs.git sigs
|
||||
git clone https://git.wownero.com/wownero/gitian.sigs.git sigs
|
||||
cd sigs
|
||||
git remote add $GH_USER git@github.com:$GH_USER/gitian.sigs.git
|
||||
cd ..
|
||||
|
||||
@@ -26,7 +26,7 @@ packages:
|
||||
- "cmake"
|
||||
- "unzip"
|
||||
remotes:
|
||||
- "url": "https://codeberg.org/wownero/wownero.git"
|
||||
- "url": "https://git.wownero.com/wownero/wownero.git"
|
||||
"dir": "wownero"
|
||||
files: []
|
||||
script: |
|
||||
|
||||
@@ -5,7 +5,7 @@ import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
gsigs = 'https://codeberg.org/wownero/gitian.sigs.git'
|
||||
gsigs = 'https://git.wownero.com/wownero/gitian.sigs.git'
|
||||
gbrepo = 'https://github.com/devrandom/gitian-builder.git'
|
||||
|
||||
platforms = {'l': ['Linux', 'linux', 'tar.bz2'],
|
||||
@@ -113,7 +113,7 @@ def main():
|
||||
parser = argparse.ArgumentParser(description='Script for running full Gitian builds.', usage='%(prog)s [options] signer version')
|
||||
parser.add_argument('-c', '--commit', action='store_true', dest='commit', help='Indicate that the version argument is for a commit or branch')
|
||||
parser.add_argument('-p', '--pull', action='store_true', dest='pull', help='Indicate that the version argument is the number of a github repository pull request')
|
||||
parser.add_argument('-u', '--url', dest='url', default='https://codeberg.org/wownero/wownero', help='Specify the URL of the repository. Default is %(default)s')
|
||||
parser.add_argument('-u', '--url', dest='url', default='https://git.wownero.com/wownero/wownero', help='Specify the URL of the repository. Default is %(default)s')
|
||||
parser.add_argument('-v', '--verify', action='store_true', dest='verify', help='Verify the Gitian build')
|
||||
parser.add_argument('-b', '--build', action='store_true', dest='build', help='Do a Gitian build')
|
||||
parser.add_argument('-B', '--buildsign', action='store_true', dest='buildsign', help='Build both signed and unsigned binaries')
|
||||
|
||||
@@ -26,7 +26,7 @@ packages:
|
||||
- "python"
|
||||
- "cmake"
|
||||
remotes:
|
||||
- "url": "https://codeberg.org/wownero/wownero.git"
|
||||
- "url": "https://git.wownero.com/wownero/wownero.git"
|
||||
"dir": "wownero"
|
||||
files: []
|
||||
script: |
|
||||
|
||||
@@ -21,7 +21,6 @@ packages:
|
||||
- "g++-7-arm-linux-gnueabihf"
|
||||
- "gcc-arm-linux-gnueabihf"
|
||||
- "g++-arm-linux-gnueabihf"
|
||||
- "g++-riscv64-linux-gnu"
|
||||
- "g++-7-multilib"
|
||||
- "gcc-7-multilib"
|
||||
- "binutils-arm-linux-gnueabihf"
|
||||
@@ -38,13 +37,13 @@ packages:
|
||||
- "python"
|
||||
- "cmake"
|
||||
remotes:
|
||||
- "url": "https://codeberg.org/wownero/wownero.git"
|
||||
- "url": "https://git.wownero.com/wownero/wownero.git"
|
||||
"dir": "wownero"
|
||||
files: []
|
||||
script: |
|
||||
|
||||
WRAP_DIR=$HOME/wrapped
|
||||
HOSTS="x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu i686-linux-gnu riscv64-linux-gnu"
|
||||
HOSTS="x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu i686-linux-gnu"
|
||||
FAKETIME_HOST_PROGS=""
|
||||
FAKETIME_PROGS="date"
|
||||
HOST_CFLAGS="-O2 -g"
|
||||
@@ -160,13 +159,7 @@ script: |
|
||||
fi
|
||||
export C_INCLUDE_PATH="$EXTRA_INCLUDES"
|
||||
export CPLUS_INCLUDE_PATH="$EXTRA_INCLUDES"
|
||||
# glibc only added riscv support in 2.27, disable backwards compatibility
|
||||
if [ "$i" == "riscv64-linux-gnu" ]; then
|
||||
BACKCOMPAT_OPTION=OFF
|
||||
else
|
||||
BACKCOMPAT_OPTION=ON
|
||||
fi
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake -DBACKCOMPAT=${BACKCOMPAT_OPTION} -DCMAKE_SKIP_RPATH=ON
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake -DBACKCOMPAT=ON -DCMAKE_SKIP_RPATH=ON
|
||||
make ${MAKEOPTS}
|
||||
chmod 755 bin/*
|
||||
cp ../utils/conf/wow.conf bin
|
||||
|
||||
@@ -24,7 +24,7 @@ packages:
|
||||
- "python-dev"
|
||||
- "python-setuptools"
|
||||
remotes:
|
||||
- "url": "https://codeberg.org/wownero/wownero.git"
|
||||
- "url": "https://git.wownero.com/wownero/wownero.git"
|
||||
"dir": "wownero"
|
||||
files: []
|
||||
script: |
|
||||
|
||||
@@ -35,7 +35,7 @@ alternatives:
|
||||
package: "x86_64-w64-mingw32-gcc"
|
||||
path: "/usr/bin/x86_64-w64-mingw32-gcc-posix"
|
||||
remotes:
|
||||
- "url": "https://codeberg.org/wownero/wownero.git"
|
||||
- "url": "https://git.wownero.com/wownero/wownero.git"
|
||||
"dir": "wownero"
|
||||
files: []
|
||||
script: |
|
||||
|
||||
@@ -71,13 +71,13 @@ type, and max connections:
|
||||
|
||||
```
|
||||
--anonymous-inbound rveahdfho7wo4b2m.onion:28083,127.0.0.1:28083,25
|
||||
--anonymous-inbound cmeua5767mz2q5jsaelk2rxhf67agrwuetaso5dzbenyzwlbkg2q.b32.i2p,127.0.0.1:30000
|
||||
--anonymous-inbound cmeua5767mz2q5jsaelk2rxhf67agrwuetaso5dzbenyzwlbkg2q.b32.i2p:5000,127.0.0.1:30000
|
||||
```
|
||||
|
||||
which tells `monerod` that a max of 25 inbound Tor connections are being
|
||||
received at address "rveahdfho7wo4b2m.onion:28083" and forwarded to `monerod`
|
||||
localhost port 28083, and a default max I2P connections are being received at
|
||||
address "cmeua5767mz2q5jsaelk2rxhf67agrwuetaso5dzbenyzwlbkg2q.b32.i2p" and
|
||||
address "cmeua5767mz2q5jsaelk2rxhf67agrwuetaso5dzbenyzwlbkg2q.b32.i2p:5000" and
|
||||
forwarded to `monerod` localhost port 30000.
|
||||
These addresses will be shared with outgoing peers, over the same network type,
|
||||
otherwise the peer will not be notified of the peer address by the proxy.
|
||||
|
||||
2
external/randomwow
vendored
2
external/randomwow
vendored
Submodule external/randomwow updated: 27b099b6dd...607bad48f3
@@ -52,9 +52,11 @@ using namespace cryptonote;
|
||||
static std::string db_path;
|
||||
|
||||
// default to fast:1
|
||||
static uint64_t records_per_sync = 128;
|
||||
static uint64_t records_per_sync = 16 * 65536;
|
||||
static const size_t slack = 512 * 1024 * 1024;
|
||||
|
||||
static std::vector<bool> is_v1;
|
||||
|
||||
static std::error_code replace_file(const boost::filesystem::path& replacement_name, const boost::filesystem::path& replaced_name)
|
||||
{
|
||||
std::error_code ec = tools::replace_file(replacement_name.string(), replaced_name.string());
|
||||
@@ -89,6 +91,14 @@ static void close(MDB_env *env)
|
||||
mdb_env_close(env);
|
||||
}
|
||||
|
||||
static void mark_v1_tx(const MDB_val &k, const MDB_val &v)
|
||||
{
|
||||
const uint64_t tx_id = *(const uint64_t*)k.mv_data;
|
||||
if (tx_id >= is_v1.size())
|
||||
is_v1.resize(tx_id + 1, false);
|
||||
is_v1[tx_id] = cryptonote::is_v1_tx(cryptonote::blobdata_ref{(const char*)v.mv_data, v.mv_size});
|
||||
}
|
||||
|
||||
static void add_size(MDB_env *env, uint64_t bytes)
|
||||
{
|
||||
try
|
||||
@@ -136,7 +146,7 @@ static void check_resize(MDB_env *env, size_t bytes)
|
||||
add_size(env, size_used + bytes + 2 * slack - mei.me_mapsize);
|
||||
}
|
||||
|
||||
static bool resize_point(size_t nrecords, MDB_env *env, MDB_txn **txn, size_t &bytes)
|
||||
static bool resize_point(size_t &nrecords, MDB_env *env, MDB_txn **txn, size_t &bytes)
|
||||
{
|
||||
if (nrecords % records_per_sync && bytes <= slack / 2)
|
||||
return false;
|
||||
@@ -146,10 +156,11 @@ static bool resize_point(size_t nrecords, MDB_env *env, MDB_txn **txn, size_t &b
|
||||
dbr = mdb_txn_begin(env, NULL, 0, txn);
|
||||
if (dbr) throw std::runtime_error("Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr)));
|
||||
bytes = 0;
|
||||
nrecords = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void copy_table(MDB_env *env0, MDB_env *env1, const char *table, unsigned int flags, unsigned int putflags, int (*cmp)(const MDB_val*, const MDB_val*)=0)
|
||||
static void copy_table(MDB_env *env0, MDB_env *env1, const char *table, unsigned int flags, unsigned int putflags, int (*cmp)(const MDB_val*, const MDB_val*)=0, void (*f)(const MDB_val&, const MDB_val&) = 0)
|
||||
{
|
||||
MDB_dbi dbi0, dbi1;
|
||||
MDB_txn *txn0, *txn1;
|
||||
@@ -200,6 +211,11 @@ static void copy_table(MDB_env *env0, MDB_env *env1, const char *table, unsigned
|
||||
dbr = mdb_cursor_open(txn1, dbi1, &cur1);
|
||||
if (dbr) throw std::runtime_error("Failed to create LMDB cursor: " + std::string(mdb_strerror(dbr)));
|
||||
|
||||
if (flags & MDB_DUPSORT)
|
||||
putflags |= MDB_APPENDDUP;
|
||||
else
|
||||
putflags |= MDB_APPEND;
|
||||
|
||||
MDB_val k;
|
||||
MDB_val v;
|
||||
MDB_cursor_op op = MDB_FIRST;
|
||||
@@ -214,7 +230,8 @@ static void copy_table(MDB_env *env0, MDB_env *env1, const char *table, unsigned
|
||||
throw std::runtime_error("Failed to enumerate " + std::string(table) + " records: " + std::string(mdb_strerror(ret)));
|
||||
|
||||
bytes += k.mv_size + v.mv_size;
|
||||
if (resize_point(++nrecords, env1, &txn1, bytes))
|
||||
++nrecords;
|
||||
if (resize_point(nrecords, env1, &txn1, bytes))
|
||||
{
|
||||
dbr = mdb_cursor_open(txn1, dbi1, &cur1);
|
||||
if (dbr) throw std::runtime_error("Failed to create LMDB cursor: " + std::string(mdb_strerror(dbr)));
|
||||
@@ -223,6 +240,9 @@ static void copy_table(MDB_env *env0, MDB_env *env1, const char *table, unsigned
|
||||
ret = mdb_cursor_put(cur1, &k, &v, putflags);
|
||||
if (ret)
|
||||
throw std::runtime_error("Failed to write " + std::string(table) + " record: " + std::string(mdb_strerror(ret)));
|
||||
|
||||
if (f)
|
||||
(*f)(k, v);
|
||||
}
|
||||
|
||||
mdb_cursor_close(cur1);
|
||||
@@ -235,17 +255,6 @@ static void copy_table(MDB_env *env0, MDB_env *env1, const char *table, unsigned
|
||||
mdb_dbi_close(env0, dbi0);
|
||||
}
|
||||
|
||||
static bool is_v1_tx(MDB_cursor *c_txs_pruned, MDB_val *tx_id)
|
||||
{
|
||||
MDB_val v;
|
||||
int ret = mdb_cursor_get(c_txs_pruned, tx_id, &v, MDB_SET);
|
||||
if (ret)
|
||||
throw std::runtime_error("Failed to find transaction pruned data: " + std::string(mdb_strerror(ret)));
|
||||
if (v.mv_size == 0)
|
||||
throw std::runtime_error("Invalid transaction pruned data");
|
||||
return cryptonote::is_v1_tx(cryptonote::blobdata_ref{(const char*)v.mv_data, v.mv_size});
|
||||
}
|
||||
|
||||
static void prune(MDB_env *env0, MDB_env *env1)
|
||||
{
|
||||
MDB_dbi dbi0_blocks, dbi0_txs_pruned, dbi0_txs_prunable, dbi0_tx_indices, dbi1_txs_prunable, dbi1_txs_prunable_tip, dbi1_properties;
|
||||
@@ -324,7 +333,10 @@ static void prune(MDB_env *env0, MDB_env *env1)
|
||||
mdb_dbi_close(env0, dbi0_blocks);
|
||||
const uint64_t blockchain_height = stats.ms_entries;
|
||||
size_t nrecords = 0, bytes = 0;
|
||||
std::vector<bool> prunable_needed;
|
||||
|
||||
// go through all txes tx indices, recording which ones should have their prunable part retained
|
||||
MINFO("Marking prunable txes");
|
||||
MDB_cursor_op op = MDB_FIRST;
|
||||
while (1)
|
||||
{
|
||||
@@ -336,7 +348,8 @@ static void prune(MDB_env *env0, MDB_env *env1)
|
||||
|
||||
const txindex *ti = (const txindex*)v.mv_data;
|
||||
const uint64_t block_height = ti->data.block_id;
|
||||
MDB_val_set(kk, ti->data.tx_id);
|
||||
const uint64_t tx_id = ti->data.tx_id;
|
||||
MDB_val_set(kk, tx_id);
|
||||
if (block_height + CRYPTONOTE_PRUNING_TIP_BLOCKS >= blockchain_height)
|
||||
{
|
||||
MDEBUG(block_height << "/" << blockchain_height << " is in tip");
|
||||
@@ -344,22 +357,23 @@ static void prune(MDB_env *env0, MDB_env *env1)
|
||||
dbr = mdb_cursor_put(cur1_txs_prunable_tip, &kk, &vv, 0);
|
||||
if (dbr) throw std::runtime_error("Failed to write prunable tx tip data: " + std::string(mdb_strerror(dbr)));
|
||||
bytes += kk.mv_size + vv.mv_size;
|
||||
}
|
||||
if (tools::has_unpruned_block(block_height, blockchain_height, pruning_seed) || is_v1_tx(cur0_txs_pruned, &kk))
|
||||
{
|
||||
MDB_val vv;
|
||||
dbr = mdb_cursor_get(cur0_txs_prunable, &kk, &vv, MDB_SET);
|
||||
if (dbr) throw std::runtime_error("Failed to read prunable tx data: " + std::string(mdb_strerror(dbr)));
|
||||
bytes += kk.mv_size + vv.mv_size;
|
||||
if (resize_point(++nrecords, env1, &txn1, bytes))
|
||||
|
||||
++nrecords;
|
||||
if (resize_point(nrecords, env1, &txn1, bytes))
|
||||
{
|
||||
dbr = mdb_cursor_open(txn1, dbi1_txs_prunable, &cur1_txs_prunable);
|
||||
if (dbr) throw std::runtime_error("Failed to create LMDB cursor: " + std::string(mdb_strerror(dbr)));
|
||||
dbr = mdb_cursor_open(txn1, dbi1_txs_prunable_tip, &cur1_txs_prunable_tip);
|
||||
if (dbr) throw std::runtime_error("Failed to create LMDB cursor: " + std::string(mdb_strerror(dbr)));
|
||||
}
|
||||
dbr = mdb_cursor_put(cur1_txs_prunable, &kk, &vv, 0);
|
||||
if (dbr) throw std::runtime_error("Failed to write prunable tx data: " + std::string(mdb_strerror(dbr)));
|
||||
}
|
||||
if (tx_id >= is_v1.size())
|
||||
throw std::runtime_error("tx_id out of range of is_v1 vector");
|
||||
if (tools::has_unpruned_block(block_height, blockchain_height, pruning_seed) || is_v1[tx_id])
|
||||
{
|
||||
if (tx_id >= prunable_needed.size())
|
||||
prunable_needed.resize(tx_id + 1, false);
|
||||
prunable_needed[tx_id] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -367,6 +381,37 @@ static void prune(MDB_env *env0, MDB_env *env1)
|
||||
}
|
||||
}
|
||||
|
||||
// go through prunable parts, carrying over those we need
|
||||
MINFO("Copying retained prunable data");
|
||||
op = MDB_FIRST;
|
||||
while (1)
|
||||
{
|
||||
int ret = mdb_cursor_get(cur0_txs_prunable, &k, &v, op);
|
||||
op = MDB_NEXT;
|
||||
if (ret == MDB_NOTFOUND)
|
||||
break;
|
||||
if (ret) throw std::runtime_error("Failed to enumerate records: " + std::string(mdb_strerror(ret)));
|
||||
|
||||
const uint64_t tx_id = *(const uint64_t*)k.mv_data;
|
||||
if (tx_id >= prunable_needed.size())
|
||||
throw std::runtime_error("tx_id out of range of prunable_needed vector");
|
||||
if (prunable_needed[tx_id])
|
||||
{
|
||||
dbr = mdb_cursor_put(cur1_txs_prunable, &k, &v, MDB_APPEND);
|
||||
if (dbr) throw std::runtime_error("Failed to write prunable tx data: " + std::string(mdb_strerror(dbr)));
|
||||
|
||||
bytes += k.mv_size + v.mv_size;
|
||||
++nrecords;
|
||||
if (resize_point(nrecords, env1, &txn1, bytes))
|
||||
{
|
||||
dbr = mdb_cursor_open(txn1, dbi1_txs_prunable, &cur1_txs_prunable);
|
||||
if (dbr) throw std::runtime_error("Failed to create LMDB cursor: " + std::string(mdb_strerror(dbr)));
|
||||
dbr = mdb_cursor_open(txn1, dbi1_txs_prunable_tip, &cur1_txs_prunable_tip);
|
||||
if (dbr) throw std::runtime_error("Failed to create LMDB cursor: " + std::string(mdb_strerror(dbr)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mdb_cursor_close(cur1_txs_prunable_tip);
|
||||
mdb_cursor_close(cur1_txs_prunable);
|
||||
mdb_cursor_close(cur0_txs_prunable);
|
||||
@@ -419,7 +464,7 @@ static bool parse_db_sync_mode(std::string db_sync_mode, uint64_t &db_flags)
|
||||
else if(options[0] == "fastest")
|
||||
{
|
||||
db_flags = DBF_FASTEST;
|
||||
records_per_sync = 1000; // default to fastest:async:1000
|
||||
// default to fastest:async:N
|
||||
}
|
||||
else
|
||||
return false;
|
||||
@@ -455,7 +500,7 @@ int main(int argc, char* argv[])
|
||||
const command_line::arg_descriptor<std::string> arg_db_sync_mode = {
|
||||
"db-sync-mode"
|
||||
, "Specify sync option, using format [safe|fast|fastest]:[nrecords_per_sync]."
|
||||
, "fast:1000"
|
||||
, "fast:" + std::to_string(records_per_sync)
|
||||
};
|
||||
const command_line::arg_descriptor<bool> arg_copy_pruned_database = {"copy-pruned-database", "Copy database anyway if already pruned"};
|
||||
|
||||
@@ -601,26 +646,27 @@ int main(int argc, char* argv[])
|
||||
MDB_env *env0 = NULL, *env1 = NULL;
|
||||
open(env0, paths[0], db_flags, true);
|
||||
open(env1, paths[1], db_flags, false);
|
||||
copy_table(env0, env1, "blocks", MDB_INTEGERKEY, MDB_APPEND);
|
||||
copy_table(env0, env1, "block_info", MDB_INTEGERKEY | MDB_DUPSORT| MDB_DUPFIXED, MDB_APPENDDUP, BlockchainLMDB::compare_uint64);
|
||||
copy_table(env0, env1, "blocks", MDB_INTEGERKEY, 0);
|
||||
copy_table(env0, env1, "block_info", MDB_INTEGERKEY | MDB_DUPSORT| MDB_DUPFIXED, 0, BlockchainLMDB::compare_uint64);
|
||||
copy_table(env0, env1, "block_heights", MDB_INTEGERKEY | MDB_DUPSORT| MDB_DUPFIXED, 0, BlockchainLMDB::compare_hash32);
|
||||
//copy_table(env0, env1, "txs", MDB_INTEGERKEY);
|
||||
copy_table(env0, env1, "txs_pruned", MDB_INTEGERKEY, MDB_APPEND);
|
||||
copy_table(env0, env1, "txs_prunable_hash", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, MDB_APPEND);
|
||||
copy_table(env0, env1, "txs_pruned", MDB_INTEGERKEY, 0, NULL, &mark_v1_tx);
|
||||
copy_table(env0, env1, "txs_prunable_hash", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, 0);
|
||||
// not copied: prunable, prunable_tip
|
||||
copy_table(env0, env1, "tx_indices", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, 0, BlockchainLMDB::compare_hash32);
|
||||
copy_table(env0, env1, "tx_outputs", MDB_INTEGERKEY, MDB_APPEND);
|
||||
copy_table(env0, env1, "output_txs", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, MDB_APPENDDUP, BlockchainLMDB::compare_uint64);
|
||||
copy_table(env0, env1, "output_amounts", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, MDB_APPENDDUP, BlockchainLMDB::compare_uint64);
|
||||
copy_table(env0, env1, "spent_keys", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, MDB_NODUPDATA, BlockchainLMDB::compare_hash32);
|
||||
copy_table(env0, env1, "txpool_meta", 0, MDB_NODUPDATA, BlockchainLMDB::compare_hash32);
|
||||
copy_table(env0, env1, "txpool_blob", 0, MDB_NODUPDATA, BlockchainLMDB::compare_hash32);
|
||||
copy_table(env0, env1, "hf_versions", MDB_INTEGERKEY, MDB_APPEND);
|
||||
copy_table(env0, env1, "tx_outputs", MDB_INTEGERKEY, 0);
|
||||
copy_table(env0, env1, "output_txs", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, 0, BlockchainLMDB::compare_uint64);
|
||||
copy_table(env0, env1, "output_amounts", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, 0, BlockchainLMDB::compare_uint64);
|
||||
copy_table(env0, env1, "spent_keys", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, 0, BlockchainLMDB::compare_hash32);
|
||||
copy_table(env0, env1, "txpool_meta", 0, 0, BlockchainLMDB::compare_hash32);
|
||||
copy_table(env0, env1, "txpool_blob", 0, 0, BlockchainLMDB::compare_hash32);
|
||||
copy_table(env0, env1, "alt_blocks", 0, 0, BlockchainLMDB::compare_hash32);
|
||||
copy_table(env0, env1, "hf_versions", MDB_INTEGERKEY, 0);
|
||||
copy_table(env0, env1, "properties", 0, 0, BlockchainLMDB::compare_string);
|
||||
if (already_pruned)
|
||||
{
|
||||
copy_table(env0, env1, "txs_prunable", MDB_INTEGERKEY, MDB_APPEND, BlockchainLMDB::compare_uint64);
|
||||
copy_table(env0, env1, "txs_prunable_tip", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, MDB_NODUPDATA, BlockchainLMDB::compare_uint64);
|
||||
copy_table(env0, env1, "txs_prunable", MDB_INTEGERKEY, 0, BlockchainLMDB::compare_uint64);
|
||||
copy_table(env0, env1, "txs_prunable_tip", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, 0, BlockchainLMDB::compare_uint64);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Binary file not shown.
@@ -233,7 +233,12 @@ namespace cryptonote
|
||||
ADD_CHECKPOINT2(489400, "b14f49eae77398117ea93435676100d8b655a804689f73a5a4d0d5e71160d603", "0x1123c39bb52f7e");
|
||||
ADD_CHECKPOINT2(491200, "cedba73ad35ce7f51aaca2beb36dc32d79ecc716d146eb8211e6a815f3666c4a", "0x11334734abbd17");
|
||||
ADD_CHECKPOINT2(497100, "2c4c70ac1ada94151f19d67ccf1aa4e846e6067f49f67c85cc03f78e768ea42b", "0x116906bc97a751");
|
||||
ADD_CHECKPOINT2(691500, "ed8e2507c0938b7eab7b02eccfb3506aeb591e51fbf6cf145fcc60ea2d351025", "0x163a280f2ce8e3");
|
||||
ADD_CHECKPOINT2(500000, "f4f771261b8c13cd83a9d8fa22e3cfe988564ad4b57dd90e79d5c0e77d61cf6a", "0x1185e7f2357a03");
|
||||
ADD_CHECKPOINT2(503500, "776f36a17056c3e22bbfb51d5aeabb58000731e9ad549f0f2f8ad1e1bcedf312", "0x11a4884467f53d");
|
||||
ADD_CHECKPOINT2(509900, "59520faa272fc68e0426c827a38b21cdc1df8f5a37c5fdcbbe00350fece5f3ae", "0x11dc780bd1b580");
|
||||
ADD_CHECKPOINT2(514000, "1569e712750f19e57aee3f73cc3091a0eea392740bd396ad3570bc96e0e6ffb5", "0x11fff58abe0a82"); //Hard fork to v20
|
||||
ADD_CHECKPOINT2(516700, "0443c47c5a4e344c3f68a491a3b2f6b78a769cdf9076249c93f187ececf9cc7c", "0x12128a532a59a6");
|
||||
ADD_CHECKPOINT2(522000, "8c15ae514063bf05e7662ab33b86a4131aa89df0784ce3da7876c5339bc1de3d", "0x123d9c604a7be6");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -279,6 +284,7 @@ namespace cryptonote
|
||||
|
||||
// All four MoneroPulse domains have DNSSEC on and valid
|
||||
static const std::vector<std::string> dns_urls = {
|
||||
"checkpoints.muchwow.lol",
|
||||
};
|
||||
|
||||
static const std::vector<std::string> testnet_dns_urls = {
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include <boost/archive/portable_binary_iarchive.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
|
||||
#include "common/util.h"
|
||||
|
||||
namespace tools
|
||||
{
|
||||
@@ -111,7 +110,7 @@ namespace tools
|
||||
catch(...)
|
||||
{
|
||||
// if failed, try reading in unportable mode
|
||||
tools::copy_file(file_path, file_path + ".unportable");
|
||||
boost::filesystem::copy_file(file_path, file_path + ".unportable", boost::filesystem::copy_option::overwrite_if_exists);
|
||||
data_file.close();
|
||||
data_file.open( file_path, std::ios_base::binary | std::ios_base::in);
|
||||
if(data_file.fail())
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <cstdint>
|
||||
|
||||
namespace tools {
|
||||
|
||||
|
||||
@@ -526,12 +526,12 @@ bool load_txt_records_from_dns(std::vector<std::string> &good_records, const std
|
||||
const std::string &url = dns_urls[cur_index];
|
||||
if (!avail[cur_index])
|
||||
{
|
||||
records[cur_index].clear();
|
||||
//records[cur_index].clear(); TODO: temp skipped DNSSEC
|
||||
LOG_PRINT_L2("DNSSEC not available for hostname: " << url << ", skipping.");
|
||||
}
|
||||
if (!valid[cur_index])
|
||||
{
|
||||
records[cur_index].clear();
|
||||
//records[cur_index].clear(); TODO: temp skipped DNSSEC
|
||||
LOG_PRINT_L2("DNSSEC validation failed for hostname: " << url << ", skipping.");
|
||||
}
|
||||
|
||||
@@ -552,7 +552,7 @@ bool load_txt_records_from_dns(std::vector<std::string> &good_records, const std
|
||||
}
|
||||
}
|
||||
|
||||
if (num_valid_records < 2)
|
||||
if (num_valid_records < 1)
|
||||
{
|
||||
LOG_PRINT_L2("WARNING: no two valid DNS TXT records were received");
|
||||
return false;
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace tools
|
||||
while (1)
|
||||
{
|
||||
t1 = epee::misc_utils::get_ns_count();
|
||||
if (t1 - t0 > 1*100000000) break; // work 0.1 seconds
|
||||
if (t1 - t0 > 1*1000000000) break; // work one second
|
||||
}
|
||||
|
||||
uint64_t r1 = get_tick_count();
|
||||
|
||||
@@ -115,24 +115,6 @@ static int flock_exnb(int fd)
|
||||
|
||||
namespace tools
|
||||
{
|
||||
|
||||
void copy_file(const std::string& from, const std::string& to)
|
||||
{
|
||||
using boost::filesystem::path;
|
||||
#if BOOST_VERSION < 107400
|
||||
// Remove this preprocessor if/else when we are bumping the boost version.
|
||||
boost::filesystem::copy_file(
|
||||
path(from),
|
||||
path(to),
|
||||
boost::filesystem::copy_option::overwrite_if_exists);
|
||||
#else
|
||||
boost::filesystem::copy_file(
|
||||
path(from),
|
||||
path(to),
|
||||
boost::filesystem::copy_options::overwrite_existing);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::function<void(int)> signal_handler::m_handler;
|
||||
|
||||
private_file::private_file() noexcept : m_handle(), m_filename() {}
|
||||
@@ -140,7 +122,7 @@ namespace tools
|
||||
private_file::private_file(std::FILE* handle, std::string&& filename) noexcept
|
||||
: m_handle(handle), m_filename(std::move(filename)) {}
|
||||
|
||||
private_file private_file::create(std::string name, uint32_t extra_flags)
|
||||
private_file private_file::create(std::string name)
|
||||
{
|
||||
#ifdef WIN32
|
||||
struct close_handle
|
||||
@@ -193,7 +175,7 @@ namespace tools
|
||||
name.c_str(),
|
||||
GENERIC_WRITE, FILE_SHARE_READ,
|
||||
std::addressof(attributes),
|
||||
CREATE_NEW, (FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE | extra_flags),
|
||||
CREATE_NEW, (FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE),
|
||||
nullptr
|
||||
)
|
||||
};
|
||||
@@ -212,7 +194,7 @@ namespace tools
|
||||
}
|
||||
}
|
||||
#else
|
||||
const int fdr = open(name.c_str(), (O_RDONLY | O_CREAT | extra_flags), S_IRUSR);
|
||||
const int fdr = open(name.c_str(), (O_RDONLY | O_CREAT), S_IRUSR);
|
||||
if (0 <= fdr)
|
||||
{
|
||||
struct stat rstats = {};
|
||||
@@ -243,23 +225,6 @@ namespace tools
|
||||
return {};
|
||||
}
|
||||
|
||||
private_file private_file::drop_and_recreate(std::string filename)
|
||||
{
|
||||
if (epee::file_io_utils::is_file_exist(filename)) {
|
||||
boost::system::error_code ec{};
|
||||
boost::filesystem::remove(filename, ec);
|
||||
if (ec) {
|
||||
MERROR("Failed to remove " << filename << ": " << ec.message());
|
||||
return {};
|
||||
}
|
||||
}
|
||||
#ifdef WIN32
|
||||
return create(filename);
|
||||
#else
|
||||
return create(filename, O_EXCL);
|
||||
#endif
|
||||
}
|
||||
|
||||
private_file::~private_file() noexcept
|
||||
{
|
||||
try
|
||||
@@ -917,6 +882,13 @@ std::string get_nix_version_display_string()
|
||||
|
||||
bool is_local_address(const std::string &address)
|
||||
{
|
||||
// always assume Tor/I2P addresses to be untrusted by default
|
||||
if (is_privacy_preserving_network(address))
|
||||
{
|
||||
MDEBUG("Address '" << address << "' is Tor/I2P, non local");
|
||||
return false;
|
||||
}
|
||||
|
||||
// extract host
|
||||
epee::net_utils::http::url_content u_c;
|
||||
if (!epee::net_utils::parse_url(address, u_c))
|
||||
@@ -930,22 +902,20 @@ std::string get_nix_version_display_string()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (u_c.host == "localhost" || boost::ends_with(u_c.host, ".localhost")) { // RFC 6761 (6.3)
|
||||
MDEBUG("Address '" << address << "' is local");
|
||||
return true;
|
||||
}
|
||||
|
||||
boost::system::error_code ec;
|
||||
const auto parsed_ip = boost::asio::ip::address::from_string(u_c.host, ec);
|
||||
if (ec) {
|
||||
MDEBUG("Failed to parse '" << address << "' as IP address: " << ec.message() << ". Considering it not local");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parsed_ip.is_loopback())
|
||||
// resolve to IP
|
||||
boost::asio::io_service io_service;
|
||||
boost::asio::ip::tcp::resolver resolver(io_service);
|
||||
boost::asio::ip::tcp::resolver::query query(u_c.host, "");
|
||||
boost::asio::ip::tcp::resolver::iterator i = resolver.resolve(query);
|
||||
while (i != boost::asio::ip::tcp::resolver::iterator())
|
||||
{
|
||||
MDEBUG("Address '" << address << "' is local");
|
||||
return true;
|
||||
const boost::asio::ip::tcp::endpoint &ep = *i;
|
||||
if (ep.address().is_loopback())
|
||||
{
|
||||
MDEBUG("Address '" << address << "' is local");
|
||||
return true;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
MDEBUG("Address '" << address << "' is not local");
|
||||
@@ -1097,7 +1067,7 @@ std::string get_nix_version_display_string()
|
||||
time_t tt = ts;
|
||||
struct tm tm;
|
||||
misc_utils::get_gmt_time(tt, tm);
|
||||
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tm);
|
||||
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%SZ", &tm);
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
|
||||
@@ -67,8 +67,6 @@ namespace tools
|
||||
}
|
||||
};
|
||||
|
||||
void copy_file(const std::string& from, const std::string& to);
|
||||
|
||||
//! A file restricted to process owner AND process. Deletes file on destruction.
|
||||
class private_file {
|
||||
std::unique_ptr<std::FILE, close_file> m_handle;
|
||||
@@ -82,11 +80,7 @@ namespace tools
|
||||
|
||||
/*! \return File only readable by owner and only used by this process
|
||||
OR `private_file{}` on error. */
|
||||
static private_file create(std::string filename, uint32_t extra_flags = 0);
|
||||
|
||||
/*! \return Drop and create file only readable by owner and only used
|
||||
by this process OR `private_file{}` on error. */
|
||||
static private_file drop_and_recreate(std::string filename);
|
||||
static private_file create(std::string filename);
|
||||
|
||||
private_file(private_file&&) = default;
|
||||
private_file& operator=(private_file&&) = default;
|
||||
|
||||
@@ -171,9 +171,7 @@ namespace crypto {
|
||||
/* Generate a value filled with random bytes.
|
||||
*/
|
||||
template<typename T>
|
||||
T rand() {
|
||||
static_assert(std::is_standard_layout<T>(), "cannot write random bytes into non-standard layout type");
|
||||
static_assert(std::is_trivially_copyable<T>(), "cannot write random bytes into non-trivially copyable type");
|
||||
typename std::enable_if<std::is_pod<T>::value, T>::type rand() {
|
||||
typename std::remove_cv<T>::type res;
|
||||
generate_random_bytes_thread_safe(sizeof(T), (uint8_t*)&res);
|
||||
return res;
|
||||
@@ -316,14 +314,8 @@ namespace crypto {
|
||||
inline std::ostream &operator <<(std::ostream &o, const crypto::public_key &v) {
|
||||
epee::to_hex::formatted(o, epee::as_byte_span(v)); return o;
|
||||
}
|
||||
/* Do NOT overload the << operator for crypto::secret_key here. Use secret_key_explicit_print_ref
|
||||
* instead to prevent accidental implicit dumping of secret key material to the logs (which has
|
||||
* happened before). For the same reason, do not overload it for crypto::ec_scalar either since
|
||||
* crypto::secret_key is a subclass. I'm not sorry that it's obtuse; that's the point, bozo.
|
||||
*/
|
||||
struct secret_key_explicit_print_ref { const crypto::secret_key &sk; };
|
||||
inline std::ostream &operator <<(std::ostream &o, const secret_key_explicit_print_ref v) {
|
||||
epee::to_hex::formatted(o, epee::as_byte_span(unwrap(unwrap(v.sk)))); return o;
|
||||
inline std::ostream &operator <<(std::ostream &o, const crypto::secret_key &v) {
|
||||
epee::to_hex::formatted(o, epee::as_byte_span(v)); return o;
|
||||
}
|
||||
inline std::ostream &operator <<(std::ostream &o, const crypto::key_derivation &v) {
|
||||
epee::to_hex::formatted(o, epee::as_byte_span(v)); return o;
|
||||
|
||||
@@ -34,7 +34,7 @@ typedef struct {
|
||||
unsigned long long databitlen; /*the message size in bits*/
|
||||
unsigned long long datasize_in_buffer; /*the size of the message remained in buffer; assumed to be multiple of 8bits except for the last partial block at the end of the message*/
|
||||
DATA_ALIGN16(uint64 x[8][2]); /*the 1024-bit state, ( x[i][0] || x[i][1] ) is the ith row of the state in the pseudocode*/
|
||||
DATA_ALIGN16(unsigned char buffer[64]); /*the 512-bit message block to be hashed;*/
|
||||
unsigned char buffer[64]; /*the 512-bit message block to be hashed;*/
|
||||
} hashState;
|
||||
|
||||
|
||||
@@ -213,24 +213,16 @@ static void E8(hashState *state)
|
||||
/*The compression function F8 */
|
||||
static void F8(hashState *state)
|
||||
{
|
||||
uint64_t* x = (uint64_t*)state->x;
|
||||
uint64 i;
|
||||
|
||||
/*xor the 512-bit message with the fist half of the 1024-bit hash state*/
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
uint64 b;
|
||||
memcpy(&b, &state->buffer[i << 3], sizeof(b));
|
||||
x[i] ^= b;
|
||||
}
|
||||
for (i = 0; i < 8; i++) state->x[i >> 1][i & 1] ^= ((uint64*)state->buffer)[i];
|
||||
|
||||
/*the bijective function E8 */
|
||||
E8(state);
|
||||
|
||||
/*xor the 512-bit message with the second half of the 1024-bit hash state*/
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
uint64 b;
|
||||
memcpy(&b, &state->buffer[i << 3], sizeof(b));
|
||||
x[i + 8] ^= b;
|
||||
}
|
||||
for (i = 0; i < 8; i++) state->x[(8+i) >> 1][(8+i) & 1] ^= ((uint64*)state->buffer)[i];
|
||||
}
|
||||
|
||||
/*before hashing a message, initialize the hash state as H0 */
|
||||
@@ -248,7 +240,6 @@ static HashReturn Init(hashState *state, int hashbitlen)
|
||||
case 224: memcpy(state->x,JH224_H0,128); break;
|
||||
case 256: memcpy(state->x,JH256_H0,128); break;
|
||||
case 384: memcpy(state->x,JH384_H0,128); break;
|
||||
default:
|
||||
case 512: memcpy(state->x,JH512_H0,128); break;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,15 +39,6 @@ namespace cryptonote {
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
template<class t_array>
|
||||
struct array_hasher: std::unary_function<t_array&, std::size_t>
|
||||
{
|
||||
std::size_t operator()(const t_array& val) const
|
||||
{
|
||||
return boost::hash_range(&val.data[0], &val.data[sizeof(val.data)]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct public_address_outer_blob
|
||||
|
||||
@@ -312,7 +312,7 @@ namespace cryptonote
|
||||
bool r = hwdev.generate_key_derivation(tx_public_key, ack.m_view_secret_key, recv_derivation);
|
||||
if (!r)
|
||||
{
|
||||
MWARNING("key image helper: failed to generate_key_derivation(" << tx_public_key << ", <viewkey>)");
|
||||
MWARNING("key image helper: failed to generate_key_derivation(" << tx_public_key << ", " << ack.m_view_secret_key << ")");
|
||||
memcpy(&recv_derivation, rct::identity().bytes, sizeof(recv_derivation));
|
||||
}
|
||||
|
||||
@@ -323,7 +323,7 @@ namespace cryptonote
|
||||
r = hwdev.generate_key_derivation(additional_tx_public_keys[i], ack.m_view_secret_key, additional_recv_derivation);
|
||||
if (!r)
|
||||
{
|
||||
MWARNING("key image helper: failed to generate_key_derivation(" << additional_tx_public_keys[i] << ", <viewkey>)");
|
||||
MWARNING("key image helper: failed to generate_key_derivation(" << additional_tx_public_keys[i] << ", " << ack.m_view_secret_key << ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1254,7 +1254,7 @@ namespace cryptonote
|
||||
char *end = NULL;
|
||||
errno = 0;
|
||||
const unsigned long long ull = strtoull(buf, &end, 10);
|
||||
CHECK_AND_ASSERT_THROW_MES(ull != ULLONG_MAX || errno == 0, "Failed to parse rounded amount: " << buf);
|
||||
CHECK_AND_ASSERT_THROW_MES(ull != ULONG_MAX || errno == 0, "Failed to parse rounded amount: " << buf);
|
||||
CHECK_AND_ASSERT_THROW_MES(ull != 0 || amount == 0, "Overflow in rounding");
|
||||
return ull;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace cryptonote
|
||||
|
||||
// load
|
||||
template <template <bool> class Archive>
|
||||
bool member_do_serialize(Archive<false>& ar)
|
||||
bool do_serialize(Archive<false>& ar)
|
||||
{
|
||||
// size - 1 - because of variant tag
|
||||
for (size = 1; size <= TX_EXTRA_PADDING_MAX_COUNT; ++size)
|
||||
@@ -73,7 +73,7 @@ namespace cryptonote
|
||||
|
||||
// store
|
||||
template <template <bool> class Archive>
|
||||
bool member_do_serialize(Archive<true>& ar)
|
||||
bool do_serialize(Archive<true>& ar)
|
||||
{
|
||||
if(TX_EXTRA_PADDING_MAX_COUNT < size)
|
||||
return false;
|
||||
@@ -129,7 +129,7 @@ namespace cryptonote
|
||||
|
||||
// load
|
||||
template <template <bool> class Archive>
|
||||
bool member_do_serialize(Archive<false>& ar)
|
||||
bool do_serialize(Archive<false>& ar)
|
||||
{
|
||||
std::string field;
|
||||
if(!::do_serialize(ar, field))
|
||||
@@ -142,7 +142,7 @@ namespace cryptonote
|
||||
|
||||
// store
|
||||
template <template <bool> class Archive>
|
||||
bool member_do_serialize(Archive<true>& ar)
|
||||
bool do_serialize(Archive<true>& ar)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
binary_archive<true> oar(oss);
|
||||
|
||||
@@ -59,7 +59,6 @@ namespace cryptonote
|
||||
bool m_fee_too_low;
|
||||
bool m_too_few_outputs;
|
||||
bool m_tx_extra_too_big;
|
||||
bool m_nonzero_unlock_time;
|
||||
};
|
||||
|
||||
struct block_verification_context
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
@@ -105,12 +104,12 @@
|
||||
|
||||
#define BLOCKS_IDS_SYNCHRONIZING_DEFAULT_COUNT 10000 //by default, blocks ids count in synchronizing
|
||||
#define BLOCKS_IDS_SYNCHRONIZING_MAX_COUNT 25000 //max blocks ids count in synchronizing
|
||||
#define BLOCKS_SYNCHRONIZING_DEFAULT_COUNT_PRE_V4 100 //by default, blocks count in blocks downloading
|
||||
#define BLOCKS_SYNCHRONIZING_DEFAULT_COUNT_PRE_V4 50 //by default, blocks count in blocks downloading
|
||||
#define BLOCKS_SYNCHRONIZING_DEFAULT_COUNT 20 //by default, blocks count in blocks downloading
|
||||
#define BLOCKS_SYNCHRONIZING_MAX_COUNT 2048 //must be a power of 2, greater than 128, equal to SEEDHASH_EPOCH_BLOCKS
|
||||
|
||||
#define CRYPTONOTE_MEMPOOL_TX_LIVETIME (86400*3) //seconds, three days
|
||||
#define CRYPTONOTE_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME 604800 //seconds, one week
|
||||
#define CRYPTONOTE_MEMPOOL_TX_LIVETIME 86400 //seconds, one day
|
||||
#define CRYPTONOTE_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME 86400 //seconds, one day
|
||||
|
||||
|
||||
#define CRYPTONOTE_DANDELIONPP_STEMS 2 // number of outgoing stem connections per epoch
|
||||
|
||||
@@ -1242,7 +1242,12 @@ bool Blockchain::switch_to_alternative_blockchain(std::list<block_extended_info>
|
||||
// just the latter (because the rollback was done above).
|
||||
rollback_blockchain_switching(disconnected_chain, split_height);
|
||||
|
||||
// FIXME: Why do we keep invalid blocks around? Possibly in case we hear
|
||||
// about them again so we can immediately dismiss them, but needs some
|
||||
// looking into.
|
||||
const crypto::hash blkid = cryptonote::get_block_hash(bei.bl);
|
||||
add_block_as_invalid(bei, blkid);
|
||||
MERROR("The block was inserted as invalid while connecting new alternative chain, block_id: " << blkid);
|
||||
m_db->remove_alt_block(blkid);
|
||||
alt_ch_iter++;
|
||||
|
||||
@@ -1250,6 +1255,7 @@ bool Blockchain::switch_to_alternative_blockchain(std::list<block_extended_info>
|
||||
{
|
||||
const auto &bei = *alt_ch_to_orph_iter++;
|
||||
const crypto::hash blkid = cryptonote::get_block_hash(bei.bl);
|
||||
add_block_as_invalid(bei, blkid);
|
||||
m_db->remove_alt_block(blkid);
|
||||
}
|
||||
return false;
|
||||
@@ -2161,7 +2167,7 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id
|
||||
cryptonote::blobdata blob;
|
||||
if (m_tx_pool.have_tx(txid, relay_category::legacy))
|
||||
{
|
||||
if (m_tx_pool.get_transaction_info(txid, td, true/*include_sensitive_data*/))
|
||||
if (m_tx_pool.get_transaction_info(txid, td))
|
||||
{
|
||||
bei.block_cumulative_weight += td.weight;
|
||||
}
|
||||
@@ -2465,7 +2471,7 @@ bool Blockchain::get_output_distribution(uint64_t amount, uint64_t from_height,
|
||||
{
|
||||
case STAGENET: start_height = stagenet_hard_forks[3].height; break;
|
||||
case TESTNET: start_height = testnet_hard_forks[3].height; break;
|
||||
case MAINNET: start_height = 0; break;
|
||||
case MAINNET: start_height = mainnet_hard_forks[3].height; break;
|
||||
case FAKECHAIN: start_height = 0; break;
|
||||
default: return false;
|
||||
}
|
||||
@@ -3817,7 +3823,7 @@ uint64_t Blockchain::get_dynamic_base_fee(uint64_t block_reward, size_t median_b
|
||||
div128_64(hi, lo, median_block_weight, &hi, &lo, NULL, NULL);
|
||||
assert(hi == 0);
|
||||
lo -= lo / 20;
|
||||
return lo == 0 ? 1 : lo;
|
||||
return lo;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3939,8 +3945,6 @@ void Blockchain::get_dynamic_base_fee_estimate_2021_scaling(uint64_t grace_block
|
||||
const uint8_t version = get_current_hard_fork_version();
|
||||
const uint64_t db_height = m_db->height();
|
||||
|
||||
CHECK_AND_ASSERT_THROW_MES(grace_blocks <= CRYPTONOTE_REWARD_BLOCKS_WINDOW, "Grace blocks invalid In 2021 fee scaling estimate.");
|
||||
|
||||
// we want Mlw = median of max((min(Mbw, 1.7 * Ml), Zm), Ml / 1.7)
|
||||
// Mbw: block weight for the last 99990 blocks, 0 for the next 10
|
||||
// Ml: penalty free zone (dynamic), aka long_term_median, aka median of max((min(Mb, 1.7 * Ml), Zm), Ml / 1.7)
|
||||
@@ -3954,6 +3958,7 @@ void Blockchain::get_dynamic_base_fee_estimate_2021_scaling(uint64_t grace_block
|
||||
const uint64_t Mlw_penalty_free_zone_for_wallet = std::max<uint64_t>(rm.median(), CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5);
|
||||
|
||||
// Msw: median over [100 - grace blocks] past + [grace blocks] future blocks
|
||||
CHECK_AND_ASSERT_THROW_MES(grace_blocks <= 100, "Grace blocks invalid In 2021 fee scaling estimate.");
|
||||
std::vector<uint64_t> weights;
|
||||
get_last_n_blocks_weights(weights, 100 - grace_blocks);
|
||||
weights.reserve(100);
|
||||
@@ -4731,9 +4736,40 @@ bool Blockchain::update_next_cumulative_weight_limit(uint64_t *long_term_effecti
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint64_t nblocks = std::min<uint64_t>(m_long_term_block_weights_window, db_height);
|
||||
const uint64_t long_term_median = get_long_term_block_weight_median(db_height - nblocks, nblocks);
|
||||
const uint64_t block_weight = m_db->get_block_weight(db_height - 1);
|
||||
|
||||
uint64_t long_term_median;
|
||||
if (db_height == 1)
|
||||
{
|
||||
long_term_median = CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t nblocks = std::min<uint64_t>(m_long_term_block_weights_window, db_height);
|
||||
if (nblocks == db_height)
|
||||
--nblocks;
|
||||
long_term_median = get_long_term_block_weight_median(db_height - nblocks - 1, nblocks);
|
||||
}
|
||||
|
||||
m_long_term_effective_median_block_weight = std::max<uint64_t>(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5, long_term_median);
|
||||
|
||||
uint64_t short_term_constraint = m_long_term_effective_median_block_weight;
|
||||
if (hf_version >= HF_VERSION_2021_SCALING)
|
||||
short_term_constraint += m_long_term_effective_median_block_weight * 7 / 10;
|
||||
else
|
||||
short_term_constraint += m_long_term_effective_median_block_weight * 2 / 5;
|
||||
uint64_t long_term_block_weight = std::min<uint64_t>(block_weight, short_term_constraint);
|
||||
|
||||
if (db_height == 1)
|
||||
{
|
||||
long_term_median = long_term_block_weight;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_long_term_block_weights_cache_tip_hash = m_db->get_block_hash_from_height(db_height - 1);
|
||||
m_long_term_block_weights_cache_rolling_median.insert(long_term_block_weight);
|
||||
long_term_median = m_long_term_block_weights_cache_rolling_median.median();
|
||||
}
|
||||
m_long_term_effective_median_block_weight = std::max<uint64_t>(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5, long_term_median);
|
||||
|
||||
std::vector<uint64_t> weights;
|
||||
@@ -5666,7 +5702,7 @@ void Blockchain::cancel()
|
||||
}
|
||||
|
||||
#if defined(PER_BLOCK_CHECKPOINT)
|
||||
static const char expected_block_hashes_hash[] = "3ee7be44d391f20b389ed17b17443ffa26889ac943a57b4e493b833db67159c5";
|
||||
static const char expected_block_hashes_hash[] = "ba330ed9cd10aabcbfd4a501d5271caecc56999fe4b2863d6c99f871b7282014";
|
||||
void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback& get_checkpoints)
|
||||
{
|
||||
if (get_checkpoints == nullptr || !m_fast_sync)
|
||||
|
||||
@@ -1731,11 +1731,6 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::get_pool_transactions_info(const std::vector<crypto::hash>& txids, std::vector<std::pair<crypto::hash, tx_memory_pool::tx_details>>& txs, bool include_sensitive_txes) const
|
||||
{
|
||||
return m_mempool.get_transactions_info(txids, txs, include_sensitive_txes);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::get_pool_transactions(std::vector<transaction>& txs, bool include_sensitive_data) const
|
||||
{
|
||||
m_mempool.get_transactions(txs, include_sensitive_data);
|
||||
@@ -1748,11 +1743,6 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::get_pool_info(time_t start_time, bool include_sensitive_txes, size_t max_tx_count, std::vector<std::pair<crypto::hash, tx_memory_pool::tx_details>>& added_txs, std::vector<crypto::hash>& remaining_added_txids, std::vector<crypto::hash>& removed_txs, bool& incremental) const
|
||||
{
|
||||
return m_mempool.get_pool_info(start_time, include_sensitive_txes, max_tx_count, added_txs, remaining_added_txids, removed_txs, incremental);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::get_pool_transaction_stats(struct txpool_stats& stats, bool include_sensitive_data) const
|
||||
{
|
||||
m_mempool.get_transaction_stats(stats, include_sensitive_data);
|
||||
@@ -1881,7 +1871,7 @@ namespace cryptonote
|
||||
" PP55YJJ3?!!7??7~^^^^~!~~!75PGGGGGBBBGGPPPPPPPPPPPPPGGGGGGGGGBG57!77!!2?!^ \n"
|
||||
" GGGPPP5J!!7?7~^:::^~~!!!77YPPPGGGGGGGGPPPPPPPPPPPPPPGGGGGGGGGGYJY7~!?BP. \n"
|
||||
" GBGGGGP55YYJ7~^^!~^~77!77775PPPPPP55PPPPPPPPPPPPPPGGGGGGGGGGGGGBPJY5PG~ \n"
|
||||
" Fve, V'q yvxr gb fcrnx gb gur jbjareb znantre "
|
||||
" Fve, V'q yvxr gb fcrnx gb gur gur jbjareb znantre "
|
||||
<< ENDL);
|
||||
MGINFO_MAGENTA(ENDL <<
|
||||
" ██ ██ █████ ██████ ███████ ███ ██ \n"
|
||||
|
||||
@@ -510,23 +510,6 @@ namespace cryptonote
|
||||
bool get_pool_transaction_hashes(std::vector<crypto::hash>& txs, bool include_sensitive_txes = false) const;
|
||||
|
||||
/**
|
||||
* @copydoc tx_memory_pool::get_pool_transactions_info
|
||||
* @param include_sensitive_txes include private transactions
|
||||
*
|
||||
* @note see tx_memory_pool::get_pool_transactions_info
|
||||
*/
|
||||
bool get_pool_transactions_info(const std::vector<crypto::hash>& txids, std::vector<std::pair<crypto::hash, tx_memory_pool::tx_details>>& txs, bool include_sensitive_txes = false) const;
|
||||
|
||||
/**
|
||||
* @copydoc tx_memory_pool::get_pool_info
|
||||
* @param include_sensitive_txes include private transactions
|
||||
* @param max_tx_count max allowed added_txs in response
|
||||
*
|
||||
* @note see tx_memory_pool::get_pool_info
|
||||
*/
|
||||
bool get_pool_info(time_t start_time, bool include_sensitive_txes, size_t max_tx_count, std::vector<std::pair<crypto::hash, tx_memory_pool::tx_details>>& added_txs, std::vector<crypto::hash>& remaining_added_txids, std::vector<crypto::hash>& removed_txs, bool& incremental) const;
|
||||
|
||||
/**
|
||||
* @copydoc tx_memory_pool::get_transactions
|
||||
* @param include_sensitive_txes include private transactions
|
||||
*
|
||||
|
||||
@@ -144,7 +144,7 @@ namespace cryptonote
|
||||
crypto::key_derivation derivation = AUTO_VAL_INIT(derivation);
|
||||
crypto::public_key out_eph_public_key = AUTO_VAL_INIT(out_eph_public_key);
|
||||
bool r = crypto::generate_key_derivation(miner_address.m_view_public_key, txkey.sec, derivation);
|
||||
CHECK_AND_ASSERT_MES(r, false, "while creating outs: failed to generate_key_derivation(" << miner_address.m_view_public_key << ", " << crypto::secret_key_explicit_print_ref{txkey.sec} << ")");
|
||||
CHECK_AND_ASSERT_MES(r, false, "while creating outs: failed to generate_key_derivation(" << miner_address.m_view_public_key << ", " << txkey.sec << ")");
|
||||
|
||||
r = crypto::derive_public_key(derivation, no, miner_address.m_spend_public_key, out_eph_public_key);
|
||||
CHECK_AND_ASSERT_MES(r, false, "while creating outs: failed to derive_public_key(" << derivation << ", " << no << ", "<< miner_address.m_spend_public_key << ")");
|
||||
@@ -216,7 +216,7 @@ namespace cryptonote
|
||||
return addr.m_view_public_key;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, bool shuffle_outs, bool use_view_tags)
|
||||
bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, bool shuffle_outs, bool use_view_tags)
|
||||
{
|
||||
hw::device &hwdev = sender_account_keys.get_device();
|
||||
|
||||
@@ -231,7 +231,7 @@ namespace cryptonote
|
||||
amount_keys.clear();
|
||||
|
||||
tx.version = rct ? 2 : 1;
|
||||
tx.unlock_time = 0;
|
||||
tx.unlock_time = unlock_time;
|
||||
|
||||
tx.extra = extra;
|
||||
crypto::public_key txkey_pub;
|
||||
@@ -450,8 +450,6 @@ namespace cryptonote
|
||||
if (!sort_tx_extra(tx.extra, tx.extra))
|
||||
return false;
|
||||
|
||||
CHECK_AND_ASSERT_MES(tx.extra.size() <= MAX_TX_EXTRA_SIZE, false, "TX extra size (" << tx.extra.size() << ") is greater than max allowed (" << MAX_TX_EXTRA_SIZE << ")");
|
||||
|
||||
//check money
|
||||
if(summary_outs_money > summary_inputs_money )
|
||||
{
|
||||
@@ -497,7 +495,7 @@ namespace cryptonote
|
||||
crypto::generate_ring_signature(tx_prefix_hash, boost::get<txin_to_key>(tx.vin[i]).k_image, keys_ptrs, in_contexts[i].in_ephemeral.sec, src_entr.real_output, sigs.data());
|
||||
ss_ring_s << "signatures:" << ENDL;
|
||||
std::for_each(sigs.begin(), sigs.end(), [&](const crypto::signature& s){ss_ring_s << s << ENDL;});
|
||||
ss_ring_s << "prefix_hash:" << tx_prefix_hash << ENDL << "in_ephemeral_key: " << crypto::secret_key_explicit_print_ref{in_contexts[i].in_ephemeral.sec} << ENDL << "real_output: " << src_entr.real_output << ENDL;
|
||||
ss_ring_s << "prefix_hash:" << tx_prefix_hash << ENDL << "in_ephemeral_key: " << in_contexts[i].in_ephemeral.sec << ENDL << "real_output: " << src_entr.real_output << ENDL;
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -621,7 +619,7 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, bool use_view_tags)
|
||||
bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, bool use_view_tags)
|
||||
{
|
||||
hw::device &hwdev = sender_account_keys.get_device();
|
||||
hwdev.open_tx(tx_key);
|
||||
@@ -642,7 +640,7 @@ namespace cryptonote
|
||||
}
|
||||
|
||||
bool shuffle_outs = true;
|
||||
bool r = construct_tx_with_tx_key(sender_account_keys, subaddresses, sources, destinations, change_addr, extra, tx, tx_key, additional_tx_keys, rct, rct_config, shuffle_outs, use_view_tags);
|
||||
bool r = construct_tx_with_tx_key(sender_account_keys, subaddresses, sources, destinations, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, rct_config, shuffle_outs, use_view_tags);
|
||||
hwdev.close_tx();
|
||||
return r;
|
||||
} catch(...) {
|
||||
@@ -651,14 +649,14 @@ namespace cryptonote
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool construct_tx(const account_keys& sender_account_keys, std::vector<tx_source_entry>& sources, const std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx)
|
||||
bool construct_tx(const account_keys& sender_account_keys, std::vector<tx_source_entry>& sources, const std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time)
|
||||
{
|
||||
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
||||
subaddresses[sender_account_keys.m_account_address.m_spend_public_key] = {0,0};
|
||||
crypto::secret_key tx_key;
|
||||
std::vector<crypto::secret_key> additional_tx_keys;
|
||||
std::vector<tx_destination_entry> destinations_copy = destinations;
|
||||
return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, change_addr, extra, tx, tx_key, additional_tx_keys, false, { rct::RangeProofBorromean, 0});
|
||||
return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, { rct::RangeProofBorromean, 0});
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool generate_genesis_block(
|
||||
|
||||
@@ -119,9 +119,9 @@ namespace cryptonote
|
||||
|
||||
//---------------------------------------------------------------
|
||||
crypto::public_key get_destination_view_key_pub(const std::vector<tx_destination_entry> &destinations, const boost::optional<cryptonote::account_public_address>& change_addr);
|
||||
bool construct_tx(const account_keys& sender_account_keys, std::vector<tx_source_entry> &sources, const std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx);
|
||||
bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, bool shuffle_outs = true, bool use_view_tags = false);
|
||||
bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, bool use_view_tags = false);
|
||||
bool construct_tx(const account_keys& sender_account_keys, std::vector<tx_source_entry> &sources, const std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time);
|
||||
bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, bool shuffle_outs = true, bool use_view_tags = false);
|
||||
bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, bool use_view_tags = false);
|
||||
bool generate_output_ephemeral_keys(const size_t tx_version, const cryptonote::account_keys &sender_account_keys, const crypto::public_key &txkey_pub, const crypto::secret_key &tx_key,
|
||||
const cryptonote::tx_destination_entry &dst_entr, const boost::optional<cryptonote::account_public_address> &change_addr, const size_t output_index,
|
||||
const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys,
|
||||
|
||||
@@ -133,12 +133,6 @@ namespace cryptonote
|
||||
// class code expects unsigned values throughout
|
||||
if (m_next_check < time_t(0))
|
||||
throw std::runtime_error{"Unexpected time_t (system clock) value"};
|
||||
|
||||
m_added_txs_start_time = (time_t)0;
|
||||
m_removed_txs_start_time = (time_t)0;
|
||||
// We don't set these to "now" already here as we don't know how long it takes from construction
|
||||
// of the pool until it "goes to work". It's safer to set when the first actual txs enter the
|
||||
// corresponding lists.
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
bool tx_memory_pool::add_tx(transaction &tx, /*const crypto::hash& tx_prefix_hash,*/ const crypto::hash &id, const cryptonote::blobdata &blob, size_t tx_weight, tx_verification_context& tvc, relay_method tx_relay, bool relayed, uint8_t version)
|
||||
@@ -236,15 +230,6 @@ namespace cryptonote
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!kept_by_block && tx.unlock_time)
|
||||
{
|
||||
LOG_PRINT_L1("transaction unlock time is not zero: " << tx.unlock_time);
|
||||
tvc.m_verifivation_failed = true;
|
||||
tvc.m_nonzero_unlock_time = true;
|
||||
tvc.m_no_drop_offense = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// if the transaction came from a block popped from the chain,
|
||||
// don't check if we have its key images as spent.
|
||||
// TODO: Investigate why not?
|
||||
@@ -256,7 +241,6 @@ namespace cryptonote
|
||||
LOG_PRINT_L1("Transaction with id= "<< id << " used already spent key images");
|
||||
tvc.m_verifivation_failed = true;
|
||||
tvc.m_double_spend = true;
|
||||
tvc.m_no_drop_offense = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -308,7 +292,7 @@ namespace cryptonote
|
||||
return false;
|
||||
|
||||
m_blockchain.add_txpool_tx(id, blob, meta);
|
||||
add_tx_to_transient_lists(id, fee / (double)(tx_weight ? tx_weight : 1), receive_time);
|
||||
m_txs_by_fee_and_receive_time.emplace(std::pair<double, std::time_t>(fee / (double)(tx_weight ? tx_weight : 1), receive_time), id);
|
||||
lock.commit();
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
@@ -379,7 +363,7 @@ namespace cryptonote
|
||||
|
||||
m_blockchain.remove_txpool_tx(id);
|
||||
m_blockchain.add_txpool_tx(id, blob, meta);
|
||||
add_tx_to_transient_lists(id, meta.fee / (double)(tx_weight ? tx_weight : 1), receive_time);
|
||||
m_txs_by_fee_and_receive_time.emplace(std::pair<double, std::time_t>(fee / (double)(tx_weight ? tx_weight : 1), receive_time), id);
|
||||
}
|
||||
lock.commit();
|
||||
}
|
||||
@@ -400,7 +384,7 @@ namespace cryptonote
|
||||
|
||||
++m_cookie;
|
||||
|
||||
MINFO("Transaction added to pool: txid " << id << " weight: " << tx_weight << " fee/byte: " << (fee / (double)(tx_weight ? tx_weight : 1)) << ", count: " << m_added_txs_by_id.size());
|
||||
MINFO("Transaction added to pool: txid " << id << " weight: " << tx_weight << " fee/byte: " << (fee / (double)(tx_weight ? tx_weight : 1)));
|
||||
|
||||
prune(m_txpool_max_weight);
|
||||
|
||||
@@ -445,14 +429,8 @@ namespace cryptonote
|
||||
void tx_memory_pool::prune(size_t bytes)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
|
||||
// Nothing to do if already empty
|
||||
if (m_txs_by_fee_and_receive_time.empty())
|
||||
return;
|
||||
|
||||
if (bytes == 0)
|
||||
bytes = m_txpool_max_weight;
|
||||
|
||||
CRITICAL_REGION_LOCAL1(m_blockchain);
|
||||
LockedTXN lock(m_blockchain.get_db());
|
||||
bool changed = false;
|
||||
@@ -497,13 +475,7 @@ namespace cryptonote
|
||||
reduce_txpool_weight(meta.weight);
|
||||
remove_transaction_keyimages(tx, txid);
|
||||
MINFO("Pruned tx " << txid << " from txpool: weight: " << meta.weight << ", fee/byte: " << it->first.first);
|
||||
|
||||
auto it_prev = it;
|
||||
--it_prev;
|
||||
|
||||
remove_tx_from_transient_lists(it, txid, !meta.matches(relay_category::broadcasted));
|
||||
it = it_prev;
|
||||
|
||||
m_txs_by_fee_and_receive_time.erase(it--);
|
||||
changed = true;
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
@@ -585,7 +557,8 @@ namespace cryptonote
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
CRITICAL_REGION_LOCAL1(m_blockchain);
|
||||
|
||||
bool sensitive = false;
|
||||
auto sorted_it = find_tx_in_sorted_container(id);
|
||||
|
||||
try
|
||||
{
|
||||
LockedTXN lock(m_blockchain.get_db());
|
||||
@@ -616,7 +589,6 @@ namespace cryptonote
|
||||
do_not_relay = meta.do_not_relay;
|
||||
double_spend_seen = meta.double_spend_seen;
|
||||
pruned = meta.pruned;
|
||||
sensitive = !meta.matches(relay_category::broadcasted);
|
||||
|
||||
// remove first, in case this throws, so key images aren't removed
|
||||
m_blockchain.remove_txpool_tx(id);
|
||||
@@ -630,12 +602,13 @@ namespace cryptonote
|
||||
return false;
|
||||
}
|
||||
|
||||
remove_tx_from_transient_lists(find_tx_in_sorted_container(id), id, sensitive);
|
||||
if (sorted_it != m_txs_by_fee_and_receive_time.end())
|
||||
m_txs_by_fee_and_receive_time.erase(sorted_it);
|
||||
++m_cookie;
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
bool tx_memory_pool::get_transaction_info(const crypto::hash &txid, tx_details &td, bool include_sensitive_data, bool include_blob) const
|
||||
bool tx_memory_pool::get_transaction_info(const crypto::hash &txid, tx_details &td) const
|
||||
{
|
||||
PERF_TIMER(get_transaction_info);
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
@@ -647,12 +620,7 @@ namespace cryptonote
|
||||
txpool_tx_meta_t meta;
|
||||
if (!m_blockchain.get_txpool_tx_meta(txid, meta))
|
||||
{
|
||||
LOG_PRINT_L2("Failed to find tx in txpool: " << txid);
|
||||
return false;
|
||||
}
|
||||
if (!include_sensitive_data && !meta.matches(relay_category::broadcasted))
|
||||
{
|
||||
// We don't want sensitive data && the tx is sensitive, so no need to return it
|
||||
MERROR("Failed to find tx in txpool");
|
||||
return false;
|
||||
}
|
||||
cryptonote::blobdata txblob = m_blockchain.get_txpool_tx_blob(txid, relay_category::all);
|
||||
@@ -678,13 +646,11 @@ namespace cryptonote
|
||||
td.kept_by_block = meta.kept_by_block;
|
||||
td.last_failed_height = meta.last_failed_height;
|
||||
td.last_failed_id = meta.last_failed_id;
|
||||
td.receive_time = include_sensitive_data ? meta.receive_time : 0;
|
||||
td.last_relayed_time = (include_sensitive_data && !meta.dandelionpp_stem) ? meta.last_relayed_time : 0;
|
||||
td.receive_time = meta.receive_time;
|
||||
td.last_relayed_time = meta.dandelionpp_stem ? 0 : meta.last_relayed_time;
|
||||
td.relayed = meta.relayed;
|
||||
td.do_not_relay = meta.do_not_relay;
|
||||
td.double_spend_seen = meta.double_spend_seen;
|
||||
if (include_blob)
|
||||
td.tx_blob = std::move(txblob);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
@@ -694,25 +660,6 @@ namespace cryptonote
|
||||
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool tx_memory_pool::get_transactions_info(const std::vector<crypto::hash>& txids, std::vector<std::pair<crypto::hash, tx_details>>& txs, bool include_sensitive) const
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
CRITICAL_REGION_LOCAL1(m_blockchain);
|
||||
|
||||
txs.clear();
|
||||
|
||||
for (const auto &it: txids)
|
||||
{
|
||||
tx_details details;
|
||||
bool success = get_transaction_info(it, details, include_sensitive, true/*include_blob*/);
|
||||
if (success)
|
||||
{
|
||||
txs.push_back(std::make_pair(it, std::move(details)));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
bool tx_memory_pool::get_complement(const std::vector<crypto::hash> &hashes, std::vector<cryptonote::blobdata> &txes) const
|
||||
{
|
||||
@@ -774,7 +721,15 @@ namespace cryptonote
|
||||
(tx_age > CRYPTONOTE_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME && meta.kept_by_block) )
|
||||
{
|
||||
LOG_PRINT_L1("Tx " << txid << " removed from tx pool due to outdated, age: " << tx_age );
|
||||
remove_tx_from_transient_lists(find_tx_in_sorted_container(txid), txid, !meta.matches(relay_category::broadcasted));
|
||||
auto sorted_it = find_tx_in_sorted_container(txid);
|
||||
if (sorted_it == m_txs_by_fee_and_receive_time.end())
|
||||
{
|
||||
LOG_PRINT_L1("Removing tx " << txid << " from tx pool, but it was not found in the sorted txs container!");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_txs_by_fee_and_receive_time.erase(sorted_it);
|
||||
}
|
||||
m_timed_out_transactions.insert(txid);
|
||||
remove.push_back(std::make_pair(txid, meta.weight));
|
||||
}
|
||||
@@ -928,12 +883,9 @@ namespace cryptonote
|
||||
meta.last_relayed_time = std::chrono::system_clock::to_time_t(now);
|
||||
|
||||
m_blockchain.update_txpool_tx(hash, meta);
|
||||
|
||||
// wait until db update succeeds to ensure tx is visible in the pool
|
||||
was_just_broadcasted = !already_broadcasted && meta.matches(relay_category::broadcasted);
|
||||
|
||||
if (was_just_broadcasted)
|
||||
// Make sure the tx gets re-added with an updated time
|
||||
add_tx_to_transient_lists(hash, meta.fee / (double)meta.weight, std::chrono::system_clock::to_time_t(now));
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
@@ -986,81 +938,6 @@ namespace cryptonote
|
||||
}, false, category);
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool tx_memory_pool::get_pool_info(time_t start_time, bool include_sensitive, size_t max_tx_count, std::vector<std::pair<crypto::hash, tx_details>>& added_txs, std::vector<crypto::hash>& remaining_added_txids, std::vector<crypto::hash>& removed_txs, bool& incremental) const
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
CRITICAL_REGION_LOCAL1(m_blockchain);
|
||||
|
||||
incremental = true;
|
||||
if (start_time == (time_t)0)
|
||||
{
|
||||
// Giving no start time means give back whole pool
|
||||
incremental = false;
|
||||
}
|
||||
else if ((m_added_txs_start_time != (time_t)0) && (m_removed_txs_start_time != (time_t)0))
|
||||
{
|
||||
if ((start_time <= m_added_txs_start_time) || (start_time <= m_removed_txs_start_time))
|
||||
{
|
||||
// If either of the two lists do not go back far enough it's not possible to
|
||||
// deliver incremental pool info
|
||||
incremental = false;
|
||||
}
|
||||
// The check uses "<=": We cannot be sure to have ALL txs exactly at start_time, only AFTER that time
|
||||
}
|
||||
else
|
||||
{
|
||||
// Some incremental info still missing completely
|
||||
incremental = false;
|
||||
}
|
||||
|
||||
added_txs.clear();
|
||||
remaining_added_txids.clear();
|
||||
removed_txs.clear();
|
||||
|
||||
std::vector<crypto::hash> txids;
|
||||
if (!incremental)
|
||||
{
|
||||
LOG_PRINT_L2("Giving back the whole pool");
|
||||
// Give back the whole pool in 'added_txs'; because calling 'get_transaction_info' right inside the
|
||||
// anonymous method somehow results in an LMDB error with transactions we have to build a list of
|
||||
// ids first and get the full info afterwards
|
||||
get_transaction_hashes(txids, include_sensitive);
|
||||
if (txids.size() > max_tx_count)
|
||||
{
|
||||
remaining_added_txids = std::vector<crypto::hash>(txids.begin() + max_tx_count, txids.end());
|
||||
txids.erase(txids.begin() + max_tx_count, txids.end());
|
||||
}
|
||||
get_transactions_info(txids, added_txs, include_sensitive);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Give back incrementally, based on time of entry into the map
|
||||
for (const auto &pit : m_added_txs_by_id)
|
||||
{
|
||||
if (pit.second >= start_time)
|
||||
txids.push_back(pit.first);
|
||||
}
|
||||
get_transactions_info(txids, added_txs, include_sensitive);
|
||||
if (added_txs.size() > max_tx_count)
|
||||
{
|
||||
remaining_added_txids.reserve(added_txs.size() - max_tx_count);
|
||||
for (size_t i = max_tx_count; i < added_txs.size(); ++i)
|
||||
remaining_added_txids.push_back(added_txs[i].first);
|
||||
added_txs.erase(added_txs.begin() + max_tx_count, added_txs.end());
|
||||
}
|
||||
|
||||
std::multimap<time_t, removed_tx_info>::const_iterator rit = m_removed_txs_by_time.lower_bound(start_time);
|
||||
while (rit != m_removed_txs_by_time.end())
|
||||
{
|
||||
if (include_sensitive || !rit->second.sensitive)
|
||||
{
|
||||
removed_txs.push_back(rit->second.txid);
|
||||
}
|
||||
++rit;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
void tx_memory_pool::get_transaction_backlog(std::vector<tx_backlog_entry>& backlog, bool include_sensitive) const
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
@@ -1095,7 +972,7 @@ namespace cryptonote
|
||||
|
||||
// If the total weight is too high, choose the best paying transactions
|
||||
if (total_weight > max_backlog_weight)
|
||||
std::stable_sort(tmp.begin(), tmp.end(), [](const auto& a, const auto& b){ return a.fee * b.weight > b.fee * a.weight; });
|
||||
std::sort(tmp.begin(), tmp.end(), [](const auto& a, const auto& b){ return a.fee * b.weight > b.fee * a.weight; });
|
||||
|
||||
backlog.clear();
|
||||
uint64_t w = 0;
|
||||
@@ -1765,12 +1642,6 @@ namespace cryptonote
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
CRITICAL_REGION_LOCAL1(m_blockchain);
|
||||
|
||||
// Simply throw away incremental info, too difficult to update
|
||||
m_added_txs_by_id.clear();
|
||||
m_added_txs_start_time = (time_t)0;
|
||||
m_removed_txs_by_time.clear();
|
||||
m_removed_txs_start_time = (time_t)0;
|
||||
|
||||
MINFO("Validating txpool contents for v" << (unsigned)version);
|
||||
|
||||
LockedTXN lock(m_blockchain.get_db());
|
||||
@@ -1828,106 +1699,6 @@ namespace cryptonote
|
||||
return n_removed;
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
void tx_memory_pool::add_tx_to_transient_lists(const crypto::hash& txid, double fee, time_t receive_time)
|
||||
{
|
||||
|
||||
time_t now = time(NULL);
|
||||
const std::unordered_map<crypto::hash, time_t>::iterator it = m_added_txs_by_id.find(txid);
|
||||
if (it == m_added_txs_by_id.end())
|
||||
{
|
||||
m_added_txs_by_id.insert(std::make_pair(txid, now));
|
||||
}
|
||||
else
|
||||
{
|
||||
// This tx was already added to the map earlier, probably because then it was in the "stem"
|
||||
// phase of Dandelion++ and now is in the "fluff" phase i.e. got broadcasted: We have to set
|
||||
// a new time for clients that are not allowed to see sensitive txs to make sure they will
|
||||
// see it now if they query incrementally
|
||||
it->second = now;
|
||||
|
||||
auto sorted_it = find_tx_in_sorted_container(txid);
|
||||
if (sorted_it == m_txs_by_fee_and_receive_time.end())
|
||||
{
|
||||
MDEBUG("Re-adding tx " << txid << " to tx pool, but it was not found in the sorted txs container");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_txs_by_fee_and_receive_time.erase(sorted_it);
|
||||
}
|
||||
}
|
||||
m_txs_by_fee_and_receive_time.emplace(std::pair<double, time_t>(fee, receive_time), txid);
|
||||
|
||||
// Don't check for "resurrected" txs in case of reorgs i.e. don't check in 'm_removed_txs_by_time'
|
||||
// whether we have that txid there and if yes remove it; this results in possible duplicates
|
||||
// where we return certain txids as deleted AND in the pool at the same time which requires
|
||||
// clients to process deleted ones BEFORE processing pool txs
|
||||
if (m_added_txs_start_time == (time_t)0)
|
||||
{
|
||||
m_added_txs_start_time = now;
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
void tx_memory_pool::remove_tx_from_transient_lists(const cryptonote::sorted_tx_container::iterator& sorted_it, const crypto::hash& txid, bool sensitive)
|
||||
{
|
||||
if (sorted_it == m_txs_by_fee_and_receive_time.end())
|
||||
{
|
||||
LOG_PRINT_L1("Removing tx " << txid << " from tx pool, but it was not found in the sorted txs container!");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_txs_by_fee_and_receive_time.erase(sorted_it);
|
||||
}
|
||||
|
||||
const std::unordered_map<crypto::hash, time_t>::iterator it = m_added_txs_by_id.find(txid);
|
||||
if (it != m_added_txs_by_id.end())
|
||||
{
|
||||
m_added_txs_by_id.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
MDEBUG("Removing tx " << txid << " from tx pool, but it was not found in the map of added txs");
|
||||
}
|
||||
track_removed_tx(txid, sensitive);
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
void tx_memory_pool::track_removed_tx(const crypto::hash& txid, bool sensitive)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
m_removed_txs_by_time.insert(std::make_pair(now, removed_tx_info{txid, sensitive}));
|
||||
MDEBUG("Transaction removed from pool: txid " << txid << ", total entries in removed list now " << m_removed_txs_by_time.size());
|
||||
if (m_removed_txs_start_time == (time_t)0)
|
||||
{
|
||||
m_removed_txs_start_time = now;
|
||||
}
|
||||
|
||||
// Simple system to make sure the list of removed ids does not swell to an unmanageable size: Set
|
||||
// an absolute size limit plus delete entries that are x minutes old (which is ok because clients
|
||||
// will sync with sensible time intervalls and should not ask for incremental info e.g. 1 hour back)
|
||||
const int MAX_REMOVED = 20000;
|
||||
if (m_removed_txs_by_time.size() > MAX_REMOVED)
|
||||
{
|
||||
auto erase_it = m_removed_txs_by_time.begin();
|
||||
std::advance(erase_it, MAX_REMOVED / 4 + 1);
|
||||
m_removed_txs_by_time.erase(m_removed_txs_by_time.begin(), erase_it);
|
||||
m_removed_txs_start_time = m_removed_txs_by_time.begin()->first;
|
||||
MDEBUG("Erased old transactions from big removed list, leaving " << m_removed_txs_by_time.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
time_t earliest = now - (30 * 60); // 30 minutes
|
||||
std::map<time_t, removed_tx_info>::iterator from, to;
|
||||
from = m_removed_txs_by_time.begin();
|
||||
to = m_removed_txs_by_time.lower_bound(earliest);
|
||||
int distance = std::distance(from, to);
|
||||
if (distance > 0)
|
||||
{
|
||||
m_removed_txs_by_time.erase(from, to);
|
||||
m_removed_txs_start_time = earliest;
|
||||
MDEBUG("Erased " << distance << " old transactions from removed list, leaving " << m_removed_txs_by_time.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
bool tx_memory_pool::init(size_t max_txpool_weight, bool mine_stem_txes)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
@@ -1935,10 +1706,6 @@ namespace cryptonote
|
||||
|
||||
m_txpool_max_weight = max_txpool_weight ? max_txpool_weight : DEFAULT_TXPOOL_MAX_WEIGHT;
|
||||
m_txs_by_fee_and_receive_time.clear();
|
||||
m_added_txs_by_id.clear();
|
||||
m_added_txs_start_time = (time_t)0;
|
||||
m_removed_txs_by_time.clear();
|
||||
m_removed_txs_start_time = (time_t)0;
|
||||
m_spent_key_images.clear();
|
||||
m_txpool_weight = 0;
|
||||
std::vector<crypto::hash> remove;
|
||||
@@ -1963,7 +1730,7 @@ namespace cryptonote
|
||||
MFATAL("Failed to insert key images from txpool tx");
|
||||
return false;
|
||||
}
|
||||
add_tx_to_transient_lists(txid, meta.fee / (double)meta.weight, meta.receive_time);
|
||||
m_txs_by_fee_and_receive_time.emplace(std::pair<double, time_t>(meta.fee / (double)meta.weight, meta.receive_time), txid);
|
||||
m_txpool_weight += meta.weight;
|
||||
return true;
|
||||
}, true, relay_category::all);
|
||||
|
||||
@@ -69,12 +69,11 @@ namespace cryptonote
|
||||
{
|
||||
// sort by greatest first, not least
|
||||
if (a.first.first > b.first.first) return true;
|
||||
if (a.first.first < b.first.first) return false;
|
||||
|
||||
if (a.first.second < b.first.second) return true;
|
||||
if (a.first.second > b.first.second) return false;
|
||||
|
||||
return memcmp(a.second.data, b.second.data, sizeof(crypto::hash)) < 0;
|
||||
else if (a.first.first < b.first.first) return false;
|
||||
else if (a.first.second < b.first.second) return true;
|
||||
else if (a.first.second > b.first.second) return false;
|
||||
else if (a.second != b.second) return true;
|
||||
else return false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -429,7 +428,6 @@ namespace cryptonote
|
||||
struct tx_details
|
||||
{
|
||||
transaction tx; //!< the transaction
|
||||
cryptonote::blobdata tx_blob; //!< the transaction's binary blob
|
||||
size_t blob_size; //!< the transaction's size
|
||||
size_t weight; //!< the transaction's weight
|
||||
uint64_t fee; //!< the transaction's fee amount
|
||||
@@ -468,25 +466,13 @@ namespace cryptonote
|
||||
/**
|
||||
* @brief get infornation about a single transaction
|
||||
*/
|
||||
bool get_transaction_info(const crypto::hash &txid, tx_details &td, bool include_sensitive_data, bool include_blob = false) const;
|
||||
|
||||
/**
|
||||
* @brief get information about multiple transactions
|
||||
*/
|
||||
bool get_transactions_info(const std::vector<crypto::hash>& txids, std::vector<std::pair<crypto::hash, tx_details>>& txs, bool include_sensitive_data = false) const;
|
||||
bool get_transaction_info(const crypto::hash &txid, tx_details &td) const;
|
||||
|
||||
/**
|
||||
* @brief get transactions not in the passed set
|
||||
*/
|
||||
bool get_complement(const std::vector<crypto::hash> &hashes, std::vector<cryptonote::blobdata> &txes) const;
|
||||
|
||||
/**
|
||||
* @brief get info necessary for update of pool-related info in a wallet, preferably incremental
|
||||
*
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool get_pool_info(time_t start_time, bool include_sensitive, size_t max_tx_count, std::vector<std::pair<crypto::hash, tx_details>>& added_txs, std::vector<crypto::hash>& remaining_added_txids, std::vector<crypto::hash>& removed_txs, bool& incremental) const;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
@@ -591,10 +577,6 @@ namespace cryptonote
|
||||
*/
|
||||
void prune(size_t bytes = 0);
|
||||
|
||||
void add_tx_to_transient_lists(const crypto::hash& txid, double fee, time_t receive_time);
|
||||
void remove_tx_from_transient_lists(const cryptonote::sorted_tx_container::iterator& sorted_it, const crypto::hash& txid, bool sensitive);
|
||||
void track_removed_tx(const crypto::hash& txid, bool sensitive);
|
||||
|
||||
//TODO: confirm the below comments and investigate whether or not this
|
||||
// is the desired behavior
|
||||
//! map key images to transactions which spent them
|
||||
@@ -627,26 +609,6 @@ private:
|
||||
|
||||
std::atomic<uint64_t> m_cookie; //!< incremented at each change
|
||||
|
||||
// Info when transactions entered the pool, accessible by txid
|
||||
std::unordered_map<crypto::hash, time_t> m_added_txs_by_id;
|
||||
|
||||
// Info at what time the pool started to track the adding of transactions
|
||||
time_t m_added_txs_start_time;
|
||||
|
||||
struct removed_tx_info
|
||||
{
|
||||
crypto::hash txid;
|
||||
bool sensitive;
|
||||
};
|
||||
|
||||
// Info about transactions that were removed from the pool, ordered by the time
|
||||
// of deletion
|
||||
std::multimap<time_t, removed_tx_info> m_removed_txs_by_time;
|
||||
|
||||
// Info how far back in time the list of removed tx ids currently reaches
|
||||
// (it gets shorted periodically to prevent overflow)
|
||||
time_t m_removed_txs_start_time;
|
||||
|
||||
/**
|
||||
* @brief get an iterator to a transaction in the sorted container
|
||||
*
|
||||
|
||||
@@ -40,6 +40,15 @@
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "cn.block_queue"
|
||||
|
||||
namespace std {
|
||||
static_assert(sizeof(size_t) <= sizeof(boost::uuids::uuid), "boost::uuids::uuid too small");
|
||||
template<> struct hash<boost::uuids::uuid> {
|
||||
std::size_t operator()(const boost::uuids::uuid &_v) const {
|
||||
return reinterpret_cast<const std::size_t &>(_v);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace cryptonote
|
||||
{
|
||||
|
||||
@@ -463,7 +472,7 @@ bool block_queue::has_spans(const boost::uuids::uuid &connection_id) const
|
||||
float block_queue::get_speed(const boost::uuids::uuid &connection_id) const
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> lock(mutex);
|
||||
std::unordered_map<boost::uuids::uuid, float, boost::hash<boost::uuids::uuid>> speeds;
|
||||
std::unordered_map<boost::uuids::uuid, float> speeds;
|
||||
for (const auto &span: blocks)
|
||||
{
|
||||
if (span.blocks.empty())
|
||||
@@ -471,7 +480,7 @@ float block_queue::get_speed(const boost::uuids::uuid &connection_id) const
|
||||
// note that the average below does not average over the whole set, but over the
|
||||
// previous pseudo average and the latest rate: this gives much more importance
|
||||
// to the latest measurements, which is fine here
|
||||
const auto i = speeds.find(span.connection_id);
|
||||
std::unordered_map<boost::uuids::uuid, float>::iterator i = speeds.find(span.connection_id);
|
||||
if (i == speeds.end())
|
||||
speeds.insert(std::make_pair(span.connection_id, span.rate));
|
||||
else
|
||||
|
||||
@@ -979,18 +979,8 @@ namespace cryptonote
|
||||
int t_cryptonote_protocol_handler<t_core>::handle_notify_new_transactions(int command, NOTIFY_NEW_TRANSACTIONS::request& arg, cryptonote_connection_context& context)
|
||||
{
|
||||
MLOG_P2P_MESSAGE("Received NOTIFY_NEW_TRANSACTIONS (" << arg.txs.size() << " txes)");
|
||||
std::unordered_set<blobdata> seen;
|
||||
for (const auto &blob: arg.txs)
|
||||
{
|
||||
MLOGIF_P2P_MESSAGE(cryptonote::transaction tx; crypto::hash hash; bool ret = cryptonote::parse_and_validate_tx_from_blob(blob, tx, hash);, ret, "Including transaction " << hash);
|
||||
if (seen.find(blob) != seen.end())
|
||||
{
|
||||
LOG_PRINT_CCONTEXT_L1("Duplicate transaction in notification, dropping connection");
|
||||
drop_connection(context, false, false);
|
||||
return 1;
|
||||
}
|
||||
seen.insert(blob);
|
||||
}
|
||||
|
||||
if(context.m_state != cryptonote_connection_context::state_normal)
|
||||
return 1;
|
||||
|
||||
@@ -396,8 +396,6 @@ namespace levin
|
||||
for (auto& connection : connections)
|
||||
{
|
||||
std::sort(connection.first.begin(), connection.first.end()); // don't leak receive order
|
||||
connection.first.erase(std::unique(connection.first.begin(), connection.first.end()),
|
||||
connection.first.end());
|
||||
make_payload_send_txs(*zone_->p2p, std::move(connection.first), connection.second, zone_->pad_txs, true);
|
||||
}
|
||||
|
||||
@@ -743,14 +741,9 @@ namespace levin
|
||||
notify::status notify::get_status() const noexcept
|
||||
{
|
||||
if (!zone_)
|
||||
return {false, false, false};
|
||||
return {false, false};
|
||||
|
||||
// `connection_count` is only set when `!noise.empty()`.
|
||||
const std::size_t connection_count = zone_->connection_count;
|
||||
bool has_outgoing = connection_count;
|
||||
if (zone_->noise.empty())
|
||||
has_outgoing = zone_->p2p->get_out_connections_count();
|
||||
return {!zone_->noise.empty(), CRYPTONOTE_NOISE_CHANNELS <= connection_count, has_outgoing};
|
||||
return {!zone_->noise.empty(), CRYPTONOTE_NOISE_CHANNELS <= zone_->connection_count};
|
||||
}
|
||||
|
||||
void notify::new_out_connection()
|
||||
|
||||
@@ -75,8 +75,7 @@ namespace levin
|
||||
struct status
|
||||
{
|
||||
bool has_noise;
|
||||
bool connections_filled; //!< True when has zone has `CRYPTONOTE_NOISE_CHANNELS` outgoing noise channels
|
||||
bool has_outgoing; //!< True when zone has outgoing connections
|
||||
bool connections_filled;
|
||||
};
|
||||
|
||||
//! Construct an instance that cannot notify.
|
||||
|
||||
@@ -696,16 +696,6 @@ bool t_command_parser_executor::ban(const std::vector<std::string>& args)
|
||||
std::ifstream ifs(ban_list_path.string());
|
||||
for (std::string line; std::getline(ifs, line); )
|
||||
{
|
||||
// ignore comments after '#' character
|
||||
const size_t pound_idx = line.find('#');
|
||||
if (pound_idx != std::string::npos)
|
||||
line.resize(pound_idx);
|
||||
|
||||
// trim whitespace and ignore empty lines
|
||||
boost::trim(line);
|
||||
if (line.empty())
|
||||
continue;
|
||||
|
||||
auto subnet = net::get_ipv4_subnet_address(line);
|
||||
if (subnet)
|
||||
{
|
||||
|
||||
@@ -196,7 +196,7 @@ bool install_service(
|
||||
, 0
|
||||
//, GENERIC_EXECUTE | GENERIC_READ
|
||||
, SERVICE_WIN32_OWN_PROCESS
|
||||
, SERVICE_DEMAND_START
|
||||
, SERVICE_AUTO_START
|
||||
, SERVICE_ERROR_NORMAL
|
||||
, full_command.c_str()
|
||||
, nullptr
|
||||
|
||||
@@ -146,9 +146,6 @@ namespace windows {
|
||||
m_handler.run();
|
||||
|
||||
on_state_change_request_(SERVICE_CONTROL_STOP);
|
||||
|
||||
// Ensure that the service is uninstalled
|
||||
uninstall_service(m_name);
|
||||
}
|
||||
|
||||
static void WINAPI on_state_change_request(DWORD control_code)
|
||||
|
||||
@@ -317,15 +317,13 @@ namespace hw {
|
||||
{
|
||||
// sending change to yourself; derivation = a*R
|
||||
r = generate_key_derivation(txkey_pub, sender_account_keys.m_view_secret_key, derivation);
|
||||
CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation(" << txkey_pub << ", <viewkey>)");
|
||||
CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation(" << txkey_pub << ", " << sender_account_keys.m_view_secret_key << ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
// sending to the recipient; derivation = r*A (or s*C in the subaddress scheme)
|
||||
const crypto::secret_key &tx_privkey{dst_entr.is_subaddress && need_additional_txkeys ? additional_txkey.sec : tx_key};
|
||||
r = generate_key_derivation(dst_entr.addr.m_view_public_key, tx_privkey, derivation);
|
||||
CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation("
|
||||
<< dst_entr.addr.m_view_public_key << ", " << crypto::secret_key_explicit_print_ref{tx_privkey} << ")");
|
||||
r = generate_key_derivation(dst_entr.addr.m_view_public_key, dst_entr.is_subaddress && need_additional_txkeys ? additional_txkey.sec : tx_key, derivation);
|
||||
CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation(" << dst_entr.addr.m_view_public_key << ", " << (dst_entr.is_subaddress && need_additional_txkeys ? additional_txkey.sec : tx_key) << ")");
|
||||
}
|
||||
|
||||
if (need_additional_txkeys)
|
||||
|
||||
@@ -527,7 +527,6 @@ namespace hw {
|
||||
{0x2c97, 0x0004, 0, 0xffa0},
|
||||
{0x2c97, 0x0005, 0, 0xffa0},
|
||||
{0x2c97, 0x0006, 0, 0xffa0},
|
||||
{0x2c97, 0x0007, 0, 0xffa0},
|
||||
};
|
||||
|
||||
bool device_ledger::connect(void) {
|
||||
|
||||
@@ -47,6 +47,7 @@ const hardfork_t mainnet_hard_forks[] = {
|
||||
{ 19, 331458, 0, 1624793373 },
|
||||
{ 20, 514000, 0, 1677222289 },
|
||||
};
|
||||
// since Wownero starts from v7, added + 6 so that the total number of hard forks = version number
|
||||
const size_t num_mainnet_hard_forks = sizeof(mainnet_hard_forks) / sizeof(mainnet_hard_forks[0]);
|
||||
const uint64_t mainnet_hard_fork_version_1_till = 0;
|
||||
|
||||
|
||||
@@ -133,7 +133,6 @@ namespace lmdb
|
||||
//! \pre `!is_end()` \return Current key
|
||||
K get_key() const noexcept
|
||||
{
|
||||
static_assert(std::is_trivially_copyable<K>(), "key is not memcpy safe");
|
||||
assert(!is_end());
|
||||
K out;
|
||||
std::memcpy(std::addressof(out), key.data(), sizeof(out));
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace lmdb
|
||||
static expect<F> get_value(MDB_val value) noexcept
|
||||
{
|
||||
static_assert(std::is_same<U, V>(), "bad MONERO_FIELD?");
|
||||
static_assert(std::is_trivially_copyable<F>(), "F must be memcpy safe");
|
||||
static_assert(std::is_pod<F>(), "F must be POD");
|
||||
static_assert(sizeof(F) + offset <= sizeof(U), "bad field type and/or offset");
|
||||
|
||||
if (value.mv_size != sizeof(U))
|
||||
|
||||
@@ -111,7 +111,6 @@ namespace lmdb
|
||||
template<typename T, std::size_t offset = 0>
|
||||
inline int less(MDB_val const* left, MDB_val const* right) noexcept
|
||||
{
|
||||
static_assert(std::is_trivially_copyable<T>(), "memcpy will not work");
|
||||
if (!left || !right || left->mv_size < sizeof(T) + offset || right->mv_size < sizeof(T) + offset)
|
||||
{
|
||||
assert("invalid use of custom comparison" == 0);
|
||||
@@ -128,7 +127,7 @@ namespace lmdb
|
||||
/*!
|
||||
A LMDB comparison function that uses `std::memcmp`.
|
||||
|
||||
\toaram T has standard layout and an alignment of 1
|
||||
\toaram T is `!epee::has_padding`
|
||||
\tparam offset to `T` within the value.
|
||||
|
||||
\return The result of `std::memcmp` over the value.
|
||||
@@ -136,7 +135,7 @@ namespace lmdb
|
||||
template<typename T, std::size_t offset = 0>
|
||||
inline int compare(MDB_val const* left, MDB_val const* right) noexcept
|
||||
{
|
||||
static_assert(std::is_standard_layout<T>() && alignof(T) == 1, "memcmp will not work");
|
||||
static_assert(!epee::has_padding<T>(), "memcmp will not work");
|
||||
if (!left || !right || left->mv_size < sizeof(T) + offset || right->mv_size < sizeof(T) + offset)
|
||||
{
|
||||
assert("invalid use of custom comparison" == 0);
|
||||
|
||||
@@ -162,8 +162,8 @@ namespace lmdb
|
||||
G get_value() const noexcept
|
||||
{
|
||||
static_assert(std::is_same<U, T>(), "bad MONERO_FIELD usage?");
|
||||
static_assert(std::is_trivially_copyable<U>(), "value type must be memcpy safe");
|
||||
static_assert(std::is_trivially_copyable<G>(), "field type must be memcpy safe");
|
||||
static_assert(std::is_pod<U>(), "value type must be pod");
|
||||
static_assert(std::is_pod<G>(), "field type must be pod");
|
||||
static_assert(sizeof(G) + uoffset <= sizeof(U), "bad field and/or offset");
|
||||
assert(sizeof(G) + uoffset <= values.size());
|
||||
assert(!is_end());
|
||||
|
||||
@@ -206,13 +206,8 @@ namespace multisig
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
void multisig_kex_msg::parse_and_validate_msg()
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(MULTISIG_KEX_MSG_V2_MAGIC_1.size() == MULTISIG_KEX_MSG_V2_MAGIC_N.size(),
|
||||
"Multisig kex msg magic inconsistency.");
|
||||
CHECK_AND_ASSERT_THROW_MES(MULTISIG_KEX_MSG_V2_MAGIC_1.size() >= MULTISIG_KEX_V1_MAGIC.size(),
|
||||
"Multisig kex msg magic inconsistency.");
|
||||
|
||||
// check message type
|
||||
CHECK_AND_ASSERT_THROW_MES(m_msg.size() >= MULTISIG_KEX_MSG_V2_MAGIC_1.size(), "Kex message unexpectedly small.");
|
||||
CHECK_AND_ASSERT_THROW_MES(m_msg.size() > 0, "Kex message unexpectedly empty.");
|
||||
CHECK_AND_ASSERT_THROW_MES(m_msg.substr(0, MULTISIG_KEX_V1_MAGIC.size()) != MULTISIG_KEX_V1_MAGIC,
|
||||
"V1 multisig kex messages are deprecated (unsafe).");
|
||||
CHECK_AND_ASSERT_THROW_MES(m_msg.substr(0, MULTISIG_KEX_MSG_V1_MAGIC.size()) != MULTISIG_KEX_MSG_V1_MAGIC,
|
||||
@@ -220,6 +215,8 @@ namespace multisig
|
||||
|
||||
// deserialize the message
|
||||
std::string msg_no_magic;
|
||||
CHECK_AND_ASSERT_THROW_MES(MULTISIG_KEX_MSG_V2_MAGIC_1.size() == MULTISIG_KEX_MSG_V2_MAGIC_N.size(),
|
||||
"Multisig kex msg magic inconsistency.");
|
||||
CHECK_AND_ASSERT_THROW_MES(tools::base58::decode(m_msg.substr(MULTISIG_KEX_MSG_V2_MAGIC_1.size()), msg_no_magic),
|
||||
"Multisig kex msg decoding error.");
|
||||
binary_archive<false> b_archive{epee::strspan<std::uint8_t>(msg_no_magic)};
|
||||
|
||||
@@ -820,6 +820,7 @@ tx_builder_ringct_t::~tx_builder_ringct_t()
|
||||
bool tx_builder_ringct_t::init(
|
||||
const cryptonote::account_keys& account_keys,
|
||||
const std::vector<std::uint8_t>& extra,
|
||||
const std::uint64_t unlock_time,
|
||||
const std::uint32_t subaddr_account,
|
||||
const std::set<std::uint32_t>& subaddr_minor_indices,
|
||||
std::vector<cryptonote::tx_source_entry>& sources,
|
||||
@@ -853,7 +854,7 @@ bool tx_builder_ringct_t::init(
|
||||
|
||||
// misc. fields
|
||||
unsigned_tx.version = 2; //rct = 2
|
||||
unsigned_tx.unlock_time = 0;
|
||||
unsigned_tx.unlock_time = unlock_time;
|
||||
|
||||
// sort inputs
|
||||
sort_sources(sources);
|
||||
|
||||
@@ -71,6 +71,7 @@ public:
|
||||
bool init(
|
||||
const cryptonote::account_keys& account_keys,
|
||||
const std::vector<std::uint8_t>& extra,
|
||||
const std::uint64_t unlock_time,
|
||||
const std::uint32_t subaddr_account,
|
||||
const std::set<std::uint32_t>& subaddr_minor_indices,
|
||||
std::vector<cryptonote::tx_source_entry>& sources,
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace net
|
||||
struct i2p_serialized
|
||||
{
|
||||
std::string host;
|
||||
std::uint16_t port; //! Leave for compatability with older clients
|
||||
std::uint16_t port;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(host)
|
||||
@@ -80,7 +80,8 @@ namespace net
|
||||
};
|
||||
}
|
||||
|
||||
i2p_address::i2p_address(const boost::string_ref host) noexcept
|
||||
i2p_address::i2p_address(const boost::string_ref host, const std::uint16_t port) noexcept
|
||||
: port_(port)
|
||||
{
|
||||
// this is a private constructor, throw if moved to public
|
||||
assert(host.size() < sizeof(host_));
|
||||
@@ -96,19 +97,27 @@ namespace net
|
||||
}
|
||||
|
||||
i2p_address::i2p_address() noexcept
|
||||
: port_(0)
|
||||
{
|
||||
static_assert(sizeof(unknown_host) <= sizeof(host_), "bad buffer size");
|
||||
std::memcpy(host_, unknown_host, sizeof(unknown_host));
|
||||
std::memset(host_ + sizeof(unknown_host), 0, sizeof(host_) - sizeof(unknown_host));
|
||||
}
|
||||
|
||||
expect<i2p_address> i2p_address::make(const boost::string_ref address)
|
||||
expect<i2p_address> i2p_address::make(const boost::string_ref address, const std::uint16_t default_port)
|
||||
{
|
||||
boost::string_ref host = address.substr(0, address.rfind(':'));
|
||||
const boost::string_ref port =
|
||||
address.substr(host.size() + (host.size() == address.size() ? 0 : 1));
|
||||
|
||||
MONERO_CHECK(host_check(host));
|
||||
|
||||
std::uint16_t porti = default_port;
|
||||
if (!port.empty() && !epee::string_tools::get_xtype_from_string(porti, std::string{port}))
|
||||
return {net::error::invalid_port};
|
||||
|
||||
static_assert(b32_length + sizeof(tld) == sizeof(i2p_address::host_), "bad internal host size");
|
||||
return i2p_address{host};
|
||||
return i2p_address{host, porti};
|
||||
}
|
||||
|
||||
bool i2p_address::_load(epee::serialization::portable_storage& src, epee::serialization::section* hparent)
|
||||
@@ -118,21 +127,23 @@ namespace net
|
||||
{
|
||||
std::memcpy(host_, in.host.data(), in.host.size());
|
||||
std::memset(host_ + in.host.size(), 0, sizeof(host_) - in.host.size());
|
||||
port_ = in.port;
|
||||
return true;
|
||||
}
|
||||
static_assert(sizeof(unknown_host) <= sizeof(host_), "bad buffer size");
|
||||
std::memcpy(host_, unknown_host, sizeof(unknown_host)); // include null terminator
|
||||
port_ = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool i2p_address::store(epee::serialization::portable_storage& dest, epee::serialization::section* hparent) const
|
||||
{
|
||||
// Set port to 1 for backwards compatability; zero is invalid port
|
||||
const i2p_serialized out{std::string{host_}, 1};
|
||||
const i2p_serialized out{std::string{host_}, port_};
|
||||
return out.store(dest, hparent);
|
||||
}
|
||||
|
||||
i2p_address::i2p_address(const i2p_address& rhs) noexcept
|
||||
: port_(rhs.port_)
|
||||
{
|
||||
std::memcpy(host_, rhs.host_, sizeof(host_));
|
||||
}
|
||||
@@ -141,6 +152,7 @@ namespace net
|
||||
{
|
||||
if (this != std::addressof(rhs))
|
||||
{
|
||||
port_ = rhs.port_;
|
||||
std::memcpy(host_, rhs.host_, sizeof(host_));
|
||||
}
|
||||
return *this;
|
||||
@@ -154,12 +166,13 @@ namespace net
|
||||
|
||||
bool i2p_address::equal(const i2p_address& rhs) const noexcept
|
||||
{
|
||||
return is_same_host(rhs);
|
||||
return port_ == rhs.port_ && is_same_host(rhs);
|
||||
}
|
||||
|
||||
bool i2p_address::less(const i2p_address& rhs) const noexcept
|
||||
{
|
||||
return std::strcmp(host_str(), rhs.host_str()) < 0;
|
||||
int res = std::strcmp(host_str(), rhs.host_str());
|
||||
return res < 0 || (res == 0 && port() < rhs.port());
|
||||
}
|
||||
|
||||
bool i2p_address::is_same_host(const i2p_address& rhs) const noexcept
|
||||
@@ -169,6 +182,20 @@ namespace net
|
||||
|
||||
std::string i2p_address::str() const
|
||||
{
|
||||
return host_str();
|
||||
const std::size_t host_length = std::strlen(host_str());
|
||||
const std::size_t port_length =
|
||||
port_ == 0 ? 0 : std::numeric_limits<std::uint16_t>::digits10 + 2;
|
||||
|
||||
std::string out{};
|
||||
out.reserve(host_length + port_length);
|
||||
out.assign(host_str(), host_length);
|
||||
|
||||
if (port_ != 0)
|
||||
{
|
||||
out.push_back(':');
|
||||
namespace karma = boost::spirit::karma;
|
||||
karma::generate(std::back_inserter(out), karma::ushort_, port());
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,10 +50,11 @@ namespace net
|
||||
//! b32 i2p address; internal format not condensed/decoded.
|
||||
class i2p_address
|
||||
{
|
||||
std::uint16_t port_;
|
||||
char host_[61]; // null-terminated
|
||||
|
||||
//! Keep in private, `host.size()` has no runtime check
|
||||
i2p_address(boost::string_ref host) noexcept;
|
||||
i2p_address(boost::string_ref host, std::uint16_t port) noexcept;
|
||||
|
||||
public:
|
||||
//! \return Size of internal buffer for host.
|
||||
@@ -73,7 +74,7 @@ namespace net
|
||||
with `default_port` being used if port is not specified in
|
||||
`address`.
|
||||
*/
|
||||
static expect<i2p_address> make(boost::string_ref address);
|
||||
static expect<i2p_address> make(boost::string_ref address, std::uint16_t default_port = 0);
|
||||
|
||||
//! Load from epee p2p format, and \return false if not valid tor address
|
||||
bool _load(epee::serialization::portable_storage& src, epee::serialization::section* hparent);
|
||||
@@ -102,8 +103,8 @@ namespace net
|
||||
//! \return Null-terminated `x.b32.i2p` value or `unknown_str()`.
|
||||
const char* host_str() const noexcept { return host_; }
|
||||
|
||||
//! \return `1` to work with I2P socks which considers `0` error.
|
||||
std::uint16_t port() const noexcept { return 1; }
|
||||
//! \return Port value or `0` if unspecified.
|
||||
std::uint16_t port() const noexcept { return port_; }
|
||||
|
||||
static constexpr bool is_loopback() noexcept { return false; }
|
||||
static constexpr bool is_local() noexcept { return false; }
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace net
|
||||
if (host_str_ref.ends_with(".onion"))
|
||||
return tor_address::make(address, default_port);
|
||||
if (host_str_ref.ends_with(".i2p"))
|
||||
return i2p_address::make(address);
|
||||
return i2p_address::make(address, default_port);
|
||||
|
||||
boost::system::error_code ec;
|
||||
boost::asio::ip::address_v6 v6 = boost::asio::ip::address_v6::from_string(host_str, ec);
|
||||
|
||||
@@ -531,16 +531,6 @@ namespace nodetool
|
||||
std::istringstream iss(banned_ips);
|
||||
for (std::string line; std::getline(iss, line); )
|
||||
{
|
||||
// ignore comments after '#' character
|
||||
const size_t pound_idx = line.find('#');
|
||||
if (pound_idx != std::string::npos)
|
||||
line.resize(pound_idx);
|
||||
|
||||
// trim whitespace and ignore empty lines
|
||||
boost::trim(line);
|
||||
if (line.empty())
|
||||
continue;
|
||||
|
||||
auto subnet = net::get_ipv4_subnet_address(line);
|
||||
if (subnet)
|
||||
{
|
||||
@@ -724,15 +714,18 @@ namespace nodetool
|
||||
}
|
||||
else
|
||||
{
|
||||
full_addrs.insert("158.69.60.225:34567"); // explore.wownero.com
|
||||
full_addrs.insert("159.65.91.59:34567"); // jw
|
||||
full_addrs.insert("51.161.131.176:34567"); // node.suchwow.xyz
|
||||
full_addrs.insert("88.198.199.23:34567");
|
||||
full_addrs.insert("192.99.8.110:34567"); // node.monerodevs.org
|
||||
full_addrs.insert("37.187.74.171"); // node2.monerodevs.org
|
||||
full_addrs.insert("88.99.195.15"); // node3.monerodevs.org
|
||||
full_addrs.insert("172.67.197.39:34567"); // wowmom.0z.network
|
||||
full_addrs.insert("195.94.188.201:34567"); // spippolatori.it
|
||||
//full_addrs.insert("158.69.60.225:34567"); // explore.wownero.com
|
||||
//full_addrs.insert("159.65.91.59:34567"); // jw
|
||||
//full_addrs.insert("51.161.131.176:34567"); // node.suchwow.xyz
|
||||
//full_addrs.insert("167.114.196.241:34567"); // wowbux.org
|
||||
//full_addrs.insert("142.93.144.79:34567"); // idontwanttogototoronto.wow.fail
|
||||
//full_addrs.insert("51.75.76.161:34567"); // eu-west-1.wow.xmr.pm
|
||||
//full_addrs.insert("145.239.93.75:34567"); // eu-west-2.wow.xmr.pm
|
||||
//full_addrs.insert("88.198.199.23:34567");
|
||||
//full_addrs.insert("167.114.119.46:34567"); // wownero.stackwallet.com
|
||||
full_addrs.insert("143.198.195.132:34567"); // singapore.muchwow.lol
|
||||
full_addrs.insert("134.122.53.193:34567"); // amsterdam.muchwow.lol
|
||||
full_addrs.insert("204.48.28.218:34567"); // nyc.muchwow.lol
|
||||
}
|
||||
return full_addrs;
|
||||
}
|
||||
@@ -864,8 +857,8 @@ namespace nodetool
|
||||
{
|
||||
return {
|
||||
"77uase4p6y6jsjdf6z2kdgpxgh7nkvywagvhurzphbm7vrkyj2d2gdid.onion:34566",
|
||||
"jhy4hqymdkfj2u7bdi7m2vr5qheom7gjyg7fraktnlyksalhmpbemiqd.onion:34566",
|
||||
"ukpgpdd5gqvholcctejvaaig5hb266td6zaszt55eivuf7docoox5lid.onion:34566",
|
||||
"v2admi6gbeprxnk6i2oscizhgy4v5ixu6iezkhj5udiwbfjjs2w7dnid.onion:34566",
|
||||
"ttc6kxud3fikyaypn5voknyyvqje7j3wnoevsb7rfjerolynnisurkqd.onion:34566",
|
||||
};
|
||||
}
|
||||
return {};
|
||||
@@ -873,6 +866,9 @@ namespace nodetool
|
||||
if (m_nettype == cryptonote::MAINNET)
|
||||
{
|
||||
return {
|
||||
"lrq65qrhpbt5voom2ncvowpes6kvobodkldhpuwhxlsrpugmgmlq.b32.i2p:34565",
|
||||
"72tbpgeczdtx2q2enbyaqcot7mghbnjenjkmdpyylrssqehr746a.b32.i2p:34565",
|
||||
"rkel2qy7xv3cc5bnxfrzwgh3jvd4woagd4vlhr3qsdxy6cfkimnq.b32.i2p:34565",
|
||||
};
|
||||
}
|
||||
return {};
|
||||
@@ -2022,12 +2018,14 @@ namespace nodetool
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::update_dns_blocklist()
|
||||
{
|
||||
if (!m_enable_dns_blocklist)
|
||||
return true;
|
||||
/*if (!m_enable_dns_blocklist) // TODO: temp forced DNS blocklist
|
||||
return true;*/
|
||||
if (m_nettype != cryptonote::MAINNET)
|
||||
return true;
|
||||
|
||||
static const std::vector<std::string> dns_urls = {
|
||||
"blocklist.wownero.com",
|
||||
"blocklist2.wownero.com",
|
||||
};
|
||||
|
||||
std::vector<std::string> records;
|
||||
@@ -2288,12 +2286,11 @@ namespace nodetool
|
||||
if (enet::zone::tor < network->first)
|
||||
break; // unknown network
|
||||
|
||||
const auto status = network->second.m_notifier.get_status();
|
||||
if (network->second.m_connect && status.has_outgoing)
|
||||
if (network->second.m_connect)
|
||||
return send(*network);
|
||||
}
|
||||
|
||||
MWARNING("Unable to send " << txs.size() << " transaction(s): anonymity networks had no outgoing connections");
|
||||
// configuration should not allow this scenario
|
||||
return enet::zone::invalid;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
#include <boost/serialization/version.hpp>
|
||||
|
||||
#include "net_peerlist_boost_serialization.h"
|
||||
#include "common/util.h"
|
||||
|
||||
|
||||
namespace nodetool
|
||||
@@ -201,7 +200,7 @@ namespace nodetool
|
||||
if (!out)
|
||||
{
|
||||
// if failed, try reading in unportable mode
|
||||
tools::copy_file(path, path + ".unportable");
|
||||
boost::filesystem::copy_file(path, path + ".unportable", boost::filesystem::copy_option::overwrite_if_exists);
|
||||
src_file.close();
|
||||
src_file.open( path , std::ios_base::binary | std::ios_base::in);
|
||||
if(src_file.fail())
|
||||
|
||||
@@ -196,7 +196,7 @@ namespace boost
|
||||
if (std::strcmp(host, net::i2p_address::unknown_str()) == 0)
|
||||
na = net::i2p_address::unknown();
|
||||
else
|
||||
na = MONERO_UNWRAP(net::i2p_address::make(host));
|
||||
na = MONERO_UNWRAP(net::i2p_address::make(host, port));
|
||||
}
|
||||
|
||||
template <class Archive, class ver_type>
|
||||
|
||||
@@ -329,10 +329,6 @@ namespace rct {
|
||||
ctkeyV outPk;
|
||||
xmr_amount txnFee; // contains b
|
||||
|
||||
rctSigBase() :
|
||||
type(RCTTypeNull), message{}, mixRing{}, pseudoOuts{}, ecdhInfo{}, outPk{}, txnFee(0)
|
||||
{}
|
||||
|
||||
template<bool W, template <bool> class Archive>
|
||||
bool serialize_rctsig_base(Archive<W> &ar, size_t inputs, size_t outputs)
|
||||
{
|
||||
@@ -370,17 +366,11 @@ namespace rct {
|
||||
{
|
||||
if (type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeBulletproofPlus)
|
||||
{
|
||||
// Since RCTTypeBulletproof2 enote types, we don't serialize the blinding factor, and only serialize the
|
||||
// first 8 bytes of ecdhInfo[i].amount
|
||||
ar.begin_object();
|
||||
crypto::hash8 trunc_amount; // placeholder variable needed to maintain "strict aliasing"
|
||||
if (!typename Archive<W>::is_saving()) // loading
|
||||
if (!typename Archive<W>::is_saving())
|
||||
memset(ecdhInfo[i].amount.bytes, 0, sizeof(ecdhInfo[i].amount.bytes));
|
||||
else // saving
|
||||
memcpy(trunc_amount.data, ecdhInfo[i].amount.bytes, sizeof(trunc_amount));
|
||||
FIELD_N("amount", trunc_amount);
|
||||
if (!typename Archive<W>::is_saving()) // loading
|
||||
memcpy(ecdhInfo[i].amount.bytes, trunc_amount.data, sizeof(trunc_amount));
|
||||
crypto::hash8 &amount = (crypto::hash8&)ecdhInfo[i].amount;
|
||||
FIELD(amount);
|
||||
ar.end_object();
|
||||
}
|
||||
else
|
||||
|
||||
@@ -599,165 +599,88 @@ namespace cryptonote
|
||||
|
||||
CHECK_PAYMENT(req, res, 1);
|
||||
|
||||
res.daemon_time = (uint64_t)time(NULL);
|
||||
// Always set daemon time, and set it early rather than late, as delivering some incremental pool
|
||||
// info twice because of slightly overlapping time intervals is no problem, whereas producing gaps
|
||||
// and never delivering something is
|
||||
|
||||
bool get_blocks = false;
|
||||
bool get_pool = false;
|
||||
switch (req.requested_info)
|
||||
// quick check for noop
|
||||
if (!req.block_ids.empty())
|
||||
{
|
||||
case COMMAND_RPC_GET_BLOCKS_FAST::BLOCKS_ONLY:
|
||||
// Compatibility value 0: Clients that do not set 'requested_info' want blocks, and only blocks
|
||||
get_blocks = true;
|
||||
break;
|
||||
case COMMAND_RPC_GET_BLOCKS_FAST::BLOCKS_AND_POOL:
|
||||
get_blocks = true;
|
||||
get_pool = true;
|
||||
break;
|
||||
case COMMAND_RPC_GET_BLOCKS_FAST::POOL_ONLY:
|
||||
get_pool = true;
|
||||
break;
|
||||
default:
|
||||
res.status = "Failed, wrong requested info";
|
||||
return true;
|
||||
}
|
||||
|
||||
res.pool_info_extent = COMMAND_RPC_GET_BLOCKS_FAST::NONE;
|
||||
|
||||
if (get_pool)
|
||||
{
|
||||
const bool restricted = m_restricted && ctx;
|
||||
const bool request_has_rpc_origin = ctx != NULL;
|
||||
const bool allow_sensitive = !request_has_rpc_origin || !restricted;
|
||||
const size_t max_tx_count = restricted ? RESTRICTED_TRANSACTIONS_COUNT : std::numeric_limits<size_t>::max();
|
||||
|
||||
bool incremental;
|
||||
std::vector<std::pair<crypto::hash, tx_memory_pool::tx_details>> added_pool_txs;
|
||||
bool success = m_core.get_pool_info((time_t)req.pool_info_since, allow_sensitive, max_tx_count, added_pool_txs, res.remaining_added_pool_txids, res.removed_pool_txids, incremental);
|
||||
if (success)
|
||||
uint64_t last_block_height;
|
||||
crypto::hash last_block_hash;
|
||||
m_core.get_blockchain_top(last_block_height, last_block_hash);
|
||||
if (last_block_hash == req.block_ids.front())
|
||||
{
|
||||
res.added_pool_txs.clear();
|
||||
if (m_rpc_payment)
|
||||
{
|
||||
CHECK_PAYMENT_SAME_TS(req, res, added_pool_txs.size() * COST_PER_TX + (res.remaining_added_pool_txids.size() + res.removed_pool_txids.size()) * COST_PER_POOL_HASH);
|
||||
}
|
||||
for (const auto &added_pool_tx: added_pool_txs)
|
||||
{
|
||||
COMMAND_RPC_GET_BLOCKS_FAST::pool_tx_info info;
|
||||
info.tx_hash = added_pool_tx.first;
|
||||
std::stringstream oss;
|
||||
binary_archive<true> ar(oss);
|
||||
bool r = req.prune
|
||||
? const_cast<cryptonote::transaction&>(added_pool_tx.second.tx).serialize_base(ar)
|
||||
: ::serialization::serialize(ar, const_cast<cryptonote::transaction&>(added_pool_tx.second.tx));
|
||||
if (!r)
|
||||
{
|
||||
res.status = "Failed to serialize transaction";
|
||||
return true;
|
||||
}
|
||||
info.tx_blob = oss.str();
|
||||
info.double_spend_seen = added_pool_tx.second.double_spend_seen;
|
||||
res.added_pool_txs.push_back(std::move(info));
|
||||
}
|
||||
}
|
||||
if (success)
|
||||
{
|
||||
res.pool_info_extent = incremental ? COMMAND_RPC_GET_BLOCKS_FAST::INCREMENTAL : COMMAND_RPC_GET_BLOCKS_FAST::FULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
res.status = "Failed to get pool info";
|
||||
res.start_height = 0;
|
||||
res.current_height = m_core.get_current_blockchain_height();
|
||||
res.status = CORE_RPC_STATUS_OK;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (get_blocks)
|
||||
size_t max_blocks = COMMAND_RPC_GET_BLOCKS_FAST_MAX_BLOCK_COUNT;
|
||||
if (m_rpc_payment)
|
||||
{
|
||||
// quick check for noop
|
||||
if (!req.block_ids.empty())
|
||||
max_blocks = res.credits / COST_PER_BLOCK;
|
||||
if (max_blocks > COMMAND_RPC_GET_BLOCKS_FAST_MAX_BLOCK_COUNT)
|
||||
max_blocks = COMMAND_RPC_GET_BLOCKS_FAST_MAX_BLOCK_COUNT;
|
||||
if (max_blocks == 0)
|
||||
{
|
||||
uint64_t last_block_height;
|
||||
crypto::hash last_block_hash;
|
||||
m_core.get_blockchain_top(last_block_height, last_block_hash);
|
||||
if (last_block_hash == req.block_ids.front())
|
||||
res.status = CORE_RPC_STATUS_PAYMENT_REQUIRED;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata> > > > bs;
|
||||
if(!m_core.find_blockchain_supplement(req.start_height, req.block_ids, bs, res.current_height, res.start_height, req.prune, !req.no_miner_tx, max_blocks, COMMAND_RPC_GET_BLOCKS_FAST_MAX_TX_COUNT))
|
||||
{
|
||||
res.status = "Failed";
|
||||
add_host_fail(ctx);
|
||||
return true;
|
||||
}
|
||||
|
||||
CHECK_PAYMENT_SAME_TS(req, res, bs.size() * COST_PER_BLOCK);
|
||||
|
||||
size_t size = 0, ntxes = 0;
|
||||
res.blocks.reserve(bs.size());
|
||||
res.output_indices.reserve(bs.size());
|
||||
for(auto& bd: bs)
|
||||
{
|
||||
res.blocks.resize(res.blocks.size()+1);
|
||||
res.blocks.back().pruned = req.prune;
|
||||
res.blocks.back().block = bd.first.first;
|
||||
size += bd.first.first.size();
|
||||
res.output_indices.push_back(COMMAND_RPC_GET_BLOCKS_FAST::block_output_indices());
|
||||
ntxes += bd.second.size();
|
||||
res.output_indices.back().indices.reserve(1 + bd.second.size());
|
||||
if (req.no_miner_tx)
|
||||
res.output_indices.back().indices.push_back(COMMAND_RPC_GET_BLOCKS_FAST::tx_output_indices());
|
||||
res.blocks.back().txs.reserve(bd.second.size());
|
||||
for (std::vector<std::pair<crypto::hash, cryptonote::blobdata>>::iterator i = bd.second.begin(); i != bd.second.end(); ++i)
|
||||
{
|
||||
res.blocks.back().txs.push_back({std::move(i->second), crypto::null_hash});
|
||||
i->second.clear();
|
||||
i->second.shrink_to_fit();
|
||||
size += res.blocks.back().txs.back().blob.size();
|
||||
}
|
||||
|
||||
const size_t n_txes_to_lookup = bd.second.size() + (req.no_miner_tx ? 0 : 1);
|
||||
if (n_txes_to_lookup > 0)
|
||||
{
|
||||
std::vector<std::vector<uint64_t>> indices;
|
||||
bool r = m_core.get_tx_outputs_gindexs(req.no_miner_tx ? bd.second.front().first : bd.first.second, n_txes_to_lookup, indices);
|
||||
if (!r)
|
||||
{
|
||||
res.start_height = 0;
|
||||
res.current_height = last_block_height + 1;
|
||||
res.status = CORE_RPC_STATUS_OK;
|
||||
res.status = "Failed";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
size_t max_blocks = COMMAND_RPC_GET_BLOCKS_FAST_MAX_BLOCK_COUNT;
|
||||
if (m_rpc_payment)
|
||||
{
|
||||
max_blocks = res.credits / COST_PER_BLOCK;
|
||||
if (max_blocks > COMMAND_RPC_GET_BLOCKS_FAST_MAX_BLOCK_COUNT)
|
||||
max_blocks = COMMAND_RPC_GET_BLOCKS_FAST_MAX_BLOCK_COUNT;
|
||||
if (max_blocks == 0)
|
||||
if (indices.size() != n_txes_to_lookup || res.output_indices.back().indices.size() != (req.no_miner_tx ? 1 : 0))
|
||||
{
|
||||
res.status = CORE_RPC_STATUS_PAYMENT_REQUIRED;
|
||||
res.status = "Failed";
|
||||
return true;
|
||||
}
|
||||
for (size_t i = 0; i < indices.size(); ++i)
|
||||
res.output_indices.back().indices.push_back({std::move(indices[i])});
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata> > > > bs;
|
||||
if(!m_core.find_blockchain_supplement(req.start_height, req.block_ids, bs, res.current_height, res.start_height, req.prune, !req.no_miner_tx, max_blocks, COMMAND_RPC_GET_BLOCKS_FAST_MAX_TX_COUNT))
|
||||
{
|
||||
res.status = "Failed";
|
||||
add_host_fail(ctx);
|
||||
return true;
|
||||
}
|
||||
|
||||
CHECK_PAYMENT_SAME_TS(req, res, bs.size() * COST_PER_BLOCK);
|
||||
|
||||
size_t size = 0, ntxes = 0;
|
||||
res.blocks.reserve(bs.size());
|
||||
res.output_indices.reserve(bs.size());
|
||||
for(auto& bd: bs)
|
||||
{
|
||||
res.blocks.resize(res.blocks.size()+1);
|
||||
res.blocks.back().pruned = req.prune;
|
||||
res.blocks.back().block = bd.first.first;
|
||||
size += bd.first.first.size();
|
||||
res.output_indices.push_back(COMMAND_RPC_GET_BLOCKS_FAST::block_output_indices());
|
||||
ntxes += bd.second.size();
|
||||
res.output_indices.back().indices.reserve(1 + bd.second.size());
|
||||
if (req.no_miner_tx)
|
||||
res.output_indices.back().indices.push_back(COMMAND_RPC_GET_BLOCKS_FAST::tx_output_indices());
|
||||
res.blocks.back().txs.reserve(bd.second.size());
|
||||
for (std::vector<std::pair<crypto::hash, cryptonote::blobdata>>::iterator i = bd.second.begin(); i != bd.second.end(); ++i)
|
||||
{
|
||||
res.blocks.back().txs.push_back({std::move(i->second), crypto::null_hash});
|
||||
i->second.clear();
|
||||
i->second.shrink_to_fit();
|
||||
size += res.blocks.back().txs.back().blob.size();
|
||||
}
|
||||
|
||||
const size_t n_txes_to_lookup = bd.second.size() + (req.no_miner_tx ? 0 : 1);
|
||||
if (n_txes_to_lookup > 0)
|
||||
{
|
||||
std::vector<std::vector<uint64_t>> indices;
|
||||
bool r = m_core.get_tx_outputs_gindexs(req.no_miner_tx ? bd.second.front().first : bd.first.second, n_txes_to_lookup, indices);
|
||||
if (!r)
|
||||
{
|
||||
res.status = "Failed";
|
||||
return true;
|
||||
}
|
||||
if (indices.size() != n_txes_to_lookup || res.output_indices.back().indices.size() != (req.no_miner_tx ? 1 : 0))
|
||||
{
|
||||
res.status = "Failed";
|
||||
return true;
|
||||
}
|
||||
for (size_t i = 0; i < indices.size(); ++i)
|
||||
res.output_indices.back().indices.push_back({std::move(indices[i])});
|
||||
}
|
||||
}
|
||||
MDEBUG("on_get_blocks: " << bs.size() << " blocks, " << ntxes << " txes, size " << size);
|
||||
}
|
||||
|
||||
MDEBUG("on_get_blocks: " << bs.size() << " blocks, " << ntxes << " txes, size " << size);
|
||||
res.status = CORE_RPC_STATUS_OK;
|
||||
return true;
|
||||
}
|
||||
@@ -997,16 +920,17 @@ namespace cryptonote
|
||||
// try the pool for any missing txes
|
||||
size_t found_in_pool = 0;
|
||||
std::unordered_set<crypto::hash> pool_tx_hashes;
|
||||
std::unordered_map<crypto::hash, tx_memory_pool::tx_details> per_tx_pool_tx_details;
|
||||
std::unordered_map<crypto::hash, tx_info> per_tx_pool_tx_info;
|
||||
if (!missed_txs.empty())
|
||||
{
|
||||
std::vector<std::pair<crypto::hash, tx_memory_pool::tx_details>> pool_txs;
|
||||
bool r = m_core.get_pool_transactions_info(missed_txs, pool_txs, !request_has_rpc_origin || !restricted);
|
||||
std::vector<tx_info> pool_tx_info;
|
||||
std::vector<spent_key_image_info> pool_key_image_info;
|
||||
bool r = m_core.get_pool_transactions_and_spent_keys_info(pool_tx_info, pool_key_image_info, !request_has_rpc_origin || !restricted);
|
||||
if(r)
|
||||
{
|
||||
// sort to match original request
|
||||
std::vector<std::tuple<crypto::hash, cryptonote::blobdata, crypto::hash, cryptonote::blobdata>> sorted_txs;
|
||||
std::vector<std::pair<crypto::hash, tx_memory_pool::tx_details>>::const_iterator i;
|
||||
std::vector<tx_info>::const_iterator i;
|
||||
unsigned txs_processed = 0;
|
||||
for (const crypto::hash &h: vh)
|
||||
{
|
||||
@@ -1026,23 +950,36 @@ namespace cryptonote
|
||||
sorted_txs.push_back(std::move(txs[txs_processed]));
|
||||
++txs_processed;
|
||||
}
|
||||
else if ((i = std::find_if(pool_txs.begin(), pool_txs.end(), [h](const std::pair<crypto::hash, tx_memory_pool::tx_details> &pt) { return h == pt.first; })) != pool_txs.end())
|
||||
else if ((i = std::find_if(pool_tx_info.begin(), pool_tx_info.end(), [h](const tx_info &txi) { return epee::string_tools::pod_to_hex(h) == txi.id_hash; })) != pool_tx_info.end())
|
||||
{
|
||||
const tx_memory_pool::tx_details &td = i->second;
|
||||
cryptonote::transaction tx;
|
||||
if (!cryptonote::parse_and_validate_tx_from_blob(i->tx_blob, tx))
|
||||
{
|
||||
res.status = "Failed to parse and validate tx from blob";
|
||||
return true;
|
||||
}
|
||||
std::stringstream ss;
|
||||
binary_archive<true> ba(ss);
|
||||
bool r = const_cast<cryptonote::transaction&>(td.tx).serialize_base(ba);
|
||||
bool r = const_cast<cryptonote::transaction&>(tx).serialize_base(ba);
|
||||
if (!r)
|
||||
{
|
||||
res.status = "Failed to serialize transaction base";
|
||||
return true;
|
||||
}
|
||||
const cryptonote::blobdata pruned = ss.str();
|
||||
const crypto::hash prunable_hash = td.tx.version == 1 ? crypto::null_hash : get_transaction_prunable_hash(td.tx);
|
||||
sorted_txs.push_back(std::make_tuple(h, pruned, prunable_hash, std::string(td.tx_blob, pruned.size())));
|
||||
const crypto::hash prunable_hash = tx.version == 1 ? crypto::null_hash : get_transaction_prunable_hash(tx);
|
||||
sorted_txs.push_back(std::make_tuple(h, pruned, prunable_hash, std::string(i->tx_blob, pruned.size())));
|
||||
missed_txs.erase(std::find(missed_txs.begin(), missed_txs.end(), h));
|
||||
pool_tx_hashes.insert(h);
|
||||
per_tx_pool_tx_details.insert(std::make_pair(h, td));
|
||||
const std::string hash_string = epee::string_tools::pod_to_hex(h);
|
||||
for (const auto &ti: pool_tx_info)
|
||||
{
|
||||
if (ti.id_hash == hash_string)
|
||||
{
|
||||
per_tx_pool_tx_info.insert(std::make_pair(h, ti));
|
||||
break;
|
||||
}
|
||||
}
|
||||
++found_in_pool;
|
||||
}
|
||||
}
|
||||
@@ -1073,7 +1010,17 @@ namespace cryptonote
|
||||
CHECK_AND_ASSERT_MES(tx_hash == std::get<0>(tx), false, "mismatched tx hash");
|
||||
e.tx_hash = *txhi++;
|
||||
e.prunable_hash = epee::string_tools::pod_to_hex(std::get<2>(tx));
|
||||
if (req.split || req.prune || std::get<3>(tx).empty())
|
||||
|
||||
// coinbase txes do not have signatures to prune, so they appear to be pruned if looking just at prunable data being empty
|
||||
bool pruned = std::get<3>(tx).empty();
|
||||
if (pruned)
|
||||
{
|
||||
cryptonote::transaction t;
|
||||
if (cryptonote::parse_and_validate_tx_base_from_blob(std::get<1>(tx), t) && is_coinbase(t))
|
||||
pruned = false;
|
||||
}
|
||||
|
||||
if (req.split || req.prune || pruned)
|
||||
{
|
||||
// use splitted form with pruned and prunable (filled only when prune=false and the daemon has it), leaving as_hex as empty
|
||||
e.pruned_as_hex = string_tools::buff_to_hex_nodelimer(std::get<1>(tx));
|
||||
@@ -1138,8 +1085,8 @@ namespace cryptonote
|
||||
{
|
||||
e.block_height = e.block_timestamp = std::numeric_limits<uint64_t>::max();
|
||||
e.confirmations = 0;
|
||||
auto it = per_tx_pool_tx_details.find(tx_hash);
|
||||
if (it != per_tx_pool_tx_details.end())
|
||||
auto it = per_tx_pool_tx_info.find(tx_hash);
|
||||
if (it != per_tx_pool_tx_info.end())
|
||||
{
|
||||
e.double_spend_seen = it->second.double_spend_seen;
|
||||
e.relayed = it->second.relayed;
|
||||
@@ -1304,6 +1251,7 @@ namespace cryptonote
|
||||
{
|
||||
LOG_PRINT_L0("[on_send_raw_tx]: Failed to parse tx from hexbuff: " << req.tx_as_hex);
|
||||
res.status = "Failed";
|
||||
res.reason = "Hex decoding failed";
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1341,8 +1289,6 @@ namespace cryptonote
|
||||
add_reason(reason, "too few outputs");
|
||||
if ((res.tx_extra_too_big = tvc.m_tx_extra_too_big))
|
||||
add_reason(reason, "tx-extra too big");
|
||||
if ((res.nonzero_unlock_time = tvc.m_nonzero_unlock_time))
|
||||
add_reason(reason, "tx unlock time is not zero");
|
||||
const std::string punctuation = reason.empty() ? "" : ": ";
|
||||
if (tvc.m_verifivation_failed)
|
||||
{
|
||||
@@ -2182,8 +2128,7 @@ namespace cryptonote
|
||||
// Fixing of high orphan issue for most pools
|
||||
// Thanks Boolberry!
|
||||
block b;
|
||||
crypto::hash blk_id;
|
||||
if(!parse_and_validate_block_from_blob(blockblob, b, blk_id))
|
||||
if(!parse_and_validate_block_from_blob(blockblob, b))
|
||||
{
|
||||
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_BLOCKBLOB;
|
||||
error_resp.message = "Wrong block blob";
|
||||
@@ -2206,7 +2151,6 @@ namespace cryptonote
|
||||
error_resp.message = "Block not accepted";
|
||||
return false;
|
||||
}
|
||||
res.block_id = epee::string_tools::pod_to_hex(blk_id);
|
||||
res.status = CORE_RPC_STATUS_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace cryptonote
|
||||
// advance which version they will stop working with
|
||||
// Don't go over 32767 for any of these
|
||||
#define CORE_RPC_VERSION_MAJOR 3
|
||||
#define CORE_RPC_VERSION_MINOR 14
|
||||
#define CORE_RPC_VERSION_MINOR 12
|
||||
#define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor))
|
||||
#define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR)
|
||||
|
||||
@@ -162,29 +162,18 @@ namespace cryptonote
|
||||
struct COMMAND_RPC_GET_BLOCKS_FAST
|
||||
{
|
||||
|
||||
enum REQUESTED_INFO
|
||||
{
|
||||
BLOCKS_ONLY = 0,
|
||||
BLOCKS_AND_POOL = 1,
|
||||
POOL_ONLY = 2
|
||||
};
|
||||
|
||||
struct request_t: public rpc_access_request_base
|
||||
{
|
||||
uint8_t requested_info;
|
||||
std::list<crypto::hash> block_ids; //*first 10 blocks id goes sequential, next goes in pow(2,n) offset, like 2, 4, 8, 16, 32, 64 and so on, and the last one is always genesis block */
|
||||
uint64_t start_height;
|
||||
bool prune;
|
||||
bool no_miner_tx;
|
||||
uint64_t pool_info_since;
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE_PARENT(rpc_access_request_base)
|
||||
KV_SERIALIZE_OPT(requested_info, (uint8_t)0)
|
||||
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(block_ids)
|
||||
KV_SERIALIZE(start_height)
|
||||
KV_SERIALIZE(prune)
|
||||
KV_SERIALIZE_OPT(no_miner_tx, false)
|
||||
KV_SERIALIZE_OPT(pool_info_since, (uint64_t)0)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<request_t> request;
|
||||
@@ -207,37 +196,12 @@ namespace cryptonote
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct pool_tx_info
|
||||
{
|
||||
crypto::hash tx_hash;
|
||||
blobdata tx_blob;
|
||||
bool double_spend_seen;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE_VAL_POD_AS_BLOB(tx_hash)
|
||||
KV_SERIALIZE(tx_blob)
|
||||
KV_SERIALIZE(double_spend_seen)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
enum POOL_INFO_EXTENT
|
||||
{
|
||||
NONE = 0,
|
||||
INCREMENTAL = 1,
|
||||
FULL = 2
|
||||
};
|
||||
|
||||
struct response_t: public rpc_access_response_base
|
||||
{
|
||||
std::vector<block_complete_entry> blocks;
|
||||
uint64_t start_height;
|
||||
uint64_t current_height;
|
||||
std::vector<block_output_indices> output_indices;
|
||||
uint64_t daemon_time;
|
||||
uint8_t pool_info_extent;
|
||||
std::vector<pool_tx_info> added_pool_txs;
|
||||
std::vector<crypto::hash> remaining_added_pool_txids;
|
||||
std::vector<crypto::hash> removed_pool_txids;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE_PARENT(rpc_access_response_base)
|
||||
@@ -245,17 +209,6 @@ namespace cryptonote
|
||||
KV_SERIALIZE(start_height)
|
||||
KV_SERIALIZE(current_height)
|
||||
KV_SERIALIZE(output_indices)
|
||||
KV_SERIALIZE_OPT(daemon_time, (uint64_t) 0)
|
||||
KV_SERIALIZE_OPT(pool_info_extent, (uint8_t) 0)
|
||||
if (pool_info_extent != POOL_INFO_EXTENT::NONE)
|
||||
{
|
||||
KV_SERIALIZE(added_pool_txs)
|
||||
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(remaining_added_pool_txids)
|
||||
}
|
||||
if (pool_info_extent == POOL_INFO_EXTENT::INCREMENTAL)
|
||||
{
|
||||
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(removed_pool_txids)
|
||||
}
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
@@ -640,7 +593,6 @@ namespace cryptonote
|
||||
bool too_few_outputs;
|
||||
bool sanity_check_failed;
|
||||
bool tx_extra_too_big;
|
||||
bool nonzero_unlock_time;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE_PARENT(rpc_access_response_base)
|
||||
@@ -656,7 +608,6 @@ namespace cryptonote
|
||||
KV_SERIALIZE(too_few_outputs)
|
||||
KV_SERIALIZE(sanity_check_failed)
|
||||
KV_SERIALIZE(tx_extra_too_big)
|
||||
KV_SERIALIZE(nonzero_unlock_time)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
@@ -1121,11 +1072,8 @@ namespace cryptonote
|
||||
|
||||
struct response_t: public rpc_response_base
|
||||
{
|
||||
std::string block_id;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE_PARENT(rpc_response_base)
|
||||
KV_SERIALIZE(block_id)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
|
||||
@@ -422,16 +422,6 @@ namespace rpc
|
||||
if (!res.error_details.empty()) res.error_details += " and ";
|
||||
res.error_details += "too few outputs";
|
||||
}
|
||||
if (tvc.m_tx_extra_too_big)
|
||||
{
|
||||
if (!res.error_details.empty()) res.error_details += " and ";
|
||||
res.error_details += "tx_extra too long";
|
||||
}
|
||||
if (tvc.m_nonzero_unlock_time)
|
||||
{
|
||||
if (!res.error_details.empty()) res.error_details += " and ";
|
||||
res.error_details += "non-zero unlock time";
|
||||
}
|
||||
if (res.error_details.empty())
|
||||
{
|
||||
res.error_details = "an unknown issue was found with the transaction";
|
||||
@@ -520,8 +510,6 @@ namespace rpc
|
||||
res.info.target_height = res.info.height;
|
||||
}
|
||||
|
||||
m_core.get_blockchain_top(res.info.top_block_height, res.info.top_block_hash);
|
||||
|
||||
auto& chain = m_core.get_blockchain_storage();
|
||||
|
||||
res.info.wide_difficulty = chain.get_difficulty_for_next_block();
|
||||
|
||||
@@ -48,11 +48,6 @@ void GetHeight::Response::doToJson(rapidjson::Writer<epee::byte_stream>& dest) c
|
||||
|
||||
void GetHeight::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, height, height);
|
||||
}
|
||||
|
||||
@@ -66,11 +61,6 @@ void GetBlocksFast::Request::doToJson(rapidjson::Writer<epee::byte_stream>& dest
|
||||
|
||||
void GetBlocksFast::Request::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, block_ids, block_ids);
|
||||
GET_FROM_JSON_OBJECT(val, start_height, start_height);
|
||||
GET_FROM_JSON_OBJECT(val, prune, prune);
|
||||
@@ -86,11 +76,6 @@ void GetBlocksFast::Response::doToJson(rapidjson::Writer<epee::byte_stream>& des
|
||||
|
||||
void GetBlocksFast::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, blocks, blocks);
|
||||
GET_FROM_JSON_OBJECT(val, start_height, start_height);
|
||||
GET_FROM_JSON_OBJECT(val, current_height, current_height);
|
||||
@@ -106,11 +91,6 @@ void GetHashesFast::Request::doToJson(rapidjson::Writer<epee::byte_stream>& dest
|
||||
|
||||
void GetHashesFast::Request::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, known_hashes, known_hashes);
|
||||
GET_FROM_JSON_OBJECT(val, start_height, start_height);
|
||||
}
|
||||
@@ -120,16 +100,10 @@ void GetHashesFast::Response::doToJson(rapidjson::Writer<epee::byte_stream>& des
|
||||
INSERT_INTO_JSON_OBJECT(dest, hashes, hashes);
|
||||
INSERT_INTO_JSON_OBJECT(dest, start_height, start_height);
|
||||
INSERT_INTO_JSON_OBJECT(dest, current_height, current_height);
|
||||
|
||||
}
|
||||
|
||||
void GetHashesFast::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, hashes, hashes);
|
||||
GET_FROM_JSON_OBJECT(val, start_height, start_height);
|
||||
GET_FROM_JSON_OBJECT(val, current_height, current_height);
|
||||
@@ -143,11 +117,6 @@ void GetTransactions::Request::doToJson(rapidjson::Writer<epee::byte_stream>& de
|
||||
|
||||
void GetTransactions::Request::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, tx_hashes, tx_hashes);
|
||||
}
|
||||
|
||||
@@ -159,11 +128,6 @@ void GetTransactions::Response::doToJson(rapidjson::Writer<epee::byte_stream>& d
|
||||
|
||||
void GetTransactions::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, txs, txs);
|
||||
GET_FROM_JSON_OBJECT(val, missed_hashes, missed_hashes);
|
||||
}
|
||||
@@ -176,11 +140,6 @@ void KeyImagesSpent::Request::doToJson(rapidjson::Writer<epee::byte_stream>& des
|
||||
|
||||
void KeyImagesSpent::Request::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, key_images, key_images);
|
||||
}
|
||||
|
||||
@@ -191,11 +150,6 @@ void KeyImagesSpent::Response::doToJson(rapidjson::Writer<epee::byte_stream>& de
|
||||
|
||||
void KeyImagesSpent::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, spent_status, spent_status);
|
||||
}
|
||||
|
||||
@@ -207,11 +161,6 @@ void GetTxGlobalOutputIndices::Request::doToJson(rapidjson::Writer<epee::byte_st
|
||||
|
||||
void GetTxGlobalOutputIndices::Request::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, tx_hash, tx_hash);
|
||||
}
|
||||
|
||||
@@ -222,11 +171,6 @@ void GetTxGlobalOutputIndices::Response::doToJson(rapidjson::Writer<epee::byte_s
|
||||
|
||||
void GetTxGlobalOutputIndices::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, output_indices, output_indices);
|
||||
}
|
||||
|
||||
@@ -238,11 +182,6 @@ void SendRawTx::Request::doToJson(rapidjson::Writer<epee::byte_stream>& dest) co
|
||||
|
||||
void SendRawTx::Request::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, tx, tx);
|
||||
GET_FROM_JSON_OBJECT(val, relay, relay);
|
||||
}
|
||||
@@ -255,11 +194,6 @@ void SendRawTx::Response::doToJson(rapidjson::Writer<epee::byte_stream>& dest) c
|
||||
|
||||
void SendRawTx::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, relayed, relayed);
|
||||
}
|
||||
|
||||
@@ -271,11 +205,6 @@ void SendRawTxHex::Request::doToJson(rapidjson::Writer<epee::byte_stream>& dest)
|
||||
|
||||
void SendRawTxHex::Request::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, tx_as_hex, tx_as_hex);
|
||||
GET_FROM_JSON_OBJECT(val, relay, relay);
|
||||
}
|
||||
@@ -290,11 +219,6 @@ void StartMining::Request::doToJson(rapidjson::Writer<epee::byte_stream>& dest)
|
||||
|
||||
void StartMining::Request::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, miner_address, miner_address);
|
||||
GET_FROM_JSON_OBJECT(val, threads_count, threads_count);
|
||||
GET_FROM_JSON_OBJECT(val, do_background_mining, do_background_mining);
|
||||
@@ -342,11 +266,6 @@ void MiningStatus::Response::doToJson(rapidjson::Writer<epee::byte_stream>& dest
|
||||
|
||||
void MiningStatus::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, active, active);
|
||||
GET_FROM_JSON_OBJECT(val, speed, speed);
|
||||
GET_FROM_JSON_OBJECT(val, threads_count, threads_count);
|
||||
@@ -369,11 +288,6 @@ void GetInfo::Response::doToJson(rapidjson::Writer<epee::byte_stream>& dest) con
|
||||
|
||||
void GetInfo::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, info, info);
|
||||
}
|
||||
|
||||
@@ -400,11 +314,6 @@ void GetBlockHash::Request::doToJson(rapidjson::Writer<epee::byte_stream>& dest)
|
||||
|
||||
void GetBlockHash::Request::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, height, height);
|
||||
}
|
||||
|
||||
@@ -415,11 +324,6 @@ void GetBlockHash::Response::doToJson(rapidjson::Writer<epee::byte_stream>& dest
|
||||
|
||||
void GetBlockHash::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, hash, hash);
|
||||
}
|
||||
|
||||
@@ -438,11 +342,6 @@ void GetLastBlockHeader::Response::doToJson(rapidjson::Writer<epee::byte_stream>
|
||||
|
||||
void GetLastBlockHeader::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, header, header);
|
||||
}
|
||||
|
||||
@@ -454,11 +353,6 @@ void GetBlockHeaderByHash::Request::doToJson(rapidjson::Writer<epee::byte_stream
|
||||
|
||||
void GetBlockHeaderByHash::Request::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, hash, hash);
|
||||
}
|
||||
|
||||
@@ -469,11 +363,6 @@ void GetBlockHeaderByHash::Response::doToJson(rapidjson::Writer<epee::byte_strea
|
||||
|
||||
void GetBlockHeaderByHash::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, header, header);
|
||||
}
|
||||
|
||||
@@ -485,11 +374,6 @@ void GetBlockHeaderByHeight::Request::doToJson(rapidjson::Writer<epee::byte_stre
|
||||
|
||||
void GetBlockHeaderByHeight::Request::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, height, height);
|
||||
}
|
||||
|
||||
@@ -500,11 +384,6 @@ void GetBlockHeaderByHeight::Response::doToJson(rapidjson::Writer<epee::byte_str
|
||||
|
||||
void GetBlockHeaderByHeight::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, header, header);
|
||||
}
|
||||
|
||||
@@ -516,11 +395,6 @@ void GetBlockHeadersByHeight::Request::doToJson(rapidjson::Writer<epee::byte_str
|
||||
|
||||
void GetBlockHeadersByHeight::Request::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, heights, heights);
|
||||
}
|
||||
|
||||
@@ -531,11 +405,6 @@ void GetBlockHeadersByHeight::Response::doToJson(rapidjson::Writer<epee::byte_st
|
||||
|
||||
void GetBlockHeadersByHeight::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, headers, headers);
|
||||
}
|
||||
|
||||
@@ -555,11 +424,6 @@ void GetPeerList::Response::doToJson(rapidjson::Writer<epee::byte_stream>& dest)
|
||||
|
||||
void GetPeerList::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, white_list, white_list);
|
||||
GET_FROM_JSON_OBJECT(val, gray_list, gray_list);
|
||||
}
|
||||
@@ -572,11 +436,6 @@ void SetLogLevel::Request::doToJson(rapidjson::Writer<epee::byte_stream>& dest)
|
||||
|
||||
void SetLogLevel::Request::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, level, level);
|
||||
}
|
||||
|
||||
@@ -603,11 +462,6 @@ void GetTransactionPool::Response::doToJson(rapidjson::Writer<epee::byte_stream>
|
||||
|
||||
void GetTransactionPool::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, transactions, transactions);
|
||||
GET_FROM_JSON_OBJECT(val, key_images, key_images);
|
||||
}
|
||||
@@ -620,11 +474,6 @@ void HardForkInfo::Request::doToJson(rapidjson::Writer<epee::byte_stream>& dest)
|
||||
|
||||
void HardForkInfo::Request::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, version, version);
|
||||
}
|
||||
|
||||
@@ -635,11 +484,6 @@ void HardForkInfo::Response::doToJson(rapidjson::Writer<epee::byte_stream>& dest
|
||||
|
||||
void HardForkInfo::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, info, info);
|
||||
}
|
||||
|
||||
@@ -655,11 +499,6 @@ void GetOutputHistogram::Request::doToJson(rapidjson::Writer<epee::byte_stream>&
|
||||
|
||||
void GetOutputHistogram::Request::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, amounts, amounts);
|
||||
GET_FROM_JSON_OBJECT(val, min_count, min_count);
|
||||
GET_FROM_JSON_OBJECT(val, max_count, max_count);
|
||||
@@ -674,11 +513,6 @@ void GetOutputHistogram::Response::doToJson(rapidjson::Writer<epee::byte_stream>
|
||||
|
||||
void GetOutputHistogram::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, histogram, histogram);
|
||||
}
|
||||
|
||||
@@ -690,11 +524,6 @@ void GetOutputKeys::Request::doToJson(rapidjson::Writer<epee::byte_stream>& dest
|
||||
|
||||
void GetOutputKeys::Request::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, outputs, outputs);
|
||||
}
|
||||
|
||||
@@ -705,11 +534,6 @@ void GetOutputKeys::Response::doToJson(rapidjson::Writer<epee::byte_stream>& des
|
||||
|
||||
void GetOutputKeys::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, keys, keys);
|
||||
}
|
||||
|
||||
@@ -728,11 +552,6 @@ void GetRPCVersion::Response::doToJson(rapidjson::Writer<epee::byte_stream>& des
|
||||
|
||||
void GetRPCVersion::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, version, version);
|
||||
}
|
||||
|
||||
@@ -743,11 +562,6 @@ void GetFeeEstimate::Request::doToJson(rapidjson::Writer<epee::byte_stream>& des
|
||||
|
||||
void GetFeeEstimate::Request::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, num_grace_blocks, num_grace_blocks);
|
||||
}
|
||||
|
||||
@@ -761,11 +575,6 @@ void GetFeeEstimate::Response::doToJson(rapidjson::Writer<epee::byte_stream>& de
|
||||
|
||||
void GetFeeEstimate::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, estimated_base_fee, estimated_base_fee);
|
||||
GET_FROM_JSON_OBJECT(val, fee_mask, fee_mask);
|
||||
GET_FROM_JSON_OBJECT(val, size_scale, size_scale);
|
||||
@@ -782,11 +591,6 @@ void GetOutputDistribution::Request::doToJson(rapidjson::Writer<epee::byte_strea
|
||||
|
||||
void GetOutputDistribution::Request::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, amounts, amounts);
|
||||
GET_FROM_JSON_OBJECT(val, from_height, from_height);
|
||||
GET_FROM_JSON_OBJECT(val, to_height, to_height);
|
||||
@@ -801,11 +605,6 @@ void GetOutputDistribution::Response::doToJson(rapidjson::Writer<epee::byte_stre
|
||||
|
||||
void GetOutputDistribution::Response::fromJson(const rapidjson::Value& val)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw json::WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, status, status);
|
||||
GET_FROM_JSON_OBJECT(val, distributions, distributions);
|
||||
}
|
||||
|
||||
@@ -178,7 +178,6 @@ namespace rpc
|
||||
{
|
||||
uint64_t height;
|
||||
uint64_t target_height;
|
||||
uint64_t top_block_height;
|
||||
cryptonote::difficulty_type wide_difficulty;
|
||||
uint64_t difficulty;
|
||||
uint64_t target;
|
||||
|
||||
@@ -158,22 +158,13 @@ void ZmqServer::serve()
|
||||
|
||||
if (!pub || sockets[2].revents)
|
||||
{
|
||||
expect<std::string> message = net::zmq::receive(rep.get(), read_flags);
|
||||
if (!message)
|
||||
{
|
||||
// EAGAIN can occur when using `zmq_poll`, which doesn't inspect for message validity
|
||||
if (message != net::zmq::make_error_code(EAGAIN))
|
||||
MONERO_THROW(message.error(), "Read failure on ZMQ-RPC");
|
||||
}
|
||||
else // no errors
|
||||
{
|
||||
MDEBUG("Received RPC request: \"" << *message << "\"");
|
||||
epee::byte_slice response = handler.handle(std::move(*message));
|
||||
std::string message = MONERO_UNWRAP(net::zmq::receive(rep.get(), read_flags));
|
||||
MDEBUG("Received RPC request: \"" << message << "\"");
|
||||
epee::byte_slice response = handler.handle(std::move(message));
|
||||
|
||||
const boost::string_ref response_view{reinterpret_cast<const char*>(response.data()), response.size()};
|
||||
MDEBUG("Sending RPC reply: \"" << response_view << "\"");
|
||||
MONERO_UNWRAP(net::zmq::send(std::move(response), rep.get()));
|
||||
}
|
||||
const boost::string_ref response_view{reinterpret_cast<const char*>(response.data()), response.size()};
|
||||
MDEBUG("Sending RPC reply: \"" << response_view << "\"");
|
||||
MONERO_UNWRAP(net::zmq::send(std::move(response), rep.get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace serialization
|
||||
typename std::enable_if<!use_container_varint<T>(), bool>::type
|
||||
serialize_container_element(Archive& ar, T& e)
|
||||
{
|
||||
return do_serialize(ar, e);
|
||||
return ::do_serialize(ar, e);
|
||||
}
|
||||
|
||||
template<typename Archive, typename T>
|
||||
@@ -52,7 +52,7 @@ namespace serialization
|
||||
static constexpr const bool previously_varint = std::is_same<uint64_t, T>() || std::is_same<uint32_t, T>();
|
||||
|
||||
if (!previously_varint && ar.varint_bug_backward_compatibility_enabled() && !typename Archive::is_saving())
|
||||
return do_serialize(ar, e);
|
||||
return ::do_serialize(ar, e);
|
||||
ar.serialize_varint(e);
|
||||
return true;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user