[SON-271] Merge recent develop branch changes(both GPOS and graphene updates) into SONs branch (#322)

This commit is contained in:
obucina 2020-03-27 18:46:30 +01:00 committed by GitHub
parent e170676ff9
commit 54390346c1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
173 changed files with 7814 additions and 1521 deletions

0
.clang-format Executable file → Normal file
View file

1
.gitignore vendored
View file

@ -11,6 +11,7 @@ moc_*
hardfork.hpp
build_xc
data
CMakeDoxyfile.in
build

3
.gitmodules vendored
View file

@ -4,5 +4,6 @@
ignore = dirty
[submodule "libraries/fc"]
path = libraries/fc
url = https://github.com/PBSA/peerplays-fc.git
url = https://github.com/peerplays-network/peerplays-fc.git
branch = latest-fc
ignore = dirty

279
CMakeDoxyfile.in Normal file
View file

@ -0,0 +1,279 @@
#
# DO NOT EDIT! THIS FILE WAS GENERATED BY CMAKE!
#
DOXYFILE_ENCODING = @DOXYGEN_DOXYFILE_ENCODING@
PROJECT_NAME = @DOXYGEN_PROJECT_NAME@
PROJECT_NUMBER = @DOXYGEN_PROJECT_NUMBER@
PROJECT_BRIEF = @DOXYGEN_PROJECT_BRIEF@
PROJECT_LOGO = @DOXYGEN_PROJECT_LOGO@
OUTPUT_DIRECTORY = @DOXYGEN_OUTPUT_DIRECTORY@
CREATE_SUBDIRS = @DOXYGEN_CREATE_SUBDIRS@
ALLOW_UNICODE_NAMES = @DOXYGEN_ALLOW_UNICODE_NAMES@
OUTPUT_LANGUAGE = @DOXYGEN_OUTPUT_LANGUAGE@
OUTPUT_TEXT_DIRECTION = @DOXYGEN_OUTPUT_TEXT_DIRECTION@
BRIEF_MEMBER_DESC = @DOXYGEN_BRIEF_MEMBER_DESC@
REPEAT_BRIEF = @DOXYGEN_REPEAT_BRIEF@
ABBREVIATE_BRIEF = @DOXYGEN_ABBREVIATE_BRIEF@
ALWAYS_DETAILED_SEC = @DOXYGEN_ALWAYS_DETAILED_SEC@
INLINE_INHERITED_MEMB = @DOXYGEN_INLINE_INHERITED_MEMB@
FULL_PATH_NAMES = @DOXYGEN_FULL_PATH_NAMES@
STRIP_FROM_PATH = @DOXYGEN_STRIP_FROM_PATH@
STRIP_FROM_INC_PATH = @DOXYGEN_STRIP_FROM_INC_PATH@
SHORT_NAMES = @DOXYGEN_SHORT_NAMES@
JAVADOC_AUTOBRIEF = @DOXYGEN_JAVADOC_AUTOBRIEF@
JAVADOC_BANNER = @DOXYGEN_JAVADOC_BANNER@
QT_AUTOBRIEF = @DOXYGEN_QT_AUTOBRIEF@
MULTILINE_CPP_IS_BRIEF = @DOXYGEN_MULTILINE_CPP_IS_BRIEF@
INHERIT_DOCS = @DOXYGEN_INHERIT_DOCS@
SEPARATE_MEMBER_PAGES = @DOXYGEN_SEPARATE_MEMBER_PAGES@
TAB_SIZE = @DOXYGEN_TAB_SIZE@
ALIASES = @DOXYGEN_ALIASES@
TCL_SUBST = @DOXYGEN_TCL_SUBST@
OPTIMIZE_OUTPUT_FOR_C = @DOXYGEN_OPTIMIZE_OUTPUT_FOR_C@
OPTIMIZE_OUTPUT_JAVA = @DOXYGEN_OPTIMIZE_OUTPUT_JAVA@
OPTIMIZE_FOR_FORTRAN = @DOXYGEN_OPTIMIZE_FOR_FORTRAN@
OPTIMIZE_OUTPUT_VHDL = @DOXYGEN_OPTIMIZE_OUTPUT_VHDL@
OPTIMIZE_OUTPUT_SLICE = @DOXYGEN_OPTIMIZE_OUTPUT_SLICE@
EXTENSION_MAPPING = @DOXYGEN_EXTENSION_MAPPING@
MARKDOWN_SUPPORT = @DOXYGEN_MARKDOWN_SUPPORT@
TOC_INCLUDE_HEADINGS = @DOXYGEN_TOC_INCLUDE_HEADINGS@
AUTOLINK_SUPPORT = @DOXYGEN_AUTOLINK_SUPPORT@
BUILTIN_STL_SUPPORT = @DOXYGEN_BUILTIN_STL_SUPPORT@
CPP_CLI_SUPPORT = @DOXYGEN_CPP_CLI_SUPPORT@
SIP_SUPPORT = @DOXYGEN_SIP_SUPPORT@
IDL_PROPERTY_SUPPORT = @DOXYGEN_IDL_PROPERTY_SUPPORT@
DISTRIBUTE_GROUP_DOC = @DOXYGEN_DISTRIBUTE_GROUP_DOC@
GROUP_NESTED_COMPOUNDS = @DOXYGEN_GROUP_NESTED_COMPOUNDS@
SUBGROUPING = @DOXYGEN_SUBGROUPING@
INLINE_GROUPED_CLASSES = @DOXYGEN_INLINE_GROUPED_CLASSES@
INLINE_SIMPLE_STRUCTS = @DOXYGEN_INLINE_SIMPLE_STRUCTS@
TYPEDEF_HIDES_STRUCT = @DOXYGEN_TYPEDEF_HIDES_STRUCT@
LOOKUP_CACHE_SIZE = @DOXYGEN_LOOKUP_CACHE_SIZE@
EXTRACT_ALL = @DOXYGEN_EXTRACT_ALL@
EXTRACT_PRIVATE = @DOXYGEN_EXTRACT_PRIVATE@
EXTRACT_PRIV_VIRTUAL = @DOXYGEN_EXTRACT_PRIV_VIRTUAL@
EXTRACT_PACKAGE = @DOXYGEN_EXTRACT_PACKAGE@
EXTRACT_STATIC = @DOXYGEN_EXTRACT_STATIC@
EXTRACT_LOCAL_CLASSES = @DOXYGEN_EXTRACT_LOCAL_CLASSES@
EXTRACT_LOCAL_METHODS = @DOXYGEN_EXTRACT_LOCAL_METHODS@
EXTRACT_ANON_NSPACES = @DOXYGEN_EXTRACT_ANON_NSPACES@
HIDE_UNDOC_MEMBERS = @DOXYGEN_HIDE_UNDOC_MEMBERS@
HIDE_UNDOC_CLASSES = @DOXYGEN_HIDE_UNDOC_CLASSES@
HIDE_FRIEND_COMPOUNDS = @DOXYGEN_HIDE_FRIEND_COMPOUNDS@
HIDE_IN_BODY_DOCS = @DOXYGEN_HIDE_IN_BODY_DOCS@
INTERNAL_DOCS = @DOXYGEN_INTERNAL_DOCS@
CASE_SENSE_NAMES = @DOXYGEN_CASE_SENSE_NAMES@
HIDE_SCOPE_NAMES = @DOXYGEN_HIDE_SCOPE_NAMES@
HIDE_COMPOUND_REFERENCE= @DOXYGEN_HIDE_COMPOUND_REFERENCE@
SHOW_INCLUDE_FILES = @DOXYGEN_SHOW_INCLUDE_FILES@
SHOW_GROUPED_MEMB_INC = @DOXYGEN_SHOW_GROUPED_MEMB_INC@
FORCE_LOCAL_INCLUDES = @DOXYGEN_FORCE_LOCAL_INCLUDES@
INLINE_INFO = @DOXYGEN_INLINE_INFO@
SORT_MEMBER_DOCS = @DOXYGEN_SORT_MEMBER_DOCS@
SORT_BRIEF_DOCS = @DOXYGEN_SORT_BRIEF_DOCS@
SORT_MEMBERS_CTORS_1ST = @DOXYGEN_SORT_MEMBERS_CTORS_1ST@
SORT_GROUP_NAMES = @DOXYGEN_SORT_GROUP_NAMES@
SORT_BY_SCOPE_NAME = @DOXYGEN_SORT_BY_SCOPE_NAME@
STRICT_PROTO_MATCHING = @DOXYGEN_STRICT_PROTO_MATCHING@
GENERATE_TODOLIST = @DOXYGEN_GENERATE_TODOLIST@
GENERATE_TESTLIST = @DOXYGEN_GENERATE_TESTLIST@
GENERATE_BUGLIST = @DOXYGEN_GENERATE_BUGLIST@
GENERATE_DEPRECATEDLIST= @DOXYGEN_GENERATE_DEPRECATEDLIST@
ENABLED_SECTIONS = @DOXYGEN_ENABLED_SECTIONS@
MAX_INITIALIZER_LINES = @DOXYGEN_MAX_INITIALIZER_LINES@
SHOW_USED_FILES = @DOXYGEN_SHOW_USED_FILES@
SHOW_FILES = @DOXYGEN_SHOW_FILES@
SHOW_NAMESPACES = @DOXYGEN_SHOW_NAMESPACES@
FILE_VERSION_FILTER = @DOXYGEN_FILE_VERSION_FILTER@
LAYOUT_FILE = @DOXYGEN_LAYOUT_FILE@
CITE_BIB_FILES = @DOXYGEN_CITE_BIB_FILES@
QUIET = @DOXYGEN_QUIET@
WARNINGS = @DOXYGEN_WARNINGS@
WARN_IF_UNDOCUMENTED = @DOXYGEN_WARN_IF_UNDOCUMENTED@
WARN_IF_DOC_ERROR = @DOXYGEN_WARN_IF_DOC_ERROR@
WARN_NO_PARAMDOC = @DOXYGEN_WARN_NO_PARAMDOC@
WARN_AS_ERROR = @DOXYGEN_WARN_AS_ERROR@
WARN_FORMAT = @DOXYGEN_WARN_FORMAT@
WARN_LOGFILE = @DOXYGEN_WARN_LOGFILE@
INPUT = @DOXYGEN_INPUT@
INPUT_ENCODING = @DOXYGEN_INPUT_ENCODING@
FILE_PATTERNS = @DOXYGEN_FILE_PATTERNS@
RECURSIVE = @DOXYGEN_RECURSIVE@
EXCLUDE = @DOXYGEN_EXCLUDE@
EXCLUDE_SYMLINKS = @DOXYGEN_EXCLUDE_SYMLINKS@
EXCLUDE_PATTERNS = @DOXYGEN_EXCLUDE_PATTERNS@
EXCLUDE_SYMBOLS = @DOXYGEN_EXCLUDE_SYMBOLS@
EXAMPLE_PATH = @DOXYGEN_EXAMPLE_PATH@
EXAMPLE_PATTERNS = @DOXYGEN_EXAMPLE_PATTERNS@
EXAMPLE_RECURSIVE = @DOXYGEN_EXAMPLE_RECURSIVE@
IMAGE_PATH = @DOXYGEN_IMAGE_PATH@
INPUT_FILTER = @DOXYGEN_INPUT_FILTER@
FILTER_PATTERNS = @DOXYGEN_FILTER_PATTERNS@
FILTER_SOURCE_FILES = @DOXYGEN_FILTER_SOURCE_FILES@
FILTER_SOURCE_PATTERNS = @DOXYGEN_FILTER_SOURCE_PATTERNS@
USE_MDFILE_AS_MAINPAGE = @DOXYGEN_USE_MDFILE_AS_MAINPAGE@
SOURCE_BROWSER = @DOXYGEN_SOURCE_BROWSER@
INLINE_SOURCES = @DOXYGEN_INLINE_SOURCES@
STRIP_CODE_COMMENTS = @DOXYGEN_STRIP_CODE_COMMENTS@
REFERENCED_BY_RELATION = @DOXYGEN_REFERENCED_BY_RELATION@
REFERENCES_RELATION = @DOXYGEN_REFERENCES_RELATION@
REFERENCES_LINK_SOURCE = @DOXYGEN_REFERENCES_LINK_SOURCE@
SOURCE_TOOLTIPS = @DOXYGEN_SOURCE_TOOLTIPS@
USE_HTAGS = @DOXYGEN_USE_HTAGS@
VERBATIM_HEADERS = @DOXYGEN_VERBATIM_HEADERS@
CLANG_ASSISTED_PARSING = @DOXYGEN_CLANG_ASSISTED_PARSING@
CLANG_OPTIONS = @DOXYGEN_CLANG_OPTIONS@
CLANG_DATABASE_PATH = @DOXYGEN_CLANG_DATABASE_PATH@
ALPHABETICAL_INDEX = @DOXYGEN_ALPHABETICAL_INDEX@
COLS_IN_ALPHA_INDEX = @DOXYGEN_COLS_IN_ALPHA_INDEX@
IGNORE_PREFIX = @DOXYGEN_IGNORE_PREFIX@
GENERATE_HTML = @DOXYGEN_GENERATE_HTML@
HTML_OUTPUT = @DOXYGEN_HTML_OUTPUT@
HTML_FILE_EXTENSION = @DOXYGEN_HTML_FILE_EXTENSION@
HTML_HEADER = @DOXYGEN_HTML_HEADER@
HTML_FOOTER = @DOXYGEN_HTML_FOOTER@
HTML_STYLESHEET = @DOXYGEN_HTML_STYLESHEET@
HTML_EXTRA_STYLESHEET = @DOXYGEN_HTML_EXTRA_STYLESHEET@
HTML_EXTRA_FILES = @DOXYGEN_HTML_EXTRA_FILES@
HTML_COLORSTYLE_HUE = @DOXYGEN_HTML_COLORSTYLE_HUE@
HTML_COLORSTYLE_SAT = @DOXYGEN_HTML_COLORSTYLE_SAT@
HTML_COLORSTYLE_GAMMA = @DOXYGEN_HTML_COLORSTYLE_GAMMA@
HTML_TIMESTAMP = @DOXYGEN_HTML_TIMESTAMP@
HTML_DYNAMIC_MENUS = @DOXYGEN_HTML_DYNAMIC_MENUS@
HTML_DYNAMIC_SECTIONS = @DOXYGEN_HTML_DYNAMIC_SECTIONS@
HTML_INDEX_NUM_ENTRIES = @DOXYGEN_HTML_INDEX_NUM_ENTRIES@
GENERATE_DOCSET = @DOXYGEN_GENERATE_DOCSET@
DOCSET_FEEDNAME = @DOXYGEN_DOCSET_FEEDNAME@
DOCSET_BUNDLE_ID = @DOXYGEN_DOCSET_BUNDLE_ID@
DOCSET_PUBLISHER_ID = @DOXYGEN_DOCSET_PUBLISHER_ID@
DOCSET_PUBLISHER_NAME = @DOXYGEN_DOCSET_PUBLISHER_NAME@
GENERATE_HTMLHELP = @DOXYGEN_GENERATE_HTMLHELP@
CHM_FILE = @DOXYGEN_CHM_FILE@
HHC_LOCATION = @DOXYGEN_HHC_LOCATION@
GENERATE_CHI = @DOXYGEN_GENERATE_CHI@
CHM_INDEX_ENCODING = @DOXYGEN_CHM_INDEX_ENCODING@
BINARY_TOC = @DOXYGEN_BINARY_TOC@
TOC_EXPAND = @DOXYGEN_TOC_EXPAND@
GENERATE_QHP = @DOXYGEN_GENERATE_QHP@
QCH_FILE = @DOXYGEN_QCH_FILE@
QHP_NAMESPACE = @DOXYGEN_QHP_NAMESPACE@
QHP_VIRTUAL_FOLDER = @DOXYGEN_QHP_VIRTUAL_FOLDER@
QHP_CUST_FILTER_NAME = @DOXYGEN_QHP_CUST_FILTER_NAME@
QHP_CUST_FILTER_ATTRS = @DOXYGEN_QHP_CUST_FILTER_ATTRS@
QHP_SECT_FILTER_ATTRS = @DOXYGEN_QHP_SECT_FILTER_ATTRS@
QHG_LOCATION = @DOXYGEN_QHG_LOCATION@
GENERATE_ECLIPSEHELP = @DOXYGEN_GENERATE_ECLIPSEHELP@
ECLIPSE_DOC_ID = @DOXYGEN_ECLIPSE_DOC_ID@
DISABLE_INDEX = @DOXYGEN_DISABLE_INDEX@
GENERATE_TREEVIEW = @DOXYGEN_GENERATE_TREEVIEW@
ENUM_VALUES_PER_LINE = @DOXYGEN_ENUM_VALUES_PER_LINE@
TREEVIEW_WIDTH = @DOXYGEN_TREEVIEW_WIDTH@
EXT_LINKS_IN_WINDOW = @DOXYGEN_EXT_LINKS_IN_WINDOW@
FORMULA_FONTSIZE = @DOXYGEN_FORMULA_FONTSIZE@
FORMULA_TRANSPARENT = @DOXYGEN_FORMULA_TRANSPARENT@
USE_MATHJAX = @DOXYGEN_USE_MATHJAX@
MATHJAX_FORMAT = @DOXYGEN_MATHJAX_FORMAT@
MATHJAX_RELPATH = @DOXYGEN_MATHJAX_RELPATH@
MATHJAX_EXTENSIONS = @DOXYGEN_MATHJAX_EXTENSIONS@
MATHJAX_CODEFILE = @DOXYGEN_MATHJAX_CODEFILE@
SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
EXTERNAL_SEARCH = @DOXYGEN_EXTERNAL_SEARCH@
SEARCHENGINE_URL = @DOXYGEN_SEARCHENGINE_URL@
SEARCHDATA_FILE = @DOXYGEN_SEARCHDATA_FILE@
EXTERNAL_SEARCH_ID = @DOXYGEN_EXTERNAL_SEARCH_ID@
EXTRA_SEARCH_MAPPINGS = @DOXYGEN_EXTRA_SEARCH_MAPPINGS@
GENERATE_LATEX = @DOXYGEN_GENERATE_LATEX@
LATEX_OUTPUT = @DOXYGEN_LATEX_OUTPUT@
LATEX_CMD_NAME = @DOXYGEN_LATEX_CMD_NAME@
MAKEINDEX_CMD_NAME = @DOXYGEN_MAKEINDEX_CMD_NAME@
LATEX_MAKEINDEX_CMD = @DOXYGEN_LATEX_MAKEINDEX_CMD@
COMPACT_LATEX = @DOXYGEN_COMPACT_LATEX@
PAPER_TYPE = @DOXYGEN_PAPER_TYPE@
EXTRA_PACKAGES = @DOXYGEN_EXTRA_PACKAGES@
LATEX_HEADER = @DOXYGEN_LATEX_HEADER@
LATEX_FOOTER = @DOXYGEN_LATEX_FOOTER@
LATEX_EXTRA_STYLESHEET = @DOXYGEN_LATEX_EXTRA_STYLESHEET@
LATEX_EXTRA_FILES = @DOXYGEN_LATEX_EXTRA_FILES@
PDF_HYPERLINKS = @DOXYGEN_PDF_HYPERLINKS@
USE_PDFLATEX = @DOXYGEN_USE_PDFLATEX@
LATEX_BATCHMODE = @DOXYGEN_LATEX_BATCHMODE@
LATEX_HIDE_INDICES = @DOXYGEN_LATEX_HIDE_INDICES@
LATEX_SOURCE_CODE = @DOXYGEN_LATEX_SOURCE_CODE@
LATEX_BIB_STYLE = @DOXYGEN_LATEX_BIB_STYLE@
LATEX_TIMESTAMP = @DOXYGEN_LATEX_TIMESTAMP@
LATEX_EMOJI_DIRECTORY = @DOXYGEN_LATEX_EMOJI_DIRECTORY@
GENERATE_RTF = @DOXYGEN_GENERATE_RTF@
RTF_OUTPUT = @DOXYGEN_RTF_OUTPUT@
COMPACT_RTF = @DOXYGEN_COMPACT_RTF@
RTF_HYPERLINKS = @DOXYGEN_RTF_HYPERLINKS@
RTF_STYLESHEET_FILE = @DOXYGEN_RTF_STYLESHEET_FILE@
RTF_EXTENSIONS_FILE = @DOXYGEN_RTF_EXTENSIONS_FILE@
RTF_SOURCE_CODE = @DOXYGEN_RTF_SOURCE_CODE@
GENERATE_MAN = @DOXYGEN_GENERATE_MAN@
MAN_OUTPUT = @DOXYGEN_MAN_OUTPUT@
MAN_EXTENSION = @DOXYGEN_MAN_EXTENSION@
MAN_SUBDIR = @DOXYGEN_MAN_SUBDIR@
MAN_LINKS = @DOXYGEN_MAN_LINKS@
GENERATE_XML = @DOXYGEN_GENERATE_XML@
XML_OUTPUT = @DOXYGEN_XML_OUTPUT@
XML_PROGRAMLISTING = @DOXYGEN_XML_PROGRAMLISTING@
XML_NS_MEMB_FILE_SCOPE = @DOXYGEN_XML_NS_MEMB_FILE_SCOPE@
GENERATE_DOCBOOK = @DOXYGEN_GENERATE_DOCBOOK@
DOCBOOK_OUTPUT = @DOXYGEN_DOCBOOK_OUTPUT@
DOCBOOK_PROGRAMLISTING = @DOXYGEN_DOCBOOK_PROGRAMLISTING@
GENERATE_AUTOGEN_DEF = @DOXYGEN_GENERATE_AUTOGEN_DEF@
GENERATE_PERLMOD = @DOXYGEN_GENERATE_PERLMOD@
PERLMOD_LATEX = @DOXYGEN_PERLMOD_LATEX@
PERLMOD_PRETTY = @DOXYGEN_PERLMOD_PRETTY@
PERLMOD_MAKEVAR_PREFIX = @DOXYGEN_PERLMOD_MAKEVAR_PREFIX@
ENABLE_PREPROCESSING = @DOXYGEN_ENABLE_PREPROCESSING@
MACRO_EXPANSION = @DOXYGEN_MACRO_EXPANSION@
EXPAND_ONLY_PREDEF = @DOXYGEN_EXPAND_ONLY_PREDEF@
SEARCH_INCLUDES = @DOXYGEN_SEARCH_INCLUDES@
INCLUDE_PATH = @DOXYGEN_INCLUDE_PATH@
INCLUDE_FILE_PATTERNS = @DOXYGEN_INCLUDE_FILE_PATTERNS@
PREDEFINED = @DOXYGEN_PREDEFINED@
EXPAND_AS_DEFINED = @DOXYGEN_EXPAND_AS_DEFINED@
SKIP_FUNCTION_MACROS = @DOXYGEN_SKIP_FUNCTION_MACROS@
TAGFILES = @DOXYGEN_TAGFILES@
GENERATE_TAGFILE = @DOXYGEN_GENERATE_TAGFILE@
ALLEXTERNALS = @DOXYGEN_ALLEXTERNALS@
EXTERNAL_GROUPS = @DOXYGEN_EXTERNAL_GROUPS@
EXTERNAL_PAGES = @DOXYGEN_EXTERNAL_PAGES@
CLASS_DIAGRAMS = @DOXYGEN_CLASS_DIAGRAMS@
DIA_PATH = @DOXYGEN_DIA_PATH@
HIDE_UNDOC_RELATIONS = @DOXYGEN_HIDE_UNDOC_RELATIONS@
HAVE_DOT = @DOXYGEN_HAVE_DOT@
DOT_NUM_THREADS = @DOXYGEN_DOT_NUM_THREADS@
DOT_FONTNAME = @DOXYGEN_DOT_FONTNAME@
DOT_FONTSIZE = @DOXYGEN_DOT_FONTSIZE@
DOT_FONTPATH = @DOXYGEN_DOT_FONTPATH@
CLASS_GRAPH = @DOXYGEN_CLASS_GRAPH@
COLLABORATION_GRAPH = @DOXYGEN_COLLABORATION_GRAPH@
GROUP_GRAPHS = @DOXYGEN_GROUP_GRAPHS@
UML_LOOK = @DOXYGEN_UML_LOOK@
UML_LIMIT_NUM_FIELDS = @DOXYGEN_UML_LIMIT_NUM_FIELDS@
TEMPLATE_RELATIONS = @DOXYGEN_TEMPLATE_RELATIONS@
INCLUDE_GRAPH = @DOXYGEN_INCLUDE_GRAPH@
INCLUDED_BY_GRAPH = @DOXYGEN_INCLUDED_BY_GRAPH@
CALL_GRAPH = @DOXYGEN_CALL_GRAPH@
CALLER_GRAPH = @DOXYGEN_CALLER_GRAPH@
GRAPHICAL_HIERARCHY = @DOXYGEN_GRAPHICAL_HIERARCHY@
DIRECTORY_GRAPH = @DOXYGEN_DIRECTORY_GRAPH@
DOT_IMAGE_FORMAT = @DOXYGEN_DOT_IMAGE_FORMAT@
INTERACTIVE_SVG = @DOXYGEN_INTERACTIVE_SVG@
DOT_PATH = @DOXYGEN_DOT_PATH@
DOTFILE_DIRS = @DOXYGEN_DOTFILE_DIRS@
MSCFILE_DIRS = @DOXYGEN_MSCFILE_DIRS@
DIAFILE_DIRS = @DOXYGEN_DIAFILE_DIRS@
PLANTUML_JAR_PATH = @DOXYGEN_PLANTUML_JAR_PATH@
PLANTUML_CFG_FILE = @DOXYGEN_PLANTUML_CFG_FILE@
PLANTUML_INCLUDE_PATH = @DOXYGEN_PLANTUML_INCLUDE_PATH@
DOT_GRAPH_MAX_NODES = @DOXYGEN_DOT_GRAPH_MAX_NODES@
MAX_DOT_GRAPH_DEPTH = @DOXYGEN_MAX_DOT_GRAPH_DEPTH@
DOT_TRANSPARENT = @DOXYGEN_DOT_TRANSPARENT@
DOT_MULTI_TARGETS = @DOXYGEN_DOT_MULTI_TARGETS@
GENERATE_LEGEND = @DOXYGEN_GENERATE_LEGEND@
DOT_CLEANUP = @DOXYGEN_DOT_CLEANUP@

View file

@ -32,7 +32,7 @@ DOXYFILE_ENCODING = UTF-8
# title of most generated pages and in a few other places.
# The default value is: My Project.
PROJECT_NAME = "Graphene"
PROJECT_NAME = "Peerplays"
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
# could be handy for archiving the generated documentation or if some version

View file

@ -5,7 +5,6 @@ add_library( graphene_app
api.cpp
application.cpp
database_api.cpp
impacted.cpp
plugin.cpp
config_util.cpp
${HEADERS}
@ -14,7 +13,8 @@ add_library( graphene_app
# 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 peerplays_sidechain )
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 peerplays_sidechain graphene_elasticsearch)
target_include_directories( graphene_app
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include"
"${CMAKE_CURRENT_SOURCE_DIR}/../egenesis/include" )

View file

@ -26,7 +26,6 @@
#include <graphene/app/api.hpp>
#include <graphene/app/api_access.hpp>
#include <graphene/app/application.hpp>
#include <graphene/app/impacted.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/get_config.hpp>
#include <graphene/utilities/key_conversion.hpp>
@ -40,8 +39,19 @@
#include <fc/crypto/hex.hpp>
#include <fc/smart_ref_impl.hpp>
#include <fc/rpc/api_connection.hpp>
#include <fc/thread/future.hpp>
template class fc::api<graphene::app::block_api>;
template class fc::api<graphene::app::network_broadcast_api>;
template class fc::api<graphene::app::network_node_api>;
template class fc::api<graphene::app::history_api>;
template class fc::api<graphene::app::crypto_api>;
template class fc::api<graphene::app::asset_api>;
template class fc::api<graphene::debug_witness::debug_api>;
template class fc::api<graphene::app::login_api>;
namespace graphene { namespace app {
login_api::login_api(application& a)
@ -103,7 +113,7 @@ namespace graphene { namespace app {
}
else if( api_name == "asset_api" )
{
_asset_api = std::make_shared< asset_api >( std::ref( *_app.chain_database() ) );
_asset_api = std::make_shared< asset_api >( _app );
}
else if( api_name == "debug_api" )
{
@ -536,10 +546,12 @@ namespace graphene { namespace app {
} // end get_relevant_accounts( obj )
#endif
vector<order_history_object> history_api::get_fill_order_history( asset_id_type a, asset_id_type b, uint32_t limit )const
vector<order_history_object> history_api::get_fill_order_history( std::string asset_a, std::string asset_b, uint32_t limit )const
{
FC_ASSERT(_app.chain_database());
const auto& db = *_app.chain_database();
asset_id_type a = database_api.get_asset_id_from_string( asset_a );
asset_id_type b = database_api.get_asset_id_from_string( asset_b );
if( a > b ) std::swap(a,b);
const auto& history_idx = db.get_index_type<graphene::market_history::history_index>().indices().get<by_key>();
history_key hkey;
@ -561,7 +573,7 @@ namespace graphene { namespace app {
return result;
}
vector<operation_history_object> history_api::get_account_history( account_id_type account,
vector<operation_history_object> history_api::get_account_history( const std::string account_id_or_name,
operation_history_id_type stop,
unsigned limit,
operation_history_id_type start ) const
@ -570,12 +582,26 @@ namespace graphene { namespace app {
const auto& db = *_app.chain_database();
FC_ASSERT( limit <= 100 );
vector<operation_history_object> result;
account_id_type account;
try {
account = database_api.get_account_id_from_string(account_id_or_name);
const account_transaction_history_object& node = account(db).statistics(db).most_recent_op(db);
if(start == operation_history_id_type() || start.instance.value > node.operation_id.instance.value)
start = node.operation_id;
} catch(...) { return result; }
if(_app.is_plugin_enabled("elasticsearch")) {
auto es = _app.get_plugin<elasticsearch::elasticsearch_plugin>("elasticsearch");
if(es.get()->get_running_mode() != elasticsearch::mode::only_save) {
if(!_app.elasticsearch_thread)
_app.elasticsearch_thread= std::make_shared<fc::thread>("elasticsearch");
return _app.elasticsearch_thread->async([&es, &account, &stop, &limit, &start]() {
return es->get_account_history(account, stop, limit, start);
}, "thread invoke for method " BOOST_PP_STRINGIZE(method_name)).wait();
}
}
const auto& hist_idx = db.get_index_type<account_transaction_history_index>();
const auto& by_op_idx = hist_idx.indices().get<by_op>();
auto index_start = by_op_idx.begin();
@ -594,7 +620,7 @@ namespace graphene { namespace app {
return result;
}
vector<operation_history_object> history_api::get_account_history_operations( account_id_type account,
vector<operation_history_object> history_api::get_account_history_operations( const std::string account_id_or_name,
int operation_id,
operation_history_id_type start,
operation_history_id_type stop,
@ -604,6 +630,11 @@ namespace graphene { namespace app {
const auto& db = *_app.chain_database();
FC_ASSERT( limit <= 100 );
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);
@ -630,7 +661,7 @@ namespace graphene { namespace app {
}
vector<operation_history_object> history_api::get_relative_account_history( account_id_type account,
vector<operation_history_object> history_api::get_relative_account_history( const std::string account_id_or_name,
uint32_t stop,
unsigned limit,
uint32_t start) const
@ -639,6 +670,10 @@ namespace graphene { namespace app {
const auto& db = *_app.chain_database();
FC_ASSERT(limit <= 100);
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( start == 0 )
start = stats.total_ops;
@ -678,11 +713,13 @@ namespace graphene { namespace app {
return hist->tracked_buckets();
}
vector<bucket_object> history_api::get_market_history( asset_id_type a, asset_id_type b,
vector<bucket_object> history_api::get_market_history( std::string asset_a, std::string asset_b,
uint32_t bucket_seconds, fc::time_point_sec start, fc::time_point_sec end )const
{ try {
FC_ASSERT(_app.chain_database());
const auto& db = *_app.chain_database();
asset_id_type a = database_api.get_asset_id_from_string( asset_a );
asset_id_type b = database_api.get_asset_id_from_string( asset_b );
vector<bucket_object> result;
result.reserve(200);
@ -702,7 +739,7 @@ namespace graphene { namespace app {
++itr;
}
return result;
} FC_CAPTURE_AND_RETHROW( (a)(b)(bucket_seconds)(start)(end) ) }
} FC_CAPTURE_AND_RETHROW( (asset_a)(asset_b)(bucket_seconds)(start)(end) ) }
crypto_api::crypto_api(){};
@ -761,12 +798,16 @@ namespace graphene { namespace app {
}
// asset_api
asset_api::asset_api(graphene::chain::database& db) : _db(db) { }
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( asset_id_type asset_id, uint32_t start, uint32_t limit ) const {
vector<account_asset_balance> asset_api::get_asset_holders( std::string asset, uint32_t start, uint32_t limit ) const {
FC_ASSERT(limit <= 100);
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 >();
auto range = bal_idx.equal_range( boost::make_tuple( asset_id ) );
@ -797,11 +838,11 @@ namespace graphene { namespace app {
return result;
}
// get number of asset holders.
int asset_api::get_asset_holders_count( asset_id_type asset_id ) const {
int asset_api::get_asset_holders_count( std::string asset ) const {
const auto& bal_idx = _db.get_index_type< account_balance_index >().indices().get< by_asset_balance >();
asset_id_type asset_id = database_api.get_asset_id_from_string( asset );
auto range = bal_idx.equal_range( boost::make_tuple( asset_id ) );
int count = boost::distance(range) - 1;
return count;

View file

@ -226,7 +226,7 @@ namespace detail {
void new_connection( const fc::http::websocket_connection_ptr& c )
{
auto wsc = std::make_shared<fc::rpc::websocket_api_connection>(c, GRAPHENE_MAX_NESTED_OBJECTS);
auto wsc = std::make_shared<fc::rpc::websocket_api_connection>(*c, GRAPHENE_MAX_NESTED_OBJECTS);
auto login = std::make_shared<graphene::app::login_api>( std::ref(*_self) );
login->enable_api("database_api");
@ -375,6 +375,11 @@ namespace detail {
}
_chain_db->add_checkpoints( loaded_checkpoints );
if( _options->count("enable-standby-votes-tracking") )
{
_chain_db->enable_standby_votes_tracking( _options->at("enable-standby-votes-tracking").as<bool>() );
}
bool replay = false;
std::string replay_reason = "reason not provided";
@ -926,6 +931,9 @@ void application::set_program_options(boost::program_options::options_descriptio
("genesis-json", bpo::value<boost::filesystem::path>(), "File to read Genesis State from")
("dbg-init-key", bpo::value<string>(), "Block signing key to use for init witnesses, overrides genesis file")
("api-access", bpo::value<boost::filesystem::path>(), "JSON file specifying API permissions")
("enable-standby-votes-tracking", bpo::value<bool>()->implicit_value(true),
"Whether to enable tracking of votes of standby witnesses and committee members. "
"Set it to true to provide accurate data to API clients, set to false for slightly better performance.")
;
command_line_options.add(configuration_file_options);
command_line_options.add_options()
@ -982,9 +990,20 @@ void application::initialize(const fc::path& data_dir, const boost::program_opti
wanted.push_back("witness");
wanted.push_back("account_history");
wanted.push_back("market_history");
wanted.push_back("bookie");
}
int es_ah_conflict_counter = 0;
for (auto& it : wanted)
{
if(it == "account_history")
++es_ah_conflict_counter;
if(it == "elasticsearch")
++es_ah_conflict_counter;
if(es_ah_conflict_counter > 1) {
elog("Can't start program with elasticsearch and account_history plugin at the same time");
std::exit(EXIT_FAILURE);
}
if (!it.empty()) enable_plugin(it);
}
}
@ -1009,9 +1028,7 @@ std::shared_ptr<abstract_plugin> application::get_plugin(const string& name) con
bool application::is_plugin_enabled(const string& name) const
{
if(my->_active_plugins.find(name) == my->_active_plugins.end())
return false;
return true;
return !(my->_active_plugins.find(name) == my->_active_plugins.end());
}
net::node_ptr application::p2p_node()
@ -1051,7 +1068,8 @@ void graphene::app::application::enable_plugin(const string& name)
my->_active_plugins[name]->plugin_set_app(this);
}
void graphene::app::application::add_available_plugin(std::shared_ptr<graphene::app::abstract_plugin> p) {
void graphene::app::application::add_available_plugin(std::shared_ptr<graphene::app::abstract_plugin> p)
{
my->_available_plugins[p->plugin_name()] = p;
}

View file

@ -26,11 +26,15 @@
#include <graphene/chain/get_config.hpp>
#include <graphene/chain/tournament_object.hpp>
#include <graphene/chain/account_object.hpp>
#include <graphene/chain/protocol/address.hpp>
#include <graphene/chain/pts_address.hpp>
#include <fc/bloom_filter.hpp>
#include <fc/smart_ref_impl.hpp>
#include <fc/crypto/hex.hpp>
#include <fc/rpc/api_connection.hpp>
#include <fc/uint128.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/rational.hpp>
@ -45,6 +49,8 @@
typedef std::map< std::pair<graphene::chain::asset_id_type, graphene::chain::asset_id_type>, std::vector<fc::variant> > market_queue_type;
template class fc::api<graphene::app::database_api>;
namespace graphene { namespace app {
class database_api_impl : public std::enable_shared_from_this<database_api_impl>
@ -81,23 +87,26 @@ class database_api_impl : public std::enable_shared_from_this<database_api_impl>
bool is_public_key_registered(string public_key) const;
// Accounts
vector<optional<account_object>> get_accounts(const vector<account_id_type>& account_ids)const;
account_id_type get_account_id_from_string(const std::string& name_or_id)const;
vector<optional<account_object>> get_accounts(const vector<std::string>& account_names_or_ids)const;
std::map<string,full_account> get_full_accounts( const vector<string>& names_or_ids, bool subscribe );
optional<account_object> get_account_by_name( string name )const;
vector<account_id_type> get_account_references( account_id_type account_id )const;
vector<account_id_type> get_account_references( const std::string account_id_or_name )const;
vector<optional<account_object>> lookup_account_names(const vector<string>& account_names)const;
map<string,account_id_type> lookup_accounts(const string& lower_bound_name, uint32_t limit)const;
uint64_t get_account_count()const;
// Balances
vector<asset> get_account_balances(account_id_type id, const flat_set<asset_id_type>& assets)const;
vector<asset> get_named_account_balances(const std::string& name, const flat_set<asset_id_type>& assets)const;
vector<asset> get_account_balances(const std::string& account_name_or_id, const flat_set<asset_id_type>& assets)const;
vector<balance_object> get_balance_objects( const vector<address>& addrs )const;
vector<asset> get_vested_balances( const vector<balance_id_type>& objs )const;
vector<vesting_balance_object> get_vesting_balances( account_id_type account_id )const;
vector<vesting_balance_object> get_vesting_balances( const std::string account_id_or_name )const;
// Assets
vector<optional<asset_object>> get_assets(const vector<asset_id_type>& asset_ids)const;
asset_id_type get_asset_id_from_string(const std::string& symbol_or_id)const;
vector<optional<asset_object>> get_assets(const vector<std::string>& asset_symbols_or_ids)const;
// helper function
vector<optional<asset_object>> get_assets( const vector<asset_id_type>& asset_ids )const;
vector<asset_object> list_assets(const string& lower_bound_symbol, uint32_t limit)const;
vector<optional<asset_object>> lookup_asset_symbols(const vector<string>& symbols_or_ids)const;
uint64_t get_asset_count()const;
@ -124,12 +133,13 @@ class database_api_impl : public std::enable_shared_from_this<database_api_impl>
asset get_sweeps_vesting_balance_available_for_claim( account_id_type account )const;
// Markets / feeds
vector<limit_order_object> get_limit_orders(asset_id_type a, asset_id_type b, uint32_t limit)const;
vector<call_order_object> get_call_orders(asset_id_type a, uint32_t limit)const;
vector<force_settlement_object> get_settle_orders(asset_id_type a, uint32_t limit)const;
vector<call_order_object> get_margin_positions( const account_id_type& id )const;
void subscribe_to_market(std::function<void(const variant&)> callback, asset_id_type a, asset_id_type b);
void unsubscribe_from_market(asset_id_type a, asset_id_type b);
vector<limit_order_object> get_limit_orders( const asset_id_type a, const asset_id_type b, const uint32_t limit )const;
vector<limit_order_object> get_limit_orders( const std::string& a, const std::string& b, const uint32_t limit)const;
vector<call_order_object> get_call_orders(const std::string& a, uint32_t limit)const;
vector<force_settlement_object> get_settle_orders(const std::string& a, uint32_t limit)const;
vector<call_order_object> get_margin_positions( const std::string account_id_or_name )const;
void subscribe_to_market(std::function<void(const variant&)> callback, const std::string& a, const std::string& b);
void unsubscribe_from_market(const std::string& a, const std::string& b);
market_ticker get_ticker( const string& base, const string& quote )const;
market_volume get_24_volume( const string& base, const string& quote )const;
order_book get_order_book( const string& base, const string& quote, unsigned limit = 50 )const;
@ -137,13 +147,13 @@ class database_api_impl : public std::enable_shared_from_this<database_api_impl>
// Witnesses
vector<optional<witness_object>> get_witnesses(const vector<witness_id_type>& witness_ids)const;
fc::optional<witness_object> get_witness_by_account(account_id_type account)const;
fc::optional<witness_object> get_witness_by_account(const std::string account_id_or_name)const;
map<string, witness_id_type> lookup_witness_accounts(const string& lower_bound_name, uint32_t limit)const;
uint64_t get_witness_count()const;
// Committee members
vector<optional<committee_member_object>> get_committee_members(const vector<committee_member_id_type>& committee_member_ids)const;
fc::optional<committee_member_object> get_committee_member_by_account(account_id_type account)const;
fc::optional<committee_member_object> get_committee_member_by_account(const std::string account_id_or_name)const;
map<string, committee_member_id_type> lookup_committee_member_accounts(const string& lower_bound_name, uint32_t limit)const;
// SON members
@ -175,10 +185,10 @@ class database_api_impl : public std::enable_shared_from_this<database_api_impl>
bool verify_authority( const signed_transaction& trx )const;
bool verify_account_authority( const string& name_or_id, const flat_set<public_key_type>& signers )const;
processed_transaction validate_transaction( const signed_transaction& trx )const;
vector< fc::variant > get_required_fees( const vector<operation>& ops, asset_id_type id )const;
vector< fc::variant > get_required_fees( const vector<operation>& ops, const std::string& asset_id_or_symbol )const;
// Proposed transactions
vector<proposal_object> get_proposed_transactions( account_id_type id )const;
vector<proposal_object> get_proposed_transactions( const std::string account_id_or_name )const;
// Blinded balances
vector<blinded_balance_object> get_blinded_balances( const flat_set<commitment_type>& commitments )const;
@ -189,8 +199,14 @@ class database_api_impl : public std::enable_shared_from_this<database_api_impl>
vector<tournament_object> get_tournaments_by_state(tournament_id_type stop, unsigned limit, tournament_id_type start, tournament_state state);
vector<tournament_id_type> get_registered_tournaments(account_id_type account_filter, uint32_t limit) const;
// gpos
gpos_info get_gpos_info(const account_id_type account) const;
//private:
const account_object* get_account_from_string( const std::string& name_or_id,
bool throw_if_not_found = true ) const;
const asset_object* get_asset_from_string( const std::string& symbol_or_id,
bool throw_if_not_found = true ) const;
template<typename T>
void subscribe_to_item( const T& i )const
{
@ -630,22 +646,27 @@ bool database_api_impl::is_public_key_registered(string public_key) const
// //
//////////////////////////////////////////////////////////////////////
vector<optional<account_object>> database_api::get_accounts(const vector<account_id_type>& account_ids)const
account_id_type database_api::get_account_id_from_string(const std::string& name_or_id)const
{
return my->get_accounts( account_ids );
return my->get_account_from_string( name_or_id )->id;
}
vector<optional<account_object>> database_api_impl::get_accounts(const vector<account_id_type>& account_ids)const
vector<optional<account_object>> database_api::get_accounts(const vector<std::string>& account_names_or_ids)const
{
vector<optional<account_object>> result; result.reserve(account_ids.size());
std::transform(account_ids.begin(), account_ids.end(), std::back_inserter(result),
[this](account_id_type id) -> optional<account_object> {
if(auto o = _db.find(id))
{
subscribe_to_item( id );
return *o;
}
return {};
return my->get_accounts( account_names_or_ids );
}
vector<optional<account_object>> database_api_impl::get_accounts(const vector<std::string>& account_names_or_ids)const
{
vector<optional<account_object>> result; result.reserve(account_names_or_ids.size());
std::transform(account_names_or_ids.begin(), account_names_or_ids.end(), std::back_inserter(result),
[this](std::string id_or_name) -> optional<account_object> {
const account_object *account = get_account_from_string(id_or_name, false);
if(account == nullptr)
return {};
subscribe_to_item( account->id );
return *account;
});
return result;
}
@ -774,16 +795,17 @@ optional<account_object> database_api_impl::get_account_by_name( string name )co
return optional<account_object>();
}
vector<account_id_type> database_api::get_account_references( account_id_type account_id )const
vector<account_id_type> database_api::get_account_references( const std::string account_id_or_name )const
{
return my->get_account_references( account_id );
return my->get_account_references( account_id_or_name );
}
vector<account_id_type> database_api_impl::get_account_references( account_id_type account_id )const
vector<account_id_type> database_api_impl::get_account_references( const std::string account_id_or_name )const
{
const auto& idx = _db.get_index_type<account_index>();
const auto& aidx = dynamic_cast<const base_primary_index&>(idx);
const auto& refs = aidx.get_secondary_index<graphene::chain::account_member_index>();
const account_id_type account_id = get_account_from_string(account_id_or_name)->id;
auto itr = refs.account_to_account_memberships.find(account_id);
vector<account_id_type> result;
@ -852,13 +874,16 @@ uint64_t database_api_impl::get_account_count()const
// //
//////////////////////////////////////////////////////////////////////
vector<asset> database_api::get_account_balances(account_id_type id, const flat_set<asset_id_type>& assets)const
vector<asset> database_api::get_account_balances(const std::string& account_name_or_id, const flat_set<asset_id_type>& assets)const
{
return my->get_account_balances( id, assets );
return my->get_account_balances( account_name_or_id, assets );
}
vector<asset> database_api_impl::get_account_balances(account_id_type acnt, const flat_set<asset_id_type>& assets)const
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);
account_id_type acnt = account->id;
vector<asset> result;
if (assets.empty())
{
@ -881,15 +906,7 @@ vector<asset> database_api_impl::get_account_balances(account_id_type acnt, cons
vector<asset> database_api::get_named_account_balances(const std::string& name, const flat_set<asset_id_type>& assets)const
{
return my->get_named_account_balances( name, assets );
}
vector<asset> database_api_impl::get_named_account_balances(const std::string& name, const flat_set<asset_id_type>& assets) const
{
const auto& accounts_by_name = _db.get_index_type<account_index>().indices().get<by_name>();
auto itr = accounts_by_name.find(name);
FC_ASSERT( itr != accounts_by_name.end() );
return get_account_balances(itr->get_id(), assets);
return my->get_account_balances( name, assets );
}
vector<balance_object> database_api::get_balance_objects( const vector<address>& addrs )const
@ -939,24 +956,26 @@ vector<asset> database_api_impl::get_vested_balances( const vector<balance_id_ty
} FC_CAPTURE_AND_RETHROW( (objs) )
}
vector<vesting_balance_object> database_api::get_vesting_balances( account_id_type account_id )const
vector<vesting_balance_object> database_api::get_vesting_balances( const std::string account_id_or_name )const
{
return my->get_vesting_balances( account_id );
return my->get_vesting_balances( account_id_or_name );
}
vector<vesting_balance_object> database_api_impl::get_vesting_balances( account_id_type account_id )const
vector<vesting_balance_object> database_api_impl::get_vesting_balances( const std::string account_id_or_name )const
{
try
{
const account_id_type account_id = get_account_from_string(account_id_or_name)->id;
vector<vesting_balance_object> result;
auto vesting_range = _db.get_index_type<vesting_balance_index>().indices().get<by_account>().equal_range(account_id);
std::for_each(vesting_range.first, vesting_range.second,
[&result](const vesting_balance_object& balance) {
result.emplace_back(balance);
if(balance.balance.amount > 0)
result.emplace_back(balance);
});
return result;
}
FC_CAPTURE_AND_RETHROW( (account_id) );
FC_CAPTURE_AND_RETHROW( (account_id_or_name) );
}
//////////////////////////////////////////////////////////////////////
@ -965,9 +984,48 @@ vector<vesting_balance_object> database_api_impl::get_vesting_balances( account_
// //
//////////////////////////////////////////////////////////////////////
vector<optional<asset_object>> database_api::get_assets(const vector<asset_id_type>& asset_ids)const
asset_id_type database_api::get_asset_id_from_string(const std::string& symbol_or_id)const
{
return my->get_assets( asset_ids );
return my->get_asset_from_string( symbol_or_id )->id;
}
const asset_object* database_api_impl::get_asset_from_string( const std::string& symbol_or_id,
bool throw_if_not_found ) const
{
// TODO cache the result to avoid repeatly fetching from db
FC_ASSERT( symbol_or_id.size() > 0);
const asset_object* asset = nullptr;
if (std::isdigit(symbol_or_id[0]))
asset = _db.find(fc::variant(symbol_or_id, 1).as<asset_id_type>(1));
else
{
const auto& idx = _db.get_index_type<asset_index>().indices().get<by_symbol>();
auto itr = idx.find(symbol_or_id);
if (itr != idx.end())
asset = &*itr;
}
if(throw_if_not_found)
FC_ASSERT( asset, "no such asset" );
return asset;
}
vector<optional<asset_object>> database_api::get_assets(const vector<std::string>& asset_symbols_or_ids)const
{
return my->get_assets( asset_symbols_or_ids );
}
vector<optional<asset_object>> database_api_impl::get_assets(const vector<std::string>& asset_symbols_or_ids)const
{
vector<optional<asset_object>> result; result.reserve(asset_symbols_or_ids.size());
std::transform(asset_symbols_or_ids.begin(), asset_symbols_or_ids.end(), std::back_inserter(result),
[this](std::string id_or_name) -> optional<asset_object> {
const asset_object* asset_obj = get_asset_from_string( id_or_name, false );
if( asset_obj == nullptr )
return {};
subscribe_to_item(asset_obj->id );
return asset_object( *asset_obj );
});
return result;
}
vector<optional<asset_object>> database_api_impl::get_assets(const vector<asset_id_type>& asset_ids)const
@ -1223,7 +1281,7 @@ vector<bet_object> database_api_impl::get_all_unmatched_bets_for_bettor(account_
// //
//////////////////////////////////////////////////////////////////////
vector<limit_order_object> database_api::get_limit_orders(asset_id_type a, asset_id_type b, uint32_t limit)const
vector<limit_order_object> database_api::get_limit_orders(const std::string& a, const std::string& b, const uint32_t limit)const
{
return my->get_limit_orders( a, b, limit );
}
@ -1231,12 +1289,22 @@ vector<limit_order_object> database_api::get_limit_orders(asset_id_type a, asset
/**
* @return the limit orders for both sides of the book for the two assets specified up to limit number on each side.
*/
vector<limit_order_object> database_api_impl::get_limit_orders(asset_id_type a, asset_id_type b, uint32_t limit)const
vector<limit_order_object> database_api_impl::get_limit_orders(const std::string& a, const std::string& b, const uint32_t limit)const
{
const asset_id_type asset_a_id = get_asset_from_string(a)->id;
const asset_id_type asset_b_id = get_asset_from_string(b)->id;
return get_limit_orders(asset_a_id, asset_b_id, limit);
}
vector<limit_order_object> database_api_impl::get_limit_orders( const asset_id_type a, const asset_id_type b,
const uint32_t limit )const
{
const auto& limit_order_idx = _db.get_index_type<limit_order_index>();
const auto& limit_price_idx = limit_order_idx.indices().get<by_price>();
vector<limit_order_object> result;
result.reserve(limit*2);
uint32_t count = 0;
auto limit_itr = limit_price_idx.lower_bound(price::max(a,b));
@ -1260,45 +1328,46 @@ vector<limit_order_object> database_api_impl::get_limit_orders(asset_id_type a,
return result;
}
vector<call_order_object> database_api::get_call_orders(asset_id_type a, uint32_t limit)const
vector<call_order_object> database_api::get_call_orders(const std::string& a, uint32_t limit)const
{
return my->get_call_orders( a, limit );
}
vector<call_order_object> database_api_impl::get_call_orders(asset_id_type a, uint32_t limit)const
vector<call_order_object> database_api_impl::get_call_orders(const std::string& a, uint32_t limit)const
{
const auto& call_index = _db.get_index_type<call_order_index>().indices().get<by_price>();
const asset_object& mia = _db.get(a);
price index_price = price::min(mia.bitasset_data(_db).options.short_backing_asset, mia.get_id());
const asset_object* mia = get_asset_from_string(a);
price index_price = price::min(mia->bitasset_data(_db).options.short_backing_asset, mia->get_id());
return vector<call_order_object>(call_index.lower_bound(index_price.min()),
call_index.lower_bound(index_price.max()));
}
vector<force_settlement_object> database_api::get_settle_orders(asset_id_type a, uint32_t limit)const
vector<force_settlement_object> database_api::get_settle_orders(const std::string& a, uint32_t limit)const
{
return my->get_settle_orders( a, limit );
}
vector<force_settlement_object> database_api_impl::get_settle_orders(asset_id_type a, uint32_t limit)const
vector<force_settlement_object> database_api_impl::get_settle_orders(const std::string& a, uint32_t limit)const
{
const auto& settle_index = _db.get_index_type<force_settlement_index>().indices().get<by_expiration>();
const asset_object& mia = _db.get(a);
return vector<force_settlement_object>(settle_index.lower_bound(mia.get_id()),
settle_index.upper_bound(mia.get_id()));
const asset_object* mia = get_asset_from_string(a);
return vector<force_settlement_object>(settle_index.lower_bound(mia->get_id()),
settle_index.upper_bound(mia->get_id()));
}
vector<call_order_object> database_api::get_margin_positions( const account_id_type& id )const
vector<call_order_object> database_api::get_margin_positions( const std::string account_id_or_name )const
{
return my->get_margin_positions( id );
return my->get_margin_positions( account_id_or_name );
}
vector<call_order_object> database_api_impl::get_margin_positions( const account_id_type& id )const
vector<call_order_object> database_api_impl::get_margin_positions( const std::string account_id_or_name )const
{
try
{
const auto& idx = _db.get_index_type<call_order_index>();
const auto& aidx = idx.indices().get<by_account>();
const account_id_type id = get_account_from_string(account_id_or_name)->id;
auto start = aidx.lower_bound( boost::make_tuple( id, asset_id_type(0) ) );
auto end = aidx.lower_bound( boost::make_tuple( id+1, asset_id_type(0) ) );
vector<call_order_object> result;
@ -1308,31 +1377,37 @@ vector<call_order_object> database_api_impl::get_margin_positions( const account
++start;
}
return result;
} FC_CAPTURE_AND_RETHROW( (id) )
} FC_CAPTURE_AND_RETHROW( (account_id_or_name) )
}
void database_api::subscribe_to_market(std::function<void(const variant&)> callback, asset_id_type a, asset_id_type b)
void database_api::subscribe_to_market(std::function<void(const variant&)> callback, const std::string& a, const std::string& b)
{
my->subscribe_to_market( callback, a, b );
}
void database_api_impl::subscribe_to_market(std::function<void(const variant&)> callback, asset_id_type a, asset_id_type b)
void database_api_impl::subscribe_to_market(std::function<void(const variant&)> callback, const std::string& a, const std::string& b)
{
if(a > b) std::swap(a,b);
FC_ASSERT(a != b);
_market_subscriptions[ std::make_pair(a,b) ] = callback;
auto asset_a_id = get_asset_from_string(a)->id;
auto asset_b_id = get_asset_from_string(b)->id;
if(asset_a_id > asset_b_id) std::swap(asset_a_id,asset_b_id);
FC_ASSERT(asset_a_id != asset_b_id);
_market_subscriptions[ std::make_pair(asset_a_id,asset_b_id) ] = callback;
}
void database_api::unsubscribe_from_market(asset_id_type a, asset_id_type b)
void database_api::unsubscribe_from_market(const std::string& a, const std::string& b)
{
my->unsubscribe_from_market( a, b );
}
void database_api_impl::unsubscribe_from_market(asset_id_type a, asset_id_type b)
void database_api_impl::unsubscribe_from_market(const std::string& a, const std::string& b)
{
if(a > b) std::swap(a,b);
FC_ASSERT(a != b);
_market_subscriptions.erase(std::make_pair(a,b));
auto asset_a_id = get_asset_from_string(a)->id;
auto asset_b_id = get_asset_from_string(b)->id;
if(asset_a_id > asset_b_id) std::swap(asset_a_id,asset_b_id);
FC_ASSERT(asset_a_id != asset_b_id);
_market_subscriptions.erase(std::make_pair(asset_a_id,asset_b_id));
}
market_ticker database_api::get_ticker( const string& base, const string& quote )const
@ -1555,9 +1630,10 @@ vector<optional<witness_object>> database_api::get_witnesses(const vector<witnes
return my->get_witnesses( witness_ids );
}
vector<worker_object> database_api::get_workers_by_account(account_id_type account)const
vector<worker_object> database_api::get_workers_by_account(const std::string account_id_or_name)const
{
const auto& idx = my->_db.get_index_type<worker_index>().indices().get<by_account>();
const account_id_type account = my->get_account_from_string(account_id_or_name)->id;
auto itr = idx.find(account);
vector<worker_object> result;
@ -1583,14 +1659,15 @@ vector<optional<witness_object>> database_api_impl::get_witnesses(const vector<w
return result;
}
fc::optional<witness_object> database_api::get_witness_by_account(account_id_type account)const
fc::optional<witness_object> database_api::get_witness_by_account(const std::string account_id_or_name)const
{
return my->get_witness_by_account( account );
return my->get_witness_by_account( account_id_or_name );
}
fc::optional<witness_object> database_api_impl::get_witness_by_account(account_id_type account) const
fc::optional<witness_object> database_api_impl::get_witness_by_account(const std::string account_id_or_name) const
{
const auto& idx = _db.get_index_type<witness_index>().indices().get<by_account>();
const account_id_type account = get_account_from_string(account_id_or_name)->id;
auto itr = idx.find(account);
if( itr != idx.end() )
return *itr;
@ -1658,14 +1735,15 @@ vector<optional<committee_member_object>> database_api_impl::get_committee_membe
return result;
}
fc::optional<committee_member_object> database_api::get_committee_member_by_account(account_id_type account)const
fc::optional<committee_member_object> database_api::get_committee_member_by_account(const std::string account_id_or_name)const
{
return my->get_committee_member_by_account( account );
return my->get_committee_member_by_account( account_id_or_name );
}
fc::optional<committee_member_object> database_api_impl::get_committee_member_by_account(account_id_type account) const
fc::optional<committee_member_object> database_api_impl::get_committee_member_by_account(const std::string account_id_or_name) const
{
const auto& idx = _db.get_index_type<committee_member_index>().indices().get<by_account>();
const account_id_type account = get_account_from_string(account_id_or_name)->id;
auto itr = idx.find(account);
if( itr != idx.end() )
return *itr;
@ -2134,9 +2212,9 @@ processed_transaction database_api_impl::validate_transaction( const signed_tran
return _db.validate_transaction(trx);
}
vector< fc::variant > database_api::get_required_fees( const vector<operation>& ops, asset_id_type id )const
vector< fc::variant > database_api::get_required_fees( const vector<operation>& ops, const std::string& asset_id_or_symbol )const
{
return my->get_required_fees( ops, id );
return my->get_required_fees( ops, asset_id_or_symbol );
}
/**
@ -2195,7 +2273,7 @@ struct get_required_fees_helper
uint32_t current_recursion = 0;
};
vector< fc::variant > database_api_impl::get_required_fees( const vector<operation>& ops, asset_id_type id )const
vector< fc::variant > database_api_impl::get_required_fees( const vector<operation>& ops, const std::string& asset_id_or_symbol )const
{
vector< operation > _ops = ops;
//
@ -2205,7 +2283,7 @@ vector< fc::variant > database_api_impl::get_required_fees( const vector<operati
vector< fc::variant > result;
result.reserve(ops.size());
const asset_object& a = id(_db);
const asset_object& a = *get_asset_from_string(asset_id_or_symbol);
get_required_fees_helper helper(
_db.current_fee_schedule(),
a.options.core_exchange_rate,
@ -2223,16 +2301,17 @@ vector< fc::variant > database_api_impl::get_required_fees( const vector<operati
// //
//////////////////////////////////////////////////////////////////////
vector<proposal_object> database_api::get_proposed_transactions( account_id_type id )const
vector<proposal_object> database_api::get_proposed_transactions( const std::string account_id_or_name )const
{
return my->get_proposed_transactions( id );
return my->get_proposed_transactions( account_id_or_name );
}
/** TODO: add secondary index that will accelerate this process */
vector<proposal_object> database_api_impl::get_proposed_transactions( account_id_type id )const
vector<proposal_object> database_api_impl::get_proposed_transactions( const std::string account_id_or_name )const
{
const auto& idx = _db.get_index_type<proposal_index>();
vector<proposal_object> result;
const account_id_type id = get_account_from_string(account_id_or_name)->id;
idx.inspect_all_objects( [&](const object& obj){
const proposal_object& p = static_cast<const proposal_object&>(obj);
@ -2347,6 +2426,26 @@ vector<tournament_object> database_api_impl::get_tournaments_by_state(tournament
return result;
}
const account_object* database_api_impl::get_account_from_string( const std::string& name_or_id,
bool throw_if_not_found ) const
{
// TODO cache the result to avoid repeatly fetching from db
FC_ASSERT( name_or_id.size() > 0);
const account_object* account = nullptr;
if (std::isdigit(name_or_id[0]))
account = _db.find(fc::variant(name_or_id, 1).as<account_id_type>(1));
else
{
const auto& idx = _db.get_index_type<account_index>().indices().get<by_name>();
auto itr = idx.find(name_or_id);
if (itr != idx.end())
account = &*itr;
}
if(throw_if_not_found)
FC_ASSERT( account, "no such account" );
return account;
}
vector<tournament_id_type> database_api::get_registered_tournaments(account_id_type account_filter, uint32_t limit) const
{
return my->get_registered_tournaments(account_filter, limit);
@ -2364,6 +2463,80 @@ vector<tournament_id_type> database_api_impl::get_registered_tournaments(account
return tournament_ids;
}
//////////////////////////////////////////////////////////////////////
// //
// GPOS methods //
// //
//////////////////////////////////////////////////////////////////////
graphene::app::gpos_info database_api::get_gpos_info(const account_id_type account) const
{
return my->get_gpos_info(account);
}
graphene::app::gpos_info database_api_impl::get_gpos_info(const account_id_type account) const
{
FC_ASSERT( _db.head_block_time() > HARDFORK_GPOS_TIME); //Can be deleted after GPOS hardfork time
gpos_info result;
result.vesting_factor = _db.calculate_vesting_factor(account(_db));
result.current_subperiod = _db.get_gpos_current_subperiod();
result.last_voted_time = account(_db).statistics(_db).last_vote_time;
const auto& dividend_data = asset_id_type()(_db).dividend_data(_db);
const account_object& dividend_distribution_account = dividend_data.dividend_distribution_account(_db);
result.award = _db.get_balance(dividend_distribution_account, asset_id_type()(_db));
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
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)
{
if (vesting_balance_obj.balance.asset_id == asset_id_type() && vesting_balance_obj.balance_type == balance_type)
{
total_amount += vesting_balance_obj.balance.amount;
}
}
#endif
vector<vesting_balance_object> account_vbos;
const time_point_sec now = _db.head_block_time();
auto vesting_range = _db.get_index_type<vesting_balance_index>().indices().get<by_account>().equal_range(account);
std::for_each(vesting_range.first, vesting_range.second,
[&account_vbos, now](const vesting_balance_object& balance) {
if(balance.balance.amount > 0 && balance.balance_type == vesting_balance_type::gpos
&& 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;
if(vesting_balance_obj.is_withdraw_allowed(_db.head_block_time(), vesting_balance_obj.balance.amount))
allowed_withdraw_amount += vesting_balance_obj.balance.amount;
}
result.total_amount = total_amount;
result.allowed_withdraw_amount = allowed_withdraw_amount;
result.account_vested_balance = account_vested_balance;
return result;
}
//////////////////////////////////////////////////////////////////////
// //
// Private methods //

View file

@ -1,369 +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/protocol/authority.hpp>
#include <graphene/app/impacted.hpp>
namespace graphene { namespace app {
using namespace fc;
using namespace graphene::chain;
// TODO: Review all of these, especially no-ops
struct get_impacted_account_visitor
{
flat_set<account_id_type>& _impacted;
get_impacted_account_visitor( flat_set<account_id_type>& impact ):_impacted(impact) {}
typedef void result_type;
void operator()( const transfer_operation& op )
{
_impacted.insert( op.to );
}
void operator()( const asset_claim_fees_operation& op ){}
void operator()( const limit_order_create_operation& op ) {}
void operator()( const limit_order_cancel_operation& op )
{
_impacted.insert( op.fee_paying_account );
}
void operator()( const call_order_update_operation& op ) {}
void operator()( const fill_order_operation& op )
{
_impacted.insert( op.account_id );
}
void operator()( const account_create_operation& op )
{
_impacted.insert( op.registrar );
_impacted.insert( op.referrer );
add_authority_accounts( _impacted, op.owner );
add_authority_accounts( _impacted, op.active );
}
void operator()( const account_update_operation& op )
{
_impacted.insert( op.account );
if( op.owner )
add_authority_accounts( _impacted, *(op.owner) );
if( op.active )
add_authority_accounts( _impacted, *(op.active) );
}
void operator()( const account_whitelist_operation& op )
{
_impacted.insert( op.account_to_list );
}
void operator()( const account_upgrade_operation& op ) {}
void operator()( const account_transfer_operation& op )
{
_impacted.insert( op.new_owner );
}
void operator()( const asset_create_operation& op ) {}
void operator()( const asset_update_operation& op )
{
if( op.new_issuer )
_impacted.insert( *(op.new_issuer) );
}
void operator()( const asset_update_bitasset_operation& op ) {}
void operator()( const asset_update_dividend_operation& op ) {}
void operator()( const asset_dividend_distribution_operation& op )
{
_impacted.insert( op.account_id );
}
void operator()( const asset_update_feed_producers_operation& op ) {}
void operator()( const asset_issue_operation& op )
{
_impacted.insert( op.issue_to_account );
}
void operator()( const asset_reserve_operation& op ) {}
void operator()( const asset_fund_fee_pool_operation& op ) {}
void operator()( const asset_settle_operation& op ) {}
void operator()( const asset_global_settle_operation& op ) {}
void operator()( const asset_publish_feed_operation& op ) {}
void operator()( const witness_create_operation& op )
{
_impacted.insert( op.witness_account );
}
void operator()( const witness_update_operation& op )
{
_impacted.insert( op.witness_account );
}
void operator()( const proposal_create_operation& op )
{
vector<authority> other;
for( const auto& proposed_op : op.proposed_ops )
operation_get_required_authorities( proposed_op.op, _impacted, _impacted, other );
for( auto& o : other )
add_authority_accounts( _impacted, o );
}
void operator()( const proposal_update_operation& op ) {}
void operator()( const proposal_delete_operation& op ) {}
void operator()( const withdraw_permission_create_operation& op )
{
_impacted.insert( op.authorized_account );
}
void operator()( const withdraw_permission_update_operation& op )
{
_impacted.insert( op.authorized_account );
}
void operator()( const withdraw_permission_claim_operation& op )
{
_impacted.insert( op.withdraw_from_account );
}
void operator()( const withdraw_permission_delete_operation& op )
{
_impacted.insert( op.authorized_account );
}
void operator()( const committee_member_create_operation& op )
{
_impacted.insert( op.committee_member_account );
}
void operator()( const committee_member_update_operation& op )
{
_impacted.insert( op.committee_member_account );
}
void operator()( const committee_member_update_global_parameters_operation& op ) {}
void operator()( const vesting_balance_create_operation& op )
{
_impacted.insert( op.owner );
}
void operator()( const vesting_balance_withdraw_operation& op ) {}
void operator()( const worker_create_operation& op ) {}
void operator()( const custom_operation& op ) {}
void operator()( const assert_operation& op ) {}
void operator()( const balance_claim_operation& op ) {}
void operator()( const override_transfer_operation& op )
{
_impacted.insert( op.to );
_impacted.insert( op.from );
_impacted.insert( op.issuer );
}
void operator()( const transfer_to_blind_operation& op )
{
_impacted.insert( op.from );
for( const auto& out : op.outputs )
add_authority_accounts( _impacted, out.owner );
}
void operator()( const blind_transfer_operation& op )
{
for( const auto& in : op.inputs )
add_authority_accounts( _impacted, in.owner );
for( const auto& out : op.outputs )
add_authority_accounts( _impacted, out.owner );
}
void operator()( const transfer_from_blind_operation& op )
{
_impacted.insert( op.to );
for( const auto& in : op.inputs )
add_authority_accounts( _impacted, in.owner );
}
void operator()( const asset_settle_cancel_operation& op )
{
_impacted.insert( op.account );
}
void operator()( const fba_distribute_operation& op )
{
_impacted.insert( op.account_id );
}
void operator()( const sport_create_operation& op ) {}
void operator()( const sport_update_operation& op ) {}
void operator()( const sport_delete_operation& op ) {}
void operator()( const event_group_create_operation& op ) {}
void operator()( const event_group_update_operation& op ) {}
void operator()( const event_group_delete_operation& op ) {}
void operator()( const event_create_operation& op ) {}
void operator()( const event_update_operation& op ) {}
void operator()( const event_update_status_operation& op ) {}
void operator()( const betting_market_rules_create_operation& op ) {}
void operator()( const betting_market_rules_update_operation& op ) {}
void operator()( const betting_market_group_create_operation& op ) {}
void operator()( const betting_market_group_update_operation& op ) {}
void operator()( const betting_market_create_operation& op ) {}
void operator()( const betting_market_update_operation& op ) {}
void operator()( const betting_market_group_resolve_operation& op ) {}
void operator()( const betting_market_group_cancel_unmatched_bets_operation& op ) {}
void operator()( const bet_place_operation& op )
{
_impacted.insert( op.bettor_id );
}
void operator()( const bet_cancel_operation& op )
{
_impacted.insert( op.bettor_id );
}
void operator()( const bet_canceled_operation& op )
{
_impacted.insert( op.bettor_id );
}
void operator()( const bet_adjusted_operation& op )
{
_impacted.insert( op.bettor_id );
}
void operator()( const bet_matched_operation& op )
{
_impacted.insert( op.bettor_id );
}
void operator()( const betting_market_group_resolved_operation& op )
{
_impacted.insert( op.bettor_id );
}
void operator()( const tournament_create_operation& op )
{
_impacted.insert( op.creator );
_impacted.insert( op.options.whitelist.begin(), op.options.whitelist.end() );
}
void operator()( const tournament_join_operation& op )
{
_impacted.insert( op.payer_account_id );
_impacted.insert( op.player_account_id );
}
void operator()( const tournament_leave_operation& op )
{
//if account canceling registration is not the player, it must be the payer
if (op.canceling_account_id != op.player_account_id)
_impacted.erase( op.canceling_account_id );
_impacted.erase( op.player_account_id );
}
void operator()( const game_move_operation& op )
{
_impacted.insert( op.player_account_id );
}
void operator()( const tournament_payout_operation& op )
{
_impacted.insert( op.payout_account_id );
}
void operator()( const affiliate_payout_operation& op )
{
_impacted.insert( op.affiliate );
}
void operator()( const affiliate_referral_payout_operation& op ) { }
void operator()( const lottery_asset_create_operation& op) { }
void operator()( const ticket_purchase_operation& op )
{
_impacted.insert( op.buyer );
}
void operator()( const lottery_reward_operation& op ) {
_impacted.insert( op.winner );
}
void operator()( const lottery_end_operation& op ) {
for( auto participant : op.participants ) {
_impacted.insert(participant.first);
}
}
void operator()( const sweeps_vesting_claim_operation& op ) {
_impacted.insert( op.account );
}
void operator()( const son_create_operation& op ){
_impacted.insert( op.owner_account );
}
void operator()( const son_update_operation& op ){
_impacted.insert( op.owner_account );
}
void operator()( const son_delete_operation& op ){
_impacted.insert( op.owner_account );
}
void operator()( const son_heartbeat_operation& op ){
_impacted.insert( op.owner_account );
}
void operator()( const son_report_down_operation& op ){
_impacted.insert( op.payer );
}
void operator()( const son_maintenance_operation& op ){
_impacted.insert( op.owner_account );
}
void operator()( const son_wallet_recreate_operation& op ){
_impacted.insert( op.payer );
}
void operator()( const son_wallet_update_operation& op ){
_impacted.insert( op.payer );
}
void operator()( const son_wallet_deposit_create_operation& op ){
_impacted.insert( op.payer );
}
void operator()( const son_wallet_deposit_process_operation& op ){
_impacted.insert( op.payer );
}
void operator()( const son_wallet_withdraw_create_operation& op ){
_impacted.insert( op.payer );
}
void operator()( const son_wallet_withdraw_process_operation& op ){
_impacted.insert( op.payer );
}
void operator()( const sidechain_address_add_operation& op ){
_impacted.insert( op.sidechain_address_account );
}
void operator()( const sidechain_address_update_operation& op ){
_impacted.insert( op.sidechain_address_account );
}
void operator()( const sidechain_address_delete_operation& op ){
_impacted.insert( op.sidechain_address_account );
}
void operator()( const sidechain_transaction_create_operation& op ){
_impacted.insert( op.payer );
}
void operator()( const sidechain_transaction_sign_operation& op ){
_impacted.insert( op.payer );
}
void operator()( const sidechain_transaction_send_operation& op ){
_impacted.insert( op.payer );
}
};
void operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result )
{
get_impacted_account_visitor vtor = get_impacted_account_visitor( result );
op.visit( vtor );
}
void transaction_get_impacted_accounts( const transaction& tx, flat_set<account_id_type>& result )
{
for( const auto& op : tx.operations )
operation_get_impacted_accounts( op, result );
}
} }

View file

@ -31,6 +31,8 @@
#include <graphene/market_history/market_history_plugin.hpp>
#include <graphene/accounts_list/accounts_list_plugin.hpp>
#include <graphene/elasticsearch/elasticsearch_plugin.hpp>
#include <graphene/debug_witness/debug_api.hpp>
#include <graphene/affiliate_stats/affiliate_stats_api.hpp>
#include <graphene/bookie/bookie_api.hpp>
@ -95,31 +97,32 @@ namespace graphene { namespace app {
class history_api
{
public:
history_api(application& app):_app(app){}
history_api(application& app)
:_app(app), database_api( std::ref(*app.chain_database())) {}
/**
* @brief Get operations relevant to the specificed account
* @param account The account whose history should be queried
* @param account_id_or_name The account ID or name whose history should be queried
* @param stop ID of the earliest operation to retrieve
* @param limit Maximum number of operations to retrieve (must not exceed 100)
* @param start ID of the most recent operation to retrieve
* @return A list of operations performed by account, ordered from most recent to oldest.
*/
vector<operation_history_object> get_account_history(account_id_type account,
vector<operation_history_object> get_account_history(const std::string account_id_or_name,
operation_history_id_type stop = operation_history_id_type(),
unsigned limit = 100,
operation_history_id_type start = operation_history_id_type())const;
/**
* @brief Get only asked operations relevant to the specified account
* @param account The account whose history should be queried
* @param account_id_or_name The account ID or name whose history should be queried
* @param operation_id The ID of the operation we want to get operations in the account( 0 = transfer , 1 = limit order create, ...)
* @param stop ID of the earliest operation to retrieve
* @param limit Maximum number of operations to retrieve (must not exceed 100)
* @param start ID of the most recent operation to retrieve
* @return A list of operations performed by account, ordered from most recent to oldest.
*/
vector<operation_history_object> get_account_history_operations(account_id_type account,
vector<operation_history_object> get_account_history_operations(const std::string account_id_or_name,
int operation_id,
operation_history_id_type start = operation_history_id_type(),
operation_history_id_type stop = operation_history_id_type(),
@ -129,7 +132,7 @@ namespace graphene { namespace app {
* @breif Get operations relevant to the specified account referenced
* by an event numbering specific to the account. The current number of operations
* for the account can be found in the account statistics (or use 0 for start).
* @param account The account whose history should be queried
* @param account_id_or_name The account ID or name whose history should be queried
* @param stop Sequence number of earliest operation. 0 is default and will
* query 'limit' number of operations.
* @param limit Maximum number of operations to retrieve (must not exceed 100)
@ -137,18 +140,19 @@ namespace graphene { namespace app {
* 0 is default, which will start querying from the most recent operation.
* @return A list of operations performed by account, ordered from most recent to oldest.
*/
vector<operation_history_object> get_relative_account_history( account_id_type account,
vector<operation_history_object> get_relative_account_history( const std::string account_id_or_name,
uint32_t stop = 0,
unsigned limit = 100,
uint32_t start = 0) const;
vector<order_history_object> get_fill_order_history( asset_id_type a, asset_id_type b, uint32_t limit )const;
vector<bucket_object> get_market_history( asset_id_type a, asset_id_type b, uint32_t bucket_seconds,
vector<order_history_object> get_fill_order_history( std::string asset_a, std::string asset_b, uint32_t limit )const;
vector<bucket_object> get_market_history( std::string asset_a, std::string asset_b, uint32_t bucket_seconds,
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;
private:
application& _app;
graphene::app::database_api database_api;
};
/**
@ -325,17 +329,47 @@ namespace graphene { namespace app {
class asset_api
{
public:
asset_api(graphene::chain::database& db);
asset_api(graphene::app::application& app);
~asset_api();
vector<account_asset_balance> get_asset_holders( asset_id_type asset_id, uint32_t start, uint32_t limit )const;
int get_asset_holders_count( asset_id_type asset_id )const;
/**
* @brief Get asset holders for a specific asset
* @param asset The specific asset id or symbol
* @param start The start index
* @param limit Maximum limit must not exceed 100
* @return A list of asset holders for the specified asset
*/
vector<account_asset_balance> get_asset_holders( std::string asset, uint32_t start, uint32_t limit )const;
/**
* @brief Get asset holders count for a specific asset
* @param asset The specific asset id or symbol
* @return Holders count for the specified asset
*/
int get_asset_holders_count( std::string asset )const;
/**
* @brief Get all asset holders
* @return A list of all asset holders
*/
vector<asset_holders> get_all_asset_holders() const;
private:
graphene::app::application& _app;
graphene::chain::database& _db;
graphene::app::database_api database_api;
};
} } // graphene::app
extern template class fc::api<graphene::app::block_api>;
extern template class fc::api<graphene::app::network_broadcast_api>;
extern template class fc::api<graphene::app::network_node_api>;
extern template class fc::api<graphene::app::history_api>;
extern template class fc::api<graphene::app::crypto_api>;
extern template class fc::api<graphene::app::asset_api>;
extern template class fc::api<graphene::debug_witness::debug_api>;
namespace graphene { namespace app {
/**
* @brief The login_api class implements the bottom layer of the RPC API
*
@ -397,6 +431,8 @@ namespace graphene { namespace app {
}} // graphene::app
extern template class fc::api<graphene::app::login_api>;
FC_REFLECT( graphene::app::network_broadcast_api::transaction_confirmation,
(id)(block_num)(trx_num)(trx) )
FC_REFLECT( graphene::app::verify_range_result,

View file

@ -56,8 +56,8 @@ namespace graphene { namespace app {
auto plug = std::make_shared<PluginType>();
plug->plugin_set_app(this);
string cli_plugin_desc = plug->plugin_name() + " plugin. " + plug->plugin_description() + "\nOptions";
boost::program_options::options_description plugin_cli_options( cli_plugin_desc ), plugin_cfg_options;
boost::program_options::options_description plugin_cli_options(plug->plugin_name() + " plugin. " + plug->plugin_description() + "\nOptions"), plugin_cfg_options;
//boost::program_options::options_description plugin_cli_options("Options for plugin " + plug->plugin_name()), plugin_cfg_options;
plug->plugin_set_program_options(plugin_cli_options, plugin_cfg_options);
if( !plugin_cli_options.options().empty() )
_cli_options.add(plugin_cli_options);
@ -99,7 +99,9 @@ namespace graphene { namespace app {
bool is_plugin_enabled(const string& name) const;
private:
std::shared_ptr<fc::thread> elasticsearch_thread;
private:
void add_available_plugin( std::shared_ptr<abstract_plugin> p );
std::shared_ptr<detail::application_impl> my;

View file

@ -117,6 +117,16 @@ struct market_trade
double value;
};
struct gpos_info {
double vesting_factor;
asset award;
share_type total_amount;
uint32_t current_subperiod;
fc::time_point_sec last_voted_time;
share_type allowed_withdraw_amount;
share_type account_vested_balance;
};
/**
* @brief The database_api class implements the RPC API for the chain database.
*
@ -244,13 +254,21 @@ class database_api
//////////////
/**
* @brief Get a list of accounts by ID
* @brief Get account object from a name or ID
* @param name_or_id name or ID of the account
* @return Account ID
*
*/
account_id_type get_account_id_from_string(const std::string& name_or_id)const;
/**
* @brief Get a list of accounts by ID or Name
* @param account_ids IDs of the accounts to retrieve
* @return The accounts corresponding to the provided IDs
*
* This function has semantics identical to @ref get_objects
*/
vector<optional<account_object>> get_accounts(const vector<account_id_type>& account_ids)const;
vector<optional<account_object>> get_accounts(const vector<std::string>& account_names_or_ids)const;
/**
* @brief Fetch all objects relevant to the specified accounts and subscribe to updates
@ -270,7 +288,7 @@ class database_api
/**
* @return all accounts that referr to the key or account id in their owner or active authorities.
*/
vector<account_id_type> get_account_references( account_id_type account_id )const;
vector<account_id_type> get_account_references( const std::string account_name_or_id )const;
/**
* @brief Get a list of accounts by name
@ -299,7 +317,8 @@ class database_api
* @param assets IDs of the assets to get balances of; if empty, get all assets account has a balance in
* @return Balances of the account
*/
vector<asset> get_account_balances(account_id_type id, const flat_set<asset_id_type>& assets)const;
vector<asset> get_account_balances( const std::string& account_name_or_id,
const flat_set<asset_id_type>& assets )const;
/// Semantically equivalent to @ref get_account_balances, but takes a name instead of an ID.
vector<asset> get_named_account_balances(const std::string& name, const flat_set<asset_id_type>& assets)const;
@ -309,7 +328,7 @@ class database_api
vector<asset> get_vested_balances( const vector<balance_id_type>& objs )const;
vector<vesting_balance_object> get_vesting_balances( account_id_type account_id )const;
vector<vesting_balance_object> get_vesting_balances( const std::string account_id_or_name )const;
/**
* @brief Get the total number of accounts registered with the blockchain
@ -320,14 +339,21 @@ class database_api
// Assets //
////////////
/**
* @brief Get asset ID from an asset symbol or ID
* @param symbol_or_id symbol name or ID of the asset
* @return asset ID
*/
asset_id_type get_asset_id_from_string(const std::string& symbol_or_id) const;
/**
* @brief Get a list of assets by ID
* @param asset_ids IDs of the assets to retrieve
* @param asset_symbols_or_ids IDs or names of the assets to retrieve
* @return The assets corresponding to the provided IDs
*
* This function has semantics identical to @ref get_objects
*/
vector<optional<asset_object>> get_assets(const vector<asset_id_type>& asset_ids)const;
vector<optional<asset_object>> get_assets(const vector<std::string>& asset_symbols_or_ids)const;
/**
* @brief Get assets alphabetically by symbol name
@ -429,47 +455,47 @@ class database_api
* @param limit Maximum number of orders to retrieve
* @return The limit orders, ordered from least price to greatest
*/
vector<limit_order_object> get_limit_orders(asset_id_type a, asset_id_type b, uint32_t limit)const;
vector<limit_order_object> get_limit_orders(const std::string& a, const std::string& b, uint32_t limit)const;
/**
* @brief Get call orders in a given asset
* @param a ID of asset being called
* @param a ID or name of asset being called
* @param limit Maximum number of orders to retrieve
* @return The call orders, ordered from earliest to be called to latest
*/
vector<call_order_object> get_call_orders(asset_id_type a, uint32_t limit)const;
vector<call_order_object> get_call_orders(const std::string& a, uint32_t limit)const;
/**
* @brief Get forced settlement orders in a given asset
* @param a ID of asset being settled
* @param a ID or name of asset being settled
* @param limit Maximum number of orders to retrieve
* @return The settle orders, ordered from earliest settlement date to latest
*/
vector<force_settlement_object> get_settle_orders(asset_id_type a, uint32_t limit)const;
vector<force_settlement_object> get_settle_orders(const std::string& a, uint32_t limit)const;
/**
* @return all open margin positions for a given account id.
*/
vector<call_order_object> get_margin_positions( const account_id_type& id )const;
vector<call_order_object> get_margin_positions( const std::string account_id_or_name )const;
/**
* @brief Request notification when the active orders in the market between two assets changes
* @param callback Callback method which is called when the market changes
* @param a First asset ID
* @param b Second asset ID
* @param a First asset ID or name
* @param b Second asset ID or name
*
* Callback will be passed a variant containing a vector<pair<operation, operation_result>>. The vector will
* contain, in order, the operations which changed the market, and their results.
*/
void subscribe_to_market(std::function<void(const variant&)> callback,
asset_id_type a, asset_id_type b);
const std::string& a, const std::string& b);
/**
* @brief Unsubscribe from updates to a given market
* @param a First asset ID
* @param b Second asset ID
* @param a First asset ID or name
* @param b Second asset ID or name
*/
void unsubscribe_from_market( asset_id_type a, asset_id_type b );
void unsubscribe_from_market( const std::string& a, const std::string& b );
/**
* @brief Returns the ticker for the market assetA:assetB
@ -528,7 +554,7 @@ class database_api
* @param account The ID of the account whose witness should be retrieved
* @return The witness object, or null if the account does not have a witness
*/
fc::optional<witness_object> get_witness_by_account(account_id_type account)const;
fc::optional<witness_object> get_witness_by_account(const std::string account_name_or_id)const;
/**
* @brief Get names and IDs for registered witnesses
@ -558,10 +584,10 @@ class database_api
/**
* @brief Get the committee_member owned by a given account
* @param account The ID of the account whose committee_member should be retrieved
* @param account_id_or_name The ID or name of the account whose committee_member should be retrieved
* @return The committee_member object, or null if the account does not have a committee_member
*/
fc::optional<committee_member_object> get_committee_member_by_account(account_id_type account)const;
fc::optional<committee_member_object> get_committee_member_by_account(const std::string account_id_or_name)const;
/**
* @brief Get names and IDs for registered committee_members
@ -671,9 +697,11 @@ class database_api
/// WORKERS
/**
* Return the worker objects associated with this account.
* @brief Return the worker objects associated with this account.
* @param account_id_or_name The ID or name of the account whose worker should be retrieved
* @return The worker object or null if the account does not have a worker
*/
vector<worker_object> get_workers_by_account(account_id_type account)const;
vector<worker_object> get_workers_by_account(const std::string account_id_or_name)const;
///////////
@ -730,7 +758,7 @@ class database_api
* For each operation calculate the required fee in the specified asset type. If the asset type does
* not have a valid core_exchange_rate
*/
vector< fc::variant > get_required_fees( const vector<operation>& ops, asset_id_type id )const;
vector< fc::variant > get_required_fees( const vector<operation>& ops, const std::string& asset_id_or_symbol )const;
///////////////////////////
// Proposed transactions //
@ -739,7 +767,7 @@ class database_api
/**
* @return the set of proposed transactions relevant to the specified account id.
*/
vector<proposal_object> get_proposed_transactions( account_id_type id )const;
vector<proposal_object> get_proposed_transactions( const std::string account_id_or_name )const;
//////////////////////
// Blinded balances //
@ -772,17 +800,31 @@ class database_api
*/
vector<tournament_id_type> get_registered_tournaments(account_id_type account_filter, uint32_t limit) const;
private:
//////////
// GPOS //
//////////
/**
* @return account and network GPOS information
*/
gpos_info get_gpos_info(const account_id_type account) const;
private:
std::shared_ptr< database_api_impl > my;
};
} }
extern template class fc::api<graphene::app::database_api>;
FC_REFLECT( graphene::app::order, (price)(quote)(base) );
FC_REFLECT( graphene::app::order_book, (base)(quote)(bids)(asks) );
FC_REFLECT( graphene::app::market_ticker, (base)(quote)(latest)(lowest_ask)(highest_bid)(percent_change)(base_volume)(quote_volume) );
FC_REFLECT( graphene::app::market_volume, (base)(quote)(base_volume)(quote_volume) );
FC_REFLECT( graphene::app::market_trade, (date)(price)(amount)(value) );
FC_REFLECT( graphene::app::gpos_info, (vesting_factor)(award)(total_amount)(current_subperiod)(last_voted_time)(allowed_withdraw_amount)(account_vested_balance) );
FC_API(graphene::app::database_api,
// Objects
@ -813,6 +855,7 @@ FC_API(graphene::app::database_api,
(is_public_key_registered)
// Accounts
(get_account_id_from_string)
(get_accounts)
(get_full_accounts)
(get_account_by_name)
@ -833,6 +876,7 @@ FC_API(graphene::app::database_api,
(list_assets)
(lookup_asset_symbols)
(get_asset_count)
(get_asset_id_from_string)
// Peerplays
(list_sports)
@ -918,4 +962,7 @@ FC_API(graphene::app::database_api,
(get_tournaments_by_state)
(get_tournaments )
(get_registered_tournaments)
// gpos
(get_gpos_info)
)

View file

@ -61,6 +61,7 @@ add_library( graphene_chain
protocol/confidential.cpp
protocol/vote.cpp
protocol/tournament.cpp
protocol/small_ops.cpp
genesis_state.cpp
get_config.cpp
@ -94,6 +95,7 @@ add_library( graphene_chain
fba_object.cpp
proposal_object.cpp
vesting_balance_object.cpp
small_objects.cpp
block_database.cpp

View file

@ -162,33 +162,39 @@ object_id_type account_create_evaluator::do_apply( const account_create_operatio
if( referrer_percent > GRAPHENE_100_PERCENT )
referrer_percent = GRAPHENE_100_PERCENT;
}
const auto& global_properties = d.get_global_properties();
const auto& new_acnt_object = db().create<account_object>( [&]( account_object& obj ){
obj.registrar = o.registrar;
obj.referrer = o.referrer;
obj.lifetime_referrer = o.referrer(db()).lifetime_referrer;
const auto& new_acnt_object = d.create<account_object>( [&o,&d,&global_properties,referrer_percent]( account_object& obj )
{
obj.registrar = o.registrar;
obj.referrer = o.referrer;
obj.lifetime_referrer = o.referrer(d).lifetime_referrer;
auto& params = db().get_global_properties().parameters;
obj.network_fee_percentage = params.network_percent_of_fee;
obj.lifetime_referrer_fee_percentage = params.lifetime_referrer_percent_of_fee;
obj.referrer_rewards_percentage = referrer_percent;
const auto& params = global_properties.parameters;
obj.network_fee_percentage = params.network_percent_of_fee;
obj.lifetime_referrer_fee_percentage = params.lifetime_referrer_percent_of_fee;
obj.referrer_rewards_percentage = referrer_percent;
obj.name = o.name;
obj.owner = o.owner;
obj.active = o.active;
obj.options = o.options;
obj.statistics = db().create<account_statistics_object>([&](account_statistics_object& s){s.owner = obj.id;}).id;
obj.name = o.name;
obj.owner = o.owner;
obj.active = o.active;
obj.options = o.options;
obj.statistics = d.create<account_statistics_object>([&obj](account_statistics_object& s){
s.owner = obj.id;
s.name = obj.name;
s.is_voting = obj.options.is_voting();
}).id;
if( o.extensions.value.owner_special_authority.valid() )
obj.owner_special_authority = *(o.extensions.value.owner_special_authority);
if( o.extensions.value.active_special_authority.valid() )
obj.active_special_authority = *(o.extensions.value.active_special_authority);
if( o.extensions.value.buyback_options.valid() )
{
obj.allowed_assets = o.extensions.value.buyback_options->markets;
obj.allowed_assets->emplace( o.extensions.value.buyback_options->asset_to_buy );
}
obj.affiliate_distributions = o.extensions.value.affiliate_distributions;
if( o.extensions.value.owner_special_authority.valid() )
obj.owner_special_authority = *(o.extensions.value.owner_special_authority);
if( o.extensions.value.active_special_authority.valid() )
obj.active_special_authority = *(o.extensions.value.active_special_authority);
if( o.extensions.value.buyback_options.valid() )
{
obj.allowed_assets = o.extensions.value.buyback_options->markets;
obj.allowed_assets->emplace( o.extensions.value.buyback_options->asset_to_buy );
}
obj.affiliate_distributions = o.extensions.value.affiliate_distributions;
});
if( has_small_percent )
@ -200,17 +206,18 @@ object_id_type account_create_evaluator::do_apply( const account_create_operatio
wlog( "Affected account object is ${o}", ("o", new_acnt_object) );
}
const auto& dynamic_properties = db().get_dynamic_global_properties();
db().modify(dynamic_properties, [](dynamic_global_property_object& p) {
const auto& dynamic_properties = d.get_dynamic_global_properties();
d.modify(dynamic_properties, [](dynamic_global_property_object& p) {
++p.accounts_registered_this_interval;
});
const auto& global_properties = db().get_global_properties();
if( dynamic_properties.accounts_registered_this_interval %
global_properties.parameters.accounts_per_fee_scale == 0 )
db().modify(global_properties, [&dynamic_properties](global_property_object& p) {
if( dynamic_properties.accounts_registered_this_interval % global_properties.parameters.accounts_per_fee_scale == 0
&& global_properties.parameters.account_fee_scale_bitshifts != 0 )
{
d.modify(global_properties, [&dynamic_properties](global_property_object& p) {
p.parameters.current_fees->get<account_create_operation>().basic_fee <<= p.parameters.account_fee_scale_bitshifts;
});
}
if( o.extensions.value.owner_special_authority.valid()
|| o.extensions.value.active_special_authority.valid() )
@ -280,18 +287,26 @@ void_result account_update_evaluator::do_apply( const account_update_operation&
{ try {
database& d = db();
bool sa_before = acnt->has_special_authority();
// update account statistics
if( o.new_options.valid() )
{
d.modify( acnt->statistics( d ), [&]( account_statistics_object& aso )
{
fc::optional< bool > flag = o.extensions.value.update_last_voting_time;
if((o.new_options->votes != acnt->options.votes ||
o.new_options->voting_account != acnt->options.voting_account))
o.new_options->voting_account != acnt->options.voting_account) ||
(flag.valid() && *flag))
aso.last_vote_time = d.head_block_time();
if(o.new_options->is_voting() != acnt->options.is_voting())
aso.is_voting = !aso.is_voting;
} );
}
bool sa_before, sa_after;
d.modify( *acnt, [&](account_object& a){
// update account object
d.modify( *acnt, [&o](account_object& a){
if( o.owner )
{
a.owner = *o.owner;
@ -303,7 +318,6 @@ void_result account_update_evaluator::do_apply( const account_update_operation&
a.top_n_control_flags = 0;
}
if( o.new_options ) a.options = *o.new_options;
sa_before = a.has_special_authority();
if( o.extensions.value.owner_special_authority.valid() )
{
a.owner_special_authority = *(o.extensions.value.owner_special_authority);
@ -314,9 +328,10 @@ void_result account_update_evaluator::do_apply( const account_update_operation&
a.active_special_authority = *(o.extensions.value.active_special_authority);
a.top_n_control_flags = 0;
}
sa_after = a.has_special_authority();
});
bool sa_after = acnt->has_special_authority();
if( sa_before & (!sa_after) )
{
const auto& sa_idx = d.get_index_type< special_authority_index >().indices().get<by_account>();

View file

@ -22,9 +22,9 @@
* THE SOFTWARE.
*/
#include <graphene/chain/account_object.hpp>
#include <graphene/chain/asset_object.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/hardfork.hpp>
#include <fc/io/raw.hpp>
#include <fc/uint128.hpp>
namespace graphene { namespace chain {
@ -46,6 +46,8 @@ void account_balance_object::adjust_balance(const asset& delta)
{
assert(delta.asset_id == asset_type);
balance += delta.amount;
if( asset_type == asset_id_type() ) // CORE asset
maintenance_flag = true;
}
void account_statistics_object::process_fees(const account_object& a, database& d) const
@ -57,8 +59,8 @@ void account_statistics_object::process_fees(const account_object& a, database&
// Check the referrer -- if he's no longer a member, pay to the lifetime referrer instead.
// No need to check the registrar; registrars are required to be lifetime members.
if( account.referrer(d).is_basic_account(d.head_block_time()) )
d.modify(account, [](account_object& a) {
a.referrer = a.lifetime_referrer;
d.modify( account, [](account_object& acc) {
acc.referrer = acc.lifetime_referrer;
});
share_type network_cut = cut_fee(core_fee_total, account.network_fee_percentage);
@ -74,8 +76,8 @@ void account_statistics_object::process_fees(const account_object& a, database&
share_type lifetime_cut = cut_fee(core_fee_total, account.lifetime_referrer_fee_percentage);
share_type referral = core_fee_total - network_cut - lifetime_cut;
d.modify(asset_dynamic_data_id_type()(d), [network_cut](asset_dynamic_data_object& d) {
d.accumulated_fees += network_cut;
d.modify( d.get_core_dynamic_data(), [network_cut](asset_dynamic_data_object& addo) {
addo.accumulated_fees += network_cut;
});
// Potential optimization: Skip some of this math and object lookups by special casing on the account type.
@ -318,3 +320,8 @@ const account_balance_object* balances_by_account_index::get_account_balance( co
}
} } // graphene::chain
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::account_object )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::account_balance_object )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::account_statistics_object )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::pending_dividend_payout_balance_for_holder_object )

View file

@ -133,33 +133,36 @@ void asset_create_evaluator::pay_fee()
object_id_type asset_create_evaluator::do_apply( const asset_create_operation& op )
{ try {
database& d = db();
// includes changes from bitshares. (https://github.com/bitshares/bitshares-core/issues/429)
bool hf_429 = fee_is_odd && db().head_block_time() > HARDFORK_CORE_429_TIME;
const asset_dynamic_data_object& dyn_asset =
db().create<asset_dynamic_data_object>( [&]( asset_dynamic_data_object& a ) {
d.create<asset_dynamic_data_object>( [hf_429,this]( asset_dynamic_data_object& a ) {
a.current_supply = 0;
a.fee_pool = core_fee_paid - (hf_429 ? 1 : 0);
});
if( fee_is_odd && !hf_429 )
{
const auto& core_dd = db().get<asset_object>( asset_id_type() ).dynamic_data( db() );
db().modify( core_dd, [=]( asset_dynamic_data_object& dd ) {
if( fee_is_odd && !hf_429 )
{
const auto& core_dd = d.get_core_asset().dynamic_data( d );
d.modify( core_dd, []( asset_dynamic_data_object& dd ) {
dd.current_supply++;
});
}
});
}
auto next_asset_id = d.get_index_type<asset_index>().get_next_id();
asset_bitasset_data_id_type bit_asset_id;
if( op.bitasset_opts.valid() )
bit_asset_id = db().create<asset_bitasset_data_object>( [&]( asset_bitasset_data_object& a ) {
bit_asset_id = d.create<asset_bitasset_data_object>( [&]( asset_bitasset_data_object& a ) {
a.options = *op.bitasset_opts;
a.is_prediction_market = op.is_prediction_market;
a.asset_id = next_asset_id;
}).id;
auto next_asset_id = db().get_index_type<asset_index>().get_next_id();
const asset_object& new_asset =
db().create<asset_object>( [&]( asset_object& a ) {
d.create<asset_object>( [&]( asset_object& a ) {
a.issuer = op.issuer;
a.symbol = op.symbol;
a.precision = op.precision;
@ -175,7 +178,7 @@ object_id_type asset_create_evaluator::do_apply( const asset_create_operation& o
if( op.bitasset_opts.valid() )
a.bitasset_data_id = bit_asset_id;
});
assert( new_asset.id == next_asset_id );
FC_ASSERT( new_asset.id == next_asset_id );
return new_asset.id;
} FC_CAPTURE_AND_RETHROW( (op) ) }
@ -281,33 +284,36 @@ void lottery_asset_create_evaluator::pay_fee()
object_id_type lottery_asset_create_evaluator::do_apply( const lottery_asset_create_operation& op )
{ try {
database& d = db();
// includes changes from bitshares. (https://github.com/bitshares/bitshares-core/issues/429)
bool hf_429 = fee_is_odd && db().head_block_time() > HARDFORK_CORE_429_TIME;
bool hf_429 = fee_is_odd && d.head_block_time() > HARDFORK_CORE_429_TIME;
const asset_dynamic_data_object& dyn_asset =
db().create<asset_dynamic_data_object>( [&]( asset_dynamic_data_object& a ) {
d.create<asset_dynamic_data_object>( [&]( asset_dynamic_data_object& a ) {
a.current_supply = 0;
a.fee_pool = core_fee_paid - (hf_429 ? 1 : 0);
});
if( fee_is_odd && !hf_429 )
{
const auto& core_dd = db().get<asset_object>( asset_id_type() ).dynamic_data( db() );
db().modify( core_dd, [=]( asset_dynamic_data_object& dd ) {
const auto& core_dd = d.get<asset_object>( asset_id_type() ).dynamic_data( db() );
d.modify( core_dd, [=]( asset_dynamic_data_object& dd ) {
dd.current_supply++;
});
}
auto next_asset_id = d.get_index_type<asset_index>().get_next_id();
asset_bitasset_data_id_type bit_asset_id;
if( op.bitasset_opts.valid() )
bit_asset_id = db().create<asset_bitasset_data_object>( [&]( asset_bitasset_data_object& a ) {
bit_asset_id = d.create<asset_bitasset_data_object>( [&op,next_asset_id]( asset_bitasset_data_object& a ) {
a.options = *op.bitasset_opts;
a.is_prediction_market = op.is_prediction_market;
a.asset_id = next_asset_id;
}).id;
auto next_asset_id = db().get_index_type<asset_index>().get_next_id();
const asset_object& new_asset =
db().create<asset_object>( [&]( asset_object& a ) {
d.create<asset_object>( [&op,next_asset_id,&dyn_asset,bit_asset_id,&d]( asset_object& a ) {
a.issuer = op.issuer;
a.symbol = op.symbol;
a.precision = op.precision;
@ -316,7 +322,7 @@ object_id_type lottery_asset_create_evaluator::do_apply( const lottery_asset_cre
a.lottery_options = op.extensions;
//a.lottery_options->balance = asset( 0, a.lottery_options->ticket_price.asset_id );
a.lottery_options->owner = a.id;
db().create<lottery_balance_object>([&](lottery_balance_object& lbo) {
d.create<lottery_balance_object>([&a](lottery_balance_object& lbo) {
lbo.lottery_id = a.id;
});
if( a.options.core_exchange_rate.base.asset_id.instance.value == 0 )
@ -327,7 +333,7 @@ object_id_type lottery_asset_create_evaluator::do_apply( const lottery_asset_cre
if( op.bitasset_opts.valid() )
a.bitasset_data_id = bit_asset_id;
});
assert( new_asset.id == next_asset_id );
FC_ASSERT( new_asset.id == next_asset_id, "Unexpected object database error, object id mismatch" );
return new_asset.id;
} FC_CAPTURE_AND_RETHROW( (op) ) }
@ -354,7 +360,7 @@ void_result asset_issue_evaluator::do_apply( const asset_issue_operation& o )
{ try {
db().adjust_balance( o.issue_to_account, o.asset_to_issue );
db().modify( *asset_dyn_data, [&]( asset_dynamic_data_object& data ){
db().modify( *asset_dyn_data, [&o]( asset_dynamic_data_object& data ){
data.current_supply += o.asset_to_issue.amount;
});
@ -386,7 +392,7 @@ void_result asset_reserve_evaluator::do_apply( const asset_reserve_operation& o
{ try {
db().adjust_balance( o.payer, -o.amount_to_reserve );
db().modify( *asset_dyn_data, [&]( asset_dynamic_data_object& data ){
db().modify( *asset_dyn_data, [&o]( asset_dynamic_data_object& data ){
data.current_supply -= o.amount_to_reserve.amount;
});
@ -408,7 +414,7 @@ void_result asset_fund_fee_pool_evaluator::do_apply(const asset_fund_fee_pool_op
{ try {
db().adjust_balance(o.from_account, -o.amount);
db().modify( *asset_dyn_data, [&]( asset_dynamic_data_object& data ) {
db().modify( *asset_dyn_data, [&o]( asset_dynamic_data_object& data ) {
data.fee_pool += o.amount;
});
@ -483,7 +489,21 @@ void_result asset_update_evaluator::do_apply(const asset_update_operation& o)
d.cancel_order(*itr);
}
d.modify(*asset_to_update, [&](asset_object& a) {
// For market-issued assets, if core change rate changed, update flag in bitasset data
if( asset_to_update->is_market_issued()
&& asset_to_update->options.core_exchange_rate != o.new_options.core_exchange_rate )
{
const auto& bitasset = asset_to_update->bitasset_data(d);
if( !bitasset.asset_cer_updated )
{
d.modify( bitasset, [](asset_bitasset_data_object& b)
{
b.asset_cer_updated = true;
});
}
}
d.modify(*asset_to_update, [&o](asset_object& a) {
if( o.new_issuer )
a.issuer = *o.new_issuer;
a.options = o.new_options;

View file

@ -24,10 +24,9 @@
#include <graphene/chain/asset_object.hpp>
#include <graphene/chain/database.hpp>
#include <fc/io/raw.hpp>
#include <fc/uint128.hpp>
#include <cmath>
using namespace graphene::chain;
share_type asset_bitasset_data_object::max_force_settlement_volume(share_type current_supply) const
@ -61,12 +60,15 @@ void asset_bitasset_data_object::update_median_feeds(time_point_sec current_time
if( current_feeds.size() < options.minimum_feeds )
{
//... don't calculate a median, and set a null feed
feed_cer_updated = false; // new median cer is null, won't update asset_object anyway, set to false for better performance
current_feed_publication_time = current_time;
current_feed = price_feed();
return;
}
if( current_feeds.size() == 1 )
{
if( current_feed.core_exchange_rate != current_feeds.front().get().core_exchange_rate )
feed_cer_updated = true;
current_feed = std::move(current_feeds.front());
return;
}
@ -85,6 +87,8 @@ void asset_bitasset_data_object::update_median_feeds(time_point_sec current_time
#undef CALCULATE_MEDIAN_VALUE
// *** End Median Calculations ***
if( current_feed.core_exchange_rate != median_feed.core_exchange_rate )
feed_cer_updated = true;
current_feed = median_feed;
}
@ -291,3 +295,11 @@ void sweeps_vesting_balance_object::adjust_balance( const asset& delta )
FC_ASSERT( delta.asset_id == asset_id );
balance += delta.amount.value;
}
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::asset_dynamic_data_object )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::asset_bitasset_data_object )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::asset_dividend_data_object )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::total_distributed_dividend_balance_object )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::asset_object )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::lottery_balance_object )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::sweeps_vesting_balance_object )

View file

@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
#include <graphene/chain/balance_evaluator.hpp>
#include <graphene/chain/pts_address.hpp>
namespace graphene { namespace chain {

View file

@ -77,15 +77,7 @@ void_result committee_member_update_evaluator::do_apply( const committee_member_
void_result committee_member_update_global_parameters_evaluator::do_evaluate(const committee_member_update_global_parameters_operation& o)
{ try {
FC_ASSERT(trx_state->_is_proposed_trx);
if( db().head_block_time() < HARDFORK_1000_TIME ) // TODO: remove after hf
FC_ASSERT( !o.new_parameters.extensions.value.min_bet_multiplier.valid()
&& !o.new_parameters.extensions.value.max_bet_multiplier.valid()
&& !o.new_parameters.extensions.value.betting_rake_fee_percentage.valid()
&& !o.new_parameters.extensions.value.permitted_betting_odds_increments.valid()
&& !o.new_parameters.extensions.value.live_betting_delay_time.valid(),
"Parameter extensions are not allowed yet!" );
dgpo = &db().get_global_properties();
if( o.new_parameters.extensions.value.min_bet_multiplier.valid()
&& !o.new_parameters.extensions.value.max_bet_multiplier.valid() )

View file

@ -77,6 +77,8 @@ void database::adjust_balance(account_id_type account, asset delta )
b.owner = account;
b.asset_type = delta.asset_id;
b.balance = delta.amount.value;
if( b.asset_type == asset_id_type() ) // CORE asset
b.maintenance_flag = true;
});
} else {
if( delta.amount < 0 )
@ -208,7 +210,7 @@ void database::deposit_cashback(const account_object& acct, share_type amount, b
acct.get_id() == GRAPHENE_TEMP_ACCOUNT )
{
// The blockchain's accounts do not get cashback; it simply goes to the reserve pool.
modify(get(asset_id_type()).dynamic_asset_data_id(*this), [amount](asset_dynamic_data_object& d) {
modify( get_core_dynamic_data(), [amount](asset_dynamic_data_object& d) {
d.current_supply -= amount;
});
return;
@ -223,10 +225,15 @@ void database::deposit_cashback(const account_object& acct, share_type amount, b
if( new_vbid.valid() )
{
modify( acct, [&]( account_object& _acct )
modify( acct, [&new_vbid]( account_object& _acct )
{
_acct.cashback_vb = *new_vbid;
} );
modify( acct.statistics( *this ), []( account_statistics_object& aso )
{
aso.has_cashback_vb = true;
} );
}
return;

View file

@ -39,6 +39,7 @@
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <graphene/chain/exceptions.hpp>
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/witness_schedule_object.hpp>
#include <fc/crypto/digest.hpp>
#include <fc/smart_ref_impl.hpp>
@ -197,82 +198,90 @@ bool database::push_block(const signed_block& new_block, uint32_t skip)
bool database::_push_block(const signed_block& new_block)
{ try {
uint32_t skip = get_node_properties().skip_flags;
if( !(skip&skip_fork_db) )
const auto now = fc::time_point::now().sec_since_epoch();
if( _fork_db.head() && new_block.timestamp.sec_since_epoch() > now - 86400 )
{
/// TODO: if the block is greater than the head block and before the next maitenance interval
// verify that the block signer is in the current set of active witnesses.
shared_ptr<fork_item> prev_block = _fork_db.fetch_block( new_block.previous );
GRAPHENE_ASSERT( prev_block, unlinkable_block_exception, "block does not link to known chain" );
if( prev_block->scheduled_witnesses && !(skip&(skip_witness_schedule_check|skip_witness_signature)) )
verify_signing_witness( new_block, *prev_block );
}
shared_ptr<fork_item> new_head = _fork_db.push_block(new_block);
shared_ptr<fork_item> new_head = _fork_db.push_block(new_block);
//If the head block from the longest chain does not build off of the current head, we need to switch forks.
if( new_head->data.previous != head_block_id() )
//If the head block from the longest chain does not build off of the current head, we need to switch forks.
if( new_head->data.previous != head_block_id() )
{
//If the newly pushed block is the same height as head, we get head back in new_head
//Only switch forks if new_head is actually higher than head
if( new_head->data.block_num() > head_block_num() )
{
//If the newly pushed block is the same height as head, we get head back in new_head
//Only switch forks if new_head is actually higher than head
if( new_head->data.block_num() > head_block_num() )
wlog( "Switching to fork: ${id}", ("id",new_head->data.id()) );
auto branches = _fork_db.fetch_branch_from(new_head->data.id(), head_block_id());
// pop blocks until we hit the forked block
while( head_block_id() != branches.second.back()->data.previous )
{
wlog( "Switching to fork: ${id}", ("id",new_head->data.id()) );
auto branches = _fork_db.fetch_branch_from(new_head->data.id(), head_block_id());
// pop blocks until we hit the forked block
while( head_block_id() != branches.second.back()->data.previous )
{
ilog( "popping block #${n} ${id}", ("n",head_block_num())("id",head_block_id()) );
pop_block();
}
// push all blocks on the new fork
for( auto ritr = branches.first.rbegin(); ritr != branches.first.rend(); ++ritr )
{
ilog( "pushing block from fork #${n} ${id}", ("n",(*ritr)->data.block_num())("id",(*ritr)->id) );
optional<fc::exception> except;
try {
undo_database::session session = _undo_db.start_undo_session();
apply_block( (*ritr)->data, skip );
_block_id_to_block.store( (*ritr)->id, (*ritr)->data );
session.commit();
}
catch ( const fc::exception& e ) { except = e; }
if( except )
{
wlog( "exception thrown while switching forks ${e}", ("e",except->to_detail_string() ) );
// remove the rest of branches.first from the fork_db, those blocks are invalid
while( ritr != branches.first.rend() )
{
ilog( "removing block from fork_db #${n} ${id}", ("n",(*ritr)->data.block_num())("id",(*ritr)->id) );
_fork_db.remove( (*ritr)->id );
++ritr;
}
_fork_db.set_head( branches.second.front() );
// pop all blocks from the bad fork
while( head_block_id() != branches.second.back()->data.previous )
{
ilog( "popping block #${n} ${id}", ("n",head_block_num())("id",head_block_id()) );
pop_block();
}
ilog( "Switching back to fork: ${id}", ("id",branches.second.front()->data.id()) );
// restore all blocks from the good fork
for( auto ritr2 = branches.second.rbegin(); ritr2 != branches.second.rend(); ++ritr2 )
{
ilog( "pushing block #${n} ${id}", ("n",(*ritr2)->data.block_num())("id",(*ritr2)->id) );
auto session = _undo_db.start_undo_session();
apply_block( (*ritr2)->data, skip );
_block_id_to_block.store( (*ritr2)->id, (*ritr2)->data );
session.commit();
}
throw *except;
}
}
return true;
ilog( "popping block #${n} ${id}", ("n",head_block_num())("id",head_block_id()) );
pop_block();
}
else return false;
// push all blocks on the new fork
for( auto ritr = branches.first.rbegin(); ritr != branches.first.rend(); ++ritr )
{
ilog( "pushing block from fork #${n} ${id}", ("n",(*ritr)->data.block_num())("id",(*ritr)->id) );
optional<fc::exception> except;
try {
undo_database::session session = _undo_db.start_undo_session();
apply_block( (*ritr)->data, skip );
update_witnesses( **ritr );
_block_id_to_block.store( (*ritr)->id, (*ritr)->data );
session.commit();
}
catch ( const fc::exception& e ) { except = e; }
if( except )
{
wlog( "exception thrown while switching forks ${e}", ("e",except->to_detail_string() ) );
// remove the rest of branches.first from the fork_db, those blocks are invalid
while( ritr != branches.first.rend() )
{
ilog( "removing block from fork_db #${n} ${id}", ("n",(*ritr)->data.block_num())("id",(*ritr)->id) );
_fork_db.remove( (*ritr)->id );
++ritr;
}
_fork_db.set_head( branches.second.front() );
// pop all blocks from the bad fork
while( head_block_id() != branches.second.back()->data.previous )
{
ilog( "popping block #${n} ${id}", ("n",head_block_num())("id",head_block_id()) );
pop_block();
}
ilog( "Switching back to fork: ${id}", ("id",branches.second.front()->data.id()) );
// restore all blocks from the good fork
for( auto ritr2 = branches.second.rbegin(); ritr2 != branches.second.rend(); ++ritr2 )
{
ilog( "pushing block #${n} ${id}", ("n",(*ritr2)->data.block_num())("id",(*ritr2)->id) );
auto session = _undo_db.start_undo_session();
apply_block( (*ritr2)->data, skip );
_block_id_to_block.store( (*ritr2)->id, (*ritr2)->data );
session.commit();
}
throw *except;
}
}
return true;
}
else return false;
}
try {
auto session = _undo_db.start_undo_session();
apply_block(new_block, skip);
if( new_block.timestamp.sec_since_epoch() > now - 86400 )
update_witnesses( *new_head );
_block_id_to_block.store(new_block.id(), new_block);
session.commit();
} catch ( const fc::exception& e ) {
@ -284,6 +293,73 @@ bool database::_push_block(const signed_block& new_block)
return false;
} FC_CAPTURE_AND_RETHROW( (new_block) ) }
void database::verify_signing_witness( const signed_block& new_block, const fork_item& fork_entry )const
{
FC_ASSERT( new_block.timestamp >= fork_entry.next_block_time );
uint32_t slot_num = ( new_block.timestamp - fork_entry.next_block_time ).to_seconds() / block_interval();
const global_property_object& gpo = get_global_properties();
if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SHUFFLED_ALGORITHM)
{
uint64_t index = ( fork_entry.next_block_aslot + slot_num ) % fork_entry.scheduled_witnesses->size();
const auto& scheduled_witness = (*fork_entry.scheduled_witnesses)[index];
FC_ASSERT( new_block.witness == scheduled_witness.first, "Witness produced block at wrong time",
("block witness",new_block.witness)("scheduled",scheduled_witness)("slot_num",slot_num) );
FC_ASSERT( new_block.validate_signee( scheduled_witness.second ) );
}
if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM &&
slot_num != 0 )
{
witness_id_type wid;
const witness_schedule_object& wso = get_witness_schedule_object();
// ask the near scheduler who goes in the given slot
bool slot_is_near = wso.scheduler.get_slot(slot_num, wid);
if(! slot_is_near)
{
// if the near scheduler doesn't know, we have to extend it to
// a far scheduler.
// n.b. instantiating it is slow, but block gaps long enough to
// need it are likely pretty rare.
witness_scheduler_rng far_rng(wso.rng_seed.begin(), GRAPHENE_FAR_SCHEDULE_CTR_IV);
far_future_witness_scheduler far_scheduler =
far_future_witness_scheduler(wso.scheduler, far_rng);
if(!far_scheduler.get_slot(slot_num, wid))
{
// no scheduled witness -- somebody set up us the bomb
// n.b. this code path is impossible, the present
// implementation of far_future_witness_scheduler
// returns true unconditionally
assert( false );
}
}
FC_ASSERT( new_block.witness == wid, "Witness produced block at wrong time",
("block witness",new_block.witness)("scheduled",wid)("slot_num",slot_num) );
FC_ASSERT( new_block.validate_signee( wid(*this).signing_key ) );
}
}
void database::update_witnesses( fork_item& fork_entry )const
{
if( fork_entry.scheduled_witnesses ) return;
const dynamic_global_property_object& dpo = get_dynamic_global_properties();
fork_entry.next_block_aslot = dpo.current_aslot + 1;
fork_entry.next_block_time = get_slot_time( 1 );
const witness_schedule_object& wso = get_witness_schedule_object();
fork_entry.scheduled_witnesses = std::make_shared< vector< pair< witness_id_type, public_key_type > > >();
fork_entry.scheduled_witnesses->reserve( wso.current_shuffled_witnesses.size() );
for( size_t i = 0; i < wso.current_shuffled_witnesses.size(); ++i )
{
const auto& witness = wso.current_shuffled_witnesses[i](*this);
fork_entry.scheduled_witnesses->emplace_back( wso.current_shuffled_witnesses[i], witness.signing_key );
}
}
/**
* Attempts to push the transaction into the pending queue
*
@ -324,7 +400,7 @@ processed_transaction database::_push_transaction( const signed_transaction& trx
temp_session.merge();
// notify anyone listening to pending transactions
on_pending_transaction( trx );
notify_on_pending_transaction( trx );
return processed_trx;
}
@ -593,7 +669,7 @@ void database::_apply_block( const signed_block& next_block )
const witness_object& signing_witness = validate_block_header(skip, next_block);
const auto& global_props = get_global_properties();
const auto& dynamic_global_props = get<dynamic_global_property_object>(dynamic_global_property_id_type());
const auto& dynamic_global_props = get_dynamic_global_properties();
bool maint_needed = (dynamic_global_props.next_maintenance_time <= next_block.timestamp);
_current_block_num = next_block_num;
@ -601,6 +677,8 @@ void database::_apply_block( const signed_block& next_block )
_current_op_in_trx = 0;
_current_virtual_op = 0;
_issue_453_affected_assets.clear();
for( const auto& trx : next_block.transactions )
{
/* We do not need to push the undo state for each transaction
@ -644,7 +722,8 @@ void database::_apply_block( const signed_block& next_block )
clear_expired_transactions();
clear_expired_proposals();
clear_expired_orders();
update_expired_feeds();
update_expired_feeds(); // this will update expired feeds and some core exchange rates
update_core_exchange_rates(); // this will update remaining core exchange rates
update_withdraw_permissions();
update_tournaments();
update_betting_markets(next_block.timestamp);
@ -666,7 +745,7 @@ void database::_apply_block( const signed_block& next_block )
apply_debug_updates();
// notify observers that the block has been applied
applied_block( next_block ); //emit
notify_applied_block( next_block ); //emit
_applied_ops.clear();
notify_changed_objects();

View file

@ -42,7 +42,7 @@ void database::debug_dump()
const asset_dynamic_data_object& core_asset_data = db.get_core_asset().dynamic_asset_data_id(db);
const auto& balance_index = db.get_index_type<account_balance_index>().indices();
const simple_index<account_statistics_object>& statistics_index = db.get_index_type<simple_index<account_statistics_object>>();
const auto& statistics_index = db.get_index_type<account_stats_index>().indices();
map<asset_id_type,share_type> total_balances;
map<asset_id_type,share_type> total_debts;
share_type core_in_orders;

View file

@ -38,22 +38,27 @@ namespace graphene { namespace chain {
const asset_object& database::get_core_asset() const
{
return get(asset_id_type());
return *_p_core_asset_obj;
}
const asset_dynamic_data_object& database::get_core_dynamic_data() const
{
return *_p_core_dynamic_data_obj;
}
const global_property_object& database::get_global_properties()const
{
return get( global_property_id_type() );
return *_p_global_prop_obj;
}
const chain_property_object& database::get_chain_properties()const
{
return get( chain_property_id_type() );
return *_p_chain_property_obj;
}
const dynamic_global_property_object& database::get_dynamic_global_properties() const
{
return get( dynamic_global_property_id_type() );
return *_p_dyn_global_prop_obj;
}
const fee_schedule& database::current_fee_schedule()const
@ -63,17 +68,17 @@ const fee_schedule& database::current_fee_schedule()const
time_point_sec database::head_block_time()const
{
return get( dynamic_global_property_id_type() ).time;
return get_dynamic_global_properties().time;
}
uint32_t database::head_block_num()const
{
return get( dynamic_global_property_id_type() ).head_block_number;
return get_dynamic_global_properties().head_block_number;
}
block_id_type database::head_block_id()const
{
return get( dynamic_global_property_id_type() ).head_block_id;
return get_dynamic_global_properties().head_block_id;
}
decltype( chain_parameters::block_interval ) database::block_interval( )const
@ -232,4 +237,17 @@ bool database::is_son_dereg_valid( son_id_type son_id )
return ret;
}
const account_statistics_object& database::get_account_stats_by_owner( account_id_type owner )const
{
auto& idx = get_index_type<account_stats_index>().indices().get<by_owner>();
auto itr = idx.find( owner );
FC_ASSERT( itr != idx.end(), "Can not find account statistics object for owner ${a}", ("a",owner) );
return *itr;
}
const witness_schedule_object& database::get_witness_schedule_object()const
{
return *_p_witness_schedule_obj;
}
} }

View file

@ -333,7 +333,7 @@ void database::initialize_indexes()
add_index< primary_index<asset_dividend_data_object_index > >();
add_index< primary_index<simple_index<global_property_object >> >();
add_index< primary_index<simple_index<dynamic_global_property_object >> >();
add_index< primary_index<simple_index<account_statistics_object >> >();
add_index< primary_index<account_stats_index > >();
add_index< primary_index<simple_index<asset_dynamic_data_object >> >();
add_index< primary_index<flat_index< block_summary_object >> >();
add_index< primary_index<simple_index<chain_property_object > > >();
@ -395,12 +395,19 @@ void database::init_genesis(const genesis_state_type& genesis_state)
n.owner.weight_threshold = 1;
n.active.weight_threshold = 1;
n.name = "committee-account";
n.statistics = create<account_statistics_object>( [&](account_statistics_object& s){ s.owner = n.id; }).id;
n.statistics = create<account_statistics_object>( [&n](account_statistics_object& s){
s.owner = n.id;
s.name = n.name;
s.core_in_balance = GRAPHENE_MAX_SHARE_SUPPLY;
}).id;
});
FC_ASSERT(committee_account.get_id() == GRAPHENE_COMMITTEE_ACCOUNT);
FC_ASSERT(create<account_object>([this](account_object& a) {
a.name = "witness-account";
a.statistics = create<account_statistics_object>([&](account_statistics_object& s){s.owner = a.id;}).id;
a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
s.owner = a.id;
s.name = a.name;
}).id;
a.owner.weight_threshold = 1;
a.active.weight_threshold = 1;
a.registrar = a.lifetime_referrer = a.referrer = GRAPHENE_WITNESS_ACCOUNT;
@ -410,7 +417,10 @@ void database::init_genesis(const genesis_state_type& genesis_state)
}).get_id() == GRAPHENE_WITNESS_ACCOUNT);
FC_ASSERT(create<account_object>([this](account_object& a) {
a.name = "relaxed-committee-account";
a.statistics = create<account_statistics_object>([&](account_statistics_object& s){s.owner = a.id;}).id;
a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
s.owner = a.id;
s.name = a.name;
}).id;
a.owner.weight_threshold = 1;
a.active.weight_threshold = 1;
a.registrar = a.lifetime_referrer = a.referrer = GRAPHENE_RELAXED_COMMITTEE_ACCOUNT;
@ -420,7 +430,10 @@ void database::init_genesis(const genesis_state_type& genesis_state)
}).get_id() == GRAPHENE_RELAXED_COMMITTEE_ACCOUNT);
FC_ASSERT(create<account_object>([this](account_object& a) {
a.name = "null-account";
a.statistics = create<account_statistics_object>([&](account_statistics_object& s){s.owner = a.id;}).id;
a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
s.owner = a.id;
s.name = a.name;
}).id;
a.owner.weight_threshold = 1;
a.active.weight_threshold = 1;
a.registrar = a.lifetime_referrer = a.referrer = GRAPHENE_NULL_ACCOUNT;
@ -430,7 +443,10 @@ void database::init_genesis(const genesis_state_type& genesis_state)
}).get_id() == GRAPHENE_NULL_ACCOUNT);
FC_ASSERT(create<account_object>([this](account_object& a) {
a.name = "temp-account";
a.statistics = create<account_statistics_object>([&](account_statistics_object& s){s.owner = a.id;}).id;
a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
s.owner = a.id;
s.name = a.name;
}).id;
a.owner.weight_threshold = 0;
a.active.weight_threshold = 0;
a.registrar = a.lifetime_referrer = a.referrer = GRAPHENE_TEMP_ACCOUNT;
@ -440,7 +456,10 @@ void database::init_genesis(const genesis_state_type& genesis_state)
}).get_id() == GRAPHENE_TEMP_ACCOUNT);
FC_ASSERT(create<account_object>([this](account_object& a) {
a.name = "proxy-to-self";
a.statistics = create<account_statistics_object>([&](account_statistics_object& s){s.owner = a.id;}).id;
a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
s.owner = a.id;
s.name = a.name;
}).id;
a.owner.weight_threshold = 1;
a.active.weight_threshold = 1;
a.registrar = a.lifetime_referrer = a.referrer = GRAPHENE_NULL_ACCOUNT;
@ -450,7 +469,10 @@ void database::init_genesis(const genesis_state_type& genesis_state)
}).get_id() == GRAPHENE_PROXY_TO_SELF_ACCOUNT);
FC_ASSERT(create<account_object>([this](account_object& a) {
a.name = "default-dividend-distribution";
a.statistics = create<account_statistics_object>([&](account_statistics_object& s){s.owner = a.id;}).id;
a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
s.owner = a.id;
s.name = a.name;
}).id;
a.owner.weight_threshold = 1;
a.active.weight_threshold = 1;
a.registrar = a.lifetime_referrer = a.referrer = GRAPHENE_PROXY_TO_SELF_ACCOUNT;
@ -464,9 +486,12 @@ void database::init_genesis(const genesis_state_type& genesis_state)
uint64_t id = get_index<account_object>().get_next_id().instance();
if( id >= genesis_state.immutable_parameters.num_special_accounts )
break;
const account_object& acct = create<account_object>([&](account_object& a) {
const account_object& acct = create<account_object>([this,id](account_object& a) {
a.name = "special-account-" + std::to_string(id);
a.statistics = create<account_statistics_object>([&](account_statistics_object& s){s.owner = a.id;}).id;
a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
s.owner = a.id;
s.name = a.name;
}).id;
a.owner.weight_threshold = 1;
a.active.weight_threshold = 1;
a.registrar = a.lifetime_referrer = a.referrer = account_id_type(id);
@ -480,12 +505,12 @@ void database::init_genesis(const genesis_state_type& genesis_state)
// Create core asset
const asset_dynamic_data_object& dyn_asset =
create<asset_dynamic_data_object>([&](asset_dynamic_data_object& a) {
create<asset_dynamic_data_object>([](asset_dynamic_data_object& a) {
a.current_supply = GRAPHENE_MAX_SHARE_SUPPLY;
});
const asset_dividend_data_object& div_asset =
create<asset_dividend_data_object>([&](asset_dividend_data_object& a) {
create<asset_dividend_data_object>([&genesis_state](asset_dividend_data_object& a) {
a.options.minimum_distribution_interval = 3*24*60*60;
a.options.minimum_fee_percentage = 10*GRAPHENE_1_PERCENT;
a.options.next_payout_time = genesis_state.initial_timestamp + fc::days(1);
@ -494,7 +519,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
});
const asset_object& core_asset =
create<asset_object>( [&]( asset_object& a ) {
create<asset_object>( [&genesis_state,&div_asset,&dyn_asset]( asset_object& a ) {
a.symbol = GRAPHENE_SYMBOL;
a.options.max_supply = genesis_state.max_core_supply;
a.precision = GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS;
@ -507,9 +532,12 @@ void database::init_genesis(const genesis_state_type& genesis_state)
a.options.core_exchange_rate.quote.asset_id = asset_id_type(0);
a.dynamic_asset_data_id = dyn_asset.id;
a.dividend_data_id = div_asset.id;
});
assert( asset_id_type(core_asset.id) == asset().asset_id );
assert( get_balance(account_id_type(), asset_id_type()) == asset(dyn_asset.current_supply) );
});
FC_ASSERT( dyn_asset.id == asset_dynamic_data_id_type() );
FC_ASSERT( asset_id_type(core_asset.id) == asset().asset_id );
FC_ASSERT( get_balance(account_id_type(), asset_id_type()) == asset(dyn_asset.current_supply) );
_p_core_asset_obj = &core_asset;
_p_core_dynamic_data_obj = &dyn_asset;
#ifdef _DEFAULT_DIVIDEND_ASSET
// Create default dividend asset
@ -542,7 +570,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
a.dynamic_asset_data_id = dyn_asset1.id;
a.dividend_data_id = div_asset1.id;
});
assert( default_asset.id == asset_id_type(1) );
FC_ASSERT( default_asset.id == asset_id_type(1) );
#endif
// Create more special assets
@ -552,10 +580,10 @@ void database::init_genesis(const genesis_state_type& genesis_state)
if( id >= genesis_state.immutable_parameters.num_special_assets )
break;
const asset_dynamic_data_object& dyn_asset =
create<asset_dynamic_data_object>([&](asset_dynamic_data_object& a) {
create<asset_dynamic_data_object>([](asset_dynamic_data_object& a) {
a.current_supply = 0;
});
const asset_object& asset_obj = create<asset_object>( [&]( asset_object& a ) {
const asset_object& asset_obj = create<asset_object>( [id,&dyn_asset]( asset_object& a ) {
a.symbol = "SPECIAL" + std::to_string( id );
a.options.max_supply = 0;
a.precision = GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS;
@ -575,14 +603,14 @@ void database::init_genesis(const genesis_state_type& genesis_state)
chain_id_type chain_id = genesis_state.compute_chain_id();
// Create global properties
create<global_property_object>([&](global_property_object& p) {
_p_global_prop_obj = & create<global_property_object>([&genesis_state](global_property_object& p) {
p.parameters = genesis_state.initial_parameters;
// Set fees to zero initially, so that genesis initialization needs not pay them
// We'll fix it at the end of the function
p.parameters.current_fees->zero_all_fees();
});
create<dynamic_global_property_object>([&](dynamic_global_property_object& p) {
_p_dyn_global_prop_obj = & create<dynamic_global_property_object>([&genesis_state](dynamic_global_property_object& p) {
p.time = genesis_state.initial_timestamp;
p.dynamic_flags = 0;
p.witness_budget = 0;
@ -595,7 +623,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
FC_ASSERT( (genesis_state.immutable_parameters.min_witness_count & 1) == 1, "min_witness_count must be odd" );
FC_ASSERT( (genesis_state.immutable_parameters.min_committee_member_count & 1) == 1, "min_committee_member_count must be odd" );
create<chain_property_object>([&](chain_property_object& p)
_p_chain_property_obj = & create<chain_property_object>([chain_id,&genesis_state](chain_property_object& p)
{
p.chain_id = chain_id;
p.immutable_parameters = genesis_state.immutable_parameters;
@ -719,7 +747,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
cop.active = cop.owner;
account_id_type owner_account_id = apply_operation(genesis_eval_state, cop).get<object_id_type>();
modify( owner_account_id(*this).statistics(*this), [&]( account_statistics_object& o ) {
modify( owner_account_id(*this).statistics(*this), [&collateral_rec]( account_statistics_object& o ) {
o.total_core_in_orders = collateral_rec.collateral;
});
@ -935,7 +963,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
});
// Set active witnesses
modify(get_global_properties(), [&](global_property_object& p) {
modify(get_global_properties(), [&genesis_state](global_property_object& p) {
for( uint32_t i = 1; i <= genesis_state.initial_active_witnesses; ++i )
{
p.active_witnesses.insert(witness_id_type(i));
@ -943,10 +971,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
});
// Initialize witness schedule
#ifndef NDEBUG
const witness_schedule_object& wso =
#endif
create<witness_schedule_object>([&](witness_schedule_object& _wso)
_p_witness_schedule_obj = & create<witness_schedule_object>([this](witness_schedule_object& _wso)
{
// for scheduled
memset(_wso.rng_seed.begin(), 0, _wso.rng_seed.size());
@ -970,7 +995,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
for( const witness_id_type& wid : get_global_properties().active_witnesses )
_wso.current_shuffled_witnesses.push_back( wid );
});
assert( wso.id == witness_schedule_id_type() );
FC_ASSERT( _p_witness_schedule_obj->id == witness_schedule_id_type() );
// Initialize witness schedule
#ifndef NDEBUG
@ -1000,12 +1025,6 @@ void database::init_genesis(const genesis_state_type& genesis_state)
p.parameters.current_fees = genesis_state.initial_parameters.current_fees;
});
// Create witness scheduler
//create<witness_schedule_object>([&]( witness_schedule_object& wso )
//{
// for( const witness_id_type& wid : get_global_properties().active_witnesses )
// wso.current_shuffled_witnesses.push_back( wid );
//});
// Create FBA counters
create<fba_accumulator_object>([&]( fba_accumulator_object& acc )

View file

@ -77,12 +77,44 @@ vector<std::reference_wrapper<const typename Index::object_type>> database::sort
return refs;
}
template<class... Types>
void database::perform_account_maintenance(std::tuple<Types...> helpers)
template<class Type>
void database::perform_account_maintenance(Type tally_helper)
{
const auto& idx = get_index_type<account_index>().indices().get<by_name>();
for( const account_object& a : idx )
detail::for_each(helpers, a, detail::gen_seq<sizeof...(Types)>());
const auto& bal_idx = get_index_type< account_balance_index >().indices().get< by_maintenance_flag >();
if( bal_idx.begin() != bal_idx.end() )
{
auto bal_itr = bal_idx.rbegin();
while( bal_itr->maintenance_flag )
{
const account_balance_object& bal_obj = *bal_itr;
modify( get_account_stats_by_owner( bal_obj.owner ), [&bal_obj](account_statistics_object& aso) {
aso.core_in_balance = bal_obj.balance;
});
modify( bal_obj, []( account_balance_object& abo ) {
abo.maintenance_flag = false;
});
bal_itr = bal_idx.rbegin();
}
}
const auto& stats_idx = get_index_type< account_stats_index >().indices().get< by_maintenance_seq >();
auto stats_itr = stats_idx.lower_bound( true );
while( stats_itr != stats_idx.end() )
{
const account_statistics_object& acc_stat = *stats_itr;
const account_object& acc_obj = acc_stat.owner( *this );
++stats_itr;
if( acc_stat.has_some_core_voting() )
tally_helper( acc_obj, acc_stat );
if( acc_stat.has_pending_fees() )
acc_stat.process_fees( acc_obj, *this );
}
}
/// @brief A visitor for @ref worker_type which calls pay_worker on the worker within
@ -319,12 +351,13 @@ void database::update_son_wallet(const vector<son_info>& new_active_sons)
void database::pay_workers( share_type& budget )
{
const auto head_time = head_block_time();
// ilog("Processing payroll! Available budget is ${b}", ("b", budget));
vector<std::reference_wrapper<const worker_object>> active_workers;
get_index_type<worker_index>().inspect_all_objects([this, &active_workers](const object& o) {
// TODO optimization: add by_expiration index to avoid iterating through all objects
get_index_type<worker_index>().inspect_all_objects([head_time, &active_workers](const object& o) {
const worker_object& w = static_cast<const worker_object&>(o);
auto now = head_block_time();
if( w.is_active(now) && w.approving_stake() > 0 )
if( w.is_active(head_time) && w.approving_stake() > 0 )
active_workers.emplace_back(w);
});
@ -338,17 +371,22 @@ void database::pay_workers( share_type& budget )
return wa.id < wb.id;
});
const auto last_budget_time = get_dynamic_global_properties().last_budget_time;
const auto passed_time_ms = head_time - last_budget_time;
const auto passed_time_count = passed_time_ms.count();
const auto day_count = fc::days(1).count();
for( uint32_t i = 0; i < active_workers.size() && budget > 0; ++i )
{
const worker_object& active_worker = active_workers[i];
share_type requested_pay = active_worker.daily_pay;
if( head_block_time() - get_dynamic_global_properties().last_budget_time != fc::days(1) )
{
fc::uint128 pay(requested_pay.value);
pay *= (head_block_time() - get_dynamic_global_properties().last_budget_time).count();
pay /= fc::days(1).count();
requested_pay = pay.to_uint64();
}
// Note: if there is a good chance that passed_time_count == day_count,
// for better performance, can avoid the 128 bit calculation by adding a check.
// Since it's not the case on BitShares mainnet, we're not using a check here.
fc::uint128 pay(requested_pay.value);
pay *= passed_time_count;
pay /= day_count;
requested_pay = pay.to_uint64();
share_type actual_pay = std::min(budget, requested_pay);
//ilog(" ==> Paying ${a} to worker ${w}", ("w", active_worker.id)("a", actual_pay));
@ -385,13 +423,27 @@ void database::update_active_witnesses()
const global_property_object& gpo = get_global_properties();
const auto& all_witnesses = get_index_type<witness_index>().indices();
auto update_witness_total_votes = [this]( const witness_object& wit ) {
modify( wit, [this]( witness_object& obj )
{
obj.total_votes = _vote_tally_buffer[obj.vote_id];
});
};
for( const witness_object& wit : all_witnesses )
if( _track_standby_votes )
{
modify( wit, [&]( witness_object& obj ){
obj.total_votes = _vote_tally_buffer[wit.vote_id];
});
const auto& all_witnesses = get_index_type<witness_index>().indices();
for( const witness_object& wit : all_witnesses )
{
update_witness_total_votes( wit );
}
}
else
{
for( const witness_object& wit : wits )
{
update_witness_total_votes( wit );
}
}
// Update witness authority
@ -467,13 +519,29 @@ void database::update_active_committee_members()
const chain_property_object& cpo = get_chain_properties();
auto committee_members = sort_votable_objects<committee_member_index>(std::max(committee_member_count*2+1, (size_t)cpo.immutable_parameters.min_committee_member_count));
for( const committee_member_object& del : committee_members )
{
modify( del, [&]( committee_member_object& obj ){
obj.total_votes = _vote_tally_buffer[del.vote_id];
});
}
auto update_committee_member_total_votes = [this]( const committee_member_object& cm ) {
modify( cm, [this]( committee_member_object& obj )
{
obj.total_votes = _vote_tally_buffer[obj.vote_id];
});
};
if( _track_standby_votes )
{
const auto& all_committee_members = get_index_type<committee_member_index>().indices();
for( const committee_member_object& cm : all_committee_members )
{
update_committee_member_total_votes( cm );
}
}
else
{
for( const committee_member_object& cm : committee_members )
{
update_committee_member_total_votes( cm );
}
}
// Update committee authorities
if( !committee_members.empty() )
{
@ -667,8 +735,8 @@ void database::update_active_sons()
void database::initialize_budget_record( fc::time_point_sec now, budget_record& rec )const
{
const dynamic_global_property_object& dpo = get_dynamic_global_properties();
const asset_object& core = asset_id_type(0)(*this);
const asset_dynamic_data_object& core_dd = core.dynamic_asset_data_id(*this);
const asset_object& core = get_core_asset();
const asset_dynamic_data_object& core_dd = get_core_dynamic_data();
rec.from_initial_reserve = core.reserved(*this);
rec.from_accumulated_fees = core_dd.accumulated_fees;
@ -721,8 +789,7 @@ void database::process_budget()
{
const global_property_object& gpo = get_global_properties();
const dynamic_global_property_object& dpo = get_dynamic_global_properties();
const asset_dynamic_data_object& core =
asset_id_type(0)(*this).dynamic_asset_data_id(*this);
const asset_dynamic_data_object& core = get_core_dynamic_data();
fc::time_point_sec now = head_block_time();
int64_t time_to_maint = (dpo.next_maintenance_time - now).to_seconds();
@ -902,8 +969,7 @@ void split_fba_balance(
if( fba.accumulated_fba_fees == 0 )
return;
const asset_object& core = asset_id_type(0)(db);
const asset_dynamic_data_object& core_dd = core.dynamic_asset_data_id(db);
const asset_dynamic_data_object& core_dd = db.get_core_dynamic_data();
if( !fba.is_configured(db) )
{
@ -1077,6 +1143,154 @@ void deprecate_annual_members( database& db )
return;
}
uint32_t database::get_gpos_current_subperiod()
{
if(this->head_block_time() < HARDFORK_GPOS_TIME) //Can be deleted after GPOS hardfork time
return 0;
fc::time_point_sec last_date_voted;
const auto &gpo = this->get_global_properties();
const auto vesting_period = gpo.parameters.gpos_period();
const auto vesting_subperiod = gpo.parameters.gpos_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();
FC_ASSERT(period_start <= now && now <= period_end);
// get in what sub period we are
uint32_t current_subperiod = 0;
std::list<uint32_t> period_list(number_of_subperiods);
std::iota(period_list.begin(), period_list.end(), 1);
std::for_each(period_list.begin(), period_list.end(),[&](uint32_t period) {
if(seconds_since_period_start >= vesting_subperiod * (period - 1) &&
seconds_since_period_start < vesting_subperiod * period)
current_subperiod = period;
});
return current_subperiod;
}
double database::calculate_vesting_factor(const account_object& stake_account)
{
fc::time_point_sec last_date_voted;
// get last time voted form account stats
// check last_vote_time of proxy voting account if proxy is set
if (stake_account.options.voting_account == GRAPHENE_PROXY_TO_SELF_ACCOUNT)
last_date_voted = stake_account.statistics(*this).last_vote_time;
else
last_date_voted = stake_account.options.voting_account(*this).statistics(*this).last_vote_time;
// get global data related to gpos
const auto &gpo = this->get_global_properties();
const auto vesting_period = gpo.parameters.gpos_period();
const auto vesting_subperiod = gpo.parameters.gpos_subperiod();
const auto period_start = fc::time_point_sec(gpo.parameters.gpos_period_start());
// 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,
// 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
{
if(last_date_voted > period_start - vesting_subperiod)
return 1;
}
if(last_date_voted < period_start) return 0;
double numerator = number_of_subperiods;
if(current_subperiod > 1) {
std::list<uint32_t> subperiod_list(current_subperiod - 1);
std::iota(subperiod_list.begin(), subperiod_list.end(), 2);
subperiod_list.reverse();
for(auto subperiod: subperiod_list)
{
numerator--;
auto last_period_start = period_start + fc::seconds(vesting_subperiod * (subperiod - 1));
auto last_period_end = period_start + fc::seconds(vesting_subperiod * (subperiod));
if (last_date_voted > last_period_start && last_date_voted <= last_period_end) {
numerator++;
break;
}
}
}
vesting_factor = numerator / number_of_subperiods;
return vesting_factor;
}
share_type credit_account(database& db, const account_id_type owner_id, const std::string owner_name,
share_type remaining_amount_to_distribute,
const share_type shares_to_credit, const asset_id_type payout_asset_type,
const pending_dividend_payout_balance_for_holder_object_index& pending_payout_balance_index,
const asset_id_type dividend_id) {
//wdump((delta_balance.value)(holder_balance)(total_balance_of_dividend_asset));
if (shares_to_credit.value) {
remaining_amount_to_distribute -= shares_to_credit;
dlog("Crediting account ${account} with ${amount}",
("account", owner_name)
("amount", asset(shares_to_credit, payout_asset_type)));
auto pending_payout_iter =
pending_payout_balance_index.indices().get<by_dividend_payout_account>().find(
boost::make_tuple(dividend_id, payout_asset_type,
owner_id));
if (pending_payout_iter ==
pending_payout_balance_index.indices().get<by_dividend_payout_account>().end())
db.create<pending_dividend_payout_balance_for_holder_object>(
[&](pending_dividend_payout_balance_for_holder_object &obj) {
obj.owner = owner_id;
obj.dividend_holder_asset_type = dividend_id;
obj.dividend_payout_asset_type = payout_asset_type;
obj.pending_balance = shares_to_credit;
});
else
db.modify(*pending_payout_iter,
[&](pending_dividend_payout_balance_for_holder_object &pending_balance) {
pending_balance.pending_balance += shares_to_credit;
});
}
return remaining_amount_to_distribute;
}
void rolling_period_start(database& db)
{
if(db.head_block_time() >= HARDFORK_GPOS_TIME)
{
auto gpo = db.get_global_properties();
auto period_start = db.get_global_properties().parameters.gpos_period_start();
auto vesting_period = db.get_global_properties().parameters.gpos_period();
auto now = db.head_block_time();
if(now.sec_since_epoch() >= (period_start + vesting_period))
{
// roll
db.modify(db.get_global_properties(), [now](global_property_object& p) {
p.parameters.extensions.value.gpos_period_start = now.sec_since_epoch();
});
}
}
}
// Schedules payouts from a dividend distribution account to the current holders of the
// dividend-paying asset. This takes any deposits made to the dividend distribution account
// since the last time it was called, and distributes them to the current owners of the
@ -1108,34 +1322,42 @@ void schedule_pending_dividend_balances(database& db,
balance_index.indices().get<by_asset_balance>().lower_bound(boost::make_tuple(dividend_holder_asset_obj.id));
auto holder_balances_end =
balance_index.indices().get<by_asset_balance>().upper_bound(boost::make_tuple(dividend_holder_asset_obj.id, share_type()));
uint32_t holder_account_count = std::distance(holder_balances_begin, holder_balances_end);
uint64_t distribution_base_fee = gpo.parameters.current_fees->get<asset_dividend_distribution_operation>().distribution_base_fee;
uint32_t distribution_fee_per_holder = gpo.parameters.current_fees->get<asset_dividend_distribution_operation>().distribution_fee_per_holder;
// the fee, in BTS, for distributing each asset in the account
uint64_t total_fee_per_asset_in_core = distribution_base_fee + holder_account_count * (uint64_t)distribution_fee_per_holder;
std::map<account_id_type, share_type> vesting_amounts;
auto balance_type = vesting_balance_type::normal;
if(db.head_block_time() >= HARDFORK_GPOS_TIME)
balance_type = vesting_balance_type::gpos;
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));
vesting_index.indices().get<by_asset_balance>().lower_bound(boost::make_tuple(dividend_holder_asset_obj.id, balance_type));
auto vesting_balances_end =
vesting_index.indices().get<by_asset_balance>().upper_bound(boost::make_tuple(dividend_holder_asset_obj.id, share_type()));
vesting_index.indices().get<by_asset_balance>().upper_bound(boost::make_tuple(dividend_holder_asset_obj.id, balance_type, share_type()));
for (const vesting_balance_object& vesting_balance_obj : boost::make_iterator_range(vesting_balances_begin, vesting_balances_end))
{
vesting_amounts[vesting_balance_obj.owner] += vesting_balance_obj.balance.amount;
//dlog("Vesting balance for account: ${owner}, amount: ${amount}",
// ("owner", vesting_balance_obj.owner(db).name)
// ("amount", vesting_balance_obj.balance.amount));
++holder_account_count;
dlog("Vesting balance for account: ${owner}, amount: ${amount}",
("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)
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));
@ -1144,6 +1366,12 @@ void schedule_pending_dividend_balances(database& db,
#endif
auto current_distribution_account_balance_iter = current_distribution_account_balance_range.begin();
if(db.head_block_time() < HARDFORK_GPOS_TIME)
holder_account_count = std::distance(holder_balances_begin, holder_balances_end);
// the fee, in BTS, for distributing each asset in the account
uint64_t total_fee_per_asset_in_core = distribution_base_fee + holder_account_count * (uint64_t)distribution_fee_per_holder;
//auto current_distribution_account_balance_iter = current_distribution_account_balance_range.first;
auto previous_distribution_account_balance_iter = previous_distribution_account_balance_range.first;
dlog("Current balances in distribution account: ${current}, Previous balances: ${previous}",
("current", (int64_t)std::distance(current_distribution_account_balance_range.begin(), current_distribution_account_balance_range.end()))
@ -1153,14 +1381,23 @@ void schedule_pending_dividend_balances(database& db,
// accounts other than the distribution account (it would be silly to distribute dividends back to
// the distribution account)
share_type total_balance_of_dividend_asset;
for (const account_balance_object& holder_balance_object : boost::make_iterator_range(holder_balances_begin, holder_balances_end))
if (holder_balance_object.owner != dividend_data.dividend_distribution_account)
{
total_balance_of_dividend_asset += holder_balance_object.balance;
auto itr = vesting_amounts.find(holder_balance_object.owner);
if (itr != vesting_amounts.end())
total_balance_of_dividend_asset += itr->second;
}
if(db.head_block_time() >= HARDFORK_GPOS_TIME && dividend_holder_asset_obj.symbol == GRAPHENE_SYMBOL) { // only core
for (const vesting_balance_object &holder_balance_object : boost::make_iterator_range(vesting_balances_begin,
vesting_balances_end))
if (holder_balance_object.owner != dividend_data.dividend_distribution_account) {
total_balance_of_dividend_asset += holder_balance_object.balance.amount;
}
}
else {
for (const account_balance_object &holder_balance_object : boost::make_iterator_range(holder_balances_begin,
holder_balances_end))
if (holder_balance_object.owner != dividend_data.dividend_distribution_account) {
total_balance_of_dividend_asset += holder_balance_object.balance;
auto itr = vesting_amounts.find(holder_balance_object.owner);
if (itr != vesting_amounts.end())
total_balance_of_dividend_asset += itr->second;
}
}
// loop through all of the assets currently or previously held in the distribution account
while (current_distribution_account_balance_iter != current_distribution_account_balance_range.end() ||
previous_distribution_account_balance_iter != previous_distribution_account_balance_range.second)
@ -1284,46 +1521,68 @@ void schedule_pending_dividend_balances(database& db,
("total", total_balance_of_dividend_asset));
share_type remaining_amount_to_distribute = delta_balance;
// credit each account with their portion, don't send any back to the dividend distribution account
for (const account_balance_object& holder_balance_object : boost::make_iterator_range(holder_balances_begin, holder_balances_end))
{
if (holder_balance_object.owner == dividend_data.dividend_distribution_account) continue;
if(db.head_block_time() >= HARDFORK_GPOS_TIME && dividend_holder_asset_obj.symbol == GRAPHENE_SYMBOL) { // core only
// credit each account with their portion, don't send any back to the dividend distribution account
for (const vesting_balance_object &holder_balance_object : boost::make_iterator_range(
vesting_balances_begin, vesting_balances_end)) {
if (holder_balance_object.owner == dividend_data.dividend_distribution_account) continue;
auto holder_balance = holder_balance_object.balance;
auto vesting_factor = db.calculate_vesting_factor(holder_balance_object.owner(db));
auto itr = vesting_amounts.find(holder_balance_object.owner);
if (itr != vesting_amounts.end())
holder_balance += itr->second;
auto holder_balance = holder_balance_object.balance;
fc::uint128_t amount_to_credit(delta_balance.value);
amount_to_credit *= holder_balance.value;
amount_to_credit /= total_balance_of_dividend_asset.value;
share_type shares_to_credit((int64_t)amount_to_credit.to_uint64());
if (shares_to_credit.value)
{
wdump((delta_balance.value)(holder_balance)(total_balance_of_dividend_asset));
fc::uint128_t amount_to_credit(delta_balance.value);
amount_to_credit *= holder_balance.amount.value;
amount_to_credit /= total_balance_of_dividend_asset.value;
share_type full_shares_to_credit((int64_t) amount_to_credit.to_uint64());
share_type shares_to_credit = (uint64_t) floor(full_shares_to_credit.value * vesting_factor);
remaining_amount_to_distribute -= shares_to_credit;
if (shares_to_credit < full_shares_to_credit) {
// Todo: sending results of decay to committee account, need to change to specified account
dlog("Crediting committee_account with ${amount}",
("amount", asset(full_shares_to_credit - shares_to_credit, payout_asset_type)));
db.adjust_balance(dividend_data.dividend_distribution_account,
-asset(full_shares_to_credit - shares_to_credit, payout_asset_type));
db.adjust_balance(account_id_type(0), asset(full_shares_to_credit - shares_to_credit, payout_asset_type));
}
dlog("Crediting account ${account} with ${amount}",
("account", holder_balance_object.owner(db).name)
("amount", asset(shares_to_credit, payout_asset_type)));
auto pending_payout_iter =
pending_payout_balance_index.indices().get<by_dividend_payout_account>().find(boost::make_tuple(dividend_holder_asset_obj.id, payout_asset_type, holder_balance_object.owner));
if (pending_payout_iter == pending_payout_balance_index.indices().get<by_dividend_payout_account>().end())
db.create<pending_dividend_payout_balance_for_holder_object>( [&]( pending_dividend_payout_balance_for_holder_object& obj ){
obj.owner = holder_balance_object.owner;
obj.dividend_holder_asset_type = dividend_holder_asset_obj.id;
obj.dividend_payout_asset_type = payout_asset_type;
obj.pending_balance = shares_to_credit;
});
else
db.modify(*pending_payout_iter, [&]( pending_dividend_payout_balance_for_holder_object& pending_balance ){
pending_balance.pending_balance += shares_to_credit;
});
remaining_amount_to_distribute = credit_account(db,
holder_balance_object.owner,
holder_balance_object.owner(db).name,
remaining_amount_to_distribute,
shares_to_credit,
payout_asset_type,
pending_payout_balance_index,
dividend_holder_asset_obj.id);
}
}
else {
// credit each account with their portion, don't send any back to the dividend distribution account
for (const account_balance_object &holder_balance_object : boost::make_iterator_range(
holder_balances_begin, holder_balances_end)) {
if (holder_balance_object.owner == dividend_data.dividend_distribution_account) continue;
auto holder_balance = holder_balance_object.balance;
auto itr = vesting_amounts.find(holder_balance_object.owner);
if (itr != vesting_amounts.end())
holder_balance += itr->second;
fc::uint128_t amount_to_credit(delta_balance.value);
amount_to_credit *= holder_balance.value;
amount_to_credit /= total_balance_of_dividend_asset.value;
share_type shares_to_credit((int64_t) amount_to_credit.to_uint64());
remaining_amount_to_distribute = credit_account(db,
holder_balance_object.owner,
holder_balance_object.owner(db).name,
remaining_amount_to_distribute,
shares_to_credit,
payout_asset_type,
pending_payout_balance_index,
dividend_holder_asset_obj.id);
}
}
for (const auto& pending_payout : pending_payout_balance_index.indices())
if (pending_payout.pending_balance.value)
dlog("Pending payout: ${account_name} -> ${amount}",
@ -1611,6 +1870,8 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
process_dividend_assets(*this);
perform_son_tasks(*this);
rolling_period_start(*this);
struct vote_tally_helper {
database& d;
const global_property_object& props;
@ -1625,24 +1886,28 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
d._son_count_histogram_buffer.resize(props.parameters.maximum_son_count / 2 + 1);
d._total_voting_stake = 0;
auto balance_type = vesting_balance_type::normal;
if(d.head_block_time() >= HARDFORK_GPOS_TIME)
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()));
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(), share_type()));
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))
{
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));
dlog("Vesting balance for account: ${owner}, amount: ${amount}",
("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)
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}",
@ -1653,7 +1918,8 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
#endif
}
void operator()(const account_object& stake_account) {
void operator()( const account_object& stake_account, const account_statistics_object& stats )
{
if( props.parameters.count_non_member_votes || stake_account.is_member(d.head_block_time()) )
{
// There may be a difference between the account whose stake is voting and the one specifying opinions.
@ -1670,13 +1936,35 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
const account_object& opinion_account = *opinion_account_ptr;
const auto& stats = stake_account.statistics(d);
uint64_t voting_stake = stats.total_core_in_orders.value
+ (stake_account.cashback_vb.valid() ? (*stake_account.cashback_vb)(d).balance.amount.value: 0)
+ d.get_balance(stake_account.get_id(), asset_id_type()).amount.value;
uint64_t voting_stake = 0;
auto itr = vesting_amounts.find(stake_account.id);
if (itr != vesting_amounts.end())
voting_stake += itr->second.value;
if(d.head_block_time() >= HARDFORK_GPOS_TIME)
{
if (itr == vesting_amounts.end() && d.head_block_time() >= (HARDFORK_GPOS_TIME + props.parameters.gpos_subperiod()/2))
return;
auto vesting_factor = d.calculate_vesting_factor(stake_account);
voting_stake = (uint64_t)floor(voting_stake * vesting_factor);
//Include votes(based on stake) for the period of gpos_subperiod()/2 as system has zero votes on GPOS activation
if(d.head_block_time() < (HARDFORK_GPOS_TIME + props.parameters.gpos_subperiod()/2))
{
voting_stake += stats.total_core_in_orders.value
+ (stake_account.cashback_vb.valid() ? (*stake_account.cashback_vb)(d).balance.amount.value : 0)
+ d.get_balance(stake_account.get_id(), asset_id_type()).amount.value;
}
}
else
{
voting_stake += stats.total_core_in_orders.value
+ (stake_account.cashback_vb.valid() ? (*stake_account.cashback_vb)(d).balance.amount.value : 0)
+ d.get_balance(stake_account.get_id(), asset_id_type()).amount.value;
}
for( vote_id_type id : opinion_account.options.votes )
{
uint32_t offset = id.instance();
@ -1724,23 +2012,8 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
}
}
} tally_helper(*this, gpo);
struct process_fees_helper {
database& d;
const global_property_object& props;
process_fees_helper(database& d, const global_property_object& gpo)
: d(d), props(gpo) {}
void operator()(const account_object& a) {
a.statistics(d).process_fees(a, d);
}
} fee_helper(*this, gpo);
perform_account_maintenance(std::tie(
tally_helper,
fee_helper
));
perform_account_maintenance( tally_helper );
struct clear_canary {
clear_canary(vector<uint64_t>& target): target(target){}
~clear_canary() { target.clear(); }
@ -1758,9 +2031,10 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
update_active_sons();
update_worker_votes();
modify(gpo, [this](global_property_object& p) {
const dynamic_global_property_object& dgpo = get_dynamic_global_properties();
modify(gpo, [&dgpo](global_property_object& p) {
// Remove scaling of account registration fee
const auto& dgpo = get_dynamic_global_properties();
p.parameters.current_fees->get<account_create_operation>().basic_fee >>= p.parameters.account_fee_scale_bitshifts *
(dgpo.accounts_registered_this_interval / p.parameters.accounts_per_fee_scale);
@ -1776,12 +2050,20 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
p.pending_parameters->extensions.value.permitted_betting_odds_increments = p.parameters.extensions.value.permitted_betting_odds_increments;
if( !p.pending_parameters->extensions.value.live_betting_delay_time.valid() )
p.pending_parameters->extensions.value.live_betting_delay_time = p.parameters.extensions.value.live_betting_delay_time;
if( !p.pending_parameters->extensions.value.gpos_period_start.valid() )
p.pending_parameters->extensions.value.gpos_period_start = p.parameters.extensions.value.gpos_period_start;
if( !p.pending_parameters->extensions.value.gpos_period.valid() )
p.pending_parameters->extensions.value.gpos_period = p.parameters.extensions.value.gpos_period;
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.parameters = std::move(*p.pending_parameters);
p.pending_parameters.reset();
}
});
auto next_maintenance_time = get<dynamic_global_property_object>(dynamic_global_property_id_type()).next_maintenance_time;
auto next_maintenance_time = dgpo.next_maintenance_time;
auto maintenance_interval = gpo.parameters.maintenance_interval;
if( next_maintenance_time <= next_block.timestamp )
@ -1811,8 +2093,6 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
}
}
const dynamic_global_property_object& dgpo = get_dynamic_global_properties();
if( (dgpo.next_maintenance_time < HARDFORK_613_TIME) && (next_maintenance_time >= HARDFORK_613_TIME) )
deprecate_annual_members(*this);

View file

@ -24,6 +24,9 @@
#include <graphene/chain/database.hpp>
#include <graphene/chain/chain_property_object.hpp>
#include <graphene/chain/witness_schedule_object.hpp>
#include <graphene/chain/special_authority_object.hpp>
#include <graphene/chain/operation_history_object.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
@ -177,7 +180,7 @@ void database::wipe(const fc::path& data_dir, bool include_blocks)
{
ilog("Wiping database", ("include_blocks", include_blocks));
if (_opened) {
close();
close(false);
}
object_database::wipe(data_dir);
if( include_blocks )
@ -215,6 +218,15 @@ void database::open(
if( !find(global_property_id_type()) )
init_genesis(genesis_loader());
else
{
_p_core_asset_obj = &get( asset_id_type() );
_p_core_dynamic_data_obj = &get( asset_dynamic_data_id_type() );
_p_global_prop_obj = &get( global_property_id_type() );
_p_chain_property_obj = &get( chain_property_id_type() );
_p_dyn_global_prop_obj = &get( dynamic_global_property_id_type() );
_p_witness_schedule_obj = &get( witness_schedule_id_type() );
}
fc::optional<block_id_type> last_block = _block_id_to_block.last_id();
if( last_block.valid() )

View file

@ -426,14 +426,16 @@ bool database::fill_order(const force_settlement_object& settle, const asset& pa
*
* @return true if a margin call was executed.
*/
bool database::check_call_orders(const asset_object& mia, bool enable_black_swan)
bool database::check_call_orders( const asset_object& mia, bool enable_black_swan, bool for_new_limit_order,
const asset_bitasset_data_object* bitasset_ptr )
{ try {
if( !mia.is_market_issued() ) return false;
if( check_for_blackswan( mia, enable_black_swan ) )
const asset_bitasset_data_object& bitasset = ( bitasset_ptr ? *bitasset_ptr : mia.bitasset_data(*this) );
if( check_for_blackswan( mia, enable_black_swan, &bitasset ) )
return false;
const asset_bitasset_data_object& bitasset = mia.bitasset_data(*this);
if( bitasset.is_prediction_market ) return false;
if( bitasset.current_feed.settlement_price.is_null() ) return false;
@ -464,7 +466,12 @@ bool database::check_call_orders(const asset_object& mia, bool enable_black_swan
bool filled_limit = false;
bool margin_called = false;
while( !check_for_blackswan( mia, enable_black_swan ) && call_itr != call_end )
auto head_time = head_block_time();
auto head_num = head_block_num();
bool after_hardfork_436 = ( head_time > HARDFORK_436_TIME );
while( !check_for_blackswan( mia, enable_black_swan, &bitasset ) && call_itr != call_end )
{
bool filled_call = false;
price match_price;
@ -481,7 +488,7 @@ bool database::check_call_orders(const asset_object& mia, bool enable_black_swan
// would be margin called, but there is no matching order #436
bool feed_protected = ( bitasset.current_feed.settlement_price > ~call_itr->call_price );
if( feed_protected && (head_block_time() > HARDFORK_436_TIME) )
if( feed_protected && after_hardfork_436 )
return margin_called;
// would be margin called, but there is no matching order
@ -506,7 +513,8 @@ bool database::check_call_orders(const asset_object& mia, bool enable_black_swan
if( usd_to_buy * match_price > call_itr->get_collateral() )
{
elog( "black swan detected" );
elog( "black swan detected on asset ${symbol} (${id}) at block ${b}",
("id",mia.id)("symbol",mia.symbol)("b",head_num) );
edump((enable_black_swan));
FC_ASSERT( enable_black_swan );
globally_settle_asset(mia, bitasset.current_feed.settlement_price );

View file

@ -33,6 +33,14 @@
#include <graphene/chain/confidential_object.hpp>
#include <graphene/chain/market_object.hpp>
#include <graphene/chain/committee_member_object.hpp>
#include <graphene/chain/exceptions.hpp>
#include <graphene/chain/witness_object.hpp>
#include <graphene/chain/proposal_object.hpp>
#include <graphene/chain/operation_history_object.hpp>
#include <graphene/chain/vesting_balance_object.hpp>
#include <graphene/chain/transaction_object.hpp>
#include <graphene/chain/impacted.hpp>
using namespace fc;
using namespace graphene::chain;
@ -341,13 +349,13 @@ struct get_impacted_account_visitor
}
};
void operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result )
void graphene::chain::operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result )
{
get_impacted_account_visitor vtor = get_impacted_account_visitor( result );
op.visit( vtor );
}
void transaction_get_impacted_accounts( const transaction& tx, flat_set<account_id_type>& result )
void graphene::chain::transaction_get_impacted_accounts( const transaction& tx, flat_set<account_id_type>& result )
{
for( const auto& op : tx.operations )
operation_get_impacted_accounts( op, result );
@ -505,6 +513,16 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
namespace graphene { namespace chain {
void database::notify_applied_block( const signed_block& block )
{
GRAPHENE_TRY_NOTIFY( applied_block, block )
}
void database::notify_on_pending_transaction( const signed_transaction& tx )
{
GRAPHENE_TRY_NOTIFY( on_pending_transaction, tx )
}
void database::notify_changed_objects()
{ try {
if( _undo_db.enabled() )
@ -524,7 +542,7 @@ void database::notify_changed_objects()
get_relevant_accounts(obj, new_accounts_impacted);
}
new_objects(new_ids, new_accounts_impacted);
GRAPHENE_TRY_NOTIFY( new_objects, new_ids, new_accounts_impacted)
}
// Changed
@ -538,7 +556,7 @@ void database::notify_changed_objects()
get_relevant_accounts(item.second.get(), changed_accounts_impacted);
}
changed_objects(changed_ids, changed_accounts_impacted);
GRAPHENE_TRY_NOTIFY( changed_objects, changed_ids, changed_accounts_impacted)
}
// Removed
@ -555,7 +573,7 @@ void database::notify_changed_objects()
get_relevant_accounts(obj, removed_accounts_impacted);
}
removed_objects(removed_ids, removed, removed_accounts_impacted);
GRAPHENE_TRY_NOTIFY( removed_objects, removed_ids, removed, removed_accounts_impacted)
}
}
} FC_CAPTURE_AND_LOG( (0) ) }

View file

@ -45,7 +45,7 @@ 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 = dynamic_global_property_id_type(0)(*this);
const dynamic_global_property_object& _dgp = get_dynamic_global_properties();
const global_property_object& gpo = get_global_properties();
// dynamic global properties updating
@ -121,6 +121,7 @@ void database::update_last_irreversible_block()
const global_property_object& gpo = get_global_properties();
const dynamic_global_property_object& dpo = get_dynamic_global_properties();
// TODO for better performance, move this to db_maint, because only need to do it once per maintenance interval
vector< const witness_object* > wit_objs;
wit_objs.reserve( gpo.active_witnesses.size() );
for( const witness_id_type& wid : gpo.active_witnesses )
@ -238,11 +239,12 @@ void database::clear_expired_proposals()
*
* A black swan occurs if MAX(HB,SP) <= LC
*/
bool database::check_for_blackswan( const asset_object& mia, bool enable_black_swan )
bool database::check_for_blackswan( const asset_object& mia, bool enable_black_swan,
const asset_bitasset_data_object* bitasset_ptr )
{
if( !mia.is_market_issued() ) return false;
const asset_bitasset_data_object& bitasset = mia.bitasset_data(*this);
const asset_bitasset_data_object& bitasset = ( bitasset_ptr ? *bitasset_ptr : mia.bitasset_data(*this) );
if( bitasset.has_settlement() ) return true; // already force settled
auto settle_price = bitasset.current_feed.settlement_price;
if( settle_price.is_null() ) return false; // no feed
@ -467,32 +469,84 @@ void database::clear_expired_orders()
void database::update_expired_feeds()
{
auto& asset_idx = get_index_type<asset_index>().indices().get<by_type>();
auto itr = asset_idx.lower_bound( true /** market issued */ );
while( itr != asset_idx.end() )
{
const asset_object& a = *itr;
++itr;
assert( a.is_market_issued() );
const auto head_time = head_block_time();
bool after_hardfork_615 = ( head_time >= HARDFORK_615_TIME );
const asset_bitasset_data_object& b = a.bitasset_data(*this);
bool feed_is_expired;
if( head_block_time() < HARDFORK_615_TIME )
feed_is_expired = b.feed_is_expired_before_hardfork_615( head_block_time() );
else
feed_is_expired = b.feed_is_expired( head_block_time() );
if( feed_is_expired )
const auto& idx = get_index_type<asset_bitasset_data_index>().indices().get<by_feed_expiration>();
auto itr = idx.begin();
while( itr != idx.end() && itr->feed_is_expired( head_time ) )
{
const asset_bitasset_data_object& b = *itr;
++itr; // not always process begin() because old code skipped updating some assets before hf 615
bool update_cer = false; // for better performance, to only update bitasset once, also check CER in this function
const asset_object* asset_ptr = nullptr;
// update feeds, check margin calls
if( after_hardfork_615 || b.feed_is_expired_before_hardfork_615( head_time ) )
{
modify(b, [this](asset_bitasset_data_object& a) {
a.update_median_feeds(head_block_time());
auto old_median_feed = b.current_feed;
modify( b, [head_time,&update_cer]( asset_bitasset_data_object& abdo )
{
abdo.update_median_feeds( head_time );
if( abdo.need_to_update_cer() )
{
update_cer = true;
abdo.asset_cer_updated = false;
abdo.feed_cer_updated = false;
}
});
check_call_orders(b.current_feed.settlement_price.base.asset_id(*this));
if( !b.current_feed.settlement_price.is_null() && !( b.current_feed == old_median_feed ) ) // `==` check is safe here
{
asset_ptr = &b.asset_id( *this );
check_call_orders( *asset_ptr, true, false, &b );
}
}
if( !b.current_feed.core_exchange_rate.is_null() &&
a.options.core_exchange_rate != b.current_feed.core_exchange_rate )
modify(a, [&b](asset_object& a) {
a.options.core_exchange_rate = b.current_feed.core_exchange_rate;
// update CER
if( update_cer )
{
if( !asset_ptr )
asset_ptr = &b.asset_id( *this );
if( asset_ptr->options.core_exchange_rate != b.current_feed.core_exchange_rate )
{
modify( *asset_ptr, [&b]( asset_object& ao )
{
ao.options.core_exchange_rate = b.current_feed.core_exchange_rate;
});
}
}
} // for each asset whose feed is expired
// process assets affected by bitshares-core issue 453 before hard fork 615
if( !after_hardfork_615 )
{
for( asset_id_type a : _issue_453_affected_assets )
{
check_call_orders( a(*this) );
}
}
}
void database::update_core_exchange_rates()
{
const auto& idx = get_index_type<asset_bitasset_data_index>().indices().get<by_cer_update>();
if( idx.begin() != idx.end() )
{
for( auto itr = idx.rbegin(); itr->need_to_update_cer(); itr = idx.rbegin() )
{
const asset_bitasset_data_object& b = *itr;
const asset_object& a = b.asset_id( *this );
if( a.options.core_exchange_rate != b.current_feed.core_exchange_rate )
{
modify( a, [&b]( asset_object& ao )
{
ao.options.core_exchange_rate = b.current_feed.core_exchange_rate;
});
}
modify( b, []( asset_bitasset_data_object& abdo )
{
abdo.asset_cer_updated = false;
abdo.feed_cer_updated = false;
});
}
}
}

View file

@ -40,14 +40,14 @@ witness_id_type database::get_scheduled_witness( uint32_t slot_num )const
if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SHUFFLED_ALGORITHM)
{
const dynamic_global_property_object& dpo = get_dynamic_global_properties();
const witness_schedule_object& wso = witness_schedule_id_type()(*this);
const witness_schedule_object& wso = get_witness_schedule_object();;
uint64_t current_aslot = dpo.current_aslot + slot_num;
return wso.current_shuffled_witnesses[ current_aslot % wso.current_shuffled_witnesses.size() ];
}
if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM &&
slot_num != 0 )
{
const witness_schedule_object& wso = witness_schedule_id_type()(*this);
const witness_schedule_object& wso = get_witness_schedule_object();
// ask the near scheduler who goes in the given slot
bool slot_is_near = wso.scheduler.get_slot(slot_num-1, wid);
if(! slot_is_near)
@ -156,7 +156,7 @@ uint32_t database::get_slot_at_time(fc::time_point_sec when)const
void database::update_witness_schedule()
{
const witness_schedule_object& wso = witness_schedule_id_type()(*this);
const witness_schedule_object& wso = get_witness_schedule_object();
const global_property_object& gpo = get_global_properties();
if( head_block_num() % gpo.active_witnesses.size() == 0 )
@ -226,7 +226,7 @@ void database::update_son_schedule()
vector<witness_id_type> database::get_near_witness_schedule()const
{
const witness_schedule_object& wso = witness_schedule_id_type()(*this);
const witness_schedule_object& wso = get_witness_schedule_object();
vector<witness_id_type> result;
result.reserve(wso.scheduler.size());
@ -243,7 +243,7 @@ void database::update_witness_schedule(const signed_block& next_block)
{
auto start = fc::time_point::now();
const global_property_object& gpo = get_global_properties();
const witness_schedule_object& wso = get(witness_schedule_id_type());
const witness_schedule_object& wso = get_witness_schedule_object();
uint32_t schedule_needs_filled = gpo.active_witnesses.size();
uint32_t schedule_slot = get_slot_at_time(next_block.timestamp);
@ -395,7 +395,7 @@ uint32_t database::witness_participation_rate()const
}
if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM)
{
const witness_schedule_object& wso = get(witness_schedule_id_type());
const witness_schedule_object& wso = get_witness_schedule_object();
return uint64_t(GRAPHENE_100_PERCENT) * wso.recent_slots_filled.popcount() / 128;
}
return 0;

View file

@ -36,3 +36,72 @@ chain_id_type genesis_state_type::compute_chain_id() const
}
} } // graphene::chain
FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type::initial_account_type, BOOST_PP_SEQ_NIL, (name)(owner_key)(active_key)(is_lifetime_member))
FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type::initial_asset_type, BOOST_PP_SEQ_NIL,
(symbol)(issuer_name)(description)(precision)(max_supply)(accumulated_fees)(is_bitasset)(collateral_records))
FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type::initial_asset_type::initial_collateral_position, BOOST_PP_SEQ_NIL,
(owner)(collateral)(debt))
FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type::initial_balance_type, BOOST_PP_SEQ_NIL,
(owner)(asset_symbol)(amount))
FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type::initial_vesting_balance_type, BOOST_PP_SEQ_NIL,
(owner)(asset_symbol)(amount)(begin_timestamp)(vesting_cliff_seconds)(vesting_duration_seconds)(begin_balance))
FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type::initial_witness_type, BOOST_PP_SEQ_NIL, (owner_name)(block_signing_key))
FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type::initial_committee_member_type, BOOST_PP_SEQ_NIL, (owner_name))
FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type::initial_worker_type, BOOST_PP_SEQ_NIL, (owner_name)(daily_pay))
FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type::initial_bts_account_type::initial_authority, BOOST_PP_SEQ_NIL,
(weight_threshold)
(account_auths)
(key_auths)
(address_auths))
FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type::initial_bts_account_type::initial_cdd_vesting_policy, BOOST_PP_SEQ_NIL,
(vesting_seconds)
(coin_seconds_earned)
(start_claim)
(coin_seconds_earned_last_update))
FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type::initial_bts_account_type::initial_linear_vesting_policy, BOOST_PP_SEQ_NIL,
(begin_timestamp)
(vesting_cliff_seconds)
(vesting_duration_seconds)
(begin_balance))
FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type::initial_bts_account_type::initial_vesting_balance, BOOST_PP_SEQ_NIL,
(asset_symbol)
(amount)
(policy_type)
(policy))
FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type::initial_bts_account_type, BOOST_PP_SEQ_NIL,
(name)
(owner_authority)
(active_authority)
(core_balance)
(vesting_balances))
FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type, BOOST_PP_SEQ_NIL,
(initial_timestamp)(max_core_supply)(initial_parameters)(initial_bts_accounts)(initial_accounts)(initial_assets)(initial_balances)
(initial_vesting_balances)(initial_active_witnesses)(initial_witness_candidates)
(initial_committee_candidates)(initial_worker_candidates)
(initial_chain_id)
(immutable_parameters))
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::genesis_state_type::initial_account_type)
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::genesis_state_type::initial_asset_type)
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::genesis_state_type::initial_asset_type::initial_collateral_position)
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::genesis_state_type::initial_balance_type)
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::genesis_state_type::initial_vesting_balance_type)
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::genesis_state_type::initial_witness_type)
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::genesis_state_type::initial_committee_member_type)
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::genesis_state_type::initial_worker_type)
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::genesis_state_type::initial_bts_account_type::initial_authority)
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::genesis_state_type::initial_bts_account_type::initial_cdd_vesting_policy)
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::genesis_state_type::initial_bts_account_type::initial_linear_vesting_policy)
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::genesis_state_type::initial_bts_account_type::initial_vesting_balance)
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::genesis_state_type::initial_bts_account_type)
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::genesis_state_type)

View file

@ -0,0 +1,4 @@
// GPOS HARDFORK Monday, 31 Dec 2019 00:00:00 GMT
#ifndef HARDFORK_GPOS_TIME
#define HARDFORK_GPOS_TIME (fc::time_point_sec( 1577750400 ))
#endif

View file

@ -22,8 +22,9 @@
* THE SOFTWARE.
*/
#pragma once
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/chain/protocol/types.hpp>
#include <graphene/db/generic_index.hpp>
#include <graphene/chain/protocol/account.hpp>
#include <boost/multi_index/composite_key.hpp>
namespace graphene { namespace chain {
@ -46,6 +47,8 @@ namespace graphene { namespace chain {
account_id_type owner;
string name; ///< redundantly store account name here for better maintenance performance
/**
* Keep the most recent operation as a root pointer to a linked list of the transaction history.
*/
@ -62,6 +65,19 @@ namespace graphene { namespace chain {
*/
share_type total_core_in_orders;
share_type core_in_balance = 0; ///< redundantly store core balance here for better maintenance performance
bool has_cashback_vb = false; ///< redundantly store this for better maintenance performance
bool is_voting = false; ///< redundately store whether this account is voting for better maintenance performance
/// Whether this account owns some CORE asset and is voting
inline bool has_some_core_voting() const
{
return is_voting && ( total_core_in_orders > 0 || core_in_balance > 0 || has_cashback_vb );
}
/**
* Tracks the total fees paid by this account for the purpose of calculating bulk discounts.
*/
@ -87,6 +103,12 @@ namespace graphene { namespace chain {
*/
time_point_sec last_vote_time;
/// Whether this account has pending fees, no matter vested or not
inline bool has_pending_fees() const { return pending_fees > 0 || pending_vested_fees > 0; }
/// Whether need to process this account during the maintenance interval
inline bool need_maintenance() const { return has_some_core_voting() || has_pending_fees(); }
/// @brief Split up and pay out @ref pending_fees and @ref pending_vested_fees
void process_fees(const account_object& a, database& d) const;
@ -112,6 +134,7 @@ namespace graphene { namespace chain {
account_id_type owner;
asset_id_type asset_type;
share_type balance;
bool maintenance_flag = false; ///< Whether need to process this balance object in maintenance interval
asset get_balance()const { return asset(balance, asset_type); }
void adjust_balance(const asset& delta);
@ -388,6 +411,9 @@ namespace graphene { namespace chain {
};
struct by_asset_balance;
struct by_maintenance_flag;
struct by_account_asset;
/**
* @ingroup object_index
*/
@ -395,6 +421,15 @@ namespace graphene { namespace chain {
account_balance_object,
indexed_by<
ordered_unique< tag<by_id>, member< object, object_id_type, &object::id > >,
ordered_non_unique< tag<by_maintenance_flag>,
member< account_balance_object, bool, &account_balance_object::maintenance_flag > >,
ordered_unique< tag<by_account_asset>,
composite_key<
account_balance_object,
member<account_balance_object, account_id_type, &account_balance_object::owner>,
member<account_balance_object, asset_id_type, &account_balance_object::asset_type>
>
>,
ordered_unique< tag<by_asset_balance>,
composite_key<
account_balance_object,
@ -434,26 +469,6 @@ namespace graphene { namespace chain {
*/
typedef generic_index<account_object, account_multi_index_type> account_index;
struct by_owner;
struct by_maintenance_seq;
/**
* @ingroup object_index
*/
typedef multi_index_container<
account_statistics_object,
indexed_by<
ordered_unique< tag<by_id>, member< object, object_id_type, &object::id > >,
ordered_unique< tag<by_owner>,
member< account_statistics_object, account_id_type, &account_statistics_object::owner > >
>
> account_stats_multi_index_type;
/**
* @ingroup object_index
*/
typedef generic_index<account_statistics_object, account_stats_multi_index_type> account_stats_index;
struct by_dividend_payout_account{}; // use when calculating pending payouts
struct by_dividend_account_payout{}; // use when doing actual payouts
struct by_account_dividend_payout{}; // use in get_full_accounts()
@ -497,6 +512,33 @@ namespace graphene { namespace chain {
*/
typedef generic_index<pending_dividend_payout_balance_for_holder_object, pending_dividend_payout_balance_for_holder_object_multi_index_type> pending_dividend_payout_balance_for_holder_object_index;
struct by_owner;
struct by_maintenance_seq;
/**
* @ingroup object_index
*/
typedef multi_index_container<
account_statistics_object,
indexed_by<
ordered_unique< tag<by_id>, member< object, object_id_type, &object::id > >,
ordered_unique< tag<by_owner>,
member< account_statistics_object, account_id_type, &account_statistics_object::owner > >,
ordered_unique< tag<by_maintenance_seq>,
composite_key<
account_statistics_object,
const_mem_fun<account_statistics_object, bool, &account_statistics_object::need_maintenance>,
member<account_statistics_object, string, &account_statistics_object::name>
>
>
>
> account_stats_multi_index_type;
/**
* @ingroup object_index
*/
typedef generic_index<account_statistics_object, account_stats_multi_index_type> account_stats_index;
}}
FC_REFLECT_DERIVED( graphene::chain::account_object,
@ -513,14 +555,17 @@ FC_REFLECT_DERIVED( graphene::chain::account_object,
FC_REFLECT_DERIVED( graphene::chain::account_balance_object,
(graphene::db::object),
(owner)(asset_type)(balance) )
(owner)(asset_type)(balance)(maintenance_flag) )
FC_REFLECT_DERIVED( graphene::chain::account_statistics_object,
(graphene::chain::object),
(owner)
(owner)(name)
(most_recent_op)
(total_ops)(removed_ops)
(total_core_in_orders)
(core_in_balance)
(has_cashback_vb)
(is_voting)
(lifetime_fees_paid)
(pending_fees)(pending_vested_fees)
(last_vote_time)
@ -530,4 +575,7 @@ FC_REFLECT_DERIVED( graphene::chain::pending_dividend_payout_balance_for_holder_
(graphene::db::object),
(owner)(dividend_holder_asset_type)(dividend_payout_asset_type)(pending_balance) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::account_object )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::account_balance_object )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::account_statistics_object )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::pending_dividend_payout_balance_for_holder_object )

View file

@ -22,10 +22,11 @@
* THE SOFTWARE.
*/
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/db/generic_index.hpp>
#include <graphene/db/flat_index.hpp>
#include <graphene/chain/protocol/asset_ops.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <graphene/db/flat_index.hpp>
#include <graphene/db/generic_index.hpp>
/**
* @defgroup prediction_market Prediction Market
@ -38,11 +39,10 @@
*/
namespace graphene { namespace chain {
class account_object;
class database;
class transaction_evaluation_state;
using namespace graphene::db;
/**
* @brief tracks the asset information that changes frequently
* @ingroup object
@ -118,9 +118,9 @@ namespace graphene { namespace chain {
/// Convert an asset to a textual representation with symbol, i.e. "123.45 USD"
string amount_to_pretty_string(const asset &amount)const
{ FC_ASSERT(amount.asset_id == id); return amount_to_pretty_string(amount.amount); }
uint32_t get_issuer_num()const
{ return issuer.instance.value; }
{ return issuer.instance.value; }
/// Ticker symbol for this asset, i.e. "USD"
string symbol;
/// Maximum number of digits after the decimal point (must be <= 12)
@ -138,7 +138,7 @@ namespace graphene { namespace chain {
map< account_id_type, vector< uint16_t > > distribute_winners_part( database& db );
void distribute_sweeps_holders_part( database& db );
void end_lottery( database& db );
/// Current supply, fee pool, and collected fees are stored in a separate object as they change frequently.
asset_dynamic_data_id_type dynamic_asset_data_id;
/// Extra data associated with BitAssets. This field is non-null if and only if is_market_issued() returns true
@ -150,7 +150,7 @@ namespace graphene { namespace chain {
optional<asset_dividend_data_id_type> dividend_data_id;
asset_id_type get_id()const { return id; }
void validate()const
{
// UIAs may not be prediction markets, have force settlement, or global settlements
@ -174,7 +174,7 @@ namespace graphene { namespace chain {
{ return db.get(dynamic_asset_data_id); }
/**
* The total amount of an asset that is reserved for future issuance.
* The total amount of an asset that is reserved for future issuance.
*/
template<class DB>
share_type reserved( const DB& db )const
@ -193,6 +193,9 @@ namespace graphene { namespace chain {
static const uint8_t space_id = implementation_ids;
static const uint8_t type_id = impl_asset_bitasset_data_type;
/// The asset this object belong to
asset_id_type asset_id;
/// The tunable options for BitAssets are stored in this field.
bitasset_options options;
@ -230,6 +233,18 @@ namespace graphene { namespace chain {
share_type settlement_fund;
///@}
/// Track whether core_exchange_rate in corresponding asset_object has updated
bool asset_cer_updated = false;
/// Track whether core exchange rate in current feed has updated
bool feed_cer_updated = false;
/// Whether need to update core_exchange_rate in asset_object
bool need_to_update_cer() const
{
return ( ( feed_cer_updated || asset_cer_updated ) && !current_feed.core_exchange_rate.is_null() );
}
/// The time when @ref current_feed would expire
time_point_sec feed_expiration_time()const
{
@ -239,7 +254,7 @@ namespace graphene { namespace chain {
else
return current_feed_publication_time + options.feed_lifetime_sec;
}
bool feed_is_expired_before_hardfork_615(time_point_sec current_time)const
{ return feed_expiration_time() >= current_time; }
bool feed_is_expired(time_point_sec current_time)const
@ -247,14 +262,34 @@ namespace graphene { namespace chain {
void update_median_feeds(time_point_sec current_time);
};
// key extractor for short backing asset
struct bitasset_short_backing_asset_extractor
{
typedef asset_id_type result_type;
result_type operator() (const asset_bitasset_data_object& obj) const
{
return obj.options.short_backing_asset;
}
};
struct by_short_backing_asset;
struct by_feed_expiration;
struct by_cer_update;
typedef multi_index_container<
asset_bitasset_data_object,
indexed_by<
ordered_unique< tag<by_id>, member< object, object_id_type, &object::id > >,
ordered_non_unique< tag<by_feed_expiration>,
const_mem_fun< asset_bitasset_data_object, time_point_sec, &asset_bitasset_data_object::feed_expiration_time >
>
ordered_unique< tag<by_id>, member< object, object_id_type, &object::id > >,
ordered_non_unique< tag<by_short_backing_asset>, bitasset_short_backing_asset_extractor >,
ordered_unique< tag<by_feed_expiration>,
composite_key< asset_bitasset_data_object,
const_mem_fun< asset_bitasset_data_object, time_point_sec, &asset_bitasset_data_object::feed_expiration_time >,
member< asset_bitasset_data_object, asset_id_type, &asset_bitasset_data_object::asset_id >
>
>,
ordered_non_unique< tag<by_cer_update>,
const_mem_fun< asset_bitasset_data_object, bool, &asset_bitasset_data_object::need_to_update_cer >
>
>
> asset_bitasset_data_object_multi_index_type;
//typedef flat_index<asset_bitasset_data_object> asset_bitasset_data_index;
@ -343,7 +378,7 @@ namespace graphene { namespace chain {
/// This field is reset any time the dividend_asset_options are updated
fc::optional<time_point_sec> last_scheduled_payout_time;
/// The time payouts on this asset were last processed
/// The time payouts on this asset were last processed
/// (this should be the maintenance interval at or after last_scheduled_payout_time)
/// This can be displayed for the user
fc::optional<time_point_sec> last_payout_time;
@ -370,7 +405,7 @@ namespace graphene { namespace chain {
typedef generic_index<asset_dividend_data_object, asset_dividend_data_object_multi_index_type> asset_dividend_data_object_index;
// This tracks the balances in a dividend distribution account at the last time
// This tracks the balances in a dividend distribution account at the last time
// pending dividend payouts were calculated (last maintenance interval).
// At each maintenance interval, we will compare the current balance to the
// balance stored here to see how much was deposited during that interval.
@ -399,9 +434,9 @@ namespace graphene { namespace chain {
>
> total_distributed_dividend_balance_object_multi_index_type;
typedef generic_index<total_distributed_dividend_balance_object, total_distributed_dividend_balance_object_multi_index_type> total_distributed_dividend_balance_object_index;
/**
* @ingroup object
*/
@ -410,17 +445,17 @@ namespace graphene { namespace chain {
public:
static const uint8_t space_id = implementation_ids;
static const uint8_t type_id = impl_lottery_balance_object_type;
asset_id_type lottery_id;
asset balance;
asset get_balance()const { return balance; }
void adjust_balance(const asset& delta);
};
struct by_owner;
/**
* @ingroup object_index
*/
@ -433,13 +468,13 @@ namespace graphene { namespace chain {
>
>
> lottery_balance_index_type;
/**
* @ingroup object_index
*/
typedef generic_index<lottery_balance_object, lottery_balance_index_type> lottery_balance_index;
class sweeps_vesting_balance_object : public abstract_object<sweeps_vesting_balance_object>
{
public:
@ -451,7 +486,7 @@ namespace graphene { namespace chain {
uint64_t balance;
asset_id_type asset_id;
time_point_sec last_claim_date;
uint64_t get_balance()const { return balance; }
void adjust_balance(const asset& delta);
asset available_for_claim() const { return asset( balance / SWEEPS_VESTING_BALANCE_MULTIPLIER , asset_id ); }
@ -481,6 +516,7 @@ FC_REFLECT_DERIVED( graphene::chain::asset_dynamic_data_object, (graphene::db::o
(current_supply)(sweeps_tickets_sold)(confidential_supply)(accumulated_fees)(fee_pool) )
FC_REFLECT_DERIVED( graphene::chain::asset_bitasset_data_object, (graphene::db::object),
(asset_id)
(feeds)
(current_feed)
(current_feed_publication_time)
@ -489,11 +525,13 @@ FC_REFLECT_DERIVED( graphene::chain::asset_bitasset_data_object, (graphene::db::
(is_prediction_market)
(settlement_price)
(settlement_fund)
(asset_cer_updated)
(feed_cer_updated)
)
FC_REFLECT_DERIVED( graphene::chain::asset_dividend_data_object, (graphene::db::object),
(options)
(last_scheduled_payout_time)
(last_scheduled_payout_time)
(last_payout_time )
(last_scheduled_distribution_time)
(last_distribution_time)
@ -523,3 +561,13 @@ FC_REFLECT_DERIVED( graphene::chain::lottery_balance_object, (graphene::db::obje
FC_REFLECT_DERIVED( graphene::chain::sweeps_vesting_balance_object, (graphene::db::object),
(owner)(balance)(asset_id)(last_claim_date) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_dynamic_data_object )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_bitasset_data_object )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_dividend_data_object )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::total_distributed_dividend_balance_object )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_object )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::lottery_balance_object )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::sweeps_vesting_balance_object )

View file

@ -73,3 +73,5 @@ namespace graphene { namespace chain {
FC_REFLECT_DERIVED( graphene::chain::balance_object, (graphene::db::object),
(owner)(balance)(vesting_policy)(last_claim_date) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::balance_object )

View file

@ -25,6 +25,8 @@
#include <fstream>
#include <graphene/chain/protocol/block.hpp>
#include <fc/filesystem.hpp>
namespace graphene { namespace chain {
class index_entry;

View file

@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/db/object.hpp>
namespace graphene { namespace chain {
@ -47,4 +48,7 @@ namespace graphene { namespace chain {
} }
FC_REFLECT_DERIVED( graphene::chain::block_summary_object, (graphene::db::object), (block_id) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::block_summary_object )

View file

@ -23,7 +23,6 @@
*/
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
namespace graphene { namespace chain {
@ -56,8 +55,6 @@ struct budget_record
share_type supply_delta = 0;
};
class budget_record_object;
class budget_record_object : public graphene::db::abstract_object<budget_record_object>
{
public:
@ -70,8 +67,7 @@ class budget_record_object : public graphene::db::abstract_object<budget_record_
} }
FC_REFLECT(
graphene::chain::budget_record,
FC_REFLECT(graphene::chain::budget_record,
(time_since_last_budget)
(from_initial_reserve)
(from_accumulated_fees)
@ -84,9 +80,8 @@ FC_REFLECT(
(supply_delta)
)
FC_REFLECT_DERIVED(
graphene::chain::budget_record_object,
(graphene::db::object),
(time)
(record)
)
FC_REFLECT_DERIVED(graphene::chain::budget_record_object,
(graphene::db::object), (time)(record) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::budget_record )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::budget_record_object )

View file

@ -65,3 +65,5 @@ typedef generic_index< buyback_object, buyback_multi_index_type > buyback_index;
} } // graphene::chain
FC_REFLECT_DERIVED( graphene::chain::buyback_object, (graphene::db::object), (asset_to_buy) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::buyback_object )

View file

@ -27,8 +27,6 @@
namespace graphene { namespace chain {
class chain_property_object;
/**
* Contains invariants which are set at genesis and never changed.
*/
@ -48,3 +46,5 @@ FC_REFLECT_DERIVED( graphene::chain::chain_property_object, (graphene::db::objec
(chain_id)
(immutable_parameters)
)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::chain_property_object )

View file

@ -29,8 +29,6 @@
namespace graphene { namespace chain {
using namespace graphene::db;
class account_object;
/**
* @brief tracks information about a committee_member account.
* @ingroup object
@ -73,5 +71,8 @@ namespace graphene { namespace chain {
using committee_member_index = generic_index<committee_member_object, committee_member_multi_index_type>;
} } // graphene::chain
FC_REFLECT_DERIVED( graphene::chain::committee_member_object, (graphene::db::object),
(committee_member_account)(vote_id)(total_votes)(url) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::committee_member_object )

View file

@ -26,7 +26,6 @@
#include <graphene/chain/protocol/authority.hpp>
#include <graphene/chain/protocol/types.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
#include <fc/crypto/elliptic.hpp>
@ -50,8 +49,6 @@ class blinded_balance_object : public graphene::db::abstract_object<blinded_bala
authority owner;
};
struct by_asset;
struct by_owner;
struct by_commitment;
/**
@ -68,4 +65,8 @@ typedef generic_index<blinded_balance_object, blinded_balance_object_multi_index
} } // graphene::chain
FC_REFLECT_DERIVED( graphene::chain::blinded_balance_object, (graphene::db::object), (commitment)(asset_id)(owner) )
FC_REFLECT_DERIVED( graphene::chain::blinded_balance_object, (graphene::db::object),
(commitment)(asset_id)(owner) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::blinded_balance_object )

View file

@ -153,7 +153,7 @@
#define GRAPHENE_RECENTLY_MISSED_COUNT_INCREMENT 4
#define GRAPHENE_RECENTLY_MISSED_COUNT_DECREMENT 3
#define GRAPHENE_CURRENT_DB_VERSION "PPY2.2"
#define GRAPHENE_CURRENT_DB_VERSION "PPY2.3"
#define GRAPHENE_IRREVERSIBLE_THRESHOLD (70 * GRAPHENE_1_PERCENT)
@ -241,3 +241,6 @@
#define SWEEPS_DEFAULT_DISTRIBUTION_ASSET (graphene::chain::asset_id_type(0))
#define SWEEPS_VESTING_BALANCE_MULTIPLIER 100000000
#define SWEEPS_ACCUMULATOR_ACCOUNT (graphene::chain::account_id_type(0))
#define GPOS_PERIOD (60*60*24*30*6) // 6 months
#define GPOS_SUBPERIOD (60*60*24*30) // 1 month
#define GPOS_VESTING_LOCKIN_PERIOD (60*60*24*30) // 1 month

View file

@ -291,11 +291,13 @@ namespace graphene { namespace chain {
const chain_id_type& get_chain_id()const;
const asset_object& get_core_asset()const;
const asset_dynamic_data_object& get_core_dynamic_data()const;
const chain_property_object& get_chain_properties()const;
const global_property_object& get_global_properties()const;
const dynamic_global_property_object& get_dynamic_global_properties()const;
const node_property_object& get_node_properties()const;
const fee_schedule& current_fee_schedule()const;
const account_statistics_object& get_account_stats_by_owner( account_id_type owner )const;
const std::vector<uint32_t> get_winner_numbers( asset_id_type for_asset, uint32_t count_members, uint8_t count_winners ) const;
std::vector<uint32_t> get_seeds( asset_id_type for_asset, uint8_t count_winners )const;
uint64_t get_random_bits( uint64_t bound );
@ -305,6 +307,7 @@ namespace graphene { namespace chain {
fc::optional<operation> create_son_deregister_proposal( son_id_type son_id, account_id_type paying_son );
signed_transaction create_signed_transaction( const fc::ecc::private_key& signing_private_key, const operation& op );
bool is_son_dereg_valid( son_id_type son_id );
const witness_schedule_object& get_witness_schedule_object()const;
time_point_sec head_block_time()const;
uint32_t head_block_num()const;
@ -462,7 +465,8 @@ namespace graphene { namespace chain {
bool fill_order( const call_order_object& order, const asset& pays, const asset& receives );
bool fill_order( const force_settlement_object& settle, const asset& pays, const asset& receives );
bool check_call_orders( const asset_object& mia, bool enable_black_swan = true );
bool check_call_orders( const asset_object& mia, bool enable_black_swan = true, bool for_new_limit_order = false,
const asset_bitasset_data_object* bitasset_ptr = nullptr );
// helpers to fill_order
void pay_order( const account_object& receiver, const asset& receives, const asset& pays );
@ -471,7 +475,7 @@ namespace graphene { namespace chain {
asset pay_market_fees( const asset_object& recv_asset, const asset& receives );
///@}
///@{
/**
* This method validates transactions without adding it to the pending state.
* @return true if the transaction would validate
@ -486,9 +490,13 @@ namespace graphene { namespace chain {
/**
* @}
*/
/// Enable or disable tracking of votes of standby witnesses and committee members
inline void enable_standby_votes_tracking(bool enable) { _track_standby_votes = enable; }
protected:
//Mark pop_undo() as protected -- we do not want outside calling pop_undo(); it should call pop_block() instead
void pop_undo() { object_database::pop_undo(); }
void notify_applied_block( const signed_block& block );
void notify_on_pending_transaction( const signed_transaction& tx );
void notify_changed_objects();
private:
@ -514,6 +522,8 @@ namespace graphene { namespace chain {
const witness_object& validate_block_header( uint32_t skip, const signed_block& next_block )const;
const witness_object& _validate_block_header( const signed_block& next_block )const;
void verify_signing_witness( const signed_block& new_block, const fork_item& fork_entry )const;
void update_witnesses( fork_item& fork_entry )const;
void create_block_summary(const signed_block& next_block);
//////////////////// db_witness_schedule.cpp ////////////////////
@ -528,11 +538,13 @@ namespace graphene { namespace chain {
void clear_expired_proposals();
void clear_expired_orders();
void update_expired_feeds();
void update_core_exchange_rates();
void update_maintenance_flag( bool new_maintenance_flag );
void update_withdraw_permissions();
void update_tournaments();
void update_betting_markets(fc::time_point_sec current_block_time);
bool check_for_blackswan( const asset_object& mia, bool enable_black_swan = true );
bool check_for_blackswan( const asset_object& mia, bool enable_black_swan = true,
const asset_bitasset_data_object* bitasset_ptr = nullptr );
///Steps performed only at maintenance intervals
///@{
@ -554,9 +566,13 @@ namespace graphene { namespace chain {
void update_son_statuses( const vector<son_info>& cur_active_sons, const vector<son_info>& new_active_sons );
void update_son_wallet( const vector<son_info>& new_active_sons );
void update_worker_votes();
template<class... Types>
void perform_account_maintenance(std::tuple<Types...> helpers);
public:
double calculate_vesting_factor(const account_object& stake_account);
uint32_t get_gpos_current_subperiod();
template<class Type>
void perform_account_maintenance(Type tally_helper);
///@}
///@}
@ -596,6 +612,11 @@ namespace graphene { namespace chain {
flat_map<uint32_t,block_id_type> _checkpoints;
node_property_object _node_property_object;
/// Whether to update votes of standby witnesses and committee members when performing chain maintenance.
/// Set it to true to provide accurate data to API clients, set to false to have better performance.
bool _track_standby_votes = true;
fc::hash_ctr_rng<secret_hash_type, 20> _random_number_generator;
bool _slow_replays = false;
@ -614,6 +635,18 @@ namespace graphene { namespace chain {
void initialize_db_sidechain();
protected:
private:
/// Tracks assets affected by bitshares-core issue #453 before hard fork #615 in one block
flat_set<asset_id_type> _issue_453_affected_assets;
/// Pointers to core asset object and global objects who will have immutable addresses after created
///@{
const asset_object* _p_core_asset_obj = nullptr;
const asset_dynamic_data_object* _p_core_dynamic_data_obj = nullptr;
const global_property_object* _p_global_prop_obj = nullptr;
const dynamic_global_property_object* _p_dyn_global_prop_obj = nullptr;
const chain_property_object* _p_chain_property_obj = nullptr;
const witness_schedule_object* _p_witness_schedule_obj = nullptr;
///@}
};
namespace detail

View file

@ -65,6 +65,21 @@
msg \
)
#define GRAPHENE_TRY_NOTIFY( signal, ... ) \
try \
{ \
signal( __VA_ARGS__ ); \
} \
catch( const graphene::chain::plugin_exception& e ) \
{ \
elog( "Caught plugin exception: ${e}", ("e", e.to_detail_string() ) ); \
throw; \
} \
catch( ... ) \
{ \
wlog( "Caught unexpected exception in plugin" ); \
}
namespace graphene { namespace chain {
FC_DECLARE_EXCEPTION( chain_exception, 3000000, "blockchain exception" )
@ -77,6 +92,7 @@ namespace graphene { namespace chain {
FC_DECLARE_DERIVED_EXCEPTION( undo_database_exception, graphene::chain::chain_exception, 3070000, "undo database exception" )
FC_DECLARE_DERIVED_EXCEPTION( unlinkable_block_exception, graphene::chain::chain_exception, 3080000, "unlinkable block" )
FC_DECLARE_DERIVED_EXCEPTION( black_swan_exception, graphene::chain::chain_exception, 3090000, "black swan" )
FC_DECLARE_DERIVED_EXCEPTION( plugin_exception, graphene::chain::chain_exception, 3100000, "plugin exception" )
FC_DECLARE_DERIVED_EXCEPTION( tx_missing_active_auth, graphene::chain::transaction_exception, 3030001, "missing required active authority" )
FC_DECLARE_DERIVED_EXCEPTION( tx_missing_owner_auth, graphene::chain::transaction_exception, 3030002, "missing required owner authority" )

View file

@ -49,4 +49,7 @@ class fba_accumulator_object : public graphene::db::abstract_object< fba_accumul
} } // graphene::chain
FC_REFLECT_DERIVED( graphene::chain::fba_accumulator_object, (graphene::db::object), (accumulated_fba_fees)(designated_asset) )
FC_REFLECT_DERIVED( graphene::chain::fba_accumulator_object, (graphene::db::object),
(accumulated_fba_fees)(designated_asset) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::fba_accumulator_object )

View file

@ -51,6 +51,11 @@ namespace graphene { namespace chain {
bool invalid = false;
block_id_type id;
signed_block data;
// contains witness block signing keys scheduled *after* the block has been applied
shared_ptr< vector< pair< witness_id_type, public_key_type > > > scheduled_witnesses;
uint64_t next_block_aslot = 0;
fc::time_point_sec next_block_time;
};
typedef shared_ptr<fork_item> item_ptr;

View file

@ -23,6 +23,7 @@
*/
#pragma once
#include <graphene/chain/protocol/address.hpp>
#include <graphene/chain/protocol/chain_parameters.hpp>
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/immutable_chain_parameters.hpp>
@ -169,56 +170,32 @@ struct genesis_state_type {
} } // namespace graphene::chain
FC_REFLECT(graphene::chain::genesis_state_type::initial_account_type, (name)(owner_key)(active_key)(is_lifetime_member))
FC_REFLECT_TYPENAME(graphene::chain::genesis_state_type::initial_account_type)
FC_REFLECT_TYPENAME(graphene::chain::genesis_state_type::initial_asset_type)
FC_REFLECT_TYPENAME(graphene::chain::genesis_state_type::initial_asset_type::initial_collateral_position)
FC_REFLECT_TYPENAME(graphene::chain::genesis_state_type::initial_balance_type)
FC_REFLECT_TYPENAME(graphene::chain::genesis_state_type::initial_vesting_balance_type)
FC_REFLECT_TYPENAME(graphene::chain::genesis_state_type::initial_witness_type)
FC_REFLECT_TYPENAME(graphene::chain::genesis_state_type::initial_committee_member_type)
FC_REFLECT_TYPENAME(graphene::chain::genesis_state_type::initial_worker_type)
FC_REFLECT_TYPENAME(graphene::chain::genesis_state_type::initial_bts_account_type::initial_authority)
FC_REFLECT_TYPENAME(graphene::chain::genesis_state_type::initial_bts_account_type::initial_cdd_vesting_policy)
FC_REFLECT_TYPENAME(graphene::chain::genesis_state_type::initial_bts_account_type::initial_linear_vesting_policy)
FC_REFLECT_TYPENAME(graphene::chain::genesis_state_type::initial_bts_account_type::initial_vesting_balance)
FC_REFLECT_TYPENAME(graphene::chain::genesis_state_type::initial_bts_account_type)
FC_REFLECT_TYPENAME(graphene::chain::genesis_state_type)
FC_REFLECT(graphene::chain::genesis_state_type::initial_asset_type,
(symbol)(issuer_name)(description)(precision)(max_supply)(accumulated_fees)(is_bitasset)(collateral_records))
FC_REFLECT(graphene::chain::genesis_state_type::initial_asset_type::initial_collateral_position,
(owner)(collateral)(debt))
FC_REFLECT(graphene::chain::genesis_state_type::initial_balance_type,
(owner)(asset_symbol)(amount))
FC_REFLECT(graphene::chain::genesis_state_type::initial_vesting_balance_type,
(owner)(asset_symbol)(amount)(begin_timestamp)(vesting_cliff_seconds)(vesting_duration_seconds)(begin_balance))
FC_REFLECT(graphene::chain::genesis_state_type::initial_witness_type, (owner_name)(block_signing_key))
FC_REFLECT(graphene::chain::genesis_state_type::initial_committee_member_type, (owner_name))
FC_REFLECT(graphene::chain::genesis_state_type::initial_worker_type, (owner_name)(daily_pay))
FC_REFLECT(graphene::chain::genesis_state_type::initial_bts_account_type::initial_authority,
(weight_threshold)
(account_auths)
(key_auths)
(address_auths))
FC_REFLECT(graphene::chain::genesis_state_type::initial_bts_account_type::initial_cdd_vesting_policy,
(vesting_seconds)
(coin_seconds_earned)
(start_claim)
(coin_seconds_earned_last_update))
FC_REFLECT(graphene::chain::genesis_state_type::initial_bts_account_type::initial_linear_vesting_policy,
(begin_timestamp)
(vesting_cliff_seconds)
(vesting_duration_seconds)
(begin_balance))
FC_REFLECT(graphene::chain::genesis_state_type::initial_bts_account_type::initial_vesting_balance,
(asset_symbol)
(amount)
(policy_type)
(policy))
FC_REFLECT(graphene::chain::genesis_state_type::initial_bts_account_type,
(name)
(owner_authority)
(active_authority)
(core_balance)
(vesting_balances))
FC_REFLECT(graphene::chain::genesis_state_type,
(initial_timestamp)(max_core_supply)(initial_parameters)(initial_bts_accounts)(initial_accounts)(initial_assets)(initial_balances)
(initial_vesting_balances)(initial_active_witnesses)(initial_witness_candidates)
(initial_committee_candidates)(initial_worker_candidates)
(initial_chain_id)
(immutable_parameters))
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::genesis_state_type::initial_account_type)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::genesis_state_type::initial_asset_type)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::genesis_state_type::initial_asset_type::initial_collateral_position)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::genesis_state_type::initial_balance_type)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::genesis_state_type::initial_vesting_balance_type)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::genesis_state_type::initial_witness_type)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::genesis_state_type::initial_committee_member_type)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::genesis_state_type::initial_worker_type)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::genesis_state_type::initial_bts_account_type::initial_authority)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::genesis_state_type::initial_bts_account_type::initial_cdd_vesting_policy)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::genesis_state_type::initial_bts_account_type::initial_linear_vesting_policy)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::genesis_state_type::initial_bts_account_type::initial_vesting_balance)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::genesis_state_type::initial_bts_account_type)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::genesis_state_type)

View file

@ -130,7 +130,6 @@ namespace graphene { namespace chain {
}}
FC_REFLECT_DERIVED( graphene::chain::dynamic_global_property_object, (graphene::db::object),
(random)
(head_block_number)
(head_block_id)
(time)
@ -156,3 +155,6 @@ FC_REFLECT_DERIVED( graphene::chain::global_property_object, (graphene::db::obje
(active_witnesses)
(active_sons)
)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::dynamic_global_property_object )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::global_property_object )

View file

@ -23,11 +23,8 @@
*/
#pragma once
#include <fc/reflect/reflect.hpp>
#include <cstdint>
#include <graphene/chain/config.hpp>
#include <graphene/chain/protocol/types.hpp>
namespace graphene { namespace chain {
@ -49,3 +46,5 @@ FC_REFLECT( graphene::chain::immutable_chain_parameters,
(num_special_accounts)
(num_special_assets)
)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::immutable_chain_parameters )

View file

@ -28,7 +28,7 @@
#include <graphene/chain/protocol/transaction.hpp>
#include <graphene/chain/protocol/types.hpp>
namespace graphene { namespace app {
namespace graphene { namespace chain {
void operation_get_impacted_accounts(
const graphene::chain::operation& op,
@ -39,4 +39,4 @@ void transaction_get_impacted_accounts(
fc::flat_set<graphene::chain::account_id_type>& result
);
} } // graphene::app
} } // graphene::app

View file

@ -217,3 +217,7 @@ FC_REFLECT_DERIVED( graphene::chain::force_settlement_object,
(graphene::db::object),
(owner)(balance)(settlement_date)
)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::limit_order_object )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::call_order_object )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::force_settlement_object )

View file

@ -22,8 +22,10 @@
* THE SOFTWARE.
*/
#pragma once
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/db/object.hpp>
#include <boost/multi_index/composite_key.hpp>
namespace graphene { namespace chain {
@ -94,15 +96,22 @@ namespace graphene { namespace chain {
operation_history_id_type operation_id;
uint32_t sequence = 0; /// the operation position within the given account
account_transaction_history_id_type next;
//std::pair<account_id_type,operation_history_id_type> account_op()const { return std::tie( account, operation_id ); }
//std::pair<account_id_type,uint32_t> account_seq()const { return std::tie( account, sequence ); }
};
struct by_id;
struct by_seq;
struct by_op;
struct by_opid;
typedef multi_index_container<
operation_history_object,
indexed_by<
ordered_unique< tag<by_id>, member< object, object_id_type, &object::id > >
>
> operation_history_multi_index_type;
typedef generic_index<operation_history_object, operation_history_multi_index_type> operation_history_index;
typedef multi_index_container<
account_transaction_history_object,
indexed_by<
@ -132,6 +141,8 @@ typedef generic_index<account_transaction_history_object, account_transaction_hi
FC_REFLECT_DERIVED( graphene::chain::operation_history_object, (graphene::chain::object),
(op)(result)(block_num)(trx_in_block)(op_in_trx)(virtual_op) )
FC_REFLECT_DERIVED( graphene::chain::account_transaction_history_object, (graphene::chain::object),
(account)(operation_id)(sequence)(next) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::operation_history_object )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::account_transaction_history_object )

View file

@ -27,9 +27,10 @@
#include <graphene/chain/transaction_evaluation_state.hpp>
#include <graphene/db/generic_index.hpp>
#include <boost/multi_index/composite_key.hpp>
namespace graphene { namespace chain {
class database;
/**
* @brief tracks the approval of a partially approved transaction
@ -97,3 +98,5 @@ FC_REFLECT_DERIVED( graphene::chain::proposal_object, (graphene::chain::object),
(expiration_time)(review_period_time)(proposed_transaction)(required_active_approvals)
(available_active_approvals)(required_owner_approvals)(available_owner_approvals)
(available_key_approvals)(proposer)(fail_reason))
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::proposal_object )

View file

@ -59,6 +59,12 @@ namespace graphene { namespace chain {
/// account's balance of core asset.
flat_set<vote_id_type> votes;
extensions_type extensions;
/// Whether this account is voting
inline bool is_voting() const
{
return ( voting_account != GRAPHENE_PROXY_TO_SELF_ACCOUNT || !votes.empty() );
}
void validate()const;
};
@ -143,6 +149,7 @@ namespace graphene { namespace chain {
optional< void_t > null_ext;
optional< special_authority > owner_special_authority;
optional< special_authority > active_special_authority;
optional< bool > update_last_voting_time;
};
struct fee_parameters_type
@ -298,7 +305,7 @@ FC_REFLECT( graphene::chain::account_create_operation,
(name)(owner)(active)(options)(extensions)
)
FC_REFLECT(graphene::chain::account_update_operation::ext, (null_ext)(owner_special_authority)(active_special_authority) )
FC_REFLECT(graphene::chain::account_update_operation::ext, (null_ext)(owner_special_authority)(active_special_authority)(update_last_voting_time) )
FC_REFLECT( graphene::chain::account_update_operation,
(fee)(account)(owner)(active)(new_options)(extensions)
)
@ -313,5 +320,16 @@ FC_REFLECT( graphene::chain::account_whitelist_operation::fee_parameters_type, (
FC_REFLECT( graphene::chain::account_update_operation::fee_parameters_type, (fee)(price_per_kbyte) )
FC_REFLECT( graphene::chain::account_upgrade_operation::fee_parameters_type, (membership_annual_fee)(membership_lifetime_fee) )
FC_REFLECT( graphene::chain::account_transfer_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::account_transfer_operation, (fee)(account_id)(new_owner)(extensions) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::account_options )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::account_create_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::account_whitelist_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::account_update_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::account_upgrade_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::account_transfer_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::account_create_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::account_whitelist_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::account_update_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::account_upgrade_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::account_transfer_operation )

View file

@ -25,14 +25,10 @@
#include <graphene/chain/config.hpp>
#include <graphene/chain/pts_address.hpp>
#include <graphene/chain/protocol/types.hpp>
#include <fc/array.hpp>
#include <fc/crypto/ripemd160.hpp>
namespace fc { namespace ecc {
class public_key;
typedef fc::array<char,33> public_key_data;
} } // fc::ecc
#include <fc/reflect/typename.hpp>
namespace graphene { namespace chain {
@ -51,7 +47,7 @@ namespace graphene { namespace chain {
class address
{
public:
address(); ///< constructs empty / null address
address(){} ///< constructs empty / null address
explicit address( const std::string& base58str ); ///< converts to binary, validates checksum
address( const fc::ecc::public_key& pub ); ///< converts to binary
explicit address( const fc::ecc::public_key_data& pub ); ///< converts to binary
@ -97,3 +93,5 @@ namespace std
#include <fc/reflect/reflect.hpp>
FC_REFLECT( graphene::chain::address, (addr) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::address )

View file

@ -23,6 +23,7 @@
*/
#pragma once
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/protocol/asset.hpp>
namespace graphene { namespace chain {
@ -112,3 +113,5 @@ FC_REFLECT( graphene::chain::block_id_predicate, (id) )
FC_REFLECT_TYPENAME( graphene::chain::predicate )
FC_REFLECT( graphene::chain::assert_operation, (fee)(fee_paying_account)(predicates)(required_auths)(extensions) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::assert_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::assert_operation )

View file

@ -218,3 +218,7 @@ FC_REFLECT( graphene::chain::price, (base)(quote) )
(core_exchange_rate)
FC_REFLECT( graphene::chain::price_feed, GRAPHENE_PRICE_FEED_FIELDS )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::price )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::price_feed )

View file

@ -764,3 +764,30 @@ FC_REFLECT( graphene::chain::asset_reserve_operation,
FC_REFLECT( graphene::chain::asset_fund_fee_pool_operation, (fee)(from_account)(asset_id)(amount)(extensions) );
FC_REFLECT( graphene::chain::asset_dividend_distribution_operation, (fee)(dividend_asset_id)(account_id)(amounts)(extensions) );
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_options )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::bitasset_options )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_create_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_global_settle_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_settle_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_fund_fee_pool_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_dividend_distribution_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_claim_fees_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_update_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_update_bitasset_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_update_feed_producers_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_publish_feed_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_issue_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_reserve_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_create_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_global_settle_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_settle_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_settle_cancel_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_fund_fee_pool_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_claim_fees_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_update_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_update_bitasset_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_update_feed_producers_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_publish_feed_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_issue_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::asset_reserve_operation )

View file

@ -23,6 +23,7 @@
*/
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/protocol/address.hpp>
namespace graphene { namespace chain {
@ -134,3 +135,5 @@ void add_authority_accounts(
FC_REFLECT( graphene::chain::authority, (weight_threshold)(account_auths)(key_auths)(address_auths) )
// FC_REFLECT_TYPENAME( graphene::chain::authority::classification )
FC_REFLECT_ENUM( graphene::chain::authority::classification, (owner)(active)(key) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::authority )

View file

@ -23,6 +23,8 @@
*/
#pragma once
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/protocol/asset.hpp>
#include <graphene/chain/protocol/authority.hpp>
namespace graphene { namespace chain {
@ -57,3 +59,5 @@ namespace graphene { namespace chain {
FC_REFLECT( graphene::chain::balance_claim_operation::fee_parameters_type, )
FC_REFLECT( graphene::chain::balance_claim_operation,
(fee)(deposit_to_account)(balance_to_claim)(balance_owner_key)(total_claimed) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::balance_claim_operation )

View file

@ -27,8 +27,13 @@
#include <graphene/chain/protocol/asset.hpp>
#include <graphene/chain/protocol/authority.hpp>
#include <fc/thread/future.hpp>
namespace graphene { namespace chain {
struct asset;
struct authority;
/**
* @defgroup operations Operations
* @ingroup transactions Transactions

View file

@ -69,3 +69,8 @@ FC_REFLECT( graphene::chain::block_header,
(extensions) )
FC_REFLECT_DERIVED( graphene::chain::signed_block_header, (graphene::chain::block_header), (witness_signature) )
FC_REFLECT_DERIVED( graphene::chain::signed_block, (graphene::chain::signed_block_header), (transactions) )
GRAPHENE_EXTERNAL_SERIALIZATION(extern, graphene::chain::block_header)
GRAPHENE_EXTERNAL_SERIALIZATION(extern, graphene::chain::signed_block_header)
GRAPHENE_EXTERNAL_SERIALIZATION(extern, graphene::chain::signed_block)

View file

@ -50,3 +50,5 @@ struct buyback_account_options
} }
FC_REFLECT( graphene::chain::buyback_account_options, (asset_to_buy)(asset_to_buy_issuer)(markets) );
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::buyback_account_options )

View file

@ -28,6 +28,8 @@
#include <fc/smart_ref_fwd.hpp>
#include <graphene/chain/hardfork.hpp>
#include <../hardfork.d/GPOS.hf>
#include <memory>
namespace graphene { namespace chain { struct fee_schedule; } }
@ -39,10 +41,16 @@ namespace graphene { namespace chain {
optional< uint16_t > betting_rake_fee_percentage;
optional< flat_map<bet_multiplier_type, bet_multiplier_type> > permitted_betting_odds_increments;
optional< uint16_t > live_betting_delay_time;
optional< uint16_t > sweeps_distribution_percentage = SWEEPS_DEFAULT_DISTRIBUTION_PERCENTAGE;
optional< asset_id_type > sweeps_distribution_asset = SWEEPS_DEFAULT_DISTRIBUTION_ASSET;
optional< account_id_type > sweeps_vesting_accumulator_account= SWEEPS_ACCUMULATOR_ACCOUNT;
/* gpos parameters */
optional < uint32_t > gpos_period = GPOS_PERIOD;
optional < uint32_t > gpos_subperiod = GPOS_SUBPERIOD;
optional < uint32_t > gpos_period_start = HARDFORK_GPOS_TIME.sec_since_epoch();
optional < uint32_t > gpos_vesting_lockin_period = GPOS_VESTING_LOCKIN_PERIOD;
optional < uint16_t > son_count;
optional< uint16_t > sweeps_distribution_percentage;
optional< asset_id_type > sweeps_distribution_asset;
optional< account_id_type > sweeps_vesting_accumulator_account;
optional < uint32_t > son_vesting_amount;
optional < uint32_t > son_vesting_period;
optional < uint32_t > son_pay_daily_max;
@ -155,6 +163,18 @@ namespace graphene { namespace chain {
inline uint16_t son_down_time()const {
return extensions.value.son_down_time.valid() ? *extensions.value.son_down_time : SON_DOWN_TIME;
}
inline uint32_t gpos_period()const {
return extensions.value.gpos_period.valid() ? *extensions.value.gpos_period : GPOS_PERIOD; /// total seconds of current gpos period
}
inline uint32_t gpos_subperiod()const {
return extensions.value.gpos_subperiod.valid() ? *extensions.value.gpos_subperiod : GPOS_SUBPERIOD; /// gpos_period % gpos_subperiod = 0
}
inline uint32_t gpos_period_start()const {
return extensions.value.gpos_period_start.valid() ? *extensions.value.gpos_period_start : HARDFORK_GPOS_TIME.sec_since_epoch(); /// current period start date
}
inline uint32_t gpos_vesting_lockin_period()const {
return extensions.value.gpos_vesting_lockin_period.valid() ? *extensions.value.gpos_vesting_lockin_period : GPOS_VESTING_LOCKIN_PERIOD; /// GPOS vesting lockin period
}
inline account_id_type son_account() const {
return extensions.value.son_account.valid() ? *extensions.value.son_account : GRAPHENE_NULL_ACCOUNT;
}
@ -172,6 +192,10 @@ FC_REFLECT( graphene::chain::parameter_extension,
(sweeps_distribution_percentage)
(sweeps_distribution_asset)
(sweeps_vesting_accumulator_account)
(gpos_period)
(gpos_subperiod)
(gpos_period_start)
(gpos_vesting_lockin_period)
(son_vesting_amount)
(son_vesting_period)
(son_pay_daily_max)
@ -228,3 +252,5 @@ FC_REFLECT( graphene::chain::chain_parameters,
(maximum_tournament_number_of_wins)
(extensions)
)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::chain_parameters )

View file

@ -104,3 +104,10 @@ FC_REFLECT( graphene::chain::committee_member_create_operation,
FC_REFLECT( graphene::chain::committee_member_update_operation,
(fee)(committee_member)(committee_member_account)(new_url) )
FC_REFLECT( graphene::chain::committee_member_update_global_parameters_operation, (fee)(new_parameters) );
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::committee_member_create_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::committee_member_update_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::committee_member_update_global_parameters_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::committee_member_create_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::committee_member_update_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::committee_member_update_global_parameters_operation )

View file

@ -281,3 +281,10 @@ FC_REFLECT( graphene::chain::blind_transfer_operation,
FC_REFLECT( graphene::chain::transfer_to_blind_operation::fee_parameters_type, (fee)(price_per_output) )
FC_REFLECT( graphene::chain::transfer_from_blind_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::blind_transfer_operation::fee_parameters_type, (fee)(price_per_output) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::transfer_to_blind_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::transfer_from_blind_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::blind_transfer_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::transfer_to_blind_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::transfer_from_blind_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::blind_transfer_operation )

View file

@ -56,3 +56,6 @@ namespace graphene { namespace chain {
FC_REFLECT( graphene::chain::custom_operation::fee_parameters_type, (fee)(price_per_kbyte) )
FC_REFLECT( graphene::chain::custom_operation, (fee)(payer)(required_auths)(id)(data) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::custom_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::custom_operation )

View file

@ -24,6 +24,7 @@
#pragma once
#include <fc/io/varint.hpp>
#include <fc/io/raw_fwd.hpp>
#include <fc/reflect/reflect.hpp>
namespace graphene { namespace chain {

View file

@ -23,6 +23,7 @@
*/
#pragma once
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/protocol/asset.hpp>
namespace graphene { namespace chain {
@ -45,3 +46,5 @@ struct fba_distribute_operation : public base_operation
FC_REFLECT( graphene::chain::fba_distribute_operation::fee_parameters_type, )
FC_REFLECT( graphene::chain::fba_distribute_operation, (fee)(account_id)(fba_id)(amount) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::fba_distribute_operation )

View file

@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
#pragma once
#include <fc/smart_ref_fwd.hpp>
#include <graphene/chain/protocol/operations.hpp>
namespace graphene { namespace chain {
@ -85,3 +86,5 @@ namespace graphene { namespace chain {
FC_REFLECT_TYPENAME( graphene::chain::fee_parameters )
FC_REFLECT( graphene::chain::fee_schedule, (parameters)(scale) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::fee_schedule )

View file

@ -23,6 +23,7 @@
*/
#pragma once
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/protocol/asset.hpp>
namespace graphene { namespace chain {
@ -165,9 +166,15 @@ FC_REFLECT( graphene::chain::limit_order_cancel_operation::fee_parameters_type,
FC_REFLECT( graphene::chain::call_order_update_operation::fee_parameters_type, (fee) )
/// THIS IS THE ONLY VIRTUAL OPERATION THUS FAR...
FC_REFLECT( graphene::chain::fill_order_operation::fee_parameters_type, )
FC_REFLECT( graphene::chain::limit_order_create_operation,(fee)(seller)(amount_to_sell)(min_to_receive)(expiration)(fill_or_kill)(extensions))
FC_REFLECT( graphene::chain::limit_order_cancel_operation,(fee)(fee_paying_account)(order)(extensions) )
FC_REFLECT( graphene::chain::call_order_update_operation, (fee)(funding_account)(delta_collateral)(delta_debt)(extensions) )
FC_REFLECT( graphene::chain::fill_order_operation, (fee)(order_id)(account_id)(pays)(receives) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::limit_order_create_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::limit_order_cancel_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::call_order_update_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::limit_order_create_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::limit_order_cancel_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::call_order_update_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::fill_order_operation )

View file

@ -89,3 +89,6 @@ namespace graphene { namespace chain {
FC_REFLECT( graphene::chain::memo_message, (checksum)(text) )
FC_REFLECT( graphene::chain::memo_data, (from)(to)(nonce)(message) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::memo_message )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::memo_data )

View file

@ -191,3 +191,5 @@ namespace graphene { namespace chain {
FC_REFLECT_TYPENAME( graphene::chain::operation )
FC_REFLECT( graphene::chain::op_wrapper, (op) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::op_wrapper )

View file

@ -23,6 +23,7 @@
*/
#pragma once
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/protocol/asset.hpp>
namespace graphene { namespace chain {
/**
@ -179,3 +180,10 @@ FC_REFLECT( graphene::chain::proposal_update_operation, (fee)(fee_paying_account
(active_approvals_to_add)(active_approvals_to_remove)(owner_approvals_to_add)(owner_approvals_to_remove)
(key_approvals_to_add)(key_approvals_to_remove)(extensions) )
FC_REFLECT( graphene::chain::proposal_delete_operation, (fee)(fee_paying_account)(using_owner_authority)(proposal)(extensions) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::proposal_create_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::proposal_update_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::proposal_delete_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::proposal_create_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::proposal_update_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::proposal_delete_operation )

View file

@ -48,3 +48,5 @@ void validate_special_authority( const special_authority& auth );
FC_REFLECT( graphene::chain::no_special_authority, )
FC_REFLECT( graphene::chain::top_holders_special_authority, (asset)(num_top_holders) )
FC_REFLECT_TYPENAME( graphene::chain::special_authority )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::top_holders_special_authority )

View file

@ -230,3 +230,8 @@ FC_REFLECT( graphene::chain::transaction, (ref_block_num)(ref_block_prefix)(expi
// Note: not reflecting signees field for backward compatibility; in addition, it should not be in p2p messages
FC_REFLECT_DERIVED( graphene::chain::signed_transaction, (graphene::chain::transaction), (signatures) )
FC_REFLECT_DERIVED( graphene::chain::processed_transaction, (graphene::chain::signed_transaction), (operation_results) )
GRAPHENE_EXTERNAL_SERIALIZATION(extern, graphene::chain::transaction)
GRAPHENE_EXTERNAL_SERIALIZATION(extern, graphene::chain::signed_transaction)
GRAPHENE_EXTERNAL_SERIALIZATION(extern, graphene::chain::processed_transaction)

View file

@ -24,6 +24,7 @@
#pragma once
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/protocol/memo.hpp>
#include <graphene/chain/protocol/asset.hpp>
namespace graphene { namespace chain {
@ -105,3 +106,8 @@ FC_REFLECT( graphene::chain::override_transfer_operation::fee_parameters_type, (
FC_REFLECT( graphene::chain::override_transfer_operation, (fee)(issuer)(from)(to)(amount)(memo)(extensions) )
FC_REFLECT( graphene::chain::transfer_operation, (fee)(from)(to)(amount)(memo)(extensions) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::transfer_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::override_transfer_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::transfer_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::override_transfer_operation )

View file

@ -27,13 +27,15 @@
#include <fc/io/enum_type.hpp>
#include <fc/crypto/sha224.hpp>
#include <fc/crypto/elliptic.hpp>
#include <fc/crypto/ripemd160.hpp>
#include <fc/reflect/reflect.hpp>
#include <fc/reflect/variant.hpp>
#include <fc/optional.hpp>
#include <fc/safe.hpp>
#include <fc/container/flat.hpp>
#include <fc/string.hpp>
#include <fc/io/raw.hpp>
#include <fc/io/datastream.hpp>
#include <fc/io/raw_fwd.hpp>
#include <fc/uint128.hpp>
#include <fc/static_variant.hpp>
#include <fc/smart_ref_fwd.hpp>
@ -42,10 +44,34 @@
#include <vector>
#include <deque>
#include <cstdint>
#include <graphene/chain/protocol/address.hpp>
#include <graphene/db/object_id.hpp>
#include <graphene/chain/protocol/config.hpp>
#define GRAPHENE_EXTERNAL_SERIALIZATION(ext, type) \
namespace fc { \
ext template void from_variant( const variant& v, type& vo, uint32_t max_depth ); \
ext template void to_variant( const type& v, variant& vo, uint32_t max_depth ); \
namespace raw { \
ext template void pack< datastream<size_t>, type >( datastream<size_t>& s, const type& tx, uint32_t _max_depth=FC_PACK_MAX_DEPTH ); \
ext template void pack< datastream<char*>, type >( datastream<char*>& s, const type& tx, uint32_t _max_depth=FC_PACK_MAX_DEPTH ); \
ext template void unpack< datastream<const char*>, type >( datastream<const char*>& s, type& tx, uint32_t _max_depth=FC_PACK_MAX_DEPTH ); \
} } // fc::raw
#define FC_REFLECT_DERIVED_NO_TYPENAME( TYPE, INHERITS, MEMBERS ) \
namespace fc { \
template<> struct reflector<TYPE> {\
typedef TYPE type; \
typedef fc::true_type is_defined; \
typedef fc::false_type is_enum; \
enum member_count_enum { \
local_member_count = 0 BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_MEMBER_COUNT, +, MEMBERS ),\
total_member_count = local_member_count BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_BASE_MEMBER_COUNT, +, INHERITS )\
}; \
FC_REFLECT_DERIVED_IMPL_INLINE( TYPE, INHERITS, MEMBERS ) \
}; \
} // fc
namespace graphene { namespace chain {
using namespace graphene::db;

View file

@ -23,11 +23,24 @@
*/
#pragma once
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/protocol/asset.hpp>
namespace graphene { namespace chain {
enum class vesting_balance_type { normal, gpos, son };
inline std::string get_vesting_balance_type(vesting_balance_type type) {
switch (type) {
case vesting_balance_type::normal:
return "NORMAL";
case vesting_balance_type::son:
return "SON";
case vesting_balance_type::gpos:
default:
return "GPOS";
}
}
struct linear_vesting_policy_initializer
{
/** while vesting begins on begin_timestamp, none may be claimed before vesting_cliff_seconds have passed */
@ -124,4 +137,9 @@ FC_REFLECT(graphene::chain::cdd_vesting_policy_initializer, (start_claim)(vestin
FC_REFLECT(graphene::chain::dormant_vesting_policy_initializer, )
FC_REFLECT_TYPENAME( graphene::chain::vesting_policy_initializer )
FC_REFLECT_ENUM( graphene::chain::vesting_balance_type, (normal)(gpos)(son) )
FC_REFLECT_ENUM( graphene::chain::vesting_balance_type, (normal)(gpos)(son))
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::vesting_balance_create_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::vesting_balance_withdraw_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::vesting_balance_create_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::vesting_balance_withdraw_operation )

View file

@ -24,12 +24,7 @@
#pragma once
#include <cassert>
#include <cstdint>
#include <string>
#include <fc/container/flat.hpp>
#include <fc/reflect/reflect.hpp>
#include <graphene/chain/protocol/types.hpp>
namespace graphene { namespace chain {
@ -151,3 +146,5 @@ FC_REFLECT_TYPENAME( fc::flat_set<graphene::chain::vote_id_type> )
FC_REFLECT_ENUM( graphene::chain::vote_id_type::vote_type, (witness)(committee)(worker)(son)(VOTE_TYPE_COUNT) )
FC_REFLECT( graphene::chain::vote_id_type, (content) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::vote_id_type )

View file

@ -24,6 +24,7 @@
#pragma once
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/protocol/memo.hpp>
#include <graphene/chain/protocol/asset.hpp>
namespace graphene { namespace chain {
@ -179,3 +180,12 @@ FC_REFLECT( graphene::chain::withdraw_permission_update_operation, (fee)(withdra
FC_REFLECT( graphene::chain::withdraw_permission_claim_operation, (fee)(withdraw_permission)(withdraw_from_account)(withdraw_to_account)(amount_to_withdraw)(memo) );
FC_REFLECT( graphene::chain::withdraw_permission_delete_operation, (fee)(withdraw_from_account)(authorized_account)
(withdrawal_permission) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::withdraw_permission_create_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::withdraw_permission_update_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::withdraw_permission_claim_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::withdraw_permission_delete_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::withdraw_permission_create_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::withdraw_permission_update_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::withdraw_permission_claim_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::withdraw_permission_delete_operation )

View file

@ -23,6 +23,7 @@
*/
#pragma once
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/protocol/asset.hpp>
namespace graphene { namespace chain {
@ -84,3 +85,8 @@ FC_REFLECT( graphene::chain::witness_create_operation, (fee)(witness_account)(ur
FC_REFLECT( graphene::chain::witness_update_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::witness_update_operation, (fee)(witness)(witness_account)(new_url)(new_signing_key)(new_initial_secret) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::witness_create_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::witness_update_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::witness_create_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::witness_update_operation )

View file

@ -23,6 +23,7 @@
*/
#pragma once
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/protocol/asset.hpp>
namespace graphene { namespace chain {
@ -104,3 +105,5 @@ FC_REFLECT( graphene::chain::worker_create_operation::fee_parameters_type, (fee)
FC_REFLECT( graphene::chain::worker_create_operation,
(fee)(owner)(work_begin_date)(work_end_date)(daily_pay)(name)(url)(initializer) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::worker_create_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::worker_create_operation )

View file

@ -24,6 +24,8 @@
#pragma once
#include <fc/array.hpp>
#include <fc/io/datastream.hpp>
#include <fc/io/raw_fwd.hpp>
#include <string>
namespace fc { namespace ecc { class public_key; } }
@ -75,4 +77,11 @@ namespace fc
{
void to_variant( const graphene::chain::pts_address& var, fc::variant& vo, uint32_t max_depth = 1 );
void from_variant( const fc::variant& var, graphene::chain::pts_address& vo, uint32_t max_depth = 1 );
}
namespace raw {
extern template void pack( datastream<size_t>& s, const graphene::chain::pts_address& tx,
uint32_t _max_depth=FC_PACK_MAX_DEPTH );
extern template void pack( datastream<char*>& s, const graphene::chain::pts_address& tx,
uint32_t _max_depth=FC_PACK_MAX_DEPTH );
extern template void unpack( datastream<const char*>& s, graphene::chain::pts_address& tx,
uint32_t _max_depth=FC_PACK_MAX_DEPTH );
} } // fc::raw

View file

@ -68,3 +68,5 @@ FC_REFLECT_DERIVED(
(graphene::db::object),
(account)
)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::special_authority_object )

View file

@ -22,12 +22,10 @@
* THE SOFTWARE.
*/
#pragma once
#include <fc/io/raw.hpp>
#include <graphene/chain/protocol/transaction.hpp>
#include <graphene/db/index.hpp>
#include <graphene/db/generic_index.hpp>
#include <fc/uint128.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
@ -72,3 +70,5 @@ namespace graphene { namespace chain {
} }
FC_REFLECT_DERIVED( graphene::chain::transaction_object, (graphene::db::object), (trx)(trx_id) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::transaction_object )

View file

@ -46,6 +46,7 @@ class vesting_balance_withdraw_evaluator : public evaluator<vesting_balance_with
void_result do_evaluate( const vesting_balance_withdraw_operation& op );
void_result do_apply( const vesting_balance_withdraw_operation& op );
virtual operation_result start_evaluate(transaction_evaluation_state& eval_state, const operation& op, bool apply);
};
} } // graphene::chain

View file

@ -37,8 +37,6 @@
namespace graphene { namespace chain {
using namespace graphene::db;
class vesting_balance_object;
struct vesting_policy_context
{
vesting_policy_context(
@ -212,12 +210,14 @@ namespace graphene { namespace chain {
composite_key<
vesting_balance_object,
member_offset<vesting_balance_object, asset_id_type, (size_t) (offsetof(vesting_balance_object,balance) + offsetof(asset,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))>
>,
composite_key_compare<
std::less< asset_id_type >,
std::less< vesting_balance_type >,
std::greater< share_type >
//std::less< account_id_type >
>
@ -255,3 +255,7 @@ FC_REFLECT_DERIVED(graphene::chain::vesting_balance_object, (graphene::db::objec
(policy)
(balance_type)
)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::linear_vesting_policy )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::cdd_vesting_policy )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::vesting_balance_object )

View file

@ -114,3 +114,5 @@ FC_REFLECT_DERIVED( graphene::chain::withdraw_permission_object, (graphene::db::
(expiration)
(claimed_this_period)
)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::withdraw_permission_object )

View file

@ -29,8 +29,6 @@
namespace graphene { namespace chain {
using namespace graphene::db;
class witness_object;
class witness_object : public abstract_object<witness_object>
{
public:
@ -85,3 +83,5 @@ FC_REFLECT_DERIVED( graphene::chain::witness_object, (graphene::db::object),
(total_missed)
(last_confirmed_block_num)
)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::witness_object )

View file

@ -153,3 +153,6 @@ FC_REFLECT_DERIVED(
(recent_slots_filled)
(current_shuffled_sons)
)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::witness_scheduler )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::witness_schedule_object )

View file

@ -22,8 +22,9 @@
* THE SOFTWARE.
*/
#pragma once
#include <graphene/db/object.hpp>
#include <graphene/chain/protocol/types.hpp>
#include <graphene/db/generic_index.hpp>
#include <graphene/chain/protocol/vote.hpp>
namespace graphene { namespace chain {
@ -175,3 +176,5 @@ FC_REFLECT_DERIVED( graphene::chain::worker_object, (graphene::db::object),
(name)
(url)
)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::worker_object )

View file

@ -46,15 +46,7 @@ struct proposal_operation_hardfork_visitor
template<typename T>
void operator()(const T &v) const {}
void operator()(const committee_member_update_global_parameters_operation &op) const {
if( block_time < HARDFORK_1000_TIME ) // TODO: remove after hf
FC_ASSERT( !op.new_parameters.extensions.value.min_bet_multiplier.valid()
&& !op.new_parameters.extensions.value.max_bet_multiplier.valid()
&& !op.new_parameters.extensions.value.betting_rake_fee_percentage.valid()
&& !op.new_parameters.extensions.value.permitted_betting_odds_increments.valid()
&& !op.new_parameters.extensions.value.live_betting_delay_time.valid(),
"Parameter extensions are not allowed yet!" );
}
void operator()(const committee_member_update_global_parameters_operation &op) const {}
void operator()(const graphene::chain::tournament_payout_operation &o) const {
// TODO: move check into tournament_payout_operation::validate after HARDFORK_999_TIME
@ -160,6 +152,11 @@ struct proposal_operation_hardfork_visitor
FC_ASSERT( block_time >= HARDFORK_SON_TIME, "son_maintenance_operation not allowed yet!" );
}
void operator()(const vesting_balance_create_operation &vbco) const {
if(block_time < HARDFORK_GPOS_TIME)
FC_ASSERT( vbco.balance_type == vesting_balance_type::normal, "balance_type in vesting create not allowed yet!" );
}
// loop and self visit in proposals
void operator()(const proposal_create_operation &v) const {
for (const op_wrapper &op : v.proposed_ops)

View file

@ -37,7 +37,7 @@ bool proposal_object::is_authorized_to_execute(database& db) const
[&]( account_id_type id ){ return &id(db).active; },
[&]( account_id_type id ){ return &id(db).owner; },
db.get_global_properties().parameters.max_authority_depth,
true, /* allow committeee */
true, /* allow committee */
available_active_approvals,
available_owner_approvals );
}
@ -90,3 +90,5 @@ void required_approval_index::object_removed( const object& obj )
}
} } // graphene::chain
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::proposal_object )

View file

@ -24,6 +24,9 @@
#include <graphene/chain/protocol/account.hpp>
#include <graphene/chain/hardfork.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <fc/io/raw.hpp>
namespace graphene { namespace chain {
/**
@ -281,6 +284,7 @@ void account_update_operation::validate()const
|| new_options.valid()
|| extensions.value.owner_special_authority.valid()
|| extensions.value.active_special_authority.valid()
|| extensions.value.update_last_voting_time.valid()
);
FC_ASSERT( has_action );
@ -326,3 +330,15 @@ void account_transfer_operation::validate()const
} } // graphene::chain
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::account_options )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::account_create_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::account_whitelist_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::account_update_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::account_upgrade_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::account_transfer_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::account_create_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::account_whitelist_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::account_update_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::account_upgrade_operation )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::account_transfer_operation )

View file

@ -27,9 +27,10 @@
#include <fc/crypto/base58.hpp>
#include <algorithm>
#include <fc/io/raw.hpp>
namespace graphene {
namespace chain {
address::address(){}
address::address( const std::string& base58str )
{
@ -110,3 +111,5 @@ namespace fc
vo = graphene::chain::address( var.as_string() );
}
}
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::address )

View file

@ -21,7 +21,11 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <graphene/chain/protocol/protocol.hpp>
#include <graphene/chain/protocol/account.hpp>
#include <graphene/chain/protocol/asset_ops.hpp>
#include <graphene/chain/protocol/assert.hpp>
#include <fc/io/raw.hpp>
namespace graphene { namespace chain {
@ -62,5 +66,7 @@ share_type assert_operation::calculate_fee(const fee_parameters_type& k)const
return k.fee * predicates.size();
}
} } // namespace graphene::chain
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::assert_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::assert_operation )

View file

@ -24,6 +24,7 @@
#include <graphene/chain/protocol/asset.hpp>
#include <boost/rational.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <fc/io/raw.hpp>
namespace graphene { namespace chain {
typedef boost::multiprecision::uint128_t uint128_t;
@ -130,7 +131,11 @@ namespace graphene { namespace chain {
return ~(asset( cp.numerator().convert_to<int64_t>(), debt.asset_id ) / asset( cp.denominator().convert_to<int64_t>(), collateral.asset_id ));
} FC_CAPTURE_AND_RETHROW( (debt)(collateral)(collateral_ratio) ) }
bool price::is_null() const { return *this == price(); }
bool price::is_null() const
{
// Effectively same as "return *this == price();" but perhaps faster
return ( base.asset_id == asset_id_type() && quote.asset_id == asset_id_type() );
}
void price::validate() const
{ try {
@ -202,3 +207,7 @@ const int64_t scaled_precision_lut[19] =
};
} } // graphene::chain
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::asset )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::price )
GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::price_feed )

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