Merge Beatrice to Master 2021-11

This commit is contained in:
serkixenos 2021-12-01 07:54:19 +00:00 committed by Bobinson K B
parent 2778a99842
commit 9955b390ee
151 changed files with 6357 additions and 2891 deletions

1
.gitignore vendored
View file

@ -14,6 +14,7 @@ data
CMakeDoxyfile.in
build
build__*
libraries/utilities/git_revision.cpp

View file

@ -1,11 +1,11 @@
# Defines BitShares library target.
project( BitShares )
# Defines Peerplays library target.
project( Peerplays )
cmake_minimum_required( VERSION 2.8.12 )
set( BLOCKCHAIN_NAME "BitShares" )
set( BLOCKCHAIN_NAME "Peerplays" )
set( CLI_CLIENT_EXECUTABLE_NAME graphene_client )
set( GUI_CLIENT_EXECUTABLE_NAME BitShares )
set( GUI_CLIENT_EXECUTABLE_NAME Peerplays )
set( CUSTOM_URL_SCHEME "gcs" )
set( INSTALLER_APP_ID "68ad7005-8eee-49c9-95ce-9eed97e5b347" )
@ -22,6 +22,34 @@ endif()
list( APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules" )
# function to help with cUrl
macro(FIND_CURL)
if (NOT WIN32 AND NOT APPLE AND CURL_STATICLIB)
find_package(OpenSSL REQUIRED)
set (OLD_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
set (CMAKE_FIND_LIBRARY_SUFFIXES .a)
find_package(CURL REQUIRED)
list(APPEND CURL_LIBRARIES ${OPENSSL_LIBRARIES} ${BOOST_THREAD_LIBRARY} ${CMAKE_DL_LIBS})
set (CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_SUFFIXES})
else (NOT WIN32 AND NOT APPLE AND CURL_STATICLIB)
find_package(CURL REQUIRED)
endif (NOT WIN32 AND NOT APPLE AND CURL_STATICLIB)
if( WIN32 )
if ( MSVC )
list( APPEND CURL_LIBRARIES Wldap32 )
endif( MSVC )
if( MINGW )
# MinGW requires a specific order of included libraries ( CURL before ZLib )
find_package( ZLIB REQUIRED )
list( APPEND CURL_LIBRARIES ${ZLIB_LIBRARY} pthread )
endif( MINGW )
list( APPEND CURL_LIBRARIES ${PLATFORM_SPECIFIC_LIBS} )
endif( WIN32 )
endmacro()
set(CMAKE_EXPORT_COMPILE_COMMANDS "ON")
set(GRAPHENE_EGENESIS_JSON "${CMAKE_CURRENT_SOURCE_DIR}/genesis.json" CACHE PATH "location of the genesis.json to embed in the executable" )
@ -71,7 +99,7 @@ ENDIF()
if( WIN32 )
message( STATUS "Configuring BitShares on WIN32")
message( STATUS "Configuring Peerplays on WIN32")
set( DB_VERSION 60 )
set( BDB_STATIC_LIBS 1 )
@ -103,20 +131,13 @@ if( WIN32 )
SET(TCL_LIBRARY ${TCL_LIBS})
else( WIN32 ) # Apple AND Linux
find_library(READLINE_LIBRARIES NAMES readline)
find_path(READLINE_INCLUDE_DIR readline/readline.h)
#if(NOT READLINE_INCLUDE_DIR OR NOT READLINE_LIBRARIES)
# MESSAGE(FATAL_ERROR "Could not find lib readline.")
#endif()
if( APPLE )
# Apple Specific Options Here
message( STATUS "Configuring BitShares on OS X" )
message( STATUS "Configuring Peerplays on OS X" )
set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++11 -stdlib=libc++ -Wall" )
else( APPLE )
# Linux Specific Options Here
message( STATUS "Configuring BitShares on Linux" )
message( STATUS "Configuring Peerplays on Linux" )
set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++11 -Wall" )
set( rt_library rt )
#set( pthread_library pthread)
@ -135,7 +156,7 @@ else( WIN32 ) # Apple AND Linux
endif( APPLE )
if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-builtin-memcmp -Wno-parentheses -Wno-terminate -Wno-invalid-offsetof -Wno-sign-compare" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" )
elseif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" )
if( CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 4.0.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.0.0 )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-invalid-partial-specialization" )
@ -154,7 +175,7 @@ else( WIN32 ) # Apple AND Linux
endif( WIN32 )
set(ENABLE_COVERAGE_TESTING FALSE CACHE BOOL "Build BitShares for code coverage analysis")
set(ENABLE_COVERAGE_TESTING FALSE CACHE BOOL "Build Peerplays for code coverage analysis")
if(ENABLE_COVERAGE_TESTING)
SET(CMAKE_CXX_FLAGS "--coverage ${CMAKE_CXX_FLAGS}")
@ -163,13 +184,13 @@ endif()
add_subdirectory( libraries )
set(BUILD_BITSHARES_PROGRAMS TRUE CACHE BOOL "Build bitshares executables (witness node, cli wallet, etc)")
set(BUILD_PEERPLAYS_PROGRAMS TRUE CACHE BOOL "Build peerplays executables (witness node, cli wallet, etc)")
add_subdirectory( programs )
set(BUILD_BITSHARES_TESTS TRUE CACHE BOOL "Build bitshares unit tests")
if( BUILD_BITSHARES_TESTS )
set(BUILD_PEERPLAYS_TESTS TRUE CACHE BOOL "Build peerplays unit tests")
if( BUILD_PEERPLAYS_TESTS )
add_subdirectory( tests )
endif( BUILD_BITSHARES_TESTS )
endif( BUILD_PEERPLAYS_TESTS )
if (ENABLE_INSTALLER)
@ -191,18 +212,18 @@ set(CPACK_PACKAGE_VERSION_MAJOR "${VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${VERSION_MINOR}")
set(CPACK_PACKAGE_VERSION_PATCH "${VERSION_PATCH}")
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
set(CPACK_PACKAGE_DESCRIPTION "A client for the BitShares network")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A client for the BitShares network")
set(CPACK_PACKAGE_DESCRIPTION "A client for the Peerplays network")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A client for the Peerplays network")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.md")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "BitShares ${CPACK_PACKAGE_VERSION}")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "Peerplays ${CPACK_PACKAGE_VERSION}")
if(WIN32)
SET(CPACK_GENERATOR "ZIP;NSIS")
set(CPACK_PACKAGE_NAME "BitShares") # override above
set(CPACK_PACKAGE_NAME "Peerplays") # override above
set(CPACK_NSIS_EXECUTABLES_DIRECTORY .)
set(CPACK_NSIS_PACKAGE_NAME "BitShares v${CPACK_PACKAGE_VERSION}")
set(CPACK_NSIS_PACKAGE_NAME "Peerplays v${CPACK_PACKAGE_VERSION}")
set(CPACK_NSIS_DISPLAY_NAME "${CPACK_NSIS_PACKAGE_NAME}")
set(CPACK_NSIS_DEFINES " !define MUI_STARTMENUPAGE_DEFAULTFOLDER \\\"BitShares\\\"")
set(CPACK_NSIS_DEFINES " !define MUI_STARTMENUPAGE_DEFAULTFOLDER \\\"Peerplays\\\"")
# it seems like windows zip files usually don't have a single directory inside them, unix tgz frequently do
SET(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0)
@ -220,3 +241,4 @@ endif(LINUX)
include(CPack)
endif(ENABLE_INSTALLER)

View file

@ -44,7 +44,6 @@ make -j$(nproc)
make install # this can install the executable files under /usr/local
```
docker build -t peerplays .
## Docker image

View file

@ -1,794 +0,0 @@
# This is the CMakeCache file.
# For build in directory: /home/pbattu/git/18.04/peerplays
# It was generated by CMake: /usr/bin/cmake
# You can edit this file to change values found and used by cmake.
# If you do not want to change any of the values, simply exit the editor.
# If you do want to change a value, simply edit, save, and exit the editor.
# The syntax for the file is as follows:
# KEY:TYPE=VALUE
# KEY is the name of a variable in the cache.
# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!.
# VALUE is the current value for the KEY.
########################
# EXTERNAL cache entries
########################
//No help, variable specified on the command line.
BOOST_ROOT:PATH=/home/pbattu/git/18.04/boost_1_67_0
//The threading library used by boost-thread
BOOST_THREAD_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libpthread.so
//Build bitshares executables (witness node, cli wallet, etc)
BUILD_BITSHARES_PROGRAMS:BOOL=TRUE
//Build bitshares unit tests
BUILD_BITSHARES_TESTS:BOOL=TRUE
//Build websocketpp examples.
BUILD_EXAMPLES:BOOL=OFF
//Build websocketpp tests.
BUILD_TESTS:BOOL=OFF
//Value Computed by CMake
BitShares_BINARY_DIR:STATIC=/home/pbattu/git/18.04/peerplays
//Value Computed by CMake
BitShares_SOURCE_DIR:STATIC=/home/pbattu/git/18.04/peerplays
//Boost chrono library (debug)
Boost_CHRONO_LIBRARY_DEBUG:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_chrono.a
//Boost chrono library (release)
Boost_CHRONO_LIBRARY_RELEASE:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_chrono.a
//Boost context library (debug)
Boost_CONTEXT_LIBRARY_DEBUG:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_context.a
//Boost context library (release)
Boost_CONTEXT_LIBRARY_RELEASE:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_context.a
//Boost coroutine library (debug)
Boost_COROUTINE_LIBRARY_DEBUG:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_coroutine.a
//Boost coroutine library (release)
Boost_COROUTINE_LIBRARY_RELEASE:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_coroutine.a
//Boost date_time library (debug)
Boost_DATE_TIME_LIBRARY_DEBUG:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_date_time.a
//Boost date_time library (release)
Boost_DATE_TIME_LIBRARY_RELEASE:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_date_time.a
//The directory containing a CMake configuration file for Boost.
Boost_DIR:PATH=Boost_DIR-NOTFOUND
//Boost filesystem library (debug)
Boost_FILESYSTEM_LIBRARY_DEBUG:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_filesystem.a
//Boost filesystem library (release)
Boost_FILESYSTEM_LIBRARY_RELEASE:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_filesystem.a
//Path to a file.
Boost_INCLUDE_DIR:PATH=/home/pbattu/git/18.04/boost_1_67_0/include
//Boost iostreams library (debug)
Boost_IOSTREAMS_LIBRARY_DEBUG:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_iostreams.a
//Boost iostreams library (release)
Boost_IOSTREAMS_LIBRARY_RELEASE:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_iostreams.a
//Boost library directory
Boost_LIBRARY_DIR:PATH=/home/pbattu/git/18.04/boost_1_67_0/lib
//Boost library directory DEBUG
Boost_LIBRARY_DIR_DEBUG:PATH=/home/pbattu/git/18.04/boost_1_67_0/lib
//Boost library directory RELEASE
Boost_LIBRARY_DIR_RELEASE:PATH=/home/pbattu/git/18.04/boost_1_67_0/lib
//Boost locale library (debug)
Boost_LOCALE_LIBRARY_DEBUG:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_locale.a
//Boost locale library (release)
Boost_LOCALE_LIBRARY_RELEASE:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_locale.a
//Boost program_options library (debug)
Boost_PROGRAM_OPTIONS_LIBRARY_DEBUG:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_program_options.a
//Boost program_options library (release)
Boost_PROGRAM_OPTIONS_LIBRARY_RELEASE:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_program_options.a
//Boost serialization library (debug)
Boost_SERIALIZATION_LIBRARY_DEBUG:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_serialization.a
//Boost serialization library (release)
Boost_SERIALIZATION_LIBRARY_RELEASE:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_serialization.a
//Boost signals library (debug)
Boost_SIGNALS_LIBRARY_DEBUG:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_signals.a
//Boost signals library (release)
Boost_SIGNALS_LIBRARY_RELEASE:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_signals.a
//Boost system library (debug)
Boost_SYSTEM_LIBRARY_DEBUG:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_system.a
//Boost system library (release)
Boost_SYSTEM_LIBRARY_RELEASE:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_system.a
//Boost thread library (debug)
Boost_THREAD_LIBRARY_DEBUG:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_thread.a
//Boost thread library (release)
Boost_THREAD_LIBRARY_RELEASE:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_thread.a
//Boost unit_test_framework library (debug)
Boost_UNIT_TEST_FRAMEWORK_LIBRARY_DEBUG:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_unit_test_framework.a
//Boost unit_test_framework library (release)
Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE:FILEPATH=/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_unit_test_framework.a
//ON or OFF
Boost_USE_STATIC_LIBS:STRING=ON
//Path to a program.
CMAKE_AR:FILEPATH=/usr/bin/ar
//Choose the type of build, options are: None(CMAKE_CXX_FLAGS or
// CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.
CMAKE_BUILD_TYPE:STRING=Debug
//Enable/Disable color output during build.
CMAKE_COLOR_MAKEFILE:BOOL=ON
//Configurations
CMAKE_CONFIGURATION_TYPES:STRING=Release;RelWithDebInfo;Debug
//CXX compiler
CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/g++-5
//A wrapper around 'ar' adding the appropriate '--plugin' option
// for the GCC compiler
CMAKE_CXX_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar-5
//A wrapper around 'ranlib' adding the appropriate '--plugin' option
// for the GCC compiler
CMAKE_CXX_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib-5
//Flags used by the compiler during all build types.
CMAKE_CXX_FLAGS:STRING=
//Flags used by the compiler during debug builds.
CMAKE_CXX_FLAGS_DEBUG:STRING=-g
//Flags used by the compiler during release builds for minimum
// size.
CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
//Flags used by the compiler during release builds.
CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
//Flags used by the compiler during release builds with debug info.
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
//C compiler
CMAKE_C_COMPILER:FILEPATH=/usr/bin/gcc-5
//A wrapper around 'ar' adding the appropriate '--plugin' option
// for the GCC compiler
CMAKE_C_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar-5
//A wrapper around 'ranlib' adding the appropriate '--plugin' option
// for the GCC compiler
CMAKE_C_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib-5
//Flags used by the compiler during all build types.
CMAKE_C_FLAGS:STRING=
//Flags used by the compiler during debug builds.
CMAKE_C_FLAGS_DEBUG:STRING=-g
//Flags used by the compiler during release builds for minimum
// size.
CMAKE_C_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
//Flags used by the compiler during release builds.
CMAKE_C_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
//Flags used by the compiler during release builds with debug info.
CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
//Flags used by the linker.
CMAKE_EXE_LINKER_FLAGS:STRING=
//Flags used by the linker during debug builds.
CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during release minsize builds.
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during release builds.
CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during Release with Debug Info builds.
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Enable/Disable output of compile commands during generation.
CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=OFF
//Install path prefix, prepended onto install directories.
CMAKE_INSTALL_PREFIX:PATH=/usr/local
//Path to a program.
CMAKE_LINKER:FILEPATH=/usr/bin/ld
//Path to a program.
CMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/make
//Flags used by the linker during the creation of modules.
CMAKE_MODULE_LINKER_FLAGS:STRING=
//Flags used by the linker during debug builds.
CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during release minsize builds.
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during release builds.
CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during Release with Debug Info builds.
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Path to a program.
CMAKE_NM:FILEPATH=/usr/bin/nm
//Path to a program.
CMAKE_OBJCOPY:FILEPATH=/usr/bin/objcopy
//Path to a program.
CMAKE_OBJDUMP:FILEPATH=/usr/bin/objdump
//Value Computed by CMake
CMAKE_PROJECT_NAME:STATIC=BitShares
//Path to a program.
CMAKE_RANLIB:FILEPATH=/usr/bin/ranlib
//Flags used by the linker during the creation of dll's.
CMAKE_SHARED_LINKER_FLAGS:STRING=
//Flags used by the linker during debug builds.
CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during release minsize builds.
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during release builds.
CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during Release with Debug Info builds.
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//If set, runtime paths are not added when installing shared libraries,
// but are added when building.
CMAKE_SKIP_INSTALL_RPATH:BOOL=NO
//If set, runtime paths are not added when using shared libraries.
CMAKE_SKIP_RPATH:BOOL=NO
//Flags used by the linker during the creation of static libraries.
CMAKE_STATIC_LINKER_FLAGS:STRING=
//Flags used by the linker during debug builds.
CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during release minsize builds.
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during release builds.
CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during Release with Debug Info builds.
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Path to a program.
CMAKE_STRIP:FILEPATH=/usr/bin/strip
//If this value is on, makefiles will be generated without the
// .SILENT directive, and all commands will be echoed to the console
// during the make. This is useful for debugging only. With Visual
// Studio IDE projects all commands are done without /nologo.
CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE
//Path to a library.
CURSES_CURSES_LIBRARY:FILEPATH=CURSES_CURSES_LIBRARY-NOTFOUND
//Path to a library.
CURSES_FORM_LIBRARY:FILEPATH=CURSES_FORM_LIBRARY-NOTFOUND
//Path to a file.
CURSES_INCLUDE_PATH:PATH=CURSES_INCLUDE_PATH-NOTFOUND
//Path to a library.
CURSES_NCURSES_LIBRARY:FILEPATH=CURSES_NCURSES_LIBRARY-NOTFOUND
//Dot tool for use with Doxygen
DOXYGEN_DOT_EXECUTABLE:FILEPATH=DOXYGEN_DOT_EXECUTABLE-NOTFOUND
//Doxygen documentation generation tool (http://www.doxygen.org)
DOXYGEN_EXECUTABLE:FILEPATH=DOXYGEN_EXECUTABLE-NOTFOUND
//secp256k1 or openssl or mixed
ECC_IMPL:STRING=secp256k1
//Build BitShares for code coverage analysis
ENABLE_COVERAGE_TESTING:BOOL=FALSE
//Build websocketpp with CPP11 features enabled.
ENABLE_CPP11:BOOL=ON
//TRUE to try to use full zlib for compression, FALSE to use miniz.c
FC_USE_FULL_ZLIB:BOOL=FALSE
//Git command line client
GIT_EXECUTABLE:FILEPATH=/usr/bin/git
//location of the genesis.json to embed in the executable
GRAPHENE_EGENESIS_JSON:PATH=/home/pbattu/git/18.04/peerplays/genesis.json
//The directory containing a CMake configuration file for Gperftools.
Gperftools_DIR:PATH=Gperftools_DIR-NOTFOUND
//Installation directory for CMake files
INSTALL_CMAKE_DIR:PATH=lib/cmake/websocketpp
//Installation directory for header files
INSTALL_INCLUDE_DIR:PATH=include
//Log long API calls over websocket (ON OR OFF)
LOG_LONG_API:BOOL=ON
//Max API execution time in ms
LOG_LONG_API_MAX_MS:STRING=1000
//API execution time in ms at which to warn
LOG_LONG_API_WARN_MS:STRING=750
//Path to a library.
OPENSSL_CRYPTO_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libcrypto.a
//Path to a file.
OPENSSL_INCLUDE_DIR:PATH=/usr/include
//Path to a library.
OPENSSL_SSL_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libssl.a
//Path to a program.
PERL_EXECUTABLE:FILEPATH=/usr/bin/perl
//pkg-config executable
PKG_CONFIG_EXECUTABLE:FILEPATH=/usr/bin/pkg-config
//Path to a file.
READLINE_INCLUDE_DIR:PATH=/usr/include
//Path to a library.
READLINE_LIBRARIES:FILEPATH=/usr/lib/x86_64-linux-gnu/libreadline.so
//Path to a file.
Readline_INCLUDE_DIR:PATH=/usr/include
//Path to a library.
Readline_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libreadline.so
//Path to a file.
Readline_ROOT_DIR:PATH=/usr
//OFF
UNITY_BUILD:BOOL=OFF
//Path to a file.
ZLIB_INCLUDE_DIR:PATH=/usr/include
//Path to a library.
ZLIB_LIBRARY_DEBUG:FILEPATH=ZLIB_LIBRARY_DEBUG-NOTFOUND
//Path to a library.
ZLIB_LIBRARY_RELEASE:FILEPATH=/usr/lib/x86_64-linux-gnu/libz.so
//Value Computed by CMake
fc_BINARY_DIR:STATIC=/home/pbattu/git/18.04/peerplays/libraries/fc
//Dependencies for the target
fc_LIB_DEPENDS:STATIC=general;-L/usr/local/lib;general;/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_thread.a;general;/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_date_time.a;general;/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_filesystem.a;general;/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_system.a;general;/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_program_options.a;general;/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_signals.a;general;/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_serialization.a;general;/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_chrono.a;general;/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_unit_test_framework.a;general;/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_context.a;general;/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_locale.a;general;/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_iostreams.a;general;/home/pbattu/git/18.04/boost_1_67_0/lib/libboost_coroutine.a;general;/usr/lib/x86_64-linux-gnu/libpthread.so;general;/usr/lib/x86_64-linux-gnu/libssl.a;general;/usr/lib/x86_64-linux-gnu/libcrypto.a;general;/usr/lib/x86_64-linux-gnu/libz.so;general;dl;general;rt;general;/usr/lib/x86_64-linux-gnu/libreadline.so;general;secp256k1;
//Value Computed by CMake
fc_SOURCE_DIR:STATIC=/home/pbattu/git/18.04/peerplays/libraries/fc
//Dependencies for the target
graphene_account_history_LIB_DEPENDS:STATIC=general;graphene_chain;general;graphene_app;
//Dependencies for the target
graphene_accounts_list_LIB_DEPENDS:STATIC=general;graphene_chain;general;graphene_app;
//Dependencies for the target
graphene_affiliate_stats_LIB_DEPENDS:STATIC=general;graphene_chain;general;graphene_app;
//Dependencies for the target
graphene_app_LIB_DEPENDS:STATIC=general;graphene_market_history;general;graphene_account_history;general;graphene_accounts_list;general;graphene_affiliate_stats;general;graphene_chain;general;fc;general;graphene_db;general;graphene_net;general;graphene_time;general;graphene_utilities;general;graphene_debug_witness;general;graphene_bookie;
//Dependencies for the target
graphene_bookie_LIB_DEPENDS:STATIC=general;graphene_chain;general;graphene_app;
//Dependencies for the target
graphene_chain_LIB_DEPENDS:STATIC=general;fc;general;graphene_db;
//Dependencies for the target
graphene_db_LIB_DEPENDS:STATIC=general;fc;
//Dependencies for the target
graphene_debug_witness_LIB_DEPENDS:STATIC=general;graphene_chain;general;graphene_app;
//Dependencies for the target
graphene_delayed_node_LIB_DEPENDS:STATIC=general;graphene_chain;general;graphene_app;
//Dependencies for the target
graphene_egenesis_brief_LIB_DEPENDS:STATIC=general;graphene_chain;general;fc;
//Dependencies for the target
graphene_egenesis_full_LIB_DEPENDS:STATIC=general;graphene_chain;general;fc;
//Dependencies for the target
graphene_egenesis_none_LIB_DEPENDS:STATIC=general;graphene_chain;general;fc;
//Dependencies for the target
graphene_generate_genesis_LIB_DEPENDS:STATIC=general;graphene_chain;general;graphene_app;general;graphene_time;
//Dependencies for the target
graphene_generate_uia_sharedrop_genesis_LIB_DEPENDS:STATIC=general;graphene_chain;general;graphene_app;general;graphene_time;
//Dependencies for the target
graphene_market_history_LIB_DEPENDS:STATIC=general;graphene_chain;general;graphene_app;
//Dependencies for the target
graphene_net_LIB_DEPENDS:STATIC=general;fc;general;graphene_db;
//Dependencies for the target
graphene_snapshot_LIB_DEPENDS:STATIC=general;graphene_chain;general;graphene_app;
//Dependencies for the target
graphene_time_LIB_DEPENDS:STATIC=general;fc;
//Dependencies for the target
graphene_utilities_LIB_DEPENDS:STATIC=general;fc;
//Dependencies for the target
graphene_wallet_LIB_DEPENDS:STATIC=general;graphene_app;general;graphene_net;general;graphene_chain;general;graphene_utilities;general;fc;general;dl;
//Dependencies for the target
graphene_witness_LIB_DEPENDS:STATIC=general;graphene_chain;general;graphene_app;
//Value Computed by CMake
websocketpp_BINARY_DIR:STATIC=/home/pbattu/git/18.04/peerplays/libraries/fc/vendor/websocketpp
//Value Computed by CMake
websocketpp_SOURCE_DIR:STATIC=/home/pbattu/git/18.04/peerplays/libraries/fc/vendor/websocketpp
########################
# INTERNAL cache entries
########################
//ADVANCED property for variable: BOOST_ROOT
BOOST_ROOT-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_CHRONO_LIBRARY_DEBUG
Boost_CHRONO_LIBRARY_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_CHRONO_LIBRARY_RELEASE
Boost_CHRONO_LIBRARY_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_CONTEXT_LIBRARY_DEBUG
Boost_CONTEXT_LIBRARY_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_CONTEXT_LIBRARY_RELEASE
Boost_CONTEXT_LIBRARY_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_COROUTINE_LIBRARY_DEBUG
Boost_COROUTINE_LIBRARY_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_COROUTINE_LIBRARY_RELEASE
Boost_COROUTINE_LIBRARY_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_DATE_TIME_LIBRARY_DEBUG
Boost_DATE_TIME_LIBRARY_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_DATE_TIME_LIBRARY_RELEASE
Boost_DATE_TIME_LIBRARY_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_DIR
Boost_DIR-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_FILESYSTEM_LIBRARY_DEBUG
Boost_FILESYSTEM_LIBRARY_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_FILESYSTEM_LIBRARY_RELEASE
Boost_FILESYSTEM_LIBRARY_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_INCLUDE_DIR
Boost_INCLUDE_DIR-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_IOSTREAMS_LIBRARY_DEBUG
Boost_IOSTREAMS_LIBRARY_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_IOSTREAMS_LIBRARY_RELEASE
Boost_IOSTREAMS_LIBRARY_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_LIBRARY_DIR
Boost_LIBRARY_DIR-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_LIBRARY_DIR_DEBUG
Boost_LIBRARY_DIR_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_LIBRARY_DIR_RELEASE
Boost_LIBRARY_DIR_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_LOCALE_LIBRARY_DEBUG
Boost_LOCALE_LIBRARY_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_LOCALE_LIBRARY_RELEASE
Boost_LOCALE_LIBRARY_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_PROGRAM_OPTIONS_LIBRARY_DEBUG
Boost_PROGRAM_OPTIONS_LIBRARY_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_PROGRAM_OPTIONS_LIBRARY_RELEASE
Boost_PROGRAM_OPTIONS_LIBRARY_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_SERIALIZATION_LIBRARY_DEBUG
Boost_SERIALIZATION_LIBRARY_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_SERIALIZATION_LIBRARY_RELEASE
Boost_SERIALIZATION_LIBRARY_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_SIGNALS_LIBRARY_DEBUG
Boost_SIGNALS_LIBRARY_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_SIGNALS_LIBRARY_RELEASE
Boost_SIGNALS_LIBRARY_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_SYSTEM_LIBRARY_DEBUG
Boost_SYSTEM_LIBRARY_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_SYSTEM_LIBRARY_RELEASE
Boost_SYSTEM_LIBRARY_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_THREAD_LIBRARY_DEBUG
Boost_THREAD_LIBRARY_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_THREAD_LIBRARY_RELEASE
Boost_THREAD_LIBRARY_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_UNIT_TEST_FRAMEWORK_LIBRARY_DEBUG
Boost_UNIT_TEST_FRAMEWORK_LIBRARY_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE
Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_AR
CMAKE_AR-ADVANCED:INTERNAL=1
//This is the directory where this CMakeCache.txt was created
CMAKE_CACHEFILE_DIR:INTERNAL=/home/pbattu/git/18.04/peerplays
//Major version of cmake used to create the current loaded cache
CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3
//Minor version of cmake used to create the current loaded cache
CMAKE_CACHE_MINOR_VERSION:INTERNAL=10
//Patch version of cmake used to create the current loaded cache
CMAKE_CACHE_PATCH_VERSION:INTERNAL=2
//ADVANCED property for variable: CMAKE_COLOR_MAKEFILE
CMAKE_COLOR_MAKEFILE-ADVANCED:INTERNAL=1
//Path to CMake executable.
CMAKE_COMMAND:INTERNAL=/usr/bin/cmake
//Path to cpack program executable.
CMAKE_CPACK_COMMAND:INTERNAL=/usr/bin/cpack
//Path to ctest program executable.
CMAKE_CTEST_COMMAND:INTERNAL=/usr/bin/ctest
//ADVANCED property for variable: CMAKE_CXX_COMPILER
CMAKE_CXX_COMPILER-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_COMPILER_AR
CMAKE_CXX_COMPILER_AR-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_COMPILER_RANLIB
CMAKE_CXX_COMPILER_RANLIB-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_COMPILER
CMAKE_C_COMPILER-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_COMPILER_AR
CMAKE_C_COMPILER_AR-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_COMPILER_RANLIB
CMAKE_C_COMPILER_RANLIB-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS
CMAKE_C_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_MINSIZEREL
CMAKE_C_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_C_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//Executable file format
CMAKE_EXECUTABLE_FORMAT:INTERNAL=ELF
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS
CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG
CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE
CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXPORT_COMPILE_COMMANDS
CMAKE_EXPORT_COMPILE_COMMANDS-ADVANCED:INTERNAL=1
//Name of external makefile project generator.
CMAKE_EXTRA_GENERATOR:INTERNAL=
//Name of generator.
CMAKE_GENERATOR:INTERNAL=Unix Makefiles
//Name of generator platform.
CMAKE_GENERATOR_PLATFORM:INTERNAL=
//Name of generator toolset.
CMAKE_GENERATOR_TOOLSET:INTERNAL=
//Have symbol pthread_create
CMAKE_HAVE_LIBC_CREATE:INTERNAL=
//Have library pthreads
CMAKE_HAVE_PTHREADS_CREATE:INTERNAL=
//Have library pthread
CMAKE_HAVE_PTHREAD_CREATE:INTERNAL=1
//Have include pthread.h
CMAKE_HAVE_PTHREAD_H:INTERNAL=1
//Source directory with the top level CMakeLists.txt file for this
// project
CMAKE_HOME_DIRECTORY:INTERNAL=/home/pbattu/git/18.04/peerplays
//Install .so files without execute permission.
CMAKE_INSTALL_SO_NO_EXE:INTERNAL=1
//ADVANCED property for variable: CMAKE_LINKER
CMAKE_LINKER-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MAKE_PROGRAM
CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS
CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG
CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE
CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_NM
CMAKE_NM-ADVANCED:INTERNAL=1
//number of local generators
CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=37
//ADVANCED property for variable: CMAKE_OBJCOPY
CMAKE_OBJCOPY-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_OBJDUMP
CMAKE_OBJDUMP-ADVANCED:INTERNAL=1
//Platform information initialized
CMAKE_PLATFORM_INFO_INITIALIZED:INTERNAL=1
//ADVANCED property for variable: CMAKE_RANLIB
CMAKE_RANLIB-ADVANCED:INTERNAL=1
//Path to CMake installation.
CMAKE_ROOT:INTERNAL=/usr/share/cmake-3.10
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG
CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE
CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SKIP_INSTALL_RPATH
CMAKE_SKIP_INSTALL_RPATH-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SKIP_RPATH
CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS
CMAKE_STATIC_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_DEBUG
CMAKE_STATIC_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELEASE
CMAKE_STATIC_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STRIP
CMAKE_STRIP-ADVANCED:INTERNAL=1
//uname command
CMAKE_UNAME:INTERNAL=/bin/uname
//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE
CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CURSES_CURSES_LIBRARY
CURSES_CURSES_LIBRARY-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CURSES_FORM_LIBRARY
CURSES_FORM_LIBRARY-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CURSES_INCLUDE_PATH
CURSES_INCLUDE_PATH-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CURSES_NCURSES_LIBRARY
CURSES_NCURSES_LIBRARY-ADVANCED:INTERNAL=1
//ADVANCED property for variable: DOXYGEN_DOT_EXECUTABLE
DOXYGEN_DOT_EXECUTABLE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: DOXYGEN_EXECUTABLE
DOXYGEN_EXECUTABLE-ADVANCED:INTERNAL=1
//Details about finding OpenSSL
FIND_PACKAGE_MESSAGE_DETAILS_OpenSSL:INTERNAL=[/usr/lib/x86_64-linux-gnu/libcrypto.a][/usr/include][v1.1.0g()]
//Details about finding Perl
FIND_PACKAGE_MESSAGE_DETAILS_Perl:INTERNAL=[/usr/bin/perl][v5.26.1()]
//Details about finding Readline
FIND_PACKAGE_MESSAGE_DETAILS_Readline:INTERNAL=[/usr/include][/usr/lib/x86_64-linux-gnu/libreadline.so][v()]
//Details about finding Threads
FIND_PACKAGE_MESSAGE_DETAILS_Threads:INTERNAL=[TRUE][v()]
//Details about finding ZLIB
FIND_PACKAGE_MESSAGE_DETAILS_ZLIB:INTERNAL=[/usr/lib/x86_64-linux-gnu/libz.so][/usr/include][v1.2.11()]
//ADVANCED property for variable: GIT_EXECUTABLE
GIT_EXECUTABLE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: OPENSSL_CRYPTO_LIBRARY
OPENSSL_CRYPTO_LIBRARY-ADVANCED:INTERNAL=1
//ADVANCED property for variable: OPENSSL_INCLUDE_DIR
OPENSSL_INCLUDE_DIR-ADVANCED:INTERNAL=1
//ADVANCED property for variable: OPENSSL_SSL_LIBRARY
OPENSSL_SSL_LIBRARY-ADVANCED:INTERNAL=1
//ADVANCED property for variable: PERL_EXECUTABLE
PERL_EXECUTABLE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: PKG_CONFIG_EXECUTABLE
PKG_CONFIG_EXECUTABLE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Readline_INCLUDE_DIR
Readline_INCLUDE_DIR-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Readline_LIBRARY
Readline_LIBRARY-ADVANCED:INTERNAL=1
//ADVANCED property for variable: Readline_ROOT_DIR
Readline_ROOT_DIR-ADVANCED:INTERNAL=1
//ADVANCED property for variable: ZLIB_INCLUDE_DIR
ZLIB_INCLUDE_DIR-ADVANCED:INTERNAL=1
//ADVANCED property for variable: ZLIB_LIBRARY_DEBUG
ZLIB_LIBRARY_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: ZLIB_LIBRARY_RELEASE
ZLIB_LIBRARY_RELEASE-ADVANCED:INTERNAL=1
//Last used BOOST_ROOT value.
_BOOST_ROOT_LAST:INTERNAL=/home/pbattu/git/18.04/boost_1_67_0
//Components requested for this build tree.
_Boost_COMPONENTS_SEARCHED:INTERNAL=chrono;context;coroutine;date_time;filesystem;iostreams;locale;program_options;serialization;signals;system;thread;unit_test_framework
//Last used Boost_INCLUDE_DIR value.
_Boost_INCLUDE_DIR_LAST:INTERNAL=/home/pbattu/git/18.04/boost_1_67_0/include
//Last used Boost_LIBRARY_DIR_DEBUG value.
_Boost_LIBRARY_DIR_DEBUG_LAST:INTERNAL=/home/pbattu/git/18.04/boost_1_67_0/lib
//Last used Boost_LIBRARY_DIR value.
_Boost_LIBRARY_DIR_LAST:INTERNAL=/home/pbattu/git/18.04/boost_1_67_0/lib
//Last used Boost_LIBRARY_DIR_RELEASE value.
_Boost_LIBRARY_DIR_RELEASE_LAST:INTERNAL=/home/pbattu/git/18.04/boost_1_67_0/lib
//Last used Boost_NAMESPACE value.
_Boost_NAMESPACE_LAST:INTERNAL=boost
//Last used Boost_USE_MULTITHREADED value.
_Boost_USE_MULTITHREADED_LAST:INTERNAL=TRUE
//Last used Boost_USE_STATIC_LIBS value.
_Boost_USE_STATIC_LIBS_LAST:INTERNAL=ON
_OPENSSL_CFLAGS:INTERNAL=
_OPENSSL_CFLAGS_I:INTERNAL=
_OPENSSL_CFLAGS_OTHER:INTERNAL=
_OPENSSL_FOUND:INTERNAL=1
_OPENSSL_INCLUDEDIR:INTERNAL=/usr/include
_OPENSSL_INCLUDE_DIRS:INTERNAL=
_OPENSSL_LDFLAGS:INTERNAL=-lssl;-lcrypto
_OPENSSL_LDFLAGS_OTHER:INTERNAL=
_OPENSSL_LIBDIR:INTERNAL=/usr/lib/x86_64-linux-gnu
_OPENSSL_LIBRARIES:INTERNAL=ssl;crypto
_OPENSSL_LIBRARY_DIRS:INTERNAL=
_OPENSSL_LIBS:INTERNAL=
_OPENSSL_LIBS_L:INTERNAL=
_OPENSSL_LIBS_OTHER:INTERNAL=
_OPENSSL_LIBS_PATHS:INTERNAL=
_OPENSSL_PREFIX:INTERNAL=/usr
_OPENSSL_STATIC_CFLAGS:INTERNAL=
_OPENSSL_STATIC_CFLAGS_I:INTERNAL=
_OPENSSL_STATIC_CFLAGS_OTHER:INTERNAL=
_OPENSSL_STATIC_INCLUDE_DIRS:INTERNAL=
_OPENSSL_STATIC_LDFLAGS:INTERNAL=-lssl;-ldl;-lcrypto;-ldl
_OPENSSL_STATIC_LDFLAGS_OTHER:INTERNAL=
_OPENSSL_STATIC_LIBDIR:INTERNAL=
_OPENSSL_STATIC_LIBRARIES:INTERNAL=ssl;dl;crypto;dl
_OPENSSL_STATIC_LIBRARY_DIRS:INTERNAL=
_OPENSSL_STATIC_LIBS:INTERNAL=
_OPENSSL_STATIC_LIBS_L:INTERNAL=
_OPENSSL_STATIC_LIBS_OTHER:INTERNAL=
_OPENSSL_STATIC_LIBS_PATHS:INTERNAL=
_OPENSSL_VERSION:INTERNAL=1.1.0g
_OPENSSL_openssl_INCLUDEDIR:INTERNAL=
_OPENSSL_openssl_LIBDIR:INTERNAL=
_OPENSSL_openssl_PREFIX:INTERNAL=
_OPENSSL_openssl_VERSION:INTERNAL=
__pkg_config_arguments__OPENSSL:INTERNAL=QUIET;openssl
__pkg_config_checked__OPENSSL:INTERNAL=1
prefix_result:INTERNAL=/usr/lib/x86_64-linux-gnu

4
clang-format.sh Executable file
View file

@ -0,0 +1,4 @@
#!/bin/bash
find ./libraries/plugins/peerplays_sidechain -regex ".*[c|h]pp" | xargs clang-format -i

View file

@ -1,12 +1,10 @@
add_subdirectory( fc )
add_subdirectory( db )
#add_subdirectory( deterministic_openssl_rand )
add_subdirectory( app )
add_subdirectory( chain )
add_subdirectory( db )
add_subdirectory( egenesis )
add_subdirectory( fc )
add_subdirectory( net )
#add_subdirectory( p2p )
add_subdirectory( plugins )
add_subdirectory( time )
add_subdirectory( utilities )
add_subdirectory( app )
add_subdirectory( plugins )
add_subdirectory( wallet )

View file

@ -4,16 +4,19 @@ file(GLOB EGENESIS_HEADERS "../egenesis/include/graphene/app/*.hpp")
add_library( graphene_app
api.cpp
application.cpp
config_util.cpp
database_api.cpp
plugin.cpp
config_util.cpp
${HEADERS}
${EGENESIS_HEADERS}
)
# need to link graphene_debug_witness because plugins aren't sufficiently isolated #246
#target_link_libraries( graphene_app graphene_market_history graphene_account_history graphene_chain fc graphene_db graphene_net graphene_utilities graphene_debug_witness )
target_link_libraries( graphene_app graphene_market_history graphene_account_history graphene_accounts_list graphene_affiliate_stats graphene_chain fc graphene_db graphene_net graphene_time graphene_utilities graphene_debug_witness graphene_bookie graphene_elasticsearch peerplays_sidechain )
target_link_libraries( graphene_app
PUBLIC graphene_net graphene_utilities
graphene_account_history graphene_accounts_list graphene_affiliate_stats graphene_bookie graphene_debug_witness graphene_elasticsearch graphene_es_objects graphene_generate_genesis graphene_market_history )
target_include_directories( graphene_app
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include"
"${CMAKE_CURRENT_SOURCE_DIR}/../egenesis/include" )
@ -30,3 +33,26 @@ INSTALL( TARGETS
ARCHIVE DESTINATION lib
)
INSTALL( FILES ${HEADERS} DESTINATION "include/graphene/app" )
add_library( graphene_plugin
plugin.cpp
include/graphene/app/plugin.hpp
)
target_link_libraries( graphene_plugin
PUBLIC graphene_net graphene_utilities )
target_include_directories( graphene_plugin
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
INSTALL( TARGETS
graphene_app
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)

View file

@ -579,7 +579,10 @@ namespace graphene { namespace app {
{
FC_ASSERT( _app.chain_database() );
const auto& db = *_app.chain_database();
FC_ASSERT( limit <= 100 );
FC_ASSERT( limit <= api_limit_get_account_history,
"Number of querying accounts can not be greater than ${configured_limit}",
("configured_limit", api_limit_get_account_history) );
vector<operation_history_object> result;
account_id_type account;
try {
@ -627,13 +630,16 @@ namespace graphene { namespace app {
{
FC_ASSERT( _app.chain_database() );
const auto& db = *_app.chain_database();
FC_ASSERT( limit <= 100 );
FC_ASSERT( limit <= api_limit_get_account_history_operations,
"Number of querying history accounts can not be greater than ${configured_limit}",
("configured_limit", api_limit_get_account_history_operations) );
vector<operation_history_object> result;
account_id_type account;
try {
account = database_api.get_account_id_from_string(account_id_or_name);
} catch (...) { return result; }
const auto& stats = account(db).statistics(db);
if( stats.most_recent_op == account_transaction_history_id_type() ) return result;
const account_transaction_history_object* node = &stats.most_recent_op(db);
@ -667,7 +673,10 @@ namespace graphene { namespace app {
{
FC_ASSERT( _app.chain_database() );
const auto& db = *_app.chain_database();
FC_ASSERT(limit <= 100);
FC_ASSERT( limit <= api_limit_get_relative_account_history,
"Number of querying accounts can not be greater than ${configured_limit}",
("configured_limit", api_limit_get_relative_account_history) );
vector<operation_history_object> result;
account_id_type account;
try {
@ -797,14 +806,16 @@ namespace graphene { namespace app {
}
// asset_api
asset_api::asset_api(graphene::app::application& app) :
asset_api::asset_api(graphene::app::application& app) :
_app(app),
_db( *app.chain_database()),
database_api( std::ref(*app.chain_database())) { }
asset_api::~asset_api() { }
vector<account_asset_balance> asset_api::get_asset_holders( std::string asset, uint32_t start, uint32_t limit ) const {
FC_ASSERT(limit <= 100);
FC_ASSERT( limit <= api_limit_get_asset_holders,
"Number of querying asset holder accounts can not be greater than ${configured_limit}",
("configured_limit", api_limit_get_asset_holders) );
asset_id_type asset_id = database_api.get_asset_id_from_string( asset );
const auto& bal_idx = _db.get_index_type< account_balance_index >().indices().get< by_asset_balance >();

View file

@ -381,7 +381,6 @@ namespace detail {
_chain_db->enable_standby_votes_tracking( _options->at("enable-standby-votes-tracking").as<bool>() );
}
bool replay = false;
std::string replay_reason = "reason not provided";
if( _options->count("replay-blockchain") )

View file

@ -235,6 +235,17 @@ class database_api_impl : public std::enable_shared_from_this<database_api_impl>
vector<offer_history_object> get_offer_history_by_item(const offer_history_id_type lower_id, const nft_id_type item, uint32_t limit) const;
vector<offer_history_object> get_offer_history_by_bidder(const offer_history_id_type lower_id, const account_id_type bidder_account_id, uint32_t limit) const;
uint32_t api_limit_get_lower_bound_symbol = 100;
uint32_t api_limit_get_limit_orders = 300;
uint32_t api_limit_get_limit_orders_by_account = 101;
uint32_t api_limit_get_order_book = 50;
uint32_t api_limit_all_offers_count = 100;
uint32_t api_limit_lookup_accounts = 1000;
uint32_t api_limit_lookup_witness_accounts = 1000;
uint32_t api_limit_lookup_committee_member_accounts = 1000;
uint32_t api_limit_get_trade_history = 100;
uint32_t api_limit_get_trade_history_by_sequence = 100;
// Account Role
vector<account_role_object> get_account_roles_by_owner(account_id_type owner) const;
@ -893,7 +904,9 @@ map<string,account_id_type> database_api::lookup_accounts(const string& lower_bo
map<string,account_id_type> database_api_impl::lookup_accounts(const string& lower_bound_name, uint32_t limit)const
{
FC_ASSERT( limit <= 1000 );
FC_ASSERT( limit <= api_limit_lookup_accounts,
"Number of querying accounts can not be greater than ${configured_limit}",
("configured_limit", api_limit_lookup_accounts) );
const auto& accounts_by_name = _db.get_index_type<account_index>().indices().get<by_name>();
map<string,account_id_type> result;
@ -930,7 +943,7 @@ vector<asset> database_api::get_account_balances(const std::string& account_name
return my->get_account_balances( account_name_or_id, assets );
}
vector<asset> database_api_impl::get_account_balances( const std::string& account_name_or_id,
vector<asset> database_api_impl::get_account_balances( const std::string& account_name_or_id,
const flat_set<asset_id_type>& assets)const
{
const account_object* account = get_account_from_string(account_name_or_id);
@ -1101,7 +1114,9 @@ vector<asset_object> database_api::list_assets(const string& lower_bound_symbol,
vector<asset_object> database_api_impl::list_assets(const string& lower_bound_symbol, uint32_t limit)const
{
FC_ASSERT( limit <= 100 );
FC_ASSERT( limit <= api_limit_get_lower_bound_symbol,
"Number of querying accounts can not be greater than ${configured_limit}",
("configured_limit", api_limit_get_lower_bound_symbol) );
const auto& assets_by_symbol = _db.get_index_type<asset_index>().indices().get<by_symbol>();
vector<asset_object> result;
result.reserve(limit);
@ -1551,7 +1566,9 @@ order_book database_api::get_order_book( const string& base, const string& quote
order_book database_api_impl::get_order_book( const string& base, const string& quote, unsigned limit )const
{
using boost::multiprecision::uint128_t;
FC_ASSERT( limit <= 50 );
FC_ASSERT( limit <= api_limit_get_order_book,
"Number of querying accounts can not be greater than ${configured_limit}",
("configured_limit", api_limit_get_order_book) );
order_book result;
result.base = base;
@ -1613,7 +1630,9 @@ vector<market_trade> database_api_impl::get_trade_history( const string& base,
fc::time_point_sec stop,
unsigned limit )const
{
FC_ASSERT( limit <= 100 );
FC_ASSERT( limit <= api_limit_get_trade_history,
"Number of querying accounts can not be greater than ${configured_limit}",
("configured_limit", api_limit_get_trade_history) );
auto assets = lookup_asset_symbols( {base, quote} );
FC_ASSERT( assets[0], "Invalid base asset symbol: ${s}", ("s",base) );
@ -1732,7 +1751,9 @@ map<string, witness_id_type> database_api::lookup_witness_accounts(const string&
map<string, witness_id_type> database_api_impl::lookup_witness_accounts(const string& lower_bound_name, uint32_t limit)const
{
FC_ASSERT( limit <= 1000 );
FC_ASSERT( limit <= api_limit_lookup_witness_accounts,
"Number of querying accounts can not be greater than ${configured_limit}",
("configured_limit", api_limit_lookup_witness_accounts) );
const auto& witnesses_by_id = _db.get_index_type<witness_index>().indices().get<by_id>();
// we want to order witnesses by account name, but that name is in the account object
@ -1808,7 +1829,9 @@ map<string, committee_member_id_type> database_api::lookup_committee_member_acco
map<string, committee_member_id_type> database_api_impl::lookup_committee_member_accounts(const string& lower_bound_name, uint32_t limit)const
{
FC_ASSERT( limit <= 1000 );
FC_ASSERT( limit <= api_limit_lookup_committee_member_accounts,
"Number of querying accounts can not be greater than ${configured_limit}",
("configured_limit", api_limit_lookup_committee_member_accounts) );
const auto& committee_members_by_id = _db.get_index_type<committee_member_index>().indices().get<by_id>();
// we want to order committee_members by account name, but that name is in the account object
@ -2562,18 +2585,8 @@ graphene::app::gpos_info database_api_impl::get_gpos_info(const account_id_type
share_type total_amount;
auto balance_type = vesting_balance_type::gpos;
#ifdef USE_VESTING_OBJECT_BY_ASSET_BALANCE_INDEX
// get only once a collection of accounts that hold nonzero vesting balances of the dividend asset
auto vesting_balances_begin =
vesting_index.indices().get<by_asset_balance>().lower_bound(boost::make_tuple(asset_id_type(), balance_type));
auto vesting_balances_end =
vesting_index.indices().get<by_asset_balance>().upper_bound(boost::make_tuple(asset_id_type(), balance_type, share_type()));
for (const vesting_balance_object& vesting_balance_obj : boost::make_iterator_range(vesting_balances_begin, vesting_balances_end))
{
total_amount += vesting_balance_obj.balance.amount;
}
#else
// get only once a collection of accounts that hold nonzero vesting balances of the dividend asset
const vesting_balance_index& vesting_index = _db.get_index_type<vesting_balance_index>();
const auto& vesting_balances = vesting_index.indices().get<by_id>();
for (const vesting_balance_object& vesting_balance_obj : vesting_balances)
@ -2583,7 +2596,6 @@ graphene::app::gpos_info database_api_impl::get_gpos_info(const account_id_type
total_amount += vesting_balance_obj.balance.amount;
}
}
#endif
vector<vesting_balance_object> account_vbos;
const time_point_sec now = _db.head_block_time();
@ -2594,9 +2606,9 @@ graphene::app::gpos_info database_api_impl::get_gpos_info(const account_id_type
&& balance.balance.asset_id == asset_id_type())
account_vbos.emplace_back(balance);
});
share_type allowed_withdraw_amount = 0, account_vested_balance = 0;
for (const vesting_balance_object& vesting_balance_obj : account_vbos)
{
account_vested_balance += vesting_balance_obj.balance.amount;
@ -2928,7 +2940,9 @@ vector<offer_object> database_api::list_offers(const offer_id_type lower_id, uin
vector<offer_object> database_api_impl::list_offers(const offer_id_type lower_id, uint32_t limit) const
{
FC_ASSERT( limit <= 100 );
FC_ASSERT( limit <= api_limit_all_offers_count,
"Number of querying offers can not be greater than ${configured_limit}",
("configured_limit", api_limit_all_offers_count) );
const auto& offers_idx = _db.get_index_type<offer_index>().indices().get<by_id>();
vector<offer_object> result;
result.reserve(limit);
@ -2948,7 +2962,9 @@ vector<offer_object> database_api::list_sell_offers(const offer_id_type lower_id
vector<offer_object> database_api_impl::list_sell_offers(const offer_id_type lower_id, uint32_t limit) const
{
FC_ASSERT( limit <= 100 );
FC_ASSERT( limit <= api_limit_all_offers_count,
"Number of querying offers can not be greater than ${configured_limit}",
("configured_limit", api_limit_all_offers_count) );
const auto& offers_idx = _db.get_index_type<offer_index>().indices().get<by_id>();
vector<offer_object> result;
result.reserve(limit);
@ -2974,7 +2990,9 @@ vector<offer_object> database_api::list_buy_offers(const offer_id_type lower_id,
vector<offer_object> database_api_impl::list_buy_offers(const offer_id_type lower_id, uint32_t limit) const
{
FC_ASSERT( limit <= 100 );
FC_ASSERT( limit <= api_limit_all_offers_count,
"Number of querying offers can not be greater than ${configured_limit}",
("configured_limit", api_limit_all_offers_count) );
const auto& offers_idx = _db.get_index_type<offer_index>().indices().get<by_id>();
vector<offer_object> result;
result.reserve(limit);
@ -3001,7 +3019,9 @@ vector<offer_history_object> database_api::list_offer_history(const offer_histor
vector<offer_history_object> database_api_impl::list_offer_history(const offer_history_id_type lower_id, uint32_t limit) const
{
FC_ASSERT( limit <= 100 );
FC_ASSERT( limit <= api_limit_all_offers_count,
"Number of querying offers can not be greater than ${configured_limit}",
("configured_limit", api_limit_all_offers_count) );
const auto& oh_idx = _db.get_index_type<offer_history_index>().indices().get<by_id>();
vector<offer_history_object> result;
result.reserve(limit);
@ -3021,7 +3041,9 @@ vector<offer_object> database_api::get_offers_by_issuer(const offer_id_type lowe
vector<offer_object> database_api_impl::get_offers_by_issuer(const offer_id_type lower_id, const account_id_type issuer_account_id, uint32_t limit) const
{
FC_ASSERT( limit <= 100 );
FC_ASSERT( limit <= api_limit_all_offers_count,
"Number of querying offers can not be greater than ${configured_limit}",
("configured_limit", api_limit_all_offers_count) );
const auto& offers_idx = _db.get_index_type<offer_index>().indices().get<by_id>();
vector<offer_object> result;
result.reserve(limit);
@ -3045,7 +3067,9 @@ vector<offer_object> database_api::get_offers_by_item(const offer_id_type lower_
vector<offer_object> database_api_impl::get_offers_by_item(const offer_id_type lower_id, const nft_id_type item, uint32_t limit) const
{
FC_ASSERT( limit <= 100 );
FC_ASSERT( limit <= api_limit_all_offers_count,
"Number of querying offers can not be greater than ${configured_limit}",
("configured_limit", api_limit_all_offers_count) );
const auto& offers_idx = _db.get_index_type<offer_index>().indices().get<by_id>();
vector<offer_object> result;
result.reserve(limit);
@ -3080,7 +3104,9 @@ vector<offer_history_object> database_api::get_offer_history_by_bidder(const off
vector<offer_history_object> database_api_impl::get_offer_history_by_issuer(const offer_history_id_type lower_id, const account_id_type issuer_account_id, uint32_t limit) const
{
FC_ASSERT( limit <= 100 );
FC_ASSERT( limit <= api_limit_all_offers_count,
"Number of querying offers can not be greater than ${configured_limit}",
("configured_limit", api_limit_all_offers_count) );
const auto& oh_idx = _db.get_index_type<offer_history_index>().indices().get<by_id>();
vector<offer_history_object> result;
result.reserve(limit);
@ -3101,7 +3127,9 @@ vector<offer_history_object> database_api_impl::get_offer_history_by_issuer(cons
vector<offer_history_object> database_api_impl::get_offer_history_by_item(const offer_history_id_type lower_id, const nft_id_type item, uint32_t limit) const
{
FC_ASSERT( limit <= 100 );
FC_ASSERT( limit <= api_limit_all_offers_count,
"Number of querying offers can not be greater than ${configured_limit}",
("configured_limit", api_limit_all_offers_count) );
const auto& oh_idx = _db.get_index_type<offer_history_index>().indices().get<by_id>();
vector<offer_history_object> result;
result.reserve(limit);
@ -3123,7 +3151,9 @@ vector<offer_history_object> database_api_impl::get_offer_history_by_item(const
vector<offer_history_object> database_api_impl::get_offer_history_by_bidder(const offer_history_id_type lower_id, const account_id_type bidder_account_id, uint32_t limit) const
{
FC_ASSERT( limit <= 100 );
FC_ASSERT( limit <= api_limit_all_offers_count,
"Number of querying offers can not be greater than ${configured_limit}",
("configured_limit", api_limit_all_offers_count) );
const auto& oh_idx = _db.get_index_type<offer_history_index>().indices().get<by_id>();
vector<offer_history_object> result;
result.reserve(limit);

View file

@ -150,6 +150,9 @@ namespace graphene { namespace app {
fc::time_point_sec start, fc::time_point_sec end )const;
vector<account_balance_object> list_core_accounts()const;
flat_set<uint32_t> get_market_history_buckets()const;
uint32_t api_limit_get_account_history_operations = 100;
uint32_t api_limit_get_account_history = 100;
uint32_t api_limit_get_relative_account_history = 100;
private:
application& _app;
graphene::app::database_api database_api;
@ -354,6 +357,7 @@ namespace graphene { namespace app {
*/
vector<asset_holders> get_all_asset_holders() const;
uint32_t api_limit_get_asset_holders = 100;
private:
graphene::app::application& _app;
graphene::chain::database& _db;

View file

@ -8,143 +8,29 @@ add_dependencies( build_hardfork_hpp cat-parts )
file(GLOB HEADERS "include/graphene/chain/*.hpp")
file(GLOB PROTOCOL_HEADERS "include/graphene/chain/protocol/*.hpp")
if( GRAPHENE_DISABLE_UNITY_BUILD )
set( GRAPHENE_DB_FILES
db_balance.cpp
db_bet.cpp
db_block.cpp
db_debug.cpp
db_getter.cpp
db_init.cpp
db_maint.cpp
db_management.cpp
db_market.cpp
db_update.cpp
db_witness_schedule.cpp
)
file(GLOB CPP_FILES "*.cpp")
file(GLOB PROTOCOL_CPP_FILES "protocol/*.cpp")
#if( GRAPHENE_DISABLE_UNITY_BUILD )
list(FILTER CPP_FILES EXCLUDE REGEX "[/]database[.]cpp$")
#message ("--- ${CPP_FILES}")
message( STATUS "Graphene database unity build disabled" )
else( GRAPHENE_DISABLE_UNITY_BUILD )
set( GRAPHENE_DB_FILES
database.cpp )
message( STATUS "Graphene database unity build enabled" )
endif( GRAPHENE_DISABLE_UNITY_BUILD )
#else( GRAPHENE_DISABLE_UNITY_BUILD )
# list(FILTER CPP_FILES EXCLUDE REGEX ".*db_.*[.]cpp$")
# #message ("--- ${CPP_FILES}")
# message( STATUS "Graphene database unity build enabled" )
#endif( GRAPHENE_DISABLE_UNITY_BUILD )
## SORT .cpp by most likely to change / break compile
add_library( graphene_chain
# As database takes the longest to compile, start it first
${GRAPHENE_DB_FILES}
fork_database.cpp
protocol/types.cpp
protocol/address.cpp
protocol/authority.cpp
protocol/asset.cpp
protocol/assert.cpp
protocol/account.cpp
protocol/transfer.cpp
protocol/chain_parameters.cpp
protocol/committee_member.cpp
protocol/witness.cpp
protocol/market.cpp
protocol/proposal.cpp
protocol/withdraw_permission.cpp
protocol/asset_ops.cpp
protocol/lottery_ops.cpp
protocol/memo.cpp
protocol/worker.cpp
protocol/custom.cpp
protocol/operations.cpp
protocol/transaction.cpp
protocol/block.cpp
protocol/fee_schedule.cpp
protocol/confidential.cpp
protocol/vote.cpp
protocol/tournament.cpp
protocol/small_ops.cpp
protocol/custom_permission.cpp
protocol/custom_account_authority.cpp
protocol/offer.cpp
genesis_state.cpp
get_config.cpp
pts_address.cpp
evaluator.cpp
balance_evaluator.cpp
account_evaluator.cpp
assert_evaluator.cpp
witness_evaluator.cpp
committee_member_evaluator.cpp
asset_evaluator.cpp
lottery_evaluator.cpp
transfer_evaluator.cpp
proposal_evaluator.cpp
market_evaluator.cpp
vesting_balance_evaluator.cpp
tournament_evaluator.cpp
tournament_object.cpp
match_object.cpp
game_object.cpp
withdraw_permission_evaluator.cpp
worker_evaluator.cpp
confidential_evaluator.cpp
special_authority.cpp
buyback.cpp
account_object.cpp
asset_object.cpp
fba_object.cpp
proposal_object.cpp
vesting_balance_object.cpp
small_objects.cpp
block_database.cpp
is_authorized_asset.cpp
protocol/sport.cpp
sport_evaluator.cpp
protocol/event_group.cpp
event_group_evaluator.cpp
event_group_object.cpp
protocol/event.cpp
event_evaluator.cpp
event_object.cpp
protocol/betting_market.cpp
betting_market_evaluator.cpp
betting_market_object.cpp
betting_market_group_object.cpp
custom_permission_evaluator.cpp
custom_account_authority_evaluator.cpp
affiliate_payout.cpp
offer_object.cpp
offer_evaluator.cpp
nft_evaluator.cpp
protocol/nft.cpp
protocol/account_role.cpp
account_role_evaluator.cpp
son_evaluator.cpp
son_object.cpp
son_wallet_evaluator.cpp
son_wallet_deposit_evaluator.cpp
son_wallet_withdraw_evaluator.cpp
sidechain_address_evaluator.cpp
sidechain_transaction_evaluator.cpp
${CPP_FILES}
${PROTOCOL_CPP_FILES}
${HEADERS}
${PROTOCOL_HEADERS}
"${CMAKE_CURRENT_BINARY_DIR}/include/graphene/chain/hardfork.hpp"
)
add_dependencies( graphene_chain build_hardfork_hpp )
target_link_libraries( graphene_chain fc graphene_db )
target_link_libraries( graphene_chain graphene_db )
target_include_directories( graphene_chain
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_BINARY_DIR}/include" )

View file

@ -597,7 +597,6 @@ void_result asset_update_dividend_evaluator::do_apply( const asset_update_divide
obj.referrer = op.issuer;
obj.lifetime_referrer = op.issuer(db()).lifetime_referrer;
auto& params = db().get_global_properties().parameters;
obj.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
obj.lifetime_referrer_fee_percentage = GRAPHENE_DEFAULT_LIFETIME_REFERRER_PERCENT_OF_FEE;
obj.referrer_rewards_percentage = GRAPHENE_DEFAULT_LIFETIME_REFERRER_PERCENT_OF_FEE;

View file

@ -266,7 +266,7 @@ map< account_id_type, vector< uint16_t > > asset_object::distribute_winners_part
*t += percents_to_distribute / holders.size();
}
auto sweeps_distribution_percentage = db.get_global_properties().parameters.sweeps_distribution_percentage();
for( int c = 0; c < winner_numbers.size(); ++c ) {
for( size_t c = 0; c < winner_numbers.size(); ++c ) {
auto winner_num = winner_numbers[c];
lottery_reward_operation reward_op;
reward_op.lottery = get_id();

View file

@ -30,6 +30,6 @@
#include "db_maint.cpp"
#include "db_management.cpp"
#include "db_market.cpp"
#include "db_notify.cpp"
#include "db_update.cpp"
#include "db_witness_schedule.cpp"
#include "db_notify.cpp"

View file

@ -140,8 +140,10 @@ void database::adjust_sweeps_vesting_balance(account_id_type account, int64_t de
b.balance = delta;
});
} else {
if( delta < 0 )
FC_ASSERT( itr->get_balance() >= -delta, "Insufficient Balance: ${a}'s balance of ${b} is less than required ${r}", ("a",account)("b",itr->get_balance())("r",-delta));
if( delta < 0 ) {
uint64_t delta_uint64 = -delta;
FC_ASSERT( itr->get_balance() >= delta_uint64, "Insufficient Balance: ${a}'s balance of ${b} is less than required ${r}", ("a",account)("b",itr->get_balance())("r",-delta));
}
modify(*itr, [&delta,&asset_id,this](sweeps_vesting_balance_object& b) {
b.adjust_balance( asset( delta, asset_id ) );
b.last_claim_date = head_block_time();

View file

@ -303,8 +303,6 @@ void database::settle_betting_market_group(const betting_market_group_object& be
remove(betting_market);
}
const event_object& event = betting_market_group.event_id(*this);
fc_dlog(fc::logger::get("betting"), "removing betting market group ${id}", ("id", betting_market_group.id));
remove(betting_market_group);
@ -537,11 +535,9 @@ int match_bet(database& db, const bet_object& taker_bet, const bet_object& maker
// because we matched at the maker's odds and not the taker's odds, the remaining amount to match
// may not be an even multiple of the taker's odds; round it down.
share_type taker_remaining_factor = unrounded_taker_remaining_amount_to_match / takers_odds_maker_odds_ratio;
share_type taker_remaining_maker_amount_to_match = taker_remaining_factor * takers_odds_maker_odds_ratio;
share_type taker_remaining_bet_amount = taker_remaining_factor * takers_odds_taker_odds_ratio;
taker_refund_amount = taker_bet.amount_to_bet.amount - taker_amount_to_match - taker_remaining_bet_amount;
//idump((taker_remaining_factor)(taker_remaining_maker_amount_to_match)(taker_remaining_bet_amount)(taker_refund_amount));
}
if (taker_refund_amount > share_type())

View file

@ -715,7 +715,8 @@ void database::_apply_block( const signed_block& next_block )
perform_chain_maintenance(next_block, global_props);
check_ending_lotteries();
check_ending_nft_lotteries();
create_block_summary(next_block);
place_delayed_bets(); // must happen after update_global_dynamic_data() updates the time
clear_expired_transactions();

View file

@ -109,7 +109,7 @@ uint32_t database::last_non_undoable_block_num() const
return head_block_num() - _undo_db.size();
}
std::vector<uint32_t> database::get_seeds(asset_id_type for_asset, uint8_t count_winners) const
std::vector<uint32_t> database::get_seeds( asset_id_type for_asset, uint8_t count_winners ) const
{
FC_ASSERT( count_winners <= 64 );
std::string salted_string = std::string(_random_number_generator._seed) + std::to_string(for_asset.instance.value);
@ -315,6 +315,38 @@ bool database::is_son_active( son_id_type son_id )
return (it_son != active_son_ids.end());
}
vector<uint64_t> database::get_random_numbers(uint64_t minimum, uint64_t maximum, uint64_t selections, bool duplicates)
{
FC_ASSERT( selections <= 100000 );
if (duplicates == false) {
FC_ASSERT( maximum - minimum >= selections );
}
vector<uint64_t> v;
v.reserve(selections);
if (duplicates) {
for (uint64_t i = 0; i < selections; i++) {
int64_t rnd = get_random_bits(maximum - minimum) + minimum;
v.push_back(rnd);
}
} else {
vector<uint64_t> tmpv;
tmpv.reserve(selections);
for (uint64_t i = minimum; i < maximum; i++) {
tmpv.push_back(i);
}
for (uint64_t i = 0; (i < selections) && (tmpv.size() > 0); i++) {
uint64_t idx = get_random_bits(tmpv.size());
v.push_back(tmpv.at(idx));
tmpv.erase(tmpv.begin() + idx);
}
}
return v;
}
bool database::is_asset_creation_allowed(const string &symbol)
{
time_point_sec now = head_block_time();

View file

@ -53,6 +53,7 @@
#include <graphene/chain/custom_account_authority_object.hpp>
#include <graphene/chain/offer_object.hpp>
#include <graphene/chain/account_role_object.hpp>
#include <graphene/chain/random_number_object.hpp>
#include <graphene/chain/nft_object.hpp>
@ -94,12 +95,14 @@
#include <graphene/chain/offer_evaluator.hpp>
#include <graphene/chain/nft_evaluator.hpp>
#include <graphene/chain/account_role_evaluator.hpp>
#include <graphene/chain/nft_lottery_evaluator.hpp>
#include <graphene/chain/son_evaluator.hpp>
#include <graphene/chain/son_wallet_evaluator.hpp>
#include <graphene/chain/son_wallet_deposit_evaluator.hpp>
#include <graphene/chain/son_wallet_withdraw_evaluator.hpp>
#include <graphene/chain/sidechain_address_evaluator.hpp>
#include <graphene/chain/sidechain_transaction_evaluator.hpp>
#include <graphene/chain/random_number_evaluator.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
@ -203,6 +206,12 @@ const uint8_t offer_history_object::type_id;
const uint8_t account_role_object::space_id;
const uint8_t account_role_object::type_id;
const uint8_t nft_lottery_balance_object::space_id;
const uint8_t nft_lottery_balance_object::type_id;
const uint8_t random_number_object::space_id;
const uint8_t random_number_object::type_id;
void database::initialize_evaluators()
{
_operation_evaluators.resize(255);
@ -295,6 +304,9 @@ void database::initialize_evaluators()
register_evaluator<account_role_create_evaluator>();
register_evaluator<account_role_update_evaluator>();
register_evaluator<account_role_delete_evaluator>();
register_evaluator<nft_lottery_token_purchase_evaluator>();
register_evaluator<nft_lottery_reward_evaluator>();
register_evaluator<nft_lottery_end_evaluator>();
register_evaluator<create_son_evaluator>();
register_evaluator<update_son_evaluator>();
register_evaluator<deregister_son_evaluator>();
@ -314,6 +326,7 @@ void database::initialize_evaluators()
register_evaluator<sidechain_transaction_sign_evaluator>();
register_evaluator<sidechain_transaction_send_evaluator>();
register_evaluator<sidechain_transaction_settle_evaluator>();
register_evaluator<random_number_store_evaluator>();
}
void database::initialize_indexes()
@ -403,7 +416,9 @@ void database::initialize_indexes()
add_index< primary_index<lottery_balance_index > >();
add_index< primary_index<sweeps_vesting_balance_index > >();
add_index< primary_index<offer_history_index > >();
add_index< primary_index<nft_lottery_balance_index > >();
add_index< primary_index<son_stats_index > >();
add_index< primary_index<random_number_index > >();
}
@ -933,7 +948,6 @@ void database::init_genesis(const genesis_state_type& genesis_state)
const auto& idx = get_index_type<asset_index>().indices().get<by_symbol>();
auto it = idx.begin();
bool has_imbalanced_assets = false;
while( it != idx.end() )
{
@ -945,7 +959,6 @@ void database::init_genesis(const genesis_state_type& genesis_state)
FC_ASSERT( debt_itr != total_debts.end() );
if( supply_itr->second != debt_itr->second )
{
has_imbalanced_assets = true;
elog( "Genesis for asset ${aname} is not balanced\n"
" Debt is ${debt}\n"
" Supply is ${supply}\n",
@ -957,10 +970,6 @@ void database::init_genesis(const genesis_state_type& genesis_state)
}
++it;
}
// @romek
#if 0
FC_ASSERT( !has_imbalanced_assets );
#endif
// Save tallied supplies
for( const auto& item : total_supplies )

View file

@ -32,24 +32,24 @@
#include <graphene/chain/is_authorized_asset.hpp>
#include <graphene/chain/account_object.hpp>
#include <graphene/chain/account_role_object.hpp>
#include <graphene/chain/asset_object.hpp>
#include <graphene/chain/budget_record_object.hpp>
#include <graphene/chain/buyback_object.hpp>
#include <graphene/chain/chain_property_object.hpp>
#include <graphene/chain/committee_member_object.hpp>
#include <graphene/chain/custom_account_authority_object.hpp>
#include <graphene/chain/fba_object.hpp>
#include <graphene/chain/global_property_object.hpp>
#include <graphene/chain/market_object.hpp>
#include <graphene/chain/special_authority_object.hpp>
#include <graphene/chain/son_object.hpp>
#include <graphene/chain/son_wallet_object.hpp>
#include <graphene/chain/vesting_balance_object.hpp>
#include <graphene/chain/vote_count.hpp>
#include <graphene/chain/witness_object.hpp>
#include <graphene/chain/witness_schedule_object.hpp>
#include <graphene/chain/worker_object.hpp>
#include <graphene/chain/custom_account_authority_object.hpp>
#define USE_VESTING_OBJECT_BY_ASSET_BALANCE_INDEX // vesting_balance_object by_asset_balance index needed
namespace graphene { namespace chain {
@ -84,7 +84,7 @@ vector<std::reference_wrapper<const son_object>> database::sort_votable_objects<
std::vector<std::reference_wrapper<const son_object>> refs;
for( auto& son : all_sons )
{
if(son.has_valid_config() && son.status != son_status::deregistered)
if(son.has_valid_config(head_block_time()) && son.status != son_status::deregistered)
{
refs.push_back(std::cref(son));
}
@ -210,20 +210,29 @@ void database::pay_sons()
if( now < HARDFORK_SON2_TIME ) {
son_weight = get_weight_before_son2_hf(_vote_tally_buffer[son_obj->vote_id]);
}
weighted_total_txs_signed += (s.txs_signed * son_weight);
uint64_t txs_signed = 0;
for (const auto &ts : s.txs_signed) {
txs_signed = txs_signed + ts.second;
}
weighted_total_txs_signed += (txs_signed * son_weight);
});
// Now pay off each SON proportional to the number of transactions signed.
get_index_type<son_stats_index>().inspect_all_objects([this, &weighted_total_txs_signed, &dpo, &son_budget, &get_weight, &get_weight_before_son2_hf, &now](const object& o) {
const son_statistics_object& s = static_cast<const son_statistics_object&>(o);
if(s.txs_signed > 0){
uint64_t txs_signed = 0;
for (const auto &ts : s.txs_signed) {
txs_signed = txs_signed + ts.second;
}
if(txs_signed > 0){
const auto& idx = get_index_type<son_index>().indices().get<by_id>();
auto son_obj = idx.find( s.owner );
auto son_weight = get_weight(_vote_tally_buffer[son_obj->vote_id]);
if( now < HARDFORK_SON2_TIME ) {
son_weight = get_weight_before_son2_hf(_vote_tally_buffer[son_obj->vote_id]);
}
share_type pay = (s.txs_signed * son_weight * son_budget.value)/weighted_total_txs_signed;
share_type pay = (txs_signed * son_weight * son_budget.value)/weighted_total_txs_signed;
modify( *son_obj, [&]( son_object& _son_obj)
{
_son_obj.pay_son_fee(pay, *this);
@ -236,8 +245,9 @@ void database::pay_sons()
//Reset the tx counter in each son statistics object
modify( s, [&]( son_statistics_object& _s)
{
_s.total_txs_signed += _s.txs_signed;
_s.txs_signed = 0;
for (const auto &ts : s.txs_signed) {
_s.txs_signed.at(ts.first) = 0;
}
});
}
});
@ -267,11 +277,13 @@ void database::update_son_metrics(const vector<son_info>& curr_active_sons)
bool is_active_son = (std::find(current_sons.begin(), current_sons.end(), son.id) != current_sons.end());
modify( stats, [&]( son_statistics_object& _stats )
{
if(is_active_son) {
_stats.total_voted_time = _stats.total_voted_time + get_global_properties().parameters.maintenance_interval;
}
_stats.total_downtime += _stats.current_interval_downtime;
_stats.current_interval_downtime = 0;
if(is_active_son)
{
_stats.total_voted_time = _stats.total_voted_time + get_global_properties().parameters.maintenance_interval;
for (const auto &str : _stats.sidechain_txs_reported) {
_stats.sidechain_txs_reported.at(str.first) = 0;
}
});
}
@ -593,7 +605,7 @@ void database::update_active_committee_members()
update_committee_member_total_votes( cm );
}
}
// Update committee authorities
if( !committee_members.empty() )
{
@ -1206,7 +1218,6 @@ uint32_t database::get_gpos_current_subperiod()
const auto period_start = fc::time_point_sec(gpo.parameters.gpos_period_start());
// variables needed
const fc::time_point_sec period_end = period_start + vesting_period;
const auto number_of_subperiods = vesting_period / vesting_subperiod;
const auto now = this->head_block_time();
auto seconds_since_period_start = now.sec_since_epoch() - period_start.sec_since_epoch();
@ -1244,13 +1255,13 @@ double database::calculate_vesting_factor(const account_object& stake_account)
// variables needed
const auto number_of_subperiods = vesting_period / vesting_subperiod;
double vesting_factor;
// get in what sub period we are
uint32_t current_subperiod = get_gpos_current_subperiod();
if(current_subperiod == 0 || current_subperiod > number_of_subperiods) return 0;
// On starting new vesting period, all votes become zero until someone votes, To avoid a situation of zero votes,
// On starting new vesting period, all votes become zero until someone votes, To avoid a situation of zero votes,
// changes were done to roll in GPOS rules, the vesting factor will be 1 for whoever votes in 6th sub-period of last vesting period
// BLOCKBACK-174 fix
if(current_subperiod == 1 && this->head_block_time() >= HARDFORK_GPOS_TIME + vesting_period) //Applicable only from 2nd vesting period
@ -1399,7 +1410,6 @@ void schedule_pending_dividend_balances(database& db,
uint32_t holder_account_count = 0;
#ifdef USE_VESTING_OBJECT_BY_ASSET_BALANCE_INDEX
// get only once a collection of accounts that hold nonzero vesting balances of the dividend asset
auto vesting_balances_begin =
vesting_index.indices().get<by_asset_balance>().lower_bound(boost::make_tuple(dividend_holder_asset_obj.id, balance_type));
@ -1414,22 +1424,6 @@ void schedule_pending_dividend_balances(database& db,
("owner", vesting_balance_obj.owner(db).name)
("amount", vesting_balance_obj.balance.amount));
}
#else
// get only once a collection of accounts that hold nonzero vesting balances of the dividend asset
const auto& vesting_balances = vesting_index.indices().get<by_id>();
for (const vesting_balance_object& vesting_balance_obj : vesting_balances)
{
if (vesting_balance_obj.balance.asset_id == dividend_holder_asset_obj.id && vesting_balance_obj.balance.amount &&
vesting_balance_object.balance_type == balance_type)
{
vesting_amounts[vesting_balance_obj.owner] += vesting_balance_obj.balance.amount;
++gpos_holder_account_count;
dlog("Vesting balance for account: ${owner}, amount: ${amount}",
("owner", vesting_balance_obj.owner(db).name)
("amount", vesting_balance_obj.balance.amount));
}
}
#endif
auto current_distribution_account_balance_iter = current_distribution_account_balance_range.begin();
if(db.head_block_time() < HARDFORK_GPOS_TIME)
@ -1883,7 +1877,6 @@ void process_dividend_assets(database& db)
{
// if there was a previous payout, make our next payment one interval
uint32_t current_time_sec = current_head_block_time.sec_since_epoch();
fc::time_point_sec reference_time = *dividend_data_obj.last_scheduled_payout_time;
uint32_t next_possible_time_sec = dividend_data_obj.last_scheduled_payout_time->sec_since_epoch();
do
next_possible_time_sec += *dividend_data_obj.options.payout_interval;
@ -1944,10 +1937,7 @@ void database::perform_son_tasks()
a.options.market_fee_percent = 500; // 5%
a.options.issuer_permissions = UIA_ASSET_ISSUER_PERMISSION_MASK;
a.options.flags = asset_issuer_permission_flags::charge_market_fee |
//asset_issuer_permission_flags::white_list |
asset_issuer_permission_flags::override_authority |
asset_issuer_permission_flags::transfer_restricted |
asset_issuer_permission_flags::disable_confidential;
asset_issuer_permission_flags::override_authority;
a.options.core_exchange_rate.base.amount = 100000;
a.options.core_exchange_rate.base.asset_id = asset_id_type(0);
a.options.core_exchange_rate.quote.amount = 2500; // CoinMarketCap approx value
@ -1964,6 +1954,74 @@ void database::perform_son_tasks()
gpo.pending_parameters->extensions.value.btc_asset = btc_asset.get_id();
});
}
// create HBD asset here because son_account is the issuer of the HBD
if (gpo.parameters.hbd_asset() == asset_id_type() && head_block_time() >= HARDFORK_SON_FOR_HIVE_TIME)
{
const asset_dynamic_data_object& dyn_asset =
create<asset_dynamic_data_object>([](asset_dynamic_data_object& a) {
a.current_supply = 0;
});
const asset_object& hbd_asset =
create<asset_object>( [&gpo, &dyn_asset]( asset_object& a ) {
a.symbol = "HBD";
a.precision = 3;
a.issuer = gpo.parameters.son_account();
a.options.max_supply = GRAPHENE_MAX_SHARE_SUPPLY;
a.options.market_fee_percent = 500; // 5%
a.options.issuer_permissions = UIA_ASSET_ISSUER_PERMISSION_MASK;
a.options.flags = asset_issuer_permission_flags::charge_market_fee |
asset_issuer_permission_flags::override_authority;
a.options.core_exchange_rate.base.amount = 100000;
a.options.core_exchange_rate.base.asset_id = asset_id_type(0);
a.options.core_exchange_rate.quote.amount = 2500; // CoinMarketCap approx value
a.options.core_exchange_rate.quote.asset_id = a.id;
a.options.whitelist_authorities.clear(); // accounts allowed to use asset, if not empty
a.options.blacklist_authorities.clear(); // accounts who can blacklist other accounts to use asset, if white_list flag is set
a.options.whitelist_markets.clear(); // might be traded with
a.options.blacklist_markets.clear(); // might not be traded with
a.dynamic_asset_data_id = dyn_asset.id;
});
modify( gpo, [&hbd_asset]( global_property_object& gpo ) {
gpo.parameters.extensions.value.hbd_asset = hbd_asset.get_id();
if( gpo.pending_parameters )
gpo.pending_parameters->extensions.value.hbd_asset = hbd_asset.get_id();
});
}
// create HIVE asset here because son_account is the issuer of the HIVE
if (gpo.parameters.hive_asset() == asset_id_type() && head_block_time() >= HARDFORK_SON_FOR_HIVE_TIME)
{
const asset_dynamic_data_object& dyn_asset =
create<asset_dynamic_data_object>([](asset_dynamic_data_object& a) {
a.current_supply = 0;
});
const asset_object& hive_asset =
create<asset_object>( [&gpo, &dyn_asset]( asset_object& a ) {
a.symbol = "HIVE";
a.precision = 3;
a.issuer = gpo.parameters.son_account();
a.options.max_supply = GRAPHENE_MAX_SHARE_SUPPLY;
a.options.market_fee_percent = 500; // 5%
a.options.issuer_permissions = UIA_ASSET_ISSUER_PERMISSION_MASK;
a.options.flags = asset_issuer_permission_flags::charge_market_fee |
asset_issuer_permission_flags::override_authority;
a.options.core_exchange_rate.base.amount = 100000;
a.options.core_exchange_rate.base.asset_id = asset_id_type(0);
a.options.core_exchange_rate.quote.amount = 2500; // CoinMarketCap approx value
a.options.core_exchange_rate.quote.asset_id = a.id;
a.options.whitelist_authorities.clear(); // accounts allowed to use asset, if not empty
a.options.blacklist_authorities.clear(); // accounts who can blacklist other accounts to use asset, if white_list flag is set
a.options.whitelist_markets.clear(); // might be traded with
a.options.blacklist_markets.clear(); // might not be traded with
a.dynamic_asset_data_id = dyn_asset.id;
});
modify( gpo, [&hive_asset]( global_property_object& gpo ) {
gpo.parameters.extensions.value.hive_asset = hive_asset.get_id();
if( gpo.pending_parameters )
gpo.pending_parameters->extensions.value.hive_asset = hive_asset.get_id();
});
}
// Pay the SONs
if (head_block_time() >= HARDFORK_SON_TIME)
{
@ -2024,7 +2082,7 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
balance_type = vesting_balance_type::gpos;
const vesting_balance_index& vesting_index = d.get_index_type<vesting_balance_index>();
#ifdef USE_VESTING_OBJECT_BY_ASSET_BALANCE_INDEX
auto vesting_balances_begin =
vesting_index.indices().get<by_asset_balance>().lower_bound(boost::make_tuple(asset_id_type(), balance_type));
auto vesting_balances_end =
@ -2036,19 +2094,7 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
("owner", vesting_balance_obj.owner(d).name)
("amount", vesting_balance_obj.balance.amount));
}
#else
const auto& vesting_balances = vesting_index.indices().get<by_id>();
for (const vesting_balance_object& vesting_balance_obj : vesting_balances)
{
if (vesting_balance_obj.balance.asset_id == asset_id_type() && vesting_balance_obj.balance.amount && vesting_balance_obj.balance_type == balance_type)
{
vesting_amounts[vesting_balance_obj.owner] += vesting_balance_obj.balance.amount;
dlog("Vesting balance for account: ${owner}, amount: ${amount}",
("owner", vesting_balance_obj.owner(d).name)
("amount", vesting_balance_obj.balance.amount));
}
}
#endif
}
void operator()( const account_object& stake_account, const account_statistics_object& stats )
@ -2145,7 +2191,7 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
}
}
} tally_helper(*this, gpo);
perform_account_maintenance( tally_helper );
struct clear_canary {
clear_canary(vector<uint64_t>& target): target(target){}
@ -2191,7 +2237,7 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
if( !p.pending_parameters->extensions.value.gpos_subperiod.valid() )
p.pending_parameters->extensions.value.gpos_subperiod = p.parameters.extensions.value.gpos_subperiod;
if( !p.pending_parameters->extensions.value.gpos_vesting_lockin_period.valid() )
p.pending_parameters->extensions.value.gpos_vesting_lockin_period = p.parameters.extensions.value.gpos_vesting_lockin_period;
p.pending_parameters->extensions.value.gpos_vesting_lockin_period = p.parameters.extensions.value.gpos_vesting_lockin_period;
if( !p.pending_parameters->extensions.value.rbac_max_permissions_per_account.valid() )
p.pending_parameters->extensions.value.rbac_max_permissions_per_account = p.parameters.extensions.value.rbac_max_permissions_per_account;
if( !p.pending_parameters->extensions.value.rbac_max_account_authority_lifetime.valid() )
@ -2224,6 +2270,10 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
p.pending_parameters->extensions.value.btc_asset = p.parameters.extensions.value.btc_asset;
if( !p.pending_parameters->extensions.value.maximum_son_count.valid() )
p.pending_parameters->extensions.value.maximum_son_count = p.parameters.extensions.value.maximum_son_count;
if( !p.pending_parameters->extensions.value.hbd_asset.valid() )
p.pending_parameters->extensions.value.hbd_asset = p.parameters.extensions.value.hbd_asset;
if( !p.pending_parameters->extensions.value.hive_asset.valid() )
p.pending_parameters->extensions.value.hive_asset = p.parameters.extensions.value.hive_asset;
p.parameters = std::move(*p.pending_parameters);
p.pending_parameters.reset();
}

View file

@ -28,6 +28,7 @@
#include <graphene/chain/witness_schedule_object.hpp>
#include <graphene/chain/special_authority_object.hpp>
#include <graphene/chain/operation_history_object.hpp>
#include <graphene/chain/nft_object.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <fc/io/fstream.hpp>
@ -107,7 +108,6 @@ void database::reindex( fc::path data_dir )
ilog( "reindexing blockchain" );
auto start = fc::time_point::now();
const auto last_block_num = last_block->block_num();
uint32_t flush_point = last_block_num < 10000 ? 0 : last_block_num - 10000;
uint32_t undo_point = last_block_num < 50 ? 0 : last_block_num - 50;
ilog( "Replaying blocks, starting at ${next}...", ("next",head_block_num() + 1) );
@ -123,8 +123,7 @@ void database::reindex( fc::path data_dir )
}
for( uint32_t i = head_block_num() + 1; i <= last_block_num; ++i )
{
if( i % 10000 == 0 ) std::cerr << " " << double(i*100)/last_block_num << "% "<<i << " of " <<last_block_num<<" \n";
if( i == flush_point )
if( i % 10000 == 0 )
{
ilog( "Writing database to disk at block ${i}", ("i",i) );
flush();
@ -244,7 +243,7 @@ void database::close(bool rewind)
{
if (!_opened)
return;
// TODO: Save pending tx's on close()
clear_pending();
@ -294,7 +293,7 @@ void database::force_slow_replays()
void database::check_ending_lotteries()
{
try {
const auto& lotteries_idx = get_index_type<asset_index>().indices().get<active_lotteries>();
const auto& lotteries_idx = get_index_type<asset_index>().indices().get<active_lotteries>();
for( auto checking_asset: lotteries_idx )
{
FC_ASSERT( checking_asset.is_lottery() );
@ -306,6 +305,24 @@ void database::check_ending_lotteries()
} catch( ... ) {}
}
void database::check_ending_nft_lotteries()
{
try {
const auto &nft_lotteries_idx = get_index_type<nft_metadata_index>().indices().get<active_nft_lotteries>();
for (auto checking_token : nft_lotteries_idx)
{
FC_ASSERT(checking_token.is_lottery());
const auto &lottery_options = checking_token.lottery_data->lottery_options;
FC_ASSERT(lottery_options.is_active);
// Check the current supply of lottery tokens
auto current_supply = checking_token.get_token_current_supply(*this);
if ((lottery_options.ending_on_soldout && (current_supply == checking_token.max_supply)) ||
(lottery_options.end_date != time_point_sec() && (lottery_options.end_date <= head_block_time())))
checking_token.end_lottery(*this);
}
} catch( ... ) {}
}
void database::check_lottery_end_by_participants( asset_id_type asset_id )
{
try {

View file

@ -24,6 +24,7 @@
#include <fc/container/flat.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/protocol/authority.hpp>
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/chain/protocol/transaction.hpp>
@ -41,6 +42,10 @@
#include <graphene/chain/transaction_object.hpp>
#include <graphene/chain/impacted.hpp>
#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/account_object.hpp>
#include <graphene/chain/account_role_object.hpp>
#include <graphene/chain/son_object.hpp>
#include <graphene/chain/sidechain_address_object.hpp>
using namespace fc;
@ -359,6 +364,13 @@ struct get_impacted_account_visitor
void operator()( const account_role_delete_operation& op ){
_impacted.insert( op.owner );
}
void operator()( const nft_lottery_token_purchase_operation& op ){
_impacted.insert( op.buyer );
}
void operator()( const nft_lottery_reward_operation& op ) {
_impacted.insert( op.winner );
}
void operator()( const nft_lottery_end_operation& op ) {}
void operator()( const son_create_operation& op ) {
_impacted.insert( op.owner_account );
}
@ -416,6 +428,9 @@ struct get_impacted_account_visitor
void operator()( const sidechain_transaction_settle_operation& op ) {
_impacted.insert( op.payer );
}
void operator()( const random_number_store_operation& op ) {
_impacted.insert( op.account );
}
};
void graphene::chain::operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result, bool ignore_custom_operation_required_auths ) {
@ -528,6 +543,9 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
} case sidechain_transaction_object_type:{
break;
}
default: {
break;
}
}
}
else if( obj->id.space() == implementation_ids )
@ -582,6 +600,10 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
break;
case impl_fba_accumulator_object_type:
break;
case impl_nft_lottery_balance_object_type:
break;
default:
break;
}
}
} // end get_relevant_accounts( const object* obj, flat_set<account_id_type>& accounts )

View file

@ -26,16 +26,18 @@
#include <graphene/chain/db_with.hpp>
#include <graphene/chain/asset_object.hpp>
#include <graphene/chain/betting_market_object.hpp>
#include <graphene/chain/game_object.hpp>
#include <graphene/chain/global_property_object.hpp>
#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/market_object.hpp>
#include <graphene/chain/offer_object.hpp>
#include <graphene/chain/proposal_object.hpp>
#include <graphene/chain/son_proposal_object.hpp>
#include <graphene/chain/tournament_object.hpp>
#include <graphene/chain/transaction_object.hpp>
#include <graphene/chain/withdraw_permission_object.hpp>
#include <graphene/chain/witness_object.hpp>
#include <graphene/chain/tournament_object.hpp>
#include <graphene/chain/game_object.hpp>
#include <graphene/chain/betting_market_object.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
@ -46,7 +48,6 @@ namespace graphene { namespace chain {
void database::update_global_dynamic_data( const signed_block& b, const uint32_t missed_blocks )
{
const dynamic_global_property_object& _dgp = get_dynamic_global_properties();
const global_property_object& gpo = get_global_properties();
// dynamic global properties updating
modify( _dgp, [&b,this,missed_blocks]( dynamic_global_property_object& dgp ){

View file

@ -1,4 +1,4 @@
// GPOS HARDFORK 2020-12-21 00:00:00 GMT
// NFT HARDFORK 2020-12-21 00:00:00 GMT
#ifndef HARDFORK_NFT_TIME
#define HARDFORK_NFT_TIME (fc::time_point_sec( 1608508800 ))
#endif
#endif

View file

@ -1,4 +1,4 @@
// GPOS HARDFORK 2020-12-21 00:00:00 GMT
// SON HARDFORK HARDFORK 2020-12-21 00:00:00 GMT
#ifndef HARDFORK_SON_TIME
#define HARDFORK_SON_TIME (fc::time_point_sec( 1608508800 ))
#endif

View file

@ -0,0 +1,4 @@
// Saturday, December 11, 2021 0:00:00
#ifndef HARDFORK_SON_FOR_HIVE_TIME
#define HARDFORK_SON_FOR_HIVE_TIME (fc::time_point_sec( 1639180800 ))
#endif

View file

@ -46,4 +46,4 @@ namespace graphene
} // namespace graphene
FC_REFLECT_DERIVED(graphene::chain::account_role_object, (graphene::db::object),
(owner)(name)(metadata)(allowed_operations)(whitelisted_accounts)(valid_to))
(owner)(name)(metadata)(allowed_operations)(whitelisted_accounts)(valid_to))

View file

@ -286,6 +286,7 @@ namespace graphene { namespace chain {
void check_lottery_end_by_participants( asset_id_type asset_id );
void check_ending_lotteries();
void check_ending_nft_lotteries();
//////////////////// db_getter.cpp ////////////////////
@ -325,6 +326,7 @@ namespace graphene { namespace chain {
uint32_t last_non_undoable_block_num() const;
vector<authority> get_account_custom_authorities(account_id_type account, const operation& op)const;
vector<uint64_t> get_random_numbers(uint64_t minimum, uint64_t maximum, uint64_t selections, bool duplicates);
//////////////////// db_init.cpp ////////////////////
void initialize_evaluators();

View file

@ -37,7 +37,7 @@ class global_betting_statistics_object : public graphene::db::abstract_object< g
static const uint8_t space_id = implementation_ids;
static const uint8_t type_id = impl_global_betting_statistics_object_type;
uint32_t number_of_active_events;
uint32_t number_of_active_events = 0;
map<asset_id_type, share_type> total_amount_staked;
};

View file

@ -38,4 +38,4 @@ void transaction_get_impacted_accounts( const graphene::chain::transaction& tx,
fc::flat_set<graphene::chain::account_id_type>& result,
bool ignore_custom_operation_required_auths );
} } // graphene::app
} } // graphene::app

View file

@ -0,0 +1,39 @@
#pragma once
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/database.hpp>
namespace graphene
{
namespace chain
{
class nft_lottery_token_purchase_evaluator : public evaluator<nft_lottery_token_purchase_evaluator>
{
public:
typedef nft_lottery_token_purchase_operation operation_type;
void_result do_evaluate(const nft_lottery_token_purchase_operation &o);
object_id_type do_apply(const nft_lottery_token_purchase_operation &o);
};
class nft_lottery_reward_evaluator : public evaluator<nft_lottery_reward_evaluator>
{
public:
typedef nft_lottery_reward_operation operation_type;
void_result do_evaluate(const nft_lottery_reward_operation &o);
void_result do_apply(const nft_lottery_reward_operation &o);
};
class nft_lottery_end_evaluator : public evaluator<nft_lottery_end_evaluator>
{
public:
typedef nft_lottery_end_operation operation_type;
void_result do_evaluate(const nft_lottery_end_operation &o);
void_result do_apply(const nft_lottery_end_operation &o);
};
} // namespace chain
} // namespace graphene

View file

@ -6,6 +6,29 @@
namespace graphene { namespace chain {
using namespace graphene::db;
class nft_lottery_balance_object : public abstract_object<nft_lottery_balance_object>
{
public:
static const uint8_t space_id = implementation_ids;
static const uint8_t type_id = impl_nft_lottery_balance_object_type;
// Total Progressive jackpot carried over from previous lotteries
asset total_progressive_jackpot;
// Current total jackpot in this lottery inclusive of the progressive jackpot
asset jackpot;
// Total tickets sold
share_type sweeps_tickets_sold;
};
struct nft_lottery_data
{
nft_lottery_data() {}
nft_lottery_data(const nft_lottery_options &options, nft_lottery_balance_id_type lottery_id)
: lottery_options(options), lottery_balance_id(lottery_id) {}
nft_lottery_options lottery_options;
nft_lottery_balance_id_type lottery_balance_id;
};
class nft_metadata_object : public abstract_object<nft_metadata_object>
{
public:
@ -21,6 +44,21 @@ namespace graphene { namespace chain {
bool is_transferable = false;
bool is_sellable = true;
optional<account_role_id_type> account_role;
share_type max_supply = GRAPHENE_MAX_SHARE_SUPPLY;
optional<nft_lottery_data> lottery_data;
nft_metadata_id_type get_id() const { return id; }
bool is_lottery() const { return lottery_data.valid(); }
uint32_t get_owner_num() const { return owner.instance.value; }
time_point_sec get_lottery_expiration() const;
asset get_lottery_jackpot(const database &db) const;
share_type get_token_current_supply(const database &db) const;
vector<account_id_type> get_holders(const database &db) const;
vector<uint64_t> get_ticket_ids(const database &db) const;
void distribute_benefactors_part(database &db);
map<account_id_type, vector<uint16_t>> distribute_winners_part(database &db);
void distribute_sweeps_holders_part(database &db);
void end_lottery(database &db);
};
class nft_object : public abstract_object<nft_object>
@ -36,8 +74,23 @@ namespace graphene { namespace chain {
std::string token_uri;
};
struct nft_lottery_comparer
{
bool operator()(const nft_metadata_object& lhs, const nft_metadata_object& rhs) const
{
if ( !lhs.is_lottery() ) return false;
if ( !lhs.lottery_data->lottery_options.is_active && !rhs.is_lottery()) return true; // not active lotteries first, just assets then
if ( !lhs.lottery_data->lottery_options.is_active ) return false;
if ( lhs.lottery_data->lottery_options.is_active && ( !rhs.is_lottery() || !rhs.lottery_data->lottery_options.is_active ) ) return true;
return lhs.get_lottery_expiration() > rhs.get_lottery_expiration();
}
};
struct by_name;
struct by_symbol;
struct active_nft_lotteries;
struct by_nft_lottery;
struct by_nft_lottery_owner;
using nft_metadata_multi_index_type = multi_index_container<
nft_metadata_object,
indexed_by<
@ -49,6 +102,34 @@ namespace graphene { namespace chain {
>,
ordered_unique< tag<by_symbol>,
member<nft_metadata_object, std::string, &nft_metadata_object::symbol>
>,
ordered_non_unique< tag<active_nft_lotteries>,
identity< nft_metadata_object >,
nft_lottery_comparer
>,
ordered_unique< tag<by_nft_lottery>,
composite_key<
nft_metadata_object,
const_mem_fun<nft_metadata_object, bool, &nft_metadata_object::is_lottery>,
member<object, object_id_type, &object::id>
>,
composite_key_compare<
std::greater< bool >,
std::greater< object_id_type >
>
>,
ordered_unique< tag<by_nft_lottery_owner>,
composite_key<
nft_metadata_object,
const_mem_fun<nft_metadata_object, bool, &nft_metadata_object::is_lottery>,
const_mem_fun<nft_metadata_object, uint32_t, &nft_metadata_object::get_owner_num>,
member<object, object_id_type, &object::id>
>,
composite_key_compare<
std::greater< bool >,
std::greater< uint32_t >,
std::greater< object_id_type >
>
>
>
>;
@ -86,8 +167,23 @@ namespace graphene { namespace chain {
>;
using nft_index = generic_index<nft_object, nft_multi_index_type>;
using nft_lottery_balance_index_type = multi_index_container<
nft_lottery_balance_object,
indexed_by<
ordered_unique< tag<by_id>, member< object, object_id_type, &object::id > >
>
>;
using nft_lottery_balance_index = generic_index<nft_lottery_balance_object, nft_lottery_balance_index_type>;
} } // graphene::chain
FC_REFLECT_DERIVED( graphene::chain::nft_lottery_balance_object, (graphene::db::object),
(total_progressive_jackpot)
(jackpot)
(sweeps_tickets_sold) )
FC_REFLECT( graphene::chain::nft_lottery_data, (lottery_options)(lottery_balance_id) )
FC_REFLECT_DERIVED( graphene::chain::nft_metadata_object, (graphene::db::object),
(owner)
(name)
@ -97,7 +193,9 @@ FC_REFLECT_DERIVED( graphene::chain::nft_metadata_object, (graphene::db::object)
(revenue_split)
(is_transferable)
(is_sellable)
(account_role) )
(account_role)
(max_supply)
(lottery_data) )
FC_REFLECT_DERIVED( graphene::chain::nft_object, (graphene::db::object),
(nft_metadata_id)

View file

@ -68,6 +68,8 @@ namespace graphene { namespace chain {
optional < account_id_type > son_account = GRAPHENE_NULL_ACCOUNT;
optional < asset_id_type > btc_asset = asset_id_type();
optional < uint16_t > maximum_son_count = GRAPHENE_DEFAULT_MAX_SONS; ///< maximum number of active SONS
optional < asset_id_type > hbd_asset = asset_id_type();
optional < asset_id_type > hive_asset = asset_id_type();
};
struct chain_parameters
@ -212,6 +214,12 @@ namespace graphene { namespace chain {
inline uint16_t maximum_son_count()const {
return extensions.value.maximum_son_count.valid() ? *extensions.value.maximum_son_count : GRAPHENE_DEFAULT_MAX_SONS;
}
inline asset_id_type hbd_asset() const {
return extensions.value.hbd_asset.valid() ? *extensions.value.hbd_asset : asset_id_type();
}
inline asset_id_type hive_asset() const {
return extensions.value.hive_asset.valid() ? *extensions.value.hive_asset : asset_id_type();
}
private:
static void safe_copy(chain_parameters& to, const chain_parameters& from);
};
@ -247,6 +255,8 @@ FC_REFLECT( graphene::chain::parameter_extension,
(son_account)
(btc_asset)
(maximum_son_count)
(hbd_asset)
(hive_asset)
)
FC_REFLECT( graphene::chain::chain_parameters,

View file

@ -0,0 +1,86 @@
#pragma once
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/protocol/types.hpp>
namespace graphene
{
namespace chain
{
struct nft_lottery_token_purchase_operation : public base_operation
{
struct fee_parameters_type
{
uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION;
};
asset fee;
// Lottery NFT Metadata
nft_metadata_id_type lottery_id;
// Buyer purchasing lottery tickets
account_id_type buyer;
// count of tickets to buy
uint64_t tickets_to_buy;
// amount that can spent
asset amount;
extensions_type extensions;
account_id_type fee_payer() const { return buyer; }
void validate() const;
share_type calculate_fee(const fee_parameters_type &k) const;
};
struct nft_lottery_reward_operation : public base_operation
{
struct fee_parameters_type
{
uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION;
};
asset fee;
// Lottery NFT Metadata
nft_metadata_id_type lottery_id;
// winner account
account_id_type winner;
// amount that won
asset amount;
// percentage of jackpot that user won
uint16_t win_percentage;
// true if recieved from benefators section of lottery; false otherwise
bool is_benefactor_reward;
uint64_t winner_ticket_id;
extensions_type extensions;
account_id_type fee_payer() const { return account_id_type(); }
void validate() const {};
share_type calculate_fee(const fee_parameters_type &k) const { return k.fee; };
};
struct nft_lottery_end_operation : public base_operation
{
struct fee_parameters_type
{
uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION;
};
asset fee;
// Lottery NFT Metadata
nft_metadata_id_type lottery_id;
extensions_type extensions;
account_id_type fee_payer() const { return account_id_type(); }
void validate() const {}
share_type calculate_fee(const fee_parameters_type &k) const { return k.fee; }
};
} // namespace chain
} // namespace graphene
FC_REFLECT(graphene::chain::nft_lottery_token_purchase_operation::fee_parameters_type, (fee))
FC_REFLECT(graphene::chain::nft_lottery_reward_operation::fee_parameters_type, (fee))
FC_REFLECT(graphene::chain::nft_lottery_end_operation::fee_parameters_type, (fee))
FC_REFLECT(graphene::chain::nft_lottery_token_purchase_operation, (fee)(lottery_id)(buyer)(tickets_to_buy)(amount)(extensions))
FC_REFLECT(graphene::chain::nft_lottery_reward_operation, (fee)(lottery_id)(winner)(amount)(win_percentage)(is_benefactor_reward)(winner_ticket_id)(extensions))
FC_REFLECT(graphene::chain::nft_lottery_end_operation, (fee)(lottery_id)(extensions))

View file

@ -4,6 +4,29 @@
namespace graphene { namespace chain {
struct nft_lottery_benefactor {
account_id_type id;
uint16_t share; // percent * GRAPHENE_1_PERCENT
nft_lottery_benefactor() = default;
nft_lottery_benefactor( const nft_lottery_benefactor & ) = default;
nft_lottery_benefactor( account_id_type _id, uint16_t _share ) : id( _id ), share( _share ) {}
};
struct nft_lottery_options
{
std::vector<nft_lottery_benefactor> benefactors;
// specifying winning tickets as shares that will be issued
std::vector<uint16_t> winning_tickets;
asset ticket_price;
time_point_sec end_date;
bool ending_on_soldout;
bool is_active;
bool delete_tickets_after_draw = false;
std::vector<nft_metadata_id_type> progressive_jackpots;
void validate() const;
};
struct nft_metadata_create_operation : public base_operation
{
struct fee_parameters_type
@ -23,6 +46,10 @@ namespace graphene { namespace chain {
bool is_sellable = true;
// Accounts Role
optional<account_role_id_type> account_role;
// Max number of NFTs that can be minted from the metadata
optional<share_type> max_supply;
// Lottery configuration
optional<nft_lottery_options> lottery_options;
extensions_type extensions;
account_id_type fee_payer()const { return owner; }
@ -133,6 +160,9 @@ namespace graphene { namespace chain {
} } // graphene::chain
FC_REFLECT( graphene::chain::nft_lottery_benefactor, (id)(share) )
FC_REFLECT( graphene::chain::nft_lottery_options, (benefactors)(winning_tickets)(ticket_price)(end_date)(ending_on_soldout)(is_active)(delete_tickets_after_draw)(progressive_jackpots) )
FC_REFLECT( graphene::chain::nft_metadata_create_operation::fee_parameters_type, (fee) (price_per_kbyte) )
FC_REFLECT( graphene::chain::nft_metadata_update_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::nft_mint_operation::fee_parameters_type, (fee) (price_per_kbyte) )
@ -140,7 +170,7 @@ FC_REFLECT( graphene::chain::nft_safe_transfer_from_operation::fee_parameters_ty
FC_REFLECT( graphene::chain::nft_approve_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::nft_set_approval_for_all_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::nft_metadata_create_operation, (fee) (owner) (name) (symbol) (base_uri) (revenue_partner) (revenue_split) (is_transferable) (is_sellable) (account_role) (extensions) )
FC_REFLECT( graphene::chain::nft_metadata_create_operation, (fee) (owner) (name) (symbol) (base_uri) (revenue_partner) (revenue_split) (is_transferable) (is_sellable) (account_role) (max_supply) (lottery_options) (extensions) )
FC_REFLECT( graphene::chain::nft_metadata_update_operation, (fee) (owner) (nft_metadata_id) (name) (symbol) (base_uri) (revenue_partner) (revenue_split) (is_transferable) (is_sellable) (account_role) (extensions) )
FC_REFLECT( graphene::chain::nft_mint_operation, (fee) (payer) (nft_metadata_id) (owner) (approved) (approved_operators) (token_uri) (extensions) )
FC_REFLECT( graphene::chain::nft_safe_transfer_from_operation, (fee) (operator_) (from) (to) (token_id) (data) (extensions) )

View file

@ -50,12 +50,14 @@
#include <graphene/chain/protocol/offer.hpp>
#include <graphene/chain/protocol/nft_ops.hpp>
#include <graphene/chain/protocol/account_role.hpp>
#include <graphene/chain/protocol/nft_lottery.hpp>
#include <graphene/chain/protocol/son.hpp>
#include <graphene/chain/protocol/sidechain_address.hpp>
#include <graphene/chain/protocol/son_wallet.hpp>
#include <graphene/chain/protocol/son_wallet_deposit.hpp>
#include <graphene/chain/protocol/son_wallet_withdraw.hpp>
#include <graphene/chain/protocol/sidechain_transaction.hpp>
#include <graphene/chain/protocol/random_number.hpp>
namespace graphene { namespace chain {
@ -184,7 +186,11 @@ namespace graphene { namespace chain {
sidechain_transaction_create_operation,
sidechain_transaction_sign_operation,
sidechain_transaction_send_operation,
sidechain_transaction_settle_operation
sidechain_transaction_settle_operation,
nft_lottery_token_purchase_operation,
nft_lottery_reward_operation,
nft_lottery_end_operation,
random_number_store_operation
> operation;
/// @} // operations group

View file

@ -0,0 +1,25 @@
#pragma once
namespace graphene { namespace chain {
struct random_number_store_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 5000 * GRAPHENE_BLOCKCHAIN_PRECISION; };
asset fee;
account_id_type account;
vector<uint64_t> random_number;
std::string data;
account_id_type fee_payer()const { return account; }
};
} } // graphene::chain
FC_REFLECT( graphene::chain::random_number_store_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::random_number_store_operation, (fee)
(account)
(random_number)
(data) )

View file

@ -183,6 +183,7 @@ namespace graphene { namespace chain {
son_wallet_withdraw_object_type,
sidechain_address_object_type,
sidechain_transaction_object_type,
random_number_object_type,
OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types
};
@ -214,7 +215,8 @@ namespace graphene { namespace chain {
impl_sweeps_vesting_balance_object_type,
impl_offer_history_object_type,
impl_son_statistics_object_type,
impl_son_schedule_object_type
impl_son_schedule_object_type,
impl_nft_lottery_balance_object_type
};
//typedef fc::unsigned_int object_id_type;
@ -258,6 +260,7 @@ namespace graphene { namespace chain {
class son_wallet_withdraw_object;
class sidechain_address_object;
class sidechain_transaction_object;
class random_number_object;
typedef object_id< protocol_ids, account_object_type, account_object> account_id_type;
typedef object_id< protocol_ids, asset_object_type, asset_object> asset_id_type;
@ -297,6 +300,7 @@ namespace graphene { namespace chain {
typedef object_id< protocol_ids, son_wallet_withdraw_object_type, son_wallet_withdraw_object> son_wallet_withdraw_id_type;
typedef object_id< protocol_ids, sidechain_address_object_type, sidechain_address_object> sidechain_address_id_type;
typedef object_id< protocol_ids, sidechain_transaction_object_type,sidechain_transaction_object> sidechain_transaction_id_type;
typedef object_id< protocol_ids, random_number_object_type, random_number_object> random_number_id_type;
// implementation types
class global_property_object;
@ -321,6 +325,7 @@ namespace graphene { namespace chain {
class lottery_balance_object;
class sweeps_vesting_balance_object;
class offer_history_object;
class nft_lottery_balance_object;
class son_statistics_object;
class son_schedule_object;
@ -352,6 +357,7 @@ namespace graphene { namespace chain {
typedef object_id< implementation_ids, impl_lottery_balance_object_type, lottery_balance_object > lottery_balance_id_type;
typedef object_id< implementation_ids, impl_sweeps_vesting_balance_object_type, sweeps_vesting_balance_object> sweeps_vesting_balance_id_type;
typedef object_id< implementation_ids, impl_offer_history_object_type, offer_history_object> offer_history_id_type;
typedef object_id< implementation_ids, impl_nft_lottery_balance_object_type, nft_lottery_balance_object> nft_lottery_balance_id_type;
typedef object_id< implementation_ids, impl_son_statistics_object_type, son_statistics_object > son_statistics_id_type;
typedef object_id< implementation_ids, impl_son_schedule_object_type, son_schedule_object> son_schedule_id_type;
@ -496,6 +502,7 @@ FC_REFLECT_ENUM( graphene::chain::object_type,
(son_wallet_withdraw_object_type)
(sidechain_address_object_type)
(sidechain_transaction_object_type)
(random_number_object_type)
(OBJECT_TYPE_COUNT)
)
FC_REFLECT_ENUM( graphene::chain::impl_object_type,
@ -526,6 +533,7 @@ FC_REFLECT_ENUM( graphene::chain::impl_object_type,
(impl_offer_history_object_type)
(impl_son_statistics_object_type)
(impl_son_schedule_object_type)
(impl_nft_lottery_balance_object_type)
)
FC_REFLECT_TYPENAME( graphene::chain::share_type )
@ -575,6 +583,7 @@ FC_REFLECT_TYPENAME( graphene::chain::offer_history_id_type )
FC_REFLECT_TYPENAME( graphene::chain::nft_metadata_id_type )
FC_REFLECT_TYPENAME( graphene::chain::nft_id_type )
FC_REFLECT_TYPENAME( graphene::chain::account_role_id_type )
FC_REFLECT_TYPENAME( graphene::chain::nft_lottery_balance_id_type )
FC_REFLECT_TYPENAME( graphene::chain::son_id_type )
FC_REFLECT_TYPENAME( graphene::chain::son_proposal_id_type )
FC_REFLECT_TYPENAME( graphene::chain::son_wallet_id_type )
@ -582,7 +591,7 @@ FC_REFLECT_TYPENAME( graphene::chain::son_wallet_deposit_id_type )
FC_REFLECT_TYPENAME( graphene::chain::son_wallet_withdraw_id_type )
FC_REFLECT_TYPENAME( graphene::chain::sidechain_address_id_type )
FC_REFLECT_TYPENAME( graphene::chain::sidechain_transaction_id_type )
FC_REFLECT_TYPENAME( graphene::chain::random_number_id_type )
FC_REFLECT( graphene::chain::void_t, )

View file

@ -0,0 +1,19 @@
#pragma once
#include <graphene/chain/database.hpp>
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/chain/protocol/types.hpp>
namespace graphene { namespace chain {
class random_number_store_evaluator : public evaluator<random_number_store_evaluator>
{
public:
typedef random_number_store_operation operation_type;
void_result do_evaluate( const random_number_store_operation& o );
object_id_type do_apply( const random_number_store_operation& o );
};
} } // graphene::chain

View file

@ -0,0 +1,41 @@
#pragma once
namespace graphene { namespace chain {
using namespace graphene::db;
class random_number_object : public abstract_object<random_number_object>
{
public:
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = random_number_object_type;
account_id_type account; /* account who requested random number */
time_point_sec timestamp; /* date and time when the number is read */
vector<uint64_t> random_number; /* random number(s) */
std::string data; /* custom data in json format */
};
struct by_account;
struct by_timestamp;
using random_number_multi_index_type = multi_index_container<
random_number_object,
indexed_by<
ordered_unique< tag<by_id>,
member<object, object_id_type, &object::id>
>,
ordered_non_unique< tag<by_account>,
member<random_number_object, account_id_type, &random_number_object::account>
>,
ordered_non_unique< tag<by_timestamp>,
member<random_number_object, time_point_sec, &random_number_object::timestamp>
>
>
>;
using random_number_index = generic_index<random_number_object, random_number_multi_index_type>;
} } // graphene::chain
FC_REFLECT_DERIVED( graphene::chain::random_number_object, (graphene::db::object),
(account) (timestamp)
(random_number) (data) )

View file

@ -57,6 +57,9 @@ namespace graphene
case operation::tag<account_role_create_operation>::value:
case operation::tag<account_role_update_operation>::value:
case operation::tag<account_role_delete_operation>::value:
case operation::tag<nft_lottery_token_purchase_operation>::value:
case operation::tag<nft_lottery_reward_operation>::value:
case operation::tag<nft_lottery_end_operation>::value:
FC_ASSERT(block_time >= HARDFORK_NFT_TIME, "Custom permissions and roles not allowed on this operation yet!");
break;
default:

View file

@ -9,7 +9,8 @@ enum class sidechain_type {
bitcoin,
ethereum,
eos,
peerplays
peerplays,
hive
};
} }
@ -19,4 +20,5 @@ FC_REFLECT_ENUM(graphene::chain::sidechain_type,
(bitcoin)
(ethereum)
(eos)
(hive)
(peerplays) )

View file

@ -26,7 +26,8 @@ namespace graphene { namespace chain {
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = sidechain_transaction_object_type;
sidechain_type sidechain;
time_point_sec timestamp;
sidechain_type sidechain = sidechain_type::unknown;
object_id_type object_id;
std::string transaction;
std::vector<son_info> signers;
@ -37,7 +38,7 @@ namespace graphene { namespace chain {
uint32_t current_weight = 0;
uint32_t threshold = 0;
sidechain_transaction_status status;
sidechain_transaction_status status = sidechain_transaction_status::invalid;
};
struct by_object_id;
@ -70,6 +71,7 @@ FC_REFLECT_ENUM( graphene::chain::sidechain_transaction_status,
(settled) )
FC_REFLECT_DERIVED( graphene::chain::sidechain_transaction_object, (graphene::db::object ),
(timestamp)
(sidechain)
(object_id)
(transaction)

View file

@ -31,9 +31,9 @@ namespace graphene { namespace chain {
son_id_type owner;
// Lifetime total transactions signed
uint64_t total_txs_signed = 0;
flat_map<sidechain_type, uint64_t> total_txs_signed;
// Transactions signed since the last son payouts
uint64_t txs_signed = 0;
flat_map<sidechain_type, uint64_t> txs_signed;
// Total Voted Active time i.e. duration selected as part of voted active SONs
uint64_t total_voted_time = 0;
// Total Downtime barring the current down time in seconds, used for stats to present to user
@ -47,9 +47,9 @@ namespace graphene { namespace chain {
// Deregistered Timestamp
fc::time_point_sec deregistered_timestamp;
// Total sidechain transactions reported by SON network while SON was active
uint64_t total_sidechain_txs_reported = 0;
flat_map<sidechain_type, uint64_t> total_sidechain_txs_reported;
// Sidechain transactions reported by this SON
uint64_t sidechain_txs_reported = 0;
flat_map<sidechain_type, uint64_t> sidechain_txs_reported;
};
/**
@ -76,6 +76,7 @@ namespace graphene { namespace chain {
void pay_son_fee(share_type pay, database& db);
bool has_valid_config()const;
bool has_valid_config(time_point_sec head_block_time)const;
};
struct by_account;

View file

@ -200,6 +200,20 @@ namespace graphene { namespace chain {
*/
struct by_account;
struct by_asset_balance;
struct by_asset_balance_helper_asset_id {
typedef asset_id_type result_type;
result_type operator()(const vesting_balance_object& vbo) const {
return vbo.balance.asset_id;
}
};
struct by_asset_balance_helper_asset_amount {
typedef share_type result_type;
result_type operator()(const vesting_balance_object& vbo) const {
return vbo.balance.amount;
}
};
typedef multi_index_container<
vesting_balance_object,
indexed_by<
@ -210,11 +224,9 @@ namespace graphene { namespace chain {
ordered_non_unique< tag<by_asset_balance>,
composite_key<
vesting_balance_object,
member_offset<vesting_balance_object, asset_id_type, (size_t) (offsetof(vesting_balance_object,balance) + offsetof(asset,asset_id))>,
by_asset_balance_helper_asset_id,
member<vesting_balance_object, vesting_balance_type, &vesting_balance_object::balance_type>,
member_offset<vesting_balance_object, share_type, (size_t) (offsetof(vesting_balance_object,balance) + offsetof(asset,amount))>
//member<vesting_balance_object, account_id_type, &vesting_balance_object::owner>
//member_offset<vesting_balance_object, account_id_type, (size_t) (offsetof(vesting_balance_object,owner))>
by_asset_balance_helper_asset_amount
>,
composite_key_compare<
std::less< asset_id_type >,

View file

@ -1,43 +0,0 @@
/*
* Copyright (c) 2015 Cryptonomex, Inc., and contributors.
*
* The MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <fc/io/raw.hpp>
#include <graphene/chain/index.hpp>
#include <graphene/chain/database.hpp>
namespace graphene { namespace chain {
void base_primary_index::save_undo( const object& obj )
{ _db.save_undo( obj ); }
void base_primary_index::on_add( const object& obj )
{
_db.save_undo_add( obj );
for( auto ob : _observers ) ob->on_add( obj );
}
void base_primary_index::on_remove( const object& obj )
{ _db.save_undo_remove( obj ); for( auto ob : _observers ) ob->on_remove( obj ); }
void base_primary_index::on_modify( const object& obj )
{for( auto ob : _observers ) ob->on_modify( obj ); }
} } // graphene::chain

View file

@ -24,6 +24,26 @@ void_result nft_metadata_create_evaluator::do_evaluate( const nft_metadata_creat
const auto& ar_obj = (*op.account_role)(db());
FC_ASSERT(ar_obj.owner == op.owner, "Only the Account Role created by the owner can be attached");
}
// Lottery Related
if (!op.lottery_options) {
return void_result();
}
FC_ASSERT((*op.lottery_options).end_date > now || (*op.lottery_options).end_date == time_point_sec());
if (op.max_supply) {
FC_ASSERT(*op.max_supply >= 5);
}
for(auto lottery_id: (*op.lottery_options).progressive_jackpots) {
const auto& lottery_obj = lottery_id(db());
FC_ASSERT(lottery_obj.owner == op.owner, "Only the Owner can attach progressive jackpots");
FC_ASSERT(lottery_obj.is_lottery(), "Only lottery objects can be attached as progressive jackpots");
FC_ASSERT(lottery_obj.lottery_data->lottery_options.is_active == false, "Lottery should not be active");
FC_ASSERT(lottery_obj.lottery_data->lottery_options.ticket_price.asset_id == (*op.lottery_options).ticket_price.asset_id, "Lottery asset type should be same");
const auto& lottery_balance_obj = lottery_obj.lottery_data->lottery_balance_id(db());
FC_ASSERT(lottery_balance_obj.jackpot.amount > 0, "Non zero progressive jackpot not allowed");
}
return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }
@ -39,6 +59,26 @@ object_id_type nft_metadata_create_evaluator::do_apply( const nft_metadata_creat
obj.is_transferable = op.is_transferable;
obj.is_sellable = op.is_sellable;
obj.account_role = op.account_role;
if (op.max_supply) {
obj.max_supply = *op.max_supply;
}
if (op.lottery_options) {
asset jackpot_sum(0,(*op.lottery_options).ticket_price.asset_id);
for(auto lottery_id: (*op.lottery_options).progressive_jackpots) {
const auto& lottery_obj = lottery_id(db());
const auto& lottery_balance_obj = lottery_obj.lottery_data->lottery_balance_id(db());
FC_ASSERT(lottery_balance_obj.jackpot.amount > 0, "Non zero progressive jackpot not allowed");
db().modify(lottery_balance_obj, [&] ( nft_lottery_balance_object& nlbo ) {
jackpot_sum += nlbo.jackpot;
nlbo.jackpot -= nlbo.jackpot;
});
}
const auto& new_lottery_balance_obj = db().create<nft_lottery_balance_object>([&](nft_lottery_balance_object& nlbo) {
nlbo.total_progressive_jackpot = jackpot_sum;
nlbo.jackpot = jackpot_sum;
});
obj.lottery_data = nft_lottery_data(*op.lottery_options, new_lottery_balance_obj.id);
}
});
return new_nft_metadata_object.id;
} FC_CAPTURE_AND_RETHROW( (op) ) }
@ -110,6 +150,7 @@ void_result nft_mint_evaluator::do_evaluate( const nft_mint_operation& op )
FC_ASSERT( itr_nft_md != idx_nft_md.end(), "NFT metadata not found" );
FC_ASSERT( itr_nft_md->owner == op.payer, "Only metadata owner can mint NFT" );
FC_ASSERT(itr_nft_md->get_token_current_supply(db()) < itr_nft_md->max_supply, "NFTs can't be minted more than max_supply");
return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }

View file

@ -0,0 +1,145 @@
#include <graphene/chain/nft_lottery_evaluator.hpp>
#include <graphene/chain/nft_object.hpp>
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/chain/account_role_object.hpp>
#include <graphene/chain/hardfork.hpp>
namespace graphene
{
namespace chain
{
void_result nft_lottery_token_purchase_evaluator::do_evaluate(const nft_lottery_token_purchase_operation &op)
{
try
{
const database &d = db();
auto now = d.head_block_time();
FC_ASSERT(now >= HARDFORK_NFT_TIME, "Not allowed until NFT HF");
op.buyer(d);
const auto &lottery_md_obj = op.lottery_id(d);
FC_ASSERT(lottery_md_obj.is_lottery(), "Not a lottery type");
if (lottery_md_obj.account_role)
{
const auto &ar_idx = d.get_index_type<account_role_index>().indices().get<by_id>();
auto ar_itr = ar_idx.find(*lottery_md_obj.account_role);
if (ar_itr != ar_idx.end())
{
FC_ASSERT(d.account_role_valid(*ar_itr, op.buyer, get_type()), "Account role not valid");
}
}
auto lottery_options = lottery_md_obj.lottery_data->lottery_options;
FC_ASSERT(lottery_options.ticket_price.asset_id == op.amount.asset_id);
FC_ASSERT((double)op.amount.amount.value / lottery_options.ticket_price.amount.value == (double)op.tickets_to_buy);
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
object_id_type nft_lottery_token_purchase_evaluator::do_apply(const nft_lottery_token_purchase_operation &op)
{
try
{
transaction_evaluation_state nft_mint_context(&db());
nft_mint_context.skip_fee_schedule_check = true;
const auto &lottery_md_obj = op.lottery_id(db());
nft_id_type nft_id;
for (size_t i = 0; i < op.tickets_to_buy; i++)
{
nft_mint_operation mint_op;
mint_op.payer = lottery_md_obj.owner;
mint_op.nft_metadata_id = lottery_md_obj.id;
mint_op.owner = op.buyer;
nft_id = db().apply_operation(nft_mint_context, mint_op).get<object_id_type>();
}
db().adjust_balance(op.buyer, -op.amount);
db().modify(lottery_md_obj.lottery_data->lottery_balance_id(db()), [&](nft_lottery_balance_object &obj) {
obj.jackpot += op.amount;
});
return nft_id;
}
FC_CAPTURE_AND_RETHROW((op))
}
void_result nft_lottery_reward_evaluator::do_evaluate(const nft_lottery_reward_operation &op)
{
try
{
const database &d = db();
auto now = d.head_block_time();
FC_ASSERT(now >= HARDFORK_NFT_TIME, "Not allowed until NFT HF");
op.winner(d);
const auto &lottery_md_obj = op.lottery_id(d);
FC_ASSERT(lottery_md_obj.is_lottery());
const auto &lottery_options = lottery_md_obj.lottery_data->lottery_options;
FC_ASSERT(lottery_options.is_active);
FC_ASSERT(lottery_md_obj.get_lottery_jackpot(d) >= op.amount);
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
void_result nft_lottery_reward_evaluator::do_apply(const nft_lottery_reward_operation &op)
{
try
{
const auto &lottery_md_obj = op.lottery_id(db());
db().adjust_balance(op.winner, op.amount);
db().modify(lottery_md_obj.lottery_data->lottery_balance_id(db()), [&](nft_lottery_balance_object &obj) {
obj.jackpot -= op.amount;
});
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
void_result nft_lottery_end_evaluator::do_evaluate(const nft_lottery_end_operation &op)
{
try
{
const database &d = db();
auto now = d.head_block_time();
FC_ASSERT(now >= HARDFORK_NFT_TIME, "Not allowed until NFT HF");
const auto &lottery_md_obj = op.lottery_id(d);
FC_ASSERT(lottery_md_obj.is_lottery());
const auto &lottery_options = lottery_md_obj.lottery_data->lottery_options;
FC_ASSERT(lottery_options.is_active);
FC_ASSERT(lottery_md_obj.get_lottery_jackpot(d).amount == 0);
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
void_result nft_lottery_end_evaluator::do_apply(const nft_lottery_end_operation &op)
{
try
{
const auto &lottery_md_obj = op.lottery_id(db());
db().modify(lottery_md_obj, [&](nft_metadata_object &obj) {
obj.lottery_data->lottery_options.is_active = false;
});
db().modify(lottery_md_obj.lottery_data->lottery_balance_id(db()), [&](nft_lottery_balance_object &obj) {
obj.sweeps_tickets_sold = lottery_md_obj.get_token_current_supply(db());
});
if (lottery_md_obj.lottery_data->lottery_options.delete_tickets_after_draw)
{
const auto &nft_index_by_md = db().get_index_type<nft_index>().indices().get<by_metadata>();
auto delete_nft_itr = nft_index_by_md.lower_bound(op.lottery_id);
while (delete_nft_itr != nft_index_by_md.end() && delete_nft_itr->nft_metadata_id == op.lottery_id)
{
const nft_object &nft_obj = *delete_nft_itr;
++delete_nft_itr;
db().remove(nft_obj);
}
}
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
} // namespace chain
} // namespace graphene

View file

@ -0,0 +1,171 @@
#include <graphene/chain/database.hpp>
#include <graphene/chain/nft_object.hpp>
namespace graphene
{
namespace chain
{
time_point_sec nft_metadata_object::get_lottery_expiration() const
{
if (lottery_data)
return lottery_data->lottery_options.end_date;
return time_point_sec();
}
asset nft_metadata_object::get_lottery_jackpot(const database &db) const
{
if (lottery_data)
return lottery_data->lottery_balance_id(db).jackpot;
return asset();
}
share_type nft_metadata_object::get_token_current_supply(const database &db) const
{
share_type current_supply;
const auto &idx_lottery_by_md = db.get_index_type<nft_index>().indices().get<by_metadata>();
auto lottery_range = idx_lottery_by_md.equal_range(id);
current_supply = std::distance(lottery_range.first, lottery_range.second);
return current_supply;
}
vector<account_id_type> nft_metadata_object::get_holders(const database &db) const
{
const auto &idx_lottery_by_md = db.get_index_type<nft_index>().indices().get<by_metadata>();
auto lottery_range = idx_lottery_by_md.equal_range(id);
vector<account_id_type> holders;
holders.reserve(std::distance(lottery_range.first, lottery_range.second));
std::for_each(lottery_range.first, lottery_range.second,
[&](const nft_object &ticket) {
holders.emplace_back(ticket.owner);
});
return holders;
}
vector<uint64_t> nft_metadata_object::get_ticket_ids(const database &db) const
{
const auto &idx_lottery_by_md = db.get_index_type<nft_index>().indices().get<by_metadata>();
auto lottery_range = idx_lottery_by_md.equal_range(id);
vector<uint64_t> tickets;
tickets.reserve(std::distance(lottery_range.first, lottery_range.second));
std::for_each(lottery_range.first, lottery_range.second,
[&](const nft_object &ticket) {
tickets.emplace_back(ticket.id.instance());
});
return tickets;
}
void nft_metadata_object::distribute_benefactors_part(database &db)
{
transaction_evaluation_state eval(&db);
const auto &lottery_options = lottery_data->lottery_options;
share_type jackpot = lottery_options.ticket_price.amount * get_token_current_supply(db) + lottery_data->lottery_balance_id(db).total_progressive_jackpot.amount;
for (auto benefactor : lottery_options.benefactors)
{
nft_lottery_reward_operation reward_op;
reward_op.lottery_id = id;
reward_op.winner = benefactor.id;
reward_op.is_benefactor_reward = true;
reward_op.win_percentage = benefactor.share;
reward_op.amount = asset(jackpot.value * benefactor.share / GRAPHENE_100_PERCENT, lottery_options.ticket_price.asset_id);
db.apply_operation(eval, reward_op);
}
}
map<account_id_type, vector<uint16_t>> nft_metadata_object::distribute_winners_part(database &db)
{
transaction_evaluation_state eval(&db);
auto current_supply = get_token_current_supply(db);
auto &lottery_options = lottery_data->lottery_options;
auto holders = get_holders(db);
vector<uint64_t> ticket_ids = get_ticket_ids(db);
FC_ASSERT(current_supply.value == (int64_t)holders.size());
FC_ASSERT(get_lottery_jackpot(db).amount.value == current_supply.value * lottery_options.ticket_price.amount.value);
map<account_id_type, vector<uint16_t>> structurized_participants;
for (account_id_type holder : holders)
{
if (!structurized_participants.count(holder))
structurized_participants.emplace(holder, vector<uint16_t>());
}
uint64_t jackpot = get_lottery_jackpot(db).amount.value;
auto selections = lottery_options.winning_tickets.size() <= holders.size() ? lottery_options.winning_tickets.size() : holders.size();
auto winner_numbers = db.get_random_numbers(0, holders.size(), selections, false);
auto &tickets(lottery_options.winning_tickets);
if (holders.size() < tickets.size())
{
uint16_t percents_to_distribute = 0;
for (auto i = tickets.begin() + holders.size(); i != tickets.end();)
{
percents_to_distribute += *i;
i = tickets.erase(i);
}
for (auto t = tickets.begin(); t != tickets.begin() + holders.size(); ++t)
*t += percents_to_distribute / holders.size();
}
auto sweeps_distribution_percentage = db.get_global_properties().parameters.sweeps_distribution_percentage();
for (size_t c = 0; c < winner_numbers.size(); ++c)
{
auto winner_num = winner_numbers[c];
nft_lottery_reward_operation reward_op;
reward_op.lottery_id = id;
reward_op.is_benefactor_reward = false;
reward_op.winner = holders[winner_num];
if (ticket_ids.size() > winner_num)
{
reward_op.winner_ticket_id = ticket_ids[winner_num];
}
reward_op.win_percentage = tickets[c];
reward_op.amount = asset(jackpot * tickets[c] * (1. - sweeps_distribution_percentage / (double)GRAPHENE_100_PERCENT) / GRAPHENE_100_PERCENT, lottery_options.ticket_price.asset_id);
db.apply_operation(eval, reward_op);
structurized_participants[holders[winner_num]].push_back(tickets[c]);
}
return structurized_participants;
}
void nft_metadata_object::distribute_sweeps_holders_part(database &db)
{
transaction_evaluation_state eval(&db);
auto &asset_bal_idx = db.get_index_type<account_balance_index>().indices().get<by_asset_balance>();
auto sweeps_params = db.get_global_properties().parameters;
uint64_t distribution_asset_supply = sweeps_params.sweeps_distribution_asset()(db).dynamic_data(db).current_supply.value;
const auto range = asset_bal_idx.equal_range(boost::make_tuple(sweeps_params.sweeps_distribution_asset()));
asset remaining_jackpot = get_lottery_jackpot(db);
uint64_t holders_sum = 0;
for (const account_balance_object &holder_balance : boost::make_iterator_range(range.first, range.second))
{
int64_t holder_part = remaining_jackpot.amount.value / (double)distribution_asset_supply * holder_balance.balance.value * SWEEPS_VESTING_BALANCE_MULTIPLIER;
db.adjust_sweeps_vesting_balance(holder_balance.owner, holder_part);
holders_sum += holder_part;
}
uint64_t balance_rest = remaining_jackpot.amount.value * SWEEPS_VESTING_BALANCE_MULTIPLIER - holders_sum;
db.adjust_sweeps_vesting_balance(sweeps_params.sweeps_vesting_accumulator_account(), balance_rest);
db.modify(lottery_data->lottery_balance_id(db), [&](nft_lottery_balance_object &obj) {
obj.jackpot -= remaining_jackpot;
});
}
void nft_metadata_object::end_lottery(database &db)
{
transaction_evaluation_state eval(&db);
const auto &lottery_options = lottery_data->lottery_options;
FC_ASSERT(is_lottery());
FC_ASSERT(lottery_options.is_active && (lottery_options.end_date <= db.head_block_time() || lottery_options.ending_on_soldout));
auto participants = distribute_winners_part(db);
if (participants.size() > 0)
{
distribute_benefactors_part(db);
distribute_sweeps_holders_part(db);
}
nft_lottery_end_operation end_op;
end_op.lottery_id = get_id();
db.apply_operation(eval, end_op);
}
} // namespace chain
} // namespace graphene

View file

@ -219,6 +219,18 @@ struct proposal_operation_hardfork_visitor
FC_ASSERT( block_time >= HARDFORK_NFT_TIME, "account_role_delete_operation not allowed yet!" );
}
void operator()(const nft_lottery_token_purchase_operation &v) const {
FC_ASSERT( block_time >= HARDFORK_NFT_TIME, "nft_lottery_token_purchase_operation not allowed yet!" );
}
void operator()(const nft_lottery_reward_operation &v) const {
FC_ASSERT( block_time >= HARDFORK_NFT_TIME, "nft_lottery_reward_operation not allowed yet!" );
}
void operator()(const nft_lottery_end_operation &v) const {
FC_ASSERT( block_time >= HARDFORK_NFT_TIME, "nft_lottery_end_operation not allowed yet!" );
}
void operator()(const son_create_operation &v) const {
FC_ASSERT( block_time >= HARDFORK_SON_TIME, "son_create_operation not allowed yet!" );
}

View file

@ -1,35 +0,0 @@
/*
* Copyright (c) 2018 Peerplays Blockchain Standards Association, and contributors.
*
* The MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <graphene/chain/protocol/competitor.hpp>
namespace graphene { namespace chain {
void competitor_create_operation::validate() const
{
FC_ASSERT( fee.amount >= 0 );
}
} } // graphene::chain

View file

@ -30,7 +30,7 @@ namespace graphene { namespace chain {
void memo_data::set_message(const fc::ecc::private_key& priv, const fc::ecc::public_key& pub,
const string& msg, uint64_t custom_nonce)
{
if( priv != fc::ecc::private_key() && public_key_type(pub) != public_key_type() )
if( priv != fc::ecc::private_key() && pub.valid() )
{
from = priv.get_public_key();
to = pub;
@ -57,7 +57,7 @@ void memo_data::set_message(const fc::ecc::private_key& priv, const fc::ecc::pub
string memo_data::get_message(const fc::ecc::private_key& priv,
const fc::ecc::public_key& pub)const
{
if( from != public_key_type() )
if( from != public_key_type() && pub.valid() )
{
auto secret = priv.get_shared_secret(pub);
auto nonce_plus_secret = fc::sha512::hash(fc::to_string(nonce) + secret.str());

View file

@ -45,6 +45,10 @@ void nft_metadata_create_operation::validate() const
FC_ASSERT(fee.amount >= 0, "Fee must not be negative");
FC_ASSERT(is_valid_nft_token_name(name), "Invalid NFT name provided");
FC_ASSERT(is_valid_nft_token_name(symbol), "Invalid NFT symbol provided");
if (lottery_options)
{
(*lottery_options).validate();
}
}
void nft_metadata_update_operation::validate() const

View file

@ -0,0 +1,38 @@
#include <graphene/chain/protocol/nft_ops.hpp>
#include <graphene/chain/protocol/nft_lottery.hpp>
#include <graphene/chain/protocol/operations.hpp>
namespace graphene
{
namespace chain
{
void nft_lottery_options::validate() const
{
FC_ASSERT(winning_tickets.size() <= 64);
FC_ASSERT(ticket_price.amount >= 1);
uint16_t total = 0;
for (auto benefactor : benefactors)
{
total += benefactor.share;
}
for (auto share : winning_tickets)
{
total += share;
}
FC_ASSERT(total == GRAPHENE_100_PERCENT, "distribution amount not equals GRAPHENE_100_PERCENT");
FC_ASSERT(ending_on_soldout == true || end_date != time_point_sec(), "lottery may not end");
}
share_type nft_lottery_token_purchase_operation::calculate_fee(const fee_parameters_type &k) const
{
return k.fee;
}
void nft_lottery_token_purchase_operation::validate() const
{
FC_ASSERT(fee.amount >= 0, "Fee must not be negative");
FC_ASSERT(tickets_to_buy > 0);
}
} // namespace chain
} // namespace graphene

View file

@ -0,0 +1,24 @@
#include <graphene/chain/random_number_evaluator.hpp>
#include <graphene/chain/random_number_object.hpp>
namespace graphene { namespace chain {
void_result random_number_store_evaluator::do_evaluate( const random_number_store_operation& op )
{ try {
return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }
object_id_type random_number_store_evaluator::do_apply( const random_number_store_operation& op )
{ try {
const auto& new_random_number_object = db().create<random_number_object>( [&]( random_number_object& obj ) {
obj.account = op.account;
obj.timestamp = db().head_block_time();
obj.random_number = op.random_number;
obj.data = op.data;
});
return new_random_number_object.id;
} FC_CAPTURE_AND_RETHROW( (op) ) }
} } // graphene::chain

View file

@ -9,7 +9,9 @@ namespace graphene { namespace chain {
void_result add_sidechain_address_evaluator::do_evaluate(const sidechain_address_add_operation& op)
{ try{
FC_ASSERT( op.deposit_public_key.length() > 0 && op.deposit_address.length() == 0 && op.deposit_address_data.length() == 0, "User should add a valid deposit public key and a null deposit address");
if (op.sidechain == sidechain_type::bitcoin) {
FC_ASSERT( op.deposit_public_key.length() > 0 && op.deposit_address.length() == 0 && op.deposit_address_data.length() == 0, "ser should add a valid deposit public key and a null deposit address (Bitcoin only)");
}
const auto& sdpke_idx = db().get_index_type<sidechain_address_index>().indices().get<by_sidechain_and_deposit_public_key_and_expires>();
FC_ASSERT( sdpke_idx.find(boost::make_tuple(op.sidechain, op.deposit_public_key, time_point_sec::maximum())) == sdpke_idx.end(), "An active deposit key already exists" );
return void_result();
@ -31,8 +33,8 @@ object_id_type add_sidechain_address_evaluator::do_apply(const sidechain_address
obj.sidechain_address_account = op.sidechain_address_account;
obj.sidechain = op.sidechain;
obj.deposit_public_key = op.deposit_public_key;
obj.deposit_address = "";
obj.deposit_address_data = "";
obj.deposit_address = op.deposit_address;
obj.deposit_address_data = op.deposit_address_data;
obj.withdraw_public_key = op.withdraw_public_key;
obj.withdraw_address = op.withdraw_address;
obj.valid_from = db().head_block_time();

View file

@ -28,6 +28,7 @@ void_result sidechain_transaction_create_evaluator::do_evaluate(const sidechain_
object_id_type sidechain_transaction_create_evaluator::do_apply(const sidechain_transaction_create_operation &op)
{ try {
const auto &new_sidechain_transaction_object = db().create<sidechain_transaction_object>([&](sidechain_transaction_object &sto) {
sto.timestamp = db().head_block_time();
sto.sidechain = op.sidechain;
sto.object_id = op.object_id;
sto.transaction = op.transaction;
@ -97,7 +98,15 @@ object_id_type sidechain_transaction_sign_evaluator::do_apply(const sidechain_tr
});
db().modify(son_obj->statistics(db()), [&](son_statistics_object& sso) {
sso.txs_signed += 1;
if (sso.total_txs_signed.find(sto_obj->sidechain) == sso.total_txs_signed.end()) {
sso.total_txs_signed[sto_obj->sidechain] = 0;
}
sso.total_txs_signed[sto_obj->sidechain] += 1;
if (sso.txs_signed.find(sto_obj->sidechain) == sso.txs_signed.end()) {
sso.txs_signed[sto_obj->sidechain] = 0;
}
sso.txs_signed[sto_obj->sidechain] += 1;
});
return op.sidechain_transaction_id;

View file

@ -12,4 +12,17 @@ namespace graphene { namespace chain {
(sidechain_public_keys.find( sidechain_type::bitcoin ) != sidechain_public_keys.end()) &&
(sidechain_public_keys.at(sidechain_type::bitcoin).length() > 0));
}
bool son_object::has_valid_config(time_point_sec head_block_time)const {
bool retval = has_valid_config();
if (head_block_time >= HARDFORK_SON_FOR_HIVE_TIME) {
retval = retval &&
(sidechain_public_keys.find( sidechain_type::hive ) != sidechain_public_keys.end()) &&
(sidechain_public_keys.at(sidechain_type::hive).length() > 0);
}
return retval;
}
}}

View file

@ -84,9 +84,16 @@ object_id_type create_son_wallet_deposit_evaluator::do_apply(const son_wallet_de
auto stats_itr = db().get_index_type<son_stats_index>().indices().get<by_owner>().find(si.son_id);
db().modify(*stats_itr, [&op, &si](son_statistics_object &sso) {
sso.total_sidechain_txs_reported = sso.total_sidechain_txs_reported + 1;
if (sso.total_sidechain_txs_reported.find(op.sidechain) == sso.total_sidechain_txs_reported.end()) {
sso.total_sidechain_txs_reported[op.sidechain] = 0;
}
sso.total_sidechain_txs_reported[op.sidechain] += 1;
if (si.son_id == op.son_id) {
sso.sidechain_txs_reported = sso.sidechain_txs_reported + 1;
if (sso.sidechain_txs_reported.find(op.sidechain) == sso.sidechain_txs_reported.end()) {
sso.sidechain_txs_reported[op.sidechain] = 0;
}
sso.sidechain_txs_reported[op.sidechain] += 1;
}
});
}
@ -122,7 +129,10 @@ object_id_type create_son_wallet_deposit_evaluator::do_apply(const son_wallet_de
});
auto stats_itr = db().get_index_type<son_stats_index>().indices().get<by_owner>().find(op.son_id);
db().modify(*stats_itr, [&op](son_statistics_object &sso) {
sso.sidechain_txs_reported = sso.sidechain_txs_reported + 1;
if (sso.sidechain_txs_reported.find(op.sidechain) == sso.sidechain_txs_reported.end()) {
sso.sidechain_txs_reported[op.sidechain] = 0;
}
sso.sidechain_txs_reported[op.sidechain] += 1;
});
return (*itr).id;
}

View file

@ -82,9 +82,16 @@ object_id_type create_son_wallet_withdraw_evaluator::do_apply(const son_wallet_w
auto stats_itr = db().get_index_type<son_stats_index>().indices().get<by_owner>().find(si.son_id);
db().modify(*stats_itr, [&op, &si](son_statistics_object &sso) {
sso.total_sidechain_txs_reported = sso.total_sidechain_txs_reported + 1;
if (sso.total_sidechain_txs_reported.find(op.sidechain) == sso.total_sidechain_txs_reported.end()) {
sso.total_sidechain_txs_reported[op.sidechain] = 0;
}
sso.total_sidechain_txs_reported[op.sidechain] += 1;
if (si.son_id == op.son_id) {
sso.sidechain_txs_reported = sso.sidechain_txs_reported + 1;
if (sso.sidechain_txs_reported.find(op.sidechain) == sso.sidechain_txs_reported.end()) {
sso.sidechain_txs_reported[op.sidechain] = 0;
}
sso.sidechain_txs_reported[op.sidechain] += 1;
}
});
}
@ -120,7 +127,10 @@ object_id_type create_son_wallet_withdraw_evaluator::do_apply(const son_wallet_w
});
auto stats_itr = db().get_index_type<son_stats_index>().indices().get<by_owner>().find(op.son_id);
db().modify(*stats_itr, [&op](son_statistics_object &sso) {
sso.sidechain_txs_reported = sso.sidechain_txs_reported + 1;
if (sso.sidechain_txs_reported.find(op.sidechain) == sso.sidechain_txs_reported.end()) {
sso.sidechain_txs_reported[op.sidechain] = 0;
}
sso.sidechain_txs_reported[op.sidechain] += 1;
});
return (*itr).id;
}

View file

@ -605,8 +605,9 @@ namespace graphene { namespace chain {
return;
// We shouldn't be here if the final match is complete
assert(last_complete_round != num_rounds - 1);
if (last_complete_round == num_rounds - 1)
uint32_t last_complete_round_uint32 = last_complete_round;
assert(last_complete_round_uint32 != num_rounds - 1);
if (last_complete_round_uint32 == num_rounds - 1)
return;
if (first_incomplete_match_was_waiting)

View file

@ -1,95 +0,0 @@
/*
* Copyright (c) 2015 Cryptonomex, Inc., and contributors.
*
* The MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <graphene/chain/transaction_object.hpp>
namespace graphene { namespace chain {
const object* transaction_index::create(const std::function<void (object*)>& constructor, object_id_type)
{
transaction_object obj;
obj.id = get_next_available_id();
constructor(&obj);
auto result = _index.insert(std::move(obj));
FC_ASSERT(result.second, "Could not create transaction_object! Most likely a uniqueness constraint is violated.");
return &*result.first;
}
void transaction_index::modify(const object* obj,
const std::function<void (object*)>& m)
{
assert(obj != nullptr);
FC_ASSERT(obj->id < _index.size());
const transaction_object* t = dynamic_cast<const transaction_object*>(obj);
assert(t != nullptr);
auto itr = _index.find(obj->id.instance());
assert(itr != _index.end());
_index.modify(itr, [&m](transaction_object& o) { m(&o); });
}
void transaction_index::add(unique_ptr<object> o)
{
assert(o);
object_id_type id = o->id;
assert(id.space() == transaction_object::space_id);
assert(id.type() == transaction_object::type_id);
assert(id.instance() == size());
auto trx = dynamic_cast<transaction_object*>(o.get());
assert(trx != nullptr);
o.release();
auto result = _index.insert(std::move(*trx));
FC_ASSERT(result.second, "Could not insert transaction_object! Most likely a uniqueness constraint is violated.");
}
void transaction_index::remove(object_id_type id)
{
auto& index = _index.get<instance>();
auto itr = index.find(id.instance());
if( itr == index.end() )
return;
assert(id.space() == transaction_object::space_id);
assert(id.type() == transaction_object::type_id);
index.erase(itr);
}
const object*transaction_index::get(object_id_type id) const
{
if( id.type() != transaction_object::type_id ||
id.space() != transaction_object::space_id )
return nullptr;
auto itr = _index.find(id.instance());
if( itr == _index.end() )
return nullptr;
return &*itr;
}
} } // graphene::chain

View file

@ -59,17 +59,7 @@ namespace graphene { namespace db {
{
mv._apply_undo = false;
}
~session() {
try {
if( _apply_undo ) _db.undo();
}
catch ( const fc::exception& e )
{
elog( "${e}", ("e",e.to_detail_string() ) );
throw; // maybe crash..
}
if( _disable_on_exit ) _db.disable();
}
~session();
void commit() { _apply_undo = false; _db.commit(); }
void undo() { if( _apply_undo ) _db.undo(); _apply_undo = false; }
void merge() { if( _apply_undo ) _db.merge(); _apply_undo = false; }

View file

@ -30,6 +30,18 @@ namespace graphene { namespace db {
void undo_database::enable() { _disabled = false; }
void undo_database::disable() { _disabled = true; }
undo_database::session::~session() {
try {
if( _apply_undo ) _db.undo();
}
catch ( const fc::exception& e )
{
elog( "${e}", ("e",e.to_detail_string() ) );
std::terminate();
}
if( _disable_on_exit ) _db.disable();
}
undo_database::session undo_database::start_undo_session( bool force_enable )
{
if( _disabled && !force_enable ) return session(*this);

View file

@ -4,7 +4,7 @@ add_library( graphene_egenesis_none
include/graphene/egenesis/egenesis.hpp
)
target_link_libraries( graphene_egenesis_none graphene_chain fc )
target_link_libraries( graphene_egenesis_none graphene_chain )
target_include_directories( graphene_egenesis_none
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
@ -12,7 +12,7 @@ add_executable( embed_genesis
embed_genesis.cpp
)
target_link_libraries( embed_genesis graphene_chain graphene_app graphene_egenesis_none fc )
target_link_libraries( embed_genesis PRIVATE graphene_app graphene_egenesis_none )
set( embed_genesis_args
-t "${CMAKE_CURRENT_SOURCE_DIR}/egenesis_brief.cpp.tmpl---${CMAKE_CURRENT_BINARY_DIR}/egenesis_brief.cpp"
@ -42,8 +42,8 @@ add_custom_command(
add_library( graphene_egenesis_brief "${CMAKE_CURRENT_BINARY_DIR}/egenesis_brief.cpp" include/graphene/egenesis/egenesis.hpp )
add_library( graphene_egenesis_full "${CMAKE_CURRENT_BINARY_DIR}/egenesis_full.cpp" include/graphene/egenesis/egenesis.hpp )
target_link_libraries( graphene_egenesis_brief graphene_chain fc )
target_link_libraries( graphene_egenesis_full graphene_chain fc )
target_link_libraries( graphene_egenesis_brief graphene_chain )
target_link_libraries( graphene_egenesis_full graphene_chain )
target_include_directories( graphene_egenesis_brief
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )

View file

@ -10,12 +10,8 @@ set(SOURCES node.cpp
add_library( graphene_net ${SOURCES} ${HEADERS} )
target_link_libraries( graphene_net
PUBLIC fc graphene_db )
target_include_directories( graphene_net
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include"
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../chain/include" "${CMAKE_CURRENT_BINARY_DIR}/../chain/include"
)
target_link_libraries( graphene_net graphene_chain )
target_include_directories( graphene_net PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
if(MSVC)
set_source_files_properties( node.cpp PROPERTIES COMPILE_FLAGS "/bigobj" )

View file

@ -2375,6 +2375,7 @@ namespace graphene { namespace net { namespace detail {
VERIFY_CORRECT_THREAD();
item_hash_t reference_point = peer->last_block_delegate_has_seen;
uint32_t reference_point_block_num = _delegate->get_block_number(peer->last_block_delegate_has_seen);
(void)reference_point_block_num;
// when we call _delegate->get_blockchain_synopsis(), we may yield and there's a
// chance this peer's state will change before we get control back. Save off
@ -3414,6 +3415,7 @@ namespace graphene { namespace net { namespace detail {
for (const item_hash_t& transaction_message_hash : contained_transaction_message_ids)
{
size_t items_erased = _items_to_fetch.get<item_id_index>().erase(item_id(trx_message_type, transaction_message_hash));
(void)items_erased;
// there are two ways we could behave here: we could either act as if we received
// the transaction outside the block and offer it to our peers, or we could just
// forget about it (we would still advertise this block to our peers so they should

View file

@ -1,14 +1,14 @@
add_subdirectory( witness )
add_subdirectory( account_history )
add_subdirectory( accounts_list )
add_subdirectory( affiliate_stats )
add_subdirectory( elasticsearch )
add_subdirectory( market_history )
add_subdirectory( delayed_node )
add_subdirectory( bookie )
add_subdirectory( debug_witness )
add_subdirectory( delayed_node )
add_subdirectory( elasticsearch )
add_subdirectory( es_objects )
add_subdirectory( generate_genesis )
add_subdirectory( generate_uia_sharedrop_genesis )
add_subdirectory( debug_witness )
add_subdirectory( snapshot )
add_subdirectory( market_history )
add_subdirectory( peerplays_sidechain )
add_subdirectory( es_objects )
add_subdirectory( snapshot )
add_subdirectory( witness )

View file

@ -4,7 +4,7 @@ add_library( graphene_account_history
account_history_plugin.cpp
)
target_link_libraries( graphene_account_history graphene_chain graphene_app )
target_link_libraries( graphene_account_history PRIVATE graphene_plugin )
target_include_directories( graphene_account_history
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )

View file

@ -4,7 +4,7 @@ add_library( graphene_accounts_list
accounts_list_plugin.cpp
)
target_link_libraries( graphene_accounts_list graphene_chain graphene_app )
target_link_libraries( graphene_accounts_list PRIVATE graphene_plugin )
target_include_directories( graphene_accounts_list
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )

View file

@ -5,7 +5,7 @@ add_library( graphene_affiliate_stats
affiliate_stats_plugin.cpp
)
target_link_libraries( graphene_affiliate_stats graphene_chain graphene_app )
target_link_libraries( graphene_affiliate_stats PRIVATE graphene_plugin graphene_account_history )
target_include_directories( graphene_affiliate_stats
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )

View file

@ -5,7 +5,7 @@ add_library( graphene_bookie
bookie_api.cpp
)
target_link_libraries( graphene_bookie graphene_chain graphene_app )
target_link_libraries( graphene_bookie PRIVATE graphene_plugin )
target_include_directories( graphene_bookie
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )

View file

@ -5,7 +5,7 @@ add_library( graphene_debug_witness
debug_witness.cpp
)
target_link_libraries( graphene_debug_witness graphene_chain graphene_app )
target_link_libraries( graphene_debug_witness PRIVATE graphene_plugin )
target_include_directories( graphene_debug_witness
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )

View file

@ -4,7 +4,7 @@ add_library( graphene_delayed_node
delayed_node_plugin.cpp
)
target_link_libraries( graphene_delayed_node graphene_chain graphene_app )
target_link_libraries( graphene_delayed_node PRIVATE graphene_plugin graphene_accounts_list graphene_affiliate_stats graphene_bookie graphene_debug_witness graphene_elasticsearch graphene_market_history )
target_include_directories( graphene_delayed_node
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )

View file

@ -4,13 +4,21 @@ add_library( graphene_elasticsearch
elasticsearch_plugin.cpp
)
target_link_libraries( graphene_elasticsearch graphene_chain graphene_app curl )
target_include_directories( graphene_elasticsearch
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
find_curl()
include_directories(${CURL_INCLUDE_DIRS})
if(MSVC)
set_source_files_properties(elasticsearch_plugin.cpp PROPERTIES COMPILE_FLAGS "/bigobj" )
endif(MSVC)
if(CURL_STATICLIB)
SET_TARGET_PROPERTIES(graphene_elasticsearch PROPERTIES
COMPILE_DEFINITIONS "CURL_STATICLIB")
endif(CURL_STATICLIB)
target_link_libraries( graphene_elasticsearch PRIVATE graphene_plugin ${CURL_LIBRARIES} )
target_include_directories( graphene_elasticsearch
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include"
PUBLIC "${CURL_INCLUDE_DIR}" )
install( TARGETS
graphene_elasticsearch

View file

@ -57,9 +57,9 @@ class elasticsearch_plugin_impl
bool _elasticsearch_visitor = false;
std::string _elasticsearch_basic_auth = "";
std::string _elasticsearch_index_prefix = "peerplays-";
bool _elasticsearch_operation_object = false;
bool _elasticsearch_operation_object = true;
uint32_t _elasticsearch_start_es_after_block = 0;
bool _elasticsearch_operation_string = true;
bool _elasticsearch_operation_string = false;
mode _elasticsearch_mode = mode::only_save;
CURL *curl; // curl handler
vector <string> bulk_lines; // vector of op lines
@ -75,20 +75,19 @@ class elasticsearch_plugin_impl
std::string bulk_line;
std::string index_name;
bool is_sync = false;
fc::time_point last_sync;
private:
bool add_elasticsearch( const account_id_type account_id, const optional<operation_history_object>& oho, const uint32_t block_number );
const account_transaction_history_object& addNewEntry(const account_statistics_object& stats_obj,
const account_id_type account_id,
const account_id_type& account_id,
const optional <operation_history_object>& oho);
const account_statistics_object& getStatsObject(const account_id_type account_id);
const account_statistics_object& getStatsObject(const account_id_type& account_id);
void growStats(const account_statistics_object& stats_obj, const account_transaction_history_object& ath);
void getOperationType(const optional <operation_history_object>& oho);
void doOperationHistory(const optional <operation_history_object>& oho);
void doBlock(const optional <operation_history_object>& oho, const signed_block& b);
void doBlock(uint32_t trx_in_block, const signed_block& b);
void doVisitor(const optional <operation_history_object>& oho);
void checkState(const fc::time_point_sec& block_time);
void cleanObjects(const account_transaction_history_object& ath, account_id_type account_id);
void cleanObjects(const account_transaction_history_id_type& ath, const account_id_type& account_id);
void createBulkLine(const account_transaction_history_object& ath);
void prepareBulk(const account_transaction_history_id_type& ath_id);
void populateESstruct();
@ -148,7 +147,7 @@ bool elasticsearch_plugin_impl::update_account_histories( const signed_block& b
// populate what we can before impacted loop
getOperationType(oho);
doOperationHistory(oho);
doBlock(oho, b);
doBlock(oho->trx_in_block, b);
if(_elasticsearch_visitor)
doVisitor(oho);
@ -174,7 +173,11 @@ bool elasticsearch_plugin_impl::update_account_histories( const signed_block& b
for( auto& account_id : impacted )
{
if(!add_elasticsearch( account_id, oho, b.block_num() ))
{
elog( "Error adding data to Elastic Search: block num ${b}, account ${a}, data ${d}",
("b",b.block_num()) ("a",account_id) ("d", oho) );
return false;
}
}
}
// we send bulk at end of block when we are in sync for better real time client experience
@ -185,23 +188,33 @@ bool elasticsearch_plugin_impl::update_account_histories( const signed_block& b
{
prepare.clear();
if(!graphene::utilities::SendBulk(es))
{
// Note: although called with `std::move()`, `es` is not updated in `SendBulk()`
elog( "Error sending ${n} lines of bulk data to Elastic Search, the first lines are:",
("n",es.bulk_lines.size()) );
for( size_t i = 0; i < es.bulk_lines.size() && i < 10; ++i )
{
edump( (es.bulk_lines[i]) );
}
return false;
}
else
bulk_lines.clear();
}
}
if(bulk_lines.size() != limit_documents)
bulk_lines.reserve(limit_documents);
return true;
}
void elasticsearch_plugin_impl::checkState(const fc::time_point_sec& block_time)
{
fc::time_point current_time(fc::time_point::now());
if(((current_time - block_time) < fc::seconds(30)) || (current_time - last_sync > fc::seconds(60)))
if((fc::time_point::now() - block_time) < fc::seconds(30))
{
limit_documents = _elasticsearch_bulk_sync;
is_sync = true;
last_sync = current_time;
}
else
{
@ -232,11 +245,11 @@ void elasticsearch_plugin_impl::doOperationHistory(const optional <operation_his
os.op = fc::json::to_string(oho->op);
}
void elasticsearch_plugin_impl::doBlock(const optional <operation_history_object>& oho, const signed_block& b)
void elasticsearch_plugin_impl::doBlock(uint32_t trx_in_block, const signed_block& b)
{
std::string trx_id = "";
if(oho->trx_in_block < b.transactions.size())
trx_id = b.transactions[oho->trx_in_block].id().str();
if(trx_in_block < b.transactions.size())
trx_id = b.transactions[trx_in_block].id().str();
bs.block_num = b.block_num();
bs.block_time = b.timestamp;
bs.trx_id = trx_id;
@ -244,23 +257,41 @@ void elasticsearch_plugin_impl::doBlock(const optional <operation_history_object
void elasticsearch_plugin_impl::doVisitor(const optional <operation_history_object>& oho)
{
graphene::chain::database& db = database();
operation_visitor o_v;
oho->op.visit(o_v);
auto fee_asset = o_v.fee_asset(db);
vs.fee_data.asset = o_v.fee_asset;
vs.fee_data.asset_name = fee_asset.symbol;
vs.fee_data.amount = o_v.fee_amount;
vs.fee_data.amount_units = (o_v.fee_amount.value)/(double)asset::scaled_precision(fee_asset.precision).value;
auto transfer_asset = o_v.transfer_asset_id(db);
vs.transfer_data.asset = o_v.transfer_asset_id;
vs.transfer_data.asset_name = transfer_asset.symbol;
vs.transfer_data.amount = o_v.transfer_amount;
vs.transfer_data.amount_units = (o_v.transfer_amount.value)/(double)asset::scaled_precision(transfer_asset.precision).value;
vs.transfer_data.from = o_v.transfer_from;
vs.transfer_data.to = o_v.transfer_to;
auto fill_pays_asset = o_v.fill_pays_asset_id(db);
auto fill_receives_asset = o_v.fill_receives_asset_id(db);
vs.fill_data.order_id = o_v.fill_order_id;
vs.fill_data.account_id = o_v.fill_account_id;
vs.fill_data.pays_asset_id = o_v.fill_pays_asset_id;
vs.fill_data.pays_asset_name = fill_pays_asset.symbol;
vs.fill_data.pays_amount = o_v.fill_pays_amount;
vs.fill_data.pays_amount_units = (o_v.fill_pays_amount.value)/(double)asset::scaled_precision(fill_pays_asset.precision).value;
vs.fill_data.receives_asset_id = o_v.fill_receives_asset_id;
vs.fill_data.receives_asset_name = fill_receives_asset.symbol;
vs.fill_data.receives_amount = o_v.fill_receives_amount;
vs.fill_data.receives_amount_units = (o_v.fill_receives_amount.value)/(double)asset::scaled_precision(fill_receives_asset.precision).value;
auto fill_price = (o_v.fill_receives_amount.value/(double)asset::scaled_precision(fill_receives_asset.precision).value) /
(o_v.fill_pays_amount.value/(double)asset::scaled_precision(fill_pays_asset.precision).value);
vs.fill_data.fill_price_units = fill_price;
//vs.fill_data.fill_price = o_v.fill_fill_price;
//vs.fill_data.is_maker = o_v.fill_is_maker;
}
@ -276,13 +307,22 @@ bool elasticsearch_plugin_impl::add_elasticsearch( const account_id_type account
createBulkLine(ath);
prepareBulk(ath.id);
}
cleanObjects(ath, account_id);
cleanObjects(ath.id, account_id);
if (curl && bulk_lines.size() >= limit_documents) { // we are in bulk time, ready to add data to elasticsearech
prepare.clear();
populateESstruct();
if(!graphene::utilities::SendBulk(es))
{
// Note: although called with `std::move()`, `es` is not updated in `SendBulk()`
elog( "Error sending ${n} lines of bulk data to Elastic Search, the first lines are:",
("n",es.bulk_lines.size()) );
for( size_t i = 0; i < es.bulk_lines.size() && i < 10; ++i )
{
edump( (es.bulk_lines[i]) );
}
return false;
}
else
bulk_lines.clear();
}
@ -290,15 +330,16 @@ bool elasticsearch_plugin_impl::add_elasticsearch( const account_id_type account
return true;
}
const account_statistics_object& elasticsearch_plugin_impl::getStatsObject(const account_id_type account_id)
const account_statistics_object& elasticsearch_plugin_impl::getStatsObject(const account_id_type& account_id)
{
graphene::chain::database& db = database();
const auto &acct = db.get<account_object>(account_id);
return acct.statistics(db);
const auto &stats_obj = db.get_account_stats_by_owner(account_id);
return stats_obj;
}
const account_transaction_history_object& elasticsearch_plugin_impl::addNewEntry(const account_statistics_object& stats_obj,
const account_id_type account_id,
const account_id_type& account_id,
const optional <operation_history_object>& oho)
{
graphene::chain::database& db = database();
@ -340,19 +381,21 @@ void elasticsearch_plugin_impl::prepareBulk(const account_transaction_history_id
fc::mutable_variant_object bulk_header;
bulk_header["_index"] = index_name;
bulk_header["_type"] = "data";
bulk_header["_id"] = fc::to_string(ath_id.space_id) + "." + fc::to_string(ath_id.type_id) + "." + ath_id.instance;
prepare = graphene::utilities::createBulk(bulk_header, bulk_line);
bulk_lines.insert(bulk_lines.end(), prepare.begin(), prepare.end());
bulk_header["_id"] = fc::to_string(ath_id.space_id) + "." + fc::to_string(ath_id.type_id) + "."
+ fc::to_string(ath_id.instance.value);
prepare = graphene::utilities::createBulk(bulk_header, std::move(bulk_line));
std::move(prepare.begin(), prepare.end(), std::back_inserter(bulk_lines));
prepare.clear();
}
void elasticsearch_plugin_impl::cleanObjects(const account_transaction_history_object& ath, account_id_type account_id)
void elasticsearch_plugin_impl::cleanObjects(const account_transaction_history_id_type& ath_id, const account_id_type& account_id)
{
graphene::chain::database& db = database();
// remove everything except current object from ath
const auto &his_idx = db.get_index_type<account_transaction_history_index>();
const auto &by_seq_idx = his_idx.indices().get<by_seq>();
auto itr = by_seq_idx.lower_bound(boost::make_tuple(account_id, 0));
if (itr != by_seq_idx.end() && itr->account == account_id && itr->id != ath.id) {
if (itr != by_seq_idx.end() && itr->account == account_id && itr->id != ath_id) {
// if found, remove the entry
const auto remove_op_id = itr->operation_id;
const auto itr_remove = itr;
@ -377,9 +420,12 @@ void elasticsearch_plugin_impl::cleanObjects(const account_transaction_history_o
void elasticsearch_plugin_impl::populateESstruct()
{
es.curl = curl;
es.bulk_lines = bulk_lines;
es.bulk_lines = std::move(bulk_lines);
es.elasticsearch_url = _elasticsearch_node_url;
es.auth = _elasticsearch_basic_auth;
es.index_prefix = _elasticsearch_index_prefix;
es.endpoint = "";
es.query = "";
}
} // end namespace detail
@ -421,11 +467,11 @@ void elasticsearch_plugin::plugin_set_program_options(
("elasticsearch-index-prefix", boost::program_options::value<std::string>(),
"Add a prefix to the index(peerplays-)")
("elasticsearch-operation-object", boost::program_options::value<bool>(),
"Save operation as object(false)")
"Save operation as object(true)")
("elasticsearch-start-es-after-block", boost::program_options::value<uint32_t>(),
"Start doing ES job after block(0)")
("elasticsearch-operation-string", boost::program_options::value<bool>(),
"Save operation as string. Needed to serve history api calls(true)")
"Save operation as string. Needed to serve history api calls(false)")
("elasticsearch-mode", boost::program_options::value<uint16_t>(),
"Mode of operation: only_save(0), only_query(1), all(2) - Default: 0")
;
@ -467,18 +513,18 @@ void elasticsearch_plugin::plugin_initialize(const boost::program_options::varia
if (options.count("elasticsearch-mode")) {
const auto option_number = options["elasticsearch-mode"].as<uint16_t>();
if(option_number > mode::all)
FC_THROW_EXCEPTION(fc::exception, "Elasticsearch mode not valid");
FC_THROW_EXCEPTION(graphene::chain::plugin_exception, "Elasticsearch mode not valid");
my->_elasticsearch_mode = static_cast<mode>(options["elasticsearch-mode"].as<uint16_t>());
}
if(my->_elasticsearch_mode != mode::only_query) {
if (my->_elasticsearch_mode == mode::all && !my->_elasticsearch_operation_string)
FC_THROW_EXCEPTION(fc::exception,
FC_THROW_EXCEPTION(graphene::chain::plugin_exception,
"If elasticsearch-mode is set to all then elasticsearch-operation-string need to be true");
database().applied_block.connect([this](const signed_block &b) {
if (!my->update_account_histories(b))
FC_THROW_EXCEPTION(fc::exception,
FC_THROW_EXCEPTION(graphene::chain::plugin_exception,
"Error populating ES database, we are going to keep trying.");
});
}
@ -563,13 +609,12 @@ vector<operation_history_object> elasticsearch_plugin::get_account_history(
const auto response = graphene::utilities::simpleQuery(es);
variant variant_response = fc::json::from_string(response);
const auto hits = variant_response["hits"]["total"]["value"];
const auto hits = variant_response["hits"]["total"];
uint32_t size;
if( hits.is_object() ) // ES-7 ?
size = static_cast<uint32_t>(hits["value"].as_uint64());
else // probably ES-6
size = static_cast<uint32_t>(hits.as_uint64());
size = std::min( size, limit );
for(unsigned i=0; i<size; i++)

View file

@ -152,12 +152,16 @@ struct block_struct {
struct fee_struct {
asset_id_type asset;
std::string asset_name;
share_type amount;
double amount_units;
};
struct transfer_struct {
asset_id_type asset;
std::string asset_name;
share_type amount;
double amount_units;
account_id_type from;
account_id_type to;
};
@ -166,10 +170,15 @@ struct fill_struct {
object_id_type order_id;
account_id_type account_id;
asset_id_type pays_asset_id;
std::string pays_asset_name;
share_type pays_amount;
double pays_amount_units;
asset_id_type receives_asset_id;
std::string receives_asset_name;
share_type receives_amount;
double receives_amount_units;
double fill_price;
double fill_price_units;
bool is_maker;
};
@ -258,6 +267,23 @@ struct adaptor_struct {
{
o["initializer"] = fc::json::to_string(o["initializer"]);
}
if (o.find("policy") != o.end())
{
o["policy"] = fc::json::to_string(o["policy"]);
}
if (o.find("predicates") != o.end())
{
o["predicates"] = fc::json::to_string(o["predicates"]);
}
if (o.find("active_special_authority") != o.end())
{
o["active_special_authority"] = fc::json::to_string(o["active_special_authority"]);
}
if (o.find("owner_special_authority") != o.end())
{
o["owner_special_authority"] = fc::json::to_string(o["owner_special_authority"]);
}
variant v;
fc::to_variant(o, v, FC_PACK_MAX_DEPTH);
@ -277,13 +303,16 @@ struct adaptor_struct {
}
}
};
} } //graphene::elasticsearch
FC_REFLECT_ENUM( graphene::elasticsearch::mode, (only_save)(only_query)(all) )
FC_REFLECT( graphene::elasticsearch::operation_history_struct, (trx_in_block)(op_in_trx)(operation_result)(virtual_op)(op)(op_object) )
FC_REFLECT( graphene::elasticsearch::block_struct, (block_num)(block_time)(trx_id) )
FC_REFLECT( graphene::elasticsearch::fee_struct, (asset)(amount) )
FC_REFLECT( graphene::elasticsearch::transfer_struct, (asset)(amount)(from)(to) )
FC_REFLECT( graphene::elasticsearch::fill_struct, (order_id)(account_id)(pays_asset_id)(pays_amount)(receives_asset_id)(receives_amount)(fill_price)(is_maker))
FC_REFLECT( graphene::elasticsearch::fee_struct, (asset)(asset_name)(amount)(amount_units) )
FC_REFLECT( graphene::elasticsearch::transfer_struct, (asset)(asset_name)(amount)(amount_units)(from)(to) )
FC_REFLECT( graphene::elasticsearch::fill_struct, (order_id)(account_id)(pays_asset_id)(pays_asset_name)(pays_amount)(pays_amount_units)
(receives_asset_id)(receives_asset_name)(receives_amount)(receives_amount_units)(fill_price)
(fill_price_units)(is_maker))
FC_REFLECT( graphene::elasticsearch::visitor_struct, (fee_data)(transfer_data)(fill_data) )
FC_REFLECT( graphene::elasticsearch::bulk_struct, (account_history)(operation_history)(operation_type)(operation_id_num)(block_data)(additional_data) )

View file

@ -4,14 +4,22 @@ add_library( graphene_es_objects
es_objects.cpp
)
target_link_libraries( graphene_es_objects graphene_chain graphene_app curl )
target_include_directories( graphene_es_objects
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
find_curl()
include_directories(${CURL_INCLUDE_DIRS})
if(CURL_STATICLIB)
SET_TARGET_PROPERTIES(graphene_es_objects PROPERTIES
COMPILE_DEFINITIONS "CURL_STATICLIB")
endif(CURL_STATICLIB)
if(MSVC)
set_source_files_properties(es_objects.cpp PROPERTIES COMPILE_FLAGS "/bigobj" )
endif(MSVC)
target_link_libraries( graphene_es_objects PRIVATE graphene_plugin ${CURL_LIBRARIES} )
target_include_directories( graphene_es_objects
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
install( TARGETS
graphene_es_objects

View file

@ -31,6 +31,22 @@
#include <graphene/chain/asset_object.hpp>
#include <graphene/chain/account_object.hpp>
#include <graphene/chain/account_role_object.hpp>
#include <graphene/chain/committee_member_object.hpp>
#include <graphene/chain/nft_object.hpp>
#include <graphene/chain/offer_object.hpp>
#include <graphene/chain/sidechain_address_object.hpp>
#include <graphene/chain/sidechain_transaction_object.hpp>
#include <graphene/chain/son_object.hpp>
#include <graphene/chain/son_proposal_object.hpp>
#include <graphene/chain/son_wallet_object.hpp>
#include <graphene/chain/son_wallet_deposit_object.hpp>
#include <graphene/chain/son_wallet_withdraw_object.hpp>
#include <graphene/chain/transaction_object.hpp>
#include <graphene/chain/vesting_balance_object.hpp>
#include <graphene/chain/witness_object.hpp>
#include <graphene/chain/worker_object.hpp>
#include <graphene/utilities/elasticsearch.hpp>
namespace graphene { namespace es_objects {
@ -61,6 +77,16 @@ class es_objects_plugin_impl
bool _es_objects_balances = true;
bool _es_objects_limit_orders = true;
bool _es_objects_asset_bitasset = true;
bool _es_objects_account_role = true;
bool _es_objects_committee_member = true;
bool _es_objects_nft = true;
bool _es_objects_son = true;
bool _es_objects_transaction = true;
bool _es_objects_vesting_balance = true;
bool _es_objects_witness = true;
bool _es_objects_worker = true;
std::string _es_objects_index_prefix = "ppobjects-";
uint32_t _es_objects_start_es_after_block = 0;
CURL *curl; // curl handler
@ -79,7 +105,6 @@ class es_objects_plugin_impl
bool es_objects_plugin_impl::genesis()
{
ilog("elasticsearch OBJECTS: inserting data from genesis");
graphene::chain::database &db = _self.database();
@ -112,13 +137,142 @@ bool es_objects_plugin_impl::genesis()
});
}
if (_es_objects_account_role) {
auto &idx = db.get_index_type<graphene::chain::account_role_index>();
idx.inspect_all_objects([this, &db](const graphene::db::object &o) {
auto obj = db.find_object(o.id);
auto b = static_cast<const account_role_object *>(obj);
prepareTemplate<account_role_object>(*b, "account_role");
});
}
if (_es_objects_committee_member) {
auto &idx = db.get_index_type<graphene::chain::committee_member_index>();
idx.inspect_all_objects([this, &db](const graphene::db::object &o) {
auto obj = db.find_object(o.id);
auto b = static_cast<const committee_member_object *>(obj);
prepareTemplate<committee_member_object>(*b, "committee_member");
});
}
if (_es_objects_nft) {
auto &idx = db.get_index_type<graphene::chain::nft_index>();
idx.inspect_all_objects([this, &db](const graphene::db::object &o) {
auto obj = db.find_object(o.id);
auto b = static_cast<const nft_object *>(obj);
prepareTemplate<nft_object>(*b, "nft");
});
}
if (_es_objects_nft) {
auto &idx = db.get_index_type<graphene::chain::nft_metadata_index>();
idx.inspect_all_objects([this, &db](const graphene::db::object &o) {
auto obj = db.find_object(o.id);
auto b = static_cast<const nft_metadata_object *>(obj);
prepareTemplate<nft_metadata_object>(*b, "nft_metadata");
});
}
if (_es_objects_nft) {
auto &idx = db.get_index_type<graphene::chain::offer_index>();
idx.inspect_all_objects([this, &db](const graphene::db::object &o) {
auto obj = db.find_object(o.id);
auto b = static_cast<const offer_object *>(obj);
prepareTemplate<offer_object>(*b, "offer");
});
}
if (_es_objects_son) {
auto &idx = db.get_index_type<graphene::chain::sidechain_address_index>();
idx.inspect_all_objects([this, &db](const graphene::db::object &o) {
auto obj = db.find_object(o.id);
auto b = static_cast<const sidechain_address_object *>(obj);
prepareTemplate<sidechain_address_object>(*b, "sidechain_address");
});
}
if (_es_objects_son) {
auto &idx = db.get_index_type<graphene::chain::sidechain_transaction_index>();
idx.inspect_all_objects([this, &db](const graphene::db::object &o) {
auto obj = db.find_object(o.id);
auto b = static_cast<const sidechain_transaction_object *>(obj);
prepareTemplate<sidechain_transaction_object>(*b, "sidechain_transaction");
});
}
if (_es_objects_son) {
auto &idx = db.get_index_type<graphene::chain::son_index>();
idx.inspect_all_objects([this, &db](const graphene::db::object &o) {
auto obj = db.find_object(o.id);
auto b = static_cast<const son_object *>(obj);
prepareTemplate<son_object>(*b, "son");
});
}
if (_es_objects_son) {
auto &idx = db.get_index_type<graphene::chain::son_proposal_index>();
idx.inspect_all_objects([this, &db](const graphene::db::object &o) {
auto obj = db.find_object(o.id);
auto b = static_cast<const son_proposal_object *>(obj);
prepareTemplate<son_proposal_object>(*b, "son_proposal");
});
}
if (_es_objects_son) {
auto &idx = db.get_index_type<graphene::chain::son_wallet_index>();
idx.inspect_all_objects([this, &db](const graphene::db::object &o) {
auto obj = db.find_object(o.id);
auto b = static_cast<const son_wallet_object *>(obj);
prepareTemplate<son_wallet_object>(*b, "son_wallet");
});
}
if (_es_objects_son) {
auto &idx = db.get_index_type<graphene::chain::son_wallet_deposit_index>();
idx.inspect_all_objects([this, &db](const graphene::db::object &o) {
auto obj = db.find_object(o.id);
auto b = static_cast<const son_wallet_deposit_object *>(obj);
prepareTemplate<son_wallet_deposit_object>(*b, "son_wallet_deposit");
});
}
if (_es_objects_son) {
auto &idx = db.get_index_type<graphene::chain::son_wallet_withdraw_index>();
idx.inspect_all_objects([this, &db](const graphene::db::object &o) {
auto obj = db.find_object(o.id);
auto b = static_cast<const son_wallet_withdraw_object *>(obj);
prepareTemplate<son_wallet_withdraw_object>(*b, "son_wallet_withdraw");
});
}
if (_es_objects_transaction) {
auto &idx = db.get_index_type<graphene::chain::transaction_index>();
idx.inspect_all_objects([this, &db](const graphene::db::object &o) {
auto obj = db.find_object(o.id);
auto b = static_cast<const transaction_object *>(obj);
prepareTemplate<transaction_object>(*b, "transaction");
});
}
if (_es_objects_vesting_balance) {
auto &idx = db.get_index_type<graphene::chain::vesting_balance_index>();
idx.inspect_all_objects([this, &db](const graphene::db::object &o) {
auto obj = db.find_object(o.id);
auto b = static_cast<const vesting_balance_object *>(obj);
prepareTemplate<vesting_balance_object>(*b, "vesting_balance");
});
}
if (_es_objects_witness) {
auto &idx = db.get_index_type<graphene::chain::witness_index>();
idx.inspect_all_objects([this, &db](const graphene::db::object &o) {
auto obj = db.find_object(o.id);
auto b = static_cast<const witness_object *>(obj);
prepareTemplate<witness_object>(*b, "witness");
});
}
if (_es_objects_worker) {
auto &idx = db.get_index_type<graphene::chain::worker_index>();
idx.inspect_all_objects([this, &db](const graphene::db::object &o) {
auto obj = db.find_object(o.id);
auto b = static_cast<const worker_object *>(obj);
prepareTemplate<worker_object>(*b, "worker");
});
}
graphene::utilities::ES es;
es.curl = curl;
es.bulk_lines = bulk;
es.elasticsearch_url = _es_objects_elasticsearch_url;
es.auth = _es_objects_auth;
if (!graphene::utilities::SendBulk(es))
FC_THROW_EXCEPTION(fc::exception, "Error inserting genesis data.");
FC_THROW_EXCEPTION(graphene::chain::plugin_exception, "Error inserting genesis data.");
else
bulk.clear();
@ -197,6 +351,150 @@ bool es_objects_plugin_impl::index_database(const vector<object_id_type>& ids, s
else
prepareTemplate<asset_bitasset_data_object>(*ba, "bitasset");
}
} else if (value.is<account_role_object>() && _es_objects_account_role) {
auto obj = db.find_object(value);
auto ba = static_cast<const account_role_object *>(obj);
if (ba != nullptr) {
if (action == "delete")
remove_from_database(ba->id, "account_role");
else
prepareTemplate<account_role_object>(*ba, "account_role");
}
} else if (value.is<committee_member_object>() && _es_objects_committee_member) {
auto obj = db.find_object(value);
auto ba = static_cast<const committee_member_object *>(obj);
if (ba != nullptr) {
if (action == "delete")
remove_from_database(ba->id, "committee_member");
else
prepareTemplate<committee_member_object>(*ba, "committee_member");
}
} else if (value.is<nft_object>() && _es_objects_nft) {
auto obj = db.find_object(value);
auto ba = static_cast<const nft_object *>(obj);
if (ba != nullptr) {
if (action == "delete")
remove_from_database(ba->id, "nft");
else
prepareTemplate<nft_object>(*ba, "nft");
}
} else if (value.is<nft_metadata_object>() && _es_objects_nft) {
auto obj = db.find_object(value);
auto ba = static_cast<const nft_metadata_object *>(obj);
if (ba != nullptr) {
if (action == "delete")
remove_from_database(ba->id, "nft_metadata");
else
prepareTemplate<nft_metadata_object>(*ba, "nft_metadata");
}
} else if (value.is<offer_object>() && _es_objects_nft) {
auto obj = db.find_object(value);
auto ba = static_cast<const offer_object *>(obj);
if (ba != nullptr) {
if (action == "delete")
remove_from_database(ba->id, "offer");
else
prepareTemplate<offer_object>(*ba, "offer");
}
} else if (value.is<sidechain_address_object>() && _es_objects_son) {
auto obj = db.find_object(value);
auto ba = static_cast<const sidechain_address_object *>(obj);
if (ba != nullptr) {
if (action == "delete")
remove_from_database(ba->id, "sidechain_address");
else
prepareTemplate<sidechain_address_object>(*ba, "sidechain_address");
}
} else if (value.is<sidechain_transaction_object>() && _es_objects_son) {
auto obj = db.find_object(value);
auto ba = static_cast<const sidechain_transaction_object *>(obj);
if (ba != nullptr) {
if (action == "delete")
remove_from_database(ba->id, "sidechain_transaction");
else
prepareTemplate<sidechain_transaction_object>(*ba, "sidechain_transaction");
}
} else if (value.is<son_object>() && _es_objects_son) {
auto obj = db.find_object(value);
auto ba = static_cast<const son_object *>(obj);
if (ba != nullptr) {
if (action == "delete")
remove_from_database(ba->id, "son");
else
prepareTemplate<son_object>(*ba, "son");
}
} else if (value.is<son_proposal_object>() && _es_objects_son) {
auto obj = db.find_object(value);
auto ba = static_cast<const son_proposal_object *>(obj);
if (ba != nullptr) {
if (action == "delete")
remove_from_database(ba->id, "son_proposal");
else
prepareTemplate<son_proposal_object>(*ba, "son_proposal");
}
} else if (value.is<son_wallet_object>() && _es_objects_son) {
auto obj = db.find_object(value);
auto ba = static_cast<const son_wallet_object *>(obj);
if (ba != nullptr) {
if (action == "delete")
remove_from_database(ba->id, "son_wallet");
else
prepareTemplate<son_wallet_object>(*ba, "son_wallet");
}
} else if (value.is<son_wallet_deposit_object>() && _es_objects_son) {
auto obj = db.find_object(value);
auto ba = static_cast<const son_wallet_deposit_object *>(obj);
if (ba != nullptr) {
if (action == "delete")
remove_from_database(ba->id, "son_wallet_deposit");
else
prepareTemplate<son_wallet_deposit_object>(*ba, "son_wallet_deposit");
}
} else if (value.is<son_wallet_withdraw_object>() && _es_objects_son) {
auto obj = db.find_object(value);
auto ba = static_cast<const son_wallet_withdraw_object *>(obj);
if (ba != nullptr) {
if (action == "delete")
remove_from_database(ba->id, "son_wallet_withdraw");
else
prepareTemplate<son_wallet_withdraw_object>(*ba, "son_wallet_withdraw");
}
} else if (value.is<transaction_object>() && _es_objects_transaction) {
auto obj = db.find_object(value);
auto ba = static_cast<const transaction_object *>(obj);
if (ba != nullptr) {
if (action == "delete")
remove_from_database(ba->id, "transaction");
else
prepareTemplate<transaction_object>(*ba, "transaction");
}
} else if (value.is<vesting_balance_object>() && _es_objects_vesting_balance) {
auto obj = db.find_object(value);
auto ba = static_cast<const vesting_balance_object *>(obj);
if (ba != nullptr) {
if (action == "delete")
remove_from_database(ba->id, "vesting_balance");
else
prepareTemplate<vesting_balance_object>(*ba, "vesting_balance");
}
} else if (value.is<witness_object>() && _es_objects_witness) {
auto obj = db.find_object(value);
auto ba = static_cast<const witness_object *>(obj);
if (ba != nullptr) {
if (action == "delete")
remove_from_database(ba->id, "witness");
else
prepareTemplate<witness_object>(*ba, "witness");
}
} else if (value.is<worker_object>() && _es_objects_worker) {
auto obj = db.find_object(value);
auto ba = static_cast<const worker_object *>(obj);
if (ba != nullptr) {
if (action == "delete")
remove_from_database(ba->id, "worker");
else
prepareTemplate<worker_object>(*ba, "worker");
}
}
}
@ -296,52 +594,39 @@ void es_objects_plugin::plugin_set_program_options(
)
{
cli.add_options()
("es-objects-elasticsearch-url", boost::program_options::value<std::string>(), "Elasticsearch node url(http://localhost:9200/)")
("es-objects-elasticsearch-url", boost::program_options::value<std::string>(),
"Elasticsearch node url(http://localhost:9200/)")
("es-objects-auth", boost::program_options::value<std::string>(), "Basic auth username:password('')")
("es-objects-bulk-replay", boost::program_options::value<uint32_t>(), "Number of bulk documents to index on replay(10000)")
("es-objects-bulk-sync", boost::program_options::value<uint32_t>(), "Number of bulk documents to index on a synchronized chain(100)")
("es-objects-bulk-replay", boost::program_options::value<uint32_t>(),
"Number of bulk documents to index on replay(10000)")
("es-objects-bulk-sync", boost::program_options::value<uint32_t>(),
"Number of bulk documents to index on a synchronized chain(100)")
("es-objects-proposals", boost::program_options::value<bool>(), "Store proposal objects(true)")
("es-objects-accounts", boost::program_options::value<bool>(), "Store account objects(true)")
("es-objects-assets", boost::program_options::value<bool>(), "Store asset objects(true)")
("es-objects-balances", boost::program_options::value<bool>(), "Store balances objects(true)")
("es-objects-limit-orders", boost::program_options::value<bool>(), "Store limit order objects(true)")
("es-objects-asset-bitasset", boost::program_options::value<bool>(), "Store feed data(true)")
("es-objects-index-prefix", boost::program_options::value<std::string>(), "Add a prefix to the index(ppobjects-)")
("es-objects-keep-only-current", boost::program_options::value<bool>(), "Keep only current state of the objects(true)")
("es-objects-start-es-after-block", boost::program_options::value<uint32_t>(), "Start doing ES job after block(0)")
("es-objects-limit-orders", boost::program_options::value<bool>(), "Store limit order objects(false)")
("es-objects-bitasset", boost::program_options::value<bool>(), "Store feed data(true)")
("es-objects-account-role", boost::program_options::value<bool>(), "Store account role objects (true)")
("es-objects-committee-member", boost::program_options::value<bool>(), "Store committee member objects(true)")
("es-objects-nft", boost::program_options::value<bool>(), "Store nft objects (true)")
("es-objects-son", boost::program_options::value<bool>(), "Store son objects (true)")
("es-objects-transaction", boost::program_options::value<bool>(), "Store transaction objects (true)")
("es-objects-vesting-balance", boost::program_options::value<bool>(), "Store vesting balance objects (true)")
("es-objects-witness", boost::program_options::value<bool>(), "Store witness objects (true)")
("es-objects-worker", boost::program_options::value<bool>(), "Store worker objects (true)")
("es-objects-index-prefix", boost::program_options::value<std::string>(),
"Add a prefix to the index(ppobjects-)")
("es-objects-keep-only-current", boost::program_options::value<bool>(),
"Keep only current state of the objects(true)")
("es-objects-start-es-after-block", boost::program_options::value<uint32_t>(),
"Start doing ES job after block(0)")
;
cfg.add(cli);
}
void es_objects_plugin::plugin_initialize(const boost::program_options::variables_map& options)
{
database().applied_block.connect([this](const signed_block &b) {
if(b.block_num() == 1) {
if (!my->genesis())
FC_THROW_EXCEPTION(fc::exception, "Error populating genesis data.");
}
});
database().new_objects.connect([this]( const vector<object_id_type>& ids, const flat_set<account_id_type>& impacted_accounts ) {
if(!my->index_database(ids, "create"))
{
FC_THROW_EXCEPTION(fc::exception, "Error creating object from ES database, we are going to keep trying.");
}
});
database().changed_objects.connect([this]( const vector<object_id_type>& ids, const flat_set<account_id_type>& impacted_accounts ) {
if(!my->index_database(ids, "update"))
{
FC_THROW_EXCEPTION(fc::exception, "Error updating object from ES database, we are going to keep trying.");
}
});
database().removed_objects.connect([this](const vector<object_id_type>& ids, const vector<const object*>& objs, const flat_set<account_id_type>& impacted_accounts) {
if(!my->index_database(ids, "delete"))
{
FC_THROW_EXCEPTION(fc::exception, "Error deleting object from ES database, we are going to keep trying.");
}
});
if (options.count("es-objects-elasticsearch-url")) {
my->_es_objects_elasticsearch_url = options["es-objects-elasticsearch-url"].as<std::string>();
}
@ -372,6 +657,30 @@ void es_objects_plugin::plugin_initialize(const boost::program_options::variable
if (options.count("es-objects-asset-bitasset")) {
my->_es_objects_asset_bitasset = options["es-objects-asset-bitasset"].as<bool>();
}
if (options.count("es-objects-account-role")) {
my->_es_objects_balances = options["es-objects-account-role"].as<bool>();
}
if (options.count("es-objects-committee-member")) {
my->_es_objects_balances = options["es-objects-committee-member"].as<bool>();
}
if (options.count("es-objects-nft")) {
my->_es_objects_balances = options["es-objects-nft"].as<bool>();
}
if (options.count("es-objects-son")) {
my->_es_objects_balances = options["es-objects-son"].as<bool>();
}
if (options.count("es-objects-transaction")) {
my->_es_objects_balances = options["es-objects-transaction"].as<bool>();
}
if (options.count("es-objects-vesting-balance")) {
my->_es_objects_balances = options["es-objects-vesting-balance"].as<bool>();
}
if (options.count("es-objects-witness")) {
my->_es_objects_balances = options["es-objects-witness"].as<bool>();
}
if (options.count("es-objects-worker")) {
my->_es_objects_balances = options["es-objects-worker"].as<bool>();
}
if (options.count("es-objects-index-prefix")) {
my->_es_objects_index_prefix = options["es-objects-index-prefix"].as<std::string>();
}
@ -381,6 +690,37 @@ void es_objects_plugin::plugin_initialize(const boost::program_options::variable
if (options.count("es-objects-start-es-after-block")) {
my->_es_objects_start_es_after_block = options["es-objects-start-es-after-block"].as<uint32_t>();
}
database().applied_block.connect([this](const signed_block &b) {
if(b.block_num() == 1 && my->_es_objects_start_es_after_block == 0) {
if (!my->genesis())
FC_THROW_EXCEPTION(graphene::chain::plugin_exception, "Error populating genesis data.");
}
});
database().new_objects.connect([this]( const vector<object_id_type>& ids,
const flat_set<account_id_type>& impacted_accounts ) {
if(!my->index_database(ids, "create"))
{
FC_THROW_EXCEPTION(graphene::chain::plugin_exception,
"Error creating object from ES database, we are going to keep trying.");
}
});
database().changed_objects.connect([this]( const vector<object_id_type>& ids,
const flat_set<account_id_type>& impacted_accounts ) {
if(!my->index_database(ids, "update"))
{
FC_THROW_EXCEPTION(graphene::chain::plugin_exception,
"Error updating object from ES database, we are going to keep trying.");
}
});
database().removed_objects.connect([this](const vector<object_id_type>& ids,
const vector<const object*>& objs, const flat_set<account_id_type>& impacted_accounts) {
if(!my->index_database(ids, "delete"))
{
FC_THROW_EXCEPTION(graphene::chain::plugin_exception,
"Error deleting object from ES database, we are going to keep trying.");
}
});
}
void es_objects_plugin::plugin_startup()
@ -396,4 +736,4 @@ void es_objects_plugin::plugin_startup()
ilog("elasticsearch OBJECTS: plugin_startup() begin");
}
} }
} }

View file

@ -4,7 +4,7 @@ add_library( graphene_generate_genesis
generate_genesis.cpp
)
target_link_libraries( graphene_generate_genesis graphene_chain graphene_app graphene_time )
target_link_libraries( graphene_generate_genesis PRIVATE graphene_plugin )
target_include_directories( graphene_generate_genesis
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )

View file

@ -4,7 +4,7 @@ add_library( graphene_generate_uia_sharedrop_genesis
generate_uia_sharedrop_genesis.cpp
)
target_link_libraries( graphene_generate_uia_sharedrop_genesis graphene_chain graphene_app graphene_time )
target_link_libraries( graphene_generate_uia_sharedrop_genesis PRIVATE graphene_plugin )
target_include_directories( graphene_generate_uia_sharedrop_genesis
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )

View file

@ -1,303 +0,0 @@
/*
* Copyright (c) 2018 Abit More, and contributors.
*
* The MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <graphene/grouped_orders/grouped_orders_plugin.hpp>
#include <graphene/chain/market_object.hpp>
namespace graphene { namespace grouped_orders {
namespace detail
{
class grouped_orders_plugin_impl
{
public:
grouped_orders_plugin_impl(grouped_orders_plugin& _plugin)
:_self( _plugin ) {}
virtual ~grouped_orders_plugin_impl();
graphene::chain::database& database()
{
return _self.database();
}
grouped_orders_plugin& _self;
flat_set<uint16_t> _tracked_groups;
};
/**
* @brief This secondary index is used to track changes on limit order objects.
*/
class limit_order_group_index : public secondary_index
{
public:
limit_order_group_index( const flat_set<uint16_t>& groups ) : _tracked_groups( groups ) {};
virtual void object_inserted( const object& obj ) override;
virtual void object_removed( const object& obj ) override;
virtual void about_to_modify( const object& before ) override;
virtual void object_modified( const object& after ) override;
const flat_set<uint16_t>& get_tracked_groups() const
{ return _tracked_groups; }
const map< limit_order_group_key, limit_order_group_data >& get_order_groups() const
{ return _og_data; }
private:
void remove_order( const limit_order_object& obj, bool remove_empty = true );
/** tracked groups */
flat_set<uint16_t> _tracked_groups;
/** maps the group key to group data */
map< limit_order_group_key, limit_order_group_data > _og_data;
};
void limit_order_group_index::object_inserted( const object& objct )
{ try {
const limit_order_object& o = static_cast<const limit_order_object&>( objct );
auto& idx = _og_data;
for( uint16_t group : get_tracked_groups() )
{
auto create_ogo = [&]() {
idx[ limit_order_group_key( group, o.sell_price ) ] = limit_order_group_data( o.sell_price, o.for_sale );
};
// if idx is empty, insert this order
// Note: not capped
if( idx.empty() )
{
create_ogo();
continue;
}
// cap the price
price capped_price = o.sell_price;
price max = o.sell_price.max();
price min = o.sell_price.min();
bool capped_max = false;
bool capped_min = false;
if( o.sell_price > max )
{
capped_price = max;
capped_max = true;
}
else if( o.sell_price < min )
{
capped_price = min;
capped_min = true;
}
// if idx is not empty, find the group that is next to this order
auto itr = idx.lower_bound( limit_order_group_key( group, capped_price ) );
bool check_previous = false;
if( itr == idx.end() || itr->first.group != group
|| itr->first.min_price.base.asset_id != o.sell_price.base.asset_id
|| itr->first.min_price.quote.asset_id != o.sell_price.quote.asset_id )
// not same market or group type
check_previous = true;
else // same market and group type
{
bool update_max = false;
if( capped_price > itr->second.max_price ) // implies itr->min_price <= itr->max_price < max
{
update_max = true;
price max_price = itr->first.min_price * ratio_type( GRAPHENE_100_PERCENT + group, GRAPHENE_100_PERCENT );
// max_price should have been capped here
if( capped_price > max_price ) // new order is out of range
check_previous = true;
}
if( !check_previous ) // new order is within the range
{
if( capped_min && o.sell_price < itr->first.min_price )
{ // need to update itr->min_price here, if itr is below min, and new order is even lower
// TODO improve performance
limit_order_group_data data( itr->second.max_price, o.for_sale + itr->second.total_for_sale );
idx.erase( itr );
idx[ limit_order_group_key( group, o.sell_price ) ] = data;
}
else
{
if( update_max || ( capped_max && o.sell_price > itr->second.max_price ) )
itr->second.max_price = o.sell_price; // store real price here, not capped
itr->second.total_for_sale += o.for_sale;
}
}
}
if( check_previous )
{
if( itr == idx.begin() ) // no previous
create_ogo();
else
{
--itr; // should be valid
if( itr->first.group != group || itr->first.min_price.base.asset_id != o.sell_price.base.asset_id
|| itr->first.min_price.quote.asset_id != o.sell_price.quote.asset_id )
// not same market or group type
create_ogo();
else // same market and group type
{
// due to lower_bound, always true: capped_price < itr->first.min_price, so no need to check again,
// if new order is in range of itr group, always need to update itr->first.min_price, unless
// o.sell_price is higher than max
price min_price = itr->second.max_price / ratio_type( GRAPHENE_100_PERCENT + group, GRAPHENE_100_PERCENT );
// min_price should have been capped here
if( capped_price < min_price ) // new order is out of range
create_ogo();
else if( capped_max && o.sell_price >= itr->first.min_price )
{ // itr is above max, and price of new order is even higher
if( o.sell_price > itr->second.max_price )
itr->second.max_price = o.sell_price;
itr->second.total_for_sale += o.for_sale;
}
else
{ // new order is within the range
// TODO improve performance
limit_order_group_data data( itr->second.max_price, o.for_sale + itr->second.total_for_sale );
idx.erase( itr );
idx[ limit_order_group_key( group, o.sell_price ) ] = data;
}
}
}
}
}
} FC_CAPTURE_AND_RETHROW( (objct) ); }
void limit_order_group_index::object_removed( const object& objct )
{ try {
const limit_order_object& o = static_cast<const limit_order_object&>( objct );
remove_order( o );
} FC_CAPTURE_AND_RETHROW( (objct) ); }
void limit_order_group_index::about_to_modify( const object& objct )
{ try {
const limit_order_object& o = static_cast<const limit_order_object&>( objct );
remove_order( o, false );
} FC_CAPTURE_AND_RETHROW( (objct) ); }
void limit_order_group_index::object_modified( const object& objct )
{ try {
object_inserted( objct );
} FC_CAPTURE_AND_RETHROW( (objct) ); }
void limit_order_group_index::remove_order( const limit_order_object& o, bool remove_empty )
{
auto& idx = _og_data;
for( uint16_t group : get_tracked_groups() )
{
// find the group that should contain this order
auto itr = idx.lower_bound( limit_order_group_key( group, o.sell_price ) );
if( itr == idx.end() || itr->first.group != group
|| itr->first.min_price.base.asset_id != o.sell_price.base.asset_id
|| itr->first.min_price.quote.asset_id != o.sell_price.quote.asset_id
|| itr->second.max_price < o.sell_price )
{
// can not find corresponding group, should not happen
wlog( "can not find the order group containing order for removing (price dismatch): ${o}", ("o",o) );
continue;
}
else // found
{
if( itr->second.total_for_sale < o.for_sale )
// should not happen
wlog( "can not find the order group containing order for removing (amount dismatch): ${o}", ("o",o) );
else if( !remove_empty || itr->second.total_for_sale > o.for_sale )
itr->second.total_for_sale -= o.for_sale;
else
// it's the only order in the group and need to be removed
idx.erase( itr );
}
}
}
grouped_orders_plugin_impl::~grouped_orders_plugin_impl()
{}
} // end namespace detail
grouped_orders_plugin::grouped_orders_plugin() :
my( new detail::grouped_orders_plugin_impl(*this) )
{
}
grouped_orders_plugin::~grouped_orders_plugin()
{
}
std::string grouped_orders_plugin::plugin_name()const
{
return "grouped_orders";
}
void grouped_orders_plugin::plugin_set_program_options(
boost::program_options::options_description& cli,
boost::program_options::options_description& cfg
)
{
cli.add_options()
("tracked-groups", boost::program_options::value<string>()->default_value("[10,100]"), // 0.1% and 1%
"Group orders by percentage increase on price. Specify a JSON array of numbers here, each number is a group, number 1 means 0.01%. ")
;
cfg.add(cli);
}
void grouped_orders_plugin::plugin_initialize(const boost::program_options::variables_map& options)
{ try {
if( options.count( "tracked-groups" ) )
{
const std::string& groups = options["tracked-groups"].as<string>();
my->_tracked_groups = fc::json::from_string(groups).as<flat_set<uint16_t>>( 2 );
my->_tracked_groups.erase( 0 );
}
else
my->_tracked_groups = fc::json::from_string("[10,100]").as<flat_set<uint16_t>>(2);
database().add_secondary_index< primary_index<limit_order_index>, detail::limit_order_group_index >( my->_tracked_groups );
} FC_CAPTURE_AND_RETHROW() }
void grouped_orders_plugin::plugin_startup()
{
}
const flat_set<uint16_t>& grouped_orders_plugin::tracked_groups() const
{
return my->_tracked_groups;
}
const map< limit_order_group_key, limit_order_group_data >& grouped_orders_plugin::limit_order_groups()
{
const auto& idx = database().get_index_type< limit_order_index >();
const auto& pidx = dynamic_cast<const primary_index< limit_order_index >&>(idx);
const auto& logidx = pidx.get_secondary_index< detail::limit_order_group_index >();
return logidx.get_order_groups();
}
} }

View file

@ -4,7 +4,7 @@ add_library( graphene_market_history
market_history_plugin.cpp
)
target_link_libraries( graphene_market_history graphene_chain graphene_app )
target_link_libraries( graphene_market_history PRIVATE graphene_plugin )
target_include_directories( graphene_market_history
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )

View file

@ -5,6 +5,7 @@ add_library( peerplays_sidechain
sidechain_net_manager.cpp
sidechain_net_handler.cpp
sidechain_net_handler_bitcoin.cpp
sidechain_net_handler_hive.cpp
sidechain_net_handler_peerplays.cpp
bitcoin/bech32.cpp
bitcoin/bitcoin_address.cpp
@ -13,6 +14,12 @@ add_library( peerplays_sidechain
bitcoin/segwit_addr.cpp
bitcoin/utils.cpp
bitcoin/sign_bitcoin_transaction.cpp
common/rpc_client.cpp
common/utils.cpp
hive/asset.cpp
hive/operations.cpp
hive/transaction.cpp
hive/types.cpp
)
if (ENABLE_DEV_FEATURES)
@ -36,7 +43,7 @@ endif()
unset(ENABLE_PEERPLAYS_ASSET_DEPOSITS)
unset(ENABLE_PEERPLAYS_ASSET_DEPOSITS CACHE)
target_link_libraries( peerplays_sidechain graphene_chain graphene_app fc zmq )
target_link_libraries( peerplays_sidechain PRIVATE curl graphene_plugin zmq )
target_include_directories( peerplays_sidechain
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )

View file

@ -1,3 +1,4 @@
#include <fc/io/raw.hpp>
#include <graphene/peerplays_sidechain/bitcoin/bitcoin_script.hpp>
#include <graphene/peerplays_sidechain/bitcoin/serialize.hpp>

View file

@ -1,4 +1,5 @@
#include <fc/crypto/base58.hpp>
#include <fc/io/raw.hpp>
#include <graphene/peerplays_sidechain/bitcoin/bitcoin_script.hpp>
#include <graphene/peerplays_sidechain/bitcoin/bitcoin_transaction.hpp>
#include <graphene/peerplays_sidechain/bitcoin/serialize.hpp>

View file

@ -1,4 +1,7 @@
#include <graphene/peerplays_sidechain/bitcoin/serialize.hpp>
#include <fc/io/raw.hpp>
#include <graphene/peerplays_sidechain/bitcoin/sign_bitcoin_transaction.hpp>
namespace graphene { namespace peerplays_sidechain { namespace bitcoin {

View file

@ -0,0 +1,185 @@
#include <graphene/peerplays_sidechain/common/rpc_client.hpp>
#include <sstream>
#include <string>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <curl/curl.h>
#include <fc/crypto/base64.hpp>
#include <fc/log/logger.hpp>
namespace graphene { namespace peerplays_sidechain {
rpc_client::rpc_client(std::string _ip, uint32_t _port, std::string _user, std::string _password, bool _debug_rpc_calls) :
ip(_ip),
port(_port),
user(_user),
password(_password),
debug_rpc_calls(_debug_rpc_calls),
request_id(0) {
authorization.key = "Authorization";
authorization.val = "Basic " + fc::base64_encode(user + ":" + password);
}
std::string rpc_client::retrieve_array_value_from_reply(std::string reply_str, std::string array_path, uint32_t idx) {
std::stringstream ss(reply_str);
boost::property_tree::ptree json;
boost::property_tree::read_json(ss, json);
if (json.find("result") == json.not_found()) {
return "";
}
auto json_result = json.get_child("result");
if (json_result.find(array_path) == json_result.not_found()) {
return "";
}
boost::property_tree::ptree array_ptree = json_result;
if (!array_path.empty()) {
array_ptree = json_result.get_child(array_path);
}
uint32_t array_el_idx = -1;
for (const auto &array_el : array_ptree) {
array_el_idx = array_el_idx + 1;
if (array_el_idx == idx) {
std::stringstream ss_res;
boost::property_tree::json_parser::write_json(ss_res, array_el.second);
return ss_res.str();
}
}
return "";
}
std::string rpc_client::retrieve_value_from_reply(std::string reply_str, std::string value_path) {
std::stringstream ss(reply_str);
boost::property_tree::ptree json;
boost::property_tree::read_json(ss, json);
if (json.find("result") == json.not_found()) {
return "";
}
auto json_result = json.get_child("result");
if (json_result.find(value_path) == json_result.not_found()) {
return "";
}
return json_result.get<std::string>(value_path);
}
std::string rpc_client::send_post_request(std::string method, std::string params, bool show_log) {
std::stringstream body;
request_id = request_id + 1;
body << "{ \"jsonrpc\": \"2.0\", \"id\": " << request_id << ", \"method\": \"" << method << "\"";
if (!params.empty()) {
body << ", \"params\": " << params;
}
body << " }";
const auto reply = send_post_request(body.str(), show_log);
if (reply.body.empty()) {
wlog("RPC call ${function} failed", ("function", __FUNCTION__));
return "";
}
std::stringstream ss(std::string(reply.body.begin(), reply.body.end()));
boost::property_tree::ptree json;
boost::property_tree::read_json(ss, json);
if (reply.status == 200) {
return ss.str();
}
if (json.count("error") && !json.get_child("error").empty()) {
wlog("RPC call ${function} with body ${body} failed with reply '${msg}'", ("function", __FUNCTION__)("body", body.str())("msg", ss.str()));
}
return "";
}
//fc::http::reply rpc_client::send_post_request(std::string body, bool show_log) {
// fc::http::connection conn;
// conn.connect_to(fc::ip::endpoint(fc::ip::address(ip), port));
//
// std::string url = "http://" + ip + ":" + std::to_string(port);
//
// //if (wallet.length() > 0) {
// // url = url + "/wallet/" + wallet;
// //}
//
// fc::http::reply reply = conn.request("POST", url, body, fc::http::headers{authorization});
//
// if (show_log) {
// ilog("### Request URL: ${url}", ("url", url));
// ilog("### Request: ${body}", ("body", body));
// std::stringstream ss(std::string(reply.body.begin(), reply.body.end()));
// ilog("### Response: ${ss}", ("ss", ss.str()));
// }
//
// return reply;
//}
static size_t write_callback(char *ptr, size_t size, size_t nmemb, rpc_reply *reply) {
size_t retval = 0;
if (reply != nullptr) {
reply->body.append(ptr, size * nmemb);
retval = size * nmemb;
}
return retval;
}
rpc_reply rpc_client::send_post_request(std::string body, bool show_log) {
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, "Accept: application/json");
headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, "charset: utf-8");
CURL *curl = curl_easy_init();
if (ip.find("https://", 0) != 0) {
curl_easy_setopt(curl, CURLOPT_URL, ip.c_str());
curl_easy_setopt(curl, CURLOPT_PORT, port);
} else {
std::string full_address = ip + ":" + std::to_string(port);
curl_easy_setopt(curl, CURLOPT_URL, full_address.c_str());
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
}
if (!user.empty()) {
curl_easy_setopt(curl, CURLOPT_USERNAME, user.c_str());
curl_easy_setopt(curl, CURLOPT_PASSWORD, password.c_str());
}
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
//curl_easy_setopt(curl, CURLOPT_VERBOSE, true);
rpc_reply reply;
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &reply);
curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &reply.status);
curl_easy_cleanup(curl);
curl_slist_free_all(headers);
if (show_log) {
std::string url = ip + ":" + std::to_string(port);
ilog("### Request URL: ${url}", ("url", url));
ilog("### Request: ${body}", ("body", body));
std::stringstream ss(std::string(reply.body.begin(), reply.body.end()));
ilog("### Response: ${ss}", ("ss", ss.str()));
}
return reply;
}
}} // namespace graphene::peerplays_sidechain

View file

@ -0,0 +1,8 @@
#include <graphene/peerplays_sidechain/common/utils.hpp>
std::string object_id_to_string(graphene::chain::object_id_type id) {
std::string object_id = fc::to_string(id.space()) + "." +
fc::to_string(id.type()) + "." +
fc::to_string(id.instance());
return object_id;
}

View file

@ -0,0 +1,69 @@
#include <graphene/peerplays_sidechain/hive/asset.hpp>
#include <fc/io/json.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/rational.hpp>
#define ASSET_AMOUNT_KEY "amount"
#define ASSET_PRECISION_KEY "precision"
#define ASSET_NAI_KEY "nai"
namespace graphene { namespace peerplays_sidechain { namespace hive {
uint64_t asset::hbd_symbol_ser = HBD_SYMBOL_SER;
uint64_t asset::hive_symbol_ser = HIVE_SYMBOL_SER;
}}} // namespace graphene::peerplays_sidechain::hive
namespace fc {
void to_variant(const graphene::peerplays_sidechain::hive::asset &var, fc::variant &vo, uint32_t max_depth) {
try {
if (var.symbol == HBD_SYMBOL_SER) {
variant v = mutable_variant_object(ASSET_AMOUNT_KEY, boost::lexical_cast<std::string>(var.amount.value))(ASSET_PRECISION_KEY, uint64_t(HBD_PRECISION))(ASSET_NAI_KEY, HBD_NAI);
vo = v;
}
if (var.symbol == HIVE_SYMBOL_SER) {
variant v = mutable_variant_object(ASSET_AMOUNT_KEY, boost::lexical_cast<std::string>(var.amount.value))(ASSET_PRECISION_KEY, uint64_t(HIVE_PRECISION))(ASSET_NAI_KEY, HIVE_NAI);
vo = v;
}
if (var.symbol == TBD_SYMBOL_SER) {
variant v = mutable_variant_object(ASSET_AMOUNT_KEY, boost::lexical_cast<std::string>(var.amount.value))(ASSET_PRECISION_KEY, uint64_t(TBD_PRECISION))(ASSET_NAI_KEY, TBD_NAI);
vo = v;
}
if (var.symbol == TESTS_SYMBOL_SER) {
variant v = mutable_variant_object(ASSET_AMOUNT_KEY, boost::lexical_cast<std::string>(var.amount.value))(ASSET_PRECISION_KEY, uint64_t(TESTS_PRECISION))(ASSET_NAI_KEY, TESTS_NAI);
vo = v;
}
}
FC_CAPTURE_AND_RETHROW()
}
void from_variant(const fc::variant &var, graphene::peerplays_sidechain::hive::asset &vo, uint32_t max_depth) {
try {
FC_ASSERT(var.is_object(), "Asset has to be treated as object.");
const auto &v_object = var.get_object();
FC_ASSERT(v_object.contains(ASSET_AMOUNT_KEY), "Amount field doesn't exist.");
FC_ASSERT(v_object[ASSET_AMOUNT_KEY].is_string(), "Expected a string type for value '${key}'.", ("key", ASSET_AMOUNT_KEY));
vo.amount = boost::lexical_cast<int64_t>(v_object[ASSET_AMOUNT_KEY].as<std::string>(max_depth));
FC_ASSERT(vo.amount >= 0, "Asset amount cannot be negative");
FC_ASSERT(v_object.contains(ASSET_PRECISION_KEY), "Precision field doesn't exist.");
FC_ASSERT(v_object[ASSET_PRECISION_KEY].is_uint64(), "Expected an unsigned integer type for value '${key}'.", ("key", ASSET_PRECISION_KEY));
FC_ASSERT(v_object.contains(ASSET_NAI_KEY), "NAI field doesn't exist.");
FC_ASSERT(v_object[ASSET_NAI_KEY].is_string(), "Expected a string type for value '${key}'.", ("key", ASSET_NAI_KEY));
if (v_object[ASSET_NAI_KEY].as<std::string>(max_depth) == HBD_NAI) {
vo.symbol = graphene::peerplays_sidechain::hive::asset::hbd_symbol_ser;
}
if (v_object[ASSET_NAI_KEY].as<std::string>(max_depth) == HIVE_NAI) {
vo.symbol = graphene::peerplays_sidechain::hive::asset::hive_symbol_ser;
}
}
FC_CAPTURE_AND_RETHROW()
}
} // namespace fc

View file

@ -0,0 +1,101 @@
#include <graphene/peerplays_sidechain/hive/operations.hpp>
#include <fc/io/raw.hpp>
namespace graphene { namespace peerplays_sidechain { namespace hive {
}}} // namespace graphene::peerplays_sidechain::hive
namespace fc {
static std::string trim_typename_namespace(const std::string &name) {
auto start = name.find_last_of(':');
start = (start == std::string::npos) ? 0 : start + 1;
return name.substr(start);
}
struct from_static_variant_for_hive {
fc::variant &var;
from_static_variant_for_hive(fc::variant &dv) :
var(dv) {
}
typedef void result_type;
template <typename T>
void operator()(const T &v) const {
auto name = trim_typename_namespace(fc::get_typename<T>::name());
fc::variant value;
to_variant(v, value, 5);
var = mutable_variant_object("type", name).set("value", value);
}
};
struct to_static_variant_for_hive {
const fc::variant &var;
to_static_variant_for_hive(const fc::variant &dv) :
var(dv) {
}
typedef void result_type;
template <typename T>
void operator()(T &v) const {
from_variant(var, v, 5);
}
};
struct get_static_variant_name {
string &name;
get_static_variant_name(string &n) :
name(n) {
}
typedef void result_type;
template <typename T>
void operator()(T &v) const {
name = trim_typename_namespace(fc::get_typename<T>::name());
}
};
void to_variant(const graphene::peerplays_sidechain::hive::hive_operation &var, fc::variant &vo, uint32_t max_depth) {
var.visit(from_static_variant_for_hive(vo));
}
void from_variant(const fc::variant &var, graphene::peerplays_sidechain::hive::hive_operation &vo, uint32_t max_depth) {
static std::map<string, int64_t> to_tag = []() {
std::map<string, int64_t> name_map;
for (int i = 0; i < graphene::peerplays_sidechain::hive::hive_operation::count(); ++i) {
graphene::peerplays_sidechain::hive::hive_operation tmp;
tmp.set_which(i);
string n;
tmp.visit(get_static_variant_name(n));
name_map[n] = i;
}
return name_map;
}();
auto ar = var.get_array();
if (ar.size() < 2)
return;
auto var_second = ar[1];
FC_ASSERT(var_second.is_object(), "Input data have to treated as object.");
auto v_object = var_second.get_object();
FC_ASSERT(v_object.contains("type"), "Type field doesn't exist.");
FC_ASSERT(v_object.contains("value"), "Value field doesn't exist.");
int64_t which = -1;
if (v_object["type"].is_integer()) {
which = v_object["type"].as_int64();
} else {
auto itr = to_tag.find(v_object["type"].as_string());
FC_ASSERT(itr != to_tag.end(), "Invalid object name: ${n}", ("n", v_object["type"]));
which = itr->second;
}
vo.set_which(which);
vo.visit(fc::to_static_variant_for_hive(v_object["value"]));
}
} // namespace fc

View file

@ -0,0 +1,57 @@
#include <graphene/peerplays_sidechain/hive/transaction.hpp>
#include <boost/algorithm/hex.hpp>
#include <fc/bitutil.hpp>
#include <fc/io/raw.hpp>
namespace graphene { namespace peerplays_sidechain { namespace hive {
digest_type transaction::digest() const {
digest_type::encoder enc;
fc::raw::pack(enc, *this);
return enc.result();
}
transaction_id_type transaction::id() const {
auto h = digest();
transaction_id_type result;
memcpy(result._hash, h._hash, std::min(sizeof(result), sizeof(h)));
return result;
}
digest_type transaction::sig_digest(const chain_id_type &chain_id) const {
digest_type::encoder enc;
fc::raw::pack(enc, chain_id);
fc::raw::pack(enc, *this);
return enc.result();
}
void transaction::set_expiration(fc::time_point_sec expiration_time) {
expiration = expiration_time;
}
void transaction::set_reference_block(const block_id_type &reference_block) {
ref_block_num = fc::endian_reverse_u32(reference_block._hash[0]);
ref_block_prefix = reference_block._hash[1];
}
void signed_transaction::clear() {
operations.clear();
signatures.clear();
}
const signature_type &signed_transaction::sign(const hive::private_key_type &key, const hive::chain_id_type &chain_id) {
digest_type h = sig_digest(chain_id);
signatures.push_back(key.sign_compact(h, true));
return signatures.back();
}
signature_type signed_transaction::sign(const hive::private_key_type &key, const hive::chain_id_type &chain_id) const {
digest_type::encoder enc;
fc::raw::pack(enc, chain_id);
fc::raw::pack(enc, *this);
return key.sign_compact(enc.result(), true);
}
}}} // namespace graphene::peerplays_sidechain::hive

View file

@ -0,0 +1,73 @@
#include <graphene/peerplays_sidechain/hive/types.hpp>
#include <fc/crypto/base58.hpp>
#include <fc/crypto/ripemd160.hpp>
#include <fc/exception/exception.hpp>
#include <fc/io/raw.hpp>
namespace graphene { namespace peerplays_sidechain { namespace hive {
std::string public_key_type::prefix = KEY_PREFIX_STM;
public_key_type::public_key_type() :
key_data(){};
public_key_type::public_key_type(const fc::ecc::public_key_data &data) :
key_data(data){};
public_key_type::public_key_type(const fc::ecc::public_key &pubkey) :
key_data(pubkey){};
public_key_type::public_key_type(const std::string &base58str) {
const size_t prefix_len = prefix.size();
FC_ASSERT(base58str.size() > prefix_len);
FC_ASSERT(base58str.substr(0, prefix_len) == prefix, "", ("base58str", base58str));
auto bin = fc::from_base58(base58str.substr(prefix_len));
auto bin_key = fc::raw::unpack<binary_key>(bin);
key_data = bin_key.data;
FC_ASSERT(fc::ripemd160::hash(key_data.data, key_data.size())._hash[0] == bin_key.check);
};
public_key_type::operator fc::ecc::public_key_data() const {
return key_data;
};
public_key_type::operator fc::ecc::public_key() const {
return fc::ecc::public_key(key_data);
};
public_key_type::operator std::string() const {
binary_key k;
k.data = key_data;
k.check = fc::ripemd160::hash(k.data.data, k.data.size())._hash[0];
auto data = fc::raw::pack(k);
return prefix + fc::to_base58(data.data(), data.size());
}
bool operator==(const public_key_type &p1, const fc::ecc::public_key &p2) {
return p1.key_data == p2.serialize();
}
bool operator==(const public_key_type &p1, const public_key_type &p2) {
return p1.key_data == p2.key_data;
}
bool operator!=(const public_key_type &p1, const public_key_type &p2) {
return p1.key_data != p2.key_data;
}
}}} // namespace graphene::peerplays_sidechain::hive
namespace fc {
using namespace std;
void to_variant(const graphene::peerplays_sidechain::hive::public_key_type &var, fc::variant &vo, uint32_t max_depth) {
vo = std::string(var);
}
void from_variant(const fc::variant &var, graphene::peerplays_sidechain::hive::public_key_type &vo, uint32_t max_depth) {
vo = graphene::peerplays_sidechain::hive::public_key_type(var.as_string());
}
} // namespace fc

View file

@ -0,0 +1,39 @@
#pragma once
#include <cstdint>
#include <string>
#include <fc/network/http/connection.hpp>
namespace graphene { namespace peerplays_sidechain {
struct rpc_reply {
uint16_t status;
std::string body;
};
class rpc_client {
public:
rpc_client(std::string _ip, uint32_t _port, std::string _user, std::string _password, bool _debug_rpc_calls);
protected:
std::string retrieve_array_value_from_reply(std::string reply_str, std::string array_path, uint32_t idx);
std::string retrieve_value_from_reply(std::string reply_str, std::string value_path);
std::string send_post_request(std::string method, std::string params, bool show_log);
std::string ip;
uint32_t port;
std::string user;
std::string password;
bool debug_rpc_calls;
uint32_t request_id;
fc::http::header authorization;
private:
//fc::http::reply send_post_request(std::string body, bool show_log);
rpc_reply send_post_request(std::string body, bool show_log);
};
}} // namespace graphene::peerplays_sidechain

View file

@ -0,0 +1,5 @@
#pragma once
#include <graphene/chain/protocol/asset.hpp>
std::string object_id_to_string(graphene::chain::object_id_type id);

View file

@ -0,0 +1,41 @@
#pragma once
#include <graphene/peerplays_sidechain/hive/types.hpp>
namespace graphene { namespace peerplays_sidechain { namespace hive {
#define HBD_NAI "@@000000013"
#define HBD_PRECISION 3
#define HBD_SYMBOL_U64 (uint64_t('S') | (uint64_t('B') << 8) | (uint64_t('D') << 16))
#define HBD_SYMBOL_SER (uint64_t(3) | (HBD_SYMBOL_U64 << 8))
#define HIVE_NAI "@@000000021"
#define HIVE_PRECISION 3
#define HIVE_SYMBOL_U64 (uint64_t('S') | (uint64_t('T') << 8) | (uint64_t('E') << 16) | (uint64_t('E') << 24) | (uint64_t('M') << 32))
#define HIVE_SYMBOL_SER (uint64_t(3) | (HIVE_SYMBOL_U64 << 8))
#define TBD_NAI "@@000000013"
#define TBD_PRECISION 3
#define TBD_SYMBOL_U64 (uint64_t('T') | (uint64_t('B') << 8) | (uint64_t('D') << 16))
#define TBD_SYMBOL_SER (uint64_t(3) | (TBD_SYMBOL_U64 << 8))
#define TESTS_NAI "@@000000021"
#define TESTS_PRECISION 3
#define TESTS_SYMBOL_U64 (uint64_t('T') | (uint64_t('E') << 8) | (uint64_t('S') << 16) | (uint64_t('T') << 24) | (uint64_t('S') << 32))
#define TESTS_SYMBOL_SER (uint64_t(3) | (TESTS_SYMBOL_U64 << 8))
struct asset {
static uint64_t hbd_symbol_ser;
static uint64_t hive_symbol_ser;
share_type amount;
uint64_t symbol;
};
}}} // namespace graphene::peerplays_sidechain::hive
namespace fc {
void to_variant(const graphene::peerplays_sidechain::hive::asset &var, fc::variant &vo, uint32_t max_depth);
void from_variant(const fc::variant &var, graphene::peerplays_sidechain::hive::asset &vo, uint32_t max_depth);
} // namespace fc
FC_REFLECT(graphene::peerplays_sidechain::hive::asset, (amount)(symbol))

View file

@ -0,0 +1,33 @@
#pragma once
#include <cstdint>
#include <fc/container/flat_fwd.hpp>
#include <graphene/peerplays_sidechain/hive/types.hpp>
namespace graphene { namespace peerplays_sidechain { namespace hive {
struct authority {
authority() {
}
enum classification {
owner = 0,
active = 1,
key = 2,
posting = 3
};
uint32_t weight_threshold = 0;
fc::flat_map<hive::account_name_type, uint16_t> account_auths;
fc::flat_map<hive::public_key_type, uint16_t> key_auths;
};
}}} // namespace graphene::peerplays_sidechain::hive
FC_REFLECT_ENUM(graphene::peerplays_sidechain::hive::authority::classification,
(owner)(active)(key)(posting))
FC_REFLECT(graphene::peerplays_sidechain::hive::authority,
(weight_threshold)(account_auths)(key_auths))

View file

@ -0,0 +1,123 @@
#pragma once
#include <cstdint>
#include <vector>
#include <fc/optional.hpp>
#include <graphene/chain/protocol/types.hpp>
#include <graphene/peerplays_sidechain/hive/asset.hpp>
#include <graphene/peerplays_sidechain/hive/authority.hpp>
#include <graphene/peerplays_sidechain/hive/types.hpp>
namespace graphene { namespace peerplays_sidechain { namespace hive {
struct vote_operation {};
struct comment_operation {};
struct transfer_operation {
hive::account_name_type from;
hive::account_name_type to;
hive::asset amount;
std::string memo;
};
struct transfer_to_vesting_operation {};
struct withdraw_vesting_operation {};
struct limit_order_create_operation {};
struct limit_order_cancel_operation {};
struct feed_publish_operation {};
struct convert_operation {};
struct account_create_operation {};
struct account_update_operation {
hive::account_name_type account;
fc::optional<authority> owner;
fc::optional<authority> active;
fc::optional<authority> posting;
hive::public_key_type memo_key;
std::string json_metadata;
};
struct witness_update_operation {};
struct account_witness_vote_operation {};
struct account_witness_proxy_operation {};
struct pow_operation {};
struct custom_operation {};
struct report_over_production_operation {};
struct delete_comment_operation {};
struct custom_json_operation {};
struct comment_options_operation {};
struct set_withdraw_vesting_route_operation {};
struct limit_order_create2_operation {};
struct claim_account_operation {};
struct create_claimed_account_operation {};
struct request_account_recovery_operation {};
struct recover_account_operation {};
struct change_recovery_account_operation {};
struct escrow_transfer_operation {};
struct escrow_dispute_operation {};
struct escrow_release_operation {};
struct pow2_operation {};
struct escrow_approve_operation {};
struct transfer_to_savings_operation {};
struct transfer_from_savings_operation {};
struct cancel_transfer_from_savings_operation {};
struct custom_binary_operation {};
struct decline_voting_rights_operation {};
struct reset_account_operation {};
struct set_reset_account_operation {};
struct claim_reward_balance_operation {};
struct delegate_vesting_shares_operation {
hive::account_name_type delegator;
hive::account_name_type delegatee;
hive::asset vesting_shares;
};
}}} // namespace graphene::peerplays_sidechain::hive
FC_REFLECT(graphene::peerplays_sidechain::hive::vote_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::comment_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::transfer_operation,
(from)(to)(amount)(memo))
FC_REFLECT(graphene::peerplays_sidechain::hive::transfer_to_vesting_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::withdraw_vesting_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::limit_order_create_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::limit_order_cancel_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::feed_publish_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::convert_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::account_create_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::account_update_operation,
(account)(owner)(active)(posting)(memo_key)(json_metadata))
FC_REFLECT(graphene::peerplays_sidechain::hive::witness_update_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::account_witness_vote_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::account_witness_proxy_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::pow_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::custom_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::report_over_production_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::delete_comment_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::custom_json_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::comment_options_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::set_withdraw_vesting_route_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::limit_order_create2_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::claim_account_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::create_claimed_account_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::request_account_recovery_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::recover_account_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::change_recovery_account_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::escrow_transfer_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::escrow_dispute_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::escrow_release_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::pow2_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::escrow_approve_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::transfer_to_savings_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::transfer_from_savings_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::cancel_transfer_from_savings_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::custom_binary_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::decline_voting_rights_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::reset_account_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::set_reset_account_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::claim_reward_balance_operation, )
FC_REFLECT(graphene::peerplays_sidechain::hive::delegate_vesting_shares_operation,
(delegator)(delegatee)(vesting_shares))

View file

@ -0,0 +1,69 @@
#pragma once
#include <graphene/peerplays_sidechain/hive/hive_operations.hpp>
namespace graphene { namespace peerplays_sidechain { namespace hive {
typedef fc::static_variant<
vote_operation,
comment_operation,
transfer_operation,
transfer_to_vesting_operation,
withdraw_vesting_operation,
limit_order_create_operation,
limit_order_cancel_operation,
feed_publish_operation,
convert_operation,
account_create_operation,
account_update_operation,
witness_update_operation,
account_witness_vote_operation,
account_witness_proxy_operation,
pow_operation,
custom_operation,
report_over_production_operation,
delete_comment_operation,
custom_json_operation,
comment_options_operation,
set_withdraw_vesting_route_operation,
limit_order_create2_operation,
claim_account_operation,
create_claimed_account_operation,
request_account_recovery_operation,
recover_account_operation,
change_recovery_account_operation,
escrow_transfer_operation,
escrow_dispute_operation,
escrow_release_operation,
pow2_operation,
escrow_approve_operation,
transfer_to_savings_operation,
transfer_from_savings_operation,
cancel_transfer_from_savings_operation,
custom_binary_operation,
decline_voting_rights_operation,
reset_account_operation,
set_reset_account_operation,
claim_reward_balance_operation,
delegate_vesting_shares_operation>
hive_operation;
}}} // namespace graphene::peerplays_sidechain::hive
namespace fc {
void to_variant(const graphene::peerplays_sidechain::hive::hive_operation &var, fc::variant &vo, uint32_t max_depth = 5);
void from_variant(const fc::variant &var, graphene::peerplays_sidechain::hive::hive_operation &vo, uint32_t max_depth = 5);
} // namespace fc
FC_REFLECT_TYPENAME(graphene::peerplays_sidechain::hive::hive_operation)

Some files were not shown because too many files have changed in this diff Show more