Compare commits

...

78 Commits

Author SHA1 Message Date
Riccardo Spagni
f3271e8f12 Merge pull request #141
b92a8b5 fix CMake for multiplatform versioning (Riccardo Spagni)
2014-09-15 20:18:40 +02:00
Riccardo Spagni
b92a8b53e0 fix CMake for multiplatform versioning 2014-09-15 20:15:26 +02:00
Riccardo Spagni
d0069112a3 Merge pull request #140
0214524 added mikezackles / Zachary Michaels gpg key (Riccardo Spagni)
2014-09-15 17:08:56 +02:00
Riccardo Spagni
0214524166 added mikezackles / Zachary Michaels gpg key 2014-09-15 16:56:54 +02:00
Riccardo Spagni
83276bf92d Merge pull request #139
72a80f6 fixed incorrect version reference (Riccardo Spagni)
95a2701 Change testnet prefix (Zachary Michaels)
120c84d Make P2P use the testnet data dir (Zachary Michaels)
2352565 Replace macro with equivalent function call (Zachary Michaels)
d033087 Separate testnet address prefix (Zachary Michaels)
ee1bacc Add testnet seed nodes (Zachary Michaels)
4a6eb0a Create testnet data dir if necessary (Zachary Michaels)
018e251 Separate testnet default data dir (Zachary Michaels)
3ef7f33 Add descriptions for RPC command line params (Zachary Michaels)
1e38a02 Add testnet genesis tx as output by CN reference (Zachary Michaels)
96eed84 Pass tx and nonce to genesis block constructor (Zachary Michaels)
257077a Separate network id for testnet (Zachary Michaels)
658b669 Separate rpc port for testnet (Zachary Michaels)
98ed9a4 Separate p2p port for testnet (Zachary Michaels)
fb4146f Reorganize testnet constants (Zachary Michaels)
79862ad Add testnet constants (Zachary Michaels)
07470fd Add testnet flag (Zachary Michaels)
32004a7 increase ABSTRACT_SERVER_SEND_QUE_MAX_COUNT to a more sane value (Riccardo Spagni)
2c0a87f additional README info on static builds and FreeBSD (Riccardo Spagni)
2014-09-15 16:46:21 +02:00
Riccardo Spagni
72a80f6213 fixed incorrect version reference 2014-09-15 15:58:22 +02:00
Zachary Michaels
95a2701ec5 Change testnet prefix 2014-09-15 15:55:07 +02:00
Zachary Michaels
120c84d04f Make P2P use the testnet data dir 2014-09-15 15:55:07 +02:00
Zachary Michaels
23525655fa Replace macro with equivalent function call
Also removed useless bool return
2014-09-15 15:55:07 +02:00
Zachary Michaels
d03308734b Separate testnet address prefix 2014-09-15 15:54:59 +02:00
Zachary Michaels
ee1bacc64f Add testnet seed nodes 2014-09-15 15:54:24 +02:00
Zachary Michaels
4a6eb0a016 Create testnet data dir if necessary 2014-09-15 15:54:24 +02:00
Zachary Michaels
018e251cc0 Separate testnet default data dir 2014-09-15 15:54:19 +02:00
Zachary Michaels
3ef7f33300 Add descriptions for RPC command line params 2014-09-15 15:53:50 +02:00
Zachary Michaels
1e38a02bb5 Add testnet genesis tx as output by CN reference 2014-09-15 15:53:50 +02:00
Zachary Michaels
96eed84aad Pass tx and nonce to genesis block constructor 2014-09-15 15:53:50 +02:00
Zachary Michaels
257077a96b Separate network id for testnet 2014-09-15 15:53:50 +02:00
Zachary Michaels
658b6690a3 Separate rpc port for testnet 2014-09-15 15:53:46 +02:00
Zachary Michaels
98ed9a41f7 Separate p2p port for testnet 2014-09-15 15:53:10 +02:00
Zachary Michaels
fb4146fa34 Reorganize testnet constants 2014-09-15 15:53:10 +02:00
Zachary Michaels
79862ad1de Add testnet constants 2014-09-15 15:53:10 +02:00
Zachary Michaels
07470fd400 Add testnet flag
Source: cryptonotefoundation
2014-09-15 15:53:01 +02:00
Riccardo Spagni
32004a756c increase ABSTRACT_SERVER_SEND_QUE_MAX_COUNT to a more sane value 2014-09-15 15:49:26 +02:00
Riccardo Spagni
2c0a87f2ac additional README info on static builds and FreeBSD 2014-09-15 15:49:26 +02:00
Riccardo Spagni
fdae09754e increase ABSTRACT_SERVER_SEND_QUE_MAX_COUNT to a more sane value 2014-09-15 15:41:07 +02:00
Riccardo Spagni
700b72c709 additional README info on static builds and FreeBSD 2014-09-15 15:41:07 +02:00
Riccardo Spagni
51011ed960 fix logic in tag check, AND -> OR
Signed-off-by: Riccardo Spagni <ric@spagni.net>
2014-09-15 08:24:32 +02:00
Riccardo Spagni
3129d51eb4 ignore tag check if we haven't pulled tags
Signed-off-by: Riccardo Spagni <ric@spagni.net>
2014-09-15 08:22:52 +02:00
Riccardo Spagni
f2937d15bd Merge branch 'master' of http://github.com/fluffypony/bitmonero 2014-09-15 08:18:34 +02:00
Riccardo Spagni
d97191d4f9 new Makefile target: release-static 2014-09-15 08:18:11 +02:00
Riccardo Spagni
8afbed4027 new Makefile target: release-static 2014-09-15 08:13:26 +02:00
Riccardo Spagni
5a3ce8a7dc FreeBSD static linking fixes 2014-09-15 08:08:03 +02:00
Riccardo Spagni
566d194c41 Merge branch 'master' of http://github.com/fluffypony/bitmonero 2014-09-14 14:13:09 +02:00
Riccardo Spagni
9e2ac5308a add gpg pubkeys to start enforcing signed commits 2014-09-14 14:12:53 +02:00
Riccardo Spagni
9c56b38b16 Merge pull request #136
bb2b606 fix incorrect error message (obvious cut and paste bug from upstream) (iamsmooth)
6b77e83 Change wallet to not try to extract tx public key when tx has no outputs (fixes 202612 tx format messages and is otherwise correct) (iamsmooth)
08205f0 output rng fix from boolberry (iamsmooth)
2014-09-13 10:24:39 +02:00
iamsmooth
bb2b606e91 fix incorrect error message (obvious cut and paste bug from upstream) 2014-09-13 08:04:05 +00:00
Riccardo Spagni
12c1b0922a add gpg pubkeys to start enforcing signed commits 2014-09-13 10:03:31 +02:00
iamsmooth
6b77e8358c Change wallet to not try to extract tx public key when tx has no outputs (fixes 202612 tx format messages and is otherwise correct) 2014-09-13 04:25:33 +00:00
iamsmooth
08205f01d9 output rng fix from boolberry 2014-09-12 22:57:32 +00:00
Riccardo Spagni
63f60b1777 Merge pull request #133 from fluffypony/master
fixed cmake variable matching
2014-09-12 13:30:14 +02:00
Riccardo Spagni
570b90eb43 fixed cmake variable matching 2014-09-12 13:27:30 +02:00
Riccardo Spagni
e7c52d94c0 Merge pull request #132 from fluffypony/master
versioning now includes the commit hash, or -final for tagged releases
2014-09-12 13:18:12 +02:00
Riccardo Spagni
aab57ba9cc Merge branch 'master' of http://github.com/fluffypony/bitmonero
Conflicts:
	src/daemon/daemon.cpp
2014-09-12 13:16:29 +02:00
Riccardo Spagni
8334ce0b24 versioning now includes the commit hash, or -final for tagged releases 2014-09-12 13:12:43 +02:00
Riccardo Spagni
446a7ddc49 always check git diff 2014-09-12 13:12:43 +02:00
Riccardo Spagni
ffaa78700c Merge pull request #129 from Jebes/master
Added documentation to varint.h and util.h
2014-09-12 13:12:07 +02:00
Riccardo Spagni
14b3b6ea02 versioning now includes the commit hash, or -final for tagged releases 2014-09-12 13:06:51 +02:00
Riccardo Spagni
dd51b03d87 always check git diff 2014-09-12 00:40:25 +02:00
jebes
a13e879251 HOW DO I ENGLISH? 2014-09-11 10:45:05 -04:00
jebes
f7900ccfc1 mispelled brief, corrected it 2014-09-11 10:36:39 -04:00
jebes
dfed3d39b6 Merge remote-tracking branch 'upstream/master' 2014-09-11 10:20:55 -04:00
jebes
9d6f9335d1 HOW DO I GIT? 2014-09-11 10:20:17 -04:00
jebes
a70bf86037 Documented varint 2014-09-11 10:14:05 -04:00
Riccardo Spagni
8779a6da39 Merge pull request #128 from fluffypony/master
fixed UPNP_LIBRARIES scope
2014-09-11 13:30:24 +02:00
fluffypony
b35c1e2491 fixed UPNP_LIBRARIES scope 2014-09-11 13:28:49 +02:00
Riccardo Spagni
6a70de32bf Merge pull request #127 from fluffypony/master
FreeBSD compatibility and default log level changes
2014-09-11 12:00:30 +02:00
fluffypony
a40d5c1847 cpu affinity fixes in performance tests for FreeBSD 2014-09-11 11:42:59 +02:00
fluffypony
afc61dda45 gtest patches for FreeBSD 2014-09-11 10:02:24 +02:00
fluffypony
3217ed39ae fixed upnp libs in tests cmake 2014-09-11 08:28:28 +02:00
fluffypony
d21cf293e1 added license to CMake 2014-09-11 08:25:07 +02:00
fluffypony
36c7ea9f77 more CMake tweaks to allow detection on OS X 2014-09-11 08:22:49 +02:00
fluffypony
8d8b47e69f more dynamic miniupnp fixes 2014-09-10 20:01:30 +02:00
fluffypony
59c0423eae miniupnpc includes fixed 2014-09-10 18:22:20 +02:00
fluffypony
7d01dad8f4 use external miniupnpc if available 2014-09-10 18:14:57 +02:00
fluffypony
81490d2aea miniupnpc changes for freebsd 2014-09-10 14:19:42 +02:00
fluffypony
ccb2ab2b7b mmap on FreeBSD doesn't have MAP_HUGETLB 2014-09-10 14:01:39 +02:00
fluffypony
110f110181 Include sys/time.h on BSD 2014-09-10 13:58:43 +02:00
fluffypony
a8d043b6dd replace ftime with gettimeofday on FreeBSD because lcompat is stupid 2014-09-10 13:55:39 +02:00
fluffypony
0e343ecfdf make FreeBSD use -lcompat till we can fix ftime() 2014-09-10 13:25:34 +02:00
jebes
c085e9294f commented util.h 2014-09-09 20:18:23 -04:00
fluffypony
266c639f4f more FreeBSD fixes 2014-09-09 14:49:13 +02:00
fluffypony
e1d31e0a8b malloc.h reference fixed for FreeBSD 2014-09-09 14:07:57 +02:00
fluffypony
5a65991480 exclude local miniupnpc for FreeBSD, install from ports instead 2014-09-09 14:03:42 +02:00
fluffypony
6afbdd9754 FreeBSD alloca.h reference fixed 2014-09-09 12:37:19 +02:00
fluffypony
4ba680f294 a few more error messages moved to log level 1 2014-09-09 12:28:16 +02:00
fluffypony
cf5a8b1d6c moved non-critical warnings and errors to log level 1 2014-09-09 11:32:00 +02:00
Riccardo Spagni
bf972c40fc Merge pull request #123 from fluffypony/master
build number increase after release
2014-09-07 08:38:54 +02:00
fluffypony
4290c78160 build number increase after release 2014-09-07 08:33:41 +02:00
66 changed files with 1506 additions and 659 deletions

16
.gitignore vendored
View File

@@ -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

View File

@@ -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)

View File

@@ -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; \

View File

@@ -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.

View File

@@ -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)

View File

@@ -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
{

View File

@@ -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;
}

View File

@@ -602,4 +602,4 @@ bool cp_server_impl<TProtocol>::is_stop_signal()
}
//-------------------------------------------------------------
}
}
}

View File

@@ -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
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------

View File

@@ -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
}
}
}
}

View File

@@ -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)

View File

@@ -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()

View File

@@ -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)

View File

@@ -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"};
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
};
}

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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 );

View File

@@ -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

View File

@@ -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));

View File

@@ -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;
}
}

View File

@@ -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);
}
//-----------------------------------------------------------------
}

View File

@@ -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; }

View File

@@ -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;

View File

@@ -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);
};

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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;
};
}

View File

@@ -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;
}

View File

@@ -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
}

View File

@@ -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";

View File

@@ -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;
};
}

View File

@@ -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...");

View File

@@ -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>());

View File

@@ -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()

View File

@@ -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

View File

@@ -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);
}
}
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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})

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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");

View File

@@ -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>

View File

@@ -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

View File

@@ -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);

View File

@@ -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"));
}

View File

@@ -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)
{

View 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-----

View 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-----