[SON-271] Merge recent develop branch changes(both GPOS and graphene updates) into SONs branch (#322)
This commit is contained in:
parent
e170676ff9
commit
54390346c1
173 changed files with 7814 additions and 1521 deletions
0
.clang-format
Executable file → Normal file
0
.clang-format
Executable file → Normal file
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -11,6 +11,7 @@ moc_*
|
|||
hardfork.hpp
|
||||
build_xc
|
||||
data
|
||||
CMakeDoxyfile.in
|
||||
|
||||
build
|
||||
|
||||
|
|
|
|||
3
.gitmodules
vendored
3
.gitmodules
vendored
|
|
@ -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
279
CMakeDoxyfile.in
Normal 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@
|
||||
2
Doxyfile
2
Doxyfile
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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" )
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 //
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
||||
} }
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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>();
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
#include <graphene/chain/balance_evaluator.hpp>
|
||||
#include <graphene/chain/pts_address.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
|
|
|
|||
|
|
@ -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() )
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
} }
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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() )
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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) ) }
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
4
libraries/chain/hardfork.d/GPOS.hf
Normal file
4
libraries/chain/hardfork.d/GPOS.hf
Normal 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
|
||||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
#include <fstream>
|
||||
#include <graphene/chain/protocol/block.hpp>
|
||||
|
||||
#include <fc/filesystem.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
class index_entry;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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" )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -68,3 +68,5 @@ FC_REFLECT_DERIVED(
|
|||
(graphene::db::object),
|
||||
(account)
|
||||
)
|
||||
|
||||
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::special_authority_object )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in a new issue