mirror of
https://codeberg.org/nahuhh/wownero
synced 2026-03-05 06:07:35 -05:00
Compare commits
132 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b1d0f2340 | ||
|
|
90fbc9b181 | ||
|
|
f2949f7cf4 | ||
|
|
c9b9251fd4 | ||
|
|
cd580e0e3c | ||
|
|
801ac3ce56 | ||
|
|
23bf7c9813 | ||
|
|
97d3f9d408 | ||
|
|
f4fac80752 | ||
|
|
516555402d | ||
|
|
a42b6750b1 | ||
|
|
09a2b6f2e8 | ||
|
|
08b99c749d | ||
|
|
0b8bf308ce | ||
|
|
a3033e741b | ||
|
|
f37d960f75 | ||
|
|
a76c6b9cae | ||
|
|
eb6469b7a5 | ||
|
|
c3137f7695 | ||
|
|
f4285bf135 | ||
|
|
e608cea2a5 | ||
|
|
117cdc4d50 | ||
|
|
27cfbe1a22 | ||
|
|
f8ec114820 | ||
|
|
0529d350ad | ||
|
|
868deaaf9e | ||
|
|
5ac11bb4d6 | ||
|
|
e0fc0ce7ad | ||
|
|
a840b7e20c | ||
|
|
3208d97f9c | ||
|
|
1cc36a652b | ||
|
|
b353da51f9 | ||
|
|
e49f87c8b3 | ||
|
|
6815ddd270 | ||
|
|
5b43b61153 | ||
|
|
7f8d14ecde | ||
|
|
67cc83a66c | ||
|
|
b974ccde3a | ||
|
|
4a971e575f | ||
|
|
0051cbdc73 | ||
|
|
7441d939e0 | ||
|
|
d9973f4d48 | ||
|
|
2b25b1097e | ||
|
|
33103494d6 | ||
|
|
6294fe26df | ||
|
|
cc70e33283 | ||
|
|
0783e940e9 | ||
|
|
ce3c13b46f | ||
|
|
ff1373149a | ||
|
|
41f5f36e16 | ||
|
|
21fa2b944b | ||
|
|
711f8c9d34 | ||
|
|
4228f785c0 | ||
|
|
9e86c1c90d | ||
|
|
c40d8f5672 | ||
|
|
0f998b9b55 | ||
|
|
38f0472a6e | ||
|
|
9774fc7868 | ||
|
|
c14276fb7c | ||
|
|
755c308c23 | ||
|
|
4053e2ae14 | ||
|
|
df5779790c | ||
|
|
aae4bf32aa | ||
|
|
d37785db0c | ||
|
|
2a38ee251a | ||
|
|
e49e6ae142 | ||
|
|
5731efa127 | ||
|
|
26a64f99d3 | ||
|
|
e47fbe1476 | ||
|
|
4cc5e174d9 | ||
|
|
7bdf566225 | ||
|
|
6b80ac2ae7 | ||
|
|
4d15c0aa13 | ||
|
|
8345e5b7bc | ||
|
|
12d81b4af1 | ||
|
|
e2260ab8ab | ||
|
|
e28f22ba2f | ||
|
|
80a21da5ba | ||
|
|
94b5378a3b | ||
|
|
cfc8640492 | ||
|
|
69e41b9d4e | ||
|
|
bcc824cac3 | ||
|
|
46b4016134 | ||
|
|
8b73fabd2a | ||
|
|
b6dee49900 | ||
|
|
1bf5b86967 | ||
|
|
dc0ac9c252 | ||
|
|
2051c5f078 | ||
|
|
51169a6c2d | ||
|
|
b8396218a3 | ||
|
|
17c5e8f949 | ||
|
|
3e8bf154eb | ||
|
|
498436c9b4 | ||
|
|
9a58ac48d2 | ||
|
|
90b7699717 | ||
|
|
1917bd3d53 | ||
|
|
cb654bbc27 | ||
|
|
ec60b05faa | ||
|
|
58e1f2f02a | ||
|
|
af941bed58 | ||
|
|
10c30ea5aa | ||
|
|
83fe535888 | ||
|
|
e52e01a445 | ||
|
|
284ec84502 | ||
|
|
86f12066f2 | ||
|
|
c336e15f0c | ||
|
|
e09d17ba1f | ||
|
|
9364b49ecb | ||
|
|
5cd3a15491 | ||
|
|
b303931b23 | ||
|
|
7b4e1b0859 | ||
|
|
8fb16a3280 | ||
|
|
4e097c26a2 | ||
|
|
2aabc5863e | ||
|
|
2a6d817ea1 | ||
|
|
f6533856df | ||
|
|
32497a641c | ||
|
|
aaa015b3e7 | ||
|
|
9c35901592 | ||
|
|
f9c0871877 | ||
|
|
96d1d08f48 | ||
|
|
2e8fae1b4c | ||
|
|
d99c27e24d | ||
|
|
48eeca2077 | ||
|
|
96ae690083 | ||
|
|
b9974f7bff | ||
|
|
389a02d93f | ||
|
|
a3c9befbb5 | ||
|
|
08a0e737f9 | ||
|
|
1396426d59 | ||
|
|
93cc82423e | ||
|
|
572d7ea5ef |
10
.drone.yml
Normal file
10
.drone.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: linux-build
|
||||
|
||||
steps:
|
||||
- name: linux-build
|
||||
image: wownero/wow-dependencies:v1.0
|
||||
commands:
|
||||
- make release-static-linux-x86_64
|
||||
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
custom: https://dev-funding.webui.wowkira.com
|
||||
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive
|
||||
- uses: msys2/setup-msys2@v2
|
||||
- uses: eine/setup-msys2@v1
|
||||
with:
|
||||
update: true
|
||||
install: mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-protobuf-c mingw-w64-x86_64-libusb git
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -23,6 +23,7 @@ cscope.po.out
|
||||
external/miniupnpc/Makefile
|
||||
miniupnpcstrings.h
|
||||
version/
|
||||
ClangBuildAnalyzerSession.txt
|
||||
# Created by https://www.gitignore.io
|
||||
|
||||
### C++ ###
|
||||
@@ -109,5 +110,3 @@ nbproject
|
||||
/testnet
|
||||
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.log
|
||||
|
||||
16
.gitmodules
vendored
16
.gitmodules
vendored
@@ -1,19 +1,19 @@
|
||||
[submodule "external/unbound"]
|
||||
path = external/unbound
|
||||
url = https://github.com/monero-project/unbound
|
||||
url = https://git.wownero.com/wownero/unbound
|
||||
branch = monero
|
||||
[submodule "external/miniupnp"]
|
||||
path = external/miniupnp
|
||||
url = https://github.com/monero-project/miniupnp
|
||||
url = https://git.wownero.com/wownero/miniupnp
|
||||
branch = monero
|
||||
[submodule "external/rapidjson"]
|
||||
path = external/rapidjson
|
||||
url = https://github.com/Tencent/rapidjson
|
||||
[submodule "external/supercop"]
|
||||
path = external/supercop
|
||||
url = https://github.com/monero-project/supercop
|
||||
branch = monero
|
||||
url = https://git.wownero.com/wownero/rapidjson
|
||||
[submodule "external/RandomWOW"]
|
||||
path = external/RandomWOW
|
||||
url = https://git.wownero.com/wownero/RandomWOW
|
||||
branch = 1.1.9-wow
|
||||
branch = 1.1.8-wow
|
||||
[submodule "external/supercop"]
|
||||
path = external/supercop
|
||||
url = https://git.wownero.com/wownero/supercop
|
||||
branch = monero
|
||||
|
||||
@@ -36,6 +36,10 @@ with additional exclusive IPv4 address(es).
|
||||
|
||||
## Usage
|
||||
|
||||
Anonymity networks have no seed nodes (the feature is still considered
|
||||
experimental), so a user must specify an address. If configured properly,
|
||||
additional peers can be found through typical p2p peerlist sharing.
|
||||
|
||||
### Outbound Connections
|
||||
|
||||
Connecting to an anonymous address requires the command line option
|
||||
@@ -50,9 +54,8 @@ separate process. On most systems the configuration will look like:
|
||||
which tells `monerod` that ".onion" p2p addresses can be forwarded to a socks
|
||||
proxy at IP 127.0.0.1 port 9050 with a max of 10 outgoing connections and
|
||||
".b32.i2p" p2p addresses can be forwarded to a socks proxy at IP 127.0.0.1 port
|
||||
9000 with the default max outgoing connections.
|
||||
|
||||
If desired, peers can be manually specified:
|
||||
9000 with the default max outgoing connections. Since there are no seed nodes
|
||||
for anonymity connections, peers must be manually specified:
|
||||
|
||||
```
|
||||
--add-exclusive-node rveahdfho7wo4b2m.onion:28083
|
||||
|
||||
126
CMakeLists.txt
126
CMakeLists.txt
@@ -54,6 +54,13 @@ if (USE_CCACHE)
|
||||
else()
|
||||
message(STATUS "ccache deselected")
|
||||
endif()
|
||||
option (USE_COMPILATION_TIME_PROFILER "Use compilation time profiler (for CLang >= 9 only)" OFF)
|
||||
if (USE_COMPILATION_TIME_PROFILER)
|
||||
if (NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
|
||||
message(FATAL_ERROR "The flag USE_COMPILATION_TIME_PROFILER is meant to be set only for CLang compiler!")
|
||||
endif()
|
||||
add_compile_options("-ftime-trace")
|
||||
endif()
|
||||
|
||||
# Job pool feature requires Ninja.
|
||||
if (${CMAKE_VERSION} VERSION_GREATER "3.0.0")
|
||||
@@ -68,6 +75,20 @@ if (${CMAKE_VERSION} VERSION_GREATER "3.0.0")
|
||||
set_property(GLOBAL APPEND PROPERTY JOB_POOLS link_job_pool=${WOWNERO_PARALLEL_LINK_JOBS})
|
||||
set(CMAKE_JOB_POOL_LINK link_job_pool)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
option (USE_CLANG_TIDY_C "Lint the code with clang-tidy - variant C" OFF)
|
||||
option (USE_CLANG_TIDY_CXX "Lint the code with clang-tidy - variant C++" OFF)
|
||||
if (USE_CLANG_TIDY_C AND USE_CLANG_TIDY_CXX)
|
||||
message(FATAL_ERROR "Enabling both USE_CLANG_TIDY_C and USE_CLANG_TIDY_CXX simultaneously crashes clang-tidy.")
|
||||
endif()
|
||||
if (USE_CLANG_TIDY_C OR USE_CLANG_TIDY_CXX)
|
||||
include(SetClangTidy)
|
||||
endif()
|
||||
if (USE_CLANG_TIDY_C)
|
||||
monero_clang_tidy("C")
|
||||
elseif (USE_CLANG_TIDY_CXX)
|
||||
monero_clang_tidy("CXX")
|
||||
endif()
|
||||
|
||||
enable_language(C ASM)
|
||||
@@ -86,18 +107,16 @@ function (die msg)
|
||||
endfunction ()
|
||||
|
||||
function (add_c_flag_if_supported flag var)
|
||||
set(TMP "-Werror ${flag}")
|
||||
string(REGEX REPLACE "[- ]" "_" supported ${TMP}_c)
|
||||
check_c_compiler_flag(${TMP} ${supported})
|
||||
string(REPLACE "-" "_" supported ${flag}_c)
|
||||
check_c_compiler_flag(${flag} ${supported})
|
||||
if(${${supported}})
|
||||
set(${var} "${${var}} ${flag}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function (add_cxx_flag_if_supported flag var)
|
||||
set(TMP "-Werror ${flag}")
|
||||
string(REGEX REPLACE "[- ]" "_" supported ${TMP}_cxx)
|
||||
check_cxx_compiler_flag(${TMP} ${supported})
|
||||
string(REPLACE "-" "_" supported ${flag}_cxx)
|
||||
check_cxx_compiler_flag(${flag} ${supported})
|
||||
if(${${supported}})
|
||||
set(${var} "${${var}} ${flag}" PARENT_SCOPE)
|
||||
endif()
|
||||
@@ -128,65 +147,23 @@ function (add_definition_if_library_exists library function header var)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Function to forbid undefined symbols and also verify
|
||||
# 1) Test project with all types of libraries and without undefined symbols can compile successfully
|
||||
# 2) Test project with all types of libraries and undefined symbols can not compile successfully
|
||||
function(forbid_undefined_symbols)
|
||||
unset(TMP)
|
||||
# https://www.unix.com/man-page/linux/1/ld, --no-undefined, Report unresolved symbol references from regular object files.
|
||||
add_linker_flag_if_supported(-Wl,--no-undefined TMP)
|
||||
# https://www.unix.com/man-page/osx/1/ld/, -undefined, Specifies how undefined symbols are to be treated.
|
||||
add_linker_flag_if_supported(-Wl,-undefined,error TMP)
|
||||
string(APPEND CMAKE_SHARED_LINKER_FLAGS ${TMP})
|
||||
string(APPEND CMAKE_MODULE_LINKER_FLAGS ${TMP})
|
||||
set(CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} PARENT_SCOPE)
|
||||
set(CMAKE_MODULE_LINKER_FLAGS ${CMAKE_MODULE_LINKER_FLAGS} PARENT_SCOPE)
|
||||
set(TEST_PROJECT "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeTmp/test_project")
|
||||
foreach(EXPECT IN ITEMS TRUE FALSE)
|
||||
file(REMOVE_RECURSE "${TEST_PROJECT}")
|
||||
file(MAKE_DIRECTORY "${TEST_PROJECT}")
|
||||
file(WRITE "${TEST_PROJECT}/CMakeLists.txt"
|
||||
[=[
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
project(test)
|
||||
option(EXPECT_SUCCESS "" ON)
|
||||
file(WRITE "${CMAKE_SOURCE_DIR}/incorrect_source.cpp" "void undefined_symbol(); void symbol() { undefined_symbol(); }")
|
||||
if (EXPECT_SUCCESS)
|
||||
file(APPEND "${CMAKE_SOURCE_DIR}/incorrect_source.cpp" " void undefined_symbol() {}; ")
|
||||
endif()
|
||||
add_library(l0 SHARED incorrect_source.cpp)
|
||||
add_library(l1 MODULE incorrect_source.cpp)
|
||||
add_library(l2 STATIC incorrect_source.cpp)
|
||||
add_library(l3 OBJECT incorrect_source.cpp)
|
||||
]=]
|
||||
)
|
||||
try_compile(SUCCESS "${TEST_PROJECT}/build" "${TEST_PROJECT}" test
|
||||
CMAKE_FLAGS
|
||||
"-DCMAKE_SHARED_LINKER_FLAGS=${CMAKE_SHARED_LINKER_FLAGS}"
|
||||
"-DCMAKE_MODULE_LINKER_FLAGS=${CMAKE_MODULE_LINKER_FLAGS}"
|
||||
"-DEXPECT_SUCCESS=${EXPECT}"
|
||||
)
|
||||
if (NOT ${SUCCESS} STREQUAL ${EXPECT})
|
||||
message(FATAL_ERROR "Undefined symbols test failure: expect(${EXPECT}), success(${SUCCESS})")
|
||||
endif()
|
||||
file(REMOVE_RECURSE "${TEST_PROJECT}")
|
||||
endforeach()
|
||||
option(RELINK_TARGETS "Relink targets, when just a dependant .so changed, but not its header?" OFF)
|
||||
function (monero_set_target_no_relink target)
|
||||
if (RELINK_TARGETS MATCHES OFF)
|
||||
# Will not relink the target, when just its dependant .so has changed, but not it's interface
|
||||
set_target_properties("${target}" PROPERTIES LINK_DEPENDS_NO_SHARED true)
|
||||
endif()
|
||||
endfunction()
|
||||
if (NOT (CMAKE_SYSTEM_NAME MATCHES "kOpenBSD.*|OpenBSD.*"))
|
||||
forbid_undefined_symbols()
|
||||
endif()
|
||||
|
||||
if (MINGW)
|
||||
function(export_all_symbols)
|
||||
unset(TMP)
|
||||
add_linker_flag_if_supported(-Wl,--export-all-symbols TMP)
|
||||
string(APPEND CMAKE_SHARED_LINKER_FLAGS ${TMP})
|
||||
string(APPEND CMAKE_MODULE_LINKER_FLAGS ${TMP})
|
||||
set(CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} PARENT_SCOPE)
|
||||
set(CMAKE_MODULE_LINKER_FLAGS ${CMAKE_MODULE_LINKER_FLAGS} PARENT_SCOPE)
|
||||
endfunction()
|
||||
export_all_symbols()
|
||||
endif()
|
||||
function (monero_add_minimal_executable name)
|
||||
source_group("${name}"
|
||||
FILES
|
||||
${ARGN})
|
||||
|
||||
add_executable("${name}"
|
||||
${ARGN})
|
||||
monero_set_target_no_relink( ${name} )
|
||||
endfunction()
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
|
||||
@@ -480,7 +457,7 @@ elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND NOT MINGW)
|
||||
set(DEFAULT_STACK_TRACE ON)
|
||||
set(STACK_TRACE_LIB "easylogging++") # for diag output only
|
||||
set(LIBUNWIND_LIBRARIES "")
|
||||
elseif (ARM AND STATIC)
|
||||
elseif (ARM)
|
||||
set(DEFAULT_STACK_TRACE OFF)
|
||||
set(LIBUNWIND_LIBRARIES "")
|
||||
else()
|
||||
@@ -534,10 +511,6 @@ if(STATIC AND NOT IOS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
list(APPEND OPENSSL_LIBRARIES ws2_32 crypt32)
|
||||
endif()
|
||||
|
||||
find_package(HIDAPI)
|
||||
|
||||
add_definition_if_library_exists(c memset_s "string.h" HAVE_MEMSET_S)
|
||||
@@ -590,17 +563,6 @@ endif()
|
||||
# Trezor support check
|
||||
include(CheckTrezor)
|
||||
|
||||
# As of OpenBSD 6.8, -march=<anything> breaks the build
|
||||
function(set_default_arch)
|
||||
if (OPENBSD)
|
||||
set(ARCH default)
|
||||
else()
|
||||
set(ARCH native)
|
||||
endif()
|
||||
|
||||
set(ARCH ${ARCH} CACHE STRING "CPU to build for: -march value or 'default' to not pass -march at all")
|
||||
endfunction()
|
||||
|
||||
if(MSVC)
|
||||
add_definitions("/bigobj /MP /W3 /GS- /D_CRT_SECURE_NO_WARNINGS /wd4996 /wd4345 /D_WIN32_WINNT=0x0600 /DWIN32_LEAN_AND_MEAN /DGTEST_HAS_TR1_TUPLE=0 /FIinline_c.h /D__SSE4_1__")
|
||||
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Dinline=__inline")
|
||||
@@ -614,7 +576,7 @@ if(MSVC)
|
||||
else()
|
||||
include(TestCXXAcceptsFlag)
|
||||
if (NOT ARCH)
|
||||
set_default_arch()
|
||||
set(ARCH native CACHE STRING "CPU to build for: -march value or 'default' to not pass -march at all")
|
||||
endif()
|
||||
message(STATUS "Building on ${CMAKE_SYSTEM_PROCESSOR} for ${ARCH}")
|
||||
if(ARCH STREQUAL "default")
|
||||
@@ -1020,12 +982,10 @@ list(APPEND EXTRA_LIBRARIES ${CMAKE_DL_LIBS})
|
||||
if (HIDAPI_FOUND OR LibUSB_COMPILE_TEST_PASSED)
|
||||
if (APPLE)
|
||||
if(DEPENDS)
|
||||
list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework AppKit -framework IOKit")
|
||||
list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework IOKit")
|
||||
else()
|
||||
find_library(COREFOUNDATION CoreFoundation)
|
||||
find_library(APPKIT AppKit)
|
||||
find_library(IOKIT IOKit)
|
||||
list(APPEND EXTRA_LIBRARIES ${APPKIT})
|
||||
list(APPEND EXTRA_LIBRARIES ${IOKIT})
|
||||
list(APPEND EXTRA_LIBRARIES ${COREFOUNDATION})
|
||||
endif()
|
||||
|
||||
334
Dockerfile
334
Dockerfile
@@ -1,18 +1,28 @@
|
||||
# Multistage docker build, requires docker 17.05
|
||||
ARG DEBIAN_VERSION="${DEBIAN_VERSION:-stable-slim}"
|
||||
FROM debian:${DEBIAN_VERSION} as git-wow
|
||||
|
||||
# builder stage
|
||||
FROM ubuntu:16.04 as builder
|
||||
WORKDIR /data
|
||||
|
||||
RUN set -ex && \
|
||||
apt-get update && \
|
||||
apt-get --no-install-recommends --yes install \
|
||||
#Cmake
|
||||
ARG CMAKE_VERSION=3.14.6
|
||||
ARG CMAKE_VERSION_DOT=v3.14
|
||||
ARG CMAKE_HASH=4e8ea11cabe459308671b476469eace1622e770317a15951d7b55a82ccaaccb9
|
||||
## Boost
|
||||
ARG BOOST_VERSION=1_70_0
|
||||
ARG BOOST_VERSION_DOT=1.70.0
|
||||
ARG BOOST_HASH=430ae8354789de4fd19ee52f3b1f739e1fba576f0aded0897c3c2bc00fb38778
|
||||
|
||||
ENV CFLAGS='-fPIC -O2 -g'
|
||||
ENV CXXFLAGS='-fPIC -O2 -g'
|
||||
ENV LDFLAGS='-static-libstdc++'
|
||||
|
||||
ENV BASE_DIR /usr/local
|
||||
|
||||
RUN apt-get update -qq && apt-get --no-install-recommends -yqq install \
|
||||
ca-certificates \
|
||||
cmake \
|
||||
g++ \
|
||||
make \
|
||||
pkg-config \
|
||||
graphviz \
|
||||
doxygen \
|
||||
git \
|
||||
curl \
|
||||
libtool-bin \
|
||||
@@ -21,191 +31,193 @@ RUN set -ex && \
|
||||
bzip2 \
|
||||
xsltproc \
|
||||
gperf \
|
||||
unzip
|
||||
|
||||
WORKDIR /usr/local
|
||||
|
||||
ENV CFLAGS='-fPIC'
|
||||
ENV CXXFLAGS='-fPIC'
|
||||
|
||||
#Cmake
|
||||
ARG CMAKE_VERSION=3.14.6
|
||||
ARG CMAKE_VERSION_DOT=v3.14
|
||||
ARG CMAKE_HASH=4e8ea11cabe459308671b476469eace1622e770317a15951d7b55a82ccaaccb9
|
||||
RUN set -ex \
|
||||
&& curl -s -O https://cmake.org/files/${CMAKE_VERSION_DOT}/cmake-${CMAKE_VERSION}.tar.gz \
|
||||
unzip > /dev/null \
|
||||
&& cd /data || exit 1 \
|
||||
&& echo "\e[32mbuilding: Cmake\e[39m" \
|
||||
&& set -ex \
|
||||
&& curl -s -O https://cmake.org/files/${CMAKE_VERSION_DOT}/cmake-${CMAKE_VERSION}.tar.gz > /dev/null \
|
||||
&& echo "${CMAKE_HASH} cmake-${CMAKE_VERSION}.tar.gz" | sha256sum -c \
|
||||
&& tar -xzf cmake-${CMAKE_VERSION}.tar.gz \
|
||||
&& cd cmake-${CMAKE_VERSION} \
|
||||
&& ./configure \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
## Boost
|
||||
ARG BOOST_VERSION=1_70_0
|
||||
ARG BOOST_VERSION_DOT=1.70.0
|
||||
ARG BOOST_HASH=430ae8354789de4fd19ee52f3b1f739e1fba576f0aded0897c3c2bc00fb38778
|
||||
RUN set -ex \
|
||||
&& curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2 \
|
||||
&& tar -xzf cmake-${CMAKE_VERSION}.tar.gz > /dev/null \
|
||||
&& cd cmake-${CMAKE_VERSION} || exit 1 \
|
||||
&& echo "\e[32mmatrix style build text redirected to /dev/null. This will take some time. Go ahead make some coffee and check your emails.\e[39m" \
|
||||
&& ./configure --prefix=$BASE_DIR > /dev/null \
|
||||
&& make > /dev/null \
|
||||
&& make install > /dev/null \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/cmake-${CMAKE_VERSION} \
|
||||
&& rm -rf /data/cmake-${CMAKE_VERSION}.tar.gz \
|
||||
&& echo "\e[32mbuilding: Boost\e[39m" \
|
||||
&& set -ex \
|
||||
&& curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 > /dev/null \
|
||||
&& echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \
|
||||
&& tar -xvf boost_${BOOST_VERSION}.tar.bz2 \
|
||||
&& cd boost_${BOOST_VERSION} \
|
||||
&& ./bootstrap.sh \
|
||||
&& ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --with-locale threading=multi threadapi=pthread cflags="$CFLAGS" cxxflags="$CXXFLAGS" stage
|
||||
ENV BOOST_ROOT /usr/local/boost_${BOOST_VERSION}
|
||||
&& tar -xvf boost_${BOOST_VERSION}.tar.bz2 > /dev/null \
|
||||
&& cd boost_${BOOST_VERSION} || exit 1 \
|
||||
&& ./bootstrap.sh > /dev/null \
|
||||
&& ./b2 -a install --prefix=$BASE_DIR --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --with-locale threading=multi threadapi=pthread cflags="$CFLAGS" cxxflags="$CXXFLAGS" stage > /dev/null \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/boost_${BOOST_VERSION} \
|
||||
&& rm -rf /data/boost_${BOOST_VERSION}.tar.bz2
|
||||
|
||||
WORKDIR /data
|
||||
ENV BASE_DIR /usr/local
|
||||
|
||||
# OpenSSL
|
||||
ARG OPENSSL_VERSION=1.1.1g
|
||||
ARG OPENSSL_VERSION=1.1.1
|
||||
ARG OPENSSL_FIX=g
|
||||
ARG OPENSSL_HASH=ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46
|
||||
RUN set -ex \
|
||||
&& curl -s -O https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz \
|
||||
&& echo "${OPENSSL_HASH} openssl-${OPENSSL_VERSION}.tar.gz" | sha256sum -c \
|
||||
&& tar -xzf openssl-${OPENSSL_VERSION}.tar.gz \
|
||||
&& cd openssl-${OPENSSL_VERSION} \
|
||||
&& ./Configure linux-x86_64 no-shared --static "$CFLAGS" \
|
||||
&& make build_generated \
|
||||
&& make libcrypto.a \
|
||||
&& make install
|
||||
ENV OPENSSL_ROOT_DIR=/usr/local/openssl-${OPENSSL_VERSION}
|
||||
|
||||
# ZMQ
|
||||
ARG ZMQ_VERSION=v4.3.2
|
||||
ARG ZMQ_HASH=a84ffa12b2eb3569ced199660bac5ad128bff1f0
|
||||
RUN set -ex \
|
||||
&& git clone https://github.com/zeromq/libzmq.git -b ${ZMQ_VERSION} \
|
||||
&& cd libzmq \
|
||||
&& test `git rev-parse HEAD` = ${ZMQ_HASH} || exit 1 \
|
||||
&& ./autogen.sh \
|
||||
&& ./configure --enable-static --disable-shared \
|
||||
&& make \
|
||||
&& make install \
|
||||
&& ldconfig
|
||||
|
||||
# zmq.hpp
|
||||
ARG CPPZMQ_VERSION=v4.4.1
|
||||
ARG CPPZMQ_HASH=f5b36e563598d48fcc0d82e589d3596afef945ae
|
||||
RUN set -ex \
|
||||
&& git clone https://github.com/zeromq/cppzmq.git -b ${CPPZMQ_VERSION} \
|
||||
&& cd cppzmq \
|
||||
&& test `git rev-parse HEAD` = ${CPPZMQ_HASH} || exit 1 \
|
||||
&& mv *.hpp /usr/local/include
|
||||
|
||||
# Readline
|
||||
ARG READLINE_VERSION=8.0
|
||||
ARG READLINE_HASH=e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461
|
||||
RUN set -ex \
|
||||
&& curl -s -O https://ftp.gnu.org/gnu/readline/readline-${READLINE_VERSION}.tar.gz \
|
||||
&& echo "${READLINE_HASH} readline-${READLINE_VERSION}.tar.gz" | sha256sum -c \
|
||||
&& tar -xzf readline-${READLINE_VERSION}.tar.gz \
|
||||
&& cd readline-${READLINE_VERSION} \
|
||||
&& ./configure \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
# Sodium
|
||||
ARG SODIUM_VERSION=1.0.18
|
||||
ARG SODIUM_HASH=4f5e89fa84ce1d178a6765b8b46f2b6f91216677
|
||||
RUN set -ex \
|
||||
&& git clone https://github.com/jedisct1/libsodium.git -b ${SODIUM_VERSION} \
|
||||
&& cd libsodium \
|
||||
|
||||
ENV CFLAGS='-fPIC -O2 -g'
|
||||
ENV CXXFLAGS='-fPIC -O2 -g'
|
||||
ENV LDFLAGS='-static-libstdc++'
|
||||
|
||||
RUN echo "\e[32mbuilding: Openssl\e[39m" \
|
||||
&& set -ex \
|
||||
&& curl -s -O https://www.openssl.org/source/openssl-${OPENSSL_VERSION}${OPENSSL_FIX}.tar.gz > /dev/null \
|
||||
# && curl -s -O https://www.openssl.org/source/old/${OPENSSL_VERSION}/openssl-${OPENSSL_VERSION}${OPENSSL_FIX}.tar.gz > /dev/null \
|
||||
&& echo "${OPENSSL_HASH} openssl-${OPENSSL_VERSION}${OPENSSL_FIX}.tar.gz" | sha256sum -c \
|
||||
&& tar -xzf openssl-${OPENSSL_VERSION}${OPENSSL_FIX}.tar.gz > /dev/null \
|
||||
&& cd openssl-${OPENSSL_VERSION}${OPENSSL_FIX} || exit 1 \
|
||||
&& ./Configure --prefix=$BASE_DIR linux-x86_64 no-shared --static "$CFLAGS" > /dev/null \
|
||||
&& make build_generated > /dev/null \
|
||||
&& make libcrypto.a > /dev/null \
|
||||
&& echo "\e[32mblah, blah, shared libraries from the glib, something, something. Don't worry about it.\e[39m" \
|
||||
&& make install > /dev/null \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/openssl-${OPENSSL_VERSION}${OPENSSL_FIX} \
|
||||
&& rm -rf /data/openssl-${OPENSSL_VERSION}${OPENSSL_FIX}.tar.gz \
|
||||
&& echo "\e[32mbuilding: ZMQ\e[39m" \
|
||||
&& set -ex \
|
||||
&& git clone --branch ${ZMQ_VERSION} --single-branch --depth 1 https://github.com/zeromq/libzmq.git > /dev/null \
|
||||
&& cd libzmq || exit 1 \
|
||||
&& test `git rev-parse HEAD` = ${ZMQ_HASH} || exit 1 \
|
||||
&& ./autogen.sh > /dev/null \
|
||||
&& ./configure --prefix=$BASE_DIR --enable-libunwind=no --enable-static --disable-shared > /dev/null \
|
||||
&& make > /dev/null \
|
||||
&& make install > /dev/null \
|
||||
&& ldconfig > /dev/null \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/libzmq \
|
||||
&& echo "\e[32mbuilding: zmq.hpp\e[39m" \
|
||||
&& set -ex \
|
||||
&& git clone --branch ${CPPZMQ_VERSION} --single-branch --depth 1 https://github.com/zeromq/cppzmq.git > /dev/null \
|
||||
&& cd cppzmq || exit 1 \
|
||||
&& test `git rev-parse HEAD` = ${CPPZMQ_HASH} || exit 1 \
|
||||
&& mv *.hpp $BASE_DIR/include \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/cppzmq \
|
||||
&& echo "\e[32mbuilding: Readline\e[39m" \
|
||||
&& set -ex \
|
||||
&& curl -s -O https://ftp.gnu.org/gnu/readline/readline-${READLINE_VERSION}.tar.gz > /dev/null \
|
||||
&& echo "${READLINE_HASH} readline-${READLINE_VERSION}.tar.gz" | sha256sum -c \
|
||||
&& tar -xzf readline-${READLINE_VERSION}.tar.gz > /dev/null \
|
||||
&& cd readline-${READLINE_VERSION} || exit 1 \
|
||||
&& ./configure --prefix=$BASE_DIR > /dev/null \
|
||||
&& make > /dev/null \
|
||||
&& make install > /dev/null \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/readline-${READLINE_VERSION} \
|
||||
&& rm -rf readline-${READLINE_VERSION}.tar.gz \
|
||||
&& echo "\e[32mbuilding: Sodium\e[39m" \
|
||||
&& set -ex \
|
||||
&& git clone --branch ${SODIUM_VERSION} --single-branch --depth 1 https://github.com/jedisct1/libsodium.git > /dev/null \
|
||||
&& cd libsodium || exit 1 \
|
||||
&& test `git rev-parse HEAD` = ${SODIUM_HASH} || exit 1 \
|
||||
&& ./autogen.sh \
|
||||
&& ./configure \
|
||||
&& make \
|
||||
&& make check \
|
||||
&& make install
|
||||
&& ./configure --prefix=$BASE_DIR > /dev/null \
|
||||
&& make > /dev/null \
|
||||
&& make check > /dev/null \
|
||||
&& make install > /dev/null \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/libsodium
|
||||
|
||||
WORKDIR /data
|
||||
ENV BASE_DIR /usr/local
|
||||
|
||||
# Udev
|
||||
ARG UDEV_VERSION=v3.2.10
|
||||
ARG UDEV_HASH=be7068512c7512fa67c64fbff3472ab140c277c8
|
||||
RUN set -ex \
|
||||
&& git clone https://github.com/gentoo/eudev -b ${UDEV_VERSION} \
|
||||
&& cd eudev \
|
||||
&& test `git rev-parse HEAD` = ${UDEV_HASH} || exit 1 \
|
||||
&& ./autogen.sh \
|
||||
&& ./configure --disable-gudev --disable-introspection --disable-hwdb --disable-manpages --disable-shared \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
ARG UDEV_VERSION=v3.2.8
|
||||
ARG UDEV_HASH=d69f3f28348123ab7fa0ebac63ec2fd16800c5e0
|
||||
# Libusb
|
||||
ARG USB_VERSION=v1.0.22
|
||||
ARG USB_HASH=0034b2afdcdb1614e78edaa2a9e22d5936aeae5d
|
||||
RUN set -ex \
|
||||
&& git clone https://github.com/libusb/libusb.git -b ${USB_VERSION} \
|
||||
&& cd libusb \
|
||||
&& test `git rev-parse HEAD` = ${USB_HASH} || exit 1 \
|
||||
&& ./autogen.sh \
|
||||
&& ./configure --disable-shared \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
# Hidapi
|
||||
ARG HIDAPI_VERSION=hidapi-0.8.0-rc1
|
||||
ARG HIDAPI_HASH=40cf516139b5b61e30d9403a48db23d8f915f52c
|
||||
RUN set -ex \
|
||||
&& git clone https://github.com/signal11/hidapi -b ${HIDAPI_VERSION} \
|
||||
&& cd hidapi \
|
||||
&& test `git rev-parse HEAD` = ${HIDAPI_HASH} || exit 1 \
|
||||
&& ./bootstrap \
|
||||
&& ./configure --enable-static --disable-shared \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
# Protobuf
|
||||
ARG PROTOBUF_VERSION=v3.7.1
|
||||
ARG PROTOBUF_HASH=6973c3a5041636c1d8dc5f7f6c8c1f3c15bc63d6
|
||||
RUN set -ex \
|
||||
&& git clone https://github.com/protocolbuffers/protobuf -b ${PROTOBUF_VERSION} \
|
||||
&& cd protobuf \
|
||||
&& test `git rev-parse HEAD` = ${PROTOBUF_HASH} || exit 1 \
|
||||
&& git submodule update --init --recursive \
|
||||
|
||||
ENV CFLAGS='-fPIC -O2 -g'
|
||||
ENV CXXFLAGS='-fPIC -O2 -g'
|
||||
ENV LDFLAGS='-static-libstdc++'
|
||||
|
||||
RUN echo "\e[32mbuilding: Udev\e[39m" \
|
||||
&& set -ex \
|
||||
&& git clone --branch ${UDEV_VERSION} --single-branch --depth 1 https://github.com/gentoo/eudev > /dev/null \
|
||||
&& cd eudev || exit 1 \
|
||||
&& test `git rev-parse HEAD` = ${UDEV_HASH} || exit 1 \
|
||||
&& ./autogen.sh \
|
||||
&& ./configure --enable-static --disable-shared \
|
||||
&& make \
|
||||
&& make install \
|
||||
&& ldconfig
|
||||
|
||||
WORKDIR /src
|
||||
COPY . .
|
||||
&& ./configure --prefix=$BASE_DIR --disable-gudev --disable-introspection --disable-hwdb --disable-manpages --disable-shared > /dev/null \
|
||||
&& make > /dev/null \
|
||||
&& make install > /dev/null \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/eudev \
|
||||
&& echo "\e[32mbuilding: Libusb. Ahh, a dependency that shouldn't have been included in the codebase. Hardware wallets are way overrated.\e[39m" \
|
||||
&& set -ex \
|
||||
&& git clone --branch ${USB_VERSION} --single-branch --depth 1 https://github.com/libusb/libusb.git > /dev/null \
|
||||
&& cd libusb || exit 1 \
|
||||
&& test `git rev-parse HEAD` = ${USB_HASH} || exit 1 \
|
||||
&& ./autogen.sh > /dev/null \
|
||||
&& ./configure --prefix=$BASE_DIR --disable-shared > /dev/null \
|
||||
&& make > /dev/null \
|
||||
&& make install > /dev/null \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/libusb \
|
||||
&& echo "\e[32mbuilding: Hidapi\e[39m" \
|
||||
&& set -ex \
|
||||
&& git clone --branch ${HIDAPI_VERSION} --single-branch --depth 1 https://github.com/signal11/hidapi > /dev/null \
|
||||
&& cd hidapi || exit 1 \
|
||||
&& test `git rev-parse HEAD` = ${HIDAPI_HASH} || exit 1 \
|
||||
&& ./bootstrap \
|
||||
&& ./configure --prefix=$BASE_DIR --enable-static --disable-shared > /dev/null \
|
||||
&& make > /dev/null \
|
||||
&& make install > /dev/null \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/hidapi \
|
||||
&& echo "\e[32mbuilding: Protobuf <- fuck you protobuf, you worthless piece of shit!\e[39m" \
|
||||
&& set -ex \
|
||||
&& git clone --branch ${PROTOBUF_VERSION} --single-branch --depth 1 https://github.com/protocolbuffers/protobuf > /dev/null \
|
||||
&& cd protobuf || exit 1 \
|
||||
&& test `git rev-parse HEAD` = ${PROTOBUF_HASH} || exit 1 \
|
||||
&& git submodule update --init --recursive > /dev/null \
|
||||
&& ./autogen.sh > /dev/null \
|
||||
&& ./configure --prefix=$BASE_DIR --enable-static --disable-shared > /dev/null \
|
||||
&& make > /dev/null \
|
||||
&& make install > /dev/null \
|
||||
&& ldconfig \
|
||||
&& cd /data || exit 1 \
|
||||
&& rm -rf /data/protobuf
|
||||
|
||||
WORKDIR /home
|
||||
ENV USE_SINGLE_BUILDDIR=1
|
||||
ARG NPROC
|
||||
RUN set -ex && \
|
||||
git submodule init && git submodule update && \
|
||||
rm -rf build && \
|
||||
if [ -z "$NPROC" ] ; \
|
||||
then make -j$(nproc) release-static ; \
|
||||
else make -j$NPROC release-static ; \
|
||||
fi
|
||||
|
||||
# runtime stage
|
||||
FROM ubuntu:16.04
|
||||
|
||||
RUN set -ex && \
|
||||
apt-get update && \
|
||||
apt-get --no-install-recommends --yes install ca-certificates && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt
|
||||
COPY --from=builder /src/build/release/bin /usr/local/bin/
|
||||
|
||||
# Create wownero user
|
||||
RUN adduser --system --group --disabled-password wownero && \
|
||||
mkdir -p /wallet /home/wownero/.wownero && \
|
||||
chown -R wownero:wownero /home/wownero/.wownero && \
|
||||
chown -R wownero:wownero /wallet
|
||||
|
||||
# Contains the blockchain
|
||||
VOLUME /home/wownero/.wownero
|
||||
|
||||
# Generate your wallet via accessing the container and run:
|
||||
# cd /wallet
|
||||
# wownero-wallet-cli
|
||||
VOLUME /wallet
|
||||
|
||||
EXPOSE 34567
|
||||
EXPOSE 34568
|
||||
|
||||
# switch to user wownero
|
||||
USER wownero
|
||||
|
||||
ENTRYPOINT ["wownerod", "--p2p-bind-ip=0.0.0.0", "--p2p-bind-port=34567", "--rpc-bind-ip=0.0.0.0", "--rpc-bind-port=34568", "--non-interactive", "--confirm-external-bind"]
|
||||
# Wownero
|
||||
RUN echo "\e[32mbuilding: Wownero\e[39m" \
|
||||
&& set -ex \
|
||||
&& git clone https://git.wownero.com/wownero/wownero \
|
||||
&& cd wownero \
|
||||
&& make -j2 release-static-linux-x86_64 \
|
||||
&& echo "\e[32mdone building Wownero, binaries located in: /home/wownero/build/release/bin\e[39m"
|
||||
|
||||
64
PKGBUILD
Normal file
64
PKGBUILD
Normal file
@@ -0,0 +1,64 @@
|
||||
# Maintainer: wowario <wowario[at]protonmail[dot]com>
|
||||
|
||||
pkgname=wownero-git
|
||||
pkgver=0.8.0.0
|
||||
pkgrel=1
|
||||
pkgdesc="Wownero: a fairly launched privacy-centric meme coin with no premine and a finite supply"
|
||||
license=('BSD')
|
||||
arch=('x86_64')
|
||||
url="https://wownero.org/"
|
||||
depends=('boost-libs' 'libunwind' 'openssl' 'readline' 'zeromq' 'pcsclite' 'hidapi' 'protobuf')
|
||||
makedepends=('git' 'cmake' 'boost')
|
||||
source=(
|
||||
"${pkgname}"::"git+https://github.com/wownero/wownero#tag=v${pkgver}"
|
||||
"git+https://github.com/monero-project/unbound.git"
|
||||
"git+https://github.com/monero-project/miniupnp.git"
|
||||
"git+https://github.com/Tencent/rapidjson.git"
|
||||
"git+https://github.com/trezor/trezor-common.git"
|
||||
"git+https://github.com/wownero/RandomWOW.git"
|
||||
"wownero.sysusers"
|
||||
"wownero.tmpfiles")
|
||||
sha512sums=('SKIP'
|
||||
'SKIP'
|
||||
'SKIP'
|
||||
'SKIP'
|
||||
'SKIP'
|
||||
'SKIP'
|
||||
'SKIP'
|
||||
'SKIP')
|
||||
|
||||
prepare() {
|
||||
cd "${pkgname}"
|
||||
git submodule init
|
||||
git config submodule.external/unbound.url "$srcdir/unbound"
|
||||
git config submodule.external/miniupnp.url "$srcdir/miniupnp"
|
||||
git config submodule.external/rapidjson.url "$srcdir/rapidjson"
|
||||
git config submodule.external/RandomWOW.url "$srcdir/RandomWOW"
|
||||
git submodule update
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${pkgname}"
|
||||
mkdir -p build && cd build
|
||||
cmake -D BUILD_TESTS=OFF -D CMAKE_BUILD_TYPE=release -D ARCH=default ../
|
||||
make
|
||||
}
|
||||
|
||||
package() {
|
||||
backup=('etc/wownerod.conf')
|
||||
|
||||
cd "${pkgname}"
|
||||
install -Dm644 "LICENSE" -t "${pkgdir}/usr/share/licenses/${pkgname}"
|
||||
|
||||
install -Dm644 "utils/conf/wownerod.conf" "${pkgdir}/etc/wownerod.conf"
|
||||
install -Dm644 "utils/systemd/wownerod.service" "${pkgdir}/usr/lib/systemd/system/wownerod.service"
|
||||
install -Dm644 "../wownero.sysusers" "${pkgdir}/usr/lib/sysusers.d/wownero.conf"
|
||||
install -Dm644 "../wownero.tmpfiles" "${pkgdir}/usr/lib/tmpfiles.d/wownero.conf"
|
||||
|
||||
install -Dm755 "build/bin/wownero-wallet-cli" \
|
||||
"build/bin/wownero-wallet-rpc" \
|
||||
"build/bin/wownerod" \
|
||||
-t "${pkgdir}/usr/bin"
|
||||
}
|
||||
|
||||
# vim: ts=2 sw=2 et:
|
||||
132
README.md
132
README.md
@@ -1,36 +1,43 @@
|
||||
[](https://ci.wownero.com/wownero/wownero)
|
||||
# ~~Mo~~Wownero - Such privacy! Many coins! Wow! 🐕
|
||||
|
||||
Copyright (c) 2014-2023 The Monero Project.
|
||||
Copyright (c) 2014-2020 The Monero Project.
|
||||
Portions Copyright (c) 2012-2013 The Cryptonote developers.
|
||||
|
||||
## Resources
|
||||
|
||||
- IRC: [OFTC #wownero](https://webchat.oftc.net/?channels=wownero)
|
||||
- Web: [wownero.org](https://wownero.org)
|
||||
- Web: [wownero.org](http://wownero.org)
|
||||
- Twitter: [@w0wn3r0](https://twitter.com/w0wn3r0)
|
||||
- Reddit: [/r/wownero](https://www.reddit.com/r/wownero)
|
||||
- Mail: [wownero@protonmail.com](mailto:wownero@protonmail.com)
|
||||
- Git: [git.wownero.com/wownero/wownero](https://git.wownero.com/wownero/wownero)
|
||||
- GitHub: [git.wownero.com/wownero/wownero](https://git.wownero.com/wownero/wownero)
|
||||
- IRC: [#wownero on Freenode](https://kiwiirc.com/client/irc.freenode.net/?nick=suchchatter|?#wownero)
|
||||
- Bitmessage Chan: wownero (`BM-2cSzWtrj2pzLva9GF1Jp2TYsnLjrnJpvba`)
|
||||
- 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)
|
||||
- Discord: [discord.gg/DSC9TWx](https://discord.gg/DSC9TWx)
|
||||
- Telegram: [t.me/wownero](https://t.me/wownero)
|
||||
- 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)
|
||||
- Feather-WOW Desktop Wallet: [featherwallet.org/wownero](https://featherwallet.org/wownero)
|
||||
- WOW Stash Web Wallet: [wowstash.app](https://wowstash.app)
|
||||
- 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
|
||||
|
||||
- [AltQuick](https://altquick.com/market/Wownero)
|
||||
- [Majestic Bank](https://majesticbank.sc)
|
||||
- [TradeOgre](https://tradeogre.com/exchange/BTC-WOW)
|
||||
|
||||
### Blockchain Explorers
|
||||
|
||||
- https://explore.wownero.com
|
||||
- http://wow5eqtzqvsg5jctqzg5g7uk3u62sfqiacj5x6lo4by7bvnj6jkvubyd.onion
|
||||
- https://wownero.club
|
||||
|
||||
### Free Public Nodes
|
||||
- global.wownodes.com:34568 (Global)
|
||||
- node.suchwow.xyz:34568 (US)
|
||||
- wow.pwned.systems:34568 (NL)
|
||||
- wowbux.org:34568 (CA)
|
||||
- super.fast.node.xmr.pm:34568 (DE)
|
||||
- wow.pwned.systems (NL)
|
||||
- wowbuxx535x4exuexja2xfezpwcyznxkofui4ndjiectj4yuh2xheiid.onion:34568
|
||||
|
||||
### Tor Peers
|
||||
- wowp2p5gelm6vhl2d5tvfqills63jilgy6hkvlrqljooov5ktaxgqdad.onion
|
||||
- f3moshycuklu3mb3wnlfjwn26nsgzreqtfzfuyjjk46u7jqxlhf7d5id.onion
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -41,11 +48,8 @@ Wownero is a privacy-centric memecoin that was fairly launched on April 1, 2018
|
||||
Wownero is a 100% community-sponsored endeavor. Supporting services are also graciously provided by sponsors:
|
||||
|
||||
[<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)
|
||||
alt="MacStadium"
|
||||
height="100">](https://www.macstadium.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 [WFS proposals](https://funding.wownero.com/proposals) or the dev slush fund.
|
||||
|
||||
@@ -61,40 +65,32 @@ 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!**
|
||||
**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://git.wownero.com/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.
|
||||
Join `#wownero-dev` on IRC freenode to participate in development conversation.
|
||||
|
||||
## Scheduled software/network upgrades
|
||||
## Scheduled software upgrades
|
||||
|
||||
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.
|
||||
Dates are provided in the format YYYY-MM-DD.
|
||||
|
||||
| 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
|
||||
| 53,666 | 2018-10-06 | Cool Cage | v0.3.0.0 | v0.3.1.3 | Cryptonight variant 2, LWMA v2, ringsize = 22, MMS
|
||||
| 63,469 | 2018-11-11 | Dank Doge | v0.4.0.0 | v0.4.0.0 | LWMA v4
|
||||
| 81,769 | 2019-02-19 | Erotic EggplantEmoji | v0.5.0.0 | v0.5.0.2 | Cryptonight/wow, LWMA v1 with N=144, Updated Bulletproofs, Fee Per Byte, Auto-churn
|
||||
| 114,969 | 2019-06-14 | F For Fappening | v0.6.1.0 | v0.6.1.2 | RandomWOW, new block weight algorithm, slightly more efficient RingCT format
|
||||
| 160,777 | 2019-11-20 | Gaping Goatse | v0.7.0.0 | v0.7.1.0 | Only allow >= 2 outputs, change to the block median used to calculate penalty, rct sigs in coinbase forbidden, 4 unlock time as protocol rule
|
||||
| - | 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
|
||||
| XXX,XXX | 2023-XX-XX | Kunty Karen | v0.11.0.0 | v0.11.0.0 | View tags, fee changes, adjusted dynamic block weight algorithm, multisig security fixes, RPC broadcast node donation sub-address
|
||||
| ------------------------------ | -----------| ----------------- | ---------------------- | -------------------------- | ---------------------------------------------------------------------------------- |
|
||||
| 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
|
||||
| 53,666 | 2018-10-06 | Cool Cage | v0.3.0.0 | v0.3.1.3 | Cryptonight variant 2, LWMA v2, ringsize = 22, MMS
|
||||
| 63,469 | 2018-11-11 | Dank Doge | v0.4.0.0 | v0.4.0.0 | LWMA v4
|
||||
| 81,769 | 2019-02-19 | Erotic EggplantEmoji | v0.5.0.0 | v0.5.0.2 | Cryptonight/wow, LWMA v1 with N=144, Updated Bulletproofs, Fee Per Byte, Auto-churn
|
||||
| 114,969 | 2019-06-14 | F For Fappening | v0.6.1.0 | v0.6.1.2 | RandomWOW, new block weight algorithm, slightly more efficient RingCT format
|
||||
| 160,777 | 2019-11-20 | Gaping Goatse | v0.7.0.0 | v0.7.1.0 | Only allow >= 2 outputs, change to the block median used to calculate penalty, rct sigs in coinbase forbidden, 4 unlock time as protocol rule
|
||||
| - | 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.2.0 | Dynamic coinbase unlock (up to 1 mo.), Deterministic unlock times, Enforce maximum coinbase amount, show_qr_code wallet command, CLSAG
|
||||
|
||||
X's indicate that these details have not been determined as of commit date.
|
||||
|
||||
@@ -120,6 +116,13 @@ Packages are available for
|
||||
|
||||
nix-shell -p wownero
|
||||
|
||||
* Ubuntu 18.04/Ubuntu 16.04/Debian 9/Debian 8 (amd64)
|
||||
|
||||
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8BC34ABB48E565F0
|
||||
sudo add-apt-repository "deb http://ppa.wownero.com/ bionic main"
|
||||
sudo apt-get update
|
||||
sudo apt-get install wownero
|
||||
|
||||
Packaging for your favorite distribution would be a welcome contribution!
|
||||
|
||||
**DISCLAIMER: These packages are not part of this repository, and as such, do not go through the same review process to ensure their trustworthiness and security.**
|
||||
@@ -166,10 +169,10 @@ To run in background:
|
||||
|
||||
To run as a systemd service, copy
|
||||
[wownerod.service](utils/systemd/wownerod.service) to `/etc/systemd/system/` and
|
||||
[wownerod.conf](wownerod.conf) to `/etc/`. The [example
|
||||
[wownerod.conf](utils/conf/wownerod.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](wownerod.conf).
|
||||
config](utils/conf/wownerod.conf).
|
||||
|
||||
Once node is synced to network, run the CLI wallet by entering:
|
||||
|
||||
@@ -179,37 +182,26 @@ Type `help` in CLI wallet to see standard commands (for advanced options, type `
|
||||
|
||||
## Tor Anonymity Network
|
||||
|
||||
### Ubuntu
|
||||
* Install [Tor Browser](https://www.torproject.org/download/)
|
||||
* Open `torrc` file in a text editor ([installation directory]/Browser/TorBrowser/Data/Tor/torrc) and add hidden service information as follows:
|
||||
|
||||
* `sudo apt-get update && sudo apt-get install tor -y`
|
||||
* `sudo nano /etc/tor/torrc`
|
||||
|
||||
add the following:
|
||||
```
|
||||
HiddenServiceDir /var/lib/tor/wownero/
|
||||
HiddenServicePort 34569 127.0.0.1:34569
|
||||
HiddenServicePort 34566 127.0.0.1:34566
|
||||
HiddenServiceDir [installation directory]/Browser/TorBrowser/Data/Tor/wow_node
|
||||
HiddenServiceVersion 3
|
||||
HiddenServicePort 44568 127.0.0.1:44568
|
||||
```
|
||||
save and close nano
|
||||
|
||||
* `sudo /etc/init.d/tor restart && sudo systemctl enable tor`
|
||||
* copy [wownerod.conf](https://git.wownero.com/wownero/wownero/raw/branch/master/wownerod.conf) file and save it in same directory as `wownerod`.
|
||||
* start wownerod like this:
|
||||
* Save `torrc` file and restart Tor Browser (keep open)
|
||||
* Change directory to the `wow_node` folder, open `hostname` file, and copy your node's ".onion" address
|
||||
* Start wownerod with the following parameters:
|
||||
|
||||
```
|
||||
./wownerod --config-file=wownerod.conf
|
||||
./wownerod --tx-proxy tor,127.0.0.1:9150,10 --add-peer hdps3qwnusz64r7odvynmae6myc2uyvrsc2emap6636qeuzll72eouid.onion:44568 --anonymous-inbound YOUR_NODE_ADDRESS.onion:44568,127.0.0.1:44568,25
|
||||
```
|
||||
|
||||
* `sudo cat /var/lib/tor/wownero/hostname`
|
||||
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
|
||||
```
|
||||
./wownero-wallet-cli --proxy 127.0.0.1:9150 --daemon-address wow7dhbgiljnkspkzpjyy66auegbrye2ptfv4gucgbhireg5rrjza5ad.onion:34568
|
||||
```
|
||||
|
||||
Use port `9050` instead of `9150` if you installed Tor as a standalone daemon. For more information, check out [ANONYMITY_NETWORKS](https://git.wownero.com/wownero/wownero/src/branch/master/ANONYMITY_NETWORKS.md).
|
||||
|
||||
@@ -91,7 +91,7 @@ endif()
|
||||
|
||||
# Protobuf compilation test
|
||||
if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON)
|
||||
execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} -I "${CMAKE_CURRENT_LIST_DIR}" -I "${Protobuf_INCLUDE_DIR}" "${CMAKE_CURRENT_LIST_DIR}/test-protobuf.proto" --cpp_out ${CMAKE_BINARY_DIR} RESULT_VARIABLE RET OUTPUT_VARIABLE OUT ERROR_VARIABLE ERR)
|
||||
execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} -I "${CMAKE_SOURCE_DIR}/cmake" -I "${Protobuf_INCLUDE_DIR}" "${CMAKE_SOURCE_DIR}/cmake/test-protobuf.proto" --cpp_out ${CMAKE_BINARY_DIR} RESULT_VARIABLE RET OUTPUT_VARIABLE OUT ERROR_VARIABLE ERR)
|
||||
if(RET)
|
||||
message(STATUS "Protobuf test generation failed: ${OUT} ${ERR}")
|
||||
endif()
|
||||
@@ -100,7 +100,7 @@ if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON)
|
||||
"${CMAKE_BINARY_DIR}"
|
||||
SOURCES
|
||||
"${CMAKE_BINARY_DIR}/test-protobuf.pb.cc"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/test-protobuf.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/cmake/test-protobuf.cpp"
|
||||
CMAKE_FLAGS
|
||||
"-DINCLUDE_DIRECTORIES=${Protobuf_INCLUDE_DIR};${CMAKE_BINARY_DIR}"
|
||||
"-DCMAKE_CXX_STANDARD=11"
|
||||
|
||||
@@ -42,19 +42,12 @@
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
if (CCACHE_FOUND)
|
||||
# Try to compile a test program with ccache, in order to verify if it really works. (needed on exotic setups)
|
||||
set(TEST_PROJECT "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeTmp")
|
||||
file(WRITE "${TEST_PROJECT}/CMakeLists.txt" [=[
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
project(test)
|
||||
option (CCACHE "")
|
||||
file(WRITE "${CMAKE_SOURCE_DIR}/test.cpp" "int main() { return 0; }")
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE}")
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CCACHE}")
|
||||
add_executable(main test.cpp)
|
||||
]=])
|
||||
try_compile(RET "${TEST_PROJECT}/build" "${TEST_PROJECT}" "test" CMAKE_FLAGS -DCCACHE="${CCACHE_FOUND}")
|
||||
unset(TEST_PROJECT)
|
||||
if (${RET})
|
||||
# Create a temporary file with a simple program.
|
||||
set(TEMP_CPP_FILE "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeTmp/test-program.cpp")
|
||||
file(WRITE "${TEMP_CPP_FILE}" "int main() { return 0; }")
|
||||
# And run the found ccache on it.
|
||||
execute_process(COMMAND "${CCACHE_FOUND}" "${CMAKE_CXX_COMPILER}" "${TEMP_CPP_FILE}" RESULT_VARIABLE RET)
|
||||
if (${RET} EQUAL 0)
|
||||
# Success
|
||||
message(STATUS "Found usable ccache: ${CCACHE_FOUND}")
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_FOUND}")
|
||||
|
||||
@@ -134,7 +134,7 @@ if ( LibUSB_FOUND )
|
||||
|
||||
try_compile(LibUSB_COMPILE_TEST_PASSED
|
||||
${CMAKE_BINARY_DIR}
|
||||
"${CMAKE_CURRENT_LIST_DIR}/test-libusb-version.c"
|
||||
"${CMAKE_SOURCE_DIR}/cmake/test-libusb-version.c"
|
||||
CMAKE_FLAGS
|
||||
"-DINCLUDE_DIRECTORIES=${LibUSB_INCLUDE_DIRS}"
|
||||
"-DLINK_DIRECTORIES=${LibUSB_LIBRARIES}"
|
||||
|
||||
72
cmake/SetClangTidy.cmake
Normal file
72
cmake/SetClangTidy.cmake
Normal file
@@ -0,0 +1,72 @@
|
||||
# Copyright (c) 2014-2020, The Monero Project
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification, are
|
||||
# permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
# of conditions and the following disclaimer in the documentation and/or other
|
||||
# materials provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software without specific
|
||||
# prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_CLANG_TIDY.html
|
||||
# This module sets the following variables:
|
||||
# CMAKE_C_CLANG_TIDY
|
||||
# CMAKE_CXX_CLANG_TIDY
|
||||
# when clang-tidy is found in PATH. Afterwards, the code is being linted by the tool.
|
||||
# The checks to be enabled can be manipulated with the variable MONERO_CLANG_TIDY_CHECKS
|
||||
|
||||
macro (monero_clang_tidy LANGUAGE)
|
||||
set(TOOL_NAME "clang-tidy")
|
||||
set(MONERO_CLANG_TIDY_MIN_VERSION "3.6")
|
||||
if(${CMAKE_VERSION} VERSION_LESS "${MONERO_CLANG_TIDY_MIN_VERSION}")
|
||||
message(FATAL_ERROR "Sorry, ${TOOL_NAME} is available for CMake from version ${MONERO_CLANG_TIDY_MIN_VERSION}")
|
||||
else()
|
||||
message(STATUS "Trying to enable ${TOOL_NAME}")
|
||||
find_program(MONERO_CLANG_BIN ${TOOL_NAME})
|
||||
if(NOT MONERO_CLANG_BIN)
|
||||
message(FATAL_ERROR "${TOOL_NAME} not found! Try running: sudo apt install ${TOOL_NAME}")
|
||||
else()
|
||||
message(STATUS "Found ${MONERO_CLANG_BIN}")
|
||||
set(MONERO_CLANG_TIDY_CHECKS
|
||||
-header-filter=.; # By default the headers are excluded. This line enables them.
|
||||
-checks=*; # Currently enabling all checks
|
||||
# An example of selectively enabling checks:
|
||||
#-checks=bugprone-*,cppcoreguidelines-avoid-goto # Have to be in one line :(
|
||||
)
|
||||
# Current list of checks is avaibale under:
|
||||
# https://clang.llvm.org/extra/clang-tidy/
|
||||
if (${LANGUAGE} STREQUAL "C")
|
||||
set(CMAKE_C_CLANG_TIDY
|
||||
${MONERO_CLANG_BIN}; # Mind the semicolon
|
||||
${MONERO_CLANG_TIDY_CHECKS}
|
||||
)
|
||||
elseif (${LANGUAGE} STREQUAL "CXX")
|
||||
set(CMAKE_CXX_CLANG_TIDY
|
||||
${MONERO_CLANG_BIN}; # Mind the semicolon
|
||||
${MONERO_CLANG_TIDY_CHECKS}
|
||||
)
|
||||
else()
|
||||
message(FATAL_ERROR "${TOOL_NAME}: Unsupported language: ${LANGUAGE}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
SOURCES_PATH ?= $(BASEDIR)/sources
|
||||
BASE_CACHE ?= $(BASEDIR)/built
|
||||
SDK_PATH ?= $(BASEDIR)/SDKs
|
||||
FALLBACK_DOWNLOAD_PATH ?= https://downloads.getmonero.org/depends-sources
|
||||
FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources
|
||||
|
||||
BUILD = $(shell ./config.guess)
|
||||
HOST ?= $(BUILD)
|
||||
|
||||
@@ -32,7 +32,7 @@ endef
|
||||
define fetch_file
|
||||
( test -f $$($(1)_source_dir)/$(4) || \
|
||||
( $(call fetch_file_inner,$(1),$(2),$(3),$(4),$(5)) || \
|
||||
$(call fetch_file_inner,$(1),$(FALLBACK_DOWNLOAD_PATH),$(4),$(4),$(5))))
|
||||
$(call fetch_file_inner,$(1),$(FALLBACK_DOWNLOAD_PATH),$(3),$(4),$(5))))
|
||||
endef
|
||||
|
||||
define int_get_build_recipe_hash
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package=boost
|
||||
$(package)_version=1_64_0
|
||||
$(package)_download_path=https://downloads.sourceforge.net/project/boost/boost/1.64.0/
|
||||
$(package)_download_path=https://dl.bintray.com/boostorg/release/1.64.0/source/
|
||||
$(package)_file_name=$(package)_$($(package)_version).tar.bz2
|
||||
$(package)_sha256_hash=7bcc5caace97baa948931d712ea5f37038dbb1c5d89b43ad4def4ed7cb683332
|
||||
$(package)_dependencies=libiconv
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package=eudev
|
||||
$(package)_version=v3.2.6
|
||||
$(package)_download_path=https://github.com/gentoo/eudev/archive/
|
||||
$(package)_download_file=$($(package)_version).tar.gz
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_file_name=$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=a96ecb8637667897b8bd4dee4c22c7c5f08b327be45186e912ce6bc768385852
|
||||
|
||||
define $(package)_set_vars
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package=gtest
|
||||
$(package)_version=1.8.1
|
||||
$(package)_download_path=https://github.com/google/googletest/archive/
|
||||
$(package)_download_file=release-$($(package)_version).tar.gz
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_file_name=release-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=9bf1fe5182a604b4135edc1a425ae356c9ad15e9b23f9f12a02e80184c3a249c
|
||||
$(package)_cxxflags=-std=c++11
|
||||
$(package)_cxxflags_linux=-fPIC
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package=native_cctools
|
||||
$(package)_version=807d6fd1be5d2224872e381870c0a75387fe05e6
|
||||
$(package)_download_path=https://github.com/theuni/cctools-port/archive
|
||||
$(package)_download_file=$($(package)_version).tar.gz
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_file_name=$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=a09c9ba4684670a0375e42d9d67e7f12c1f62581a27f28f7c825d6d7032ccc6a
|
||||
$(package)_build_subdir=cctools
|
||||
$(package)_clang_version=3.7.1
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package=openssl
|
||||
$(package)_version=1.1.1k
|
||||
$(package)_version=1.1.1i
|
||||
$(package)_download_path=https://www.openssl.org/source
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=892a0875b9872acd04a9fde79b1f943075d5ea162415de3047c327df33fbaee5
|
||||
$(package)_sha256_hash=e8be6a35fe41d10603c3cc635e93289ed00bf34b79671a3a4de64fcee00d5242
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_env=AR="$($(package)_ar)" ARFLAGS=$($(package)_arflags) RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)"
|
||||
|
||||
@@ -58,7 +58,6 @@ namespace epee
|
||||
byte_buffer buffer_; //! Beginning of buffer
|
||||
std::uint8_t* next_write_; //! Current write position
|
||||
const std::uint8_t* end_; //! End of buffer
|
||||
std::size_t increase_size_; //! Minimum buffer size increase
|
||||
|
||||
//! \post `requested <= available()`
|
||||
void overflow(const std::size_t requested);
|
||||
@@ -75,29 +74,17 @@ namespace epee
|
||||
using char_type = std::uint8_t;
|
||||
using Ch = char_type;
|
||||
|
||||
//! \return Default minimum size increase on buffer overflow
|
||||
static constexpr std::size_t default_increase() noexcept { return 4096; }
|
||||
|
||||
//! Increase internal buffer by at least `byte_stream_increase` bytes.
|
||||
byte_stream() noexcept
|
||||
: byte_stream(default_increase())
|
||||
{}
|
||||
|
||||
//! Increase internal buffer by at least `increase` bytes.
|
||||
explicit byte_stream(const std::size_t increase) noexcept
|
||||
: buffer_(nullptr),
|
||||
next_write_(nullptr),
|
||||
end_(nullptr),
|
||||
increase_size_(increase)
|
||||
end_(nullptr)
|
||||
{}
|
||||
|
||||
byte_stream(byte_stream&& rhs) noexcept;
|
||||
~byte_stream() noexcept = default;
|
||||
byte_stream& operator=(byte_stream&& rhs) noexcept;
|
||||
|
||||
//! \return The minimum increase size on buffer overflow
|
||||
std::size_t increase_size() const noexcept { return increase_size_; }
|
||||
|
||||
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_; }
|
||||
@@ -188,7 +175,7 @@ namespace epee
|
||||
void put_n(const std::uint8_t ch, const std::size_t count)
|
||||
{
|
||||
check(count);
|
||||
std::memset(tellp(), ch, count);
|
||||
std::memset(tellp(), count, ch);
|
||||
next_write_ += count;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace http
|
||||
virtual bool connect(std::chrono::milliseconds timeout) = 0;
|
||||
virtual bool disconnect() = 0;
|
||||
virtual bool is_connected(bool *ssl = NULL) = 0;
|
||||
virtual bool invoke(const boost::string_ref uri, const boost::string_ref method, const std::string& body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) = 0;
|
||||
virtual bool invoke(const boost::string_ref uri, const boost::string_ref method, const boost::string_ref body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) = 0;
|
||||
virtual bool invoke_get(const boost::string_ref uri, std::chrono::milliseconds timeout, const std::string& body = std::string(), const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) = 0;
|
||||
virtual bool invoke_post(const boost::string_ref uri, const std::string& body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) = 0;
|
||||
virtual uint64_t get_bytes_sent() const = 0;
|
||||
|
||||
@@ -207,6 +207,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
buffer_ssl_init_fill = 0;
|
||||
if (is_income && m_ssl_support != epee::net_utils::ssl_support_t::e_ssl_support_disabled)
|
||||
socket().async_receive(boost::asio::buffer(buffer_),
|
||||
boost::asio::socket_base::message_peek,
|
||||
strand_.wrap(
|
||||
std::bind(&connection<t_protocol_handler>::handle_receive, self,
|
||||
std::placeholders::_1,
|
||||
@@ -269,6 +270,8 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
//_dbg3("[sock " << socket().native_handle() << "] add_ref, m_peer_number=" << mI->m_peer_number);
|
||||
CRITICAL_REGION_LOCAL(self->m_self_refs_lock);
|
||||
//_dbg3("[sock " << socket().native_handle() << "] add_ref 2, m_peer_number=" << mI->m_peer_number);
|
||||
if(m_was_shutdown)
|
||||
return false;
|
||||
++m_reference_count;
|
||||
m_self_ref = std::move(self);
|
||||
return true;
|
||||
@@ -331,9 +334,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
TRY_ENTRY();
|
||||
//_info("[sock " << socket().native_handle() << "] Async read calledback.");
|
||||
|
||||
if (m_was_shutdown)
|
||||
return;
|
||||
|
||||
if (!e)
|
||||
{
|
||||
double current_speed_down;
|
||||
@@ -360,9 +360,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
CRITICAL_REGION_LOCAL( epee::net_utils::network_throttle_manager::m_lock_get_global_throttle_in );
|
||||
delay = epee::net_utils::network_throttle_manager::get_global_throttle_in().get_sleep_time_after_tick( bytes_transferred );
|
||||
}
|
||||
|
||||
if (m_was_shutdown)
|
||||
return;
|
||||
|
||||
delay *= 0.5;
|
||||
long int ms = (long int)(delay * 100);
|
||||
@@ -434,9 +431,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
std::size_t bytes_transferred)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
|
||||
if (m_was_shutdown) return;
|
||||
|
||||
if (e)
|
||||
{
|
||||
// offload the error case
|
||||
@@ -444,11 +438,13 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
return;
|
||||
}
|
||||
|
||||
reset_timer(get_timeout_from_bytes_read(bytes_transferred), false);
|
||||
|
||||
buffer_ssl_init_fill += bytes_transferred;
|
||||
MTRACE("we now have " << buffer_ssl_init_fill << "/" << get_ssl_magic_size() << " bytes needed to detect SSL");
|
||||
if (buffer_ssl_init_fill < get_ssl_magic_size())
|
||||
if (buffer_ssl_init_fill <= get_ssl_magic_size())
|
||||
{
|
||||
socket().async_receive(boost::asio::buffer(buffer_.data() + buffer_ssl_init_fill, buffer_.size() - buffer_ssl_init_fill),
|
||||
boost::asio::socket_base::message_peek,
|
||||
strand_.wrap(
|
||||
boost::bind(&connection<t_protocol_handler>::handle_receive, connection<t_protocol_handler>::shared_from_this(),
|
||||
boost::asio::placeholders::error,
|
||||
@@ -474,7 +470,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
if (m_ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled)
|
||||
{
|
||||
// Handshake
|
||||
if (!handshake(boost::asio::ssl::stream_base::server, boost::asio::const_buffer(buffer_.data(), buffer_ssl_init_fill)))
|
||||
if (!handshake(boost::asio::ssl::stream_base::server))
|
||||
{
|
||||
MERROR("SSL handshake failed");
|
||||
boost::interprocess::ipcdetail::atomic_write32(&m_want_close_connection, 1);
|
||||
@@ -489,11 +485,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
handle_read(e, buffer_ssl_init_fill);
|
||||
return;
|
||||
}
|
||||
|
||||
async_read_some(boost::asio::buffer(buffer_),
|
||||
strand_.wrap(
|
||||
@@ -660,8 +651,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds( ms ) );
|
||||
m_send_que_lock.lock();
|
||||
_dbg1("sleep for queue: " << ms);
|
||||
if (m_was_shutdown)
|
||||
return false;
|
||||
|
||||
if (retry > retry_limit) {
|
||||
MWARNING("send que size is more than ABSTRACT_SERVER_SEND_QUE_MAX_COUNT(" << ABSTRACT_SERVER_SEND_QUE_MAX_COUNT << "), shutting down connection");
|
||||
@@ -759,8 +748,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
template<class t_protocol_handler>
|
||||
void connection<t_protocol_handler>::reset_timer(boost::posix_time::milliseconds ms, bool add)
|
||||
{
|
||||
const auto tms = ms.total_milliseconds();
|
||||
if (tms < 0 || (add && tms == 0))
|
||||
if (ms.total_milliseconds() < 0)
|
||||
{
|
||||
MWARNING("Ignoring negative timeout " << ms);
|
||||
return;
|
||||
|
||||
@@ -132,10 +132,10 @@ class connection_basic { // not-templated base class for rapid developmet of som
|
||||
ssl_support_t get_ssl_support() const { return m_ssl_support; }
|
||||
void disable_ssl() { m_ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_disabled; }
|
||||
|
||||
bool handshake(boost::asio::ssl::stream_base::handshake_type type, boost::asio::const_buffer buffer = {})
|
||||
bool handshake(boost::asio::ssl::stream_base::handshake_type type)
|
||||
{
|
||||
//m_state != nullptr verified in constructor
|
||||
return m_state->ssl_options().handshake(socket_, type, buffer);
|
||||
return m_state->ssl_options().handshake(socket_, type);
|
||||
}
|
||||
|
||||
template<typename MutableBufferSequence, typename ReadHandler>
|
||||
|
||||
@@ -233,7 +233,7 @@ namespace net_utils
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
inline bool invoke(const boost::string_ref uri, const boost::string_ref method, const std::string& body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) override
|
||||
inline bool invoke(const boost::string_ref uri, const boost::string_ref method, const boost::string_ref body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) override
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_lock);
|
||||
if(!is_connected())
|
||||
|
||||
@@ -118,8 +118,10 @@
|
||||
return true; \
|
||||
} \
|
||||
uint64_t ticks2 = misc_utils::get_tick_count(); \
|
||||
epee::serialization::store_t_to_binary(static_cast<command_type::response&>(resp), response_info.m_body); \
|
||||
epee::byte_slice buffer; \
|
||||
epee::serialization::store_t_to_binary(static_cast<command_type::response&>(resp), buffer, 64 * 1024); \
|
||||
uint64_t ticks3 = epee::misc_utils::get_tick_count(); \
|
||||
response_info.m_body.assign(reinterpret_cast<const char*>(buffer.data()), buffer.size()); \
|
||||
response_info.m_mime_tipe = " application/octet-stream"; \
|
||||
response_info.m_header_info.m_content_type = " application/octet-stream"; \
|
||||
MDEBUG( s_pattern << "() processed with " << ticks1-ticks << "/"<< ticks2-ticks1 << "/" << ticks3-ticks2 << "ms"); \
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "byte_slice.h"
|
||||
#include "net_utils_base.h"
|
||||
#include "span.h"
|
||||
|
||||
@@ -39,6 +38,7 @@
|
||||
|
||||
namespace epee
|
||||
{
|
||||
class byte_slice;
|
||||
namespace levin
|
||||
{
|
||||
#pragma pack(push)
|
||||
@@ -72,8 +72,7 @@ namespace levin
|
||||
|
||||
|
||||
#define LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED 0
|
||||
#define LEVIN_INITIAL_MAX_PACKET_SIZE 256*1024 // 256 KiB before handshake
|
||||
#define LEVIN_DEFAULT_MAX_PACKET_SIZE 100000000 //100MB by default after handshake
|
||||
#define LEVIN_DEFAULT_MAX_PACKET_SIZE 100000000 //100MB by default
|
||||
|
||||
#define LEVIN_PACKET_REQUEST 0x00000001
|
||||
#define LEVIN_PACKET_RESPONSE 0x00000002
|
||||
@@ -87,7 +86,7 @@ namespace levin
|
||||
template<class t_connection_context = net_utils::connection_context_base>
|
||||
struct levin_commands_handler
|
||||
{
|
||||
virtual int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, t_connection_context& context)=0;
|
||||
virtual int invoke(int command, const epee::span<const uint8_t> in_buff, byte_slice& buff_out, t_connection_context& context)=0;
|
||||
virtual int notify(int command, const epee::span<const uint8_t> in_buff, t_connection_context& context)=0;
|
||||
virtual void callback(t_connection_context& context){};
|
||||
|
||||
|
||||
@@ -84,8 +84,7 @@ class async_protocol_handler_config
|
||||
|
||||
public:
|
||||
typedef t_connection_context connection_context;
|
||||
uint64_t m_initial_max_packet_size;
|
||||
uint64_t m_max_packet_size;
|
||||
uint64_t m_max_packet_size;
|
||||
uint64_t m_invoke_timeout;
|
||||
|
||||
int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, boost::uuids::uuid connection_id);
|
||||
@@ -106,7 +105,7 @@ public:
|
||||
size_t get_in_connections_count();
|
||||
void set_handler(levin_commands_handler<t_connection_context>* handler, void (*destroy)(levin_commands_handler<t_connection_context>*) = NULL);
|
||||
|
||||
async_protocol_handler_config():m_pcommands_handler(NULL), m_pcommands_handler_destroy(NULL), m_initial_max_packet_size(LEVIN_INITIAL_MAX_PACKET_SIZE), m_max_packet_size(LEVIN_DEFAULT_MAX_PACKET_SIZE), m_invoke_timeout(LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED)
|
||||
async_protocol_handler_config():m_pcommands_handler(NULL), m_pcommands_handler_destroy(NULL), m_max_packet_size(LEVIN_DEFAULT_MAX_PACKET_SIZE), m_invoke_timeout(LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED)
|
||||
{}
|
||||
~async_protocol_handler_config() { set_handler(NULL, NULL); }
|
||||
void del_out_connections(size_t count);
|
||||
@@ -163,7 +162,6 @@ public:
|
||||
net_utils::i_service_endpoint* m_pservice_endpoint;
|
||||
config_type& m_config;
|
||||
t_connection_context& m_connection_context;
|
||||
std::atomic<uint64_t> m_max_packet_size;
|
||||
|
||||
net_utils::buffer m_cache_in_buffer;
|
||||
stream_state m_state;
|
||||
@@ -291,8 +289,7 @@ public:
|
||||
m_current_head(bucket_head2()),
|
||||
m_pservice_endpoint(psnd_hndlr),
|
||||
m_config(config),
|
||||
m_connection_context(conn_context),
|
||||
m_max_packet_size(config.m_initial_max_packet_size),
|
||||
m_connection_context(conn_context),
|
||||
m_cache_in_buffer(4 * 1024),
|
||||
m_state(stream_state_head)
|
||||
{
|
||||
@@ -402,14 +399,13 @@ public:
|
||||
}
|
||||
|
||||
// these should never fail, but do runtime check for safety
|
||||
const uint64_t max_packet_size = m_max_packet_size;
|
||||
CHECK_AND_ASSERT_MES(max_packet_size >= m_cache_in_buffer.size(), false, "Bad m_cache_in_buffer.size()");
|
||||
CHECK_AND_ASSERT_MES(max_packet_size - m_cache_in_buffer.size() >= m_fragment_buffer.size(), false, "Bad m_cache_in_buffer.size() + m_fragment_buffer.size()");
|
||||
CHECK_AND_ASSERT_MES(m_config.m_max_packet_size >= m_cache_in_buffer.size(), false, "Bad m_cache_in_buffer.size()");
|
||||
CHECK_AND_ASSERT_MES(m_config.m_max_packet_size - m_cache_in_buffer.size() >= m_fragment_buffer.size(), false, "Bad m_cache_in_buffer.size() + m_fragment_buffer.size()");
|
||||
|
||||
// flipped to subtraction; prevent overflow since m_max_packet_size is variable and public
|
||||
if(cb > max_packet_size - m_cache_in_buffer.size() - m_fragment_buffer.size())
|
||||
if(cb > m_config.m_max_packet_size - m_cache_in_buffer.size() - m_fragment_buffer.size())
|
||||
{
|
||||
MWARNING(m_connection_context << "Maximum packet size exceed!, m_max_packet_size = " << max_packet_size
|
||||
MWARNING(m_connection_context << "Maximum packet size exceed!, m_max_packet_size = " << m_config.m_max_packet_size
|
||||
<< ", packet received " << m_cache_in_buffer.size() + cb
|
||||
<< ", connection will be closed.");
|
||||
return false;
|
||||
@@ -434,7 +430,7 @@ public:
|
||||
//async call scenario
|
||||
boost::shared_ptr<invoke_response_handler_base> response_handler = m_invoke_response_handlers.front();
|
||||
response_handler->reset_timer();
|
||||
MDEBUG(m_connection_context << "LEVIN_PACKET partial msg received. len=" << cb << ", current total " << m_cache_in_buffer.size() << "/" << m_current_head.m_cb << " (" << (100.0f * m_cache_in_buffer.size() / (m_current_head.m_cb ? m_current_head.m_cb : 1)) << "%)");
|
||||
MDEBUG(m_connection_context << "LEVIN_PACKET partial msg received. len=" << cb);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -469,14 +465,6 @@ public:
|
||||
temp = std::move(m_fragment_buffer);
|
||||
m_fragment_buffer.clear();
|
||||
std::memcpy(std::addressof(m_current_head), std::addressof(temp[0]), sizeof(bucket_head2));
|
||||
const size_t max_bytes = m_connection_context.get_max_bytes(m_current_head.m_command);
|
||||
if(m_current_head.m_cb > std::min<size_t>(max_packet_size, max_bytes))
|
||||
{
|
||||
MERROR(m_connection_context << "Maximum packet size exceed!, m_max_packet_size = " << std::min<size_t>(max_packet_size, max_bytes)
|
||||
<< ", packet header received " << m_current_head.m_cb << ", command " << m_current_head.m_command
|
||||
<< ", connection will be closed.");
|
||||
return false;
|
||||
}
|
||||
buff_to_invoke = {reinterpret_cast<const uint8_t*>(temp.data()) + sizeof(bucket_head2), temp.size() - sizeof(bucket_head2)};
|
||||
}
|
||||
|
||||
@@ -526,20 +514,15 @@ public:
|
||||
{
|
||||
if(m_current_head.m_have_to_return_data)
|
||||
{
|
||||
std::string return_buff;
|
||||
byte_slice return_buff;
|
||||
const uint32_t return_code = m_config.m_pcommands_handler->invoke(
|
||||
m_current_head.m_command, buff_to_invoke, return_buff, m_connection_context
|
||||
);
|
||||
|
||||
// peer_id remains unset if dropped
|
||||
if (m_current_head.m_command == m_connection_context.handshake_command() && m_connection_context.handshake_complete())
|
||||
m_max_packet_size = m_config.m_max_packet_size;
|
||||
|
||||
bucket_head2 head = make_header(m_current_head.m_command, return_buff.size(), LEVIN_PACKET_RESPONSE, false);
|
||||
head.m_return_code = SWAP32LE(return_code);
|
||||
return_buff.insert(0, reinterpret_cast<const char*>(&head), sizeof(head));
|
||||
|
||||
if(!m_pservice_endpoint->do_send(byte_slice{std::move(return_buff)}))
|
||||
if(!m_pservice_endpoint->do_send(byte_slice{{epee::as_byte_span(head), epee::to_span(return_buff)}}))
|
||||
return false;
|
||||
|
||||
MDEBUG(m_connection_context << "LEVIN_PACKET_SENT. [len=" << head.m_cb
|
||||
@@ -593,11 +576,10 @@ public:
|
||||
m_cache_in_buffer.erase(sizeof(bucket_head2));
|
||||
m_state = stream_state_body;
|
||||
m_oponent_protocol_ver = m_current_head.m_protocol_version;
|
||||
const size_t max_bytes = m_connection_context.get_max_bytes(m_current_head.m_command);
|
||||
if(m_current_head.m_cb > std::min<size_t>(max_packet_size, max_bytes))
|
||||
if(m_current_head.m_cb > m_config.m_max_packet_size)
|
||||
{
|
||||
LOG_ERROR_CC(m_connection_context, "Maximum packet size exceed!, m_max_packet_size = " << std::min<size_t>(max_packet_size, max_bytes)
|
||||
<< ", packet header received " << m_current_head.m_cb << ", command " << m_current_head.m_command
|
||||
LOG_ERROR_CC(m_connection_context, "Maximum packet size exceed!, m_max_packet_size = " << m_config.m_max_packet_size
|
||||
<< ", packet header received " << m_current_head.m_cb
|
||||
<< ", connection will be closed.");
|
||||
return false;
|
||||
}
|
||||
@@ -651,9 +633,6 @@ public:
|
||||
boost::interprocess::ipcdetail::atomic_write32(&m_invoke_buf_ready, 0);
|
||||
CRITICAL_REGION_BEGIN(m_invoke_response_handlers_lock);
|
||||
|
||||
if (command == m_connection_context.handshake_command())
|
||||
m_max_packet_size = m_config.m_max_packet_size;
|
||||
|
||||
if(!send_message(command, in_buff, LEVIN_PACKET_REQUEST, true))
|
||||
{
|
||||
LOG_ERROR_CC(m_connection_context, "Failed to do_send");
|
||||
@@ -695,9 +674,6 @@ public:
|
||||
|
||||
boost::interprocess::ipcdetail::atomic_write32(&m_invoke_buf_ready, 0);
|
||||
|
||||
if (command == m_connection_context.handshake_command())
|
||||
m_max_packet_size = m_config.m_max_packet_size;
|
||||
|
||||
if (!send_message(command, in_buff, LEVIN_PACKET_REQUEST, true))
|
||||
{
|
||||
LOG_ERROR_CC(m_connection_context, "Failed to send request");
|
||||
@@ -800,32 +776,36 @@ void async_protocol_handler_config<t_connection_context>::del_connection(async_p
|
||||
template<class t_connection_context>
|
||||
void async_protocol_handler_config<t_connection_context>::delete_connections(size_t count, bool incoming)
|
||||
{
|
||||
std::vector<typename connections_map::mapped_type> connections;
|
||||
|
||||
auto scope_exit_handler = misc_utils::create_scope_leave_handler([&connections]{
|
||||
for (auto &aph: connections)
|
||||
aph->finish_outer_call();
|
||||
});
|
||||
|
||||
std::vector <boost::uuids::uuid> connections;
|
||||
CRITICAL_REGION_BEGIN(m_connects_lock);
|
||||
for (auto& c: m_connects)
|
||||
{
|
||||
if (c.second->m_connection_context.m_is_income == incoming)
|
||||
if (c.second->start_outer_call())
|
||||
connections.push_back(c.second);
|
||||
connections.push_back(c.first);
|
||||
}
|
||||
|
||||
// close random connections from the provided set
|
||||
// TODO or better just keep removing random elements (performance)
|
||||
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
|
||||
shuffle(connections.begin(), connections.end(), std::default_random_engine(seed));
|
||||
for (size_t i = 0; i < connections.size() && i < count; ++i)
|
||||
m_connects.erase(connections[i]->get_connection_id());
|
||||
while (count > 0 && connections.size() > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto i = connections.end() - 1;
|
||||
async_protocol_handler<t_connection_context> *conn = m_connects.at(*i);
|
||||
del_connection(conn);
|
||||
conn->close();
|
||||
connections.erase(i);
|
||||
}
|
||||
catch (const std::out_of_range &e)
|
||||
{
|
||||
MWARNING("Connection not found in m_connects, continuing");
|
||||
}
|
||||
--count;
|
||||
}
|
||||
|
||||
CRITICAL_REGION_END();
|
||||
|
||||
for (size_t i = 0; i < connections.size() && i < count; ++i)
|
||||
connections[i]->close();
|
||||
}
|
||||
//------------------------------------------------------------------------------------------
|
||||
template<class t_connection_context>
|
||||
@@ -887,35 +867,23 @@ int async_protocol_handler_config<t_connection_context>::invoke_async(int comman
|
||||
template<class t_connection_context> template<class callback_t>
|
||||
bool async_protocol_handler_config<t_connection_context>::foreach_connection(const callback_t &cb)
|
||||
{
|
||||
std::vector<typename connections_map::mapped_type> conn;
|
||||
|
||||
auto scope_exit_handler = misc_utils::create_scope_leave_handler([&conn]{
|
||||
for (auto &aph: conn)
|
||||
aph->finish_outer_call();
|
||||
});
|
||||
|
||||
CRITICAL_REGION_BEGIN(m_connects_lock);
|
||||
conn.reserve(m_connects.size());
|
||||
for (auto &e: m_connects)
|
||||
if (e.second->start_outer_call())
|
||||
conn.push_back(e.second);
|
||||
CRITICAL_REGION_END()
|
||||
|
||||
for (auto &aph: conn)
|
||||
if (!cb(aph->get_context_ref()))
|
||||
CRITICAL_REGION_LOCAL(m_connects_lock);
|
||||
for(auto& c: m_connects)
|
||||
{
|
||||
async_protocol_handler<t_connection_context>* aph = c.second;
|
||||
if(!cb(aph->get_context_ref()))
|
||||
return false;
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------
|
||||
template<class t_connection_context> template<class callback_t>
|
||||
bool async_protocol_handler_config<t_connection_context>::for_connection(const boost::uuids::uuid &connection_id, const callback_t &cb)
|
||||
{
|
||||
async_protocol_handler<t_connection_context>* aph = nullptr;
|
||||
if (find_and_lock_connection(connection_id, aph) != LEVIN_OK)
|
||||
CRITICAL_REGION_LOCAL(m_connects_lock);
|
||||
async_protocol_handler<t_connection_context>* aph = find_connection(connection_id);
|
||||
if (!aph)
|
||||
return false;
|
||||
auto scope_exit_handler = misc_utils::create_scope_leave_handler(
|
||||
boost::bind(&async_protocol_handler<t_connection_context>::finish_outer_call, aph));
|
||||
if(!cb(aph->get_context_ref()))
|
||||
return false;
|
||||
return true;
|
||||
@@ -978,14 +946,12 @@ int async_protocol_handler_config<t_connection_context>::send(byte_slice message
|
||||
template<class t_connection_context>
|
||||
bool async_protocol_handler_config<t_connection_context>::close(boost::uuids::uuid connection_id)
|
||||
{
|
||||
async_protocol_handler<t_connection_context>* aph = nullptr;
|
||||
if (find_and_lock_connection(connection_id, aph) != LEVIN_OK)
|
||||
CRITICAL_REGION_LOCAL(m_connects_lock);
|
||||
async_protocol_handler<t_connection_context>* aph = find_connection(connection_id);
|
||||
if (!aph)
|
||||
return false;
|
||||
auto scope_exit_handler = misc_utils::create_scope_leave_handler(
|
||||
boost::bind(&async_protocol_handler<t_connection_context>::finish_outer_call, aph));
|
||||
if (!aph->close())
|
||||
return false;
|
||||
CRITICAL_REGION_LOCAL(m_connects_lock);
|
||||
m_connects.erase(connection_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <boost/lambda/lambda.hpp>
|
||||
#include <boost/interprocess/detail/atomic.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include <functional>
|
||||
#include "net/net_utils_base.h"
|
||||
#include "net/net_ssl.h"
|
||||
@@ -178,7 +179,7 @@ namespace net_utils
|
||||
// SSL Options
|
||||
if (m_ssl_options.support == epee::net_utils::ssl_support_t::e_ssl_support_enabled || m_ssl_options.support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect)
|
||||
{
|
||||
if (!m_ssl_options.handshake(*m_ssl_socket, boost::asio::ssl::stream_base::client, {}, addr, timeout))
|
||||
if (!m_ssl_options.handshake(*m_ssl_socket, boost::asio::ssl::stream_base::client, addr, timeout))
|
||||
{
|
||||
if (m_ssl_options.support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect)
|
||||
{
|
||||
@@ -280,7 +281,7 @@ namespace net_utils
|
||||
|
||||
|
||||
inline
|
||||
bool send(const std::string& buff, std::chrono::milliseconds timeout)
|
||||
bool send(const boost::string_ref buff, std::chrono::milliseconds timeout)
|
||||
{
|
||||
|
||||
try
|
||||
@@ -298,7 +299,7 @@ namespace net_utils
|
||||
// object is used as a callback and will update the ec variable when the
|
||||
// operation completes. The blocking_udp_client.cpp example shows how you
|
||||
// can use boost::bind rather than boost::lambda.
|
||||
async_write(buff.c_str(), buff.size(), ec);
|
||||
async_write(buff.data(), buff.size(), ec);
|
||||
|
||||
// Block until the asynchronous operation has completed.
|
||||
while (ec == boost::asio::error::would_block)
|
||||
|
||||
@@ -131,8 +131,8 @@ namespace net_utils
|
||||
inline
|
||||
bool parse_url_ipv6(const std::string url_str, http::url_content& content)
|
||||
{
|
||||
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^((.*?)://)?(\\[(.*)\\](:(\\d+))?)(.*)?", boost::regex::icase | boost::regex::normal);
|
||||
// 12 3 4 5 6 7
|
||||
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^(([^:]*?)://)?(\\[(.*)\\](:(\\d+))?)(.*)?", boost::regex::icase | boost::regex::normal);
|
||||
// 12 3 4 5 6 7
|
||||
|
||||
content.port = 0;
|
||||
boost::smatch result;
|
||||
@@ -175,8 +175,8 @@ namespace net_utils
|
||||
|
||||
///iframe_test.html?api_url=http://api.vk.com/api.php&api_id=3289090&api_settings=1&viewer_id=562964060&viewer_type=0&sid=0aad8d1c5713130f9ca0076f2b7b47e532877424961367d81e7fa92455f069be7e21bc3193cbd0be11895&secret=368ebbc0ef&access_token=668bc03f43981d883f73876ffff4aa8564254b359cc745dfa1b3cde7bdab2e94105d8f6d8250717569c0a7&user_id=0&group_id=0&is_app_user=1&auth_key=d2f7a895ca5ff3fdb2a2a8ae23fe679a&language=0&parent_language=0&ad_info=ElsdCQBaQlxiAQRdFUVUXiN2AVBzBx5pU1BXIgZUJlIEAWcgAUoLQg==&referrer=unknown&lc_name=9834b6a3&hash=
|
||||
//STATIC_REGEXP_EXPR_1(rexp_match_uri, "^([^?#]*)(\\?([^#]*))?(#(.*))?", boost::regex::icase | boost::regex::normal);
|
||||
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^((.*?)://)?(([^/:]*)(:(\\d+))?)(.*)?", boost::regex::icase | boost::regex::normal);
|
||||
// 12 34 5 6 7
|
||||
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^(([^:]*?)://)?(([^/:]*)(:(\\d+))?)(.*)?", boost::regex::icase | boost::regex::normal);
|
||||
// 12 34 5 6 7
|
||||
content.port = 0;
|
||||
boost::smatch result;
|
||||
if(!(boost::regex_search(url_str, result, rexp_match_uri, boost::match_default) && result[0].matched))
|
||||
|
||||
@@ -132,7 +132,6 @@ namespace net_utils
|
||||
bool handshake(
|
||||
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> &socket,
|
||||
boost::asio::ssl::stream_base::handshake_type type,
|
||||
boost::asio::const_buffer buffer = {},
|
||||
const std::string& host = {},
|
||||
std::chrono::milliseconds timeout = std::chrono::seconds(15)) const;
|
||||
};
|
||||
|
||||
@@ -236,7 +236,6 @@ namespace net_utils
|
||||
virtual address_type get_type_id() const = 0;
|
||||
virtual zone get_zone() const = 0;
|
||||
virtual bool is_blockable() const = 0;
|
||||
virtual std::uint16_t port() const = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@@ -267,7 +266,6 @@ namespace net_utils
|
||||
virtual address_type get_type_id() const override { return value.get_type_id(); }
|
||||
virtual zone get_zone() const override { return value.get_zone(); }
|
||||
virtual bool is_blockable() const override { return value.is_blockable(); }
|
||||
virtual std::uint16_t port() const override { return value.port(); }
|
||||
};
|
||||
|
||||
std::shared_ptr<interface> self;
|
||||
@@ -314,7 +312,6 @@ namespace net_utils
|
||||
address_type get_type_id() const { return self ? self->get_type_id() : address_type::invalid; }
|
||||
zone get_zone() const { return self ? self->get_zone() : zone::invalid; }
|
||||
bool is_blockable() const { return self ? self->is_blockable() : false; }
|
||||
std::uint16_t port() const { return self ? self->port() : 0; }
|
||||
template<typename Type> const Type &as() const { return as_mutable<const Type>(); }
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
|
||||
@@ -141,6 +141,7 @@ public:
|
||||
|
||||
rolling_median_t(rolling_median_t &&m)
|
||||
{
|
||||
free(data);
|
||||
memcpy(this, &m, sizeof(rolling_median_t));
|
||||
m.data = NULL;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include "byte_slice.h"
|
||||
#include "portable_storage_template_helper.h"
|
||||
#include "net/http_base.h"
|
||||
#include "net/http_server_handlers_map2.h"
|
||||
@@ -74,12 +75,12 @@ namespace epee
|
||||
template<class t_request, class t_response, class t_transport>
|
||||
bool invoke_http_bin(const boost::string_ref uri, const t_request& out_struct, t_response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref method = "POST")
|
||||
{
|
||||
std::string req_param;
|
||||
if(!serialization::store_t_to_binary(out_struct, req_param))
|
||||
byte_slice req_param;
|
||||
if(!serialization::store_t_to_binary(out_struct, req_param, 16 * 1024))
|
||||
return false;
|
||||
|
||||
const http::http_response_info* pri = NULL;
|
||||
if(!transport.invoke(uri, method, req_param, timeout, std::addressof(pri)))
|
||||
if(!transport.invoke(uri, method, boost::string_ref{reinterpret_cast<const char*>(req_param.data()), req_param.size()}, timeout, std::addressof(pri)))
|
||||
{
|
||||
LOG_PRINT_L1("Failed to invoke http request to " << uri);
|
||||
return false;
|
||||
@@ -97,12 +98,7 @@ namespace epee
|
||||
return false;
|
||||
}
|
||||
|
||||
static const constexpr epee::serialization::portable_storage::limits_t default_http_bin_limits = {
|
||||
65536 * 3, // objects
|
||||
65536 * 3, // fields
|
||||
65536 * 3, // strings
|
||||
};
|
||||
return serialization::load_t_from_binary(result_struct, epee::strspan<uint8_t>(pri->m_body), &default_http_bin_limits);
|
||||
return serialization::load_t_from_binary(result_struct, epee::strspan<uint8_t>(pri->m_body));
|
||||
}
|
||||
|
||||
template<class t_request, class t_response, class t_transport>
|
||||
|
||||
@@ -27,8 +27,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "portable_storage_template_helper.h"
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include <boost/utility/value_init.hpp>
|
||||
#include <functional>
|
||||
#include "byte_slice.h"
|
||||
#include "span.h"
|
||||
#include "net/levin_base.h"
|
||||
|
||||
@@ -50,11 +52,6 @@ namespace
|
||||
snprintf(buf, sizeof(buf), "command-%u", command);
|
||||
return on_levin_traffic(context, initiator, sent, error, bytes, buf);
|
||||
}
|
||||
static const constexpr epee::serialization::portable_storage::limits_t default_levin_limits = {
|
||||
8192, // objects
|
||||
16384, // fields
|
||||
16384, // strings
|
||||
};
|
||||
}
|
||||
|
||||
namespace epee
|
||||
@@ -80,7 +77,7 @@ namespace epee
|
||||
return false;
|
||||
}
|
||||
serialization::portable_storage stg_ret;
|
||||
if(!stg_ret.load_from_binary(buff_to_recv, &default_levin_limits))
|
||||
if(!stg_ret.load_from_binary(buff_to_recv))
|
||||
{
|
||||
LOG_ERROR("Failed to load_from_binary on command " << command);
|
||||
return false;
|
||||
@@ -115,18 +112,19 @@ namespace epee
|
||||
const boost::uuids::uuid &conn_id = context.m_connection_id;
|
||||
typename serialization::portable_storage stg;
|
||||
out_struct.store(stg);
|
||||
std::string buff_to_send, buff_to_recv;
|
||||
stg.store_to_binary(buff_to_send);
|
||||
byte_slice buff_to_send;
|
||||
std::string buff_to_recv;
|
||||
stg.store_to_binary(buff_to_send, 16 * 1024);
|
||||
|
||||
on_levin_traffic(context, true, true, false, buff_to_send.size(), command);
|
||||
int res = transport.invoke(command, buff_to_send, buff_to_recv, conn_id);
|
||||
int res = transport.invoke(command, boost::string_ref{reinterpret_cast<const char*>(buff_to_send.data()), buff_to_send.size()}, buff_to_recv, conn_id);
|
||||
if( res <=0 )
|
||||
{
|
||||
LOG_PRINT_L1("Failed to invoke command " << command << " return code " << res);
|
||||
return false;
|
||||
}
|
||||
typename serialization::portable_storage stg_ret;
|
||||
if(!stg_ret.load_from_binary(buff_to_recv, &default_levin_limits))
|
||||
if(!stg_ret.load_from_binary(buff_to_recv))
|
||||
{
|
||||
on_levin_traffic(context, true, false, true, buff_to_recv.size(), command);
|
||||
LOG_ERROR("Failed to load_from_binary on command " << command);
|
||||
@@ -142,10 +140,10 @@ namespace epee
|
||||
const boost::uuids::uuid &conn_id = context.m_connection_id;
|
||||
typename serialization::portable_storage stg;
|
||||
const_cast<t_arg&>(out_struct).store(stg);//TODO: add true const support to searilzation
|
||||
std::string buff_to_send;
|
||||
stg.store_to_binary(buff_to_send);
|
||||
byte_slice buff_to_send;
|
||||
stg.store_to_binary(buff_to_send, 16 * 1024);
|
||||
on_levin_traffic(context, true, true, false, buff_to_send.size(), command);
|
||||
int res = transport.invoke_async(command, epee::strspan<uint8_t>(buff_to_send), conn_id, [cb, command](int code, const epee::span<const uint8_t> buff, typename t_transport::connection_context& context)->bool
|
||||
int res = transport.invoke_async(command, epee::to_span(buff_to_send), conn_id, [cb, command](int code, const epee::span<const uint8_t> buff, typename t_transport::connection_context& context)->bool
|
||||
{
|
||||
t_result result_struct = AUTO_VAL_INIT(result_struct);
|
||||
if( code <=0 )
|
||||
@@ -157,7 +155,7 @@ namespace epee
|
||||
return false;
|
||||
}
|
||||
serialization::portable_storage stg_ret;
|
||||
if(!stg_ret.load_from_binary(buff, &default_levin_limits))
|
||||
if(!stg_ret.load_from_binary(buff))
|
||||
{
|
||||
on_levin_traffic(context, true, false, true, buff.size(), command);
|
||||
LOG_ERROR("Failed to load_from_binary on command " << command);
|
||||
@@ -189,11 +187,11 @@ namespace epee
|
||||
const boost::uuids::uuid &conn_id = context.m_connection_id;
|
||||
serialization::portable_storage stg;
|
||||
out_struct.store(stg);
|
||||
std::string buff_to_send;
|
||||
byte_slice buff_to_send;
|
||||
stg.store_to_binary(buff_to_send);
|
||||
|
||||
on_levin_traffic(context, true, true, false, buff_to_send.size(), command);
|
||||
int res = transport.notify(command, epee::strspan<uint8_t>(buff_to_send), conn_id);
|
||||
int res = transport.notify(command, epee::to_span(buff_to_send), conn_id);
|
||||
if(res <=0 )
|
||||
{
|
||||
MERROR("Failed to notify command " << command << " return code " << res);
|
||||
@@ -204,10 +202,10 @@ namespace epee
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template<class t_owner, class t_in_type, class t_out_type, class t_context, class callback_t>
|
||||
int buff_to_t_adapter(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, callback_t cb, t_context& context )
|
||||
int buff_to_t_adapter(int command, const epee::span<const uint8_t> in_buff, byte_slice& buff_out, callback_t cb, t_context& context )
|
||||
{
|
||||
serialization::portable_storage strg;
|
||||
if(!strg.load_from_binary(in_buff, &default_levin_limits))
|
||||
if(!strg.load_from_binary(in_buff))
|
||||
{
|
||||
on_levin_traffic(context, false, false, true, in_buff.size(), command);
|
||||
LOG_ERROR("Failed to load_from_binary in command " << command);
|
||||
@@ -227,7 +225,7 @@ namespace epee
|
||||
serialization::portable_storage strg_out;
|
||||
static_cast<t_out_type&>(out_struct).store(strg_out);
|
||||
|
||||
if(!strg_out.store_to_binary(buff_out))
|
||||
if(!strg_out.store_to_binary(buff_out, 32 * 1024))
|
||||
{
|
||||
LOG_ERROR("Failed to store_to_binary in command" << command);
|
||||
return -1;
|
||||
@@ -241,7 +239,7 @@ namespace epee
|
||||
int buff_to_t_adapter(t_owner* powner, int command, const epee::span<const uint8_t> in_buff, callback_t cb, t_context& context)
|
||||
{
|
||||
serialization::portable_storage strg;
|
||||
if(!strg.load_from_binary(in_buff, &default_levin_limits))
|
||||
if(!strg.load_from_binary(in_buff))
|
||||
{
|
||||
on_levin_traffic(context, false, false, true, in_buff.size(), command);
|
||||
LOG_ERROR("Failed to load_from_binary in notify " << command);
|
||||
@@ -259,7 +257,7 @@ namespace epee
|
||||
}
|
||||
|
||||
#define CHAIN_LEVIN_INVOKE_MAP2(context_type) \
|
||||
int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, context_type& context) \
|
||||
int invoke(int command, const epee::span<const uint8_t> in_buff, epee::byte_slice& buff_out, context_type& context) \
|
||||
{ \
|
||||
bool handled = false; \
|
||||
return handle_invoke_map(false, command, in_buff, buff_out, context, handled); \
|
||||
@@ -268,13 +266,13 @@ namespace epee
|
||||
#define CHAIN_LEVIN_NOTIFY_MAP2(context_type) \
|
||||
int notify(int command, const epee::span<const uint8_t> in_buff, context_type& context) \
|
||||
{ \
|
||||
bool handled = false; std::string fake_str;\
|
||||
bool handled = false; epee::byte_slice fake_str; \
|
||||
return handle_invoke_map(true, command, in_buff, fake_str, context, handled); \
|
||||
}
|
||||
|
||||
|
||||
#define CHAIN_LEVIN_INVOKE_MAP() \
|
||||
int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, epee::net_utils::connection_context_base& context) \
|
||||
int invoke(int command, const epee::span<const uint8_t> in_buff, epee::byte_slice& buff_out, epee::net_utils::connection_context_base& context) \
|
||||
{ \
|
||||
bool handled = false; \
|
||||
return handle_invoke_map(false, command, in_buff, buff_out, context, handled); \
|
||||
@@ -294,7 +292,7 @@ namespace epee
|
||||
}
|
||||
|
||||
#define BEGIN_INVOKE_MAP2(owner_type) \
|
||||
template <class t_context> int handle_invoke_map(bool is_notify, int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, t_context& context, bool& handled) \
|
||||
template <class t_context> int handle_invoke_map(bool is_notify, int command, const epee::span<const uint8_t> in_buff, epee::byte_slice& buff_out, t_context& context, bool& handled) \
|
||||
{ \
|
||||
try { \
|
||||
typedef owner_type internal_owner_type_name;
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
|
||||
#include "misc_language.h"
|
||||
#include "portable_storage_base.h"
|
||||
#include "portable_storage_to_bin.h"
|
||||
#include "portable_storage_from_bin.h"
|
||||
#include "portable_storage_to_json.h"
|
||||
#include "portable_storage_from_json.h"
|
||||
@@ -40,10 +39,9 @@
|
||||
#include "span.h"
|
||||
#include "int-util.h"
|
||||
|
||||
#include <boost/mpl/contains.hpp>
|
||||
|
||||
namespace epee
|
||||
{
|
||||
class byte_slice;
|
||||
namespace serialization
|
||||
{
|
||||
/************************************************************************/
|
||||
@@ -56,13 +54,6 @@ namespace epee
|
||||
typedef epee::serialization::harray harray;
|
||||
typedef storage_entry meta_entry;
|
||||
|
||||
struct limits_t
|
||||
{
|
||||
size_t n_objects;
|
||||
size_t n_fields;
|
||||
size_t n_strings; // not counting field names
|
||||
};
|
||||
|
||||
portable_storage(){}
|
||||
virtual ~portable_storage(){}
|
||||
hsection open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist = false);
|
||||
@@ -92,9 +83,9 @@ namespace epee
|
||||
bool delete_entry(const std::string& pentry_name, hsection hparent_section = nullptr);
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
bool store_to_binary(binarybuffer& target);
|
||||
bool load_from_binary(const epee::span<const uint8_t> target, const limits_t *limits = NULL);
|
||||
bool load_from_binary(const std::string& target, const limits_t *limits = NULL) { return load_from_binary(epee::strspan<uint8_t>(target), limits); }
|
||||
bool store_to_binary(byte_slice& target, std::size_t initial_buffer_size = 8192);
|
||||
bool load_from_binary(const epee::span<const uint8_t> target);
|
||||
bool load_from_binary(const std::string& target) { return load_from_binary(epee::strspan<uint8_t>(target)); }
|
||||
template<class trace_policy>
|
||||
bool dump_as_xml(std::string& targetObj, const std::string& root_name = "");
|
||||
bool dump_as_json(std::string& targetObj, size_t indent = 0, bool insert_newlines = true);
|
||||
@@ -142,24 +133,8 @@ namespace epee
|
||||
{
|
||||
return false;//TODO: don't think i ever again will use xml - ambiguous and "overtagged" format
|
||||
}
|
||||
|
||||
inline
|
||||
bool portable_storage::store_to_binary(binarybuffer& target)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
std::stringstream ss;
|
||||
storage_block_header sbh = AUTO_VAL_INIT(sbh);
|
||||
sbh.m_signature_a = SWAP32LE(PORTABLE_STORAGE_SIGNATUREA);
|
||||
sbh.m_signature_b = SWAP32LE(PORTABLE_STORAGE_SIGNATUREB);
|
||||
sbh.m_ver = PORTABLE_STORAGE_FORMAT_VER;
|
||||
ss.write((const char*)&sbh, sizeof(storage_block_header));
|
||||
pack_entry_to_buff(ss, m_root);
|
||||
target = ss.str();
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::store_to_binary", false)
|
||||
}
|
||||
inline
|
||||
bool portable_storage::load_from_binary(const epee::span<const uint8_t> source, const limits_t *limits)
|
||||
bool portable_storage::load_from_binary(const epee::span<const uint8_t> source)
|
||||
{
|
||||
m_root.m_entries.clear();
|
||||
if(source.size() < sizeof(storage_block_header))
|
||||
@@ -182,8 +157,6 @@ namespace epee
|
||||
}
|
||||
TRY_ENTRY();
|
||||
throwable_buffer_reader buf_reader(source.data()+sizeof(storage_block_header), source.size()-sizeof(storage_block_header));
|
||||
if (limits)
|
||||
buf_reader.set_limits(limits->n_objects, limits->n_fields, limits->n_strings);
|
||||
buf_reader.read(m_root);
|
||||
return true;//TODO:
|
||||
CATCH_ENTRY("portable_storage::load_from_binary", false);
|
||||
@@ -293,7 +266,6 @@ namespace epee
|
||||
static_assert(std::is_rvalue_reference<entry_type&&>(), "unexpected copy of value");
|
||||
TRY_ENTRY();
|
||||
CHECK_AND_ASSERT(psection, nullptr);
|
||||
CHECK_AND_ASSERT(!pentry_name.empty(), nullptr);
|
||||
auto ins_res = psection->m_entries.emplace(pentry_name, std::forward<entry_type>(entry));
|
||||
return &ins_res.first->second;
|
||||
CATCH_ENTRY("portable_storage::insert_new_entry_get_storage_entry", nullptr);
|
||||
|
||||
@@ -42,24 +42,6 @@ namespace epee
|
||||
{
|
||||
namespace serialization
|
||||
{
|
||||
template<typename T>
|
||||
struct ps_min_bytes {
|
||||
static constexpr const size_t strict = 4096; // actual low bound
|
||||
};
|
||||
template<> struct ps_min_bytes<uint64_t> { static constexpr const size_t strict = 8; };
|
||||
template<> struct ps_min_bytes<int64_t> { static constexpr const size_t strict = 8; };
|
||||
template<> struct ps_min_bytes<uint32_t> { static constexpr const size_t strict = 4; };
|
||||
template<> struct ps_min_bytes<int32_t> { static constexpr const size_t strict = 4; };
|
||||
template<> struct ps_min_bytes<uint16_t> { static constexpr const size_t strict = 2; };
|
||||
template<> struct ps_min_bytes<int16_t> { static constexpr const size_t strict = 2; };
|
||||
template<> struct ps_min_bytes<uint8_t> { static constexpr const size_t strict = 1; };
|
||||
template<> struct ps_min_bytes<int8_t> { static constexpr const size_t strict = 1; };
|
||||
template<> struct ps_min_bytes<double> { static constexpr const size_t strict = 8; };
|
||||
template<> struct ps_min_bytes<bool> { static constexpr const size_t strict = 1; };
|
||||
template<> struct ps_min_bytes<std::string> { static constexpr const size_t strict = 2; };
|
||||
template<> struct ps_min_bytes<section> { static constexpr const size_t strict = 1; };
|
||||
template<> struct ps_min_bytes<array_entry> { static constexpr const size_t strict = 1; };
|
||||
|
||||
struct throwable_buffer_reader
|
||||
{
|
||||
throwable_buffer_reader(const void* ptr, size_t sz);
|
||||
@@ -79,9 +61,6 @@ namespace epee
|
||||
void read(section& sec);
|
||||
void read(std::string& str);
|
||||
void read(array_entry &ae);
|
||||
template<class t_type>
|
||||
size_t min_bytes() const;
|
||||
void set_limits(size_t objects, size_t fields, size_t strings);
|
||||
private:
|
||||
struct recursuion_limitation_guard
|
||||
{
|
||||
@@ -102,13 +81,6 @@ namespace epee
|
||||
const uint8_t* m_ptr;
|
||||
size_t m_count;
|
||||
size_t m_recursion_count;
|
||||
size_t m_objects;
|
||||
size_t m_fields;
|
||||
size_t m_strings;
|
||||
|
||||
size_t max_objects;
|
||||
size_t max_fields;
|
||||
size_t max_strings;
|
||||
};
|
||||
|
||||
inline throwable_buffer_reader::throwable_buffer_reader(const void* ptr, size_t sz)
|
||||
@@ -120,12 +92,6 @@ namespace epee
|
||||
m_ptr = (uint8_t*)ptr;
|
||||
m_count = sz;
|
||||
m_recursion_count = 0;
|
||||
m_objects = 0;
|
||||
m_fields = 0;
|
||||
m_strings = 0;
|
||||
max_objects = std::numeric_limits<size_t>::max();
|
||||
max_fields = std::numeric_limits<size_t>::max();
|
||||
max_strings = std::numeric_limits<size_t>::max();
|
||||
}
|
||||
inline
|
||||
void throwable_buffer_reader::read(void* target, size_t count)
|
||||
@@ -142,7 +108,6 @@ namespace epee
|
||||
RECURSION_LIMITATION();
|
||||
uint8_t name_len = 0;
|
||||
read(name_len);
|
||||
CHECK_AND_ASSERT_THROW_MES(name_len > 0, "Section name is missing");
|
||||
sce_name.resize(name_len);
|
||||
read((void*)sce_name.data(), name_len);
|
||||
}
|
||||
@@ -173,18 +138,7 @@ namespace epee
|
||||
//for pod types
|
||||
array_entry_t<type_name> sa;
|
||||
size_t size = read_varint();
|
||||
CHECK_AND_ASSERT_THROW_MES(size <= m_count / ps_min_bytes<type_name>::strict, "Size sanity check failed");
|
||||
if (std::is_same<type_name, section>())
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(size <= max_objects - m_objects, "Too many objects");
|
||||
m_objects += size;
|
||||
}
|
||||
else if (std::is_same<type_name, std::string>())
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(size <= max_strings - m_strings, "Too many strings");
|
||||
m_strings += size;
|
||||
}
|
||||
|
||||
CHECK_AND_ASSERT_THROW_MES(size <= m_count, "Size sanity check failed");
|
||||
sa.reserve(size);
|
||||
//TODO: add some optimization here later
|
||||
while(size--)
|
||||
@@ -250,8 +204,6 @@ namespace epee
|
||||
inline storage_entry throwable_buffer_reader::read_se<std::string>()
|
||||
{
|
||||
RECURSION_LIMITATION();
|
||||
CHECK_AND_ASSERT_THROW_MES(m_strings + 1 <= max_strings, "Too many strings");
|
||||
m_strings += 1;
|
||||
return storage_entry(read<std::string>());
|
||||
}
|
||||
|
||||
@@ -260,8 +212,6 @@ namespace epee
|
||||
inline storage_entry throwable_buffer_reader::read_se<section>()
|
||||
{
|
||||
RECURSION_LIMITATION();
|
||||
CHECK_AND_ASSERT_THROW_MES(m_objects < max_objects, "Too many objects");
|
||||
++m_objects;
|
||||
section s;//use extra variable due to vs bug, line "storage_entry se(section()); " can't be compiled in visual studio
|
||||
storage_entry se(std::move(s));
|
||||
section& section_entry = boost::get<section>(se);
|
||||
@@ -313,16 +263,12 @@ namespace epee
|
||||
RECURSION_LIMITATION();
|
||||
sec.m_entries.clear();
|
||||
size_t count = read_varint();
|
||||
CHECK_AND_ASSERT_THROW_MES(count <= max_fields - m_fields, "Too many object fields");
|
||||
m_fields += count;
|
||||
while(count--)
|
||||
{
|
||||
//read section name string
|
||||
std::string sec_name;
|
||||
read_sec_name(sec_name);
|
||||
const auto insert_loc = sec.m_entries.lower_bound(sec_name);
|
||||
CHECK_AND_ASSERT_THROW_MES(insert_loc == sec.m_entries.end() || insert_loc->first != sec_name, "duplicate key: " << sec_name);
|
||||
sec.m_entries.emplace_hint(insert_loc, std::move(sec_name), load_storage_entry());
|
||||
sec.m_entries.emplace(std::move(sec_name), load_storage_entry());
|
||||
}
|
||||
}
|
||||
inline
|
||||
@@ -343,12 +289,5 @@ namespace epee
|
||||
RECURSION_LIMITATION();
|
||||
CHECK_AND_ASSERT_THROW_MES(false, "Reading array entry is not supported");
|
||||
}
|
||||
inline
|
||||
void throwable_buffer_reader::set_limits(size_t objects, size_t fields, size_t strings)
|
||||
{
|
||||
max_objects = objects;
|
||||
max_fields = fields;
|
||||
max_strings = strings;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "byte_slice.h"
|
||||
#include "parserse_base_utils.h"
|
||||
#include "portable_storage.h"
|
||||
#include "file_io_utils.h"
|
||||
@@ -84,10 +85,10 @@ namespace epee
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
template<class t_struct>
|
||||
bool load_t_from_binary(t_struct& out, const epee::span<const uint8_t> binary_buff, const epee::serialization::portable_storage::limits_t *limits = NULL)
|
||||
bool load_t_from_binary(t_struct& out, const epee::span<const uint8_t> binary_buff)
|
||||
{
|
||||
portable_storage ps;
|
||||
bool rs = ps.load_from_binary(binary_buff, limits);
|
||||
bool rs = ps.load_from_binary(binary_buff);
|
||||
if(!rs)
|
||||
return false;
|
||||
|
||||
@@ -111,18 +112,18 @@ namespace epee
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
template<class t_struct>
|
||||
bool store_t_to_binary(t_struct& str_in, std::string& binary_buff, size_t indent = 0)
|
||||
bool store_t_to_binary(t_struct& str_in, byte_slice& binary_buff, size_t initial_buffer_size = 8192)
|
||||
{
|
||||
portable_storage ps;
|
||||
str_in.store(ps);
|
||||
return ps.store_to_binary(binary_buff);
|
||||
return ps.store_to_binary(binary_buff, initial_buffer_size);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
template<class t_struct>
|
||||
std::string store_t_to_binary(t_struct& str_in, size_t indent = 0)
|
||||
byte_slice store_t_to_binary(t_struct& str_in, size_t initial_buffer_size = 8192)
|
||||
{
|
||||
std::string binary_buff;
|
||||
store_t_to_binary(str_in, binary_buff, indent);
|
||||
byte_slice binary_buff;
|
||||
store_t_to_binary(str_in, binary_buff, initial_buffer_size);
|
||||
return binary_buff;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,7 +211,6 @@ namespace epee
|
||||
for(const section_pair& se: sec.m_entries)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(se.first.size() < std::numeric_limits<uint8_t>::max(), "storage_entry_name is too long: " << se.first.size() << ", val: " << se.first);
|
||||
CHECK_AND_ASSERT_THROW_MES(!se.first.empty(), "storage_entry_name is empty");
|
||||
uint8_t len = static_cast<uint8_t>(se.first.size());
|
||||
strm.write((const char*)&len, sizeof(len));
|
||||
strm.write(se.first.data(), size_t(len));
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
add_library(epee byte_slice.cpp byte_stream.cpp hex.cpp abstract_http_client.cpp http_auth.cpp mlog.cpp net_helper.cpp net_utils_base.cpp string_tools.cpp
|
||||
add_library(epee STATIC byte_slice.cpp byte_stream.cpp hex.cpp abstract_http_client.cpp http_auth.cpp mlog.cpp net_helper.cpp net_utils_base.cpp string_tools.cpp
|
||||
wipeable_string.cpp levin_base.cpp memwipe.c connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp net_ssl.cpp
|
||||
int-util.cpp)
|
||||
int-util.cpp portable_storage.cpp)
|
||||
|
||||
if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
|
||||
add_library(epee_readline STATIC readline_buffer.cpp)
|
||||
@@ -60,23 +60,14 @@ target_link_libraries(epee
|
||||
${Boost_CHRONO_LIBRARY}
|
||||
${Boost_FILESYSTEM_LIBRARY}
|
||||
${Boost_THREAD_LIBRARY}
|
||||
${Boost_REGEX_LIBRARY}
|
||||
${Boost_SYSTEM_LIBRARY}
|
||||
${OPENSSL_LIBRARIES}
|
||||
PRIVATE
|
||||
${OPENSSL_LIBRARIES}
|
||||
${EXTRA_LIBRARIES})
|
||||
|
||||
if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
|
||||
target_link_libraries(epee_readline
|
||||
PUBLIC
|
||||
easylogging
|
||||
${Boost_SYSTEM_LIBRARY}
|
||||
PRIVATE
|
||||
${GNU_READLINE_LIBRARY})
|
||||
endif()
|
||||
|
||||
target_include_directories(epee
|
||||
PUBLIC
|
||||
"${EPEE_INCLUDE_DIR_BASE}"
|
||||
"${OPENSSL_INCLUDE_DIR}")
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <limits>
|
||||
#include <string.h>
|
||||
#include "net/buffer.h"
|
||||
|
||||
|
||||
@@ -34,6 +34,11 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr const std::size_t minimum_increase = 4096;
|
||||
}
|
||||
|
||||
namespace epee
|
||||
{
|
||||
void byte_stream::overflow(const std::size_t requested)
|
||||
@@ -46,7 +51,7 @@ namespace epee
|
||||
|
||||
const std::size_t len = size();
|
||||
const std::size_t cap = capacity();
|
||||
const std::size_t increase = std::max(need, increase_size());
|
||||
const std::size_t increase = std::max(std::max(need, cap), minimum_increase);
|
||||
|
||||
next_write_ = nullptr;
|
||||
end_ = nullptr;
|
||||
@@ -62,8 +67,7 @@ namespace epee
|
||||
byte_stream::byte_stream(byte_stream&& rhs) noexcept
|
||||
: buffer_(std::move(rhs.buffer_)),
|
||||
next_write_(rhs.next_write_),
|
||||
end_(rhs.end_),
|
||||
increase_size_(rhs.increase_size_)
|
||||
end_(rhs.end_)
|
||||
{
|
||||
rhs.next_write_ = nullptr;
|
||||
rhs.end_ = nullptr;
|
||||
@@ -76,7 +80,6 @@ namespace epee
|
||||
buffer_ = std::move(rhs.buffer_);
|
||||
next_write_ = rhs.next_write_;
|
||||
end_ = rhs.end_;
|
||||
increase_size_ = rhs.increase_size_;
|
||||
rhs.next_write_ = nullptr;
|
||||
rhs.end_ = nullptr;
|
||||
}
|
||||
|
||||
@@ -473,7 +473,6 @@ bool ssl_options_t::has_fingerprint(boost::asio::ssl::verify_context &ctx) const
|
||||
bool ssl_options_t::handshake(
|
||||
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> &socket,
|
||||
boost::asio::ssl::stream_base::handshake_type type,
|
||||
boost::asio::const_buffer buffer,
|
||||
const std::string& host,
|
||||
std::chrono::milliseconds timeout) const
|
||||
{
|
||||
@@ -531,7 +530,7 @@ bool ssl_options_t::handshake(
|
||||
});
|
||||
|
||||
boost::system::error_code ec = boost::asio::error::would_block;
|
||||
socket.async_handshake(type, boost::asio::buffer(buffer), boost::lambda::var(ec) = boost::lambda::_1);
|
||||
socket.async_handshake(type, boost::lambda::var(ec) = boost::lambda::_1);
|
||||
if (io_service.stopped())
|
||||
{
|
||||
io_service.reset();
|
||||
|
||||
29
contrib/epee/src/portable_storage.cpp
Normal file
29
contrib/epee/src/portable_storage.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
#include "byte_slice.h"
|
||||
#include "byte_stream.h"
|
||||
#include "misc_log_ex.h"
|
||||
#include "span.h"
|
||||
#include "storages/portable_storage.h"
|
||||
#include "storages/portable_storage_to_bin.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace serialization
|
||||
{
|
||||
bool portable_storage::store_to_binary(byte_slice& target, const std::size_t initial_buffer_size)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
byte_stream ss;
|
||||
ss.reserve(initial_buffer_size);
|
||||
storage_block_header sbh{};
|
||||
sbh.m_signature_a = SWAP32LE(PORTABLE_STORAGE_SIGNATUREA);
|
||||
sbh.m_signature_b = SWAP32LE(PORTABLE_STORAGE_SIGNATUREB);
|
||||
sbh.m_ver = PORTABLE_STORAGE_FORMAT_VER;
|
||||
ss.write(epee::as_byte_span(sbh));
|
||||
pack_entry_to_buff(ss, m_root);
|
||||
target = epee::byte_slice{std::move(ss)};
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::store_to_binary", false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,6 @@
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <boost/optional/optional.hpp>
|
||||
#include <limits>
|
||||
#include <string.h>
|
||||
#include "memwipe.h"
|
||||
#include "misc_log_ex.h"
|
||||
|
||||
@@ -126,7 +126,7 @@ Setup for LXC:
|
||||
|
||||
```bash
|
||||
GH_USER=fluffypony
|
||||
VERSION=v0.17.2.0
|
||||
VERSION=v0.17.0.0
|
||||
|
||||
./gitian-build.py --setup $GH_USER $VERSION
|
||||
```
|
||||
@@ -182,7 +182,7 @@ If you chose to do detached signing using `--detach-sign` above (recommended), y
|
||||
|
||||
```bash
|
||||
GH_USER=fluffypony
|
||||
VERSION=v0.17.2.0
|
||||
VERSION=v0.17.0.0
|
||||
|
||||
gpg --detach-sign ${VERSION}-linux/${GH_USER}/monero-linux-*-build.assert
|
||||
gpg --detach-sign ${VERSION}-win/${GH_USER}/monero-win-*-build.assert
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: "wownero-android-0.10"
|
||||
name: "wownero-android-0.9"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
|
||||
@@ -94,6 +94,10 @@ def build():
|
||||
os.chdir('builder')
|
||||
os.makedirs('inputs', exist_ok=True)
|
||||
|
||||
subprocess.check_call(['wget', '-N', '-P', 'inputs', 'https://downloads.sourceforge.net/project/osslsigncode/osslsigncode/osslsigncode-1.7.1.tar.gz'])
|
||||
subprocess.check_call(['wget', '-N', '-P', 'inputs', 'https://bitcoincore.org/cfields/osslsigncode-Backports-to-1.7.1.patch'])
|
||||
subprocess.check_output(["echo 'a8c4e9cafba922f89de0df1f2152e7be286aba73f78505169bc351a7938dd911 inputs/osslsigncode-Backports-to-1.7.1.patch' | sha256sum -c"], shell=True)
|
||||
subprocess.check_output(["echo 'f9a8cdb38b9c309326764ebc937cba1523a3a751a7ab05df3ecc99d18ae466c9 inputs/osslsigncode-1.7.1.tar.gz' | sha256sum -c"], shell=True)
|
||||
subprocess.check_call(['make', '-C', 'inputs/wownero/contrib/depends', 'download', 'SOURCES_PATH=' + os.getcwd() + '/cache/common'])
|
||||
|
||||
rebuild()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: "wownero-freebsd-0.10"
|
||||
name: "wownero-freebsd-0.9"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: "wownero-linux-0.10"
|
||||
name: "wownero-linux-0.9"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: "wownero-osx-0.10"
|
||||
name: "wownero-osx-0.9"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: "wownero-win-0.10"
|
||||
name: "wownero-win-0.9"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
@@ -23,6 +23,12 @@ packages:
|
||||
- "rename"
|
||||
- "cmake"
|
||||
alternatives:
|
||||
-
|
||||
package: "i686-w64-mingw32-g++"
|
||||
path: "/usr/bin/i686-w64-mingw32-g++-posix"
|
||||
-
|
||||
package: "i686-w64-mingw32-gcc"
|
||||
path: "/usr/bin/i686-w64-mingw32-gcc-posix"
|
||||
-
|
||||
package: "x86_64-w64-mingw32-g++"
|
||||
path: "/usr/bin/x86_64-w64-mingw32-g++-posix"
|
||||
|
||||
BIN
contrib/snap/setup/gui/icon.png
Normal file
BIN
contrib/snap/setup/gui/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
76
contrib/snap/snapcraft.yaml
Normal file
76
contrib/snap/snapcraft.yaml
Normal file
@@ -0,0 +1,76 @@
|
||||
name: wownero
|
||||
version: 0.5.0.0
|
||||
summary: "Wownero: the secure, private, untraceable cryptocurrency http://wownero.org"
|
||||
description: |
|
||||
Wownero: a fairly launched privacy-centric meme coin with no premine and a finite supply.
|
||||
grade: devel
|
||||
confinement: strict
|
||||
|
||||
apps:
|
||||
wownerod:
|
||||
daemon: forking
|
||||
command: |
|
||||
wownerod-wrapper --detach --data-dir ${SNAP_COMMON} --config-file ${SNAP_USER_DATA}/etc/wownerod.conf
|
||||
plugs:
|
||||
- network
|
||||
- network-bind
|
||||
wownero-wallet-rpc:
|
||||
command: |
|
||||
wownero-wallet-rpc --log-file ${SNAP_USER_DATA}
|
||||
plugs:
|
||||
- home
|
||||
- network
|
||||
- network-bind
|
||||
wownero-wallet-cli:
|
||||
command: |
|
||||
wownero-wallet-cli --log-file ${SNAP_USER_DATA}
|
||||
plugs:
|
||||
- home
|
||||
- network
|
||||
|
||||
parts:
|
||||
cmake-build:
|
||||
plugin: cmake
|
||||
configflags:
|
||||
- -DBDB_STATIC=1
|
||||
- -DBoost_USE_STATIC_LIBS=1
|
||||
- -DBoost_USE_STATIC_RUNTIME=1
|
||||
- -DARCH=default
|
||||
source: .
|
||||
build-packages:
|
||||
- gcc
|
||||
- pkg-config
|
||||
- libunbound-dev
|
||||
- libevent-dev
|
||||
- libboost-all-dev
|
||||
- libzmqpp-dev
|
||||
- libzmq3-dev
|
||||
- libsodium-dev
|
||||
- libdb-dev
|
||||
- libunwind-dev
|
||||
- libminiupnpc-dev
|
||||
- libldns-dev
|
||||
- libexpat1-dev
|
||||
- libreadline6-dev
|
||||
- bison
|
||||
- doxygen
|
||||
- graphviz
|
||||
stage-packages:
|
||||
- libminiupnpc10
|
||||
- libunbound2
|
||||
- libunwind8
|
||||
prime:
|
||||
- bin
|
||||
- usr/lib/
|
||||
- -usr/lib/gcc
|
||||
- -usr/share
|
||||
|
||||
dist-files:
|
||||
plugin: dump
|
||||
source: .
|
||||
organize:
|
||||
contrib/snap/wownerod.conf: etc/wownerod.conf
|
||||
contrib/snap/wownerod-wrapper: bin/wownerod-wrapper
|
||||
prime:
|
||||
- etc
|
||||
- bin
|
||||
8
contrib/snap/wownerod-wrapper
Executable file
8
contrib/snap/wownerod-wrapper
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ ! -d "$SNAP_USER_DATA/etc" ]; then
|
||||
mkdir $SNAP_USER_DATA/etc/
|
||||
cp -R $SNAP/etc/wownerod.conf $SNAP_USER_DATA/etc/wownerod.conf
|
||||
fi
|
||||
|
||||
exec "$SNAP/bin/wownerod" "$@"
|
||||
10
contrib/snap/wownerod.conf
Normal file
10
contrib/snap/wownerod.conf
Normal file
@@ -0,0 +1,10 @@
|
||||
# Configuration for monerod
|
||||
# Syntax: any command line option may be specified as 'clioptionname=value'.
|
||||
# Boolean options such as 'no-igd' are specified as 'no-igd=1'.
|
||||
# See 'monerod --help' for all available options.
|
||||
|
||||
# Overridden by snap:
|
||||
# data-dir=/var/lib/wownero
|
||||
# log-file=/var/log/wownero/wownero.log
|
||||
|
||||
log-level=0
|
||||
@@ -1,101 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
DIR=$(realpath $(dirname $0))
|
||||
|
||||
echo "Checking wownerod..."
|
||||
monerod=""
|
||||
for dir in \
|
||||
. \
|
||||
"$DIR" \
|
||||
"$DIR/../.." \
|
||||
"$DIR/build/release/bin" \
|
||||
"$DIR/../../build/release/bin" \
|
||||
"$DIR/build/Linux/master/release/bin" \
|
||||
"$DIR/../../build/Linux/master/release/bin" \
|
||||
"$DIR/build/Windows/master/release/bin" \
|
||||
"$DIR/../../build/Windows/master/release/bin"
|
||||
do
|
||||
if test -x "$dir/wownerod"
|
||||
then
|
||||
monerod="$dir/wownerod"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$wownerod"
|
||||
then
|
||||
echo "wownerod not found"
|
||||
exit 1
|
||||
fi
|
||||
echo "Found: $wownerod"
|
||||
|
||||
TORDIR="$DIR/wownero-over-tor"
|
||||
TORRC="$TORDIR/torrc"
|
||||
HOSTNAMEFILE="$TORDIR/hostname"
|
||||
echo "Creating configuration..."
|
||||
mkdir -p "$TORDIR"
|
||||
chmod 700 "$TORDIR"
|
||||
rm -f "$TORRC"
|
||||
cat << EOF > "$TORRC"
|
||||
ControlSocket $TORDIR/control
|
||||
ControlSocketsGroupWritable 1
|
||||
CookieAuthentication 1
|
||||
CookieAuthFile $TORDIR/control.authcookie
|
||||
CookieAuthFileGroupReadable 1
|
||||
HiddenServiceDir $TORDIR
|
||||
HiddenServicePort 34568 127.0.0.1:34568
|
||||
HiddenServicePort 34566 127.0.0.1:34566
|
||||
HiddenServiceVersion 3
|
||||
EOF
|
||||
|
||||
echo "Starting Tor..."
|
||||
nohup tor -f "$TORRC" 2> "$TORDIR/tor.stderr" 1> "$TORDIR/tor.stdout" &
|
||||
ready=0
|
||||
for i in `seq 10`
|
||||
do
|
||||
sleep 1
|
||||
if test -f "$HOSTNAMEFILE"
|
||||
then
|
||||
ready=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test "$ready" = 0
|
||||
then
|
||||
echo "Error starting Tor"
|
||||
cat "$TORDIR/tor.stdout"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Starting wownerod..."
|
||||
HOSTNAME=$(cat "$HOSTNAMEFILE")
|
||||
"$monerod" \
|
||||
--anonymous-inbound "$HOSTNAME":34566,127.0.0.1:34566,25 --tx-proxy tor,127.0.0.1:9050,10 \
|
||||
--add-priority-node v2admi6gbeprxnk6i2oscizhgy4v5ixu6iezkhj5udiwbfjjs2w7dnid.onion:34568 \
|
||||
--add-priority-node iy6ry6uudpzvbd72zsipepukp6nsazjdu72n52vg3isfnxqn342flzad.onion:34568 \
|
||||
--add-priority-node 7ftpbpp6rbgqi5kjmhyin46essnh3eqb3m3rhfi7r2fr33iwkeuer3yd.onion:34568 \
|
||||
--add-priority-node j7rf2jcccizcp47y5moehguyuqdpg4lusk642sw4nayuruitqaqbc7ad.onion:34568 \
|
||||
--add-priority-node aje53o5z5twne5q2ljw44zkahhsuhjtwaxuburxddbf7n4pfsj4rj6qd.onion:34568 \
|
||||
--add-priority-node nepc4lxndsooj2akn7ofrj3ooqc25242obchcag6tw3f2mxrms2uuvyd.onion:34568 \
|
||||
--add-priority-node 666l2ajxqjgj5lskvbokvworjysgvqag4oitokjuy7wz6juisul4jqad.onion:34568 \
|
||||
--add-priority-node ty7ppqozzodz75audgvkprekiiqsovbyrkfdjwadrkbe3etyzloatxad.onion:34568 \
|
||||
--detach
|
||||
ready=0
|
||||
for i in `seq 10`
|
||||
do
|
||||
sleep 1
|
||||
status=$("$wownerod" status)
|
||||
echo "$status" | grep -q "Height:"
|
||||
if test $? = 0
|
||||
then
|
||||
ready=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test "$ready" = 0
|
||||
then
|
||||
echo "Error starting wownerod"
|
||||
tail -n 400 "$HOME/.wownero/wownero.log" | grep -Ev stacktrace\|"Error: Couldn't connect to daemon:"\|"src/daemon/main.cpp:.*Wownero\ \'" | tail -n 20
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Ready. Your Tor hidden service is $HOSTNAME"
|
||||
2
external/RandomWOW
vendored
2
external/RandomWOW
vendored
Submodule external/RandomWOW updated: 62c6ea1176...89b7c02bba
10
external/db_drivers/liblmdb/mdb.c
vendored
10
external/db_drivers/liblmdb/mdb.c
vendored
@@ -3461,9 +3461,9 @@ mdb_freelist_save(MDB_txn *txn)
|
||||
} else {
|
||||
x = mdb_mid2l_search(dl, mp->mp_pgno);
|
||||
mdb_tassert(txn, dl[x].mid == mp->mp_pgno);
|
||||
mdb_dpage_free(env, mp);
|
||||
}
|
||||
dl[x].mptr = NULL;
|
||||
mdb_dpage_free(env, mp);
|
||||
}
|
||||
{
|
||||
/* squash freed slots out of the dirty list */
|
||||
@@ -4882,6 +4882,9 @@ mdb_env_open2(MDB_env *env, int prev)
|
||||
#endif
|
||||
env->me_maxpg = env->me_mapsize / env->me_psize;
|
||||
|
||||
if (env->me_txns)
|
||||
env->me_txns->mti_txnid = meta.mm_txnid;
|
||||
|
||||
#if MDB_DEBUG
|
||||
{
|
||||
MDB_meta *meta = mdb_env_pick_meta(env);
|
||||
@@ -4981,9 +4984,6 @@ static int ESECT
|
||||
mdb_env_share_locks(MDB_env *env, int *excl)
|
||||
{
|
||||
int rc = 0;
|
||||
MDB_meta *meta = mdb_env_pick_meta(env);
|
||||
|
||||
env->me_txns->mti_txnid = meta->mm_txnid;
|
||||
|
||||
#ifdef _WIN32
|
||||
{
|
||||
@@ -7867,7 +7867,7 @@ put_sub:
|
||||
xdata.mv_size = 0;
|
||||
xdata.mv_data = "";
|
||||
leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
|
||||
if ((flags & (MDB_CURRENT|MDB_APPENDDUP)) == MDB_CURRENT) {
|
||||
if (flags == MDB_CURRENT) {
|
||||
xflags = MDB_CURRENT|MDB_NOSPILL;
|
||||
} else {
|
||||
mdb_xcursor_init1(mc, leaf);
|
||||
|
||||
2
external/rapidjson
vendored
2
external/rapidjson
vendored
Submodule external/rapidjson updated: 129d19ba7f...3729501db9
@@ -75,6 +75,8 @@ function (monero_add_executable name)
|
||||
PROPERTY
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
||||
enable_stack_trace("${name}")
|
||||
|
||||
monero_set_target_no_relink("${name}")
|
||||
endfunction ()
|
||||
|
||||
function (monero_add_library name)
|
||||
@@ -92,6 +94,7 @@ function (monero_add_library_with_deps)
|
||||
set(objlib obj_${MONERO_ADD_LIBRARY_NAME})
|
||||
add_library(${objlib} OBJECT ${MONERO_ADD_LIBRARY_SOURCES})
|
||||
add_library("${MONERO_ADD_LIBRARY_NAME}" $<TARGET_OBJECTS:${objlib}>)
|
||||
monero_set_target_no_relink("${MONERO_ADD_LIBRARY_NAME}")
|
||||
if (MONERO_ADD_LIBRARY_DEPENDS)
|
||||
add_dependencies(${objlib} ${MONERO_ADD_LIBRARY_DEPENDS})
|
||||
endif()
|
||||
|
||||
@@ -248,15 +248,8 @@ void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const std::pair
|
||||
}
|
||||
else
|
||||
{
|
||||
rct::key commitment;
|
||||
if (tx.version > 1)
|
||||
{
|
||||
commitment = tx.rct_signatures.outPk[i].mask;
|
||||
if (rct::is_rct_bulletproof_plus(tx.rct_signatures.type))
|
||||
commitment = rct::scalarmult8(commitment);
|
||||
}
|
||||
amount_output_indices[i] = add_output(tx_hash, tx.vout[i], i, tx.unlock_time,
|
||||
tx.version > 1 ? &commitment : NULL);
|
||||
tx.version > 1 ? &tx.rct_signatures.outPk[i].mask : NULL);
|
||||
}
|
||||
}
|
||||
add_tx_amount_output_indices(tx_id, amount_output_indices);
|
||||
|
||||
@@ -1312,20 +1312,17 @@ public:
|
||||
* height. The number of blocks returned is variable, based on the max_size passed.
|
||||
*
|
||||
* @param start_height the height of the first block
|
||||
* @param min_block_count the minimum number of blocks to return, if they exist
|
||||
* @param max_block_count the maximum number of blocks to return
|
||||
* @param max_tx_count the maximum number of txes to return
|
||||
* @param min_count the minimum number of blocks to return, if they exist
|
||||
* @param max_count the maximum number of blocks to return
|
||||
* @param max_size the maximum size of block/transaction data to return (will be exceeded by one blocks's worth at most, if min_count is met)
|
||||
* @param blocks the returned block/transaction data
|
||||
* @param pruned whether to return full or pruned tx data
|
||||
* @param skip_coinbase whether to return or skip coinbase transactions (they're in blocks regardless)
|
||||
* @param get_miner_tx_hash whether to calculate and return the miner (coinbase) tx hash
|
||||
*
|
||||
* The call will return at least min_block_count if possible, even if this contravenes max_tx_count
|
||||
*
|
||||
* @return true iff the blocks and transactions were found
|
||||
*/
|
||||
virtual bool get_blocks_from(uint64_t start_height, size_t min_block_count, size_t max_block_count, size_t max_tx_count, size_t max_size, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata>>>>& blocks, bool pruned, bool skip_coinbase, bool get_miner_tx_hash) const = 0;
|
||||
virtual bool get_blocks_from(uint64_t start_height, size_t min_count, size_t max_count, size_t max_size, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata>>>>& blocks, bool pruned, bool skip_coinbase, bool get_miner_tx_hash) const = 0;
|
||||
|
||||
/**
|
||||
* @brief fetches the prunable transaction blob with the given hash
|
||||
|
||||
@@ -3171,7 +3171,7 @@ bool BlockchainLMDB::get_pruned_tx_blobs_from(const crypto::hash& h, size_t coun
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BlockchainLMDB::get_blocks_from(uint64_t start_height, size_t min_block_count, size_t max_block_count, size_t max_tx_count, size_t max_size, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata>>>>& blocks, bool pruned, bool skip_coinbase, bool get_miner_tx_hash) const
|
||||
bool BlockchainLMDB::get_blocks_from(uint64_t start_height, size_t min_count, size_t max_count, size_t max_size, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata>>>>& blocks, bool pruned, bool skip_coinbase, bool get_miner_tx_hash) const
|
||||
{
|
||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||
check_open();
|
||||
@@ -3185,15 +3185,14 @@ bool BlockchainLMDB::get_blocks_from(uint64_t start_height, size_t min_block_cou
|
||||
RCURSOR(txs_prunable);
|
||||
}
|
||||
|
||||
blocks.reserve(std::min<size_t>(max_block_count, 10000)); // guard against very large max count if only checking bytes
|
||||
blocks.reserve(std::min<size_t>(max_count, 10000)); // guard against very large max count if only checking bytes
|
||||
const uint64_t blockchain_height = height();
|
||||
uint64_t size = 0;
|
||||
size_t num_txes = 0;
|
||||
MDB_val_copy<uint64_t> key(start_height);
|
||||
MDB_val k, v, val_tx_id;
|
||||
uint64_t tx_id = ~0;
|
||||
MDB_cursor_op op = MDB_SET;
|
||||
for (uint64_t h = start_height; h < blockchain_height && blocks.size() < max_block_count && (size < max_size || blocks.size() < min_block_count); ++h)
|
||||
for (uint64_t h = start_height; h < blockchain_height && blocks.size() < max_count && (size < max_size || blocks.size() < min_count); ++h)
|
||||
{
|
||||
MDB_cursor_op op = h == start_height ? MDB_SET : MDB_NEXT;
|
||||
int result = mdb_cursor_get(m_cur_blocks, &key, &v, op);
|
||||
@@ -3244,7 +3243,6 @@ bool BlockchainLMDB::get_blocks_from(uint64_t start_height, size_t min_block_cou
|
||||
op = MDB_NEXT;
|
||||
|
||||
current_block.second.reserve(b.tx_hashes.size());
|
||||
num_txes += b.tx_hashes.size() + (skip_coinbase ? 0 : 1);
|
||||
for (const auto &tx_hash: b.tx_hashes)
|
||||
{
|
||||
// get pruned data
|
||||
@@ -3264,9 +3262,6 @@ bool BlockchainLMDB::get_blocks_from(uint64_t start_height, size_t min_block_cou
|
||||
current_block.second.push_back(std::make_pair(tx_hash, std::move(tx_blob)));
|
||||
size += current_block.second.back().second.size();
|
||||
}
|
||||
|
||||
if (blocks.size() >= min_block_count && num_txes >= max_tx_count)
|
||||
break;
|
||||
}
|
||||
|
||||
TXN_POSTFIX_RDONLY();
|
||||
|
||||
@@ -257,7 +257,7 @@ public:
|
||||
virtual bool get_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const;
|
||||
virtual bool get_pruned_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const;
|
||||
virtual bool get_pruned_tx_blobs_from(const crypto::hash& h, size_t count, std::vector<cryptonote::blobdata> &bd) const;
|
||||
virtual bool get_blocks_from(uint64_t start_height, size_t min_block_count, size_t max_block_count, size_t max_tx_count, size_t max_size, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata>>>>& blocks, bool pruned, bool skip_coinbase, bool get_miner_tx_hash) const;
|
||||
virtual bool get_blocks_from(uint64_t start_height, size_t min_count, size_t max_count, size_t max_size, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata>>>>& blocks, bool pruned, bool skip_coinbase, bool get_miner_tx_hash) const;
|
||||
virtual bool get_prunable_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const;
|
||||
virtual bool get_prunable_tx_hash(const crypto::hash& tx_hash, crypto::hash &prunable_hash) const;
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ public:
|
||||
virtual bool get_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const override { return false; }
|
||||
virtual bool get_pruned_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const override { return false; }
|
||||
virtual bool get_pruned_tx_blobs_from(const crypto::hash& h, size_t count, std::vector<cryptonote::blobdata> &bd) const override { return false; }
|
||||
virtual bool get_blocks_from(uint64_t start_height, size_t min_block_count, size_t max_block_count, size_t max_tx_count, size_t max_size, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata>>>>& blocks, bool pruned, bool skip_coinbase, bool get_miner_tx_hash) const override { return false; }
|
||||
virtual bool get_blocks_from(uint64_t start_height, size_t min_count, size_t max_count, size_t max_size, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata>>>>& blocks, bool pruned, bool skip_coinbase, bool get_miner_tx_hash) const override { return false; }
|
||||
virtual bool get_prunable_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const override { return false; }
|
||||
virtual bool get_prunable_tx_hash(const crypto::hash& tx_hash, crypto::hash &prunable_hash) const override { return false; }
|
||||
virtual uint64_t get_block_height(const crypto::hash& h) const override { return 0; }
|
||||
|
||||
@@ -28,33 +28,21 @@
|
||||
|
||||
set(GENERATED_SOURCES "")
|
||||
|
||||
set(GENERATOR "${CMAKE_CURRENT_BINARY_DIR}/blocks_generator.cmake")
|
||||
file(GENERATE OUTPUT ${GENERATOR} CONTENT [=[
|
||||
file(READ "${INPUT_DAT_FILE}" DATA HEX)
|
||||
string(REGEX REPLACE "[0-9a-fA-F][0-9a-fA-F]" "0x\\0," DATA "${DATA}")
|
||||
file(WRITE "${OUTPUT_C_SOURCE}" "
|
||||
#include <stddef.h>
|
||||
const unsigned char ${BLOB_NAME}[]={
|
||||
${DATA}
|
||||
};
|
||||
const size_t ${BLOB_NAME}_len = sizeof(${BLOB_NAME});
|
||||
"
|
||||
)
|
||||
]=])
|
||||
foreach(BLOB_NAME checkpoints)
|
||||
set(OUTPUT_C_SOURCE "generated_${BLOB_NAME}.c")
|
||||
list(APPEND GENERATED_SOURCES ${OUTPUT_C_SOURCE})
|
||||
set(INPUT_DAT_FILE "${BLOB_NAME}.dat")
|
||||
add_custom_command(
|
||||
OUTPUT ${OUTPUT_C_SOURCE}
|
||||
MAIN_DEPENDENCY ${INPUT_DAT_FILE}
|
||||
DEPENDS ${GENERATOR}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
"-DINPUT_DAT_FILE=${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_DAT_FILE}"
|
||||
"-DBLOB_NAME=${BLOB_NAME}"
|
||||
"-DOUTPUT_C_SOURCE=${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_C_SOURCE}"
|
||||
-P "${GENERATOR}"
|
||||
OUTPUT ${OUTPUT_C_SOURCE}
|
||||
MAIN_DEPENDENCY ${INPUT_DAT_FILE}
|
||||
COMMAND
|
||||
cd ${CMAKE_CURRENT_BINARY_DIR} &&
|
||||
echo "'#include\t<stddef.h>'" > ${OUTPUT_C_SOURCE} &&
|
||||
echo "'const\tunsigned\tchar\t${BLOB_NAME}[]={'" >> ${OUTPUT_C_SOURCE} &&
|
||||
od -v -An -tx1 ${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_DAT_FILE} | sed -e "'s/[0-9a-fA-F]\\{1,\\}/0x&,/g'" -e "'$$s/.$$//'" >> ${OUTPUT_C_SOURCE} &&
|
||||
echo "'};'" >> ${OUTPUT_C_SOURCE} &&
|
||||
echo "'const\tsize_t\t${BLOB_NAME}_len\t=\tsizeof(${BLOB_NAME});'" >> ${OUTPUT_C_SOURCE}
|
||||
)
|
||||
endforeach()
|
||||
|
||||
add_library(blocks STATIC blocks.cpp ${GENERATED_SOURCES})
|
||||
monero_add_library(blocks blocks.cpp ${GENERATED_SOURCES})
|
||||
|
||||
Binary file not shown.
@@ -182,6 +182,17 @@ namespace cryptonote
|
||||
{
|
||||
if (nettype == TESTNET)
|
||||
{
|
||||
ADD_CHECKPOINT2(1, "c47b8effcc84e22ddd1b876d059c8fbd3e26e4bdffb6bed8b8f4fe283104a7af", "0x2");
|
||||
ADD_CHECKPOINT2(5, "292add330f6cf5f3845dc4cd2f28ce8d211dd487ddcfe1b5d1d545d7b90ff7d1", "0x5df"); //Hard fork to v8
|
||||
ADD_CHECKPOINT2(10, "fbdf7d812aa6dd4c5915aadcbf023e722eab1d8ad47c24a230634e688d314798", "0xfa3"); //Hard fork to v9
|
||||
ADD_CHECKPOINT2(15, "9b86e40b959d7cfe75366686dfd2657699e85b8c658aa8c20b23f7bc01b38af0", "0x1967"); //Hard fork to v10
|
||||
ADD_CHECKPOINT2(20, "8f65c309ba3ed2bf25df2b7d91e1db40c864230aa3caaf823db81bc19e0bd6a3", "0x232b"); //Hard fork to v11
|
||||
ADD_CHECKPOINT2(25, "35f2957fdba45d5421561ba2f126a61ec0101b5c2eb79b9e296310acbbdbbe58", "0x2cef"); //Hard fork to v12
|
||||
ADD_CHECKPOINT2(30, "32cc5aacce8bea10ae869313e194ba51a30720810f3665433ffeea2818938429", "0x36b3"); //Hard fork to v13
|
||||
ADD_CHECKPOINT2(35, "7f1cdd2c4a6002772343ad9de6c5dba743a0be1d326a6f63924511f08b15863a", "0x4077"); //Hard fork to v14
|
||||
ADD_CHECKPOINT2(40, "63cf4f703489a881baf63bacd6a3af2b5bde79b558ce123e97313890be6f747f", "0x4a3b"); //Hard fork to v15
|
||||
ADD_CHECKPOINT2(45, "65da4c966ae02983c6c8b7ab9b959df612863c379c5e48669061cbbb1e02a3ab", "0x53ff"); //Hard fork to v16
|
||||
ADD_CHECKPOINT2(50, "8c68a444b6743a14152f130357be9751e42e82a84f69f25320eda532a830c7b0", "0x5dc3"); //Hard fork to v17
|
||||
return true;
|
||||
}
|
||||
if (nettype == STAGENET)
|
||||
@@ -189,7 +200,7 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
// make RPC call to daemon
|
||||
// curl http://127.0.0.1:34568/json_rpc -d '{"jsonrpc":"2.0","id":"0","method":"get_block","params":{"height":307880}}' -H 'Content-Type: application/json'
|
||||
// curl http://127.0.0.1:34568/json_rpc -d '{"jsonrpc":"2.0","id":"0","method":"get_block","params":{"height":271600}}' -H 'Content-Type: application/json'
|
||||
// "wide_cumulative_difficulty": "0x14eb4d0131fe8",
|
||||
ADD_CHECKPOINT2(1, "97f4ce4d7879b3bea54dcec738cd2ebb7952b4e9bb9743262310cd5fec749340", "0x2");
|
||||
ADD_CHECKPOINT2(6969, "aa7b66e8c461065139b55c29538a39c33ceda93e587f84d490ed573d80511c87", "0x118eef693fd"); //Hard fork to v8
|
||||
@@ -204,27 +215,6 @@ namespace cryptonote
|
||||
ADD_CHECKPOINT2(254287, "b37cb55abe73965b424f8028bf71bef98d069645077ffa52f0c134907b7734e3", "0x1746622f56668"); //Hard fork to v17
|
||||
ADD_CHECKPOINT2(256700, "389a8ab95a80e84ec74639c1078bc67b33af208ef00f53bd9609cfc40efa7059", "0x185ace3c1bd68");
|
||||
ADD_CHECKPOINT2(271600, "9597cdbdc52ca57d7dbd8f9c0a23a73194ef2ebbcfdc75c21992672706108d43", "0x1e2d2d6a2a9e8");
|
||||
ADD_CHECKPOINT2(278300, "b10dcdf7a51651f60fbcc0447409773eef1458d2c706d9a61daf467571ac19c9", "0x20a83a16d3968");
|
||||
ADD_CHECKPOINT2(282700, "79c06cafd7cb5f76bcebbf8f1ae16203bb41fd75b284bcd0eb0b457991ab7d4a", "0x22e3baf142de8");
|
||||
ADD_CHECKPOINT2(307686, "dfd056b2739c132a07629409a59a028cb7414fac23e3419e79d2f49d66fc3af5", "0x305ba542e3ea8"); // "difficulty": 25800000
|
||||
ADD_CHECKPOINT2(307692, "d822cd72037f62824ec87c9dc11768b45dc2632f697fa372e1885789c90f37fc", "0x305e124633878"); // "difficulty": 1890000
|
||||
ADD_CHECKPOINT2(307735, "60970378aecdc0a78ccf5154edcc56f23aad8554b49e4716f820461a7588bfdc", "0x3070771b9ba58"); // "difficulty": 17900000
|
||||
ADD_CHECKPOINT2(307742, "0ed835bc9fcd949b5a184cf607dcc62ac4268c9e4cf220f8b09bcce58f10916b", "0x30732f1248978"); // "difficulty": 21300000
|
||||
ADD_CHECKPOINT2(307750, "7bcafbc757237125b70f569b181eb1b66c530b10d817d7b940f7a73dc827211c", "0x30766666b3d98"); // "difficulty": 10900000
|
||||
ADD_CHECKPOINT2(307766, "02fd6c7d6bae710cfa3efb08f50e4bc9a590f6ab61eabd87e5e951338c0c36f6", "0x307d2d47a7918"); // "difficulty": 2960000
|
||||
ADD_CHECKPOINT2(307800, "3594894b4231cfdfe911afed6552f9fb4cfe6048bacd0973a3a98623ec8548ce", "0x308b305ca7618");
|
||||
ADD_CHECKPOINT2(307880, "659274b698f680c6cae2716cbd4e15ad5def23b5de98e53734c4af2c2e74bb7a", "0x30af6e91e8018");
|
||||
ADD_CHECKPOINT2(307883, "9a8c35cd10963a14bba8a9628d1776df92fee5e3153b7249f5d15726efafaaea", "0x30b0965ba5a18");
|
||||
ADD_CHECKPOINT2(312130, "e0da085bd273fff9f5f8e604fce0e91908bc62b6b004731a93e16e89cb9b1f54", "0x3cfe7148f2e18");
|
||||
ADD_CHECKPOINT2(324600, "b24cd1ed7c192bbcf3d5b15729f2b032566687f96bda6f8cb73a5b16df4c6e6b", "0x69caecbe78718");
|
||||
ADD_CHECKPOINT2(327700, "f113c8cbe077aab9296ecbfb41780c147aeb54edfece7e4b9946b8abd0f06de7", "0x732431429c818");
|
||||
ADD_CHECKPOINT2(331170, "05243fba853fe375c671a6783eecac28777bca51f5977d5285c235424e52bb69", "0x7c3469310d218"); //Hard fork to v18
|
||||
ADD_CHECKPOINT2(331458, "f79a664a5e4bc11fa7d804be2c3c72db50c87a27f1f540f337564cbb6314e4cd", "0x7c34d47adf218"); //Hard fork to v19
|
||||
ADD_CHECKPOINT2(331891, "faceea4b4ab33fc962c24dfa2f98c2aeda4788f67c1e0044c62419912c1a64fe", "0x7c359086aeb58"); // restart DIFFICULTY_WINDOW
|
||||
ADD_CHECKPOINT2(332100, "d32c409058c1eceb9a105190c7a5f480b2d6f49f318b18652b49ae971c710124", "0x7c538441cca36");
|
||||
ADD_CHECKPOINT2(334000, "17d3b15f8e1a73e1c61335ee7979e9e3d211b9055e8a7fb2481e5f49a51b1c22", "0x7ddd5a79d69c4");
|
||||
ADD_CHECKPOINT2(348500, "2d43a157f369e2aa26a329b56456142ecd1361f5808c688d97112a2e3bbd23f4", "0x90889ed877ada");
|
||||
ADD_CHECKPOINT2(489400, "b14f49eae77398117ea93435676100d8b655a804689f73a5a4d0d5e71160d603", "0x1123c39bb52f7e");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,11 @@ using namespace epee;
|
||||
|
||||
static const char *DEFAULT_DNS_PUBLIC_ADDR[] =
|
||||
{
|
||||
"194.150.168.168", // CCC (Germany)
|
||||
"80.67.169.40", // FDN (France)
|
||||
"89.233.43.71", // http://censurfridns.dk (Denmark)
|
||||
"109.69.8.51", // punCAT (Spain)
|
||||
"193.58.251.251", // SkyDNS (Russia)
|
||||
};
|
||||
|
||||
static boost::mutex instance_lock;
|
||||
@@ -400,7 +405,7 @@ namespace dns_utils
|
||||
std::string address_from_txt_record(const std::string& s)
|
||||
{
|
||||
// make sure the txt record has "oa1:xmr" and find it
|
||||
auto pos = s.find("oa1:wow");
|
||||
auto pos = s.find("oa1:xmr");
|
||||
if (pos == std::string::npos)
|
||||
return {};
|
||||
// search from there to find "recipient_address="
|
||||
@@ -412,14 +417,14 @@ std::string address_from_txt_record(const std::string& s)
|
||||
auto pos2 = s.find(";", pos);
|
||||
if (pos2 != std::string::npos)
|
||||
{
|
||||
// length of address == 97, we can at least validate that much here
|
||||
if (pos2 - pos == 97)
|
||||
// length of address == 95, we can at least validate that much here
|
||||
if (pos2 - pos == 95)
|
||||
{
|
||||
return s.substr(pos, 97);
|
||||
return s.substr(pos, 95);
|
||||
}
|
||||
else if (pos2 - pos == 108) // length of address == 108 --> integrated address
|
||||
else if (pos2 - pos == 106) // length of address == 106 --> integrated address
|
||||
{
|
||||
return s.substr(pos, 108);
|
||||
return s.substr(pos, 106);
|
||||
}
|
||||
}
|
||||
return {};
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include "file_io_utils.h"
|
||||
#include "common/i18n.h"
|
||||
#include "translation_files.h"
|
||||
#include <algorithm>
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "i18n"
|
||||
|
||||
26
src/common/powerof.h
Normal file
26
src/common/powerof.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace tools
|
||||
{
|
||||
template<uint64_t a, uint64_t b>
|
||||
struct PowerOf
|
||||
{
|
||||
enum Data : uint64_t
|
||||
{
|
||||
// a^b = a * a^(b-1)
|
||||
Value = a * PowerOf<a, b - 1>::Value,
|
||||
};
|
||||
};
|
||||
|
||||
template<uint64_t a>
|
||||
struct PowerOf<a, 0>
|
||||
{
|
||||
enum Data : uint64_t
|
||||
{
|
||||
// a^0 = 1
|
||||
Value = 1,
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -871,19 +871,10 @@ std::string get_nix_version_display_string()
|
||||
return max_concurrency;
|
||||
}
|
||||
|
||||
bool is_privacy_preserving_network(const std::string &address)
|
||||
{
|
||||
if (boost::ends_with(address, ".onion"))
|
||||
return true;
|
||||
if (boost::ends_with(address, ".i2p"))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_local_address(const std::string &address)
|
||||
{
|
||||
// always assume Tor/I2P addresses to be untrusted by default
|
||||
if (is_privacy_preserving_network(address))
|
||||
if (boost::ends_with(address, ".onion") || boost::ends_with(address, ".i2p"))
|
||||
{
|
||||
MDEBUG("Address '" << address << "' is Tor/I2P, non local");
|
||||
return false;
|
||||
@@ -1009,13 +1000,13 @@ std::string get_nix_version_display_string()
|
||||
for (char c: val)
|
||||
{
|
||||
if (c == '*')
|
||||
newval += escape ? "*" : ".*";
|
||||
newval += escape ? "*" : ".*", escape = false;
|
||||
else if (c == '?')
|
||||
newval += escape ? "?" : ".";
|
||||
newval += escape ? "?" : ".", escape = false;
|
||||
else if (c == '\\')
|
||||
newval += '\\', escape = !escape;
|
||||
else
|
||||
newval += c;
|
||||
newval += c, escape = false;
|
||||
}
|
||||
return newval;
|
||||
}
|
||||
@@ -1355,12 +1346,8 @@ std::string get_nix_version_display_string()
|
||||
100743, 92152, 57565, 22533, 37564, 21823, 19980, 18277, 18402, 14344,
|
||||
12142, 15842, 13677, 17631, 18294, 22270, 41422, 39296, 36688, 33512,
|
||||
33831, 27582, 22276, 27516, 27317, 25505, 24426, 20566, 23045, 26766,
|
||||
28185, 26169, 27011, 28642, 34994, 34442, 30682, 34357, 31640, 41167,
|
||||
41301, 48616, 51075, 55061, 49909, 44606, 47091, 53828, 42520, 39023,
|
||||
55245, 56145, 51119, 60398, 71821, 48142, 60310, 56041, 54176, 66220,
|
||||
56336, 55248, 56656, 63305, 54029, 77136, 71902, 71618, 83587, 81068,
|
||||
69062, 54848, 53681, 53555,
|
||||
50616 // Blocks 2,400,000 to 2,409,999 in July 2021
|
||||
28185, 26169, 27011,
|
||||
28642 // Blocks 1,990,000 to 1,999,999 in December 2019
|
||||
};
|
||||
const uint64_t block_range_size = 10000;
|
||||
|
||||
|
||||
@@ -228,7 +228,6 @@ namespace tools
|
||||
unsigned get_max_concurrency();
|
||||
|
||||
bool is_local_address(const std::string &address);
|
||||
bool is_privacy_preserving_network(const std::string &address);
|
||||
int vercmp(const char *v0, const char *v1); // returns < 0, 0, > 0, similar to strcmp, but more human friendly than lexical - does not attempt to validate
|
||||
|
||||
bool sha256sum(const uint8_t *data, size_t len, crypto::hash &hash);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,13 +11,7 @@ enum V4_Settings
|
||||
|
||||
// Always generate at least 60 instructions
|
||||
NUM_INSTRUCTIONS = 60,
|
||||
|
||||
// Always generate at least 60 instructions
|
||||
NUM_INSTRUCTIONS_MIN = 60,
|
||||
|
||||
// Never generate more than 70 instructions (final RET instruction doesn't count here)
|
||||
NUM_INSTRUCTIONS_MAX = 70,
|
||||
|
||||
|
||||
// Available ALUs for MUL
|
||||
// Modern CPUs typically have only 1 ALU which can do multiplications
|
||||
ALU_COUNT_MUL = 1,
|
||||
|
||||
@@ -36,17 +36,8 @@ if(APPLE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
monero_add_library(cryptonote_format_utils_basic
|
||||
cryptonote_format_utils_basic.cpp
|
||||
)
|
||||
target_link_libraries(cryptonote_format_utils_basic
|
||||
PUBLIC
|
||||
cncrypto
|
||||
)
|
||||
|
||||
set(cryptonote_basic_sources
|
||||
account.cpp
|
||||
connection_context.cpp
|
||||
cryptonote_basic_impl.cpp
|
||||
cryptonote_format_utils.cpp
|
||||
difficulty.cpp
|
||||
@@ -80,7 +71,6 @@ target_link_libraries(cryptonote_basic
|
||||
common
|
||||
cncrypto
|
||||
checkpoints
|
||||
cryptonote_format_utils_basic
|
||||
device
|
||||
${Boost_DATE_TIME_LIBRARY}
|
||||
${Boost_PROGRAM_OPTIONS_LIBRARY}
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
// Copyright (c) 2020, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "connection_context.h"
|
||||
|
||||
#include "cryptonote_protocol/cryptonote_protocol_defs.h"
|
||||
#include "p2p/p2p_protocol_defs.h"
|
||||
|
||||
namespace cryptonote
|
||||
{
|
||||
std::size_t cryptonote_connection_context::get_max_bytes(const int command) noexcept
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case nodetool::COMMAND_HANDSHAKE_T<cryptonote::CORE_SYNC_DATA>::ID:
|
||||
return 65536;
|
||||
case nodetool::COMMAND_TIMED_SYNC_T<cryptonote::CORE_SYNC_DATA>::ID:
|
||||
return 65536;
|
||||
case nodetool::COMMAND_PING::ID:
|
||||
return 4096;
|
||||
case nodetool::COMMAND_REQUEST_SUPPORT_FLAGS::ID:
|
||||
return 4096;
|
||||
case cryptonote::NOTIFY_NEW_BLOCK::ID:
|
||||
return 1024 * 1024 * 128; // 128 MB (max packet is a bit less than 100 MB though)
|
||||
case cryptonote::NOTIFY_NEW_TRANSACTIONS::ID:
|
||||
return 1024 * 1024 * 128; // 128 MB (max packet is a bit less than 100 MB though)
|
||||
case cryptonote::NOTIFY_REQUEST_GET_OBJECTS::ID:
|
||||
return 1024 * 1024 * 2; // 2 MB
|
||||
case cryptonote::NOTIFY_RESPONSE_GET_OBJECTS::ID:
|
||||
return 1024 * 1024 * 128; // 128 MB (max packet is a bit less than 100 MB though)
|
||||
case cryptonote::NOTIFY_REQUEST_CHAIN::ID:
|
||||
return 512 * 1024; // 512 kB
|
||||
case cryptonote::NOTIFY_RESPONSE_CHAIN_ENTRY::ID:
|
||||
return 1024 * 1024 * 4; // 4 MB
|
||||
case cryptonote::NOTIFY_NEW_FLUFFY_BLOCK::ID:
|
||||
return 1024 * 1024 * 4; // 4 MB, but it does not includes transaction data
|
||||
case cryptonote::NOTIFY_REQUEST_FLUFFY_MISSING_TX::ID:
|
||||
return 1024 * 1024; // 1 MB
|
||||
case cryptonote::NOTIFY_GET_TXPOOL_COMPLEMENT::ID:
|
||||
return 1024 * 1024 * 4; // 4 MB
|
||||
default:
|
||||
break;
|
||||
};
|
||||
return std::numeric_limits<size_t>::max();
|
||||
}
|
||||
} // cryptonote
|
||||
@@ -31,7 +31,6 @@
|
||||
#pragma once
|
||||
#include <unordered_set>
|
||||
#include <atomic>
|
||||
#include <algorithm>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include "net/net_utils_base.h"
|
||||
#include "copyable_atomic.h"
|
||||
@@ -39,12 +38,13 @@
|
||||
|
||||
namespace cryptonote
|
||||
{
|
||||
|
||||
struct cryptonote_connection_context: public epee::net_utils::connection_context_base
|
||||
{
|
||||
cryptonote_connection_context(): m_state(state_before_handshake), m_remote_blockchain_height(0), m_last_response_height(0),
|
||||
m_last_request_time(boost::date_time::not_a_date_time), m_callback_request_count(0),
|
||||
m_last_known_hash(crypto::null_hash), m_pruning_seed(0), m_rpc_port(0), m_rpc_credits_per_hash(0), m_anchor(false), m_score(0),
|
||||
m_expect_response(0), m_expect_height(0), m_num_requested(0) {}
|
||||
m_expect_response(0) {}
|
||||
|
||||
enum state
|
||||
{
|
||||
@@ -55,12 +55,6 @@ namespace cryptonote
|
||||
state_normal
|
||||
};
|
||||
|
||||
static constexpr int handshake_command() noexcept { return 1001; }
|
||||
bool handshake_complete() const noexcept { return m_state != state_before_handshake; }
|
||||
|
||||
//! \return Maximum number of bytes permissible for `command`.
|
||||
static size_t get_max_bytes(int command) noexcept;
|
||||
|
||||
state m_state;
|
||||
std::vector<std::pair<crypto::hash, uint64_t>> m_needed_objects;
|
||||
std::unordered_set<crypto::hash> m_requested_objects;
|
||||
@@ -76,9 +70,6 @@ namespace cryptonote
|
||||
int32_t m_score;
|
||||
int m_expect_response;
|
||||
uint64_t m_expect_height;
|
||||
size_t m_num_requested;
|
||||
epee::copyable_atomic m_new_stripe_notification{0};
|
||||
epee::copyable_atomic m_idle_peer_notification{0};
|
||||
};
|
||||
|
||||
inline std::string get_protocol_state_string(cryptonote_connection_context::state s)
|
||||
|
||||
@@ -450,8 +450,6 @@ namespace cryptonote
|
||||
uint64_t timestamp;
|
||||
crypto::hash prev_id;
|
||||
uint32_t nonce;
|
||||
crypto::signature signature;
|
||||
uint16_t vote;
|
||||
|
||||
BEGIN_SERIALIZE()
|
||||
VARINT_FIELD(major_version)
|
||||
@@ -459,11 +457,6 @@ namespace cryptonote
|
||||
VARINT_FIELD(timestamp)
|
||||
FIELD(prev_id)
|
||||
FIELD(nonce)
|
||||
if (major_version >= BLOCK_HEADER_MINER_SIG)
|
||||
{
|
||||
FIELD(signature)
|
||||
FIELD(vote)
|
||||
}
|
||||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
|
||||
@@ -185,11 +185,6 @@ namespace boost
|
||||
a & b.timestamp;
|
||||
a & b.prev_id;
|
||||
a & b.nonce;
|
||||
if (b.major_version >= BLOCK_HEADER_MINER_SIG)
|
||||
{
|
||||
a & b.signature;
|
||||
a & b.vote;
|
||||
}
|
||||
//------------------
|
||||
a & b.miner_tx;
|
||||
a & b.tx_hashes;
|
||||
@@ -232,20 +227,6 @@ namespace boost
|
||||
a & x.t;
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
inline void serialize(Archive &a, rct::BulletproofPlus &x, const boost::serialization::version_type ver)
|
||||
{
|
||||
a & x.V;
|
||||
a & x.A;
|
||||
a & x.A1;
|
||||
a & x.B;
|
||||
a & x.r1;
|
||||
a & x.s1;
|
||||
a & x.d1;
|
||||
a & x.L;
|
||||
a & x.R;
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
inline void serialize(Archive &a, rct::boroSig &x, const boost::serialization::version_type ver)
|
||||
{
|
||||
@@ -324,7 +305,7 @@ namespace boost
|
||||
a & x.type;
|
||||
if (x.type == rct::RCTTypeNull)
|
||||
return;
|
||||
if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof && x.type != rct::RCTTypeBulletproof2 && x.type != rct::RCTTypeFullBulletproof && x.type != rct::RCTTypeSimpleBulletproof && x.type != rct::RCTTypeCLSAG && x.type != rct::RCTTypeBulletproofPlus)
|
||||
if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof && x.type != rct::RCTTypeBulletproof2 && x.type != rct::RCTTypeFullBulletproof && x.type != rct::RCTTypeSimpleBulletproof && x.type != rct::RCTTypeCLSAG)
|
||||
throw boost::archive::archive_exception(boost::archive::archive_exception::other_exception, "Unsupported rct type");
|
||||
// a & x.message; message is not serialized, as it can be reconstructed from the tx data
|
||||
// a & x.mixRing; mixRing is not serialized, as it can be reconstructed from the offsets
|
||||
@@ -340,11 +321,7 @@ namespace boost
|
||||
{
|
||||
a & x.rangeSigs;
|
||||
if (x.rangeSigs.empty())
|
||||
{
|
||||
a & x.bulletproofs;
|
||||
if (ver >= 2u)
|
||||
a & x.bulletproofs_plus;
|
||||
}
|
||||
a & x.MGs;
|
||||
if (ver >= 1u)
|
||||
a & x.CLSAGs;
|
||||
@@ -358,7 +335,7 @@ namespace boost
|
||||
a & x.type;
|
||||
if (x.type == rct::RCTTypeNull)
|
||||
return;
|
||||
if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof && x.type != rct::RCTTypeBulletproof2 && x.type != rct::RCTTypeFullBulletproof && x.type != rct::RCTTypeSimpleBulletproof && x.type != rct::RCTTypeCLSAG && x.type != rct::RCTTypeBulletproofPlus)
|
||||
if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof && x.type != rct::RCTTypeBulletproof2 && x.type != rct::RCTTypeFullBulletproof && x.type != rct::RCTTypeSimpleBulletproof && x.type != rct::RCTTypeCLSAG)
|
||||
throw boost::archive::archive_exception(boost::archive::archive_exception::other_exception, "Unsupported rct type");
|
||||
// a & x.message; message is not serialized, as it can be reconstructed from the tx data
|
||||
// a & x.mixRing; mixRing is not serialized, as it can be reconstructed from the offsets
|
||||
@@ -370,15 +347,11 @@ namespace boost
|
||||
//--------------
|
||||
a & x.p.rangeSigs;
|
||||
if (x.p.rangeSigs.empty())
|
||||
{
|
||||
a & x.p.bulletproofs;
|
||||
if (ver >= 2u)
|
||||
a & x.p.bulletproofs_plus;
|
||||
}
|
||||
a & x.p.MGs;
|
||||
if (ver >= 1u)
|
||||
a & x.p.CLSAGs;
|
||||
if (x.type == rct::RCTTypeBulletproof || x.type == rct::RCTTypeBulletproof2 || x.type == rct::RCTTypeSimpleBulletproof || x.type == rct::RCTTypeCLSAG || x.type == rct::RCTTypeBulletproofPlus)
|
||||
if (x.type == rct::RCTTypeBulletproof || x.type == rct::RCTTypeBulletproof2 || x.type == rct::RCTTypeSimpleBulletproof || x.type == rct::RCTTypeCLSAG)
|
||||
a & x.p.pseudoOuts;
|
||||
}
|
||||
|
||||
@@ -419,6 +392,6 @@ namespace boost
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_CLASS_VERSION(rct::rctSigPrunable, 2)
|
||||
BOOST_CLASS_VERSION(rct::rctSig, 2)
|
||||
BOOST_CLASS_VERSION(rct::rctSigPrunable, 1)
|
||||
BOOST_CLASS_VERSION(rct::rctSig, 1)
|
||||
BOOST_CLASS_VERSION(rct::multisig_out, 1)
|
||||
|
||||
@@ -105,8 +105,7 @@ namespace cryptonote
|
||||
uint64_t get_transaction_weight_clawback(const transaction &tx, size_t n_padded_outputs)
|
||||
{
|
||||
const rct::rctSig &rv = tx.rct_signatures;
|
||||
const bool plus = rv.type == rct::RCTTypeBulletproofPlus;
|
||||
const uint64_t bp_base = (32 * ((plus ? 6 : 9) + 7 * 2)) / 2; // notional size of a 2 output proof, normalized to 1 proof (ie, divided by 2)
|
||||
const uint64_t bp_base = 368;
|
||||
const size_t n_outputs = tx.vout.size();
|
||||
if (n_padded_outputs <= 2)
|
||||
return 0;
|
||||
@@ -114,7 +113,7 @@ namespace cryptonote
|
||||
while ((1u << nlr) < n_padded_outputs)
|
||||
++nlr;
|
||||
nlr += 6;
|
||||
const size_t bp_size = 32 * ((plus ? 6 : 9) + 2 * nlr);
|
||||
const size_t bp_size = 32 * (9 + 2 * nlr);
|
||||
CHECK_AND_ASSERT_THROW_MES_L1(n_outputs <= BULLETPROOF_MAX_OUTPUTS, "maximum number of outputs is " + std::to_string(BULLETPROOF_MAX_OUTPUTS) + " per transaction");
|
||||
CHECK_AND_ASSERT_THROW_MES_L1(bp_base * n_padded_outputs >= bp_size, "Invalid bulletproof clawback: bp_base " + std::to_string(bp_base) + ", n_padded_outputs "
|
||||
+ std::to_string(n_padded_outputs) + ", bp_size " + std::to_string(bp_size));
|
||||
@@ -140,6 +139,22 @@ namespace cryptonote
|
||||
return h;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
void get_transaction_prefix_hash(const transaction_prefix& tx, crypto::hash& h)
|
||||
{
|
||||
std::ostringstream s;
|
||||
binary_archive<true> a(s);
|
||||
::serialization::serialize(a, const_cast<transaction_prefix&>(tx));
|
||||
crypto::cn_fast_hash(s.str().data(), s.str().size(), h);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx)
|
||||
{
|
||||
crypto::hash h = null_hash;
|
||||
get_transaction_prefix_hash(tx, h);
|
||||
return h;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool expand_transaction_1(transaction &tx, bool base_only)
|
||||
{
|
||||
if (tx.version >= 2 && !is_coinbase(tx))
|
||||
@@ -164,31 +179,6 @@ namespace cryptonote
|
||||
|
||||
if (!base_only)
|
||||
{
|
||||
const bool bulletproof_plus = rct::is_rct_bulletproof_plus(rv.type);
|
||||
if (bulletproof_plus)
|
||||
{
|
||||
if (rv.p.bulletproofs_plus.size() != 1)
|
||||
{
|
||||
LOG_PRINT_L1("Failed to parse transaction from blob, bad bulletproofs_plus size in tx " << get_transaction_hash(tx));
|
||||
return false;
|
||||
}
|
||||
if (rv.p.bulletproofs_plus[0].L.size() < 6)
|
||||
{
|
||||
LOG_PRINT_L1("Failed to parse transaction from blob, bad bulletproofs_plus L size in tx " << get_transaction_hash(tx));
|
||||
return false;
|
||||
}
|
||||
const size_t max_outputs = 1 << (rv.p.bulletproofs_plus[0].L.size() - 6);
|
||||
if (max_outputs < tx.vout.size())
|
||||
{
|
||||
LOG_PRINT_L1("Failed to parse transaction from blob, bad bulletproofs_plus max outputs in tx " << get_transaction_hash(tx));
|
||||
return false;
|
||||
}
|
||||
const size_t n_amounts = tx.vout.size();
|
||||
CHECK_AND_ASSERT_MES(n_amounts == rv.outPk.size(), false, "Internal error filling out V");
|
||||
rv.p.bulletproofs_plus[0].V.resize(n_amounts);
|
||||
for (size_t i = 0; i < n_amounts; ++i)
|
||||
rv.p.bulletproofs_plus[0].V[i] = rv.outPk[i].mask;
|
||||
}
|
||||
const bool bulletproof = rct::is_rct_bulletproof(rv.type);
|
||||
if (rct::is_rct_new_bulletproof(rv.type))
|
||||
{
|
||||
@@ -454,16 +444,15 @@ namespace cryptonote
|
||||
if (tx.version < 2)
|
||||
return blob_size;
|
||||
const rct::rctSig &rv = tx.rct_signatures;
|
||||
const bool bulletproof = rct::is_rct_bulletproof(rv.type);
|
||||
const bool bulletproof_plus = rct::is_rct_bulletproof_plus(rv.type);
|
||||
if (!bulletproof && !bulletproof_plus)
|
||||
if (!rct::is_rct_bulletproof(rv.type))
|
||||
return blob_size;
|
||||
const size_t n_outputs = tx.vout.size();
|
||||
if (n_outputs <= 2)
|
||||
return blob_size;
|
||||
if (rct::is_rct_old_bulletproof(rv.type))
|
||||
return blob_size;
|
||||
const size_t n_padded_outputs = bulletproof_plus ? rct::n_bulletproof_plus_max_amounts(rv.p.bulletproofs_plus) : rct::n_bulletproof_max_amounts(rv.p.bulletproofs);
|
||||
const uint64_t bp_base = 368;
|
||||
const size_t n_padded_outputs = rct::n_bulletproof_max_amounts(rv.p.bulletproofs);
|
||||
uint64_t bp_clawback = get_transaction_weight_clawback(tx, n_padded_outputs);
|
||||
CHECK_AND_ASSERT_THROW_MES_L1(bp_clawback <= std::numeric_limits<uint64_t>::max() - blob_size, "Weight overflow");
|
||||
return blob_size + bp_clawback;
|
||||
@@ -473,7 +462,7 @@ namespace cryptonote
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(tx.pruned, std::numeric_limits<uint64_t>::max(), "get_pruned_transaction_weight does not support non pruned txes");
|
||||
CHECK_AND_ASSERT_MES(tx.version >= 2, std::numeric_limits<uint64_t>::max(), "get_pruned_transaction_weight does not support v1 txes");
|
||||
CHECK_AND_ASSERT_MES(tx.rct_signatures.type == rct::RCTTypeBulletproof2 || tx.rct_signatures.type == rct::RCTTypeCLSAG || tx.rct_signatures.type == rct::RCTTypeBulletproofPlus,
|
||||
CHECK_AND_ASSERT_MES(tx.rct_signatures.type >= rct::RCTTypeBulletproof2 || tx.rct_signatures.type == rct::RCTTypeCLSAG,
|
||||
std::numeric_limits<uint64_t>::max(), "get_pruned_transaction_weight does not support older range proof types");
|
||||
CHECK_AND_ASSERT_MES(!tx.vin.empty(), std::numeric_limits<uint64_t>::max(), "empty vin");
|
||||
CHECK_AND_ASSERT_MES(tx.vin[0].type() == typeid(cryptonote::txin_to_key), std::numeric_limits<uint64_t>::max(), "empty vin");
|
||||
@@ -492,12 +481,12 @@ namespace cryptonote
|
||||
while ((n_padded_outputs = (1u << nrl)) < tx.vout.size())
|
||||
++nrl;
|
||||
nrl += 6;
|
||||
extra = 32 * ((rct::is_rct_bulletproof_plus(tx.rct_signatures.type) ? 6 : 9) + 2 * nrl) + 2;
|
||||
extra = 32 * (9 + 2 * nrl) + 2;
|
||||
weight += extra;
|
||||
|
||||
// calculate deterministic CLSAG/MLSAG data size
|
||||
const size_t ring_size = boost::get<cryptonote::txin_to_key>(tx.vin[0]).key_offsets.size();
|
||||
if (tx.rct_signatures.type == rct::RCTTypeCLSAG || tx.rct_signatures.type == rct::RCTTypeBulletproofPlus)
|
||||
if (tx.rct_signatures.type == rct::RCTTypeCLSAG)
|
||||
extra = tx.vin.size() * (ring_size + 2) * 32;
|
||||
else
|
||||
extra = tx.vin.size() * (ring_size * (1 + 1) * 32 + 32 /* cc */);
|
||||
@@ -1013,9 +1002,9 @@ namespace cryptonote
|
||||
switch (decimal_point)
|
||||
{
|
||||
case 11:
|
||||
case 8:
|
||||
case 5:
|
||||
case 2:
|
||||
case 9:
|
||||
case 6:
|
||||
case 3:
|
||||
case 0:
|
||||
default_decimal_point = decimal_point;
|
||||
break;
|
||||
@@ -1037,14 +1026,14 @@ namespace cryptonote
|
||||
{
|
||||
case 11:
|
||||
return "wownero";
|
||||
case 8:
|
||||
return "verywow";
|
||||
case 5:
|
||||
return "muchwow";
|
||||
case 2:
|
||||
return "suchwow";
|
||||
case 9:
|
||||
return "millinero";
|
||||
case 6:
|
||||
return "micronero";
|
||||
case 3:
|
||||
return "nanonero";
|
||||
case 0:
|
||||
return "dust";
|
||||
return "piconero";
|
||||
default:
|
||||
ASSERT_MES_AND_THROW("Invalid decimal point specification: " << decimal_point);
|
||||
}
|
||||
@@ -1313,25 +1302,6 @@ namespace cryptonote
|
||||
return p;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
crypto::hash get_sig_data(const block& b)
|
||||
{
|
||||
crypto::hash sig_data;
|
||||
blobdata blob = get_block_hashing_blob_sig_data(b);
|
||||
crypto::cn_fast_hash(blob.data(), blob.size(), sig_data);
|
||||
return sig_data;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
blobdata get_block_hashing_blob_sig_data(const block& b)
|
||||
{
|
||||
block_header tmp = static_cast<const block_header&>(b);
|
||||
memset(&tmp.signature, 0, sizeof(tmp.signature));
|
||||
blobdata blob = t_serializable_object_to_blob(tmp);
|
||||
crypto::hash tree_root_hash = get_tx_tree_hash(b);
|
||||
blob.append(reinterpret_cast<const char*>(&tree_root_hash), sizeof(tree_root_hash));
|
||||
blob.append(tools::get_varint_data(b.tx_hashes.size()+1));
|
||||
return blob;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
std::vector<uint64_t> relative_output_offsets_to_absolute(const std::vector<uint64_t>& off)
|
||||
{
|
||||
std::vector<uint64_t> res = off;
|
||||
|
||||
@@ -120,8 +120,6 @@ namespace cryptonote
|
||||
bool calculate_block_hash(const block& b, crypto::hash& res, const blobdata_ref *blob = NULL);
|
||||
bool get_block_hash(const block& b, crypto::hash& res);
|
||||
crypto::hash get_block_hash(const block& b);
|
||||
crypto::hash get_sig_data(const block& b);
|
||||
blobdata get_block_hashing_blob_sig_data(const block& b);
|
||||
bool parse_and_validate_block_from_blob(const blobdata_ref& b_blob, block& b, crypto::hash *block_hash);
|
||||
bool parse_and_validate_block_from_blob(const blobdata_ref& b_blob, block& b);
|
||||
bool parse_and_validate_block_from_blob(const blobdata_ref& b_blob, block& b, crypto::hash &block_hash);
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
// Copyright (c) 2014-2021, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
|
||||
|
||||
#include "cryptonote_format_utils.h"
|
||||
|
||||
namespace cryptonote
|
||||
{
|
||||
void get_transaction_prefix_hash(const transaction_prefix& tx, crypto::hash& h)
|
||||
{
|
||||
std::ostringstream s;
|
||||
binary_archive<true> a(s);
|
||||
::serialization::serialize(a, const_cast<transaction_prefix&>(tx));
|
||||
crypto::cn_fast_hash(s.str().data(), s.str().size(), h);
|
||||
}
|
||||
|
||||
crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx)
|
||||
{
|
||||
crypto::hash h = crypto::null_hash;
|
||||
get_transaction_prefix_hash(tx, h);
|
||||
return h;
|
||||
}
|
||||
}
|
||||
@@ -208,16 +208,12 @@ namespace cryptonote {
|
||||
timestamps.resize(DIFFICULTY_WINDOW);
|
||||
cumulative_difficulties.resize(DIFFICULTY_WINDOW);
|
||||
}
|
||||
|
||||
|
||||
size_t length = timestamps.size();
|
||||
assert(length == cumulative_difficulties.size());
|
||||
if (length <= 1) {
|
||||
return 1;
|
||||
}
|
||||
if (HEIGHT < 10 && HEIGHT > 2 && m_nettype == TESTNET) { return 500; }
|
||||
if (HEIGHT <= 55 + DIFFICULTY_WINDOW && HEIGHT >= 55 && m_nettype == TESTNET) { return 1337; }
|
||||
if (HEIGHT <= DIFFICULTY_RESET_HEIGHT + DIFFICULTY_WINDOW && HEIGHT >= DIFFICULTY_RESET_HEIGHT && m_nettype == MAINNET) { return DIFFICULTY_RESET_LEVEL; }
|
||||
if (HEIGHT < 200 && HEIGHT > 2 && m_nettype == TESTNET) { return 500; }
|
||||
static_assert(DIFFICULTY_WINDOW >= 2, "Window is too small");
|
||||
assert(length <= DIFFICULTY_WINDOW);
|
||||
sort(timestamps.begin(), timestamps.end());
|
||||
@@ -379,16 +375,7 @@ namespace cryptonote {
|
||||
if (HEIGHT < 200 && m_nettype == TESTNET) { return 500; }
|
||||
assert(timestamps.size() == N+1);
|
||||
|
||||
// hardcoding previously erroneously calculated difficulty entries
|
||||
if(HEIGHT == 307686) return 25800000;
|
||||
if(HEIGHT == 307692) return 1890000;
|
||||
if(HEIGHT == 307735) return 17900000;
|
||||
if(HEIGHT == 307742) return 21300000;
|
||||
if(HEIGHT == 307750) return 10900000;
|
||||
if(HEIGHT == 307766) return 2960000;
|
||||
|
||||
uint64_t i, this_timestamp(0), previous_timestamp(0);
|
||||
difficulty_type L(0), next_D, avg_D;
|
||||
uint64_t L(0), next_D, i, this_timestamp(0), previous_timestamp(0), avg_D;
|
||||
|
||||
previous_timestamp = timestamps[0]-T;
|
||||
for ( i = 1; i <= N; i++) {
|
||||
@@ -399,13 +386,10 @@ namespace cryptonote {
|
||||
previous_timestamp = this_timestamp;
|
||||
}
|
||||
if (L < N*N*T/20 ) { L = N*N*T/20; }
|
||||
avg_D = ( cumulative_difficulties[N] - cumulative_difficulties[0] )/ N;
|
||||
avg_D = static_cast<uint64_t>(( cumulative_difficulties[N] - cumulative_difficulties[0] )/ N);
|
||||
|
||||
// Prevent round off error for small D and overflow for large D.
|
||||
if (avg_D > 2000000*N*N*T && HEIGHT < 307800) {
|
||||
next_D = (avg_D/(200*L))*(N*(N+1)*T*99);
|
||||
}
|
||||
else if (avg_D > uint64_t(-1)/(N*(N+1)*T*99) && HEIGHT > 307800) {
|
||||
if (avg_D > 2000000*N*N*T) {
|
||||
next_D = (avg_D/(200*L))*(N*(N+1)*T*99);
|
||||
}
|
||||
else { next_D = (avg_D*N*(N+1)*T*99)/(200*L); }
|
||||
|
||||
@@ -99,8 +99,6 @@ namespace cryptonote
|
||||
const command_line::arg_descriptor<uint64_t> arg_bg_mining_min_idle_interval_seconds = {"bg-mining-min-idle-interval", "Specify min lookback interval in seconds for determining idle state", miner::BACKGROUND_MINING_DEFAULT_MIN_IDLE_INTERVAL_IN_SECONDS, true};
|
||||
const command_line::arg_descriptor<uint16_t> arg_bg_mining_idle_threshold_percentage = {"bg-mining-idle-threshold", "Specify minimum avg idle percentage over lookback interval", miner::BACKGROUND_MINING_DEFAULT_IDLE_THRESHOLD_PERCENTAGE, true};
|
||||
const command_line::arg_descriptor<uint16_t> arg_bg_mining_miner_target_percentage = {"bg-mining-miner-target", "Specify maximum percentage cpu use by miner(s)", miner::BACKGROUND_MINING_DEFAULT_MINING_TARGET_PERCENTAGE, true};
|
||||
const command_line::arg_descriptor<std::string> arg_spendkey = {"spendkey", "Specify secret spend key used for mining", "", true};
|
||||
const command_line::arg_descriptor<std::string> arg_vote = {"vote", "Vote for proposals.", "", true};
|
||||
}
|
||||
|
||||
|
||||
@@ -293,42 +291,10 @@ namespace cryptonote
|
||||
command_line::add_arg(desc, arg_bg_mining_min_idle_interval_seconds);
|
||||
command_line::add_arg(desc, arg_bg_mining_idle_threshold_percentage);
|
||||
command_line::add_arg(desc, arg_bg_mining_miner_target_percentage);
|
||||
command_line::add_arg(desc, arg_spendkey);
|
||||
command_line::add_arg(desc, arg_vote);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
bool miner::init(const boost::program_options::variables_map& vm, network_type nettype)
|
||||
{
|
||||
if(command_line::has_arg(vm, arg_spendkey))
|
||||
{
|
||||
std::string skey_str = command_line::get_arg(vm, arg_spendkey);
|
||||
crypto::secret_key spendkey;
|
||||
epee::string_tools::hex_to_pod(skey_str, spendkey);
|
||||
crypto::secret_key viewkey;
|
||||
keccak((uint8_t *)&spendkey, 32, (uint8_t *)&viewkey, 32);
|
||||
sc_reduce32((uint8_t *)&viewkey);
|
||||
m_spendkey = spendkey;
|
||||
m_viewkey = viewkey;
|
||||
}
|
||||
if(!command_line::has_arg(vm, arg_vote))
|
||||
{
|
||||
m_int_vote = 0;
|
||||
} else {
|
||||
m_vote = command_line::get_arg(vm, arg_vote);
|
||||
if(m_vote != "yes" && m_vote != "no")
|
||||
{
|
||||
LOG_ERROR("Voting format error, only a \"yes\" or \"no\" response is accepted");
|
||||
return false;
|
||||
}
|
||||
if(m_vote == "yes")
|
||||
{
|
||||
m_int_vote = 1;
|
||||
}
|
||||
if(m_vote == "no")
|
||||
{
|
||||
m_int_vote = 2;
|
||||
}
|
||||
}
|
||||
if(command_line::has_arg(vm, arg_extra_messages))
|
||||
{
|
||||
std::string buff;
|
||||
@@ -559,7 +525,7 @@ namespace cryptonote
|
||||
{
|
||||
uint32_t th_local_index = boost::interprocess::ipcdetail::atomic_inc32(&m_thread_index);
|
||||
MLOG_SET_THREAD_NAME(std::string("[miner ") + std::to_string(th_local_index) + "]");
|
||||
MGINFO_GREEN("*Spins roulette wheel*... Mining started. Good luck!");
|
||||
MGINFO("Miner thread was started ["<< th_local_index << "]");
|
||||
uint32_t nonce = m_starter_nonce + th_local_index;
|
||||
uint64_t height = 0;
|
||||
difficulty_type local_diff = 0;
|
||||
@@ -607,28 +573,6 @@ namespace cryptonote
|
||||
}
|
||||
|
||||
b.nonce = nonce;
|
||||
|
||||
// Miner Block Header Signing
|
||||
if (b.major_version >= BLOCK_HEADER_MINER_SIG)
|
||||
{
|
||||
// tx key derivation
|
||||
crypto::key_derivation derivation;
|
||||
cryptonote::keypair in_ephemeral;
|
||||
crypto::secret_key eph_secret_key;
|
||||
crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(b.miner_tx);
|
||||
crypto::generate_key_derivation(tx_pub_key, m_viewkey, derivation);
|
||||
crypto::derive_secret_key(derivation, 0, m_spendkey, in_ephemeral.sec);
|
||||
eph_secret_key = in_ephemeral.sec;
|
||||
// keccak hash and sign block header data
|
||||
crypto::signature signature;
|
||||
crypto::hash sig_data = get_sig_data(b);
|
||||
crypto::public_key eph_pub_key = boost::get<txout_to_key>(b.miner_tx.vout[0].target).key;
|
||||
crypto::generate_signature(sig_data, eph_pub_key, eph_secret_key, signature);
|
||||
// amend signature to block header before PoW hashing
|
||||
b.signature = signature;
|
||||
b.vote = m_int_vote;
|
||||
}
|
||||
|
||||
crypto::hash h;
|
||||
m_gbh(b, height, NULL, tools::get_max_concurrency(), h);
|
||||
|
||||
@@ -636,42 +580,7 @@ namespace cryptonote
|
||||
{
|
||||
//we lucky!
|
||||
++m_config.current_extra_message_index;
|
||||
MGINFO_YELLOW(ENDL <<
|
||||
" ╦ ╦┬┌┐┌┐┌┌─┐┬─┐ ┬ ┬┬┌┐┌┐┌┌─┐┬─┐ ┌─┐┬ ┬┬┌─┐┬┌─┌─┐┌┐┌ ┌┬┐┬┌┐┌┐┌┌─┐┬─┐ ||\n"
|
||||
" ║║║││││││├┤ ├┬┘ │││││││││├┤ ├┬┘ │ ├─┤││ ├┴┐├┤ │││ ││││││││├┤ ├┬┘ ||\n"
|
||||
" ╚╩╝┴┘└┘└┘└─┘┴└─ └┴┘┴┘└┘└┘└─┘┴└─ └─┘┴ ┴┴└─┘┴ ┴└─┘┘└┘ ─┴┘┴┘└┘└┘└─┘┴└─ ()\n"
|
||||
<< ENDL);
|
||||
MGINFO_MAGENTA(ENDL <<
|
||||
"\n\n"
|
||||
" //@@@@@@@@@@@@@@@@@// \n"
|
||||
" //%%%%%%%%%%%%%%%%%%%%%%%%%%%/% \n"
|
||||
" @/%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/ \n"
|
||||
" //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/& \n"
|
||||
" /%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/ \n"
|
||||
" &/%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/ \n"
|
||||
" ////////////%%%%%%%%%%%%%%%%%%%%%%#//////////// \n"
|
||||
" /@@////////@@/%%%%%%%%%%%%%%%%%%%%%/@@////////@@/ \n"
|
||||
" /@@////////@@/%%%%%%%%/@@#/%%%%%%%%/@@////////@@/ \n"
|
||||
" /@@/////////@@/%%%%%%/@@@/@@@/%%%%%%/@@////////#@/ \n"
|
||||
" /@&////////@@/%%%%/@@@/////@@@/%%%%/@@////////@@/ \n"
|
||||
" /@@////////@@/%(/@@///////////@@/%%/@@////////@@/ \n"
|
||||
" /@@////////@/@@@///////////////@@&@@////////@@/ \n"
|
||||
" /@@///////@@@///////////////////@@@///////@@/ \n"
|
||||
" /@@//////@///////////////////////@//////@@/ \n"
|
||||
" #/@@/////////////////////////////////@@/ \n"
|
||||
" /@@@///////////////////////////@@@/ \n"
|
||||
" %/@@@@///////////////////@@@@/ \n"
|
||||
" //@@@@@@@@@@@@@@@@@// \n"
|
||||
<< ENDL);
|
||||
MGINFO_GREEN("Awesome, you won a block reward!\n" << get_block_hash(b) << " at height " << height);
|
||||
if (b.vote == 1)
|
||||
{
|
||||
MGINFO_GREEN("Your \"YES\" vote has been cast.");
|
||||
}
|
||||
if (b.vote == 2)
|
||||
{
|
||||
MGINFO_GREEN("Your \"NO\" vote has been cast.");
|
||||
}
|
||||
MGINFO_GREEN("Found block " << get_block_hash(b) << " at height " << height << " for difficulty: " << local_diff);
|
||||
cryptonote::block_verification_context bvc;
|
||||
if(!m_phandler->handle_block_found(b, bvc) || !bvc.m_added_to_main_chain)
|
||||
{
|
||||
|
||||
@@ -136,10 +136,6 @@ namespace cryptonote
|
||||
i_miner_handler* m_phandler;
|
||||
get_block_hash_t m_gbh;
|
||||
account_public_address m_mine_address;
|
||||
crypto::secret_key m_spendkey;
|
||||
crypto::secret_key m_viewkey;
|
||||
std::string m_vote;
|
||||
uint16_t m_int_vote;
|
||||
epee::math_helper::once_a_time_seconds<5> m_update_block_template_interval;
|
||||
epee::math_helper::once_a_time_seconds<2> m_update_merge_hr_interval;
|
||||
epee::math_helper::once_a_time_seconds<1> m_autodetect_interval;
|
||||
|
||||
@@ -40,12 +40,9 @@
|
||||
#define CRYPTONOTE_MAX_TX_SIZE 1000000
|
||||
#define CRYPTONOTE_MAX_TX_PER_BLOCK 0x10000000
|
||||
#define CRYPTONOTE_PUBLIC_ADDRESS_TEXTBLOB_VER 0
|
||||
#define CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW_V2 288
|
||||
#define CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW 60
|
||||
#define CURRENT_TRANSACTION_VERSION 2
|
||||
#define CURRENT_BLOCK_MAJOR_VERSION 7
|
||||
#define CURRENT_BLOCK_MINOR_VERSION 7
|
||||
#define BLOCK_HEADER_MINER_SIG 18
|
||||
#define CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT_V2 300*2
|
||||
#define CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT 60*60*2
|
||||
#define CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE 4
|
||||
@@ -90,9 +87,6 @@
|
||||
#define DIFFICULTY_BLOCKS_COUNT_V3 DIFFICULTY_WINDOW_V3 + 1 // added +1 to make N=N
|
||||
#define DIFFICULTY_BLOCKS_COUNT_V2 DIFFICULTY_WINDOW_V2 + 1 // added +1 to make N=N
|
||||
#define DIFFICULTY_BLOCKS_COUNT DIFFICULTY_WINDOW + DIFFICULTY_LAG
|
||||
#define DIFFICULTY_RESET_HEIGHT 331170// ~July 4, 2021 Pool Independence Day
|
||||
#define DIFFICULTY_RESET_LEVEL 100000000 // 100 mill
|
||||
|
||||
|
||||
#define CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V1 DIFFICULTY_TARGET_V1 * CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_BLOCKS
|
||||
#define CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V2 DIFFICULTY_TARGET_V2 * CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_BLOCKS
|
||||
@@ -134,8 +128,7 @@
|
||||
|
||||
#define CRYPTONOTE_MAX_FRAGMENTS 20 // ~20 * NOISE_BYTES max payload size for covert/noise send
|
||||
|
||||
#define COMMAND_RPC_GET_BLOCKS_FAST_MAX_BLOCK_COUNT 1000
|
||||
#define COMMAND_RPC_GET_BLOCKS_FAST_MAX_TX_COUNT 20000
|
||||
#define COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT 1000
|
||||
|
||||
#define P2P_LOCAL_WHITE_PEERLIST_LIMIT 1000
|
||||
#define P2P_LOCAL_GRAY_PEERLIST_LIMIT 5000
|
||||
@@ -167,6 +160,7 @@
|
||||
#define RPC_IP_FAILS_BEFORE_BLOCK 3
|
||||
|
||||
#define CRYPTONOTE_NAME "wownero"
|
||||
#define CRYPTONOTE_POOLDATA_FILENAME "poolstate.bin"
|
||||
#define CRYPTONOTE_BLOCKCHAINDATA_FILENAME "data.mdb"
|
||||
#define CRYPTONOTE_BLOCKCHAINDATA_LOCK_FILENAME "lock.mdb"
|
||||
#define P2P_NET_DATA_FILENAME "p2pstate.bin"
|
||||
@@ -193,8 +187,6 @@
|
||||
#define HF_VERSION_CLSAG 16
|
||||
#define HF_VERSION_DETERMINISTIC_UNLOCK_TIME 16
|
||||
#define HF_VERSION_DYNAMIC_UNLOCK 16
|
||||
#define HF_VERSION_FIXED_UNLOCK 18
|
||||
#define HF_VERSION_BULLETPROOF_PLUS 18
|
||||
|
||||
#define PER_KB_FEE_QUANTIZATION_DECIMALS 8
|
||||
|
||||
@@ -203,7 +195,6 @@
|
||||
#define DEFAULT_TXPOOL_MAX_WEIGHT 648000000ull // 3 days at 300000, in bytes
|
||||
|
||||
#define BULLETPROOF_MAX_OUTPUTS 16
|
||||
#define BULLETPROOF_PLUS_MAX_OUTPUTS 16
|
||||
|
||||
#define CRYPTONOTE_PRUNING_STRIPE_SIZE 4096 // the smaller, the smoother the increase
|
||||
#define CRYPTONOTE_PRUNING_LOG_STRIPES 3 // the higher, the more space saved
|
||||
@@ -212,8 +203,6 @@
|
||||
|
||||
#define RPC_CREDITS_PER_HASH_SCALE ((float)(1<<24))
|
||||
|
||||
#define DNS_BLOCKLIST_LIFETIME (86400 * 8)
|
||||
|
||||
// New constants are intended to go here
|
||||
namespace config
|
||||
{
|
||||
@@ -236,8 +225,6 @@ namespace config
|
||||
|
||||
// Hash domain separators
|
||||
const char HASH_KEY_BULLETPROOF_EXPONENT[] = "bulletproof";
|
||||
const char HASH_KEY_BULLETPROOF_PLUS_EXPONENT[] = "bulletproof_plus";
|
||||
const char HASH_KEY_BULLETPROOF_PLUS_TRANSCRIPT[] = "bulletproof_plus_transcript";
|
||||
const char HASH_KEY_RINGDB[] = "ringdsb";
|
||||
const char HASH_KEY_SUBADDRESS[] = "SubAddr";
|
||||
const unsigned char HASH_KEY_ENCRYPTED_PAYMENT_ID = 0x8d;
|
||||
|
||||
@@ -865,7 +865,7 @@ start:
|
||||
ss << "Re-locked, height " << height << ", tail id " << new_top_hash << (new_top_hash == top_hash ? "" : " (different)") << std::endl;
|
||||
top_hash = new_top_hash;
|
||||
uint8_t version = get_current_hard_fork_version();
|
||||
uint64_t difficulty_blocks_count = version <= 17 && version >= 11 ? DIFFICULTY_BLOCKS_COUNT_V3 : version <= 10 && version >= 8 ? DIFFICULTY_BLOCKS_COUNT_V2 : DIFFICULTY_BLOCKS_COUNT;
|
||||
uint64_t difficulty_blocks_count = version >= 11 ? DIFFICULTY_BLOCKS_COUNT_V3 : version <= 10 && version >= 8 ? DIFFICULTY_BLOCKS_COUNT_V2 : DIFFICULTY_BLOCKS_COUNT;
|
||||
|
||||
// ND: Speedup
|
||||
// 1. Keep a list of the last 735 (or less) blocks that is used to compute difficulty,
|
||||
@@ -948,7 +948,7 @@ start:
|
||||
|
||||
difficulty_type diff = next_difficulty(timestamps, m_nettype, difficulties, target, HEIGHT);
|
||||
|
||||
if (version <= 17 && version >= 11) {
|
||||
if (version >= 11) {
|
||||
diff = next_difficulty_v5(timestamps, m_nettype, difficulties, T, N, HEIGHT);
|
||||
} else if (version == 10) {
|
||||
diff = next_difficulty_v4(timestamps, m_nettype, difficulties, HEIGHT);
|
||||
@@ -983,7 +983,7 @@ start:
|
||||
MGINFO("START DUMP");
|
||||
MGINFO(ss.str());
|
||||
MGINFO("END DUMP");
|
||||
MGINFO("Please send wowario on IRC OTFC #wownero-dev the contents of this log, from a couple dozen lines before START DUMP to END DUMP");
|
||||
MGINFO("Please send wowario on Freenode #wownero-dev the contents of this log, from a couple dozen lines before START DUMP to END DUMP");
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
@@ -1015,7 +1015,7 @@ size_t Blockchain::recalculate_difficulties(boost::optional<uint64_t> start_heig
|
||||
const uint64_t top_height = m_db->height() - 1;
|
||||
MGINFO("Recalculating difficulties from height " << start_height << " to height " << top_height);
|
||||
uint8_t version = get_current_hard_fork_version();
|
||||
uint64_t difficulty_blocks_count = version <= 17 && version >= 11 ? DIFFICULTY_BLOCKS_COUNT_V3 : version <= 10 && version >= 8 ? DIFFICULTY_BLOCKS_COUNT_V2 : DIFFICULTY_BLOCKS_COUNT;
|
||||
uint64_t difficulty_blocks_count = version >= 11 ? DIFFICULTY_BLOCKS_COUNT_V3 : version <= 10 && version >= 8 ? DIFFICULTY_BLOCKS_COUNT_V2 : DIFFICULTY_BLOCKS_COUNT;
|
||||
std::vector<uint64_t> timestamps;
|
||||
std::vector<difficulty_type> difficulties;
|
||||
timestamps.reserve(difficulty_blocks_count + 1);
|
||||
@@ -1043,7 +1043,7 @@ size_t Blockchain::recalculate_difficulties(boost::optional<uint64_t> start_heig
|
||||
size_t target = get_ideal_hard_fork_version(height) < 2 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2;
|
||||
difficulty_type recalculated_diff = next_difficulty(timestamps, m_nettype, difficulties, target, HEIGHT);
|
||||
|
||||
if (version <= 17 && version >= 11) {
|
||||
if (version >= 11) {
|
||||
recalculated_diff = next_difficulty_v5(timestamps, m_nettype, difficulties, T, N, HEIGHT);
|
||||
} else if (version == 10) {
|
||||
recalculated_diff = next_difficulty_v4(timestamps, m_nettype, difficulties, HEIGHT);
|
||||
@@ -1297,7 +1297,8 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
|
||||
std::vector<difficulty_type> cumulative_difficulties;
|
||||
|
||||
uint8_t version = get_current_hard_fork_version();
|
||||
size_t difficulty_blocks_count = version <= 17 && version >= 11 ? DIFFICULTY_BLOCKS_COUNT_V3 : version <= 10 && version >= 8 ? DIFFICULTY_BLOCKS_COUNT_V2 : DIFFICULTY_BLOCKS_COUNT;
|
||||
size_t height = m_db->height();
|
||||
size_t difficulty_blocks_count = version >= 11 ? DIFFICULTY_BLOCKS_COUNT_V3 : version <= 10 && version >= 8 ? DIFFICULTY_BLOCKS_COUNT_V2 : DIFFICULTY_BLOCKS_COUNT;
|
||||
|
||||
// if the alt chain isn't long enough to calculate the difficulty target
|
||||
// based on its blocks alone, need to get more blocks from the main chain
|
||||
@@ -1356,7 +1357,7 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
|
||||
uint64_t HEIGHT = m_db->height();
|
||||
|
||||
// calculate the difficulty target for the block and return it
|
||||
if (version <= 17 && version >= 11) {
|
||||
if (version >= 11) {
|
||||
return next_difficulty_v5(timestamps, m_nettype, cumulative_difficulties, T, N, HEIGHT);
|
||||
} else if (version == 10) {
|
||||
return next_difficulty_v4(timestamps, m_nettype, cumulative_difficulties, HEIGHT);
|
||||
@@ -1377,40 +1378,6 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
|
||||
// a non-overflowing tx amount (dubious necessity on this check)
|
||||
bool Blockchain::prevalidate_miner_transaction(const block& b, uint64_t height, uint8_t hf_version)
|
||||
{
|
||||
// Miner Block Header Signing
|
||||
if (hf_version >= BLOCK_HEADER_MINER_SIG)
|
||||
{
|
||||
// sanity checks
|
||||
if (b.miner_tx.vout.size() != 1)
|
||||
{
|
||||
MWARNING("Only 1 output in miner transaction allowed");
|
||||
return false;
|
||||
}
|
||||
if (b.miner_tx.vout[0].target.type() != typeid(txout_to_key))
|
||||
{
|
||||
MWARNING("Wrong txout type");
|
||||
return false;
|
||||
}
|
||||
if (b.vote > 2)
|
||||
{
|
||||
MWARNING("Vote integer must be either 0, 1, or 2");
|
||||
return false;
|
||||
}
|
||||
// keccak hash block header data and check miner signature
|
||||
// if signature is invalid, reject block
|
||||
crypto::hash sig_data = get_sig_data(b);
|
||||
crypto::signature signature = b.signature;
|
||||
crypto::public_key eph_pub_key = boost::get<txout_to_key>(b.miner_tx.vout[0].target).key;
|
||||
if (!crypto::check_signature(sig_data, eph_pub_key, signature))
|
||||
{
|
||||
MWARNING("Miner signature is invalid");
|
||||
return false;
|
||||
} else {
|
||||
LOG_PRINT_L1("Miner signature is good");
|
||||
LOG_PRINT_L1("Vote: " << b.vote);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.vin.size() == 1, false, "coinbase transaction in the block has no inputs");
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.vin[0].type() == typeid(txin_gen), false, "coinbase transaction in the block has the wrong type");
|
||||
@@ -1429,11 +1396,12 @@ bool Blockchain::prevalidate_miner_transaction(const block& b, uint64_t height,
|
||||
}
|
||||
MDEBUG("Miner tx hash: " << get_transaction_hash(b.miner_tx));
|
||||
|
||||
if (hf_version >= HF_VERSION_FIXED_UNLOCK)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.unlock_time == height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW_V2, false, "coinbase transaction transaction has the wrong unlock time="
|
||||
<< b.miner_tx.unlock_time << ", expected " << height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW_V2);
|
||||
} else if (hf_version < HF_VERSION_FIXED_UNLOCK && hf_version >= HF_VERSION_DYNAMIC_UNLOCK)
|
||||
// Dynamic unlock time from HF 16
|
||||
// To calculate unlock window, get the block hash at height-1337, convert the
|
||||
// first 3 characters from hexadecimal to decimal, multiply by 2, and then add 288.
|
||||
// Unlock minimum 1 day (288 blocks), maximum is ~29 days ((4095*2)+288 = 8478 blocks)
|
||||
// unlock time = unlock_window + height
|
||||
if (hf_version >= HF_VERSION_DYNAMIC_UNLOCK)
|
||||
{
|
||||
uint64_t N = m_nettype == MAINNET ? 1337 : 5;
|
||||
crypto::hash blk_id = get_block_id_by_height(height-N);
|
||||
@@ -1450,8 +1418,8 @@ bool Blockchain::prevalidate_miner_transaction(const block& b, uint64_t height,
|
||||
"\nblk_height: " << height-N << ", blk_id: " << blk_id <<
|
||||
"\nhex_str: " << hex_str << ", blk_num: " << blk_num);
|
||||
} else {
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.unlock_time == height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, false, "coinbase transaction transaction has the wrong unlock time="
|
||||
<< b.miner_tx.unlock_time << ", expected " << height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW);
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.unlock_time == height + 60, false, "coinbase transaction transaction has the wrong unlock time="
|
||||
<< b.miner_tx.unlock_time << ", expected " << height + 60);
|
||||
}
|
||||
|
||||
//check outs overflow
|
||||
@@ -1897,7 +1865,6 @@ bool Blockchain::complete_timestamps_vector(uint64_t start_top_height, std::vect
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
uint8_t version = get_current_hard_fork_version();
|
||||
size_t blockchain_timestamp_check_window = version >= 10 ? BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW_V2 : BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW;
|
||||
|
||||
if(timestamps.size() >= blockchain_timestamp_check_window)
|
||||
return true;
|
||||
|
||||
@@ -2813,7 +2780,7 @@ bool Blockchain::find_blockchain_supplement(const std::list<crypto::hash>& qbloc
|
||||
// find split point between ours and foreign blockchain (or start at
|
||||
// blockchain height <req_start_block>), and return up to max_count FULL
|
||||
// blocks by reference.
|
||||
bool Blockchain::find_blockchain_supplement(const uint64_t req_start_block, const std::list<crypto::hash>& qblock_ids, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata> > > >& blocks, uint64_t& total_height, uint64_t& start_height, bool pruned, bool get_miner_tx_hash, size_t max_block_count, size_t max_tx_count) const
|
||||
bool Blockchain::find_blockchain_supplement(const uint64_t req_start_block, const std::list<crypto::hash>& qblock_ids, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata> > > >& blocks, uint64_t& total_height, uint64_t& start_height, bool pruned, bool get_miner_tx_hash, size_t max_count) const
|
||||
{
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
@@ -2838,8 +2805,8 @@ bool Blockchain::find_blockchain_supplement(const uint64_t req_start_block, cons
|
||||
|
||||
db_rtxn_guard rtxn_guard(m_db);
|
||||
total_height = get_current_blockchain_height();
|
||||
blocks.reserve(std::min(std::min(max_block_count, (size_t)10000), (size_t)(total_height - start_height)));
|
||||
CHECK_AND_ASSERT_MES(m_db->get_blocks_from(start_height, 3, max_block_count, max_tx_count, FIND_BLOCKCHAIN_SUPPLEMENT_MAX_SIZE, blocks, pruned, true, get_miner_tx_hash),
|
||||
blocks.reserve(std::min(std::min(max_count, (size_t)10000), (size_t)(total_height - start_height)));
|
||||
CHECK_AND_ASSERT_MES(m_db->get_blocks_from(start_height, 3, max_count, FIND_BLOCKCHAIN_SUPPLEMENT_MAX_SIZE, blocks, pruned, true, get_miner_tx_hash),
|
||||
false, "Error getting blocks");
|
||||
|
||||
return true;
|
||||
@@ -2870,44 +2837,32 @@ void Blockchain::flush_invalid_blocks()
|
||||
m_invalid_blocks.clear();
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool Blockchain::have_block_unlocked(const crypto::hash& id, int *where) const
|
||||
bool Blockchain::have_block(const crypto::hash& id) const
|
||||
{
|
||||
// WARNING: this function does not take m_blockchain_lock, and thus should only call read only
|
||||
// m_db functions which do not depend on one another (ie, no getheight + gethash(height-1), as
|
||||
// well as not accessing class members, even read only (ie, m_invalid_blocks). The caller must
|
||||
// lock if it is otherwise needed.
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
|
||||
if(m_db->block_exists(id))
|
||||
{
|
||||
LOG_PRINT_L2("block " << id << " found in main chain");
|
||||
if (where) *where = HAVE_BLOCK_MAIN_CHAIN;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(m_db->get_alt_block(id, NULL, NULL))
|
||||
{
|
||||
LOG_PRINT_L2("block " << id << " found in alternative chains");
|
||||
if (where) *where = HAVE_BLOCK_ALT_CHAIN;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(m_invalid_blocks.count(id))
|
||||
{
|
||||
LOG_PRINT_L2("block " << id << " found in m_invalid_blocks");
|
||||
if (where) *where = HAVE_BLOCK_INVALID;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool Blockchain::have_block(const crypto::hash& id, int *where) const
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
return have_block_unlocked(id, where);
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool Blockchain::handle_block_to_main_chain(const block& bl, block_verification_context& bvc, bool notify/* = true*/)
|
||||
{
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
@@ -3212,32 +3167,6 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
|
||||
}
|
||||
}
|
||||
|
||||
// from v18, allow bulletproofs plus
|
||||
if (hf_version < HF_VERSION_BULLETPROOF_PLUS) {
|
||||
if (tx.version >= 2) {
|
||||
const bool bulletproof_plus = rct::is_rct_bulletproof_plus(tx.rct_signatures.type);
|
||||
if (bulletproof_plus || !tx.rct_signatures.p.bulletproofs_plus.empty())
|
||||
{
|
||||
MERROR_VER("Bulletproofs plus are not allowed before v" << std::to_string(HF_VERSION_BULLETPROOF_PLUS));
|
||||
tvc.m_invalid_output = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// from v19, forbid bulletproofs
|
||||
if (hf_version > HF_VERSION_BULLETPROOF_PLUS) {
|
||||
if (tx.version >= 2) {
|
||||
const bool bulletproof = rct::is_rct_bulletproof(tx.rct_signatures.type);
|
||||
if (bulletproof)
|
||||
{
|
||||
MERROR_VER("Bulletproof range proofs are not allowed after v" + std::to_string(HF_VERSION_BULLETPROOF_PLUS));
|
||||
tvc.m_invalid_output = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
@@ -3278,7 +3207,7 @@ bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_pr
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof || rv.type == rct::RCTTypeBulletproof2 || rv.type == rct::RCTTypeSimpleBulletproof || rv.type == rct::RCTTypeCLSAG || rv.type == rct::RCTTypeBulletproofPlus)
|
||||
else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof || rv.type == rct::RCTTypeBulletproof2 || rv.type == rct::RCTTypeSimpleBulletproof || rv.type == rct::RCTTypeCLSAG)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(!pubkeys.empty() && !pubkeys[0].empty(), false, "empty pubkeys");
|
||||
rv.mixRing.resize(pubkeys.size());
|
||||
@@ -3291,14 +3220,6 @@ bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_pr
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (rv.type == rct::RCTTypeCLSAG)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(rv.p.CLSAGs.size() == tx.vin.size(), false, "Bad CLSAGs size");
|
||||
for (size_t n = 0; n < tx.vin.size(); ++n)
|
||||
{
|
||||
rv.p.CLSAGs[n].I = rct::ki2rct(boost::get<txin_to_key>(tx.vin[n]).k_image);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(false, false, "Unsupported rct tx type: " + boost::lexical_cast<std::string>(rv.type));
|
||||
@@ -3327,7 +3248,7 @@ bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_pr
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (rv.type == rct::RCTTypeCLSAG || rv.type == rct::RCTTypeBulletproofPlus)
|
||||
else if (rv.type == rct::RCTTypeCLSAG)
|
||||
{
|
||||
if (!tx.pruned)
|
||||
{
|
||||
@@ -3432,9 +3353,9 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
|
||||
}
|
||||
}
|
||||
|
||||
if (((hf_version == HF_VERSION_MIN_MIXIN_21 || hf_version == HF_VERSION_MIN_MIXIN_21+1) && min_actual_mixin != 10) || (hf_version >= HF_VERSION_MIN_MIXIN_21+2 && min_actual_mixin > 21))
|
||||
if (((hf_version == HF_VERSION_MIN_MIXIN_21 || hf_version == HF_VERSION_MIN_MIXIN_21+1) && min_actual_mixin != 21) || (hf_version >= HF_VERSION_MIN_MIXIN_21+2 && min_actual_mixin > 21))
|
||||
{
|
||||
MERROR_VER("Tx " << get_transaction_hash(tx) << " has invalid ring size (" << (min_actual_mixin + 1) << "), it should be 11");
|
||||
MERROR_VER("Tx " << get_transaction_hash(tx) << " has invalid ring size (" << (min_actual_mixin + 1) << "), it should be 22");
|
||||
tvc.m_low_mixin = true;
|
||||
return false;
|
||||
}
|
||||
@@ -3621,7 +3542,6 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
|
||||
case rct::RCTTypeBulletproof:
|
||||
case rct::RCTTypeBulletproof2:
|
||||
case rct::RCTTypeCLSAG:
|
||||
case rct::RCTTypeBulletproofPlus:
|
||||
{
|
||||
// check all this, either reconstructed (so should really pass), or not
|
||||
{
|
||||
@@ -3657,7 +3577,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
|
||||
}
|
||||
}
|
||||
|
||||
const size_t n_sigs = rv.type == rct::RCTTypeCLSAG || rv.type == rct::RCTTypeBulletproofPlus ? rv.p.CLSAGs.size() : rv.p.MGs.size();
|
||||
const size_t n_sigs = rv.type == rct::RCTTypeCLSAG ? rv.p.CLSAGs.size() : rv.p.MGs.size();
|
||||
if (n_sigs != tx.vin.size())
|
||||
{
|
||||
MERROR_VER("Failed to check ringct signatures: mismatched MGs/vin sizes");
|
||||
@@ -3666,7 +3586,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
|
||||
for (size_t n = 0; n < tx.vin.size(); ++n)
|
||||
{
|
||||
bool error;
|
||||
if (rv.type == rct::RCTTypeCLSAG || rv.type == rct::RCTTypeBulletproofPlus)
|
||||
if (rv.type == rct::RCTTypeCLSAG)
|
||||
error = memcmp(&boost::get<txin_to_key>(tx.vin[n]).k_image, &rv.p.CLSAGs[n].I, 32);
|
||||
else
|
||||
error = rv.p.MGs[n].II.empty() || memcmp(&boost::get<txin_to_key>(tx.vin[n]).k_image, &rv.p.MGs[n].II[0], 32);
|
||||
@@ -3782,19 +3702,6 @@ void Blockchain::check_ring_signature(const crypto::hash &tx_prefix_hash, const
|
||||
result = crypto::check_ring_signature(tx_prefix_hash, key_image, p_output_keys, sig.data()) ? 1 : 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
uint64_t Blockchain::get_fee_quantization_mask()
|
||||
{
|
||||
static uint64_t mask = 0;
|
||||
if (mask == 0)
|
||||
{
|
||||
mask = 1;
|
||||
for (size_t n = PER_KB_FEE_QUANTIZATION_DECIMALS; n < CRYPTONOTE_DISPLAY_DECIMAL_POINT; ++n)
|
||||
mask *= 10;
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
uint64_t Blockchain::get_dynamic_base_fee(uint64_t block_reward, size_t median_block_weight, uint8_t version)
|
||||
{
|
||||
@@ -4900,8 +4807,6 @@ uint64_t Blockchain::prevalidate_block_hashes(uint64_t height, const std::vector
|
||||
|
||||
CHECK_AND_ASSERT_MES(weights.empty() || weights.size() == hashes.size(), 0, "Unexpected weights size");
|
||||
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
|
||||
// easy case: height >= hashes
|
||||
if (height >= m_blocks_hash_of_hashes.size() * HASH_OF_HASHES_STEP)
|
||||
return hashes.size();
|
||||
@@ -5541,7 +5446,7 @@ void Blockchain::cancel()
|
||||
}
|
||||
|
||||
#if defined(PER_BLOCK_CHECKPOINT)
|
||||
static const char expected_block_hashes_hash[] = "cdb3d018fc4c2505619423a24b2d694348103df9af9a3f4f0cc203f4e21363bd";
|
||||
static const char expected_block_hashes_hash[] = "bd1d32aed063dd71c1355dc950eb0fc22b10e41530029f54d40a0fd6f6b328f1";
|
||||
void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback& get_checkpoints)
|
||||
{
|
||||
if (get_checkpoints == nullptr || !m_fast_sync)
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "string_tools.h"
|
||||
#include "rolling_median.h"
|
||||
#include "cryptonote_basic/cryptonote_basic.h"
|
||||
#include "common/powerof.h"
|
||||
#include "common/util.h"
|
||||
#include "cryptonote_protocol/cryptonote_protocol_defs.h"
|
||||
#include "rpc/core_rpc_server_commands_defs.h"
|
||||
@@ -376,12 +377,10 @@ namespace cryptonote
|
||||
* for a block with the given hash
|
||||
*
|
||||
* @param id the hash to search for
|
||||
* @param where the type of block, if non NULL
|
||||
*
|
||||
* @return true if the block is known, else false
|
||||
*/
|
||||
bool have_block_unlocked(const crypto::hash& id, int *where = NULL) const;
|
||||
bool have_block(const crypto::hash& id, int *where = NULL) const;
|
||||
bool have_block(const crypto::hash& id) const;
|
||||
|
||||
/**
|
||||
* @brief gets the total number of transactions on the main chain
|
||||
@@ -466,12 +465,11 @@ namespace cryptonote
|
||||
* @param total_height return-by-reference our current blockchain height
|
||||
* @param start_height return-by-reference the height of the first block returned
|
||||
* @param pruned whether to return full or pruned tx blobs
|
||||
* @param max_block_count the max number of blocks to get
|
||||
* @param max_tx_count the max number of txes to get (it can get overshot by the last block's number of txes minus 1)
|
||||
* @param max_count the max number of blocks to get
|
||||
*
|
||||
* @return true if a block found in common or req_start_block specified, else false
|
||||
*/
|
||||
bool find_blockchain_supplement(const uint64_t req_start_block, const std::list<crypto::hash>& qblock_ids, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata> > > >& blocks, uint64_t& total_height, uint64_t& start_height, bool pruned, bool get_miner_tx_hash, size_t max_block_count, size_t max_tx_count) const;
|
||||
bool find_blockchain_supplement(const uint64_t req_start_block, const std::list<crypto::hash>& qblock_ids, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata> > > >& blocks, uint64_t& total_height, uint64_t& start_height, bool pruned, bool get_miner_tx_hash, size_t max_count) const;
|
||||
|
||||
/**
|
||||
* @brief retrieves a set of blocks and their transactions, and possibly other transactions
|
||||
@@ -594,7 +592,10 @@ namespace cryptonote
|
||||
*
|
||||
* @return the fee quantized mask
|
||||
*/
|
||||
static uint64_t get_fee_quantization_mask();
|
||||
static uint64_t get_fee_quantization_mask()
|
||||
{
|
||||
return tools::PowerOf<10, CRYPTONOTE_DISPLAY_DECIMAL_POINT - PER_KB_FEE_QUANTIZATION_DECIMALS>::Value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get dynamic per kB or byte fee for a given block weight
|
||||
|
||||
@@ -56,9 +56,6 @@ using namespace epee;
|
||||
#include "common/notify.h"
|
||||
#include "hardforks/hardforks.h"
|
||||
#include "version.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "cn"
|
||||
@@ -916,16 +913,6 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
static bool is_canonical_bulletproof_plus_layout(const std::vector<rct::BulletproofPlus> &proofs)
|
||||
{
|
||||
if (proofs.size() != 1)
|
||||
return false;
|
||||
const size_t sz = proofs[0].V.size();
|
||||
if (sz == 0 || sz > BULLETPROOF_PLUS_MAX_OUTPUTS)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::handle_incoming_tx_accumulated_batch(std::vector<tx_verification_batch_info> &tx_info, bool keeped_by_block)
|
||||
{
|
||||
bool ret = true;
|
||||
@@ -992,17 +979,6 @@ namespace cryptonote
|
||||
}
|
||||
rvv.push_back(&rv); // delayed batch verification
|
||||
break;
|
||||
case rct::RCTTypeBulletproofPlus:
|
||||
if (!is_canonical_bulletproof_plus_layout(rv.p.bulletproofs_plus))
|
||||
{
|
||||
MERROR_VER("Bulletproof_plus does not have canonical form");
|
||||
set_semantics_failed(tx_info[n].tx_hash);
|
||||
tx_info[n].tvc.m_verifivation_failed = true;
|
||||
tx_info[n].result = false;
|
||||
break;
|
||||
}
|
||||
rvv.push_back(&rv); // delayed batch verification
|
||||
break;
|
||||
default:
|
||||
MERROR_VER("Unknown rct type: " << rv.type);
|
||||
set_semantics_failed(tx_info[n].tx_hash);
|
||||
@@ -1020,7 +996,7 @@ namespace cryptonote
|
||||
{
|
||||
if (!tx_info[n].result)
|
||||
continue;
|
||||
if (tx_info[n].tx->rct_signatures.type != rct::RCTTypeBulletproof && tx_info[n].tx->rct_signatures.type != rct::RCTTypeBulletproof2 && tx_info[n].tx->rct_signatures.type != rct::RCTTypeCLSAG && tx_info[n].tx->rct_signatures.type != rct::RCTTypeBulletproofPlus)
|
||||
if (tx_info[n].tx->rct_signatures.type != rct::RCTTypeBulletproof && tx_info[n].tx->rct_signatures.type != rct::RCTTypeBulletproof2 && tx_info[n].tx->rct_signatures.type != rct::RCTTypeCLSAG)
|
||||
continue;
|
||||
if (assumed_bad || !rct::verRctSemanticsSimple(tx_info[n].tx->rct_signatures))
|
||||
{
|
||||
@@ -1470,9 +1446,9 @@ namespace cryptonote
|
||||
return m_blockchain_storage.find_blockchain_supplement(qblock_ids, clip_pruned, resp);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::find_blockchain_supplement(const uint64_t req_start_block, const std::list<crypto::hash>& qblock_ids, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata> > > >& blocks, uint64_t& total_height, uint64_t& start_height, bool pruned, bool get_miner_tx_hash, size_t max_block_count, size_t max_tx_count) const
|
||||
bool core::find_blockchain_supplement(const uint64_t req_start_block, const std::list<crypto::hash>& qblock_ids, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata> > > >& blocks, uint64_t& total_height, uint64_t& start_height, bool pruned, bool get_miner_tx_hash, size_t max_count) const
|
||||
{
|
||||
return m_blockchain_storage.find_blockchain_supplement(req_start_block, qblock_ids, blocks, total_height, start_height, pruned, get_miner_tx_hash, max_block_count, max_tx_count);
|
||||
return m_blockchain_storage.find_blockchain_supplement(req_start_block, qblock_ids, blocks, total_height, start_height, pruned, get_miner_tx_hash, max_count);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::get_outs(const COMMAND_RPC_GET_OUTPUTS_BIN::request& req, COMMAND_RPC_GET_OUTPUTS_BIN::response& res) const
|
||||
@@ -1689,14 +1665,9 @@ namespace cryptonote
|
||||
return m_mempool.get_transactions_count(include_sensitive_txes);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::have_block_unlocked(const crypto::hash& id, int *where) const
|
||||
bool core::have_block(const crypto::hash& id) const
|
||||
{
|
||||
return m_blockchain_storage.have_block_unlocked(id, where);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::have_block(const crypto::hash& id, int *where) const
|
||||
{
|
||||
return m_blockchain_storage.have_block(id, where);
|
||||
return m_blockchain_storage.have_block(id);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::parse_tx_from_blob(transaction& tx, crypto::hash& tx_hash, const blobdata& blob) const
|
||||
@@ -1767,27 +1738,6 @@ namespace cryptonote
|
||||
return m_blockchain_storage.get_block_by_hash(h, blk, orphan);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
std::string core::get_addy() const
|
||||
{
|
||||
std::string addy;
|
||||
std::ifstream file; file.open("address.txt");
|
||||
if (file.is_open())
|
||||
{
|
||||
file >> addy;
|
||||
if (addy.length() == 97 && addy.rfind("WW", 0) == 0)
|
||||
{
|
||||
return addy;
|
||||
} else {
|
||||
addy = "0";
|
||||
}
|
||||
}
|
||||
if (file.fail())
|
||||
{
|
||||
addy = "0";
|
||||
}
|
||||
return addy;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
std::string core::print_pool(bool short_format) const
|
||||
{
|
||||
return m_mempool.print_pool(short_format);
|
||||
@@ -1808,51 +1758,37 @@ namespace cryptonote
|
||||
main_message = "The daemon is running offline and will not attempt to sync to the Monero network.";
|
||||
else
|
||||
main_message = "The daemon will start synchronizing with the network. This may take a long time to complete.";
|
||||
MGINFO_YELLOW(ENDL <<
|
||||
"\n\n"
|
||||
" ██╗██╗ ██╗███╗ ██╗██╗ ██╗██╗███████╗ \n"
|
||||
" ██║██║ ██║████╗ ██║██║ ██╔╝██║██╔════╝ \n"
|
||||
" ██║██║ ██║██╔██╗ ██║█████╔╝ ██║█████╗ \n"
|
||||
" ██ ██║██║ ██║██║╚██╗██║██╔═██╗ ██║██╔══╝ \n"
|
||||
" ╚█████╔╝╚██████╔╝██║ ╚████║██║ ██╗██║███████╗ \n"
|
||||
" ╚════╝ ╚═════╝ ╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝╚══════╝ "
|
||||
<< ENDL);
|
||||
MGINFO_MAGENTA(ENDL <<
|
||||
" @@@@&///////////////@ \n"
|
||||
" @@@@@@@@@@@@@@@@*/////////////////////#@ \n"
|
||||
" @#////////(&@@@@//////////////////////////////////@ \n"
|
||||
" @&////////////////////////////#@@@@@@@ *////////@ \n"
|
||||
" @%///////////////////////////&@@@@@@/ /////&@ \n"
|
||||
" @@//////////////////////////%@@@@@@ */////@ \n"
|
||||
" @@#//////////////#@@@@@@@@@@@@@@@& ,///////////* /////#@ \n"
|
||||
" @///////////*@@@@@@@@@@@@@ .////////////@@@#//////&@ \n"
|
||||
" @(///////////%@@@@/,%&&/ ,//////. */////////(@@@%///#@ \n"
|
||||
" @%//////////// *//////////////////////////// //////////@@@@///& \n"
|
||||
"@%//////////. *///////////////S/v/n/g/V/f/G/u/r/C/b/b/e//////@@@@/// \n"
|
||||
" @////////////*.///////%/////////////Z/n/a/f/Z/b/a/r/l/////////@@@(// \n"
|
||||
" @@@#////////////..///@@@(///////////////////////////////////@@@/// \n"
|
||||
" @@#//////////. //&@@(//////////////////////////((((*////(//// \n"
|
||||
" &//////// ///@@%////////////////////(((((((((,*///////// \n"
|
||||
" //&@@///////////((((%%%%(/////%%%%(,*//////// \n"
|
||||
" .//@@@/////////*(((///%%//%//%%/////*///////# \n"
|
||||
" //(@@@@////////**////(%%%%%%%%%//////**////// \n"
|
||||
" ////////////////,/////%%%//%%////////#*//// \n"
|
||||
" .////////////////*///////////////..,**///// \n"
|
||||
" ,////////////////*/////#...,***////////// \n"
|
||||
" &////////////////*,,**///////////////// \n"
|
||||
" #/////////////////////////////////// \n"
|
||||
" %/////////////////////////////// \n"
|
||||
" ////////////////////////// \n"
|
||||
" //////////////// "
|
||||
<< ENDL);
|
||||
MGINFO_YELLOW(ENDL <<
|
||||
" ██╗███████╗███████╗███████╗ \n"
|
||||
" ██║██╔════╝██╔════╝██╔════╝ \n"
|
||||
" ██║█████╗ █████╗ █████╗ \n"
|
||||
" ██ ██║██╔══╝ ██╔══╝ ██╔══╝ \n"
|
||||
" ╚█████╔╝███████╗██║ ██║ \n"
|
||||
" ╚════╝ ╚══════╝╚═╝ ╚═╝ \n"
|
||||
"\n\n" << ENDL);
|
||||
MGINFO_MAGENTA(ENDL <<
|
||||
"\n \n"
|
||||
" ... . -..- \n"
|
||||
" `-. .-'. \n"
|
||||
" `-. -./\\.- .-' \n"
|
||||
" -. /__\\ .- \n"
|
||||
" `-. `/__|_\\' .-'. \n"
|
||||
" `-. -./ .-- \\.- ' \n"
|
||||
" `-. / <(O)> \\ .-' \n"
|
||||
" - .`/__ .-- ___\\ .- Magnus \n"
|
||||
" ,...`-./___|__|__|__\\.-'.,. Frater \n"
|
||||
" -.. .-. ..- --. ... Spectat Te \n"
|
||||
" .-. --- -.-. -.- -. .-. --- .-.. .-.. \n"
|
||||
" ,-' ________________ `-, \n"
|
||||
" /'/____|_____|_____\\ \n"
|
||||
" / /__|___|___|___|___\\ \n"
|
||||
" / /|_____|_____|____|__\\ \n"
|
||||
" ' /_____|____|_____|_____\\ \n"
|
||||
" ' /__|_____|______|_____|__\\ \n"
|
||||
" /' /_|_____|_____|_____|____|_\\ \n"
|
||||
" .. - . .-. .- - .. ...- ./ /____|_____|_____|_____|_____\\-.. .. ... -.-. --- ..- .-. ... .\n"
|
||||
" / /__|_____|_____|_____|_____|___\\ \n"
|
||||
" / /|_____|_____|_____|_____|_____|_\\ \n"
|
||||
" / /____|_____|_____|_____|_____|_____\\ \n"
|
||||
" / /__|_____|_____|_____|_____|_____|___\\ \n"
|
||||
" / /|_____|_____|_____|_____|_____|_____|_\\ \n"
|
||||
" / /____|_____|_____|_____|_____|_____|_____\\ \n"
|
||||
" \\ /___________.-- --- .-- -. . .-. ---_______\\ \n"
|
||||
" IV.I.MMXVIII \n"
|
||||
" .- / -... .-.. .- -.-. -.- .... .- - / -.-. ..- .-.. - ..- .-. . \n"
|
||||
"\n \n" << ENDL);
|
||||
MGINFO_YELLOW(ENDL << "**********************************************************************" << ENDL
|
||||
<< main_message << ENDL
|
||||
<< ENDL
|
||||
|
||||
@@ -55,8 +55,6 @@
|
||||
PUSH_WARNINGS
|
||||
DISABLE_VS_WARNINGS(4355)
|
||||
|
||||
enum { HAVE_BLOCK_MAIN_CHAIN, HAVE_BLOCK_ALT_CHAIN, HAVE_BLOCK_INVALID };
|
||||
|
||||
namespace cryptonote
|
||||
{
|
||||
struct test_options {
|
||||
@@ -226,14 +224,14 @@ namespace cryptonote
|
||||
*
|
||||
* @return true if the block was added to the main chain, otherwise false
|
||||
*/
|
||||
virtual bool handle_block_found(block& b, block_verification_context &bvc);
|
||||
virtual bool handle_block_found(block& b, block_verification_context &bvc) override;
|
||||
|
||||
/**
|
||||
* @copydoc Blockchain::create_block_template
|
||||
*
|
||||
* @note see Blockchain::create_block_template
|
||||
*/
|
||||
virtual bool get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash);
|
||||
virtual bool get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash) override;
|
||||
virtual bool get_block_template(block& b, const crypto::hash *prev_block, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash);
|
||||
|
||||
/**
|
||||
@@ -545,8 +543,7 @@ namespace cryptonote
|
||||
*
|
||||
* @note see Blockchain::have_block
|
||||
*/
|
||||
bool have_block_unlocked(const crypto::hash& id, int *where = NULL) const;
|
||||
bool have_block(const crypto::hash& id, int *where = NULL) const;
|
||||
bool have_block(const crypto::hash& id) const;
|
||||
|
||||
/**
|
||||
* @copydoc Blockchain::get_short_chain_history
|
||||
@@ -567,7 +564,7 @@ namespace cryptonote
|
||||
*
|
||||
* @note see Blockchain::find_blockchain_supplement(const uint64_t, const std::list<crypto::hash>&, std::vector<std::pair<cryptonote::blobdata, std::vector<transaction> > >&, uint64_t&, uint64_t&, size_t) const
|
||||
*/
|
||||
bool find_blockchain_supplement(const uint64_t req_start_block, const std::list<crypto::hash>& qblock_ids, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata> > > >& blocks, uint64_t& total_height, uint64_t& start_height, bool pruned, bool get_miner_tx_hash, size_t max_block_count, size_t max_tx_count) const;
|
||||
bool find_blockchain_supplement(const uint64_t req_start_block, const std::list<crypto::hash>& qblock_ids, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata> > > >& blocks, uint64_t& total_height, uint64_t& start_height, bool pruned, bool get_miner_tx_hash, size_t max_count) const;
|
||||
|
||||
/**
|
||||
* @copydoc Blockchain::get_tx_outputs_gindexs
|
||||
@@ -633,13 +630,6 @@ namespace cryptonote
|
||||
*/
|
||||
const Blockchain& get_blockchain_storage()const{return m_blockchain_storage;}
|
||||
|
||||
/**
|
||||
* @brief gets addy
|
||||
*
|
||||
* @note get addy
|
||||
*/
|
||||
std::string get_addy() const;
|
||||
|
||||
/**
|
||||
* @copydoc tx_memory_pool::print_pool
|
||||
*
|
||||
|
||||
@@ -167,10 +167,7 @@ namespace cryptonote
|
||||
tx.version = 1;
|
||||
|
||||
//lock
|
||||
if (hard_fork_version >= HF_VERSION_FIXED_UNLOCK)
|
||||
{
|
||||
tx.unlock_time = height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW_V2;
|
||||
} else if (hard_fork_version < HF_VERSION_FIXED_UNLOCK && hard_fork_version >= HF_VERSION_DYNAMIC_UNLOCK)
|
||||
if (hard_fork_version >= HF_VERSION_DYNAMIC_UNLOCK)
|
||||
{
|
||||
uint64_t N = m_nettype == MAINNET ? 1337 : 5;
|
||||
crypto::hash blk_id = pb->get_block_id_by_height(height-N);
|
||||
@@ -179,7 +176,7 @@ namespace cryptonote
|
||||
uint64_t unlock_window = blk_num + 288;
|
||||
tx.unlock_time = height + unlock_window;
|
||||
} else {
|
||||
tx.unlock_time = height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW;
|
||||
tx.unlock_time = height + 60;
|
||||
}
|
||||
tx.vin.push_back(in);
|
||||
|
||||
|
||||
@@ -45,10 +45,10 @@ namespace cryptonote
|
||||
typedef std::pair<uint64_t, rct::ctkey> output_entry;
|
||||
|
||||
std::vector<output_entry> outputs; //index + key + optional ringct commitment
|
||||
uint64_t real_output; //index in outputs vector of real output_entry
|
||||
size_t real_output; //index in outputs vector of real output_entry
|
||||
crypto::public_key real_out_tx_key; //incoming real tx public key
|
||||
std::vector<crypto::public_key> real_out_additional_tx_keys; //incoming real tx additional public keys
|
||||
uint64_t real_output_in_tx_index; //index in transaction outputs vector
|
||||
size_t real_output_in_tx_index; //index in transaction outputs vector
|
||||
uint64_t amount; //money
|
||||
bool rct; //true if the output is rct
|
||||
rct::key mask; //ringct amount mask
|
||||
|
||||
@@ -1422,10 +1422,7 @@ namespace cryptonote
|
||||
txpool_tx_meta_t meta;
|
||||
if (!m_blockchain.get_txpool_tx_meta(sorted_it->second, meta))
|
||||
{
|
||||
static bool warned = false;
|
||||
if (!warned)
|
||||
MERROR(" failed to find tx meta: " << sorted_it->second << " (will only print once)");
|
||||
warned = true;
|
||||
MDEBUG(" failed to find tx meta");
|
||||
continue;
|
||||
}
|
||||
LOG_PRINT_L2("Considering " << sorted_it->second << ", weight " << meta.weight << ", current block weight " << total_weight << "/" << max_total_weight << ", current coinbase " << print_money(best_coinbase) << ", relay method " << (unsigned)meta.get_relay_method());
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <boost/program_options/variables_map.hpp>
|
||||
#include <string>
|
||||
|
||||
#include "byte_slice.h"
|
||||
#include "math_helper.h"
|
||||
#include "storages/levin_abstract_invoke2.h"
|
||||
#include "warnings.h"
|
||||
@@ -100,7 +101,7 @@ namespace cryptonote
|
||||
void set_p2p_endpoint(nodetool::i_p2p_endpoint<connection_context>* p2p);
|
||||
//bool process_handshake_data(const blobdata& data, cryptonote_connection_context& context);
|
||||
bool process_payload_sync_data(const CORE_SYNC_DATA& hshd, cryptonote_connection_context& context, bool is_inital);
|
||||
bool get_payload_sync_data(blobdata& data);
|
||||
bool get_payload_sync_data(epee::byte_slice& data);
|
||||
bool get_payload_sync_data(CORE_SYNC_DATA& hshd);
|
||||
bool on_callback(cryptonote_connection_context& context);
|
||||
t_core& get_core(){return m_core;}
|
||||
@@ -149,7 +150,7 @@ namespace cryptonote
|
||||
bool update_sync_search();
|
||||
int try_add_next_blocks(cryptonote_connection_context &context);
|
||||
void notify_new_stripe(cryptonote_connection_context &context, uint32_t stripe);
|
||||
size_t skip_unneeded_hashes(cryptonote_connection_context& context, bool check_block_queue) const;
|
||||
void skip_unneeded_hashes(cryptonote_connection_context& context, bool check_block_queue) const;
|
||||
bool request_txpool_complement(cryptonote_connection_context &context);
|
||||
void hit_score(cryptonote_connection_context &context, int32_t score);
|
||||
|
||||
@@ -194,10 +195,10 @@ namespace cryptonote
|
||||
bool post_notify(typename t_parameter::request& arg, cryptonote_connection_context& context)
|
||||
{
|
||||
LOG_PRINT_L2("[" << epee::net_utils::print_connection_context_short(context) << "] post " << typeid(t_parameter).name() << " -->");
|
||||
std::string blob;
|
||||
epee::serialization::store_t_to_binary(arg, blob);
|
||||
epee::byte_slice blob;
|
||||
epee::serialization::store_t_to_binary(arg, blob, 256 * 1024); // optimize for block responses
|
||||
//handler_response_blocks_now(blob.size()); // XXX
|
||||
return m_p2p->invoke_notify_to_peer(t_parameter::ID, epee::strspan<uint8_t>(blob), context);
|
||||
return m_p2p->invoke_notify_to_peer(t_parameter::ID, epee::to_span(blob), context);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -137,42 +137,7 @@ namespace cryptonote
|
||||
CHECK_AND_ASSERT_MES_CC( context.m_callback_request_count > 0, false, "false callback fired, but context.m_callback_request_count=" << context.m_callback_request_count);
|
||||
--context.m_callback_request_count;
|
||||
|
||||
uint32_t notified = true;
|
||||
if (context.m_idle_peer_notification.compare_exchange_strong(notified, not notified))
|
||||
{
|
||||
if (context.m_state == cryptonote_connection_context::state_synchronizing && context.m_last_request_time != boost::date_time::not_a_date_time)
|
||||
{
|
||||
const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
|
||||
const boost::posix_time::time_duration dt = now - context.m_last_request_time;
|
||||
const auto ms = dt.total_microseconds();
|
||||
if (ms > IDLE_PEER_KICK_TIME || (context.m_expect_response && ms > NON_RESPONSIVE_PEER_KICK_TIME))
|
||||
{
|
||||
if (context.m_score-- >= 0)
|
||||
{
|
||||
MINFO(context << " kicking idle peer, last update " << (dt.total_microseconds() / 1.e6) << " seconds ago, expecting " << (int)context.m_expect_response);
|
||||
context.m_last_request_time = boost::date_time::not_a_date_time;
|
||||
context.m_expect_response = 0;
|
||||
context.m_expect_height = 0;
|
||||
context.m_state = cryptonote_connection_context::state_standby; // we'll go back to adding, then (if we can't), download
|
||||
}
|
||||
else
|
||||
{
|
||||
MINFO(context << "dropping idle peer with negative score");
|
||||
drop_connection_with_score(context, context.m_expect_response == 0 ? 1 : 5, false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
notified = true;
|
||||
if (context.m_new_stripe_notification.compare_exchange_strong(notified, not notified))
|
||||
{
|
||||
if (context.m_state == cryptonote_connection_context::state_normal)
|
||||
context.m_state = cryptonote_connection_context::state_synchronizing;
|
||||
}
|
||||
|
||||
if(context.m_state == cryptonote_connection_context::state_synchronizing && context.m_last_request_time == boost::posix_time::not_a_date_time)
|
||||
if(context.m_state == cryptonote_connection_context::state_synchronizing)
|
||||
{
|
||||
NOTIFY_REQUEST_CHAIN::request r = {};
|
||||
context.m_needed_objects.clear();
|
||||
@@ -444,7 +409,6 @@ namespace cryptonote
|
||||
++context.m_callback_request_count;
|
||||
m_p2p->request_callback(context);
|
||||
MLOG_PEER_STATE("requesting callback");
|
||||
context.m_num_requested = 0;
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -462,7 +426,7 @@ namespace cryptonote
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
bool t_cryptonote_protocol_handler<t_core>::get_payload_sync_data(blobdata& data)
|
||||
bool t_cryptonote_protocol_handler<t_core>::get_payload_sync_data(epee::byte_slice& data)
|
||||
{
|
||||
CORE_SYNC_DATA hsd = {};
|
||||
get_payload_sync_data(hsd);
|
||||
@@ -1676,22 +1640,8 @@ namespace cryptonote
|
||||
+ std::to_string(previous_stripe) + " -> " + std::to_string(current_stripe);
|
||||
if (ELPP->vRegistry()->allowed(el::Level::Debug, "sync-info"))
|
||||
timing_message += std::string(": ") + m_block_queue.get_overview(current_blockchain_height);
|
||||
uint64_t num = (rand() % 4) + 1;
|
||||
switch (num)
|
||||
{
|
||||
case 1:
|
||||
MGINFO_MAGENTA("Synced " << current_blockchain_height << "/" << target_blockchain_height << progress_message << timing_message);
|
||||
break;
|
||||
case 2:
|
||||
MGINFO_YELLOW("Synced " << current_blockchain_height << "/" << target_blockchain_height << progress_message << timing_message);
|
||||
break;
|
||||
case 3:
|
||||
MGINFO_BLUE("Synced " << current_blockchain_height << "/" << target_blockchain_height << progress_message << timing_message);
|
||||
break;
|
||||
case 4:
|
||||
MGINFO_GREEN("Synced " << current_blockchain_height << "/" << target_blockchain_height << progress_message << timing_message);
|
||||
break;
|
||||
}
|
||||
MGINFO_YELLOW("Synced " << current_blockchain_height << "/" << target_blockchain_height
|
||||
<< progress_message << timing_message);
|
||||
if (previous_stripe != current_stripe)
|
||||
notify_new_stripe(context, current_stripe);
|
||||
}
|
||||
@@ -1737,7 +1687,7 @@ skip:
|
||||
const uint32_t peer_stripe = tools::get_pruning_stripe(context.m_pruning_seed);
|
||||
if (stripe && peer_stripe && peer_stripe != stripe)
|
||||
return true;
|
||||
context.m_new_stripe_notification = true;
|
||||
context.m_state = cryptonote_connection_context::state_synchronizing;
|
||||
LOG_PRINT_CCONTEXT_L2("requesting callback");
|
||||
++context.m_callback_request_count;
|
||||
m_p2p->request_callback(context);
|
||||
@@ -1760,6 +1710,7 @@ skip:
|
||||
bool t_cryptonote_protocol_handler<t_core>::kick_idle_peers()
|
||||
{
|
||||
MTRACE("Checking for idle peers...");
|
||||
std::vector<std::pair<boost::uuids::uuid, unsigned>> idle_peers;
|
||||
m_p2p->for_each_connection([&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)->bool
|
||||
{
|
||||
if (context.m_state == cryptonote_connection_context::state_synchronizing && context.m_last_request_time != boost::date_time::not_a_date_time)
|
||||
@@ -1769,16 +1720,36 @@ skip:
|
||||
const auto ms = dt.total_microseconds();
|
||||
if (ms > IDLE_PEER_KICK_TIME || (context.m_expect_response && ms > NON_RESPONSIVE_PEER_KICK_TIME))
|
||||
{
|
||||
context.m_idle_peer_notification = true;
|
||||
LOG_PRINT_CCONTEXT_L2("requesting callback");
|
||||
++context.m_callback_request_count;
|
||||
m_p2p->request_callback(context);
|
||||
MLOG_PEER_STATE("requesting callback");
|
||||
if (context.m_score-- >= 0)
|
||||
{
|
||||
MINFO(context << " kicking idle peer, last update " << (dt.total_microseconds() / 1.e6) << " seconds ago, expecting " << (int)context.m_expect_response);
|
||||
LOG_PRINT_CCONTEXT_L2("requesting callback");
|
||||
context.m_last_request_time = boost::date_time::not_a_date_time;
|
||||
context.m_expect_response = 0;
|
||||
context.m_expect_height = 0;
|
||||
context.m_state = cryptonote_connection_context::state_standby; // we'll go back to adding, then (if we can't), download
|
||||
++context.m_callback_request_count;
|
||||
m_p2p->request_callback(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
idle_peers.push_back(std::make_pair(context.m_connection_id, context.m_expect_response == 0 ? 1 : 5));
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
for (const auto &e: idle_peers)
|
||||
{
|
||||
const auto &uuid = e.first;
|
||||
m_p2p->for_connection(uuid, [&](cryptonote_connection_context& ctx, nodetool::peerid_type peer_id, uint32_t f)->bool{
|
||||
MINFO(ctx << "dropping idle peer with negative score");
|
||||
drop_connection_with_score(ctx, e.second, false);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -2019,7 +1990,7 @@ skip:
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
size_t t_cryptonote_protocol_handler<t_core>::skip_unneeded_hashes(cryptonote_connection_context& context, bool check_block_queue) const
|
||||
void t_cryptonote_protocol_handler<t_core>::skip_unneeded_hashes(cryptonote_connection_context& context, bool check_block_queue) const
|
||||
{
|
||||
// take out blocks we already have
|
||||
size_t skip = 0;
|
||||
@@ -2036,7 +2007,6 @@ skip:
|
||||
MDEBUG(context << "skipping " << skip << "/" << context.m_needed_objects.size() << " blocks");
|
||||
context.m_needed_objects = std::vector<std::pair<crypto::hash, uint64_t>>(context.m_needed_objects.begin() + skip, context.m_needed_objects.end());
|
||||
}
|
||||
return skip;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
@@ -2090,17 +2060,7 @@ skip:
|
||||
const size_t block_queue_size_threshold = m_block_download_max_size ? m_block_download_max_size : BLOCK_QUEUE_SIZE_THRESHOLD;
|
||||
bool queue_proceed = nspans < BLOCK_QUEUE_NSPANS_THRESHOLD || size < block_queue_size_threshold;
|
||||
// get rid of blocks we already requested, or already have
|
||||
if (skip_unneeded_hashes(context, true) && context.m_needed_objects.empty() && context.m_num_requested == 0)
|
||||
{
|
||||
if (context.m_remote_blockchain_height > m_block_queue.get_next_needed_height(bc_height))
|
||||
{
|
||||
MERROR(context << "Nothing we can request from this peer, and we did not request anything previously");
|
||||
return false;
|
||||
}
|
||||
MDEBUG(context << "Nothing to get from this peer, and it's not ahead of us, all done");
|
||||
context.m_state = cryptonote_connection_context::state_normal;
|
||||
return true;
|
||||
}
|
||||
skip_unneeded_hashes(context, true);
|
||||
uint64_t next_needed_height = m_block_queue.get_next_needed_height(bc_height);
|
||||
uint64_t next_block_height;
|
||||
if (context.m_needed_objects.empty())
|
||||
@@ -2236,17 +2196,7 @@ skip:
|
||||
context.m_last_response_height = 0;
|
||||
goto skip;
|
||||
}
|
||||
if (skip_unneeded_hashes(context, false) && context.m_needed_objects.empty() && context.m_num_requested == 0)
|
||||
{
|
||||
if (context.m_remote_blockchain_height > m_block_queue.get_next_needed_height(m_core.get_current_blockchain_height()))
|
||||
{
|
||||
MERROR(context << "Nothing we can request from this peer, and we did not request anything previously");
|
||||
return false;
|
||||
}
|
||||
MDEBUG(context << "Nothing to get from this peer, and it's not ahead of us, all done");
|
||||
context.m_state = cryptonote_connection_context::state_normal;
|
||||
return true;
|
||||
}
|
||||
skip_unneeded_hashes(context, false);
|
||||
|
||||
const uint64_t first_block_height = context.m_last_response_height - context.m_needed_objects.size() + 1;
|
||||
static const uint64_t bp_fork_height = m_core.get_earliest_ideal_height_for_version(HF_VERSION_SMALLER_BP);
|
||||
@@ -2343,22 +2293,35 @@ skip:
|
||||
<< "/" << tools::get_pruning_stripe(span.first + span.second - 1, context.m_remote_blockchain_height, CRYPTONOTE_PRUNING_LOG_STRIPES)
|
||||
<< ", ours " << tools::get_pruning_stripe(m_core.get_blockchain_pruning_seed()) << ", peer stripe " << tools::get_pruning_stripe(context.m_pruning_seed));
|
||||
|
||||
context.m_num_requested += req.blocks.size();
|
||||
post_notify<NOTIFY_REQUEST_GET_OBJECTS>(req, context);
|
||||
MLOG_PEER_STATE("requesting objects");
|
||||
return true;
|
||||
}
|
||||
|
||||
// we can do nothing, so drop this peer to make room for others unless we think we've downloaded all we need
|
||||
const uint64_t blockchain_height = m_core.get_current_blockchain_height();
|
||||
if (std::max(blockchain_height, m_block_queue.get_next_needed_height(blockchain_height)) >= m_core.get_target_blockchain_height())
|
||||
// if we're still around, we might be at a point where the peer is pruned, so we could either
|
||||
// drop it to make space for other peers, or ask for a span further down the line
|
||||
const uint32_t next_stripe = get_next_needed_pruning_stripe().first;
|
||||
const uint32_t peer_stripe = tools::get_pruning_stripe(context.m_pruning_seed);
|
||||
const uint32_t local_stripe = tools::get_pruning_stripe(m_core.get_blockchain_pruning_seed());
|
||||
if (!(m_sync_pruned_blocks && peer_stripe == local_stripe) && next_stripe && peer_stripe && next_stripe != peer_stripe)
|
||||
{
|
||||
// at this point, we have to either close the connection, or start getting blocks past the
|
||||
// current point, or become dormant
|
||||
MDEBUG(context << "this peer is pruned at seed " << epee::string_tools::to_string_hex(context.m_pruning_seed) <<
|
||||
", next stripe needed is " << next_stripe);
|
||||
if (!context.m_is_income)
|
||||
{
|
||||
if (should_drop_connection(context, next_stripe))
|
||||
{
|
||||
m_p2p->add_used_stripe_peer(context);
|
||||
return false; // drop outgoing connections
|
||||
}
|
||||
}
|
||||
// we'll get back stuck waiting for the go ahead
|
||||
context.m_state = cryptonote_connection_context::state_normal;
|
||||
MLOG_PEER_STATE("Nothing to do for now, switching to normal state");
|
||||
return true;
|
||||
}
|
||||
MLOG_PEER_STATE("We can download nothing from this peer, dropping");
|
||||
return false;
|
||||
}
|
||||
|
||||
skip:
|
||||
@@ -2598,6 +2561,17 @@ skip:
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::unordered_set<crypto::hash> hashes;
|
||||
for (const auto &h: arg.m_block_ids)
|
||||
{
|
||||
if (!hashes.insert(h).second)
|
||||
{
|
||||
LOG_ERROR_CCONTEXT("sent duplicate block, dropping connection");
|
||||
drop_connection(context, true, false);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t n_use_blocks = m_core.prevalidate_block_hashes(arg.start_height, arg.m_block_ids, arg.m_block_weights);
|
||||
if (n_use_blocks == 0 || n_use_blocks + HASH_OF_HASHES_STEP <= arg.m_block_ids.size())
|
||||
{
|
||||
@@ -2609,74 +2583,18 @@ skip:
|
||||
context.m_needed_objects.clear();
|
||||
uint64_t added = 0;
|
||||
std::unordered_set<crypto::hash> blocks_found;
|
||||
bool first = true;
|
||||
bool expect_unknown = false;
|
||||
for (size_t i = 0; i < arg.m_block_ids.size(); ++i)
|
||||
{
|
||||
if (!blocks_found.insert(arg.m_block_ids[i]).second)
|
||||
{
|
||||
LOG_ERROR_CCONTEXT("Duplicate blocks in chain entry response, dropping connection");
|
||||
drop_connection_with_score(context, 5, false);
|
||||
drop_connection(context, true, false);
|
||||
return 1;
|
||||
}
|
||||
int where;
|
||||
const bool have_block = m_core.have_block_unlocked(arg.m_block_ids[i], &where);
|
||||
if (first)
|
||||
{
|
||||
if (!have_block && !m_block_queue.requested(arg.m_block_ids[i]) && !m_block_queue.have(arg.m_block_ids[i]))
|
||||
{
|
||||
LOG_ERROR_CCONTEXT("First block hash is unknown, dropping connection");
|
||||
drop_connection_with_score(context, 5, false);
|
||||
return 1;
|
||||
}
|
||||
if (!have_block)
|
||||
expect_unknown = true;
|
||||
}
|
||||
if (!first)
|
||||
{
|
||||
// after the first, blocks may be known or unknown, but if they are known,
|
||||
// they should be at the same height if on the main chain
|
||||
if (have_block)
|
||||
{
|
||||
switch (where)
|
||||
{
|
||||
default:
|
||||
case HAVE_BLOCK_INVALID:
|
||||
LOG_ERROR_CCONTEXT("Block is invalid or known without known type, dropping connection");
|
||||
drop_connection(context, true, false);
|
||||
return 1;
|
||||
case HAVE_BLOCK_MAIN_CHAIN:
|
||||
if (expect_unknown)
|
||||
{
|
||||
LOG_ERROR_CCONTEXT("Block is on the main chain, but we did not expect a known block, dropping connection");
|
||||
drop_connection_with_score(context, 5, false);
|
||||
return 1;
|
||||
}
|
||||
if (m_core.get_block_id_by_height(arg.start_height + i) != arg.m_block_ids[i])
|
||||
{
|
||||
LOG_ERROR_CCONTEXT("Block is on the main chain, but not at the expected height, dropping connection");
|
||||
drop_connection_with_score(context, 5, false);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case HAVE_BLOCK_ALT_CHAIN:
|
||||
if (expect_unknown)
|
||||
{
|
||||
LOG_ERROR_CCONTEXT("Block is on the main chain, but we did not expect a known block, dropping connection");
|
||||
drop_connection_with_score(context, 5, false);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
expect_unknown = true;
|
||||
}
|
||||
const uint64_t block_weight = arg.m_block_weights.empty() ? 0 : arg.m_block_weights[i];
|
||||
context.m_needed_objects.push_back(std::make_pair(arg.m_block_ids[i], block_weight));
|
||||
if (++added == n_use_blocks)
|
||||
break;
|
||||
first = false;
|
||||
}
|
||||
context.m_last_response_height -= arg.m_block_ids.size() - n_use_blocks;
|
||||
|
||||
@@ -2690,7 +2608,6 @@ skip:
|
||||
if (arg.total_height > m_core.get_target_blockchain_height())
|
||||
m_core.set_target_blockchain_height(arg.total_height);
|
||||
|
||||
context.m_num_requested = 0;
|
||||
return 1;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -2707,7 +2624,6 @@ skip:
|
||||
std::vector<std::pair<epee::net_utils::zone, boost::uuids::uuid>> fullConnections, fluffyConnections;
|
||||
m_p2p->for_each_connection([this, &exclude_context, &fullConnections, &fluffyConnections](connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)
|
||||
{
|
||||
// peer_id also filters out connections before handshake
|
||||
if (peer_id && exclude_context.m_connection_id != context.m_connection_id && context.m_remote_address.get_zone() == epee::net_utils::zone::public_)
|
||||
{
|
||||
if(m_core.fluffy_blocks_enabled() && (support_flags & P2P_SUPPORT_FLAG_FLUFFY_BLOCKS))
|
||||
@@ -2727,15 +2643,15 @@ skip:
|
||||
// send fluffy ones first, we want to encourage people to run that
|
||||
if (!fluffyConnections.empty())
|
||||
{
|
||||
std::string fluffyBlob;
|
||||
epee::serialization::store_t_to_binary(fluffy_arg, fluffyBlob);
|
||||
m_p2p->relay_notify_to_list(NOTIFY_NEW_FLUFFY_BLOCK::ID, epee::strspan<uint8_t>(fluffyBlob), std::move(fluffyConnections));
|
||||
epee::byte_slice fluffyBlob;
|
||||
epee::serialization::store_t_to_binary(fluffy_arg, fluffyBlob, 32 * 1024);
|
||||
m_p2p->relay_notify_to_list(NOTIFY_NEW_FLUFFY_BLOCK::ID, epee::to_span(fluffyBlob), std::move(fluffyConnections));
|
||||
}
|
||||
if (!fullConnections.empty())
|
||||
{
|
||||
std::string fullBlob;
|
||||
epee::serialization::store_t_to_binary(arg, fullBlob);
|
||||
m_p2p->relay_notify_to_list(NOTIFY_NEW_BLOCK::ID, epee::strspan<uint8_t>(fullBlob), std::move(fullConnections));
|
||||
epee::byte_slice fullBlob;
|
||||
epee::serialization::store_t_to_binary(arg, fullBlob, 128 * 1024);
|
||||
m_p2p->relay_notify_to_list(NOTIFY_NEW_BLOCK::ID, epee::to_span(fullBlob), std::move(fullConnections));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
#include "byte_slice.h"
|
||||
#include "common/expect.h"
|
||||
#include "common/varint.h"
|
||||
#include "cryptonote_config.h"
|
||||
@@ -52,7 +53,7 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
int get_command_from_message(const cryptonote::blobdata &msg)
|
||||
int get_command_from_message(const epee::byte_slice &msg)
|
||||
{
|
||||
return msg.size() >= sizeof(epee::levin::bucket_head2) ? SWAP32LE(((epee::levin::bucket_head2*)msg.data())->m_command) : 0;
|
||||
}
|
||||
@@ -166,7 +167,7 @@ namespace levin
|
||||
return get_out_connections(p2p, get_blockchain_height(p2p, core));
|
||||
}
|
||||
|
||||
std::string make_tx_payload(std::vector<blobdata>&& txs, const bool pad, const bool fluff)
|
||||
epee::byte_slice make_tx_payload(std::vector<blobdata>&& txs, const bool pad, const bool fluff)
|
||||
{
|
||||
NOTIFY_NEW_TRANSACTIONS::request request{};
|
||||
request.txs = std::move(txs);
|
||||
@@ -188,7 +189,7 @@ namespace levin
|
||||
padding -= overhead;
|
||||
request._ = std::string(padding, ' ');
|
||||
|
||||
std::string arg_buff;
|
||||
epee::byte_slice arg_buff;
|
||||
epee::serialization::store_t_to_binary(request, arg_buff);
|
||||
|
||||
// we probably lowballed the payload size a bit, so added a but too much. Fix this now.
|
||||
@@ -200,7 +201,7 @@ namespace levin
|
||||
// if the size of _ moved enough, we might lose byte in size encoding, we don't care
|
||||
}
|
||||
|
||||
std::string fullBlob;
|
||||
epee::byte_slice fullBlob;
|
||||
if (!epee::serialization::store_t_to_binary(request, fullBlob))
|
||||
throw std::runtime_error{"Failed to serialize to epee binary format"};
|
||||
|
||||
@@ -209,12 +210,12 @@ namespace levin
|
||||
|
||||
bool make_payload_send_txs(connections& p2p, std::vector<blobdata>&& txs, const boost::uuids::uuid& destination, const bool pad, const bool fluff)
|
||||
{
|
||||
const cryptonote::blobdata blob = make_tx_payload(std::move(txs), pad, fluff);
|
||||
const epee::byte_slice blob = make_tx_payload(std::move(txs), pad, fluff);
|
||||
p2p.for_connection(destination, [&blob](detail::p2p_context& context) {
|
||||
on_levin_traffic(context, true, true, false, blob.size(), get_command_from_message(blob));
|
||||
return true;
|
||||
});
|
||||
return p2p.notify(NOTIFY_NEW_TRANSACTIONS::ID, epee::strspan<std::uint8_t>(blob), destination);
|
||||
return p2p.notify(NOTIFY_NEW_TRANSACTIONS::ID, epee::to_span(blob), destination);
|
||||
}
|
||||
|
||||
/* The current design uses `asio::strand`s. The documentation isn't as clear
|
||||
@@ -286,6 +287,7 @@ namespace levin
|
||||
connection_count(0),
|
||||
flush_callbacks(0),
|
||||
nzone(zone),
|
||||
is_public(is_public),
|
||||
pad_txs(pad_txs),
|
||||
fluffing(false)
|
||||
{
|
||||
@@ -303,6 +305,7 @@ namespace levin
|
||||
std::atomic<std::size_t> connection_count; //!< Only update in strand, can be read at any time
|
||||
std::uint32_t flush_callbacks; //!< Number of active fluff flush callbacks queued
|
||||
const epee::net_utils::zone nzone; //!< Zone is public ipv4/ipv6 connections, or i2p or tor
|
||||
const bool is_public; //!< Zone is public ipv4/ipv6 connections
|
||||
const bool pad_txs; //!< Pad txs to the next boundary for privacy
|
||||
bool fluffing; //!< Zone is in Dandelion++ fluff epoch
|
||||
};
|
||||
@@ -442,7 +445,7 @@ namespace levin
|
||||
zone->p2p->foreach_connection([txs, now, &zone, &source, &in_duration, &out_duration, &next_flush] (detail::p2p_context& context)
|
||||
{
|
||||
// When i2p/tor, only fluff to outbound connections
|
||||
if (context.handshake_complete() && source != context.m_connection_id && (zone->nzone == epee::net_utils::zone::public_ || !context.m_is_income))
|
||||
if (source != context.m_connection_id && (zone->nzone == epee::net_utils::zone::public_ || !context.m_is_income))
|
||||
{
|
||||
if (context.fluff_txs.empty())
|
||||
context.flush_time = now + (context.m_is_income ? in_duration() : out_duration());
|
||||
@@ -677,7 +680,7 @@ namespace levin
|
||||
|
||||
auto connections = get_out_connections(*zone_->p2p, height);
|
||||
if (connections.empty())
|
||||
MDEBUG("Unable to send transaction(s) to " << epee::net_utils::zone_to_string(zone_->nzone) <<
|
||||
MWARNING("Unable to send transaction(s) to " << epee::net_utils::zone_to_string(zone_->nzone) <<
|
||||
" - no suitable outbound connections at height " << height);
|
||||
|
||||
zone_->strand.post(update_channels{zone_, std::move(connections)});
|
||||
@@ -823,9 +826,9 @@ namespace levin
|
||||
|
||||
// Padding is not useful when using noise mode. Send as stem so receiver
|
||||
// forwards in Dandelion++ mode.
|
||||
const std::string payload = make_tx_payload(std::move(txs), false, false);
|
||||
const epee::byte_slice payload = make_tx_payload(std::move(txs), false, false);
|
||||
epee::byte_slice message = epee::levin::make_fragmented_notify(
|
||||
zone_->noise, NOTIFY_NEW_TRANSACTIONS::ID, epee::strspan<std::uint8_t>(payload)
|
||||
zone_->noise, NOTIFY_NEW_TRANSACTIONS::ID, epee::to_span(payload)
|
||||
);
|
||||
if (CRYPTONOTE_MAX_FRAGMENTS * zone_->noise.size() < message.size())
|
||||
{
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
#include "common/dns_utils.h"
|
||||
#include "common/command_line.h"
|
||||
#include "net/parse.h"
|
||||
#include "daemon/command_parser_executor.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
@@ -51,7 +50,7 @@ bool t_command_parser_executor::print_peer_list(const std::vector<std::string>&
|
||||
{
|
||||
if (args.size() > 3)
|
||||
{
|
||||
std::cout << "use: print_pl [white] [gray] [<limit>] [pruned] [publicrpc]" << std::endl;
|
||||
std::cout << "Invalid syntax: Too many parameters. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -80,7 +79,7 @@ bool t_command_parser_executor::print_peer_list(const std::vector<std::string>&
|
||||
}
|
||||
else if (!epee::string_tools::get_xtype_from_string(limit, args[i]))
|
||||
{
|
||||
std::cout << "unexpected argument: " << args[i] << std::endl;
|
||||
std::cout << "Invalid syntax: Unexpected parameter: " << args[i] << ". For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -91,56 +90,79 @@ bool t_command_parser_executor::print_peer_list(const std::vector<std::string>&
|
||||
|
||||
bool t_command_parser_executor::print_peer_list_stats(const std::vector<std::string>& args)
|
||||
{
|
||||
if (!args.empty()) return false;
|
||||
if (!args.empty()) {
|
||||
std::cout << "Invalid syntax: No parameters expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.print_peer_list_stats();
|
||||
}
|
||||
|
||||
bool t_command_parser_executor::save_blockchain(const std::vector<std::string>& args)
|
||||
{
|
||||
if (!args.empty()) return false;
|
||||
|
||||
if (!args.empty()) {
|
||||
std::cout << "Invalid syntax: No parameters expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
return m_executor.save_blockchain();
|
||||
}
|
||||
|
||||
bool t_command_parser_executor::show_hash_rate(const std::vector<std::string>& args)
|
||||
{
|
||||
if (!args.empty()) return false;
|
||||
if (!args.empty()) {
|
||||
std::cout << "Invalid syntax: No parameters expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.show_hash_rate();
|
||||
}
|
||||
|
||||
bool t_command_parser_executor::hide_hash_rate(const std::vector<std::string>& args)
|
||||
{
|
||||
if (!args.empty()) return false;
|
||||
if (!args.empty()) {
|
||||
std::cout << "Invalid syntax: No parameters expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.hide_hash_rate();
|
||||
}
|
||||
|
||||
bool t_command_parser_executor::show_difficulty(const std::vector<std::string>& args)
|
||||
{
|
||||
if (!args.empty()) return false;
|
||||
if (!args.empty()) {
|
||||
std::cout << "Invalid syntax: No parameters expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.show_difficulty();
|
||||
}
|
||||
|
||||
bool t_command_parser_executor::show_status(const std::vector<std::string>& args)
|
||||
{
|
||||
if (!args.empty()) return false;
|
||||
if (!args.empty()) {
|
||||
std::cout << "Invalid syntax: No parameters expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.show_status();
|
||||
}
|
||||
|
||||
bool t_command_parser_executor::print_connections(const std::vector<std::string>& args)
|
||||
{
|
||||
if (!args.empty()) return false;
|
||||
if (!args.empty()) {
|
||||
std::cout << "Invalid syntax: No parameters expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.print_connections();
|
||||
}
|
||||
|
||||
bool t_command_parser_executor::print_net_stats(const std::vector<std::string>& args)
|
||||
{
|
||||
if (!args.empty()) return false;
|
||||
if (!args.empty()) {
|
||||
std::cout << "Invalid syntax: No parameters expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.print_net_stats();
|
||||
}
|
||||
@@ -149,8 +171,8 @@ bool t_command_parser_executor::print_blockchain_info(const std::vector<std::str
|
||||
{
|
||||
if(!args.size())
|
||||
{
|
||||
std::cout << "need block index parameter" << std::endl;
|
||||
return false;
|
||||
std::cout << "Invalid syntax: At least one parameter expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
uint64_t start_index = 0;
|
||||
uint64_t end_index = 0;
|
||||
@@ -159,20 +181,20 @@ bool t_command_parser_executor::print_blockchain_info(const std::vector<std::str
|
||||
int64_t nblocks;
|
||||
if(!epee::string_tools::get_xtype_from_string(nblocks, args[0]))
|
||||
{
|
||||
std::cout << "wrong number of blocks" << std::endl;
|
||||
return false;
|
||||
std::cout << "Invalid syntax: Wrong number of blocks. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
return m_executor.print_blockchain_info(nblocks, (uint64_t)-nblocks);
|
||||
}
|
||||
if(!epee::string_tools::get_xtype_from_string(start_index, args[0]))
|
||||
{
|
||||
std::cout << "wrong starter block index parameter" << std::endl;
|
||||
return false;
|
||||
std::cout << "Invalid syntax: Wrong starter block index parameter. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
if(args.size() >1 && !epee::string_tools::get_xtype_from_string(end_index, args[1]))
|
||||
{
|
||||
std::cout << "wrong end block index parameter" << std::endl;
|
||||
return false;
|
||||
std::cout << "Invalid syntax: Wrong end block index parameter. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.print_blockchain_info(start_index, end_index);
|
||||
@@ -182,7 +204,7 @@ bool t_command_parser_executor::set_log_level(const std::vector<std::string>& ar
|
||||
{
|
||||
if(args.size() > 1)
|
||||
{
|
||||
std::cout << "use: set_log [<log_level_number_0-4> | <categories>]" << std::endl;
|
||||
std::cout << "Invalid syntax: Too many parameters. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -196,7 +218,7 @@ bool t_command_parser_executor::set_log_level(const std::vector<std::string>& ar
|
||||
{
|
||||
if(4 < l)
|
||||
{
|
||||
std::cout << "wrong number range, use: set_log <log_level_number_0-4>" << std::endl;
|
||||
std::cout << "Invalid syntax: Wrong number range, use: set_log <log_level_number_0-4>. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
return m_executor.set_log_level(l);
|
||||
@@ -209,7 +231,10 @@ bool t_command_parser_executor::set_log_level(const std::vector<std::string>& ar
|
||||
|
||||
bool t_command_parser_executor::print_height(const std::vector<std::string>& args)
|
||||
{
|
||||
if (!args.empty()) return false;
|
||||
if (!args.empty()) {
|
||||
std::cout << "Invalid syntax: No parameters expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.print_height();
|
||||
}
|
||||
@@ -224,14 +249,14 @@ bool t_command_parser_executor::print_block(const std::vector<std::string>& args
|
||||
include_hex = true;
|
||||
else
|
||||
{
|
||||
std::cout << "unexpected argument: " << args[i] << std::endl;
|
||||
std::cout << "Invalid syntax: Unexpected parameter: " << args[i] << ". For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (args.empty())
|
||||
{
|
||||
std::cout << "expected: print_block (<block_hash> | <block_height>) [+hex]" << std::endl;
|
||||
return false;
|
||||
std::cout << "Invalid syntax: At least one parameter expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::string& arg = args.front();
|
||||
@@ -249,7 +274,7 @@ bool t_command_parser_executor::print_block(const std::vector<std::string>& args
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool t_command_parser_executor::print_transaction(const std::vector<std::string>& args)
|
||||
@@ -268,13 +293,13 @@ bool t_command_parser_executor::print_transaction(const std::vector<std::string>
|
||||
include_json = true;
|
||||
else
|
||||
{
|
||||
std::cout << "unexpected argument: " << args[i] << std::endl;
|
||||
std::cout << "Invalid syntax: Unexpected parameter: " << args[i] << ". For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (args.empty())
|
||||
{
|
||||
std::cout << "expected: print_tx <transaction_hash> [+meta] [+hex] [+json]" << std::endl;
|
||||
std::cout << "Invalid syntax: At least one parameter expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -292,7 +317,7 @@ bool t_command_parser_executor::is_key_image_spent(const std::vector<std::string
|
||||
{
|
||||
if (args.empty())
|
||||
{
|
||||
std::cout << "expected: is_key_image_spent <key_image>" << std::endl;
|
||||
std::cout << "Invalid syntax: At least one parameter expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -310,34 +335,149 @@ bool t_command_parser_executor::is_key_image_spent(const std::vector<std::string
|
||||
|
||||
bool t_command_parser_executor::print_transaction_pool_long(const std::vector<std::string>& args)
|
||||
{
|
||||
if (!args.empty()) return false;
|
||||
if (!args.empty()) {
|
||||
std::cout << "Invalid syntax: No parameters expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.print_transaction_pool_long();
|
||||
}
|
||||
|
||||
bool t_command_parser_executor::print_transaction_pool_short(const std::vector<std::string>& args)
|
||||
{
|
||||
if (!args.empty()) return false;
|
||||
if (!args.empty()) {
|
||||
std::cout << "Invalid syntax: No parameters expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.print_transaction_pool_short();
|
||||
}
|
||||
|
||||
bool t_command_parser_executor::print_transaction_pool_stats(const std::vector<std::string>& args)
|
||||
{
|
||||
if (!args.empty()) return false;
|
||||
if (!args.empty()) {
|
||||
std::cout << "Invalid syntax: No parameters expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.print_transaction_pool_stats();
|
||||
}
|
||||
|
||||
bool t_command_parser_executor::start_mining(const std::vector<std::string>& args)
|
||||
{
|
||||
std::cout << "You can't mine within wownerod. To mine, restart node like this: ./wownerod --start-mining YOUR-ADDRESS --spendkey SECRET-SPENDKEY" << std::endl;
|
||||
if(!args.size())
|
||||
{
|
||||
std::cout << "Invalid syntax: At least one parameter expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
cryptonote::address_parse_info info;
|
||||
cryptonote::network_type nettype = cryptonote::MAINNET;
|
||||
if(!cryptonote::get_account_address_from_str(info, cryptonote::MAINNET, args.front()))
|
||||
{
|
||||
if(!cryptonote::get_account_address_from_str(info, cryptonote::TESTNET, args.front()))
|
||||
{
|
||||
if(!cryptonote::get_account_address_from_str(info, cryptonote::STAGENET, args.front()))
|
||||
{
|
||||
bool dnssec_valid;
|
||||
std::string address_str = tools::dns_utils::get_account_address_as_str_from_url(args.front(), dnssec_valid,
|
||||
[](const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid){return addresses[0];});
|
||||
if(!cryptonote::get_account_address_from_str(info, cryptonote::MAINNET, address_str))
|
||||
{
|
||||
if(!cryptonote::get_account_address_from_str(info, cryptonote::TESTNET, address_str))
|
||||
{
|
||||
if(!cryptonote::get_account_address_from_str(info, cryptonote::STAGENET, address_str))
|
||||
{
|
||||
std::cout << "Invalid syntax: Target account address has wrong format. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
nettype = cryptonote::STAGENET;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nettype = cryptonote::TESTNET;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nettype = cryptonote::STAGENET;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nettype = cryptonote::TESTNET;
|
||||
}
|
||||
}
|
||||
if (info.is_subaddress)
|
||||
{
|
||||
tools::fail_msg_writer() << "subaddress for mining reward is not yet supported!" << std::endl;
|
||||
return true;
|
||||
}
|
||||
if(nettype != cryptonote::MAINNET)
|
||||
std::cout << "Mining to a " << (nettype == cryptonote::TESTNET ? "testnet" : "stagenet") << " address, make sure this is intentional!" << std::endl;
|
||||
uint64_t threads_count = 1;
|
||||
bool do_background_mining = false;
|
||||
bool ignore_battery = false;
|
||||
if(args.size() > 4)
|
||||
{
|
||||
std::cout << "Invalid syntax: Too many parameters. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(args.size() == 4)
|
||||
{
|
||||
if(args[3] == "true" || command_line::is_yes(args[3]) || args[3] == "1")
|
||||
{
|
||||
ignore_battery = true;
|
||||
}
|
||||
else if(args[3] != "false" && !command_line::is_no(args[3]) && args[3] != "0")
|
||||
{
|
||||
std::cout << "Invalid syntax: Invalid combination of parameters. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(args.size() >= 3)
|
||||
{
|
||||
if(args[2] == "true" || command_line::is_yes(args[2]) || args[2] == "1")
|
||||
{
|
||||
do_background_mining = true;
|
||||
}
|
||||
else if(args[2] != "false" && !command_line::is_no(args[2]) && args[2] != "0")
|
||||
{
|
||||
std::cout << "Invalid syntax: Invalid combination of parameters. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(args.size() >= 2)
|
||||
{
|
||||
if (args[1] == "auto" || args[1] == "autodetect")
|
||||
{
|
||||
threads_count = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool ok = epee::string_tools::get_xtype_from_string(threads_count, args[1]);
|
||||
threads_count = (ok && 0 < threads_count) ? threads_count : 1;
|
||||
}
|
||||
}
|
||||
|
||||
m_executor.start_mining(info.address, threads_count, nettype, do_background_mining, ignore_battery);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool t_command_parser_executor::stop_mining(const std::vector<std::string>& args)
|
||||
{
|
||||
if (!args.empty()) return false;
|
||||
if (!args.empty()) {
|
||||
std::cout << "Invalid syntax: No parameters expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.stop_mining();
|
||||
}
|
||||
@@ -349,21 +489,31 @@ bool t_command_parser_executor::mining_status(const std::vector<std::string>& ar
|
||||
|
||||
bool t_command_parser_executor::stop_daemon(const std::vector<std::string>& args)
|
||||
{
|
||||
if (!args.empty()) return false;
|
||||
if (!args.empty()) {
|
||||
std::cout << "Invalid syntax: No parameters expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.stop_daemon();
|
||||
}
|
||||
|
||||
bool t_command_parser_executor::print_status(const std::vector<std::string>& args)
|
||||
{
|
||||
if (!args.empty()) return false;
|
||||
if (!args.empty()) {
|
||||
std::cout << "Invalid syntax: No parameters expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.print_status();
|
||||
}
|
||||
|
||||
bool t_command_parser_executor::set_limit(const std::vector<std::string>& args)
|
||||
{
|
||||
if(args.size()>1) return false;
|
||||
if(args.size()>1) {
|
||||
std::cout << "Invalid syntax: Too many parameters. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(args.size()==0) {
|
||||
return m_executor.get_limit();
|
||||
}
|
||||
@@ -372,8 +522,8 @@ bool t_command_parser_executor::set_limit(const std::vector<std::string>& args)
|
||||
limit = std::stoll(args[0]);
|
||||
}
|
||||
catch(const std::exception& ex) {
|
||||
std::cout << "failed to parse argument" << std::endl;
|
||||
return false;
|
||||
std::cout << "Invalid syntax: Failed to parse limit. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.set_limit(limit, limit);
|
||||
@@ -381,7 +531,11 @@ bool t_command_parser_executor::set_limit(const std::vector<std::string>& args)
|
||||
|
||||
bool t_command_parser_executor::set_limit_up(const std::vector<std::string>& args)
|
||||
{
|
||||
if(args.size()>1) return false;
|
||||
if(args.size()>1) {
|
||||
std::cout << "Invalid syntax: Too many parameters. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(args.size()==0) {
|
||||
return m_executor.get_limit_up();
|
||||
}
|
||||
@@ -390,8 +544,8 @@ bool t_command_parser_executor::set_limit_up(const std::vector<std::string>& arg
|
||||
limit = std::stoll(args[0]);
|
||||
}
|
||||
catch(const std::exception& ex) {
|
||||
std::cout << "failed to parse argument" << std::endl;
|
||||
return false;
|
||||
std::cout << "Invalid syntax: Failed to parse limit. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.set_limit(0, limit);
|
||||
@@ -399,7 +553,11 @@ bool t_command_parser_executor::set_limit_up(const std::vector<std::string>& arg
|
||||
|
||||
bool t_command_parser_executor::set_limit_down(const std::vector<std::string>& args)
|
||||
{
|
||||
if(args.size()>1) return false;
|
||||
if(args.size()>1) {
|
||||
std::cout << "Invalid syntax: Too many parameters. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(args.size()==0) {
|
||||
return m_executor.get_limit_down();
|
||||
}
|
||||
@@ -408,8 +566,8 @@ bool t_command_parser_executor::set_limit_down(const std::vector<std::string>& a
|
||||
limit = std::stoll(args[0]);
|
||||
}
|
||||
catch(const std::exception& ex) {
|
||||
std::cout << "failed to parse argument" << std::endl;
|
||||
return false;
|
||||
std::cout << "Invalid syntax: Failed to parse limit. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.set_limit(limit, 0);
|
||||
@@ -426,12 +584,13 @@ bool t_command_parser_executor::out_peers(const std::vector<std::string>& args)
|
||||
set = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
catch(const std::exception& ex) {
|
||||
_erro("stoi exception");
|
||||
return false;
|
||||
std::cout << "Invalid syntax: Failed to parse number. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return m_executor.out_peers(set, limit);
|
||||
}
|
||||
|
||||
@@ -449,7 +608,8 @@ bool t_command_parser_executor::in_peers(const std::vector<std::string>& args)
|
||||
|
||||
catch(const std::exception& ex) {
|
||||
_erro("stoi exception");
|
||||
return false;
|
||||
std::cout << "Invalid syntax: Failed to parse number." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.in_peers(set, limit);
|
||||
@@ -466,26 +626,38 @@ bool t_command_parser_executor::hard_fork_info(const std::vector<std::string>& a
|
||||
version = std::stoi(args[0]);
|
||||
}
|
||||
catch(const std::exception& ex) {
|
||||
return false;
|
||||
std::cout << "Invalid syntax: Failed to parse version number. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
if (version <= 0 || version > 255) {
|
||||
std::cout << "Invalid syntax: Unknown version number. Must be between 0 and 255. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
if (version <= 0 || version > 255)
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
std::cout << "Invalid syntax: Too many parameters. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
return m_executor.hard_fork_info(version);
|
||||
}
|
||||
|
||||
bool t_command_parser_executor::show_bans(const std::vector<std::string>& args)
|
||||
{
|
||||
if (!args.empty()) return false;
|
||||
if (!args.empty()) {
|
||||
std::cout << "Invalid syntax: No parameters expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.print_bans();
|
||||
}
|
||||
|
||||
bool t_command_parser_executor::ban(const std::vector<std::string>& args)
|
||||
{
|
||||
if (args.size() != 1 && args.size() != 2) return false;
|
||||
if (args.size() != 1 && args.size() != 2) {
|
||||
std::cout << "Invalid syntax: Expects one or two parameters. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
std::string ip = args[0];
|
||||
time_t seconds = P2P_IP_BLOCKTIME;
|
||||
if (args.size() > 1)
|
||||
{
|
||||
@@ -495,77 +667,45 @@ bool t_command_parser_executor::ban(const std::vector<std::string>& args)
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
return false;
|
||||
std::cout << "Invalid syntax: Failed to parse seconds. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
if (seconds == 0)
|
||||
{
|
||||
return false;
|
||||
std::cout << "Seconds must be greater than 0." << std::endl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (boost::starts_with(args[0], "@"))
|
||||
{
|
||||
const std::string ban_list = args[0].substr(1);
|
||||
|
||||
try
|
||||
{
|
||||
const boost::filesystem::path ban_list_path(ban_list);
|
||||
boost::system::error_code ec;
|
||||
if (!boost::filesystem::exists(ban_list_path, ec))
|
||||
{
|
||||
std::cout << "Can't find ban list file " + ban_list + " - " + ec.message() << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ret = true;
|
||||
std::ifstream ifs(ban_list_path.string());
|
||||
for (std::string line; std::getline(ifs, line); )
|
||||
{
|
||||
auto subnet = net::get_ipv4_subnet_address(line);
|
||||
if (subnet)
|
||||
{
|
||||
ret &= m_executor.ban(subnet->str(), seconds);
|
||||
continue;
|
||||
}
|
||||
const expect<epee::net_utils::network_address> parsed_addr = net::get_network_address(line, 0);
|
||||
if (parsed_addr)
|
||||
{
|
||||
ret &= m_executor.ban(parsed_addr->host_str(), seconds);
|
||||
continue;
|
||||
}
|
||||
std::cout << "Invalid IP address or IPv4 subnet: " << line << std::endl;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
std::cout << "Error loading ban list: " << e.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::string ip = args[0];
|
||||
return m_executor.ban(ip, seconds);
|
||||
}
|
||||
return m_executor.ban(ip, seconds);
|
||||
}
|
||||
|
||||
bool t_command_parser_executor::unban(const std::vector<std::string>& args)
|
||||
{
|
||||
if (args.size() != 1) return false;
|
||||
if (args.size() != 1) {
|
||||
std::cout << "Invalid syntax: One parameter expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string ip = args[0];
|
||||
return m_executor.unban(ip);
|
||||
}
|
||||
|
||||
bool t_command_parser_executor::banned(const std::vector<std::string>& args)
|
||||
{
|
||||
if (args.size() != 1) return false;
|
||||
if (args.size() != 1) {
|
||||
std::cout << "Invalid syntax: One parameter expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
std::string address = args[0];
|
||||
return m_executor.banned(address);
|
||||
}
|
||||
|
||||
bool t_command_parser_executor::flush_txpool(const std::vector<std::string>& args)
|
||||
{
|
||||
if (args.size() > 1) return false;
|
||||
if (args.size() > 1) {
|
||||
std::cout << "Invalid syntax: Too many parameters. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string txid;
|
||||
if (args.size() == 1)
|
||||
@@ -573,7 +713,7 @@ bool t_command_parser_executor::flush_txpool(const std::vector<std::string>& arg
|
||||
crypto::hash hash;
|
||||
if (!parse_hash256(args[0], hash))
|
||||
{
|
||||
std::cout << "failed to parse tx id" << std::endl;
|
||||
std::cout << "Invalid syntax: Failed to parse tx id. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
txid = args[0];
|
||||
@@ -606,7 +746,7 @@ bool t_command_parser_executor::output_histogram(const std::vector<std::string>&
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Invalid syntax: more than two non-amount parameters" << std::endl;
|
||||
std::cout << "Invalid syntax: More than two non-amount parameters. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -617,20 +757,21 @@ bool t_command_parser_executor::print_coinbase_tx_sum(const std::vector<std::str
|
||||
{
|
||||
if(!args.size())
|
||||
{
|
||||
std::cout << "need block height parameter" << std::endl;
|
||||
return false;
|
||||
std::cout << "Invalid syntax: At least one parameter expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t height = 0;
|
||||
uint64_t count = 0;
|
||||
if(!epee::string_tools::get_xtype_from_string(height, args[0]))
|
||||
{
|
||||
std::cout << "wrong starter block height parameter" << std::endl;
|
||||
return false;
|
||||
std::cout << "Invalid syntax: Wrong starter block height parameter. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
if(args.size() >1 && !epee::string_tools::get_xtype_from_string(count, args[1]))
|
||||
{
|
||||
std::cout << "wrong count parameter" << std::endl;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.print_coinbase_tx_sum(height, count);
|
||||
@@ -640,8 +781,8 @@ bool t_command_parser_executor::alt_chain_info(const std::vector<std::string>& a
|
||||
{
|
||||
if(args.size() > 1)
|
||||
{
|
||||
std::cout << "usage: alt_chain_info [block_hash|>N|-N]" << std::endl;
|
||||
return false;
|
||||
std::cout << "Invalid syntax: Too many parameters. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string tip;
|
||||
@@ -653,16 +794,16 @@ bool t_command_parser_executor::alt_chain_info(const std::vector<std::string>& a
|
||||
{
|
||||
if (!epee::string_tools::get_xtype_from_string(above, args[0].c_str() + 1))
|
||||
{
|
||||
std::cout << "invalid above parameter" << std::endl;
|
||||
return false;
|
||||
std::cout << "Invalid syntax: Invalid above parameter. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (args[0].size() > 0 && args[0][0] == '-')
|
||||
{
|
||||
if (!epee::string_tools::get_xtype_from_string(last_blocks, args[0].c_str() + 1))
|
||||
{
|
||||
std::cout << "invalid last_blocks parameter" << std::endl;
|
||||
return false;
|
||||
std::cout << "Invalid syntax: Invalid last_blocks parameter. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -678,15 +819,15 @@ bool t_command_parser_executor::print_blockchain_dynamic_stats(const std::vector
|
||||
{
|
||||
if(args.size() != 1)
|
||||
{
|
||||
std::cout << "Exactly one parameter is needed" << std::endl;
|
||||
return false;
|
||||
std::cout << "Invalid syntax: One parameter expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t nblocks = 0;
|
||||
if(!epee::string_tools::get_xtype_from_string(nblocks, args[0]) || nblocks == 0)
|
||||
{
|
||||
std::cout << "wrong number of blocks" << std::endl;
|
||||
return false;
|
||||
std::cout << "Invalid syntax: Wrong number of blocks. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.print_blockchain_dynamic_stats(nblocks);
|
||||
@@ -694,10 +835,10 @@ bool t_command_parser_executor::print_blockchain_dynamic_stats(const std::vector
|
||||
|
||||
bool t_command_parser_executor::update(const std::vector<std::string>& args)
|
||||
{
|
||||
if(args.size() != 1)
|
||||
if (args.size() != 1)
|
||||
{
|
||||
std::cout << "Exactly one parameter is needed: check, download, or update" << std::endl;
|
||||
return false;
|
||||
std::cout << "Invalid syntax: One parameter expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.update(args.front());
|
||||
@@ -705,13 +846,17 @@ bool t_command_parser_executor::update(const std::vector<std::string>& args)
|
||||
|
||||
bool t_command_parser_executor::relay_tx(const std::vector<std::string>& args)
|
||||
{
|
||||
if (args.size() != 1) return false;
|
||||
if (args.size() != 1)
|
||||
{
|
||||
std::cout << "Invalid syntax: One parameter expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string txid;
|
||||
crypto::hash hash;
|
||||
if (!parse_hash256(args[0], hash))
|
||||
{
|
||||
std::cout << "failed to parse tx id" << std::endl;
|
||||
std::cout << "Invalid syntax: Failed to parse tx id. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
txid = args[0];
|
||||
@@ -720,7 +865,10 @@ bool t_command_parser_executor::relay_tx(const std::vector<std::string>& args)
|
||||
|
||||
bool t_command_parser_executor::sync_info(const std::vector<std::string>& args)
|
||||
{
|
||||
if (args.size() != 0) return false;
|
||||
if (args.size() != 0) {
|
||||
std::cout << "Invalid syntax: No parameters expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.sync_info();
|
||||
}
|
||||
@@ -729,8 +877,8 @@ bool t_command_parser_executor::pop_blocks(const std::vector<std::string>& args)
|
||||
{
|
||||
if (args.size() != 1)
|
||||
{
|
||||
std::cout << "Exactly one parameter is needed" << std::endl;
|
||||
return false;
|
||||
std::cout << "Invalid syntax: One parameter expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
@@ -738,21 +886,24 @@ bool t_command_parser_executor::pop_blocks(const std::vector<std::string>& args)
|
||||
uint64_t nblocks = boost::lexical_cast<uint64_t>(args[0]);
|
||||
if (nblocks < 1)
|
||||
{
|
||||
std::cout << "number of blocks must be greater than 0" << std::endl;
|
||||
return false;
|
||||
std::cout << "Invalid syntax: Number of blocks must be greater than 0. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
return m_executor.pop_blocks(nblocks);
|
||||
}
|
||||
catch (const boost::bad_lexical_cast&)
|
||||
{
|
||||
std::cout << "number of blocks must be a number greater than 0" << std::endl;
|
||||
std::cout << "Invalid syntax: Number of blocks must be a number greater than 0. For more details, use the help command." << std::endl;
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool t_command_parser_executor::rpc_payments(const std::vector<std::string>& args)
|
||||
{
|
||||
if (args.size() != 0) return false;
|
||||
if (args.size() != 0) {
|
||||
std::cout << "Invalid syntax: No parameters expected. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.rpc_payments();
|
||||
}
|
||||
@@ -764,7 +915,11 @@ bool t_command_parser_executor::version(const std::vector<std::string>& args)
|
||||
|
||||
bool t_command_parser_executor::prune_blockchain(const std::vector<std::string>& args)
|
||||
{
|
||||
if (args.size() > 1) return false;
|
||||
if (args.size() > 1)
|
||||
{
|
||||
std::cout << "Invalid syntax: Too many parameters. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.empty() || args[0] != "confirm")
|
||||
{
|
||||
@@ -790,7 +945,8 @@ bool t_command_parser_executor::set_bootstrap_daemon(const std::vector<std::stri
|
||||
const size_t args_count = args.size();
|
||||
if (args_count < 1 || args_count > 3)
|
||||
{
|
||||
return false;
|
||||
std::cout << "Invalid syntax: Wrong number of parameters. For more details, use the help command." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_executor.set_bootstrap_daemon(
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user