mirror of
https://github.com/monero-project/monero.git
synced 2025-12-13 00:00:33 -08:00
Compare commits
78 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3271e8f12 | ||
|
|
b92a8b53e0 | ||
|
|
d0069112a3 | ||
|
|
0214524166 | ||
|
|
83276bf92d | ||
|
|
72a80f6213 | ||
|
|
95a2701ec5 | ||
|
|
120c84d04f | ||
|
|
23525655fa | ||
|
|
d03308734b | ||
|
|
ee1bacc64f | ||
|
|
4a6eb0a016 | ||
|
|
018e251cc0 | ||
|
|
3ef7f33300 | ||
|
|
1e38a02bb5 | ||
|
|
96eed84aad | ||
|
|
257077a96b | ||
|
|
658b6690a3 | ||
|
|
98ed9a41f7 | ||
|
|
fb4146fa34 | ||
|
|
79862ad1de | ||
|
|
07470fd400 | ||
|
|
32004a756c | ||
|
|
2c0a87f2ac | ||
|
|
fdae09754e | ||
|
|
700b72c709 | ||
|
|
51011ed960 | ||
|
|
3129d51eb4 | ||
|
|
f2937d15bd | ||
|
|
d97191d4f9 | ||
|
|
8afbed4027 | ||
|
|
5a3ce8a7dc | ||
|
|
566d194c41 | ||
|
|
9e2ac5308a | ||
|
|
9c56b38b16 | ||
|
|
bb2b606e91 | ||
|
|
12c1b0922a | ||
|
|
6b77e8358c | ||
|
|
08205f01d9 | ||
|
|
63f60b1777 | ||
|
|
570b90eb43 | ||
|
|
e7c52d94c0 | ||
|
|
aab57ba9cc | ||
|
|
8334ce0b24 | ||
|
|
446a7ddc49 | ||
|
|
ffaa78700c | ||
|
|
14b3b6ea02 | ||
|
|
dd51b03d87 | ||
|
|
a13e879251 | ||
|
|
f7900ccfc1 | ||
|
|
dfed3d39b6 | ||
|
|
9d6f9335d1 | ||
|
|
a70bf86037 | ||
|
|
8779a6da39 | ||
|
|
b35c1e2491 | ||
|
|
6a70de32bf | ||
|
|
a40d5c1847 | ||
|
|
afc61dda45 | ||
|
|
3217ed39ae | ||
|
|
d21cf293e1 | ||
|
|
36c7ea9f77 | ||
|
|
8d8b47e69f | ||
|
|
59c0423eae | ||
|
|
7d01dad8f4 | ||
|
|
81490d2aea | ||
|
|
ccb2ab2b7b | ||
|
|
110f110181 | ||
|
|
a8d043b6dd | ||
|
|
0e343ecfdf | ||
|
|
c085e9294f | ||
|
|
266c639f4f | ||
|
|
e1d31e0a8b | ||
|
|
5a65991480 | ||
|
|
6afbdd9754 | ||
|
|
4ba680f294 | ||
|
|
cf5a8b1d6c | ||
|
|
bf972c40fc | ||
|
|
4290c78160 |
16
.gitignore
vendored
16
.gitignore
vendored
@@ -1,7 +1,23 @@
|
||||
.DS_Store
|
||||
/doc
|
||||
/build
|
||||
/tags
|
||||
|
||||
# vim swap files
|
||||
*.swp
|
||||
*.swo
|
||||
TAGS
|
||||
!TAGS/
|
||||
tags
|
||||
!tags/
|
||||
gtags.files
|
||||
GTAGS
|
||||
GRTAGS
|
||||
GPATH
|
||||
cscope.files
|
||||
cscope.out
|
||||
cscope.in.out
|
||||
cscope.po.out
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,14 +1,58 @@
|
||||
cmake_minimum_required(VERSION 2.8.6)
|
||||
# Copyright (c) 2014, 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
|
||||
|
||||
set(VERSION "0.1")
|
||||
# $Format:Packaged from commit %H%nset(COMMIT %h)%nset(REFS "%d")$
|
||||
cmake_minimum_required(VERSION 2.8.6)
|
||||
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
set(CMAKE_CONFIGURATION_TYPES "Debug;Release")
|
||||
enable_testing()
|
||||
|
||||
# Check if we're on FreeBSD so we can exclude the local miniupnpc (it should be installed from ports instead)
|
||||
# CMAKE_SYSTEM_NAME checks are commonly known, but specifically taken from libsdl's CMakeLists
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "kFreeBSD.*")
|
||||
set(FREEBSD TRUE)
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "DragonFly.*|FreeBSD")
|
||||
set(FREEBSD TRUE)
|
||||
endif()
|
||||
|
||||
# TODO: check bsdi, NetBSD, OpenBSD, to see if they need the same FreeBSD changes
|
||||
#
|
||||
# elseif(CMAKE_SYSTEM_NAME MATCHES "kNetBSD.*|NetBSD.*")
|
||||
# set(NETBSD TRUE)
|
||||
# elseif(CMAKE_SYSTEM_NAME MATCHES "kOpenBSD.*|OpenBSD.*")
|
||||
# set(OPENBSD TRUE)
|
||||
# elseif(CMAKE_SYSTEM_NAME MATCHES ".*BSDI.*")
|
||||
# set(BSDI TRUE)
|
||||
|
||||
function(set_static_flags)
|
||||
if (NOT APPLE)
|
||||
if (NOT APPLE AND NOT FREEBSD)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
|
||||
endif()
|
||||
endfunction(set_static_flags)
|
||||
@@ -91,7 +135,7 @@ else()
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEBUG_FLAGS}")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${RELEASE_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${RELEASE_FLAGS}")
|
||||
if(STATIC AND NOT APPLE)
|
||||
if(STATIC AND NOT APPLE AND NOT FREEBSD)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
|
||||
endif()
|
||||
endif()
|
||||
@@ -107,38 +151,33 @@ endif()
|
||||
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
|
||||
if(MINGW)
|
||||
set(Boost_LIBRARIES "${Boost_LIBRARIES};ws2_32;mswsock")
|
||||
elseif(APPLE)
|
||||
elseif(APPLE OR FREEBSD)
|
||||
set(Boost_LIBRARIES "${Boost_LIBRARIES}")
|
||||
elseif(NOT MSVC)
|
||||
set(Boost_LIBRARIES "${Boost_LIBRARIES};rt;pthread")
|
||||
endif()
|
||||
|
||||
set(COMMIT_ID_IN_VERSION ON CACHE BOOL "Include commit ID in version")
|
||||
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/version")
|
||||
if (NOT COMMIT_ID_IN_VERSION)
|
||||
set(VERSION "${VERSION}-unknown")
|
||||
configure_file("src/version.h.in" "version/version.h")
|
||||
add_custom_target(version ALL)
|
||||
elseif(DEFINED COMMIT)
|
||||
string(REPLACE "." "\\." VERSION_RE "${VERSION}")
|
||||
if(NOT REFS MATCHES "(\\(|, )tag: v${VERSION_RE}(\\)|, )")
|
||||
set(VERSION "${VERSION}-g${COMMIT}")
|
||||
endif()
|
||||
configure_file("src/version.h.in" "version/version.h")
|
||||
add_custom_target(version ALL)
|
||||
find_package(Git QUIET)
|
||||
if(Git_FOUND OR GIT_FOUND)
|
||||
message(STATUS "Found Git: ${GIT_EXECUTABLE}")
|
||||
add_custom_target(version ALL "${CMAKE_COMMAND}" "-D" "GIT=${GIT_EXECUTABLE}" "-D" "TO=${CMAKE_BINARY_DIR}/version/version.h" "-P" "src/version.cmake" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
|
||||
else()
|
||||
find_package(Git QUIET)
|
||||
if(Git_FOUND OR GIT_FOUND)
|
||||
message(STATUS "Found Git: ${GIT_EXECUTABLE}")
|
||||
add_custom_target(version ALL "${CMAKE_COMMAND}" "-D" "VERSION=${VERSION}" "-D" "GIT=${GIT_EXECUTABLE}" "-D" "TO=${CMAKE_BINARY_DIR}/version/version.h" "-P" "src/version.cmake" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
|
||||
else()
|
||||
message(STATUS "WARNING: Git was not found!")
|
||||
set(VERSION "${VERSION}-unknown")
|
||||
configure_file("src/version.h.in" "version/version.h")
|
||||
add_custom_target(version ALL)
|
||||
endif()
|
||||
message(STATUS "WARNING: Git was not found!")
|
||||
set(VERSIONTAG "unknown")
|
||||
configure_file("src/version.h.in" "version/version.h")
|
||||
add_custom_target(version ALL)
|
||||
endif()
|
||||
|
||||
add_subdirectory(external)
|
||||
|
||||
# Final setup for miniupnpc
|
||||
if(UPNP_STATIC)
|
||||
add_definitions("-DUPNP_STATIC")
|
||||
else()
|
||||
add_definitions("-DUPNP_DYNAMIC")
|
||||
include_directories(${UPNP_INCLUDE})
|
||||
endif()
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(tests)
|
||||
|
||||
4
Makefile
4
Makefile
@@ -24,6 +24,10 @@ test-release: build-release
|
||||
|
||||
all-release: build-release
|
||||
|
||||
release-static:
|
||||
mkdir -p build/release
|
||||
cd build/release && cmake -D STATIC=ON -D ARCH="x86-64" -D CMAKE_BUILD_TYPE=Release ../.. && $(MAKE)
|
||||
|
||||
clean:
|
||||
@echo "WARNING: Back-up your wallet if it exists within ./build!" ; \
|
||||
read -r -p "This will destroy the build directory, continue (y/N)?: " CONTINUE; \
|
||||
|
||||
@@ -60,6 +60,7 @@ Dependencies: GCC 4.7.3 or later, CMake 2.8.6 or later, and Boost 1.53 or later
|
||||
**Advanced options:**
|
||||
|
||||
* Parallel build: run `make -j<number of threads>` instead of `make`.
|
||||
* Statically linked release build: run `make release-static`.
|
||||
* Debug build: run `make build-debug`.
|
||||
* Test suite: run `make test-release` to run tests in addition to building. Running `make test-debug` will do the same to the debug version.
|
||||
* Building with Clang: it may be possible to use Clang instead of GCC, but this may not work everywhere. To build, run `export CC=clang CXX=clang++` before running `make`.
|
||||
@@ -87,6 +88,12 @@ msbuild Project.sln /p:Configuration=Release
|
||||
```
|
||||
* If you don't have your path environment variable configured with the VS paths, you may may want to run `C:\program files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat` (or equivalent) to temporarily set the environment variables.
|
||||
|
||||
### On FreeBSD:
|
||||
|
||||
The project can be built from scratch by following instructions for Unix and Linux above.
|
||||
|
||||
We expect to add Monero into the ports tree in the near future, which will aid in managing installations using ports or packages.
|
||||
|
||||
## Building Documentation
|
||||
|
||||
Monero developer documentation uses Doxygen, and is currently a work-in-progress.
|
||||
|
||||
@@ -1385,6 +1385,7 @@ POP_WARNINGS
|
||||
#define LOG_PRINT_MAGENTA(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, epee::log_space::console_color_magenta)
|
||||
|
||||
#define LOG_PRINT_RED_L0(mess) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, LOG_LEVEL_0, epee::log_space::console_color_red)
|
||||
#define LOG_PRINT_RED_L1(mess) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, LOG_LEVEL_1, epee::log_space::console_color_red)
|
||||
|
||||
#define LOG_PRINT_L0(mess) LOG_PRINT(mess, LOG_LEVEL_0)
|
||||
#define LOG_PRINT_L1(mess) LOG_PRINT(mess, LOG_LEVEL_1)
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
#include "syncobj.h"
|
||||
|
||||
|
||||
#define ABSTRACT_SERVER_SEND_QUE_MAX_COUNT 100
|
||||
#define ABSTRACT_SERVER_SEND_QUE_MAX_COUNT 1000
|
||||
|
||||
namespace epee
|
||||
{
|
||||
|
||||
@@ -376,7 +376,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
|
||||
if (e)
|
||||
{
|
||||
LOG_PRINT_L0("[sock " << socket_.native_handle() << "] Some problems at write: " << e.message() << ':' << e.value());
|
||||
LOG_PRINT_L1("[sock " << socket_.native_handle() << "] Some problems at write: " << e.message() << ':' << e.value());
|
||||
shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -602,4 +602,4 @@ bool cp_server_impl<TProtocol>::is_stop_signal()
|
||||
}
|
||||
//-------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ int levin_client_impl::invoke(int command, const std::string& in_buff, std::stri
|
||||
|
||||
if(head.m_signature!=LEVIN_SIGNATURE)
|
||||
{
|
||||
LOG_PRINT_L0("Signature missmatch in response");
|
||||
LOG_PRINT_L1("Signature missmatch in response");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ inline
|
||||
|
||||
if(head.m_signature!=LEVIN_SIGNATURE)
|
||||
{
|
||||
LOG_PRINT_L0("Signature missmatch in response");
|
||||
LOG_PRINT_L1("Signature missmatch in response");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -191,4 +191,4 @@ inline
|
||||
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace net_utils
|
||||
boost::smatch result;
|
||||
if(!boost::regex_search(uri, result, rexp_match_uri, boost::match_default) && result[0].matched)
|
||||
{
|
||||
LOG_PRINT_L0("[PARSE URI] regex not matched for uri: " << uri);
|
||||
LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << uri);
|
||||
content.m_path = uri;
|
||||
return true;
|
||||
}
|
||||
@@ -139,7 +139,7 @@ namespace net_utils
|
||||
boost::smatch result;
|
||||
if(!boost::regex_search(url_str, result, rexp_match_uri, boost::match_default) && result[0].matched)
|
||||
{
|
||||
LOG_PRINT_L0("[PARSE URI] regex not matched for uri: " << rexp_match_uri);
|
||||
LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << rexp_match_uri);
|
||||
//content.m_path = uri;
|
||||
return true;
|
||||
}
|
||||
@@ -165,4 +165,4 @@ namespace net_utils
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace net_utils
|
||||
#define LOG_PRINT_CC_YELLOW(ct, message, log_level) LOG_PRINT_YELLOW("[" << epee::net_utils::print_connection_context_short(ct) << "]" << message, log_level)
|
||||
#define LOG_PRINT_CC_CYAN(ct, message, log_level) LOG_PRINT_CYAN("[" << epee::net_utils::print_connection_context_short(ct) << "]" << message, log_level)
|
||||
#define LOG_PRINT_CC_MAGENTA(ct, message, log_level) LOG_PRINT_MAGENTA("[" << epee::net_utils::print_connection_context_short(ct) << "]" << message, log_level)
|
||||
#define LOG_ERROR_CC(ct, message) LOG_ERROR("[" << epee::net_utils::print_connection_context_short(ct) << "]" << message)
|
||||
#define LOG_ERROR_CC(ct, message) LOG_PRINT_RED("[" << epee::net_utils::print_connection_context_short(ct) << "]" << message, LOG_LEVEL_1)
|
||||
|
||||
#define LOG_PRINT_CC_L0(ct, message) LOG_PRINT_L0("[" << epee::net_utils::print_connection_context_short(ct) << "]" << message)
|
||||
#define LOG_PRINT_CC_L1(ct, message) LOG_PRINT_L1("[" << epee::net_utils::print_connection_context_short(ct) << "]" << message)
|
||||
|
||||
249
external/CMakeLists.txt
vendored
249
external/CMakeLists.txt
vendored
@@ -1,11 +1,242 @@
|
||||
set(UPNPC_BUILD_STATIC ON CACHE BOOL "Build static library")
|
||||
set(UPNPC_BUILD_SHARED OFF CACHE BOOL "Build shared library")
|
||||
set(UPNPC_BUILD_TESTS OFF CACHE BOOL "Build test executables")
|
||||
add_subdirectory(miniupnpc)
|
||||
# Copyright (c) 2014, 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
|
||||
|
||||
set_property(TARGET upnpc-static PROPERTY FOLDER "external")
|
||||
if(MSVC)
|
||||
set_property(TARGET upnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -wd4244 -wd4267")
|
||||
elseif(NOT MSVC)
|
||||
set_property(TARGET upnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-undef -Wno-unused-result -Wno-unused-value")
|
||||
# --------------------------------- FindMiniupnpc Start ---------------------------------
|
||||
# Locate miniupnp library
|
||||
# This module defines
|
||||
# MINIUPNP_FOUND, if false, do not try to link to miniupnp
|
||||
# MINIUPNP_LIBRARY, the miniupnp variant
|
||||
# MINIUPNP_INCLUDE_DIR, where to find miniupnpc.h and family)
|
||||
# MINIUPNPC_VERSION_PRE1_6 --> set if we detect the version of miniupnpc is
|
||||
# pre 1.6
|
||||
# MINIUPNPC_VERSION_PRE1_5 --> set if we detect the version of miniupnpc is
|
||||
# pre 1.5
|
||||
#
|
||||
# Note that the expected include convention is
|
||||
# #include "miniupnpc.h"
|
||||
# and not
|
||||
# #include <miniupnpc/miniupnpc.h>
|
||||
# This is because, the miniupnpc location is not standardized and may exist
|
||||
# in locations other than miniupnpc/
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2011 Mark Vejvoda
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distributed this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
if (MINIUPNP_INCLUDE_DIR AND MINIUPNP_LIBRARY)
|
||||
# Already in cache, be silent
|
||||
set(MINIUPNP_FIND_QUIETLY TRUE)
|
||||
endif (MINIUPNP_INCLUDE_DIR AND MINIUPNP_LIBRARY)
|
||||
|
||||
find_path(MINIUPNP_INCLUDE_DIR miniupnpc.h
|
||||
PATH_SUFFIXES miniupnpc)
|
||||
find_library(MINIUPNP_LIBRARY miniupnpc)
|
||||
|
||||
if (MINIUPNP_INCLUDE_DIR AND MINIUPNP_LIBRARY)
|
||||
set (MINIUPNP_FOUND TRUE)
|
||||
endif ()
|
||||
|
||||
if (MINIUPNP_FOUND)
|
||||
include(CheckCXXSourceRuns)
|
||||
if (NOT MINIUPNP_FIND_QUIETLY)
|
||||
message (STATUS "Found the miniupnpc libraries at ${MINIUPNP_LIBRARY}")
|
||||
message (STATUS "Found the miniupnpc headers at ${MINIUPNP_INCLUDE_DIR}")
|
||||
endif (NOT MINIUPNP_FIND_QUIETLY)
|
||||
|
||||
message(STATUS "Detecting version of miniupnpc in path: ${MINIUPNP_INCLUDE_DIR}")
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${MINIUPNP_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${MINIUPNP_LIBRARY})
|
||||
check_cxx_source_runs("
|
||||
#include <miniwget.h>
|
||||
#include <miniupnpc.h>
|
||||
#include <upnpcommands.h>
|
||||
#include <stdio.h>
|
||||
int main()
|
||||
{
|
||||
static struct UPNPUrls urls;
|
||||
static struct IGDdatas data;
|
||||
|
||||
GetUPNPUrls (&urls, &data, \"myurl\",0);
|
||||
|
||||
return 0;
|
||||
}"
|
||||
MINIUPNPC_VERSION_1_7_OR_HIGHER)
|
||||
|
||||
IF (NOT MINIUPNPC_VERSION_1_7_OR_HIGHER)
|
||||
set(CMAKE_REQUIRED_INCLUDES ${MINIUPNP_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${MINIUPNP_LIBRARY})
|
||||
check_cxx_source_runs("
|
||||
#include <miniwget.h>
|
||||
#include <miniupnpc.h>
|
||||
#include <upnpcommands.h>
|
||||
#include <stdio.h>
|
||||
int main()
|
||||
{
|
||||
struct UPNPDev *devlist = NULL;
|
||||
int upnp_delay = 5000;
|
||||
const char *upnp_multicastif = NULL;
|
||||
const char *upnp_minissdpdsock = NULL;
|
||||
int upnp_sameport = 0;
|
||||
int upnp_ipv6 = 0;
|
||||
int upnp_error = 0;
|
||||
devlist = upnpDiscover(upnp_delay, upnp_multicastif, upnp_minissdpdsock, upnp_sameport, upnp_ipv6, &upnp_error);
|
||||
|
||||
return 0;
|
||||
}"
|
||||
MINIUPNPC_VERSION_PRE1_7)
|
||||
ENDIF()
|
||||
|
||||
IF (NOT MINIUPNPC_VERSION_PRE1_7 AND NOT MINIUPNPC_VERSION_1_7_OR_HIGHER)
|
||||
set(CMAKE_REQUIRED_INCLUDES ${MINIUPNP_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${MINIUPNP_LIBRARY})
|
||||
check_cxx_source_runs("
|
||||
#include <miniwget.h>
|
||||
#include <miniupnpc.h>
|
||||
#include <upnpcommands.h>
|
||||
#include <stdio.h>
|
||||
int main()
|
||||
{
|
||||
struct UPNPDev *devlist = NULL;
|
||||
int upnp_delay = 5000;
|
||||
const char *upnp_multicastif = NULL;
|
||||
const char *upnp_minissdpdsock = NULL;
|
||||
int upnp_sameport = 0;
|
||||
int upnp_ipv6 = 0;
|
||||
int upnp_error = 0;
|
||||
devlist = upnpDiscover(upnp_delay, upnp_multicastif, upnp_minissdpdsock, upnp_sameport);
|
||||
|
||||
return 0;
|
||||
}"
|
||||
MINIUPNPC_VERSION_PRE1_6)
|
||||
|
||||
ENDIF()
|
||||
|
||||
IF (NOT MINIUPNPC_VERSION_PRE1_6 AND NOT MINIUPNPC_VERSION_PRE1_7 AND NOT MINIUPNPC_VERSION_1_7_OR_HIGHER)
|
||||
set(CMAKE_REQUIRED_INCLUDES ${MINIUPNP_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${MINIUPNP_LIBRARY})
|
||||
check_cxx_source_runs("
|
||||
#include <miniwget.h>
|
||||
#include <miniupnpc.h>
|
||||
#include <upnpcommands.h>
|
||||
#include <stdio.h>
|
||||
static struct UPNPUrls urls;
|
||||
static struct IGDdatas data;
|
||||
int main()
|
||||
{
|
||||
char externalIP[16] = \"\";
|
||||
UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIP);
|
||||
|
||||
return 0;
|
||||
}"
|
||||
MINIUPNPC_VERSION_1_5_OR_HIGHER)
|
||||
ENDIF()
|
||||
|
||||
IF (NOT MINIUPNPC_VERSION_1_5_OR_HIGHER AND NOT MINIUPNPC_VERSION_PRE1_6 AND NOT MINIUPNPC_VERSION_PRE1_7 AND NOT MINIUPNPC_VERSION_1_7_OR_HIGHER)
|
||||
set(CMAKE_REQUIRED_INCLUDES ${MINIUPNP_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${MINIUPNP_LIBRARY})
|
||||
check_cxx_source_runs("
|
||||
#include <miniwget.h>
|
||||
#include <miniupnpc.h>
|
||||
#include <upnpcommands.h>
|
||||
#include <stdio.h>
|
||||
static struct UPNPUrls urls;
|
||||
static struct IGDdatas data;
|
||||
int main()
|
||||
{
|
||||
char externalIP[16] = \"\";
|
||||
UPNP_GetExternalIPAddress(urls.controlURL, data.servicetype, externalIP);
|
||||
|
||||
return 0;
|
||||
}"
|
||||
MINIUPNPC_VERSION_PRE1_5)
|
||||
|
||||
ENDIF()
|
||||
|
||||
IF(MINIUPNPC_VERSION_PRE1_5)
|
||||
message(STATUS "Found miniupnpc version is pre v1.5")
|
||||
ENDIF()
|
||||
IF(MINIUPNPC_VERSION_PRE1_6)
|
||||
message(STATUS "Found miniupnpc version is pre v1.6")
|
||||
ENDIF()
|
||||
IF(MINIUPNPC_VERSION_PRE1_7)
|
||||
message(STATUS "Found miniupnpc version is pre v1.7")
|
||||
ENDIF()
|
||||
|
||||
IF(NOT MINIUPNPC_VERSION_PRE1_5 AND NOT MINIUPNPC_VERSION_PRE1_6 AND NOT MINIUPNPC_VERSION_PRE1_7)
|
||||
IF(MINIUPNPC_VERSION_1_5_OR_HIGHER)
|
||||
message(STATUS "Found miniupnpc version is v1.5 or higher")
|
||||
ELSE()
|
||||
message(STATUS "Found miniupnpc version is v1.7 or higher")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
else ()
|
||||
message (STATUS "Could not find miniupnp")
|
||||
endif ()
|
||||
|
||||
MARK_AS_ADVANCED(MINIUPNP_INCLUDE_DIR MINIUPNP_LIBRARY)
|
||||
# --------------------------------- FindMiniupnpc End ---------------------------------
|
||||
|
||||
# And now on to the Monero part of things
|
||||
|
||||
if(MINIUPNP_FOUND AND MINIUPNPC_VERSION_1_7_OR_HIGHER)
|
||||
message(STATUS "Using shared miniupnpc found at ${MINIUPNP_INCLUDE_DIR}")
|
||||
|
||||
set(UPNP_STATIC false PARENT_SCOPE)
|
||||
set(UPNP_INCLUDE ${MINIUPNP_INCLUDE_DIR} PARENT_SCOPE)
|
||||
set(UPNP_LIBRARIES ${MINIUPNP_LIBRARY} PARENT_SCOPE)
|
||||
else()
|
||||
message(STATUS "Using static miniupnpc from external")
|
||||
|
||||
set(UPNPC_BUILD_STATIC ON CACHE BOOL "Build static library")
|
||||
set(UPNPC_BUILD_SHARED OFF CACHE BOOL "Build shared library")
|
||||
set(UPNPC_BUILD_TESTS OFF CACHE BOOL "Build test executables")
|
||||
add_subdirectory(miniupnpc)
|
||||
|
||||
set_property(TARGET upnpc-static PROPERTY FOLDER "external")
|
||||
if(MSVC)
|
||||
set_property(TARGET upnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -wd4244 -wd4267")
|
||||
elseif(NOT MSVC)
|
||||
set_property(TARGET upnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-undef -Wno-unused-result -Wno-unused-value")
|
||||
endif()
|
||||
|
||||
set(UPNP_STATIC true PARENT_SCOPE)
|
||||
set(UPNP_LIBRARIES "upnpc-static" PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
@@ -1,3 +1,33 @@
|
||||
# Copyright (c) 2014, 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
|
||||
|
||||
add_definitions(-DSTATICLIB)
|
||||
|
||||
file(GLOB_RECURSE COMMON common/*)
|
||||
@@ -30,13 +60,13 @@ add_library(cryptonote_core ${CRYPTONOTE_CORE})
|
||||
add_executable(daemon ${DAEMON} ${P2P} ${CRYPTONOTE_PROTOCOL})
|
||||
add_executable(connectivity_tool ${CONN_TOOL})
|
||||
add_executable(simpleminer ${MINER})
|
||||
target_link_libraries(daemon rpc cryptonote_core crypto common upnpc-static ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||
target_link_libraries(daemon rpc cryptonote_core crypto common ${UPNP_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||
target_link_libraries(connectivity_tool cryptonote_core crypto common ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||
target_link_libraries(simpleminer cryptonote_core crypto common ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||
add_library(rpc ${RPC})
|
||||
add_library(wallet ${WALLET})
|
||||
add_executable(simplewallet ${SIMPLEWALLET} )
|
||||
target_link_libraries(simplewallet wallet rpc cryptonote_core crypto common upnpc-static ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||
target_link_libraries(simplewallet wallet rpc cryptonote_core crypto common ${UPNP_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||
add_dependencies(daemon version)
|
||||
add_dependencies(rpc version)
|
||||
add_dependencies(simplewallet version)
|
||||
|
||||
@@ -47,4 +47,5 @@ namespace command_line
|
||||
const arg_descriptor<bool> arg_help = {"help", "Produce help message"};
|
||||
const arg_descriptor<bool> arg_version = {"version", "Output version information"};
|
||||
const arg_descriptor<std::string> arg_data_dir = {"data-dir", "Specify data directory"};
|
||||
const arg_descriptor<std::string> arg_testnet_data_dir = {"testnet-data-dir", "Specify testnet data directory"};
|
||||
}
|
||||
|
||||
@@ -203,4 +203,5 @@ namespace command_line
|
||||
extern const arg_descriptor<bool> arg_help;
|
||||
extern const arg_descriptor<bool> arg_version;
|
||||
extern const arg_descriptor<std::string> arg_data_dir;
|
||||
extern const arg_descriptor<std::string> arg_testnet_data_dir;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ using namespace epee;
|
||||
|
||||
namespace tools
|
||||
{
|
||||
std::function<void(void)> signal_handler::m_handler;
|
||||
std::function<void(void)> signal_handler::m_handler;
|
||||
|
||||
#ifdef WIN32
|
||||
std::string get_windows_version_display_string()
|
||||
@@ -313,17 +313,19 @@ std::string get_nix_version_display_string()
|
||||
return "";
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
std::string get_default_data_dir()
|
||||
{
|
||||
//namespace fs = boost::filesystem;
|
||||
/* Please for the love of god refactor the ifdefs out of this */
|
||||
|
||||
// namespace fs = boost::filesystem;
|
||||
// Windows < Vista: C:\Documents and Settings\Username\Application Data\CRYPTONOTE_NAME
|
||||
// Windows >= Vista: C:\Users\Username\AppData\Roaming\CRYPTONOTE_NAME
|
||||
// Mac: ~/Library/Application Support/CRYPTONOTE_NAME
|
||||
// Unix: ~/.CRYPTONOTE_NAME
|
||||
std::string config_folder;
|
||||
|
||||
#ifdef WIN32
|
||||
// Windows
|
||||
config_folder = get_special_folder_path(CSIDL_APPDATA, true) + "/" + CRYPTONOTE_NAME;
|
||||
#else
|
||||
std::string pathRet;
|
||||
|
||||
@@ -39,11 +39,41 @@
|
||||
#include "misc_language.h"
|
||||
#include "p2p/p2p_protocol_defs.h"
|
||||
|
||||
/*! \brief Various Tools
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
namespace tools
|
||||
{
|
||||
/*! \brief Returns the default data directory.
|
||||
*
|
||||
* \details Windows < Vista: C:\\Documents and Settings\\Username\\Application Data\\CRYPTONOTE_NAME
|
||||
*
|
||||
* Windows >= Vista: C:\\Users\\Username\\AppData\\Roaming\\CRYPTONOTE_NAME
|
||||
*
|
||||
* Mac: ~/Library/Application Support/CRYPTONOTE_NAME
|
||||
*
|
||||
* Unix: ~/.CRYPTONOTE_NAME
|
||||
*/
|
||||
std::string get_default_data_dir();
|
||||
|
||||
/*! \brief Returns the OS version string
|
||||
*
|
||||
* \details This is a wrapper around the primitives
|
||||
* get_windows_version_display_string() and
|
||||
* get_nix_version_display_string()
|
||||
*/
|
||||
std::string get_os_version_string();
|
||||
|
||||
/*! \brief creates directories for a path
|
||||
*
|
||||
* wrapper around boost::filesyste::create_directories.
|
||||
* (ensure-directory-exists): greenspun's tenth rule in action!
|
||||
*/
|
||||
bool create_directories_if_necessary(const std::string& path);
|
||||
/*! \brief std::rename wrapper for nix and something strange for windows.
|
||||
*/
|
||||
std::error_code replace_file(const std::string& replacement_name, const std::string& replaced_name);
|
||||
|
||||
inline crypto::hash get_proof_of_trust_hash(const nodetool::proof_of_trust& pot)
|
||||
@@ -54,10 +84,12 @@ namespace tools
|
||||
return crypto::cn_fast_hash(s.data(), s.size());
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Defines a signal handler for win32 and *nix
|
||||
*/
|
||||
class signal_handler
|
||||
{
|
||||
public:
|
||||
/*! \brief installs a signal handler */
|
||||
template<typename T>
|
||||
static bool install(T t)
|
||||
{
|
||||
@@ -69,6 +101,7 @@ namespace tools
|
||||
}
|
||||
return r;
|
||||
#else
|
||||
/* Only blocks SIGINT and SIGTERM */
|
||||
signal(SIGINT, posix_handler);
|
||||
signal(SIGTERM, posix_handler);
|
||||
m_handler = t;
|
||||
@@ -78,12 +111,12 @@ namespace tools
|
||||
|
||||
private:
|
||||
#if defined(WIN32)
|
||||
/*! \brief Handler for win */
|
||||
static BOOL WINAPI win_handler(DWORD type)
|
||||
{
|
||||
if (CTRL_C_EVENT == type || CTRL_BREAK_EVENT == type)
|
||||
{
|
||||
handle_signal();
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -93,12 +126,14 @@ namespace tools
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
/*! \brief handler for NIX */
|
||||
static void posix_handler(int /*type*/)
|
||||
{
|
||||
handle_signal();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! \brief calles m_handler */
|
||||
static void handle_signal()
|
||||
{
|
||||
static std::mutex m_mutex;
|
||||
@@ -106,7 +141,7 @@ namespace tools
|
||||
m_handler();
|
||||
}
|
||||
|
||||
private:
|
||||
/*! \brief where the installed handler is stored */
|
||||
static std::function<void(void)> m_handler;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -35,54 +35,94 @@
|
||||
#include <utility>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
/*! \file varint.h
|
||||
* \breif provides the implementation of varint's
|
||||
*
|
||||
* The representation of varints is rather odd. The first bit of each
|
||||
* octet is significant, it represents wheter there is another part
|
||||
* waiting to be read. For example 0x8002 would return 0x200, even
|
||||
* though 0x02 does not have its msb set. The actual way they are read
|
||||
* is as follows: Strip the msb of each byte, then from left to right,
|
||||
* read in what remains, placing it in reverse, into the buffer. Thus,
|
||||
* the following bit stream: 0xff02 would return 0x027f. 0xff turns
|
||||
* into 0x7f, is placed on the beggining of the buffer, then 0x02 is
|
||||
* unchanged, since its msb is not set, and placed at the end of the
|
||||
* buffer.
|
||||
*/
|
||||
|
||||
namespace tools {
|
||||
|
||||
template<typename OutputIt, typename T>
|
||||
typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value, void>::type
|
||||
write_varint(OutputIt &&dest, T i) {
|
||||
while (i >= 0x80) {
|
||||
*dest++ = (static_cast<char>(i) & 0x7f) | 0x80;
|
||||
i >>= 7;
|
||||
}
|
||||
*dest++ = static_cast<char>(i);
|
||||
}
|
||||
/*! \brief Error codes for varint
|
||||
*/
|
||||
enum {
|
||||
/* \brief Represents the overflow error */
|
||||
EVARINT_OVERFLOW = -1,
|
||||
/* \brief Represents a non conical represnetation */
|
||||
EVARINT_REPRESENT = -2,
|
||||
};
|
||||
|
||||
template<typename t_type>
|
||||
std::string get_varint_data(const t_type& v)
|
||||
/*! \brief writes a varint to a stream.
|
||||
*/
|
||||
template<typename OutputIt, typename T>
|
||||
/* Requires T to be both an integral type and unsigned, should be a compile error if it is not */
|
||||
typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value, void>::type
|
||||
write_varint(OutputIt &&dest, T i) {
|
||||
/* Make sure that there is one after this */
|
||||
while (i >= 0x80) {
|
||||
*dest = (static_cast<char>(i) & 0x7f) | 0x80;
|
||||
++dest;
|
||||
i >>= 7; /* I should be in multiples of 7, this should just get the next part */
|
||||
}
|
||||
/* writes the last one to dest */
|
||||
*dest = static_cast<char>(i);
|
||||
dest++; /* Seems kinda pointless... */
|
||||
}
|
||||
|
||||
/*! \brief Returns the string that represents the varint
|
||||
*/
|
||||
template<typename T>
|
||||
std::string get_varint_data(const T& v)
|
||||
{
|
||||
std::stringstream ss;
|
||||
write_varint(std::ostreambuf_iterator<char>(ss), v);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
template<int bits, typename InputIt, typename T>
|
||||
/*! \brief reads in the varint that is pointed to by InputIt into write
|
||||
*/
|
||||
template<int bits, typename InputIt, typename T>
|
||||
typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value && 0 <= bits && bits <= std::numeric_limits<T>::digits, int>::type
|
||||
read_varint(InputIt &&first, InputIt &&last, T &i) {
|
||||
int read = 0;
|
||||
i = 0;
|
||||
for (int shift = 0;; shift += 7) {
|
||||
if (first == last) {
|
||||
return read; // End of input.
|
||||
}
|
||||
unsigned char byte = *first++;
|
||||
++read;
|
||||
if (shift + 7 >= bits && byte >= 1 << (bits - shift)) {
|
||||
return -1; // Overflow.
|
||||
}
|
||||
if (byte == 0 && shift != 0) {
|
||||
return -2; // Non-canonical representation.
|
||||
}
|
||||
i |= static_cast<T>(byte & 0x7f) << shift;
|
||||
if ((byte & 0x80) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return read;
|
||||
}
|
||||
read_varint(InputIt &&first, InputIt &&last, T &write) {
|
||||
int read = 0;
|
||||
write = 0;
|
||||
for (int shift = 0;; shift += 7) {
|
||||
if (first == last) {
|
||||
return read;
|
||||
}
|
||||
unsigned char byte = *first;
|
||||
++first;
|
||||
++read;
|
||||
if (shift + 7 >= bits && byte >= 1 << (bits - shift)) {
|
||||
return EVARINT_OVERFLOW;
|
||||
}
|
||||
if (byte == 0 && shift != 0) {
|
||||
return EVARINT_REPRESENT;
|
||||
}
|
||||
|
||||
template<typename InputIt, typename T>
|
||||
int read_varint(InputIt &&first, InputIt &&last, T &i) {
|
||||
return read_varint<std::numeric_limits<T>::digits, InputIt, T>(std::move(first), std::move(last), i);
|
||||
write |= static_cast<T>(byte & 0x7f) << shift; /* Does the actualy placing into write, stripping the first bit */
|
||||
|
||||
/* If there is no next */
|
||||
if ((byte & 0x80) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return read;
|
||||
}
|
||||
|
||||
/*! \brief Wrapper around the other read_varint,
|
||||
* Sets template parameters for you.
|
||||
*/
|
||||
template<typename InputIt, typename T>
|
||||
int read_varint(InputIt &&first, InputIt &&last, T &i) {
|
||||
return read_varint<std::numeric_limits<T>::digits, InputIt, T>(std::move(first), std::move(last), i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ bool handle_request_stat(po::variables_map& vm, peerid_type peer_id)
|
||||
pot.peer_id = peer_id;
|
||||
pot.time = time(NULL);
|
||||
crypto::public_key pubk = AUTO_VAL_INIT(pubk);
|
||||
string_tools::hex_to_pod(P2P_STAT_TRUSTED_PUB_KEY, pubk);
|
||||
string_tools::hex_to_pod(::config::P2P_REMOTE_DEBUG_TRUSTED_PUB_KEY, pubk);
|
||||
crypto::hash h = tools::get_proof_of_trust_hash(pot);
|
||||
crypto::generate_signature(h, pubk, prvk, pot.sign);
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
//
|
||||
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
|
||||
|
||||
#include <alloca.h>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
@@ -42,6 +41,12 @@
|
||||
#include "crypto.h"
|
||||
#include "hash.h"
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
#include <alloca.h>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
namespace crypto {
|
||||
|
||||
using std::abort;
|
||||
|
||||
@@ -33,13 +33,20 @@ static const char _NR[] = {
|
||||
|
||||
#include <stddef.h>
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef __APPLE__
|
||||
#include <malloc.h>
|
||||
// Both OS X and FreeBSD don't need malloc.h
|
||||
#if !defined(__APPLE__) && !defined(__FreeBSD__)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
// FreeBSD also doesn't need timeb.h
|
||||
#ifndef __FreeBSD__
|
||||
#include <sys/timeb.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
@@ -463,6 +470,7 @@ OAES_RET oaes_sprintf(
|
||||
#ifdef OAES_HAVE_ISAAC
|
||||
static void oaes_get_seed( char buf[RANDSIZ + 1] )
|
||||
{
|
||||
#ifndef __FreeBSD__
|
||||
struct timeb timer;
|
||||
struct tm *gmTimer;
|
||||
char * _test = NULL;
|
||||
@@ -474,13 +482,27 @@ static void oaes_get_seed( char buf[RANDSIZ + 1] )
|
||||
gmTimer->tm_year + 1900, gmTimer->tm_mon + 1, gmTimer->tm_mday,
|
||||
gmTimer->tm_hour, gmTimer->tm_min, gmTimer->tm_sec, timer.millitm,
|
||||
_test + timer.millitm, getpid() );
|
||||
#else
|
||||
struct timeval timer;
|
||||
struct tm *gmTimer;
|
||||
char * _test = NULL;
|
||||
|
||||
gettimeofday(&timer, NULL);
|
||||
gmTimer = gmtime( &timer.tv_sec );
|
||||
_test = (char *) calloc( sizeof( char ), timer.tv_usec/1000 );
|
||||
sprintf( buf, "%04d%02d%02d%02d%02d%02d%03d%p%d",
|
||||
gmTimer->tm_year + 1900, gmTimer->tm_mon + 1, gmTimer->tm_mday,
|
||||
gmTimer->tm_hour, gmTimer->tm_min, gmTimer->tm_sec, timer.tv_usec/1000,
|
||||
_test + timer.tv_usec/1000, getpid() );
|
||||
#endif
|
||||
|
||||
if( _test )
|
||||
free( _test );
|
||||
}
|
||||
#else
|
||||
static uint32_t oaes_get_seed(void)
|
||||
{
|
||||
#ifndef __FreeBSD__
|
||||
struct timeb timer;
|
||||
struct tm *gmTimer;
|
||||
char * _test = NULL;
|
||||
@@ -492,6 +514,19 @@ static uint32_t oaes_get_seed(void)
|
||||
_ret = gmTimer->tm_year + 1900 + gmTimer->tm_mon + 1 + gmTimer->tm_mday +
|
||||
gmTimer->tm_hour + gmTimer->tm_min + gmTimer->tm_sec + timer.millitm +
|
||||
(uintptr_t) ( _test + timer.millitm ) + getpid();
|
||||
#else
|
||||
struct timeval timer;
|
||||
struct tm *gmTimer;
|
||||
char * _test = NULL;
|
||||
uint32_t _ret = 0;
|
||||
|
||||
gettimeofday(&timer, NULL);
|
||||
gmTimer = gmtime( &timer.tv_sec );
|
||||
_test = (char *) calloc( sizeof( char ), timer.tv_usec/1000 );
|
||||
_ret = gmTimer->tm_year + 1900 + gmTimer->tm_mon + 1 + gmTimer->tm_mday +
|
||||
gmTimer->tm_hour + gmTimer->tm_min + gmTimer->tm_sec + timer.tv_usec/1000 +
|
||||
(uintptr_t) ( _test + timer.tv_usec/1000 ) + getpid();
|
||||
#endif
|
||||
|
||||
if( _test )
|
||||
free( _test );
|
||||
|
||||
@@ -330,7 +330,7 @@ void slow_hash_allocate_state(void)
|
||||
hp_state = (uint8_t *) VirtualAlloc(hp_state, MEMORY, MEM_LARGE_PAGES |
|
||||
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
#else
|
||||
#if defined(__APPLE__)
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||||
hp_state = mmap(0, MEMORY, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANON, 0, 0);
|
||||
#else
|
||||
|
||||
@@ -28,13 +28,18 @@
|
||||
//
|
||||
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
|
||||
|
||||
#include <alloca.h>
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "hash-ops.h"
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
#include <alloca.h>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
/// Quick check if this is power of two (use on unsigned types; in this case for size_t only)
|
||||
bool ispowerof2_size_t(size_t x) {
|
||||
return x && !(x & (x - 1));
|
||||
|
||||
@@ -30,12 +30,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
|
||||
#define CRYPTONOTE_MAX_BLOCK_NUMBER 500000000
|
||||
#define CRYPTONOTE_MAX_BLOCK_SIZE 500000000 // block header blob limit, never used!
|
||||
#define CRYPTONOTE_GETBLOCKTEMPLATE_MAX_BLOCK_SIZE 196608 //size of block (bytes) that is the maximum that miners will produce
|
||||
#define CRYPTONOTE_MAX_TX_SIZE 1000000000
|
||||
#define CRYPTONOTE_PUBLIC_ADDRESS_TEXTBLOB_VER 0
|
||||
#define CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX 18 // addresses start with "4"
|
||||
#define CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW 60
|
||||
#define CURRENT_TRANSACTION_VERSION 1
|
||||
#define CURRENT_BLOCK_MAJOR_VERSION 1
|
||||
@@ -81,8 +83,6 @@
|
||||
#define CRYPTONOTE_MEMPOOL_TX_LIVETIME 86400 //seconds, one day
|
||||
#define CRYPTONOTE_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME 604800 //seconds, one week
|
||||
|
||||
#define P2P_DEFAULT_PORT 18080
|
||||
#define RPC_DEFAULT_PORT 18081
|
||||
#define COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT 1000
|
||||
|
||||
#define P2P_LOCAL_WHITE_PEERLIST_LIMIT 1000
|
||||
@@ -96,7 +96,6 @@
|
||||
#define P2P_DEFAULT_PING_CONNECTION_TIMEOUT 2000 //2 seconds
|
||||
#define P2P_DEFAULT_INVOKE_TIMEOUT 60*2*1000 //2 minutes
|
||||
#define P2P_DEFAULT_HANDSHAKE_INVOKE_TIMEOUT 5000 //5 seconds
|
||||
#define P2P_STAT_TRUSTED_PUB_KEY "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
#define P2P_DEFAULT_WHITELIST_CONNECTIONS_PERCENT 70
|
||||
|
||||
#define ALLOW_DEBUG_COMMANDS
|
||||
@@ -110,3 +109,32 @@
|
||||
|
||||
#define THREAD_STACK_SIZE 5 * 1024 * 1024
|
||||
|
||||
// New constants are intended to go here
|
||||
namespace config
|
||||
{
|
||||
uint64_t const DEFAULT_FEE_ATOMIC_XMR_PER_KB = 500; // Just a placeholder! Change me!
|
||||
uint8_t const FEE_CALCULATION_MAX_RETRIES = 10;
|
||||
uint64_t const DEFAULT_DUST_THRESHOLD = 5000000000; // 5 * 10^9
|
||||
std::string const P2P_REMOTE_DEBUG_TRUSTED_PUB_KEY = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
|
||||
uint64_t const CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX = 18;
|
||||
uint16_t const P2P_DEFAULT_PORT = 18080;
|
||||
uint16_t const RPC_DEFAULT_PORT = 18081;
|
||||
boost::uuids::uuid const NETWORK_ID = { {
|
||||
0x12 ,0x30, 0xF1, 0x71 , 0x61, 0x04 , 0x41, 0x61, 0x17, 0x31, 0x00, 0x82, 0x16, 0xA1, 0xA1, 0x10
|
||||
} }; // Bender's nightmare
|
||||
std::string const GENESIS_TX = "013c01ff0001ffffffffffff03029b2e4c0281c0b02e7c53291a94d1d0cbff8883f8024f5142ee494ffbbd08807121017767aafcde9be00dcfd098715ebcf7f410daebc582fda69d24a28e9d0bc890d1";
|
||||
uint32_t const GENESIS_NONCE = 10000;
|
||||
|
||||
namespace testnet
|
||||
{
|
||||
uint64_t const CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX = 53;
|
||||
uint16_t const P2P_DEFAULT_PORT = 28080;
|
||||
uint16_t const RPC_DEFAULT_PORT = 28081;
|
||||
boost::uuids::uuid const NETWORK_ID = { {
|
||||
0x12 ,0x30, 0xF1, 0x71 , 0x61, 0x04 , 0x41, 0x61, 0x17, 0x31, 0x00, 0x82, 0x16, 0xA1, 0xA1, 0x11
|
||||
} }; // Bender's daydream
|
||||
std::string const GENESIS_TX = "013c01ff0001ffffffffffff0f029b2e4c0281c0b02e7c53291a94d1d0cbff8883f8024f5142ee494ffbbd0880712101168d0c4ca86fb55a4cf6a36d31431be1c53a3bd7411bb24e8832410289fa6f3b";
|
||||
uint32_t const GENESIS_NONCE = 10001;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,10 +93,10 @@ DISABLE_VS_WARNINGS(4244 4345)
|
||||
return m_keys;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
std::string account_base::get_public_address_str()
|
||||
std::string account_base::get_public_address_str(bool testnet)
|
||||
{
|
||||
//TODO: change this code into base 58
|
||||
return get_account_address_as_str(m_keys.m_account_address);
|
||||
return get_account_address_as_str(testnet, m_keys.m_account_address);
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace cryptonote
|
||||
account_base();
|
||||
crypto::secret_key generate(const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false, bool two_random = false);
|
||||
const account_keys& get_keys() const;
|
||||
std::string get_public_address_str();
|
||||
std::string get_public_address_str(bool testnet);
|
||||
|
||||
uint64_t get_createtime() const { return m_creation_timestamp; }
|
||||
void set_createtime(uint64_t val) { m_creation_timestamp = val; }
|
||||
|
||||
@@ -82,7 +82,7 @@ uint64_t blockchain_storage::get_current_blockchain_height()
|
||||
return m_blocks.size();
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool blockchain_storage::init(const std::string& config_folder)
|
||||
bool blockchain_storage::init(const std::string& config_folder, bool testnet)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
m_config_folder = config_folder;
|
||||
@@ -114,18 +114,42 @@ bool blockchain_storage::init(const std::string& config_folder)
|
||||
LOG_PRINT_L0("Can't load blockchain storage from file, generating genesis block.");
|
||||
block bl = boost::value_initialized<block>();
|
||||
block_verification_context bvc = boost::value_initialized<block_verification_context>();
|
||||
generate_genesis_block(bl);
|
||||
if (testnet)
|
||||
{
|
||||
generate_genesis_block(bl, config::testnet::GENESIS_TX, config::testnet::GENESIS_NONCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
generate_genesis_block(bl, config::GENESIS_TX, config::GENESIS_NONCE);
|
||||
}
|
||||
add_new_block(bl, bvc);
|
||||
CHECK_AND_ASSERT_MES(!bvc.m_verifivation_failed && bvc.m_added_to_main_chain, false, "Failed to add genesis block to blockchain");
|
||||
}
|
||||
if(!m_blocks.size())
|
||||
{
|
||||
LOG_PRINT_L0("Blockchain not loaded, generating genesis block.");
|
||||
block bl = boost::value_initialized<block>();
|
||||
block_verification_context bvc = boost::value_initialized<block_verification_context>();
|
||||
generate_genesis_block(bl);
|
||||
add_new_block(bl, bvc);
|
||||
CHECK_AND_ASSERT_MES(!bvc.m_verifivation_failed, false, "Failed to add genesis block to blockchain");
|
||||
|
||||
if (!store_genesis_block(testnet)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
cryptonote::block b;
|
||||
|
||||
if (testnet)
|
||||
{
|
||||
generate_genesis_block(b, config::testnet::GENESIS_TX, config::testnet::GENESIS_NONCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
generate_genesis_block(b, config::GENESIS_TX, config::GENESIS_NONCE);
|
||||
}
|
||||
|
||||
crypto::hash genesis_hash = get_block_hash(m_blocks[0].bl);
|
||||
crypto::hash testnet_genesis_hash = get_block_hash(b);
|
||||
if (genesis_hash != testnet_genesis_hash) {
|
||||
LOG_ERROR("Failed to init: genesis block mismatch. Probably you set --testnet flag with data dir with non-test blockchain or another network.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
uint64_t timestamp_diff = time(NULL) - m_blocks.back().bl.timestamp;
|
||||
if(!m_blocks.back().bl.timestamp)
|
||||
@@ -134,6 +158,24 @@ bool blockchain_storage::init(const std::string& config_folder)
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool blockchain_storage::store_genesis_block(bool testnet) {
|
||||
block bl = ::boost::value_initialized<block>();
|
||||
block_verification_context bvc = boost::value_initialized<block_verification_context>();
|
||||
|
||||
if (testnet)
|
||||
{
|
||||
generate_genesis_block(bl, config::testnet::GENESIS_TX, config::testnet::GENESIS_NONCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
generate_genesis_block(bl, config::GENESIS_TX, config::GENESIS_NONCE);
|
||||
}
|
||||
|
||||
add_new_block(bl, bvc);
|
||||
CHECK_AND_ASSERT_MES(!bvc.m_verifivation_failed, false, "Failed to add genesis block to blockchain");
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool blockchain_storage::store_blockchain()
|
||||
{
|
||||
m_is_blockchain_storing = true;
|
||||
@@ -403,17 +445,17 @@ bool blockchain_storage::rollback_blockchain_switching(std::list<block>& origina
|
||||
for(size_t i = m_blocks.size()-1; i >=rollback_height; i--)
|
||||
{
|
||||
bool r = pop_block_from_blockchain();
|
||||
CHECK_AND_ASSERT_MES(r, false, "PANIC!!! failed to remove block while chain switching during the rollback!");
|
||||
CHECK_AND_ASSERT_MES(r, false, "PANIC! failed to remove block while chain switching during the rollback!");
|
||||
}
|
||||
//return back original chain
|
||||
BOOST_FOREACH(auto& bl, original_chain)
|
||||
{
|
||||
block_verification_context bvc = boost::value_initialized<block_verification_context>();
|
||||
bool r = handle_block_to_main_chain(bl, bvc);
|
||||
CHECK_AND_ASSERT_MES(r && bvc.m_added_to_main_chain, false, "PANIC!!! failed to add (again) block while chain switching during the rollback!");
|
||||
CHECK_AND_ASSERT_MES(r && bvc.m_added_to_main_chain, false, "PANIC! failed to add (again) block while chain switching during the rollback!");
|
||||
}
|
||||
|
||||
LOG_PRINT_L0("Rollback success.");
|
||||
LOG_PRINT_L1("Rollback success.");
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
@@ -443,10 +485,10 @@ bool blockchain_storage::switch_to_alternative_blockchain(std::list<blocks_ext_b
|
||||
bool r = handle_block_to_main_chain(ch_ent->second.bl, bvc);
|
||||
if(!r || !bvc.m_added_to_main_chain)
|
||||
{
|
||||
LOG_PRINT_L0("Failed to switch to alternative blockchain");
|
||||
LOG_PRINT_L1("Failed to switch to alternative blockchain");
|
||||
rollback_blockchain_switching(disconnected_chain, split_height);
|
||||
add_block_as_invalid(ch_ent->second, get_block_hash(ch_ent->second.bl));
|
||||
LOG_PRINT_L0("The block was inserted as invalid while connecting new alternative chain, block_id: " << get_block_hash(ch_ent->second.bl));
|
||||
LOG_PRINT_L1("The block was inserted as invalid while connecting new alternative chain, block_id: " << get_block_hash(ch_ent->second.bl));
|
||||
m_alternative_chains.erase(ch_ent);
|
||||
|
||||
for(auto alt_ch_to_orph_iter = ++alt_ch_iter; alt_ch_to_orph_iter != alt_chain.end(); alt_ch_to_orph_iter++)
|
||||
@@ -468,7 +510,7 @@ bool blockchain_storage::switch_to_alternative_blockchain(std::list<blocks_ext_b
|
||||
bool r = handle_alternative_block(old_ch_ent, get_block_hash(old_ch_ent), bvc);
|
||||
if(!r)
|
||||
{
|
||||
LOG_ERROR("Failed to push ex-main chain blocks to alternative chain ");
|
||||
LOG_PRINT_L1("Failed to push ex-main chain blocks to alternative chain ");
|
||||
rollback_blockchain_switching(disconnected_chain, split_height);
|
||||
return false;
|
||||
}
|
||||
@@ -536,17 +578,17 @@ bool blockchain_storage::prevalidate_miner_transaction(const block& b, uint64_t
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.vin[0].type() == typeid(txin_gen), false, "coinbase transaction in the block has the wrong type");
|
||||
if(boost::get<txin_gen>(b.miner_tx.vin[0]).height != height)
|
||||
{
|
||||
LOG_PRINT_RED_L0("The miner transaction in block has invalid height: " << boost::get<txin_gen>(b.miner_tx.vin[0]).height << ", expected: " << height);
|
||||
LOG_PRINT_RED_L1("The miner transaction in block has invalid height: " << boost::get<txin_gen>(b.miner_tx.vin[0]).height << ", expected: " << height);
|
||||
return false;
|
||||
}
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.unlock_time == height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW,
|
||||
false,
|
||||
"coinbase transaction transaction have wrong unlock time=" << b.miner_tx.unlock_time << ", expected " << height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW);
|
||||
"coinbase transaction transaction has the wrong unlock time=" << b.miner_tx.unlock_time << ", expected " << height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
//check outs overflow
|
||||
if(!check_outs_overflow(b.miner_tx))
|
||||
{
|
||||
LOG_PRINT_RED_L0("miner transaction have money overflow in block " << get_block_hash(b));
|
||||
LOG_PRINT_RED_L1("miner transaction has money overflow in block " << get_block_hash(b));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -563,17 +605,17 @@ bool blockchain_storage::validate_miner_transaction(const block& b, size_t cumul
|
||||
std::vector<size_t> last_blocks_sizes;
|
||||
get_last_n_blocks_sizes(last_blocks_sizes, CRYPTONOTE_REWARD_BLOCKS_WINDOW);
|
||||
if (!get_block_reward(epee::misc_utils::median(last_blocks_sizes), cumulative_block_size, already_generated_coins, base_reward)) {
|
||||
LOG_PRINT_L0("block size " << cumulative_block_size << " is bigger than allowed for this blockchain");
|
||||
LOG_PRINT_L1("block size " << cumulative_block_size << " is bigger than allowed for this blockchain");
|
||||
return false;
|
||||
}
|
||||
if(base_reward + fee < money_in_use)
|
||||
{
|
||||
LOG_ERROR("coinbase transaction spend too much money (" << print_money(money_in_use) << "). Block reward is " << print_money(base_reward + fee) << "(" << print_money(base_reward) << "+" << print_money(fee) << ")");
|
||||
LOG_PRINT_L1("coinbase transaction spend too much money (" << print_money(money_in_use) << "). Block reward is " << print_money(base_reward + fee) << "(" << print_money(base_reward) << "+" << print_money(fee) << ")");
|
||||
return false;
|
||||
}
|
||||
if(base_reward + fee != money_in_use)
|
||||
{
|
||||
LOG_ERROR("coinbase transaction doesn't use full amount of block reward: spent: "
|
||||
LOG_PRINT_L1("coinbase transaction doesn't use full amount of block reward: spent: "
|
||||
<< print_money(money_in_use) << ", block reward " << print_money(base_reward + fee) << "(" << print_money(base_reward) << "+" << print_money(fee) << ")");
|
||||
return false;
|
||||
}
|
||||
@@ -706,7 +748,7 @@ bool blockchain_storage::create_block_template(block& b, const account_public_ad
|
||||
b.miner_tx.extra.resize(b.miner_tx.extra.size() - 1);
|
||||
if (cumulative_size != txs_size + get_object_blobsize(b.miner_tx)) {
|
||||
//fuck, not lucky, -1 makes varint-counter size smaller, in that case we continue to grow with cumulative_size
|
||||
LOG_PRINT_RED("Miner tx creation have no luck with delta_extra size = " << delta << " and " << delta - 1 , LOG_LEVEL_2);
|
||||
LOG_PRINT_RED("Miner tx creation has no luck with delta_extra size = " << delta << " and " << delta - 1 , LOG_LEVEL_2);
|
||||
cumulative_size += delta - 1;
|
||||
continue;
|
||||
}
|
||||
@@ -751,13 +793,13 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto::
|
||||
uint64_t block_height = get_block_height(b);
|
||||
if(0 == block_height)
|
||||
{
|
||||
LOG_ERROR("Block with id: " << epee::string_tools::pod_to_hex(id) << " (as alternative) have wrong miner transaction");
|
||||
LOG_PRINT_L1("Block with id: " << epee::string_tools::pod_to_hex(id) << " (as alternative) has wrong miner transaction");
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
if (!m_checkpoints.is_alternative_block_allowed(get_current_blockchain_height(), block_height))
|
||||
{
|
||||
LOG_PRINT_RED_L0("Block with id: " << id
|
||||
LOG_PRINT_RED_L1("Block with id: " << id
|
||||
<< ENDL << " can't be accepted for alternative chain, block height: " << block_height
|
||||
<< ENDL << " blockchain height: " << get_current_blockchain_height());
|
||||
bvc.m_verifivation_failed = true;
|
||||
@@ -789,7 +831,7 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto::
|
||||
CHECK_AND_ASSERT_MES(m_blocks.size() > alt_chain.front()->second.height, false, "main blockchain wrong height");
|
||||
crypto::hash h = null_hash;
|
||||
get_block_hash(m_blocks[alt_chain.front()->second.height - 1].bl, h);
|
||||
CHECK_AND_ASSERT_MES(h == alt_chain.front()->second.bl.prev_id, false, "alternative chain have wrong connection to main chain");
|
||||
CHECK_AND_ASSERT_MES(h == alt_chain.front()->second.bl.prev_id, false, "alternative chain has wrong connection to main chain");
|
||||
complete_timestamps_vector(alt_chain.front()->second.height - 1, timestamps);
|
||||
}else
|
||||
{
|
||||
@@ -799,8 +841,8 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto::
|
||||
//check timestamp correct
|
||||
if(!check_block_timestamp(timestamps, b))
|
||||
{
|
||||
LOG_PRINT_RED_L0("Block with id: " << id
|
||||
<< ENDL << " for alternative chain, have invalid timestamp: " << b.timestamp);
|
||||
LOG_PRINT_RED_L1("Block with id: " << id
|
||||
<< ENDL << " for alternative chain, has invalid timestamp: " << b.timestamp);
|
||||
//add_block_as_invalid(b, id);//do not add blocks to invalid storage before proof of work check was passed
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
@@ -826,8 +868,8 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto::
|
||||
get_block_longhash(bei.bl, proof_of_work, bei.height);
|
||||
if(!check_hash(proof_of_work, current_diff))
|
||||
{
|
||||
LOG_PRINT_RED_L0("Block with id: " << id
|
||||
<< ENDL << " for alternative chain, have not enough proof of work: " << proof_of_work
|
||||
LOG_PRINT_RED_L1("Block with id: " << id
|
||||
<< ENDL << " for alternative chain, does not have enough proof of work: " << proof_of_work
|
||||
<< ENDL << " expected difficulty: " << current_diff);
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
@@ -835,8 +877,8 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto::
|
||||
|
||||
if(!prevalidate_miner_transaction(b, bei.height))
|
||||
{
|
||||
LOG_PRINT_RED_L0("Block with id: " << epee::string_tools::pod_to_hex(id)
|
||||
<< " (as alternative) have wrong miner transaction.");
|
||||
LOG_PRINT_RED_L1("Block with id: " << epee::string_tools::pod_to_hex(id)
|
||||
<< " (as alternative) has incorrect miner transaction.");
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
|
||||
@@ -883,7 +925,7 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto::
|
||||
{
|
||||
//block orphaned
|
||||
bvc.m_marked_as_orphaned = true;
|
||||
LOG_PRINT_RED_L0("Block recognized as orphaned and rejected, id = " << id);
|
||||
LOG_PRINT_RED_L1("Block recognized as orphaned and rejected, id = " << id);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -899,7 +941,7 @@ bool blockchain_storage::get_blocks(uint64_t start_offset, size_t count, std::li
|
||||
blocks.push_back(m_blocks[i].bl);
|
||||
std::list<crypto::hash> missed_ids;
|
||||
get_transactions(m_blocks[i].bl.tx_hashes, txs, missed_ids);
|
||||
CHECK_AND_ASSERT_MES(!missed_ids.size(), false, "have missed transactions in own block in main blockchain");
|
||||
CHECK_AND_ASSERT_MES(!missed_ids.size(), false, "has missed transactions in own block in main blockchain");
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -928,7 +970,7 @@ bool blockchain_storage::handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request&
|
||||
std::list<crypto::hash> missed_tx_id;
|
||||
std::list<transaction> txs;
|
||||
get_transactions(bl.tx_hashes, txs, rsp.missed_ids);
|
||||
CHECK_AND_ASSERT_MES(!missed_tx_id.size(), false, "Internal error: have missed missed_tx_id.size()=" << missed_tx_id.size()
|
||||
CHECK_AND_ASSERT_MES(!missed_tx_id.size(), false, "Internal error: has missed missed_tx_id.size()=" << missed_tx_id.size()
|
||||
<< ENDL << "for block id = " << get_block_hash(bl));
|
||||
rsp.blocks.push_back(block_complete_entry());
|
||||
block_complete_entry& e = rsp.blocks.back();
|
||||
@@ -1006,7 +1048,6 @@ size_t blockchain_storage::find_end_of_allowed_index(const std::vector<std::pair
|
||||
//------------------------------------------------------------------
|
||||
bool blockchain_storage::get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res)
|
||||
{
|
||||
srand(static_cast<unsigned int>(time(NULL)));
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
BOOST_FOREACH(uint64_t amount, req.amounts)
|
||||
{
|
||||
@@ -1015,7 +1056,7 @@ bool blockchain_storage::get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDO
|
||||
auto it = m_outputs.find(amount);
|
||||
if(it == m_outputs.end())
|
||||
{
|
||||
LOG_ERROR("COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS: not outs for amount " << amount << ", wallet should use some real outs when it lookup for some mix, so, at least one out for this amount should exist");
|
||||
LOG_PRINT_L1("COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS: not outs for amount " << amount << ", wallet should use some real outs when it lookup for some mix, so, at least one out for this amount should exist");
|
||||
continue;//actually this is strange situation, wallet should use some real outs when it lookup for some mix, so, at least one out for this amount should exist
|
||||
}
|
||||
std::vector<std::pair<crypto::hash, size_t> >& amount_outs = it->second;
|
||||
@@ -1029,7 +1070,7 @@ bool blockchain_storage::get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDO
|
||||
size_t try_count = 0;
|
||||
for(uint64_t j = 0; j != req.outs_count && try_count < up_index_limit;)
|
||||
{
|
||||
size_t i = rand()%up_index_limit;
|
||||
size_t i = crypto::rand<size_t>()%up_index_limit;
|
||||
if(used.count(i))
|
||||
continue;
|
||||
bool added = add_out_to_get_random_outs(amount_outs, result_outs, amount, i);
|
||||
@@ -1053,13 +1094,13 @@ bool blockchain_storage::find_blockchain_supplement(const std::list<crypto::hash
|
||||
|
||||
if(!qblock_ids.size() /*|| !req.m_total_height*/)
|
||||
{
|
||||
LOG_ERROR("Client sent wrong NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << qblock_ids.size() << /*", m_height=" << req.m_total_height <<*/ ", dropping connection");
|
||||
LOG_PRINT_L1("Client sent wrong NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << qblock_ids.size() << /*", m_height=" << req.m_total_height <<*/ ", dropping connection");
|
||||
return false;
|
||||
}
|
||||
//check genesis match
|
||||
if(qblock_ids.back() != get_block_hash(m_blocks[0].bl))
|
||||
{
|
||||
LOG_ERROR("Client sent wrong NOTIFY_REQUEST_CHAIN: genesis block missmatch: " << ENDL << "id: "
|
||||
LOG_PRINT_L1("Client sent wrong NOTIFY_REQUEST_CHAIN: genesis block missmatch: " << ENDL << "id: "
|
||||
<< qblock_ids.back() << ", " << ENDL << "expected: " << get_block_hash(m_blocks[0].bl)
|
||||
<< "," << ENDL << " dropping connection");
|
||||
return false;
|
||||
@@ -1078,14 +1119,14 @@ bool blockchain_storage::find_blockchain_supplement(const std::list<crypto::hash
|
||||
|
||||
if(bl_it == qblock_ids.end())
|
||||
{
|
||||
LOG_ERROR("Internal error handling connection, can't find split point");
|
||||
LOG_PRINT_L1("Internal error handling connection, can't find split point");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(block_index_it == m_blocks_index.end())
|
||||
{
|
||||
//this should NEVER happen, but, dose of paranoia in such cases is not too bad
|
||||
LOG_ERROR("Internal error handling connection, can't find split point");
|
||||
LOG_PRINT_L1("Internal error handling connection, can't find split point");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1110,7 +1151,7 @@ void blockchain_storage::print_blockchain(uint64_t start_index, uint64_t end_ind
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
if(start_index >=m_blocks.size())
|
||||
{
|
||||
LOG_PRINT_L0("Wrong starter index set: " << start_index << ", expected max index " << m_blocks.size()-1);
|
||||
LOG_PRINT_L1("Wrong starter index set: " << start_index << ", expected max index " << m_blocks.size()-1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1205,7 +1246,7 @@ bool blockchain_storage::add_block_as_invalid(const block_extended_info& bei, co
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
auto i_res = m_invalid_blocks.insert(std::map<crypto::hash, block_extended_info>::value_type(h, bei));
|
||||
CHECK_AND_ASSERT_MES(i_res.second, false, "at insertion invalid by tx returned status existed");
|
||||
LOG_PRINT_L0("BLOCK ADDED AS INVALID: " << h << ENDL << ", prev_id=" << bei.bl.prev_id << ", m_invalid_blocks count=" << m_invalid_blocks.size());
|
||||
LOG_PRINT_L1("BLOCK ADDED AS INVALID: " << h << ENDL << ", prev_id=" << bei.bl.prev_id << ", m_invalid_blocks count=" << m_invalid_blocks.size());
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
@@ -1306,7 +1347,7 @@ bool blockchain_storage::add_transaction_from_block(const transaction& tx, const
|
||||
if(!r.second)
|
||||
{
|
||||
//double spend detected
|
||||
LOG_PRINT_L0("tx with id: " << m_tx_id << " in block id: " << m_bl_id << " have input marked as spent with key image: " << ki << ", block declined");
|
||||
LOG_PRINT_L1("tx with id: " << m_tx_id << " in block id: " << m_bl_id << " has input marked as spent with key image: " << ki << ", block declined");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -1321,7 +1362,7 @@ bool blockchain_storage::add_transaction_from_block(const transaction& tx, const
|
||||
{
|
||||
if(!boost::apply_visitor(add_transaction_input_visitor(m_spent_keys, tx_id, bl_id), in))
|
||||
{
|
||||
LOG_ERROR("critical internal error: add_transaction_input_visitor failed. but here key_images should be shecked");
|
||||
LOG_PRINT_L1("critical internal error: add_transaction_input_visitor failed. but here key_images should be checked");
|
||||
purge_transaction_keyimages_from_blockchain(tx, false);
|
||||
return false;
|
||||
}
|
||||
@@ -1332,7 +1373,7 @@ bool blockchain_storage::add_transaction_from_block(const transaction& tx, const
|
||||
auto i_r = m_transactions.insert(std::pair<crypto::hash, transaction_chain_entry>(tx_id, ch_e));
|
||||
if(!i_r.second)
|
||||
{
|
||||
LOG_PRINT_L0("tx with id: " << tx_id << " in block id: " << bl_id << " already in blockchain");
|
||||
LOG_PRINT_L1("tx with id: " << tx_id << " in block id: " << bl_id << " already in blockchain");
|
||||
return false;
|
||||
}
|
||||
bool r = push_transaction_to_global_outs_index(tx, tx_id, i_r.first->second.m_global_output_indexes);
|
||||
@@ -1349,7 +1390,7 @@ bool blockchain_storage::get_tx_outputs_gindexs(const crypto::hash& tx_id, std::
|
||||
auto it = m_transactions.find(tx_id);
|
||||
if(it == m_transactions.end())
|
||||
{
|
||||
LOG_PRINT_RED_L0("warning: get_tx_outputs_gindexs failed to find transaction with id = " << tx_id);
|
||||
LOG_PRINT_RED_L1("warning: get_tx_outputs_gindexs failed to find transaction with id = " << tx_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1407,7 +1448,7 @@ bool blockchain_storage::check_tx_inputs(const transaction& tx, const crypto::ha
|
||||
CHECK_AND_ASSERT_MES(sig_index < tx.signatures.size(), false, "wrong transaction: not signature entry for input with index= " << sig_index);
|
||||
if(!check_tx_input(in_to_key, tx_prefix_hash, tx.signatures[sig_index], pmax_used_block_height))
|
||||
{
|
||||
LOG_PRINT_L0("Failed to check ring signature for tx " << get_transaction_hash(tx));
|
||||
LOG_PRINT_L1("Failed to check ring signature for tx " << get_transaction_hash(tx));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1453,13 +1494,13 @@ bool blockchain_storage::check_tx_input(const txin_to_key& txin, const crypto::h
|
||||
//check tx unlock time
|
||||
if(!m_bch.is_tx_spendtime_unlocked(tx.unlock_time))
|
||||
{
|
||||
LOG_PRINT_L0("One of outputs for one of inputs have wrong tx.unlock_time = " << tx.unlock_time);
|
||||
LOG_PRINT_L1("One of outputs for one of inputs has wrong tx.unlock_time = " << tx.unlock_time);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(out.target.type() != typeid(txout_to_key))
|
||||
{
|
||||
LOG_PRINT_L0("Output have wrong type id, which=" << out.target.which());
|
||||
LOG_PRINT_L1("Output has wrong type id, which=" << out.target.which());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1473,13 +1514,13 @@ bool blockchain_storage::check_tx_input(const txin_to_key& txin, const crypto::h
|
||||
outputs_visitor vi(output_keys, *this);
|
||||
if(!scan_outputkeys_for_indexes(txin, vi, pmax_related_block_height))
|
||||
{
|
||||
LOG_PRINT_L0("Failed to get output keys for tx with amount = " << print_money(txin.amount) << " and count indexes " << txin.key_offsets.size());
|
||||
LOG_PRINT_L1("Failed to get output keys for tx with amount = " << print_money(txin.amount) << " and count indexes " << txin.key_offsets.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(txin.key_offsets.size() != output_keys.size())
|
||||
{
|
||||
LOG_PRINT_L0("Output keys for tx with amount = " << txin.amount << " and count indexes " << txin.key_offsets.size() << " returned wrong keys count " << output_keys.size());
|
||||
LOG_PRINT_L1("Output keys for tx with amount = " << txin.amount << " and count indexes " << txin.key_offsets.size() << " returned wrong keys count " << output_keys.size());
|
||||
return false;
|
||||
}
|
||||
CHECK_AND_ASSERT_MES(sig.size() == output_keys.size(), false, "internal error: tx signatures count=" << sig.size() << " mismatch with outputs keys count for inputs=" << output_keys.size());
|
||||
@@ -1498,7 +1539,7 @@ bool blockchain_storage::check_block_timestamp_main(const block& b)
|
||||
{
|
||||
if(b.timestamp > get_adjusted_time() + CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT)
|
||||
{
|
||||
LOG_PRINT_L0("Timestamp of block with id: " << get_block_hash(b) << ", " << b.timestamp << ", bigger than adjusted time + 2 hours");
|
||||
LOG_PRINT_L1("Timestamp of block with id: " << get_block_hash(b) << ", " << b.timestamp << ", bigger than adjusted time + 2 hours");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1519,7 +1560,7 @@ bool blockchain_storage::check_block_timestamp(std::vector<uint64_t> timestamps,
|
||||
|
||||
if(b.timestamp < median_ts)
|
||||
{
|
||||
LOG_PRINT_L0("Timestamp of block with id: " << get_block_hash(b) << ", " << b.timestamp << ", less than median of last " << BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW << " blocks, " << median_ts);
|
||||
LOG_PRINT_L1("Timestamp of block with id: " << get_block_hash(b) << ", " << b.timestamp << ", less than median of last " << BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW << " blocks, " << median_ts);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1532,16 +1573,16 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
if(bl.prev_id != get_tail_id())
|
||||
{
|
||||
LOG_PRINT_L0("Block with id: " << id << ENDL
|
||||
<< "have wrong prev_id: " << bl.prev_id << ENDL
|
||||
LOG_PRINT_L1("Block with id: " << id << ENDL
|
||||
<< "has wrong prev_id: " << bl.prev_id << ENDL
|
||||
<< "expected: " << get_tail_id());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!check_block_timestamp_main(bl))
|
||||
{
|
||||
LOG_PRINT_L0("Block with id: " << id << ENDL
|
||||
<< "have invalid timestamp: " << bl.timestamp);
|
||||
LOG_PRINT_L1("Block with id: " << id << ENDL
|
||||
<< "has invalid timestamp: " << bl.timestamp);
|
||||
//add_block_as_invalid(bl, id);//do not add blocks to invalid storage befor proof of work check was passed
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
@@ -1565,9 +1606,9 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
|
||||
|
||||
if(!check_hash(proof_of_work, current_diffic))
|
||||
{
|
||||
LOG_PRINT_L0("Block with id: " << id << ENDL
|
||||
<< "have not enough proof of work: " << proof_of_work << ENDL
|
||||
<< "nexpected difficulty: " << current_diffic );
|
||||
LOG_PRINT_L1("Block with id: " << id << ENDL
|
||||
<< "does not have enough proof of work: " << proof_of_work << ENDL
|
||||
<< "unexpected difficulty: " << current_diffic );
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
@@ -1588,7 +1629,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
|
||||
|
||||
if(!prevalidate_miner_transaction(bl, m_blocks.size()))
|
||||
{
|
||||
LOG_PRINT_L0("Block with id: " << id
|
||||
LOG_PRINT_L1("Block with id: " << id
|
||||
<< " failed to pass prevalidation");
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
@@ -1598,7 +1639,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
|
||||
//process transactions
|
||||
if(!add_transaction_from_block(bl.miner_tx, get_transaction_hash(bl.miner_tx), id, get_current_blockchain_height()))
|
||||
{
|
||||
LOG_PRINT_L0("Block with id: " << id << " failed to add transaction to blockchain storage");
|
||||
LOG_PRINT_L1("Block with id: " << id << " failed to add transaction to blockchain storage");
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
@@ -1611,7 +1652,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
|
||||
uint64_t fee = 0;
|
||||
if(!m_tx_pool.take_tx(tx_id, tx, blob_size, fee))
|
||||
{
|
||||
LOG_PRINT_L0("Block with id: " << id << "have at least one unknown transaction with id: " << tx_id);
|
||||
LOG_PRINT_L1("Block with id: " << id << "has at least one unknown transaction with id: " << tx_id);
|
||||
purge_block_data_from_blockchain(bl, tx_processed_count);
|
||||
//add_block_as_invalid(bl, id);
|
||||
bvc.m_verifivation_failed = true;
|
||||
@@ -1619,20 +1660,20 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
|
||||
}
|
||||
if(!check_tx_inputs(tx))
|
||||
{
|
||||
LOG_PRINT_L0("Block with id: " << id << "have at least one transaction (id: " << tx_id << ") with wrong inputs.");
|
||||
LOG_PRINT_L1("Block with id: " << id << "has at least one transaction (id: " << tx_id << ") with wrong inputs.");
|
||||
cryptonote::tx_verification_context tvc = AUTO_VAL_INIT(tvc);
|
||||
bool add_res = m_tx_pool.add_tx(tx, tvc, true);
|
||||
CHECK_AND_ASSERT_MES2(add_res, "handle_block_to_main_chain: failed to add transaction back to transaction pool");
|
||||
purge_block_data_from_blockchain(bl, tx_processed_count);
|
||||
add_block_as_invalid(bl, id);
|
||||
LOG_PRINT_L0("Block with id " << id << " added as invalid becouse of wrong inputs in transactions");
|
||||
LOG_PRINT_L1("Block with id " << id << " added as invalid becouse of wrong inputs in transactions");
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!add_transaction_from_block(tx, tx_id, id, get_current_blockchain_height()))
|
||||
{
|
||||
LOG_PRINT_L0("Block with id: " << id << " failed to add transaction to blockchain storage");
|
||||
LOG_PRINT_L1("Block with id: " << id << " failed to add transaction to blockchain storage");
|
||||
cryptonote::tx_verification_context tvc = AUTO_VAL_INIT(tvc);
|
||||
bool add_res = m_tx_pool.add_tx(tx, tvc, true);
|
||||
CHECK_AND_ASSERT_MES2(add_res, "handle_block_to_main_chain: failed to add transaction back to transaction pool");
|
||||
@@ -1648,8 +1689,8 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
|
||||
uint64_t already_generated_coins = m_blocks.size() ? m_blocks.back().already_generated_coins:0;
|
||||
if(!validate_miner_transaction(bl, cumulative_block_size, fee_summary, base_reward, already_generated_coins))
|
||||
{
|
||||
LOG_PRINT_L0("Block with id: " << id
|
||||
<< " have wrong miner transaction");
|
||||
LOG_PRINT_L1("Block with id: " << id
|
||||
<< " has incorrect miner transaction");
|
||||
purge_block_data_from_blockchain(bl, tx_processed_count);
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
@@ -1669,7 +1710,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
|
||||
auto ind_res = m_blocks_index.insert(std::pair<crypto::hash, size_t>(id, bei.height));
|
||||
if(!ind_res.second)
|
||||
{
|
||||
LOG_ERROR("block with id: " << id << " already in block indexes");
|
||||
LOG_PRINT_L1("block with id: " << id << " already in block indexes");
|
||||
purge_block_data_from_blockchain(bl, tx_processed_count);
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
|
||||
@@ -81,8 +81,8 @@ namespace cryptonote
|
||||
blockchain_storage(tx_memory_pool& tx_pool):m_tx_pool(tx_pool), m_current_block_cumul_sz_limit(0), m_is_in_checkpoint_zone(false), m_is_blockchain_storing(false)
|
||||
{};
|
||||
|
||||
bool init() { return init(tools::get_default_data_dir()); }
|
||||
bool init(const std::string& config_folder);
|
||||
bool init() { return init(tools::get_default_data_dir(), true); }
|
||||
bool init(const std::string& config_folder, bool testnet = false);
|
||||
bool deinit();
|
||||
|
||||
void set_checkpoints(checkpoints&& chk_pts) { m_checkpoints = chk_pts; }
|
||||
@@ -242,6 +242,7 @@ namespace cryptonote
|
||||
uint64_t get_adjusted_time();
|
||||
bool complete_timestamps_vector(uint64_t start_height, std::vector<uint64_t>& timestamps);
|
||||
bool update_next_comulative_size_limit();
|
||||
bool store_genesis_block(bool testnet);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -103,9 +103,15 @@ namespace cryptonote {
|
||||
return summ;
|
||||
}
|
||||
//-----------------------------------------------------------------------
|
||||
std::string get_account_address_as_str(const account_public_address& adr)
|
||||
std::string get_account_address_as_str(
|
||||
bool testnet
|
||||
, account_public_address const & adr
|
||||
)
|
||||
{
|
||||
return tools::base58::encode_addr(CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX, t_serializable_object_to_blob(adr));
|
||||
uint64_t address_prefix = testnet ?
|
||||
config::testnet::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX : config::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX;
|
||||
|
||||
return tools::base58::encode_addr(address_prefix, t_serializable_object_to_blob(adr));
|
||||
}
|
||||
//-----------------------------------------------------------------------
|
||||
bool is_coinbase(const transaction& tx)
|
||||
@@ -119,8 +125,15 @@ namespace cryptonote {
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------
|
||||
bool get_account_address_from_str(account_public_address& adr, const std::string& str)
|
||||
bool get_account_address_from_str(
|
||||
account_public_address& adr
|
||||
, bool testnet
|
||||
, std::string const & str
|
||||
)
|
||||
{
|
||||
uint64_t address_prefix = testnet ?
|
||||
config::testnet::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX : config::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX;
|
||||
|
||||
if (2 * sizeof(public_address_outer_blob) != str.size())
|
||||
{
|
||||
blobdata data;
|
||||
@@ -131,9 +144,9 @@ namespace cryptonote {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX != prefix)
|
||||
if (address_prefix != prefix)
|
||||
{
|
||||
LOG_PRINT_L1("Wrong address prefix: " << prefix << ", expected " << CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX);
|
||||
LOG_PRINT_L1("Wrong address prefix: " << prefix << ", expected " << address_prefix);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,8 +66,18 @@ namespace cryptonote {
|
||||
size_t get_max_tx_size();
|
||||
bool get_block_reward(size_t median_size, size_t current_block_size, uint64_t already_generated_coins, uint64_t &reward);
|
||||
uint8_t get_account_address_checksum(const public_address_outer_blob& bl);
|
||||
std::string get_account_address_as_str(const account_public_address& adr);
|
||||
bool get_account_address_from_str(account_public_address& adr, const std::string& str);
|
||||
|
||||
std::string get_account_address_as_str(
|
||||
bool testnet
|
||||
, const account_public_address& adr
|
||||
);
|
||||
|
||||
bool get_account_address_from_str(
|
||||
account_public_address& adr
|
||||
, bool testnet
|
||||
, const std::string& str
|
||||
);
|
||||
|
||||
bool is_coinbase(const transaction& tx);
|
||||
|
||||
bool operator ==(const cryptonote::transaction& a, const cryptonote::transaction& b);
|
||||
|
||||
@@ -75,9 +75,10 @@ namespace cryptonote
|
||||
{
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::handle_command_line(const boost::program_options::variables_map& vm)
|
||||
bool core::handle_command_line(const boost::program_options::variables_map& vm, bool testnet)
|
||||
{
|
||||
m_config_folder = command_line::get_arg(vm, command_line::arg_data_dir);
|
||||
auto data_dir_arg = testnet ? command_line::arg_testnet_data_dir : command_line::arg_data_dir;
|
||||
m_config_folder = command_line::get_arg(vm, data_dir_arg);
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
@@ -116,17 +117,17 @@ namespace cryptonote
|
||||
return m_blockchain_storage.get_alternative_blocks_count();
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::init(const boost::program_options::variables_map& vm)
|
||||
bool core::init(const boost::program_options::variables_map& vm, bool testnet)
|
||||
{
|
||||
bool r = handle_command_line(vm);
|
||||
bool r = handle_command_line(vm, testnet);
|
||||
|
||||
r = m_mempool.init(m_config_folder);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize memory pool");
|
||||
|
||||
r = m_blockchain_storage.init(m_config_folder);
|
||||
r = m_blockchain_storage.init(m_config_folder, testnet);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize blockchain storage");
|
||||
|
||||
r = m_miner.init(vm);
|
||||
r = m_miner.init(vm, testnet);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize blockchain storage");
|
||||
|
||||
return load_state_data();
|
||||
@@ -159,7 +160,7 @@ namespace cryptonote
|
||||
|
||||
if(tx_blob.size() > get_max_tx_size())
|
||||
{
|
||||
LOG_PRINT_L0("WRONG TRANSACTION BLOB, too big size " << tx_blob.size() << ", rejected");
|
||||
LOG_PRINT_L1("WRONG TRANSACTION BLOB, too big size " << tx_blob.size() << ", rejected");
|
||||
tvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
@@ -170,7 +171,7 @@ namespace cryptonote
|
||||
|
||||
if(!parse_tx_from_blob(tx, tx_hash, tx_prefixt_hash, tx_blob))
|
||||
{
|
||||
LOG_PRINT_L0("WRONG TRANSACTION BLOB, Failed to parse, rejected");
|
||||
LOG_PRINT_L1("WRONG TRANSACTION BLOB, Failed to parse, rejected");
|
||||
tvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
@@ -178,23 +179,23 @@ namespace cryptonote
|
||||
|
||||
if(!check_tx_syntax(tx))
|
||||
{
|
||||
LOG_PRINT_L0("WRONG TRANSACTION BLOB, Failed to check tx " << tx_hash << " syntax, rejected");
|
||||
LOG_PRINT_L1("WRONG TRANSACTION BLOB, Failed to check tx " << tx_hash << " syntax, rejected");
|
||||
tvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!check_tx_semantic(tx, keeped_by_block))
|
||||
{
|
||||
LOG_PRINT_L0("WRONG TRANSACTION BLOB, Failed to check tx " << tx_hash << " semantic, rejected");
|
||||
LOG_PRINT_L1("WRONG TRANSACTION BLOB, Failed to check tx " << tx_hash << " semantic, rejected");
|
||||
tvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool r = add_new_tx(tx, tx_hash, tx_prefixt_hash, tx_blob.size(), tvc, keeped_by_block);
|
||||
if(tvc.m_verifivation_failed)
|
||||
{LOG_PRINT_RED_L0("Transaction verification failed: " << tx_hash);}
|
||||
{LOG_PRINT_RED_L1("Transaction verification failed: " << tx_hash);}
|
||||
else if(tvc.m_verifivation_impossible)
|
||||
{LOG_PRINT_RED_L0("Transaction verification impossible: " << tx_hash);}
|
||||
{LOG_PRINT_RED_L1("Transaction verification impossible: " << tx_hash);}
|
||||
|
||||
if(tvc.m_added_to_pool)
|
||||
LOG_PRINT_L1("tx added: " << tx_hash);
|
||||
@@ -216,25 +217,25 @@ namespace cryptonote
|
||||
{
|
||||
if(!tx.vin.size())
|
||||
{
|
||||
LOG_PRINT_RED_L0("tx with empty inputs, rejected for tx id= " << get_transaction_hash(tx));
|
||||
LOG_PRINT_RED_L1("tx with empty inputs, rejected for tx id= " << get_transaction_hash(tx));
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!check_inputs_types_supported(tx))
|
||||
{
|
||||
LOG_PRINT_RED_L0("unsupported input types for tx id= " << get_transaction_hash(tx));
|
||||
LOG_PRINT_RED_L1("unsupported input types for tx id= " << get_transaction_hash(tx));
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!check_outs_valid(tx))
|
||||
{
|
||||
LOG_PRINT_RED_L0("tx with invalid outputs, rejected for tx id= " << get_transaction_hash(tx));
|
||||
LOG_PRINT_RED_L1("tx with invalid outputs, rejected for tx id= " << get_transaction_hash(tx));
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!check_money_overflow(tx))
|
||||
{
|
||||
LOG_PRINT_RED_L0("tx have money overflow, rejected for tx id= " << get_transaction_hash(tx));
|
||||
LOG_PRINT_RED_L1("tx has money overflow, rejected for tx id= " << get_transaction_hash(tx));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -244,20 +245,20 @@ namespace cryptonote
|
||||
|
||||
if(amount_in <= amount_out)
|
||||
{
|
||||
LOG_PRINT_RED_L0("tx with wrong amounts: ins " << amount_in << ", outs " << amount_out << ", rejected for tx id= " << get_transaction_hash(tx));
|
||||
LOG_PRINT_RED_L1("tx with wrong amounts: ins " << amount_in << ", outs " << amount_out << ", rejected for tx id= " << get_transaction_hash(tx));
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!keeped_by_block && get_object_blobsize(tx) >= m_blockchain_storage.get_current_comulative_blocksize_limit() - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE)
|
||||
{
|
||||
LOG_PRINT_RED_L0("tx have to big size " << get_object_blobsize(tx) << ", expected not bigger than " << m_blockchain_storage.get_current_comulative_blocksize_limit() - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE);
|
||||
LOG_PRINT_RED_L1("tx is too large " << get_object_blobsize(tx) << ", expected not bigger than " << m_blockchain_storage.get_current_comulative_blocksize_limit() - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE);
|
||||
return false;
|
||||
}
|
||||
|
||||
//check if tx use different key images
|
||||
if(!check_tx_inputs_keyimages_diff(tx))
|
||||
{
|
||||
LOG_PRINT_RED_L0("tx have to big size " << get_object_blobsize(tx) << ", expected not bigger than " << m_blockchain_storage.get_current_comulative_blocksize_limit() - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE);
|
||||
LOG_PRINT_RED_L1("tx uses a single key image more than once");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -385,7 +386,7 @@ namespace cryptonote
|
||||
m_blockchain_storage.get_transactions(b.tx_hashes, txs, missed_txs);
|
||||
if(missed_txs.size() && m_blockchain_storage.get_block_id_by_height(get_block_height(b)) != get_block_hash(b))
|
||||
{
|
||||
LOG_PRINT_L0("Block found but, seems that reorganize just happened after that, do not relay this block");
|
||||
LOG_PRINT_L1("Block found but, seems that reorganize just happened after that, do not relay this block");
|
||||
return true;
|
||||
}
|
||||
CHECK_AND_ASSERT_MES(txs.size() == b.tx_hashes.size() && !missed_txs.size(), false, "cant find some transactions in found block:" << get_block_hash(b) << " txs.size()=" << txs.size()
|
||||
@@ -420,7 +421,7 @@ namespace cryptonote
|
||||
bvc = boost::value_initialized<block_verification_context>();
|
||||
if(block_blob.size() > get_max_block_size())
|
||||
{
|
||||
LOG_PRINT_L0("WRONG BLOCK BLOB, too big size " << block_blob.size() << ", rejected");
|
||||
LOG_PRINT_L1("WRONG BLOCK BLOB, too big size " << block_blob.size() << ", rejected");
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
@@ -428,7 +429,7 @@ namespace cryptonote
|
||||
block b = AUTO_VAL_INIT(b);
|
||||
if(!parse_and_validate_block_from_blob(block_blob, b))
|
||||
{
|
||||
LOG_PRINT_L0("Failed to parse and validate new block");
|
||||
LOG_PRINT_L1("Failed to parse and validate new block");
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
@@ -444,7 +445,7 @@ namespace cryptonote
|
||||
{
|
||||
if(block_blob.size() > get_max_block_size())
|
||||
{
|
||||
LOG_PRINT_L0("WRONG BLOCK BLOB, too big size " << block_blob.size() << ", rejected");
|
||||
LOG_PRINT_L1("WRONG BLOCK BLOB, too big size " << block_blob.size() << ", rejected");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace cryptonote
|
||||
|
||||
miner& get_miner(){return m_miner;}
|
||||
static void init_options(boost::program_options::options_description& desc);
|
||||
bool init(const boost::program_options::variables_map& vm);
|
||||
bool init(const boost::program_options::variables_map& vm, bool testnet);
|
||||
bool set_genesis_block(const block& b);
|
||||
bool deinit();
|
||||
uint64_t get_current_blockchain_height();
|
||||
@@ -136,7 +136,7 @@ namespace cryptonote
|
||||
bool check_tx_ring_signature(const txin_to_key& tx, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig);
|
||||
bool is_tx_spendtime_unlocked(uint64_t unlock_time);
|
||||
bool update_miner_block_template();
|
||||
bool handle_command_line(const boost::program_options::variables_map& vm);
|
||||
bool handle_command_line(const boost::program_options::variables_map& vm, bool testnet);
|
||||
bool on_update_blocktemplate_interval();
|
||||
bool check_tx_inputs_keyimages_diff(const transaction& tx);
|
||||
|
||||
|
||||
@@ -660,7 +660,11 @@ namespace cryptonote
|
||||
return p;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool generate_genesis_block(block& bl)
|
||||
bool generate_genesis_block(
|
||||
block& bl
|
||||
, std::string const & genesis_tx
|
||||
, uint32_t nonce
|
||||
)
|
||||
{
|
||||
//genesis block
|
||||
bl = boost::value_initialized<block>();
|
||||
@@ -672,8 +676,7 @@ namespace cryptonote
|
||||
blobdata txb = tx_to_blob(bl.miner_tx);
|
||||
std::string hex_tx_represent = string_tools::buff_to_hex_nodelimer(txb);
|
||||
|
||||
//hard code coinbase tx in genesis block, because "tru" generating tx use random, but genesis should be always the same
|
||||
std::string genesis_coinbase_tx_hex = "013c01ff0001ffffffffffff03029b2e4c0281c0b02e7c53291a94d1d0cbff8883f8024f5142ee494ffbbd08807121017767aafcde9be00dcfd098715ebcf7f410daebc582fda69d24a28e9d0bc890d1";
|
||||
std::string genesis_coinbase_tx_hex = config::GENESIS_TX;
|
||||
|
||||
blobdata tx_bl;
|
||||
string_tools::parse_hexstr_to_binbuff(genesis_coinbase_tx_hex, tx_bl);
|
||||
@@ -682,7 +685,7 @@ namespace cryptonote
|
||||
bl.major_version = CURRENT_BLOCK_MAJOR_VERSION;
|
||||
bl.minor_version = CURRENT_BLOCK_MINOR_VERSION;
|
||||
bl.timestamp = 0;
|
||||
bl.nonce = 10000;
|
||||
bl.nonce = nonce;
|
||||
miner::find_nonce_for_given_block(bl, 1, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -105,7 +105,11 @@ namespace cryptonote
|
||||
crypto::hash get_block_hash(const block& b);
|
||||
bool get_block_longhash(const block& b, crypto::hash& res, uint64_t height);
|
||||
crypto::hash get_block_longhash(const block& b, uint64_t height);
|
||||
bool generate_genesis_block(block& bl);
|
||||
bool generate_genesis_block(
|
||||
block& bl
|
||||
, std::string const & genesis_tx
|
||||
, uint32_t nonce
|
||||
);
|
||||
bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b);
|
||||
bool get_inputs_money_amount(const transaction& tx, uint64_t& money);
|
||||
uint64_t get_outs_money_amount(const transaction& tx);
|
||||
|
||||
@@ -171,7 +171,7 @@ namespace cryptonote
|
||||
command_line::add_arg(desc, arg_mining_threads);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
bool miner::init(const boost::program_options::variables_map& vm)
|
||||
bool miner::init(const boost::program_options::variables_map& vm, bool testnet)
|
||||
{
|
||||
if(command_line::has_arg(vm, arg_extra_messages))
|
||||
{
|
||||
@@ -198,7 +198,7 @@ namespace cryptonote
|
||||
|
||||
if(command_line::has_arg(vm, arg_start_mining))
|
||||
{
|
||||
if(!cryptonote::get_account_address_from_str(m_mine_address, command_line::get_arg(vm, arg_start_mining)))
|
||||
if(!cryptonote::get_account_address_from_str(m_mine_address, testnet, command_line::get_arg(vm, arg_start_mining)))
|
||||
{
|
||||
LOG_ERROR("Target account address " << command_line::get_arg(vm, arg_start_mining) << " has wrong format, starting daemon canceled");
|
||||
return false;
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace cryptonote
|
||||
public:
|
||||
miner(i_miner_handler* phandler);
|
||||
~miner();
|
||||
bool init(const boost::program_options::variables_map& vm);
|
||||
bool init(const boost::program_options::variables_map& vm, bool testnet);
|
||||
static void init_options(boost::program_options::options_description& desc);
|
||||
bool set_block_template(const block& bl, const difficulty_type& diffic, uint64_t height);
|
||||
bool on_block_chain_update();
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace cryptonote
|
||||
|
||||
if(outputs_amount >= inputs_amount)
|
||||
{
|
||||
LOG_PRINT_L0("transaction use more money then it has: use " << print_money(outputs_amount) << ", have " << print_money(inputs_amount));
|
||||
LOG_PRINT_L1("transaction use more money then it has: use " << print_money(outputs_amount) << ", have " << print_money(inputs_amount));
|
||||
tvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
@@ -88,14 +88,14 @@ namespace cryptonote
|
||||
uint64_t fee = inputs_amount - outputs_amount;
|
||||
if (!kept_by_block && fee < DEFAULT_FEE)
|
||||
{
|
||||
LOG_ERROR("transaction fee is not enough: " << print_money(fee) << ", minumim fee: " << print_money(DEFAULT_FEE));
|
||||
LOG_PRINT_L1("transaction fee is not enough: " << print_money(fee) << ", minumim fee: " << print_money(DEFAULT_FEE));
|
||||
tvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!kept_by_block && blob_size >= TRANSACTION_SIZE_LIMIT)
|
||||
{
|
||||
LOG_ERROR("transaction is too big: " << blob_size << " bytes, maximum size: " << TRANSACTION_SIZE_LIMIT);
|
||||
LOG_PRINT_L1("transaction is too big: " << blob_size << " bytes, maximum size: " << TRANSACTION_SIZE_LIMIT);
|
||||
tvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
@@ -105,7 +105,7 @@ namespace cryptonote
|
||||
{
|
||||
if(have_tx_keyimges_as_spent(tx))
|
||||
{
|
||||
LOG_ERROR("Transaction with id= "<< id << " used already spent key images");
|
||||
LOG_PRINT_L1("Transaction with id= "<< id << " used already spent key images");
|
||||
tvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
@@ -134,7 +134,7 @@ namespace cryptonote
|
||||
tvc.m_added_to_pool = true;
|
||||
}else
|
||||
{
|
||||
LOG_PRINT_L0("tx used wrong inputs, rejected");
|
||||
LOG_PRINT_L1("tx used wrong inputs, rejected");
|
||||
tvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
@@ -242,7 +242,7 @@ namespace cryptonote
|
||||
if((tx_age > CRYPTONOTE_MEMPOOL_TX_LIVETIME && !it->second.kept_by_block) ||
|
||||
(tx_age > CRYPTONOTE_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME && it->second.kept_by_block) )
|
||||
{
|
||||
LOG_PRINT_L0("Tx " << it->first << " removed from tx pool due to outdated, age: " << tx_age );
|
||||
LOG_PRINT_L1("Tx " << it->first << " removed from tx pool due to outdated, age: " << tx_age );
|
||||
m_transactions.erase(it++);
|
||||
}else
|
||||
++it;
|
||||
@@ -467,7 +467,7 @@ namespace cryptonote
|
||||
bool res = tools::unserialize_obj_from_file(*this, state_file_path);
|
||||
if(!res)
|
||||
{
|
||||
LOG_ERROR("Failed to load memory pool from file " << state_file_path);
|
||||
LOG_PRINT_L1("Failed to load memory pool from file " << state_file_path);
|
||||
|
||||
m_transactions.clear();
|
||||
m_spent_key_images.clear();
|
||||
@@ -476,7 +476,7 @@ namespace cryptonote
|
||||
for (auto it = m_transactions.begin(); it != m_transactions.end(); ) {
|
||||
auto it2 = it++;
|
||||
if (it2->second.blob_size >= TRANSACTION_SIZE_LIMIT) {
|
||||
LOG_PRINT_L0("Transaction " << get_transaction_hash(it2->second.tx) << " is too big (" << it2->second.blob_size << " bytes), removing it from pool");
|
||||
LOG_PRINT_L1("Transaction " << get_transaction_hash(it2->second.tx) << " is too big (" << it2->second.blob_size << " bytes), removing it from pool");
|
||||
remove_transaction_keyimages(it2->second.tx);
|
||||
m_transactions.erase(it2);
|
||||
}
|
||||
@@ -491,7 +491,7 @@ namespace cryptonote
|
||||
{
|
||||
if (!tools::create_directories_if_necessary(m_config_folder))
|
||||
{
|
||||
LOG_PRINT_L0("Failed to create data directory: " << m_config_folder);
|
||||
LOG_PRINT_L1("Failed to create data directory: " << m_config_folder);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -499,7 +499,7 @@ namespace cryptonote
|
||||
bool res = tools::serialize_obj_to_file(*this, state_file_path);
|
||||
if(!res)
|
||||
{
|
||||
LOG_PRINT_L0("Failed to serialize memory pool to file " << state_file_path);
|
||||
LOG_PRINT_L1("Failed to serialize memory pool to file " << state_file_path);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ namespace cryptonote
|
||||
m_core.handle_incoming_tx(*tx_blob_it, tvc, true);
|
||||
if(tvc.m_verifivation_failed)
|
||||
{
|
||||
LOG_PRINT_CCONTEXT_L0("Block verification failed: transaction verification failed, dropping connection");
|
||||
LOG_PRINT_CCONTEXT_L1("Block verification failed: transaction verification failed, dropping connection");
|
||||
m_p2p->drop_connection(context);
|
||||
return 1;
|
||||
}
|
||||
@@ -238,7 +238,7 @@ namespace cryptonote
|
||||
m_core.resume_mine();
|
||||
if(bvc.m_verifivation_failed)
|
||||
{
|
||||
LOG_PRINT_CCONTEXT_L0("Block verification failed, dropping connection");
|
||||
LOG_PRINT_CCONTEXT_L1("Block verification failed, dropping connection");
|
||||
m_p2p->drop_connection(context);
|
||||
return 1;
|
||||
}
|
||||
@@ -272,7 +272,7 @@ namespace cryptonote
|
||||
m_core.handle_incoming_tx(*tx_blob_it, tvc, false);
|
||||
if(tvc.m_verifivation_failed)
|
||||
{
|
||||
LOG_PRINT_CCONTEXT_L0("Tx verification failed, dropping connection");
|
||||
LOG_PRINT_CCONTEXT_L1("Tx verification failed, dropping connection");
|
||||
m_p2p->drop_connection(context);
|
||||
return 1;
|
||||
}
|
||||
@@ -404,13 +404,13 @@ namespace cryptonote
|
||||
|
||||
if(bvc.m_verifivation_failed)
|
||||
{
|
||||
LOG_PRINT_CCONTEXT_L0("Block verification failed, dropping connection");
|
||||
LOG_PRINT_CCONTEXT_L1("Block verification failed, dropping connection");
|
||||
m_p2p->drop_connection(context);
|
||||
return 1;
|
||||
}
|
||||
if(bvc.m_marked_as_orphaned)
|
||||
{
|
||||
LOG_PRINT_CCONTEXT_L0("Block received at sync phase was marked as orphaned, dropping connection");
|
||||
LOG_PRINT_CCONTEXT_L1("Block received at sync phase was marked as orphaned, dropping connection");
|
||||
m_p2p->drop_connection(context);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
|
||||
|
||||
// node.cpp : Defines the entry point for the console application.
|
||||
//
|
||||
// Does this file exist?
|
||||
|
||||
|
||||
#include "include_base_utils.h"
|
||||
@@ -42,6 +42,7 @@ using namespace epee;
|
||||
#include "crypto/hash.h"
|
||||
#include "console_handler.h"
|
||||
#include "p2p/net_node.h"
|
||||
#include "cryptonote_config.h"
|
||||
#include "cryptonote_core/checkpoints_create.h"
|
||||
#include "cryptonote_core/cryptonote_core.h"
|
||||
#include "rpc/core_rpc_server.h"
|
||||
@@ -62,177 +63,11 @@ namespace
|
||||
const command_line::arg_descriptor<std::string> arg_log_file = {"log-file", "", ""};
|
||||
const command_line::arg_descriptor<int> arg_log_level = {"log-level", "", LOG_LEVEL_0};
|
||||
const command_line::arg_descriptor<bool> arg_console = {"no-console", "Disable daemon console commands"};
|
||||
}
|
||||
|
||||
bool command_line_preprocessor(const boost::program_options::variables_map& vm);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
string_tools::set_module_name_and_folder(argv[0]);
|
||||
#ifdef WIN32
|
||||
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
|
||||
#endif
|
||||
log_space::get_set_log_detalisation_level(true, LOG_LEVEL_0);
|
||||
log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL);
|
||||
LOG_PRINT_L0("Starting...");
|
||||
|
||||
TRY_ENTRY();
|
||||
|
||||
po::options_description desc_cmd_only("Command line options");
|
||||
po::options_description desc_cmd_sett("Command line options and settings options");
|
||||
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_help);
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_version);
|
||||
command_line::add_arg(desc_cmd_only, arg_os_version);
|
||||
// tools::get_default_data_dir() can't be called during static initialization
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_data_dir, tools::get_default_data_dir());
|
||||
command_line::add_arg(desc_cmd_only, arg_config_file);
|
||||
|
||||
command_line::add_arg(desc_cmd_sett, arg_log_file);
|
||||
command_line::add_arg(desc_cmd_sett, arg_log_level);
|
||||
command_line::add_arg(desc_cmd_sett, arg_console);
|
||||
|
||||
|
||||
cryptonote::core::init_options(desc_cmd_sett);
|
||||
cryptonote::core_rpc_server::init_options(desc_cmd_sett);
|
||||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >::init_options(desc_cmd_sett);
|
||||
cryptonote::miner::init_options(desc_cmd_sett);
|
||||
|
||||
po::options_description desc_options("Allowed options");
|
||||
desc_options.add(desc_cmd_only).add(desc_cmd_sett);
|
||||
|
||||
po::variables_map vm;
|
||||
bool r = command_line::handle_error_helper(desc_options, [&]()
|
||||
{
|
||||
po::store(po::parse_command_line(argc, argv, desc_options), vm);
|
||||
|
||||
if (command_line::get_arg(vm, command_line::arg_help))
|
||||
{
|
||||
std::cout << CRYPTONOTE_NAME << " v" << PROJECT_VERSION_LONG << ENDL << ENDL;
|
||||
std::cout << desc_options << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string data_dir = command_line::get_arg(vm, command_line::arg_data_dir);
|
||||
std::string config = command_line::get_arg(vm, arg_config_file);
|
||||
|
||||
boost::filesystem::path data_dir_path(data_dir);
|
||||
boost::filesystem::path config_path(config);
|
||||
if (!config_path.has_parent_path())
|
||||
{
|
||||
config_path = data_dir_path / config_path;
|
||||
}
|
||||
|
||||
boost::system::error_code ec;
|
||||
if (boost::filesystem::exists(config_path, ec))
|
||||
{
|
||||
po::store(po::parse_config_file<char>(config_path.string<std::string>().c_str(), desc_cmd_sett), vm);
|
||||
}
|
||||
po::notify(vm);
|
||||
|
||||
return true;
|
||||
});
|
||||
if (!r)
|
||||
return 1;
|
||||
|
||||
//set up logging options
|
||||
boost::filesystem::path log_file_path(command_line::get_arg(vm, arg_log_file));
|
||||
if (log_file_path.empty())
|
||||
log_file_path = log_space::log_singletone::get_default_log_file();
|
||||
std::string log_dir;
|
||||
log_dir = log_file_path.has_parent_path() ? log_file_path.parent_path().string() : log_space::log_singletone::get_default_log_folder();
|
||||
|
||||
log_space::log_singletone::add_logger(LOGGER_FILE, log_file_path.filename().string().c_str(), log_dir.c_str());
|
||||
LOG_PRINT_L0(CRYPTONOTE_NAME << " v" << PROJECT_VERSION_LONG);
|
||||
|
||||
if (command_line_preprocessor(vm))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOG_PRINT("Module folder: " << argv[0], LOG_LEVEL_0);
|
||||
|
||||
bool res = true;
|
||||
cryptonote::checkpoints checkpoints;
|
||||
res = cryptonote::create_checkpoints(checkpoints);
|
||||
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize checkpoints");
|
||||
|
||||
//create objects and link them
|
||||
cryptonote::core ccore(NULL);
|
||||
ccore.set_checkpoints(std::move(checkpoints));
|
||||
cryptonote::t_cryptonote_protocol_handler<cryptonote::core> cprotocol(ccore, NULL);
|
||||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> > p2psrv(cprotocol);
|
||||
cryptonote::core_rpc_server rpc_server(ccore, p2psrv);
|
||||
cprotocol.set_p2p_endpoint(&p2psrv);
|
||||
ccore.set_cryptonote_protocol(&cprotocol);
|
||||
daemon_cmmands_handler dch(p2psrv);
|
||||
|
||||
//initialize objects
|
||||
LOG_PRINT_L0("Initializing p2p server...");
|
||||
res = p2psrv.init(vm);
|
||||
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize p2p server.");
|
||||
LOG_PRINT_L0("P2p server initialized OK");
|
||||
|
||||
LOG_PRINT_L0("Initializing cryptonote protocol...");
|
||||
res = cprotocol.init(vm);
|
||||
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize cryptonote protocol.");
|
||||
LOG_PRINT_L0("Cryptonote protocol initialized OK");
|
||||
|
||||
LOG_PRINT_L0("Initializing core rpc server...");
|
||||
res = rpc_server.init(vm);
|
||||
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core rpc server.");
|
||||
LOG_PRINT_GREEN("Core rpc server initialized OK on port: " << rpc_server.get_binded_port(), LOG_LEVEL_0);
|
||||
|
||||
//initialize core here
|
||||
LOG_PRINT_L0("Initializing core...");
|
||||
res = ccore.init(vm);
|
||||
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core");
|
||||
LOG_PRINT_L0("Core initialized OK");
|
||||
|
||||
// start components
|
||||
if(!command_line::has_arg(vm, arg_console))
|
||||
{
|
||||
dch.start_handling();
|
||||
}
|
||||
|
||||
LOG_PRINT_L0("Starting core rpc server...");
|
||||
res = rpc_server.run(2, false);
|
||||
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core rpc server.");
|
||||
LOG_PRINT_L0("Core rpc server started ok");
|
||||
|
||||
tools::signal_handler::install([&dch, &p2psrv] {
|
||||
dch.stop_handling();
|
||||
p2psrv.send_stop_signal();
|
||||
});
|
||||
|
||||
LOG_PRINT_L0("Starting p2p net loop...");
|
||||
p2psrv.run();
|
||||
LOG_PRINT_L0("p2p net loop stopped");
|
||||
|
||||
//stop components
|
||||
LOG_PRINT_L0("Stopping core rpc server...");
|
||||
rpc_server.send_stop_signal();
|
||||
rpc_server.timed_wait_server_stop(5000);
|
||||
|
||||
//deinitialize components
|
||||
LOG_PRINT_L0("Deinitializing core...");
|
||||
ccore.deinit();
|
||||
LOG_PRINT_L0("Deinitializing rpc server ...");
|
||||
rpc_server.deinit();
|
||||
LOG_PRINT_L0("Deinitializing cryptonote_protocol...");
|
||||
cprotocol.deinit();
|
||||
LOG_PRINT_L0("Deinitializing p2p...");
|
||||
p2psrv.deinit();
|
||||
|
||||
|
||||
ccore.set_cryptonote_protocol(NULL);
|
||||
cprotocol.set_p2p_endpoint(NULL);
|
||||
|
||||
LOG_PRINT("Node stopped.", LOG_LEVEL_0);
|
||||
return 0;
|
||||
|
||||
CATCH_ENTRY_L0("main", 1);
|
||||
const command_line::arg_descriptor<bool> arg_testnet_on = {
|
||||
"testnet"
|
||||
, "Run on testnet. The wallet must be launched with --testnet flag."
|
||||
, false
|
||||
};
|
||||
}
|
||||
|
||||
bool command_line_preprocessor(const boost::program_options::variables_map& vm)
|
||||
@@ -240,7 +75,7 @@ bool command_line_preprocessor(const boost::program_options::variables_map& vm)
|
||||
bool exit = false;
|
||||
if (command_line::get_arg(vm, command_line::arg_version))
|
||||
{
|
||||
std::cout << CRYPTONOTE_NAME << " v" << PROJECT_VERSION_LONG << ENDL;
|
||||
std::cout << CRYPTONOTE_NAME << " v" << MONERO_VERSION_FULL << ENDL;
|
||||
exit = true;
|
||||
}
|
||||
if (command_line::get_arg(vm, arg_os_version))
|
||||
@@ -267,3 +102,191 @@ bool command_line_preprocessor(const boost::program_options::variables_map& vm)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
string_tools::set_module_name_and_folder(argv[0]);
|
||||
#ifdef WIN32
|
||||
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
|
||||
#endif
|
||||
log_space::get_set_log_detalisation_level(true, LOG_LEVEL_0);
|
||||
log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL);
|
||||
LOG_PRINT_L0("Starting...");
|
||||
|
||||
TRY_ENTRY();
|
||||
|
||||
boost::filesystem::path default_data_path {tools::get_default_data_dir()};
|
||||
boost::filesystem::path default_testnet_data_path {default_data_path / "testnet"};
|
||||
|
||||
po::options_description desc_cmd_only("Command line options");
|
||||
po::options_description desc_cmd_sett("Command line options and settings options");
|
||||
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_help);
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_version);
|
||||
command_line::add_arg(desc_cmd_only, arg_os_version);
|
||||
// tools::get_default_data_dir() can't be called during static initialization
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_data_dir, default_data_path.string());
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_testnet_data_dir, default_testnet_data_path.string());
|
||||
command_line::add_arg(desc_cmd_only, arg_config_file);
|
||||
|
||||
command_line::add_arg(desc_cmd_sett, arg_log_file);
|
||||
command_line::add_arg(desc_cmd_sett, arg_log_level);
|
||||
command_line::add_arg(desc_cmd_sett, arg_console);
|
||||
command_line::add_arg(desc_cmd_sett, arg_testnet_on);
|
||||
|
||||
cryptonote::core::init_options(desc_cmd_sett);
|
||||
cryptonote::core_rpc_server::init_options(desc_cmd_sett);
|
||||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >::init_options(desc_cmd_sett);
|
||||
cryptonote::miner::init_options(desc_cmd_sett);
|
||||
|
||||
po::options_description desc_options("Allowed options");
|
||||
desc_options.add(desc_cmd_only).add(desc_cmd_sett);
|
||||
|
||||
po::variables_map vm;
|
||||
bool r = command_line::handle_error_helper(desc_options, [&]()
|
||||
{
|
||||
po::store(po::parse_command_line(argc, argv, desc_options), vm);
|
||||
po::notify(vm);
|
||||
|
||||
return true;
|
||||
});
|
||||
if (!r)
|
||||
return 1;
|
||||
|
||||
if (command_line::get_arg(vm, command_line::arg_help))
|
||||
{
|
||||
std::cout << CRYPTONOTE_NAME << " v" << MONERO_VERSION_FULL << ENDL << ENDL;
|
||||
std::cout << desc_options << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool testnet_mode = command_line::get_arg(vm, arg_testnet_on);
|
||||
|
||||
auto data_dir_arg = testnet_mode ? command_line::arg_testnet_data_dir : command_line::arg_data_dir;
|
||||
|
||||
std::string data_dir = command_line::get_arg(vm, data_dir_arg);
|
||||
tools::create_directories_if_necessary(data_dir);
|
||||
std::string config = command_line::get_arg(vm, arg_config_file);
|
||||
|
||||
boost::filesystem::path data_dir_path(data_dir);
|
||||
boost::filesystem::path config_path(config);
|
||||
if (!config_path.has_parent_path())
|
||||
{
|
||||
config_path = data_dir_path / config_path;
|
||||
}
|
||||
|
||||
boost::system::error_code ec;
|
||||
if (boost::filesystem::exists(config_path, ec))
|
||||
{
|
||||
po::store(po::parse_config_file<char>(config_path.string<std::string>().c_str(), desc_cmd_sett), vm);
|
||||
}
|
||||
|
||||
//set up logging options
|
||||
boost::filesystem::path log_file_path(command_line::get_arg(vm, arg_log_file));
|
||||
if (log_file_path.empty())
|
||||
log_file_path = log_space::log_singletone::get_default_log_file();
|
||||
std::string log_dir;
|
||||
log_dir = log_file_path.has_parent_path() ? log_file_path.parent_path().string() : log_space::log_singletone::get_default_log_folder();
|
||||
|
||||
log_space::log_singletone::add_logger(LOGGER_FILE, log_file_path.filename().string().c_str(), log_dir.c_str());
|
||||
LOG_PRINT_L0(CRYPTONOTE_NAME << " v" << MONERO_VERSION_FULL);
|
||||
|
||||
if (command_line_preprocessor(vm))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOG_PRINT("Module folder: " << argv[0], LOG_LEVEL_0);
|
||||
|
||||
bool res = true;
|
||||
cryptonote::checkpoints checkpoints;
|
||||
res = cryptonote::create_checkpoints(checkpoints);
|
||||
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize checkpoints");
|
||||
|
||||
//create objects and link them
|
||||
cryptonote::core ccore(NULL);
|
||||
|
||||
if (testnet_mode) {
|
||||
LOG_PRINT_L0("Starting in testnet mode!");
|
||||
} else {
|
||||
ccore.set_checkpoints(std::move(checkpoints));
|
||||
}
|
||||
|
||||
cryptonote::t_cryptonote_protocol_handler<cryptonote::core> cprotocol(ccore, NULL);
|
||||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> > p2psrv {
|
||||
cprotocol
|
||||
, testnet_mode ? std::move(config::testnet::NETWORK_ID) : std::move(config::NETWORK_ID)
|
||||
};
|
||||
cryptonote::core_rpc_server rpc_server {ccore, p2psrv, testnet_mode};
|
||||
cprotocol.set_p2p_endpoint(&p2psrv);
|
||||
ccore.set_cryptonote_protocol(&cprotocol);
|
||||
daemon_cmmands_handler dch(p2psrv, testnet_mode);
|
||||
|
||||
//initialize objects
|
||||
LOG_PRINT_L0("Initializing P2P server...");
|
||||
res = p2psrv.init(vm, testnet_mode);
|
||||
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize P2P server.");
|
||||
LOG_PRINT_L0("P2P server initialized OK");
|
||||
|
||||
LOG_PRINT_L0("Initializing protocol...");
|
||||
res = cprotocol.init(vm);
|
||||
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize protocol.");
|
||||
LOG_PRINT_L0("Protocol initialized OK");
|
||||
|
||||
LOG_PRINT_L0("Initializing core RPC server...");
|
||||
res = rpc_server.init(vm);
|
||||
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core RPC server.");
|
||||
LOG_PRINT_GREEN("Core RPC server initialized OK on port: " << rpc_server.get_binded_port(), LOG_LEVEL_0);
|
||||
|
||||
//initialize core here
|
||||
LOG_PRINT_L0("Initializing core...");
|
||||
res = ccore.init(vm, testnet_mode);
|
||||
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core");
|
||||
LOG_PRINT_L0("Core initialized OK");
|
||||
|
||||
// start components
|
||||
if(!command_line::has_arg(vm, arg_console))
|
||||
{
|
||||
dch.start_handling();
|
||||
}
|
||||
|
||||
LOG_PRINT_L0("Starting core RPC server...");
|
||||
res = rpc_server.run(2, false);
|
||||
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core RPC server.");
|
||||
LOG_PRINT_L0("Core RPC server started ok");
|
||||
|
||||
tools::signal_handler::install([&dch, &p2psrv] {
|
||||
dch.stop_handling();
|
||||
p2psrv.send_stop_signal();
|
||||
});
|
||||
|
||||
LOG_PRINT_L0("Starting P2P net loop...");
|
||||
p2psrv.run();
|
||||
LOG_PRINT_L0("P2P net loop stopped");
|
||||
|
||||
//stop components
|
||||
LOG_PRINT_L0("Stopping core rpc server...");
|
||||
rpc_server.send_stop_signal();
|
||||
rpc_server.timed_wait_server_stop(5000);
|
||||
|
||||
//deinitialize components
|
||||
LOG_PRINT_L0("Deinitializing core...");
|
||||
ccore.deinit();
|
||||
LOG_PRINT_L0("Deinitializing RPC server ...");
|
||||
rpc_server.deinit();
|
||||
LOG_PRINT_L0("Deinitializing protocol...");
|
||||
cprotocol.deinit();
|
||||
LOG_PRINT_L0("Deinitializing P2P...");
|
||||
p2psrv.deinit();
|
||||
|
||||
|
||||
ccore.set_cryptonote_protocol(NULL);
|
||||
cprotocol.set_p2p_endpoint(NULL);
|
||||
|
||||
LOG_PRINT("Node stopped.", LOG_LEVEL_0);
|
||||
return 0;
|
||||
|
||||
CATCH_ENTRY_L0("main", 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
//
|
||||
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
|
||||
|
||||
|
||||
/* This isn't a header file, may want to refactor this... */
|
||||
#pragma once
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
@@ -39,12 +41,21 @@
|
||||
#include "crypto/hash.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
/*!
|
||||
* \brief I don't really know right now
|
||||
*
|
||||
*
|
||||
*/
|
||||
class daemon_cmmands_handler
|
||||
{
|
||||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& m_srv;
|
||||
public:
|
||||
daemon_cmmands_handler(nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& srv):m_srv(srv)
|
||||
daemon_cmmands_handler(
|
||||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& srv
|
||||
, bool testnet
|
||||
)
|
||||
: m_srv(srv)
|
||||
, m_testnet {testnet}
|
||||
{
|
||||
m_cmd_binder.set_handler("help", boost::bind(&daemon_cmmands_handler::help, this, _1), "Show this help");
|
||||
m_cmd_binder.set_handler("print_pl", boost::bind(&daemon_cmmands_handler::print_pl, this, _1), "Print peer list");
|
||||
@@ -78,12 +89,13 @@ public:
|
||||
|
||||
private:
|
||||
epee::srv_console_handlers_binder<nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> > > m_cmd_binder;
|
||||
bool m_testnet;
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
std::string get_commands_str()
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << CRYPTONOTE_NAME << " v" << PROJECT_VERSION_LONG << ENDL;
|
||||
ss << CRYPTONOTE_NAME << " v" << MONERO_VERSION_FULL << ENDL;
|
||||
ss << "Commands: " << ENDL;
|
||||
std::string usage = m_cmd_binder.get_usage();
|
||||
boost::replace_all(usage, "\n", "\n ");
|
||||
@@ -362,7 +374,7 @@ private:
|
||||
}
|
||||
|
||||
cryptonote::account_public_address adr;
|
||||
if(!cryptonote::get_account_address_from_str(adr, args.front()))
|
||||
if(!cryptonote::get_account_address_from_str(adr, m_testnet, args.front()))
|
||||
{
|
||||
std::cout << "target account address has wrong format" << std::endl;
|
||||
return true;
|
||||
|
||||
@@ -41,13 +41,14 @@
|
||||
#include <boost/program_options/options_description.hpp>
|
||||
#include <boost/program_options/variables_map.hpp>
|
||||
#include <boost/serialization/version.hpp>
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
|
||||
#include "cryptonote_config.h"
|
||||
#include "warnings.h"
|
||||
#include "net/levin_server_cp2.h"
|
||||
#include "p2p_protocol_defs.h"
|
||||
#include "storages/levin_abstract_invoke2.h"
|
||||
#include "net_peerlist.h"
|
||||
#include "p2p_networks.h"
|
||||
#include "math_helper.h"
|
||||
#include "net_node_common.h"
|
||||
#include "common/command_line.h"
|
||||
@@ -78,14 +79,21 @@ namespace nodetool
|
||||
|
||||
public:
|
||||
typedef t_payload_net_handler payload_net_handler;
|
||||
// Some code
|
||||
node_server(t_payload_net_handler& payload_handler):m_payload_handler(payload_handler), m_allow_local_ip(false), m_hide_my_port(false)
|
||||
|
||||
node_server(
|
||||
t_payload_net_handler& payload_handler
|
||||
, boost::uuids::uuid network_id
|
||||
)
|
||||
: m_payload_handler(payload_handler)
|
||||
, m_allow_local_ip(false)
|
||||
, m_hide_my_port(false)
|
||||
, m_network_id(std::move(network_id))
|
||||
{}
|
||||
|
||||
static void init_options(boost::program_options::options_description& desc);
|
||||
|
||||
bool run();
|
||||
bool init(const boost::program_options::variables_map& vm);
|
||||
bool init(const boost::program_options::variables_map& vm, bool testnet);
|
||||
bool deinit();
|
||||
bool send_stop_signal();
|
||||
uint32_t get_this_peer_port(){return m_listenning_port;}
|
||||
@@ -149,7 +157,10 @@ namespace nodetool
|
||||
virtual void for_each_connection(std::function<bool(typename t_payload_net_handler::connection_context&, peerid_type)> f);
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool parse_peer_from_string(nodetool::net_address& pe, const std::string& node_addr);
|
||||
bool handle_command_line(const boost::program_options::variables_map& vm);
|
||||
bool handle_command_line(
|
||||
const boost::program_options::variables_map& vm
|
||||
, bool testnet
|
||||
);
|
||||
bool idle_worker();
|
||||
bool handle_remote_peerlist(const std::list<peerlist_entry>& peerlist, time_t local_time, const epee::net_utils::connection_context_base& context);
|
||||
bool get_local_node_data(basic_node_data& node_data);
|
||||
@@ -229,6 +240,7 @@ namespace nodetool
|
||||
uint64_t m_peer_livetime;
|
||||
//keep connections to initiate some interactions
|
||||
net_server m_net_server;
|
||||
boost::uuids::uuid m_network_id;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -42,8 +42,15 @@
|
||||
#include "net/local_ip.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "storages/levin_abstract_invoke2.h"
|
||||
#include <miniupnpc/miniupnpc.h>
|
||||
#include <miniupnpc/upnpcommands.h>
|
||||
|
||||
// We have to look for miniupnpc headers in different places, dependent on if its compiled or external
|
||||
#ifdef UPNP_STATIC
|
||||
#include <miniupnpc/miniupnpc.h>
|
||||
#include <miniupnpc/upnpcommands.h>
|
||||
#else
|
||||
#include "miniupnpc.h"
|
||||
#include "upnpcommands.h"
|
||||
#endif
|
||||
|
||||
#define NET_MAKE_IP(b1,b2,b3,b4) ((LPARAM)(((DWORD)(b1)<<24)+((DWORD)(b2)<<16)+((DWORD)(b3)<<8)+((DWORD)(b4))))
|
||||
|
||||
@@ -53,7 +60,16 @@ namespace nodetool
|
||||
namespace
|
||||
{
|
||||
const command_line::arg_descriptor<std::string> arg_p2p_bind_ip = {"p2p-bind-ip", "Interface for p2p network protocol", "0.0.0.0"};
|
||||
const command_line::arg_descriptor<std::string> arg_p2p_bind_port = {"p2p-bind-port", "Port for p2p network protocol", boost::to_string(P2P_DEFAULT_PORT)};
|
||||
const command_line::arg_descriptor<std::string> arg_p2p_bind_port = {
|
||||
"p2p-bind-port"
|
||||
, "Port for p2p network protocol"
|
||||
, std::to_string(config::P2P_DEFAULT_PORT)
|
||||
};
|
||||
const command_line::arg_descriptor<std::string> arg_testnet_p2p_bind_port = {
|
||||
"testnet-p2p-bind-port"
|
||||
, "Port for testnet p2p network protocol"
|
||||
, std::to_string(config::testnet::P2P_DEFAULT_PORT)
|
||||
};
|
||||
const command_line::arg_descriptor<uint32_t> arg_p2p_external_port = {"p2p-external-port", "External port for p2p network protocol (if port forwarding used with NAT)", 0};
|
||||
const command_line::arg_descriptor<bool> arg_p2p_allow_local_ip = {"allow-local-ip", "Allow local ip add to peer list, mostly in debug purposes"};
|
||||
const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_add_peer = {"add-peer", "Manually add peer to local peerlist"};
|
||||
@@ -70,6 +86,7 @@ namespace nodetool
|
||||
{
|
||||
command_line::add_arg(desc, arg_p2p_bind_ip);
|
||||
command_line::add_arg(desc, arg_p2p_bind_port);
|
||||
command_line::add_arg(desc, arg_testnet_p2p_bind_port);
|
||||
command_line::add_arg(desc, arg_p2p_external_port);
|
||||
command_line::add_arg(desc, arg_p2p_allow_local_ip);
|
||||
command_line::add_arg(desc, arg_p2p_add_peer);
|
||||
@@ -131,10 +148,15 @@ namespace nodetool
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::handle_command_line(const boost::program_options::variables_map& vm)
|
||||
bool node_server<t_payload_net_handler>::handle_command_line(
|
||||
const boost::program_options::variables_map& vm
|
||||
, bool testnet
|
||||
)
|
||||
{
|
||||
auto p2p_bind_arg = testnet ? arg_testnet_p2p_bind_port : arg_p2p_bind_port;
|
||||
|
||||
m_bind_ip = command_line::get_arg(vm, arg_p2p_bind_ip);
|
||||
m_port = command_line::get_arg(vm, arg_p2p_bind_port);
|
||||
m_port = command_line::get_arg(vm, p2p_bind_arg);
|
||||
m_external_port = command_line::get_arg(vm, arg_p2p_external_port);
|
||||
m_allow_local_ip = command_line::get_arg(vm, arg_p2p_allow_local_ip);
|
||||
|
||||
@@ -173,67 +195,74 @@ namespace nodetool
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
namespace
|
||||
inline void add_hardcoded_seed_node(
|
||||
std::vector<net_address> & seed_nodes
|
||||
, std::string const & addr
|
||||
)
|
||||
{
|
||||
template<typename T>
|
||||
bool append_net_address(T& nodes, const std::string& addr)
|
||||
using namespace boost::asio;
|
||||
|
||||
size_t pos = addr.find_last_of(':');
|
||||
CHECK_AND_ASSERT_MES_NO_RET(std::string::npos != pos && addr.length() - 1 != pos && 0 != pos, "Failed to parse seed address from string: '" << addr << '\'');
|
||||
std::string host = addr.substr(0, pos);
|
||||
std::string port = addr.substr(pos + 1);
|
||||
|
||||
io_service io_srv;
|
||||
ip::tcp::resolver resolver(io_srv);
|
||||
ip::tcp::resolver::query query(host, port);
|
||||
boost::system::error_code ec;
|
||||
ip::tcp::resolver::iterator i = resolver.resolve(query, ec);
|
||||
CHECK_AND_ASSERT_MES_NO_RET(!ec, "Failed to resolve host name '" << host << "': " << ec.message() << ':' << ec.value());
|
||||
|
||||
ip::tcp::resolver::iterator iend;
|
||||
for (; i != iend; ++i)
|
||||
{
|
||||
using namespace boost::asio;
|
||||
|
||||
size_t pos = addr.find_last_of(':');
|
||||
CHECK_AND_ASSERT_MES(std::string::npos != pos && addr.length() - 1 != pos && 0 != pos, false, "Failed to parse seed address from string: '" << addr << '\'');
|
||||
std::string host = addr.substr(0, pos);
|
||||
std::string port = addr.substr(pos + 1);
|
||||
|
||||
io_service io_srv;
|
||||
ip::tcp::resolver resolver(io_srv);
|
||||
ip::tcp::resolver::query query(host, port);
|
||||
boost::system::error_code ec;
|
||||
ip::tcp::resolver::iterator i = resolver.resolve(query, ec);
|
||||
CHECK_AND_NO_ASSERT_MES(!ec, false, "Failed to resolve host name '" << host << "': " << ec.message() << ':' << ec.value());
|
||||
|
||||
ip::tcp::resolver::iterator iend;
|
||||
for (; i != iend; ++i)
|
||||
ip::tcp::endpoint endpoint = *i;
|
||||
if (endpoint.address().is_v4())
|
||||
{
|
||||
ip::tcp::endpoint endpoint = *i;
|
||||
if (endpoint.address().is_v4())
|
||||
{
|
||||
nodetool::net_address na;
|
||||
na.ip = boost::asio::detail::socket_ops::host_to_network_long(endpoint.address().to_v4().to_ulong());
|
||||
na.port = endpoint.port();
|
||||
nodes.push_back(na);
|
||||
LOG_PRINT_L4("Added seed node: " << endpoint.address().to_v4().to_string(ec) << ':' << na.port);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_PRINT_L2("IPv6 doesn't supported, skip '" << host << "' -> " << endpoint.address().to_v6().to_string(ec));
|
||||
}
|
||||
nodetool::net_address na;
|
||||
na.ip = boost::asio::detail::socket_ops::host_to_network_long(endpoint.address().to_v4().to_ulong());
|
||||
na.port = endpoint.port();
|
||||
seed_nodes.push_back(na);
|
||||
LOG_PRINT_L4("Added seed node: " << endpoint.address().to_v4().to_string(ec) << ':' << na.port);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_PRINT_L2("IPv6 doesn't supported, skip '" << host << "' -> " << endpoint.address().to_v6().to_string(ec));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#define ADD_HARDCODED_SEED_NODE(addr) append_net_address(m_seed_nodes, addr);
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::init(const boost::program_options::variables_map& vm)
|
||||
bool node_server<t_payload_net_handler>::init(const boost::program_options::variables_map& vm, bool testnet)
|
||||
{
|
||||
ADD_HARDCODED_SEED_NODE("62.210.78.186:18080");
|
||||
ADD_HARDCODED_SEED_NODE("195.12.60.154:18080");
|
||||
ADD_HARDCODED_SEED_NODE("54.241.246.125:18080");
|
||||
ADD_HARDCODED_SEED_NODE("107.170.157.169:18080");
|
||||
ADD_HARDCODED_SEED_NODE("54.207.112.216:18080");
|
||||
ADD_HARDCODED_SEED_NODE("78.27.112.54:18080");
|
||||
ADD_HARDCODED_SEED_NODE("209.222.30.57:18080");
|
||||
ADD_HARDCODED_SEED_NODE("80.71.13.55:18080");
|
||||
ADD_HARDCODED_SEED_NODE("107.178.112.126:18080");
|
||||
ADD_HARDCODED_SEED_NODE("107.158.233.98:18080");
|
||||
ADD_HARDCODED_SEED_NODE("64.22.111.2:18080");
|
||||
if (testnet)
|
||||
{
|
||||
add_hardcoded_seed_node(m_seed_nodes, "107.152.187.202:28080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "197.242.158.240:28080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "107.152.130.98:28080");
|
||||
}
|
||||
else
|
||||
{
|
||||
add_hardcoded_seed_node(m_seed_nodes, "62.210.78.186:18080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "195.12.60.154:18080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "54.241.246.125:18080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "107.170.157.169:18080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "54.207.112.216:18080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "78.27.112.54:18080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "209.222.30.57:18080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "80.71.13.55:18080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "107.178.112.126:18080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "107.158.233.98:18080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "64.22.111.2:18080");
|
||||
}
|
||||
|
||||
bool res = handle_command_line(vm);
|
||||
bool res = handle_command_line(vm, testnet);
|
||||
CHECK_AND_ASSERT_MES(res, false, "Failed to handle command line");
|
||||
m_config_folder = command_line::get_arg(vm, command_line::arg_data_dir);
|
||||
|
||||
auto config_arg = testnet ? command_line::arg_testnet_data_dir : command_line::arg_data_dir;
|
||||
m_config_folder = command_line::get_arg(vm, config_arg);
|
||||
|
||||
res = init_config();
|
||||
CHECK_AND_ASSERT_MES(res, false, "Failed to init config.");
|
||||
@@ -261,7 +290,7 @@ namespace nodetool
|
||||
CHECK_AND_ASSERT_MES(res, false, "Failed to bind server");
|
||||
|
||||
m_listenning_port = m_net_server.get_binded_port();
|
||||
LOG_PRINT_GREEN("Net service binded on " << m_bind_ip << ":" << m_listenning_port, LOG_LEVEL_0);
|
||||
LOG_PRINT_GREEN("Net service bound to " << m_bind_ip << ":" << m_listenning_port, LOG_LEVEL_0);
|
||||
if(m_external_port)
|
||||
LOG_PRINT_L0("External port defined as " << m_external_port);
|
||||
|
||||
@@ -403,7 +432,7 @@ namespace nodetool
|
||||
return;
|
||||
}
|
||||
|
||||
if(rsp.node_data.network_id != MONERO_NETWORK)
|
||||
if(rsp.node_data.network_id != m_network_id)
|
||||
{
|
||||
LOG_ERROR_CCONTEXT("COMMAND_HANDSHAKE Failed, wrong network! (" << epee::string_tools::get_str_from_guid_a(rsp.node_data.network_id) << "), closing connection.");
|
||||
return;
|
||||
@@ -541,7 +570,7 @@ namespace nodetool
|
||||
#define LOG_PRINT_CC_PRIORITY_NODE(priority, con, msg) \
|
||||
do { \
|
||||
if (priority) {\
|
||||
LOG_PRINT_CC_L0(con, msg); \
|
||||
LOG_PRINT_CC_L1(con, msg); \
|
||||
} else {\
|
||||
LOG_PRINT_CC_L1(con, msg); \
|
||||
} \
|
||||
@@ -780,7 +809,7 @@ namespace nodetool
|
||||
{
|
||||
if(be.last_seen > local_time)
|
||||
{
|
||||
LOG_PRINT_RED_L0("FOUND FUTURE peerlist for entry " << epee::string_tools::get_ip_string_from_int32(be.adr.ip) << ":" << be.adr.port << " last_seen: " << be.last_seen << ", local_time(on remote node):" << local_time);
|
||||
LOG_PRINT_RED_L1("FOUND FUTURE peerlist for entry " << epee::string_tools::get_ip_string_from_int32(be.adr.ip) << ":" << be.adr.port << " last_seen: " << be.last_seen << ", local_time(on remote node):" << local_time);
|
||||
return false;
|
||||
}
|
||||
be.last_seen += delta;
|
||||
@@ -811,7 +840,7 @@ namespace nodetool
|
||||
node_data.my_port = m_external_port ? m_external_port : m_listenning_port;
|
||||
else
|
||||
node_data.my_port = 0;
|
||||
node_data.network_id = MONERO_NETWORK;
|
||||
node_data.network_id = m_network_id;
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
@@ -837,7 +866,7 @@ namespace nodetool
|
||||
return false;
|
||||
}
|
||||
crypto::public_key pk = AUTO_VAL_INIT(pk);
|
||||
epee::string_tools::hex_to_pod(P2P_STAT_TRUSTED_PUB_KEY, pk);
|
||||
epee::string_tools::hex_to_pod(::config::P2P_REMOTE_DEBUG_TRUSTED_PUB_KEY, pk);
|
||||
crypto::hash h = tools::get_proof_of_trust_hash(tr);
|
||||
if(!crypto::check_signature(h, pk, tr.sign))
|
||||
{
|
||||
@@ -859,7 +888,7 @@ namespace nodetool
|
||||
}
|
||||
rsp.connections_count = m_net_server.get_config_object().get_connections_count();
|
||||
rsp.incoming_connections_count = rsp.connections_count - get_outgoing_connections_count();
|
||||
rsp.version = PROJECT_VERSION_LONG;
|
||||
rsp.version = MONERO_VERSION_FULL;
|
||||
rsp.os_version = tools::get_os_version_string();
|
||||
m_payload_handler.get_stat_info(rsp.payload_info);
|
||||
return 1;
|
||||
@@ -1031,10 +1060,10 @@ namespace nodetool
|
||||
template<class t_payload_net_handler>
|
||||
int node_server<t_payload_net_handler>::handle_handshake(int command, typename COMMAND_HANDSHAKE::request& arg, typename COMMAND_HANDSHAKE::response& rsp, p2p_connection_context& context)
|
||||
{
|
||||
if(arg.node_data.network_id != MONERO_NETWORK)
|
||||
if(arg.node_data.network_id != m_network_id)
|
||||
{
|
||||
|
||||
LOG_PRINT_CCONTEXT_L0("WRONG NETWORK AGENT CONNECTED! id=" << epee::string_tools::get_str_from_guid_a(arg.node_data.network_id));
|
||||
LOG_PRINT_CCONTEXT_L1("WRONG NETWORK AGENT CONNECTED! id=" << epee::string_tools::get_str_from_guid_a(arg.node_data.network_id));
|
||||
drop_connection(context);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
// Copyright (c) 2014, 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
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace nodetool
|
||||
{
|
||||
const static boost::uuids::uuid MONERO_NETWORK = { { 0x12 ,0x30, 0xF1, 0x71 , 0x61, 0x04 , 0x41, 0x61, 0x17, 0x31, 0x00, 0x82, 0x16, 0xA1, 0xA1, 0x10} }; //Bender's nightmare
|
||||
}
|
||||
@@ -45,8 +45,23 @@ namespace cryptonote
|
||||
{
|
||||
namespace
|
||||
{
|
||||
const command_line::arg_descriptor<std::string> arg_rpc_bind_ip = {"rpc-bind-ip", "", "127.0.0.1"};
|
||||
const command_line::arg_descriptor<std::string> arg_rpc_bind_port = {"rpc-bind-port", "", std::to_string(RPC_DEFAULT_PORT)};
|
||||
const command_line::arg_descriptor<std::string> arg_rpc_bind_ip = {
|
||||
"rpc-bind-ip"
|
||||
, "IP for RPC server"
|
||||
, "127.0.0.1"
|
||||
};
|
||||
|
||||
const command_line::arg_descriptor<std::string> arg_rpc_bind_port = {
|
||||
"rpc-bind-port"
|
||||
, "Port for RPC server"
|
||||
, std::to_string(config::RPC_DEFAULT_PORT)
|
||||
};
|
||||
|
||||
const command_line::arg_descriptor<std::string> arg_testnet_rpc_bind_port = {
|
||||
"testnet-rpc-bind-port"
|
||||
, "Port for testnet RPC server"
|
||||
, std::to_string(config::testnet::RPC_DEFAULT_PORT)
|
||||
};
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
@@ -54,19 +69,33 @@ namespace cryptonote
|
||||
{
|
||||
command_line::add_arg(desc, arg_rpc_bind_ip);
|
||||
command_line::add_arg(desc, arg_rpc_bind_port);
|
||||
command_line::add_arg(desc, arg_testnet_rpc_bind_port);
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
core_rpc_server::core_rpc_server(core& cr, nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& p2p):m_core(cr), m_p2p(p2p)
|
||||
core_rpc_server::core_rpc_server(
|
||||
core& cr
|
||||
, nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& p2p
|
||||
, bool testnet
|
||||
)
|
||||
: m_core(cr)
|
||||
, m_p2p(p2p)
|
||||
, m_testnet {testnet}
|
||||
{}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::handle_command_line(const boost::program_options::variables_map& vm)
|
||||
bool core_rpc_server::handle_command_line(
|
||||
const boost::program_options::variables_map& vm
|
||||
)
|
||||
{
|
||||
auto p2p_bind_arg = m_testnet ? arg_testnet_rpc_bind_port : arg_rpc_bind_port;
|
||||
|
||||
m_bind_ip = command_line::get_arg(vm, arg_rpc_bind_ip);
|
||||
m_port = command_line::get_arg(vm, arg_rpc_bind_port);
|
||||
m_port = command_line::get_arg(vm, p2p_bind_arg);
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::init(const boost::program_options::variables_map& vm)
|
||||
bool core_rpc_server::init(
|
||||
const boost::program_options::variables_map& vm
|
||||
)
|
||||
{
|
||||
m_net_server.set_threads_prefix("RPC");
|
||||
bool r = handle_command_line(vm);
|
||||
@@ -278,7 +307,7 @@ namespace cryptonote
|
||||
{
|
||||
CHECK_CORE_READY();
|
||||
account_public_address adr;
|
||||
if(!get_account_address_from_str(adr, req.miner_address))
|
||||
if(!get_account_address_from_str(adr, m_testnet, req.miner_address))
|
||||
{
|
||||
res.status = "Failed, wrong address";
|
||||
return true;
|
||||
@@ -318,7 +347,7 @@ namespace cryptonote
|
||||
res.speed = lMiner.get_speed();
|
||||
res.threads_count = lMiner.get_threads_count();
|
||||
const account_public_address& lMiningAdr = lMiner.get_mining_address();
|
||||
res.address = get_account_address_as_str(lMiningAdr);
|
||||
res.address = get_account_address_as_str(m_testnet, lMiningAdr);
|
||||
}
|
||||
|
||||
res.status = CORE_RPC_STATUS_OK;
|
||||
@@ -402,7 +431,7 @@ namespace cryptonote
|
||||
|
||||
cryptonote::account_public_address acc = AUTO_VAL_INIT(acc);
|
||||
|
||||
if(!req.wallet_address.size() || !cryptonote::get_account_address_from_str(acc, req.wallet_address))
|
||||
if(!req.wallet_address.size() || !cryptonote::get_account_address_from_str(acc, m_testnet, req.wallet_address))
|
||||
{
|
||||
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_WALLET_ADDRESS;
|
||||
error_resp.message = "Failed to parse wallet address";
|
||||
|
||||
@@ -49,10 +49,16 @@ namespace cryptonote
|
||||
public:
|
||||
typedef epee::net_utils::connection_context_base connection_context;
|
||||
|
||||
core_rpc_server(core& cr, nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& p2p);
|
||||
core_rpc_server(
|
||||
core& cr
|
||||
, nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& p2p
|
||||
, bool testnet
|
||||
);
|
||||
|
||||
static void init_options(boost::program_options::options_description& desc);
|
||||
bool init(const boost::program_options::variables_map& vm);
|
||||
bool init(
|
||||
const boost::program_options::variables_map& vm
|
||||
);
|
||||
private:
|
||||
|
||||
CHAIN_HTTP_TO_MAP2(connection_context); //forward http requests to uri map
|
||||
@@ -105,7 +111,9 @@ namespace cryptonote
|
||||
bool on_get_connections(const COMMAND_RPC_GET_CONNECTIONS::request& req, COMMAND_RPC_GET_CONNECTIONS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx);
|
||||
bool on_get_info_json(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res, epee::json_rpc::error& error_resp, connection_context& cntx);
|
||||
//-----------------------
|
||||
bool handle_command_line(const boost::program_options::variables_map& vm);
|
||||
bool handle_command_line(
|
||||
const boost::program_options::variables_map& vm
|
||||
);
|
||||
bool check_core_busy();
|
||||
bool check_core_ready();
|
||||
|
||||
@@ -117,5 +125,6 @@ namespace cryptonote
|
||||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& m_p2p;
|
||||
std::string m_port;
|
||||
std::string m_bind_ip;
|
||||
bool m_testnet;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ namespace
|
||||
const command_line::arg_descriptor<bool> arg_non_deterministic = {"non-deterministic", "creates non-deterministic view and spend keys", false};
|
||||
const command_line::arg_descriptor<int> arg_daemon_port = {"daemon-port", "Use daemon instance at port <arg> instead of 8081", 0};
|
||||
const command_line::arg_descriptor<uint32_t> arg_log_level = {"set_log", "", 0, true};
|
||||
const command_line::arg_descriptor<bool> arg_testnet = {"testnet", "Used to deploy test nets. The daemon must be launched with --testnet flag", false};
|
||||
|
||||
const command_line::arg_descriptor< std::vector<std::string> > arg_command = {"command", ""};
|
||||
|
||||
@@ -327,10 +328,16 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
|
||||
if(!ask_wallet_create_if_needed()) return false;
|
||||
}
|
||||
|
||||
bool testnet = command_line::get_arg(vm, arg_testnet);
|
||||
|
||||
if (m_daemon_host.empty())
|
||||
m_daemon_host = "localhost";
|
||||
|
||||
if (!m_daemon_port)
|
||||
m_daemon_port = RPC_DEFAULT_PORT;
|
||||
{
|
||||
m_daemon_port = testnet ? config::testnet::RPC_DEFAULT_PORT : config::RPC_DEFAULT_PORT;
|
||||
}
|
||||
|
||||
if (m_daemon_address.empty())
|
||||
m_daemon_address = std::string("http://") + m_daemon_host + ":" + std::to_string(m_daemon_port);
|
||||
|
||||
@@ -378,12 +385,12 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool r = new_wallet(m_wallet_file, pwd_container.password(), m_recovery_key, m_restore_deterministic_wallet, m_non_deterministic);
|
||||
bool r = new_wallet(m_wallet_file, pwd_container.password(), m_recovery_key, m_restore_deterministic_wallet, m_non_deterministic, testnet);
|
||||
CHECK_AND_ASSERT_MES(r, false, "account creation failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
bool r = open_wallet(m_wallet_file, pwd_container.password());
|
||||
bool r = open_wallet(m_wallet_file, pwd_container.password(), testnet);
|
||||
CHECK_AND_ASSERT_MES(r, false, "could not open account");
|
||||
}
|
||||
|
||||
@@ -423,18 +430,20 @@ bool simple_wallet::try_connect_to_daemon()
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::new_wallet(const string &wallet_file, const std::string& password, const crypto::secret_key& recovery_key, bool recover, bool two_random)
|
||||
bool simple_wallet::new_wallet(const string &wallet_file, const std::string& password, const crypto::secret_key& recovery_key, bool recover, bool two_random, bool testnet)
|
||||
{
|
||||
m_wallet_file = wallet_file;
|
||||
|
||||
m_wallet.reset(new tools::wallet2());
|
||||
m_wallet.reset(new tools::wallet2(testnet));
|
||||
m_wallet->callback(this);
|
||||
|
||||
crypto::secret_key recovery_val;
|
||||
try
|
||||
{
|
||||
recovery_val = m_wallet->generate(wallet_file, password, recovery_key, recover, two_random);
|
||||
message_writer(epee::log_space::console_color_white, true) << "Generated new wallet: " << m_wallet->get_account().get_public_address_str() << std::endl << "view key: " << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_view_secret_key);
|
||||
message_writer(epee::log_space::console_color_white, true) << "Generated new wallet: "
|
||||
<< m_wallet->get_account().get_public_address_str(m_wallet->testnet()) << std::endl << "view key: "
|
||||
<< string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_view_secret_key);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@@ -471,16 +480,17 @@ bool simple_wallet::new_wallet(const string &wallet_file, const std::string& pas
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::open_wallet(const string &wallet_file, const std::string& password)
|
||||
bool simple_wallet::open_wallet(const string &wallet_file, const std::string& password, bool testnet)
|
||||
{
|
||||
m_wallet_file = wallet_file;
|
||||
m_wallet.reset(new tools::wallet2());
|
||||
m_wallet.reset(new tools::wallet2(testnet));
|
||||
m_wallet->callback(this);
|
||||
|
||||
try
|
||||
{
|
||||
m_wallet->load(m_wallet_file, password);
|
||||
message_writer(epee::log_space::console_color_white, true) << "Opened wallet: " << m_wallet->get_account().get_public_address_str();
|
||||
message_writer(epee::log_space::console_color_white, true) << "Opened wallet: "
|
||||
<< m_wallet->get_account().get_public_address_str(m_wallet->testnet());
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@@ -541,7 +551,7 @@ bool simple_wallet::start_mining(const std::vector<std::string>& args)
|
||||
return true;
|
||||
|
||||
COMMAND_RPC_START_MINING::request req;
|
||||
req.miner_address = m_wallet->get_account().get_public_address_str();
|
||||
req.miner_address = m_wallet->get_account().get_public_address_str(m_wallet->testnet());
|
||||
|
||||
bool ok = true;
|
||||
size_t max_mining_threads_count = (std::max)(std::thread::hardware_concurrency(), static_cast<unsigned>(2));
|
||||
@@ -898,7 +908,7 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
||||
for (size_t i = 0; i < local_args.size(); i += 2)
|
||||
{
|
||||
cryptonote::tx_destination_entry de;
|
||||
if(!get_account_address_from_str(de.addr, local_args[i]))
|
||||
if(!get_account_address_from_str(de.addr, m_wallet->testnet(), local_args[i]))
|
||||
{
|
||||
fail_msg_writer() << "wrong address: " << local_args[i];
|
||||
return true;
|
||||
@@ -1028,7 +1038,7 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::run()
|
||||
{
|
||||
std::string addr_start = m_wallet->get_account().get_public_address_str().substr(0, 6);
|
||||
std::string addr_start = m_wallet->get_account().get_public_address_str(m_wallet->testnet()).substr(0, 6);
|
||||
return m_cmd_binder.run_handling("[wallet " + addr_start + "]: ", "");
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
@@ -1040,7 +1050,7 @@ void simple_wallet::stop()
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::print_address(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
|
||||
{
|
||||
success_msg_writer() << m_wallet->get_account().get_public_address_str();
|
||||
success_msg_writer() << m_wallet->get_account().get_public_address_str(m_wallet->testnet());
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
@@ -1075,6 +1085,7 @@ int main(int argc, char* argv[])
|
||||
command_line::add_arg(desc_params, arg_restore_deterministic_wallet );
|
||||
command_line::add_arg(desc_params, arg_non_deterministic );
|
||||
command_line::add_arg(desc_params, arg_electrum_seed );
|
||||
command_line::add_arg(desc_params, arg_testnet);
|
||||
tools::wallet_rpc_server::init_options(desc_params);
|
||||
|
||||
po::positional_options_description positional_options;
|
||||
@@ -1090,14 +1101,14 @@ int main(int argc, char* argv[])
|
||||
|
||||
if (command_line::get_arg(vm, command_line::arg_help))
|
||||
{
|
||||
success_msg_writer() << CRYPTONOTE_NAME << " wallet v" << PROJECT_VERSION_LONG;
|
||||
success_msg_writer() << CRYPTONOTE_NAME << " wallet v" << MONERO_VERSION_FULL;
|
||||
success_msg_writer() << "Usage: simplewallet [--wallet-file=<file>|--generate-new-wallet=<file>] [--daemon-address=<host>:<port>] [<COMMAND>]";
|
||||
success_msg_writer() << desc_all << '\n' << w.get_commands_str();
|
||||
return false;
|
||||
}
|
||||
else if (command_line::get_arg(vm, command_line::arg_version))
|
||||
{
|
||||
success_msg_writer() << CRYPTONOTE_NAME << " wallet v" << PROJECT_VERSION_LONG;
|
||||
success_msg_writer() << CRYPTONOTE_NAME << " wallet v" << MONERO_VERSION_FULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1116,7 +1127,7 @@ int main(int argc, char* argv[])
|
||||
log_space::log_singletone::get_default_log_file().c_str(),
|
||||
log_space::log_singletone::get_default_log_folder().c_str(), LOG_LEVEL_4);
|
||||
|
||||
message_writer(epee::log_space::console_color_white, true) << CRYPTONOTE_NAME << " wallet v" << PROJECT_VERSION_LONG;
|
||||
message_writer(epee::log_space::console_color_white, true) << CRYPTONOTE_NAME << " wallet v" << MONERO_VERSION_FULL;
|
||||
|
||||
if(command_line::has_arg(vm, arg_log_level))
|
||||
{
|
||||
@@ -1144,6 +1155,7 @@ int main(int argc, char* argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool testnet = command_line::get_arg(vm, arg_testnet);
|
||||
std::string wallet_file = command_line::get_arg(vm, arg_wallet_file);
|
||||
std::string wallet_password = command_line::get_arg(vm, arg_password);
|
||||
std::string daemon_address = command_line::get_arg(vm, arg_daemon_address);
|
||||
@@ -1152,11 +1164,11 @@ int main(int argc, char* argv[])
|
||||
if (daemon_host.empty())
|
||||
daemon_host = "localhost";
|
||||
if (!daemon_port)
|
||||
daemon_port = RPC_DEFAULT_PORT;
|
||||
daemon_port = config::RPC_DEFAULT_PORT;
|
||||
if (daemon_address.empty())
|
||||
daemon_address = std::string("http://") + daemon_host + ":" + std::to_string(daemon_port);
|
||||
|
||||
tools::wallet2 wal;
|
||||
tools::wallet2 wal(testnet);
|
||||
try
|
||||
{
|
||||
LOG_PRINT_L0("Loading wallet...");
|
||||
|
||||
@@ -66,8 +66,8 @@ namespace cryptonote
|
||||
|
||||
bool run_console_handler();
|
||||
|
||||
bool new_wallet(const std::string &wallet_file, const std::string& password, const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false, bool two_random = false);
|
||||
bool open_wallet(const std::string &wallet_file, const std::string& password);
|
||||
bool new_wallet(const std::string &wallet_file, const std::string& password, const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false, bool two_random = false, bool testnet = false);
|
||||
bool open_wallet(const std::string &wallet_file, const std::string& password, bool testnet);
|
||||
bool close_wallet();
|
||||
|
||||
bool viewkey(const std::vector<std::string> &args = std::vector<std::string>());
|
||||
|
||||
@@ -1,11 +1,30 @@
|
||||
execute_process(COMMAND "${GIT}" describe --dirty --match "v${VERSION}" RESULT_VARIABLE RET OUTPUT_VARIABLE DESCRIPTION OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND "${GIT}" rev-parse --short HEAD RESULT_VARIABLE RET OUTPUT_VARIABLE COMMIT OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
if(RET)
|
||||
message(WARNING "Cannot determine current revision. Make sure that you are building either from a Git working tree or from a source archive.")
|
||||
set(VERSION "${COMMIT}")
|
||||
message(WARNING "Cannot determine current commit. Make sure that you are building either from a Git working tree or from a source archive.")
|
||||
set(VERSIONTAG "unknown")
|
||||
configure_file("src/version.h.in" "${TO}")
|
||||
else()
|
||||
string(REGEX MATCH "([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f])?(-dirty)? $" COMMIT "${DESCRIPTION} ")
|
||||
string(STRIP "${COMMIT}" COMMIT)
|
||||
set(VERSION "${COMMIT}")
|
||||
message(STATUS "You are currently on commit ${COMMIT}")
|
||||
execute_process(COMMAND "${GIT}" show-ref --tags -d --abbrev RESULT_VARIABLE RET OUTPUT_VARIABLE TAGGEDCOMMITOUT OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
string(REPLACE " refs/" "\n" TAGGEDCOMMITOUT2 ${TAGGEDCOMMITOUT})
|
||||
string(REPLACE "\n" ";" TAGGEDCOMMITLIST ${TAGGEDCOMMITOUT2})
|
||||
list(GET TAGGEDCOMMITLIST -2 TAGGEDCOMMIT)
|
||||
|
||||
if(RET OR NOT TAGGEDCOMMIT)
|
||||
message(WARNING "Cannot determine most recent tag. Make sure that you are building either from a Git working tree or from a source archive.")
|
||||
set(VERSIONTAG "${COMMIT}")
|
||||
else()
|
||||
message(STATUS "The most recent tag was at ${TAGGEDCOMMIT}")
|
||||
if(${COMMIT} MATCHES ${TAGGEDCOMMIT})
|
||||
message(STATUS "You are building a tagged release")
|
||||
set(VERSIONTAG "release")
|
||||
else()
|
||||
message(STATUS "You are ahead or behind of a tagged release")
|
||||
set(VERSIONTAG "${COMMIT}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
configure_file("src/version.h.in" "${TO}")
|
||||
endif()
|
||||
@@ -1,4 +1,3 @@
|
||||
#define BUILD_COMMIT_ID "@VERSION@"
|
||||
#define PROJECT_VERSION "0.8.8"
|
||||
#define PROJECT_VERSION_BUILD_NO "3"
|
||||
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO "(" BUILD_COMMIT_ID ")"
|
||||
#define MONERO_VERSION_TAG "@VERSIONTAG@"
|
||||
#define MONERO_VERSION "0.8.8.4"
|
||||
#define MONERO_VERSION_FULL MONERO_VERSION "-" MONERO_VERSION_TAG
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "include_base_utils.h"
|
||||
using namespace epee;
|
||||
|
||||
#include "cryptonote_config.h"
|
||||
#include "wallet2.h"
|
||||
#include "cryptonote_core/cryptonote_format_utils.h"
|
||||
#include "rpc/core_rpc_server_commands_defs.h"
|
||||
@@ -109,55 +110,59 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_
|
||||
LOG_PRINT_L0("Transaction extra has unsupported format: " << get_transaction_hash(tx));
|
||||
}
|
||||
|
||||
tx_extra_pub_key pub_key_field;
|
||||
if(!find_tx_extra_field_by_type(tx_extra_fields, pub_key_field))
|
||||
// Don't try to extract tx public key if tx has no ouputs
|
||||
if (!tx.vout.empty())
|
||||
{
|
||||
LOG_PRINT_L0("Public key wasn't found in the transaction extra. Skipping transaction " << get_transaction_hash(tx));
|
||||
if(0 != m_callback)
|
||||
m_callback->on_skip_transaction(height, tx);
|
||||
return;
|
||||
}
|
||||
|
||||
crypto::public_key tx_pub_key = pub_key_field.pub_key;
|
||||
bool r = lookup_acc_outs(m_account.get_keys(), tx, tx_pub_key, outs, tx_money_got_in_outs);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
|
||||
|
||||
if(!outs.empty() && tx_money_got_in_outs)
|
||||
{
|
||||
//good news - got money! take care about it
|
||||
//usually we have only one transfer for user in transaction
|
||||
cryptonote::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request req = AUTO_VAL_INIT(req);
|
||||
cryptonote::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response res = AUTO_VAL_INIT(res);
|
||||
req.txid = get_transaction_hash(tx);
|
||||
bool r = net_utils::invoke_http_bin_remote_command2(m_daemon_address + "/get_o_indexes.bin", req, res, m_http_client, WALLET_RCP_CONNECTION_TIMEOUT);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_o_indexes.bin");
|
||||
THROW_WALLET_EXCEPTION_IF(res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_o_indexes.bin");
|
||||
THROW_WALLET_EXCEPTION_IF(res.status != CORE_RPC_STATUS_OK, error::get_out_indices_error, res.status);
|
||||
THROW_WALLET_EXCEPTION_IF(res.o_indexes.size() != tx.vout.size(), error::wallet_internal_error,
|
||||
"transactions outputs size=" + std::to_string(tx.vout.size()) +
|
||||
" not match with COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES response size=" + std::to_string(res.o_indexes.size()));
|
||||
|
||||
BOOST_FOREACH(size_t o, outs)
|
||||
tx_extra_pub_key pub_key_field;
|
||||
if(!find_tx_extra_field_by_type(tx_extra_fields, pub_key_field))
|
||||
{
|
||||
THROW_WALLET_EXCEPTION_IF(tx.vout.size() <= o, error::wallet_internal_error, "wrong out in transaction: internal index=" +
|
||||
std::to_string(o) + ", total_outs=" + std::to_string(tx.vout.size()));
|
||||
LOG_PRINT_L0("Public key wasn't found in the transaction extra. Skipping transaction " << get_transaction_hash(tx));
|
||||
if(0 != m_callback)
|
||||
m_callback->on_skip_transaction(height, tx);
|
||||
return;
|
||||
}
|
||||
|
||||
m_transfers.push_back(boost::value_initialized<transfer_details>());
|
||||
transfer_details& td = m_transfers.back();
|
||||
td.m_block_height = height;
|
||||
td.m_internal_output_index = o;
|
||||
td.m_global_output_index = res.o_indexes[o];
|
||||
td.m_tx = tx;
|
||||
td.m_spent = false;
|
||||
cryptonote::keypair in_ephemeral;
|
||||
cryptonote::generate_key_image_helper(m_account.get_keys(), tx_pub_key, o, in_ephemeral, td.m_key_image);
|
||||
THROW_WALLET_EXCEPTION_IF(in_ephemeral.pub != boost::get<cryptonote::txout_to_key>(tx.vout[o].target).key,
|
||||
error::wallet_internal_error, "key_image generated ephemeral public key not matched with output_key");
|
||||
crypto::public_key tx_pub_key = pub_key_field.pub_key;
|
||||
bool r = lookup_acc_outs(m_account.get_keys(), tx, tx_pub_key, outs, tx_money_got_in_outs);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
|
||||
|
||||
m_key_images[td.m_key_image] = m_transfers.size()-1;
|
||||
LOG_PRINT_L0("Received money: " << print_money(td.amount()) << ", with tx: " << get_transaction_hash(tx));
|
||||
if (0 != m_callback)
|
||||
m_callback->on_money_received(height, td.m_tx, td.m_internal_output_index);
|
||||
if(!outs.empty() && tx_money_got_in_outs)
|
||||
{
|
||||
//good news - got money! take care about it
|
||||
//usually we have only one transfer for user in transaction
|
||||
cryptonote::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request req = AUTO_VAL_INIT(req);
|
||||
cryptonote::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response res = AUTO_VAL_INIT(res);
|
||||
req.txid = get_transaction_hash(tx);
|
||||
bool r = net_utils::invoke_http_bin_remote_command2(m_daemon_address + "/get_o_indexes.bin", req, res, m_http_client, WALLET_RCP_CONNECTION_TIMEOUT);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_o_indexes.bin");
|
||||
THROW_WALLET_EXCEPTION_IF(res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_o_indexes.bin");
|
||||
THROW_WALLET_EXCEPTION_IF(res.status != CORE_RPC_STATUS_OK, error::get_out_indices_error, res.status);
|
||||
THROW_WALLET_EXCEPTION_IF(res.o_indexes.size() != tx.vout.size(), error::wallet_internal_error,
|
||||
"transactions outputs size=" + std::to_string(tx.vout.size()) +
|
||||
" not match with COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES response size=" + std::to_string(res.o_indexes.size()));
|
||||
|
||||
BOOST_FOREACH(size_t o, outs)
|
||||
{
|
||||
THROW_WALLET_EXCEPTION_IF(tx.vout.size() <= o, error::wallet_internal_error, "wrong out in transaction: internal index=" +
|
||||
std::to_string(o) + ", total_outs=" + std::to_string(tx.vout.size()));
|
||||
|
||||
m_transfers.push_back(boost::value_initialized<transfer_details>());
|
||||
transfer_details& td = m_transfers.back();
|
||||
td.m_block_height = height;
|
||||
td.m_internal_output_index = o;
|
||||
td.m_global_output_index = res.o_indexes[o];
|
||||
td.m_tx = tx;
|
||||
td.m_spent = false;
|
||||
cryptonote::keypair in_ephemeral;
|
||||
cryptonote::generate_key_image_helper(m_account.get_keys(), tx_pub_key, o, in_ephemeral, td.m_key_image);
|
||||
THROW_WALLET_EXCEPTION_IF(in_ephemeral.pub != boost::get<cryptonote::txout_to_key>(tx.vout[o].target).key,
|
||||
error::wallet_internal_error, "key_image generated ephemeral public key not matched with output_key");
|
||||
|
||||
m_key_images[td.m_key_image] = m_transfers.size()-1;
|
||||
LOG_PRINT_L0("Received money: " << print_money(td.amount()) << ", with tx: " << get_transaction_hash(tx));
|
||||
if (0 != m_callback)
|
||||
m_callback->on_money_received(height, td.m_tx, td.m_internal_output_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -416,9 +421,6 @@ bool wallet2::clear()
|
||||
{
|
||||
m_blockchain.clear();
|
||||
m_transfers.clear();
|
||||
cryptonote::block b;
|
||||
cryptonote::generate_genesis_block(b);
|
||||
m_blockchain.push_back(get_block_hash(b));
|
||||
m_local_bc_height = 1;
|
||||
return true;
|
||||
}
|
||||
@@ -494,9 +496,13 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const std::stri
|
||||
bool r = store_keys(m_keys_file, password);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_keys_file);
|
||||
|
||||
r = file_io_utils::save_string_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str());
|
||||
r = file_io_utils::save_string_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_testnet));
|
||||
if(!r) LOG_PRINT_RED_L0("String with address text not saved");
|
||||
|
||||
cryptonote::block b;
|
||||
generate_genesis(b);
|
||||
m_blockchain.push_back(get_block_hash(b));
|
||||
|
||||
store();
|
||||
return retval;
|
||||
}
|
||||
@@ -537,8 +543,12 @@ bool wallet2::check_connection()
|
||||
|
||||
net_utils::http::url_content u;
|
||||
net_utils::parse_url(m_daemon_address, u);
|
||||
|
||||
if(!u.port)
|
||||
u.port = RPC_DEFAULT_PORT;
|
||||
{
|
||||
u.port = m_testnet ? config::testnet::RPC_DEFAULT_PORT : config::RPC_DEFAULT_PORT;
|
||||
}
|
||||
|
||||
return m_http_client.connect(u.host, std::to_string(u.port), WALLET_RCP_CONNECTION_TIMEOUT);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
@@ -552,7 +562,7 @@ void wallet2::load(const std::string& wallet_, const std::string& password)
|
||||
THROW_WALLET_EXCEPTION_IF(e || !exists, error::file_not_found, m_keys_file);
|
||||
|
||||
load_keys(m_keys_file, password);
|
||||
LOG_PRINT_L0("Loaded wallet keys file, with public address: " << m_account.get_public_address_str());
|
||||
LOG_PRINT_L0("Loaded wallet keys file, with public address: " << m_account.get_public_address_str(m_testnet));
|
||||
|
||||
//keys loaded ok!
|
||||
//try to load wallet file. but even if we failed, it is not big problem
|
||||
@@ -569,15 +579,28 @@ void wallet2::load(const std::string& wallet_, const std::string& password)
|
||||
m_account_public_address.m_view_public_key != m_account.get_keys().m_account_address.m_view_public_key,
|
||||
error::wallet_files_doesnt_correspond, m_keys_file, m_wallet_file);
|
||||
|
||||
if(m_blockchain.empty())
|
||||
cryptonote::block genesis;
|
||||
generate_genesis(genesis);
|
||||
crypto::hash genesis_hash = get_block_hash(genesis);
|
||||
|
||||
if (m_blockchain.empty())
|
||||
{
|
||||
cryptonote::block b;
|
||||
cryptonote::generate_genesis_block(b);
|
||||
m_blockchain.push_back(get_block_hash(b));
|
||||
m_blockchain.push_back(genesis_hash);
|
||||
}
|
||||
else
|
||||
{
|
||||
check_genesis(genesis_hash);
|
||||
}
|
||||
|
||||
m_local_bc_height = m_blockchain.size();
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::check_genesis(const crypto::hash& genesis_hash) {
|
||||
std::string what("Genesis block missmatch. You probably use wallet without testnet flag with blockchain from test network or vice versa");
|
||||
|
||||
THROW_WALLET_EXCEPTION_IF(genesis_hash != m_blockchain[0], error::wallet_internal_error, what);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::store()
|
||||
{
|
||||
bool r = tools::serialize_obj_to_file(*this, m_wallet_file);
|
||||
@@ -914,4 +937,16 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::generate_genesis(cryptonote::block& b) {
|
||||
if (m_testnet)
|
||||
{
|
||||
cryptonote::generate_genesis_block(b, config::testnet::GENESIS_TX, config::testnet::GENESIS_NONCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
cryptonote::generate_genesis_block(b, config::GENESIS_TX, config::GENESIS_NONCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,9 +80,9 @@ namespace tools
|
||||
|
||||
class wallet2
|
||||
{
|
||||
wallet2(const wallet2&) : m_run(true), m_callback(0) {};
|
||||
wallet2(const wallet2&) : m_run(true), m_callback(0), m_testnet(false) {};
|
||||
public:
|
||||
wallet2() : m_run(true), m_callback(0) {};
|
||||
wallet2(bool testnet = false) : m_run(true), m_callback(0), m_testnet(testnet) {};
|
||||
struct transfer_details
|
||||
{
|
||||
uint64_t m_block_height;
|
||||
@@ -158,6 +158,8 @@ namespace tools
|
||||
void refresh(uint64_t start_height, size_t & blocks_fetched, bool& received_money);
|
||||
bool refresh(size_t & blocks_fetched, bool& received_money, bool& ok);
|
||||
|
||||
bool testnet() { return m_testnet; }
|
||||
|
||||
uint64_t balance();
|
||||
uint64_t unlocked_balance();
|
||||
template<typename T>
|
||||
@@ -209,6 +211,8 @@ namespace tools
|
||||
bool prepare_file_names(const std::string& file_path);
|
||||
void process_unconfirmed(const cryptonote::transaction& tx);
|
||||
void add_unconfirmed_tx(const cryptonote::transaction& tx, uint64_t change_amount);
|
||||
void generate_genesis(cryptonote::block& b);
|
||||
void check_genesis(const crypto::hash& genesis_hash); //throws
|
||||
|
||||
cryptonote::account_base m_account;
|
||||
std::string m_daemon_address;
|
||||
@@ -228,6 +232,7 @@ namespace tools
|
||||
std::atomic<bool> m_run;
|
||||
|
||||
i_wallet2_callback* m_callback;
|
||||
bool m_testnet;
|
||||
};
|
||||
}
|
||||
BOOST_CLASS_VERSION(tools::wallet2, 7)
|
||||
@@ -357,7 +362,7 @@ namespace tools
|
||||
{
|
||||
THROW_WALLET_EXCEPTION_IF(0 == dt.amount, error::zero_destination);
|
||||
needed_money += dt.amount;
|
||||
THROW_WALLET_EXCEPTION_IF(needed_money < dt.amount, error::tx_sum_overflow, dsts, fee);
|
||||
THROW_WALLET_EXCEPTION_IF(needed_money < dt.amount, error::tx_sum_overflow, dsts, fee, m_testnet);
|
||||
}
|
||||
|
||||
// randomly select inputs for transaction
|
||||
@@ -462,7 +467,7 @@ namespace tools
|
||||
}
|
||||
|
||||
bool r = cryptonote::construct_tx(m_account.get_keys(), sources, splitted_dsts, extra, tx, unlock_time);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, splitted_dsts, unlock_time);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, splitted_dsts, unlock_time, m_testnet);
|
||||
THROW_WALLET_EXCEPTION_IF(m_upper_transaction_size_limit <= get_object_blobsize(tx), error::tx_too_big, tx, m_upper_transaction_size_limit);
|
||||
|
||||
std::string key_images;
|
||||
|
||||
@@ -376,11 +376,18 @@ namespace tools
|
||||
typedef std::vector<cryptonote::tx_source_entry> sources_t;
|
||||
typedef std::vector<cryptonote::tx_destination_entry> destinations_t;
|
||||
|
||||
explicit tx_not_constructed(std::string&& loc, const sources_t& sources, const destinations_t& destinations, uint64_t unlock_time)
|
||||
: transfer_error(std::move(loc), "transaction was not constructed")
|
||||
, m_sources(sources)
|
||||
, m_destinations(destinations)
|
||||
, m_unlock_time(unlock_time)
|
||||
explicit tx_not_constructed(
|
||||
std::string && loc
|
||||
, sources_t const & sources
|
||||
, destinations_t const & destinations
|
||||
, uint64_t unlock_time
|
||||
, bool testnet
|
||||
)
|
||||
: transfer_error {std::move(loc), "transaction was not constructed"}
|
||||
, m_sources {sources}
|
||||
, m_destinations {destinations}
|
||||
, m_unlock_time {unlock_time}
|
||||
, m_testnet {testnet}
|
||||
{
|
||||
}
|
||||
|
||||
@@ -414,7 +421,7 @@ namespace tools
|
||||
for (size_t i = 0; i < m_destinations.size(); ++i)
|
||||
{
|
||||
const cryptonote::tx_destination_entry& dst = m_destinations[i];
|
||||
ss << "\n " << i << ": " << cryptonote::get_account_address_as_str(dst.addr) << " " <<
|
||||
ss << "\n " << i << ": " << cryptonote::get_account_address_as_str(m_testnet, dst.addr) << " " <<
|
||||
cryptonote::print_money(dst.amount);
|
||||
}
|
||||
|
||||
@@ -427,6 +434,7 @@ namespace tools
|
||||
sources_t m_sources;
|
||||
destinations_t m_destinations;
|
||||
uint64_t m_unlock_time;
|
||||
bool m_testnet;
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
struct tx_rejected : public transfer_error
|
||||
@@ -457,10 +465,16 @@ namespace tools
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
struct tx_sum_overflow : public transfer_error
|
||||
{
|
||||
explicit tx_sum_overflow(std::string&& loc, const std::vector<cryptonote::tx_destination_entry>& destinations, uint64_t fee)
|
||||
: transfer_error(std::move(loc), "transaction sum + fee exceeds " + cryptonote::print_money(std::numeric_limits<uint64_t>::max()))
|
||||
, m_destinations(destinations)
|
||||
, m_fee(fee)
|
||||
explicit tx_sum_overflow(
|
||||
std::string && loc
|
||||
, const std::vector<cryptonote::tx_destination_entry>& destinations
|
||||
, uint64_t fee
|
||||
, bool testnet
|
||||
)
|
||||
: transfer_error {std::move(loc), "transaction sum + fee exceeds " + cryptonote::print_money(std::numeric_limits<uint64_t>::max())}
|
||||
, m_destinations {destinations}
|
||||
, m_fee {fee}
|
||||
, m_testnet {testnet}
|
||||
{
|
||||
}
|
||||
|
||||
@@ -475,7 +489,7 @@ namespace tools
|
||||
", destinations:";
|
||||
for (const auto& dst : m_destinations)
|
||||
{
|
||||
ss << '\n' << cryptonote::print_money(dst.amount) << " -> " << cryptonote::get_account_address_as_str(dst.addr);
|
||||
ss << '\n' << cryptonote::print_money(dst.amount) << " -> " << cryptonote::get_account_address_as_str(m_testnet, dst.addr);
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
@@ -483,6 +497,7 @@ namespace tools
|
||||
private:
|
||||
std::vector<cryptonote::tx_destination_entry> m_destinations;
|
||||
uint64_t m_fee;
|
||||
bool m_testnet;
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
struct tx_too_big : public transfer_error
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace tools
|
||||
{
|
||||
try
|
||||
{
|
||||
res.address = m_wallet.get_account().get_public_address_str();
|
||||
res.address = m_wallet.get_account().get_public_address_str(m_wallet.testnet());
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
@@ -118,7 +118,7 @@ namespace tools
|
||||
for (auto it = destinations.begin(); it != destinations.end(); it++)
|
||||
{
|
||||
cryptonote::tx_destination_entry de;
|
||||
if(!get_account_address_from_str(de.addr, it->address))
|
||||
if(!get_account_address_from_str(de.addr, m_wallet.testnet(), it->address))
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS;
|
||||
er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + it->address;
|
||||
|
||||
@@ -1,3 +1,33 @@
|
||||
# Copyright (c) 2014, 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
|
||||
|
||||
add_definitions(-DSTATICLIB)
|
||||
|
||||
add_subdirectory(gtest)
|
||||
@@ -31,7 +61,7 @@ add_executable(unit_tests ${UNIT_TESTS})
|
||||
add_executable(net_load_tests_clt net_load_tests/clt.cpp)
|
||||
add_executable(net_load_tests_srv net_load_tests/srv.cpp)
|
||||
|
||||
target_link_libraries(core_proxy cryptonote_core common crypto upnpc-static ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||
target_link_libraries(core_proxy cryptonote_core common crypto ${UPNP_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||
target_link_libraries(coretests cryptonote_core common crypto ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||
target_link_libraries(difficulty-tests cryptonote_core)
|
||||
target_link_libraries(functional_tests cryptonote_core wallet common crypto ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||
|
||||
@@ -104,7 +104,10 @@ int main(int argc, char* argv[])
|
||||
//create objects and link them
|
||||
tests::proxy_core pr_core;
|
||||
cryptonote::t_cryptonote_protocol_handler<tests::proxy_core> cprotocol(pr_core, NULL);
|
||||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<tests::proxy_core> > p2psrv(cprotocol);
|
||||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<tests::proxy_core> > p2psrv {
|
||||
cprotocol
|
||||
, std::move(config::NETWORK_ID)
|
||||
};
|
||||
cprotocol.set_p2p_endpoint(&p2psrv);
|
||||
//pr_core.set_cryptonote_protocol(&cprotocol);
|
||||
//daemon_cmmands_handler dch(p2psrv);
|
||||
@@ -112,7 +115,7 @@ int main(int argc, char* argv[])
|
||||
//initialize objects
|
||||
|
||||
LOG_PRINT_L0("Initializing p2p server...");
|
||||
bool res = p2psrv.init(vm);
|
||||
bool res = p2psrv.init(vm, false);
|
||||
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize p2p server.");
|
||||
LOG_PRINT_L0("P2p server initialized OK");
|
||||
|
||||
@@ -224,7 +227,7 @@ bool tests::proxy_core::get_blockchain_top(uint64_t& height, crypto::hash& top_i
|
||||
}
|
||||
|
||||
bool tests::proxy_core::init(const boost::program_options::variables_map& /*vm*/) {
|
||||
generate_genesis_block(m_genesis);
|
||||
generate_genesis_block(m_genesis, config::GENESIS_TX, config::GENESIS_NONCE);
|
||||
crypto::hash h = get_block_hash(m_genesis);
|
||||
add_block(h, get_block_longhash(m_genesis, 0), m_genesis, block_to_blob(m_genesis));
|
||||
return true;
|
||||
|
||||
@@ -487,7 +487,7 @@ inline bool do_replay_events(std::vector<test_event_entry>& events)
|
||||
|
||||
cryptonote::cryptonote_protocol_stub pr; //TODO: stub only for this kind of test, make real validation of relayed objects
|
||||
cryptonote::core c(&pr);
|
||||
if (!c.init(vm))
|
||||
if (!c.init(vm, false))
|
||||
{
|
||||
std::cout << concolor::magenta << "Failed to init core" << concolor::normal << std::endl;
|
||||
return false;
|
||||
|
||||
@@ -54,7 +54,7 @@ bool test_transaction_generation_and_ring_signature()
|
||||
account_base miner_acc6;
|
||||
miner_acc6.generate();
|
||||
|
||||
std::string add_str = miner_acc3.get_public_address_str();
|
||||
std::string add_str = miner_acc3.get_public_address_str(false);
|
||||
|
||||
|
||||
account_base rv_acc;
|
||||
@@ -150,7 +150,7 @@ bool test_block_creation()
|
||||
uint64_t vszs[] = {80,476,476,475,475,474,475,474,474,475,472,476,476,475,475,474,475,474,474,475,472,476,476,475,475,474,475,474,474,475,9391,476,476,475,475,474,475,8819,8301,475,472,4302,5316,14347,16620,19583,19403,19728,19442,19852,19015,19000,19016,19795,19749,18087,19787,19704,19750,19267,19006,19050,19445,19407,19522,19546,19788,19369,19486,19329,19370,18853,19600,19110,19320,19746,19474,19474,19743,19494,19755,19715,19769,19620,19368,19839,19532,23424,28287,30707};
|
||||
std::vector<uint64_t> szs(&vszs[0], &vszs[90]);
|
||||
account_public_address adr;
|
||||
bool r = get_account_address_from_str(adr, "0099be99c70ef10fd534c43c88e9d13d1c8853213df7e362afbec0e4ee6fec4948d0c190b58f4b356cd7feaf8d9d0a76e7c7e5a9a0a497a6b1faf7a765882dd08ac2");
|
||||
bool r = get_account_address_from_str(adr, false, "0099be99c70ef10fd534c43c88e9d13d1c8853213df7e362afbec0e4ee6fec4948d0c190b58f4b356cd7feaf8d9d0a76e7c7e5a9a0a497a6b1faf7a765882dd08ac2");
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to import");
|
||||
block b;
|
||||
r = construct_miner_tx(90, epee::misc_utils::median(szs), 3553616528562147, 33094, 10000000, adr, b.miner_tx, blobdata(), 11);
|
||||
|
||||
@@ -54,7 +54,7 @@ TEST(Transfers, Transfers)
|
||||
miner.generate();
|
||||
ASSERT_TRUE(miner.init());
|
||||
ASSERT_TRUE(miner.store("miner.b2wallet"));
|
||||
cout << "miner: " << miner.get_account().get_public_address_str() << endl;
|
||||
cout << "miner: " << miner.get_account().get_public_address_str(false) << endl;
|
||||
|
||||
for (int i = 0; i < ACCS; i++) {
|
||||
ostringstream s;
|
||||
@@ -69,7 +69,7 @@ TEST(Transfers, Transfers)
|
||||
|
||||
{
|
||||
COMMAND_RPC_START_MINE::request req;
|
||||
req.miner_address = miner.get_account().get_public_address_str();
|
||||
req.miner_address = miner.get_account().get_public_address_str(false);
|
||||
req.threads_count = 1;
|
||||
COMMAND_RPC_START_MINE::response res;
|
||||
bool r = net_utils::http::invoke_http_json_remote_command(daemon_address + "/start_mine", req, res, http_client);
|
||||
|
||||
@@ -37,6 +37,12 @@ using namespace epee;
|
||||
#include "wallet/wallet2.h"
|
||||
using namespace cryptonote;
|
||||
|
||||
namespace
|
||||
{
|
||||
uint64_t const TEST_FEE = 5000000000; // 5 * 10^9
|
||||
uint64_t const TEST_DUST_THRESHOLD = 5000000000; // 5 * 10^9
|
||||
}
|
||||
|
||||
std::string generate_random_wallet_name()
|
||||
{
|
||||
std::stringstream ss;
|
||||
@@ -79,7 +85,7 @@ bool do_send_money(tools::wallet2& w1, tools::wallet2& w2, size_t mix_in_factor,
|
||||
try
|
||||
{
|
||||
tools::wallet2::pending_tx ptx;
|
||||
w1.transfer(dsts, mix_in_factor, 0, DEFAULT_FEE, std::vector<uint8_t>(), tools::detail::null_split_strategy, tools::tx_dust_policy(DEFAULT_FEE), tx, ptx);
|
||||
w1.transfer(dsts, mix_in_factor, 0, TEST_FEE, std::vector<uint8_t>(), tools::detail::null_split_strategy, tools::tx_dust_policy(TEST_DUST_THRESHOLD), tx, ptx);
|
||||
w1.commit_tx(ptx);
|
||||
return true;
|
||||
}
|
||||
@@ -145,8 +151,8 @@ bool transactions_flow_test(std::string& working_folder,
|
||||
w2.init(daemon_addr_b);
|
||||
|
||||
LOG_PRINT_GREEN("Using wallets: " << ENDL
|
||||
<< "Source: " << w1.get_account().get_public_address_str() << ENDL << "Path: " << working_folder + "/" + path_source_wallet << ENDL
|
||||
<< "Target: " << w2.get_account().get_public_address_str() << ENDL << "Path: " << working_folder + "/" + path_terget_wallet, LOG_LEVEL_1);
|
||||
<< "Source: " << w1.get_account().get_public_address_str(false) << ENDL << "Path: " << working_folder + "/" + path_source_wallet << ENDL
|
||||
<< "Target: " << w2.get_account().get_public_address_str(false) << ENDL << "Path: " << working_folder + "/" + path_terget_wallet, LOG_LEVEL_1);
|
||||
|
||||
//lets do some money
|
||||
epee::net_utils::http::http_simple_client http_client;
|
||||
@@ -157,7 +163,7 @@ bool transactions_flow_test(std::string& working_folder,
|
||||
|
||||
COMMAND_RPC_START_MINING::request daemon_req = AUTO_VAL_INIT(daemon_req);
|
||||
COMMAND_RPC_START_MINING::response daemon_rsp = AUTO_VAL_INIT(daemon_rsp);
|
||||
daemon_req.miner_address = w1.get_account().get_public_address_str();
|
||||
daemon_req.miner_address = w1.get_account().get_public_address_str(false);
|
||||
daemon_req.threads_count = 9;
|
||||
r = net_utils::invoke_http_json_remote_command2(daemon_addr_a + "/start_mining", daemon_req, daemon_rsp, http_client, 10000);
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to get getrandom_outs");
|
||||
@@ -185,7 +191,7 @@ bool transactions_flow_test(std::string& working_folder,
|
||||
BOOST_FOREACH(tools::wallet2::transfer_details& td, incoming_transfers)
|
||||
{
|
||||
cryptonote::transaction tx_s;
|
||||
bool r = do_send_money(w1, w1, 0, td.m_tx.vout[td.m_internal_output_index].amount - DEFAULT_FEE, tx_s, 50);
|
||||
bool r = do_send_money(w1, w1, 0, td.m_tx.vout[td.m_internal_output_index].amount - TEST_FEE, tx_s, 50);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to send starter tx " << get_transaction_hash(tx_s));
|
||||
LOG_PRINT_GREEN("Starter transaction sent " << get_transaction_hash(tx_s), LOG_LEVEL_0);
|
||||
if(++count >= FIRST_N_TRANSFERS)
|
||||
@@ -213,7 +219,7 @@ bool transactions_flow_test(std::string& working_folder,
|
||||
for(i = 0; i != transactions_count; i++)
|
||||
{
|
||||
uint64_t amount_to_tx = (amount_to_transfer - transfered_money) > transfer_size ? transfer_size: (amount_to_transfer - transfered_money);
|
||||
while(w1.unlocked_balance() < amount_to_tx + DEFAULT_FEE)
|
||||
while(w1.unlocked_balance() < amount_to_tx + TEST_FEE)
|
||||
{
|
||||
misc_utils::sleep_no_w(1000);
|
||||
LOG_PRINT_L0("not enough money, waiting for cashback or mining");
|
||||
|
||||
@@ -44,7 +44,11 @@
|
||||
# include <sys/types.h>
|
||||
# include <sys/wait.h>
|
||||
# include <unistd.h>
|
||||
# include <signal.h>
|
||||
#endif // GTEST_OS_LINUX
|
||||
#if GTEST_CAN_STREAM_RESULTS_
|
||||
# include <sys/socket.h>
|
||||
#endif // GTEST_CAN_STREAM_RESULTS_
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -188,6 +188,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#ifndef _WIN32_WCE
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
@@ -232,6 +233,9 @@
|
||||
# ifdef ANDROID
|
||||
# define GTEST_OS_LINUX_ANDROID 1
|
||||
# endif // ANDROID
|
||||
#elif defined __FreeBSD__
|
||||
# define GTEST_OS_LINUX 1
|
||||
# define GTEST_HAS_CLONE 0
|
||||
#elif defined __MVS__
|
||||
# define GTEST_OS_ZOS 1
|
||||
#elif defined(__sun) && defined(__SVR4)
|
||||
@@ -449,7 +453,7 @@
|
||||
// defining __GNUC__ and friends, but cannot compile GCC's tuple
|
||||
// implementation. MSVC 2008 (9.0) provides TR1 tuple in a 323 MB
|
||||
// Feature Pack download, which we cannot assume the user has.
|
||||
# if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000)) \
|
||||
# if (defined(__GNUC__) && !defined(__CUDACC__) && !defined(_LIBCPP_VERSION) && (GTEST_GCC_VER_ >= 40000)) \
|
||||
|| _MSC_VER >= 1600
|
||||
# define GTEST_USE_OWN_TR1_TUPLE 0
|
||||
# else
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
void set_process_affinity(int core)
|
||||
{
|
||||
#if defined (__APPLE__)
|
||||
#if defined (__APPLE__) || defined(__FreeBSD__)
|
||||
return;
|
||||
#elif defined(BOOST_WINDOWS)
|
||||
DWORD_PTR mask = 1;
|
||||
@@ -62,7 +62,7 @@ void set_process_affinity(int core)
|
||||
|
||||
void set_thread_high_priority()
|
||||
{
|
||||
#if defined(__APPLE__)
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||||
return;
|
||||
#elif defined(BOOST_WINDOWS)
|
||||
::SetPriorityClass(::GetCurrentProcess(), HIGH_PRIORITY_CLASS);
|
||||
|
||||
@@ -473,14 +473,14 @@ TEST(get_account_address_as_str, works_correctly)
|
||||
{
|
||||
cryptonote::account_public_address addr;
|
||||
ASSERT_TRUE(serialization::parse_binary(test_serialized_keys, addr));
|
||||
std::string addr_str = cryptonote::get_account_address_as_str(addr);
|
||||
std::string addr_str = cryptonote::get_account_address_as_str(false, addr);
|
||||
ASSERT_EQ(addr_str, test_keys_addr_str);
|
||||
}
|
||||
|
||||
TEST(get_account_address_from_str, handles_valid_address)
|
||||
{
|
||||
cryptonote::account_public_address addr;
|
||||
ASSERT_TRUE(cryptonote::get_account_address_from_str(addr, test_keys_addr_str));
|
||||
ASSERT_TRUE(cryptonote::get_account_address_from_str(addr, false, test_keys_addr_str));
|
||||
|
||||
std::string blob;
|
||||
ASSERT_TRUE(serialization::dump_binary(addr, blob));
|
||||
@@ -493,7 +493,7 @@ TEST(get_account_address_from_str, fails_on_invalid_address_format)
|
||||
std::string addr_str = test_keys_addr_str;
|
||||
addr_str[0] = '0';
|
||||
|
||||
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, addr_str));
|
||||
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, false, addr_str));
|
||||
}
|
||||
|
||||
TEST(get_account_address_from_str, fails_on_invalid_address_prefix)
|
||||
@@ -501,39 +501,39 @@ TEST(get_account_address_from_str, fails_on_invalid_address_prefix)
|
||||
std::string addr_str = base58::encode_addr(0, test_serialized_keys);
|
||||
|
||||
cryptonote::account_public_address addr;
|
||||
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, addr_str));
|
||||
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, false, addr_str));
|
||||
}
|
||||
|
||||
TEST(get_account_address_from_str, fails_on_invalid_address_content)
|
||||
{
|
||||
std::string addr_str = base58::encode_addr(CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX, test_serialized_keys.substr(1));
|
||||
std::string addr_str = base58::encode_addr(config::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX, test_serialized_keys.substr(1));
|
||||
|
||||
cryptonote::account_public_address addr;
|
||||
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, addr_str));
|
||||
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, false, addr_str));
|
||||
}
|
||||
|
||||
TEST(get_account_address_from_str, fails_on_invalid_address_spend_key)
|
||||
{
|
||||
std::string serialized_keys_copy = test_serialized_keys;
|
||||
serialized_keys_copy[0] = '\0';
|
||||
std::string addr_str = base58::encode_addr(CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX, serialized_keys_copy);
|
||||
std::string addr_str = base58::encode_addr(config::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX, serialized_keys_copy);
|
||||
|
||||
cryptonote::account_public_address addr;
|
||||
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, addr_str));
|
||||
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, false, addr_str));
|
||||
}
|
||||
|
||||
TEST(get_account_address_from_str, fails_on_invalid_address_view_key)
|
||||
{
|
||||
std::string serialized_keys_copy = test_serialized_keys;
|
||||
serialized_keys_copy.back() = '\x01';
|
||||
std::string addr_str = base58::encode_addr(CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX, serialized_keys_copy);
|
||||
std::string addr_str = base58::encode_addr(config::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX, serialized_keys_copy);
|
||||
|
||||
cryptonote::account_public_address addr;
|
||||
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, addr_str));
|
||||
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, false, addr_str));
|
||||
}
|
||||
|
||||
TEST(get_account_address_from_str, parses_old_address_format)
|
||||
{
|
||||
cryptonote::account_public_address addr;
|
||||
ASSERT_TRUE(cryptonote::get_account_address_from_str(addr, "002391bbbb24dea6fd95232e97594a27769d0153d053d2102b789c498f57a2b00b69cd6f2f5c529c1660f2f4a2b50178d6640c20ce71fe26373041af97c5b10236fc"));
|
||||
ASSERT_TRUE(cryptonote::get_account_address_from_str(addr, false, "002391bbbb24dea6fd95232e97594a27769d0153d053d2102b789c498f57a2b00b69cd6f2f5c529c1660f2f4a2b50178d6640c20ce71fe26373041af97c5b10236fc"));
|
||||
}
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
#include "common/util.h"
|
||||
#include "cryptonote_core/cryptonote_format_utils.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
uint64_t const TEST_FEE = 5000000000; // 5 * 10^9
|
||||
}
|
||||
|
||||
TEST(parse_tx_extra, handles_empty_extra)
|
||||
{
|
||||
@@ -135,7 +139,7 @@ TEST(parse_and_validate_tx_extra, is_valid_tx_extra_parsed)
|
||||
cryptonote::account_base acc;
|
||||
acc.generate();
|
||||
cryptonote::blobdata b = "dsdsdfsdfsf";
|
||||
ASSERT_TRUE(cryptonote::construct_miner_tx(0, 0, 10000000000000, 1000, DEFAULT_FEE, acc.get_keys().m_account_address, tx, b, 1));
|
||||
ASSERT_TRUE(cryptonote::construct_miner_tx(0, 0, 10000000000000, 1000, TEST_FEE, acc.get_keys().m_account_address, tx, b, 1));
|
||||
crypto::public_key tx_pub_key = cryptonote::get_tx_pub_key_from_extra(tx);
|
||||
ASSERT_NE(tx_pub_key, cryptonote::null_pkey);
|
||||
}
|
||||
@@ -145,7 +149,7 @@ TEST(parse_and_validate_tx_extra, fails_on_big_extra_nonce)
|
||||
cryptonote::account_base acc;
|
||||
acc.generate();
|
||||
cryptonote::blobdata b(TX_EXTRA_NONCE_MAX_COUNT + 1, 0);
|
||||
ASSERT_FALSE(cryptonote::construct_miner_tx(0, 0, 10000000000000, 1000, DEFAULT_FEE, acc.get_keys().m_account_address, tx, b, 1));
|
||||
ASSERT_FALSE(cryptonote::construct_miner_tx(0, 0, 10000000000000, 1000, TEST_FEE, acc.get_keys().m_account_address, tx, b, 1));
|
||||
}
|
||||
TEST(parse_and_validate_tx_extra, fails_on_wrong_size_in_extra_nonce)
|
||||
{
|
||||
|
||||
50
utils/gpg_keys/fluffypony.asc
Normal file
50
utils/gpg_keys/fluffypony.asc
Normal file
@@ -0,0 +1,50 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1
|
||||
|
||||
mQENBFFi2TMBCACgt1CvPYw/3A5ygzQq4QEqBnh1Td7h3Hfd/SBdZDuZHypO8raH
|
||||
M/60m3kql50olpzlArFSIhgOIIoGyjqkfNqnqw2QHTgh1eB2zKYNsIIyKqyipB4B
|
||||
OEondI/0r5tJlLBFcVK5JTd3KzdbgXDNmSo2ahB0mW0hxNyegb7L5RQIzkjZnuV5
|
||||
uUUdWB7FZ4WjLDfRB1GaLq+4pLpCJghHBU/qF7hJn7RDwoybv6thTnsDp7M6bmu5
|
||||
DYSp2rfpLfPlm7dcvBvo9PuOURad3QsQEYGGqK/Bdqg+CymyiH1/yapKRCeWQhf8
|
||||
Bl5VYzuOZ085PDXRfZlqmohCHvD1hzMF8rJ3ABEBAAG0IFJpY2NhcmRvIFNwYWdu
|
||||
aSA8cmljQHNwYWduaS5uZXQ+iQE3BBMBCgAhBQJRYtkzAhsvBQsJCAcDBRUKCQgL
|
||||
BRYCAwEAAh4BAheAAAoJEHRVxePAzc65uFEH/1shu6eKlyYzkdcs/wxOQfNuyGhF
|
||||
xM5goXeCH9TUTO3vohxgIjK3/cttK8QRf8XudnqBDhMvOPKAiwRKaZvAhB/uekah
|
||||
6QJCT5dg2R8ein7TAanyIP3MQ5F8gVx1ijdrWiXNs5VHoE+NJ2BghOvnIBrE21sd
|
||||
WwMMsgKnToM72cbMJiZgmS9jrO60NEmVYLuV6gcyW2x4/yKxWXr4svbtBJ1asvSa
|
||||
qSJTQAD+QRFGH/fwuQcURq4ZX937HomsUejTy1ufP6hjkblwKgKV/Jwek3VBLtZ4
|
||||
anxAkhjS+Ey1Ihg+1lWCyIhl9QUiuAhI//b1WnLWXwYblVfyNfzRfyWXl1GJAYEE
|
||||
EwEIAGsFAlPEeO4FgwlmAYBeFIAAAAAAFQBAYmxvY2toYXNoQGJpdGNvaW4ub3Jn
|
||||
MDAwMDAwMDAwMDAwMDAwMDIzODY2NTRiNGRmMmU5MDY0Mzc5ZTNmOGU0Y2JmZGE4
|
||||
ZGQ3Mzg2ZTI0NzA4OTc2ZQAKCRB/qxFCZ+T6BHwTCACPg/bl9xRyerLUwWE4Ejm0
|
||||
fuRnEtw+C3I1eM9ItIcXkKlqdR1PP6zxwU3wTIQweh3y0wUGlIyASqTkd2F36all
|
||||
E1g+c4Cs0wlArL/obDFFCoUX9+xxL5oDaVVH0FT6Tv7A1220j+1QItjUksRPzp4v
|
||||
+P786UiZdHkdmwMUiW8kH8+niJSyA26sFLGNXnCIze3zpzPHe2DfzkNewnGNJimY
|
||||
KjThjD5sqFkeINM5xipC4onA3cP9E0iD1qALS4kYnJ6KR+CmZmEmi8ETtsoPyIy4
|
||||
Dj1tR3HF2x5o5dgyWZtTD2ZJ3iP/zqfdahIYCCW4x5mKbiLtuyN7WjhJAC/MlAb7
|
||||
iQEcBBABCAAGBQJTrsKSAAoJEJ8xgCx5ZC8ldgcH/1007gKaplGwFG00a6gAcqJe
|
||||
wrKK6j5bHMkS5c5dCJO9gq130AbBEre6hWH9I05XadnRcpKw4OhtPqXbAOA4ZkJv
|
||||
v9bGSySHiqA45GA9kke8kH91uomVQIXVr9ze8tPYTxMqu8CCDJukGTmIcGasjz/h
|
||||
Lflem71nmafSlLDirf/njbKjZNKsKJzfDgWnoBy/NShWghQ2j6Eouj2XCgvOebmc
|
||||
oRVWaTCJsZaa+xMdcx5n4Z1f4dTwdZKc+1lGZWczmrizosQ477A/8eJjmlv9+9mb
|
||||
c4N10EHXo3ojZierXueqoqXiKGfTGnVkc3VcG4gulMNFD2QtVB06O44hAOKNc5m5
|
||||
AQ0EUWLZMwEIAMPF4uAI9Vld6rnbJTNLWzEVEn1Ay9yVR1IL+GHKJ2D4jfP/OFoP
|
||||
soFmzVt5lhTa8Hn0/TxuAXdDxN1uyA+ZJmxoVzWxaz4ZjBgc+ypDktUF7tcSL46C
|
||||
JeioCU4O90P4J+6UBt/7KFTfP7UBGqt0c4f0xq5lSUaXhpPNBzB8m5oR5/cCYL1a
|
||||
6rNBCoORiC6GCVKXyF6jBgW0itjT5wCrFhtINy9CPSm3YlwxmwxOwxPutwuWfl07
|
||||
wuhH8CccWo2aTPJ3AWJcDg955D+Gq3ZDKP++EsdOn6ToZ5FKjiq1yXozrJn8OPLT
|
||||
4wb2n6WI+DqnlwKd5TkxBHCVOKOoHGYL6N8AEQEAAYkCPgQYAQoACQUCUWLZMwIb
|
||||
LgEpCRB0VcXjwM3OucBdIAQZAQoABgUCUWLZMwAKCRBVQy3zHM1PzXwzCACKdHE0
|
||||
k1DC6JHlpla0M1L/YahRuNqwiTSYW+hjmOha0m7geLt16CapEqJALhnBXY5h8DLN
|
||||
PaS7qifLnWS2bqOvcxgzALqRynFsNhzfxL++QVL7F2yzKSE/zQ0oAMaJo8VaxZWI
|
||||
VR8E/wwzaWuw93CJ2B6oaJn/urzGJWdkVbLnsOXieeDL3o1aheDZtjr+F6Cx/W0+
|
||||
5LBXCKRro63VTMjCjjBt2fTzdnwx1uVSpiIJAH3G8WCEW+J81wjWJLIniCtSd512
|
||||
jd0Bhb7BjNRmrutKEln921WMBMu7SepCAF3PIxpPQPo/H1AVqRXU4DW278LWMY+W
|
||||
X/bGfjBCUhcM8nEOETsH/jywj5YkR9hivViaZRzbILD2qEeeBWSbf8RNDkB/YS7W
|
||||
WRdA7FUSCh4IBr+tQURfWLKKz/vwu1iP+BD1ywT8FtRu+tGOlYuuDX2KuIPiEN2y
|
||||
KXmJCgcWhhqLyuWjl67gR5yQWrnJPrQ7s3sXKLvDsNdCH4Hd9OumV0lcYR5Hr0MT
|
||||
2lKb18ljJax7EoaoZYVJuxvPhssp/31cRZWGS3l0Dyhj+SJW/PsbAXlBXUWlJzSk
|
||||
tjLXdWWtTXXcGF3UDnCjsMN4jV6oqbHN3YK4ZrZUNSm/ZZjgoU3Er6P0V5tFmCLa
|
||||
zltmy11aIY4E8FZOzyaPKDGLkQwO7B2QK6J9sMlB6Sk=
|
||||
=V86E
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
30
utils/gpg_keys/mikezackles.asc
Normal file
30
utils/gpg_keys/mikezackles.asc
Normal file
@@ -0,0 +1,30 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v2
|
||||
|
||||
mQENBFOZuBcBCAC58b89hQieAu57Krj7jqBQkBUdm2tDbwOoCVJK9jBBvzrxlBsc
|
||||
yCMTnl7Vs3oAyQ79fnNi88lH9mwUHbAzt6QlkVPQOwDu2DMTUPDAd9b1Op2nf1g3
|
||||
a5MtPc2R2NDyAWbZTVk/tvode9/SgKU0vmurTuKtWOxkkNLiad2milVay3o1AfM6
|
||||
HbaZsnP//lx3lubkfM93sgoqsBRSXtT8BGifFKWJ6jIkm5yqVmqETDfxY+gfIs3P
|
||||
XMJnpXxg/WGUwRO9lfAT8YLfqzIh1BhqqNoxFI2RHTiIYHXVYJ9u4xjYUTM8F+lc
|
||||
/PhIouuXgPS9HCiWTzog0JsAHM4mfHZ4GyRxABEBAAG0KFphY2hhcnkgTWljaGFl
|
||||
bHMgPG1pa2V6YWNrbGVzQGdtYWlsLmNvbT6JATkEEwECACMFAlOZuBcCGwMHCwkI
|
||||
BwMCAQYVCAIJCgsEFgIDAQIeAQIXgAAKCRBAHd9kV5Gk0WgVB/4qLz4IhZqzR720
|
||||
/JIyj3Fpxkn5TCzAupaWMRz8oCL6ASBN+56FofVxh7Mua7Cxm9oHmnC5AjU788j6
|
||||
ATE8wV+DzPrl+YfcCnY1FLvkZ31US9XIpmA8V3/fUlrYOGS5HSoWvsy5mt9OX5sR
|
||||
P4gn35bY5cJbNSc9yz86YjLkzaXVGZ6o/qIKatdgMWRqAdYKA0ALu1dptjF026xG
|
||||
yTkjqK3RhwBMPVTTpreTuc0OpHWBjT0POmFnQkK7rRcIU4B7+9oPiRgfuCRzEzPP
|
||||
4nfuj+rczyZ3Hl07P1055Pk1q4LZ3knJzSRxw6FLw39Zby+eC252Eq7yWllWvSSD
|
||||
sNb611WBuQENBFOZuBcBCADcpyVCOX72KkMdJckMpYw5TSofbqXL0N0UAIrMk+pP
|
||||
rfvNQsJWiQATJLeMEoucUPaWYZ9Ysw97I9wGQovSUAMe/7/FJDllahvEDHfQp+oq
|
||||
PEjK+UA0xoA5fCn9rdpha8va9kSsHTISdhjwwpojxHP4b6zCYJlmuq3teidtNbTv
|
||||
c/M3aCWwJfKsK8Hk9H9fPZEoAcFrfzqspKyQi0a0RFm5/VSa6njxwZcjrRRSoJ9I
|
||||
uDAtuXl9avkD7LgmcSfnBdj+iCdUQ/YL/ZFHdaxdAouMfiotUOVoBCBaO4gYvIHk
|
||||
nMw5ArB21Vw1gAks1vHz480SYta5KrxUavQcYUmstvG/ABEBAAGJAR8EGAECAAkF
|
||||
AlOZuBcCGwwACgkQQB3fZFeRpNHlfAf/UryZMEhuOfcGjBca42dYZaTMjmOknZqq
|
||||
A2W5lG3PDaciEeWb94gFa3clhuS+AFL07+O69q3YHM2qRI4G6CBIKA20ezv2xLeP
|
||||
11bnKEORIoYauJ63UN7wAJ1U1UHP7R6X0EUuV+uZTxt+RLiSgar/SvfYhUrXKZ8b
|
||||
lCCsY3KQYm644QEesfTHsj3r/nQfM2sha4ZG9P7n5NAAlDwF3PfsB6fzc24uAGfm
|
||||
H2DUvymFODHSVkobityf87k4nk/yNYR/D7CkvjcPYfGawzHzpO2l+zKnGxJaim2u
|
||||
oqi0vJkk1ySytkX5DxanbnqLO/jLONrEZGpdFbO0710+tM4/7ScaXg==
|
||||
=WtIs
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
Reference in New Issue
Block a user